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