d37c80491e392f6f28a50b0181a6549046506114
[libfirm] / ir / be / sparc / bearch_sparc.c
1 /*
2  * Copyright (C) 1995-2010 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 sparc backend driver file.
23  * @author   Hannes Rapp, Matthias Braun
24  * @version  $Id$
25  */
26 #include "config.h"
27
28 #include "lc_opts.h"
29 #include "lc_opts_enum.h"
30
31 #include "irgwalk.h"
32 #include "irprog.h"
33 #include "irprintf.h"
34 #include "ircons.h"
35 #include "irgmod.h"
36 #include "irgopt.h"
37 #include "iroptimize.h"
38 #include "irtools.h"
39 #include "irdump.h"
40 #include "lowering.h"
41 #include "lower_dw.h"
42
43 #include "bitset.h"
44 #include "debug.h"
45 #include "array_t.h"
46 #include "error.h"
47 #include "util.h"
48
49 #include "../bearch.h"
50 #include "../benode.h"
51 #include "../belower.h"
52 #include "../besched.h"
53 #include "be.h"
54 #include "../bemachine.h"
55 #include "../bemodule.h"
56 #include "../beirg.h"
57 #include "../bespillslots.h"
58 #include "../begnuas.h"
59 #include "../belistsched.h"
60 #include "../beflags.h"
61
62 #include "bearch_sparc_t.h"
63
64 #include "sparc_new_nodes.h"
65 #include "gen_sparc_regalloc_if.h"
66 #include "sparc_transform.h"
67 #include "sparc_emitter.h"
68
69 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
70
71 static arch_irn_class_t sparc_classify(const ir_node *node)
72 {
73         (void) node;
74         return arch_irn_class_none;
75 }
76
77 static ir_entity *sparc_get_frame_entity(const ir_node *node)
78 {
79         if (is_sparc_FrameAddr(node)) {
80                 const sparc_attr_t *attr = get_sparc_attr_const(node);
81                 return attr->immediate_value_entity;
82         }
83
84         if (sparc_has_load_store_attr(node)) {
85                 const sparc_load_store_attr_t *load_store_attr
86                         = get_sparc_load_store_attr_const(node);
87                 if (load_store_attr->is_frame_entity) {
88                         return load_store_attr->base.immediate_value_entity;
89                 }
90         }
91
92         return NULL;
93 }
94
95 /**
96  * This function is called by the generic backend to correct offsets for
97  * nodes accessing the stack.
98  */
99 static void sparc_set_frame_offset(ir_node *node, int offset)
100 {
101         sparc_attr_t *attr = get_sparc_attr(node);
102         attr->immediate_value += offset;
103
104         /* must be a FrameAddr or a load/store node with frame_entity */
105         assert(is_sparc_FrameAddr(node) ||
106                         get_sparc_load_store_attr_const(node)->is_frame_entity);
107 }
108
109 static int sparc_get_sp_bias(const ir_node *node)
110 {
111         if (is_sparc_Save(node)) {
112                 const sparc_attr_t *attr = get_sparc_attr_const(node);
113                 if (get_irn_arity(node) == 3)
114                         panic("no support for _reg variant yet");
115
116                 /* Note we do not report the change of the SPARC_MIN_STACKSIZE
117                  * size, since we have additional magic in the emitter which
118                  * calculates that! */
119                 assert(attr->immediate_value <= -SPARC_MIN_STACKSIZE);
120                 return attr->immediate_value + SPARC_MIN_STACKSIZE;
121         } else if (is_sparc_RestoreZero(node)) {
122                 return SP_BIAS_RESET;
123         }
124         return 0;
125 }
126
127 /* fill register allocator interface */
128
129 const arch_irn_ops_t sparc_irn_ops = {
130         sparc_classify,
131         sparc_get_frame_entity,
132         sparc_set_frame_offset,
133         sparc_get_sp_bias,
134         NULL,    /* get_inverse             */
135         NULL,    /* get_op_estimated_cost   */
136         NULL,    /* possible_memory_operand */
137         NULL,    /* perform_memory_operand  */
138 };
139
140 /**
141  * Transforms the standard firm graph into
142  * a SPARC firm graph
143  */
144 static void sparc_prepare_graph(ir_graph *irg)
145 {
146         sparc_transform_graph(irg);
147 }
148
149 static bool sparc_modifies_flags(const ir_node *node)
150 {
151         return arch_irn_get_flags(node) & sparc_arch_irn_flag_modifies_flags;
152 }
153
154 static bool sparc_modifies_fp_flags(const ir_node *node)
155 {
156         return arch_irn_get_flags(node) & sparc_arch_irn_flag_modifies_fp_flags;
157 }
158
159 static void sparc_before_ra(ir_graph *irg)
160 {
161         /* fixup flags register */
162         be_sched_fix_flags(irg, &sparc_reg_classes[CLASS_sparc_flags_class],
163                            NULL, sparc_modifies_flags);
164         be_sched_fix_flags(irg, &sparc_reg_classes[CLASS_sparc_fpflags_class],
165                            NULL, sparc_modifies_fp_flags);
166 }
167
168 /**
169  * transform reload node => load
170  */
171 static void transform_Reload(ir_node *node)
172 {
173         ir_node   *block  = get_nodes_block(node);
174         dbg_info  *dbgi   = get_irn_dbg_info(node);
175         ir_node   *ptr    = get_irn_n(node, n_be_Spill_frame);
176         ir_node   *mem    = get_irn_n(node, n_be_Reload_mem);
177         ir_mode   *mode   = get_irn_mode(node);
178         ir_entity *entity = be_get_frame_entity(node);
179         const arch_register_t *reg;
180         ir_node   *proj;
181         ir_node   *load;
182
183         ir_node  *sched_point = sched_prev(node);
184
185         load = new_bd_sparc_Ld_imm(dbgi, block, ptr, mem, mode, entity, 0, true);
186         sched_add_after(sched_point, load);
187         sched_remove(node);
188
189         proj = new_rd_Proj(dbgi, load, mode, pn_sparc_Ld_res);
190
191         reg = arch_get_irn_register(node);
192         arch_set_irn_register(proj, reg);
193
194         exchange(node, proj);
195 }
196
197 /**
198  * transform spill node => store
199  */
200 static void transform_Spill(ir_node *node)
201 {
202         ir_node   *block  = get_nodes_block(node);
203         dbg_info  *dbgi   = get_irn_dbg_info(node);
204         ir_node   *ptr    = get_irn_n(node, n_be_Spill_frame);
205         ir_graph  *irg    = get_irn_irg(node);
206         ir_node   *mem    = get_irg_no_mem(irg);
207         ir_node   *val    = get_irn_n(node, n_be_Spill_val);
208         ir_mode   *mode   = get_irn_mode(val);
209         ir_entity *entity = be_get_frame_entity(node);
210         ir_node   *sched_point;
211         ir_node   *store;
212
213         sched_point = sched_prev(node);
214         store = new_bd_sparc_St_imm(dbgi, block, val, ptr, mem, mode, entity, 0, true);
215         sched_remove(node);
216         sched_add_after(sched_point, store);
217
218         exchange(node, store);
219 }
220
221 /**
222  * walker to transform be_Spill and be_Reload nodes
223  */
224 static void sparc_after_ra_walker(ir_node *block, void *data)
225 {
226         ir_node *node, *prev;
227         (void) data;
228
229         for (node = sched_last(block); !sched_is_begin(node); node = prev) {
230                 prev = sched_prev(node);
231
232                 if (be_is_Reload(node)) {
233                         transform_Reload(node);
234                 } else if (be_is_Spill(node)) {
235                         transform_Spill(node);
236                 }
237         }
238 }
239
240 static void sparc_collect_frame_entity_nodes(ir_node *node, void *data)
241 {
242         be_fec_env_t  *env = (be_fec_env_t*)data;
243         const ir_mode *mode;
244         int            align;
245         ir_entity     *entity;
246         const sparc_load_store_attr_t *attr;
247
248         if (be_is_Reload(node) && be_get_frame_entity(node) == NULL) {
249                 mode  = get_irn_mode(node);
250                 align = get_mode_size_bytes(mode);
251                 be_node_needs_frame_entity(env, node, mode, align);
252                 return;
253         }
254
255         if (!is_sparc_Ld(node) && !is_sparc_Ldf(node))
256                 return;
257
258         attr   = get_sparc_load_store_attr_const(node);
259         entity = attr->base.immediate_value_entity;
260         mode   = attr->load_store_mode;
261         if (entity != NULL)
262                 return;
263         if (!attr->is_frame_entity)
264                 return;
265         if (arch_irn_get_flags(node) & sparc_arch_irn_flag_needs_64bit_spillslot)
266                 mode = mode_Lu;
267         align  = get_mode_size_bytes(mode);
268         be_node_needs_frame_entity(env, node, mode, align);
269 }
270
271 static void sparc_set_frame_entity(ir_node *node, ir_entity *entity)
272 {
273         if (is_be_node(node)) {
274                 be_node_set_frame_entity(node, entity);
275         } else {
276                 /* we only say be_node_needs_frame_entity on nodes with load_store
277                  * attributes, so this should be fine */
278                 sparc_load_store_attr_t *attr = get_sparc_load_store_attr(node);
279                 assert(attr->is_frame_entity);
280                 assert(attr->base.immediate_value_entity == NULL);
281                 attr->base.immediate_value_entity = entity;
282         }
283 }
284
285 static void sparc_after_ra(ir_graph *irg)
286 {
287         be_stack_layout_t *stack_layout = be_get_irg_stack_layout(irg);
288         bool               at_begin     = stack_layout->sp_relative ? true : false;
289         be_fec_env_t      *fec_env      = be_new_frame_entity_coalescer(irg);
290
291         irg_walk_graph(irg, NULL, sparc_collect_frame_entity_nodes, fec_env);
292         be_assign_entities(fec_env, sparc_set_frame_entity, at_begin);
293         be_free_frame_entity_coalescer(fec_env);
294
295         irg_block_walk_graph(irg, NULL, sparc_after_ra_walker, NULL);
296
297         sparc_introduce_prolog_epilog(irg);
298 }
299
300 static void sparc_init_graph(ir_graph *irg)
301 {
302         (void) irg;
303 }
304
305 extern const arch_isa_if_t sparc_isa_if;
306 static sparc_isa_t sparc_isa_template = {
307         {
308                 &sparc_isa_if,                      /* isa interface implementation */
309                 N_SPARC_REGISTERS,
310                 sparc_registers,
311                 N_SPARC_CLASSES,
312                 sparc_reg_classes,
313                 &sparc_registers[REG_SP],           /* stack pointer register */
314                 &sparc_registers[REG_FRAME_POINTER],/* base pointer register */
315                 &sparc_reg_classes[CLASS_sparc_gp], /* link pointer register class */
316                 3,                                  /* power of two stack alignment
317                                                        for calls */
318                 NULL,                               /* main environment */
319                 7,                                  /* costs for a spill instruction */
320                 5,                                  /* costs for a reload instruction */
321                 true,                               /* custom abi handling */
322         },
323         NULL,     /* constants */
324 };
325
326 /**
327  * rewrite unsigned->float conversion.
328  * Sparc has no instruction for this so instead we do the following:
329  *
330  *   int    signed_x = unsigned_value_x;
331  *   double res      = signed_x;
332  *   if (signed_x < 0)
333  *       res += 4294967296. ;
334  *   return (float) res;
335  */
336 static void rewrite_unsigned_float_Conv(ir_node *node)
337 {
338         ir_graph *irg         = get_irn_irg(node);
339         dbg_info *dbgi        = get_irn_dbg_info(node);
340         ir_node  *lower_block = get_nodes_block(node);
341
342         part_block(node);
343
344         {
345                 ir_node   *block       = get_nodes_block(node);
346                 ir_node   *unsigned_x  = get_Conv_op(node);
347                 ir_mode   *mode_u      = get_irn_mode(unsigned_x);
348                 ir_mode   *mode_s      = find_signed_mode(mode_u);
349                 ir_mode   *mode_d      = mode_D;
350                 ir_node   *signed_x    = new_rd_Conv(dbgi, block, unsigned_x, mode_s);
351                 ir_node   *res         = new_rd_Conv(dbgi, block, signed_x, mode_d);
352                 ir_node   *zero        = new_r_Const(irg, get_mode_null(mode_s));
353                 ir_node   *cmp         = new_rd_Cmp(dbgi, block, signed_x, zero,
354                                                     ir_relation_less);
355                 ir_node   *cond        = new_rd_Cond(dbgi, block, cmp);
356                 ir_node   *proj_true   = new_r_Proj(cond, mode_X, pn_Cond_true);
357                 ir_node   *proj_false  = new_r_Proj(cond, mode_X, pn_Cond_false);
358                 ir_node   *in_true[1]  = { proj_true };
359                 ir_node   *in_false[1] = { proj_false };
360                 ir_node   *true_block  = new_r_Block(irg, ARRAY_SIZE(in_true), in_true);
361                 ir_node   *false_block = new_r_Block(irg, ARRAY_SIZE(in_false),in_false);
362                 ir_node   *true_jmp    = new_r_Jmp(true_block);
363                 ir_node   *false_jmp   = new_r_Jmp(false_block);
364                 ir_tarval *correction  = new_tarval_from_double(4294967296., mode_d);
365                 ir_node   *c_const     = new_r_Const(irg, correction);
366                 ir_node   *fadd        = new_rd_Add(dbgi, true_block, res, c_const,
367                                                    mode_d);
368
369                 ir_node  *lower_in[2] = { true_jmp, false_jmp };
370                 ir_node  *phi_in[2]   = { fadd, res };
371                 ir_mode  *dest_mode   = get_irn_mode(node);
372                 ir_node  *phi;
373                 ir_node  *res_conv;
374
375                 set_irn_in(lower_block, ARRAY_SIZE(lower_in), lower_in);
376                 phi = new_r_Phi(lower_block, ARRAY_SIZE(phi_in), phi_in, mode_d);
377                 assert(get_Block_phis(lower_block) == NULL);
378                 set_Block_phis(lower_block, phi);
379                 set_Phi_next(phi, NULL);
380
381                 res_conv = new_rd_Conv(dbgi, lower_block, phi, dest_mode);
382
383                 exchange(node, res_conv);
384         }
385 }
386
387 static int sparc_rewrite_Conv(ir_node *node, void *ctx)
388 {
389         ir_mode *to_mode   = get_irn_mode(node);
390         ir_node *op        = get_Conv_op(node);
391         ir_mode *from_mode = get_irn_mode(op);
392         (void) ctx;
393
394         if (mode_is_float(to_mode) && mode_is_int(from_mode)
395                         && get_mode_size_bits(from_mode) == 32
396                         && !mode_is_signed(from_mode)) {
397                 rewrite_unsigned_float_Conv(node);
398                 return 1;
399         }
400
401         return 0;
402 }
403
404 static void sparc_handle_intrinsics(void)
405 {
406         ir_type *tp, *int_tp, *uint_tp;
407         i_record records[8];
408         size_t n_records = 0;
409
410         runtime_rt rt_iMod, rt_uMod;
411
412 #define ID(x) new_id_from_chars(x, sizeof(x)-1)
413
414         int_tp  = new_type_primitive(mode_Is);
415         uint_tp = new_type_primitive(mode_Iu);
416
417         /* we need to rewrite some forms of int->float conversions */
418         {
419                 i_instr_record *map_Conv = &records[n_records++].i_instr;
420
421                 map_Conv->kind     = INTRINSIC_INSTR;
422                 map_Conv->op       = op_Conv;
423                 map_Conv->i_mapper = sparc_rewrite_Conv;
424         }
425         /* SPARC has no signed mod instruction ... */
426         {
427                 i_instr_record *map_Mod = &records[n_records++].i_instr;
428
429                 tp = new_type_method(2, 1);
430                 set_method_param_type(tp, 0, int_tp);
431                 set_method_param_type(tp, 1, int_tp);
432                 set_method_res_type(tp, 0, int_tp);
433
434                 rt_iMod.ent             = new_entity(get_glob_type(), ID(".rem"), tp);
435                 set_entity_ld_ident(rt_iMod.ent, ID(".rem"));
436                 rt_iMod.mode            = mode_T;
437                 rt_iMod.res_mode        = mode_Is;
438                 rt_iMod.mem_proj_nr     = pn_Mod_M;
439                 rt_iMod.regular_proj_nr = pn_Mod_X_regular;
440                 rt_iMod.exc_proj_nr     = pn_Mod_X_except;
441                 rt_iMod.exc_mem_proj_nr = pn_Mod_M;
442                 rt_iMod.res_proj_nr     = pn_Mod_res;
443
444                 set_entity_visibility(rt_iMod.ent, ir_visibility_external);
445
446                 map_Mod->kind     = INTRINSIC_INSTR;
447                 map_Mod->op       = op_Mod;
448                 map_Mod->i_mapper = (i_mapper_func)i_mapper_RuntimeCall;
449                 map_Mod->ctx      = &rt_iMod;
450         }
451         /* ... nor an unsigned mod. */
452         {
453                 i_instr_record *map_Mod = &records[n_records++].i_instr;
454
455                 tp = new_type_method(2, 1);
456                 set_method_param_type(tp, 0, uint_tp);
457                 set_method_param_type(tp, 1, uint_tp);
458                 set_method_res_type(tp, 0, uint_tp);
459
460                 rt_uMod.ent             = new_entity(get_glob_type(), ID(".urem"), tp);
461                 set_entity_ld_ident(rt_uMod.ent, ID(".urem"));
462                 rt_uMod.mode            = mode_T;
463                 rt_uMod.res_mode        = mode_Iu;
464                 rt_uMod.mem_proj_nr     = pn_Mod_M;
465                 rt_uMod.regular_proj_nr = pn_Mod_X_regular;
466                 rt_uMod.exc_proj_nr     = pn_Mod_X_except;
467                 rt_uMod.exc_mem_proj_nr = pn_Mod_M;
468                 rt_uMod.res_proj_nr     = pn_Mod_res;
469
470                 set_entity_visibility(rt_uMod.ent, ir_visibility_external);
471
472                 map_Mod->kind     = INTRINSIC_INSTR;
473                 map_Mod->op       = op_Mod;
474                 map_Mod->i_mapper = (i_mapper_func)i_mapper_RuntimeCall;
475                 map_Mod->ctx      = &rt_uMod;
476         }
477
478         assert(n_records < ARRAY_SIZE(records));
479         lower_intrinsics(records, n_records, /*part_block_used=*/ true);
480 }
481
482 /**
483  * Initializes the backend ISA
484  */
485 static arch_env_t *sparc_init(FILE *outfile)
486 {
487         sparc_isa_t *isa = XMALLOC(sparc_isa_t);
488         *isa = sparc_isa_template;
489         isa->constants = pmap_create();
490
491         be_emit_init(outfile);
492
493         sparc_register_init();
494         sparc_create_opcodes(&sparc_irn_ops);
495         sparc_handle_intrinsics();
496
497         return &isa->base;
498 }
499
500 /**
501  * Closes the output file and frees the ISA structure.
502  */
503 static void sparc_done(void *self)
504 {
505         sparc_isa_t *isa = (sparc_isa_t*)self;
506
507         /* emit now all global declarations */
508         be_gas_emit_decls(isa->base.main_env);
509
510         pmap_destroy(isa->constants);
511         be_emit_exit();
512         free(isa);
513 }
514
515
516 /**
517  * Get the register class which shall be used to store a value of a given mode.
518  * @param self The this pointer.
519  * @param mode The mode in question.
520  * @return A register class which can hold values of the given mode.
521  */
522 static const arch_register_class_t *sparc_get_reg_class_for_mode(const ir_mode *mode)
523 {
524         if (mode_is_float(mode))
525                 return &sparc_reg_classes[CLASS_sparc_fp];
526         else
527                 return &sparc_reg_classes[CLASS_sparc_gp];
528 }
529
530 /**
531  * Returns the necessary byte alignment for storing a register of given class.
532  */
533 static int sparc_get_reg_class_alignment(const arch_register_class_t *cls)
534 {
535         ir_mode *mode = arch_register_class_mode(cls);
536         return get_mode_size_bytes(mode);
537 }
538
539 static ir_node *sparc_create_set(ir_node *cond)
540 {
541         return ir_create_cond_set(cond, mode_Iu);
542 }
543
544 static void sparc_lower_for_target(void)
545 {
546         size_t i, n_irgs = get_irp_n_irgs();
547         lower_mode_b_config_t lower_mode_b_config = {
548                 mode_Iu,
549                 sparc_create_set,
550                 0,
551         };
552         lower_params_t params = {
553                 4,                                     /* def_ptr_alignment */
554                 LF_COMPOUND_RETURN | LF_RETURN_HIDDEN, /* flags */
555                 ADD_HIDDEN_ALWAYS_IN_FRONT,            /* hidden_params */
556                 NULL,                                  /* find pointer type */
557                 NULL,                                  /* ret_compound_in_regs */
558         };
559         lower_calls_with_compounds(&params);
560
561         sparc_lower_64bit();
562
563         for (i = 0; i < n_irgs; ++i) {
564                 ir_graph *irg = get_irp_irg(i);
565                 ir_lower_mode_b(irg, &lower_mode_b_config);
566                 lower_switch(irg, 4, 256, false);
567         }
568 }
569
570 static int sparc_is_mux_allowed(ir_node *sel, ir_node *mux_false,
571                                 ir_node *mux_true)
572 {
573         ir_graph *irg  = get_irn_irg(sel);
574         ir_mode  *mode = get_irn_mode(mux_true);
575
576         if (get_irg_phase_state(irg) == phase_low)
577                 return false;
578
579         if (!mode_is_int(mode) && !mode_is_reference(mode) && mode != mode_b)
580                 return false;
581         if (is_Const(mux_true) && is_Const_one(mux_true) &&
582                         is_Const(mux_false) && is_Const_null(mux_false))
583                 return true;
584         return false;
585 }
586
587 /**
588  * Returns the libFirm configuration parameter for this backend.
589  */
590 static const backend_params *sparc_get_backend_params(void)
591 {
592         static const ir_settings_arch_dep_t arch_dep = {
593                 1,     /* also_use_subs */
594                 1,     /* maximum_shifts */
595                 31,    /* highest_shift_amount */
596                 NULL,  /* evaluate_cost_func */
597                 1,     /* allow mulhs */
598                 1,     /* allow mulhu */
599                 32,    /* max_bits_for_mulh */
600         };
601         static backend_params p = {
602                 0,     /* no inline assembly */
603                 0,     /* no support for RotL nodes */
604                 1,     /* big endian */
605                 &arch_dep,              /* will be set later */
606                 sparc_is_mux_allowed,   /* parameter for if conversion */
607                 32,    /* machine size */
608                 NULL,  /* float arithmetic mode */
609                 128,   /* size of long double */
610                 0,     /* no trampoline support: size 0 */
611                 0,     /* no trampoline support: align 0 */
612                 NULL,  /* no trampoline support: no trampoline builder */
613                 4      /* alignment of stack parameter: typically 4 (32bit) or 8 (64bit) */
614         };
615         return &p;
616 }
617
618 static ir_graph **sparc_get_backend_irg_list(const void *self,
619                                              ir_graph ***irgs)
620 {
621         (void) self;
622         (void) irgs;
623         return NULL;
624 }
625
626 static asm_constraint_flags_t sparc_parse_asm_constraint(const char **c)
627 {
628         (void) c;
629         return ASM_CONSTRAINT_FLAG_INVALID;
630 }
631
632 static int sparc_is_valid_clobber(const char *clobber)
633 {
634         (void) clobber;
635         return 0;
636 }
637
638 const arch_isa_if_t sparc_isa_if = {
639         sparc_init,
640         sparc_lower_for_target,
641         sparc_done,
642         NULL,                /* handle intrinsics */
643         sparc_get_reg_class_for_mode,
644         NULL,
645         sparc_get_reg_class_alignment,
646         sparc_get_backend_params,
647         sparc_get_backend_irg_list,
648         NULL,                    /* mark remat */
649         sparc_parse_asm_constraint,
650         sparc_is_valid_clobber,
651
652         sparc_init_graph,
653         NULL, /* get_pic_base */
654         NULL, /* before_abi */
655         sparc_prepare_graph,
656         sparc_before_ra,
657         sparc_after_ra,
658         sparc_finish,
659         sparc_emit_routine,
660         NULL, /* register_saved_by */
661 };
662
663 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_sparc)
664 void be_init_arch_sparc(void)
665 {
666         be_register_isa_if("sparc", &sparc_isa_if);
667         FIRM_DBG_REGISTER(dbg, "firm.be.sparc.cg");
668         sparc_init_transform();
669         sparc_init_emitter();
670 }