arm_transform.c 50.4 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2008 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
23
 * @brief   The codegenerator (transform FIRM into arm FIRM)
 * @author  Oliver Richter, Tobias Gneist, Michael Beck
24
25
 * @version $Id$
 */
26
27
28
29
30
31
32
33
34
35
36
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#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
37
#include "irprintf.h"
38
39
40
#include "dbginfo.h"
#include "iropt_t.h"
#include "debug.h"
Michael Beck's avatar
Michael Beck committed
41
#include "error.h"
42
43

#include "../benode_t.h"
Michael Beck's avatar
Michael Beck committed
44
#include "../beirg_t.h"
45
#include "../beutil.h"
46
#include "../betranshlp.h"
47
48
49
#include "bearch_arm_t.h"

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

#include "gen_arm_regalloc_if.h"

#include <limits.h>

Michael Beck's avatar
Michael Beck committed
60

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

64
extern ir_op *get_op_Mulh(void);
65
66
67
68
69
70
71
72
73
74
75
76


/****************************************************************************************************
 *                  _        _                        __                           _   _
 *                 | |      | |                      / _|                         | | (_)
 *  _ __   ___   __| | ___  | |_ _ __ __ _ _ __  ___| |_ ___  _ __ _ __ ___   __ _| |_ _  ___  _ __
 * | '_ \ / _ \ / _` |/ _ \ | __| '__/ _` | '_ \/ __|  _/ _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \
 * | | | | (_) | (_| |  __/ | |_| | | (_| | | | \__ \ || (_) | |  | | | | | | (_| | |_| | (_) | | | |
 * |_| |_|\___/ \__,_|\___|  \__|_|  \__,_|_| |_|___/_| \___/|_|  |_| |_| |_|\__,_|\__|_|\___/|_| |_|
 *
 ****************************************************************************************************/

77
static INLINE int mode_needs_gp_reg(ir_mode *mode) {
78
	return mode_is_int(mode) || mode_is_reference(mode);
79
80
}

Michael Beck's avatar
Michael Beck committed
81
82
83
/**
 * Creates a arm_Const node.
 */
84
static ir_node *create_mov_node(dbg_info *dbg, ir_node *block, long value) {
Michael Beck's avatar
Michael Beck committed
85
	ir_mode *mode  = mode_Iu;
86
	ir_graph *irg  = current_ir_graph;
87
88
89
90
	ir_node *res;

	if (mode_needs_gp_reg(mode))
		mode = mode_Iu;
Michael Beck's avatar
Michael Beck committed
91
	res = new_rd_arm_Mov_i(dbg, irg, block, mode, value);
92
93
	/* ensure the const is scheduled AFTER the stack frame */
	add_irn_dep(res, get_irg_frame(irg));
Michael Beck's avatar
Michael Beck committed
94
	return res;
95
96
}

Michael Beck's avatar
Michael Beck committed
97
98
99
/**
 * Creates a arm_Const_Neg node.
 */
100
static ir_node *create_mvn_node(dbg_info *dbg, ir_node *block, long value) {
Michael Beck's avatar
Michael Beck committed
101
	ir_mode *mode = mode_Iu;
Michael Beck's avatar
Michael Beck committed
102
	ir_graph *irg = current_ir_graph;
103
104
105
106
	ir_node *res;

	if (mode_needs_gp_reg(mode))
		mode = mode_Iu;
Michael Beck's avatar
Michael Beck committed
107
	res = new_rd_arm_Mvn_i(dbg, irg, block, mode, value);
108
109
	/* ensure the const is scheduled AFTER the stack frame */
	add_irn_dep(res, get_irg_frame(irg));
Michael Beck's avatar
Michael Beck committed
110
	return res;
111
112
}

113
#define NEW_BINOP_NODE(opname, env, op1, op2) new_rd_arm_##opname(env->dbg, current_ir_graph, env->block, op1, op2, env->mode)
114

Michael Beck's avatar
Michael Beck committed
115
116
117
/**
 * Creates a possible DAG for an constant.
 */
118
static ir_node *create_const_graph_value(dbg_info *dbg, ir_node *block, unsigned int value) {
119
	ir_node *result;
120
	arm_vals v, vn;
Michael Beck's avatar
Michael Beck committed
121
	int cnt;
Michael Beck's avatar
Michael Beck committed
122
	ir_mode *mode = mode_Iu;
123

124
125
	arm_gen_vals_from_word(value, &v);
	arm_gen_vals_from_word(~value, &vn);
Michael Beck's avatar
Michael Beck committed
126
127
128

	if (vn.ops < v.ops) {
		/* remove bits */
129
		result = create_mvn_node(dbg, block, arm_encode_imm_w_shift(vn.shifts[0], vn.values[0]));
Michael Beck's avatar
Michael Beck committed
130
131

		for (cnt = 1; cnt < vn.ops; ++cnt) {
Michael Beck's avatar
Michael Beck committed
132
133
			long value = arm_encode_imm_w_shift(vn.shifts[cnt], vn.values[cnt]);
			ir_node *bic_i_node = new_rd_arm_Bic_i(dbg, current_ir_graph, block, result, mode, value);
Michael Beck's avatar
Michael Beck committed
134
			result = bic_i_node;
135
136
		}
	}
Michael Beck's avatar
Michael Beck committed
137
138
	else {
		/* add bits */
139
		result = create_mov_node(dbg, block, arm_encode_imm_w_shift(v.shifts[0], v.values[0]));
Michael Beck's avatar
Michael Beck committed
140
141

		for (cnt = 1; cnt < v.ops; ++cnt) {
Michael Beck's avatar
Michael Beck committed
142
143
			long value = arm_encode_imm_w_shift(v.shifts[cnt], v.values[cnt]);
			ir_node *orr_i_node = new_rd_arm_Or_i(dbg, current_ir_graph, block, result, mode, value);
Michael Beck's avatar
Michael Beck committed
144
145
			result = orr_i_node;
		}
146
147
148
149
	}
	return result;
}

150
151
152
153
154
/**
 * Create a DAG constructing a given Const.
 *
 * @param irn  a Firm const
 */
155
static ir_node *create_const_graph(ir_node *irn, ir_node *block) {
156
157
158
159
160
161
162
163
164
165
	tarval  *tv = get_Const_tarval(irn);
	ir_mode *mode = get_tarval_mode(tv);
	int     value;

	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);
166
	return create_const_graph_value(get_irn_dbg_info(irn), block, value);
167
168
}

Michael Beck's avatar
Michael Beck committed
169
170
171
/**
 * Create an And that will mask all upper bits
 */
172
static ir_node *gen_zero_extension(dbg_info *dbg, ir_node *block, ir_node *op, int result_bits) {
173
	unsigned mask_bits = (1 << result_bits) - 1;
174
	ir_node *mask_node = create_const_graph_value(dbg, block, mask_bits);
Michael Beck's avatar
Michael Beck committed
175
	return new_rd_arm_And(dbg, current_ir_graph, block, op, mask_node, mode_Iu, ARM_SHF_NONE, 0);
176
177
}

Michael Beck's avatar
Michael Beck committed
178
179
180
/**
 * Generate code for a sign extension.
 */
181
static ir_node *gen_sign_extension(dbg_info *dbg, ir_node *block, ir_node *op, int result_bits) {
Michael Beck's avatar
Michael Beck committed
182
	ir_graph *irg   = current_ir_graph;
183
	int shift_width = 32 - result_bits;
184
	ir_node *shift_const_node = create_const_graph_value(dbg, block, shift_width);
Michael Beck's avatar
Michael Beck committed
185
186
	ir_node *lshift_node = new_rd_arm_Shl(dbg, irg, block, op, shift_const_node, mode_Iu);
	ir_node *rshift_node = new_rd_arm_Shrs(dbg, irg, block, lshift_node, shift_const_node, mode_Iu);
187
188
189
	return rshift_node;
}

Michael Beck's avatar
Michael Beck committed
190
191
192
/**
 * Transforms a Conv node.
 *
193
 * @return The created ia32 Conv node
Michael Beck's avatar
Michael Beck committed
194
 */
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
static ir_node *gen_Conv(ir_node *node) {
	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_graph *irg      = current_ir_graph;
	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)) {
		env_cg->have_fp_insn = 1;

		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
213
					/* from float to float */
214
					return new_rd_arm_fpaMvf(dbg, irg, block, new_op, dst_mode);
Michael Beck's avatar
Michael Beck committed
215
216
217
				}
				else {
					/* from float to int */
218
					return new_rd_arm_fpaFix(dbg, irg, block, new_op, dst_mode);
Michael Beck's avatar
Michael Beck committed
219
220
221
222
				}
			}
			else {
				/* from int to float */
223
				return new_rd_arm_fpaFlt(dbg, irg, block, new_op, dst_mode);
Michael Beck's avatar
Michael Beck committed
224
225
			}
		}
Michael Beck's avatar
Michael Beck committed
226
		else if (USE_VFP(env_cg->isa)) {
227
228
229
			panic("VFP not supported yet\n");
			return NULL;
		}
Michael Beck's avatar
Michael Beck committed
230
231
232
233
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
		}
Michael Beck's avatar
Michael Beck committed
234
235
	}
	else { /* complete in gp registers */
236
237
		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
238
239
		int min_bits;
		ir_mode *min_mode;
240

Michael Beck's avatar
Michael Beck committed
241
242
243
		if (is_Load(skip_Proj(op))) {
			if (src_bits == dst_bits) {
				/* kill unneccessary conv */
244
				return new_op;
245
			}
Michael Beck's avatar
Michael Beck committed
246
247
			/* after a load, the bit size is already converted */
			src_bits = 32;
248
		}
Michael Beck's avatar
Michael Beck committed
249
250
251
252
253
254
255
256

		if (src_bits == dst_bits) {
			/* kill unneccessary conv */
			return new_op;
		} else if (dst_bits <= 32 && src_bits <= 32) {
			if (src_bits < dst_bits) {
				min_bits = src_bits;
				min_mode = src_mode;
257
			} else {
Michael Beck's avatar
Michael Beck committed
258
259
				min_bits = dst_bits;
				min_mode = dst_mode;
260
			}
Michael Beck's avatar
Michael Beck committed
261
			if (mode_is_signed(min_mode)) {
262
				return gen_sign_extension(dbg, block, new_op, min_bits);
263
			} else {
264
				return gen_zero_extension(dbg, block, new_op, min_bits);
265
			}
Michael Beck's avatar
Michael Beck committed
266
267
268
269
		} else {
			panic("Cannot handle Conv %+F->%+F with %d->%d bits\n", src_mode, dst_mode,
				src_bits, dst_bits);
			return NULL;
270
271
272
273
		}
	}
}

Michael Beck's avatar
Michael Beck committed
274
275
276
277
278
279
280
281
282
283
284
/**
 * Return true if an operand is a shifter operand
 */
static int is_shifter_operand(ir_node *n, arm_shift_modifier *pmod) {
	arm_shift_modifier mod = ARM_SHF_NONE;

	if (is_arm_Mov(n))
		mod = get_arm_shift_modifier(n);

	*pmod = mod;
	if (mod != ARM_SHF_NONE) {
Michael Beck's avatar
Michael Beck committed
285
		long v = get_arm_imm_value(n);
Michael Beck's avatar
Michael Beck committed
286
287
288
289
290
		if (v < 32)
			return (int)v;
	}
	return 0;
}
291
292

/**
293
 * Creates an ARM Add.
294
295
296
 *
 * @return the created arm Add node
 */
297
298
299
300
301
302
303
304
305
static ir_node *gen_Add(ir_node *node) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op1     = get_Add_left(node);
	ir_node  *new_op1 = be_transform_node(op1);
	ir_node  *op2     = get_Add_right(node);
	ir_node  *new_op2 = be_transform_node(op2);
	ir_mode  *mode    = get_irn_mode(node);
	ir_graph *irg     = current_ir_graph;
	ir_node  *new_op3;
Michael Beck's avatar
Michael Beck committed
306
307
	int v;
	arm_shift_modifier mod;
308
	dbg_info *dbg = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
309

310
	if (mode_is_float(mode)) {
311
		env_cg->have_fp_insn = 1;
312
313
		if (USE_FPA(env_cg->isa)) {
			if (is_arm_fpaMvf_i(new_op1))
Michael Beck's avatar
Michael Beck committed
314
				return new_rd_arm_fpaAdf_i(dbg, irg, block, new_op2, mode, get_arm_imm_value(new_op1));
315
			if (is_arm_fpaMvf_i(new_op2))
Michael Beck's avatar
Michael Beck committed
316
				return new_rd_arm_fpaAdf_i(dbg, irg, block, new_op1, mode, get_arm_imm_value(new_op2));
317
318
			return new_rd_arm_fpaAdf(dbg, irg, block, new_op1, new_op2, mode);
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
319
			assert(mode != mode_E && "IEEE Extended FP not supported");
320
321
			panic("VFP not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
322
		}
323
324
325
326
327
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
		}
	} else {
328
		assert(mode_is_data(mode));
329
		mode = mode_Iu;
330
331

		if (is_arm_Mov_i(new_op1))
Michael Beck's avatar
Michael Beck committed
332
			return new_rd_arm_Add_i(dbg, irg, block, new_op2, mode, get_arm_imm_value(new_op1));
333
		if (is_arm_Mov_i(new_op2))
Michael Beck's avatar
Michael Beck committed
334
			return new_rd_arm_Add_i(dbg, irg, block, new_op1, mode, get_arm_imm_value(new_op2));
Michael Beck's avatar
Michael Beck committed
335
336

		/* check for MLA */
Michael Beck's avatar
Michael Beck committed
337
		if (is_arm_Mul(new_op1) && get_irn_n_edges(op1) == 1) {
338
			new_op3 = new_op2;
Michael Beck's avatar
Michael Beck committed
339
340
			new_op2 = get_irn_n(new_op1, 1);
			new_op1 = get_irn_n(new_op1, 0);
Michael Beck's avatar
Michael Beck committed
341

342
			return new_rd_arm_Mla(dbg, irg, block, new_op1, new_op2, new_op3, mode);
Michael Beck's avatar
Michael Beck committed
343
		}
Michael Beck's avatar
Michael Beck committed
344
		if (is_arm_Mul(new_op2) && get_irn_n_edges(op2) == 1) {
345
346
347
			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
348

349
			return new_rd_arm_Mla(dbg, irg, block, new_op1, new_op2, new_op3, mode);
Michael Beck's avatar
Michael Beck committed
350
		}
351

Michael Beck's avatar
Michael Beck committed
352
		/* is the first a shifter */
353
		v = is_shifter_operand(new_op1, &mod);
Michael Beck's avatar
Michael Beck committed
354
		if (v) {
355
			new_op1 = get_irn_n(new_op1, 0);
Michael Beck's avatar
Michael Beck committed
356
			return new_rd_arm_Add(dbg, irg, block, new_op2, new_op1, mode, mod, v);
Michael Beck's avatar
Michael Beck committed
357
358
		}
		/* is the second a shifter */
359
		v = is_shifter_operand(new_op2, &mod);
Michael Beck's avatar
Michael Beck committed
360
		if (v) {
361
			new_op2 = get_irn_n(new_op2, 0);
Michael Beck's avatar
Michael Beck committed
362
			return new_rd_arm_Add(dbg, irg, block, new_op1, new_op2, mode, mod, v);
Michael Beck's avatar
Michael Beck committed
363
		}
364

Michael Beck's avatar
Michael Beck committed
365
		/* normal ADD */
Michael Beck's avatar
Michael Beck committed
366
		return new_rd_arm_Add(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, 0);
Michael Beck's avatar
Michael Beck committed
367
368
	}
}
369
370

/**
371
 * Creates an ARM Mul.
372
373
374
 *
 * @return the created arm Mul node
 */
375
376
377
378
379
380
381
382
383
static ir_node *gen_Mul(ir_node *node) {
	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);
	ir_graph *irg     = current_ir_graph;
	dbg_info *dbg     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
384

385
	if (mode_is_float(mode)) {
386
		env_cg->have_fp_insn = 1;
387
388
		if (USE_FPA(env_cg->isa)) {
			if (is_arm_Mov_i(new_op1))
Michael Beck's avatar
Michael Beck committed
389
				return new_rd_arm_fpaMuf_i(dbg, irg, block, new_op2, mode, get_arm_imm_value(new_op1));
390
			if (is_arm_Mov_i(new_op2))
Michael Beck's avatar
Michael Beck committed
391
				return new_rd_arm_fpaMuf_i(dbg, irg, block, new_op1, mode, get_arm_imm_value(new_op2));
392
393
			return new_rd_arm_fpaMuf(dbg, irg, block, new_op1, new_op2, mode);
		}
394
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
395
			assert(mode != mode_E && "IEEE Extended FP not supported");
396
			panic("VFP not supported yet\n");
397
			return NULL;
398
399
400
401
		}
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
402
		}
403
	}
404
	assert(mode_is_data(mode));
405
	mode = mode_Iu;
406
	return new_rd_arm_Mul(dbg, irg, block, new_op1, new_op2, mode);
407
408
409
}

/**
410
 * Creates an ARM floating point Div.
411
 *
Michael Beck's avatar
Michael Beck committed
412
 * @param env   The transformation environment
413
414
 * @return the created arm fDiv node
 */
415
416
417
418
419
420
421
422
static ir_node *gen_Quot(ir_node *node) {
	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
423

424
	assert(mode != mode_E && "IEEE Extended FP not supported");
425

426
	env_cg->have_fp_insn = 1;
427
428
	if (USE_FPA(env_cg->isa)) {
		if (is_arm_Mov_i(new_op1))
Michael Beck's avatar
Michael Beck committed
429
			return new_rd_arm_fpaRdf_i(dbg, current_ir_graph, block, new_op2, mode, get_arm_imm_value(new_op1));
430
		if (is_arm_Mov_i(new_op2))
Michael Beck's avatar
Michael Beck committed
431
			return new_rd_arm_fpaDvf_i(dbg, current_ir_graph, block, new_op1, mode, get_arm_imm_value(new_op2));
432
433
		return new_rd_arm_fpaDvf(dbg, current_ir_graph, block, new_op1, new_op2, mode);
	} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
434
		assert(mode != mode_E && "IEEE Extended FP not supported");
435
436
437
438
439
		panic("VFP not supported yet\n");
	}
	else {
		panic("Softfloat not supported yet\n");
		return NULL;
Michael Beck's avatar
Michael Beck committed
440
	}
Michael Beck's avatar
Michael Beck committed
441
442
443
}

#define GEN_INT_OP(op) \
444
445
446
447
448
449
	ir_node  *block   = be_transform_node(get_nodes_block(node)); \
	ir_node  *op1     = get_ ## op ## _left(node); \
	ir_node  *new_op1 = be_transform_node(op1); \
	ir_node  *op2     = get_ ## op ## _right(node); \
	ir_node  *new_op2 = be_transform_node(op2); \
	ir_graph *irg     = current_ir_graph; \
450
	ir_mode  *mode    = mode_Iu; \
451
452
	dbg_info *dbg     = get_irn_dbg_info(node); \
	int      v; \
Michael Beck's avatar
Michael Beck committed
453
454
	arm_shift_modifier mod; \
 \
455
	if (is_arm_Mov_i(new_op1)) \
Michael Beck's avatar
Michael Beck committed
456
		return new_rd_arm_ ## op ## _i(dbg, irg, block, new_op2, mode, get_arm_imm_value(new_op1)); \
457
	if (is_arm_Mov_i(new_op2)) \
Michael Beck's avatar
Michael Beck committed
458
		return new_rd_arm_ ## op ## _i(dbg, irg, block, new_op1, mode, get_arm_imm_value(new_op2)); \
Michael Beck's avatar
Michael Beck committed
459
	/* is the first a shifter */ \
460
	v = is_shifter_operand(new_op1, &mod); \
Michael Beck's avatar
Michael Beck committed
461
	if (v) { \
462
		new_op1 = get_irn_n(new_op1, 0); \
Michael Beck's avatar
Michael Beck committed
463
		return new_rd_arm_ ## op(dbg, irg, block, new_op2, new_op1, mode, mod, v); \
Michael Beck's avatar
Michael Beck committed
464
465
	} \
	/* is the second a shifter */ \
466
	v = is_shifter_operand(new_op2, &mod); \
Michael Beck's avatar
Michael Beck committed
467
	if (v) { \
468
		new_op2 = get_irn_n(new_op2, 0); \
Michael Beck's avatar
Michael Beck committed
469
		return new_rd_arm_ ## op(dbg, irg, block, new_op1, new_op2, mode, mod, v); \
Michael Beck's avatar
Michael Beck committed
470
471
	} \
	/* Normal op */ \
Michael Beck's avatar
Michael Beck committed
472
	return new_rd_arm_ ## op(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, 0) \
473
474

/**
475
 * Creates an ARM And.
476
477
478
 *
 * @return the created arm And node
 */
479
480
481
static ir_node *gen_And(ir_node *node) {
	GEN_INT_OP(And);
}
482
483

/**
484
 * Creates an ARM Orr.
485
 *
Michael Beck's avatar
Michael Beck committed
486
 * @param env   The transformation environment
487
488
 * @return the created arm Or node
 */
489
490
491
static ir_node *gen_Or(ir_node *node) {
	GEN_INT_OP(Or);
}
492
493

/**
494
 * Creates an ARM Eor.
495
496
497
 *
 * @return the created arm Eor node
 */
498
499
500
static ir_node *gen_Eor(ir_node *node) {
	GEN_INT_OP(Eor);
}
501
502

/**
503
 * Creates an ARM Sub.
504
505
506
 *
 * @return the created arm Sub node
 */
507
508
509
510
511
static ir_node *gen_Sub(ir_node *node) {
	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
512
	ir_node  *new_op2 = be_transform_node(op2);
513
514
515
516
	ir_mode  *mode    = get_irn_mode(node);
	ir_graph *irg     = current_ir_graph;
	dbg_info *dbg     = get_irn_dbg_info(node);
	int      v;
Michael Beck's avatar
Michael Beck committed
517
518
	arm_shift_modifier mod;

519
	if (mode_is_float(mode)) {
520
		env_cg->have_fp_insn = 1;
521
522
		if (USE_FPA(env_cg->isa)) {
			if (is_arm_Mov_i(new_op1))
Michael Beck's avatar
Michael Beck committed
523
				return new_rd_arm_fpaRsf_i(dbg, irg, block, new_op2, mode, get_arm_imm_value(new_op1));
524
			if (is_arm_Mov_i(new_op2))
Michael Beck's avatar
Michael Beck committed
525
				return new_rd_arm_fpaSuf_i(dbg, irg, block, new_op1, mode, get_arm_imm_value(new_op2));
526
527
			return new_rd_arm_fpaSuf(dbg, irg, block, new_op1, new_op2, mode);
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
528
			assert(mode != mode_E && "IEEE Extended FP not supported");
529
530
531
532
533
534
			panic("VFP not supported yet\n");
			return NULL;
		}
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
535
		}
Michael Beck's avatar
Michael Beck committed
536
	}
537
	else {
538
		assert(mode_is_data(mode) && "unknown mode for Sub");
539
		mode = mode_Iu;
540
541

		if (is_arm_Mov_i(new_op1))
Michael Beck's avatar
Michael Beck committed
542
			return new_rd_arm_Rsb_i(dbg, irg, block, new_op2, mode, get_arm_imm_value(new_op1));
543
		if (is_arm_Mov_i(new_op2))
Michael Beck's avatar
Michael Beck committed
544
			return new_rd_arm_Sub_i(dbg, irg, block, new_op1, mode, get_arm_imm_value(new_op2));
Michael Beck's avatar
Michael Beck committed
545
546

		/* is the first a shifter */
547
		v = is_shifter_operand(new_op1, &mod);
Michael Beck's avatar
Michael Beck committed
548
		if (v) {
549
			new_op1 = get_irn_n(new_op1, 0);
Michael Beck's avatar
Michael Beck committed
550
			return new_rd_arm_Rsb(dbg, irg, block, new_op2, new_op1, mode, mod, v);
551
		}
Michael Beck's avatar
Michael Beck committed
552
		/* is the second a shifter */
553
		v = is_shifter_operand(new_op2, &mod);
Michael Beck's avatar
Michael Beck committed
554
		if (v) {
555
			new_op2 = get_irn_n(new_op2, 0);
Michael Beck's avatar
Michael Beck committed
556
			return new_rd_arm_Sub(dbg, irg, block, new_op1, new_op2, mode, mod, v);
Michael Beck's avatar
Michael Beck committed
557
558
		}
		/* normal sub */
Michael Beck's avatar
Michael Beck committed
559
		return new_rd_arm_Sub(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, 0);
560
561
562
563
	}
}

/**
564
 * Creates an ARM Shl.
565
 *
566
 * @return the created ARM Shl node
567
 */
568
569
570
571
572
573
static ir_node *gen_Shl(ir_node *node) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op1     = get_Shl_left(node);
	ir_node  *new_op1 = be_transform_node(op1);
	ir_node  *op2     = get_Shl_right(node);
	ir_node  *new_op2 = be_transform_node(op2);
574
	ir_mode  *mode    = mode_Iu;
575
576
577
	dbg_info *dbg     = get_irn_dbg_info(node);

	if (is_arm_Mov_i(new_op2)) {
Michael Beck's avatar
Michael Beck committed
578
		return new_rd_arm_Mov(dbg, current_ir_graph, block, new_op1, mode, ARM_SHF_LSL, get_arm_imm_value(new_op2));
579
	}
580
	return new_rd_arm_Shl(dbg, current_ir_graph, block, new_op1, new_op2, mode);
581
582
583
}

/**
584
 * Creates an ARM Shr.
585
 *
586
 * @return the created ARM Shr node
587
 */
588
589
590
591
592
593
static ir_node *gen_Shr(ir_node *node) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op1     = get_Shr_left(node);
	ir_node  *new_op1 = be_transform_node(op1);
	ir_node  *op2     = get_Shr_right(node);
	ir_node  *new_op2 = be_transform_node(op2);
594
	ir_mode  *mode    = mode_Iu;
595
596
597
	dbg_info *dbg     = get_irn_dbg_info(node);

	if (is_arm_Mov_i(new_op2)) {
Michael Beck's avatar
Michael Beck committed
598
		return new_rd_arm_Mov(dbg, current_ir_graph, block, new_op1, mode, ARM_SHF_LSR, get_arm_imm_value(new_op2));
599
	}
600
	return new_rd_arm_Shr(dbg, current_ir_graph, block, new_op1, new_op2, mode);
601
602
603
}

/**
604
 * Creates an ARM Shrs.
605
 *
606
 * @return the created ARM Shrs node
607
 */
608
609
610
611
612
613
static ir_node *gen_Shrs(ir_node *node) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op1     = get_Shrs_left(node);
	ir_node  *new_op1 = be_transform_node(op1);
	ir_node  *op2     = get_Shrs_right(node);
	ir_node  *new_op2 = be_transform_node(op2);
614
	ir_mode  *mode    = mode_Iu;
615
616
617
	dbg_info *dbg     = get_irn_dbg_info(node);

	if (is_arm_Mov_i(new_op2)) {
Michael Beck's avatar
Michael Beck committed
618
		return new_rd_arm_Mov(dbg, current_ir_graph, block, new_op1, mode, ARM_SHF_ASR, get_arm_imm_value(new_op2));
619
	}
620
	return new_rd_arm_Shrs(dbg, current_ir_graph, block, new_op1, new_op2, mode);
621
622
}

Michael Beck's avatar
Michael Beck committed
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
/**
 * Creates an ARM Ror.
 *
 * @return the created ARM Ror node
 */
static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *new_op1 = be_transform_node(op1);
	ir_node  *new_op2 = be_transform_node(op2);
	ir_mode  *mode    = mode_Iu;
	dbg_info *dbg     = get_irn_dbg_info(node);

	if (is_arm_Mov_i(new_op2)) {
		return new_rd_arm_Mov(dbg, current_ir_graph, block, new_op1, mode, ARM_SHF_ROR, get_arm_imm_value(new_op2));
	}
	return new_rd_arm_Ror(dbg, current_ir_graph, block, new_op1, new_op2, mode);
}

/**
 * Creates an ARM Rol.
 *
 * @return the created ARM Rol node
 *
 * Note: there is no Rol on arm, we have to use Ror
 */
static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *new_op1 = be_transform_node(op1);
	ir_mode  *mode    = mode_Iu;
	dbg_info *dbg     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
653
654
655
	ir_node  *new_op2 = be_transform_node(op2);

	new_op2 = new_rd_arm_Rsb_i(dbg, current_ir_graph, block, new_op2, mode, 32);
Michael Beck's avatar
Michael Beck committed
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
	return new_rd_arm_Ror(dbg, current_ir_graph, block, new_op1, new_op2, mode);
}

/**
 * Creates an ARM ROR from a Firm Rotl.
 *
 * @return the created ARM Ror node
 */
static ir_node *gen_Rotl(ir_node *node) {
	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
674
		ir_node *right = get_Add_right(op2);
Michael Beck's avatar
Michael Beck committed
675
676
677
678
		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
679
			ir_node *left = get_Add_left(op2);
Michael Beck's avatar
Michael Beck committed
680
681

			if (is_Minus(left) &&
Michael Beck's avatar
Michael Beck committed
682
			    tarval_is_long(tv)          &&
Michael Beck's avatar
Michael Beck committed
683
684
685
686
			    get_tarval_long(tv) == bits &&
			    bits                == 32)
				rotate = gen_Ror(node, op1, get_Minus_op(left));
		}
Michael Beck's avatar
Michael Beck committed
687
688
689
690
691
692
693
694
695
696
697
698
699
700
	} 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);
		}

Michael Beck's avatar
Michael Beck committed
701
702
703
704
705
706
707
708
709
	}

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

	return rotate;
}

710
711
712
/**
 * Transforms a Not node.
 *
713
 * @return the created ARM Not node
714
 */
715
716
717
718
719
static ir_node *gen_Not(ir_node *node) {
	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);
	dbg_info *dbg     = get_irn_dbg_info(node);
720
	ir_mode  *mode    = mode_Iu;
Michael Beck's avatar
Michael Beck committed
721
	arm_shift_modifier mod = ARM_SHF_NONE;
722
	int      v        = is_shifter_operand(new_op, &mod);
Michael Beck's avatar
Michael Beck committed
723
724

	if (v) {
725
		new_op = get_irn_n(new_op, 0);
Michael Beck's avatar
Michael Beck committed
726
	}
Michael Beck's avatar
Michael Beck committed
727
	return new_rd_arm_Mvn(dbg, current_ir_graph, block, new_op, mode, mod, v);
728
729
}

Michael Beck's avatar
Michael Beck committed
730
731
732
733
/**
 * Transforms an Abs node.
 *
 * @param env   The transformation environment
734
 * @return the created ARM Abs node
Michael Beck's avatar
Michael Beck committed
735
 */
736
737
static ir_node *gen_Abs(ir_node *node) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
738
	ir_node  *op      = get_Abs_op(node);
739
740
741
	ir_node  *new_op  = be_transform_node(op);
	dbg_info *dbg     = get_irn_dbg_info(node);
	ir_mode  *mode    = get_irn_mode(node);
742

743
	if (mode_is_float(mode)) {
744
745
746
747
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
			return new_rd_arm_fpaAbs(dbg, current_ir_graph, block, new_op, mode);
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
748
			assert(mode != mode_E && "IEEE Extended FP not supported");
Michael Beck's avatar
Michael Beck committed
749
750
751
752
			panic("VFP not supported yet\n");
		}
		else {
			panic("Softfloat not supported yet\n");
Michael Beck's avatar
Michael Beck committed
753
		}
754
	}
755
	assert(mode_is_data(mode));
756
	mode = mode_Iu;
757
	return new_rd_arm_Abs(dbg, current_ir_graph, block, new_op, mode);
758
759
760
761
762
}

/**
 * Transforms a Minus node.
 *
763
 * @return the created ARM Minus node
764
 */
765
766
767
768
769
770
static ir_node *gen_Minus(ir_node *node) {
	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);
	dbg_info *dbg     = get_irn_dbg_info(node);
	ir_mode  *mode    = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
771

772
	if (mode_is_float(mode)) {
773
774
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
775
			return new_rd_arm_fpaMvf(dbg, current_ir_graph, block, op, mode);
776
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
777
			assert(mode != mode_E && "IEEE Extended FP not supported");
Michael Beck's avatar
Michael Beck committed
778
779
780
781
			panic("VFP not supported yet\n");
		}
		else {
			panic("Softfloat not supported yet\n");
Michael Beck's avatar
Michael Beck committed
782
		}
783
	}
784
	assert(mode_is_data(mode));
785
	mode = mode_Iu;
Michael Beck's avatar
Michael Beck committed
786
	return new_rd_arm_Rsb_i(dbg, current_ir_graph, block, new_op, mode, 0);
787
788
789
790
791
}

/**
 * Transforms a Load.
 *
792
 * @return the created ARM Load node
793
 */
794
static ir_node *gen_Load(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
795
796
797
798
799
800
801
802
803
	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);
	ir_graph *irg      = current_ir_graph;
	dbg_info *dbg      = get_irn_dbg_info(node);
	ir_node  *new_load = NULL;
804

Michael Beck's avatar
Michael Beck committed
805
	if (mode_is_float(mode)) {
806
807
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
Michael Beck's avatar
Michael Beck committed
808
			new_load = new_rd_arm_fpaLdf(dbg, irg, block, new_ptr, new_mem, mode);
809
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
810
			assert(mode != mode_E && "IEEE Extended FP not supported");
811
812
813
814
			panic("VFP not supported yet\n");
		}
		else {
			panic("Softfloat not supported yet\n");
Michael Beck's avatar
Michael Beck committed
815
		}
816
	}
817
	else {
818
		assert(mode_is_data(mode) && "unsupported mode for Load");
819
820
821
822
823

		if (mode_is_signed(mode)) {
			/* sign extended loads */
			switch (get_mode_size_bits(mode)) {
			case 8:
Michael Beck's avatar
Michael Beck committed
824
				new_load = new_rd_arm_Loadbs(dbg, irg, block, new_ptr, new_mem);
Michael Beck's avatar
Michael Beck committed
825
				break;
826
			case 16:
Michael Beck's avatar
Michael Beck committed
827
				new_load = new_rd_arm_Loadhs(dbg, irg, block, new_ptr, new_mem);
Michael Beck's avatar
Michael Beck committed
828
				break;
829
			case 32:
Michael Beck's avatar
Michael Beck committed
830
				new_load = new_rd_arm_Load(dbg, irg, block, new_ptr, new_mem);
831
832
				break;
			default:
Michael Beck's avatar
Michael Beck committed
833
				panic("mode size not supported\n");
834
835
836
837
838
			}
		} else {
			/* zero extended loads */
			switch (get_mode_size_bits(mode)) {
			case 8:
Michael Beck's avatar
Michael Beck committed
839
				new_load = new_rd_arm_Loadb(dbg, irg, block, new_ptr, new_mem);
Michael Beck's avatar
Michael Beck committed
840
				break;
841
			case 16:
Michael Beck's avatar
Michael Beck committed
842
				new_load = new_rd_arm_Loadh(dbg, irg, block, new_ptr, new_mem);
Michael Beck's avatar
Michael Beck committed
843
				break;
844
			case 32:
Michael Beck's avatar
Michael Beck committed
845
				new_load = new_rd_arm_Load(dbg, irg, block, new_ptr, new_mem);
846
847
				break;
			default:
Michael Beck's avatar
Michael Beck committed
848
				panic("mode size not supported\n");
849
850
			}
		}
851
	}
Michael Beck's avatar
Michael Beck committed
852
	set_irn_pinned(new_load, get_irn_pinned(node));
853
854
855
856
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 */
		ir_node *proj = new_r_Proj(irg, block, new_load, mode_Iu, pn_arm_Load_res);
		be_new_Keep(arch_get_irn_reg_class(env_cg->arch_env, proj, -1), irg, block, 1, &proj);
	}

Michael Beck's avatar
Michael Beck committed
861
	return new_load;
862
863
864
865
866
}

/**
 * Transforms a Store.
 *
867
 * @return the created ARM Store node
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
878
879
880
	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);
	ir_graph *irg      = current_ir_graph;
	dbg_info *dbg      = get_irn_dbg_info(node);
	ir_node *new_store = NULL;
881

Michael Beck's avatar
Michael Beck committed
882
	if (mode_is_float(mode)) {
883
884
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
Michael Beck's avatar
Michael Beck committed
885
			new_store = new_rd_arm_fpaStf(dbg, irg, block, new_ptr, new_val, new_mem, mode);
886
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
887
			assert(mode != mode_E && "IEEE Extended FP not supported");
Michael Beck's avatar
Michael Beck committed
888
889
890
891
892
			panic("VFP not supported yet\n");
		} else {
			panic("Softfloat not supported yet\n");
		}
	} else {
893
		assert(mode_is_data(mode) && "unsupported mode for Store");
Michael Beck's avatar
Michael Beck committed
894
895
896
897
898
899
900
		switch (get_mode_size_bits(mode)) {
		case 8:
			new_store = new_rd_arm_Storeb(dbg, irg, block, new_ptr, new_val, new_mem);
		case 16:
			new_store = new_rd_arm_Storeh(dbg, irg, block, new_ptr, new_val, new_mem);
		default:
			new_store = new_rd_arm_Store(dbg, irg, block, new_ptr, new_val, new_mem);
Michael Beck's avatar
Michael Beck committed
901
		}
902
	}
Michael Beck's avatar
Michael Beck committed
903
904
	set_irn_pinned(new_store, get_irn_pinned(node));
	return new_store;
905
906
}

907
908
909
910
911
912
913
914
915
916
917
918
919
/**
 * Transforms a Cond.
 *
 * @return the created ARM Cond node
 */
static ir_node *gen_Cond(ir_node *node) {
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *selector = get_Cond_selector(node);
	ir_graph *irg      = current_ir_graph;
	dbg_info *dbg      = get_irn_dbg_info(node);
	ir_mode  *mode     = get_irn_mode(selector);

	if (mode == mode_b) {
920
		/* an conditional jump */
921
922
923
924
925
926
		ir_node *cmp_node = get_Proj_pred(selector);
		ir_node *op1      = get_Cmp_left(cmp_node);
		ir_node *new_op1  = be_transform_node(op1);
		ir_node *op2      = get_Cmp_right(cmp_node);
		ir_node *new_op2  = be_transform_node(op2);

927
928
929
930
931
932
933
934
935
936
937
938
939
940
		if (mode_is_float(get_irn_mode(op1))) {
			/* floating point compare */
			pn_Cmp pnc = get_Proj_proj(selector);

			if (pnc & pn_Cmp_Uo) {
				/* check for unordered, need cmf */
				return new_rd_arm_fpaCmfBra(dbg, irg, block, new_op1, new_op2, pnc);
			}
			/* Hmm: use need cmfe */
			return new_rd_arm_fpaCmfeBra(dbg, irg, block, new_op1, new_op2, pnc);
		} else {
			/* integer compare */
			return new_rd_arm_CmpBra(dbg, irg, block, new_op1, new_op2, get_Proj_proj(selector));
		}
941
	} else {
942
943
		/* SwitchJmp */
		ir_node *new_op = be_transform_node(selector);
944
945
946
947
948
949
950
951
952
953
954
		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;

955
		foreach_out_edge(node, edge) {
956
957
958
959
960
961
962
963
964
			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;