b3e9cb4e04309b2a0be34ba218838fb3c3a603d7
[libfirm] / ir / be / sparc / sparc_emitter.c
1 /*
2  * Copyright (C) 1995-2008 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: sparc_emitter.c 26542 2009-09-18 09:18:32Z matze $
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
55 #define SNPRINTF_BUF_LEN 128
56 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
57
58 static set *sym_or_tv;
59
60 /**
61  * Returns the register at in position pos.
62  */
63 static const arch_register_t *get_in_reg(const ir_node *node, int pos)
64 {
65         ir_node                *op;
66         const arch_register_t  *reg = NULL;
67
68         assert(get_irn_arity(node) > pos && "Invalid IN position");
69
70         /* The out register of the operator at position pos is the
71            in register we need. */
72         op = get_irn_n(node, pos);
73
74         reg = arch_get_irn_register(op);
75
76         assert(reg && "no in register found");
77         return reg;
78 }
79
80 /**
81  * Returns the register at out position pos.
82  */
83 static const arch_register_t *get_out_reg(const ir_node *node, int pos)
84 {
85         ir_node                *proj;
86         const arch_register_t  *reg = NULL;
87
88         /* 1st case: irn is not of mode_T, so it has only                 */
89         /*           one OUT register -> good                             */
90         /* 2nd case: irn is of mode_T -> collect all Projs and ask the    */
91         /*           Proj with the corresponding projnum for the register */
92
93         if (get_irn_mode(node) != mode_T) {
94                 reg = arch_get_irn_register(node);
95         } else if (is_sparc_irn(node)) {
96                 reg = arch_irn_get_register(node, pos);
97         } else {
98                 const ir_edge_t *edge;
99
100                 foreach_out_edge(node, edge) {
101                         proj = get_edge_src_irn(edge);
102                         assert(is_Proj(proj) && "non-Proj from mode_T node");
103                         if (get_Proj_proj(proj) == pos) {
104                                 reg = arch_get_irn_register(proj);
105                                 break;
106                         }
107                 }
108         }
109
110         assert(reg && "no out register found");
111         return reg;
112 }
113
114 /*************************************************************
115  *             _       _    __   _          _
116  *            (_)     | |  / _| | |        | |
117  *  _ __  _ __ _ _ __ | |_| |_  | |__   ___| |_ __   ___ _ __
118  * | '_ \| '__| | '_ \| __|  _| | '_ \ / _ \ | '_ \ / _ \ '__|
119  * | |_) | |  | | | | | |_| |   | | | |  __/ | |_) |  __/ |
120  * | .__/|_|  |_|_| |_|\__|_|   |_| |_|\___|_| .__/ \___|_|
121  * | |                                       | |
122  * |_|                                       |_|
123  *************************************************************/
124
125 void sparc_emit_immediate(const ir_node *node)
126 {
127         // TODO: make sure it's a valid simm13 ?
128         const sparc_attr_t *attr = get_sparc_attr_const(node);
129         be_emit_irprintf("%d", attr->immediate_value);
130 }
131
132 void sparc_emit_source_register(const ir_node *node, int pos)
133 {
134         const arch_register_t *reg = get_in_reg(node, pos);
135         be_emit_char('%');
136         be_emit_string(arch_register_get_name(reg));
137 }
138
139 void sparc_emit_dest_register(const ir_node *node, int pos)
140 {
141         const arch_register_t *reg = get_out_reg(node, pos);
142         be_emit_char('%');
143         be_emit_string(arch_register_get_name(reg));
144 }
145
146 /**
147  * Emits either a imm or register depending on arity of node
148  * @param node
149  * @param register no (-1 if no register)
150  */
151 void sparc_emit_reg_or_imm(const ir_node *node, int pos)
152 {
153         if (get_irn_arity(node) > pos) {
154                 // we have reg input
155                 sparc_emit_source_register(node, pos);
156         } else {
157                 // we have a imm input
158                 sparc_emit_immediate(node);
159         }
160 }
161
162 void sparc_emit_offset(const ir_node *node)
163 {
164         (void) node;
165 }
166
167 /**
168  *  Emit load mode char
169  */
170 void sparc_emit_load_mode(const ir_node *node)
171 {
172         const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
173     ir_mode *mode      = attr->load_store_mode;
174     int      bits      = get_mode_size_bits(mode);
175     bool     is_signed = mode_is_signed(mode);
176
177     if (bits == 16) {
178         be_emit_string(is_signed ? "sh" : "uh");
179     } else if (bits == 8) {
180         be_emit_string(is_signed ? "sb" : "ub");
181     } else if (bits == 64) {
182         be_emit_string("d");
183     } else {
184         assert(bits == 32);
185     }
186 }
187
188 /**
189  * Emit store mode char
190  */
191 void sparc_emit_store_mode(const ir_node *node)
192 {
193         const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
194     ir_mode *mode      = attr->load_store_mode;
195     int      bits      = get_mode_size_bits(mode);
196
197     if (bits == 16) {
198         be_emit_string("h");
199     } else if (bits == 8) {
200         be_emit_string("b");
201     } else if (bits == 64) {
202         be_emit_string("d");
203     } else {
204         assert(bits == 32);
205     }
206 }
207
208 /**
209  * Returns the target label for a control flow node.
210  */
211 static void sparc_emit_cfop_target(const ir_node *node)
212 {
213         ir_node *block = get_irn_link(node);
214         be_emit_irprintf("BLOCK_%ld", get_irn_node_nr(block));
215 }
216
217 /**
218  * Emit single entity
219  */
220 static void sparc_emit_entity(ir_entity *entity)
221 {
222         set_entity_backend_marked(entity, 1);
223         be_emit_ident(get_entity_ld_ident(entity));
224 }
225
226 /***********************************************************************************
227  *                  _          __                                             _
228  *                 (_)        / _|                                           | |
229  *  _ __ ___   __ _ _ _ __   | |_ _ __ __ _ _ __ ___   _____      _____  _ __| | __
230  * | '_ ` _ \ / _` | | '_ \  |  _| '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ /
231  * | | | | | | (_| | | | | | | | | | | (_| | | | | | |  __/\ V  V / (_) | |  |   <
232  * |_| |_| |_|\__,_|_|_| |_| |_| |_|  \__,_|_| |_| |_|\___| \_/\_/ \___/|_|  |_|\_\
233  *
234  ***********************************************************************************/
235
236 /**
237  * Emits code for a unconditional jump.
238  */
239 static void emit_Jmp(const ir_node *node)
240 {
241         ir_node *block;
242
243         /* for now, the code works for scheduled and non-schedules blocks */
244         block = get_nodes_block(node);
245
246         be_emit_cstring("\tjmp ");
247         sparc_emit_cfop_target(node);
248         be_emit_finish_line_gas(node);
249 }
250
251
252 /**
253  * Emits code for stack space management
254  */
255 static void emit_be_IncSP(const ir_node *irn)
256 {
257         int offs = -be_get_IncSP_offset(irn);
258
259         if (offs != 0) {
260                 /* SPARC stack grows downwards */
261                 if (offs < 0) {
262                         be_emit_cstring("\tadd ");
263                         offs = -offs;
264                 } else {
265                         be_emit_cstring("\tsub ");
266                 }
267
268                 sparc_emit_source_register(irn, 0);
269                 be_emit_irprintf(", %d", offs);
270                 be_emit_cstring(", ");
271                 sparc_emit_dest_register(irn, 0);
272         } else {
273                 // ignore IncSP(0)
274                 //be_emit_cstring("\t/* IncSP(0) skipped */");
275                 be_emit_cstring("\t/* ");
276                 be_emit_cstring("sub ");
277                 offs = -offs;
278                 sparc_emit_source_register(irn, 0);
279                 be_emit_irprintf(", %d", offs);
280                 be_emit_cstring(", ");
281                 sparc_emit_dest_register(irn, 0);
282                 be_emit_cstring(" ignored */ ");
283         }
284
285         be_emit_finish_line_gas(irn);
286 }
287
288 /**
289  * Emits code for return node
290  */
291 static void emit_be_Return(const ir_node *irn)
292 {
293         be_emit_cstring("\tret");
294         be_emit_finish_line_gas(irn);
295 }
296
297 /**
298  * Emits code for Call node
299  */
300 static void emit_be_Call(const ir_node *irn)
301 {
302         ir_entity *entity = be_Call_get_entity(irn);
303
304         if (entity != NULL) {
305                 be_emit_cstring("\tcall ");
306             sparc_emit_entity(entity);
307                 be_emit_finish_line_gas(irn);
308                 be_emit_cstring("\tnop\t /* TODO: use delay slot */\n ");
309         } else {
310                 be_emit_cstring("\tnop\t /* TODO: Entity == NULL */\n ");
311                 /*
312                 be_emit_cstring("\tmov lr, pc");
313                 be_emit_finish_line_gas(irn);
314                 be_emit_cstring("\tmov pc, ");
315                 sparc_emit_source_register(irn, be_pos_Call_ptr);
316                 */
317                 be_emit_finish_line_gas(irn);
318         }
319 }
320
321 /** An entry in the sym_or_tv set. */
322 typedef struct sym_or_tv_t {
323         union {
324                 ident  *id;          /**< An ident. */
325                 tarval *tv;          /**< A tarval. */
326                 const void *generic; /**< For generic compare. */
327         } u;
328         unsigned label;      /**< the associated label. */
329         char is_ident;       /**< Non-zero if an ident is stored. */
330 } sym_or_tv_t;
331
332 /**
333  * Returns a unique label. This number will not be used a second time.
334  */
335 static unsigned get_unique_label(void) {
336         static unsigned id = 0;
337         return ++id;
338 }
339
340 /**
341  * Emit a SymConst.
342  */
343 static void emit_sparc_SymConst(const ir_node *irn)
344 {
345         const sparc_symconst_attr_t *attr = get_sparc_symconst_attr_const(irn);
346         sym_or_tv_t key, *entry;
347         unsigned label;
348
349         set_entity_backend_marked(attr->entity, 1);
350
351         key.u.id     = get_entity_ld_ident(attr->entity);
352         key.is_ident = 1;
353         key.label    = 0;
354         entry = (sym_or_tv_t *)set_insert(sym_or_tv, &key, sizeof(key), HASH_PTR(key.u.generic));
355         if (entry->label == 0) {
356                 /* allocate a label */
357                 entry->label = get_unique_label();
358         }
359
360         label = entry->label;
361
362         /* load the symbol indirect */
363         be_emit_cstring("\tld ");
364         be_emit_irprintf(".L%u, ", label);
365         sparc_emit_dest_register(irn, 0);
366         be_emit_finish_line_gas(irn);
367 }
368
369
370 /**
371  * Emits code for FrameAddr fix
372  */
373 static void emit_sparc_FrameAddr(const ir_node *irn)
374 {
375         const sparc_symconst_attr_t *attr = get_irn_generic_attr_const(irn);
376         be_emit_cstring("\tadd ");
377         sparc_emit_source_register(irn, 0);
378         be_emit_cstring(", ");
379         sparc_emit_dest_register(irn, 0);
380         be_emit_cstring(", ");
381         be_emit_irprintf("#0x%X", attr->fp_offset);
382         be_emit_finish_line_gas(irn);
383 }
384
385
386 /**
387  * Emits code for Branch
388  */
389 static void emit_sparc_Branch(const ir_node *irn)
390 {
391         (void) irn;
392 }
393
394 /**
395  * dummy emitter for ignored nodes
396  */
397 static void emit_nothing(const ir_node *irn)
398 {
399         (void) irn;
400 }
401
402
403
404 /**
405  * type of emitter function
406  */
407 typedef void (*emit_func) (const ir_node *);
408
409 /**
410  * Set a node emitter. Make it a bit more type safe.
411  */
412 static inline void set_emitter(ir_op *op, emit_func sparc_emit_node)
413 {
414         op->ops.generic = (op_func)sparc_emit_node;
415 }
416
417 /**
418  * Enters the emitter functions for handled nodes into the generic
419  * pointer of an opcode.
420  */
421 static void sparc_register_emitters(void)
422 {
423
424         /* first clear the generic function pointer for all ops */
425         clear_irp_opcodes_generic_func();
426
427         /* register all emitter functions defined in spec */
428         sparc_register_spec_emitters();
429
430         /* custom emitter */
431     set_emitter(op_be_IncSP,       emit_be_IncSP);
432     set_emitter(op_be_Return,      emit_be_Return);
433     set_emitter(op_be_Call,        emit_be_Call);
434     set_emitter(op_sparc_FrameAddr,  emit_sparc_FrameAddr);
435     set_emitter(op_sparc_Branch,   emit_sparc_Branch);
436     set_emitter(op_sparc_SymConst,   emit_sparc_SymConst);
437
438 /*
439     set_emitter(op_arm_B,          emit_arm_B);
440     set_emitter(op_arm_CopyB,      emit_arm_CopyB);
441     set_emitter(op_arm_fpaConst,   emit_arm_fpaConst);
442     set_emitter(op_arm_fpaDbl2GP,  emit_arm_fpaDbl2GP);
443     set_emitter(op_arm_Jmp,        emit_arm_Jmp);
444     set_emitter(op_arm_LdTls,      emit_arm_LdTls);
445     set_emitter(op_arm_SwitchJmp,  emit_arm_SwitchJmp);
446     set_emitter(op_be_Copy,        emit_be_Copy);
447     set_emitter(op_be_CopyKeep,    emit_be_Copy);
448     set_emitter(op_be_MemPerm,     emit_be_MemPerm);
449     set_emitter(op_be_Perm,        emit_be_Perm);
450 */
451     /* no need to emit anything for the following nodes */
452         set_emitter(op_Phi,            emit_nothing);
453         set_emitter(op_be_Keep,        emit_nothing);
454         set_emitter(op_be_Start,       emit_nothing);
455         set_emitter(op_be_Barrier,     emit_nothing);
456
457 }
458
459 /**
460  * Emits code for a node.
461  */
462 void sparc_emit_node(const ir_node *node)
463 {
464         ir_op               *op       = get_irn_op(node);
465
466         if (op->ops.generic) {
467                 emit_func func = (emit_func) op->ops.generic;
468                 be_dbg_set_dbg_info(get_irn_dbg_info(node));
469                 (*func) (node);
470         } else {
471                 panic("Error: No emit handler for node %+F (graph %+F)\n",
472                         node, current_ir_graph);
473         }
474 }
475
476 /**
477  * Walks over the nodes in a block connected by scheduling edges
478  * and emits code for each node.
479  */
480 void sparc_gen_block(ir_node *block, void *data) {
481         ir_node *node;
482         (void) data;
483
484         if (! is_Block(block))
485                 return;
486 /*
487         be_emit_cstring("BLOCK_");
488         be_emit_irprintf("%ld:\n", get_irn_node_nr(block));
489         be_emit_write_line();
490 */
491         sched_foreach(block, node) {
492                 sparc_emit_node(node);
493         }
494 }
495
496
497 /**
498  * Emits code for function start.
499  */
500 void sparc_emit_func_prolog(ir_graph *irg) {
501         ir_entity *ent = get_irg_entity(irg);
502         const char *irg_name = get_entity_ld_name(ent);
503
504         /* TODO: emit function header */
505         be_emit_cstring("# -- Begin ");
506         be_emit_string(irg_name);
507         be_emit_cstring("\n");
508
509
510         be_emit_write_line();
511         be_gas_emit_switch_section(GAS_SECTION_TEXT);
512         be_emit_cstring("\t.align  4\n");
513
514         if (get_entity_visibility(ent) == visibility_external_visible)
515                 be_emit_irprintf("\t.global %s\n", irg_name);
516
517         be_emit_cstring("\t/* .proc  n - n specifies which registers will contain the return value upon return from the procedure */\n");
518         be_emit_irprintf("\t.type %s, #function\n", irg_name);
519
520         be_emit_irprintf("%s:\n", irg_name);
521         // TODO: fetch reg names via API func
522         // TODO: move value to SPARC_MIN_STACKSIZE const
523         be_emit_cstring("\tsave %r14, -64, %r14");
524         be_emit_cstring("\t/* incr CWP and alloc min. required stack space */\n");
525         be_emit_write_line();
526 }
527
528 /**
529  * Emits code for function end
530  */
531 void sparc_emit_func_epilog(ir_graph *irg) {
532         ir_entity *ent = get_irg_entity(irg);
533         const char *irg_name = get_entity_ld_name(ent);
534
535         be_emit_cstring("\trestore");
536         be_emit_cstring("\t/* decr CWP */\n");
537         be_emit_irprintf("\t.size  %s, .-%s\n", irg_name, irg_name);
538         be_emit_cstring("# -- End ");
539         be_emit_string(irg_name);
540         be_emit_cstring("\n");
541         be_emit_write_line();
542 }
543
544 /**
545  * Sets labels for control flow nodes (jump target)
546  * TODO: Jump optimization
547  */
548 void sparc_gen_labels(ir_node *block, void *env) {
549         ir_node *pred;
550         int n = get_Block_n_cfgpreds(block);
551         (void) env;
552
553         for (n--; n >= 0; n--) {
554                 pred = get_Block_cfgpred(block, n);
555                 set_irn_link(pred, block);
556         }
557 }
558
559 /**
560  * Compare two entries of the symbol or tarval set.
561  */
562 static int cmp_sym_or_tv(const void *elt, const void *key, size_t size) {
563         const sym_or_tv_t *p1 = elt;
564         const sym_or_tv_t *p2 = key;
565         (void) size;
566
567         /* as an identifier NEVER can point to a tarval, it's enough
568                 to compare it this way */
569         return p1->u.generic != p2->u.generic;
570 }
571
572 void gen_symconst_values()
573 {
574         sym_or_tv = new_set(cmp_sym_or_tv, 8);
575
576         /* emit SymConst values */
577         if (set_count(sym_or_tv) > 0) {
578                 sym_or_tv_t *entry;
579
580                 be_emit_cstring("\t.align 2\n");
581
582                 foreach_set(sym_or_tv, entry) {
583                         be_emit_irprintf(".L%u:\n", entry->label);
584
585                         if (entry->is_ident) {
586                                 be_emit_cstring("\t.word\t");
587                                 be_emit_ident(entry->u.id);
588                                 be_emit_char('\n');
589                                 be_emit_write_line();
590                         } else {
591                                 tarval *tv = entry->u.tv;
592                                 int i, size = get_mode_size_bytes(get_tarval_mode(tv));
593                                 unsigned v;
594
595                                 /* TODO: beware: ARM fpa uses big endian format */
596                                 for (i = ((size + 3) & ~3) - 4; i >= 0; i -= 4) {
597                                         /* get 32 bits */
598                                         v =            get_tarval_sub_bits(tv, i+3);
599                                         v = (v << 8) | get_tarval_sub_bits(tv, i+2);
600                                         v = (v << 8) | get_tarval_sub_bits(tv, i+1);
601                                         v = (v << 8) | get_tarval_sub_bits(tv, i+0);
602                                         be_emit_irprintf("\t.word\t%u\n", v);
603                                         be_emit_write_line();
604                                 }
605                         }
606                 }
607                 be_emit_char('\n');
608                 be_emit_write_line();
609         }
610         del_set(sym_or_tv);
611 }
612
613 /**
614  * Main driver
615  */
616 void sparc_gen_routine(const sparc_code_gen_t *cg, ir_graph *irg)
617 {
618         ir_entity *entity     = get_irg_entity(irg);
619
620         /* register all emitter functions */
621         sparc_register_emitters();
622         be_dbg_method_begin(entity, be_abi_get_stack_layout(cg->birg->abi));
623         sparc_emit_func_prolog(irg);
624         irg_block_walk_graph(irg, sparc_gen_labels, NULL, NULL);
625         irg_walk_blkwise_graph(irg, NULL, sparc_gen_block, NULL);
626         sparc_emit_func_epilog(irg);
627
628         gen_symconst_values();
629 }
630
631 void sparc_init_emitter(void)
632 {
633         FIRM_DBG_REGISTER(dbg, "firm.be.sparc.emit");
634 }