ia32_new_nodes.c 26.6 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2011 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
/**
Christian Würdig's avatar
Christian Würdig committed
21
22
23
24
 * @file
 * @brief       Handling of ia32 specific firm opcodes.
 * @author      Christian Wuerdig
 *
yb9976's avatar
yb9976 committed
25
 * This file implements the creation of the architecture specific firm opcodes
Christoph Mallon's avatar
Christoph Mallon committed
26
 * and the corresponding node constructors for the ia32 assembler irg.
27
 */
28
#include "config.h"
29
30

#include <stdlib.h>
31
#include <stdbool.h>
32

33
#include "irargs_t.h"
34
35
36
37
38
39
#include "irprog_t.h"
#include "irgraph_t.h"
#include "irnode_t.h"
#include "irmode_t.h"
#include "ircons_t.h"
#include "iropt_t.h"
Christian Würdig's avatar
Christian Würdig committed
40
#include "irop.h"
41
#include "irverify_t.h"
42
#include "irprintf.h"
43
#include "iredges.h"
44
#include "error.h"
Matthias Braun's avatar
Matthias Braun committed
45
#include "raw_bitset.h"
46
#include "xmalloc.h"
47

48
49
#include "bearch.h"
#include "beinfo.h"
50

51
#include "bearch_ia32_t.h"
52
#include "ia32_common_transform.h"
53
54
#include "ia32_nodes_attr.h"
#include "ia32_new_nodes.h"
Christian Würdig's avatar
Christian Würdig committed
55
#include "gen_ia32_regalloc_if.h"
56

Matthias Braun's avatar
Matthias Braun committed
57
58
struct obstack opcodes_obst;

59
60
61
62
63
64
65
/**
 * Dumper interface for dumping ia32 nodes in vcg.
 * @param n        the node to dump
 * @param F        the output file
 * @param reason   indicates which kind of information should be dumped
 * @return 0 on success or != 0 on failure
 */
66
static void ia32_dump_node(FILE *F, const ir_node *n, dump_reason_t reason)
67
{
68
	ir_mode *mode = NULL;
Christian Würdig's avatar
Christian Würdig committed
69
70
71

	switch (reason) {
		case dump_node_opcode_txt:
72
			fprintf(F, "%s", get_irn_opname(n));
73

74
			if (is_ia32_Immediate(n) || is_ia32_Const(n)) {
75
76
77
78
				const ia32_immediate_attr_t *attr
					= get_ia32_immediate_attr_const(n);

				fputc(' ', F);
79
80
				if (attr->symconst) {
					if (attr->sc_sign) {
81
82
83
84
						fputc('-', F);
					}
					fputs(get_entity_name(attr->symconst), F);
				}
85
86
				if (attr->offset != 0 || attr->symconst == NULL) {
					if (attr->offset > 0 && attr->symconst != NULL) {
87
88
89
						fputc('+', F);
					}
					fprintf(F, "%ld", attr->offset);
90
91
92
					if (attr->no_pic_adjust) {
						fputs("(no_pic_adjust)", F);
					}
93
				}
Christian Würdig's avatar
Christian Würdig committed
94
			}
Michael Beck's avatar
Michael Beck committed
95
			else {
96
97
				const ia32_attr_t *attr = get_ia32_attr_const(n);

98
				if (attr->am_sc != NULL || attr->am_offs != 0)
99
100
					fputs(" [", F);

101
102
				if (attr->am_sc != NULL) {
					if (attr->data.am_sc_sign) {
103
104
105
						fputc('-', F);
					}
					fputs(get_entity_name(attr->am_sc), F);
106
					if (attr->data.am_sc_no_pic_adjust) {
107
108
						fputs("(no_pic_adjust)", F);
					}
109
				}
110
111
				if (attr->am_offs != 0) {
					if (attr->am_offs > 0 && attr->am_sc != NULL) {
112
113
114
115
116
						fputc('+', F);
					}
					fprintf(F, "%d", attr->am_offs);
				}

117
				if (attr->am_sc != NULL || attr->am_offs != 0)
118
119
					fputc(']', F);
			}
Christian Würdig's avatar
Christian Würdig committed
120
121
			break;

122
		case dump_node_mode_txt:
123
124
125
			mode = get_ia32_ls_mode(n);
			if (mode != NULL)
				fprintf(F, "[%s]", get_mode_name(mode));
126
			break;
Christian Würdig's avatar
Christian Würdig committed
127

128
		case dump_node_nodeattr_txt:
129
			if (! is_ia32_Lea(n)) {
130
131
132
133
				switch (get_ia32_op_type(n)) {
				case ia32_Normal:    break;
				case ia32_AddrModeS: fprintf(F, "[AM S] "); break;
				case ia32_AddrModeD: fprintf(F, "[AM D] "); break;
134
				}
Christian Würdig's avatar
Christian Würdig committed
135
136
137
138
			}
			break;

		case dump_node_info_txt:
139
			arch_dump_reqs_and_registers(F, n);
140
141
142

			/* dump op type */
			fprintf(F, "op = ");
143
			switch (get_ia32_op_type(n)) {
144
145
146
147
148
149
150
151
152
				case ia32_Normal:
					fprintf(F, "Normal");
					break;
				case ia32_AddrModeD:
					fprintf(F, "AM Dest (Load+Store)");
					break;
				case ia32_AddrModeS:
					fprintf(F, "AM Source (Load)");
					break;
Christian Würdig's avatar
Christian Würdig committed
153
				default:
Matthias Braun's avatar
Matthias Braun committed
154
					fprintf(F, "unknown (%d)", (int)get_ia32_op_type(n));
Christian Würdig's avatar
Christian Würdig committed
155
					break;
156
157
158
159
160
			}
			fprintf(F, "\n");

			/* dump supported am */
			fprintf(F, "AM support = ");
161
			switch (get_ia32_am_support(n)) {
162
163
164
165
				case ia32_am_none:   fputs("none\n",            F); break;
				case ia32_am_unary:  fputs("source (unary)\n",  F); break;
				case ia32_am_binary: fputs("source (binary)\n", F); break;

Christian Würdig's avatar
Christian Würdig committed
166
				default:
Matthias Braun's avatar
Matthias Braun committed
167
					fprintf(F, "unknown (%d)\n", (int)get_ia32_am_support(n));
Christian Würdig's avatar
Christian Würdig committed
168
					break;
169
			}
Christian Würdig's avatar
Christian Würdig committed
170

171
			/* dump AM offset */
172
			if (get_ia32_am_offs_int(n) != 0) {
173
				fprintf(F, "AM offset = %d\n", get_ia32_am_offs_int(n));
174
			}
Christian Würdig's avatar
Christian Würdig committed
175

Matthias Braun's avatar
Matthias Braun committed
176
			/* dump AM symconst */
177
			if (get_ia32_am_sc(n) != NULL) {
178
179
180
				ir_entity *ent = get_ia32_am_sc(n);
				ident *id = get_entity_ld_ident(ent);
				fprintf(F, "AM symconst = %s\n", get_id_str(id));
Matthias Braun's avatar
Matthias Braun committed
181
182
			}

183
			/* dump AM scale */
184
			fprintf(F, "AM scale = %u\n", get_ia32_am_scale(n));
Christian Würdig's avatar
Christian Würdig committed
185

186
			/* dump pn code */
Matthias Braun's avatar
Matthias Braun committed
187
			if (is_ia32_CMovcc(n) || is_ia32_Setcc(n) || is_ia32_Jcc(n)) {
188
				const ia32_attr_t *attr = get_ia32_attr_const(n);
Matthias Braun's avatar
Matthias Braun committed
189
				fprintf(F, "condition_code = 0x%X\n", (unsigned)get_ia32_condcode(n));
190
				fprintf(F, "ins_permuted = %u\n", (unsigned)attr->data.ins_permuted);
Michael Beck's avatar
Michael Beck committed
191
192
			}
			else if (is_ia32_CopyB(n) || is_ia32_CopyB_i(n)) {
Michael Beck's avatar
Michael Beck committed
193
				fprintf(F, "size = %u\n", get_ia32_copyb_size(n));
194
			}
Christian Würdig's avatar
Christian Würdig committed
195

Michael Beck's avatar
Michael Beck committed
196
197
			fprintf(F, "use_frame = %d\n",     is_ia32_use_frame(n));
			fprintf(F, "commutative = %d\n",   is_ia32_commutative(n));
198
			fprintf(F, "need stackent = %d\n", is_ia32_need_stackent(n));
Michael Beck's avatar
Michael Beck committed
199
			fprintf(F, "is reload = %d\n",     is_ia32_is_reload(n));
200
			fprintf(F, "latency = %u\n",       get_ia32_latency(n));
Christian Würdig's avatar
Christian Würdig committed
201

202
203
204
205
206
207
208
209
210
			/* dump frame entity */
			fprintf(F, "frame entity = ");
			if (get_ia32_frame_ent(n)) {
				ir_fprintf(F, "%+F", get_ia32_frame_ent(n));
			}
			else {
				fprintf(F, "n/a");
			}
			fprintf(F, "\n");
211

212
213
214
215
216
217
218
219
220
221
			/* dump modes */
			fprintf(F, "ls_mode = ");
			if (get_ia32_ls_mode(n)) {
				ir_fprintf(F, "%+F", get_ia32_ls_mode(n));
			}
			else {
				fprintf(F, "n/a");
			}
			fprintf(F, "\n");

Christian Würdig's avatar
Christian Würdig committed
222
223
#ifndef NDEBUG
			/* dump original ir node name */
224
225
			char const *orig = get_ia32_attr_const(n)->orig_node;
			fprintf(F, "orig node = %s\n", orig ? orig : "n/a");
Christian Würdig's avatar
Christian Würdig committed
226
227
#endif /* NDEBUG */

Christian Würdig's avatar
Christian Würdig committed
228
			break;
229
	}
230
231
232
233
}



234
235
ia32_attr_t *get_ia32_attr(ir_node *node)
{
236
	assert(is_ia32_irn(node) && "need ia32 node to get ia32 attributes");
237
	return (ia32_attr_t *)get_irn_generic_attr(node);
238
239
}

240
241
const ia32_attr_t *get_ia32_attr_const(const ir_node *node)
{
242
243
244
245
	assert(is_ia32_irn(node) && "need ia32 node to get ia32 attributes");
	return (const ia32_attr_t*) get_irn_generic_attr_const(node);
}

246
247
ia32_x87_attr_t *get_ia32_x87_attr(ir_node *node)
{
248
249
250
251
252
	ia32_attr_t     *attr     = get_ia32_attr(node);
	ia32_x87_attr_t *x87_attr = CAST_IA32_ATTR(ia32_x87_attr_t, attr);
	return x87_attr;
}

253
254
const ia32_x87_attr_t *get_ia32_x87_attr_const(const ir_node *node)
{
255
256
257
258
259
	const ia32_attr_t     *attr     = get_ia32_attr_const(node);
	const ia32_x87_attr_t *x87_attr = CONST_CAST_IA32_ATTR(ia32_x87_attr_t, attr);
	return x87_attr;
}

260
261
const ia32_asm_attr_t *get_ia32_asm_attr_const(const ir_node *node)
{
262
263
264
265
266
267
	const ia32_attr_t     *attr     = get_ia32_attr_const(node);
	const ia32_asm_attr_t *asm_attr = CONST_CAST_IA32_ATTR(ia32_asm_attr_t, attr);

	return asm_attr;
}

268
269
ia32_immediate_attr_t *get_ia32_immediate_attr(ir_node *node)
{
270
271
272
273
274
275
	ia32_attr_t           *attr      = get_ia32_attr(node);
	ia32_immediate_attr_t *imm_attr  = CAST_IA32_ATTR(ia32_immediate_attr_t, attr);

	return imm_attr;
}

276
277
const ia32_immediate_attr_t *get_ia32_immediate_attr_const(const ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
278
279
	const ia32_attr_t           *attr     = get_ia32_attr_const(node);
	const ia32_immediate_attr_t *imm_attr = CONST_CAST_IA32_ATTR(ia32_immediate_attr_t, attr);
280

Michael Beck's avatar
Michael Beck committed
281
282
283
	return imm_attr;
}

284
285
ia32_condcode_attr_t *get_ia32_condcode_attr(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
286
287
288
289
290
291
	ia32_attr_t          *attr    = get_ia32_attr(node);
	ia32_condcode_attr_t *cc_attr = CAST_IA32_ATTR(ia32_condcode_attr_t, attr);

	return cc_attr;
}

292
293
const ia32_condcode_attr_t *get_ia32_condcode_attr_const(const ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
294
295
296
297
298
299
	const ia32_attr_t          *attr    = get_ia32_attr_const(node);
	const ia32_condcode_attr_t *cc_attr = CONST_CAST_IA32_ATTR(ia32_condcode_attr_t, attr);

	return cc_attr;
}

300
301
302
303
304
305
306
307
308
309
310
311
312
313
ia32_switch_attr_t *get_ia32_switch_attr(ir_node *node)
{
	ia32_attr_t        *attr        = get_ia32_attr(node);
	ia32_switch_attr_t *switch_attr = CAST_IA32_ATTR(ia32_switch_attr_t, attr);
	return switch_attr;
}

const ia32_switch_attr_t *get_ia32_switch_attr_const(const ir_node *node)
{
	const ia32_attr_t        *attr        = get_ia32_attr_const(node);
	const ia32_switch_attr_t *switch_attr = CONST_CAST_IA32_ATTR(ia32_switch_attr_t, attr);
	return switch_attr;
}

314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
ia32_call_attr_t *get_ia32_call_attr(ir_node *node)
{
	ia32_attr_t      *attr      = get_ia32_attr(node);
	ia32_call_attr_t *call_attr = CAST_IA32_ATTR(ia32_call_attr_t, attr);

	return call_attr;
}

const ia32_call_attr_t *get_ia32_call_attr_const(const ir_node *node)
{
	const ia32_attr_t      *attr      = get_ia32_attr_const(node);
	const ia32_call_attr_t *call_attr = CONST_CAST_IA32_ATTR(ia32_call_attr_t, attr);

	return call_attr;
}

330
331
ia32_copyb_attr_t *get_ia32_copyb_attr(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
332
333
334
335
336
337
	ia32_attr_t       *attr       = get_ia32_attr(node);
	ia32_copyb_attr_t *copyb_attr = CAST_IA32_ATTR(ia32_copyb_attr_t, attr);

	return copyb_attr;
}

338
339
const ia32_copyb_attr_t *get_ia32_copyb_attr_const(const ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
340
341
342
343
	const ia32_attr_t       *attr       = get_ia32_attr_const(node);
	const ia32_copyb_attr_t *copyb_attr = CONST_CAST_IA32_ATTR(ia32_copyb_attr_t, attr);

	return copyb_attr;
344
345
}

346
347
ia32_climbframe_attr_t *get_ia32_climbframe_attr(ir_node *node)
{
348
349
350
351
352
353
	ia32_attr_t            *attr            = get_ia32_attr(node);
	ia32_climbframe_attr_t *climbframe_attr = CAST_IA32_ATTR(ia32_climbframe_attr_t, attr);

	return climbframe_attr;
}

354
355
const ia32_climbframe_attr_t *get_ia32_climbframe_attr_const(const ir_node *node)
{
356
357
358
359
360
361
	const ia32_attr_t            *attr            = get_ia32_attr_const(node);
	const ia32_climbframe_attr_t *climbframe_attr = CONST_CAST_IA32_ATTR(ia32_climbframe_attr_t, attr);

	return climbframe_attr;
}

362
/**
363
 * Gets the type of an ia32 node.
364
 */
365
366
ia32_op_type_t get_ia32_op_type(const ir_node *node)
{
367
	const ia32_attr_t *attr = get_ia32_attr_const(node);
368
	return (ia32_op_type_t)attr->data.tp;
369
370
371
}

/**
372
 * Sets the type of an ia32 node.
373
 */
374
375
void set_ia32_op_type(ir_node *node, ia32_op_type_t tp)
{
376
	ia32_attr_t *attr = get_ia32_attr(node);
377
	attr->data.tp     = tp;
378
379
}

380
381
ia32_am_type_t get_ia32_am_support(const ir_node *node)
{
Matthias Braun's avatar
Matthias Braun committed
382
	const ia32_attr_t *attr = get_ia32_attr_const(node);
383
	return (ia32_am_type_t)attr->data.am_arity;
Matthias Braun's avatar
Matthias Braun committed
384
385
}

386
/**
387
 * Sets the supported address mode of an ia32 node
388
 */
389
390
391
392
void set_ia32_am_support(ir_node *node, ia32_am_type_t arity)
{
	ia32_attr_t *attr   = get_ia32_attr(node);
	attr->data.am_arity = arity;
Christian Würdig's avatar
Christian Würdig committed
393
394
}

395
/**
396
 * Gets the address mode offset as int.
397
 */
398
399
int get_ia32_am_offs_int(const ir_node *node)
{
400
	const ia32_attr_t *attr = get_ia32_attr_const(node);
401
402
403
	return attr->am_offs;
}

404
/**
405
 * Sets the address mode offset from an int.
406
 */
407
408
void set_ia32_am_offs_int(ir_node *node, int offset)
{
409
410
411
412
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->am_offs = offset;
}

413
414
void add_ia32_am_offs_int(ir_node *node, int offset)
{
415
416
417
418
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->am_offs += offset;
}

419
/**
420
 * Returns the symconst entity associated to address mode.
421
 */
422
423
ir_entity *get_ia32_am_sc(const ir_node *node)
{
424
	const ia32_attr_t *attr = get_ia32_attr_const(node);
425
426
427
428
	return attr->am_sc;
}

/**
429
 * Sets the symconst entity associated to address mode.
430
 */
431
432
void set_ia32_am_sc(ir_node *node, ir_entity *entity)
{
433
	ia32_attr_t *attr = get_ia32_attr(node);
434
	attr->am_sc       = entity;
435
436
437
438
439
}

/**
 * Sets the sign bit for address mode symconst.
 */
440
441
void set_ia32_am_sc_sign(ir_node *node)
{
442
443
444
445
446
447
448
	ia32_attr_t *attr     = get_ia32_attr(node);
	attr->data.am_sc_sign = 1;
}

/**
 * Clears the sign bit for address mode symconst.
 */
449
450
void clear_ia32_am_sc_sign(ir_node *node)
{
451
452
453
454
455
456
457
	ia32_attr_t *attr     = get_ia32_attr(node);
	attr->data.am_sc_sign = 0;
}

/**
 * Returns the sign bit for address mode symconst.
 */
458
459
int is_ia32_am_sc_sign(const ir_node *node)
{
460
	const ia32_attr_t *attr = get_ia32_attr_const(node);
461
462
463
	return attr->data.am_sc_sign;
}

464
465
466
467
468
469
470
471
472
473
474
475
void set_ia32_am_tls_segment(ir_node *node, bool value)
{
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->data.am_tls_segment = value;
}

bool get_ia32_am_tls_segment(const ir_node *node)
{
	const ia32_attr_t *attr = get_ia32_attr_const(node);
	return attr->data.am_tls_segment;
}

476
477
478
/**
 * Gets the addr mode const.
 */
479
480
unsigned get_ia32_am_scale(const ir_node *node)
{
481
	const ia32_attr_t *attr = get_ia32_attr_const(node);
482
	return attr->data.am_scale;
483
484
}

Christian Würdig's avatar
Christian Würdig committed
485
/**
486
 * Sets the index register scale for address mode.
Christian Würdig's avatar
Christian Würdig committed
487
 */
488
489
void set_ia32_am_scale(ir_node *node, unsigned scale)
{
490
	ia32_attr_t *attr = get_ia32_attr(node);
Michael Beck's avatar
Michael Beck committed
491
	assert(scale <= 3 && "AM scale out of range [0 ... 3]");
Christian Würdig's avatar
Christian Würdig committed
492
	attr->data.am_scale = scale;
Christian Würdig's avatar
Christian Würdig committed
493
494
}

495
496
497
498
499
void ia32_copy_am_attrs(ir_node *to, const ir_node *from)
{
	set_ia32_ls_mode(to, get_ia32_ls_mode(from));
	set_ia32_am_scale(to, get_ia32_am_scale(from));
	set_ia32_am_sc(to, get_ia32_am_sc(from));
500
	if (is_ia32_am_sc_sign(from))
501
502
503
504
505
506
507
		set_ia32_am_sc_sign(to);
	add_ia32_am_offs_int(to, get_ia32_am_offs_int(from));
	set_ia32_frame_ent(to, get_ia32_frame_ent(from));
	if (is_ia32_use_frame(from))
		set_ia32_use_frame(to);
}

508
/**
509
510
 * Sets the uses_frame flag.
 */
511
512
void set_ia32_use_frame(ir_node *node)
{
Christian Würdig's avatar
Christian Würdig committed
513
	ia32_attr_t *attr    = get_ia32_attr(node);
514
515
516
517
518
	attr->data.use_frame = 1;
}

/**
 * Clears the uses_frame flag.
519
 */
520
521
void clear_ia32_use_frame(ir_node *node)
{
Christian Würdig's avatar
Christian Würdig committed
522
	ia32_attr_t *attr    = get_ia32_attr(node);
523
524
525
526
527
528
	attr->data.use_frame = 0;
}

/**
 * Gets the uses_frame flag.
 */
529
530
int is_ia32_use_frame(const ir_node *node)
{
531
	const ia32_attr_t *attr = get_ia32_attr_const(node);
532
533
534
535
536
537
	return attr->data.use_frame;
}

/**
 * Sets node to commutative.
 */
538
539
void set_ia32_commutative(ir_node *node)
{
540
541
542
543
544
545
546
	ia32_attr_t *attr         = get_ia32_attr(node);
	attr->data.is_commutative = 1;
}

/**
 * Sets node to non-commutative.
 */
547
548
void clear_ia32_commutative(ir_node *node)
{
549
550
	ia32_attr_t *attr         = get_ia32_attr(node);
	attr->data.is_commutative = 0;
551
552
553
}

/**
554
 * Checks if node is commutative.
555
 */
556
557
int is_ia32_commutative(const ir_node *node)
{
558
	const ia32_attr_t *attr = get_ia32_attr_const(node);
559
	return attr->data.is_commutative;
560
561
}

562
563
void set_ia32_need_stackent(ir_node *node)
{
Christian Würdig's avatar
Christian Würdig committed
564
	ia32_attr_t *attr     = get_ia32_attr(node);
565
	attr->data.need_stackent = 1;
Christian Würdig's avatar
Christian Würdig committed
566
567
}

568
569
void clear_ia32_need_stackent(ir_node *node)
{
Christian Würdig's avatar
Christian Würdig committed
570
	ia32_attr_t *attr     = get_ia32_attr(node);
571
	attr->data.need_stackent = 0;
Christian Würdig's avatar
Christian Würdig committed
572
573
}

574
575
int is_ia32_need_stackent(const ir_node *node)
{
576
	const ia32_attr_t *attr = get_ia32_attr_const(node);
577
	return attr->data.need_stackent;
Christian Würdig's avatar
Christian Würdig committed
578
579
}

580
581
void set_ia32_is_reload(ir_node *node)
{
582
583
584
585
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->data.is_reload = 1;
}

586
587
int is_ia32_is_reload(const ir_node *node)
{
588
589
590
591
	const ia32_attr_t *attr = get_ia32_attr_const(node);
	return attr->data.is_reload;
}

592
593
void set_ia32_is_spill(ir_node *node)
{
594
595
596
597
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->data.is_spill = 1;
}

598
599
int is_ia32_is_spill(const ir_node *node)
{
600
601
602
603
	const ia32_attr_t *attr = get_ia32_attr_const(node);
	return attr->data.is_spill;
}

604
605
void set_ia32_is_remat(ir_node *node)
{
606
607
608
609
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->data.is_remat = 1;
}

610
611
int is_ia32_is_remat(const ir_node *node)
{
612
613
614
615
	const ia32_attr_t *attr = get_ia32_attr_const(node);
	return attr->data.is_remat;
}

616
617
618
/**
 * Gets the mode of the stored/loaded value (only set for Store/Load)
 */
619
620
ir_mode *get_ia32_ls_mode(const ir_node *node)
{
621
	const ia32_attr_t *attr = get_ia32_attr_const(node);
622
	return attr->ls_mode;
623
624
625
626
627
}

/**
 * Sets the mode of the stored/loaded value (only set for Store/Load)
 */
628
629
void set_ia32_ls_mode(ir_node *node, ir_mode *mode)
{
630
631
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->ls_mode     = mode;
632
633
}

634
/**
635
 * Gets the frame entity assigned to this node.
636
 */
637
638
ir_entity *get_ia32_frame_ent(const ir_node *node)
{
639
	const ia32_attr_t *attr = get_ia32_attr_const(node);
640
641
642
643
	return attr->frame_ent;
}

/**
644
 * Sets the frame entity for this node.
645
 */
646
647
void set_ia32_frame_ent(ir_node *node, ir_entity *ent)
{
648
649
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->frame_ent   = ent;
650
	if (ent != NULL)
651
652
653
		set_ia32_use_frame(node);
	else
		clear_ia32_use_frame(node);
654
655
}

Christian Würdig's avatar
Christian Würdig committed
656
657
658
659

/**
 * Gets the instruction latency.
 */
660
661
unsigned get_ia32_latency(const ir_node *node)
{
662
663
664
	const ir_op *op               = get_irn_op(node);
	const ia32_op_attr_t *op_attr = (ia32_op_attr_t*) get_op_attr(op);
	return op_attr->latency;
Christian Würdig's avatar
Christian Würdig committed
665
666
}

Matthias Braun's avatar
Matthias Braun committed
667
668
669
670
671
672
const ir_switch_table *get_ia32_switch_table(const ir_node *node)
{
	const ia32_switch_attr_t *attr = get_ia32_switch_attr_const(node);
	return attr->table;
}

673
ia32_condition_code_t get_ia32_condcode(const ir_node *node)
Matthias Braun's avatar
Matthias Braun committed
674
{
Michael Beck's avatar
Michael Beck committed
675
	const ia32_condcode_attr_t *attr = get_ia32_condcode_attr_const(node);
676
	return attr->condition_code;
Christian Würdig's avatar
Christian Würdig committed
677
678
679
}

/**
Michael Beck's avatar
Michael Beck committed
680
 * Sets the condition code of a node
Christian Würdig's avatar
Christian Würdig committed
681
 */
682
void set_ia32_condcode(ir_node *node, ia32_condition_code_t code)
Matthias Braun's avatar
Matthias Braun committed
683
{
Michael Beck's avatar
Michael Beck committed
684
	ia32_condcode_attr_t *attr = get_ia32_condcode_attr(node);
685
686
687
	attr->condition_code = code;
}

Michael Beck's avatar
Michael Beck committed
688
689
690
691
692
693
694
/**
 * Returns the condition code of a node.
 */
unsigned get_ia32_copyb_size(const ir_node *node)
{
	const ia32_copyb_attr_t *attr = get_ia32_copyb_attr_const(node);
	return attr->size;
695
696
}

697
698
699
/**
 * Get the exception label attribute.
 */
700
701
unsigned get_ia32_exc_label(const ir_node *node)
{
702
	const ia32_attr_t *attr = get_ia32_attr_const(node);
703
	return attr->data.has_except_label;
704
705
706
707
708
}

/**
 * Set the exception label attribute.
 */
709
710
void set_ia32_exc_label(ir_node *node, unsigned flag)
{
711
	ia32_attr_t *attr = get_ia32_attr(node);
712
713
714
715
716
717
	attr->data.has_except_label = flag;
}

/**
 * Return the exception label id.
 */
718
719
ir_label_t get_ia32_exc_label_id(const ir_node *node)
{
720
721
722
723
724
725
726
727
728
	const ia32_attr_t *attr = get_ia32_attr_const(node);

	assert(attr->data.has_except_label);
	return attr->exc_label;
}

/**
 * Assign the exception label id.
 */
729
730
void set_ia32_exc_label_id(ir_node *node, ir_label_t id)
{
731
732
733
734
	ia32_attr_t *attr = get_ia32_attr(node);

	assert(attr->data.has_except_label);
	attr->exc_label = id;
735
736
}

Christian Würdig's avatar
Christian Würdig committed
737
738
#ifndef NDEBUG

739
740
static const char *ia32_get_old_node_name(const ir_node *irn)
{
741
742
	ir_graph       *irg  = get_irn_irg(irn);
	struct obstack *obst = be_get_be_obst(irg);
743
744
745

	lc_eoprintf(firm_get_arg_env(), obst, "%+F", irn);
	obstack_1grow(obst, 0);
746
	return (const char*)obstack_finish(obst);
747
748
}

Christian Würdig's avatar
Christian Würdig committed
749
750
751
/**
 * Sets the name of the original ir node.
 */
752
753
754
void set_ia32_orig_node(ir_node *node, const ir_node *old)
{
	const char  *name = ia32_get_old_node_name(old);
Christian Würdig's avatar
Christian Würdig committed
755
756
757
758
759
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->orig_node   = name;
}

#endif /* NDEBUG */
760

761
762
void ia32_swap_left_right(ir_node *node)
{
763
764
765
766
	ia32_attr_t *attr  = get_ia32_attr(node);
	ir_node     *left  = get_irn_n(node, n_ia32_binary_left);
	ir_node     *right = get_irn_n(node, n_ia32_binary_right);

Michael Beck's avatar
Michael Beck committed
767
	assert(is_ia32_commutative(node));
768
	attr->data.ins_permuted = !attr->data.ins_permuted;
769
770
	set_irn_n(node, n_ia32_binary_left,  right);
	set_irn_n(node, n_ia32_binary_right, left);
771
772
}

773
774
775
/**
 * Initializes the nodes attributes.
 */
776
777
778
static void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags,
                                 const arch_register_req_t **in_reqs,
                                 int n_res)
779
{
Matthias Braun's avatar
Matthias Braun committed
780
781
782
	ir_graph        *irg  = get_irn_irg(node);
	struct obstack  *obst = get_irg_obstack(irg);
	ia32_attr_t     *attr = get_ia32_attr(node);
783
	backend_info_t  *info;
784

785
786
	arch_set_irn_flags(node, flags);
	arch_set_irn_register_reqs_in(node, in_reqs);
787

788
789
790
#ifndef NDEBUG
	attr->attr_type  |= IA32_ATTR_ia32_attr_t;
#endif
791

792
	info            = be_get_info(node);
793
	info->out_infos = NEW_ARR_DZ(reg_out_info_t, obst, n_res);
794
795
}

796
static void init_ia32_x87_attributes(ir_node *res)
797
798
799
800
801
{
#ifndef NDEBUG
	ia32_attr_t *attr  = get_ia32_attr(res);
	attr->attr_type   |= IA32_ATTR_ia32_x87_attr_t;
#endif
802
803
	ir_graph *const irg = get_irn_irg(res);
	ia32_request_x87_sim(irg);
804
805
}

806
static void init_ia32_asm_attributes(ir_node *res)
807
808
809
810
811
{
#ifndef NDEBUG
	ia32_attr_t *attr  = get_ia32_attr(res);
	attr->attr_type   |= IA32_ATTR_ia32_asm_attr_t;
#endif
812
813
814

	ir_graph *const irg = get_irn_irg(res);
	ia32_request_x87_sim(irg); /* asm might have fp operands. */
815
816
}

817
818
819
static void init_ia32_immediate_attributes(ir_node *res, ir_entity *symconst,
                                           int symconst_sign, int no_pic_adjust,
                                           long offset)
820
{
821
	ia32_immediate_attr_t *attr = (ia32_immediate_attr_t*)get_irn_generic_attr(res);
822

823
#ifndef NDEBUG
Michael Beck's avatar
Michael Beck committed
824
825
	attr->attr.attr_type  |= IA32_ATTR_ia32_immediate_attr_t;
#endif
826
827
828
829
	attr->symconst      = symconst;
	attr->sc_sign       = symconst_sign;
	attr->no_pic_adjust = no_pic_adjust;
	attr->offset        = offset;
Michael Beck's avatar
Michael Beck committed
830
831
}

832
833
static void init_ia32_call_attributes(ir_node* res, unsigned pop,
                                      ir_type* call_tp)
834
{
835
	ia32_call_attr_t *attr = (ia32_call_attr_t*)get_irn_generic_attr(res);
836
837
838
839
840
841
842
843

#ifndef NDEBUG
	attr->attr.attr_type  |= IA32_ATTR_ia32_call_attr_t;
#endif
	attr->pop     = pop;
	attr->call_tp = call_tp;
}

844
static void init_ia32_copyb_attributes(ir_node *res, unsigned size)
845
{
846
	ia32_copyb_attr_t *attr = (ia32_copyb_attr_t*)get_irn_generic_attr(res);
Michael Beck's avatar
Michael Beck committed
847
848
849

#ifndef NDEBUG
	attr->attr.attr_type  |= IA32_ATTR_ia32_copyb_attr_t;
850
#endif
Michael Beck's avatar
Michael Beck committed
851
852
853
	attr->size = size;
}

854
855
static void init_ia32_condcode_attributes(ir_node *res,
                                          ia32_condition_code_t cc)
856
{
857
	ia32_condcode_attr_t *attr = (ia32_condcode_attr_t*)get_irn_generic_attr(res);
Michael Beck's avatar
Michael Beck committed
858
859
860
861

#ifndef NDEBUG
	attr->attr.attr_type  |= IA32_ATTR_ia32_condcode_attr_t;
#endif
862
	attr->condition_code = cc;
863
864
}

865
static void init_ia32_climbframe_attributes(ir_node *res, unsigned count)
866
{
867
	ia32_climbframe_attr_t *attr = (ia32_climbframe_attr_t*)get_irn_generic_attr(res);
868
869
870
871
872
873
874

#ifndef NDEBUG
	attr->attr.attr_type  |= IA32_ATTR_ia32_climbframe_attr_t;
#endif
	attr->count = count;
}

Matthias Braun's avatar
Matthias Braun committed
875
876
static void init_ia32_switch_attributes(ir_node *node,
                                        const ir_switch_table *table)
877
{
Matthias Braun's avatar
Matthias Braun committed
878
	ia32_switch_attr_t *attr = (ia32_switch_attr_t*) get_irn_generic_attr(node);
879
880
881
#ifndef NDEBUG
	attr->attr.attr_type |= IA32_ATTR_ia32_switch_attr_t;
#endif
Matthias Braun's avatar
Matthias Braun committed
882
	attr->table = table;
883

884
	be_foreach_out(node, o) {
Matthias Braun's avatar
Matthias Braun committed
885
886
887
		arch_set_irn_register_req_out(node, o, arch_no_register_req);
	}
}
Christian Würdig's avatar
Christian Würdig committed
888

889
/* default compare operation to compare attributes */
890
static int ia32_compare_attr(const ia32_attr_t *a, const ia32_attr_t *b)
Christoph Mallon's avatar
Christoph Mallon committed
891
{
892
	if (a->data.tp != b->data.tp)
893
894
		return 1;

895
	if (a->data.am_scale != b->data.am_scale
896
897
898
	    || a->data.am_sc_sign != b->data.am_sc_sign
	    || a->am_offs != b->am_offs
	    || a->am_sc != b->am_sc
899
		|| a->data.am_sc_no_pic_adjust != b->data.am_sc_no_pic_adjust
900
	    || a->ls_mode != b->ls_mode)
901
902
		return 1;

903
904
	/* nodes with not yet assigned entities shouldn't be CSEd (important for
	 * unsigned int -> double conversions */
905
	if (a->data.use_frame && a->frame_ent == NULL)
906
		return 1;
907
	if (b->data.use_frame && b->frame_ent == NULL)
908
909
		return 1;

910
	if (a->data.use_frame != b->data.use_frame
911
	    || a->frame_ent != b->frame_ent)
912
913
		return 1;

914
	if (a->data.has_except_label != b->data.has_except_label)
915
916
		return 1;

917
	if (a->data.ins_permuted != b->data.ins_permuted)
918
919
		return 1;

920
	return 0;
Christian Würdig's avatar
Christian Würdig committed
921
922
}

Michael Beck's avatar
Michael Beck committed
923
/** Compare nodes attributes for all "normal" nodes. */
Michael Beck's avatar
Michael Beck committed
924
static int ia32_compare_nodes_attr(const ir_node *a, const ir_node *b)
925
926
927
928
929
930
931
{
	const ia32_attr_t* attr_a = get_ia32_attr_const(a);
	const ia32_attr_t* attr_b = get_ia32_attr_const(b);

	return ia32_compare_attr(attr_a, attr_b);
}

Michael Beck's avatar
Michael Beck committed
932
/** Compare node attributes for nodes with condition code. */
Michael Beck's avatar
Michael Beck committed
933
static int ia32_compare_condcode_attr(const ir_node *a, const ir_node *b)
934
{
Michael Beck's avatar
Michael Beck committed
935
936
937
938
939
940
941
942
943
	const ia32_condcode_attr_t *attr_a;
	const ia32_condcode_attr_t *attr_b;

	if (ia32_compare_nodes_attr(a, b))
		return 1;

	attr_a = get_ia32_condcode_attr_const(a);
	attr_b = get_ia32_condcode_attr_const(b);

944
945
946
947
948
949
	if (attr_a->condition_code != attr_b->condition_code)
		return 1;

	return 0;
}

950
/** Compare node attributes for call nodes. */
Michael Beck's avatar
Michael Beck committed
951
static int ia32_compare_call_attr(const ir_node *a, const ir_node *b)
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
{
	const ia32_call_attr_t *attr_a;
	const ia32_call_attr_t *attr_b;

	if (ia32_compare_nodes_attr(a, b))
		return 1;

	attr_a = get_ia32_call_attr_const(a);
	attr_b = get_ia32_call_attr_const(b);

	if (attr_a->pop != attr_b->pop)
		return 1;

	if (attr_a->call_tp != attr_b->call_tp)
		return 1;

	return 0;
}

Michael Beck's avatar
Michael Beck committed
971
/** Compare node attributes for CopyB nodes. */
Michael Beck's avatar
Michael Beck committed
972
static int ia32_compare_copyb_attr(const ir_node *a, const ir_node *b)
Michael Beck's avatar
Michael Beck committed
973
974
975
976
977
978
979
980
981
982
{
	const ia32_copyb_attr_t *attr_a;
	const ia32_copyb_attr_t *attr_b;

	if (ia32_compare_nodes_attr(a, b))
		return 1;

	attr_a = get_ia32_copyb_attr_const(a);
	attr_b = get_ia32_copyb_attr_const(b);

983
	if (attr_a->size != attr_b->size)
Michael Beck's avatar
Michael Beck committed
984
985
986
		return 1;

	return 0;
987
988
}

Michael Beck's avatar
Michael Beck committed
989
990

/** Compare ASM node attributes. */