1 /* The codegenrator (transform FIRM into arm FIRM */
19 #include "../benode_t.h"
20 #include "bearch_arm_t.h"
22 #include "arm_nodes_attr.h"
23 #include "../arch/archop.h" /* we need this for Min and Max nodes */
24 #include "arm_transform.h"
25 #include "arm_new_nodes.h"
26 #include "arm_map_regs.h"
28 #include "gen_arm_regalloc_if.h"
32 extern ir_op *get_op_Mulh(void);
36 /****************************************************************************************************
38 * | | | | / _| | | (_)
39 * _ __ ___ __| | ___ | |_ _ __ __ _ _ __ ___| |_ ___ _ __ _ __ ___ __ _| |_ _ ___ _ __
40 * | '_ \ / _ \ / _` |/ _ \ | __| '__/ _` | '_ \/ __| _/ _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \
41 * | | | | (_) | (_| | __/ | |_| | | (_| | | | \__ \ || (_) | | | | | | | | (_| | |_| | (_) | | | |
42 * |_| |_|\___/ \__,_|\___| \__|_| \__,_|_| |_|___/_| \___/|_| |_| |_| |_|\__,_|\__|_|\___/|_| |_|
44 ****************************************************************************************************/
46 typedef struct vals_ {
48 unsigned char values[4];
49 unsigned char shifts[4];
52 static vals construct_vals(void) {
53 vals result = { 0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } };
57 static vals gen_vals_from_word(unsigned int value)
59 vals result = construct_vals();
62 if ((value & 3) == 0) {
66 result.values[result.ops] = value & 0xff;
67 result.shifts[result.ops] = cur_offset;
76 static ir_node *create_const_node(arm_transform_env_t *env, int value) {
77 ir_node *result = new_rd_arm_Const(env->dbg, env->irg, env->block, env->mode);
78 get_arm_attr(result)->value = new_tarval_from_long(value, env->mode);
82 #define NEW_BINOP_NODE(opname, env, op1, op2) new_rd_arm_##opname(env->dbg, env->irg, env->block, op1, op2, env->mode)
84 unsigned int create_shifter_operand(unsigned int shift, unsigned int immediate) {
85 return immediate | ((shift>>1)<<8);
88 static ir_node *create_const_graph_value(arm_transform_env_t *env, unsigned int value) {
92 if (value < 0x100 || ~value < 0x100 ) {
93 if ( ~value < 0x100 ) {
97 result = create_const_node(env, value);
100 vals v1 = gen_vals_from_word(value);
101 vals v2 = gen_vals_from_word(~value);
104 result = new_rd_arm_Const_Neg(env->dbg, env->irg, env->block, env->mode);
105 set_arm_value(result, new_tarval_from_long(create_shifter_operand(v2.shifts[0], v2.values[0]), mode_Iu));
107 if ( v2.ops < v1.ops ) {
113 if (v.shifts[cnt] == 0) {
114 result = create_const_node(env, v.values[cnt]);
116 result = create_const_node(env, create_shifter_operand(v.shifts[cnt], v.values[cnt]));
120 ir_node *const_node = create_const_node(env, v.values[cnt]);
121 ir_node *orr_i_node = new_rd_arm_Or_i(env->dbg, env->irg, env->block, result, env->mode);
122 set_arm_value(orr_i_node, new_tarval_from_long(create_shifter_operand(v.shifts[cnt], v.values[cnt]), mode_Iu));
129 result = new_rd_arm_Not(env->dbg, env->irg, env->block, result, env->mode);
134 // static ir_node *create_const_graph_value(arm_transform_env_t *env, unsigned int value) {
135 // ir_node *irn = env->irn;
139 // if ( ~value < 0x100 ) {
144 // if (value < 0x100) {
145 // return create_const_node(env, value);
147 // vals v = gen_vals_from_word(value);
149 // ir_node *mov_val = create_const_node(env, v.values[cnt]);
150 // if (v.shifts[cnt] != 0) {
151 // ir_node *shift_node = new_rd_arm_Shl_i(env->dbg, env->irg, env->block, mov_val, env->mode);
152 // set_arm_value(shift_node, new_tarval_from_long(v.shifts[cnt], mode_Iu));
153 // result = shift_node;
158 // while(cnt < v.ops) {
159 // ir_node *const_node = create_const_node(env, v.values[cnt]);
160 // ir_node *orr_i_node = new_rd_arm_Or_i(env->dbg, env->irg, env->block, result, env->mode);
161 // unsigned shift = v.shifts[cnt];
162 // unsigned immediate = v.values[cnt];
163 // unsigned immediate_with_shift = immediate | ((shift>>1)<<8);
164 // set_arm_value(orr_i_node, new_tarval_from_long(immediate_with_shift, mode_Iu));
165 // result = orr_i_node;
172 static ir_node *create_const_graph(arm_transform_env_t *env) {
173 int value = get_tarval_long(get_Const_tarval(env->irn));
174 return create_const_graph_value(env, value);
179 static ir_node *gen_Const(arm_transform_env_t *env) {
181 assert(env->mode != mode_E && "IEEE Extended FP not supported");
182 if (env->mode == mode_F) {
183 result = new_rd_arm_fConst(env->dbg, env->irg, env->block, env->mode);
184 get_arm_attr(result)->value = get_Const_tarval(env->irn);
185 } else if (env->mode == mode_D) {
186 result = new_rd_arm_fConst(env->dbg, env->irg, env->block, env->mode);
187 get_arm_attr(result)->value = get_Const_tarval(env->irn);
188 } else if (env->mode == mode_P) {
191 result = create_const_graph(env);
196 static ir_node *gen_mask(arm_transform_env_t *env, ir_node *op, int result_bits) {
197 unsigned mask_bits = (1 << result_bits) - 1;
198 ir_node *mask_node = create_const_graph_value(env, mask_bits);
199 return new_rd_arm_And(env->dbg, env->irg, env->block, op, mask_node, get_irn_mode(env->irn));
202 static ir_node *gen_sign_extension(arm_transform_env_t *env, ir_node *op, int result_bits) {
203 int shift_width = 32 - result_bits;
204 ir_node *shift_const_node = create_const_graph_value(env, shift_width);
205 ir_node *lshift_node = new_rd_arm_Shl(env->dbg, env->irg, env->block, op, shift_const_node, get_irn_mode(op));
206 ir_node *rshift_node = new_rd_arm_Shrs(env->dbg, env->irg, env->block, lshift_node, shift_const_node, get_irn_mode(env->irn));
210 static ir_node *gen_Conv(arm_transform_env_t *env, ir_node *op) {
211 ir_mode *in_mode = get_irn_mode(op);
212 ir_mode *out_mode = env->mode;
214 assert( in_mode != mode_E && "");
215 assert( in_mode != mode_Ls && "");
216 assert( in_mode != mode_Lu && "");
217 assert( out_mode != mode_E && "");
218 assert( out_mode != mode_Ls && "");
219 assert( out_mode != mode_Lu && "");
221 if (in_mode == out_mode)
224 if ((mode_is_int(in_mode) || mode_is_reference(in_mode))
225 && (mode_is_reference(out_mode) || mode_is_int(out_mode))) {
226 int in_bits = get_mode_size_bits(in_mode);
227 int out_bits = get_mode_size_bits(out_mode);
228 int in_sign = get_mode_sign(in_mode);
229 int out_sign = get_mode_sign(out_mode);
233 if (in_bits == out_bits && in_bits == 32)
237 // unsigned -> unsigned
239 // unsigned -> signed
240 // sign extension (31:16)=(15)
241 // signed -> unsigned
242 // maskieren (31:16)=0
245 if (in_bits == out_bits && out_bits < 32) {
246 if (in_sign && !out_sign) {
247 return gen_mask(env, op, out_bits);
249 return gen_sign_extension(env, op, out_bits);
254 // unsigned -> unsigned
256 // unsigned -> signed
258 // signed -> unsigned
259 // sign extension (31:16)=(15)
261 // sign extension (31:16)=(15)
262 if (in_bits < out_bits) {
264 return gen_sign_extension(env, op, out_bits);
271 // unsigned -> unsigned
272 // maskieren (31:16)=0
273 // unsigned -> signed
274 // maskieren (31:16)=0
275 // signed -> unsigned
276 // maskieren (31:16)=0
278 // sign extension (erledigt auch maskieren) (31:16)=(15)
279 if (in_bits > out_bits) {
280 if (in_sign && out_sign) {
281 return gen_sign_extension(env, op, out_bits);
283 return gen_mask(env, op, out_bits);
286 assert(0 && "recheck integer conversion logic!");
288 } else if (in_mode == mode_D && out_mode == mode_F) {
289 return new_rd_arm_fConvD2S(env->dbg, env->irg, env->block, op, env->mode);
290 } else if (in_mode == mode_F && out_mode == mode_D) {
291 return new_rd_arm_fConvS2D(env->dbg, env->irg, env->block, op, env->mode);
292 } else if (mode_is_int(in_mode) && mode_is_float(out_mode)) {
293 return env->irn; /* TODO: implement int->float conversion*/
294 } else if (mode_is_float(in_mode) && mode_is_int(out_mode)) {
295 return env->irn; /* TODO: implement float->int conversion*/
297 assert(0 && "not implemented conversion");
304 * Creates an arm Add.
306 * @param env The transformation environment
307 * @param op1 first operator
308 * @param op2 second operator
309 * @return the created arm Add node
311 static ir_node *gen_Add(arm_transform_env_t *env, ir_node *op1, ir_node *op2) {
312 ir_node *result = NULL;
313 assert(!mode_is_float(env->mode) || (get_irn_mode(op1)->sort == get_irn_mode(op2)->sort));
314 assert(env->mode != mode_E && "IEEE Extended FP not supported");
316 if (env->mode == mode_F) {
317 result = new_rd_arm_fAdds(env->dbg, env->irg, env->block, op1, op2, env->mode);
318 } else if (env->mode == mode_D) {
319 result = new_rd_arm_fAddd(env->dbg, env->irg, env->block, op1, op2, env->mode);
320 } else if (mode_is_numP(env->mode)) {
321 if (is_arm_Const(op1)) {
322 result = new_rd_arm_Add_i(env->dbg, env->irg, env->block, op2, env->mode);
323 set_arm_value(result, get_arm_value(op1));
324 } else if (is_arm_Const(op2)) {
325 result = new_rd_arm_Add_i(env->dbg, env->irg, env->block, op1, env->mode);
326 set_arm_value(result, get_arm_value(op2));
328 result = new_rd_arm_Add(env->dbg, env->irg, env->block, op1, op2, env->mode);
331 assert(0 && "unknown mode for add");
339 * Creates an arm Mul.
341 * @param dbg firm node dbg
342 * @param block the block the new node should belong to
343 * @param op1 first operator
344 * @param op2 second operator
345 * @param mode node mode
346 * @return the created arm Mul node
348 static ir_node *gen_Mul(arm_transform_env_t *env, ir_node *op1, ir_node *op2) {
349 assert(!mode_is_float(env->mode) || (get_irn_mode(op1)->sort == get_irn_mode(op2)->sort));
350 assert(env->mode != mode_E && "IEEE Extended FP not supported");
352 if (env->mode == mode_F) {
353 return new_rd_arm_fMuls(env->dbg, env->irg, env->block, op1, op2, env->mode);
355 if (env->mode == mode_D) {
356 return new_rd_arm_fMuld(env->dbg, env->irg, env->block, op1, op2, env->mode);
358 return new_rd_arm_Mul(env->dbg, env->irg, env->block, op1, op2, env->mode);
363 * Creates an arm floating Div.
365 * @param dbg firm node dbg
366 * @param block the block the new node should belong to
367 * @param op1 first operator
368 * @param op2 second operator
369 * @param mode node mode
370 * @return the created arm fDiv node
372 static ir_node *gen_Quot(arm_transform_env_t *env, ir_node *op1, ir_node *op2) {
373 // assert(mode_is_float(env->mode) && "only floating point supported");
374 assert(get_irn_mode(op1)->sort == get_irn_mode(op2)->sort);
375 assert(mode_is_float(get_irn_mode(op1)));
376 assert(get_irn_mode(op1) != mode_E && "IEEE Extended FP not supported");
378 if (get_irn_mode(op1) == mode_F) {
379 return new_rd_arm_fDivs(env->dbg, env->irg, env->block, op1, op2, env->mode);
381 return new_rd_arm_fDivd(env->dbg, env->irg, env->block, op1, op2, env->mode);
386 * Creates an arm And.
388 * @param dbg firm node dbg
389 * @param block the block the new node should belong to
390 * @param op1 first operator
391 * @param op2 second operator
392 * @param mode node mode
393 * @return the created arm And node
395 static ir_node *gen_And(arm_transform_env_t *env, ir_node *op1, ir_node *op2) {
397 if (is_arm_Const(op1)) {
398 result = new_rd_arm_And_i(env->dbg, env->irg, env->block, op2, env->mode);
399 set_arm_value(result, get_arm_value(op1));
400 } else if (is_arm_Const(op2)) {
401 result = new_rd_arm_And_i(env->dbg, env->irg, env->block, op1, env->mode);
402 set_arm_value(result, get_arm_value(op2));
404 result = new_rd_arm_And(env->dbg, env->irg, env->block, op1, op2, env->mode);
414 * @param dbg firm node dbg
415 * @param block the block the new node should belong to
416 * @param op1 first operator
417 * @param op2 second operator
418 * @param mode node mode
419 * @return the created arm Or node
421 static ir_node *gen_Or(arm_transform_env_t *env, ir_node *op1, ir_node *op2) {
423 if (is_arm_Const(op1)) {
424 result = new_rd_arm_Or_i(env->dbg, env->irg, env->block, op2, env->mode);
425 set_arm_value(result, get_arm_value(op1));
426 } else if (is_arm_Const(op2)) {
427 result = new_rd_arm_Or_i(env->dbg, env->irg, env->block, op1, env->mode);
428 set_arm_value(result, get_arm_value(op2));
430 result = new_rd_arm_Or(env->dbg, env->irg, env->block, op1, op2, env->mode);
438 * Creates an arm Eor.
440 * @param dbg firm node dbg
441 * @param block the block the new node should belong to
442 * @param op1 first operator
443 * @param op2 second operator
444 * @param mode node mode
445 * @return the created arm Eor node
447 static ir_node *gen_Eor(arm_transform_env_t *env, ir_node *op1, ir_node *op2) {
449 if (is_arm_Const(op1)) {
450 result = new_rd_arm_Eor_i(env->dbg, env->irg, env->block, op2, env->mode);
451 set_arm_value(result, get_arm_value(op1));
452 } else if (is_arm_Const(op2)) {
453 result = new_rd_arm_Eor_i(env->dbg, env->irg, env->block, op1, env->mode);
454 set_arm_value(result, get_arm_value(op2));
456 result = new_rd_arm_Eor(env->dbg, env->irg, env->block, op1, op2, env->mode);
464 * Creates an arm Sub.
466 * @param dbg firm node dbg
467 * @param block the block the new node should belong to
468 * @param op1 first operator
469 * @param op2 second operator
470 * @param mode node mode
471 * @return the created arm Sub node
473 static ir_node *gen_Sub(arm_transform_env_t *env, ir_node *op1, ir_node *op2) {
474 ir_node *result = NULL;
475 assert(!mode_is_float(env->mode) || (get_irn_mode(op1)->sort == get_irn_mode(op2)->sort));
476 assert(env->mode != mode_E && "IEEE Extended FP not supported");
478 if (env->mode == mode_F) {
479 result = new_rd_arm_fSubs(env->dbg, env->irg, env->block, op1, op2, env->mode);
480 } else if (env->mode == mode_D) {
481 result = new_rd_arm_fSubd(env->dbg, env->irg, env->block, op1, op2, env->mode);
482 } else if (mode_is_numP(env->mode)) {
483 if (is_arm_Const(op2)) {
484 result = new_rd_arm_Sub_i(env->dbg, env->irg, env->block, op1, env->mode);
485 set_arm_value(result, get_arm_value(op2));
487 result = new_rd_arm_Sub(env->dbg, env->irg, env->block, op1, op2, env->mode);
490 assert(0 && "unknown mode for sub");
496 * Creates an arm Shl.
498 * @param dbg firm node dbg
499 * @param block the block the new node should belong to
500 * @param op1 first operator
501 * @param op2 second operator
502 * @param mode node mode
503 * @return the created arm Shl node
505 static ir_node *gen_Shl(arm_transform_env_t *env, ir_node *op1, ir_node *op2) {
507 if (is_arm_Const(op2)) {
508 result = new_rd_arm_Shl_i(env->dbg, env->irg, env->block, op1, env->mode);
509 set_arm_value(result, get_arm_value(op2));
511 result = new_rd_arm_Shl(env->dbg, env->irg, env->block, op1, op2, env->mode);
519 * Creates an arm Shr.
521 * @param dbg firm node dbg
522 * @param block the block the new node should belong to
523 * @param op1 first operator
524 * @param op2 second operator
525 * @param mode node mode
526 * @return the created arm Shr node
528 static ir_node *gen_Shr(arm_transform_env_t *env, ir_node *op1, ir_node *op2) {
530 if (is_arm_Const(op2)) {
531 result = new_rd_arm_Shr_i(env->dbg, env->irg, env->block, op1, env->mode);
532 set_arm_value(result, get_arm_value(op2));
534 result = new_rd_arm_Shr(env->dbg, env->irg, env->block, op1, op2, env->mode);
540 * Creates an arm Shrs.
542 * @param dbg firm node dbg
543 * @param block the block the new node should belong to
544 * @param op1 first operator
545 * @param op2 second operator
546 * @param mode node mode
547 * @return the created arm Shrs node
549 static ir_node *gen_Shrs(arm_transform_env_t *env, ir_node *op1, ir_node *op2) {
551 if (is_arm_Const(op2)) {
552 result = new_rd_arm_Shrs_i(env->dbg, env->irg, env->block, op1, env->mode);
553 set_arm_value(result, get_arm_value(op2));
555 result = new_rd_arm_Shrs(env->dbg, env->irg, env->block, op1, op2, env->mode);
561 * Transforms a Not node.
563 * @param mod the debug module
564 * @param block the block the new node should belong to
565 * @param node the ir Not node
567 * @param mode node mode
568 * @return the created arm Not node
570 static ir_node *gen_Not(arm_transform_env_t *env, ir_node *op) {
571 return new_rd_arm_Not(env->dbg, env->irg, env->block, op, env->mode);
575 static ir_node *gen_Abs(arm_transform_env_t *env, ir_node *op) {
576 assert(env->mode != mode_E && "IEEE Extended FP not supported");
578 if (env->mode == mode_F) {
579 return new_rd_arm_fAbss(env->dbg, env->irg, env->block, op, env->mode);
581 if (env->mode == mode_D) {
582 return new_rd_arm_fAbsd(env->dbg, env->irg, env->block, op, env->mode);
585 return new_rd_arm_Abs(env->dbg, env->irg, env->block, op, env->mode);
590 * Transforms a Minus node.
592 * @param mod the debug module
593 * @param block the block the new node should belong to
594 * @param node the ir Minus node
596 * @param mode node mode
597 * @return the created arm Minus node
599 static ir_node *gen_Minus(arm_transform_env_t *env, ir_node *op) {
600 if (mode_is_float(env->mode)) {
601 return new_rd_arm_fMinus(env->dbg, env->irg, env->block, op, env->mode);
603 return new_rd_arm_Minus(env->dbg, env->irg, env->block, op, env->mode);
610 * @param mod the debug module
611 * @param block the block the new node should belong to
612 * @param node the ir Load node
613 * @param mode node mode
614 * @return the created arm Load node
616 static ir_node *gen_Load(arm_transform_env_t *env) {
617 ir_node *node = env->irn;
618 ir_mode *mode = get_Load_mode(node);
620 // const ir_edge_t *edge;
622 // foreach_out_edge(node, edge) {
623 // ir_node* proj = get_edge_src_irn(edge);
624 // long nr = get_Proj_proj(proj);
625 // if ( nr == pn_Load_res )
626 // mode = proj->mode;
628 // besser: get_Load_mode() verwenden!
630 assert(mode!=NULL && "irgendwie hat das load kein proj fuers result");
632 return new_rd_arm_fLoads(env->dbg, env->irg, env->block, get_Load_ptr(node), get_Load_mem(node), env->mode);
635 return new_rd_arm_fLoadd(env->dbg, env->irg, env->block, get_Load_ptr(node), get_Load_mem(node), env->mode);
637 if (mode == mode_Bu) {
638 return new_rd_arm_Loadb(env->dbg, env->irg, env->block, get_Load_ptr(node), get_Load_mem(node), env->mode);
640 if (mode == mode_Bs) {
641 return new_rd_arm_Loadbs(env->dbg, env->irg, env->block, get_Load_ptr(node), get_Load_mem(node), env->mode);
643 if (mode == mode_Hu) {
644 return new_rd_arm_Loadh(env->dbg, env->irg, env->block, get_Load_ptr(node), get_Load_mem(node), env->mode);
646 if (mode == mode_Hs) {
647 return new_rd_arm_Loadhs(env->dbg, env->irg, env->block, get_Load_ptr(node), get_Load_mem(node), env->mode);
649 if (mode_is_reference(mode)) {
650 return new_rd_arm_Load(env->dbg, env->irg, env->block, get_Load_ptr(node), get_Load_mem(node), env->mode);
652 return new_rd_arm_Load(env->dbg, env->irg, env->block, get_Load_ptr(node), get_Load_mem(node), env->mode);
658 * Transforms a Store.
660 * @param mod the debug module
661 * @param block the block the new node should belong to
662 * @param node the ir Store node
663 * @param mode node mode
664 * @return the created arm Store node
666 static ir_node *gen_Store(arm_transform_env_t *env) {
667 ir_node *node = env->irn;
668 ir_mode *mode = get_irn_mode(get_Store_value(node));
669 assert(env->mode != mode_E && "IEEE Extended FP not supported");
671 if (mode == mode_F) {
672 return new_rd_arm_fStores(env->dbg, env->irg, env->block, get_Store_ptr(node), get_Store_value(node), get_Store_mem(node), env->mode);
674 if (mode == mode_D) {
675 return new_rd_arm_fStored(env->dbg, env->irg, env->block, get_Store_ptr(node), get_Store_value(node), get_Store_mem(node), env->mode);
677 if (mode == mode_Bu) {
678 return new_rd_arm_Storeb(env->dbg, env->irg, env->block, get_Store_ptr(node), get_Store_value(node), get_Store_mem(node), env->mode);
680 if (mode == mode_Bs) {
681 return new_rd_arm_Storebs(env->dbg, env->irg, env->block, get_Store_ptr(node), get_Store_value(node), get_Store_mem(node), env->mode);
683 if (mode == mode_Hu) {
684 return new_rd_arm_Storeh(env->dbg, env->irg, env->block, get_Store_ptr(node), get_Store_value(node), get_Store_mem(node), env->mode);
686 if (mode == mode_Hs) {
687 return new_rd_arm_Storehs(env->dbg, env->irg, env->block, get_Store_ptr(node), get_Store_value(node), get_Store_mem(node), env->mode);
689 return new_rd_arm_Store(env->dbg, env->irg, env->block, get_Store_ptr(node), get_Store_value(node), get_Store_mem(node), env->mode);
693 static ir_node *gen_Cond(arm_transform_env_t *env) {
694 ir_node *result = NULL;
695 ir_node *selector = get_Cond_selector(env->irn);
696 ir_node *irn = env->irn;
698 if ( get_irn_mode(selector) == mode_b ) {
700 ir_node *proj_node = get_Cond_selector(irn);
701 ir_node *cmp_node = get_Proj_pred(proj_node);
702 ir_node *op1 = get_Cmp_left(cmp_node);
703 ir_node *op2 = get_Cmp_right(cmp_node);
704 result = new_rd_arm_CondJmp(env->dbg, env->irg, env->block, op1, op2, mode_T);
705 set_arm_proj_num(result, get_Proj_proj(proj_node));
708 ir_node *op = get_irn_n(env->irn, 0);
709 ir_node *const_graph;
714 const ir_edge_t *edge;
721 arm_transform_env_t const_env;
725 foreach_out_edge(irn, edge) {
726 proj = get_edge_src_irn(edge);
727 assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
729 pn = get_Proj_proj(proj);
731 min = pn<min ? pn : min;
732 max = pn>max ? pn : max;
735 norm_max = max - translation;
736 norm_min = min - translation;
738 n_projs = norm_max + 1;
739 projs = xcalloc(n_projs , sizeof(ir_node*));
742 foreach_out_edge(irn, edge) {
743 proj = get_edge_src_irn(edge);
744 assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
746 pn = get_Proj_proj(proj) - translation;
747 set_Proj_proj(proj, pn);
751 const_node = new_rd_Const(env->dbg, env->irg, env->block, mode_Iu, new_tarval_from_long(translation, mode_Iu));
753 const_env.mode = mode_Is;
754 const_env.irn = const_node;
755 const_graph = gen_Const(&const_env);
756 sub = new_rd_arm_Sub(env->dbg, env->irg, env->block, op, const_graph, get_irn_mode(op));
757 result = new_rd_arm_SwitchJmp(env->dbg, env->irg, env->block, sub, mode_T);
758 set_arm_n_projs(result, n_projs);
759 set_arm_default_proj_num(result, get_Cond_defaultProj(irn)-translation);
765 * Returns the name of a SymConst.
766 * @param symc the SymConst
767 * @return name of the SymConst
769 const char *get_sc_name(ir_node *symc) {
770 if (get_irn_opcode(symc) != iro_SymConst)
773 switch (get_SymConst_kind(symc)) {
774 case symconst_addr_name:
775 return get_id_str(get_SymConst_name(symc));
777 case symconst_addr_ent:
778 return get_entity_ld_name(get_SymConst_entity(symc));
781 assert(0 && "Unsupported SymConst");
787 static ir_node *gen_SymConst(arm_transform_env_t *env) {
789 const char *str = get_sc_name(env->irn);
790 result = new_rd_arm_SymConst(env->dbg, env->irg, env->block, env->mode);
791 set_arm_symconst_label(result, str);
800 * Transforms a CopyB node.
802 * @param env The transformation environment
803 * @return The transformed node.
805 static ir_node *gen_CopyB(arm_transform_env_t *env) {
807 dbg_info *dbg = env->dbg;
808 ir_graph *irg = env->irg;
809 ir_mode *mode = env->mode;
810 ir_node *block = env->block;
811 ir_node *node = env->irn;
812 ir_node *src = get_CopyB_src(node);
813 ir_node *dst = get_CopyB_dst(node);
814 ir_node *mem = get_CopyB_mem(node);
815 int size = get_type_size_bytes(get_CopyB_type(node));
819 arm_transform_env_t const_env;
820 const_env.block = block;
823 const_env.irn = node;
824 DEBUG_ONLY(const_env.mod = env->mod;)
825 const_env.mode = mode_Iu;
827 src_copy = be_new_Copy(&arm_reg_classes[CLASS_arm_general_purpose], irg, block, src);
828 dst_copy = be_new_Copy(&arm_reg_classes[CLASS_arm_general_purpose], irg, block, dst);
830 res = new_rd_arm_CopyB( dbg, irg, block, dst_copy, src_copy, new_rd_arm_EmptyReg(dbg, irg, block, mode_Iu), new_rd_arm_EmptyReg(dbg, irg, block, mode_Iu), new_rd_arm_EmptyReg(dbg, irg, block, mode_Iu), mem, mode);
831 set_arm_value(res, new_tarval_from_long(size, mode_Iu));
840 // /************************************************************************/
841 // /* be transforms */
842 // /************************************************************************/
844 // static ir_node *gen_be_Copy(arm_transform_env_t *env, ir_node *op) {
845 // return new_rd_arm_Copy(env->dbg, env->irg, env->block, op, env->mode);
848 /*********************************************************
851 * _ __ ___ __ _ _ _ __ __| |_ __ ___ _____ _ __
852 * | '_ ` _ \ / _` | | '_ \ / _` | '__| \ \ / / _ \ '__|
853 * | | | | | | (_| | | | | | | (_| | | | |\ V / __/ |
854 * |_| |_| |_|\__,_|_|_| |_| \__,_|_| |_| \_/ \___|_|
856 *********************************************************/
858 /************************************************************************/
859 /* move constants out of startblock */
860 /************************************************************************/
861 void arm_move_consts(ir_node *node, void *env) {
862 arm_code_gen_t *cgenv = (arm_code_gen_t *)env;
867 for (i=0; i<get_irn_arity(node); i++) {
868 ir_node *pred = get_irn_n(node,i);
869 opcode pred_code = get_irn_opcode(pred);
870 if (pred_code == iro_Const) {
871 ir_node *const_graph;
872 arm_transform_env_t tenv;
873 tenv.block = get_nodes_block(get_irn_n(get_nodes_block(node),i));
874 tenv.dbg = get_irn_dbg_info(pred);
875 tenv.irg = current_ir_graph;
877 DEBUG_ONLY(tenv.mod = cgenv->mod;)
878 tenv.mode = get_irn_mode(pred);
879 const_graph = create_const_graph(&tenv);
880 set_irn_n(node, i, const_graph);
881 } else if (pred_code == iro_SymConst) {
882 const char *str = get_sc_name(pred);
883 ir_node *symconst_node;
884 symconst_node = new_rd_arm_SymConst(get_irn_dbg_info(pred),
885 current_ir_graph, get_nodes_block(get_irn_n(get_nodes_block(node),i)), get_irn_mode(pred));
886 set_arm_symconst_label(symconst_node, str);
887 set_irn_n(node, i, symconst_node);
892 for (i=0; i<get_irn_arity(node); i++) {
893 ir_node *pred = get_irn_n(node,i);
894 opcode pred_code = get_irn_opcode(pred);
895 if (pred_code == iro_Const) {
896 ir_node *const_graph;
897 arm_transform_env_t tenv;
898 tenv.block = get_nodes_block(node);
899 tenv.dbg = get_irn_dbg_info(pred);
900 tenv.irg = current_ir_graph;
902 DEBUG_ONLY(tenv.mod = cgenv->mod;)
903 tenv.mode = get_irn_mode(pred);
904 const_graph = create_const_graph(&tenv);
905 set_irn_n(node, i, const_graph);
906 } else if (pred_code == iro_SymConst) {
907 const char *str = get_sc_name(pred);
908 ir_node *symconst_node;
909 symconst_node = new_rd_arm_SymConst(get_irn_dbg_info(pred),
910 current_ir_graph, get_nodes_block(node), get_irn_mode(pred));
911 set_arm_symconst_label(symconst_node, str);
912 set_irn_n(node, i, symconst_node);
918 /************************************************************************/
919 /* move symbolic constants out of startblock */
920 /************************************************************************/
921 void arm_move_symconsts(ir_node *node, void *env) {
927 for (i = 0; i < get_irn_arity(node); i++) {
928 ir_node *pred = get_irn_n(node,i);
929 opcode pred_code = get_irn_opcode(pred);
931 if (pred_code == iro_SymConst) {
932 const char *str = get_sc_name(pred);
933 ir_node *symconst_node;
935 symconst_node = new_rd_arm_SymConst(get_irn_dbg_info(pred),
936 current_ir_graph, get_nodes_block(node), get_irn_mode(pred));
938 set_arm_symconst_label(symconst_node, str);
939 set_irn_n(node, i, symconst_node);
946 * Transforms the given firm node (and maybe some other related nodes)
947 * into one or more assembler nodes.
949 * @param node the firm node
950 * @param env the debug module
952 void arm_transform_node(ir_node *node, void *env) {
953 arm_code_gen_t *cgenv = (arm_code_gen_t *)env;
954 opcode code = get_irn_opcode(node);
955 ir_node *asm_node = NULL;
956 arm_transform_env_t tenv;
961 tenv.block = get_nodes_block(node);
962 tenv.dbg = get_irn_dbg_info(node);
963 tenv.irg = current_ir_graph;
965 DEBUG_ONLY(tenv.mod = cgenv->mod;)
966 tenv.mode = get_irn_mode(node);
968 #define UNOP(a) case iro_##a: asm_node = gen_##a(&tenv, get_##a##_op(node)); break
969 #define BINOP(a) case iro_##a: asm_node = gen_##a(&tenv, get_##a##_left(node), get_##a##_right(node)); break
970 #define GEN(a) case iro_##a: asm_node = gen_##a(&tenv); break
971 #define IGN(a) case iro_##a: break
972 #define BAD(a) case iro_##a: goto bad
974 DBG((tenv.mod, LEVEL_1, "check %+F ... ", node));
994 GEN(Const); // TODO: floating point consts
995 UNOP(Conv); // TODO: floating point conversions
1001 GEN(Cond); // integer done
1003 /* TODO: implement these nodes */
1005 IGN(Div); // intrinsic lowering
1006 IGN(Mod); // intrinsic lowering
1007 IGN(DivMod); // TODO: implement DivMod
1011 IGN(Cmp); // done, implemented in cond
1013 /* You probably don't need to handle the following nodes */
1025 IGN(Jmp); // emitter done
1044 if (get_irn_op(node) == get_op_Max() ||
1045 get_irn_op(node) == get_op_Min() ||
1046 get_irn_op(node) == get_op_Mulh())
1048 /* TODO: implement */
1049 /* ignore for now */
1053 fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node));
1058 exchange(node, asm_node);
1059 DB((tenv.mod, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
1062 DB((tenv.mod, LEVEL_1, "ignored\n"));