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