reorganize backend headers (kill some _t variants in favor of a be_types.h)
[libfirm] / ir / be / ppc32 / bearch_ppc32.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 ppc backend driver file.
23  * @author  Moritz Kroll, Jens Mueller
24  * @version $Id$
25  */
26 #include "config.h"
27
28 #include "pseudo_irg.h"
29 #include "irgwalk.h"
30 #include "irprog.h"
31 #include "irprintf.h"
32 #include "ircons.h"
33 #include "irgmod.h"
34 #include "irdump.h"
35
36 #include "bitset.h"
37 #include "debug.h"
38 #include "error.h"
39
40 #include "../bearch.h"                /* the general register allocator interface */
41 #include "../benode_t.h"
42 #include "../belower.h"
43 #include "../besched.h"
44 #include "be.h"
45 #include "../beabi.h"
46 #include "../bemachine.h"
47 #include "../bemodule.h"
48 #include "../bespillslots.h"
49 #include "../beblocksched.h"
50 #include "../beirg.h"
51 #include "../begnuas.h"
52 #include "../belistsched.h"
53
54 #include "pset.h"
55
56 #include "bearch_ppc32_t.h"
57
58 #include "ppc32_new_nodes.h"           /* ppc nodes interface */
59 #include "gen_ppc32_regalloc_if.h"     /* the generated interface (register type and class defenitions) */
60 #include "ppc32_transform.h"
61 #include "ppc32_transform_conv.h"
62 #include "ppc32_emitter.h"
63 #include "ppc32_map_regs.h"
64
65 #define DEBUG_MODULE "firm.be.ppc.isa"
66
67 int isleaf;
68
69 /* TODO: ugly, but we need it to get access to the registers assigned to Phi nodes */
70 static set *cur_reg_set = NULL;
71
72 /**************************************************
73  *                         _ _              _  __
74  *                        | | |            (_)/ _|
75  *  _ __ ___  __ _    __ _| | | ___   ___   _| |_
76  * | '__/ _ \/ _` |  / _` | | |/ _ \ / __| | |  _|
77  * | | |  __/ (_| | | (_| | | | (_) | (__  | | |
78  * |_|  \___|\__, |  \__,_|_|_|\___/ \___| |_|_|
79  *            __/ |
80  *           |___/
81  **************************************************/
82
83 /**
84  * Return register requirements for a ppc node.
85  * If the node returns a tuple (mode_T) then the proj's
86  * will be asked for this information.
87  */
88 static const arch_register_req_t *ppc32_get_irn_reg_req(const ir_node *irn,
89                                                         int pos)
90 {
91         long               node_pos = pos == -1 ? 0 : pos;
92         ir_mode           *mode     = get_irn_mode(irn);
93         FIRM_DBG_REGISTER(firm_dbg_module_t *mod, DEBUG_MODULE);
94
95         if (is_Block(irn) || mode == mode_X || mode == mode_M) {
96                 DBG((mod, LEVEL_1, "ignoring block, mode_X or mode_M node %+F\n", irn));
97                 return arch_no_register_req;
98         }
99
100         if (mode == mode_T && pos < 0) {
101                 DBG((mod, LEVEL_1, "ignoring request for OUT requirements at %+F", irn));
102                 return arch_no_register_req;
103         }
104
105         DBG((mod, LEVEL_1, "get requirements at pos %d for %+F ... ", pos, irn));
106
107         if (is_Proj(irn)) {
108                 /* in case of a proj, we need to get the correct OUT slot */
109                 /* of the node corresponding to the proj number */
110                 if (pos == -1) {
111                         node_pos = ppc32_translate_proj_pos(irn);
112                 } else {
113                         node_pos = pos;
114                 }
115
116                 irn = skip_Proj_const(irn);
117
118                 DB((mod, LEVEL_1, "skipping Proj, going to %+F at pos %d ... ", irn, node_pos));
119         }
120
121         /* get requirements for our own nodes */
122         if (is_ppc32_irn(irn)) {
123                 const arch_register_req_t *req;
124                 if (pos >= 0) {
125                         req = get_ppc32_in_req(irn, pos);
126                 } else {
127                         req = get_ppc32_out_req(irn, node_pos);
128                 }
129
130                 DB((mod, LEVEL_1, "returning reqs for %+F at pos %d\n", irn, pos));
131                 return req;
132         }
133
134         /* unknowns should be transformed by now */
135         assert(!is_Unknown(irn));
136
137         DB((mod, LEVEL_1, "returning NULL for %+F (node not supported)\n", irn));
138         return arch_no_register_req;
139 }
140
141 static arch_irn_class_t ppc32_classify(const ir_node *irn)
142 {
143         irn = skip_Proj_const(irn);
144
145         if (is_cfop(irn)) {
146                 return arch_irn_class_branch;
147         }
148
149         return 0;
150 }
151
152 static ir_entity *ppc32_get_frame_entity(const ir_node *irn)
153 {
154         if(!is_ppc32_irn(irn)) return NULL;
155         if(get_ppc32_type(irn)!=ppc32_ac_FrameEntity) return NULL;
156         return get_ppc32_frame_entity(irn);
157 }
158
159 static void ppc32_set_frame_entity(ir_node *irn, ir_entity *ent)
160 {
161         if (! is_ppc32_irn(irn) || get_ppc32_type(irn) != ppc32_ac_FrameEntity)
162                 return;
163         set_ppc32_frame_entity(irn, ent);
164 }
165
166 /**
167  * This function is called by the generic backend to correct offsets for
168  * nodes accessing the stack.
169  */
170 static void ppc32_set_stack_bias(ir_node *irn, int bias)
171 {
172         set_ppc32_offset(irn, bias);
173 }
174
175 static int ppc32_get_sp_bias(const ir_node *irn)
176 {
177         (void) irn;
178         return 0;
179 }
180
181 typedef struct
182 {
183         const be_abi_call_t *call;
184         ir_graph *irg;
185 } ppc32_abi_env;
186
187 /**
188  * Initialize the callback object.
189  * @param call The call object.
190  * @param aenv The architecture environment.
191  * @param irg  The graph with the method.
192  * @return     Some pointer. This pointer is passed to all other callback functions as self object.
193  */
194 static void *ppc32_abi_init(const be_abi_call_t *call, const arch_env_t *aenv, ir_graph *irg)
195 {
196         ppc32_abi_env *env = XMALLOC(ppc32_abi_env);
197         (void) aenv;
198
199         env->call = call;
200         env->irg = irg;
201         return env;
202 }
203
204 /**
205  * Destroy the callback object.
206  * @param self The callback object.
207  */
208 static void ppc32_abi_done(void *self)
209 {
210         free(self);
211 }
212
213 /**
214  * Get the between type for that call.
215  * @param self The callback object.
216  * @return The between type of for that call.
217  */
218 static ir_type *ppc32_abi_get_between_type(void *self)
219 {
220         static ir_type *between_type = NULL;
221         static ir_entity *old_bp_ent = NULL;
222         (void) self;
223
224         if(!between_type) {
225                 ir_entity *ret_addr_ent;
226                 ir_type *ret_addr_type = new_type_primitive(new_id_from_str("return_addr"), mode_P);
227                 ir_type *old_bp_type   = new_type_primitive(new_id_from_str("bp"), mode_P);
228
229                 between_type           = new_type_class(new_id_from_str("ppc32_between_type"));
230                 old_bp_ent             = new_entity(between_type, new_id_from_str("old_bp"), old_bp_type);
231                 ret_addr_ent           = new_entity(between_type, new_id_from_str("old_bp"), ret_addr_type);
232
233                 set_entity_offset(old_bp_ent, 0);
234                 set_entity_offset(ret_addr_ent, get_type_size_bytes(old_bp_type));
235                 set_type_size_bytes(between_type, get_type_size_bytes(old_bp_type) + get_type_size_bytes(ret_addr_type));
236         }
237
238         return between_type;
239 }
240
241 /**
242  * Generate the prologue.
243  * @param self       The callback object.
244  * @param mem        A pointer to the mem node. Update this if you define new memory.
245  * @param reg_map    A mapping mapping all callee_save/ignore/parameter registers to their defining nodes.
246  * @param stack_bias Points to the current stack bias, can be modified if needed.
247  *
248  * @return        The register which shall be used as a stack frame base.
249  *
250  * All nodes which define registers in @p reg_map must keep @p reg_map current.
251  */
252 static const arch_register_t *ppc32_abi_prologue(void *self, ir_node **mem, pmap *reg_map, int *stack_bias)
253 {
254         ppc32_abi_env *env = (ppc32_abi_env *) self;
255         be_abi_call_flags_t flags = be_abi_call_get_flags(env->call);
256         (void) mem;
257         (void) reg_map;
258         (void) stack_bias;
259         isleaf = flags.bits.irg_is_leaf;
260
261         if (flags.bits.try_omit_fp)
262                 return &ppc32_gp_regs[REG_R1];
263         else
264                 return &ppc32_gp_regs[REG_R31];
265 }
266
267 /**
268  * Generate the epilogue.
269  * @param self    The callback object.
270  * @param mem     Memory one can attach to.
271  * @param reg_map A mapping mapping all callee_save/ignore/return registers to their defining nodes.
272  *
273  * All nodes which define registers in @p reg_map must keep @p reg_map current.
274  * Also, the @p mem variable must be updated, if memory producing nodes are inserted.
275  */
276 static void ppc32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_map)
277 {
278         (void) self;
279         (void) bl;
280         (void) mem;
281         (void) reg_map;
282 }
283
284 static const be_abi_callbacks_t ppc32_abi_callbacks = {
285         ppc32_abi_init,
286         ppc32_abi_done,
287         ppc32_abi_get_between_type,
288         ppc32_abi_prologue,
289         ppc32_abi_epilogue,
290 };
291
292 /* fill register allocator interface */
293
294 static const arch_irn_ops_t ppc32_irn_ops = {
295         ppc32_get_irn_reg_req,
296         ppc32_classify,
297         ppc32_get_frame_entity,
298         ppc32_set_frame_entity,
299         ppc32_set_stack_bias,
300         ppc32_get_sp_bias,
301         NULL,    /* get_inverse             */
302         NULL,    /* get_op_estimated_cost   */
303         NULL,    /* possible_memory_operand */
304         NULL,    /* perform_memory_operand  */
305 };
306
307 /**************************************************
308  *                _                         _  __
309  *               | |                       (_)/ _|
310  *   ___ ___   __| | ___  __ _  ___ _ __    _| |_
311  *  / __/ _ \ / _` |/ _ \/ _` |/ _ \ '_ \  | |  _|
312  * | (_| (_) | (_| |  __/ (_| |  __/ | | | | | |
313  *  \___\___/ \__,_|\___|\__, |\___|_| |_| |_|_|
314  *                        __/ |
315  *                       |___/
316  **************************************************/
317
318 static void ppc32_before_abi(void *self) {
319         ppc32_code_gen_t *cg = self;
320         ir_type *frame_type = get_irg_frame_type(cg->irg);
321
322         frame_alloc_area(frame_type, 24, 4, 1);
323
324         ppc32_init_conv_walk();
325         irg_walk_blkwise_graph(cg->irg, NULL, ppc32_conv_walk, cg);
326
327         if (cg->area_size) {
328                 if(cg->area_size < 32) cg->area_size = 32;
329                 cg->area = frame_alloc_area(get_irg_frame_type(cg->irg), cg->area_size+24, 16, 1);
330         }
331 }
332
333 static void ppc32_search_start_successor(ir_node *block, void *env) {
334         ppc32_code_gen_t *cg = env;
335         int n = get_Block_n_cfgpreds(block);
336         ir_node *startblock = get_irg_start_block(cg->irg);
337         if(block == startblock) return;
338
339         for (n--; n >= 0; n--) {
340                 ir_node *predblock = get_irn_n(get_Block_cfgpred(block, n), -1);
341                 if(predblock == startblock)
342                 {
343                         cg->start_succ_block = block;
344                         return;
345                 }
346         }
347 }
348
349 /**
350  * Transforms the standard firm graph into
351  * a ppc firm graph
352  */
353 static void ppc32_prepare_graph(void *self) {
354         ppc32_code_gen_t *cg = self;
355
356         irg_block_walk_graph(cg->irg, NULL, ppc32_search_start_successor, cg);
357         irg_walk_blkwise_graph(cg->irg, NULL, ppc32_pretransform_walk, cg);
358         be_dump(cg->irg, "-pretransformed", dump_ir_block_graph);
359
360         ppc32_register_transformers();
361         irg_walk_blkwise_graph(cg->irg, NULL, ppc32_transform_node, cg);
362         be_dump(cg->irg, "-transformed", dump_ir_block_graph);
363         irg_walk_blkwise_graph(cg->irg, NULL, ppc32_transform_const, cg);
364 }
365
366
367
368 /**
369  * Called immediatly before emit phase.
370  */
371 static void ppc32_finish_irg(void *self) {
372         (void) self;
373         /* TODO: - fix offsets for nodes accessing stack
374                          - ...
375         */
376 }
377
378
379 /**
380  * Called before the register allocator.
381  * Calculate a block schedule here. We need it for the x87
382  * simulator and the emitter.
383  */
384 static void ppc32_before_ra(void *self) {
385         ppc32_code_gen_t *cg = self;
386         cg->blk_sched = be_create_block_schedule(cg->irg, cg->birg->exec_freq);
387 }
388
389 static void ppc32_transform_spill(ir_node *node, void *env)
390 {
391         (void)env;
392
393         if(be_is_Spill(node))
394         {
395                 ir_node  *store, *proj;
396                 dbg_info *dbg   = get_irn_dbg_info(node);
397                 ir_node  *block = get_nodes_block(node);
398
399                 const arch_register_class_t *regclass = arch_get_irn_reg_class(node, 1);
400
401                 if (regclass == &ppc32_reg_classes[CLASS_ppc32_gp])
402                 {
403                         store = new_bd_ppc32_Stw(dbg, block,
404                                 get_irn_n(node, 0), get_irn_n(node, 1), new_NoMem());
405                 }
406                 else if (regclass == &ppc32_reg_classes[CLASS_ppc32_fp])
407                 {
408                         store = new_bd_ppc32_Stfd(dbg, block,
409                                 get_irn_n(node, 0), get_irn_n(node, 1), new_NoMem());
410                 }
411                 else panic("Spill for register class not supported yet!");
412
413                 set_ppc32_frame_entity(store, be_get_frame_entity(node));
414
415                 proj = new_rd_Proj(dbg, block, store, mode_M, pn_Store_M);
416
417                 if (sched_is_scheduled(node)) {
418                         sched_add_after(sched_prev(node), store);
419                         sched_add_after(store, proj);
420
421                         sched_remove(node);
422                 }
423
424                 exchange(node, proj);
425         }
426
427         if(be_is_Reload(node))
428         {
429                 ir_node *load, *proj;
430                 const arch_register_t *reg;
431                 dbg_info *dbg   = get_irn_dbg_info(node);
432                 ir_node  *block = get_nodes_block(node);
433                 ir_mode  *mode  = get_irn_mode(node);
434
435                 const arch_register_class_t *regclass = arch_get_irn_reg_class_out(node);
436
437                 if (regclass == &ppc32_reg_classes[CLASS_ppc32_gp])
438                 {
439                         load = new_bd_ppc32_Lwz(dbg, block,     get_irn_n(node, 0), get_irn_n(node, 1));
440                 }
441                 else if (regclass == &ppc32_reg_classes[CLASS_ppc32_fp])
442                 {
443                         load = new_bd_ppc32_Lfd(dbg, block,     get_irn_n(node, 0), get_irn_n(node, 1));
444                 }
445                 else panic("Reload for register class not supported yet!");
446
447                 set_ppc32_frame_entity(load, be_get_frame_entity(node));
448
449                 proj = new_rd_Proj(dbg, block, load, mode, pn_Load_res);
450
451                 if (sched_is_scheduled(node)) {
452                         sched_add_after(sched_prev(node), load);
453                         sched_add_after(load, proj);
454
455                         sched_remove(node);
456                 }
457
458                 /* copy the register from the old node to the new Load */
459                 reg = arch_get_irn_register(node);
460                 arch_set_irn_register(load, reg);
461
462                 exchange(node, proj);
463         }
464 }
465
466 /**
467  * Some stuff to do immediately after register allocation
468  */
469 static void ppc32_after_ra(void *self) {
470         ppc32_code_gen_t *cg = self;
471         be_coalesce_spillslots(cg->birg);
472         irg_walk_blkwise_graph(cg->irg, NULL, ppc32_transform_spill, NULL);
473 }
474
475 /**
476  * Emits the code, closes the output file and frees
477  * the code generator interface.
478  */
479 static void ppc32_emit_and_done(void *self) {
480         ppc32_code_gen_t *cg = self;
481         ir_graph         *irg = cg->irg;
482
483         dump_ir_block_graph_sched(irg, "-ppc-finished");
484         ppc32_gen_routine(cg, irg);
485
486         cur_reg_set = NULL;
487
488         /* de-allocate code generator */
489         del_set(cg->reg_set);
490         free(self);
491 }
492
493 int is_direct_entity(ir_entity *ent);
494
495 static void *ppc32_cg_init(be_irg_t *birg);
496
497 static const arch_code_generator_if_t ppc32_code_gen_if = {
498         ppc32_cg_init,
499         NULL,                 /* get_pic_base */
500         ppc32_before_abi,
501         ppc32_prepare_graph,
502         NULL,                 /* spill */
503         ppc32_before_ra,      /* before register allocation hook */
504         ppc32_after_ra,
505         ppc32_finish_irg,
506         ppc32_emit_and_done
507 };
508
509 /**
510  * Initializes the code generator.
511  */
512 static void *ppc32_cg_init(be_irg_t *birg) {
513         ppc32_isa_t      *isa = (ppc32_isa_t *)birg->main_env->arch_env;
514         ppc32_code_gen_t *cg  = XMALLOC(ppc32_code_gen_t);
515
516         cg->impl      = &ppc32_code_gen_if;
517         cg->irg       = birg->irg;
518         cg->reg_set   = new_set(ppc32_cmp_irn_reg_assoc, 1024);
519         cg->isa       = isa;
520         cg->birg      = birg;
521         cg->area_size = 0;
522         cg->area      = NULL;
523         cg->start_succ_block = NULL;
524         cg->blk_sched = NULL;
525         FIRM_DBG_REGISTER(cg->mod, "firm.be.ppc.cg");
526
527         cur_reg_set = cg->reg_set;
528
529         return (arch_code_generator_t *)cg;
530 }
531
532
533
534 /*****************************************************************
535  *  ____             _                  _   _____  _____
536  * |  _ \           | |                | | |_   _|/ ____|  /\
537  * | |_) | __ _  ___| | _____ _ __   __| |   | | | (___   /  \
538  * |  _ < / _` |/ __| |/ / _ \ '_ \ / _` |   | |  \___ \ / /\ \
539  * | |_) | (_| | (__|   <  __/ | | | (_| |  _| |_ ____) / ____ \
540  * |____/ \__,_|\___|_|\_\___|_| |_|\__,_| |_____|_____/_/    \_\
541  *
542  *****************************************************************/
543
544 static ppc32_isa_t ppc32_isa_template = {
545         {
546                 &ppc32_isa_if,           /* isa interface */
547                 &ppc32_gp_regs[REG_R1],  /* stack pointer */
548                 &ppc32_gp_regs[REG_R31], /* base pointer */
549                 &ppc32_reg_classes[CLASS_ppc32_gp],  /* static link pointer class */
550                 -1,                      /* stack is decreasing */
551                 2,                       /* power of two stack alignment for calls, 2^2 == 4 */
552                 NULL,                    /* main environment */
553                 7,                       /* spill costs */
554                 5,                       /* reload costs */
555         },
556         NULL                    /* symbol set */
557 };
558
559 /**
560  * Collects all SymConsts which need to be accessed "indirectly"
561  *
562  * @param node    the firm node
563  * @param env     the symbol set
564  */
565 static void ppc32_collect_symconsts_walk(ir_node *node, void *env) {
566         pset *symbol_set = env;
567
568         if (is_SymConst(node)) {
569                 ir_entity *ent = get_SymConst_entity(node);
570                 set_entity_backend_marked(ent, 1);
571                 if (! is_direct_entity(ent))
572                         pset_insert_ptr(symbol_set, ent);
573         }
574 }
575
576 /**
577  * Initializes the backend ISA and opens the output file.
578  */
579 static arch_env_t *ppc32_init(FILE *file_handle) {
580         static int inited = 0;
581         ppc32_isa_t *isa;
582         int i;
583
584         if (inited)
585                 return NULL;
586
587         isa = XMALLOC(ppc32_isa_t);
588         memcpy(isa, &ppc32_isa_template, sizeof(*isa));
589
590         be_emit_init(file_handle);
591
592         ppc32_register_init();
593         ppc32_create_opcodes(&ppc32_irn_ops);
594
595         inited = 1;
596
597         isa->symbol_set = pset_new_ptr(8);
598         for (i = 0; i < get_irp_n_irgs(); ++i) {
599                 ir_graph *irg = get_irp_irg(i);
600                 irg_walk_blkwise_graph(irg, NULL, ppc32_collect_symconsts_walk, isa->symbol_set);
601         }
602
603         /* we mark referenced global entities, so we can only emit those which
604          * are actually referenced. (Note: you mustn't use the type visited flag
605          * elsewhere in the backend)
606          */
607         inc_master_type_visited();
608
609         return &isa->arch_env;
610 }
611
612 static void ppc32_dump_indirect_symbols(ppc32_isa_t *isa) {
613         ir_entity *ent;
614
615         foreach_pset(isa->symbol_set, ent) {
616                 const char *ld_name = get_entity_ld_name(ent);
617                 be_emit_irprintf(".non_lazy_symbol_pointer\n%s:\n\t.indirect_symbol _%s\n\t.long 0\n\n", ld_name, ld_name);
618                 be_emit_write_line();
619         }
620 }
621
622 /**
623  * Closes the output file and frees the ISA structure.
624  */
625 static void ppc32_done(void *self) {
626         ppc32_isa_t *isa = self;
627
628         be_gas_emit_decls(isa->arch_env.main_env, 1);
629         be_gas_emit_switch_section(GAS_SECTION_DATA);
630         ppc32_dump_indirect_symbols(isa);
631
632         be_emit_exit();
633         del_pset(isa->symbol_set);
634
635         free(self);
636 }
637
638
639
640 static unsigned ppc32_get_n_reg_class(const void *self) {
641         (void) self;
642         return N_CLASSES;
643 }
644
645 static const arch_register_class_t *ppc32_get_reg_class(const void *self,
646                                                         unsigned i) {
647         (void) self;
648         assert(i < N_CLASSES && "Invalid ppc register class requested.");
649         return &ppc32_reg_classes[i];
650 }
651
652
653
654 /**
655  * Get the register class which shall be used to store a value of a given mode.
656  * @param self The this pointer.
657  * @param mode The mode in question.
658  * @return A register class which can hold values of the given mode.
659  */
660 const arch_register_class_t *ppc32_get_reg_class_for_mode(const void *self, const ir_mode *mode) {
661         (void) self;
662         if (mode_is_float(mode))
663                 return &ppc32_reg_classes[CLASS_ppc32_fp];
664         else
665                 return &ppc32_reg_classes[CLASS_ppc32_gp];
666 }
667
668
669 /**
670  * Get the ABI restrictions for procedure calls.
671  * @param self        The this pointer.
672  * @param method_type The type of the method (procedure) in question.
673  * @param abi         The abi object to be modified
674  */
675 static void ppc32_get_call_abi(const void *self, ir_type *method_type, be_abi_call_t *abi) {
676         ir_type  *tp;
677         ir_mode  *mode;
678         int       i, n = get_method_n_params(method_type);
679         int               stackoffs = 0, lastoffs = 0, stackparamsize;
680
681         int               gpregi = REG_R3;
682         int               fpregi = REG_F1;
683
684         const arch_register_t *reg;
685         be_abi_call_flags_t call_flags = { { 0, 0, 1, 0, 0, 0, 1 } };
686
687         (void) self;
688         if(get_type_visibility(method_type)!=visibility_external_allocated)
689                 call_flags.bits.call_has_imm = 1;
690
691         /* set stack parameter passing style */
692         be_abi_call_set_flags(abi, call_flags, &ppc32_abi_callbacks);
693
694         for (i = 0; i < n; i++) {
695                 tp   = get_method_param_type(method_type, i);
696                 mode = get_type_mode(tp);
697                 if(is_atomic_type(tp))
698                 {
699                         if(mode_is_float(mode))
700                         {
701                                 if(fpregi <= REG_F13)
702                                 {
703                                         if(get_mode_size_bits(mode) == 32) gpregi++, stackparamsize=4;
704                                         else gpregi += 2, stackparamsize=8;                                                             // mode == irm_D
705                                         reg = &ppc32_fp_regs[fpregi++];
706                                 }
707                                 else
708                                 {
709                                         if(get_mode_size_bits(mode) == 32) stackparamsize=4;
710                                         else stackparamsize=8;                                                          // mode == irm_D
711                                         reg = NULL;
712                                 }
713                         }
714                         else
715                         {
716                                 if(gpregi <= REG_R10)
717                                         reg = &ppc32_gp_regs[gpregi++];
718                                 else
719                                         reg = NULL;
720                                 stackparamsize=4;
721                         }
722
723                         if(reg)
724                                 be_abi_call_param_reg(abi, i, reg);
725                         else
726                         {
727                                 be_abi_call_param_stack(abi, i, mode, 4, stackoffs - lastoffs, 0);
728                                 lastoffs = stackoffs+stackparamsize;
729                         }
730                         stackoffs += stackparamsize;
731                 }
732                 else
733                 {
734                         be_abi_call_param_stack(abi, i, mode, 4, stackoffs - lastoffs, 0);
735                         stackoffs += (get_type_size_bytes(tp)+3) & -4;
736                         lastoffs = stackoffs;
737                 }
738         }
739
740         /* explain where result can be found if any */
741         if (get_method_n_ress(method_type) > 0) {
742                 tp   = get_method_res_type(method_type, 0);
743                 mode = get_type_mode(tp);
744
745                 be_abi_call_res_reg(abi, 0,
746                         mode_is_float(mode) ? &ppc32_fp_regs[REG_F1] : &ppc32_gp_regs[REG_R3]);
747         }
748 }
749
750 int ppc32_to_appear_in_schedule(void *block_env, const ir_node *irn) {
751         (void) block_env;
752         if(!is_ppc32_irn(irn))
753                 return -1;
754
755         return 1;
756 }
757
758 /**
759  * Initializes the code generator interface.
760  */
761 static const arch_code_generator_if_t *ppc32_get_code_generator_if(void *self) {
762         (void) self;
763         return &ppc32_code_gen_if;
764 }
765
766 list_sched_selector_t ppc32_sched_selector;
767
768 /**
769  * Returns the reg_pressure scheduler with to_appear_in_schedule() overloaded
770  */
771 static const list_sched_selector_t *ppc32_get_list_sched_selector(const void *self, list_sched_selector_t *selector) {
772         (void) self;
773         (void) selector;
774         ppc32_sched_selector = trivial_selector;
775         ppc32_sched_selector.to_appear_in_schedule = ppc32_to_appear_in_schedule;
776         return &ppc32_sched_selector;
777 }
778
779 static const ilp_sched_selector_t *ppc32_get_ilp_sched_selector(const void *self) {
780         (void) self;
781         return NULL;
782 }
783
784 /**
785  * Returns the necessary byte alignment for storing a register of given class.
786  */
787 static int ppc32_get_reg_class_alignment(const void *self, const arch_register_class_t *cls) {
788         ir_mode *mode = arch_register_class_mode(cls);
789         (void) self;
790
791         return get_mode_size_bytes(mode);
792 }
793
794 static const be_execution_unit_t ***ppc32_get_allowed_execution_units(const void *self, const ir_node *irn) {
795         (void) self;
796         (void) irn;
797         /* TODO */
798         panic("Unimplemented ppc32_get_allowed_execution_units()");
799         return NULL;
800 }
801
802 static const be_machine_t *ppc32_get_machine(const void *self) {
803         (void) self;
804         /* TODO */
805         panic("Unimplemented ppc32_get_machine()");
806         return NULL;
807 }
808
809 /**
810  * Return irp irgs in the desired order.
811  */
812 static ir_graph **ppc32_get_irg_list(const void *self, ir_graph ***irg_list) {
813         (void) self;
814         (void) irg_list;
815         return NULL;
816 }
817
818 /**
819  * Returns the libFirm configuration parameter for this backend.
820  */
821 static const backend_params *ppc32_get_libfirm_params(void) {
822         static backend_params p = {
823                 1,     /* need dword lowering */
824                 0,     /* don't support inline assembler yet */
825                 NULL,  /* will be set later */
826                 NULL,  /* but yet no creator function */
827                 NULL,  /* context for create_intrinsic_fkt */
828                 NULL,  /* no if conversion settings */
829                 NULL,  /* no float arithmetic mode (TODO) */
830                 0,     /* no trampoline support: size 0 */
831                 0,     /* no trampoline support: align 0 */
832                 NULL,  /* no trampoline support: no trampoline builder */
833                 4      /* alignment of stack parameter */
834         };
835
836         return &p;
837 }
838
839 static asm_constraint_flags_t ppc32_parse_asm_constraint(const void *self, const char **c)
840 {
841         /* no asm support yet */
842         (void) self;
843         (void) c;
844         return ASM_CONSTRAINT_FLAG_INVALID;
845 }
846
847 static int ppc32_is_valid_clobber(const void *self, const char *clobber)
848 {
849         /* no asm support yet */
850         (void) self;
851         (void) clobber;
852         return 0;
853 }
854
855 const arch_isa_if_t ppc32_isa_if = {
856         ppc32_init,
857         ppc32_done,
858         NULL,             /* handle intrinsics */
859         ppc32_get_n_reg_class,
860         ppc32_get_reg_class,
861         ppc32_get_reg_class_for_mode,
862         ppc32_get_call_abi,
863         ppc32_get_code_generator_if,
864         ppc32_get_list_sched_selector,
865         ppc32_get_ilp_sched_selector,
866         ppc32_get_reg_class_alignment,
867         ppc32_get_libfirm_params,
868         ppc32_get_allowed_execution_units,
869         ppc32_get_machine,
870         ppc32_get_irg_list,
871         NULL,                 /* mark remat */
872         ppc32_parse_asm_constraint,
873         ppc32_is_valid_clobber
874 };
875
876 void be_init_arch_ppc32(void)
877 {
878         be_register_isa_if("ppc32", &ppc32_isa_if);
879 }
880
881 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_ppc32);