deb99f50fd2fc4f33f3ec9b96e0e94b1ec4f1dab
[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 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "irnode_t.h"
31 #include "irgraph_t.h"
32 #include "irmode_t.h"
33 #include "irgmod.h"
34 #include "iredges.h"
35 #include "irvrfy.h"
36 #include "ircons.h"
37 #include "irprintf.h"
38 #include "dbginfo.h"
39 #include "iropt_t.h"
40 #include "debug.h"
41 #include "error.h"
42
43 #include "../benode_t.h"
44 #include "../beirg_t.h"
45 #include "../beutil.h"
46 #include "../betranshlp.h"
47 #include "bearch_arm_t.h"
48
49 #include "arm_nodes_attr.h"
50 #include "archop.h"
51 #include "arm_transform.h"
52 #include "arm_new_nodes.h"
53 #include "arm_map_regs.h"
54
55 #include "gen_arm_regalloc_if.h"
56
57 #include <limits.h>
58
59
60 /** hold the current code generator during transformation */
61 static arm_code_gen_t *env_cg;
62
63 extern ir_op *get_op_Mulh(void);
64
65
66 /****************************************************************************************************
67  *                  _        _                        __                           _   _
68  *                 | |      | |                      / _|                         | | (_)
69  *  _ __   ___   __| | ___  | |_ _ __ __ _ _ __  ___| |_ ___  _ __ _ __ ___   __ _| |_ _  ___  _ __
70  * | '_ \ / _ \ / _` |/ _ \ | __| '__/ _` | '_ \/ __|  _/ _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \
71  * | | | | (_) | (_| |  __/ | |_| | | (_| | | | \__ \ || (_) | |  | | | | | | (_| | |_| | (_) | | | |
72  * |_| |_|\___/ \__,_|\___|  \__|_|  \__,_|_| |_|___/_| \___/|_|  |_| |_| |_|\__,_|\__|_|\___/|_| |_|
73  *
74  ****************************************************************************************************/
75
76 static INLINE int mode_needs_gp_reg(ir_mode *mode) {
77         return mode_is_int(mode) || mode_is_reference(mode);
78 }
79
80 typedef struct vals_ {
81         int ops;
82         unsigned char values[4];
83         unsigned char shifts[4];
84 } vals;
85
86 /** Execute ROL. */
87 static unsigned do_rol(unsigned v, unsigned rol) {
88         return (v << rol) | (v >> (32 - rol));
89 }
90
91 /**
92  * construct 8bit values and rot amounts for a value
93  */
94 static void gen_vals_from_word(unsigned int value, vals *result)
95 {
96         int initial = 0;
97
98         memset(result, 0, sizeof(*result));
99
100         /* special case: we prefer shift amount 0 */
101         if (value < 0x100) {
102                 result->values[0] = value;
103                 result->ops       = 1;
104                 return;
105         }
106
107         while (value != 0) {
108                 if (value & 0xFF) {
109                         unsigned v = do_rol(value, 8) & 0xFFFFFF;
110                         int shf = 0;
111                         for (;;) {
112                                 if ((v & 3) != 0)
113                                         break;
114                                 shf += 2;
115                                 v >>= 2;
116                         }
117                         v  &= 0xFF;
118                         shf = (initial + shf - 8) & 0x1F;
119                         result->values[result->ops] = v;
120                         result->shifts[result->ops] = shf;
121                         ++result->ops;
122
123                         value ^= do_rol(v, shf) >> initial;
124                 }
125                 else {
126                         value >>= 8;
127                         initial += 8;
128                 }
129         }
130 }
131
132 /**
133  * Creates a arm_Const node.
134  */
135 static ir_node *create_const_node(dbg_info *dbg, ir_node *block, long value) {
136         ir_mode *mode  = mode_Iu;
137         tarval   *tv   = new_tarval_from_long(value, mode);
138         ir_graph *irg  = current_ir_graph;
139         ir_node *res;
140
141         if (mode_needs_gp_reg(mode))
142                 mode = mode_Iu;
143         res = new_rd_arm_Mov_i(dbg, irg, block, mode, tv);
144         /* ensure the const is scheduled AFTER the stack frame */
145         add_irn_dep(res, get_irg_frame(irg));
146         return res;
147 }
148
149 /**
150  * Creates a arm_Const_Neg node.
151  */
152 static ir_node *create_const_neg_node(dbg_info *dbg, ir_node *block, long value) {
153         ir_mode *mode = mode_Iu;
154         tarval  *tv   = new_tarval_from_long(value, mode);
155         ir_graph *irg  = current_ir_graph;
156         ir_node *res;
157
158         if (mode_needs_gp_reg(mode))
159                 mode = mode_Iu;
160         res = new_rd_arm_Mvn_i(dbg, irg, block, mode, tv);
161         /* ensure the const is scheduled AFTER the stack frame */
162         add_irn_dep(res, get_irg_frame(irg));
163         return res;
164 }
165
166 #define NEW_BINOP_NODE(opname, env, op1, op2) new_rd_arm_##opname(env->dbg, current_ir_graph, env->block, op1, op2, env->mode)
167
168 /**
169  * Encodes an immediate with shifter operand
170  */
171 static unsigned int arm_encode_imm_w_shift(unsigned int shift, unsigned int immediate) {
172         return immediate | ((shift>>1)<<8);
173 }
174
175 /**
176  * Decode an immediate with shifter operand
177  */
178 unsigned int arm_decode_imm_w_shift(tarval *tv) {
179         unsigned l = get_tarval_long(tv);
180         unsigned rol = (l & ~0xFF) >> 7;
181
182         return do_rol(l & 0xFF, rol);
183 }
184
185 /**
186  * Creates a possible DAG for an constant.
187  */
188 static ir_node *create_const_graph_value(dbg_info *dbg, ir_node *block, unsigned int value) {
189         ir_node *result;
190         vals v, vn;
191         int cnt;
192         ir_mode *mode = mode_Iu;
193
194         gen_vals_from_word(value, &v);
195         gen_vals_from_word(~value, &vn);
196
197         if (vn.ops < v.ops) {
198                 /* remove bits */
199                 result = create_const_neg_node(dbg, block, arm_encode_imm_w_shift(vn.shifts[0], vn.values[0]));
200
201                 for (cnt = 1; cnt < vn.ops; ++cnt) {
202                         tarval *tv = new_tarval_from_long(arm_encode_imm_w_shift(vn.shifts[cnt], vn.values[cnt]), mode);
203                         ir_node *bic_i_node = new_rd_arm_Bic_i(dbg, current_ir_graph, block, result, mode, tv);
204                         result = bic_i_node;
205                 }
206         }
207         else {
208                 /* add bits */
209                 result = create_const_node(dbg, block, arm_encode_imm_w_shift(v.shifts[0], v.values[0]));
210
211                 for (cnt = 1; cnt < v.ops; ++cnt) {
212                         tarval *tv = new_tarval_from_long(arm_encode_imm_w_shift(v.shifts[cnt], v.values[cnt]), mode);
213                         ir_node *orr_i_node = new_rd_arm_Or_i(dbg, current_ir_graph, block, result, mode, tv);
214                         result = orr_i_node;
215                 }
216         }
217         return result;
218 }
219
220 /**
221  * Create a DAG constructing a given Const.
222  *
223  * @param irn  a Firm const
224  */
225 static ir_node *create_const_graph(ir_node *irn, ir_node *block) {
226         tarval  *tv = get_Const_tarval(irn);
227         ir_mode *mode = get_tarval_mode(tv);
228         int     value;
229
230         if (mode_is_reference(mode)) {
231                 /* ARM is 32bit, so we can safely convert a reference tarval into Iu */
232                 assert(get_mode_size_bits(mode) == get_mode_size_bits(mode_Iu));
233                 tv = tarval_convert_to(tv, mode_Iu);
234         }
235         value = get_tarval_long(tv);
236         return create_const_graph_value(get_irn_dbg_info(irn), block, value);
237 }
238
239 /**
240  * Create an And that will mask all upper bits
241  */
242 static ir_node *gen_zero_extension(dbg_info *dbg, ir_node *block, ir_node *op, int result_bits) {
243         unsigned mask_bits = (1 << result_bits) - 1;
244         ir_node *mask_node = create_const_graph_value(dbg, block, mask_bits);
245         return new_rd_arm_And(dbg, current_ir_graph, block, op, mask_node, mode_Iu, ARM_SHF_NONE, NULL);
246 }
247
248 /**
249  * Generate code for a sign extension.
250  */
251 static ir_node *gen_sign_extension(dbg_info *dbg, ir_node *block, ir_node *op, int result_bits) {
252         ir_graph *irg   = current_ir_graph;
253         int shift_width = 32 - result_bits;
254         ir_node *shift_const_node = create_const_graph_value(dbg, block, shift_width);
255         ir_node *lshift_node = new_rd_arm_Shl(dbg, irg, block, op, shift_const_node, mode_Iu);
256         ir_node *rshift_node = new_rd_arm_Shrs(dbg, irg, block, lshift_node, shift_const_node, mode_Iu);
257         return rshift_node;
258 }
259
260 /**
261  * Transforms a Conv node.
262  *
263  * @return The created ia32 Conv node
264  */
265 static ir_node *gen_Conv(ir_node *node) {
266         ir_node  *block    = be_transform_node(get_nodes_block(node));
267         ir_node  *op       = get_Conv_op(node);
268         ir_node  *new_op   = be_transform_node(op);
269         ir_graph *irg      = current_ir_graph;
270         ir_mode  *src_mode = get_irn_mode(op);
271         ir_mode  *dst_mode = get_irn_mode(node);
272         dbg_info *dbg      = get_irn_dbg_info(node);
273
274         if (src_mode == dst_mode)
275                 return new_op;
276
277         if (mode_is_float(src_mode) || mode_is_float(dst_mode)) {
278                 env_cg->have_fp_insn = 1;
279
280                 if (USE_FPA(env_cg->isa)) {
281                         if (mode_is_float(src_mode)) {
282                                 if (mode_is_float(dst_mode)) {
283                                         /* from float to float */
284                                         return new_rd_arm_fpaMvf(dbg, irg, block, new_op, dst_mode);
285                                 }
286                                 else {
287                                         /* from float to int */
288                                         return new_rd_arm_fpaFix(dbg, irg, block, new_op, dst_mode);
289                                 }
290                         }
291                         else {
292                                 /* from int to float */
293                                 return new_rd_arm_fpaFlt(dbg, irg, block, new_op, dst_mode);
294                         }
295                 }
296                 else if (USE_VFP(env_cg->isa)) {
297                         panic("VFP not supported yet\n");
298                         return NULL;
299                 }
300                 else {
301                         panic("Softfloat not supported yet\n");
302                         return NULL;
303                 }
304         }
305         else { /* complete in gp registers */
306                 int src_bits = get_mode_size_bits(src_mode);
307                 int dst_bits = get_mode_size_bits(dst_mode);
308                 int min_bits;
309                 ir_mode *min_mode;
310
311                 if (is_Load(skip_Proj(op))) {
312                         if (src_bits == dst_bits) {
313                                 /* kill unneccessary conv */
314                                 return new_op;
315                         }
316                         /* after a load, the bit size is already converted */
317                         src_bits = 32;
318                 }
319
320                 if (src_bits == dst_bits) {
321                         /* kill unneccessary conv */
322                         return new_op;
323                 } else if (dst_bits <= 32 && src_bits <= 32) {
324                         if (src_bits < dst_bits) {
325                                 min_bits = src_bits;
326                                 min_mode = src_mode;
327                         } else {
328                                 min_bits = dst_bits;
329                                 min_mode = dst_mode;
330                         }
331                         if (mode_is_signed(min_mode)) {
332                                 return gen_sign_extension(dbg, block, new_op, min_bits);
333                         } else {
334                                 return gen_zero_extension(dbg, block, new_op, min_bits);
335                         }
336                 } else {
337                         panic("Cannot handle Conv %+F->%+F with %d->%d bits\n", src_mode, dst_mode,
338                                 src_bits, dst_bits);
339                         return NULL;
340                 }
341         }
342 }
343
344 /**
345  * Return true if an operand is a shifter operand
346  */
347 static int is_shifter_operand(ir_node *n, arm_shift_modifier *pmod) {
348         arm_shift_modifier mod = ARM_SHF_NONE;
349
350         if (is_arm_Mov(n))
351                 mod = get_arm_shift_modifier(n);
352
353         *pmod = mod;
354         if (mod != ARM_SHF_NONE) {
355                 long v = get_tarval_long(get_arm_value(n));
356                 if (v < 32)
357                         return (int)v;
358         }
359         return 0;
360 }
361
362 /**
363  * Creates an ARM Add.
364  *
365  * @return the created arm Add node
366  */
367 static ir_node *gen_Add(ir_node *node) {
368         ir_node  *block   = be_transform_node(get_nodes_block(node));
369         ir_node  *op1     = get_Add_left(node);
370         ir_node  *new_op1 = be_transform_node(op1);
371         ir_node  *op2     = get_Add_right(node);
372         ir_node  *new_op2 = be_transform_node(op2);
373         ir_mode  *mode    = get_irn_mode(node);
374         ir_graph *irg     = current_ir_graph;
375         ir_node  *new_op3;
376         int v;
377         arm_shift_modifier mod;
378         dbg_info *dbg = get_irn_dbg_info(node);
379
380         if (mode_is_float(mode)) {
381                 env_cg->have_fp_insn = 1;
382                 if (USE_FPA(env_cg->isa)) {
383                         if (is_arm_fpaMvf_i(new_op1))
384                                 return new_rd_arm_fpaAdf_i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1));
385                         if (is_arm_fpaMvf_i(new_op2))
386                                 return new_rd_arm_fpaAdf_i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2));
387                         return new_rd_arm_fpaAdf(dbg, irg, block, new_op1, new_op2, mode);
388                 } else if (USE_VFP(env_cg->isa)) {
389                         assert(mode != mode_E && "IEEE Extended FP not supported");
390                         panic("VFP not supported yet\n");
391                         return NULL;
392                 }
393                 else {
394                         panic("Softfloat not supported yet\n");
395                         return NULL;
396                 }
397         } else {
398                 assert(mode_is_data(mode));
399                 mode = mode_Iu;
400
401                 if (is_arm_Mov_i(new_op1))
402                         return new_rd_arm_Add_i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1));
403                 if (is_arm_Mov_i(new_op2))
404                         return new_rd_arm_Add_i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2));
405
406                 /* check for MLA */
407                 if (is_arm_Mul(new_op1) && get_irn_n_edges(op1) == 1) {
408                         new_op3 = new_op2;
409                         new_op2 = get_irn_n(new_op1, 1);
410                         new_op1 = get_irn_n(new_op1, 0);
411
412                         return new_rd_arm_Mla(dbg, irg, block, new_op1, new_op2, new_op3, mode);
413                 }
414                 if (is_arm_Mul(new_op2) && get_irn_n_edges(op2) == 1) {
415                         new_op3 = new_op1;
416                         new_op1 = get_irn_n(new_op2, 0);
417                         new_op2 = get_irn_n(new_op2, 1);
418
419                         return new_rd_arm_Mla(dbg, irg, block, new_op1, new_op2, new_op3, mode);
420                 }
421
422                 /* is the first a shifter */
423                 v = is_shifter_operand(new_op1, &mod);
424                 if (v) {
425                         new_op1 = get_irn_n(new_op1, 0);
426                         return new_rd_arm_Add(dbg, irg, block, new_op2, new_op1, mode, mod, new_tarval_from_long(v, mode_Iu));
427                 }
428                 /* is the second a shifter */
429                 v = is_shifter_operand(new_op2, &mod);
430                 if (v) {
431                         new_op2 = get_irn_n(new_op2, 0);
432                         return new_rd_arm_Add(dbg, irg, block, new_op1, new_op2, mode, mod, new_tarval_from_long(v, mode_Iu));
433                 }
434
435                 /* normal ADD */
436                 return new_rd_arm_Add(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, NULL);
437         }
438 }
439
440 /**
441  * Creates an ARM Mul.
442  *
443  * @return the created arm Mul node
444  */
445 static ir_node *gen_Mul(ir_node *node) {
446         ir_node  *block   = be_transform_node(get_nodes_block(node));
447         ir_node  *op1     = get_Mul_left(node);
448         ir_node  *new_op1 = be_transform_node(op1);
449         ir_node  *op2     = get_Mul_right(node);
450         ir_node  *new_op2 = be_transform_node(op2);
451         ir_mode  *mode    = get_irn_mode(node);
452         ir_graph *irg     = current_ir_graph;
453         dbg_info *dbg     = get_irn_dbg_info(node);
454
455         if (mode_is_float(mode)) {
456                 env_cg->have_fp_insn = 1;
457                 if (USE_FPA(env_cg->isa)) {
458                         if (is_arm_Mov_i(new_op1))
459                                 return new_rd_arm_fpaMuf_i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1));
460                         if (is_arm_Mov_i(new_op2))
461                                 return new_rd_arm_fpaMuf_i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2));
462                         return new_rd_arm_fpaMuf(dbg, irg, block, new_op1, new_op2, mode);
463                 }
464                 else if (USE_VFP(env_cg->isa)) {
465                         assert(mode != mode_E && "IEEE Extended FP not supported");
466                         panic("VFP not supported yet\n");
467                         return NULL;
468                 }
469                 else {
470                         panic("Softfloat not supported yet\n");
471                         return NULL;
472                 }
473         }
474         assert(mode_is_data(mode));
475         mode = mode_Iu;
476         return new_rd_arm_Mul(dbg, irg, block, new_op1, new_op2, mode);
477 }
478
479 /**
480  * Creates an ARM floating point Div.
481  *
482  * @param env   The transformation environment
483  * @return the created arm fDiv node
484  */
485 static ir_node *gen_Quot(ir_node *node) {
486         ir_node  *block   = be_transform_node(get_nodes_block(node));
487         ir_node  *op1     = get_Quot_left(node);
488         ir_node  *new_op1 = be_transform_node(op1);
489         ir_node  *op2     = get_Quot_right(node);
490         ir_node  *new_op2 = be_transform_node(op2);
491         ir_mode  *mode    = get_irn_mode(node);
492         dbg_info *dbg     = get_irn_dbg_info(node);
493
494         assert(mode != mode_E && "IEEE Extended FP not supported");
495
496         env_cg->have_fp_insn = 1;
497         if (USE_FPA(env_cg->isa)) {
498                 if (is_arm_Mov_i(new_op1))
499                         return new_rd_arm_fpaRdf_i(dbg, current_ir_graph, block, new_op2, mode, get_arm_value(new_op1));
500                 if (is_arm_Mov_i(new_op2))
501                         return new_rd_arm_fpaDvf_i(dbg, current_ir_graph, block, new_op1, mode, get_arm_value(new_op2));
502                 return new_rd_arm_fpaDvf(dbg, current_ir_graph, block, new_op1, new_op2, mode);
503         } else if (USE_VFP(env_cg->isa)) {
504                 assert(mode != mode_E && "IEEE Extended FP not supported");
505                 panic("VFP not supported yet\n");
506         }
507         else {
508                 panic("Softfloat not supported yet\n");
509                 return NULL;
510         }
511 }
512
513 #define GEN_INT_OP(op) \
514         ir_node  *block   = be_transform_node(get_nodes_block(node)); \
515         ir_node  *op1     = get_ ## op ## _left(node); \
516         ir_node  *new_op1 = be_transform_node(op1); \
517         ir_node  *op2     = get_ ## op ## _right(node); \
518         ir_node  *new_op2 = be_transform_node(op2); \
519         ir_graph *irg     = current_ir_graph; \
520         ir_mode  *mode    = mode_Iu; \
521         dbg_info *dbg     = get_irn_dbg_info(node); \
522         int      v; \
523         arm_shift_modifier mod; \
524  \
525         if (is_arm_Mov_i(new_op1)) \
526                 return new_rd_arm_ ## op ## _i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1)); \
527         if (is_arm_Mov_i(new_op2)) \
528                 return new_rd_arm_ ## op ## _i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2)); \
529         /* is the first a shifter */ \
530         v = is_shifter_operand(new_op1, &mod); \
531         if (v) { \
532                 new_op1 = get_irn_n(new_op1, 0); \
533                 return new_rd_arm_ ## op(dbg, irg, block, new_op2, new_op1, mode, mod, new_tarval_from_long(v, mode_Iu)); \
534         } \
535         /* is the second a shifter */ \
536         v = is_shifter_operand(new_op2, &mod); \
537         if (v) { \
538                 new_op2 = get_irn_n(new_op2, 0); \
539                 return new_rd_arm_ ## op(dbg, irg, block, new_op1, new_op2, mode, mod, new_tarval_from_long(v, mode_Iu)); \
540         } \
541         /* Normal op */ \
542         return new_rd_arm_ ## op(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, NULL) \
543
544 /**
545  * Creates an ARM And.
546  *
547  * @return the created arm And node
548  */
549 static ir_node *gen_And(ir_node *node) {
550         GEN_INT_OP(And);
551 }
552
553 /**
554  * Creates an ARM Orr.
555  *
556  * @param env   The transformation environment
557  * @return the created arm Or node
558  */
559 static ir_node *gen_Or(ir_node *node) {
560         GEN_INT_OP(Or);
561 }
562
563 /**
564  * Creates an ARM Eor.
565  *
566  * @return the created arm Eor node
567  */
568 static ir_node *gen_Eor(ir_node *node) {
569         GEN_INT_OP(Eor);
570 }
571
572 /**
573  * Creates an ARM Sub.
574  *
575  * @return the created arm Sub node
576  */
577 static ir_node *gen_Sub(ir_node *node) {
578         ir_node  *block   = be_transform_node(get_nodes_block(node));
579         ir_node  *op1     = get_Sub_left(node);
580         ir_node  *new_op1 = be_transform_node(op1);
581         ir_node  *op2     = get_Sub_right(node);
582         ir_node  *new_op2 = be_transform_node(op2);
583         ir_mode  *mode    = get_irn_mode(node);
584         ir_graph *irg     = current_ir_graph;
585         dbg_info *dbg     = get_irn_dbg_info(node);
586         int      v;
587         arm_shift_modifier mod;
588
589         if (mode_is_float(mode)) {
590                 env_cg->have_fp_insn = 1;
591                 if (USE_FPA(env_cg->isa)) {
592                         if (is_arm_Mov_i(new_op1))
593                                 return new_rd_arm_fpaRsf_i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1));
594                         if (is_arm_Mov_i(new_op2))
595                                 return new_rd_arm_fpaSuf_i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2));
596                         return new_rd_arm_fpaSuf(dbg, irg, block, new_op1, new_op2, mode);
597                 } else if (USE_VFP(env_cg->isa)) {
598                         assert(mode != mode_E && "IEEE Extended FP not supported");
599                         panic("VFP not supported yet\n");
600                         return NULL;
601                 }
602                 else {
603                         panic("Softfloat not supported yet\n");
604                         return NULL;
605                 }
606         }
607         else {
608                 assert(mode_is_data(mode) && "unknown mode for Sub");
609                 mode = mode_Iu;
610
611                 if (is_arm_Mov_i(new_op1))
612                         return new_rd_arm_Rsb_i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1));
613                 if (is_arm_Mov_i(new_op2))
614                         return new_rd_arm_Sub_i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2));
615
616                 /* is the first a shifter */
617                 v = is_shifter_operand(new_op1, &mod);
618                 if (v) {
619                         new_op1 = get_irn_n(new_op1, 0);
620                         return new_rd_arm_Rsb(dbg, irg, block, new_op2, new_op1, mode, mod, new_tarval_from_long(v, mode_Iu));
621                 }
622                 /* is the second a shifter */
623                 v = is_shifter_operand(new_op2, &mod);
624                 if (v) {
625                         new_op2 = get_irn_n(new_op2, 0);
626                         return new_rd_arm_Sub(dbg, irg, block, new_op1, new_op2, mode, mod, new_tarval_from_long(v, mode_Iu));
627                 }
628                 /* normal sub */
629                 return new_rd_arm_Sub(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, NULL);
630         }
631 }
632
633 /**
634  * Creates an ARM Shl.
635  *
636  * @return the created ARM Shl node
637  */
638 static ir_node *gen_Shl(ir_node *node) {
639         ir_node  *block   = be_transform_node(get_nodes_block(node));
640         ir_node  *op1     = get_Shl_left(node);
641         ir_node  *new_op1 = be_transform_node(op1);
642         ir_node  *op2     = get_Shl_right(node);
643         ir_node  *new_op2 = be_transform_node(op2);
644         ir_mode  *mode    = mode_Iu;
645         dbg_info *dbg     = get_irn_dbg_info(node);
646
647         if (is_arm_Mov_i(new_op2)) {
648                 return new_rd_arm_Mov(dbg, current_ir_graph, block, new_op1, mode, ARM_SHF_LSL, get_arm_value(new_op2));
649         }
650         return new_rd_arm_Shl(dbg, current_ir_graph, block, new_op1, new_op2, mode);
651 }
652
653 /**
654  * Creates an ARM Shr.
655  *
656  * @return the created ARM Shr node
657  */
658 static ir_node *gen_Shr(ir_node *node) {
659         ir_node  *block   = be_transform_node(get_nodes_block(node));
660         ir_node  *op1     = get_Shr_left(node);
661         ir_node  *new_op1 = be_transform_node(op1);
662         ir_node  *op2     = get_Shr_right(node);
663         ir_node  *new_op2 = be_transform_node(op2);
664         ir_mode  *mode    = mode_Iu;
665         dbg_info *dbg     = get_irn_dbg_info(node);
666
667         if (is_arm_Mov_i(new_op2)) {
668                 return new_rd_arm_Mov(dbg, current_ir_graph, block, new_op1, mode, ARM_SHF_LSR, get_arm_value(new_op2));
669         }
670         return new_rd_arm_Shr(dbg, current_ir_graph, block, new_op1, new_op2, mode);
671 }
672
673 /**
674  * Creates an ARM Shrs.
675  *
676  * @return the created ARM Shrs node
677  */
678 static ir_node *gen_Shrs(ir_node *node) {
679         ir_node  *block   = be_transform_node(get_nodes_block(node));
680         ir_node  *op1     = get_Shrs_left(node);
681         ir_node  *new_op1 = be_transform_node(op1);
682         ir_node  *op2     = get_Shrs_right(node);
683         ir_node  *new_op2 = be_transform_node(op2);
684         ir_mode  *mode    = mode_Iu;
685         dbg_info *dbg     = get_irn_dbg_info(node);
686
687         if (is_arm_Mov_i(new_op2)) {
688                 return new_rd_arm_Mov(dbg, current_ir_graph, block, new_op1, mode, ARM_SHF_ASR, get_arm_value(new_op2));
689         }
690         return new_rd_arm_Shrs(dbg, current_ir_graph, block, new_op1, new_op2, mode);
691 }
692
693 /**
694  * Transforms a Not node.
695  *
696  * @return the created ARM Not node
697  */
698 static ir_node *gen_Not(ir_node *node) {
699         ir_node  *block   = be_transform_node(get_nodes_block(node));
700         ir_node  *op      = get_Not_op(node);
701         ir_node  *new_op  = be_transform_node(op);
702         dbg_info *dbg     = get_irn_dbg_info(node);
703         tarval   *tv      = NULL;
704         ir_mode  *mode    = mode_Iu;
705         arm_shift_modifier mod = ARM_SHF_NONE;
706         int      v        = is_shifter_operand(new_op, &mod);
707
708         if (v) {
709                 new_op = get_irn_n(new_op, 0);
710                 tv = new_tarval_from_long(v, mode_Iu);
711         }
712         return new_rd_arm_Mvn(dbg, current_ir_graph, block, new_op, mode, mod, tv);
713 }
714
715 /**
716  * Transforms an Abs node.
717  *
718  * @param env   The transformation environment
719  * @return the created ARM Abs node
720  */
721 static ir_node *gen_Abs(ir_node *node) {
722         ir_node  *block   = be_transform_node(get_nodes_block(node));
723         ir_node  *op      = get_Abs_op(node);
724         ir_node  *new_op  = be_transform_node(op);
725         dbg_info *dbg     = get_irn_dbg_info(node);
726         ir_mode  *mode    = get_irn_mode(node);
727
728         if (mode_is_float(mode)) {
729                 env_cg->have_fp_insn = 1;
730                 if (USE_FPA(env_cg->isa))
731                         return new_rd_arm_fpaAbs(dbg, current_ir_graph, block, new_op, mode);
732                 else if (USE_VFP(env_cg->isa)) {
733                         assert(mode != mode_E && "IEEE Extended FP not supported");
734                         panic("VFP not supported yet\n");
735                 }
736                 else {
737                         panic("Softfloat not supported yet\n");
738                 }
739         }
740         assert(mode_is_data(mode));
741         mode = mode_Iu;
742         return new_rd_arm_Abs(dbg, current_ir_graph, block, new_op, mode);
743 }
744
745 /**
746  * Transforms a Minus node.
747  *
748  * @return the created ARM Minus node
749  */
750 static ir_node *gen_Minus(ir_node *node) {
751         ir_node  *block   = be_transform_node(get_nodes_block(node));
752         ir_node  *op      = get_Minus_op(node);
753         ir_node  *new_op  = be_transform_node(op);
754         dbg_info *dbg     = get_irn_dbg_info(node);
755         ir_mode  *mode    = get_irn_mode(node);
756
757         if (mode_is_float(mode)) {
758                 env_cg->have_fp_insn = 1;
759                 if (USE_FPA(env_cg->isa))
760                         return new_rd_arm_fpaMvf(dbg, current_ir_graph, block, op, mode);
761                 else if (USE_VFP(env_cg->isa)) {
762                         assert(mode != mode_E && "IEEE Extended FP not supported");
763                         panic("VFP not supported yet\n");
764                 }
765                 else {
766                         panic("Softfloat not supported yet\n");
767                 }
768         }
769         assert(mode_is_data(mode));
770         mode = mode_Iu;
771         return new_rd_arm_Rsb_i(dbg, current_ir_graph, block, new_op, mode, get_mode_null(mode));
772 }
773
774 /**
775  * Transforms a Load.
776  *
777  * @return the created ARM Load node
778  */
779 static ir_node *gen_Load(ir_node *node) {
780         ir_node  *block    = be_transform_node(get_nodes_block(node));
781         ir_node  *ptr      = get_Load_ptr(node);
782         ir_node  *new_ptr  = be_transform_node(ptr);
783         ir_node  *mem      = get_Load_mem(node);
784         ir_node  *new_mem  = be_transform_node(mem);
785         ir_mode  *mode     = get_Load_mode(node);
786         ir_graph *irg      = current_ir_graph;
787         dbg_info *dbg      = get_irn_dbg_info(node);
788         ir_node  *new_load = NULL;
789
790         if (mode_is_float(mode)) {
791                 env_cg->have_fp_insn = 1;
792                 if (USE_FPA(env_cg->isa))
793                         new_load = new_rd_arm_fpaLdf(dbg, irg, block, new_ptr, new_mem, mode);
794                 else if (USE_VFP(env_cg->isa)) {
795                         assert(mode != mode_E && "IEEE Extended FP not supported");
796                         panic("VFP not supported yet\n");
797                 }
798                 else {
799                         panic("Softfloat not supported yet\n");
800                 }
801         }
802         else {
803                 assert(mode_is_data(mode) && "unsupported mode for Load");
804
805                 if (mode_is_signed(mode)) {
806                         /* sign extended loads */
807                         switch (get_mode_size_bits(mode)) {
808                         case 8:
809                                 new_load = new_rd_arm_Loadbs(dbg, irg, block, new_ptr, new_mem);
810                                 break;
811                         case 16:
812                                 new_load = new_rd_arm_Loadhs(dbg, irg, block, new_ptr, new_mem);
813                                 break;
814                         case 32:
815                                 new_load = new_rd_arm_Load(dbg, irg, block, new_ptr, new_mem);
816                                 break;
817                         default:
818                                 panic("mode size not supported\n");
819                         }
820                 } else {
821                         /* zero extended loads */
822                         switch (get_mode_size_bits(mode)) {
823                         case 8:
824                                 new_load = new_rd_arm_Loadb(dbg, irg, block, new_ptr, new_mem);
825                                 break;
826                         case 16:
827                                 new_load = new_rd_arm_Loadh(dbg, irg, block, new_ptr, new_mem);
828                                 break;
829                         case 32:
830                                 new_load = new_rd_arm_Load(dbg, irg, block, new_ptr, new_mem);
831                                 break;
832                         default:
833                                 panic("mode size not supported\n");
834                         }
835                 }
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(irg, block, new_load, mode_Iu, pn_arm_Load_res);
843                 be_new_Keep(arch_get_irn_reg_class(env_cg->arch_env, proj, -1), irg, 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         ir_node  *block    = be_transform_node(get_nodes_block(node));
856         ir_node  *ptr      = get_Store_ptr(node);
857         ir_node  *new_ptr  = be_transform_node(ptr);
858         ir_node  *mem      = get_Store_mem(node);
859         ir_node  *new_mem  = be_transform_node(mem);
860         ir_node  *val      = get_Store_value(node);
861         ir_node  *new_val  = be_transform_node(val);
862         ir_mode  *mode     = get_irn_mode(val);
863         ir_graph *irg      = current_ir_graph;
864         dbg_info *dbg      = 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_rd_arm_fpaStf(dbg, irg, block, new_ptr, new_val, new_mem, mode);
871                 else if (USE_VFP(env_cg->isa)) {
872                         assert(mode != mode_E && "IEEE Extended FP not supported");
873                         panic("VFP not supported yet\n");
874                 } else {
875                         panic("Softfloat not supported yet\n");
876                 }
877         } else {
878                 assert(mode_is_data(mode) && "unsupported mode for Store");
879                 switch (get_mode_size_bits(mode)) {
880                 case 8:
881                         new_store = new_rd_arm_Storeb(dbg, irg, block, new_ptr, new_val, new_mem);
882                 case 16:
883                         new_store = new_rd_arm_Storeh(dbg, irg, block, new_ptr, new_val, new_mem);
884                 default:
885                         new_store = new_rd_arm_Store(dbg, irg, block, new_ptr, new_val, new_mem);
886                 }
887         }
888         set_irn_pinned(new_store, get_irn_pinned(node));
889         return new_store;
890 }
891
892 /**
893  * Transforms a Cond.
894  *
895  * @return the created ARM Cond node
896  */
897 static ir_node *gen_Cond(ir_node *node) {
898         ir_node  *block    = be_transform_node(get_nodes_block(node));
899         ir_node  *selector = get_Cond_selector(node);
900         ir_graph *irg      = current_ir_graph;
901         dbg_info *dbg      = get_irn_dbg_info(node);
902         ir_mode  *mode     = get_irn_mode(selector);
903
904         if (mode == mode_b) {
905                 /* an conditional jump */
906                 ir_node *cmp_node = get_Proj_pred(selector);
907                 ir_node *op1      = get_Cmp_left(cmp_node);
908                 ir_node *new_op1  = be_transform_node(op1);
909                 ir_node *op2      = get_Cmp_right(cmp_node);
910                 ir_node *new_op2  = be_transform_node(op2);
911
912                 if (mode_is_float(get_irn_mode(op1))) {
913                         /* floating point compare */
914                         pn_Cmp pnc = get_Proj_proj(selector);
915
916                         if (pnc & pn_Cmp_Uo) {
917                                 /* check for unordered, need cmf */
918                                 return new_rd_arm_fpaCmfBra(dbg, irg, block, new_op1, new_op2, pnc);
919                         }
920                         /* Hmm: use need cmfe */
921                         return new_rd_arm_fpaCmfeBra(dbg, irg, block, new_op1, new_op2, pnc);
922                 } else {
923                         /* integer compare */
924                         return new_rd_arm_CmpBra(dbg, irg, block, new_op1, new_op2, get_Proj_proj(selector));
925                 }
926         } else {
927                 /* SwitchJmp */
928                 ir_node *new_op = be_transform_node(selector);
929                 ir_node *const_graph;
930                 ir_node *sub;
931
932                 ir_node *proj;
933                 const ir_edge_t *edge;
934                 int min = INT_MAX;
935                 int max = INT_MIN;
936                 int translation;
937                 int pn;
938                 int n_projs;
939
940                 foreach_out_edge(node, edge) {
941                         proj = get_edge_src_irn(edge);
942                         assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
943
944                         pn = get_Proj_proj(proj);
945
946                         min = pn<min ? pn : min;
947                         max = pn>max ? pn : max;
948                 }
949                 translation = min;
950                 n_projs = max - translation + 1;
951
952                 foreach_out_edge(node, edge) {
953                         proj = get_edge_src_irn(edge);
954                         assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
955
956                         pn = get_Proj_proj(proj) - translation;
957                         set_Proj_proj(proj, pn);
958                 }
959
960                 const_graph = create_const_graph_value(dbg, block, translation);
961                 sub = new_rd_arm_Sub(dbg, irg, block, new_op, const_graph, mode, ARM_SHF_NONE, NULL);
962                 return new_rd_arm_SwitchJmp(dbg, irg, block, sub, n_projs, get_Cond_defaultProj(node) - translation);
963         }
964 }
965
966 /**
967  * Returns the name of a SymConst.
968  * @param symc  the SymConst
969  * @return name of the SymConst
970  */
971 static ident *get_sc_ident(ir_node *symc) {
972         ir_entity *ent;
973
974         switch (get_SymConst_kind(symc)) {
975                 case symconst_addr_name:
976                         return get_SymConst_name(symc);
977
978                 case symconst_addr_ent:
979                         ent = get_SymConst_entity(symc);
980                         set_entity_backend_marked(ent, 1);
981                         return get_entity_ld_ident(ent);
982
983                 default:
984                         assert(0 && "Unsupported SymConst");
985         }
986
987         return NULL;
988 }
989
990 enum fpa_immediates {
991         fpa_null = 0,
992         fpa_one,
993         fpa_two,
994         fpa_three,
995         fpa_four,
996         fpa_five,
997         fpa_ten,
998         fpa_half,
999         fpa_max
1000 };
1001
1002 static tarval *fpa_imm[3][fpa_max];
1003
1004 /**
1005  * Check, if a floating point tarval is an fpa immediate, i.e.
1006  * one of 0, 1, 2, 3, 4, 5, 10, or 0.5.
1007  */
1008 static int is_fpa_immediate(tarval *tv) {
1009         ir_mode *mode = get_tarval_mode(tv);
1010         int i, j, res = 1;
1011
1012         switch (get_mode_size_bits(mode)) {
1013         case 32:
1014                 i = 0;
1015                 break;
1016         case 64:
1017                 i = 1;
1018                 break;
1019         default:
1020                 i = 2;
1021         }
1022
1023         if (tarval_cmp(tv, get_tarval_null(mode)) & pn_Cmp_Lt) {
1024                 tv = tarval_neg(tv);
1025                 res = -1;
1026         }
1027
1028         for (j = 0; j < fpa_max; ++j) {
1029                 if (tv == fpa_imm[i][j])
1030                         return res;
1031         }
1032         return 0;
1033 }
1034
1035 /**
1036  * Transforms a Const node.
1037  *
1038  * @return The transformed ARM node.
1039  */
1040 static ir_node *gen_Const(ir_node *node) {
1041         ir_node  *block = be_transform_node(get_nodes_block(node));
1042         ir_graph *irg = current_ir_graph;
1043         ir_mode *mode = get_irn_mode(node);
1044         dbg_info *dbg = get_irn_dbg_info(node);
1045
1046         if (mode_is_float(mode)) {
1047                 env_cg->have_fp_insn = 1;
1048                 if (USE_FPA(env_cg->isa)) {
1049                         tarval *tv = get_Const_tarval(node);
1050                         int imm = is_fpa_immediate(tv);
1051
1052                         if (imm) {
1053                                 if (imm > 0)
1054                                         node = new_rd_arm_fpaMvf_i(dbg, irg, block, tv);
1055                                 else
1056                                         node = new_rd_arm_fpaMnf_i(dbg, irg, block, tv);
1057                         } else {
1058                                 node = new_rd_arm_fpaConst(dbg, irg, block, tv);
1059                         }
1060                         /* ensure the const is scheduled AFTER the stack frame */
1061                         add_irn_dep(node, get_irg_frame(irg));
1062                         return node;
1063                 }
1064                 else if (USE_VFP(env_cg->isa)) {
1065                         assert(mode != mode_E && "IEEE Extended FP not supported");
1066                         panic("VFP not supported yet\n");
1067                 }
1068                 else {
1069                         panic("Softfloat not supported yet\n");
1070                 }
1071         }
1072         return create_const_graph(node, block);
1073 }
1074
1075 /**
1076  * Transforms a SymConst node.
1077  *
1078  * @return The transformed ARM node.
1079  */
1080 static ir_node *gen_SymConst(ir_node *node) {
1081         ir_node  *block = be_transform_node(get_nodes_block(node));
1082         ir_mode  *mode  = mode_Iu;
1083         dbg_info *dbg   = get_irn_dbg_info(node);
1084         ir_graph *irg   = current_ir_graph;
1085         ir_node  *res;
1086
1087         res = new_rd_arm_SymConst(dbg, irg, block, mode, get_sc_ident(node));
1088         /* ensure the const is scheduled AFTER the stack frame */
1089         add_irn_dep(res, get_irg_frame(irg));
1090         return res;
1091 }
1092
1093 /**
1094  * Transforms a CopyB node.
1095  *
1096  * @return The transformed ARM node.
1097  */
1098 static ir_node *gen_CopyB(ir_node *node) {
1099         ir_node  *block    = be_transform_node(get_nodes_block(node));
1100         ir_node  *src      = get_CopyB_src(node);
1101         ir_node  *new_src  = be_transform_node(src);
1102         ir_node  *dst      = get_CopyB_dst(node);
1103         ir_node  *new_dst  = be_transform_node(dst);
1104         ir_node  *mem      = get_CopyB_mem(node);
1105         ir_node  *new_mem  = be_transform_node(mem);
1106         ir_graph *irg      = current_ir_graph;
1107         dbg_info *dbg      = get_irn_dbg_info(node);
1108         int      size      = get_type_size_bytes(get_CopyB_type(node));
1109         ir_node  *src_copy;
1110         ir_node  *dst_copy;
1111
1112         src_copy = be_new_Copy(&arm_reg_classes[CLASS_arm_gp], irg, block, new_src);
1113         dst_copy = be_new_Copy(&arm_reg_classes[CLASS_arm_gp], irg, block, new_dst);
1114
1115         return new_rd_arm_CopyB(dbg, irg, block, dst_copy, src_copy,
1116                         new_rd_arm_EmptyReg(dbg, irg, block, mode_Iu),
1117                         new_rd_arm_EmptyReg(dbg, irg, block, mode_Iu),
1118                         new_rd_arm_EmptyReg(dbg, irg, block, mode_Iu),
1119                         new_mem, new_tarval_from_long(size, mode_Iu));
1120 }
1121
1122
1123 /********************************************
1124  *  _                          _
1125  * | |                        | |
1126  * | |__   ___ _ __   ___   __| | ___  ___
1127  * | '_ \ / _ \ '_ \ / _ \ / _` |/ _ \/ __|
1128  * | |_) |  __/ | | | (_) | (_| |  __/\__ \
1129  * |_.__/ \___|_| |_|\___/ \__,_|\___||___/
1130  *
1131  ********************************************/
1132
1133 /**
1134  * Return an expanding stack offset.
1135  * Note that function is called in the transform phase
1136  * where the stack offsets are still relative regarding
1137  * the first (frame allocating) IncSP.
1138  * However this is exactly what we want because frame
1139  * access must be done relative the the fist IncSP ...
1140  */
1141 static int get_sp_expand_offset(ir_node *inc_sp) {
1142         int offset = be_get_IncSP_offset(inc_sp);
1143
1144         if (offset == BE_STACK_FRAME_SIZE_EXPAND)
1145                 return 0;
1146
1147         return offset;
1148 }
1149
1150 #if 0
1151 static ir_node *gen_StackParam(ir_node *irn) {
1152         ir_node  *block    = be_transform_node(get_nodes_block(node));
1153         ir_node   *new_op = NULL;
1154         ir_node   *noreg  = ia32_new_NoReg_gp(env->cg);
1155         ir_node   *mem    = new_rd_NoMem(env->irg);
1156         ir_node   *ptr    = get_irn_n(irn, 0);
1157         ir_entity *ent    = be_get_frame_entity(irn);
1158         ir_mode   *mode   = env->mode;
1159
1160 //      /* If the StackParam has only one user ->     */
1161 //      /* put it in the Block where the user resides */
1162 //      if (get_irn_n_edges(node) == 1) {
1163 //              env->block = get_nodes_block(get_edge_src_irn(get_irn_out_edge_first(node)));
1164 //      }
1165
1166         if (mode_is_float(mode)) {
1167                 if (USE_SSE2(env->cg))
1168                         new_op = new_rd_ia32_fLoad(env->dbg, env->irg, block, ptr, noreg, mem, mode_T);
1169                 else {
1170                         env->cg->used_x87 = 1;
1171                         new_op = new_rd_ia32_vfld(env->dbg, env->irg, block, ptr, noreg, mem, mode_T);
1172                 }
1173         }
1174         else {
1175                 new_op = new_rd_ia32_Load(env->dbg, env->irg, block, ptr, noreg, mem, mode_T);
1176         }
1177
1178         set_ia32_frame_ent(new_op, ent);
1179         set_ia32_use_frame(new_op);
1180
1181         set_ia32_am_support(new_op, ia32_am_Source);
1182         set_ia32_op_type(new_op, ia32_AddrModeS);
1183         set_ia32_am_flavour(new_op, ia32_B);
1184         set_ia32_ls_mode(new_op, mode);
1185
1186         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
1187
1188         return new_rd_Proj(env->dbg, env->irg, block, new_op, mode, 0);
1189 }
1190 #endif
1191
1192 /**
1193  * Transforms a FrameAddr into an ARM Add.
1194  */
1195 static ir_node *gen_be_FrameAddr(ir_node *node) {
1196         ir_node   *block  = be_transform_node(get_nodes_block(node));
1197         ir_entity *ent    = be_get_frame_entity(node);
1198         int       offset  = get_entity_offset(ent);
1199         ir_node   *op     = be_get_FrameAddr_frame(node);
1200         ir_node   *new_op = be_transform_node(op);
1201         dbg_info  *dbg    = get_irn_dbg_info(node);
1202         ir_mode   *mode   = mode_Iu;
1203         ir_node   *cnst;
1204
1205         if (be_is_IncSP(op)) {
1206                 /* BEWARE: we get an offset which is absolute from an offset that
1207                    is relative. Both must be merged */
1208                 offset += get_sp_expand_offset(op);
1209         }
1210         cnst = create_const_graph_value(dbg, block, (unsigned)offset);
1211         if (is_arm_Mov_i(cnst))
1212                 return new_rd_arm_Add_i(dbg, current_ir_graph, block, new_op, mode, get_arm_value(cnst));
1213         return new_rd_arm_Add(dbg, current_ir_graph, block, new_op, cnst, mode, ARM_SHF_NONE, NULL);
1214 }
1215
1216 #if 0
1217 /**
1218  * Transforms a FrameLoad into an ARM Load.
1219  */
1220 static ir_node *gen_FrameLoad(ir_node *irn) {
1221         ir_node   *new_op = NULL;
1222         ir_node   *noreg  = ia32_new_NoReg_gp(env->cg);
1223         ir_node   *mem    = get_irn_n(irn, 0);
1224         ir_node   *ptr    = get_irn_n(irn, 1);
1225         ir_entity *ent    = be_get_frame_entity(irn);
1226         ir_mode   *mode   = get_type_mode(get_entity_type(ent));
1227
1228         if (mode_is_float(mode)) {
1229                 if (USE_SSE2(env->cg))
1230                         new_op = new_rd_ia32_fLoad(env->dbg, current_ir_graph, env->block, ptr, noreg, mem, mode_T);
1231                 else {
1232                         env->cg->used_x87 = 1;
1233                         new_op = new_rd_ia32_vfld(env->dbg, current_ir_graph, env->block, ptr, noreg, mem, mode_T);
1234                 }
1235         }
1236         else {
1237                 new_op = new_rd_ia32_Load(env->dbg, current_ir_graph, env->block, ptr, noreg, mem, mode_T);
1238         }
1239
1240         set_ia32_frame_ent(new_op, ent);
1241         set_ia32_use_frame(new_op);
1242
1243         set_ia32_am_support(new_op, ia32_am_Source);
1244         set_ia32_op_type(new_op, ia32_AddrModeS);
1245         set_ia32_am_flavour(new_op, ia32_B);
1246         set_ia32_ls_mode(new_op, mode);
1247
1248         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
1249
1250         return new_op;
1251 }
1252 #endif
1253
1254 /**
1255  * Transform a be_AddSP into an arm_AddSP. Eat up const sizes.
1256  */
1257 static ir_node *gen_be_AddSP(ir_node *node) {
1258         ir_node  *block  = be_transform_node(get_nodes_block(node));
1259         ir_node  *sz     = get_irn_n(node, be_pos_AddSP_size);
1260         ir_node  *new_sz = be_transform_node(sz);
1261         ir_node  *sp     = get_irn_n(node, be_pos_AddSP_old_sp);
1262         ir_node  *new_sp = be_transform_node(sp);
1263         ir_graph *irg    = current_ir_graph;
1264         dbg_info *dbgi   = get_irn_dbg_info(node);
1265         ir_node  *nomem  = new_NoMem();
1266         ir_node  *new_op;
1267
1268         /* ARM stack grows in reverse direction, make a SubSP */
1269         new_op = new_rd_arm_SubSP(dbgi, irg, block, new_sp, new_sz, nomem);
1270
1271         return new_op;
1272 }
1273
1274 /**
1275  * Transform a be_SubSP into an arm_SubSP. Eat up const sizes.
1276  */
1277 static ir_node *gen_be_SubSP(ir_node *node) {
1278         ir_node  *block  = be_transform_node(get_nodes_block(node));
1279         ir_node  *sz     = get_irn_n(node, be_pos_SubSP_size);
1280         ir_node  *new_sz = be_transform_node(sz);
1281         ir_node  *sp     = get_irn_n(node, be_pos_SubSP_old_sp);
1282         ir_node  *new_sp = be_transform_node(sp);
1283         ir_graph *irg    = current_ir_graph;
1284         dbg_info *dbgi   = get_irn_dbg_info(node);
1285         ir_node  *nomem  = new_NoMem();
1286         ir_node  *new_op;
1287
1288         /* ARM stack grows in reverse direction, make an AddSP */
1289         new_op = new_rd_arm_AddSP(dbgi, irg, block, new_sp, new_sz, nomem);
1290
1291         return new_op;
1292 }
1293
1294 /**
1295  * Transform a be_Copy.
1296  */
1297 static ir_node *gen_be_Copy(ir_node *node) {
1298         ir_node *result = be_duplicate_node(node);
1299         ir_mode *mode   = get_irn_mode(result);
1300
1301         if (mode_needs_gp_reg(mode)) {
1302                 set_irn_mode(node, mode_Iu);
1303         }
1304
1305         return result;
1306 }
1307
1308 /**
1309  * Transform a Proj from a Load.
1310  */
1311 static ir_node *gen_Proj_Load(ir_node *node) {
1312         ir_node  *block    = be_transform_node(get_nodes_block(node));
1313         ir_node  *load     = get_Proj_pred(node);
1314         ir_node  *new_load = be_transform_node(load);
1315         ir_graph *irg      = current_ir_graph;
1316         dbg_info *dbgi     = get_irn_dbg_info(node);
1317         long     proj      = get_Proj_proj(node);
1318
1319         /* renumber the proj */
1320         switch (get_arm_irn_opcode(new_load)) {
1321         case iro_arm_Load:
1322         case iro_arm_Loadb:
1323         case iro_arm_Loadbs:
1324         case iro_arm_Loadh:
1325         case iro_arm_Loadhs:
1326                 /* handle all gp loads equal: they have the same proj numbers. */
1327                 if (proj == pn_Load_res) {
1328                         return new_rd_Proj(dbgi, irg, block, new_load, mode_Iu, pn_arm_Load_res);
1329                 } else if (proj == pn_Load_M) {
1330                         return new_rd_Proj(dbgi, irg, block, new_load, mode_M, pn_arm_Load_M);
1331                 }
1332                 break;
1333         case iro_arm_fpaLdf:
1334                 if (proj == pn_Load_res) {
1335                         ir_mode *mode = get_Load_mode(load);
1336                         return new_rd_Proj(dbgi, irg, block, new_load, mode, pn_arm_fpaLdf_res);
1337                 } else if (proj == pn_Load_M) {
1338                         return new_rd_Proj(dbgi, irg, block, new_load, mode_M, pn_arm_fpaLdf_M);
1339                 }
1340                 break;
1341         default:
1342                 break;
1343         }
1344         assert(0);
1345         return new_rd_Unknown(irg, get_irn_mode(node));
1346 }
1347
1348 /**
1349  * Transform and renumber the Projs from a CopyB.
1350  */
1351 static ir_node *gen_Proj_CopyB(ir_node *node) {
1352         ir_node  *block    = be_transform_node(get_nodes_block(node));
1353         ir_node  *pred     = get_Proj_pred(node);
1354         ir_node  *new_pred = be_transform_node(pred);
1355         ir_graph *irg      = current_ir_graph;
1356         dbg_info *dbgi     = get_irn_dbg_info(node);
1357         ir_mode  *mode     = get_irn_mode(node);
1358         long     proj      = get_Proj_proj(node);
1359
1360         switch(proj) {
1361         case pn_CopyB_M_regular:
1362                 if (is_arm_CopyB(new_pred)) {
1363                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_CopyB_M);
1364                 }
1365                 break;
1366         default:
1367                 break;
1368         }
1369         assert(0);
1370         return new_rd_Unknown(irg, mode);
1371 }
1372
1373 /**
1374  * Transform and renumber the Projs from a Quot.
1375  */
1376 static ir_node *gen_Proj_Quot(ir_node *node) {
1377         ir_node  *block    = be_transform_node(get_nodes_block(node));
1378         ir_node  *pred     = get_Proj_pred(node);
1379         ir_node  *new_pred = be_transform_node(pred);
1380         ir_graph *irg      = current_ir_graph;
1381         dbg_info *dbgi     = get_irn_dbg_info(node);
1382         ir_mode  *mode     = get_irn_mode(node);
1383         long     proj      = get_Proj_proj(node);
1384
1385         switch (proj) {
1386         case pn_Quot_M:
1387                 if (is_arm_fpaDvf(new_pred) || is_arm_fpaDvf_i(new_pred)) {
1388                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaDvf_M);
1389                 } else if (is_arm_fpaRdf(new_pred) || is_arm_fpaRdf_i(new_pred)) {
1390                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaRdf_M);
1391                 } else if (is_arm_fpaFdv(new_pred) || is_arm_fpaFdv_i(new_pred)) {
1392                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaFdv_M);
1393                 } else if (is_arm_fpaFrd(new_pred) || is_arm_fpaFrd_i(new_pred)) {
1394                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaFrd_M);
1395                 }
1396                 break;
1397         case pn_Quot_res:
1398                 if (is_arm_fpaDvf(new_pred) || is_arm_fpaDvf_i(new_pred)) {
1399                         return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaDvf_res);
1400                 } else if (is_arm_fpaRdf(new_pred) || is_arm_fpaRdf_i(new_pred)) {
1401                         return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaRdf_res);
1402                 } else if (is_arm_fpaFdv(new_pred) || is_arm_fpaFdv_i(new_pred)) {
1403                         return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaFdv_res);
1404                 } else if (is_arm_fpaFrd(new_pred) || is_arm_fpaFrd_i(new_pred)) {
1405                         return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaFrd_res);
1406                 }
1407                 break;
1408         default:
1409                 break;
1410         }
1411         assert(0);
1412         return new_rd_Unknown(irg, mode);
1413 }
1414
1415 /**
1416  * Transform the Projs of an AddSP.
1417  */
1418 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
1419         ir_node  *block    = be_transform_node(get_nodes_block(node));
1420         ir_node  *pred     = get_Proj_pred(node);
1421         ir_node  *new_pred = be_transform_node(pred);
1422         ir_graph *irg      = current_ir_graph;
1423         dbg_info *dbgi     = get_irn_dbg_info(node);
1424         long     proj      = get_Proj_proj(node);
1425
1426         if (proj == pn_be_AddSP_res) {
1427                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_arm_AddSP_stack);
1428                 arch_set_irn_register(env_cg->arch_env, res, &arm_gp_regs[REG_SP]);
1429                 return res;
1430         } else if (proj == pn_be_AddSP_M) {
1431                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_AddSP_M);
1432         }
1433
1434         assert(0);
1435         return new_rd_Unknown(irg, get_irn_mode(node));
1436 }
1437
1438 /**
1439  * Transform the Projs of a SubSP.
1440  */
1441 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
1442         ir_node  *block    = be_transform_node(get_nodes_block(node));
1443         ir_node  *pred     = get_Proj_pred(node);
1444         ir_node  *new_pred = be_transform_node(pred);
1445         ir_graph *irg      = current_ir_graph;
1446         dbg_info *dbgi     = get_irn_dbg_info(node);
1447         long     proj      = get_Proj_proj(node);
1448
1449         if (proj == pn_be_SubSP_sp) {
1450                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
1451                                            pn_arm_SubSP_stack);
1452                 arch_set_irn_register(env_cg->arch_env, res, &arm_gp_regs[REG_SP]);
1453                 return res;
1454         } else if (proj == pn_be_SubSP_M) {
1455                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_SubSP_M);
1456         }
1457
1458         assert(0);
1459         return new_rd_Unknown(irg, get_irn_mode(node));
1460 }
1461
1462 /**
1463  * Transform the Projs from a Cmp.
1464  */
1465 static ir_node *gen_Proj_Cmp(ir_node *node) {
1466         (void) node;
1467         panic("Psi NYI\n");
1468 }
1469
1470
1471 /**
1472  * Transform the Thread Local Storage Proj.
1473  */
1474 static ir_node *gen_Proj_tls(ir_node *node) {
1475         ir_node  *block = be_transform_node(get_nodes_block(node));
1476         ir_graph *irg   = current_ir_graph;
1477         dbg_info *dbgi  = NULL;
1478
1479         return new_rd_arm_LdTls(dbgi, irg, block, mode_Iu);
1480 }
1481
1482 /**
1483  * Transform a Proj node.
1484  */
1485 static ir_node *gen_Proj(ir_node *node) {
1486         ir_graph *irg  = current_ir_graph;
1487         dbg_info *dbgi = get_irn_dbg_info(node);
1488         ir_node  *pred = get_Proj_pred(node);
1489         long     proj  = get_Proj_proj(node);
1490
1491         if (is_Store(pred)) {
1492                 if (proj == pn_Store_M) {
1493                         return be_transform_node(pred);
1494                 } else {
1495                         assert(0);
1496                         return new_r_Bad(irg);
1497                 }
1498         } else if (is_Load(pred)) {
1499                 return gen_Proj_Load(node);
1500         } else if (is_CopyB(pred)) {
1501                 return gen_Proj_CopyB(node);
1502         } else if (is_Quot(pred)) {
1503                 return gen_Proj_Quot(node);
1504         } else if (be_is_SubSP(pred)) {
1505                 return gen_Proj_be_SubSP(node);
1506         } else if (be_is_AddSP(pred)) {
1507                 return gen_Proj_be_AddSP(node);
1508         } else if (is_Cmp(pred)) {
1509                 return gen_Proj_Cmp(node);
1510         } else if (get_irn_op(pred) == op_Start) {
1511                 if (proj == pn_Start_X_initial_exec) {
1512                         ir_node *block = get_nodes_block(pred);
1513                         ir_node *jump;
1514
1515                         /* we exchange the ProjX with a jump */
1516                         block = be_transform_node(block);
1517                         jump  = new_rd_Jmp(dbgi, irg, block);
1518                         ir_fprintf(stderr, "created jump: %+F\n", jump);
1519                         return jump;
1520                 }
1521                 if (node == get_irg_anchor(irg, anchor_tls)) {
1522                         return gen_Proj_tls(node);
1523                 }
1524         } else {
1525                 ir_node *new_pred = be_transform_node(pred);
1526                 ir_mode *mode     = get_irn_mode(node);
1527                 if (mode_needs_gp_reg(mode)) {
1528                         ir_node *block    = be_transform_node(get_nodes_block(node));
1529                         ir_node *new_proj = new_r_Proj(irg, block, new_pred, mode_Iu,
1530                                                        get_Proj_proj(node));
1531 #ifdef DEBUG_libfirm
1532                         new_proj->node_nr = node->node_nr;
1533 #endif
1534                         return new_proj;
1535                 }
1536         }
1537
1538         return be_duplicate_node(node);
1539 }
1540
1541 typedef ir_node *(*create_const_node_func)(dbg_info *db, ir_graph *irg, ir_node *block);
1542
1543 static INLINE ir_node *create_const(ir_node **place,
1544                                     create_const_node_func func,
1545                                     const arch_register_t* reg)
1546 {
1547         ir_node *block, *res;
1548
1549         if (*place != NULL)
1550                 return *place;
1551
1552         block = get_irg_start_block(env_cg->irg);
1553         res = func(NULL, env_cg->irg, block);
1554         arch_set_irn_register(env_cg->arch_env, res, reg);
1555         *place = res;
1556
1557         add_irn_dep(get_irg_end(env_cg->irg), res);
1558         return res;
1559 }
1560
1561 static ir_node *arm_new_Unknown_gp(void) {
1562         return create_const(&env_cg->unknown_gp, new_rd_arm_Unknown_GP,
1563                             &arm_gp_regs[REG_GP_UKNWN]);
1564 }
1565
1566 static ir_node *arm_new_Unknown_fpa(void) {
1567         return create_const(&env_cg->unknown_fpa, new_rd_arm_Unknown_FPA,
1568                             &arm_fpa_regs[REG_FPA_UKNWN]);
1569 }
1570
1571 /**
1572  * This function just sets the register for the Unknown node
1573  * as this is not done during register allocation because Unknown
1574  * is an "ignore" node.
1575  */
1576 static ir_node *gen_Unknown(ir_node *node) {
1577         ir_mode *mode = get_irn_mode(node);
1578         if (mode_is_float(mode)) {
1579                 if (USE_FPA(env_cg->isa))
1580                         return arm_new_Unknown_fpa();
1581                 else if (USE_VFP(env_cg->isa))
1582                         panic("VFP not supported yet");
1583                 else
1584                         panic("Softfloat not supported yet");
1585         } else if (mode_needs_gp_reg(mode)) {
1586                 return arm_new_Unknown_gp();
1587         } else {
1588                 assert(0 && "unsupported Unknown-Mode");
1589         }
1590
1591         return NULL;
1592 }
1593
1594 /**
1595  * Change some phi modes
1596  */
1597 static ir_node *gen_Phi(ir_node *node) {
1598         ir_node  *block = be_transform_node(get_nodes_block(node));
1599         ir_graph *irg   = current_ir_graph;
1600         dbg_info *dbgi  = get_irn_dbg_info(node);
1601         ir_mode  *mode  = get_irn_mode(node);
1602         ir_node  *phi;
1603
1604         if (mode_needs_gp_reg(mode)) {
1605                 /* we shouldn't have any 64bit stuff around anymore */
1606                 assert(get_mode_size_bits(mode) <= 32);
1607                 /* all integer operations are on 32bit registers now */
1608                 mode = mode_Iu;
1609         }
1610
1611         /* phi nodes allow loops, so we use the old arguments for now
1612          * and fix this later */
1613         phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node), get_irn_in(node) + 1);
1614         copy_node_attr(node, phi);
1615         be_duplicate_deps(node, phi);
1616
1617         be_set_transformed_node(node, phi);
1618         be_enqueue_preds(node);
1619
1620         return phi;
1621 }
1622
1623 /*********************************************************
1624  *                  _             _      _
1625  *                 (_)           | |    (_)
1626  *  _ __ ___   __ _ _ _ __     __| |_ __ ___   _____ _ __
1627  * | '_ ` _ \ / _` | | '_ \   / _` | '__| \ \ / / _ \ '__|
1628  * | | | | | | (_| | | | | | | (_| | |  | |\ V /  __/ |
1629  * |_| |_| |_|\__,_|_|_| |_|  \__,_|_|  |_| \_/ \___|_|
1630  *
1631  *********************************************************/
1632
1633 /**
1634  * the BAD transformer.
1635  */
1636 static ir_node *bad_transform(ir_node *irn) {
1637         panic("ARM backend: Not implemented: %+F\n", irn);
1638         return irn;
1639 }
1640
1641 /**
1642  * Set a node emitter. Make it a bit more type safe.
1643  */
1644 static INLINE void set_transformer(ir_op *op, be_transform_func arm_transform_func) {
1645         op->ops.generic = (op_func)arm_transform_func;
1646 }
1647
1648 /**
1649  * Enters all transform functions into the generic pointer
1650  */
1651 static void arm_register_transformers(void) {
1652         ir_op *op_Max, *op_Min, *op_Mulh;
1653
1654         /* first clear the generic function pointer for all ops */
1655         clear_irp_opcodes_generic_func();
1656
1657 #define GEN(a)     set_transformer(op_##a, gen_##a)
1658 #define BAD(a)     set_transformer(op_##a, bad_transform)
1659
1660         GEN(Add);
1661         GEN(Sub);
1662         GEN(Mul);
1663         GEN(And);
1664         GEN(Or);
1665         GEN(Eor);
1666
1667         GEN(Shl);
1668         GEN(Shr);
1669         GEN(Shrs);
1670         BAD(Rot);       /* unsupported yet */
1671
1672         GEN(Quot);
1673
1674         /* should be lowered */
1675         BAD(Div);
1676         BAD(Mod);
1677         BAD(DivMod);
1678
1679         GEN(Minus);
1680         GEN(Conv);
1681         GEN(Abs);
1682         GEN(Not);
1683
1684         GEN(Load);
1685         GEN(Store);
1686         GEN(Cond);
1687
1688         BAD(ASM);       /* unsupported yet */
1689         GEN(CopyB);
1690         BAD(Mux);
1691         BAD(Psi);       /* unsupported yet */
1692         GEN(Proj);
1693         GEN(Phi);
1694
1695         GEN(Const);
1696         GEN(SymConst);
1697
1698         /* we should never see these nodes */
1699         BAD(Raise);
1700         BAD(Sel);
1701         BAD(InstOf);
1702         BAD(Cast);
1703         BAD(Free);
1704         BAD(Tuple);
1705         BAD(Id);
1706         //BAD(Bad);
1707         BAD(Confirm);
1708         BAD(Filter);
1709         BAD(CallBegin);
1710         BAD(EndReg);
1711         BAD(EndExcept);
1712
1713         /* handle generic backend nodes */
1714         GEN(be_FrameAddr);
1715         //GEN(be_Call);
1716         //GEN(be_Return);
1717         GEN(be_AddSP);
1718         GEN(be_SubSP);
1719         GEN(be_Copy);
1720
1721         /* set the register for all Unknown nodes */
1722         GEN(Unknown);
1723
1724         op_Max = get_op_Max();
1725         if (op_Max)
1726                 BAD(Max);       /* unsupported yet */
1727         op_Min = get_op_Min();
1728         if (op_Min)
1729                 BAD(Min);       /* unsupported yet */
1730         op_Mulh = get_op_Mulh();
1731         if (op_Mulh)
1732                 BAD(Mulh);      /* unsupported yet */
1733
1734 #undef GEN
1735 #undef BAD
1736 }
1737
1738 /**
1739  * Pre-transform all unknown nodes.
1740  */
1741 static void arm_pretransform_node(void *arch_cg) {
1742         arm_code_gen_t *cg = arch_cg;
1743
1744         cg->unknown_gp  = be_pre_transform_node(cg->unknown_gp);
1745         cg->unknown_fpa = be_pre_transform_node(cg->unknown_fpa);
1746 }
1747
1748 /**
1749  * Initialize fpa Immediate support.
1750  */
1751 static void arm_init_fpa_immediate(void) {
1752         /* 0, 1, 2, 3, 4, 5, 10, or 0.5. */
1753         fpa_imm[0][fpa_null]  = get_tarval_null(mode_F);
1754         fpa_imm[0][fpa_one]   = get_tarval_one(mode_F);
1755         fpa_imm[0][fpa_two]   = new_tarval_from_str("2", 1, mode_F);
1756         fpa_imm[0][fpa_three] = new_tarval_from_str("3", 1, mode_F);
1757         fpa_imm[0][fpa_four]  = new_tarval_from_str("4", 1, mode_F);
1758         fpa_imm[0][fpa_five]  = new_tarval_from_str("5", 1, mode_F);
1759         fpa_imm[0][fpa_ten]   = new_tarval_from_str("10", 2, mode_F);
1760         fpa_imm[0][fpa_half]  = new_tarval_from_str("0.5", 3, mode_F);
1761
1762         fpa_imm[1][fpa_null]  = get_tarval_null(mode_D);
1763         fpa_imm[1][fpa_one]   = get_tarval_one(mode_D);
1764         fpa_imm[1][fpa_two]   = new_tarval_from_str("2", 1, mode_D);
1765         fpa_imm[1][fpa_three] = new_tarval_from_str("3", 1, mode_D);
1766         fpa_imm[1][fpa_four]  = new_tarval_from_str("4", 1, mode_D);
1767         fpa_imm[1][fpa_five]  = new_tarval_from_str("5", 1, mode_D);
1768         fpa_imm[1][fpa_ten]   = new_tarval_from_str("10", 2, mode_D);
1769         fpa_imm[1][fpa_half]  = new_tarval_from_str("0.5", 3, mode_D);
1770
1771         fpa_imm[2][fpa_null]  = get_tarval_null(mode_E);
1772         fpa_imm[2][fpa_one]   = get_tarval_one(mode_E);
1773         fpa_imm[2][fpa_two]   = new_tarval_from_str("2", 1, mode_E);
1774         fpa_imm[2][fpa_three] = new_tarval_from_str("3", 1, mode_E);
1775         fpa_imm[2][fpa_four]  = new_tarval_from_str("4", 1, mode_E);
1776         fpa_imm[2][fpa_five]  = new_tarval_from_str("5", 1, mode_E);
1777         fpa_imm[2][fpa_ten]   = new_tarval_from_str("10", 2, mode_E);
1778         fpa_imm[2][fpa_half]  = new_tarval_from_str("0.5", 3, mode_E);
1779 }
1780
1781 /**
1782  * Transform a Firm graph into an ARM graph.
1783  */
1784 void arm_transform_graph(arm_code_gen_t *cg) {
1785         static int imm_initialized = 0;
1786
1787         if (! imm_initialized) {
1788                 arm_init_fpa_immediate();
1789                 imm_initialized = 1;
1790         }
1791         arm_register_transformers();
1792         env_cg = cg;
1793         be_transform_graph(cg->birg, arm_pretransform_node, cg);
1794 }
1795
1796 void arm_init_transform(void) {
1797         // FIRM_DBG_REGISTER(dbg, "firm.be.arm.transform");
1798 }