arm_transform.c 60.3 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2010 University of Karlsruhe.  All right reserved.
Christian Würdig's avatar
Christian Würdig committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

20
21
/**
 * @file
Michael Beck's avatar
Michael Beck committed
22
 * @brief   The codegenerator (transform FIRM into arm FIRM)
23
 * @author  Matthias Braun, Oliver Richter, Tobias Gneist, Michael Beck
24
25
 * @version $Id$
 */
26
27
28
29
30
31
32
33
34
#include "config.h"

#include "irnode_t.h"
#include "irgraph_t.h"
#include "irmode_t.h"
#include "irgmod.h"
#include "iredges.h"
#include "irvrfy.h"
#include "ircons.h"
Michael Beck's avatar
Michael Beck committed
35
#include "irprintf.h"
36
37
38
#include "dbginfo.h"
#include "iropt_t.h"
#include "debug.h"
Michael Beck's avatar
Michael Beck committed
39
#include "error.h"
40

41
#include "../benode.h"
42
#include "../beirg.h"
43
#include "../beutil.h"
44
#include "../betranshlp.h"
45
46
#include "../beabihelper.h"
#include "../beabi.h"
47

48
#include "bearch_arm_t.h"
49
50
#include "arm_nodes_attr.h"
#include "arm_transform.h"
51
#include "arm_optimize.h"
52
53
#include "arm_new_nodes.h"
#include "arm_map_regs.h"
54
#include "arm_cconv.h"
55
56
57
58
59

#include "gen_arm_regalloc_if.h"

#include <limits.h>

60
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
Michael Beck's avatar
Michael Beck committed
61

62
63
/** hold the current code generator during transformation */
static arm_code_gen_t *env_cg;
64

65
66
static const arch_register_t *sp_reg = &arm_gp_regs[REG_SP];
static ir_mode               *mode_gp;
67
static ir_mode               *mode_fp;
68
69
70
71
72
73
static beabi_helper_env_t    *abihelper;
static calling_convention_t  *cconv = NULL;

static pmap                  *node_to_stack;

static bool mode_needs_gp_reg(ir_mode *mode)
74
{
75
	return mode_is_int(mode) || mode_is_reference(mode);
76
77
}

Michael Beck's avatar
Michael Beck committed
78
/**
79
 * create firm graph for a constant
Michael Beck's avatar
Michael Beck committed
80
 */
81
82
83
static ir_node *create_const_graph_value(dbg_info *dbgi, ir_node *block,
                                         unsigned int value)
{
84
	ir_node *result;
85
	arm_vals v, vn;
Michael Beck's avatar
Michael Beck committed
86
	int cnt;
87

88
89
90
91
92
93
	/* We only have 8 bit immediates. So we possibly have to combine several
	 * operations to construct the desired value.
	 *
	 * we can either create the value by adding bits to 0 or by removing bits
	 * from an register with all bits set. Try which alternative needs fewer
	 * operations */
94
95
	arm_gen_vals_from_word(value, &v);
	arm_gen_vals_from_word(~value, &vn);
Michael Beck's avatar
Michael Beck committed
96
97
98

	if (vn.ops < v.ops) {
		/* remove bits */
99
100
		result = new_bd_arm_Mvn_imm(dbgi, block, vn.values[0], vn.rors[0]);
		be_dep_on_frame(result);
Michael Beck's avatar
Michael Beck committed
101
102

		for (cnt = 1; cnt < vn.ops; ++cnt) {
103
104
			result = new_bd_arm_Bic_imm(dbgi, block, result,
			                            vn.values[cnt], vn.rors[cnt]);
105
		}
106
	} else {
Michael Beck's avatar
Michael Beck committed
107
		/* add bits */
108
109
		result = new_bd_arm_Mov_imm(dbgi, block, v.values[0], v.rors[0]);
		be_dep_on_frame(result);
Michael Beck's avatar
Michael Beck committed
110
111

		for (cnt = 1; cnt < v.ops; ++cnt) {
112
113
			result = new_bd_arm_Or_imm(dbgi, block, result,
			                           v.values[cnt], v.rors[cnt]);
Michael Beck's avatar
Michael Beck committed
114
		}
115
116
117
118
	}
	return result;
}

119
120
121
122
123
/**
 * Create a DAG constructing a given Const.
 *
 * @param irn  a Firm const
 */
124
125
static ir_node *create_const_graph(ir_node *irn, ir_node *block)
{
126
127
	tarval  *tv = get_Const_tarval(irn);
	ir_mode *mode = get_tarval_mode(tv);
128
	unsigned value;
129
130
131
132
133
134
135

	if (mode_is_reference(mode)) {
		/* ARM is 32bit, so we can safely convert a reference tarval into Iu */
		assert(get_mode_size_bits(mode) == get_mode_size_bits(mode_Iu));
		tv = tarval_convert_to(tv, mode_Iu);
	}
	value = get_tarval_long(tv);
136
	return create_const_graph_value(get_irn_dbg_info(irn), block, value);
137
138
}

Michael Beck's avatar
Michael Beck committed
139
/**
Michael Beck's avatar
Michael Beck committed
140
141
142
143
144
145
 * Create an And that will zero out upper bits.
 *
 * @param dbgi     debug info
 * @param block    the basic block
 * @param op       the original node
 * param src_bits  number of lower bits that will remain
Michael Beck's avatar
Michael Beck committed
146
 */
147
148
149
150
151
152
153
154
155
156
157
158
static ir_node *gen_zero_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
                                   int src_bits)
{
	if (src_bits == 8) {
		return new_bd_arm_And_imm(dbgi, block, op, 0xFF, 0);
	} else if (src_bits == 16) {
		ir_node *lshift = new_bd_arm_Mov_reg_shift_imm(dbgi, block, op, ARM_SHF_LSL_IMM, 16);
		ir_node *rshift = new_bd_arm_Mov_reg_shift_imm(dbgi, block, lshift, ARM_SHF_LSR_IMM, 16);
		return rshift;
	} else {
		panic("zero extension only supported for 8 and 16 bits");
	}
159
160
}

Michael Beck's avatar
Michael Beck committed
161
162
163
/**
 * Generate code for a sign extension.
 */
164
165
166
167
168
169
static ir_node *gen_sign_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
                                   int src_bits)
{
	int shift_width = 32 - src_bits;
	ir_node *lshift_node = new_bd_arm_Mov_reg_shift_imm(dbgi, block, op, ARM_SHF_LSL_IMM, shift_width);
	ir_node *rshift_node = new_bd_arm_Mov_reg_shift_imm(dbgi, block, lshift_node, ARM_SHF_ASR_IMM, shift_width);
170
171
172
	return rshift_node;
}

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
static ir_node *gen_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
                              ir_mode *orig_mode)
{
	int bits = get_mode_size_bits(orig_mode);
	if (bits == 32)
		return op;

	if (mode_is_signed(orig_mode)) {
		return gen_sign_extension(dbgi, block, op, bits);
	} else {
		return gen_zero_extension(dbgi, block, op, bits);
	}
}

/**
 * returns true if it is assured, that the upper bits of a node are "clean"
 * which means for a 16 or 8 bit value, that the upper bits in the register
 * are 0 for unsigned and a copy of the last significant bit for signed
 * numbers.
 */
static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
{
	(void) transformed_node;
	(void) mode;
	/* TODO */
	return false;
}

Michael Beck's avatar
Michael Beck committed
201
202
203
/**
 * Transforms a Conv node.
 *
204
 * @return The created ia32 Conv node
Michael Beck's avatar
Michael Beck committed
205
 */
206
207
static ir_node *gen_Conv(ir_node *node)
{
208
209
210
211
212
213
214
215
216
217
218
219
220
221
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *op       = get_Conv_op(node);
	ir_node  *new_op   = be_transform_node(op);
	ir_mode  *src_mode = get_irn_mode(op);
	ir_mode  *dst_mode = get_irn_mode(node);
	dbg_info *dbg      = get_irn_dbg_info(node);

	if (src_mode == dst_mode)
		return new_op;

	if (mode_is_float(src_mode) || mode_is_float(dst_mode)) {
		if (USE_FPA(env_cg->isa)) {
			if (mode_is_float(src_mode)) {
				if (mode_is_float(dst_mode)) {
Michael Beck's avatar
Michael Beck committed
222
					/* from float to float */
223
					return new_bd_arm_Mvf(dbg, block, new_op, dst_mode);
224
				} else {
Michael Beck's avatar
Michael Beck committed
225
					/* from float to int */
226
					panic("TODO");
Michael Beck's avatar
Michael Beck committed
227
				}
228
			} else {
Michael Beck's avatar
Michael Beck committed
229
				/* from int to float */
230
231
232
233
234
				if (!mode_is_signed(src_mode)) {
					panic("TODO");
				} else {
					return new_bd_arm_FltX(dbg, block, new_op, dst_mode);
				}
Michael Beck's avatar
Michael Beck committed
235
			}
236
		} else if (USE_VFP(env_cg->isa)) {
237
			panic("VFP not supported yet");
238
		} else {
239
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
240
		}
241
	} else { /* complete in gp registers */
242
243
		int src_bits = get_mode_size_bits(src_mode);
		int dst_bits = get_mode_size_bits(dst_mode);
Michael Beck's avatar
Michael Beck committed
244
245
		int min_bits;
		ir_mode *min_mode;
246

Michael Beck's avatar
Michael Beck committed
247
		if (src_bits == dst_bits) {
Michael Beck's avatar
Michael Beck committed
248
			/* kill unnecessary conv */
Michael Beck's avatar
Michael Beck committed
249
			return new_op;
250
251
252
253
254
		}

		if (src_bits < dst_bits) {
			min_bits = src_bits;
			min_mode = src_mode;
Michael Beck's avatar
Michael Beck committed
255
		} else {
256
257
258
259
260
261
262
263
264
265
266
267
			min_bits = dst_bits;
			min_mode = dst_mode;
		}

		if (upper_bits_clean(new_op, min_mode)) {
			return new_op;
		}

		if (mode_is_signed(min_mode)) {
			return gen_sign_extension(dbg, block, new_op, min_bits);
		} else {
			return gen_zero_extension(dbg, block, new_op, min_bits);
268
269
270
271
		}
	}
}

272
273
274
275
276
277
278
typedef struct {
	unsigned char  imm_8;
	unsigned char  rot;
} arm_immediate_t;

static bool try_encode_as_immediate(const ir_node *node, arm_immediate_t *res)
{
Michael Beck's avatar
Michael Beck committed
279
	unsigned val, low_pos, high_pos;
280
281
282

	if (!is_Const(node))
		return false;
Michael Beck's avatar
Michael Beck committed
283

284
	val = get_tarval_long(get_Const_tarval(node));
Michael Beck's avatar
Michael Beck committed
285

286
287
288
289
290
291
292
293
294
	if (val == 0) {
		res->imm_8 = 0;
		res->rot   = 0;
		return true;
	}
	if (val <= 0xff) {
		res->imm_8 = val;
		res->rot   = 0;
		return true;
Michael Beck's avatar
Michael Beck committed
295
	}
296
297
298
299
300
301
302
	/* arm allows to use to rotate an 8bit immediate value by a multiple of 2
	   (= 0, 2, 4, 6, ...).
	   So we determine the smallest even position with a bit set
	   and the highest even position with no bit set anymore.
	   If the difference between these 2 is <= 8, then we can encode the value
	   as immediate.
	 */
Michael Beck's avatar
Michael Beck committed
303
304
	low_pos  = ntz(val) & ~1u;
	high_pos = (32-nlz(val)+1) & ~1u;
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323

	if (high_pos - low_pos <= 8) {
		res->imm_8 = val >> low_pos;
		res->rot   = 32 - low_pos;
		return true;
	}

	if (high_pos > 24) {
		res->rot = 34 - high_pos;
		val      = val >> (32-res->rot) | val << (res->rot);
		if (val <= 0xff) {
			res->imm_8 = val;
			return true;
		}
	}

	return false;
}

324
static bool is_downconv(const ir_node *node)
325
326
327
328
329
{
	ir_mode *src_mode;
	ir_mode *dest_mode;

	if (!is_Conv(node))
330
		return false;
331
332
333
334
335

	/* we only want to skip the conv when we're the only user
	 * (not optimal but for now...)
	 */
	if (get_irn_n_edges(node) > 1)
336
		return false;
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358

	src_mode  = get_irn_mode(get_Conv_op(node));
	dest_mode = get_irn_mode(node);
	return
		mode_needs_gp_reg(src_mode)  &&
		mode_needs_gp_reg(dest_mode) &&
		get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
}

static ir_node *arm_skip_downconv(ir_node *node)
{
	while (is_downconv(node))
		node = get_Conv_op(node);
	return node;
}

typedef enum {
	MATCH_NONE         = 0,
	MATCH_COMMUTATIVE  = 1 << 0,
	MATCH_SIZE_NEUTRAL = 1 << 1,
} match_flags_t;

Michael Beck's avatar
Michael Beck committed
359
360
361
362
363
364
365
366
367
368
369
370
371
/**
 * possible binop constructors.
 */
typedef struct arm_binop_factory_t {
	/** normal reg op reg operation. */
	ir_node *(*new_binop_reg)(dbg_info *dbgi, ir_node *block, ir_node *op1, ir_node *op2);
	/** normal reg op imm operation. */
	ir_node *(*new_binop_imm)(dbg_info *dbgi, ir_node *block, ir_node *op1, unsigned char imm8, unsigned char imm_rot);
	/** barrel shifter reg op (reg shift reg operation. */
	ir_node *(*new_binop_reg_shift_reg)(dbg_info *dbgi, ir_node *block, ir_node *left, ir_node *right, ir_node *shift, arm_shift_modifier_t shift_modifier);
	/** barrel shifter reg op (reg shift imm operation. */
	ir_node *(*new_binop_reg_shift_imm)(dbg_info *dbgi, ir_node *block, ir_node *left, ir_node *right, arm_shift_modifier_t shift_modifier, unsigned shift_immediate);
} arm_binop_factory_t;
372
373

static ir_node *gen_int_binop(ir_node *node, match_flags_t flags,
Michael Beck's avatar
Michael Beck committed
374
		const arm_binop_factory_t *factory)
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
{
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op1     = get_binop_left(node);
	ir_node  *new_op1;
	ir_node  *op2     = get_binop_right(node);
	ir_node  *new_op2;
	dbg_info *dbgi    = get_irn_dbg_info(node);
	arm_immediate_t imm;

	if (flags & MATCH_SIZE_NEUTRAL) {
		op1 = arm_skip_downconv(op1);
		op2 = arm_skip_downconv(op2);
	} else {
		assert(get_mode_size_bits(get_irn_mode(node)) == 32);
	}

	if (try_encode_as_immediate(op2, &imm)) {
		ir_node *new_op1 = be_transform_node(op1);
Michael Beck's avatar
Michael Beck committed
393
		return factory->new_binop_imm(dbgi, block, new_op1, imm.imm_8, imm.rot);
394
395
396
	}
	new_op2 = be_transform_node(op2);
    if ((flags & MATCH_COMMUTATIVE) && try_encode_as_immediate(op1, &imm)) {
Michael Beck's avatar
Michael Beck committed
397
		return factory->new_binop_imm(dbgi, block, new_op2, imm.imm_8, imm.rot);
398
399
400
	}
	new_op1 = be_transform_node(op1);

Michael Beck's avatar
Michael Beck committed
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
	/* check if we can fold in a Mov */
	if (is_arm_Mov(new_op2)) {
		const arm_shifter_operand_t *attr = get_arm_shifter_operand_attr_const(new_op2);

		switch (attr->shift_modifier) {
			ir_node *mov_op, *mov_sft;

		case ARM_SHF_IMM:
		case ARM_SHF_ASR_IMM:
		case ARM_SHF_LSL_IMM:
		case ARM_SHF_LSR_IMM:
		case ARM_SHF_ROR_IMM:
			if (factory->new_binop_reg_shift_imm) {
				mov_op = get_irn_n(new_op2, 0);
				return factory->new_binop_reg_shift_imm(dbgi, block, new_op1, mov_op,
					attr->shift_modifier, attr->shift_immediate);
			}
			break;

		case ARM_SHF_ASR_REG:
		case ARM_SHF_LSL_REG:
		case ARM_SHF_LSR_REG:
		case ARM_SHF_ROR_REG:
			if (factory->new_binop_reg_shift_reg) {
				mov_op  = get_irn_n(new_op2, 0);
				mov_sft = get_irn_n(new_op2, 1);
				return factory->new_binop_reg_shift_reg(dbgi, block, new_op1, mov_op, mov_sft,
					attr->shift_modifier);
			}
			break;
		}
	}
	if ((flags & MATCH_COMMUTATIVE) && is_arm_Mov(new_op1)) {
		const arm_shifter_operand_t *attr = get_arm_shifter_operand_attr_const(new_op1);

		switch (attr->shift_modifier) {
			ir_node *mov_op, *mov_sft;

		case ARM_SHF_IMM:
		case ARM_SHF_ASR_IMM:
		case ARM_SHF_LSL_IMM:
		case ARM_SHF_LSR_IMM:
		case ARM_SHF_ROR_IMM:
			if (factory->new_binop_reg_shift_imm) {
				mov_op = get_irn_n(new_op1, 0);
				return factory->new_binop_reg_shift_imm(dbgi, block, new_op2, mov_op,
					attr->shift_modifier, attr->shift_immediate);
			}
			break;

		case ARM_SHF_ASR_REG:
		case ARM_SHF_LSL_REG:
		case ARM_SHF_LSR_REG:
		case ARM_SHF_ROR_REG:
			if (factory->new_binop_reg_shift_reg) {
				mov_op  = get_irn_n(new_op1, 0);
				mov_sft = get_irn_n(new_op1, 1);
				return factory->new_binop_reg_shift_reg(dbgi, block, new_op2, mov_op, mov_sft,
					attr->shift_modifier);
			}
			break;
		}
	}
	return factory->new_binop_reg(dbgi, block, new_op1, new_op2);
Michael Beck's avatar
Michael Beck committed
465
}
466
467

/**
468
 * Creates an ARM Add.
469
470
471
 *
 * @return the created arm Add node
 */
472
473
static ir_node *gen_Add(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
474
475
476
477
478
479
480
481
	static const arm_binop_factory_t add_factory = {
		new_bd_arm_Add_reg,
		new_bd_arm_Add_imm,
		new_bd_arm_Add_reg_shift_reg,
		new_bd_arm_Add_reg_shift_imm
	};

	ir_mode *mode = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
482

483
	if (mode_is_float(mode)) {
484
485
486
487
488
489
		ir_node  *block   = be_transform_node(get_nodes_block(node));
		ir_node  *op1     = get_Add_left(node);
		ir_node  *op2     = get_Add_right(node);
		dbg_info *dbgi    = get_irn_dbg_info(node);
		ir_node  *new_op1 = be_transform_node(op1);
		ir_node  *new_op2 = be_transform_node(op2);
490
		if (USE_FPA(env_cg->isa)) {
491
			return new_bd_arm_Adf(dbgi, block, new_op1, new_op2, mode);
492
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
493
			assert(mode != mode_E && "IEEE Extended FP not supported");
494
			panic("VFP not supported yet");
495
		} else {
496
			panic("Softfloat not supported yet");
497
498
		}
	} else {
499
#if 0
Michael Beck's avatar
Michael Beck committed
500
		/* check for MLA */
Michael Beck's avatar
Michael Beck committed
501
		if (is_arm_Mul(new_op1) && get_irn_n_edges(op1) == 1) {
502
			new_op3 = new_op2;
Michael Beck's avatar
Michael Beck committed
503
504
			new_op2 = get_irn_n(new_op1, 1);
			new_op1 = get_irn_n(new_op1, 0);
Michael Beck's avatar
Michael Beck committed
505

506
			return new_bd_arm_Mla(dbgi, block, new_op1, new_op2, new_op3);
Michael Beck's avatar
Michael Beck committed
507
		}
Michael Beck's avatar
Michael Beck committed
508
		if (is_arm_Mul(new_op2) && get_irn_n_edges(op2) == 1) {
509
510
511
			new_op3 = new_op1;
			new_op1 = get_irn_n(new_op2, 0);
			new_op2 = get_irn_n(new_op2, 1);
Michael Beck's avatar
Michael Beck committed
512

513
			return new_bd_arm_Mla(dbgi, block, new_op1, new_op2, new_op3);
Michael Beck's avatar
Michael Beck committed
514
		}
515
#endif
516

Michael Beck's avatar
Michael Beck committed
517
		return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL, &add_factory);
Michael Beck's avatar
Michael Beck committed
518
519
	}
}
520
521

/**
522
 * Creates an ARM Mul.
523
524
525
 *
 * @return the created arm Mul node
 */
526
527
static ir_node *gen_Mul(ir_node *node)
{
528
529
530
531
532
533
534
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op1     = get_Mul_left(node);
	ir_node  *new_op1 = be_transform_node(op1);
	ir_node  *op2     = get_Mul_right(node);
	ir_node  *new_op2 = be_transform_node(op2);
	ir_mode  *mode    = get_irn_mode(node);
	dbg_info *dbg     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
535

536
	if (mode_is_float(mode)) {
537
		if (USE_FPA(env_cg->isa)) {
538
			return new_bd_arm_Muf(dbg, block, new_op1, new_op2, mode);
539
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
540
			assert(mode != mode_E && "IEEE Extended FP not supported");
541
			panic("VFP not supported yet");
542
		} else {
543
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
544
		}
545
	}
546
	assert(mode_is_data(mode));
547
	return new_bd_arm_Mul(dbg, block, new_op1, new_op2);
548
549
}

550
551
static ir_node *gen_Quot(ir_node *node)
{
552
553
554
555
556
557
558
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op1     = get_Quot_left(node);
	ir_node  *new_op1 = be_transform_node(op1);
	ir_node  *op2     = get_Quot_right(node);
	ir_node  *new_op2 = be_transform_node(op2);
	ir_mode  *mode    = get_irn_mode(node);
	dbg_info *dbg     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
559

560
	assert(mode != mode_E && "IEEE Extended FP not supported");
561

562
	if (USE_FPA(env_cg->isa)) {
563
		return new_bd_arm_Dvf(dbg, block, new_op1, new_op2, mode);
564
	} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
565
		assert(mode != mode_E && "IEEE Extended FP not supported");
566
		panic("VFP not supported yet");
567
	} else {
568
		panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
569
	}
Michael Beck's avatar
Michael Beck committed
570
571
}

572
573
static ir_node *gen_And(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
574
575
576
577
578
579
580
581
	static const arm_binop_factory_t and_factory = {
		new_bd_arm_And_reg,
		new_bd_arm_And_imm,
		new_bd_arm_And_reg_shift_reg,
		new_bd_arm_And_reg_shift_imm
	};

	return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL, &and_factory);
582
}
583

584
585
static ir_node *gen_Or(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
586
587
588
589
590
591
592
593
	static const arm_binop_factory_t or_factory = {
		new_bd_arm_Or_reg,
		new_bd_arm_Or_imm,
		new_bd_arm_Or_reg_shift_reg,
		new_bd_arm_Or_reg_shift_imm
	};

	return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL, &or_factory);
594
}
595

596
597
static ir_node *gen_Eor(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
598
599
600
601
602
603
604
605
	static const arm_binop_factory_t eor_factory = {
		new_bd_arm_Eor_reg,
		new_bd_arm_Eor_imm,
		new_bd_arm_Eor_reg_shift_reg,
		new_bd_arm_Eor_reg_shift_imm
	};

	return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL, &eor_factory);
606
}
607

608
609
static ir_node *gen_Sub(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
610
611
612
613
614
615
616
	static const arm_binop_factory_t sub_factory = {
		new_bd_arm_Sub_reg,
		new_bd_arm_Sub_imm,
		new_bd_arm_Sub_reg_shift_reg,
		new_bd_arm_Sub_reg_shift_imm
	};

617
618
619
620
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op1     = get_Sub_left(node);
	ir_node  *new_op1 = be_transform_node(op1);
	ir_node  *op2     = get_Sub_right(node);
Michael Beck's avatar
Michael Beck committed
621
	ir_node  *new_op2 = be_transform_node(op2);
622
	ir_mode  *mode    = get_irn_mode(node);
623
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
624

625
	if (mode_is_float(mode)) {
626
		if (USE_FPA(env_cg->isa)) {
627
			return new_bd_arm_Suf(dbgi, block, new_op1, new_op2, mode);
628
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
629
			assert(mode != mode_E && "IEEE Extended FP not supported");
630
			panic("VFP not supported yet");
631
		} else {
632
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
633
		}
634
	} else {
Michael Beck's avatar
Michael Beck committed
635
		return gen_int_binop(node, MATCH_SIZE_NEUTRAL, &sub_factory);
Michael Beck's avatar
Michael Beck committed
636
	}
637
}
Michael Beck's avatar
Michael Beck committed
638

Michael Beck's avatar
Michael Beck committed
639
640
641
642
/**
 * Checks if a given value can be used as an immediate for the given
 * ARM shift mode.
 */
643
644
645
646
647
648
649
650
651
652
static bool can_use_shift_constant(unsigned int val,
                                   arm_shift_modifier_t modifier)
{
	if (val <= 31)
		return true;
	if (val == 32 && modifier != ARM_SHF_LSL_REG && modifier != ARM_SHF_ROR_REG)
		return true;
	return false;
}

Michael Beck's avatar
Michael Beck committed
653
654
655
656
657
658
659
/**
 * generate an ARM shift instruction.
 *
 * @param node            the node
 * @param flags           matching flags
 * @param shift_modifier  initial encoding of the desired shift operation
 */
660
static ir_node *make_shift(ir_node *node, match_flags_t flags,
661
		arm_shift_modifier_t shift_modifier)
662
{
663
664
665
666
	ir_node  *block = be_transform_node(get_nodes_block(node));
	ir_node  *op1   = get_binop_left(node);
	ir_node  *op2   = get_binop_right(node);
	dbg_info *dbgi  = get_irn_dbg_info(node);
667
668
669
670
671
672
	ir_node  *new_op1;
	ir_node  *new_op2;

	if (flags & MATCH_SIZE_NEUTRAL) {
		op1 = arm_skip_downconv(op1);
		op2 = arm_skip_downconv(op2);
673
	}
674

675
	new_op1 = be_transform_node(op1);
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
	if (is_Const(op2)) {
		tarval      *tv  = get_Const_tarval(op2);
		unsigned int val = get_tarval_long(tv);
		assert(tarval_is_long(tv));
		if (can_use_shift_constant(val, shift_modifier)) {
			switch (shift_modifier) {
			case ARM_SHF_LSL_REG: shift_modifier = ARM_SHF_LSL_IMM; break;
			case ARM_SHF_LSR_REG: shift_modifier = ARM_SHF_LSR_IMM; break;
			case ARM_SHF_ASR_REG: shift_modifier = ARM_SHF_ASR_IMM; break;
			case ARM_SHF_ROR_REG: shift_modifier = ARM_SHF_ROR_IMM; break;
			default: panic("unexpected shift modifier");
			}
			return new_bd_arm_Mov_reg_shift_imm(dbgi, block, new_op1,
			                                    shift_modifier, val);
		}
	}

693
	new_op2 = be_transform_node(op2);
694
695
	return new_bd_arm_Mov_reg_shift_reg(dbgi, block, new_op1, new_op2,
	                                    shift_modifier);
696
697
}

698
699
700
static ir_node *gen_Shl(ir_node *node)
{
	return make_shift(node, MATCH_SIZE_NEUTRAL, ARM_SHF_LSL_REG);
701
702
}

703
704
705
static ir_node *gen_Shr(ir_node *node)
{
	return make_shift(node, MATCH_NONE, ARM_SHF_LSR_REG);
706
707
}

708
709
710
static ir_node *gen_Shrs(ir_node *node)
{
	return make_shift(node, MATCH_NONE, ARM_SHF_ASR_REG);
711
712
}

713
714
static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
{
Michael Beck's avatar
Michael Beck committed
715
716
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *new_op1 = be_transform_node(op1);
717
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
718
719
	ir_node  *new_op2 = be_transform_node(op2);

720
721
	return new_bd_arm_Mov_reg_shift_reg(dbgi, block, new_op1, new_op2,
	                                    ARM_SHF_ROR_REG);
Michael Beck's avatar
Michael Beck committed
722
723
}

724
725
static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
{
Michael Beck's avatar
Michael Beck committed
726
727
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *new_op1 = be_transform_node(op1);
728
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
729
730
	ir_node  *new_op2 = be_transform_node(op2);

731
	/* Note: there is no Rol on arm, we have to use Ror */
732
733
734
	new_op2 = new_bd_arm_Rsb_imm(dbgi, block, new_op2, 32, 0);
	return new_bd_arm_Mov_reg_shift_reg(dbgi, block, new_op1, new_op2,
	                                    ARM_SHF_ROR_REG);
Michael Beck's avatar
Michael Beck committed
735
736
}

737
738
static ir_node *gen_Rotl(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
739
740
741
742
743
744
745
746
747
	ir_node *rotate = NULL;
	ir_node *op1    = get_Rotl_left(node);
	ir_node *op2    = get_Rotl_right(node);

	/* Firm has only RotL, so we are looking for a right (op2)
	   operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
	   that means we can create a RotR. */

	if (is_Add(op2)) {
Michael Beck's avatar
Michael Beck committed
748
		ir_node *right = get_Add_right(op2);
Michael Beck's avatar
Michael Beck committed
749
750
751
752
		if (is_Const(right)) {
			tarval  *tv   = get_Const_tarval(right);
			ir_mode *mode = get_irn_mode(node);
			long     bits = get_mode_size_bits(mode);
Michael Beck's avatar
Michael Beck committed
753
			ir_node *left = get_Add_left(op2);
Michael Beck's avatar
Michael Beck committed
754
755

			if (is_Minus(left) &&
Michael Beck's avatar
Michael Beck committed
756
			    tarval_is_long(tv)          &&
Michael Beck's avatar
Michael Beck committed
757
758
759
760
			    get_tarval_long(tv) == bits &&
			    bits                == 32)
				rotate = gen_Ror(node, op1, get_Minus_op(left));
		}
Michael Beck's avatar
Michael Beck committed
761
762
763
764
765
766
767
768
769
770
771
772
773
	} else if (is_Sub(op2)) {
		ir_node *left = get_Sub_left(op2);
		if (is_Const(left)) {
			tarval  *tv   = get_Const_tarval(left);
			ir_mode *mode = get_irn_mode(node);
			long     bits = get_mode_size_bits(mode);
			ir_node *right = get_Sub_right(op2);

			if (tarval_is_long(tv)          &&
			    get_tarval_long(tv) == bits &&
			    bits                == 32)
				rotate = gen_Ror(node, op1, right);
		}
774
	} else if (is_Const(op2)) {
775
776
777
		tarval  *tv   = get_Const_tarval(op2);
		ir_mode *mode = get_irn_mode(node);
		long     bits = get_mode_size_bits(mode);
Michael Beck's avatar
Michael Beck committed
778

779
780
781
782
		if (tarval_is_long(tv) && bits == 32) {
			ir_node  *block   = be_transform_node(get_nodes_block(node));
			ir_node  *new_op1 = be_transform_node(op1);
			dbg_info *dbgi    = get_irn_dbg_info(node);
783

784
785
786
			bits = (bits - get_tarval_long(tv)) & 31;
			rotate = new_bd_arm_Mov_reg_shift_imm(dbgi, block, new_op1, ARM_SHF_ROR_IMM, bits);
		}
Michael Beck's avatar
Michael Beck committed
787
788
789
790
791
792
793
794
795
	}

	if (rotate == NULL) {
		rotate = gen_Rol(node, op1, op2);
	}

	return rotate;
}

796
797
static ir_node *gen_Not(ir_node *node)
{
798
799
800
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op      = get_Not_op(node);
	ir_node  *new_op  = be_transform_node(op);
801
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
802

803
804
805
	/* TODO: we could do alot more here with all the Mvn variations */

	return new_bd_arm_Mvn_reg(dbgi, block, new_op);
806
807
}

808
809
static ir_node *gen_Minus(ir_node *node)
{
810
811
812
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op      = get_Minus_op(node);
	ir_node  *new_op  = be_transform_node(op);
813
	dbg_info *dbgi    = get_irn_dbg_info(node);
814
	ir_mode  *mode    = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
815

816
	if (mode_is_float(mode)) {
817
		if (USE_FPA(env_cg->isa)) {
818
			return new_bd_arm_Mvf(dbgi, block, op, mode);
819
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
820
			assert(mode != mode_E && "IEEE Extended FP not supported");
821
			panic("VFP not supported yet");
822
		} else {
823
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
824
		}
825
	}
826
	assert(mode_is_data(mode));
827
	return new_bd_arm_Rsb_imm(dbgi, block, new_op, 0, 0);
828
829
}

830
831
static ir_node *gen_Load(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
832
833
834
835
836
837
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *ptr      = get_Load_ptr(node);
	ir_node  *new_ptr  = be_transform_node(ptr);
	ir_node  *mem      = get_Load_mem(node);
	ir_node  *new_mem  = be_transform_node(mem);
	ir_mode  *mode     = get_Load_mode(node);
838
	dbg_info *dbgi      = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
839
	ir_node  *new_load = NULL;
840

Michael Beck's avatar
Michael Beck committed
841
	if (mode_is_float(mode)) {
842
		if (USE_FPA(env_cg->isa)) {
843
844
			new_load = new_bd_arm_Ldf(dbgi, block, new_ptr, new_mem, mode,
			                          NULL, 0, 0, false);
845
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
846
			assert(mode != mode_E && "IEEE Extended FP not supported");
847
			panic("VFP not supported yet");
848
		} else {
849
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
850
		}
851
	} else {
852
		assert(mode_is_data(mode) && "unsupported mode for Load");
853

854
		new_load = new_bd_arm_Ldr(dbgi, block, new_ptr, new_mem, mode, NULL, 0, 0, false);
855
	}
Michael Beck's avatar
Michael Beck committed
856
	set_irn_pinned(new_load, get_irn_pinned(node));
857
858
859
860

	/* check for special case: the loaded value might not be used */
	if (be_get_Proj_for_pn(node, pn_Load_res) == NULL) {
		/* add a result proj and a Keep to produce a pseudo use */
861
		ir_node *proj = new_r_Proj(new_load, mode_Iu, pn_arm_Ldr_res);
862
		be_new_Keep(block, 1, &proj);
863
864
	}

Michael Beck's avatar
Michael Beck committed
865
	return new_load;
866
867
}

868
869
static ir_node *gen_Store(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
870
871
872
873
874
875
876
877
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *ptr      = get_Store_ptr(node);
	ir_node  *new_ptr  = be_transform_node(ptr);
	ir_node  *mem      = get_Store_mem(node);
	ir_node  *new_mem  = be_transform_node(mem);
	ir_node  *val      = get_Store_value(node);
	ir_node  *new_val  = be_transform_node(val);
	ir_mode  *mode     = get_irn_mode(val);
878
	dbg_info *dbgi     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
879
	ir_node *new_store = NULL;
880

Michael Beck's avatar
Michael Beck committed
881
	if (mode_is_float(mode)) {
882
		if (USE_FPA(env_cg->isa)) {
883
884
			new_store = new_bd_arm_Stf(dbgi, block, new_ptr, new_val,
			                           new_mem, mode, NULL, 0, 0, false);
885
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
886
			assert(mode != mode_E && "IEEE Extended FP not supported");
887
			panic("VFP not supported yet");
Michael Beck's avatar
Michael Beck committed
888
		} else {
889
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
890
891
		}
	} else {
892
		assert(mode_is_data(mode) && "unsupported mode for Store");
893
894
		new_store = new_bd_arm_Str(dbgi, block, new_ptr, new_val, new_mem, mode,
		                           NULL, 0, 0, false);
895
	}
Michael Beck's avatar
Michael Beck committed
896
897
	set_irn_pinned(new_store, get_irn_pinned(node));
	return new_store;
898
899
}

900
901
902
903
904
905
906
907
908
static ir_node *gen_Jmp(ir_node *node)
{
	ir_node  *block     = get_nodes_block(node);
	ir_node  *new_block = be_transform_node(block);
	dbg_info *dbgi      = get_irn_dbg_info(node);

	return new_bd_arm_Jmp(dbgi, new_block);
}

909
910
static ir_node *gen_SwitchJmp(ir_node *node)
{
911
912
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *selector = get_Cond_selector(node);
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
	dbg_info *dbgi     = get_irn_dbg_info(node);
	ir_node *new_op = be_transform_node(selector);
	ir_node *const_graph;
	ir_node *sub;

	ir_node *proj;
	const ir_edge_t *edge;
	int min = INT_MAX;
	int max = INT_MIN;
	int translation;
	int pn;
	int n_projs;

	foreach_out_edge(node, edge) {
		proj = get_edge_src_irn(edge);
		assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");

		pn = get_Proj_proj(proj);

		min = pn<min ? pn : min;
		max = pn>max ? pn : max;
	}
	translation = min;
	n_projs = max - translation + 1;
937

938
939
940
	foreach_out_edge(node, edge) {
		proj = get_edge_src_irn(edge);
		assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
941

942
943
944
		pn = get_Proj_proj(proj) - translation;
		set_Proj_proj(proj, pn);
	}
945

946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
	const_graph = create_const_graph_value(dbgi, block, translation);
	sub = new_bd_arm_Sub_reg(dbgi, block, new_op, const_graph);
	return new_bd_arm_SwitchJmp(dbgi, block, sub, n_projs, get_Cond_default_proj(node) - translation);
}

static ir_node *gen_Cmp(ir_node *node)
{
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *op1      = get_Cmp_left(node);
	ir_node  *op2      = get_Cmp_right(node);
	ir_mode  *cmp_mode = get_irn_mode(op1);
	dbg_info *dbgi     = get_irn_dbg_info(node);
	ir_node  *new_op1;
	ir_node  *new_op2;
	bool      is_unsigned;

	if (mode_is_float(cmp_mode)) {
963
964
965
966
967
968
		/* TODO: this is broken... */
		new_op1 = be_transform_node(op1);
		new_op2 = be_transform_node(op2);

		return new_bd_arm_Cmfe(dbgi, block, new_op1, new_op2, false);

969
970
971
972
973
974
975
976
		panic("FloatCmp NIY");
#if 0
		ir_node *new_op2  = be_transform_node(op2);
		/* floating point compare */
		pn_Cmp pnc = get_Proj_proj(selector);

		if (pnc & pn_Cmp_Uo) {
			/* check for unordered, need cmf */
977
			return new_bd_arm_CmfBra(dbgi, block, new_op1, new_op2, pnc);
978
		}
979
		/* Hmm: use need cmfe */
980
		return new_bd_arm_CmfeBra(dbgi, block, new_op1, new_op2, pnc);
981
982
#endif
	}
983

984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
	assert(get_irn_mode(op2) == cmp_mode);
	is_unsigned = !mode_is_signed(cmp_mode);

	/* compare with 0 can be done with Tst */
	if (is_Const(op2) && tarval_is_null(get_Const_tarval(op2))) {
		new_op1 = be_transform_node(op1);
		new_op1 = gen_extension(dbgi, block, new_op1, cmp_mode);
		return new_bd_arm_Tst_reg(dbgi, block, new_op1, new_op1, false,
		                          is_unsigned);
	}
	if (is_Const(op1) && tarval_is_null(get_Const_tarval(op1))) {
		new_op2 = be_transform_node(op2);
		new_op2 = gen_extension(dbgi, block, new_op2, cmp_mode);
		return new_bd_arm_Tst_reg(dbgi, block, new_op2, new_op2, true,
		                          is_unsigned);
999
	}
1000

Michael Beck's avatar
Michael Beck committed
1001
	/* integer compare, TODO: use shifter_op in all its combinations */
1002
1003
1004
1005
1006
1007
	new_op1 = be_transform_node(op1);
	new_op1 = gen_extension(dbgi, block, new_op1, cmp_mode);
	new_op2 = be_transform_node(op2);
	new_op2 = gen_extension(dbgi, block, new_op2, cmp_mode);
	return new_bd_arm_Cmp_reg(dbgi, block, new_op1, new_op2, false,
	                          is_unsigned);
1008
1009
}

1010
1011
1012
1013
1014
1015
1016
static ir_node *gen_Cond(ir_node *node)
{
	ir_node  *selector = get_Cond_selector(node);
	ir_mode  *mode     = get_irn_mode(selector);
	ir_node  *block;
	ir_node  *flag_node;
	dbg_info *dbgi;
1017

1018
1019
	if (mode != mode_b) {
		return gen_SwitchJmp(node);
1020
	}
1021
1022
1023
1024
1025
	assert(is_Proj(selector));

	block     = be_transform_node(get_nodes_block(node));
	dbgi      = get_irn_dbg_info(node);
	flag_node = be_transform_node(get_Proj_pred(selector));
1026

1027
	return new_bd_arm_B(dbgi, block, flag_node, get_Proj_proj(selector));
1028
1029
}

1030
1031
static tarval *fpa_imm[3][fpa_max];

1032
#if 0
1033
1034
/**
 * Check, if a floating point tarval is an fpa immediate, i.e.
1035
 * one of 0, 1, 2, 3, 4, 5, 10, or 0.5.
1036
 */
1037
1038
static int is_fpa_immediate(tarval *tv)
{
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
	ir_mode *mode = get_tarval_mode(tv);
	int i, j, res = 1;

	switch (get_mode_size_bits(mode)) {
	case 32:
		i = 0;
		break;
	case 64:
		i = 1;
		break;
	default:
		i = 2;
	}

1053
	if (tarval_is_negative(tv)) {
1054
1055
1056
1057
1058
1059
		tv = tarval_neg(tv);
		res = -1;
	}

	for (j = 0; j < fpa_max; ++j) {
		if (tv == fpa_imm[i][j])
Michael Beck's avatar
Michael Beck committed
1060
			return res * j;
1061
	}
Michael Beck's avatar
Michael Beck committed
1062
	return fpa_max;
1063
}
1064
#endif
1065

1066
1067
static ir_node *gen_Const(ir_node *node)
{
1068
	ir_node  *block = be_transform_node(get_nodes_block(node));
Michael Beck's avatar
Michael Beck committed
1069
1070
	ir_mode *mode = get_irn_mode(node);
	dbg_info *dbg = get_irn_dbg_info(node);
1071

Michael Beck's avatar
Michael Beck committed
1072
1073
	if (mode_is_float(mode)) {
		if (USE_FPA(env_cg->isa)) {
1074
			tarval *tv = get_Const_tarval(node);
1075
			node       = new_bd_arm_fConst(dbg, block, tv);
1076
			be_dep_on_frame(node);
Michael Beck's avatar
Michael Beck committed
1077
			return node;
1078
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
1079
			assert(mode != mode_E && "IEEE Extended FP not supported");
1080
			panic("VFP not supported yet");
1081
		} else {
1082
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
1083
1084
		}
	}
1085
	return create_const_graph(node, block);
1086
}
1087