2 * Copyright (C) 1995-2010 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
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.
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.
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
22 * @brief emit assembler for a backend graph
40 #include "raw_bitset.h"
43 #include "../besched.h"
44 #include "../beblocksched.h"
46 #include "../begnuas.h"
47 #include "../be_dbgout.h"
48 #include "../benode.h"
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"
56 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
59 * Returns the register at in position pos.
61 static const arch_register_t *get_in_reg(const ir_node *node, int pos)
64 const arch_register_t *reg = NULL;
66 assert(get_irn_arity(node) > pos && "Invalid IN position");
68 /* The out register of the operator at position pos is the
69 in register we need. */
70 op = get_irn_n(node, pos);
72 reg = arch_get_irn_register(op);
74 assert(reg && "no in register found");
79 * Returns the register at out position pos.
81 static const arch_register_t *get_out_reg(const ir_node *node, int pos)
84 const arch_register_t *reg = NULL;
86 /* 1st case: irn is not of mode_T, so it has only */
87 /* one OUT register -> good */
88 /* 2nd case: irn is of mode_T -> collect all Projs and ask the */
89 /* Proj with the corresponding projnum for the register */
91 if (get_irn_mode(node) != mode_T) {
92 reg = arch_get_irn_register(node);
93 } else if (is_sparc_irn(node)) {
94 reg = arch_irn_get_register(node, pos);
96 const ir_edge_t *edge;
98 foreach_out_edge(node, edge) {
99 proj = get_edge_src_irn(edge);
100 assert(is_Proj(proj) && "non-Proj from mode_T node");
101 if (get_Proj_proj(proj) == pos) {
102 reg = arch_get_irn_register(proj);
108 assert(reg && "no out register found");
112 void sparc_emit_immediate(const ir_node *node)
114 int32_t value = get_sparc_attr_const(node)->immediate_value;
115 assert(-4096 <= value && value < 4096);
116 be_emit_irprintf("%d", value);
119 void sparc_emit_high_immediate(const ir_node *node)
121 uint32_t value = (uint32_t) get_sparc_attr_const(node)->immediate_value;
122 be_emit_irprintf("%%hi(0x%X)", value);
125 void sparc_emit_source_register(const ir_node *node, int pos)
127 const arch_register_t *reg = get_in_reg(node, pos);
129 be_emit_string(arch_register_get_name(reg));
132 void sparc_emit_dest_register(const ir_node *node, int pos)
134 const arch_register_t *reg = get_out_reg(node, pos);
136 be_emit_string(arch_register_get_name(reg));
140 * Emits either a imm or register depending on arity of node
142 * @param register no (-1 if no register)
144 void sparc_emit_reg_or_imm(const ir_node *node, int pos)
146 if (get_irn_arity(node) > pos) {
148 sparc_emit_source_register(node, pos);
150 // we have a imm input
151 sparc_emit_immediate(node);
155 static bool is_stack_pointer_relative(const ir_node *node)
157 const arch_register_t *sp = &sparc_gp_regs[REG_SP];
158 return (is_sparc_St(node) && get_in_reg(node, n_sparc_St_ptr) == sp)
159 || (is_sparc_Ld(node) && get_in_reg(node, n_sparc_Ld_ptr) == sp);
165 void sparc_emit_offset(const ir_node *node)
167 const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
168 long offset = attr->offset;
170 /* bad hack: the real stack stuff is behind the always-there spill
171 * space for the register window and stack */
172 if (is_stack_pointer_relative(node))
173 offset += SPARC_MIN_STACKSIZE;
175 be_emit_irprintf("%+ld", offset);
179 void sparc_emit_float_load_store_mode(const ir_node *node)
181 const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
182 ir_mode *mode = attr->load_store_mode;
183 int bits = get_mode_size_bits(mode);
185 assert(mode_is_float(mode));
189 case 64: be_emit_char('d'); return;
190 case 128: be_emit_char('q'); return;
192 panic("invalid flaot load/store mode %+F", mode);
196 * Emit load mode char
198 void sparc_emit_load_mode(const ir_node *node)
200 const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
201 ir_mode *mode = attr->load_store_mode;
202 int bits = get_mode_size_bits(mode);
203 bool is_signed = mode_is_signed(mode);
206 be_emit_string(is_signed ? "sh" : "uh");
207 } else if (bits == 8) {
208 be_emit_string(is_signed ? "sb" : "ub");
209 } else if (bits == 64) {
217 * Emit store mode char
219 void sparc_emit_store_mode(const ir_node *node)
221 const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
222 ir_mode *mode = attr->load_store_mode;
223 int bits = get_mode_size_bits(mode);
227 } else if (bits == 8) {
229 } else if (bits == 64) {
237 * emit integer signed/unsigned prefix char
239 void sparc_emit_mode_sign_prefix(const ir_node *node)
241 ir_mode *mode = get_irn_mode(node);
242 bool is_signed = mode_is_signed(mode);
243 be_emit_string(is_signed ? "s" : "u");
246 static void emit_fp_suffix(const ir_mode *mode)
248 unsigned bits = get_mode_size_bits(mode);
249 assert(mode_is_float(mode));
253 } else if (bits == 64) {
255 } else if (bits == 128) {
258 panic("invalid FP mode");
262 void sparc_emit_fp_conv_source(const ir_node *node)
264 const sparc_fp_conv_attr_t *attr = get_sparc_fp_conv_attr_const(node);
265 emit_fp_suffix(attr->src_mode);
268 void sparc_emit_fp_conv_destination(const ir_node *node)
270 const sparc_fp_conv_attr_t *attr = get_sparc_fp_conv_attr_const(node);
271 emit_fp_suffix(attr->dest_mode);
275 * emits the FP mode suffix char
277 void sparc_emit_fp_mode_suffix(const ir_node *node)
279 const sparc_fp_attr_t *attr = get_sparc_fp_attr_const(node);
280 emit_fp_suffix(attr->fp_mode);
284 * Returns the target label for a control flow node.
286 static void sparc_emit_cfop_target(const ir_node *node)
288 ir_node *block = get_irn_link(node);
289 be_gas_emit_block_name(block);
295 static void sparc_emit_entity(ir_entity *entity)
297 be_gas_emit_entity(entity);
301 * Emits code for stack space management
303 static void emit_be_IncSP(const ir_node *irn)
305 int offs = -be_get_IncSP_offset(irn);
310 /* SPARC stack grows downwards */
312 be_emit_cstring("\tsub ");
315 be_emit_cstring("\tadd ");
318 sparc_emit_source_register(irn, 0);
319 be_emit_irprintf(", %d", offs);
320 be_emit_cstring(", ");
321 sparc_emit_dest_register(irn, 0);
322 be_emit_finish_line_gas(irn);
326 * emits code for save instruction with min. required stack space
328 static void emit_sparc_Save(const ir_node *irn)
330 const sparc_save_attr_t *save_attr = get_sparc_save_attr_const(irn);
331 be_emit_cstring("\tsave ");
332 sparc_emit_source_register(irn, 0);
333 be_emit_irprintf(", %d, ", -save_attr->initial_stacksize);
334 sparc_emit_dest_register(irn, 0);
335 be_emit_finish_line_gas(irn);
339 * emits code for mulh
341 static void emit_sparc_Mulh(const ir_node *irn)
343 be_emit_cstring("\t");
344 sparc_emit_mode_sign_prefix(irn);
345 be_emit_cstring("mul ");
347 sparc_emit_source_register(irn, 0);
348 be_emit_cstring(", ");
349 sparc_emit_reg_or_imm(irn, 1);
350 be_emit_cstring(", ");
351 sparc_emit_dest_register(irn, 0);
352 be_emit_finish_line_gas(irn);
354 // our result is in the y register now
355 // we just copy it to the assigned target reg
356 be_emit_cstring("\tmov %y, ");
357 sparc_emit_dest_register(irn, 0);
358 be_emit_finish_line_gas(irn);
361 static void emit_sparc_Div(const ir_node *node, bool is_signed)
363 /* can we get the delay count of the wr instruction somewhere? */
364 unsigned wry_delay_count = 3;
367 be_emit_cstring("\twr ");
368 sparc_emit_source_register(node, 0);
369 be_emit_cstring(", 0, %y");
370 be_emit_finish_line_gas(node);
372 for (i = 0; i < wry_delay_count; ++i) {
373 be_emit_cstring("\tnop");
374 be_emit_finish_line_gas(node);
377 be_emit_irprintf("\t%s ", is_signed ? "sdiv" : "udiv");
378 sparc_emit_source_register(node, 1);
379 be_emit_cstring(", ");
380 sparc_emit_source_register(node, 2);
381 be_emit_cstring(", ");
382 sparc_emit_dest_register(node, 0);
383 be_emit_finish_line_gas(node);
386 static void emit_sparc_SDiv(const ir_node *node)
389 /* aehm we would need an aditional register for an sra instruction to
390 * compute the upper bits... Just panic for now */
391 //emit_sparc_Div(node, true);
392 panic("signed div is wrong");
395 static void emit_sparc_UDiv(const ir_node *node)
397 emit_sparc_Div(node, false);
401 * Emits code for return node
403 static void emit_be_Return(const ir_node *irn)
405 be_emit_cstring("\tret");
406 //be_emit_cstring("\tjmp %i7+8");
407 be_emit_finish_line_gas(irn);
408 be_emit_cstring("\trestore");
409 be_emit_finish_line_gas(irn);
413 * Emits code for Call node
415 static void emit_sparc_Call(const ir_node *node)
417 const sparc_attr_t *attr = get_sparc_attr_const(node);
418 ir_entity *entity = attr->immediate_value_entity;
420 be_emit_cstring("\tcall ");
421 if (entity != NULL) {
422 sparc_emit_entity(entity);
423 be_emit_cstring(", 0");
425 int last = get_irn_arity(node);
426 sparc_emit_source_register(node, last-1);
428 be_emit_finish_line_gas(node);
430 /* fill delay slot */
431 be_emit_cstring("\tnop");
432 be_emit_finish_line_gas(node);
436 * Emit code for Perm node
438 static void emit_be_Perm(const ir_node *irn)
440 be_emit_cstring("\txor ");
441 sparc_emit_source_register(irn, 1);
442 be_emit_cstring(", ");
443 sparc_emit_source_register(irn, 0);
444 be_emit_cstring(", ");
445 sparc_emit_source_register(irn, 0);
446 be_emit_finish_line_gas(NULL);
448 be_emit_cstring("\txor ");
449 sparc_emit_source_register(irn, 1);
450 be_emit_cstring(", ");
451 sparc_emit_source_register(irn, 0);
452 be_emit_cstring(", ");
453 sparc_emit_source_register(irn, 1);
454 be_emit_finish_line_gas(NULL);
456 be_emit_cstring("\txor ");
457 sparc_emit_source_register(irn, 1);
458 be_emit_cstring(", ");
459 sparc_emit_source_register(irn, 0);
460 be_emit_cstring(", ");
461 sparc_emit_source_register(irn, 0);
462 be_emit_finish_line_gas(irn);
466 * TODO: not really tested but seems to work with memperm_arity == 1
468 static void emit_be_MemPerm(const ir_node *node)
473 ir_graph *irg = get_irn_irg(node);
474 be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
476 /* this implementation only works with frame pointers currently */
477 assert(layout->sp_relative == false);
479 /* TODO: this implementation is slower than necessary.
480 The longterm goal is however to avoid the memperm node completely */
482 memperm_arity = be_get_MemPerm_entity_arity(node);
483 // we use our local registers - so this is limited to 8 inputs !
484 if (memperm_arity > 8)
485 panic("memperm with more than 8 inputs not supported yet");
487 be_emit_irprintf("\tsub %%sp, %d, %%sp", memperm_arity*4);
488 be_emit_finish_line_gas(node);
490 for (i = 0; i < memperm_arity; ++i) {
491 ir_entity *entity = be_get_MemPerm_in_entity(node, i);
492 int offset = be_get_stack_entity_offset(layout, entity, 0);
495 be_emit_irprintf("\tst %%l%d, [%%sp%+d]", i, sp_change + SPARC_MIN_STACKSIZE);
496 be_emit_finish_line_gas(node);
498 /* load from entity */
499 be_emit_irprintf("\tld [%%fp%+d], %%l%d", offset, i);
500 be_emit_finish_line_gas(node);
504 for (i = memperm_arity-1; i >= 0; --i) {
505 ir_entity *entity = be_get_MemPerm_out_entity(node, i);
506 int offset = be_get_stack_entity_offset(layout, entity, 0);
510 /* store to new entity */
511 be_emit_irprintf("\tst %%l%d, [%%fp%+d]", i, offset);
512 be_emit_finish_line_gas(node);
513 /* restore register */
514 be_emit_irprintf("\tld [%%sp%+d], %%l%d", sp_change + SPARC_MIN_STACKSIZE, i);
515 be_emit_finish_line_gas(node);
518 be_emit_irprintf("\tadd %%sp, %d, %%sp", memperm_arity*4);
519 be_emit_finish_line_gas(node);
521 assert(sp_change == 0);
527 static void emit_sparc_SymConst(const ir_node *irn)
529 const sparc_symconst_attr_t *attr = get_sparc_symconst_attr_const(irn);
531 //sethi %hi(const32),%reg
532 //or %reg,%lo(const32),%reg
534 be_emit_cstring("\tsethi %hi(");
535 be_gas_emit_entity(attr->entity);
536 be_emit_cstring("), ");
537 sparc_emit_dest_register(irn, 0);
538 be_emit_cstring("\n ");
540 // TODO: could be combined with the following load/store instruction
541 be_emit_cstring("\tor ");
542 sparc_emit_dest_register(irn, 0);
543 be_emit_cstring(", %lo(");
544 be_gas_emit_entity(attr->entity);
545 be_emit_cstring("), ");
546 sparc_emit_dest_register(irn, 0);
547 be_emit_finish_line_gas(irn);
551 * Emits code for FrameAddr fix
553 static void emit_sparc_FrameAddr(const ir_node *irn)
555 const sparc_symconst_attr_t *attr = get_irn_generic_attr_const(irn);
557 // no need to fix offset as we are adressing via the framepointer
558 if (attr->fp_offset >= 0) {
559 be_emit_cstring("\tadd ");
560 sparc_emit_source_register(irn, 0);
561 be_emit_cstring(", ");
562 be_emit_irprintf("%ld", attr->fp_offset);
564 be_emit_cstring("\tsub ");
565 sparc_emit_source_register(irn, 0);
566 be_emit_cstring(", ");
567 be_emit_irprintf("%ld", -attr->fp_offset);
570 be_emit_cstring(", ");
571 sparc_emit_dest_register(irn, 0);
572 be_emit_finish_line_gas(irn);
575 static const char *get_icc_unsigned(pn_Cmp pnc)
578 case pn_Cmp_False: return "bn";
579 case pn_Cmp_Eq: return "be";
580 case pn_Cmp_Lt: return "blu";
581 case pn_Cmp_Le: return "bleu";
582 case pn_Cmp_Gt: return "bgu";
583 case pn_Cmp_Ge: return "bgeu";
584 case pn_Cmp_Lg: return "bne";
585 case pn_Cmp_Leg: return "ba";
586 default: panic("Cmp has unsupported pnc");
590 static const char *get_icc_signed(pn_Cmp pnc)
593 case pn_Cmp_False: return "bn";
594 case pn_Cmp_Eq: return "be";
595 case pn_Cmp_Lt: return "bl";
596 case pn_Cmp_Le: return "ble";
597 case pn_Cmp_Gt: return "bg";
598 case pn_Cmp_Ge: return "bge";
599 case pn_Cmp_Lg: return "bne";
600 case pn_Cmp_Leg: return "ba";
601 default: panic("Cmp has unsupported pnc");
605 static const char *get_fcc(pn_Cmp pnc)
608 case pn_Cmp_False: return "fbn";
609 case pn_Cmp_Eq: return "fbe";
610 case pn_Cmp_Lt: return "fbl";
611 case pn_Cmp_Le: return "fble";
612 case pn_Cmp_Gt: return "fbg";
613 case pn_Cmp_Ge: return "fbge";
614 case pn_Cmp_Lg: return "fblg";
615 case pn_Cmp_Leg: return "fbo";
616 case pn_Cmp_Uo: return "fbu";
617 case pn_Cmp_Ue: return "fbue";
618 case pn_Cmp_Ul: return "fbul";
619 case pn_Cmp_Ule: return "fbule";
620 case pn_Cmp_Ug: return "fbug";
621 case pn_Cmp_Uge: return "fbuge";
622 case pn_Cmp_Ne: return "fbne";
623 case pn_Cmp_True: return "fba";
627 panic("invalid pnc");
630 typedef const char* (*get_cc_func)(pn_Cmp pnc);
633 * Emits code for Branch
635 static void emit_sparc_branch(const ir_node *node, get_cc_func get_cc)
637 const sparc_jmp_cond_attr_t *attr = get_sparc_jmp_cond_attr_const(node);
638 pn_Cmp pnc = attr->pnc;
639 const ir_node *proj_true = NULL;
640 const ir_node *proj_false = NULL;
641 const ir_edge_t *edge;
642 const ir_node *block;
643 const ir_node *next_block;
645 foreach_out_edge(node, edge) {
646 ir_node *proj = get_edge_src_irn(edge);
647 long nr = get_Proj_proj(proj);
648 if (nr == pn_Cond_true) {
655 /* for now, the code works for scheduled and non-schedules blocks */
656 block = get_nodes_block(node);
658 /* we have a block schedule */
659 next_block = get_irn_link(block);
661 if (get_irn_link(proj_true) == next_block) {
662 /* exchange both proj's so the second one can be omitted */
663 const ir_node *t = proj_true;
665 proj_true = proj_false;
667 if (is_sparc_fbfcc(node)) {
668 pnc = get_negated_pnc(pnc, mode_F);
670 pnc = get_negated_pnc(pnc, mode_Iu);
674 /* emit the true proj */
675 be_emit_cstring("\t");
676 be_emit_string(get_cc(pnc));
678 sparc_emit_cfop_target(proj_true);
679 be_emit_finish_line_gas(proj_true);
681 be_emit_cstring("\tnop");
682 be_emit_pad_comment();
683 be_emit_cstring("/* TODO: use delay slot */\n");
685 if (get_irn_link(proj_false) == next_block) {
686 be_emit_cstring("\t/* fallthrough to ");
687 sparc_emit_cfop_target(proj_false);
688 be_emit_cstring(" */");
689 be_emit_finish_line_gas(proj_false);
691 be_emit_cstring("\tba ");
692 sparc_emit_cfop_target(proj_false);
693 be_emit_finish_line_gas(proj_false);
694 be_emit_cstring("\tnop\t\t/* TODO: use delay slot */\n");
695 be_emit_finish_line_gas(proj_false);
699 static void emit_sparc_Bicc(const ir_node *node)
701 const sparc_jmp_cond_attr_t *attr = get_sparc_jmp_cond_attr_const(node);
702 bool is_unsigned = attr->is_unsigned;
703 emit_sparc_branch(node, is_unsigned ? get_icc_unsigned : get_icc_signed);
706 static void emit_sparc_fbfcc(const ir_node *node)
708 emit_sparc_branch(node, get_fcc);
712 * emit Jmp (which actually is a branch always (ba) instruction)
714 static void emit_sparc_Ba(const ir_node *node)
716 ir_node *block, *next_block;
718 /* for now, the code works for scheduled and non-schedules blocks */
719 block = get_nodes_block(node);
721 /* we have a block schedule */
722 next_block = get_irn_link(block);
723 if (get_irn_link(node) != next_block) {
724 be_emit_cstring("\tba ");
725 sparc_emit_cfop_target(node);
726 be_emit_finish_line_gas(node);
727 be_emit_cstring("\tnop\t\t/* TODO: use delay slot */\n");
729 be_emit_cstring("\t/* fallthrough to ");
730 sparc_emit_cfop_target(node);
731 be_emit_cstring(" */");
733 be_emit_finish_line_gas(node);
736 static void emit_fmov(const ir_node *node, const arch_register_t *src_reg,
737 const arch_register_t *dst_reg)
739 be_emit_cstring("\tfmov ");
740 be_emit_string(arch_register_get_name(src_reg));
741 be_emit_cstring(", ");
742 be_emit_string(arch_register_get_name(dst_reg));
743 be_emit_finish_line_gas(node);
746 static const arch_register_t *get_next_fp_reg(const arch_register_t *reg)
748 unsigned index = reg->index;
749 assert(reg == &sparc_fp_regs[index]);
751 assert(index < N_sparc_fp_REGS);
752 return &sparc_fp_regs[index];
758 static void emit_be_Copy(const ir_node *node)
760 ir_mode *mode = get_irn_mode(node);
761 const arch_register_t *src_reg = get_in_reg(node, 0);
762 const arch_register_t *dst_reg = get_out_reg(node, 0);
764 if (src_reg == dst_reg)
767 if (mode_is_float(mode)) {
768 unsigned bits = get_mode_size_bits(mode);
769 int n = bits > 32 ? bits > 64 ? 3 : 1 : 0;
771 emit_fmov(node, src_reg, dst_reg);
772 for (i = 0; i < n; ++i) {
773 src_reg = get_next_fp_reg(src_reg);
774 dst_reg = get_next_fp_reg(dst_reg);
775 emit_fmov(node, src_reg, dst_reg);
777 } else if (mode_is_data(mode)) {
778 be_emit_cstring("\tmov ");
779 sparc_emit_source_register(node, 0);
780 be_emit_cstring(", ");
781 sparc_emit_dest_register(node, 0);
782 be_emit_finish_line_gas(node);
784 panic("emit_be_Copy: invalid mode");
790 * dummy emitter for ignored nodes
792 static void emit_nothing(const ir_node *irn)
798 * type of emitter function
800 typedef void (*emit_func) (const ir_node *);
803 * Set a node emitter. Make it a bit more type safe.
805 static inline void set_emitter(ir_op *op, emit_func sparc_emit_node)
807 op->ops.generic = (op_func)sparc_emit_node;
811 * Enters the emitter functions for handled nodes into the generic
812 * pointer of an opcode.
814 static void sparc_register_emitters(void)
816 /* first clear the generic function pointer for all ops */
817 clear_irp_opcodes_generic_func();
818 /* register all emitter functions defined in spec */
819 sparc_register_spec_emitters();
822 set_emitter(op_be_Copy, emit_be_Copy);
823 set_emitter(op_be_CopyKeep, emit_be_Copy);
824 set_emitter(op_be_IncSP, emit_be_IncSP);
825 set_emitter(op_be_MemPerm, emit_be_MemPerm);
826 set_emitter(op_be_Perm, emit_be_Perm);
827 set_emitter(op_be_Return, emit_be_Return);
828 set_emitter(op_sparc_Ba, emit_sparc_Ba);
829 set_emitter(op_sparc_Bicc, emit_sparc_Bicc);
830 set_emitter(op_sparc_Call, emit_sparc_Call);
831 set_emitter(op_sparc_fbfcc, emit_sparc_fbfcc);
832 set_emitter(op_sparc_FrameAddr, emit_sparc_FrameAddr);
833 set_emitter(op_sparc_Mulh, emit_sparc_Mulh);
834 set_emitter(op_sparc_Save, emit_sparc_Save);
835 set_emitter(op_sparc_SDiv, emit_sparc_SDiv);
836 set_emitter(op_sparc_SymConst, emit_sparc_SymConst);
837 set_emitter(op_sparc_UDiv, emit_sparc_UDiv);
839 /* no need to emit anything for the following nodes */
840 set_emitter(op_be_Barrier, emit_nothing);
841 set_emitter(op_be_Keep, emit_nothing);
842 set_emitter(op_be_Start, emit_nothing);
843 set_emitter(op_Phi, emit_nothing);
847 * Emits code for a node.
849 static void sparc_emit_node(const ir_node *node)
851 ir_op *op = get_irn_op(node);
853 if (op->ops.generic) {
854 emit_func func = (emit_func) op->ops.generic;
855 be_dbg_set_dbg_info(get_irn_dbg_info(node));
858 panic("No emit handler for node %+F (graph %+F)\n", node,
864 * Walks over the nodes in a block connected by scheduling edges
865 * and emits code for each node.
867 static void sparc_gen_block(ir_node *block, void *data)
872 if (! is_Block(block))
875 be_gas_emit_block_name(block);
876 be_emit_cstring(":\n");
877 be_emit_write_line();
879 sched_foreach(block, node) {
880 sparc_emit_node(node);
886 * Emits code for function start.
888 static void sparc_emit_func_prolog(ir_graph *irg)
890 ir_entity *ent = get_irg_entity(irg);
891 be_gas_emit_function_prolog(ent, 4);
892 be_emit_write_line();
896 * Emits code for function end
898 static void sparc_emit_func_epilog(ir_graph *irg)
900 ir_entity *ent = get_irg_entity(irg);
901 const char *irg_name = get_entity_ld_name(ent);
902 be_emit_write_line();
903 be_emit_irprintf("\t.size %s, .-%s\n", irg_name, irg_name);
904 be_emit_cstring("# -- End ");
905 be_emit_string(irg_name);
906 be_emit_cstring("\n");
907 be_emit_write_line();
912 * TODO: Sets labels for control flow nodes (jump target).
913 * Links control predecessors to there destination blocks.
915 static void sparc_gen_labels(ir_node *block, void *env)
918 int n = get_Block_n_cfgpreds(block);
921 for (n--; n >= 0; n--) {
922 pred = get_Block_cfgpred(block, n);
923 set_irn_link(pred, block); // link the pred of a block (which is a jmp)
931 void sparc_gen_routine(const sparc_code_gen_t *cg, ir_graph *irg)
934 ir_node *last_block = NULL;
935 ir_entity *entity = get_irg_entity(irg);
939 be_gas_elf_type_char = '#';
940 be_gas_object_file_format = OBJECT_FILE_FORMAT_ELF_SPARC;
942 /* register all emitter functions */
943 sparc_register_emitters();
944 be_dbg_method_begin(entity);
946 /* create the block schedule. For now, we don't need it earlier. */
947 blk_sched = be_create_block_schedule(irg);
949 // emit function prolog
950 sparc_emit_func_prolog(irg);
952 // generate BLOCK labels
953 irg_block_walk_graph(irg, sparc_gen_labels, NULL, NULL);
955 // inject block scheduling links & emit code of each block
956 n = ARR_LEN(blk_sched);
957 for (i = 0; i < n;) {
958 ir_node *block, *next_bl;
960 block = blk_sched[i];
962 next_bl = i < n ? blk_sched[i] : NULL;
964 /* set here the link. the emitter expects to find the next block here */
965 set_irn_link(block, next_bl);
966 sparc_gen_block(block, last_block);
970 // emit function epilog
971 sparc_emit_func_epilog(irg);
974 void sparc_init_emitter(void)
976 FIRM_DBG_REGISTER(dbg, "firm.be.sparc.emit");