54ceacd11cc8127075154f91ad431bef9dbee25f
[libfirm] / ir / be / sparc / sparc_emitter.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   emit assembler for a backend graph
23  * @version $Id$
24  */
25 #include "config.h"
26
27 #include <limits.h>
28
29 #include "xmalloc.h"
30 #include "tv.h"
31 #include "iredges.h"
32 #include "debug.h"
33 #include "irgwalk.h"
34 #include "irprintf.h"
35 #include "irop_t.h"
36 #include "irargs_t.h"
37 #include "irprog.h"
38 #include "irargs_t.h"
39 #include "error.h"
40 #include "raw_bitset.h"
41 #include "dbginfo.h"
42
43 #include "../besched.h"
44 #include "../beblocksched.h"
45 #include "../beirg.h"
46 #include "../begnuas.h"
47 #include "../be_dbgout.h"
48 #include "../benode.h"
49
50 #include "sparc_emitter.h"
51 #include "gen_sparc_emitter.h"
52 #include "sparc_nodes_attr.h"
53 #include "sparc_new_nodes.h"
54 #include "gen_sparc_regalloc_if.h"
55
56
57 #define SNPRINTF_BUF_LEN 128
58 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
59
60 /**
61  * attribute of SAVE node which follows immediatelly after the START node
62  * we need this to correct all offsets since SPARC expects
63  * some reserved stack space after the stackpointer
64  */
65 const sparc_save_attr_t *save_attr;
66
67 /**
68  * Returns the register at in position pos.
69  */
70 static const arch_register_t *get_in_reg(const ir_node *node, int pos)
71 {
72         ir_node                *op;
73         const arch_register_t  *reg = NULL;
74
75         assert(get_irn_arity(node) > pos && "Invalid IN position");
76
77         /* The out register of the operator at position pos is the
78            in register we need. */
79         op = get_irn_n(node, pos);
80
81         reg = arch_get_irn_register(op);
82
83         assert(reg && "no in register found");
84         return reg;
85 }
86
87 /**
88  * Returns the register at out position pos.
89  */
90 static const arch_register_t *get_out_reg(const ir_node *node, int pos)
91 {
92         ir_node                *proj;
93         const arch_register_t  *reg = NULL;
94
95         /* 1st case: irn is not of mode_T, so it has only                 */
96         /*           one OUT register -> good                             */
97         /* 2nd case: irn is of mode_T -> collect all Projs and ask the    */
98         /*           Proj with the corresponding projnum for the register */
99
100         if (get_irn_mode(node) != mode_T) {
101                 reg = arch_get_irn_register(node);
102         } else if (is_sparc_irn(node)) {
103                 reg = arch_irn_get_register(node, pos);
104         } else {
105                 const ir_edge_t *edge;
106
107                 foreach_out_edge(node, edge) {
108                         proj = get_edge_src_irn(edge);
109                         assert(is_Proj(proj) && "non-Proj from mode_T node");
110                         if (get_Proj_proj(proj) == pos) {
111                                 reg = arch_get_irn_register(proj);
112                                 break;
113                         }
114                 }
115         }
116
117         assert(reg && "no out register found");
118         return reg;
119 }
120
121 void sparc_emit_immediate(const ir_node *node)
122 {
123         int const val = get_sparc_attr_const(node)->immediate_value;
124         assert(-4096 <= val && val < 4096);
125         be_emit_irprintf("%d", val);
126 }
127
128 void sparc_emit_source_register(const ir_node *node, int pos)
129 {
130         const arch_register_t *reg = get_in_reg(node, pos);
131         be_emit_char('%');
132         be_emit_string(arch_register_get_name(reg));
133 }
134
135 void sparc_emit_dest_register(const ir_node *node, int pos)
136 {
137         const arch_register_t *reg = get_out_reg(node, pos);
138         be_emit_char('%');
139         be_emit_string(arch_register_get_name(reg));
140 }
141
142 /**
143  * Emits either a imm or register depending on arity of node
144  * @param node
145  * @param register no (-1 if no register)
146  */
147 void sparc_emit_reg_or_imm(const ir_node *node, int pos)
148 {
149         if (get_irn_arity(node) > pos) {
150                 // we have reg input
151                 sparc_emit_source_register(node, pos);
152         } else {
153                 // we have a imm input
154                 sparc_emit_immediate(node);
155         }
156 }
157
158 /**
159  * emit SP offset
160  */
161 void sparc_emit_offset(const ir_node *node)
162 {
163         const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
164         assert(attr->base.is_load_store);
165
166         if (attr->offset != 0) {
167                 be_emit_irprintf("%+ld", attr->offset);
168         }
169 }
170
171
172 /**
173  *  Emit load mode char
174  */
175 void sparc_emit_load_mode(const ir_node *node)
176 {
177         const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
178         ir_mode *mode      = attr->load_store_mode;
179         int      bits      = get_mode_size_bits(mode);
180         bool     is_signed = mode_is_signed(mode);
181
182         if (bits == 16) {
183                 be_emit_string(is_signed ? "sh" : "uh");
184         } else if (bits == 8) {
185                 be_emit_string(is_signed ? "sb" : "ub");
186         } else if (bits == 64) {
187                 be_emit_string("d");
188         } else {
189                 assert(bits == 32);
190         }
191 }
192
193 /**
194  * Emit store mode char
195  */
196 void sparc_emit_store_mode(const ir_node *node)
197 {
198         const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
199         ir_mode *mode      = attr->load_store_mode;
200         int      bits      = get_mode_size_bits(mode);
201
202         if (bits == 16) {
203                 be_emit_string("h");
204         } else if (bits == 8) {
205                 be_emit_string("b");
206         } else if (bits == 64) {
207                 be_emit_string("d");
208         } else {
209                 assert(bits == 32);
210         }
211 }
212
213 /**
214  * emit integer signed/unsigned prefix char
215  */
216 void sparc_emit_mode_sign_prefix(const ir_node *node)
217 {
218         ir_mode *mode      = get_irn_mode(node);
219         bool     is_signed = mode_is_signed(mode);
220         be_emit_string(is_signed ? "s" : "u");
221 }
222
223 /**
224  * emit FP load mode char
225  */
226 void sparc_emit_fp_load_mode(const ir_node *node)
227 {
228         const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
229         ir_mode *mode      = attr->load_store_mode;
230         int      bits      = get_mode_size_bits(mode);
231
232         assert(mode_is_float(mode));
233
234         if (bits == 32) {
235                 be_emit_string("f");
236         } else if (bits == 64) {
237                 be_emit_string("df");
238         } else {
239                 panic("FP load mode > 64bits not implemented yet");
240         }
241 }
242
243 /**
244  * emit FP store mode char
245  */
246 void sparc_emit_fp_store_mode(const ir_node *node)
247 {
248         const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
249         ir_mode *mode      = attr->load_store_mode;
250         int      bits      = get_mode_size_bits(mode);
251
252         assert(mode_is_float(mode));
253
254         if (bits == 32) {
255                 be_emit_string("f");
256         } else if (bits == 64) {
257                 be_emit_string("df");
258         } else {
259                 panic("FP store mode > 64bits not implemented yet");
260         }
261 }
262
263 /**
264  * emits the FP mode suffix char
265  */
266 void sparc_emit_fp_mode_suffix(const ir_node *node)
267 {
268         ir_mode *mode      = get_irn_mode(node);
269         int      bits      = get_mode_size_bits(mode);
270
271         assert(mode_is_float(mode));
272
273         if (bits == 32) {
274                 be_emit_string("s");
275         } else if (bits == 64) {
276                 be_emit_string("d");
277         } else {
278                 panic("FP mode > 64bits not implemented yet");
279         }
280 }
281
282 /**
283  * Returns the target label for a control flow node.
284  */
285 static void sparc_emit_cfop_target(const ir_node *node)
286 {
287         ir_node *block = get_irn_link(node);
288         be_gas_emit_block_name(block);
289 }
290
291 /**
292  * Emit single entity
293  */
294 static void sparc_emit_entity(ir_entity *entity)
295 {
296         be_gas_emit_entity(entity);
297 }
298
299 /**
300  * Emits code for stack space management
301  */
302 static void emit_be_IncSP(const ir_node *irn)
303 {
304         int offs = -be_get_IncSP_offset(irn);
305
306         if (offs == 0)
307                         return;
308
309         /* SPARC stack grows downwards */
310         if (offs < 0) {
311                 be_emit_cstring("\tsub ");
312                 offs = -offs;
313         } else {
314                 be_emit_cstring("\tadd ");
315         }
316
317         sparc_emit_source_register(irn, 0);
318         be_emit_irprintf(", %d", offs);
319         be_emit_cstring(", ");
320         sparc_emit_dest_register(irn, 0);
321         be_emit_finish_line_gas(irn);
322 }
323
324 /**
325  * emits code for save instruction with min. required stack space
326  */
327 static void emit_sparc_Save(const ir_node *irn)
328 {
329         save_attr = get_sparc_save_attr_const(irn);
330         be_emit_cstring("\tsave ");
331         sparc_emit_source_register(irn, 0);
332         be_emit_irprintf(", %d, ", -save_attr->initial_stacksize);
333         sparc_emit_dest_register(irn, 0);
334         be_emit_finish_line_gas(irn);
335 }
336
337 /**
338  * emits code to load hi 22 bit of a constant
339  */
340 static void emit_sparc_HiImm(const ir_node *irn)
341 {
342         const sparc_attr_t *attr = get_sparc_attr_const(irn);
343         be_emit_cstring("\tsethi ");
344         be_emit_irprintf("%%hi(%d), ", attr->immediate_value);
345         sparc_emit_dest_register(irn, 0);
346         be_emit_finish_line_gas(irn);
347 }
348
349 /**
350  * emits code to load lo 10bits of a constant
351  */
352 static void emit_sparc_LoImm(const ir_node *irn)
353 {
354         const sparc_attr_t *attr = get_sparc_attr_const(irn);
355         be_emit_cstring("\tor ");
356         sparc_emit_source_register(irn, 0);
357         be_emit_irprintf(", %%lo(%d), ", attr->immediate_value);
358         sparc_emit_dest_register(irn, 0);
359         be_emit_finish_line_gas(irn);
360 }
361
362 /**
363  * emit code for div with the correct sign prefix
364  */
365 static void emit_sparc_Div(const ir_node *irn)
366 {
367         be_emit_cstring("\t");
368         sparc_emit_mode_sign_prefix(irn);
369         be_emit_cstring("div ");
370
371         sparc_emit_source_register(irn, 0);
372         be_emit_cstring(", ");
373         sparc_emit_reg_or_imm(irn, 1);
374         be_emit_cstring(", ");
375         sparc_emit_dest_register(irn, 0);
376         be_emit_finish_line_gas(irn);
377 }
378
379 /**
380  * emit code for mul with the correct sign prefix
381  */
382 static void emit_sparc_Mul(const ir_node *irn)
383 {
384         be_emit_cstring("\t");
385         sparc_emit_mode_sign_prefix(irn);
386         be_emit_cstring("mul ");
387
388         sparc_emit_source_register(irn, 0);
389         be_emit_cstring(", ");
390         sparc_emit_reg_or_imm(irn, 1);
391         be_emit_cstring(", ");
392         sparc_emit_dest_register(irn, 0);
393         be_emit_finish_line_gas(irn);
394 }
395
396 /**
397  * emits code for mulh
398  */
399 static void emit_sparc_Mulh(const ir_node *irn)
400 {
401         be_emit_cstring("\t");
402         sparc_emit_mode_sign_prefix(irn);
403         be_emit_cstring("mul ");
404
405         sparc_emit_source_register(irn, 0);
406         be_emit_cstring(", ");
407         sparc_emit_reg_or_imm(irn, 1);
408         be_emit_cstring(", ");
409         sparc_emit_dest_register(irn, 0);
410         be_emit_finish_line_gas(irn);
411
412         // our result is in the y register now
413         // we just copy it to the assigned target reg
414         be_emit_cstring("\tmov ");
415         be_emit_char('%');
416         be_emit_string(arch_register_get_name(&sparc_flags_regs[REG_Y]));
417         be_emit_cstring(", ");
418         sparc_emit_dest_register(irn, 0);
419         be_emit_finish_line_gas(irn);
420 }
421
422 /**
423  * Emits code for return node
424  */
425 static void emit_be_Return(const ir_node *irn)
426 {
427         be_emit_cstring("\tret");
428         //be_emit_cstring("\tjmp %i7+8");
429         be_emit_finish_line_gas(irn);
430         be_emit_cstring("\trestore");
431         be_emit_finish_line_gas(irn);
432 }
433
434 /**
435  * Emits code for Call node
436  */
437 static void emit_be_Call(const ir_node *irn)
438 {
439         ir_entity *entity = be_Call_get_entity(irn);
440
441         if (entity != NULL) {
442                 be_emit_cstring("\tcall ");
443             sparc_emit_entity(entity);
444                 be_emit_cstring(", 0");
445                 be_emit_finish_line_gas(irn);
446                 be_emit_cstring("\tnop");
447                 be_emit_pad_comment();
448                 be_emit_cstring("/* TODO: use delay slot */\n");
449         } else {
450                 be_emit_cstring("\tnop\n");
451                 be_emit_pad_comment();
452                 be_emit_cstring("/* TODO: Entity == NULL */\n");
453                 be_emit_finish_line_gas(irn);
454         }
455 }
456
457 /**
458  * Emit code for Perm node
459  */
460 static void emit_be_Perm(const ir_node *irn)
461 {
462         be_emit_cstring("\txor ");
463         sparc_emit_source_register(irn, 1);
464         be_emit_cstring(", ");
465         sparc_emit_source_register(irn, 0);
466         be_emit_cstring(", ");
467         sparc_emit_source_register(irn, 0);
468         be_emit_finish_line_gas(NULL);
469
470         be_emit_cstring("\txor ");
471         sparc_emit_source_register(irn, 1);
472         be_emit_cstring(", ");
473         sparc_emit_source_register(irn, 0);
474         be_emit_cstring(", ");
475         sparc_emit_source_register(irn, 1);
476         be_emit_finish_line_gas(NULL);
477
478         be_emit_cstring("\txor ");
479         sparc_emit_source_register(irn, 1);
480         be_emit_cstring(", ");
481         sparc_emit_source_register(irn, 0);
482         be_emit_cstring(", ");
483         sparc_emit_source_register(irn, 0);
484         be_emit_finish_line_gas(irn);
485 }
486
487 /**
488  * TODO: not really tested but seems to work with memperm_arity == 1
489  */
490 static void emit_be_MemPerm(const ir_node *node)
491 {
492         int i;
493         int memperm_arity;
494         int sp_change = 0;
495
496         /* TODO: this implementation is slower than necessary.
497            The longterm goal is however to avoid the memperm node completely */
498
499         memperm_arity = be_get_MemPerm_entity_arity(node);
500         // we use our local registers - so this is limited to 8 inputs !
501         if (memperm_arity > 8)
502                 panic("memperm with more than 8 inputs not supported yet");
503
504         for (i = 0; i < memperm_arity; ++i) {
505                 int offset;
506                 ir_entity *entity = be_get_MemPerm_in_entity(node, i);
507
508                 /* spill register */
509                 sp_change += 4;
510                 be_emit_irprintf("\tst %%l%d, [%%sp-%d]", i, sp_change);
511                 be_emit_finish_line_gas(node);
512
513                 /* load from entity */
514                 offset = get_entity_offset(entity) + sp_change;
515                 be_emit_irprintf("\tld [%%sp+%d], %%l%d", offset, i);
516                 be_emit_finish_line_gas(node);
517         }
518
519         for (i = memperm_arity-1; i >= 0; --i) {
520                 int        offset;
521                 ir_entity *entity = be_get_MemPerm_out_entity(node, i);
522
523                 /* store to new entity */
524                 offset = get_entity_offset(entity) + sp_change;
525                 be_emit_irprintf("\tst %%l%d, [%%sp+%d]", i, offset);
526                 be_emit_finish_line_gas(node);
527                 /* restore register */
528                 be_emit_irprintf("\tld [%%sp-%d], %%l%d", sp_change, i);
529                 sp_change -= 4;
530                 be_emit_finish_line_gas(node);
531         }
532         assert(sp_change == 0);
533 }
534
535 /**
536  * Emit a SymConst.
537  */
538 static void emit_sparc_SymConst(const ir_node *irn)
539 {
540         const sparc_symconst_attr_t *attr = get_sparc_symconst_attr_const(irn);
541
542         //sethi %hi(const32),%reg
543         //or    %reg,%lo(const32),%reg
544
545         be_emit_cstring("\tsethi %hi(");
546         be_gas_emit_entity(attr->entity);
547         be_emit_cstring("), ");
548         sparc_emit_dest_register(irn, 0);
549         be_emit_cstring("\n ");
550
551         // TODO: could be combined with the following load/store instruction
552         be_emit_cstring("\tor ");
553         sparc_emit_dest_register(irn, 0);
554         be_emit_cstring(", %lo(");
555         be_gas_emit_entity(attr->entity);
556         be_emit_cstring("), ");
557         sparc_emit_dest_register(irn, 0);
558         be_emit_finish_line_gas(irn);
559 }
560
561 /**
562  * Emits code for FrameAddr fix
563  */
564 static void emit_sparc_FrameAddr(const ir_node *irn)
565 {
566         const sparc_symconst_attr_t *attr = get_irn_generic_attr_const(irn);
567
568         // no need to fix offset as we are adressing via the framepointer
569         if (attr->fp_offset >= 0) {
570                 be_emit_cstring("\tadd ");
571                 sparc_emit_source_register(irn, 0);
572                 be_emit_cstring(", ");
573                 be_emit_irprintf("%ld", attr->fp_offset + save_attr->initial_stacksize);
574         } else {
575                 be_emit_cstring("\tsub ");
576                 sparc_emit_source_register(irn, 0);
577                 be_emit_cstring(", ");
578                 be_emit_irprintf("%ld", -attr->fp_offset);
579         }
580
581         be_emit_cstring(", ");
582         sparc_emit_dest_register(irn, 0);
583         be_emit_finish_line_gas(irn);
584 }
585
586
587 /**
588  * Emits code for Branch
589  */
590 static void emit_sparc_BXX(const ir_node *irn)
591 {
592         const ir_edge_t *edge;
593         const ir_node *proj_true  = NULL;
594         const ir_node *proj_false = NULL;
595         const ir_node *block;
596         const ir_node *next_block;
597         ir_node *op1 = get_irn_n(irn, 0);
598         const char *suffix;
599         int proj_num = get_sparc_jmp_cond_proj_num(irn);
600         const sparc_cmp_attr_t *cmp_attr = get_irn_generic_attr_const(op1);
601         // bool is_signed = !cmp_attr->is_unsigned;
602
603         assert(is_sparc_Cmp(op1) || is_sparc_Tst(op1));
604
605         foreach_out_edge(irn, edge) {
606                 ir_node *proj = get_edge_src_irn(edge);
607                 long nr = get_Proj_proj(proj);
608                 if (nr == pn_Cond_true) {
609                         proj_true = proj;
610                 } else {
611                         proj_false = proj;
612                 }
613         }
614
615         if (cmp_attr->ins_permuted) {
616                 proj_num = get_mirrored_pnc(proj_num);
617         }
618
619         /* for now, the code works for scheduled and non-schedules blocks */
620         block = get_nodes_block(irn);
621
622         /* we have a block schedule */
623         next_block = get_irn_link(block);
624
625         assert(proj_num != pn_Cmp_False);
626         assert(proj_num != pn_Cmp_True);
627
628         if (get_irn_link(proj_true) == next_block) {
629                 /* exchange both proj's so the second one can be omitted */
630                 const ir_node *t = proj_true;
631
632                 proj_true  = proj_false;
633                 proj_false = t;
634                 proj_num   = get_negated_pnc(proj_num, mode_Iu);
635         }
636
637
638         switch (proj_num) {
639                 case pn_Cmp_Eq:  suffix = "e"; break;
640                 case pn_Cmp_Lt:  suffix = "l"; break;
641                 case pn_Cmp_Le:  suffix = "le"; break;
642                 case pn_Cmp_Gt:  suffix = "g"; break;
643                 case pn_Cmp_Ge:  suffix = "ge"; break;
644                 case pn_Cmp_Lg:  suffix = "ne"; break;
645                 case pn_Cmp_Leg: suffix = "a"; break;
646                 default: panic("Cmp has unsupported pnc");
647         }
648
649         /* emit the true proj */
650         be_emit_irprintf("\tb%s ", suffix);
651         sparc_emit_cfop_target(proj_true);
652         be_emit_finish_line_gas(proj_true);
653
654         be_emit_cstring("\tnop");
655         be_emit_pad_comment();
656         be_emit_cstring("/* TODO: use delay slot */\n");
657
658         if (get_irn_link(proj_false) == next_block) {
659                 be_emit_cstring("\t/* false-fallthrough to ");
660                 sparc_emit_cfop_target(proj_false);
661                 be_emit_cstring(" */");
662                 be_emit_finish_line_gas(proj_false);
663         } else {
664                 be_emit_cstring("\tba ");
665                 sparc_emit_cfop_target(proj_false);
666                 be_emit_finish_line_gas(proj_false);
667                 be_emit_cstring("\tnop\t\t/* TODO: use delay slot */\n");
668                 be_emit_finish_line_gas(proj_false);
669         }
670 }
671
672 /**
673  * emit Jmp (which actually is a branch always (ba) instruction)
674  */
675 static void emit_sparc_Ba(const ir_node *node)
676 {
677         ir_node *block, *next_block;
678
679         /* for now, the code works for scheduled and non-schedules blocks */
680         block = get_nodes_block(node);
681
682         /* we have a block schedule */
683         next_block = get_irn_link(block);
684         if (get_irn_link(node) != next_block) {
685                 be_emit_cstring("\tba ");
686                 sparc_emit_cfop_target(node);
687                 be_emit_finish_line_gas(node);
688                 be_emit_cstring("\tnop\t\t/* TODO: use delay slot */\n");
689         } else {
690                 be_emit_cstring("\t/* fallthrough to ");
691                 sparc_emit_cfop_target(node);
692                 be_emit_cstring(" */");
693         }
694         be_emit_finish_line_gas(node);
695 }
696
697 /**
698  * emit copy node
699  */
700 static void emit_be_Copy(const ir_node *irn)
701 {
702         ir_mode *mode = get_irn_mode(irn);
703
704         if (get_in_reg(irn, 0) == get_out_reg(irn, 0)) {
705                 /* omitted Copy */
706                 return;
707         }
708
709         if (mode_is_float(mode)) {
710                 panic("emit_be_Copy: move not supported for FP");
711         } else if (mode_is_data(mode)) {
712                 be_emit_cstring("\tmov ");
713                 sparc_emit_source_register(irn, 0);
714                 be_emit_cstring(", ");
715                 sparc_emit_dest_register(irn, 0);
716                 be_emit_finish_line_gas(irn);
717         } else {
718                 panic("emit_be_Copy: move not supported for this mode");
719         }
720 }
721
722
723 /**
724  * dummy emitter for ignored nodes
725  */
726 static void emit_nothing(const ir_node *irn)
727 {
728         (void) irn;
729 }
730
731
732
733 /**
734  * type of emitter function
735  */
736 typedef void (*emit_func) (const ir_node *);
737
738 /**
739  * Set a node emitter. Make it a bit more type safe.
740  */
741 static inline void set_emitter(ir_op *op, emit_func sparc_emit_node)
742 {
743         op->ops.generic = (op_func)sparc_emit_node;
744 }
745
746 /**
747  * Enters the emitter functions for handled nodes into the generic
748  * pointer of an opcode.
749  */
750 static void sparc_register_emitters(void)
751 {
752         /* first clear the generic function pointer for all ops */
753         clear_irp_opcodes_generic_func();
754         /* register all emitter functions defined in spec */
755         sparc_register_spec_emitters();
756
757         /* custom emitter */
758         set_emitter(op_be_Call,         emit_be_Call);
759         set_emitter(op_be_Copy,         emit_be_Copy);
760         set_emitter(op_be_CopyKeep,     emit_be_Copy);
761         set_emitter(op_be_IncSP,        emit_be_IncSP);
762         set_emitter(op_be_MemPerm,      emit_be_MemPerm);
763         set_emitter(op_be_Perm,         emit_be_Perm);
764         set_emitter(op_be_Return,       emit_be_Return);
765         set_emitter(op_sparc_BXX,       emit_sparc_BXX);
766         set_emitter(op_sparc_Div,       emit_sparc_Div);
767         set_emitter(op_sparc_FrameAddr, emit_sparc_FrameAddr);
768         set_emitter(op_sparc_HiImm,     emit_sparc_HiImm);
769         set_emitter(op_sparc_Ba,        emit_sparc_Ba);
770         set_emitter(op_sparc_LoImm,     emit_sparc_LoImm);
771         set_emitter(op_sparc_Mul,       emit_sparc_Mul);
772         set_emitter(op_sparc_Mulh,      emit_sparc_Mulh);
773         set_emitter(op_sparc_Save,      emit_sparc_Save);
774         set_emitter(op_sparc_SymConst,  emit_sparc_SymConst);
775
776         /* no need to emit anything for the following nodes */
777         set_emitter(op_be_Barrier, emit_nothing);
778         set_emitter(op_be_Keep,    emit_nothing);
779         set_emitter(op_be_Start,   emit_nothing);
780         set_emitter(op_Phi,        emit_nothing);
781 }
782
783 /**
784  * Emits code for a node.
785  */
786 static void sparc_emit_node(const ir_node *node)
787 {
788         ir_op               *op       = get_irn_op(node);
789
790         if (op->ops.generic) {
791                 emit_func func = (emit_func) op->ops.generic;
792                 be_dbg_set_dbg_info(get_irn_dbg_info(node));
793                 (*func) (node);
794         } else {
795                 panic("Error: No emit handler for node %+F (graph %+F)\n",
796                         node, current_ir_graph);
797         }
798 }
799
800 /**
801  * Walks over the nodes in a block connected by scheduling edges
802  * and emits code for each node.
803  */
804 static void sparc_gen_block(ir_node *block, void *data)
805 {
806         ir_node *node;
807         (void) data;
808
809         if (! is_Block(block))
810                 return;
811
812         be_gas_emit_block_name(block);
813         be_emit_cstring(":\n");
814         be_emit_write_line();
815
816         sched_foreach(block, node) {
817                 sparc_emit_node(node);
818         }
819 }
820
821
822 /**
823  * Emits code for function start.
824  */
825 static void sparc_emit_func_prolog(ir_graph *irg)
826 {
827         ir_entity *ent = get_irg_entity(irg);
828         be_gas_emit_function_prolog(ent, 4);
829         be_emit_write_line();
830 }
831
832 /**
833  * Emits code for function end
834  */
835 static void sparc_emit_func_epilog(ir_graph *irg)
836 {
837         ir_entity *ent = get_irg_entity(irg);
838         const char *irg_name = get_entity_ld_name(ent);
839         be_emit_write_line();
840         be_emit_irprintf("\t.size  %s, .-%s\n", irg_name, irg_name);
841         be_emit_cstring("# -- End ");
842         be_emit_string(irg_name);
843         be_emit_cstring("\n");
844         be_emit_write_line();
845 }
846
847 /**
848  * Block-walker:
849  * TODO: Sets labels for control flow nodes (jump target).
850  * Links control predecessors to there destination blocks.
851  */
852 static void sparc_gen_labels(ir_node *block, void *env)
853 {
854         ir_node *pred;
855         int n = get_Block_n_cfgpreds(block);
856         (void) env;
857
858         for (n--; n >= 0; n--) {
859                 pred = get_Block_cfgpred(block, n);
860                 set_irn_link(pred, block); // link the pred of a block (which is a jmp)
861         }
862 }
863
864
865 /**
866  * Main driver
867  */
868 void sparc_gen_routine(const sparc_code_gen_t *cg, ir_graph *irg)
869 {
870         ir_node **blk_sched;
871         ir_node *last_block = NULL;
872         ir_entity *entity     = get_irg_entity(irg);
873         int i, n;
874         (void) cg;
875
876         be_gas_elf_type_char = '#';
877         be_gas_object_file_format = OBJECT_FILE_FORMAT_ELF_SPARC;
878
879         /* register all emitter functions */
880         sparc_register_emitters();
881         be_dbg_method_begin(entity);
882
883         /* create the block schedule. For now, we don't need it earlier. */
884         blk_sched = be_create_block_schedule(irg);
885
886         // emit function prolog
887         sparc_emit_func_prolog(irg);
888
889         // generate BLOCK labels
890         irg_block_walk_graph(irg, sparc_gen_labels, NULL, NULL);
891
892         // inject block scheduling links & emit code of each block
893         n = ARR_LEN(blk_sched);
894         for (i = 0; i < n;) {
895                 ir_node *block, *next_bl;
896
897                 block = blk_sched[i];
898                 ++i;
899                 next_bl = i < n ? blk_sched[i] : NULL;
900
901                 /* set here the link. the emitter expects to find the next block here */
902                 set_irn_link(block, next_bl);
903                 sparc_gen_block(block, last_block);
904                 last_block = block;
905         }
906
907         // emit function epilog
908         sparc_emit_func_epilog(irg);
909 }
910
911 void sparc_init_emitter(void)
912 {
913         FIRM_DBG_REGISTER(dbg, "firm.be.sparc.emit");
914 }