sparc_transform.c 79.2 KB
Newer Older
Hannes Rapp's avatar
Hannes Rapp committed
1
2
/*
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
Hannes Rapp's avatar
Hannes Rapp committed
4
5
6
7
8
 */

/**
 * @file
 * @brief   code selection (transform FIRM into SPARC FIRM)
Matthias Braun's avatar
Matthias Braun committed
9
 * @author  Hannes Rapp, Matthias Braun
Hannes Rapp's avatar
Hannes Rapp committed
10
 */
11
#include <stdint.h>
12
#include <stdbool.h>
13

Hannes Rapp's avatar
Hannes Rapp committed
14
15
16
17
18
19
#include "irnode_t.h"
#include "irgraph_t.h"
#include "irmode_t.h"
#include "irgmod.h"
#include "iredges.h"
#include "ircons.h"
20
#include "iroptimize.h"
Hannes Rapp's avatar
Hannes Rapp committed
21
22
23
#include "dbginfo.h"
#include "iropt_t.h"
#include "debug.h"
Matthias Braun's avatar
Matthias Braun committed
24
#include "panic.h"
Matthias Braun's avatar
Matthias Braun committed
25
#include "util.h"
Hannes Rapp's avatar
Hannes Rapp committed
26

27
#include "beasm.h"
28
29
30
31
#include "benode.h"
#include "beirg.h"
#include "beutil.h"
#include "betranshlp.h"
Hannes Rapp's avatar
Hannes Rapp committed
32
33
34
35
36
37
38
39
#include "bearch_sparc_t.h"

#include "sparc_nodes_attr.h"
#include "sparc_transform.h"
#include "sparc_new_nodes.h"
#include "gen_sparc_new_nodes.h"

#include "gen_sparc_regalloc_if.h"
40
#include "sparc_cconv.h"
Hannes Rapp's avatar
Hannes Rapp committed
41
42
43

DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)

44
static const arch_register_t *sp_reg = &sparc_registers[REG_SP];
45
static calling_convention_t  *current_cconv = NULL;
46
static be_stackorder_t       *stackorder;
47
48
static ir_mode               *mode_gp;
static ir_mode               *mode_fp;
49
50
static ir_mode               *mode_fp2;
//static ir_mode               *mode_fp4;
51
static pmap                  *node_to_stack;
52
static ir_node               *frame_base;
Hannes Rapp's avatar
Hannes Rapp committed
53

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
static const arch_register_t *const omit_fp_callee_saves[] = {
	&sparc_registers[REG_L0],
	&sparc_registers[REG_L1],
	&sparc_registers[REG_L2],
	&sparc_registers[REG_L3],
	&sparc_registers[REG_L4],
	&sparc_registers[REG_L5],
	&sparc_registers[REG_L6],
	&sparc_registers[REG_L7],
	&sparc_registers[REG_I0],
	&sparc_registers[REG_I1],
	&sparc_registers[REG_I2],
	&sparc_registers[REG_I3],
	&sparc_registers[REG_I4],
	&sparc_registers[REG_I5],
};

71
static inline bool mode_needs_gp_reg(ir_mode *mode)
Hannes Rapp's avatar
Hannes Rapp committed
72
{
73
74
75
76
77
78
	if (mode_is_int(mode) || mode_is_reference(mode)) {
		/* we should only see 32bit code */
		assert(get_mode_size_bits(mode) <= 32);
		return true;
	}
	return false;
Hannes Rapp's avatar
Hannes Rapp committed
79
80
}

81
82
83
/**
 * Create an And that will zero out upper bits.
 *
Michael Beck's avatar
Michael Beck committed
84
85
86
 * @param dbgi      debug info
 * @param block     the basic block
 * @param op        the original node
87
88
89
90
91
92
 * @param src_bits  number of lower bits that will remain
 */
static ir_node *gen_zero_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
                                   int src_bits)
{
	if (src_bits == 8) {
93
		return new_bd_sparc_And_imm(dbgi, block, op, NULL, 0xFF);
94
	} else if (src_bits == 16) {
95
		ir_node *lshift = new_bd_sparc_Sll_imm(dbgi, block, op, NULL, 16);
96
		ir_node *rshift = new_bd_sparc_Srl_imm(dbgi, block, lshift, NULL, 16);
97
98
99
100
101
102
103
104
		return rshift;
	} else {
		panic("zero extension only supported for 8 and 16 bits");
	}
}

/**
 * Generate code for a sign extension.
Michael Beck's avatar
Michael Beck committed
105
106
107
108
109
 *
 * @param dbgi      debug info
 * @param block     the basic block
 * @param op        the original node
 * @param src_bits  number of lower bits that will remain
110
111
112
113
114
 */
static ir_node *gen_sign_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
                                   int src_bits)
{
	int shift_width = 32 - src_bits;
115
116
	ir_node *lshift_node = new_bd_sparc_Sll_imm(dbgi, block, op, NULL, shift_width);
	ir_node *rshift_node = new_bd_sparc_Sra_imm(dbgi, block, lshift_node, NULL, shift_width);
117
118
119
	return rshift_node;
}

Michael Beck's avatar
Michael Beck committed
120
121
122
123
124
125
126
127
/**
 * Extend a value to 32 bit signed/unsigned depending on its mode.
 *
 * @param dbgi      debug info
 * @param block     the basic block
 * @param op        the original node
 * @param orig_mode the original mode of op
 */
128
129
130
131
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);
132
	assert(bits < 32);
133
134
135
136
137
138
139
140

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

Hannes Rapp's avatar
Hannes Rapp committed
141
typedef enum {
142
143
144
145
146
	MATCH_NONE          = 0,
	MATCH_COMMUTATIVE   = 1U << 0, /**< commutative operation. */
	MATCH_MODE_NEUTRAL  = 1U << 1, /**< the higher bits of the inputs don't
	                                    influence the significant lower bit at
	                                    all (for cases where mode < 32bit) */
147
	MATCH_SIGN_EXT_LEFT = 1U << 2, /**< we need to sign-extend the left operand
Christoph Mallon's avatar
Christoph Mallon committed
148
	                                    (for cases when mode < 32bit) */
149
150
	MATCH_ZERO_EXT_LEFT = 1U << 3, /**< we need to zero-extend the left operand
                                            (for cases when mode < 32bit) */
Hannes Rapp's avatar
Hannes Rapp committed
151
} match_flags_t;
152
ENUM_BITSET(match_flags_t)
Hannes Rapp's avatar
Hannes Rapp committed
153
154

typedef ir_node* (*new_binop_reg_func) (dbg_info *dbgi, ir_node *block, ir_node *op1, ir_node *op2);
Hannes Rapp's avatar
Hannes Rapp committed
155
typedef ir_node* (*new_binop_fp_func) (dbg_info *dbgi, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode);
156
typedef ir_node* (*new_binop_imm_func) (dbg_info *dbgi, ir_node *block, ir_node *op1, ir_entity *entity, int32_t immediate);
157
typedef ir_node* (*new_unop_fp_func) (dbg_info *dbgi, ir_node *block, ir_node *op1, ir_mode *mode);
Hannes Rapp's avatar
Hannes Rapp committed
158
159

/**
160
 * checks if a node's value can be encoded as a immediate
Hannes Rapp's avatar
Hannes Rapp committed
161
162
163
164
165
166
 */
static bool is_imm_encodeable(const ir_node *node)
{
	if (!is_Const(node))
		return false;

167
	long const value = get_Const_long(node);
168
	return sparc_is_value_imm_encodeable(value);
Hannes Rapp's avatar
Hannes Rapp committed
169
170
}

171
static bool needs_extension(ir_node *op)
172
{
173
	ir_mode *mode = get_irn_mode(op);
174
175
	unsigned gp_bits = get_mode_size_bits(mode_gp);
	if (get_mode_size_bits(mode) >= gp_bits)
176
		return false;
177
	return !be_upper_bits_clean(op, mode);
178
179
}

180
static void sparc_parse_constraint_letter(void const *const env, be_asm_constraint_t* const c, char const l)
181
{
182
183
184
185
186
187
188
189
190
191
192
193
194
195
	(void)env;

	switch (l) {
	case 'r':
		c->cls                   = &sparc_reg_classes[CLASS_sparc_gp];
		c->all_registers_allowed = true;
		break;

	case 'e':
	case 'f':
		c->cls                   = &sparc_reg_classes[CLASS_sparc_fp];
		c->all_registers_allowed = true;
		break;

196
197
	case 'g':
		c->all_registers_allowed = true;
198
		c->memory_possible       = true;
199
200
		/* FALLTHROUGH */
	case 'A':
201
	case 'I':
202
203
204
205
206
	case 'J':
	case 'L':
	case 'M':
	case 'O':
	case 'P':
207
	case 'i':
208
	case 'n':
209
210
211
212
		c->cls            = &sparc_reg_classes[CLASS_sparc_gp];
		c->immediate_type = l;
		break;

213
214
215
216
217
	case 'm':
	case 'w':
		c->memory_possible = true;
		break;

218
219
	default:
		panic("unknown asm constraint '%c'", l);
220
	}
221
}
222

223
224
225
static void parse_asm_constraints(be_asm_constraint_t *const constraint, ident *const constraint_text, bool const is_output)
{
	be_parse_asm_constraints_internal(constraint, constraint_text, is_output, &sparc_parse_constraint_letter, NULL);
226
227
228
229
230
231
232
233
234
235
236
237
238
239
}

static const arch_register_t *find_register(const char *name)
{
	for (size_t i = 0; i < N_SPARC_REGISTERS; ++i) {
		const arch_register_t *const reg = &sparc_registers[i];
		if (strcmp(reg->name, name) == 0)
			return reg;
	}
	return NULL;
}

void sparc_init_asm_constraints(void)
{
240
	be_set_constraint_support(ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER,  "0123456789efr");
241
	be_set_constraint_support(ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE, "AIJLMOPin");
242
243
	be_set_constraint_support(ASM_CONSTRAINT_FLAG_SUPPORTS_ANY,       "g");
	be_set_constraint_support(ASM_CONSTRAINT_FLAG_SUPPORTS_MEMOP,     "mw");
244
245
246
247
248
249
250
251
252
	/* Note there are many more flags in gcc which we can't properly support
	 * at the moment. see gcc/config/sparc/constraints.md */
}

int sparc_is_valid_clobber(const char *clobber)
{
	return strcmp(clobber, "memory") == 0 || strcmp(clobber, "cc") == 0;
}

253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
static bool sparc_check_immediate_constraint(long const val, char const imm_type)
{
	switch (imm_type) {
	case 'A': return   -16 <= val && val <   16;
	case 'I': return sparc_is_value_imm_encodeable(val);
	case 'J': return val ==    0;
	case 'L': return -1024 <= val && val < 1024;
	case 'M': return  -512 <= val && val <  512;
	case 'O': return val == 4096;
	case 'P': return val ==   -1;

	case 'g':
	case 'i':
	case 'n': return true;
	}
	panic("invalid immediate constraint found");
}

271
272
273
274
static bool sparc_match_immediate(sparc_asm_operand_t *const operand, ir_node *const node, char const imm_type)
{
	ir_tarval *offset;
	ir_entity *entity;
Matthias Braun's avatar
Matthias Braun committed
275
276
	unsigned   reloc_kind;
	if (!be_match_immediate(node, &offset, &entity, &reloc_kind))
277
278
		return false;

279
	if (entity && imm_type != 'g' && imm_type != 'i')
280
281
282
283
284
		return false;

	long value;
	if (offset) {
		value = get_tarval_long(offset);
285
		if (!sparc_check_immediate_constraint(value, imm_type))
286
287
288
289
290
291
292
293
294
295
296
			return false;
	} else {
		value = 0;
	}

	operand->kind                   = ASM_OPERAND_IMMEDIATE;
	operand->immediate_value        = value;
	operand->immediate_value_entity = entity;
	return true;
}

297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
static ir_node *gen_ASM(ir_node *node)
{
	ident   **clobbers     = get_ASM_clobbers(node);
	//unsigned  clobber_bits[BITSET_SIZE_ELEMS(N_SPARC_REGISTERS)];

	for (size_t c = 0; c < get_ASM_n_clobbers(node); ++c) {
		const char *const clobber = get_id_str(clobbers[c]);
		if (strcmp(clobber, "memory") == 0)
			continue;
		if (strcmp(clobber, "cc") == 0) {
			continue;
		}

		const arch_register_t *reg = find_register(clobber);
		if (reg == NULL)
			panic("invalid clobber in sparc asm");

#if 0
		rbitset_set(clobber_bits, reg->global_index);
#else
		panic("clobbers not correctly supported yet");
#endif
	}

321
322
323
324
	unsigned             const n_operands = be_count_asm_operands(node);
	ir_graph            *const irg        = get_irn_irg(node);
	struct obstack      *const obst       = get_irg_obstack(irg);
	sparc_asm_operand_t *const operands   = NEW_ARR_DZ(sparc_asm_operand_t, obst, n_operands);
325

326
327
328
329
	int                      n_inputs          = get_ASM_n_inputs(node);
	size_t                   n_out_constraints = get_ASM_n_output_constraints(node);
	ir_asm_constraint const *in_constraints    = get_ASM_input_constraints(node);
	ir_asm_constraint const *out_constraints   = get_ASM_output_constraints(node);
330
331

	/* construct output constraints */
332
	arch_register_req_t const **out_reqs = NEW_ARR_F(arch_register_req_t const*, 0);
333
334
335
336
337

	size_t out_idx;
	for (out_idx = 0; out_idx < n_out_constraints; ++out_idx) {
		const ir_asm_constraint *constraint = &out_constraints[out_idx];
		unsigned                 pos        = constraint->pos;
338
		be_asm_constraint_t      parsed_constraint;
339
340
341
		parse_asm_constraints(&parsed_constraint, constraint->constraint, true);

		assert(parsed_constraint.immediate_type == 0);
342
343
		arch_register_req_t const *const req = be_make_register_req(obst, &parsed_constraint, n_out_constraints, out_reqs, out_idx);
		ARR_APP1(arch_register_req_t const*, out_reqs, req);
344
345
346
347
348
349
350
351
352

		/* TODO: adjust register_req for clobbers */

		sparc_asm_operand_t *const operand = &operands[pos];
		operand->kind = ASM_OPERAND_OUTPUT_VALUE;
		operand->pos  = out_idx;
	}

	/* inputs + input constraints */
353
354
	ir_node                   **in      = NEW_ARR_F(ir_node*, 0);
	arch_register_req_t const **in_reqs = NEW_ARR_F(arch_register_req_t const*, 0);
355
356
357
358
359
	for (int i = 0; i < n_inputs; ++i) {
		ir_node                 *pred         = get_ASM_input(node, i);
		const ir_asm_constraint *constraint   = &in_constraints[i];
		unsigned                 pos          = constraint->pos;

360
		be_asm_constraint_t parsed_constraint;
361
362
363
364
365
366
		parse_asm_constraints(&parsed_constraint, constraint->constraint, false);

		sparc_asm_operand_t *const operand = &operands[pos];

		/* try to use an immediate value */
		char imm_type = parsed_constraint.immediate_type;
367
368
		if (imm_type != '\0' && sparc_match_immediate(operand, pred, imm_type))
			continue;
369

370
371
		ir_node             *const new_pred = be_transform_node(pred);
		operand_kind_t             kind     = ASM_OPERAND_INPUT_VALUE;
372
		arch_register_req_t const *req      = be_make_register_req(obst, &parsed_constraint, n_out_constraints, out_reqs, i);
373
374
375
376
		if (req == arch_no_register_req) {
			kind = ASM_OPERAND_MEMORY;
			req  = arch_get_irn_register_req(new_pred)->cls->class_req;
		}
377

378
		operand->kind = kind;
379
380
381
		operand->pos  = ARR_LEN(in);
		ARR_APP1(ir_node*, in, new_pred);
		ARR_APP1(arch_register_req_t const*, in_reqs, req);
382
383
384
385
386
387
388
389
	}

	/* parse clobbers */
	for (size_t c = 0; c < get_ASM_n_clobbers(node); ++c) {
		const char *const clobber = get_id_str(clobbers[c]);
		if (strcmp(clobber, "memory") == 0)
			continue;
		if (strcmp(clobber, "cc") == 0) {
390
391
			ARR_APP1(arch_register_req_t const*, out_reqs, sparc_registers[REG_PSR].single_req);
			ARR_APP1(arch_register_req_t const*, out_reqs, sparc_registers[REG_FSR].single_req);
392
393
394
395
396
			continue;
		}

		const arch_register_t *reg = find_register(clobber);
		assert(reg != NULL); /* otherwise we had a panic earlier */
397
		ARR_APP1(arch_register_req_t const*, out_reqs, reg->single_req);
398
399
	}

400
	return be_make_asm(node, in, in_reqs, out_reqs, operands);
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
/* Transforms the left operand of a binary operation.
 *
 * Performs sign/zero extension if necessary.
 */
static ir_node *gen_helper_binop_left(ir_node *left, dbg_info *dbgi,
                                      ir_node *block, match_flags_t flags)
{
	ir_mode *mode     = get_irn_mode(left);
	ir_node *new_left = be_transform_node(left);

	if (flags & MATCH_MODE_NEUTRAL)
		return new_left;

	int bits    = get_mode_size_bits(mode);
	int gp_bits = get_mode_size_bits(mode_gp);

	if (bits >= gp_bits)
		return new_left;

	if (flags & MATCH_SIGN_EXT_LEFT) {
		if (!mode_is_signed(mode) || needs_extension(left)) {
			return gen_sign_extension(dbgi, block, new_left, bits);
		}
	} else if (flags & MATCH_ZERO_EXT_LEFT) {
		if (mode_is_signed(mode) || needs_extension(left)) {
			return gen_zero_extension(dbgi, block, new_left, bits);
		}
	} else if (needs_extension(left)) {
		return gen_extension(dbgi, block, new_left, mode);
	}

	return new_left;
}

Hannes Rapp's avatar
Hannes Rapp committed
437
438
439
/**
 * helper function for binop operations
 *
Michael Beck's avatar
Michael Beck committed
440
441
 * @param new_reg  register generation function ptr
 * @param new_imm  immediate generation function ptr
Hannes Rapp's avatar
Hannes Rapp committed
442
 */
Matthias Braun's avatar
Matthias Braun committed
443
444
445
446
447
static ir_node *gen_helper_binop_args(ir_node *node,
                                      ir_node *op1, ir_node *op2,
                                      match_flags_t flags,
                                      new_binop_reg_func new_reg,
                                      new_binop_imm_func new_imm)
Hannes Rapp's avatar
Hannes Rapp committed
448
{
449
	dbg_info *dbgi  = get_irn_dbg_info(node);
450
	ir_node  *block = be_transform_nodes_block(node);
451
452

	if (flags & MATCH_MODE_NEUTRAL) {
453
454
		op1 = be_skip_downconv(op1, false);
		op2 = be_skip_downconv(op2, false);
455
	}
Matthias Braun's avatar
Matthias Braun committed
456
	ir_mode *mode2 = get_irn_mode(op2);
457
458
	/* we should not see 64bit code */
	assert(get_mode_size_bits(get_irn_mode(op1)) <= 32);
459
	assert(get_mode_size_bits(mode2) <= 32);
Hannes Rapp's avatar
Hannes Rapp committed
460
461

	if (is_imm_encodeable(op2)) {
462
463
		int32_t  const immediate = get_Const_long(op2);
		ir_node *const new_op1   = gen_helper_binop_left(op1, dbgi, block, flags);
464
		return new_imm(dbgi, block, new_op1, NULL, immediate);
Hannes Rapp's avatar
Hannes Rapp committed
465
	}
Matthias Braun's avatar
Matthias Braun committed
466
	ir_node *new_op2 = be_transform_node(op2);
467
	if (! (flags & MATCH_MODE_NEUTRAL) && needs_extension(op2)) {
468
469
		new_op2 = gen_extension(dbgi, block, new_op2, mode2);
	}
Hannes Rapp's avatar
Hannes Rapp committed
470
471

	if ((flags & MATCH_COMMUTATIVE) && is_imm_encodeable(op1)) {
472
		int32_t const immediate = get_Const_long(op1);
473
		return new_imm(dbgi, block, new_op2, NULL, immediate);
Hannes Rapp's avatar
Hannes Rapp committed
474
475
	}

476
	ir_node *new_op1 = gen_helper_binop_left(op1, dbgi, block, flags);
Hannes Rapp's avatar
Hannes Rapp committed
477
478
479
	return new_reg(dbgi, block, new_op1, new_op2);
}

Matthias Braun's avatar
Matthias Braun committed
480
481
482
483
484
485
486
487
488
static ir_node *gen_helper_binop(ir_node *node, match_flags_t flags,
                                 new_binop_reg_func new_reg,
                                 new_binop_imm_func new_imm)
{
	ir_node *op1 = get_binop_left(node);
	ir_node *op2 = get_binop_right(node);
	return gen_helper_binop_args(node, op1, op2, flags, new_reg, new_imm);
}

Hannes Rapp's avatar
Hannes Rapp committed
489
490
491
/**
 * helper function for FP binop operations
 */
492
static ir_node *gen_helper_binfpop(ir_node *node, ir_mode *mode,
493
494
495
                                   new_binop_fp_func new_func_single,
                                   new_binop_fp_func new_func_double,
                                   new_binop_fp_func new_func_quad)
Hannes Rapp's avatar
Hannes Rapp committed
496
{
497
	ir_node  *block   = be_transform_nodes_block(node);
Hannes Rapp's avatar
Hannes Rapp committed
498
	ir_node  *op1     = get_binop_left(node);
499
	ir_node  *new_op1 = be_transform_node(op1);
Hannes Rapp's avatar
Hannes Rapp committed
500
	ir_node  *op2     = get_binop_right(node);
501
	ir_node  *new_op2 = be_transform_node(op2);
Hannes Rapp's avatar
Hannes Rapp committed
502
	dbg_info *dbgi    = get_irn_dbg_info(node);
503
504
505
506
507
508
509
510
511
512
513
514
515
	unsigned  bits    = get_mode_size_bits(mode);

	switch (bits) {
	case 32:
		return new_func_single(dbgi, block, new_op1, new_op2, mode);
	case 64:
		return new_func_double(dbgi, block, new_op1, new_op2, mode);
	case 128:
		return new_func_quad(dbgi, block, new_op1, new_op2, mode);
	default:
		break;
	}
	panic("unsupported mode %+F for float op", mode);
Hannes Rapp's avatar
Hannes Rapp committed
516
517
}

518
519
520
521
522
523
524
525
526
527
528
529
530
typedef ir_node* (*new_binopx_imm_func)(dbg_info *dbgi, ir_node *block,
                                        ir_node *op1, ir_node *flags,
                                        ir_entity *imm_entity, int32_t imm);

typedef ir_node* (*new_binopx_reg_func)(dbg_info *dbgi, ir_node *block,
                                        ir_node *op1, ir_node *op2,
                                        ir_node *flags);

static ir_node *gen_helper_binopx(ir_node *node, match_flags_t match_flags,
                                  new_binopx_reg_func new_binopx_reg,
                                  new_binopx_imm_func new_binopx_imm)
{
	dbg_info *dbgi      = get_irn_dbg_info(node);
531
	ir_node  *block     = be_transform_nodes_block(node);
532
533
534
535
536
537
538
539
540
	ir_node  *op1       = get_irn_n(node, 0);
	ir_node  *op2       = get_irn_n(node, 1);
	ir_node  *flags     = get_irn_n(node, 2);
	ir_node  *new_flags = be_transform_node(flags);

	/* only support for mode-neutral implemented so far */
	assert(match_flags & MATCH_MODE_NEUTRAL);

	if (is_imm_encodeable(op2)) {
541
542
		int32_t  const immediate = get_Const_long(op2);
		ir_node *const new_op1   = be_transform_node(op1);
543
544
		return new_binopx_imm(dbgi, block, new_op1, new_flags, NULL, immediate);
	}
Matthias Braun's avatar
Matthias Braun committed
545
	ir_node *new_op2 = be_transform_node(op2);
546
	if ((match_flags & MATCH_COMMUTATIVE) && is_imm_encodeable(op1)) {
547
		int32_t const immediate = get_Const_long(op1);
548
549
		return new_binopx_imm(dbgi, block, new_op2, new_flags, NULL, immediate);
	}
Matthias Braun's avatar
Matthias Braun committed
550
	ir_node *new_op1 = be_transform_node(op1);
551
552
553
554
	return new_binopx_reg(dbgi, block, new_op1, new_op2, new_flags);

}

555
556
static ir_node *get_g0(ir_graph *irg)
{
Christoph Mallon's avatar
Christoph Mallon committed
557
	return be_get_Start_proj(irg, &sparc_registers[REG_G0]);
558
559
}

560
561
static ir_node *get_g7(ir_graph *irg)
{
Christoph Mallon's avatar
Christoph Mallon committed
562
	return be_get_Start_proj(irg, &sparc_registers[REG_G7]);
563
564
565
566
567
568
569
570
571
572
573
574
575
}

static ir_node *make_tls_offset(dbg_info *dbgi, ir_node *block,
                                ir_entity *entity, int32_t offset)
{
	ir_node  *hi  = new_bd_sparc_SetHi(dbgi, block, entity, offset);
	ir_node  *low = new_bd_sparc_Xor_imm(dbgi, block, hi, entity, offset);
	return low;
}

static ir_node *make_address(dbg_info *dbgi, ir_node *block, ir_entity *entity,
                             int32_t offset)
{
576
	if (is_tls_entity(entity)) {
577
578
579
580
581
582
583
584
585
586
587
588
		ir_graph *irg     = get_irn_irg(block);
		ir_node  *g7      = get_g7(irg);
		ir_node  *offsetn = make_tls_offset(dbgi, block, entity, offset);
		ir_node  *add     = new_bd_sparc_Add_reg(dbgi, block, g7, offsetn);
		return add;
	} else {
		ir_node *hi  = new_bd_sparc_SetHi(dbgi, block, entity, offset);
		ir_node *low = new_bd_sparc_Or_imm(dbgi, block, hi, entity, offset);
		return low;
	}
}

589
typedef struct address_t {
590
591
	ir_node   *ptr;
	ir_node   *ptr2;
592
593
594
595
	ir_entity *entity;
	int32_t    offset;
} address_t;

596
597
598
599
/**
 * Match a load/store address
 */
static void match_address(ir_node *ptr, address_t *address, bool use_ptr2)
600
601
602
603
604
605
606
607
{
	ir_node   *base   = ptr;
	int32_t    offset = 0;

	if (is_Add(base)) {
		ir_node *add_right = get_Add_right(base);
		if (is_Const(add_right)) {
			base    = get_Add_left(base);
608
			offset += get_Const_long(add_right);
609
610
611
612
613
		}
	}
	/* Note that we don't match sub(x, Const) or chains of adds/subs
	 * because this should all be normalized by now */

614
	/* we only use the entity if we're the only user otherwise we probably
615
616
	 * won't save anything but produce multiple sethi+or combinations with
	 * just different offsets */
Matthias Braun's avatar
Matthias Braun committed
617
618
	ir_node   *ptr2   = NULL;
	ir_entity *entity = NULL;
619
620
	if (is_Address(base) && get_irn_n_edges(base) == 1) {
		ir_entity *sc_entity = get_Address_entity(base);
621
		dbg_info  *dbgi      = get_irn_dbg_info(ptr);
622
		ir_node   *new_block = be_transform_nodes_block(ptr);
623

624
		if (is_tls_entity(sc_entity)) {
625
626
627
628
629
630
631
632
633
634
635
636
			if (!use_ptr2) {
				goto only_offset;
			} else {
				ptr2   = make_tls_offset(dbgi, new_block, sc_entity, offset);
				offset = 0;
				base   = get_g7(get_irn_irg(base));
			}
		} else {
			entity = sc_entity;
			base   = new_bd_sparc_SetHi(dbgi, new_block, entity, offset);
		}
	} else if (use_ptr2 && is_Add(base) && offset == 0) {
637
638
		ptr2 = be_transform_node(get_Add_right(base));
		base = be_transform_node(get_Add_left(base));
639
	} else {
640
only_offset:
641
		if (sparc_is_value_imm_encodeable(offset)) {
642
643
644
645
646
647
648
			base = be_transform_node(base);
		} else {
			base   = be_transform_node(ptr);
			offset = 0;
		}
	}

649
650
	address->ptr    = base;
	address->ptr2   = ptr2;
651
652
653
654
	address->entity = entity;
	address->offset = offset;
}

Hannes Rapp's avatar
Hannes Rapp committed
655
656
657
658
659
660
661
662
/**
 * Creates an sparc Add.
 *
 * @param node   FIRM node
 * @return the created sparc Add node
 */
static ir_node *gen_Add(ir_node *node)
{
663
	ir_mode *mode = get_irn_mode(node);
664
	if (mode_is_float(mode)) {
665
666
		return gen_helper_binfpop(node, mode, new_bd_sparc_fadd_s,
		                          new_bd_sparc_fadd_d, new_bd_sparc_fadd_q);
667
	}
Hannes Rapp's avatar
Hannes Rapp committed
668

669
	/* special case: + 0x1000 can be represented as - 0x1000 */
Matthias Braun's avatar
Matthias Braun committed
670
	ir_node *right = get_Add_right(node);
671
	if (is_Const(right)) {
Matthias Braun's avatar
Matthias Braun committed
672
		ir_node   *left = get_Add_left(node);
673
674
		/* is this simple address arithmetic? then we can let the linker do
		 * the calculation. */
675
		if (is_Address(left) && get_irn_n_edges(left) == 1) {
676
			dbg_info *dbgi  = get_irn_dbg_info(node);
677
			ir_node  *block = be_transform_nodes_block(node);
678

679
			/* the value of use_ptr2 shouldn't matter here */
Matthias Braun's avatar
Matthias Braun committed
680
			address_t address;
681
682
683
			match_address(node, &address, false);
			assert(is_sparc_SetHi(address.ptr));
			return new_bd_sparc_Or_imm(dbgi, block, address.ptr,
684
685
686
			                           address.entity, address.offset);
		}

687
		uint32_t const val = get_Const_long(right);
688
689
		if (val == 0x1000) {
			dbg_info *dbgi   = get_irn_dbg_info(node);
690
			ir_node  *block  = be_transform_nodes_block(node);
691
692
			ir_node  *op     = get_Add_left(node);
			ir_node  *new_op = be_transform_node(op);
693
			return new_bd_sparc_Sub_imm(dbgi, block, new_op, NULL, -0x1000);
694
695
696
		}
	}

697
698
	return gen_helper_binop(node, MATCH_COMMUTATIVE | MATCH_MODE_NEUTRAL,
	                        new_bd_sparc_Add_reg, new_bd_sparc_Add_imm);
Hannes Rapp's avatar
Hannes Rapp committed
699
700
}

701
702
static ir_node *gen_AddCC_t(ir_node *node)
{
yb9976's avatar
yb9976 committed
703
704
705
	ir_node *left     = get_irn_n(node, n_sparc_AddCC_t_left);
	ir_node *right    = get_irn_n(node, n_sparc_AddCC_t_right);
	ir_node *new_node = gen_helper_binop_args(node, left, right,
706
707
	                             MATCH_COMMUTATIVE | MATCH_MODE_NEUTRAL,
	                             new_bd_sparc_AddCC_reg, new_bd_sparc_AddCC_imm);
708
	arch_set_irn_register_out(new_node, pn_sparc_AddCC_flags, &sparc_registers[REG_PSR]);
yb9976's avatar
yb9976 committed
709
710

	return new_node;
711
712
713
714
}

static ir_node *gen_Proj_AddCC_t(ir_node *node)
{
715
	unsigned pn       = get_Proj_num(node);
716
717
718
719
720
	ir_node *pred     = get_Proj_pred(node);
	ir_node *new_pred = be_transform_node(pred);

	switch (pn) {
	case pn_sparc_AddCC_t_res:
721
		return be_new_Proj(new_pred, pn_sparc_AddCC_res);
722
	case pn_sparc_AddCC_t_flags:
723
		return be_new_Proj(new_pred, pn_sparc_AddCC_flags);
724
	default:
725
		panic("invalid proj found");
726
727
728
729
730
731
732
733
734
	}
}

static ir_node *gen_AddX_t(ir_node *node)
{
	return gen_helper_binopx(node, MATCH_COMMUTATIVE | MATCH_MODE_NEUTRAL,
	                         new_bd_sparc_AddX_reg, new_bd_sparc_AddX_imm);
}

Hannes Rapp's avatar
Hannes Rapp committed
735
736
737
738
739
740
741
742
/**
 * Creates an sparc Sub.
 *
 * @param node       FIRM node
 * @return the created sparc Sub node
 */
static ir_node *gen_Sub(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
743
	ir_mode *mode = get_irn_mode(node);
744
	if (mode_is_float(mode)) {
745
746
		return gen_helper_binfpop(node, mode, new_bd_sparc_fsub_s,
		                          new_bd_sparc_fsub_d, new_bd_sparc_fsub_q);
747
	}
Hannes Rapp's avatar
Hannes Rapp committed
748

Matthias Braun's avatar
Matthias Braun committed
749
750
	return gen_helper_binop(node, MATCH_MODE_NEUTRAL,
	                        new_bd_sparc_Sub_reg, new_bd_sparc_Sub_imm);
Hannes Rapp's avatar
Hannes Rapp committed
751
752
}

753
754
static ir_node *gen_SubCC_t(ir_node *node)
{
yb9976's avatar
yb9976 committed
755
756
757
	ir_node *left     = get_irn_n(node, n_sparc_SubCC_t_left);
	ir_node *right    = get_irn_n(node, n_sparc_SubCC_t_right);
	ir_node *new_node = gen_helper_binop_args(node, left, right, MATCH_MODE_NEUTRAL,
758
	                             new_bd_sparc_SubCC_reg, new_bd_sparc_SubCC_imm);
759
	arch_set_irn_register_out(new_node, pn_sparc_SubCC_flags, &sparc_registers[REG_PSR]);
yb9976's avatar
yb9976 committed
760
761

	return new_node;
762
763
764
765
}

static ir_node *gen_Proj_SubCC_t(ir_node *node)
{
766
	unsigned pn       = get_Proj_num(node);
767
768
769
770
771
	ir_node *pred     = get_Proj_pred(node);
	ir_node *new_pred = be_transform_node(pred);

	switch (pn) {
	case pn_sparc_SubCC_t_res:
772
		return be_new_Proj(new_pred, pn_sparc_SubCC_res);
773
	case pn_sparc_SubCC_t_flags:
774
		return be_new_Proj(new_pred, pn_sparc_SubCC_flags);
775
	default:
776
		panic("invalid proj found");
777
778
779
780
781
782
783
784
785
	}
}

static ir_node *gen_SubX_t(ir_node *node)
{
	return gen_helper_binopx(node, MATCH_MODE_NEUTRAL,
	                         new_bd_sparc_SubX_reg, new_bd_sparc_SubX_imm);
}

786
787
788
ir_node *create_ldf(dbg_info *dbgi, ir_node *block, ir_node *ptr,
                    ir_node *mem, ir_mode *mode, ir_entity *entity,
                    long offset, bool is_frame_entity)
789
790
791
792
793
{
	unsigned bits = get_mode_size_bits(mode);
	assert(mode_is_float(mode));
	if (bits == 32) {
		return new_bd_sparc_Ldf_s(dbgi, block, ptr, mem, mode, entity,
794
		                          offset, is_frame_entity);
795
796
	} else if (bits == 64) {
		return new_bd_sparc_Ldf_d(dbgi, block, ptr, mem, mode, entity,
797
		                          offset, is_frame_entity);
798
799
800
	} else {
		assert(bits == 128);
		return new_bd_sparc_Ldf_q(dbgi, block, ptr, mem, mode, entity,
801
		                          offset, is_frame_entity);
802
803
804
	}
}

805
806
807
808
ir_node *create_stf(dbg_info *dbgi, ir_node *block, ir_node *value,
                    ir_node *ptr, ir_node *mem, ir_mode *mode,
                    ir_entity *entity, long offset,
                    bool is_frame_entity)
809
810
811
812
{
	unsigned bits = get_mode_size_bits(mode);
	assert(mode_is_float(mode));
	if (bits == 32) {
813
		return new_bd_sparc_Stf_s(dbgi, block, value, ptr, mem, mode, entity,
814
		                          offset, is_frame_entity);
815
	} else if (bits == 64) {
816
		return new_bd_sparc_Stf_d(dbgi, block, value, ptr, mem, mode, entity,
817
		                          offset, is_frame_entity);
818
819
	} else {
		assert(bits == 128);
820
		return new_bd_sparc_Stf_q(dbgi, block, value, ptr, mem, mode, entity,
821
		                          offset, is_frame_entity);
822
823
824
	}
}

Hannes Rapp's avatar
Hannes Rapp committed
825
826
827
828
829
830
831
832
/**
 * Transforms a Load.
 *
 * @param node    the ir Load node
 * @return the created sparc Load node
 */
static ir_node *gen_Load(ir_node *node)
{
833
	dbg_info *dbgi     = get_irn_dbg_info(node);
Hannes Rapp's avatar
Hannes Rapp committed
834
	ir_mode  *mode     = get_Load_mode(node);
835
	ir_node  *block    = be_transform_nodes_block(node);
Hannes Rapp's avatar
Hannes Rapp committed
836
837
838
	ir_node  *ptr      = get_Load_ptr(node);
	ir_node  *mem      = get_Load_mem(node);
	ir_node  *new_mem  = be_transform_node(mem);
839

840
	if (get_Load_unaligned(node) == align_non_aligned) {
841
		panic("transformation of unaligned Loads not implemented yet");
842
843
	}

Matthias Braun's avatar
Matthias Braun committed
844
	ir_node  *new_load;
845
	if (mode_is_float(mode)) {
Matthias Braun's avatar
Matthias Braun committed
846
		address_t address;
847
848
		match_address(ptr, &address, false);
		new_load = create_ldf(dbgi, block, address.ptr, new_mem, mode,
849
		                      address.entity, address.offset, false);
850
	} else {
Matthias Braun's avatar
Matthias Braun committed
851
		address_t address;
852
853
854
855
856
857
858
859
860
861
		match_address(ptr, &address, true);
		if (address.ptr2 != NULL) {
			assert(address.entity == NULL && address.offset == 0);
			new_load = new_bd_sparc_Ld_reg(dbgi, block, address.ptr,
			                               address.ptr2, new_mem, mode);
		} else {
			new_load = new_bd_sparc_Ld_imm(dbgi, block, address.ptr, new_mem,
			                               mode, address.entity, address.offset,
			                               false);
		}
862
	}
Hannes Rapp's avatar
Hannes Rapp committed
863
864
	set_irn_pinned(new_load, get_irn_pinned(node));

Hannes Rapp's avatar
Hannes Rapp committed
865
866
867
868
869
870
871
872
873
874
875
	return new_load;
}

/**
 * Transforms a Store.
 *
 * @param node    the ir Store node
 * @return the created sparc Store node
 */
static ir_node *gen_Store(ir_node *node)
{
876
	ir_node  *block    = be_transform_nodes_block(node);
Hannes Rapp's avatar
Hannes Rapp committed
877
878
879
880
881
882
	ir_node  *ptr      = get_Store_ptr(node);
	ir_node  *mem      = get_Store_mem(node);
	ir_node  *new_mem  = be_transform_node(mem);
	ir_node  *val      = get_Store_value(node);
	ir_mode  *mode     = get_irn_mode(val);
	dbg_info *dbgi     = get_irn_dbg_info(node);
883

884
	if (get_Store_unaligned(node) == align_non_aligned) {
885
		panic("transformation of unaligned Stores not implemented yet");
886
887
	}

Matthias Braun's avatar
Matthias Braun committed
888
	ir_node  *new_store;
889
	if (mode_is_float(mode)) {
890
		ir_node *new_val = be_transform_node(val);
891
		/* TODO: variants with reg+reg address mode */
Matthias Braun's avatar
Matthias Braun committed
892
		address_t address;
893
894
		match_address(ptr, &address, false);
		new_store = create_stf(dbgi, block, new_val, address.ptr, new_mem,
895
		                       mode, address.entity, address.offset, false);
896
	} else {
897
		val = be_skip_downconv(val, false);
Matthias Braun's avatar
Matthias Braun committed
898
		ir_node *new_val = be_transform_node(val);
899

900
		assert(get_mode_size_bits(mode) <= 32);
Matthias Braun's avatar
Matthias Braun committed
901
		address_t address;
902
903
904
905
906
907
908
909
910
911
		match_address(ptr, &address, true);
		if (address.ptr2 != NULL) {
			assert(address.entity == NULL && address.offset == 0);
			new_store = new_bd_sparc_St_reg(dbgi, block, new_val, address.ptr,
			                                address.ptr2, new_mem, mode);
		} else {
			new_store = new_bd_sparc_St_imm(dbgi, block, new_val, address.ptr,
			                                new_mem, mode, address.entity,
			                                address.offset, false);
		}
912
913
	}
	set_irn_pinned(new_store, get_irn_pinned(node));
Hannes Rapp's avatar
Hannes Rapp committed
914
915
916
917

	return new_store;
}

918
919
/**
 * Creates an sparc Mul.
920
 * returns the lower 32bits of the 64bit multiply result
921
922
923
 *
 * @return the created sparc Mul node
 */
924
925
926
static ir_node *gen_Mul(ir_node *node)
{
	ir_mode *mode = get_irn_mode(node);
Hannes Rapp's avatar
Hannes Rapp committed
927
	if (mode_is_float(mode)) {
928
929
		return gen_helper_binfpop(node, mode, new_bd_sparc_fmul_s,
		                          new_bd_sparc_fmul_d, new_bd_sparc_fmul_q);
Hannes Rapp's avatar
Hannes Rapp committed
930
	}
931

932
	return gen_helper_binop(node, MATCH_COMMUTATIVE | MATCH_MODE_NEUTRAL,
933
	                        new_bd_sparc_Mul_reg, new_bd_sparc_Mul_imm);
934
935
936
937
938
939
940
941
}

/**
 * Creates an sparc Mulh.
 * Mulh returns the upper 32bits of a mul instruction
 *
 * @return the created sparc Mulh node
 */
942
943
static ir_node *gen_Mulh(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
944
	ir_mode *mode = get_irn_mode(node);
945
946
947
	if (mode_is_float(mode))
		panic("FP not supported yet");

948
	if (mode_is_signed(mode)) {
949
		return gen_helper_binop(node, MATCH_COMMUTATIVE, new_bd_sparc_SMulh_reg, new_bd_sparc_SMulh_imm);
950
	} else {
951
		return gen_helper_binop(node, MATCH_COMMUTATIVE, new_bd_sparc_UMulh_reg, new_bd_sparc_UMulh_imm);
952
	}
953
}
Hannes Rapp's avatar
Hannes Rapp committed
954

955
956
static ir_node *gen_sign_extension_value(ir_node *node)
{
957
	ir_node *new_block = be_transform_nodes_block(node);
958
959
960
961
962
963
964
	ir_node *new_node  = be_transform_node(node);
	/* TODO: we could do some shortcuts for some value types probably.
	 * (For constants or other cases where we know the sign bit in
	 *  advance) */
	return new_bd_sparc_Sra_imm(NULL, new_block, new_node, NULL, 31);
}

965
966
967
968
969
/**
 * Creates an sparc Div.
 *
 * @return the created sparc Div node
 */
970
971
static ir_node *gen_Div(ir_node *node)
{
972
	dbg_info *dbgi      = get_irn_dbg_info(node);
973
	ir_node  *new_block = be_transform_nodes_block(node);
974
975
976
977
	ir_mode  *mode      = get_Div_resmode(node);
	ir_node  *left      = get_Div_left(node);
	ir_node  *left_low  = be_transform_node(left);
	ir_node  *right     = get_Div_right(node);
978

979
980
	if (mode_is_float(mode)) {
		return gen_helper_binfpop(node, mode, new_bd_sparc_fdiv_s,
yb9976's avatar
yb9976 committed
981
		                          new_bd_sparc_fdiv_d, new_bd_sparc_fdiv_q);
982
983
	}

984
985
	ir_node *mem     = get_Div_mem(node);
	ir_node *new_mem = be_transform_node(mem);
Matthias Braun's avatar
Matthias Braun committed
986
	ir_node *res;
987
	if (mode_is_signed(mode)) {
988
989
990
		ir_node *left_high = gen_sign_extension_value(left);

		if (is_imm_encodeable(right)) {
991
			int32_t const immediate = get_Const_long(right);
992
			res = new_bd_sparc_SDiv_imm(dbgi, new_block, new_mem, left_high, left_low,
993
994
995
			                            NULL, immediate);
		} else {
			ir_node *new_right = be_transform_node(right);
996
			res = new_bd_sparc_SDiv_reg(dbgi, new_block, new_mem, left_high, left_low,
997
998
			                            new_right);
		}
999
	} else {
1000
1001
		ir_graph *irg       = get_irn_irg(node);
		ir_node  *left_high = get_g0(irg);
1002
		if (is_imm_encodeable(right)) {
1003
			int32_t const immediate = get_Const_long(right);
1004
			res = new_bd_sparc_UDiv_imm(dbgi, new_block, new_mem, left_high, left_low,
1005
1006
1007
			                            NULL, immediate);
		} else {
			ir_node *new_right = be_transform_node(right);
1008
			res = new_bd_sparc_UDiv_reg(dbgi, new_block, new_mem, left_high, left_low,
1009
1010
			                            new_right);
		}
1011
	}
1012

1013
	return res;
1014
1015
}

1016
1017
1018
/**
 * Transforms a Not node.
 *
Michael Beck's avatar
Michael Beck committed
1019
 * @return the created sparc Not node
1020
1021
1022
 */
static ir_node *gen_Not(ir_node *node)
{
Matthias Braun's avatar
Matthias Braun committed
1023
	ir_node  *op     = get_Not_op(node);
1024
1025
	ir_graph *irg    = get_irn_irg(node);
	ir_node  *zero   = get_g0(irg);
1026
	dbg_info *dbgi   = get_irn_dbg_info(node);
1027
	ir_node  *block  = be_transform_nodes_block(node);
1028
	ir_node  *new_op = be_transform_node(op);
1029

1030
	/* Note: Not(Eor()) is normalize in firm localopts already so
Matthias Braun's avatar
Matthias Braun committed
1031
1032
1033
	 * we don't match it for xnor here */

	/* Not can be represented with xnor 0, n */
1034
	return new_bd_sparc_XNor_reg(dbgi, block, zero, new_op);
1035
1036
}