427b89e1628a99a481726563f900168eec8958a2
[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 #include "heights.h"
43
44 #include "../besched.h"
45 #include "../beblocksched.h"
46 #include "../beirg.h"
47 #include "../begnuas.h"
48 #include "../be_dbgout.h"
49 #include "../benode.h"
50
51 #include "sparc_emitter.h"
52 #include "gen_sparc_emitter.h"
53 #include "sparc_nodes_attr.h"
54 #include "sparc_new_nodes.h"
55 #include "gen_sparc_regalloc_if.h"
56
57 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
58
59 static ir_heights_t  *heights;
60 static const ir_node *delay_slot_filler; /**< this node has been choosen to fill
61                                               the next delay slot */
62
63 static void sparc_emit_node(const ir_node *node);
64
65 /**
66  * Returns the register at in position pos.
67  */
68 static const arch_register_t *get_in_reg(const ir_node *node, int pos)
69 {
70         ir_node                *op;
71         const arch_register_t  *reg = NULL;
72
73         assert(get_irn_arity(node) > pos && "Invalid IN position");
74
75         /* The out register of the operator at position pos is the
76            in register we need. */
77         op = get_irn_n(node, pos);
78
79         reg = arch_get_irn_register(op);
80
81         assert(reg && "no in register found");
82         return reg;
83 }
84
85 /**
86  * Returns the register at out position pos.
87  */
88 static const arch_register_t *get_out_reg(const ir_node *node, int pos)
89 {
90         ir_node                *proj;
91         const arch_register_t  *reg = NULL;
92
93         /* 1st case: irn is not of mode_T, so it has only                 */
94         /*           one OUT register -> good                             */
95         /* 2nd case: irn is of mode_T -> collect all Projs and ask the    */
96         /*           Proj with the corresponding projnum for the register */
97
98         if (get_irn_mode(node) != mode_T) {
99                 reg = arch_get_irn_register(node);
100         } else if (is_sparc_irn(node)) {
101                 reg = arch_irn_get_register(node, pos);
102         } else {
103                 const ir_edge_t *edge;
104
105                 foreach_out_edge(node, edge) {
106                         proj = get_edge_src_irn(edge);
107                         assert(is_Proj(proj) && "non-Proj from mode_T node");
108                         if (get_Proj_proj(proj) == pos) {
109                                 reg = arch_get_irn_register(proj);
110                                 break;
111                         }
112                 }
113         }
114
115         assert(reg && "no out register found");
116         return reg;
117 }
118
119 static bool is_valid_immediate(int32_t value)
120 {
121         return -4096 <= value && value < 4096;
122 }
123
124 void sparc_emit_immediate(const ir_node *node)
125 {
126         const sparc_attr_t *attr   = get_sparc_attr_const(node);
127         ir_entity          *entity = attr->immediate_value_entity;
128
129         if (entity == NULL) {
130                 int32_t value = attr->immediate_value;
131                 assert(is_valid_immediate(value));
132                 be_emit_irprintf("%d", value);
133         } else {
134                 be_emit_cstring("%lo(");
135                 be_gas_emit_entity(entity);
136                 if (attr->immediate_value != 0) {
137                         be_emit_irprintf("%+d", attr->immediate_value);
138                 }
139                 be_emit_char(')');
140         }
141 }
142
143 void sparc_emit_high_immediate(const ir_node *node)
144 {
145         const sparc_attr_t *attr   = get_sparc_attr_const(node);
146         ir_entity          *entity = attr->immediate_value_entity;
147
148         be_emit_cstring("%hi(");
149         if (entity == NULL) {
150                 uint32_t value = (uint32_t) attr->immediate_value;
151                 be_emit_irprintf("0x%X", value);
152         } else {
153                 be_gas_emit_entity(entity);
154                 if (attr->immediate_value != 0) {
155                         be_emit_irprintf("%+d", attr->immediate_value);
156                 }
157         }
158         be_emit_char(')');
159 }
160
161 void sparc_emit_source_register(const ir_node *node, int pos)
162 {
163         const arch_register_t *reg = get_in_reg(node, pos);
164         be_emit_char('%');
165         be_emit_string(arch_register_get_name(reg));
166 }
167
168 void sparc_emit_dest_register(const ir_node *node, int pos)
169 {
170         const arch_register_t *reg = get_out_reg(node, pos);
171         be_emit_char('%');
172         be_emit_string(arch_register_get_name(reg));
173 }
174
175 /**
176  * Emits either a imm or register depending on arity of node
177  * @param node
178  * @param register no (-1 if no register)
179  */
180 void sparc_emit_reg_or_imm(const ir_node *node, int pos)
181 {
182         if (get_irn_arity(node) > pos) {
183                 // we have reg input
184                 sparc_emit_source_register(node, pos);
185         } else {
186                 // we have a imm input
187                 sparc_emit_immediate(node);
188         }
189 }
190
191 static bool is_stack_pointer_relative(const ir_node *node)
192 {
193         const arch_register_t *sp = &sparc_gp_regs[REG_SP];
194         return (is_sparc_St(node) && get_in_reg(node, n_sparc_St_ptr) == sp)
195             || (is_sparc_Ld(node) && get_in_reg(node, n_sparc_Ld_ptr) == sp);
196 }
197
198 /**
199  * emit SP offset
200  */
201 void sparc_emit_offset(const ir_node *node, int offset_node_pos)
202 {
203         const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
204
205         if (attr->is_reg_reg) {
206                 assert(!attr->is_frame_entity);
207                 assert(attr->base.immediate_value == 0);
208                 assert(attr->base.immediate_value_entity == NULL);
209                 be_emit_char('+');
210                 sparc_emit_source_register(node, offset_node_pos);
211         } else if (attr->is_frame_entity) {
212                 int32_t offset = attr->base.immediate_value;
213                 /* bad hack: the real stack stuff is behind the always-there spill
214                  * space for the register window and stack */
215                 if (is_stack_pointer_relative(node))
216                         offset += SPARC_MIN_STACKSIZE;
217                 if (offset != 0) {
218                         assert(is_valid_immediate(offset));
219                         be_emit_irprintf("%+ld", offset);
220                 }
221         } else if (attr->base.immediate_value != 0
222                         || attr->base.immediate_value_entity != NULL) {
223                 be_emit_char('+');
224                 sparc_emit_immediate(node);
225         }
226 }
227
228 void sparc_emit_float_load_store_mode(const ir_node *node)
229 {
230         const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
231         ir_mode *mode = attr->load_store_mode;
232         int      bits = get_mode_size_bits(mode);
233
234         assert(mode_is_float(mode));
235
236         switch (bits) {
237         case 32:  return;
238         case 64:  be_emit_char('d'); return;
239         case 128: be_emit_char('q'); return;
240         }
241         panic("invalid flaot load/store mode %+F", mode);
242 }
243
244 /**
245  *  Emit load mode char
246  */
247 void sparc_emit_load_mode(const ir_node *node)
248 {
249         const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
250         ir_mode *mode      = attr->load_store_mode;
251         int      bits      = get_mode_size_bits(mode);
252         bool     is_signed = mode_is_signed(mode);
253
254         if (bits == 16) {
255                 be_emit_string(is_signed ? "sh" : "uh");
256         } else if (bits == 8) {
257                 be_emit_string(is_signed ? "sb" : "ub");
258         } else if (bits == 64) {
259                 be_emit_char('d');
260         } else {
261                 assert(bits == 32);
262         }
263 }
264
265 /**
266  * Emit store mode char
267  */
268 void sparc_emit_store_mode(const ir_node *node)
269 {
270         const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
271         ir_mode *mode      = attr->load_store_mode;
272         int      bits      = get_mode_size_bits(mode);
273
274         if (bits == 16) {
275                 be_emit_string("h");
276         } else if (bits == 8) {
277                 be_emit_string("b");
278         } else if (bits == 64) {
279                 be_emit_char('d');
280         } else {
281                 assert(bits == 32);
282         }
283 }
284
285 /**
286  * emit integer signed/unsigned prefix char
287  */
288 void sparc_emit_mode_sign_prefix(const ir_node *node)
289 {
290         ir_mode *mode      = get_irn_mode(node);
291         bool     is_signed = mode_is_signed(mode);
292         be_emit_string(is_signed ? "s" : "u");
293 }
294
295 static void emit_fp_suffix(const ir_mode *mode)
296 {
297         unsigned bits = get_mode_size_bits(mode);
298         assert(mode_is_float(mode));
299
300         if (bits == 32) {
301                 be_emit_char('s');
302         } else if (bits == 64) {
303                 be_emit_char('d');
304         } else if (bits == 128) {
305                 be_emit_char('q');
306         } else {
307                 panic("invalid FP mode");
308         }
309 }
310
311 void sparc_emit_fp_conv_source(const ir_node *node)
312 {
313         const sparc_fp_conv_attr_t *attr = get_sparc_fp_conv_attr_const(node);
314         emit_fp_suffix(attr->src_mode);
315 }
316
317 void sparc_emit_fp_conv_destination(const ir_node *node)
318 {
319         const sparc_fp_conv_attr_t *attr = get_sparc_fp_conv_attr_const(node);
320         emit_fp_suffix(attr->dest_mode);
321 }
322
323 /**
324  * emits the FP mode suffix char
325  */
326 void sparc_emit_fp_mode_suffix(const ir_node *node)
327 {
328         const sparc_fp_attr_t *attr = get_sparc_fp_attr_const(node);
329         emit_fp_suffix(attr->fp_mode);
330 }
331
332 static ir_node *get_jump_target(const ir_node *jump)
333 {
334         return get_irn_link(jump);
335 }
336
337 /**
338  * Returns the target label for a control flow node.
339  */
340 static void sparc_emit_cfop_target(const ir_node *node)
341 {
342         ir_node *block = get_jump_target(node);
343         be_gas_emit_block_name(block);
344 }
345
346 static int get_sparc_Call_dest_addr_pos(const ir_node *node)
347 {
348         return get_irn_arity(node)-1;
349 }
350
351 static bool ba_is_fallthrough(const ir_node *node)
352 {
353         ir_node *block      = get_nodes_block(node);
354         ir_node *next_block = get_irn_link(block);
355         return get_irn_link(node) == next_block;
356 }
357
358 static bool is_no_instruction(const ir_node *node)
359 {
360         /* copies are nops if src_reg == dest_reg */
361         if (be_is_Copy(node) || be_is_CopyKeep(node)) {
362                 const arch_register_t *src_reg  = get_in_reg(node, 0);
363                 const arch_register_t *dest_reg = get_out_reg(node, 0);
364
365                 if (src_reg == dest_reg)
366                         return true;
367         }
368         /* Ba is not emitted if it is a simple fallthrough */
369         if (is_sparc_Ba(node) && ba_is_fallthrough(node))
370                 return true;
371
372         return be_is_Keep(node) || be_is_Barrier(node) || be_is_Start(node)
373                 || is_Phi(node);
374 }
375
376 static bool has_delay_slot(const ir_node *node)
377 {
378         if (is_sparc_Ba(node) && ba_is_fallthrough(node))
379                 return false;
380
381         return is_sparc_Bicc(node) || is_sparc_fbfcc(node) || is_sparc_Ba(node)
382                 || is_sparc_SwitchJmp(node) || is_sparc_Call(node)
383                 || is_sparc_SDiv(node) || is_sparc_UDiv(node);
384 }
385
386 /** returns true if the emitter for this sparc node can produce more than one
387  * actual sparc instruction.
388  * Usually it is a bad sign if we have to add instructions here. We should
389  * rather try to get them lowered down. So we can actually put them into
390  * delay slots and make them more accessible to the scheduler.
391  */
392 static bool emits_multiple_instructions(const ir_node *node)
393 {
394         if (has_delay_slot(node))
395                 return true;
396
397         return is_sparc_Mulh(node) || is_sparc_SDiv(node) || is_sparc_UDiv(node)
398                 || be_is_MemPerm(node) || be_is_Perm(node) || be_is_Return(node);
399 }
400
401 /**
402  * search for an instruction that can fill the delay slot of @p node
403  */
404 static const ir_node *pick_delay_slot_for(const ir_node *node)
405 {
406         const ir_node *check      = node;
407         const ir_node *schedpoint = node;
408         unsigned       tries      = 0;
409         /* currently we don't track which registers are still alive, so we can't
410          * pick any other instructions other than the one directly preceding */
411         static const unsigned PICK_DELAY_SLOT_MAX_DISTANCE = 1;
412
413         assert(has_delay_slot(node));
414
415         if (is_sparc_Call(node)) {
416                 const sparc_attr_t *attr   = get_sparc_attr_const(node);
417                 ir_entity          *entity = attr->immediate_value_entity;
418                 if (entity != NULL) {
419                         check = NULL; /* pick any instruction, dependencies on Call
420                                          don't matter */
421                 } else {
422                         /* we only need to check the value for the call destination */
423                         check = get_irn_n(node, get_sparc_Call_dest_addr_pos(node));
424                 }
425
426                 /* the Call also destroys the value of %o7, but since this is currently
427                  * marked as ignore register in the backend, it should never be used by
428                  * the instruction in the delay slot. */
429         } else {
430                 check = node;
431         }
432
433         while (sched_has_prev(schedpoint)) {
434                 schedpoint = sched_prev(schedpoint);
435
436                 if (tries++ >= PICK_DELAY_SLOT_MAX_DISTANCE)
437                         break;
438
439                 if (has_delay_slot(schedpoint))
440                         break;
441
442                 /* skip things which don't really result in instructions */
443                 if (is_no_instruction(schedpoint))
444                         continue;
445
446                 if (emits_multiple_instructions(schedpoint))
447                         continue;
448
449                 /* allowed for delayslot: any instruction which is not necessary to
450                  * compute an input to the branch. */
451                 if (check != NULL
452                                 && heights_reachable_in_block(heights, check, schedpoint))
453                         continue;
454
455                 /* found something */
456                 return schedpoint;
457         }
458
459         return NULL;
460 }
461
462 /**
463  * Emits code for stack space management
464  */
465 static void emit_be_IncSP(const ir_node *irn)
466 {
467         int offs = -be_get_IncSP_offset(irn);
468
469         if (offs == 0)
470                 return;
471
472         /* SPARC stack grows downwards */
473         if (offs < 0) {
474                 be_emit_cstring("\tsub ");
475                 offs = -offs;
476         } else {
477                 be_emit_cstring("\tadd ");
478         }
479
480         sparc_emit_source_register(irn, 0);
481         be_emit_irprintf(", %d", offs);
482         be_emit_cstring(", ");
483         sparc_emit_dest_register(irn, 0);
484         be_emit_finish_line_gas(irn);
485 }
486
487 /**
488  * emits code for save instruction with min. required stack space
489  */
490 static void emit_sparc_Save(const ir_node *irn)
491 {
492         const sparc_save_attr_t *save_attr = get_sparc_save_attr_const(irn);
493         be_emit_cstring("\tsave ");
494         sparc_emit_source_register(irn, 0);
495         be_emit_irprintf(", %d, ", -save_attr->initial_stacksize);
496         sparc_emit_dest_register(irn, 0);
497         be_emit_finish_line_gas(irn);
498 }
499
500 /**
501  * emits code for mulh
502  */
503 static void emit_sparc_Mulh(const ir_node *irn)
504 {
505         be_emit_cstring("\t");
506         sparc_emit_mode_sign_prefix(irn);
507         be_emit_cstring("mul ");
508
509         sparc_emit_source_register(irn, 0);
510         be_emit_cstring(", ");
511         sparc_emit_reg_or_imm(irn, 1);
512         be_emit_cstring(", ");
513         sparc_emit_dest_register(irn, 0);
514         be_emit_finish_line_gas(irn);
515
516         // our result is in the y register now
517         // we just copy it to the assigned target reg
518         be_emit_cstring("\tmov %y, ");
519         sparc_emit_dest_register(irn, 0);
520         be_emit_finish_line_gas(irn);
521 }
522
523 static void fill_delay_slot(void)
524 {
525         if (delay_slot_filler != NULL) {
526                 sparc_emit_node(delay_slot_filler);
527                 delay_slot_filler = NULL;
528         } else {
529                 be_emit_cstring("\tnop\n");
530                 be_emit_write_line();
531         }
532 }
533
534 static void emit_sparc_Div(const ir_node *node, bool is_signed)
535 {
536         /* can we get the delay count of the wr instruction somewhere? */
537         unsigned wry_delay_count = 3;
538         unsigned i;
539
540         be_emit_cstring("\twr ");
541         sparc_emit_source_register(node, 0);
542         be_emit_cstring(", 0, %y");
543         be_emit_finish_line_gas(node);
544
545         for (i = 0; i < wry_delay_count; ++i) {
546                 fill_delay_slot();
547         }
548
549         be_emit_irprintf("\t%s ", is_signed ? "sdiv" : "udiv");
550         sparc_emit_source_register(node, 1);
551         be_emit_cstring(", ");
552         sparc_emit_reg_or_imm(node, 2);
553         be_emit_cstring(", ");
554         sparc_emit_dest_register(node, 0);
555         be_emit_finish_line_gas(node);
556 }
557
558 static void emit_sparc_SDiv(const ir_node *node)
559 {
560         emit_sparc_Div(node, true);
561 }
562
563 static void emit_sparc_UDiv(const ir_node *node)
564 {
565         emit_sparc_Div(node, false);
566 }
567
568 /**
569  * Emits code for return node
570  */
571 static void emit_be_Return(const ir_node *irn)
572 {
573         be_emit_cstring("\tret");
574         //be_emit_cstring("\tjmp %i7+8");
575         be_emit_finish_line_gas(irn);
576         be_emit_cstring("\trestore");
577         be_emit_finish_line_gas(irn);
578 }
579
580 /**
581  * Emits code for Call node
582  */
583 static void emit_sparc_Call(const ir_node *node)
584 {
585         const sparc_attr_t *attr   = get_sparc_attr_const(node);
586         ir_entity          *entity = attr->immediate_value_entity;
587
588         be_emit_cstring("\tcall ");
589         if (entity != NULL) {
590             be_gas_emit_entity(entity);
591             if (attr->immediate_value != 0) {
592                         be_emit_irprintf("%+d", attr->immediate_value);
593                 }
594                 be_emit_cstring(", 0");
595         } else {
596                 int dest_addr = get_sparc_Call_dest_addr_pos(node);
597                 sparc_emit_source_register(node, dest_addr);
598         }
599         be_emit_finish_line_gas(node);
600
601         fill_delay_slot();
602 }
603
604 /**
605  * Emit code for Perm node
606  */
607 static void emit_be_Perm(const ir_node *irn)
608 {
609         be_emit_cstring("\txor ");
610         sparc_emit_source_register(irn, 1);
611         be_emit_cstring(", ");
612         sparc_emit_source_register(irn, 0);
613         be_emit_cstring(", ");
614         sparc_emit_source_register(irn, 0);
615         be_emit_finish_line_gas(NULL);
616
617         be_emit_cstring("\txor ");
618         sparc_emit_source_register(irn, 1);
619         be_emit_cstring(", ");
620         sparc_emit_source_register(irn, 0);
621         be_emit_cstring(", ");
622         sparc_emit_source_register(irn, 1);
623         be_emit_finish_line_gas(NULL);
624
625         be_emit_cstring("\txor ");
626         sparc_emit_source_register(irn, 1);
627         be_emit_cstring(", ");
628         sparc_emit_source_register(irn, 0);
629         be_emit_cstring(", ");
630         sparc_emit_source_register(irn, 0);
631         be_emit_finish_line_gas(irn);
632 }
633
634 static void emit_be_MemPerm(const ir_node *node)
635 {
636         int i;
637         int memperm_arity;
638         int sp_change = 0;
639         ir_graph          *irg    = get_irn_irg(node);
640         be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
641
642         /* this implementation only works with frame pointers currently */
643         assert(layout->sp_relative == false);
644
645         /* TODO: this implementation is slower than necessary.
646            The longterm goal is however to avoid the memperm node completely */
647
648         memperm_arity = be_get_MemPerm_entity_arity(node);
649         // we use our local registers - so this is limited to 8 inputs !
650         if (memperm_arity > 8)
651                 panic("memperm with more than 8 inputs not supported yet");
652
653         be_emit_irprintf("\tsub %%sp, %d, %%sp", memperm_arity*4);
654         be_emit_finish_line_gas(node);
655
656         for (i = 0; i < memperm_arity; ++i) {
657                 ir_entity *entity = be_get_MemPerm_in_entity(node, i);
658                 int        offset = be_get_stack_entity_offset(layout, entity, 0);
659
660                 /* spill register */
661                 be_emit_irprintf("\tst %%l%d, [%%sp%+d]", i, sp_change + SPARC_MIN_STACKSIZE);
662                 be_emit_finish_line_gas(node);
663
664                 /* load from entity */
665                 be_emit_irprintf("\tld [%%fp%+d], %%l%d", offset, i);
666                 be_emit_finish_line_gas(node);
667                 sp_change += 4;
668         }
669
670         for (i = memperm_arity-1; i >= 0; --i) {
671                 ir_entity *entity = be_get_MemPerm_out_entity(node, i);
672                 int        offset = be_get_stack_entity_offset(layout, entity, 0);
673
674                 sp_change -= 4;
675
676                 /* store to new entity */
677                 be_emit_irprintf("\tst %%l%d, [%%fp%+d]", i, offset);
678                 be_emit_finish_line_gas(node);
679                 /* restore register */
680                 be_emit_irprintf("\tld [%%sp%+d], %%l%d", sp_change + SPARC_MIN_STACKSIZE, i);
681                 be_emit_finish_line_gas(node);
682         }
683
684         be_emit_irprintf("\tadd %%sp, %d, %%sp", memperm_arity*4);
685         be_emit_finish_line_gas(node);
686
687         assert(sp_change == 0);
688 }
689
690 static void emit_sparc_FrameAddr(const ir_node *node)
691 {
692         const sparc_attr_t *attr = get_sparc_attr_const(node);
693
694         // no need to fix offset as we are adressing via the framepointer
695         if (attr->immediate_value >= 0) {
696                 be_emit_cstring("\tadd ");
697                 sparc_emit_source_register(node, 0);
698                 be_emit_cstring(", ");
699                 be_emit_irprintf("%ld", attr->immediate_value);
700         } else {
701                 be_emit_cstring("\tsub ");
702                 sparc_emit_source_register(node, 0);
703                 be_emit_cstring(", ");
704                 be_emit_irprintf("%ld", -attr->immediate_value);
705         }
706
707         be_emit_cstring(", ");
708         sparc_emit_dest_register(node, 0);
709         be_emit_finish_line_gas(node);
710 }
711
712 static const char *get_icc_unsigned(pn_Cmp pnc)
713 {
714         switch (pnc) {
715         case pn_Cmp_False: return "bn";
716         case pn_Cmp_Eq:    return "be";
717         case pn_Cmp_Lt:    return "blu";
718         case pn_Cmp_Le:    return "bleu";
719         case pn_Cmp_Gt:    return "bgu";
720         case pn_Cmp_Ge:    return "bgeu";
721         case pn_Cmp_Lg:    return "bne";
722         case pn_Cmp_Leg:   return "ba";
723         default: panic("Cmp has unsupported pnc");
724         }
725 }
726
727 static const char *get_icc_signed(pn_Cmp pnc)
728 {
729         switch (pnc) {
730         case pn_Cmp_False: return "bn";
731         case pn_Cmp_Eq:    return "be";
732         case pn_Cmp_Lt:    return "bl";
733         case pn_Cmp_Le:    return "ble";
734         case pn_Cmp_Gt:    return "bg";
735         case pn_Cmp_Ge:    return "bge";
736         case pn_Cmp_Lg:    return "bne";
737         case pn_Cmp_Leg:   return "ba";
738         default: panic("Cmp has unsupported pnc");
739         }
740 }
741
742 static const char *get_fcc(pn_Cmp pnc)
743 {
744         switch (pnc) {
745         case pn_Cmp_False: return "fbn";
746         case pn_Cmp_Eq:    return "fbe";
747         case pn_Cmp_Lt:    return "fbl";
748         case pn_Cmp_Le:    return "fble";
749         case pn_Cmp_Gt:    return "fbg";
750         case pn_Cmp_Ge:    return "fbge";
751         case pn_Cmp_Lg:    return "fblg";
752         case pn_Cmp_Leg:   return "fbo";
753         case pn_Cmp_Uo:    return "fbu";
754         case pn_Cmp_Ue:    return "fbue";
755         case pn_Cmp_Ul:    return "fbul";
756         case pn_Cmp_Ule:   return "fbule";
757         case pn_Cmp_Ug:    return "fbug";
758         case pn_Cmp_Uge:   return "fbuge";
759         case pn_Cmp_Ne:    return "fbne";
760         case pn_Cmp_True:  return "fba";
761         case pn_Cmp_max:
762                 break;
763         }
764         panic("invalid pnc");
765 }
766
767 typedef const char* (*get_cc_func)(pn_Cmp pnc);
768
769 static void emit_sparc_branch(const ir_node *node, get_cc_func get_cc)
770 {
771         const sparc_jmp_cond_attr_t *attr = get_sparc_jmp_cond_attr_const(node);
772         pn_Cmp           pnc         = attr->pnc;
773         const ir_node   *proj_true   = NULL;
774         const ir_node   *proj_false  = NULL;
775         const ir_edge_t *edge;
776         const ir_node   *block;
777         const ir_node   *next_block;
778
779         foreach_out_edge(node, edge) {
780                 ir_node *proj = get_edge_src_irn(edge);
781                 long nr = get_Proj_proj(proj);
782                 if (nr == pn_Cond_true) {
783                         proj_true = proj;
784                 } else {
785                         proj_false = proj;
786                 }
787         }
788
789         /* for now, the code works for scheduled and non-schedules blocks */
790         block = get_nodes_block(node);
791
792         /* we have a block schedule */
793         next_block = get_irn_link(block);
794
795         if (get_irn_link(proj_true) == next_block) {
796                 /* exchange both proj's so the second one can be omitted */
797                 const ir_node *t = proj_true;
798
799                 proj_true  = proj_false;
800                 proj_false = t;
801                 if (is_sparc_fbfcc(node)) {
802                         pnc = get_negated_pnc(pnc, mode_F);
803                 } else {
804                         pnc = get_negated_pnc(pnc, mode_Iu);
805                 }
806         }
807
808         /* emit the true proj */
809         be_emit_cstring("\t");
810         be_emit_string(get_cc(pnc));
811         be_emit_char(' ');
812         sparc_emit_cfop_target(proj_true);
813         be_emit_finish_line_gas(proj_true);
814
815         fill_delay_slot();
816
817         if (get_irn_link(proj_false) == next_block) {
818                 be_emit_cstring("\t/* fallthrough to ");
819                 sparc_emit_cfop_target(proj_false);
820                 be_emit_cstring(" */");
821                 be_emit_finish_line_gas(proj_false);
822         } else {
823                 be_emit_cstring("\tba ");
824                 sparc_emit_cfop_target(proj_false);
825                 be_emit_finish_line_gas(proj_false);
826                 fill_delay_slot();
827         }
828 }
829
830 static void emit_sparc_Bicc(const ir_node *node)
831 {
832         const sparc_jmp_cond_attr_t *attr = get_sparc_jmp_cond_attr_const(node);
833         bool             is_unsigned = attr->is_unsigned;
834         emit_sparc_branch(node, is_unsigned ? get_icc_unsigned : get_icc_signed);
835 }
836
837 static void emit_sparc_fbfcc(const ir_node *node)
838 {
839         emit_sparc_branch(node, get_fcc);
840 }
841
842 static void emit_sparc_Ba(const ir_node *node)
843 {
844         if (ba_is_fallthrough(node)) {
845                 be_emit_cstring("\t/* fallthrough to ");
846                 sparc_emit_cfop_target(node);
847                 be_emit_cstring(" */");
848         } else {
849                 be_emit_cstring("\tba ");
850                 sparc_emit_cfop_target(node);
851                 be_emit_finish_line_gas(node);
852                 fill_delay_slot();
853         }
854         be_emit_finish_line_gas(node);
855 }
856
857 static void emit_jump_table(const ir_node *node)
858 {
859         const sparc_switch_jmp_attr_t *attr = get_sparc_switch_jmp_attr_const(node);
860         long             switch_min    = LONG_MAX;
861         long             switch_max    = LONG_MIN;
862         long             default_pn    = attr->default_proj_num;
863         ir_entity       *entity        = attr->jump_table;
864         ir_node         *default_block = NULL;
865         unsigned         length;
866         const ir_edge_t *edge;
867         unsigned         i;
868         ir_node        **table;
869
870         /* go over all proj's and collect them */
871         foreach_out_edge(node, edge) {
872                 ir_node *proj = get_edge_src_irn(edge);
873                 long     pn   = get_Proj_proj(proj);
874
875                 /* check for default proj */
876                 if (pn == default_pn) {
877                         assert(default_block == NULL); /* more than 1 default_pn? */
878                         default_block = get_jump_target(proj);
879                 } else {
880                         switch_min = pn < switch_min ? pn : switch_min;
881                         switch_max = pn > switch_max ? pn : switch_max;
882                 }
883         }
884         length = (unsigned long) (switch_max - switch_min) + 1;
885         assert(switch_min < LONG_MAX || switch_max > LONG_MIN);
886
887         table = XMALLOCNZ(ir_node*, length);
888         foreach_out_edge(node, edge) {
889                 ir_node *proj = get_edge_src_irn(edge);
890                 long     pn   = get_Proj_proj(proj);
891                 if (pn == default_pn)
892                         continue;
893
894                 table[pn - switch_min] = get_jump_target(proj);
895         }
896
897         /* emit table */
898         be_gas_emit_switch_section(GAS_SECTION_RODATA);
899         be_emit_cstring("\t.align 4\n");
900         be_gas_emit_entity(entity);
901         be_emit_cstring(":\n");
902         for (i = 0; i < length; ++i) {
903                 ir_node *block = table[i];
904                 if (block == NULL)
905                         block = default_block;
906                 be_emit_cstring("\t.long ");
907                 be_gas_emit_block_name(block);
908                 be_emit_char('\n');
909                 be_emit_write_line();
910         }
911         be_gas_emit_switch_section(GAS_SECTION_TEXT);
912
913         xfree(table);
914 }
915
916 static void emit_sparc_SwitchJmp(const ir_node *node)
917 {
918         be_emit_cstring("\tjmp ");
919         sparc_emit_source_register(node, 0);
920         be_emit_finish_line_gas(node);
921         fill_delay_slot();
922
923         emit_jump_table(node);
924 }
925
926 static void emit_fmov(const ir_node *node, const arch_register_t *src_reg,
927                       const arch_register_t *dst_reg)
928 {
929         be_emit_cstring("\tfmov ");
930         be_emit_string(arch_register_get_name(src_reg));
931         be_emit_cstring(", ");
932         be_emit_string(arch_register_get_name(dst_reg));
933         be_emit_finish_line_gas(node);
934 }
935
936 static const arch_register_t *get_next_fp_reg(const arch_register_t *reg)
937 {
938         unsigned index = reg->index;
939         assert(reg == &sparc_fp_regs[index]);
940         index++;
941         assert(index < N_sparc_fp_REGS);
942         return &sparc_fp_regs[index];
943 }
944
945 static void emit_be_Copy(const ir_node *node)
946 {
947         ir_mode               *mode    = get_irn_mode(node);
948         const arch_register_t *src_reg = get_in_reg(node, 0);
949         const arch_register_t *dst_reg = get_out_reg(node, 0);
950
951         if (src_reg == dst_reg)
952                 return;
953
954         if (mode_is_float(mode)) {
955                 unsigned bits = get_mode_size_bits(mode);
956                 int      n    = bits > 32 ? bits > 64 ? 3 : 1 : 0;
957                 int      i;
958                 emit_fmov(node, src_reg, dst_reg);
959                 for (i = 0; i < n; ++i) {
960                         src_reg = get_next_fp_reg(src_reg);
961                         dst_reg = get_next_fp_reg(dst_reg);
962                         emit_fmov(node, src_reg, dst_reg);
963                 }
964         } else if (mode_is_data(mode)) {
965                 be_emit_cstring("\tmov ");
966                 sparc_emit_source_register(node, 0);
967                 be_emit_cstring(", ");
968                 sparc_emit_dest_register(node, 0);
969                 be_emit_finish_line_gas(node);
970         } else {
971                 panic("emit_be_Copy: invalid mode");
972         }
973 }
974
975 static void emit_nothing(const ir_node *irn)
976 {
977         (void) irn;
978 }
979
980 typedef void (*emit_func) (const ir_node *);
981
982 static inline void set_emitter(ir_op *op, emit_func sparc_emit_node)
983 {
984         op->ops.generic = (op_func)sparc_emit_node;
985 }
986
987 /**
988  * Enters the emitter functions for handled nodes into the generic
989  * pointer of an opcode.
990  */
991 static void sparc_register_emitters(void)
992 {
993         /* first clear the generic function pointer for all ops */
994         clear_irp_opcodes_generic_func();
995         /* register all emitter functions defined in spec */
996         sparc_register_spec_emitters();
997
998         /* custom emitter */
999         set_emitter(op_be_Copy,         emit_be_Copy);
1000         set_emitter(op_be_CopyKeep,     emit_be_Copy);
1001         set_emitter(op_be_IncSP,        emit_be_IncSP);
1002         set_emitter(op_be_MemPerm,      emit_be_MemPerm);
1003         set_emitter(op_be_Perm,         emit_be_Perm);
1004         set_emitter(op_be_Return,       emit_be_Return);
1005         set_emitter(op_sparc_Ba,        emit_sparc_Ba);
1006         set_emitter(op_sparc_Bicc,      emit_sparc_Bicc);
1007         set_emitter(op_sparc_Call,      emit_sparc_Call);
1008         set_emitter(op_sparc_fbfcc,     emit_sparc_fbfcc);
1009         set_emitter(op_sparc_FrameAddr, emit_sparc_FrameAddr);
1010         set_emitter(op_sparc_Mulh,      emit_sparc_Mulh);
1011         set_emitter(op_sparc_Save,      emit_sparc_Save);
1012         set_emitter(op_sparc_SDiv,      emit_sparc_SDiv);
1013         set_emitter(op_sparc_SwitchJmp, emit_sparc_SwitchJmp);
1014         set_emitter(op_sparc_UDiv,      emit_sparc_UDiv);
1015
1016         /* no need to emit anything for the following nodes */
1017         set_emitter(op_be_Barrier, emit_nothing);
1018         set_emitter(op_be_Keep,    emit_nothing);
1019         set_emitter(op_be_Start,   emit_nothing);
1020         set_emitter(op_Phi,        emit_nothing);
1021 }
1022
1023 /**
1024  * Emits code for a node.
1025  */
1026 static void sparc_emit_node(const ir_node *node)
1027 {
1028         ir_op *op = get_irn_op(node);
1029
1030         if (op->ops.generic) {
1031                 emit_func func = (emit_func) op->ops.generic;
1032                 be_dbg_set_dbg_info(get_irn_dbg_info(node));
1033                 (*func) (node);
1034         } else {
1035                 panic("No emit handler for node %+F (graph %+F)\n",     node,
1036                       current_ir_graph);
1037         }
1038 }
1039
1040 static ir_node *find_next_delay_slot(ir_node *from)
1041 {
1042         ir_node *schedpoint = from;
1043         while (!has_delay_slot(schedpoint)) {
1044                 if (!sched_has_next(schedpoint))
1045                         return NULL;
1046                 schedpoint = sched_next(schedpoint);
1047         }
1048         return schedpoint;
1049 }
1050
1051 /**
1052  * Walks over the nodes in a block connected by scheduling edges
1053  * and emits code for each node.
1054  */
1055 static void sparc_emit_block(ir_node *block)
1056 {
1057         ir_node *node;
1058         ir_node *next_delay_slot;
1059
1060         assert(is_Block(block));
1061
1062         be_gas_emit_block_name(block);
1063         be_emit_cstring(":\n");
1064         be_emit_write_line();
1065
1066         next_delay_slot = find_next_delay_slot(sched_first(block));
1067         if (next_delay_slot != NULL)
1068                 delay_slot_filler = pick_delay_slot_for(next_delay_slot);
1069
1070         sched_foreach(block, node) {
1071                 if (node == delay_slot_filler) {
1072                         continue;
1073                 }
1074
1075                 sparc_emit_node(node);
1076
1077                 if (node == next_delay_slot) {
1078                         assert(delay_slot_filler == NULL);
1079                         next_delay_slot = find_next_delay_slot(sched_next(node));
1080                         if (next_delay_slot != NULL)
1081                                 delay_slot_filler = pick_delay_slot_for(next_delay_slot);
1082                 }
1083         }
1084 }
1085
1086 /**
1087  * Emits code for function start.
1088  */
1089 static void sparc_emit_func_prolog(ir_graph *irg)
1090 {
1091         ir_entity *ent = get_irg_entity(irg);
1092         be_gas_emit_function_prolog(ent, 4);
1093         be_emit_write_line();
1094 }
1095
1096 /**
1097  * Emits code for function end
1098  */
1099 static void sparc_emit_func_epilog(ir_graph *irg)
1100 {
1101         ir_entity *ent = get_irg_entity(irg);
1102         const char *irg_name = get_entity_ld_name(ent);
1103         be_emit_write_line();
1104         be_emit_irprintf("\t.size  %s, .-%s\n", irg_name, irg_name);
1105         be_emit_cstring("# -- End ");
1106         be_emit_string(irg_name);
1107         be_emit_cstring("\n");
1108         be_emit_write_line();
1109 }
1110
1111 static void sparc_gen_labels(ir_node *block, void *env)
1112 {
1113         ir_node *pred;
1114         int n = get_Block_n_cfgpreds(block);
1115         (void) env;
1116
1117         for (n--; n >= 0; n--) {
1118                 pred = get_Block_cfgpred(block, n);
1119                 set_irn_link(pred, block); // link the pred of a block (which is a jmp)
1120         }
1121 }
1122
1123 void sparc_emit_routine(ir_graph *irg)
1124 {
1125         ir_entity  *entity = get_irg_entity(irg);
1126         ir_node   **block_schedule;
1127         int         i;
1128         int         n;
1129
1130         be_gas_elf_type_char      = '#';
1131         be_gas_object_file_format = OBJECT_FILE_FORMAT_ELF_SPARC;
1132
1133         heights = heights_new(irg);
1134
1135         /* register all emitter functions */
1136         sparc_register_emitters();
1137         be_dbg_method_begin(entity);
1138
1139         /* create the block schedule. For now, we don't need it earlier. */
1140         block_schedule = be_create_block_schedule(irg);
1141
1142         sparc_emit_func_prolog(irg);
1143         irg_block_walk_graph(irg, sparc_gen_labels, NULL, NULL);
1144
1145         /* inject block scheduling links & emit code of each block */
1146         n = ARR_LEN(block_schedule);
1147         for (i = 0; i < n; ++i) {
1148                 ir_node *block      = block_schedule[i];
1149                 ir_node *next_block = i+1 < n ? block_schedule[i+1] : NULL;
1150                 set_irn_link(block, next_block);
1151         }
1152
1153         for (i = 0; i < n; ++i) {
1154                 ir_node *block = block_schedule[i];
1155                 if (block == get_irg_end_block(irg))
1156                         continue;
1157                 sparc_emit_block(block);
1158         }
1159
1160         /* emit function epilog */
1161         sparc_emit_func_epilog(irg);
1162
1163         heights_free(heights);
1164 }
1165
1166 void sparc_init_emitter(void)
1167 {
1168         FIRM_DBG_REGISTER(dbg, "firm.be.sparc.emit");
1169 }