383c1c0742558a2c28747a48160d79482302c91f
[libfirm] / ir / be / arm / bearch_arm.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief   The main arm backend driver file.
23  * @author  Matthias Braun, Oliver Richter, Tobias Gneist
24  * @version $Id$
25  */
26 #include "config.h"
27
28 #include "lc_opts.h"
29 #include "lc_opts_enum.h"
30
31 #include "pseudo_irg.h"
32 #include "irgwalk.h"
33 #include "irprog.h"
34 #include "irprintf.h"
35 #include "ircons.h"
36 #include "irgmod.h"
37 #include "irgopt.h"
38 #include "iroptimize.h"
39 #include "irdump.h"
40 #include "lowering.h"
41 #include "error.h"
42
43 #include "bitset.h"
44 #include "debug.h"
45 #include "array_t.h"
46 #include "irtools.h"
47
48 #include "../bearch.h"
49 #include "../benode.h"
50 #include "../belower.h"
51 #include "../besched.h"
52 #include "be.h"
53 #include "../beabi.h"
54 #include "../bemachine.h"
55 #include "../beilpsched.h"
56 #include "../bemodule.h"
57 #include "../beirg.h"
58 #include "../bespillslots.h"
59 #include "../begnuas.h"
60 #include "../belistsched.h"
61 #include "../beflags.h"
62
63 #include "bearch_arm_t.h"
64
65 #include "arm_new_nodes.h"
66 #include "gen_arm_regalloc_if.h"
67 #include "arm_transform.h"
68 #include "arm_optimize.h"
69 #include "arm_emitter.h"
70 #include "arm_map_regs.h"
71
72 static arch_irn_class_t arm_classify(const ir_node *irn)
73 {
74         (void) irn;
75         /* TODO: we should mark reload/spill instructions and classify them here */
76         return 0;
77 }
78
79 static ir_entity *arm_get_frame_entity(const ir_node *irn)
80 {
81         const arm_attr_t *attr = get_arm_attr_const(irn);
82
83         if (is_arm_FrameAddr(irn)) {
84                 const arm_SymConst_attr_t *attr = get_irn_generic_attr_const(irn);
85                 return attr->entity;
86         }
87         if (attr->is_load_store) {
88                 const arm_load_store_attr_t *load_store_attr
89                         = get_arm_load_store_attr_const(irn);
90                 if (load_store_attr->is_frame_entity) {
91                         return load_store_attr->entity;
92                 }
93         }
94         return NULL;
95 }
96
97 static void arm_set_frame_entity(ir_node *irn, ir_entity *ent)
98 {
99         (void) irn;
100         (void) ent;
101         panic("arm_set_frame_entity() called. This should not happen.");
102 }
103
104 /**
105  * This function is called by the generic backend to correct offsets for
106  * nodes accessing the stack.
107  */
108 static void arm_set_stack_bias(ir_node *irn, int bias)
109 {
110         if (is_arm_FrameAddr(irn)) {
111                 arm_SymConst_attr_t *attr = get_irn_generic_attr(irn);
112                 attr->fp_offset += bias;
113         } else {
114                 arm_load_store_attr_t *attr = get_arm_load_store_attr(irn);
115                 assert(attr->base.is_load_store);
116                 attr->offset += bias;
117         }
118 }
119
120 static int arm_get_sp_bias(const ir_node *irn)
121 {
122         /* We don't have any nodes changing the stack pointer.
123            We probably want to support post-/pre increment/decrement later */
124         (void) irn;
125         return 0;
126 }
127
128 /* fill register allocator interface */
129
130 static const arch_irn_ops_t arm_irn_ops = {
131         get_arm_in_req,
132         arm_classify,
133         arm_get_frame_entity,
134         arm_set_frame_entity,
135         arm_set_stack_bias,
136         arm_get_sp_bias,
137         NULL,    /* get_inverse             */
138         NULL,    /* get_op_estimated_cost   */
139         NULL,    /* possible_memory_operand */
140         NULL,    /* perform_memory_operand  */
141 };
142
143 /**
144  * Transforms the standard Firm graph into
145  * a ARM firm graph.
146  */
147 static void arm_prepare_graph(void *self)
148 {
149         arm_code_gen_t *cg = self;
150
151         /* transform nodes into assembler instructions */
152         arm_transform_graph(cg);
153
154         /* do local optimizations (mainly CSE) */
155         local_optimize_graph(cg->irg);
156
157         if (cg->dump)
158                 dump_ir_graph(cg->irg, "transformed");
159
160         /* do code placement, to optimize the position of constants */
161         place_code(cg->irg);
162
163         if (cg->dump)
164                 dump_ir_graph(cg->irg, "place");
165 }
166
167 /**
168  * Called immediately before emit phase.
169  */
170 static void arm_finish_irg(void *self)
171 {
172         arm_code_gen_t *cg = self;
173
174         /* do peephole optimizations and fix stack offsets */
175         arm_peephole_optimization(cg);
176 }
177
178 static ir_node *arm_flags_remat(ir_node *node, ir_node *after)
179 {
180         ir_node *block;
181         ir_node *copy;
182
183         if (is_Block(after)) {
184                 block = after;
185         } else {
186                 block = get_nodes_block(after);
187         }
188         copy = exact_copy(node);
189         set_nodes_block(copy, block);
190         sched_add_after(after, copy);
191         return copy;
192 }
193
194 static void arm_before_ra(void *self)
195 {
196         arm_code_gen_t *cg = self;
197
198         be_sched_fix_flags(cg->irg, &arm_reg_classes[CLASS_arm_flags],
199                            &arm_flags_remat);
200 }
201
202 static void transform_Reload(ir_node *node)
203 {
204         ir_node   *block  = get_nodes_block(node);
205         dbg_info  *dbgi   = get_irn_dbg_info(node);
206         ir_node   *ptr    = get_irn_n(node, be_pos_Reload_frame);
207         ir_node   *mem    = get_irn_n(node, be_pos_Reload_mem);
208         ir_mode   *mode   = get_irn_mode(node);
209         ir_entity *entity = be_get_frame_entity(node);
210         const arch_register_t *reg;
211         ir_node   *proj;
212         ir_node   *load;
213
214         ir_node  *sched_point = sched_prev(node);
215
216         load = new_bd_arm_Ldr(dbgi, block, ptr, mem, mode, entity, false, 0, true);
217         sched_add_after(sched_point, load);
218         sched_remove(node);
219
220         proj = new_rd_Proj(dbgi, load, mode, pn_arm_Ldr_res);
221
222         reg = arch_get_irn_register(node);
223         arch_set_irn_register(proj, reg);
224
225         exchange(node, proj);
226 }
227
228 static void transform_Spill(ir_node *node)
229 {
230         ir_node   *block  = get_nodes_block(node);
231         dbg_info  *dbgi   = get_irn_dbg_info(node);
232         ir_node   *ptr    = get_irn_n(node, be_pos_Spill_frame);
233         ir_node   *mem    = new_NoMem();
234         ir_node   *val    = get_irn_n(node, be_pos_Spill_val);
235         ir_mode   *mode   = get_irn_mode(val);
236         ir_entity *entity = be_get_frame_entity(node);
237         ir_node   *sched_point;
238         ir_node   *store;
239
240         sched_point = sched_prev(node);
241         store = new_bd_arm_Str(dbgi, block, ptr, val, mem, mode, entity, false, 0,
242                                true);
243
244         sched_remove(node);
245         sched_add_after(sched_point, store);
246
247         exchange(node, store);
248 }
249
250 static void arm_after_ra_walker(ir_node *block, void *data)
251 {
252         ir_node *node, *prev;
253         (void) data;
254
255         for (node = sched_last(block); !sched_is_begin(node); node = prev) {
256                 prev = sched_prev(node);
257
258                 if (be_is_Reload(node)) {
259                         transform_Reload(node);
260                 } else if (be_is_Spill(node)) {
261                         transform_Spill(node);
262                 }
263         }
264 }
265
266 static void arm_after_ra(void *self)
267 {
268         arm_code_gen_t *cg = self;
269         be_coalesce_spillslots(cg->irg);
270
271         irg_block_walk_graph(cg->irg, NULL, arm_after_ra_walker, NULL);
272 }
273
274 /**
275  * Emits the code, closes the output file and frees
276  * the code generator interface.
277  */
278 static void arm_emit_and_done(void *self)
279 {
280         arm_code_gen_t *cg = self;
281         ir_graph       *irg = cg->irg;
282
283         arm_gen_routine(cg, irg);
284
285         /* de-allocate code generator */
286         del_set(cg->reg_set);
287         free(self);
288 }
289
290 /* forward */
291 static void *arm_cg_init(ir_graph *irg);
292
293 static const arch_code_generator_if_t arm_code_gen_if = {
294         arm_cg_init,
295         NULL,               /* get_pic_base */
296         NULL,               /* before abi introduce */
297         arm_prepare_graph,
298         NULL,               /* spill */
299         arm_before_ra,      /* before register allocation hook */
300         arm_after_ra,
301         arm_finish_irg,
302         arm_emit_and_done,
303 };
304
305 /**
306  * Initializes the code generator.
307  */
308 static void *arm_cg_init(ir_graph *irg)
309 {
310         static ir_type *int_tp = NULL;
311         arm_isa_t      *isa = (arm_isa_t *) be_get_irg_arch_env(irg);
312         arm_code_gen_t *cg;
313
314         if (! int_tp) {
315                 /* create an integer type with machine size */
316                 int_tp = new_type_primitive(mode_Is);
317         }
318
319         cg = XMALLOC(arm_code_gen_t);
320         cg->impl         = &arm_code_gen_if;
321         cg->irg          = irg;
322         cg->reg_set      = new_set(arm_cmp_irn_reg_assoc, 1024);
323         cg->isa          = isa;
324         cg->int_tp       = int_tp;
325         cg->have_fp_insn = 0;
326         cg->dump         = (be_get_irg_options(irg)->dump_flags & DUMP_BE) ? 1 : 0;
327
328         FIRM_DBG_REGISTER(cg->mod, "firm.be.arm.cg");
329
330         /* enter the current code generator */
331         isa->cg = cg;
332
333         return (arch_code_generator_t *)cg;
334 }
335
336
337 /**
338  * Maps all intrinsic calls that the backend support
339  * and map all instructions the backend did not support
340  * to runtime calls.
341  */
342 static void arm_handle_intrinsics(void)
343 {
344         ir_type *tp, *int_tp, *uint_tp;
345         i_record records[8];
346         int n_records = 0;
347
348         runtime_rt rt_iDiv, rt_uDiv, rt_iMod, rt_uMod;
349
350 #define ID(x) new_id_from_chars(x, sizeof(x)-1)
351
352         int_tp  = new_type_primitive(mode_Is);
353         uint_tp = new_type_primitive(mode_Iu);
354
355         /* ARM has neither a signed div instruction ... */
356         {
357                 i_instr_record *map_Div = &records[n_records++].i_instr;
358
359                 tp = new_type_method(2, 1);
360                 set_method_param_type(tp, 0, int_tp);
361                 set_method_param_type(tp, 1, int_tp);
362                 set_method_res_type(tp, 0, int_tp);
363
364                 rt_iDiv.ent             = new_entity(get_glob_type(), ID("__divsi3"), tp);
365                 set_entity_ld_ident(rt_iDiv.ent, ID("__divsi3"));
366                 rt_iDiv.mode            = mode_T;
367                 rt_iDiv.res_mode        = mode_Is;
368                 rt_iDiv.mem_proj_nr     = pn_Div_M;
369                 rt_iDiv.regular_proj_nr = pn_Div_X_regular;
370                 rt_iDiv.exc_proj_nr     = pn_Div_X_except;
371                 rt_iDiv.exc_mem_proj_nr = pn_Div_M;
372                 rt_iDiv.res_proj_nr     = pn_Div_res;
373
374                 add_entity_linkage(rt_iDiv.ent, IR_LINKAGE_CONSTANT);
375                 set_entity_visibility(rt_iDiv.ent, ir_visibility_external);
376
377                 map_Div->kind     = INTRINSIC_INSTR;
378                 map_Div->op       = op_Div;
379                 map_Div->i_mapper = (i_mapper_func)i_mapper_RuntimeCall;
380                 map_Div->ctx      = &rt_iDiv;
381         }
382         /* ... nor an unsigned div instruction ... */
383         {
384                 i_instr_record *map_Div = &records[n_records++].i_instr;
385
386                 tp = new_type_method(2, 1);
387                 set_method_param_type(tp, 0, uint_tp);
388                 set_method_param_type(tp, 1, uint_tp);
389                 set_method_res_type(tp, 0, uint_tp);
390
391                 rt_uDiv.ent             = new_entity(get_glob_type(), ID("__udivsi3"), tp);
392                 set_entity_ld_ident(rt_uDiv.ent, ID("__udivsi3"));
393                 rt_uDiv.mode            = mode_T;
394                 rt_uDiv.res_mode        = mode_Iu;
395                 rt_uDiv.mem_proj_nr     = pn_Div_M;
396                 rt_uDiv.regular_proj_nr = pn_Div_X_regular;
397                 rt_uDiv.exc_proj_nr     = pn_Div_X_except;
398                 rt_uDiv.exc_mem_proj_nr = pn_Div_M;
399                 rt_uDiv.res_proj_nr     = pn_Div_res;
400
401                 set_entity_visibility(rt_uDiv.ent, ir_visibility_external);
402
403                 map_Div->kind     = INTRINSIC_INSTR;
404                 map_Div->op       = op_Div;
405                 map_Div->i_mapper = (i_mapper_func)i_mapper_RuntimeCall;
406                 map_Div->ctx      = &rt_uDiv;
407         }
408         /* ... nor a signed mod instruction ... */
409         {
410                 i_instr_record *map_Mod = &records[n_records++].i_instr;
411
412                 tp = new_type_method(2, 1);
413                 set_method_param_type(tp, 0, int_tp);
414                 set_method_param_type(tp, 1, int_tp);
415                 set_method_res_type(tp, 0, int_tp);
416
417                 rt_iMod.ent             = new_entity(get_glob_type(), ID("__modsi3"), tp);
418                 set_entity_ld_ident(rt_iMod.ent, ID("__modsi3"));
419                 rt_iMod.mode            = mode_T;
420                 rt_iMod.res_mode        = mode_Is;
421                 rt_iMod.mem_proj_nr     = pn_Mod_M;
422                 rt_iMod.regular_proj_nr = pn_Mod_X_regular;
423                 rt_iMod.exc_proj_nr     = pn_Mod_X_except;
424                 rt_iMod.exc_mem_proj_nr = pn_Mod_M;
425                 rt_iMod.res_proj_nr     = pn_Mod_res;
426
427                 set_entity_visibility(rt_iMod.ent, ir_visibility_external);
428
429                 map_Mod->kind     = INTRINSIC_INSTR;
430                 map_Mod->op       = op_Mod;
431                 map_Mod->i_mapper = (i_mapper_func)i_mapper_RuntimeCall;
432                 map_Mod->ctx      = &rt_iMod;
433         }
434         /* ... nor an unsigned mod. */
435         {
436                 i_instr_record *map_Mod = &records[n_records++].i_instr;
437
438                 tp = new_type_method(2, 1);
439                 set_method_param_type(tp, 0, uint_tp);
440                 set_method_param_type(tp, 1, uint_tp);
441                 set_method_res_type(tp, 0, uint_tp);
442
443                 rt_uMod.ent             = new_entity(get_glob_type(), ID("__umodsi3"), tp);
444                 set_entity_ld_ident(rt_uMod.ent, ID("__umodsi3"));
445                 rt_uMod.mode            = mode_T;
446                 rt_uMod.res_mode        = mode_Iu;
447                 rt_uMod.mem_proj_nr     = pn_Mod_M;
448                 rt_uMod.regular_proj_nr = pn_Mod_X_regular;
449                 rt_uMod.exc_proj_nr     = pn_Mod_X_except;
450                 rt_uMod.exc_mem_proj_nr = pn_Mod_M;
451                 rt_uMod.res_proj_nr     = pn_Mod_res;
452
453                 set_entity_visibility(rt_uMod.ent, ir_visibility_external);
454
455                 map_Mod->kind     = INTRINSIC_INSTR;
456                 map_Mod->op       = op_Mod;
457                 map_Mod->i_mapper = (i_mapper_func)i_mapper_RuntimeCall;
458                 map_Mod->ctx      = &rt_uMod;
459         }
460
461         if (n_records > 0)
462                 lower_intrinsics(records, n_records, /*part_block_used=*/0);
463 }
464
465
466 static arm_isa_t arm_isa_template = {
467         {
468                 &arm_isa_if,           /* isa interface */
469                 &arm_gp_regs[REG_SP],  /* stack pointer */
470                 &arm_gp_regs[REG_R11], /* base pointer */
471                 &arm_reg_classes[CLASS_arm_gp],  /* static link pointer class */
472                 -1,                    /* stack direction */
473                 2,                     /* power of two stack alignment for calls, 2^2 == 4 */
474                 NULL,                  /* main environment */
475                 7,                     /* spill costs */
476                 5,                     /* reload costs */
477                 true,                  /* we do have custom abi handling */
478         },
479         0,                     /* use generic register names instead of SP, LR, PC */
480         ARM_FPU_ARCH_FPE,      /* FPU architecture */
481         NULL,                  /* current code generator */
482 };
483
484 /**
485  * Initializes the backend ISA and opens the output file.
486  */
487 static arch_env_t *arm_init(FILE *file_handle)
488 {
489         static int inited = 0;
490         arm_isa_t *isa;
491
492         if (inited)
493                 return NULL;
494
495         isa = XMALLOC(arm_isa_t);
496         memcpy(isa, &arm_isa_template, sizeof(*isa));
497
498         arm_register_init();
499
500         isa->cg  = NULL;
501         be_emit_init(file_handle);
502
503         arm_create_opcodes(&arm_irn_ops);
504         arm_handle_intrinsics();
505
506         be_gas_emit_types = false;
507
508         /* needed for the debug support */
509         be_gas_emit_switch_section(GAS_SECTION_TEXT);
510         be_emit_irprintf("%stext0:\n", be_gas_get_private_prefix());
511         be_emit_write_line();
512
513         inited = 1;
514         return &isa->arch_env;
515 }
516
517
518
519 /**
520  * Closes the output file and frees the ISA structure.
521  */
522 static void arm_done(void *self)
523 {
524         arm_isa_t *isa = self;
525
526         be_gas_emit_decls(isa->arch_env.main_env);
527
528         be_emit_exit();
529         free(self);
530 }
531
532
533 /**
534  * Report the number of register classes.
535  * If we don't have fp instructions, report only GP
536  * here to speed up register allocation (and makes dumps
537  * smaller and more readable).
538  */
539 static unsigned arm_get_n_reg_class(void)
540 {
541         return N_CLASSES;
542 }
543
544 /**
545  * Return the register class with requested index.
546  */
547 static const arch_register_class_t *arm_get_reg_class(unsigned i)
548 {
549         assert(i < N_CLASSES);
550         return &arm_reg_classes[i];
551 }
552
553 /**
554  * Get the register class which shall be used to store a value of a given mode.
555  * @param self The this pointer.
556  * @param mode The mode in question.
557  * @return A register class which can hold values of the given mode.
558  */
559 static const arch_register_class_t *arm_get_reg_class_for_mode(const ir_mode *mode)
560 {
561         if (mode_is_float(mode))
562                 return &arm_reg_classes[CLASS_arm_fpa];
563         else
564                 return &arm_reg_classes[CLASS_arm_gp];
565 }
566
567 /**
568  * Produces the type which sits between the stack args and the locals on the stack.
569  * it will contain the return address and space to store the old base pointer.
570  * @return The Firm type modeling the ABI between type.
571  */
572 static ir_type *arm_get_between_type(void *self)
573 {
574         static ir_type *between_type = NULL;
575         (void) self;
576
577         if (between_type == NULL) {
578                 between_type = new_type_class(new_id_from_str("arm_between_type"));
579                 set_type_size_bytes(between_type, 0);
580         }
581
582         return between_type;
583 }
584
585
586 typedef struct {
587         be_abi_call_flags_bits_t flags;
588         const arch_env_t *arch_env;
589         ir_graph *irg;
590 } arm_abi_env_t;
591
592 static void *arm_abi_init(const be_abi_call_t *call, const arch_env_t *arch_env, ir_graph *irg)
593 {
594         arm_abi_env_t       *env = XMALLOC(arm_abi_env_t);
595         be_abi_call_flags_t  fl  = be_abi_call_get_flags(call);
596         env->flags    = fl.bits;
597         env->irg      = irg;
598         env->arch_env = arch_env;
599         return env;
600 }
601
602 /**
603  * Generate the routine prologue.
604  *
605  * @param self       The callback object.
606  * @param mem        A pointer to the mem node. Update this if you define new memory.
607  * @param reg_map    A map mapping all callee_save/ignore/parameter registers to their defining nodes.
608  * @param stack_bias Points to the current stack bias, can be modified if needed.
609  *
610  * @return        The register which shall be used as a stack frame base.
611  *
612  * All nodes which define registers in @p reg_map must keep @p reg_map current.
613  */
614 static const arch_register_t *arm_abi_prologue(void *self, ir_node **mem, pmap *reg_map, int *stack_bias)
615 {
616         arm_abi_env_t         *env = self;
617         ir_node               *store;
618         ir_graph              *irg;
619         ir_node               *block;
620         arch_register_class_t *gp;
621
622         ir_node               *fp, *ip, *lr, *pc;
623         ir_node               *sp = be_abi_reg_map_get(reg_map, env->arch_env->sp);
624
625         (void) stack_bias;
626
627         if (env->flags.try_omit_fp)
628                 return env->arch_env->sp;
629
630         fp = be_abi_reg_map_get(reg_map, env->arch_env->bp);
631         ip = be_abi_reg_map_get(reg_map, &arm_gp_regs[REG_R12]);
632         lr = be_abi_reg_map_get(reg_map, &arm_gp_regs[REG_LR]);
633         pc = be_abi_reg_map_get(reg_map, &arm_gp_regs[REG_PC]);
634
635         gp    = &arm_reg_classes[CLASS_arm_gp];
636         irg   = env->irg;
637         block = get_irg_start_block(irg);
638
639         /* mark bp register as ignore */
640         be_set_constr_single_reg_out(get_Proj_pred(fp),
641                                      get_Proj_proj(fp), env->arch_env->bp,
642                                      arch_register_req_type_ignore);
643
644         /* copy SP to IP (so we can spill it */
645         ip = be_new_Copy(gp, block, sp);
646         be_set_constr_single_reg_out(ip, 0, &arm_gp_regs[REG_R12], 0);
647
648         /* spill stuff */
649         store = new_bd_arm_StoreStackM4Inc(NULL, block, sp, fp, ip, lr, pc, *mem);
650
651         sp = new_r_Proj(store, env->arch_env->sp->reg_class->mode, pn_arm_StoreStackM4Inc_ptr);
652         arch_set_irn_register(sp, env->arch_env->sp);
653         *mem = new_r_Proj(store, mode_M, pn_arm_StoreStackM4Inc_M);
654
655         /* frame pointer is ip-4 (because ip is our old sp value) */
656         fp = new_bd_arm_Sub_imm(NULL, block, ip, 4, 0);
657         arch_set_irn_register(fp, env->arch_env->bp);
658
659         /* beware: we change the fp but the StoreStackM4Inc above wants the old
660          * fp value. We are not allowed to spill or anything in the prolog, so we
661          * have to enforce some order here. (scheduler/regalloc are too stupid
662          * to extract this order from register requirements) */
663         add_irn_dep(fp, store);
664
665         fp = be_new_Copy(gp, block, fp); // XXX Gammelfix: only be_ have custom register requirements
666         be_set_constr_single_reg_out(fp, 0, env->arch_env->bp,
667                                      arch_register_req_type_ignore);
668         arch_set_irn_register(fp, env->arch_env->bp);
669
670         be_abi_reg_map_set(reg_map, env->arch_env->bp, fp);
671         be_abi_reg_map_set(reg_map, &arm_gp_regs[REG_R12], ip);
672         be_abi_reg_map_set(reg_map, env->arch_env->sp, sp);
673         be_abi_reg_map_set(reg_map, &arm_gp_regs[REG_LR], lr);
674         be_abi_reg_map_set(reg_map, &arm_gp_regs[REG_PC], pc);
675
676         return env->arch_env->bp;
677 }
678
679 /**
680  * Builds the ARM epilogue
681  */
682 static void arm_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_map)
683 {
684         arm_abi_env_t *env = self;
685         ir_node *curr_sp = be_abi_reg_map_get(reg_map, env->arch_env->sp);
686         ir_node *curr_bp = be_abi_reg_map_get(reg_map, env->arch_env->bp);
687         ir_node *curr_pc = be_abi_reg_map_get(reg_map, &arm_gp_regs[REG_PC]);
688         ir_node *curr_lr = be_abi_reg_map_get(reg_map, &arm_gp_regs[REG_LR]);
689
690         // TODO: Activate Omit fp in epilogue
691         if (env->flags.try_omit_fp) {
692                 ir_node *incsp = be_new_IncSP(env->arch_env->sp, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK, 0);
693                 curr_sp = incsp;
694         } else {
695                 ir_node *load_node;
696
697                 load_node = new_bd_arm_LoadStackM3Epilogue(NULL, bl, curr_bp, *mem);
698
699                 curr_bp = new_r_Proj(load_node, env->arch_env->bp->reg_class->mode, pn_arm_LoadStackM3Epilogue_res0);
700                 curr_sp = new_r_Proj(load_node, env->arch_env->sp->reg_class->mode, pn_arm_LoadStackM3Epilogue_res1);
701                 curr_pc = new_r_Proj(load_node, mode_Iu, pn_arm_LoadStackM3Epilogue_res2);
702                 *mem    = new_r_Proj(load_node, mode_M, pn_arm_LoadStackM3Epilogue_M);
703                 arch_set_irn_register(curr_bp, env->arch_env->bp);
704                 arch_set_irn_register(curr_sp, env->arch_env->sp);
705                 arch_set_irn_register(curr_pc, &arm_gp_regs[REG_PC]);
706         }
707         be_abi_reg_map_set(reg_map, env->arch_env->sp, curr_sp);
708         be_abi_reg_map_set(reg_map, env->arch_env->bp, curr_bp);
709         be_abi_reg_map_set(reg_map, &arm_gp_regs[REG_LR], curr_lr);
710         be_abi_reg_map_set(reg_map, &arm_gp_regs[REG_PC], curr_pc);
711 }
712
713 static const be_abi_callbacks_t arm_abi_callbacks = {
714         arm_abi_init,
715         free,
716         arm_get_between_type,
717         arm_abi_prologue,
718         arm_abi_epilogue,
719 };
720
721
722 /**
723  * Get the ABI restrictions for procedure calls.
724  * @param self        The this pointer.
725  * @param method_type The type of the method (procedure) in question.
726  * @param abi         The abi object to be modified
727  */
728 static void arm_get_call_abi(const void *self, ir_type *method_type, be_abi_call_t *abi)
729 {
730         ir_type  *tp;
731         ir_mode  *mode;
732         int       i;
733         int       n = get_method_n_params(method_type);
734         be_abi_call_flags_t call_flags = be_abi_call_get_flags(abi);
735         (void) self;
736
737         /* set abi flags for calls */
738         call_flags.bits.left_to_right         = 0;
739         call_flags.bits.store_args_sequential = 0;
740         /* call_flags.bits.try_omit_fp     don't change this we can handle both */
741         call_flags.bits.fp_free               = 0;
742         call_flags.bits.call_has_imm          = 1;
743
744         /* set stack parameter passing style */
745         be_abi_call_set_flags(abi, call_flags, &arm_abi_callbacks);
746
747         for (i = 0; i < n; i++) {
748                 /* reg = get reg for param i;          */
749                 /* be_abi_call_param_reg(abi, i, reg); */
750                 if (i < 4) {
751                         be_abi_call_param_reg(abi, i, arm_get_RegParam_reg(i), ABI_CONTEXT_BOTH);
752                 } else {
753                         tp   = get_method_param_type(method_type, i);
754                         mode = get_type_mode(tp);
755                         be_abi_call_param_stack(abi, i, mode, 4, 0, 0, ABI_CONTEXT_BOTH);
756                 }
757         }
758
759         /* set return registers */
760         n = get_method_n_ress(method_type);
761
762         assert(n <= 2 && "more than two results not supported");
763
764         /* In case of 64bit returns, we will have two 32bit values */
765         if (n == 2) {
766                 tp   = get_method_res_type(method_type, 0);
767                 mode = get_type_mode(tp);
768
769                 assert(!mode_is_float(mode) && "two FP results not supported");
770
771                 tp   = get_method_res_type(method_type, 1);
772                 mode = get_type_mode(tp);
773
774                 assert(!mode_is_float(mode) && "mixed INT, FP results not supported");
775
776                 be_abi_call_res_reg(abi, 0, &arm_gp_regs[REG_R0], ABI_CONTEXT_BOTH);
777                 be_abi_call_res_reg(abi, 1, &arm_gp_regs[REG_R1], ABI_CONTEXT_BOTH);
778         } else if (n == 1) {
779                 const arch_register_t *reg;
780
781                 tp   = get_method_res_type(method_type, 0);
782                 assert(is_atomic_type(tp));
783                 mode = get_type_mode(tp);
784
785                 reg = mode_is_float(mode) ? &arm_fpa_regs[REG_F0] : &arm_gp_regs[REG_R0];
786                 be_abi_call_res_reg(abi, 0, reg, ABI_CONTEXT_BOTH);
787         }
788 }
789
790 static int arm_to_appear_in_schedule(void *block_env, const ir_node *irn)
791 {
792         (void) block_env;
793         if (!is_arm_irn(irn))
794                 return -1;
795
796         return 1;
797 }
798
799 /**
800  * Initializes the code generator interface.
801  */
802 static const arch_code_generator_if_t *arm_get_code_generator_if(void *self)
803 {
804         (void) self;
805         return &arm_code_gen_if;
806 }
807
808 list_sched_selector_t arm_sched_selector;
809
810 /**
811  * Returns the reg_pressure scheduler with to_appear_in_schedule() over\loaded
812  */
813 static const list_sched_selector_t *arm_get_list_sched_selector(const void *self, list_sched_selector_t *selector)
814 {
815         (void) self;
816         memcpy(&arm_sched_selector, selector, sizeof(arm_sched_selector));
817         /* arm_sched_selector.exectime              = arm_sched_exectime; */
818         arm_sched_selector.to_appear_in_schedule = arm_to_appear_in_schedule;
819         return &arm_sched_selector;
820
821 }
822
823 static const ilp_sched_selector_t *arm_get_ilp_sched_selector(const void *self)
824 {
825         (void) self;
826         return NULL;
827 }
828
829 /**
830  * Returns the necessary byte alignment for storing a register of given class.
831  */
832 static int arm_get_reg_class_alignment(const arch_register_class_t *cls)
833 {
834         (void) cls;
835         /* ARM is a 32 bit CPU, no need for other alignment */
836         return 4;
837 }
838
839 static const be_execution_unit_t ***arm_get_allowed_execution_units(const ir_node *irn)
840 {
841         (void) irn;
842         /* TODO */
843         panic("Unimplemented arm_get_allowed_execution_units()");
844 }
845
846 static const be_machine_t *arm_get_machine(const void *self)
847 {
848         (void) self;
849         /* TODO */
850         panic("Unimplemented arm_get_machine()");
851 }
852
853 /**
854  * Return irp irgs in the desired order.
855  */
856 static ir_graph **arm_get_irg_list(const void *self, ir_graph ***irg_list)
857 {
858         (void) self;
859         (void) irg_list;
860         return NULL;
861 }
862
863 /**
864  * Allows or disallows the creation of Psi nodes for the given Phi nodes.
865  * @return 1 if allowed, 0 otherwise
866  */
867 static int arm_is_mux_allowed(ir_node *sel, ir_node *mux_false,
868                               ir_node *mux_true)
869 {
870         (void) sel;
871         (void) mux_false;
872         (void) mux_true;
873
874         return 0;
875 }
876
877 static asm_constraint_flags_t arm_parse_asm_constraint(const char **c)
878 {
879         /* asm not supported */
880         (void) c;
881         return ASM_CONSTRAINT_FLAG_INVALID;
882 }
883
884 static int arm_is_valid_clobber(const char *clobber)
885 {
886         (void) clobber;
887         return 0;
888 }
889
890 /**
891  * Returns the libFirm configuration parameter for this backend.
892  */
893 static const backend_params *arm_get_libfirm_params(void)
894 {
895         static const ir_settings_if_conv_t ifconv = {
896                 4,                    /* maxdepth, doesn't matter for Psi-conversion */
897                 arm_is_mux_allowed   /* allows or disallows Mux creation for given selector */
898         };
899         static ir_settings_arch_dep_t ad = {
900                 1,    /* allow subs */
901                 1,        /* Muls are fast enough on ARM but ... */
902                 31,   /* ... one shift would be possible better */
903                 NULL, /* no evaluator function */
904                 0,    /* SMUL is needed, only in Arch M */
905                 0,    /* UMUL is needed, only in Arch M */
906                 32,   /* SMUL & UMUL available for 32 bit */
907         };
908         static backend_params p = {
909                 1,     /* need dword lowering */
910                 0,     /* don't support inline assembler yet */
911                 NULL,  /* will be set later */
912                 NULL,  /* but yet no creator function */
913                 NULL,  /* context for create_intrinsic_fkt */
914                 NULL,  /* ifconv_info will be set below */
915                 NULL,  /* float arithmetic mode (TODO) */
916                 0,     /* no trampoline support: size 0 */
917                 0,     /* no trampoline support: align 0 */
918                 NULL,  /* no trampoline support: no trampoline builder */
919                 4      /* alignment of stack parameter */
920         };
921
922         p.dep_param    = &ad;
923         p.if_conv_info = &ifconv;
924         return &p;
925 }
926
927 /* fpu set architectures. */
928 static const lc_opt_enum_int_items_t arm_fpu_items[] = {
929         { "softfloat", ARM_FPU_ARCH_SOFTFLOAT },
930         { "fpe",       ARM_FPU_ARCH_FPE },
931         { "fpa",       ARM_FPU_ARCH_FPA },
932         { "vfp1xd",    ARM_FPU_ARCH_VFP_V1xD },
933         { "vfp1",      ARM_FPU_ARCH_VFP_V1 },
934         { "vfp2",      ARM_FPU_ARCH_VFP_V2 },
935         { NULL,        0 }
936 };
937
938 static lc_opt_enum_int_var_t arch_fpu_var = {
939         &arm_isa_template.fpu_arch, arm_fpu_items
940 };
941
942 static const lc_opt_table_entry_t arm_options[] = {
943         LC_OPT_ENT_ENUM_INT("fpunit",    "select the floating point unit", &arch_fpu_var),
944         LC_OPT_ENT_BOOL("gen_reg_names", "use generic register names", &arm_isa_template.gen_reg_names),
945         LC_OPT_LAST
946 };
947
948 const arch_isa_if_t arm_isa_if = {
949         arm_init,
950         arm_done,
951         NULL,  /* handle_intrinsics */
952         arm_get_n_reg_class,
953         arm_get_reg_class,
954         arm_get_reg_class_for_mode,
955         arm_get_call_abi,
956         arm_get_code_generator_if,
957         arm_get_list_sched_selector,
958         arm_get_ilp_sched_selector,
959         arm_get_reg_class_alignment,
960         arm_get_libfirm_params,
961         arm_get_allowed_execution_units,
962         arm_get_machine,
963         arm_get_irg_list,
964         NULL,               /* mark remat */
965         arm_parse_asm_constraint,
966         arm_is_valid_clobber
967 };
968
969 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_arm);
970 void be_init_arch_arm(void)
971 {
972         lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
973         lc_opt_entry_t *arm_grp = lc_opt_get_grp(be_grp, "arm");
974
975         lc_opt_add_table(arm_grp, arm_options);
976
977         be_register_isa_if("arm", &arm_isa_if);
978
979         arm_init_transform();
980         arm_init_emitter();
981 }