fixed doxygen comment
[libfirm] / ir / be / arm / arm_transform.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   The codegenerator (transform FIRM into arm FIRM)
23  * @author  Oliver Richter, Tobias Gneist, Michael Beck
24  * @version $Id$
25  */
26 #include "config.h"
27
28 #include "irnode_t.h"
29 #include "irgraph_t.h"
30 #include "irmode_t.h"
31 #include "irgmod.h"
32 #include "iredges.h"
33 #include "irvrfy.h"
34 #include "ircons.h"
35 #include "irprintf.h"
36 #include "dbginfo.h"
37 #include "iropt_t.h"
38 #include "debug.h"
39 #include "error.h"
40
41 #include "../benode.h"
42 #include "../beirg.h"
43 #include "../beutil.h"
44 #include "../betranshlp.h"
45 #include "bearch_arm_t.h"
46
47 #include "arm_nodes_attr.h"
48 #include "arm_transform.h"
49 #include "arm_optimize.h"
50 #include "arm_new_nodes.h"
51 #include "arm_map_regs.h"
52
53 #include "gen_arm_regalloc_if.h"
54
55 #include <limits.h>
56
57 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
58
59 /** hold the current code generator during transformation */
60 static arm_code_gen_t *env_cg;
61
62 static inline int mode_needs_gp_reg(ir_mode *mode)
63 {
64         return mode_is_int(mode) || mode_is_reference(mode);
65 }
66
67 /**
68  * Creates a possible DAG for an constant.
69  */
70 static ir_node *create_const_graph_value(dbg_info *dbgi, ir_node *block,
71                                          unsigned int value)
72 {
73         ir_node *result;
74         arm_vals v, vn;
75         int cnt;
76
77         arm_gen_vals_from_word(value, &v);
78         arm_gen_vals_from_word(~value, &vn);
79
80         if (vn.ops < v.ops) {
81                 /* remove bits */
82                 result = new_bd_arm_Mvn_imm(dbgi, block, vn.values[0], vn.rors[0]);
83                 be_dep_on_frame(result);
84
85                 for (cnt = 1; cnt < vn.ops; ++cnt) {
86                         result = new_bd_arm_Bic_imm(dbgi, block, result,
87                                                     vn.values[cnt], vn.rors[cnt]);
88                 }
89         } else {
90                 /* add bits */
91                 result = new_bd_arm_Mov_imm(dbgi, block, v.values[0], v.rors[0]);
92                 be_dep_on_frame(result);
93
94                 for (cnt = 1; cnt < v.ops; ++cnt) {
95                         result = new_bd_arm_Or_imm(dbgi, block, result,
96                                                    v.values[cnt], v.rors[cnt]);
97                 }
98         }
99         return result;
100 }
101
102 /**
103  * Create a DAG constructing a given Const.
104  *
105  * @param irn  a Firm const
106  */
107 static ir_node *create_const_graph(ir_node *irn, ir_node *block)
108 {
109         tarval  *tv = get_Const_tarval(irn);
110         ir_mode *mode = get_tarval_mode(tv);
111         unsigned value;
112
113         if (mode_is_reference(mode)) {
114                 /* ARM is 32bit, so we can safely convert a reference tarval into Iu */
115                 assert(get_mode_size_bits(mode) == get_mode_size_bits(mode_Iu));
116                 tv = tarval_convert_to(tv, mode_Iu);
117         }
118         value = get_tarval_long(tv);
119         return create_const_graph_value(get_irn_dbg_info(irn), block, value);
120 }
121
122 /**
123  * Create an And that will zero out upper bits.
124  *
125  * @param dbgi     debug info
126  * @param block    the basic block
127  * @param op       the original node
128  * param src_bits  number of lower bits that will remain
129  */
130 static ir_node *gen_zero_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
131                                    int src_bits)
132 {
133         if (src_bits == 8) {
134                 return new_bd_arm_And_imm(dbgi, block, op, 0xFF, 0);
135         } else if (src_bits == 16) {
136                 ir_node *lshift = new_bd_arm_Mov_reg_shift_imm(dbgi, block, op, ARM_SHF_LSL_IMM, 16);
137                 ir_node *rshift = new_bd_arm_Mov_reg_shift_imm(dbgi, block, lshift, ARM_SHF_LSR_IMM, 16);
138                 return rshift;
139         } else {
140                 panic("zero extension only supported for 8 and 16 bits");
141         }
142 }
143
144 /**
145  * Generate code for a sign extension.
146  */
147 static ir_node *gen_sign_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
148                                    int src_bits)
149 {
150         int shift_width = 32 - src_bits;
151         ir_node *lshift_node = new_bd_arm_Mov_reg_shift_imm(dbgi, block, op, ARM_SHF_LSL_IMM, shift_width);
152         ir_node *rshift_node = new_bd_arm_Mov_reg_shift_imm(dbgi, block, lshift_node, ARM_SHF_ASR_IMM, shift_width);
153         return rshift_node;
154 }
155
156 static ir_node *gen_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
157                               ir_mode *orig_mode)
158 {
159         int bits = get_mode_size_bits(orig_mode);
160         if (bits == 32)
161                 return op;
162
163         if (mode_is_signed(orig_mode)) {
164                 return gen_sign_extension(dbgi, block, op, bits);
165         } else {
166                 return gen_zero_extension(dbgi, block, op, bits);
167         }
168 }
169
170 /**
171  * returns true if it is assured, that the upper bits of a node are "clean"
172  * which means for a 16 or 8 bit value, that the upper bits in the register
173  * are 0 for unsigned and a copy of the last significant bit for signed
174  * numbers.
175  */
176 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
177 {
178         (void) transformed_node;
179         (void) mode;
180         /* TODO */
181         return false;
182 }
183
184 /**
185  * Transforms a Conv node.
186  *
187  * @return The created ia32 Conv node
188  */
189 static ir_node *gen_Conv(ir_node *node) {
190         ir_node  *block    = be_transform_node(get_nodes_block(node));
191         ir_node  *op       = get_Conv_op(node);
192         ir_node  *new_op   = be_transform_node(op);
193         ir_mode  *src_mode = get_irn_mode(op);
194         ir_mode  *dst_mode = get_irn_mode(node);
195         dbg_info *dbg      = get_irn_dbg_info(node);
196
197         if (src_mode == dst_mode)
198                 return new_op;
199
200         if (mode_is_float(src_mode) || mode_is_float(dst_mode)) {
201                 env_cg->have_fp_insn = 1;
202
203                 if (USE_FPA(env_cg->isa)) {
204                         if (mode_is_float(src_mode)) {
205                                 if (mode_is_float(dst_mode)) {
206                                         /* from float to float */
207                                         return new_bd_arm_fpaMvf(dbg, block, new_op, dst_mode);
208                                 }
209                                 else {
210                                         /* from float to int */
211                                         return new_bd_arm_fpaFix(dbg, block, new_op, dst_mode);
212                                 }
213                         }
214                         else {
215                                 /* from int to float */
216                                 return new_bd_arm_fpaFlt(dbg, block, new_op, dst_mode);
217                         }
218                 } else if (USE_VFP(env_cg->isa)) {
219                         panic("VFP not supported yet");
220                         return NULL;
221                 } else {
222                         panic("Softfloat not supported yet");
223                         return NULL;
224                 }
225         } else { /* complete in gp registers */
226                 int src_bits = get_mode_size_bits(src_mode);
227                 int dst_bits = get_mode_size_bits(dst_mode);
228                 int min_bits;
229                 ir_mode *min_mode;
230
231                 if (src_bits == dst_bits) {
232                         /* kill unneccessary conv */
233                         return new_op;
234                 }
235
236                 if (src_bits < dst_bits) {
237                         min_bits = src_bits;
238                         min_mode = src_mode;
239                 } else {
240                         min_bits = dst_bits;
241                         min_mode = dst_mode;
242                 }
243
244                 if (upper_bits_clean(new_op, min_mode)) {
245                         return new_op;
246                 }
247
248                 if (mode_is_signed(min_mode)) {
249                         return gen_sign_extension(dbg, block, new_op, min_bits);
250                 } else {
251                         return gen_zero_extension(dbg, block, new_op, min_bits);
252                 }
253         }
254 }
255
256 typedef struct {
257         unsigned char  imm_8;
258         unsigned char  rot;
259 } arm_immediate_t;
260
261 static bool try_encode_as_immediate(const ir_node *node, arm_immediate_t *res)
262 {
263         unsigned val, low_pos, high_pos;
264
265         if (!is_Const(node))
266                 return false;
267
268         val = get_tarval_long(get_Const_tarval(node));
269
270         if (val == 0) {
271                 res->imm_8 = 0;
272                 res->rot   = 0;
273                 return true;
274         }
275         if (val <= 0xff) {
276                 res->imm_8 = val;
277                 res->rot   = 0;
278                 return true;
279         }
280         /* arm allows to use to rotate an 8bit immediate value by a multiple of 2
281            (= 0, 2, 4, 6, ...).
282            So we determine the smallest even position with a bit set
283            and the highest even position with no bit set anymore.
284            If the difference between these 2 is <= 8, then we can encode the value
285            as immediate.
286          */
287         low_pos  = ntz(val) & ~1u;
288         high_pos = (32-nlz(val)+1) & ~1u;
289
290         if (high_pos - low_pos <= 8) {
291                 res->imm_8 = val >> low_pos;
292                 res->rot   = 32 - low_pos;
293                 return true;
294         }
295
296         if (high_pos > 24) {
297                 res->rot = 34 - high_pos;
298                 val      = val >> (32-res->rot) | val << (res->rot);
299                 if (val <= 0xff) {
300                         res->imm_8 = val;
301                         return true;
302                 }
303         }
304
305         return false;
306 }
307
308 static int is_downconv(const ir_node *node)
309 {
310         ir_mode *src_mode;
311         ir_mode *dest_mode;
312
313         if (!is_Conv(node))
314                 return 0;
315
316         /* we only want to skip the conv when we're the only user
317          * (not optimal but for now...)
318          */
319         if (get_irn_n_edges(node) > 1)
320                 return 0;
321
322         src_mode  = get_irn_mode(get_Conv_op(node));
323         dest_mode = get_irn_mode(node);
324         return
325                 mode_needs_gp_reg(src_mode)  &&
326                 mode_needs_gp_reg(dest_mode) &&
327                 get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
328 }
329
330 static ir_node *arm_skip_downconv(ir_node *node)
331 {
332         while (is_downconv(node))
333                 node = get_Conv_op(node);
334         return node;
335 }
336
337 typedef enum {
338         MATCH_NONE         = 0,
339         MATCH_COMMUTATIVE  = 1 << 0,
340         MATCH_SIZE_NEUTRAL = 1 << 1,
341 } match_flags_t;
342
343 typedef ir_node* (*new_binop_reg_func) (dbg_info *dbgi, ir_node *block, ir_node *op1, ir_node *op2);
344 typedef ir_node* (*new_binop_imm_func) (dbg_info *dbgi, ir_node *block, ir_node *op1, unsigned char imm8, unsigned char imm_rot);
345
346 static ir_node *gen_int_binop(ir_node *node, match_flags_t flags,
347                 new_binop_reg_func new_reg, new_binop_imm_func new_imm)
348 {
349         ir_node  *block   = be_transform_node(get_nodes_block(node));
350         ir_node  *op1     = get_binop_left(node);
351         ir_node  *new_op1;
352         ir_node  *op2     = get_binop_right(node);
353         ir_node  *new_op2;
354         dbg_info *dbgi    = get_irn_dbg_info(node);
355         arm_immediate_t imm;
356
357         if (flags & MATCH_SIZE_NEUTRAL) {
358                 op1 = arm_skip_downconv(op1);
359                 op2 = arm_skip_downconv(op2);
360         } else {
361                 assert(get_mode_size_bits(get_irn_mode(node)) == 32);
362         }
363
364         if (try_encode_as_immediate(op2, &imm)) {
365                 ir_node *new_op1 = be_transform_node(op1);
366                 return new_imm(dbgi, block, new_op1, imm.imm_8, imm.rot);
367         }
368         new_op2 = be_transform_node(op2);
369     if ((flags & MATCH_COMMUTATIVE) && try_encode_as_immediate(op1, &imm)) {
370                 return new_imm(dbgi, block, new_op2, imm.imm_8, imm.rot);
371         }
372         new_op1 = be_transform_node(op1);
373
374         return new_reg(dbgi, block, new_op1, new_op2);
375 }
376
377 /**
378  * Creates an ARM Add.
379  *
380  * @return the created arm Add node
381  */
382 static ir_node *gen_Add(ir_node *node)
383 {
384         ir_mode  *mode    = get_irn_mode(node);
385
386         if (mode_is_float(mode)) {
387                 ir_node  *block   = be_transform_node(get_nodes_block(node));
388                 ir_node  *op1     = get_Add_left(node);
389                 ir_node  *op2     = get_Add_right(node);
390                 dbg_info *dbgi    = get_irn_dbg_info(node);
391                 ir_node  *new_op1 = be_transform_node(op1);
392                 ir_node  *new_op2 = be_transform_node(op2);
393                 env_cg->have_fp_insn = 1;
394                 if (USE_FPA(env_cg->isa)) {
395 #if 0
396                         if (is_arm_fpaMvf_i(new_op1))
397                                 return new_bd_arm_fpaAdf_i(dbgi, block, new_op2, mode, get_arm_imm_value(new_op1));
398                         if (is_arm_fpaMvf_i(new_op2))
399                                 return new_bd_arm_fpaAdf_i(dbgi, block, new_op1, mode, get_arm_imm_value(new_op2));
400 #endif
401                         return new_bd_arm_fpaAdf(dbgi, block, new_op1, new_op2, mode);
402                 } else if (USE_VFP(env_cg->isa)) {
403                         assert(mode != mode_E && "IEEE Extended FP not supported");
404                         panic("VFP not supported yet");
405                         return NULL;
406                 }
407                 else {
408                         panic("Softfloat not supported yet");
409                         return NULL;
410                 }
411         } else {
412 #if 0
413                 /* check for MLA */
414                 if (is_arm_Mul(new_op1) && get_irn_n_edges(op1) == 1) {
415                         new_op3 = new_op2;
416                         new_op2 = get_irn_n(new_op1, 1);
417                         new_op1 = get_irn_n(new_op1, 0);
418
419                         return new_bd_arm_Mla(dbgi, block, new_op1, new_op2, new_op3);
420                 }
421                 if (is_arm_Mul(new_op2) && get_irn_n_edges(op2) == 1) {
422                         new_op3 = new_op1;
423                         new_op1 = get_irn_n(new_op2, 0);
424                         new_op2 = get_irn_n(new_op2, 1);
425
426                         return new_bd_arm_Mla(dbgi, block, new_op1, new_op2, new_op3);
427                 }
428 #endif
429
430                 return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL,
431                                 new_bd_arm_Add_reg, new_bd_arm_Add_imm);
432         }
433 }
434
435 /**
436  * Creates an ARM Mul.
437  *
438  * @return the created arm Mul node
439  */
440 static ir_node *gen_Mul(ir_node *node) {
441         ir_node  *block   = be_transform_node(get_nodes_block(node));
442         ir_node  *op1     = get_Mul_left(node);
443         ir_node  *new_op1 = be_transform_node(op1);
444         ir_node  *op2     = get_Mul_right(node);
445         ir_node  *new_op2 = be_transform_node(op2);
446         ir_mode  *mode    = get_irn_mode(node);
447         dbg_info *dbg     = get_irn_dbg_info(node);
448
449         if (mode_is_float(mode)) {
450                 env_cg->have_fp_insn = 1;
451                 if (USE_FPA(env_cg->isa)) {
452 #if 0
453                         if (is_arm_Mov_i(new_op1))
454                                 return new_bd_arm_fpaMuf_i(dbg, block, new_op2, mode, get_arm_imm_value(new_op1));
455                         if (is_arm_Mov_i(new_op2))
456                                 return new_bd_arm_fpaMuf_i(dbg, block, new_op1, mode, get_arm_imm_value(new_op2));
457 #endif
458                         return new_bd_arm_fpaMuf(dbg, block, new_op1, new_op2, mode);
459                 }
460                 else if (USE_VFP(env_cg->isa)) {
461                         assert(mode != mode_E && "IEEE Extended FP not supported");
462                         panic("VFP not supported yet");
463                         return NULL;
464                 }
465                 else {
466                         panic("Softfloat not supported yet");
467                         return NULL;
468                 }
469         }
470         assert(mode_is_data(mode));
471         return new_bd_arm_Mul(dbg, block, new_op1, new_op2);
472 }
473
474 /**
475  * Creates an ARM floating point Div.
476  *
477  * @param env   The transformation environment
478  * @return the created arm fDiv node
479  */
480 static ir_node *gen_Quot(ir_node *node) {
481         ir_node  *block   = be_transform_node(get_nodes_block(node));
482         ir_node  *op1     = get_Quot_left(node);
483         ir_node  *new_op1 = be_transform_node(op1);
484         ir_node  *op2     = get_Quot_right(node);
485         ir_node  *new_op2 = be_transform_node(op2);
486         ir_mode  *mode    = get_irn_mode(node);
487         dbg_info *dbg     = get_irn_dbg_info(node);
488
489         assert(mode != mode_E && "IEEE Extended FP not supported");
490
491         env_cg->have_fp_insn = 1;
492         if (USE_FPA(env_cg->isa)) {
493 #if 0
494                 if (is_arm_Mov_i(new_op1))
495                         return new_bd_arm_fpaRdf_i(dbg, block, new_op2, mode, get_arm_imm_value(new_op1));
496                 if (is_arm_Mov_i(new_op2))
497                         return new_bd_arm_fpaDvf_i(dbg, block, new_op1, mode, get_arm_imm_value(new_op2));
498 #endif
499                 return new_bd_arm_fpaDvf(dbg, block, new_op1, new_op2, mode);
500         } else if (USE_VFP(env_cg->isa)) {
501                 assert(mode != mode_E && "IEEE Extended FP not supported");
502                 panic("VFP not supported yet");
503         }
504         else {
505                 panic("Softfloat not supported yet");
506                 return NULL;
507         }
508 }
509
510 /**
511  * Creates an ARM And.
512  *
513  * @return the created arm And node
514  */
515 static ir_node *gen_And(ir_node *node)
516 {
517         return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL,
518                         new_bd_arm_And_reg, new_bd_arm_And_imm);
519 }
520
521 /**
522  * Creates an ARM Orr.
523  *
524  * @param env   The transformation environment
525  * @return the created arm Or node
526  */
527 static ir_node *gen_Or(ir_node *node)
528 {
529         return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL,
530                         new_bd_arm_Or_reg, new_bd_arm_Or_imm);
531 }
532
533 /**
534  * Creates an ARM Eor.
535  *
536  * @return the created arm Eor node
537  */
538 static ir_node *gen_Eor(ir_node *node)
539 {
540         return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL,
541                         new_bd_arm_Eor_reg, new_bd_arm_Eor_imm);
542 }
543
544 /**
545  * Creates an ARM Sub.
546  *
547  * @return the created arm Sub node
548  */
549 static ir_node *gen_Sub(ir_node *node)
550 {
551         ir_node  *block   = be_transform_node(get_nodes_block(node));
552         ir_node  *op1     = get_Sub_left(node);
553         ir_node  *new_op1 = be_transform_node(op1);
554         ir_node  *op2     = get_Sub_right(node);
555         ir_node  *new_op2 = be_transform_node(op2);
556         ir_mode  *mode    = get_irn_mode(node);
557         dbg_info *dbgi    = get_irn_dbg_info(node);
558
559         if (mode_is_float(mode)) {
560                 env_cg->have_fp_insn = 1;
561                 if (USE_FPA(env_cg->isa)) {
562 #if 0
563                         if (is_arm_Mov_i(new_op1))
564                                 return new_bd_arm_fpaRsf_i(dbgi, block, new_op2, mode, get_arm_imm_value(new_op1));
565                         if (is_arm_Mov_i(new_op2))
566                                 return new_bd_arm_fpaSuf_i(dbgi, block, new_op1, mode, get_arm_imm_value(new_op2));
567 #endif
568                         return new_bd_arm_fpaSuf(dbgi, block, new_op1, new_op2, mode);
569                 } else if (USE_VFP(env_cg->isa)) {
570                         assert(mode != mode_E && "IEEE Extended FP not supported");
571                         panic("VFP not supported yet");
572                         return NULL;
573                 } else {
574                         panic("Softfloat not supported yet");
575                         return NULL;
576                 }
577         } else {
578                 return gen_int_binop(node, MATCH_SIZE_NEUTRAL,
579                                 new_bd_arm_Sub_reg, new_bd_arm_Sub_imm);
580         }
581 }
582
583 static ir_node *make_shift(ir_node *node, match_flags_t flags,
584                 arm_shift_modifier shift_modifier)
585 {
586         ir_node  *block   = be_transform_node(get_nodes_block(node));
587         ir_node  *op1     = get_binop_left(node);
588         ir_node  *op2     = get_binop_right(node);
589         dbg_info *dbgi    = get_irn_dbg_info(node);
590         ir_node  *new_op1;
591         ir_node  *new_op2;
592
593         if (flags & MATCH_SIZE_NEUTRAL) {
594                 op1 = arm_skip_downconv(op1);
595                 op2 = arm_skip_downconv(op2);
596         }
597         new_op1 = be_transform_node(op1);
598         new_op2 = be_transform_node(op2);
599         return new_bd_arm_Mov_reg_shift_reg(dbgi, block, new_op1, new_op2, shift_modifier);
600 }
601
602 /**
603  * Creates an ARM Shl.
604  *
605  * @return the created ARM Shl node
606  */
607 static ir_node *gen_Shl(ir_node *node)
608 {
609         return make_shift(node, MATCH_SIZE_NEUTRAL, ARM_SHF_LSL_REG);
610 }
611
612 /**
613  * Creates an ARM Shr.
614  *
615  * @return the created ARM Shr node
616  */
617 static ir_node *gen_Shr(ir_node *node)
618 {
619         return make_shift(node, MATCH_NONE, ARM_SHF_LSR_REG);
620 }
621
622 /**
623  * Creates an ARM Shrs.
624  *
625  * @return the created ARM Shrs node
626  */
627 static ir_node *gen_Shrs(ir_node *node)
628 {
629         return make_shift(node, MATCH_NONE, ARM_SHF_ASR_REG);
630 }
631
632 /**
633  * Creates an ARM Ror.
634  *
635  * @return the created ARM Ror node
636  */
637 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
638 {
639         ir_node  *block   = be_transform_node(get_nodes_block(node));
640         ir_node  *new_op1 = be_transform_node(op1);
641         dbg_info *dbgi    = get_irn_dbg_info(node);
642         ir_node  *new_op2 = be_transform_node(op2);
643
644         return new_bd_arm_Mov_reg_shift_reg(dbgi, block, new_op1, new_op2,
645                                             ARM_SHF_ROR_REG);
646 }
647
648 /**
649  * Creates an ARM Rol.
650  *
651  * @return the created ARM Rol node
652  *
653  * Note: there is no Rol on arm, we have to use Ror
654  */
655 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
656 {
657         ir_node  *block   = be_transform_node(get_nodes_block(node));
658         ir_node  *new_op1 = be_transform_node(op1);
659         dbg_info *dbgi    = get_irn_dbg_info(node);
660         ir_node  *new_op2 = be_transform_node(op2);
661
662         new_op2 = new_bd_arm_Rsb_imm(dbgi, block, new_op2, 32, 0);
663         return new_bd_arm_Mov_reg_shift_reg(dbgi, block, new_op1, new_op2,
664                                             ARM_SHF_ROR_REG);
665 }
666
667 /**
668  * Creates an ARM ROR from a Firm Rotl.
669  *
670  * @return the created ARM Ror node
671  */
672 static ir_node *gen_Rotl(ir_node *node)
673 {
674         ir_node *rotate = NULL;
675         ir_node *op1    = get_Rotl_left(node);
676         ir_node *op2    = get_Rotl_right(node);
677
678         /* Firm has only RotL, so we are looking for a right (op2)
679            operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
680            that means we can create a RotR. */
681
682         if (is_Add(op2)) {
683                 ir_node *right = get_Add_right(op2);
684                 if (is_Const(right)) {
685                         tarval  *tv   = get_Const_tarval(right);
686                         ir_mode *mode = get_irn_mode(node);
687                         long     bits = get_mode_size_bits(mode);
688                         ir_node *left = get_Add_left(op2);
689
690                         if (is_Minus(left) &&
691                             tarval_is_long(tv)          &&
692                             get_tarval_long(tv) == bits &&
693                             bits                == 32)
694                                 rotate = gen_Ror(node, op1, get_Minus_op(left));
695                 }
696         } else if (is_Sub(op2)) {
697                 ir_node *left = get_Sub_left(op2);
698                 if (is_Const(left)) {
699                         tarval  *tv   = get_Const_tarval(left);
700                         ir_mode *mode = get_irn_mode(node);
701                         long     bits = get_mode_size_bits(mode);
702                         ir_node *right = get_Sub_right(op2);
703
704                         if (tarval_is_long(tv)          &&
705                             get_tarval_long(tv) == bits &&
706                             bits                == 32)
707                                 rotate = gen_Ror(node, op1, right);
708                 }
709         } else if (is_Const(op2)) {
710                 tarval  *tv   = get_Const_tarval(op2);
711                 ir_mode *mode = get_irn_mode(node);
712                 long     bits = get_mode_size_bits(mode);
713
714                 if (tarval_is_long(tv) && bits == 32) {
715                         ir_node  *block   = be_transform_node(get_nodes_block(node));
716                         ir_node  *new_op1 = be_transform_node(op1);
717                         dbg_info *dbgi    = get_irn_dbg_info(node);
718
719                         bits = (bits - get_tarval_long(tv)) & 31;
720                         rotate = new_bd_arm_Mov_reg_shift_imm(dbgi, block, new_op1, ARM_SHF_ROR_IMM, bits);
721                 }
722         }
723
724         if (rotate == NULL) {
725                 rotate = gen_Rol(node, op1, op2);
726         }
727
728         return rotate;
729 }
730
731 /**
732  * Transforms a Not node.
733  *
734  * @return the created ARM Not node
735  */
736 static ir_node *gen_Not(ir_node *node)
737 {
738         ir_node  *block   = be_transform_node(get_nodes_block(node));
739         ir_node  *op      = get_Not_op(node);
740         ir_node  *new_op  = be_transform_node(op);
741         dbg_info *dbgi    = get_irn_dbg_info(node);
742
743         /* TODO: we could do alot more here with all the Mvn variations */
744
745         return new_bd_arm_Mvn_reg(dbgi, block, new_op);
746 }
747
748 /**
749  * Transforms an Abs node.
750  *
751  * @param env   The transformation environment
752  * @return the created ARM Abs node
753  */
754 static ir_node *gen_Abs(ir_node *node)
755 {
756         ir_node  *block   = be_transform_node(get_nodes_block(node));
757         ir_node  *op      = get_Abs_op(node);
758         ir_node  *new_op  = be_transform_node(op);
759         dbg_info *dbgi    = get_irn_dbg_info(node);
760         ir_mode  *mode    = get_irn_mode(node);
761
762         if (mode_is_float(mode)) {
763                 env_cg->have_fp_insn = 1;
764                 if (USE_FPA(env_cg->isa))
765                         return new_bd_arm_fpaAbs(dbgi, block, new_op, mode);
766                 else if (USE_VFP(env_cg->isa)) {
767                         assert(mode != mode_E && "IEEE Extended FP not supported");
768                         panic("VFP not supported yet");
769                 }
770                 else {
771                         panic("Softfloat not supported yet");
772                 }
773         }
774         assert(mode_is_data(mode));
775         return new_bd_arm_Abs(dbgi, block, new_op);
776 }
777
778 /**
779  * Transforms a Minus node.
780  *
781  * @return the created ARM Minus node
782  */
783 static ir_node *gen_Minus(ir_node *node)
784 {
785         ir_node  *block   = be_transform_node(get_nodes_block(node));
786         ir_node  *op      = get_Minus_op(node);
787         ir_node  *new_op  = be_transform_node(op);
788         dbg_info *dbgi    = get_irn_dbg_info(node);
789         ir_mode  *mode    = get_irn_mode(node);
790
791         if (mode_is_float(mode)) {
792                 env_cg->have_fp_insn = 1;
793                 if (USE_FPA(env_cg->isa))
794                         return new_bd_arm_fpaMvf(dbgi, block, op, mode);
795                 else if (USE_VFP(env_cg->isa)) {
796                         assert(mode != mode_E && "IEEE Extended FP not supported");
797                         panic("VFP not supported yet");
798                 }
799                 else {
800                         panic("Softfloat not supported yet");
801                 }
802         }
803         assert(mode_is_data(mode));
804         return new_bd_arm_Rsb_imm(dbgi, block, new_op, 0, 0);
805 }
806
807 /**
808  * Transforms a Load.
809  *
810  * @return the created ARM Load node
811  */
812 static ir_node *gen_Load(ir_node *node) {
813         ir_node  *block    = be_transform_node(get_nodes_block(node));
814         ir_node  *ptr      = get_Load_ptr(node);
815         ir_node  *new_ptr  = be_transform_node(ptr);
816         ir_node  *mem      = get_Load_mem(node);
817         ir_node  *new_mem  = be_transform_node(mem);
818         ir_mode  *mode     = get_Load_mode(node);
819         dbg_info *dbgi      = get_irn_dbg_info(node);
820         ir_node  *new_load = NULL;
821
822         if (mode_is_float(mode)) {
823                 env_cg->have_fp_insn = 1;
824                 if (USE_FPA(env_cg->isa))
825                         new_load = new_bd_arm_fpaLdf(dbgi, block, new_ptr, new_mem, mode);
826                 else if (USE_VFP(env_cg->isa)) {
827                         assert(mode != mode_E && "IEEE Extended FP not supported");
828                         panic("VFP not supported yet");
829                 } else {
830                         panic("Softfloat not supported yet");
831                 }
832         } else {
833                 assert(mode_is_data(mode) && "unsupported mode for Load");
834
835                 new_load = new_bd_arm_Ldr(dbgi, block, new_ptr, new_mem, mode, NULL, 0, 0, false);
836         }
837         set_irn_pinned(new_load, get_irn_pinned(node));
838
839         /* check for special case: the loaded value might not be used */
840         if (be_get_Proj_for_pn(node, pn_Load_res) == NULL) {
841                 /* add a result proj and a Keep to produce a pseudo use */
842                 ir_node *proj = new_r_Proj(block, new_load, mode_Iu, pn_arm_Ldr_res);
843                 be_new_Keep(block, 1, &proj);
844         }
845
846         return new_load;
847 }
848
849 /**
850  * Transforms a Store.
851  *
852  * @return the created ARM Store node
853  */
854 static ir_node *gen_Store(ir_node *node)
855 {
856         ir_node  *block    = be_transform_node(get_nodes_block(node));
857         ir_node  *ptr      = get_Store_ptr(node);
858         ir_node  *new_ptr  = be_transform_node(ptr);
859         ir_node  *mem      = get_Store_mem(node);
860         ir_node  *new_mem  = be_transform_node(mem);
861         ir_node  *val      = get_Store_value(node);
862         ir_node  *new_val  = be_transform_node(val);
863         ir_mode  *mode     = get_irn_mode(val);
864         dbg_info *dbgi     = get_irn_dbg_info(node);
865         ir_node *new_store = NULL;
866
867         if (mode_is_float(mode)) {
868                 env_cg->have_fp_insn = 1;
869                 if (USE_FPA(env_cg->isa))
870                         new_store = new_bd_arm_fpaStf(dbgi, block, new_ptr, new_val,
871                                                       new_mem, mode);
872                 else if (USE_VFP(env_cg->isa)) {
873                         assert(mode != mode_E && "IEEE Extended FP not supported");
874                         panic("VFP not supported yet");
875                 } else {
876                         panic("Softfloat not supported yet");
877                 }
878         } else {
879                 assert(mode_is_data(mode) && "unsupported mode for Store");
880                 new_store = new_bd_arm_Str(dbgi, block, new_ptr, new_val, new_mem, mode,
881                                            NULL, 0, 0, false);
882         }
883         set_irn_pinned(new_store, get_irn_pinned(node));
884         return new_store;
885 }
886
887 static ir_node *gen_Jmp(ir_node *node)
888 {
889         ir_node  *block     = get_nodes_block(node);
890         ir_node  *new_block = be_transform_node(block);
891         dbg_info *dbgi      = get_irn_dbg_info(node);
892
893         return new_bd_arm_Jmp(dbgi, new_block);
894 }
895
896 static ir_node *gen_be_Call(ir_node *node)
897 {
898         ir_node *res = be_duplicate_node(node);
899         arch_irn_add_flags(res, arch_irn_flags_modify_flags);
900
901         return res;
902 }
903
904 static ir_node *gen_SwitchJmp(ir_node *node)
905 {
906         ir_node  *block    = be_transform_node(get_nodes_block(node));
907         ir_node  *selector = get_Cond_selector(node);
908         dbg_info *dbgi     = get_irn_dbg_info(node);
909         ir_node *new_op = be_transform_node(selector);
910         ir_node *const_graph;
911         ir_node *sub;
912
913         ir_node *proj;
914         const ir_edge_t *edge;
915         int min = INT_MAX;
916         int max = INT_MIN;
917         int translation;
918         int pn;
919         int n_projs;
920
921         foreach_out_edge(node, edge) {
922                 proj = get_edge_src_irn(edge);
923                 assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
924
925                 pn = get_Proj_proj(proj);
926
927                 min = pn<min ? pn : min;
928                 max = pn>max ? pn : max;
929         }
930         translation = min;
931         n_projs = max - translation + 1;
932
933         foreach_out_edge(node, edge) {
934                 proj = get_edge_src_irn(edge);
935                 assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
936
937                 pn = get_Proj_proj(proj) - translation;
938                 set_Proj_proj(proj, pn);
939         }
940
941         const_graph = create_const_graph_value(dbgi, block, translation);
942         sub = new_bd_arm_Sub_reg(dbgi, block, new_op, const_graph);
943         return new_bd_arm_SwitchJmp(dbgi, block, sub, n_projs, get_Cond_default_proj(node) - translation);
944 }
945
946 static ir_node *gen_Cmp(ir_node *node)
947 {
948         ir_node  *block    = be_transform_node(get_nodes_block(node));
949         ir_node  *op1      = get_Cmp_left(node);
950         ir_node  *op2      = get_Cmp_right(node);
951         ir_mode  *cmp_mode = get_irn_mode(op1);
952         dbg_info *dbgi     = get_irn_dbg_info(node);
953         ir_node  *new_op1;
954         ir_node  *new_op2;
955         bool      is_unsigned;
956
957         if (mode_is_float(cmp_mode)) {
958                 /* TODO: revivie this code */
959                 panic("FloatCmp NIY");
960 #if 0
961                 ir_node *new_op2  = be_transform_node(op2);
962                 /* floating point compare */
963                 pn_Cmp pnc = get_Proj_proj(selector);
964
965                 if (pnc & pn_Cmp_Uo) {
966                         /* check for unordered, need cmf */
967                         return new_bd_arm_fpaCmfBra(dbgi, block, new_op1, new_op2, pnc);
968                 }
969                 /* Hmm: use need cmfe */
970                 return new_bd_arm_fpaCmfeBra(dbgi, block, new_op1, new_op2, pnc);
971 #endif
972         }
973
974         assert(get_irn_mode(op2) == cmp_mode);
975         is_unsigned = !mode_is_signed(cmp_mode);
976
977         /* compare with 0 can be done with Tst */
978         if (is_Const(op2) && tarval_is_null(get_Const_tarval(op2))) {
979                 new_op1 = be_transform_node(op1);
980                 new_op1 = gen_extension(dbgi, block, new_op1, cmp_mode);
981                 return new_bd_arm_Tst_reg(dbgi, block, new_op1, new_op1, false,
982                                           is_unsigned);
983         }
984         if (is_Const(op1) && tarval_is_null(get_Const_tarval(op1))) {
985                 new_op2 = be_transform_node(op2);
986                 new_op2 = gen_extension(dbgi, block, new_op2, cmp_mode);
987                 return new_bd_arm_Tst_reg(dbgi, block, new_op2, new_op2, true,
988                                           is_unsigned);
989         }
990
991         /* integer compare, TODO: use shifer_op in all its combinations */
992         new_op1 = be_transform_node(op1);
993         new_op1 = gen_extension(dbgi, block, new_op1, cmp_mode);
994         new_op2 = be_transform_node(op2);
995         new_op2 = gen_extension(dbgi, block, new_op2, cmp_mode);
996         return new_bd_arm_Cmp_reg(dbgi, block, new_op1, new_op2, false,
997                                   is_unsigned);
998 }
999
1000 /**
1001  * Transforms a Cond.
1002  *
1003  * @return the created ARM Cond node
1004  */
1005 static ir_node *gen_Cond(ir_node *node)
1006 {
1007         ir_node  *selector = get_Cond_selector(node);
1008         ir_mode  *mode     = get_irn_mode(selector);
1009         ir_node  *block;
1010         ir_node  *flag_node;
1011         dbg_info *dbgi;
1012
1013         if (mode != mode_b) {
1014                 return gen_SwitchJmp(node);
1015         }
1016         assert(is_Proj(selector));
1017
1018         block     = be_transform_node(get_nodes_block(node));
1019         dbgi      = get_irn_dbg_info(node);
1020         flag_node = be_transform_node(get_Proj_pred(selector));
1021
1022         return new_bd_arm_B(dbgi, block, flag_node, get_Proj_proj(selector));
1023 }
1024
1025 static tarval *fpa_imm[3][fpa_max];
1026
1027 #if 0
1028 /**
1029  * Check, if a floating point tarval is an fpa immediate, i.e.
1030  * one of 0, 1, 2, 3, 4, 5, 10, or 0.5.
1031  */
1032 static int is_fpa_immediate(tarval *tv)
1033 {
1034         ir_mode *mode = get_tarval_mode(tv);
1035         int i, j, res = 1;
1036
1037         switch (get_mode_size_bits(mode)) {
1038         case 32:
1039                 i = 0;
1040                 break;
1041         case 64:
1042                 i = 1;
1043                 break;
1044         default:
1045                 i = 2;
1046         }
1047
1048         if (tarval_cmp(tv, get_tarval_null(mode)) & pn_Cmp_Lt) {
1049                 tv = tarval_neg(tv);
1050                 res = -1;
1051         }
1052
1053         for (j = 0; j < fpa_max; ++j) {
1054                 if (tv == fpa_imm[i][j])
1055                         return res * j;
1056         }
1057         return fpa_max;
1058 }
1059 #endif
1060
1061 /**
1062  * Transforms a Const node.
1063  *
1064  * @return The transformed ARM node.
1065  */
1066 static ir_node *gen_Const(ir_node *node) {
1067         ir_node  *block = be_transform_node(get_nodes_block(node));
1068         ir_mode *mode = get_irn_mode(node);
1069         dbg_info *dbg = get_irn_dbg_info(node);
1070
1071         if (mode_is_float(mode)) {
1072                 env_cg->have_fp_insn = 1;
1073                 if (USE_FPA(env_cg->isa)) {
1074                         tarval *tv = get_Const_tarval(node);
1075 #if 0
1076                         int imm = is_fpa_immediate(tv);
1077
1078                         if (imm != fpa_max) {
1079                                 if (imm > 0)
1080                                         node = new_bd_arm_fpaMvf_i(dbg, block, mode, imm);
1081                                 else
1082                                         node = new_bd_arm_fpaMnf_i(dbg, block, mode, -imm);
1083                         } else {
1084 #endif
1085                         {
1086                                 node = new_bd_arm_fpaConst(dbg, block, tv);
1087                         }
1088                         be_dep_on_frame(node);
1089                         return node;
1090                 }
1091                 else if (USE_VFP(env_cg->isa)) {
1092                         assert(mode != mode_E && "IEEE Extended FP not supported");
1093                         panic("VFP not supported yet");
1094                 }
1095                 else {
1096                         panic("Softfloat not supported yet");
1097                 }
1098         }
1099         return create_const_graph(node, block);
1100 }
1101
1102 /**
1103  * Transforms a SymConst node.
1104  *
1105  * @return The transformed ARM node.
1106  */
1107 static ir_node *gen_SymConst(ir_node *node)
1108 {
1109         ir_node   *block  = be_transform_node(get_nodes_block(node));
1110         ir_entity *entity = get_SymConst_entity(node);
1111         dbg_info  *dbgi   = get_irn_dbg_info(node);
1112         ir_node   *new_node;
1113
1114         new_node = new_bd_arm_SymConst(dbgi, block, entity);
1115         be_dep_on_frame(new_node);
1116         return new_node;
1117 }
1118
1119 /**
1120  * Transforms a CopyB node.
1121  *
1122  * @return The transformed ARM node.
1123  */
1124 static ir_node *gen_CopyB(ir_node *node) {
1125         ir_node  *block    = be_transform_node(get_nodes_block(node));
1126         ir_node  *src      = get_CopyB_src(node);
1127         ir_node  *new_src  = be_transform_node(src);
1128         ir_node  *dst      = get_CopyB_dst(node);
1129         ir_node  *new_dst  = be_transform_node(dst);
1130         ir_node  *mem      = get_CopyB_mem(node);
1131         ir_node  *new_mem  = be_transform_node(mem);
1132         dbg_info *dbg      = get_irn_dbg_info(node);
1133         int      size      = get_type_size_bytes(get_CopyB_type(node));
1134         ir_node  *src_copy;
1135         ir_node  *dst_copy;
1136
1137         src_copy = be_new_Copy(&arm_reg_classes[CLASS_arm_gp], block, new_src);
1138         dst_copy = be_new_Copy(&arm_reg_classes[CLASS_arm_gp], block, new_dst);
1139
1140         return new_bd_arm_CopyB(dbg, block, dst_copy, src_copy,
1141                         new_bd_arm_EmptyReg(dbg, block),
1142                         new_bd_arm_EmptyReg(dbg, block),
1143                         new_bd_arm_EmptyReg(dbg, block),
1144                         new_mem, size);
1145 }
1146
1147 /**
1148  * Transforms a FrameAddr into an ARM Add.
1149  */
1150 static ir_node *gen_be_FrameAddr(ir_node *node)
1151 {
1152         ir_node   *block  = be_transform_node(get_nodes_block(node));
1153         ir_entity *ent    = be_get_frame_entity(node);
1154         ir_node   *fp     = be_get_FrameAddr_frame(node);
1155         ir_node   *new_fp = be_transform_node(fp);
1156         dbg_info  *dbgi   = get_irn_dbg_info(node);
1157         ir_node   *new_node;
1158
1159         new_node = new_bd_arm_FrameAddr(dbgi, block, new_fp, ent);
1160         return new_node;
1161 }
1162
1163 /**
1164  * Transform a be_AddSP into an arm_AddSP. Eat up const sizes.
1165  */
1166 static ir_node *gen_be_AddSP(ir_node *node) {
1167         ir_node  *block  = be_transform_node(get_nodes_block(node));
1168         ir_node  *sz     = get_irn_n(node, be_pos_AddSP_size);
1169         ir_node  *new_sz = be_transform_node(sz);
1170         ir_node  *sp     = get_irn_n(node, be_pos_AddSP_old_sp);
1171         ir_node  *new_sp = be_transform_node(sp);
1172         dbg_info *dbgi   = get_irn_dbg_info(node);
1173         ir_node  *nomem  = new_NoMem();
1174         ir_node  *new_op;
1175
1176         /* ARM stack grows in reverse direction, make a SubSPandCopy */
1177         new_op = new_bd_arm_SubSPandCopy(dbgi, block, new_sp, new_sz, nomem);
1178
1179         return new_op;
1180 }
1181
1182 /**
1183  * Transform a be_SubSP into an arm_SubSP. Eat up const sizes.
1184  */
1185 static ir_node *gen_be_SubSP(ir_node *node) {
1186         ir_node  *block  = be_transform_node(get_nodes_block(node));
1187         ir_node  *sz     = get_irn_n(node, be_pos_SubSP_size);
1188         ir_node  *new_sz = be_transform_node(sz);
1189         ir_node  *sp     = get_irn_n(node, be_pos_SubSP_old_sp);
1190         ir_node  *new_sp = be_transform_node(sp);
1191         dbg_info *dbgi   = get_irn_dbg_info(node);
1192         ir_node  *nomem  = new_NoMem();
1193         ir_node  *new_op;
1194
1195         /* ARM stack grows in reverse direction, make an AddSP */
1196         new_op = new_bd_arm_AddSP(dbgi, block, new_sp, new_sz, nomem);
1197
1198         return new_op;
1199 }
1200
1201 /**
1202  * Transform a be_Copy.
1203  */
1204 static ir_node *gen_be_Copy(ir_node *node) {
1205         ir_node *result = be_duplicate_node(node);
1206         ir_mode *mode   = get_irn_mode(result);
1207
1208         if (mode_needs_gp_reg(mode)) {
1209                 set_irn_mode(node, mode_Iu);
1210         }
1211
1212         return result;
1213 }
1214
1215 /**
1216  * Transform a Proj from a Load.
1217  */
1218 static ir_node *gen_Proj_Load(ir_node *node) {
1219         ir_node  *block    = be_transform_node(get_nodes_block(node));
1220         ir_node  *load     = get_Proj_pred(node);
1221         ir_node  *new_load = be_transform_node(load);
1222         dbg_info *dbgi     = get_irn_dbg_info(node);
1223         long     proj      = get_Proj_proj(node);
1224
1225         /* renumber the proj */
1226         switch (get_arm_irn_opcode(new_load)) {
1227         case iro_arm_Ldr:
1228                 /* handle all gp loads equal: they have the same proj numbers. */
1229                 if (proj == pn_Load_res) {
1230                         return new_rd_Proj(dbgi, block, new_load, mode_Iu, pn_arm_Ldr_res);
1231                 } else if (proj == pn_Load_M) {
1232                         return new_rd_Proj(dbgi, block, new_load, mode_M, pn_arm_Ldr_M);
1233                 }
1234                 break;
1235         case iro_arm_fpaLdf:
1236                 if (proj == pn_Load_res) {
1237                         ir_mode *mode = get_Load_mode(load);
1238                         return new_rd_Proj(dbgi, block, new_load, mode, pn_arm_fpaLdf_res);
1239                 } else if (proj == pn_Load_M) {
1240                         return new_rd_Proj(dbgi, block, new_load, mode_M, pn_arm_fpaLdf_M);
1241                 }
1242                 break;
1243         default:
1244                 break;
1245         }
1246         panic("Unsupported Proj from Load");
1247 }
1248
1249 /**
1250  * Transform and renumber the Projs from a CopyB.
1251  */
1252 static ir_node *gen_Proj_CopyB(ir_node *node) {
1253         ir_node  *block    = be_transform_node(get_nodes_block(node));
1254         ir_node  *pred     = get_Proj_pred(node);
1255         ir_node  *new_pred = be_transform_node(pred);
1256         dbg_info *dbgi     = get_irn_dbg_info(node);
1257         long     proj      = get_Proj_proj(node);
1258
1259         switch(proj) {
1260         case pn_CopyB_M_regular:
1261                 if (is_arm_CopyB(new_pred)) {
1262                         return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_arm_CopyB_M);
1263                 }
1264                 break;
1265         default:
1266                 break;
1267         }
1268         panic("Unsupported Proj from CopyB");
1269 }
1270
1271 /**
1272  * Transform and renumber the Projs from a Quot.
1273  */
1274 static ir_node *gen_Proj_Quot(ir_node *node) {
1275         ir_node  *block    = be_transform_node(get_nodes_block(node));
1276         ir_node  *pred     = get_Proj_pred(node);
1277         ir_node  *new_pred = be_transform_node(pred);
1278         dbg_info *dbgi     = get_irn_dbg_info(node);
1279         ir_mode  *mode     = get_irn_mode(node);
1280         long     proj      = get_Proj_proj(node);
1281
1282         switch (proj) {
1283         case pn_Quot_M:
1284                 if (is_arm_fpaDvf(new_pred)) {
1285                         return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_arm_fpaDvf_M);
1286                 } else if (is_arm_fpaRdf(new_pred)) {
1287                         return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_arm_fpaRdf_M);
1288                 } else if (is_arm_fpaFdv(new_pred)) {
1289                         return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_arm_fpaFdv_M);
1290                 } else if (is_arm_fpaFrd(new_pred)) {
1291                         return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_arm_fpaFrd_M);
1292                 }
1293                 break;
1294         case pn_Quot_res:
1295                 if (is_arm_fpaDvf(new_pred)) {
1296                         return new_rd_Proj(dbgi, block, new_pred, mode, pn_arm_fpaDvf_res);
1297                 } else if (is_arm_fpaRdf(new_pred)) {
1298                         return new_rd_Proj(dbgi, block, new_pred, mode, pn_arm_fpaRdf_res);
1299                 } else if (is_arm_fpaFdv(new_pred)) {
1300                         return new_rd_Proj(dbgi, block, new_pred, mode, pn_arm_fpaFdv_res);
1301                 } else if (is_arm_fpaFrd(new_pred)) {
1302                         return new_rd_Proj(dbgi, block, new_pred, mode, pn_arm_fpaFrd_res);
1303                 }
1304                 break;
1305         default:
1306                 break;
1307         }
1308         panic("Unsupported Proj from Quot");
1309 }
1310
1311 /**
1312  * Transform the Projs of a be_AddSP.
1313  */
1314 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
1315         ir_node  *block    = be_transform_node(get_nodes_block(node));
1316         ir_node  *pred     = get_Proj_pred(node);
1317         ir_node  *new_pred = be_transform_node(pred);
1318         dbg_info *dbgi     = get_irn_dbg_info(node);
1319         long     proj      = get_Proj_proj(node);
1320
1321         if (proj == pn_be_AddSP_sp) {
1322                 ir_node *res = new_rd_Proj(dbgi, block, new_pred, mode_Iu,
1323                                            pn_arm_SubSPandCopy_stack);
1324                 arch_set_irn_register(res, &arm_gp_regs[REG_SP]);
1325                 return res;
1326         } else if(proj == pn_be_AddSP_res) {
1327                 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_arm_SubSPandCopy_addr);
1328         } else if (proj == pn_be_AddSP_M) {
1329                 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_arm_SubSPandCopy_M);
1330         }
1331         panic("Unsupported Proj from AddSP");
1332 }
1333
1334 /**
1335  * Transform the Projs of a be_SubSP.
1336  */
1337 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
1338         ir_node  *block    = be_transform_node(get_nodes_block(node));
1339         ir_node  *pred     = get_Proj_pred(node);
1340         ir_node  *new_pred = be_transform_node(pred);
1341         dbg_info *dbgi     = get_irn_dbg_info(node);
1342         long     proj      = get_Proj_proj(node);
1343
1344         if (proj == pn_be_SubSP_sp) {
1345                 ir_node *res = new_rd_Proj(dbgi, block, new_pred, mode_Iu,
1346                                            pn_arm_AddSP_stack);
1347                 arch_set_irn_register(res, &arm_gp_regs[REG_SP]);
1348                 return res;
1349         } else if (proj == pn_be_SubSP_M) {
1350                 return new_rd_Proj(dbgi,  block, new_pred, mode_M, pn_arm_AddSP_M);
1351         }
1352         panic("Unsupported Proj from SubSP");
1353 }
1354
1355 /**
1356  * Transform the Projs from a Cmp.
1357  */
1358 static ir_node *gen_Proj_Cmp(ir_node *node) {
1359         (void) node;
1360         panic("Mux NYI");
1361 }
1362
1363
1364 /**
1365  * Transform the Thread Local Storage Proj.
1366  */
1367 static ir_node *gen_Proj_tls(ir_node *node) {
1368         ir_node  *block = be_transform_node(get_nodes_block(node));
1369         dbg_info *dbgi  = NULL;
1370
1371         return new_bd_arm_LdTls(dbgi, block, mode_Iu);
1372 }
1373
1374 /**
1375  * Transform a Proj node.
1376  */
1377 static ir_node *gen_Proj(ir_node *node) {
1378         ir_graph *irg  = current_ir_graph;
1379         dbg_info *dbgi = get_irn_dbg_info(node);
1380         ir_node  *pred = get_Proj_pred(node);
1381         long     proj  = get_Proj_proj(node);
1382
1383         if (is_Store(pred)) {
1384                 if (proj == pn_Store_M) {
1385                         return be_transform_node(pred);
1386                 } else {
1387                         panic("Unsupported Proj from Store");
1388                 }
1389         } else if (is_Load(pred)) {
1390                 return gen_Proj_Load(node);
1391         } else if (is_CopyB(pred)) {
1392                 return gen_Proj_CopyB(node);
1393         } else if (is_Quot(pred)) {
1394                 return gen_Proj_Quot(node);
1395         } else if (be_is_SubSP(pred)) {
1396                 return gen_Proj_be_SubSP(node);
1397         } else if (be_is_AddSP(pred)) {
1398                 return gen_Proj_be_AddSP(node);
1399         } else if (is_Cmp(pred)) {
1400                 return gen_Proj_Cmp(node);
1401         } else if (is_Start(pred)) {
1402                 if (proj == pn_Start_X_initial_exec) {
1403                         ir_node *block = get_nodes_block(pred);
1404                         ir_node *jump;
1405
1406                         /* we exchange the ProjX with a jump */
1407                         block = be_transform_node(block);
1408                         jump  = new_rd_Jmp(dbgi, block);
1409                         return jump;
1410                 }
1411                 if (node == get_irg_anchor(irg, anchor_tls)) {
1412                         return gen_Proj_tls(node);
1413                 }
1414         } else {
1415                 ir_node *new_pred = be_transform_node(pred);
1416                 ir_mode *mode     = get_irn_mode(node);
1417                 if (mode_needs_gp_reg(mode)) {
1418                         ir_node *block    = be_transform_node(get_nodes_block(node));
1419                         ir_node *new_proj = new_r_Proj(block, new_pred, mode_Iu,
1420                                                        get_Proj_proj(node));
1421                         new_proj->node_nr = node->node_nr;
1422                         return new_proj;
1423                 }
1424         }
1425
1426         return be_duplicate_node(node);
1427 }
1428
1429 typedef ir_node *(*create_const_node_func)(dbg_info *db, ir_node *block);
1430
1431 static inline ir_node *create_const(ir_node **place,
1432                                     create_const_node_func func,
1433                                     const arch_register_t* reg)
1434 {
1435         ir_node *block, *res;
1436
1437         if (*place != NULL)
1438                 return *place;
1439
1440         block = get_irg_start_block(env_cg->irg);
1441         res = func(NULL, block);
1442         arch_set_irn_register(res, reg);
1443         *place = res;
1444         return res;
1445 }
1446
1447 static ir_node *gen_Unknown(ir_node *node)
1448 {
1449         ir_node  *block     = get_nodes_block(node);
1450         ir_node  *new_block = be_transform_node(block);
1451         dbg_info *dbgi      = get_irn_dbg_info(node);
1452
1453         /* just produce a 0 */
1454         ir_mode *mode = get_irn_mode(node);
1455         if (mode_is_float(mode)) {
1456                 tarval *tv = get_mode_null(mode);
1457                 ir_node *node = new_bd_arm_fpaConst(dbgi, new_block, tv);
1458                 be_dep_on_frame(node);
1459                 return node;
1460         } else if (mode_needs_gp_reg(mode)) {
1461                 return create_const_graph_value(dbgi, new_block, 0);
1462         }
1463
1464         panic("Unexpected Unknown mode");
1465 }
1466
1467 /**
1468  * Change some phi modes
1469  */
1470 static ir_node *gen_Phi(ir_node *node)
1471 {
1472         const arch_register_req_t *req;
1473         ir_node  *block = be_transform_node(get_nodes_block(node));
1474         ir_graph *irg   = current_ir_graph;
1475         dbg_info *dbgi  = get_irn_dbg_info(node);
1476         ir_mode  *mode  = get_irn_mode(node);
1477         ir_node  *phi;
1478
1479         if (mode_needs_gp_reg(mode)) {
1480                 /* we shouldn't have any 64bit stuff around anymore */
1481                 assert(get_mode_size_bits(mode) <= 32);
1482                 /* all integer operations are on 32bit registers now */
1483                 mode = mode_Iu;
1484                 req  = arm_reg_classes[CLASS_arm_gp].class_req;
1485         } else {
1486                 req = arch_no_register_req;
1487         }
1488
1489         /* phi nodes allow loops, so we use the old arguments for now
1490          * and fix this later */
1491         phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
1492                           get_irn_in(node) + 1);
1493         copy_node_attr(node, phi);
1494         be_duplicate_deps(node, phi);
1495
1496         arch_set_out_register_req(phi, 0, req);
1497
1498         be_enqueue_preds(node);
1499
1500         return phi;
1501 }
1502
1503 /**
1504  * the BAD transformer.
1505  */
1506 static ir_node *bad_transform(ir_node *irn)
1507 {
1508         panic("ARM backend: Not implemented: %+F", irn);
1509 }
1510
1511 /**
1512  * Set a node emitter. Make it a bit more type safe.
1513  */
1514 static void set_transformer(ir_op *op, be_transform_func arm_transform_func)
1515 {
1516         op->ops.generic = (op_func)arm_transform_func;
1517 }
1518
1519 /**
1520  * Enters all transform functions into the generic pointer
1521  */
1522 static void arm_register_transformers(void)
1523 {
1524         /* first clear the generic function pointer for all ops */
1525         clear_irp_opcodes_generic_func();
1526
1527         set_transformer(op_Abs,          gen_Abs);
1528         set_transformer(op_Add,          gen_Add);
1529         set_transformer(op_And,          gen_And);
1530         set_transformer(op_be_AddSP,     gen_be_AddSP);
1531         set_transformer(op_be_Call,      gen_be_Call);
1532         set_transformer(op_be_Copy,      gen_be_Copy);
1533         set_transformer(op_be_FrameAddr, gen_be_FrameAddr);
1534         set_transformer(op_be_SubSP,     gen_be_SubSP);
1535         set_transformer(op_Cmp,          gen_Cmp);
1536         set_transformer(op_Cond,         gen_Cond);
1537         set_transformer(op_Const,        gen_Const);
1538         set_transformer(op_Conv,         gen_Conv);
1539         set_transformer(op_CopyB,        gen_CopyB);
1540         set_transformer(op_Eor,          gen_Eor);
1541         set_transformer(op_Jmp,          gen_Jmp);
1542         set_transformer(op_Load,         gen_Load);
1543         set_transformer(op_Minus,        gen_Minus);
1544         set_transformer(op_Mul,          gen_Mul);
1545         set_transformer(op_Not,          gen_Not);
1546         set_transformer(op_Or,           gen_Or);
1547         set_transformer(op_Phi,          gen_Phi);
1548         set_transformer(op_Proj,         gen_Proj);
1549         set_transformer(op_Quot,         gen_Quot);
1550         set_transformer(op_Rotl,         gen_Rotl);
1551         set_transformer(op_Shl,          gen_Shl);
1552         set_transformer(op_Shr,          gen_Shr);
1553         set_transformer(op_Shrs,         gen_Shrs);
1554         set_transformer(op_Store,        gen_Store);
1555         set_transformer(op_Sub,          gen_Sub);
1556         set_transformer(op_SymConst,     gen_SymConst);
1557         set_transformer(op_Unknown,      gen_Unknown);
1558
1559         set_transformer(op_ASM,       bad_transform);
1560         set_transformer(op_Builtin,   bad_transform);
1561         set_transformer(op_CallBegin, bad_transform);
1562         set_transformer(op_Cast,      bad_transform);
1563         set_transformer(op_Confirm,   bad_transform);
1564         set_transformer(op_DivMod,    bad_transform);
1565         set_transformer(op_EndExcept, bad_transform);
1566         set_transformer(op_EndReg,    bad_transform);
1567         set_transformer(op_Filter,    bad_transform);
1568         set_transformer(op_Free,      bad_transform);
1569         set_transformer(op_Id,        bad_transform);
1570         set_transformer(op_InstOf,    bad_transform);
1571         set_transformer(op_Mulh,      bad_transform);
1572         set_transformer(op_Mux,       bad_transform);
1573         set_transformer(op_Raise,     bad_transform);
1574         set_transformer(op_Sel,       bad_transform);
1575         set_transformer(op_Tuple,     bad_transform);
1576 }
1577
1578 /**
1579  * Pre-transform all unknown nodes.
1580  */
1581 static void arm_pretransform_node(void)
1582 {
1583         arm_code_gen_t *cg = env_cg;
1584
1585         cg->unknown_gp  = be_pre_transform_node(cg->unknown_gp);
1586         cg->unknown_fpa = be_pre_transform_node(cg->unknown_fpa);
1587 }
1588
1589 /**
1590  * Initialize fpa Immediate support.
1591  */
1592 static void arm_init_fpa_immediate(void)
1593 {
1594         /* 0, 1, 2, 3, 4, 5, 10, or 0.5. */
1595         fpa_imm[0][fpa_null]  = get_tarval_null(mode_F);
1596         fpa_imm[0][fpa_one]   = get_tarval_one(mode_F);
1597         fpa_imm[0][fpa_two]   = new_tarval_from_str("2", 1, mode_F);
1598         fpa_imm[0][fpa_three] = new_tarval_from_str("3", 1, mode_F);
1599         fpa_imm[0][fpa_four]  = new_tarval_from_str("4", 1, mode_F);
1600         fpa_imm[0][fpa_five]  = new_tarval_from_str("5", 1, mode_F);
1601         fpa_imm[0][fpa_ten]   = new_tarval_from_str("10", 2, mode_F);
1602         fpa_imm[0][fpa_half]  = new_tarval_from_str("0.5", 3, mode_F);
1603
1604         fpa_imm[1][fpa_null]  = get_tarval_null(mode_D);
1605         fpa_imm[1][fpa_one]   = get_tarval_one(mode_D);
1606         fpa_imm[1][fpa_two]   = new_tarval_from_str("2", 1, mode_D);
1607         fpa_imm[1][fpa_three] = new_tarval_from_str("3", 1, mode_D);
1608         fpa_imm[1][fpa_four]  = new_tarval_from_str("4", 1, mode_D);
1609         fpa_imm[1][fpa_five]  = new_tarval_from_str("5", 1, mode_D);
1610         fpa_imm[1][fpa_ten]   = new_tarval_from_str("10", 2, mode_D);
1611         fpa_imm[1][fpa_half]  = new_tarval_from_str("0.5", 3, mode_D);
1612
1613         fpa_imm[2][fpa_null]  = get_tarval_null(mode_E);
1614         fpa_imm[2][fpa_one]   = get_tarval_one(mode_E);
1615         fpa_imm[2][fpa_two]   = new_tarval_from_str("2", 1, mode_E);
1616         fpa_imm[2][fpa_three] = new_tarval_from_str("3", 1, mode_E);
1617         fpa_imm[2][fpa_four]  = new_tarval_from_str("4", 1, mode_E);
1618         fpa_imm[2][fpa_five]  = new_tarval_from_str("5", 1, mode_E);
1619         fpa_imm[2][fpa_ten]   = new_tarval_from_str("10", 2, mode_E);
1620         fpa_imm[2][fpa_half]  = new_tarval_from_str("0.5", 3, mode_E);
1621 }
1622
1623 /**
1624  * Transform a Firm graph into an ARM graph.
1625  */
1626 void arm_transform_graph(arm_code_gen_t *cg)
1627 {
1628         static int imm_initialized = 0;
1629
1630         if (! imm_initialized) {
1631                 arm_init_fpa_immediate();
1632                 imm_initialized = 1;
1633         }
1634         arm_register_transformers();
1635         env_cg = cg;
1636         be_transform_graph(cg->birg, arm_pretransform_node);
1637 }
1638
1639 void arm_init_transform(void)
1640 {
1641         FIRM_DBG_REGISTER(dbg, "firm.be.arm.transform");
1642 }