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