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