Restructured
[libfirm] / ir / be / beabi.c
1 /**
2  * ABI lowering.
3  *
4  *
5  *
6  */
7
8 #include "firm_config.h"
9 #include "obst.h"
10
11 #include "type.h"
12
13 #include "irgraph_t.h"
14 #include "irnode_t.h"
15 #include "ircons_t.h"
16 #include "iredges_t.h"
17 #include "irgmod.h"
18 #include "irgwalk.h"
19
20 #include "be.h"
21 #include "beabi.h"
22 #include "bearch.h"
23 #include "benode_t.h"
24 #include "besched_t.h"
25
26 #define MAX(x, y) ((x) > (y) ? (x) : (y))
27 #define MIN(x, y) ((x) < (y) ? (x) : (y))
28
29 typedef struct _be_abi_call_arg_t {
30         unsigned is_res : 1;
31         unsigned in_reg : 1;
32
33         int pos;
34         const arch_register_t *reg;
35 } be_abi_call_arg_t;
36
37 struct _be_abi_call_t {
38         be_abi_call_flags_t flags;
39         unsigned arg_gap;
40         set *params;
41 };
42
43 struct _be_abi_irg_t {
44         struct obstack      obst;
45         be_irg_t            *birg;
46         be_abi_call_t       *call;
47         type                *method_type;
48
49         ir_node             *init_sp;      /**< The node representing the stack pointer
50                                                                              at the start of the function. */
51
52         ir_node             *reg_params;
53
54         pset                *stack_ops;    /**< Contains all nodes modifying the stack pointer. */
55         pmap                *callee_save;
56
57         int start_block_bias;
58
59         unsigned omit_fp : 1;
60         unsigned dedicated_fp : 1;
61         unsigned left_to_right : 1;
62
63         firm_dbg_module_t *dbg;            /**< The debugging module. */
64 };
65
66 static int cmp_call_arg(const void *a, const void *b, size_t n)
67 {
68         const be_abi_call_arg_t *p = a, *q = b;
69         return !(p->is_res == q->is_res && p->pos == q->pos);
70 }
71
72 static be_abi_call_arg_t *get_or_set_call_arg(be_abi_call_t *call, int is_res, int pos, int do_insert)
73 {
74         be_abi_call_arg_t arg;
75         unsigned hash;
76
77         arg.is_res = is_res;
78         arg.pos    = pos;
79
80         hash = is_res * 100 + pos;
81
82         return do_insert
83                 ? set_insert(call->params, &arg, sizeof(arg), hash)
84                 : set_find(call->params, &arg, sizeof(arg), hash);
85 }
86
87 static INLINE be_abi_call_arg_t *get_call_arg(be_abi_call_t *call, int is_res, int pos)
88 {
89         return get_or_set_call_arg(call, is_res, pos, 0);
90 }
91
92 void be_abi_call_set_flags(be_abi_call_t *call, be_abi_call_flags_t flags, unsigned arg_gap)
93 {
94         call->flags   = flags;
95         call->arg_gap = arg_gap;
96 }
97
98 void be_abi_call_param_stack(be_abi_call_t *call, int arg_pos)
99 {
100         be_abi_call_arg_t *arg = get_or_set_call_arg(call, 0, arg_pos, 1);
101 }
102
103 void be_abi_call_param_reg(be_abi_call_t *call, int arg_pos, const arch_register_t *reg)
104 {
105         be_abi_call_arg_t *arg = get_or_set_call_arg(call, 0, arg_pos, 1);
106         arg->reg = reg;
107 }
108
109 void be_abi_call_res_reg(be_abi_call_t *call, int arg_pos, const arch_register_t *reg)
110 {
111         be_abi_call_arg_t *arg = get_or_set_call_arg(call, 1, arg_pos, 1);
112         arg->reg = reg;
113 }
114
115 be_abi_call_t *be_abi_call_new(void)
116 {
117         be_abi_call_t *call = malloc(sizeof(call[0]));
118         call->flags  = BE_ABI_NONE;
119         call->params = new_set(cmp_call_arg, 16);
120         return call;
121 }
122
123 void be_abi_call_free(be_abi_call_t *call)
124 {
125         del_set(call->params);
126         free(call);
127 }
128
129 static INLINE int is_on_stack(be_abi_call_t *call, int pos)
130 {
131         be_abi_call_arg_t *arg = get_call_arg(call, 0, pos);
132         return arg && !arg->in_reg;
133 }
134
135 static void adjust_call(be_abi_irg_t *env, ir_node *irn)
136 {
137         ir_graph *irg             = env->birg->irg;
138         const arch_isa_t *isa     = env->birg->main_env->arch_env->isa;
139         be_abi_call_t *call       = be_abi_call_new();
140         ir_type *mt               = get_Call_type(irn);
141         int n_params              = get_method_n_params(mt);
142         ir_node *curr_sp          = get_irg_frame(irg);
143         ir_node *curr_mem         = get_Call_mem(irn);
144         ir_node *bl               = get_nodes_block(irn);
145         pset *results             = pset_new_ptr(8);
146         pset *caller_save         = pset_new_ptr(8);
147         int stack_size            = 0;
148         int stack_dir             = arch_isa_stack_dir(isa);
149         const arch_register_t *sp = arch_isa_sp(isa);
150         ir_mode *mach_mode        = sp->reg_class->mode;
151         struct obstack *obst      = &env->obst;
152         ir_node *no_mem           = get_irg_no_mem(irg);
153
154         ir_node *res_proj = NULL;
155         int curr_res_proj = -1;
156         int n_low_args    = 0;
157         int n_pos         = 0;
158
159         ir_node *low_call;
160         ir_node **in;
161         ir_node *sp_proj;
162         const ir_edge_t *edge;
163         int *low_args;
164         int *pos;
165         int i, n;
166
167         /* Let the isa fill out the abi description for that call node. */
168         arch_isa_get_call_abi(isa, mt, call);
169
170         /* Insert code to put the stack arguments on the stack. */
171         for(i = get_irn_arity(irn); i >= 0; --i) {
172                 if(is_on_stack(call, i)) {
173                         stack_size += get_type_size_bytes(get_method_param_type(mt, i));
174                         obstack_int_grow(obst, i);
175                         n_pos++;
176                 }
177         }
178         pos = obstack_finish(obst);
179
180         /* Collect all arguments which are passed in registers. */
181         for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
182                 be_abi_call_arg_t *arg = get_call_arg(call, 0, i);
183                 if(arg && arg->in_reg) {
184                         obstack_int_grow(obst, i);
185                         n_low_args++;
186                 }
187         }
188         low_args = obstack_finish(obst);
189
190         /* If there are some parameters shich shall be passed on the stack. */
191         if(n_pos > 0) {
192                 int curr_ofs      = 0;
193                 int do_seq        = (call->flags & BE_ABI_USE_PUSH);
194
195                 /* Reverse list of stack parameters if call arguments are from left to right */
196                 if(call->flags & BE_ABI_LEFT_TO_RIGHT) {
197                         for(i = 0; i < n_pos / 2; ++i) {
198                                 int other  = n_pos - i - 1;
199                                 int tmp    = pos[i];
200                                 pos[i]     = pos[other];
201                                 pos[other] = tmp;
202                         }
203                 }
204
205                 /*
206                  * If the stack is decreasing and we do not want to store sequentially,
207                  * we allocate as much space on the stack all parameters need, by
208                  * moving the stack pointer along the stack's direction.
209                  */
210                 if(stack_dir < 0 && !do_seq) {
211                         curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, no_mem, stack_size, be_stack_dir_along);
212                         pset_insert_ptr(env->stack_ops, curr_sp);
213                 }
214
215                 assert(mode_is_reference(mach_mode) && "machine mode must be pointer");
216                 for(i = 0; i < n_pos; ++i) {
217                         int p            = pos[i];
218                         ir_node *param   = get_irn_n(irn, p);
219                         ir_node *addr    = curr_sp;
220                         ir_node *mem     = NULL;
221                         type *param_type = get_method_param_type(mt, p);
222                         int param_size   = get_type_size_bytes(param_type);
223
224                         /* Make the expression to compute the argument's offset. */
225                         if(curr_ofs > 0) {
226                                 addr = new_r_Const_long(irg, bl, mode_Is, curr_ofs);
227                                 addr = new_r_Add(irg, bl, curr_sp, addr, mach_mode);
228                         }
229
230                         /* Insert a store for primitive arguments. */
231                         if(is_atomic_type(param_type)) {
232                                 mem = new_r_Store(irg, bl, curr_mem, addr, param);
233                                 mem = new_r_Proj(irg, bl, mem, mode_M, pn_Store_M);
234                         }
235
236                         /* Make a memcopy for compound arguments. */
237                         else {
238                                 assert(mode_is_reference(get_irn_mode(param)));
239                                 mem = new_r_CopyB(irg, bl, curr_mem, addr, param, param_type);
240                                 mem = new_r_Proj(irg, bl, mem, mode_M, pn_CopyB_M_regular);
241                         }
242
243                         obstack_ptr_grow(obst, mem);
244
245                         curr_ofs += param_size;
246
247                         /*
248                         * If we wanted to build the arguments sequentially,
249                         * the stack pointer for the next must be incremented,
250                         * and the memory value propagated.
251                         */
252                         if(do_seq) {
253                                 curr_ofs = 0;
254                                 curr_sp  = be_new_IncSP(sp, irg, bl, curr_sp, no_mem, param_size, be_stack_dir_along);
255                                 curr_mem = mem;
256
257                                 /*
258                                  * only put the first IncSP to the stack fixup set since the other
259                                  * ones are correctly connected to other nodes and do not need
260                                  * to be fixed.
261                                  */
262                                 if(i == 0)
263                                         pset_insert_ptr(env->stack_ops, curr_sp);
264                         }
265                 }
266
267                 in = (ir_node **) obstack_finish(obst);
268
269                 /* We need the sync only, if we didn't build the stores sequentially. */
270                 if(!do_seq)
271                         curr_mem = new_r_Sync(irg, bl, n_pos, in);
272                 obstack_free(obst, in);
273         }
274
275         /* Collect caller save registers */
276         for(i = 0; env->birg->main_env->caller_save[i]; ++i)
277                 pset_insert_ptr(caller_save, env->birg->main_env->caller_save[i]);
278
279         /* search the greatest result proj number */
280         foreach_out_edge(irn, edge) {
281                 const ir_edge_t *res_edge;
282                 ir_node *irn = get_edge_src_irn(edge);
283
284                 if(is_Proj(irn) && get_irn_mode(irn) == mode_T) {
285                         res_proj = irn;
286                         foreach_out_edge(irn, res_edge) {
287                                 int proj;
288                                 be_abi_call_arg_t *arg;
289                                 ir_node *res = get_edge_src_irn(res_edge);
290
291                                 assert(is_Proj(res));
292                                 proj = get_Proj_proj(res);
293                                 arg = get_call_arg(call, 1, proj);
294                                 if(proj > curr_res_proj)
295                                         curr_res_proj = proj;
296                                 if(arg->in_reg)
297                                         pset_remove_ptr(caller_save, arg->reg);
298                         }
299                 }
300         }
301         curr_res_proj++;
302
303         /* Make additional projs for the caller save registers
304            and the Keep node which keeps them alive. */
305         if(pset_count(caller_save) > 0) {
306                 const arch_register_t *reg;
307                 ir_node **in;
308
309                 if(!res_proj)
310                         res_proj = new_r_Proj(irg, bl, irn, mode_T, pn_Call_T_result);
311
312                 for(reg = pset_first(caller_save); reg; reg = pset_next(caller_save))
313                         obstack_ptr_grow(obst, new_r_Proj(irg, bl, res_proj, reg->reg_class->mode, curr_res_proj++));
314
315                 in = (ir_node **) obstack_finish(obst);
316                 be_new_Keep(NULL, irg, bl, pset_count(caller_save), in);
317                 obstack_free(obst, in);
318         }
319
320         /* Clean up the stack. */
321         if(stack_size > 0) {
322                 ir_node *last_inc_sp;
323
324                 /* Get the result ProjT */
325                 if(!res_proj)
326                         res_proj = new_r_Proj(irg, bl, irn, mode_T, pn_Call_T_result);
327
328                 /* Make a Proj for the stack pointer. */
329                 sp_proj     = new_r_Proj(irg, bl, res_proj, sp->reg_class->mode, curr_res_proj++);
330                 last_inc_sp = be_new_IncSP(sp, irg, bl, sp_proj, no_mem, stack_size, be_stack_dir_against);
331                 pset_insert_ptr(env->stack_ops, last_inc_sp);
332         }
333
334         /* at last make the backend call node and set its register requirements. */
335         for(i = 0; i < n_low_args; ++i)
336                 obstack_ptr_grow(obst, get_irn_n(irn, low_args[i]));
337         in = obstack_finish(obst);
338         low_call = be_new_Call(irg, bl, curr_mem, curr_sp, get_Call_ptr(irn), curr_res_proj, n_low_args, in);
339         obstack_free(obst, in);
340
341         exchange(irn, low_call);
342
343         be_abi_call_free(call);
344         obstack_free(obst, pos);
345         del_pset(results);
346         del_pset(caller_save);
347 }
348
349 static void adjust_call_walker(ir_node *irn, void *data)
350 {
351         if(get_irn_opcode(irn) == iro_Call)
352                 adjust_call(data, irn);
353 }
354
355 /**
356  * Walker to implement alloca-style allocations.
357  * They are implemented using an add to the stack pointer
358  * and a copy instruction.
359  */
360 static void implement_stack_alloc(be_abi_irg_t *env, ir_node *irn)
361 {
362         const arch_isa_t *isa = env->birg->main_env->arch_env->isa;
363         ir_node *bl           = get_nodes_block(irn);
364         ir_node *res          = env->init_sp;
365         ir_node *size;
366
367         assert(get_irn_opcode(irn) == iro_Alloc && get_Alloc_where(irn) == stack_alloc);
368
369         size = get_Alloc_size(irn);
370         if(isa->stack_dir > 0)
371                 res = be_new_Copy(isa->sp->reg_class, env->birg->irg, bl, res);
372
373         res = be_new_AddSP(isa->sp, env->birg->irg, bl, res, size);
374         pset_insert_ptr(env->stack_ops, res);
375
376         if(isa->stack_dir < 0)
377                 res = be_new_Copy(isa->sp->reg_class, env->birg->irg, bl, res);
378
379 }
380
381 static void collect_return_walker(ir_node *irn, void *data)
382 {
383         if(get_irn_opcode(irn) == iro_Return) {
384                 struct obstack *obst = data;
385                 obstack_ptr_grow(obst, irn);
386         }
387 }
388
389 static ir_node *setup_frame(be_abi_irg_t *env)
390 {
391         const arch_isa_t *isa = env->birg->main_env->arch_env->isa;
392         const arch_register_t *sp = isa->sp;
393         const arch_register_t *bp = isa->bp;
394         ir_graph *irg      = env->birg->irg;
395         ir_node *bl        = get_irg_start_block(irg);
396         ir_node *no_mem    = get_irg_no_mem(irg);
397         ir_node *old_frame = get_irg_frame(irg);
398         int store_old_fp   = 1;
399         int omit_fp        = env->omit_fp;
400         ir_node *stack     = pmap_get(env->callee_save, (void *) sp);
401         ir_node *frame     = pmap_get(env->callee_save, (void *) bp);
402
403         int stack_nr       = get_Proj_proj(stack);
404
405         if(omit_fp) {
406                 stack = be_new_IncSP(sp, irg, bl, stack, no_mem, BE_STACK_FRAME_SIZE, be_stack_dir_along);
407                 frame = stack;
408         }
409
410         else {
411                 if(store_old_fp) {
412                         ir_node *irn;
413
414                         irn   = new_r_Store(irg, bl, get_irg_initial_mem(irg), stack, frame);
415                         irn   = new_r_Proj(irg, bl, irn, mode_M, pn_Store_M);
416                         stack = be_new_IncSP(sp, irg, bl, irn, no_mem, get_mode_size_bytes(bp->reg_class->mode), be_stack_dir_along);
417                 }
418
419                 frame = be_new_Copy(bp->reg_class, irg, bl, stack);
420
421                 if(env->dedicated_fp) {
422                         be_set_constr_single_reg(frame, -1, bp);
423                         be_node_set_flags(frame, -1, arch_irn_flags_ignore);
424                 }
425
426                 stack = be_new_IncSP(sp, irg, bl, stack, no_mem, BE_STACK_FRAME_SIZE, be_stack_dir_along);
427         }
428
429         be_node_set_flags(env->reg_params, -(stack_nr + 1), arch_irn_flags_ignore);
430         env->init_sp = stack;
431         set_irg_frame(irg, frame);
432         edges_reroute(old_frame, frame, irg);
433
434         return frame;
435 }
436
437 static ir_node *clearup_frame(be_abi_irg_t *env, ir_node *stack, ir_node *frame)
438 {
439
440 }
441
442 /**
443  * Modify the irg itself and the frame type.
444  */
445 static void modify_irg(be_abi_irg_t *env)
446 {
447         firm_dbg_module_t *dbg    = env->dbg;
448         be_abi_call_t *call       = be_abi_call_new();
449         const arch_isa_t *isa     = env->birg->main_env->arch_env->isa;
450         const arch_register_t *sp = arch_isa_sp(isa);
451         ir_graph *irg             = env->birg->irg;
452         ir_node *bl               = get_irg_start_block(irg);
453         ir_node *end              = get_irg_end_block(irg);
454         ir_node *arg_tuple        = get_irg_args(irg);
455         ir_node *no_mem           = get_irg_no_mem(irg);
456         type *method_type         = get_entity_type(get_irg_entity(irg));
457         int n_params              = get_method_n_params(method_type);
458         pmap *regs                = pmap_create();
459
460         int max_arg               = 0;
461         int reg_params_nr         = 0;
462         int arg_offset            = 0;
463
464         int i, j, n;
465
466         ir_node *frame_pointer;
467         ir_node *reg_params, *reg_params_bl;
468         ir_node **args, **args_repl;
469         const ir_edge_t *edge;
470
471         pmap_entry *ent;
472
473
474         DBG((dbg, LEVEL_1, "introducing abi on %+F\n", irg));
475
476         /* Find the maximum proj number of the argument tuple proj */
477         foreach_out_edge(arg_tuple, edge)  {
478                 ir_node *irn = get_edge_src_irn(edge);
479                 int nr       = get_Proj_proj(irn);
480                 max_arg      = MAX(max_arg, nr);
481         }
482         max_arg += 1;
483         args      = obstack_alloc(&env->obst, max_arg * sizeof(args[0]));
484         args_repl = obstack_alloc(&env->obst, max_arg * sizeof(args[0]));
485         memset(args, 0, max_arg * sizeof(args[0]));
486         memset(args_repl, 0, max_arg * sizeof(args[0]));
487
488         /* Fill the argument vector */
489         foreach_out_edge(arg_tuple, edge) {
490                 ir_node *irn = get_edge_src_irn(edge);
491                 int nr       = get_Proj_proj(irn);
492                 args[nr]     = irn;
493                 DBG((dbg, LEVEL_2, "\treading arg: %d -> %+F\n", nr, irn));
494         }
495
496         /* Get the ABI constraints from the ISA */
497         arch_isa_get_call_abi(isa, method_type, call);
498
499         /* Count the register params and add them to the number of Projs for the RegParams node */
500         for(i = 0; i < n_params; ++i) {
501                 be_abi_call_arg_t *arg = get_call_arg(call, 0, i);
502                 if(arg->in_reg) {
503                         assert(arg->reg != sp && "cannot use stack pointer as parameter register");
504                         pmap_insert(regs, (void *) arg->reg, NULL);
505                         DBG((dbg, LEVEL_2, "\targ #%d -> reg %s\n", i, arg->reg->name));
506                 }
507         }
508
509         /* Collect all callee-save registers */
510         for(i = 0, n = arch_isa_get_n_reg_class(isa); i < n; ++i) {
511                 const arch_register_class_t *cls = arch_isa_get_reg_class(isa, i);
512                 for(j = 0; j < cls->n_regs; ++j) {
513                         const arch_register_t *reg = &cls->regs[j];
514                         if(arch_register_type_is(reg, callee_save))
515                                 pmap_insert(regs, (void *) reg, NULL);
516                 }
517         }
518
519         /* The stack pointer must also be saved but not necessarily be marked as callee save */
520         pmap_insert(regs, (void *) sp, NULL);
521
522         reg_params_bl = get_irg_start_block(irg);
523         env->reg_params = reg_params = be_new_RegParams(irg, reg_params_bl, pmap_count(regs));
524         reg_params_nr = 0;
525
526         /*
527          * make proj nodes for the callee save registers.
528          * memorize them, since Return nodes get those as inputs.
529          */
530         for(ent = pmap_first(regs); ent; ent = pmap_next(regs)) {
531                 arch_register_t *reg = ent->key;
532                 int pos = -(reg_params_nr + 1);
533                 ent->value = new_r_Proj(irg, reg_params_bl, reg_params, reg->reg_class->mode, reg_params_nr);
534                 be_set_constr_single_reg(reg_params, pos, reg);
535
536                 /*
537                  * If the register is an ignore register,
538                  * The Proj for that register shall also be ignored during register allocation.
539                  */
540                 if(arch_register_type_is(reg, ignore))
541                         be_node_set_flags(reg_params, pos, arch_irn_flags_ignore);
542
543                 reg_params_nr++;
544
545                 DBG((dbg, LEVEL_2, "\tregister save proj #%d -> reg %s\n", reg_params_nr - 1, reg->name));
546         }
547
548         /* Insert the code to set up the stack frame */
549         frame_pointer = setup_frame(env);
550
551 #if 0
552         proj_sp = pmap_get(regs, (void *) sp);
553         proj_bp = pmap_get(regs, (void *) bp);
554         assert(proj_sp != NULL && "There must be a Proj for the stack pointer");
555         assert(proj_sp != NULL && "There must be a Proj for the base pointer");
556
557         /* Set the Proj for the stack pointer to ignore. */
558         be_node_set_flags(reg_params, -(get_Proj_proj(proj_sp) + 1), arch_irn_flags_ignore);
559
560         /*
561          * If a frame pointer is needed and the frame pointer is in a dedicated register,
562          * also exclude that from register allocation by setting the corresponding
563          * Proj to ignore.
564          */
565         if(!env->omit_fp && env->dedicated_fp)
566                 be_node_set_flags(reg_params, -(get_Proj_proj(proj_bp) + 1), arch_irn_flags_ignore);
567
568
569         if(env->omit_fp) {
570                 /* This is the stack pointer add/sub which allocates the frame. remind it for later fix up. */
571                 env->init_sp  = be_new_IncSP(sp, irg, reg_params_bl, proj_sp, no_mem, 0, be_stack_dir_along);
572                 frame_pointer = env->init_sp;
573         }
574
575         else {
576                 env->init_sp  = proj_sp;
577                 frame_pointer = be_new_Copy(sp->reg_class, irg, reg_params_bl, proj_sp);
578         }
579
580         /* Set the new frame pointer. */
581         exchange(get_irg_frame(irg), frame_pointer);
582         set_irg_frame(irg, frame_pointer);
583 #endif
584
585         /* compute the start offset for the stack parameters. */
586         {
587                 int arg_offset = 0;
588                 int arg_size   = 0;
589                 int inc_dir    = isa->stack_dir * (env->left_to_right ? 1 : -1);
590
591                 for(i = 0; i < n_params; ++i) {
592                         be_abi_call_arg_t *arg = get_call_arg(call, 0, i);
593                         if(!arg->in_reg)
594                                 arg_size += get_type_size_bytes(get_method_param_type(method_type, i));
595                 }
596
597                 arg_offset = -isa->stack_dir * call->arg_gap + env->left_to_right * arg_size;
598
599                 /* Now, introduce stack param nodes for all parameters passed on the stack */
600                 for(i = 0; i < max_arg; ++i) {
601                         ir_node *arg_proj = args[i];
602                         if(arg_proj != NULL) {
603                                 be_abi_call_arg_t *arg;
604                                 ir_type *param_type;
605                                 int nr = get_Proj_proj(arg_proj);
606
607                                 nr         = MIN(nr, n_params);
608                                 arg        = get_call_arg(call, 0, nr);
609                                 param_type = get_method_param_type(method_type, nr);
610
611                                 if(arg->in_reg) {
612                                         args_repl[i] = new_r_Proj(irg, reg_params_bl, reg_params, get_irn_mode(arg_proj), reg_params_nr);
613                                         be_set_constr_single_reg(reg_params, -(reg_params_nr + 1), arg->reg);
614                                         reg_params_nr++;
615                                 }
616
617                                 /* when the (stack) parameter is primitive, we insert a StackParam
618                                 node representing the load of that parameter */
619                                 else {
620                                         int size = get_type_size_bytes(param_type) * isa->stack_dir;
621
622                                         if(inc_dir < 0)
623                                                 arg_offset -= size;
624
625                                         if(is_atomic_type(param_type)) {
626                                                 ir_mode *mode                    = get_type_mode(param_type);
627                                                 const arch_register_class_t *cls = arch_isa_get_reg_class_for_mode(isa, mode);
628                                                 args_repl[i] = be_new_StackParam(cls, irg, reg_params_bl, mode, frame_pointer, arg_offset);
629                                         }
630
631                                         /* The stack parameter is not primitive (it is a struct or array),
632                                         we thus will create a node representing the parameter's address
633                                         on the stack. */
634                                         else {
635                                                 assert(0 && "struct parameters are not supported");
636                                         }
637
638                                         if(inc_dir > 0)
639                                                 arg_offset += size;
640                                 }
641                         }
642                 }
643         }
644
645         /* reroute the edges from the original argument projs to the RegParam ones. */
646         for(i = 0; i < max_arg; ++i) {
647                 if(args[i] != NULL) {
648                         assert(args_repl[i] != NULL);
649                         edges_reroute(args[i], args_repl[i], irg);
650                 }
651         }
652
653         /* All Return nodes hang on the End node, so look for them there. */
654         for(i = 0, n = get_irn_arity(end); i < n; ++i) {
655                 ir_node *irn = get_irn_n(end, i);
656
657                 if(get_irn_opcode(irn) == iro_Return) {
658                         ir_node *bl = get_nodes_block(irn);
659                         ir_node *ret;
660                         int i, n;
661                         ir_node **in;
662
663                         /* collect all arguments of the return */
664                         for(i = 0, n = get_irn_arity(irn); i < n; ++i)
665                                 obstack_ptr_grow(&env->obst, get_irn_n(irn, i));
666
667                         /* Add the Proj nodes representing the caller save registers. */
668                         for(ent = pmap_first(regs); ent; ent = pmap_next(regs), ++n) {
669                                 const arch_register_t *reg = ent->key;
670                                 ir_node *irn               = ent->value;
671
672                                 /*
673                                  * If the register is the stack pointer,
674                                  * add the fix up code. Either add the size of the stack
675                                  * frame if we omitted the frame pointer or move the
676                                  * frame pointer back to the stack register.
677                                  */
678                                 if(reg == sp) {
679                                         irn = be_new_IncSP(sp, irg, bl, frame_pointer, no_mem, env->omit_fp ? BE_STACK_FRAME_SIZE : 0, be_stack_dir_against);
680                                 }
681                                 obstack_ptr_grow(&env->obst, irn);
682                         }
683
684                         /* The in array for the new back end return is now ready. */
685                         in  = obstack_finish(&env->obst);
686                         ret = be_new_Return(irg, bl, n, in);
687                         edges_reroute(irn, ret, irg);
688                         obstack_free(&env->obst, in);
689                 }
690         }
691
692         obstack_free(&env->obst, args);
693         be_abi_call_free(call);
694         env->callee_save = regs;
695 }
696
697 static void collect_alloca_walker(ir_node *irn, void *data)
698 {
699         be_abi_irg_t *env = data;
700         if(get_irn_opcode(irn) == iro_Alloc && get_Alloc_where(irn) == stack_alloc)
701                 obstack_ptr_grow(&env->obst, irn);
702 }
703
704 be_abi_irg_t *be_abi_introduce(be_irg_t *birg)
705 {
706         be_abi_irg_t *env = malloc(sizeof(env[0]));
707
708         int i;
709         ir_node **stack_allocs;
710
711         env->method_type   = get_entity_type(get_irg_entity(birg->irg));
712         env->call          = be_abi_call_new();
713         arch_isa_get_call_abi(birg->main_env->arch_env->isa, env->method_type, env->call);
714
715         env->omit_fp       = (env->call->flags & BE_ABI_TRY_OMIT_FRAME_POINTER) != 0;
716         env->dedicated_fp  = (env->call->flags & BE_ABI_FRAME_POINTER_DEDICATED) != 0;
717         env->left_to_right = (env->call->flags & BE_ABI_LEFT_TO_RIGHT) != 0;
718         env->birg          = birg;
719         env->stack_ops     = pset_new_ptr(32);
720         env->dbg           = firm_dbg_register("firm.be.abi");
721         obstack_init(&env->obst);
722
723         /* search for stack allocation nodes and record them */
724         irg_walk_graph(env->birg->irg, collect_alloca_walker, NULL, env);
725         obstack_ptr_grow(&env->obst, NULL);
726         stack_allocs = obstack_finish(&env->obst);
727
728         /* If there are stack allocations in the irg, we need a frame pointer */
729         if(stack_allocs[0] != NULL)
730                 env->omit_fp = 0;
731
732         modify_irg(env);
733
734         for(i = 0; stack_allocs[i] != NULL; ++i)
735                 implement_stack_alloc(env, stack_allocs[i]);
736
737         irg_walk_graph(env->birg->irg, NULL, adjust_call_walker, env);
738         return env;
739 }
740
741 static void collect_stack_nodes(ir_node *irn, void *data)
742 {
743         pset *s = data;
744
745         switch(be_get_irn_opcode(irn)) {
746         case beo_IncSP:
747         case beo_AddSP:
748                 pset_insert_ptr(s, irn);
749         }
750 }
751
752 void be_abi_fix_stack_nodes(be_abi_irg_t *env)
753 {
754         dom_front_info_t *df;
755         pset *stack_ops;
756
757         /* We need dominance frontiers for fix up */
758         df = be_compute_dominance_frontiers(env->birg->irg);
759
760         stack_ops = pset_new_ptr_default();
761         pset_insert_ptr(env->stack_ops, env->init_sp);
762         irg_walk_graph(env->birg->irg, collect_stack_nodes, NULL, stack_ops);
763         be_ssa_constr_set(df, stack_ops);
764         del_pset(stack_ops);
765
766         /* free these dominance frontiers */
767         be_free_dominance_frontiers(df);
768 }
769
770 static int get_dir(ir_node *irn)
771 {
772         return 1 - 2 * (be_get_IncSP_direction(irn) == be_stack_dir_against);
773 }
774
775 static int process_stack_bias(be_abi_irg_t *env, ir_node *bl, int bias)
776 {
777         const arch_env_t *aenv = env->birg->main_env->arch_env;
778         ir_node *irn;
779         int start_bias = bias;
780
781         sched_foreach(bl, irn) {
782                 if(be_is_IncSP(irn)) {
783                         int ofs = be_get_IncSP_offset(irn);
784                         int dir = get_dir(irn);
785
786                         if(ofs == BE_STACK_FRAME_SIZE) {
787                                 ofs = get_type_size_bytes(get_irg_frame_type(env->birg->irg));
788                                 be_set_IncSP_offset(irn, ofs);
789                         }
790
791                         bias += dir * ofs;
792                 }
793
794                 else
795                         arch_set_stack_bias(aenv, irn, bias);
796         }
797
798         return bias;
799 }
800
801 static void stack_bias_walker(ir_node *bl, void *data)
802 {
803         if(bl != get_irg_start_block(get_irn_irg(bl))) {
804                 be_abi_irg_t *env = data;
805                 process_stack_bias(env, bl, env->start_block_bias);
806         }
807 }
808
809 void be_abi_fix_stack_bias(be_abi_irg_t *env)
810 {
811         ir_graph *irg  = env->birg->irg;
812
813         /* Determine the stack bias at the and of the start block. */
814         env->start_block_bias = process_stack_bias(env, get_irg_start_block(irg), 0);
815
816         /* fix the bias is all other blocks */
817         irg_block_walk_graph(irg, stack_bias_walker, NULL, env);
818 }
819
820 void be_abi_free(be_abi_irg_t *env)
821 {
822         del_pset(env->stack_ops);
823         obstack_free(&env->obst, NULL);
824         free(env);
825 }
826
827 ir_node *be_abi_get_callee_save_node(be_abi_irg_t *abi, const arch_register_t *reg)
828 {
829         assert(arch_register_type_is(reg, callee_save));
830         assert(pmap_contains(abi->callee_save, (void *) reg));
831         return pmap_get(abi->callee_save, (void *) reg);
832 }