sparc_transform.c 66.8 KB
Newer Older
Hannes Rapp's avatar
Hannes Rapp committed
1
/*
2
 * Copyright (C) 1995-2010 University of Karlsruhe.  All right reserved.
Hannes Rapp's avatar
Hannes Rapp committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *
 * 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.
 */

/**
 * @file
 * @brief   code selection (transform FIRM into SPARC FIRM)
Matthias Braun's avatar
Matthias Braun committed
23
 * @author  Hannes Rapp, Matthias Braun
Michael Beck's avatar
Michael Beck committed
24
 * @version $Id$
Hannes Rapp's avatar
Hannes Rapp committed
25
26
27
 */
#include "config.h"

28
#include <stdint.h>
29
#include <stdbool.h>
30

Hannes Rapp's avatar
Hannes Rapp committed
31
32
33
34
35
36
37
#include "irnode_t.h"
#include "irgraph_t.h"
#include "irmode_t.h"
#include "irgmod.h"
#include "iredges.h"
#include "ircons.h"
#include "irprintf.h"
38
#include "iroptimize.h"
Hannes Rapp's avatar
Hannes Rapp committed
39
40
41
42
#include "dbginfo.h"
#include "iropt_t.h"
#include "debug.h"
#include "error.h"
Matthias Braun's avatar
Matthias Braun committed
43
#include "util.h"
Hannes Rapp's avatar
Hannes Rapp committed
44
45
46
47
48

#include "../benode.h"
#include "../beirg.h"
#include "../beutil.h"
#include "../betranshlp.h"
49
#include "../beabihelper.h"
Hannes Rapp's avatar
Hannes Rapp committed
50
51
52
53
54
55
56
57
#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"
58
#include "sparc_cconv.h"
Hannes Rapp's avatar
Hannes Rapp committed
59
60
61
62
63

#include <limits.h>

DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)

64
static beabi_helper_env_t    *abihelper;
65
66
static const arch_register_t *sp_reg = &sparc_registers[REG_SP];
static const arch_register_t *fp_reg = &sparc_registers[REG_FRAME_POINTER];
67
68
static calling_convention_t  *cconv  = NULL;
static ir_mode               *mode_gp;
69
static ir_mode               *mode_flags;
70
static ir_mode               *mode_fp;
71
72
static ir_mode               *mode_fp2;
//static ir_mode               *mode_fp4;
73
static pmap                  *node_to_stack;
Hannes Rapp's avatar
Hannes Rapp committed
74

75
static inline bool mode_needs_gp_reg(ir_mode *mode)
Hannes Rapp's avatar
Hannes Rapp committed
76
{
77
78
79
80
81
82
	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
83
84
}

85
86
87
/**
 * Create an And that will zero out upper bits.
 *
Michael Beck's avatar
Michael Beck committed
88
89
90
 * @param dbgi      debug info
 * @param block     the basic block
 * @param op        the original node
91
92
93
94
95
96
 * @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) {
97
		return new_bd_sparc_And_imm(dbgi, block, op, NULL, 0xFF);
98
	} else if (src_bits == 16) {
99
		ir_node *lshift = new_bd_sparc_Sll_imm(dbgi, block, op, NULL, 16);
100
		ir_node *rshift = new_bd_sparc_Srl_imm(dbgi, block, lshift, NULL, 16);
101
102
103
104
105
106
107
108
		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
109
110
111
112
113
 *
 * @param dbgi      debug info
 * @param block     the basic block
 * @param op        the original node
 * @param src_bits  number of lower bits that will remain
114
115
116
117
118
 */
static ir_node *gen_sign_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
                                   int src_bits)
{
	int shift_width = 32 - src_bits;
119
120
	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);
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
	return rshift_node;
}

/**
 * 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
138
139
140
141
142
143
144
145
/**
 * 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
 */
146
147
148
149
150
151
152
153
154
155
156
157
158
159
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);
	}
}

Hannes Rapp's avatar
Hannes Rapp committed
160
161
typedef enum {
	MATCH_NONE         = 0,
162
163
164
165
	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) */
Hannes Rapp's avatar
Hannes Rapp committed
166
} match_flags_t;
167
ENUM_BITSET(match_flags_t)
Hannes Rapp's avatar
Hannes Rapp committed
168
169

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
170
typedef ir_node* (*new_binop_fp_func) (dbg_info *dbgi, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode);
171
typedef ir_node* (*new_binop_imm_func) (dbg_info *dbgi, ir_node *block, ir_node *op1, ir_entity *entity, int32_t immediate);
172
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
173
174

/**
175
 * checks if a node's value can be encoded as a immediate
Hannes Rapp's avatar
Hannes Rapp committed
176
177
178
 */
static bool is_imm_encodeable(const ir_node *node)
{
179
	long value;
Hannes Rapp's avatar
Hannes Rapp committed
180
181
182
	if (!is_Const(node))
		return false;

183
	value = get_tarval_long(get_Const_tarval(node));
184
	return sparc_is_value_imm_encodeable(value);
Hannes Rapp's avatar
Hannes Rapp committed
185
186
}

187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
static bool needs_extension(ir_mode *mode)
{
	return get_mode_size_bits(mode) < get_mode_size_bits(mode_gp);
}

/**
 * Check, if a given node is a Down-Conv, ie. a integer Conv
 * from a mode with a mode with more bits to a mode with lesser bits.
 * Moreover, we return only true if the node has not more than 1 user.
 *
 * @param node   the node
 * @return non-zero if node is a Down-Conv
 */
static bool is_downconv(const ir_node *node)
{
	ir_mode *src_mode;
	ir_mode *dest_mode;

	if (!is_Conv(node))
		return false;

	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 *sparc_skip_downconv(ir_node *node)
{
	while (is_downconv(node)) {
		node = get_Conv_op(node);
	}
	return node;
}

Hannes Rapp's avatar
Hannes Rapp committed
224
225
226
/**
 * helper function for binop operations
 *
Michael Beck's avatar
Michael Beck committed
227
228
 * @param new_reg  register generation function ptr
 * @param new_imm  immediate generation function ptr
Hannes Rapp's avatar
Hannes Rapp committed
229
 */
Matthias Braun's avatar
Matthias Braun committed
230
231
232
233
234
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
235
{
236
237
	dbg_info *dbgi  = get_irn_dbg_info(node);
	ir_node  *block = be_transform_node(get_nodes_block(node));
Hannes Rapp's avatar
Hannes Rapp committed
238
239
	ir_node  *new_op1;
	ir_node  *new_op2;
240
241
242
243
244
245
246
247
248
	ir_mode  *mode1;
	ir_mode  *mode2;

	if (flags & MATCH_MODE_NEUTRAL) {
		op1 = sparc_skip_downconv(op1);
		op2 = sparc_skip_downconv(op2);
	}
	mode1 = get_irn_mode(op1);
	mode2 = get_irn_mode(op2);
249
250
251
	/* we shouldn't see 64bit code */
	assert(get_mode_size_bits(mode1) <= 32);
	assert(get_mode_size_bits(mode2) <= 32);
Hannes Rapp's avatar
Hannes Rapp committed
252
253

	if (is_imm_encodeable(op2)) {
254
255
256
257
258
		ir_node *new_op1   = be_transform_node(op1);
		int32_t  immediate = get_tarval_long(get_Const_tarval(op2));
		if (! (flags & MATCH_MODE_NEUTRAL) && needs_extension(mode1)) {
			new_op1 = gen_extension(dbgi, block, new_op1, mode1);
		}
259
		return new_imm(dbgi, block, new_op1, NULL, immediate);
Hannes Rapp's avatar
Hannes Rapp committed
260
261
	}
	new_op2 = be_transform_node(op2);
262
263
264
	if (! (flags & MATCH_MODE_NEUTRAL) && needs_extension(mode2)) {
		new_op2 = gen_extension(dbgi, block, new_op2, mode2);
	}
Hannes Rapp's avatar
Hannes Rapp committed
265
266

	if ((flags & MATCH_COMMUTATIVE) && is_imm_encodeable(op1)) {
267
268
		int32_t immediate = get_tarval_long(get_Const_tarval(op1));
		return new_imm(dbgi, block, new_op2, NULL, immediate);
Hannes Rapp's avatar
Hannes Rapp committed
269
270
	}

271
272
273
274
	new_op1 = be_transform_node(op1);
	if (! (flags & MATCH_MODE_NEUTRAL) && needs_extension(mode1)) {
		new_op1 = gen_extension(dbgi, block, new_op1, mode1);
	}
Hannes Rapp's avatar
Hannes Rapp committed
275
276
277
	return new_reg(dbgi, block, new_op1, new_op2);
}

Matthias Braun's avatar
Matthias Braun committed
278
279
280
281
282
283
284
285
286
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
287
288
289
/**
 * helper function for FP binop operations
 */
290
static ir_node *gen_helper_binfpop(ir_node *node, ir_mode *mode,
291
292
293
                                   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
294
295
296
{
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op1     = get_binop_left(node);
297
	ir_node  *new_op1 = be_transform_node(op1);
Hannes Rapp's avatar
Hannes Rapp committed
298
	ir_node  *op2     = get_binop_right(node);
299
	ir_node  *new_op2 = be_transform_node(op2);
Hannes Rapp's avatar
Hannes Rapp committed
300
	dbg_info *dbgi    = get_irn_dbg_info(node);
301
302
303
304
305
306
307
308
309
310
311
312
313
	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
314
315
}

316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
static ir_node *gen_helper_unfpop(ir_node *node, ir_mode *mode,
                                  new_unop_fp_func new_func_single,
                                  new_unop_fp_func new_func_double,
                                  new_unop_fp_func new_func_quad)
{
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op1     = get_binop_left(node);
	ir_node  *new_op1 = be_transform_node(op1);
	dbg_info *dbgi    = get_irn_dbg_info(node);
	unsigned  bits    = get_mode_size_bits(mode);

	switch (bits) {
	case 32:
		return new_func_single(dbgi, block, new_op1, mode);
	case 64:
		return new_func_double(dbgi, block, new_op1, mode);
	case 128:
		return new_func_quad(dbgi, block, new_op1, mode);
	default:
		break;
	}
	panic("unsupported mode %+F for float op", mode);
}

340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
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);
	ir_node  *block     = be_transform_node(get_nodes_block(node));
	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);
	ir_node  *new_op1;
	ir_node  *new_op2;

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

	if (is_imm_encodeable(op2)) {
		ir_node *new_op1   = be_transform_node(op1);
		int32_t  immediate = get_tarval_long(get_Const_tarval(op2));
		return new_binopx_imm(dbgi, block, new_op1, new_flags, NULL, immediate);
	}
	new_op2 = be_transform_node(op2);
	if ((match_flags & MATCH_COMMUTATIVE) && is_imm_encodeable(op1)) {
		int32_t immediate = get_tarval_long(get_Const_tarval(op1));
		return new_binopx_imm(dbgi, block, new_op2, new_flags, NULL, immediate);
	}
	new_op1 = be_transform_node(op1);
	return new_binopx_reg(dbgi, block, new_op1, new_op2, new_flags);

}

379
380
static ir_node *get_g0(void)
{
381
	return be_prolog_get_reg_value(abihelper, &sparc_registers[REG_G0]);
382
383
}

384
typedef struct address_t {
385
386
	ir_node   *ptr;
	ir_node   *ptr2;
387
388
389
390
	ir_entity *entity;
	int32_t    offset;
} address_t;

391
392
393
394
/**
 * Match a load/store address
 */
static void match_address(ir_node *ptr, address_t *address, bool use_ptr2)
395
396
{
	ir_node   *base   = ptr;
397
	ir_node   *ptr2   = NULL;
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
	int32_t    offset = 0;
	ir_entity *entity = NULL;

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

	/* we only use the symconst if we're the only user otherwise we probably
	 * won't save anything but produce multiple sethi+or combinations with
	 * just different offsets */
	if (is_SymConst(base) && get_irn_n_edges(base) == 1) {
		dbg_info *dbgi      = get_irn_dbg_info(ptr);
		ir_node  *block     = get_nodes_block(ptr);
		ir_node  *new_block = be_transform_node(block);
		entity = get_SymConst_entity(base);
		base   = new_bd_sparc_SetHi(dbgi, new_block, entity, offset);
420
421
422
	} else if (use_ptr2 && is_Add(base) && entity == NULL && offset == 0) {
		ptr2 = be_transform_node(get_Add_right(base));
		base = be_transform_node(get_Add_left(base));
423
	} else {
424
		if (sparc_is_value_imm_encodeable(offset)) {
425
426
427
428
429
430
431
			base = be_transform_node(base);
		} else {
			base   = be_transform_node(ptr);
			offset = 0;
		}
	}

432
433
	address->ptr    = base;
	address->ptr2   = ptr2;
434
435
436
437
	address->entity = entity;
	address->offset = offset;
}

Hannes Rapp's avatar
Hannes Rapp committed
438
439
440
441
442
443
444
445
/**
 * Creates an sparc Add.
 *
 * @param node   FIRM node
 * @return the created sparc Add node
 */
static ir_node *gen_Add(ir_node *node)
{
446
447
	ir_mode *mode = get_irn_mode(node);
	ir_node *right;
Hannes Rapp's avatar
Hannes Rapp committed
448

449
	if (mode_is_float(mode)) {
450
451
		return gen_helper_binfpop(node, mode, new_bd_sparc_fadd_s,
		                          new_bd_sparc_fadd_d, new_bd_sparc_fadd_q);
452
	}
Hannes Rapp's avatar
Hannes Rapp committed
453

454
	/* special case: + 0x1000 can be represented as - 0x1000 */
455
	right = get_Add_right(node);
456
	if (is_Const(right)) {
Matthias Braun's avatar
Matthias Braun committed
457
458
459
		ir_node   *left = get_Add_left(node);
		ir_tarval *tv;
		uint32_t   val;
460
461
		/* is this simple address arithmetic? then we can let the linker do
		 * the calculation. */
462
		if (is_SymConst(left) && get_irn_n_edges(left) == 1) {
463
464
465
466
			dbg_info *dbgi  = get_irn_dbg_info(node);
			ir_node  *block = be_transform_node(get_nodes_block(node));
			address_t address;

467
468
469
470
			/* the value of use_ptr2 shouldn't matter here */
			match_address(node, &address, false);
			assert(is_sparc_SetHi(address.ptr));
			return new_bd_sparc_Or_imm(dbgi, block, address.ptr,
471
472
473
474
475
			                           address.entity, address.offset);
		}

		tv  = get_Const_tarval(right);
		val = get_tarval_long(tv);
476
477
478
479
480
		if (val == 0x1000) {
			dbg_info *dbgi   = get_irn_dbg_info(node);
			ir_node  *block  = be_transform_node(get_nodes_block(node));
			ir_node  *op     = get_Add_left(node);
			ir_node  *new_op = be_transform_node(op);
481
			return new_bd_sparc_Sub_imm(dbgi, block, new_op, NULL, -0x1000);
482
483
484
		}
	}

485
486
	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
487
488
}

489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
static ir_node *gen_AddCC_t(ir_node *node)
{
	return gen_helper_binop(node, MATCH_COMMUTATIVE | MATCH_MODE_NEUTRAL,
	                        new_bd_sparc_AddCC_reg, new_bd_sparc_AddCC_imm);
}

static ir_node *gen_Proj_AddCC_t(ir_node *node)
{
	long     pn       = get_Proj_proj(node);
	ir_node *pred     = get_Proj_pred(node);
	ir_node *new_pred = be_transform_node(pred);

	switch (pn) {
	case pn_sparc_AddCC_t_res:
		return new_r_Proj(new_pred, mode_gp, pn_sparc_AddCC_res);
	case pn_sparc_AddCC_t_flags:
		return new_r_Proj(new_pred, mode_flags, pn_sparc_AddCC_flags);
	default:
		panic("Invalid AddCC_t proj found");
	}
}

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
517
518
519
520
521
522
523
524
/**
 * 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
525
	ir_mode *mode = get_irn_mode(node);
526
527

	if (mode_is_float(mode)) {
528
529
		return gen_helper_binfpop(node, mode, new_bd_sparc_fsub_s,
		                          new_bd_sparc_fsub_d, new_bd_sparc_fsub_q);
530
	}
Hannes Rapp's avatar
Hannes Rapp committed
531

Matthias Braun's avatar
Matthias Braun committed
532
533
	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
534
535
}

536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
static ir_node *gen_SubCC_t(ir_node *node)
{
	return gen_helper_binop(node, MATCH_MODE_NEUTRAL,
	                        new_bd_sparc_SubCC_reg, new_bd_sparc_SubCC_imm);
}

static ir_node *gen_Proj_SubCC_t(ir_node *node)
{
	long     pn       = get_Proj_proj(node);
	ir_node *pred     = get_Proj_pred(node);
	ir_node *new_pred = be_transform_node(pred);

	switch (pn) {
	case pn_sparc_SubCC_t_res:
		return new_r_Proj(new_pred, mode_gp, pn_sparc_SubCC_res);
	case pn_sparc_SubCC_t_flags:
		return new_r_Proj(new_pred, mode_flags, pn_sparc_SubCC_flags);
	default:
		panic("Invalid SubCC_t proj found");
	}
}

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);
}

564
565
static ir_node *create_ldf(dbg_info *dbgi, ir_node *block, ir_node *ptr,
                           ir_node *mem, ir_mode *mode, ir_entity *entity,
566
                           long offset, bool is_frame_entity)
567
568
569
570
571
{
	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,
572
		                          offset, is_frame_entity);
573
574
	} else if (bits == 64) {
		return new_bd_sparc_Ldf_d(dbgi, block, ptr, mem, mode, entity,
575
		                          offset, is_frame_entity);
576
577
578
	} else {
		assert(bits == 128);
		return new_bd_sparc_Ldf_q(dbgi, block, ptr, mem, mode, entity,
579
		                          offset, is_frame_entity);
580
581
582
	}
}

583
584
static ir_node *create_stf(dbg_info *dbgi, ir_node *block, ir_node *value,
                           ir_node *ptr, ir_node *mem, ir_mode *mode,
585
                           ir_entity *entity, long offset,
586
587
588
589
590
                           bool is_frame_entity)
{
	unsigned bits = get_mode_size_bits(mode);
	assert(mode_is_float(mode));
	if (bits == 32) {
591
		return new_bd_sparc_Stf_s(dbgi, block, value, ptr, mem, mode, entity,
592
		                          offset, is_frame_entity);
593
	} else if (bits == 64) {
594
		return new_bd_sparc_Stf_d(dbgi, block, value, ptr, mem, mode, entity,
595
		                          offset, is_frame_entity);
596
597
	} else {
		assert(bits == 128);
598
		return new_bd_sparc_Stf_q(dbgi, block, value, ptr, mem, mode, entity,
599
		                          offset, is_frame_entity);
600
601
602
	}
}

Hannes Rapp's avatar
Hannes Rapp committed
603
604
605
606
607
608
609
610
/**
 * Transforms a Load.
 *
 * @param node    the ir Load node
 * @return the created sparc Load node
 */
static ir_node *gen_Load(ir_node *node)
{
611
	dbg_info *dbgi     = get_irn_dbg_info(node);
Hannes Rapp's avatar
Hannes Rapp committed
612
613
614
615
616
617
	ir_mode  *mode     = get_Load_mode(node);
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *ptr      = get_Load_ptr(node);
	ir_node  *mem      = get_Load_mem(node);
	ir_node  *new_mem  = be_transform_node(mem);
	ir_node  *new_load = NULL;
618
619
	address_t address;

620
621
622
623
	if (get_Load_unaligned(node) == align_non_aligned) {
		panic("sparc: transformation of unaligned Loads not implemented yet");
	}

624
	if (mode_is_float(mode)) {
625
626
		match_address(ptr, &address, false);
		new_load = create_ldf(dbgi, block, address.ptr, new_mem, mode,
627
		                      address.entity, address.offset, false);
628
	} else {
629
630
631
632
633
634
635
636
637
638
		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);
		}
639
	}
Hannes Rapp's avatar
Hannes Rapp committed
640
641
	set_irn_pinned(new_load, get_irn_pinned(node));

Hannes Rapp's avatar
Hannes Rapp committed
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
	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)
{
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	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_node  *new_val  = be_transform_node(val);
	ir_mode  *mode     = get_irn_mode(val);
	dbg_info *dbgi     = get_irn_dbg_info(node);
661
662
663
	ir_node  *new_store = NULL;
	address_t address;

664
665
666
667
	if (get_Store_unaligned(node) == align_non_aligned) {
		panic("sparc: transformation of unaligned Stores not implemented yet");
	}

668
	if (mode_is_float(mode)) {
669
670
671
		/* TODO: variants with reg+reg address mode */
		match_address(ptr, &address, false);
		new_store = create_stf(dbgi, block, new_val, address.ptr, new_mem,
672
		                       mode, address.entity, address.offset, false);
673
	} else {
674
		assert(get_mode_size_bits(mode) <= 32);
675
676
677
678
679
680
681
682
683
684
		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);
		}
685
686
	}
	set_irn_pinned(new_store, get_irn_pinned(node));
Hannes Rapp's avatar
Hannes Rapp committed
687
688
689
690

	return new_store;
}

691
692
/**
 * Creates an sparc Mul.
693
 * returns the lower 32bits of the 64bit multiply result
694
695
696
 *
 * @return the created sparc Mul node
 */
697
698
699
static ir_node *gen_Mul(ir_node *node)
{
	ir_mode *mode = get_irn_mode(node);
Hannes Rapp's avatar
Hannes Rapp committed
700
	if (mode_is_float(mode)) {
701
702
		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
703
	}
704

705
	return gen_helper_binop(node, MATCH_COMMUTATIVE | MATCH_MODE_NEUTRAL,
706
	                        new_bd_sparc_Mul_reg, new_bd_sparc_Mul_imm);
707
708
709
710
711
712
713
714
}

/**
 * Creates an sparc Mulh.
 * Mulh returns the upper 32bits of a mul instruction
 *
 * @return the created sparc Mulh node
 */
715
716
static ir_node *gen_Mulh(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
717
	ir_mode *mode = get_irn_mode(node);
718
719
720
721
722
	ir_node *mul;

	if (mode_is_float(mode))
		panic("FP not supported yet");

723
	mul = gen_helper_binop(node, MATCH_COMMUTATIVE, new_bd_sparc_Mulh_reg, new_bd_sparc_Mulh_imm);
724
	return new_r_Proj(mul, mode_gp, pn_sparc_Mulh_low);
725
}
Hannes Rapp's avatar
Hannes Rapp committed
726

727
728
729
730
731
732
733
734
735
736
737
static ir_node *gen_sign_extension_value(ir_node *node)
{
	ir_node *block     = get_nodes_block(node);
	ir_node *new_block = be_transform_node(block);
	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);
}

738
739
740
741
742
/**
 * Creates an sparc Div.
 *
 * @return the created sparc Div node
 */
743
744
static ir_node *gen_Div(ir_node *node)
{
745
746
747
748
749
750
751
752
	dbg_info *dbgi      = get_irn_dbg_info(node);
	ir_node  *block     = get_nodes_block(node);
	ir_node  *new_block = be_transform_node(block);
	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);
	ir_node  *res;
753

754
755
756
757
758
	if (mode_is_float(mode)) {
		return gen_helper_binfpop(node, mode, new_bd_sparc_fdiv_s,
								  new_bd_sparc_fdiv_d, new_bd_sparc_fdiv_q);
	}

759
	if (mode_is_signed(mode)) {
760
761
762
763
764
765
766
767
768
769
770
		ir_node *left_high = gen_sign_extension_value(left);

		if (is_imm_encodeable(right)) {
			int32_t immediate = get_tarval_long(get_Const_tarval(right));
			res = new_bd_sparc_SDiv_imm(dbgi, new_block, left_high, left_low,
			                            NULL, immediate);
		} else {
			ir_node *new_right = be_transform_node(right);
			res = new_bd_sparc_SDiv_reg(dbgi, new_block, left_high, left_low,
			                            new_right);
		}
771
	} else {
772
773
774
775
776
777
778
779
780
781
		ir_node *left_high = get_g0();
		if (is_imm_encodeable(right)) {
			int32_t immediate = get_tarval_long(get_Const_tarval(right));
			res = new_bd_sparc_UDiv_imm(dbgi, new_block, left_high, left_low,
			                            NULL, immediate);
		} else {
			ir_node *new_right = be_transform_node(right);
			res = new_bd_sparc_UDiv_reg(dbgi, new_block, left_high, left_low,
			                            new_right);
		}
782
	}
783

784
	return res;
785
786
}

787
#if 0
788
789
790
static ir_node *gen_Abs(ir_node *node)
{
	ir_mode *const mode = get_irn_mode(node);
791

792
	if (mode_is_float(mode)) {
793
794
		return gen_helper_unfpop(node, mode, new_bd_sparc_fabs_s,
		                         new_bd_sparc_fabs_d, new_bd_sparc_fabs_q);
795
796
797
798
799
	} else {
		ir_node  *const block  = be_transform_node(get_nodes_block(node));
		dbg_info *const dbgi   = get_irn_dbg_info(node);
		ir_node  *const op     = get_Abs_op(node);
		ir_node  *const new_op = be_transform_node(op);
800
		ir_node  *const sra    = new_bd_sparc_Sra_imm(dbgi, block, new_op, NULL, 31);
801
802
803
		ir_node  *const xor    = new_bd_sparc_Xor_reg(dbgi, block, new_op, sra);
		ir_node  *const sub    = new_bd_sparc_Sub_reg(dbgi, block, xor,    sra);
		return sub;
804
	}
805
}
806
#endif
807
808
809
810

/**
 * Transforms a Not node.
 *
Michael Beck's avatar
Michael Beck committed
811
 * @return the created sparc Not node
812
813
814
 */
static ir_node *gen_Not(ir_node *node)
{
Matthias Braun's avatar
Matthias Braun committed
815
816
	ir_node  *op     = get_Not_op(node);
	ir_node  *zero   = get_g0();
817
818
819
	dbg_info *dbgi   = get_irn_dbg_info(node);
	ir_node  *block  = be_transform_node(get_nodes_block(node));
	ir_node  *new_op = be_transform_node(op);
820

821
	/* Note: Not(Eor()) is normalize in firm localopts already so
Matthias Braun's avatar
Matthias Braun committed
822
823
824
	 * we don't match it for xnor here */

	/* Not can be represented with xnor 0, n */
825
	return new_bd_sparc_XNor_reg(dbgi, block, zero, new_op);
826
827
}

828
829
830
831
832
static ir_node *gen_helper_bitop(ir_node *node,
                                 new_binop_reg_func new_reg,
                                 new_binop_imm_func new_imm,
                                 new_binop_reg_func new_not_reg,
                                 new_binop_imm_func new_not_imm)
833
{
834
835
836
	ir_node *op1 = get_binop_left(node);
	ir_node *op2 = get_binop_right(node);
	if (is_Not(op1)) {
Matthias Braun's avatar
Matthias Braun committed
837
		return gen_helper_binop_args(node, op2, get_Not_op(op1),
838
839
		                             MATCH_MODE_NEUTRAL,
		                             new_not_reg, new_not_imm);
840
	}
841
842
843
844
	if (is_Not(op2)) {
		return gen_helper_binop_args(node, op1, get_Not_op(op2),
		                             MATCH_MODE_NEUTRAL,
		                             new_not_reg, new_not_imm);
845
	}
846
847
848
849
	return gen_helper_binop_args(node, op1, op2,
								 MATCH_MODE_NEUTRAL | MATCH_COMMUTATIVE,
								 new_reg, new_imm);
}
850

851
852
853
854
855
856
857
static ir_node *gen_And(ir_node *node)
{
	return gen_helper_bitop(node,
	                        new_bd_sparc_And_reg,
	                        new_bd_sparc_And_imm,
	                        new_bd_sparc_AndN_reg,
	                        new_bd_sparc_AndN_imm);
858
859
860
861
}

static ir_node *gen_Or(ir_node *node)
{
862
863
864
865
866
	return gen_helper_bitop(node,
	                        new_bd_sparc_Or_reg,
	                        new_bd_sparc_Or_imm,
	                        new_bd_sparc_OrN_reg,
	                        new_bd_sparc_OrN_imm);
867
868
}

869
static ir_node *gen_Eor(ir_node *node)
Hannes Rapp's avatar
Hannes Rapp committed
870
{
871
872
873
874
875
	return gen_helper_bitop(node,
	                        new_bd_sparc_Xor_reg,
	                        new_bd_sparc_Xor_imm,
	                        new_bd_sparc_XNor_reg,
	                        new_bd_sparc_XNor_imm);
Hannes Rapp's avatar
Hannes Rapp committed
876
877
}

878
879
static ir_node *gen_Shl(ir_node *node)
{
880
	return gen_helper_binop(node, MATCH_NONE, new_bd_sparc_Sll_reg, new_bd_sparc_Sll_imm);
881
882
883
884
}

static ir_node *gen_Shr(ir_node *node)
{
885
	return gen_helper_binop(node, MATCH_NONE, new_bd_sparc_Srl_reg, new_bd_sparc_Srl_imm);
886
}
Hannes Rapp's avatar
Hannes Rapp committed
887

888
static ir_node *gen_Shrs(ir_node *node)
889
{
890
	return gen_helper_binop(node, MATCH_NONE, new_bd_sparc_Sra_reg, new_bd_sparc_Sra_imm);
891
892
}

893
894
895
896
897
/**
 * Transforms a Minus node.
 */
static ir_node *gen_Minus(ir_node *node)
{
898
899
900
901
902
903
	ir_mode  *mode = get_irn_mode(node);
	ir_node  *op;
	ir_node  *block;
	ir_node  *new_op;
	ir_node  *zero;
	dbg_info *dbgi;
904
905

	if (mode_is_float(mode)) {
906
907
		return gen_helper_unfpop(node, mode, new_bd_sparc_fneg_s,
		                         new_bd_sparc_fneg_d, new_bd_sparc_fneg_q);
908
	}
909
910
911
912
913
914
	block  = be_transform_node(get_nodes_block(node));
	dbgi   = get_irn_dbg_info(node);
	op     = get_Minus_op(node);
	new_op = be_transform_node(op);
	zero   = get_g0();
	return new_bd_sparc_Sub_reg(dbgi, block, zero, new_op);
915
916
}

917
/**
Michael Beck's avatar
Michael Beck committed
918
 * Create an entity for a given (floating point) tarval
919
 */
Matthias Braun's avatar
Matthias Braun committed
920
static ir_entity *create_float_const_entity(ir_tarval *tv)
921
{
922
923
924
	const arch_env_t *arch_env = be_get_irg_arch_env(current_ir_graph);
	sparc_isa_t      *isa      = (sparc_isa_t*) arch_env;
	ir_entity        *entity   = (ir_entity*) pmap_get(isa->constants, tv);
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
	ir_initializer_t *initializer;
	ir_mode          *mode;
	ir_type          *type;
	ir_type          *glob;

	if (entity != NULL)
		return entity;

	mode   = get_tarval_mode(tv);
	type   = get_type_for_mode(mode);
	glob   = get_glob_type();
	entity = new_entity(glob, id_unique("C%u"), type);
	set_entity_visibility(entity, ir_visibility_private);
	add_entity_linkage(entity, IR_LINKAGE_CONSTANT);

	initializer = create_initializer_tarval(tv);
	set_entity_initializer(entity, initializer);

943
	pmap_insert(isa->constants, tv, entity);
944
945
946
	return entity;
}

947
948
949
950
static ir_node *gen_float_const(dbg_info *dbgi, ir_node *block, ir_tarval *tv)
{
	ir_entity *entity = create_float_const_entity(tv);
	ir_node   *hi     = new_bd_sparc_SetHi(dbgi, block, entity, 0);
951
	ir_node   *mem    = get_irg_no_mem(current_ir_graph);
952
953
954
	ir_mode   *mode   = get_tarval_mode(tv);
	ir_node   *new_op
		= create_ldf(dbgi, block, hi, mem, mode, entity, 0, false);
955
	ir_node   *proj   = new_r_Proj(new_op, mode, pn_sparc_Ldf_res);
956
957
958
959
960

	set_irn_pinned(new_op, op_pin_state_floats);
	return proj;
}

961
962
static ir_node *gen_Const(ir_node *node)
{
Matthias Braun's avatar
Matthias Braun committed
963
964
965
	ir_node   *block = be_transform_node(get_nodes_block(node));
	ir_mode   *mode  = get_irn_mode(node);
	dbg_info  *dbgi  = get_irn_dbg_info(node);
966
	ir_tarval *tv    = get_Const_tarval(node);
Matthias Braun's avatar
Matthias Braun committed
967
	long       value;
Hannes Rapp's avatar
Hannes Rapp committed
968
969

	if (mode_is_float(mode)) {
970
		return gen_float_const(dbgi, block, tv);
Hannes Rapp's avatar
Hannes Rapp committed
971
	}
Hannes Rapp's avatar
Hannes Rapp committed
972

973
974
	value = get_tarval_long(tv);
	if (value == 0) {
975
		return get_g0();
976
	} else if (sparc_is_value_imm_encodeable(value)) {
977
		return new_bd_sparc_Or_imm(dbgi, block, get_g0(), NULL, value);
978
	} else {
979
		ir_node *hi = new_bd_sparc_SetHi(dbgi, block, NULL, value);
980
		if ((value & 0x3ff) != 0) {
981
			return new_bd_sparc_Or_imm(dbgi, block, hi, NULL, value & 0x3ff);
982
983
984
		} else {
			return hi;
		}
985
	}
Hannes Rapp's avatar
Hannes Rapp committed
986
987
}

988
static ir_mode *get_cmp_mode(ir_node *b_value)
989
990
991
{
	ir_node *op;

992
	if (!is_Cmp(b_value))
993
		panic("can't determine cond signednes (no cmp)");
994
	op = get_Cmp_left(b_value);
995
	return get_irn_mode(op);
996
997
}

998
999
1000
1001
1002
static ir_node *make_address(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_Or_imm(dbgi, block, hi, entity, offset);
1003
1004
1005

	if (get_entity_owner(entity) == get_tls_type())
		panic("thread local storage not supported yet in sparc backend");
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
	return low;
}

static ir_node *gen_SwitchJmp(ir_node *node)
{
	dbg_info        *dbgi         = get_irn_dbg_info(node);
	ir_node         *block        = be_transform_node(get_nodes_block(node));
	ir_node         *selector     = get_Cond_selector(node);
	ir_node         *new_selector = be_transform_node(selector);
	long             default_pn   = get_Cond_default_proj(node);
	ir_entity       *entity;
	ir_node         *table_address;
	ir_node         *index;
	ir_node         *load;
	ir_node         *address;

	/* switch with smaller mode not implemented yet */
	assert(get_mode_size_bits(get_irn_mode(selector)) == 32);

	entity = new_entity(NULL, id_unique("TBL%u"), get_unknown_type());
	set_entity_visibility(entity, ir_visibility_private);
	add_entity_linkage(entity, IR_LINKAGE_CONSTANT);

	/* TODO: this code does not construct code to check for access
	 * out-of bounds of the jumptable yet. I think we should put this stuff
	 * into the switch_lowering phase to get some additional optimisations
	 * done. */

	/* construct base address */
1035
	table_address = make_address(dbgi, block, entity, 0);
1036
1037
1038
	/* scale index */
	index = new_bd_sparc_Sll_imm(dbgi, block, new_selector, NULL, 2);
	/* load from jumptable */
1039
	load = new_bd_sparc_Ld_reg(dbgi, block, table_address, index,
1040
	                           get_irg_no_mem(current_ir_graph),
1041
1042
1043
1044
1045
1046
	                           mode_gp);
	address = new_r_Proj(load, mode_gp, pn_sparc_Ld_res);

	return new_bd_sparc_SwitchJmp(dbgi, block, address, default_pn, entity);
}

Hannes Rapp's avatar
Hannes Rapp committed
1047
1048
static ir_node *gen_Cond(ir_node *node)
{
1049
1050
1051
1052
1053
1054
1055
1056
	ir_node    *selector = get_Cond_selector(node);
	ir_mode    *mode     = get_irn_mode(selector);
	ir_mode    *cmp_mode;
	ir_node    *block;
	ir_node    *flag_node;
	bool        is_unsigned;
	ir_relation relation;
	dbg_info   *dbgi;
Hannes Rapp's avatar
Hannes Rapp committed
1057
1058
1059

	// switch/case jumps
	if (mode != mode_b) {
1060
		return gen_SwitchJmp(node);
Hannes Rapp's avatar
Hannes Rapp committed
1061
1062
1063
	}

	// regular if/else jumps
1064
	assert(is_Cmp(selector));
Hannes Rapp's avatar
Hannes Rapp committed
1065

1066
1067
	cmp_mode = get_cmp_mode(selector);

1068
1069
	block       = be_transform_node(get_nodes_block(node));
	dbgi        = get_irn_dbg_info(node);
1070
	flag_node   = be_transform_node(selector);
1071
	relation    = get_Cmp_relation(selector);
1072
1073
1074
	is_unsigned = !mode_is_signed(cmp_mode);
	if (mode_is_float(cmp_mode)) {
		assert(!is_unsigned);
1075
		return new_bd_sparc_fbfcc(dbgi, block, flag_node, relation);
1076
	} else {
1077
		return new_bd_sparc_Bicc(dbgi, block, flag_node, relation, is_unsigned);
1078
	}
Hannes Rapp's avatar
Hannes Rapp committed
1079
1080
1081
1082
1083
1084
1085
}

/**
 * transform Cmp
 */
static ir_node *gen_Cmp(ir_node *node)
{
1086
1087
1088
	ir_node *op1      = get_Cmp_left(node);
	ir_node *op2      = get_Cmp_right(node);
	ir_mode *cmp_mode = get_irn_mode(op1);
Hannes Rapp's avatar
Hannes Rapp committed
1089
1090
	assert(get_irn_mode(op2) == cmp_mode);

1091
	if (mode_is_float(cmp_mode)) {
1092
1093
1094
1095
1096
		ir_node  *block   = be_transform_node(get_nodes_block(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);
		unsigned  bits    = get_mode_size_bits(cmp_mode);
1097
1098
1099
1100
1101
1102
1103
1104
		if (bits == 32) {
			return new_bd_sparc_fcmp_s(dbgi, block, new_op1, new_op2, cmp_mode);
		} else if (bits == 64) {
			return new_bd_sparc_fcmp_d(dbgi, block, new_op1, new_op2, cmp_mode);
		} else {
			assert(bits == 128);
			return new_bd_sparc_fcmp_q(dbgi, block, new_op1, new_op2, cmp_mode);
		}
Hannes Rapp's avatar
Hannes Rapp committed
1105
1106
	}

1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
	/* when we compare a bitop like and,or,... with 0 then we can directly use
	 * the bitopcc variant.
	 * Currently we only do this when we're the only user of the node...
	 */
	if (is_Const(op2) && is_Const_null(op2) && get_irn_n_edges(op1) == 1) {
		if (is_And(op1)) {
			return gen_helper_bitop(op1,
			                        new_bd_sparc_AndCCZero_reg,
			                        new_bd_sparc_AndCCZero_imm,
			                        new_bd_sparc_AndNCCZero_reg,
			                        new_bd_sparc_AndNCCZero_imm);
		} else if (is_Or(op1)) {
			return gen_helper_bitop(op1,
			                        new_bd_sparc_OrCCZero_reg,
			                        new_bd_sparc_OrCCZero_imm,
			                        new_bd_sparc_OrNCCZero_reg,
			                        new_bd_sparc_OrNCCZero_imm);
		} else if (is_Eor(op1)) {
			return gen_helper_bitop(op1,
			                        new_bd_sparc_XorCCZero_reg,
			                        new_bd_sparc_XorCCZero_imm,
			                        new_bd_sparc_XNorCCZero_reg,
			                        new_bd_sparc_XNorCCZero_imm);
		}
	}

Hannes Rapp's avatar
Hannes Rapp committed
1133
	/* integer compare */
1134
1135
	return gen_helper_binop_args(node, op1, op2, MATCH_NONE,
	                             new_bd_sparc_Cmp_reg, new_bd_sparc_Cmp_imm);
Hannes Rapp's avatar
Hannes Rapp committed
1136
1137
1138
1139
1140
1141
1142
}

/**
 * Transforms a SymConst node.
 */
static ir_node *gen_SymConst(ir_node *node)
{
1143
1144
1145
1146
	ir_entity *entity    = get_SymConst_entity(node);
	dbg_info  *dbgi      = get_irn_dbg_info(node);
	ir_node   *block     = get_nodes_block(node);
	ir_node   *new_block = be_transform_node(block);
1147
	return make_address(dbgi, new_block, entity, 0);
Hannes Rapp's avatar
Hannes Rapp committed
1148
1149
}

1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
static ir_node *create_fftof(dbg_info *dbgi, ir_node *block, ir_node *op,
                             ir_mode *src_mode, ir_mode *dst_mode)
{
	unsigned src_bits = get_mode_size_bits(src_mode);
	unsigned dst_bits = get_mode_size_bits(dst_mode);
	if (src_bits == 32) {
		if (dst_bits == 64) {
			return new_bd_sparc_fftof_s_d(dbgi, block, op, src_mode, dst_mode);
		} else {
			assert(dst_bits == 128);
			return new_bd_sparc_fftof_s_q(dbgi, block, op, src_mode, dst_mode);
		}
	} else if (src_bits == 64) {
		if (dst_bits == 32) {
			return new_bd_sparc_fftof_d_s(dbgi, block, op, src_mode, dst_mode);
		} else {
			assert(dst_bits == 128);
			return new_bd_sparc_fftof_d_q(dbgi, block, op, src_mode, dst_mode);
		}
	} else {
		assert(src_bits == 128);
		if (dst_bits == 32) {
			return new_bd_sparc_fftof_q_s(dbgi, block, op, src_mode, dst_mode);
		} else {
			assert(dst_bits == 64);
			return new_bd_sparc_fftof_q_d(dbgi, block, op, src_mode, dst_mode);
		}
	}
}

static ir_node *create_ftoi(dbg_info *dbgi, ir_node *block, ir_node *op,
                            ir_mode *src_mode)
{
1183
1184
	ir_node  *ftoi;
	unsigned  bits = get_mode_size_bits(src_mode);
1185
	if (bits == 32) {
1186
		ftoi = new_bd_sparc_fftoi_s(dbgi, block, op, src_mode);
1187
	} else if (bits == 64) {
1188
		ftoi = new_bd_sparc_fftoi_d(dbgi, block, op, src_mode);
1189
1190
	} else {
		assert(bits == 128);
1191
1192
1193
1194
1195
1196
		ftoi = new_bd_sparc_fftoi_q(dbgi, block, op, src_mode);
	}

	{
	ir_graph *irg   = get_irn_irg(block);
	ir_node  *sp    = get_irg_frame(irg);
1197
	ir_node  *nomem = get_irg_no_mem(irg);
1198
1199
1200
1201
1202
1203
1204
1205
	ir_node  *stf   = create_stf(dbgi, block, ftoi, sp, nomem, src_mode,
	                             NULL, 0, true);
	ir_node  *ld    = new_bd_sparc_Ld_imm(dbgi, block, sp, stf, mode_gp,
	                                      NULL, 0, true);
	ir_node  *res   = new_r_Proj(ld, mode_gp, pn_sparc_Ld_res);
	set_irn_pinned(stf, op_pin_state_floats);
	set_irn_pinned(ld, op_pin_state_floats);
	return res;
1206
1207
1208
1209
1210
1211
	}
}

static ir_node *create_itof(dbg_info *dbgi, ir_node *block, ir_node *op,
                            ir_mode *dst_mode)
{
1212
1213
	ir_graph *irg   = get_irn_irg(block);
	ir_node  *sp    = get_irg_frame(irg);
1214
	ir_node  *nomem = get_irg_no_mem(irg);
1215
1216
1217
1218
1219
1220
1221
1222
1223
	ir_node  *st    = new_bd_sparc_St_imm(dbgi, block, op, sp, nomem,
	                                      mode_gp, NULL, 0, true);
	ir_node  *ldf   = new_bd_sparc_Ldf_s(dbgi, block, sp, st, mode_fp,
	                                     NULL, 0, true);
	ir_node  *res   = new_r_Proj(ldf, mode_fp, pn_sparc_Ldf_res);
	unsigned  bits  = get_mode_size_bits(dst_mode);
	set_irn_pinned(st, op_pin_state_floats);
	set_irn_pinned(ldf, op_pin_state_floats);

1224
	if (bits == 32) {