ia32_new_nodes.c 27.8 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
25
 * @file
 * @brief       Handling of ia32 specific firm opcodes.
 * @author      Christian Wuerdig
 * @version     $Id$
 *
yb9976's avatar
yb9976 committed
26
 * This file implements the creation of the architecture specific firm opcodes
Christoph Mallon's avatar
Christoph Mallon committed
27
 * and the corresponding node constructors for the ia32 assembler irg.
28
 */
29
#include "config.h"
30
31

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

34
#include "irargs_t.h"
35
36
37
38
39
40
#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
41
#include "irop.h"
42
#include "irverify_t.h"
43
#include "irprintf.h"
44
#include "iredges.h"
45
#include "error.h"
Matthias Braun's avatar
Matthias Braun committed
46
#include "raw_bitset.h"
47
#include "xmalloc.h"
48

49
#include "../bearch.h"
50
#include "../beinfo.h"
51

52
#include "bearch_ia32_t.h"
53
#include "ia32_common_transform.h"
54
55
#include "ia32_nodes_attr.h"
#include "ia32_new_nodes.h"
Christian Würdig's avatar
Christian Würdig committed
56
#include "gen_ia32_regalloc_if.h"
57
#include "gen_ia32_machine.h"
58
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, 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
130
131
			if (! is_ia32_Lea(n)) {
				if (is_ia32_AddrModeS(n)) {
					fprintf(F, "[AM S] ");
132
				} else if (is_ia32_AddrModeD(n)) {
133
134
					fprintf(F, "[AM D] ");
				}
Christian Würdig's avatar
Christian Würdig committed
135
136
137
138
139
			}

			break;

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

			/* dump op type */
			fprintf(F, "op = ");
144
			switch (get_ia32_op_type(n)) {
145
146
147
148
149
150
151
152
153
				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
154
				default:
155
					fprintf(F, "unknown (%d)", get_ia32_op_type(n));
Christian Würdig's avatar
Christian Würdig committed
156
					break;
157
158
159
160
161
			}
			fprintf(F, "\n");

			/* dump supported am */
			fprintf(F, "AM support = ");
162
			switch (get_ia32_am_support(n)) {
163
164
165
166
				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
167
				default:
168
					fprintf(F, "unknown (%d)\n", get_ia32_am_support(n));
Christian Würdig's avatar
Christian Würdig committed
169
					break;
170
			}
Christian Würdig's avatar
Christian Würdig committed
171

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

Matthias Braun's avatar
Matthias Braun committed
177
			/* dump AM symconst */
178
			if (get_ia32_am_sc(n) != NULL) {
179
180
181
				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
182
183
			}

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

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

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

205
206
207
208
209
210
211
212
213
			/* 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");
214

215
216
217
218
219
220
221
222
223
224
			/* 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
225
226
227
228
229
230
231
232
233
234
235
236
#ifndef NDEBUG
			/* dump original ir node name */
			fprintf(F, "orig node = ");
			if (get_ia32_orig_node(n)) {
				fprintf(F, "%s", get_ia32_orig_node(n));
			}
			else {
				fprintf(F, "n/a");
			}
			fprintf(F, "\n");
#endif /* NDEBUG */

Christian Würdig's avatar
Christian Würdig committed
237
			break;
238
	}
239
240
241
242
}



243
244
ia32_attr_t *get_ia32_attr(ir_node *node)
{
245
	assert(is_ia32_irn(node) && "need ia32 node to get ia32 attributes");
246
	return (ia32_attr_t *)get_irn_generic_attr(node);
247
248
}

249
250
const ia32_attr_t *get_ia32_attr_const(const ir_node *node)
{
251
252
253
254
	assert(is_ia32_irn(node) && "need ia32 node to get ia32 attributes");
	return (const ia32_attr_t*) get_irn_generic_attr_const(node);
}

255
256
ia32_x87_attr_t *get_ia32_x87_attr(ir_node *node)
{
257
258
259
260
261
	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;
}

262
263
const ia32_x87_attr_t *get_ia32_x87_attr_const(const ir_node *node)
{
264
265
266
267
268
	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;
}

269
270
const ia32_asm_attr_t *get_ia32_asm_attr_const(const ir_node *node)
{
271
272
273
274
275
276
	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;
}

277
278
ia32_immediate_attr_t *get_ia32_immediate_attr(ir_node *node)
{
279
280
281
282
283
284
	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;
}

285
286
const ia32_immediate_attr_t *get_ia32_immediate_attr_const(const ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
287
288
	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);
289

Michael Beck's avatar
Michael Beck committed
290
291
292
	return imm_attr;
}

293
294
ia32_condcode_attr_t *get_ia32_condcode_attr(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
295
296
297
298
299
300
	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;
}

301
302
const ia32_condcode_attr_t *get_ia32_condcode_attr_const(const ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
303
304
305
306
307
308
	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;
}

309
310
311
312
313
314
315
316
317
318
319
320
321
322
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;
}

323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
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;
}

339
340
ia32_copyb_attr_t *get_ia32_copyb_attr(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
341
342
343
344
345
346
	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;
}

347
348
const ia32_copyb_attr_t *get_ia32_copyb_attr_const(const ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
349
350
351
352
	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;
353
354
}

355
356
ia32_climbframe_attr_t *get_ia32_climbframe_attr(ir_node *node)
{
357
358
359
360
361
362
	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;
}

363
364
const ia32_climbframe_attr_t *get_ia32_climbframe_attr_const(const ir_node *node)
{
365
366
367
368
369
370
	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;
}

371
/**
372
 * Gets the type of an ia32 node.
373
 */
374
375
ia32_op_type_t get_ia32_op_type(const ir_node *node)
{
376
	const ia32_attr_t *attr = get_ia32_attr_const(node);
377
	return (ia32_op_type_t)attr->data.tp;
378
379
380
}

/**
381
 * Sets the type of an ia32 node.
382
 */
383
384
void set_ia32_op_type(ir_node *node, ia32_op_type_t tp)
{
385
	ia32_attr_t *attr = get_ia32_attr(node);
386
	attr->data.tp     = tp;
387
388
}

389
390
ia32_am_type_t get_ia32_am_support(const ir_node *node)
{
Matthias Braun's avatar
Matthias Braun committed
391
	const ia32_attr_t *attr = get_ia32_attr_const(node);
392
	return (ia32_am_type_t)attr->data.am_arity;
Matthias Braun's avatar
Matthias Braun committed
393
394
}

395
/**
396
 * Sets the supported address mode of an ia32 node
397
 */
398
399
400
401
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
402
403
}

404
/**
405
 * Gets the address mode offset as int.
406
 */
407
408
int get_ia32_am_offs_int(const ir_node *node)
{
409
	const ia32_attr_t *attr = get_ia32_attr_const(node);
410
411
412
	return attr->am_offs;
}

413
/**
414
 * Sets the address mode offset from an int.
415
 */
416
417
void set_ia32_am_offs_int(ir_node *node, int offset)
{
418
419
420
421
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->am_offs = offset;
}

422
423
void add_ia32_am_offs_int(ir_node *node, int offset)
{
424
425
426
427
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->am_offs += offset;
}

428
/**
429
 * Returns the symconst entity associated to address mode.
430
 */
431
432
ir_entity *get_ia32_am_sc(const ir_node *node)
{
433
	const ia32_attr_t *attr = get_ia32_attr_const(node);
434
435
436
437
	return attr->am_sc;
}

/**
438
 * Sets the symconst entity associated to address mode.
439
 */
440
441
void set_ia32_am_sc(ir_node *node, ir_entity *entity)
{
442
	ia32_attr_t *attr = get_ia32_attr(node);
443
	attr->am_sc       = entity;
444
445
446
447
448
}

/**
 * Sets the sign bit for address mode symconst.
 */
449
450
void set_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 = 1;
}

/**
 * Clears the sign bit for address mode symconst.
 */
458
459
void clear_ia32_am_sc_sign(ir_node *node)
{
460
461
462
463
464
465
466
	ia32_attr_t *attr     = get_ia32_attr(node);
	attr->data.am_sc_sign = 0;
}

/**
 * Returns the sign bit for address mode symconst.
 */
467
468
int is_ia32_am_sc_sign(const ir_node *node)
{
469
	const ia32_attr_t *attr = get_ia32_attr_const(node);
470
471
472
	return attr->data.am_sc_sign;
}

473
474
475
476
477
478
479
480
481
482
483
484
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;
}

485
486
487
/**
 * Gets the addr mode const.
 */
488
489
unsigned get_ia32_am_scale(const ir_node *node)
{
490
	const ia32_attr_t *attr = get_ia32_attr_const(node);
491
	return attr->data.am_scale;
492
493
}

Christian Würdig's avatar
Christian Würdig committed
494
/**
495
 * Sets the index register scale for address mode.
Christian Würdig's avatar
Christian Würdig committed
496
 */
497
498
void set_ia32_am_scale(ir_node *node, unsigned scale)
{
499
	ia32_attr_t *attr = get_ia32_attr(node);
Michael Beck's avatar
Michael Beck committed
500
	assert(scale <= 3 && "AM scale out of range [0 ... 3]");
Christian Würdig's avatar
Christian Würdig committed
501
	attr->data.am_scale = scale;
Christian Würdig's avatar
Christian Würdig committed
502
503
}

504
505
506
507
508
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));
509
	if (is_ia32_am_sc_sign(from))
510
511
512
513
514
515
516
		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);
}

517
/**
518
519
 * Sets the uses_frame flag.
 */
520
521
void set_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
	attr->data.use_frame = 1;
}

/**
 * Clears the uses_frame flag.
528
 */
529
530
void clear_ia32_use_frame(ir_node *node)
{
Christian Würdig's avatar
Christian Würdig committed
531
	ia32_attr_t *attr    = get_ia32_attr(node);
532
533
534
535
536
537
	attr->data.use_frame = 0;
}

/**
 * Gets the uses_frame flag.
 */
538
539
int is_ia32_use_frame(const ir_node *node)
{
540
	const ia32_attr_t *attr = get_ia32_attr_const(node);
541
542
543
544
545
546
	return attr->data.use_frame;
}

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

/**
 * Sets node to non-commutative.
 */
556
557
void clear_ia32_commutative(ir_node *node)
{
558
559
	ia32_attr_t *attr         = get_ia32_attr(node);
	attr->data.is_commutative = 0;
560
561
562
}

/**
563
 * Checks if node is commutative.
564
 */
565
566
int is_ia32_commutative(const ir_node *node)
{
567
	const ia32_attr_t *attr = get_ia32_attr_const(node);
568
	return attr->data.is_commutative;
569
570
}

571
572
void set_ia32_need_stackent(ir_node *node)
{
Christian Würdig's avatar
Christian Würdig committed
573
	ia32_attr_t *attr     = get_ia32_attr(node);
574
	attr->data.need_stackent = 1;
Christian Würdig's avatar
Christian Würdig committed
575
576
}

577
578
void clear_ia32_need_stackent(ir_node *node)
{
Christian Würdig's avatar
Christian Würdig committed
579
	ia32_attr_t *attr     = get_ia32_attr(node);
580
	attr->data.need_stackent = 0;
Christian Würdig's avatar
Christian Würdig committed
581
582
}

583
584
int is_ia32_need_stackent(const ir_node *node)
{
585
	const ia32_attr_t *attr = get_ia32_attr_const(node);
586
	return attr->data.need_stackent;
Christian Würdig's avatar
Christian Würdig committed
587
588
}

589
590
void set_ia32_is_reload(ir_node *node)
{
591
592
593
594
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->data.is_reload = 1;
}

595
596
int is_ia32_is_reload(const ir_node *node)
{
597
598
599
600
	const ia32_attr_t *attr = get_ia32_attr_const(node);
	return attr->data.is_reload;
}

601
602
void set_ia32_is_spill(ir_node *node)
{
603
604
605
606
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->data.is_spill = 1;
}

607
608
int is_ia32_is_spill(const ir_node *node)
{
609
610
611
612
	const ia32_attr_t *attr = get_ia32_attr_const(node);
	return attr->data.is_spill;
}

613
614
void set_ia32_is_remat(ir_node *node)
{
615
616
617
618
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->data.is_remat = 1;
}

619
620
int is_ia32_is_remat(const ir_node *node)
{
621
622
623
624
	const ia32_attr_t *attr = get_ia32_attr_const(node);
	return attr->data.is_remat;
}

625
626
627
/**
 * Gets the mode of the stored/loaded value (only set for Store/Load)
 */
628
629
ir_mode *get_ia32_ls_mode(const ir_node *node)
{
630
	const ia32_attr_t *attr = get_ia32_attr_const(node);
631
	return attr->ls_mode;
632
633
634
635
636
}

/**
 * Sets the mode of the stored/loaded value (only set for Store/Load)
 */
637
638
void set_ia32_ls_mode(ir_node *node, ir_mode *mode)
{
639
640
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->ls_mode     = mode;
641
642
}

643
/**
644
 * Gets the frame entity assigned to this node.
645
 */
646
647
ir_entity *get_ia32_frame_ent(const ir_node *node)
{
648
	const ia32_attr_t *attr = get_ia32_attr_const(node);
649
650
651
652
	return attr->frame_ent;
}

/**
653
 * Sets the frame entity for this node.
654
 */
655
656
void set_ia32_frame_ent(ir_node *node, ir_entity *ent)
{
657
658
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->frame_ent   = ent;
659
	if (ent != NULL)
660
661
662
		set_ia32_use_frame(node);
	else
		clear_ia32_use_frame(node);
663
664
}

Christian Würdig's avatar
Christian Würdig committed
665
666
667
668

/**
 * Gets the instruction latency.
 */
669
670
unsigned get_ia32_latency(const ir_node *node)
{
671
672
673
	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
674
675
}

Christian Würdig's avatar
Christian Würdig committed
676
/**
Michael Beck's avatar
Michael Beck committed
677
 * Returns the condition code of a node.
Christian Würdig's avatar
Christian Würdig committed
678
 */
679
ia32_condition_code_t get_ia32_condcode(const ir_node *node)
Matthias Braun's avatar
Matthias Braun committed
680
{
Michael Beck's avatar
Michael Beck committed
681
	const ia32_condcode_attr_t *attr = get_ia32_condcode_attr_const(node);
682
	return attr->condition_code;
Christian Würdig's avatar
Christian Würdig committed
683
684
685
}

/**
Michael Beck's avatar
Michael Beck committed
686
 * Sets the condition code of a node
Christian Würdig's avatar
Christian Würdig committed
687
 */
688
void set_ia32_condcode(ir_node *node, ia32_condition_code_t code)
Matthias Braun's avatar
Matthias Braun committed
689
{
Michael Beck's avatar
Michael Beck committed
690
	ia32_condcode_attr_t *attr = get_ia32_condcode_attr(node);
691
692
693
694
695
696
697
	attr->condition_code = code;
}

long get_ia32_default_pn(const ir_node *node)
{
	const ia32_switch_attr_t *attr = get_ia32_switch_attr_const(node);
	return attr->default_pn;
Michael Beck's avatar
Michael Beck committed
698
699
700
701
702
703
704
705
706
}

/**
 * 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;
707
708
}

709
/**
710
 * Get the list of available execution units.
711
 */
712
713
const be_execution_unit_t ***get_ia32_exec_units(const ir_node *node)
{
714
	const ia32_attr_t *attr = get_ia32_attr_const(node);
715
	return attr->exec_units;
716
717
}

718
719
720
/**
 * Get the exception label attribute.
 */
721
722
unsigned get_ia32_exc_label(const ir_node *node)
{
723
	const ia32_attr_t *attr = get_ia32_attr_const(node);
724
	return attr->data.has_except_label;
725
726
727
728
729
}

/**
 * Set the exception label attribute.
 */
730
731
void set_ia32_exc_label(ir_node *node, unsigned flag)
{
732
	ia32_attr_t *attr = get_ia32_attr(node);
733
734
735
736
737
738
	attr->data.has_except_label = flag;
}

/**
 * Return the exception label id.
 */
739
740
ir_label_t get_ia32_exc_label_id(const ir_node *node)
{
741
742
743
744
745
746
747
748
749
	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.
 */
750
751
void set_ia32_exc_label_id(ir_node *node, ir_label_t id)
{
752
753
754
755
	ia32_attr_t *attr = get_ia32_attr(node);

	assert(attr->data.has_except_label);
	attr->exc_label = id;
756
757
}

Christian Würdig's avatar
Christian Würdig committed
758
759
760
761
762
#ifndef NDEBUG

/**
 * Returns the name of the original ir node.
 */
763
764
const char *get_ia32_orig_node(const ir_node *node)
{
765
	const ia32_attr_t *attr = get_ia32_attr_const(node);
Christian Würdig's avatar
Christian Würdig committed
766
767
768
	return attr->orig_node;
}

769
770
static const char *ia32_get_old_node_name(const ir_node *irn)
{
771
772
	ir_graph       *irg  = get_irn_irg(irn);
	struct obstack *obst = be_get_be_obst(irg);
773
774
775

	lc_eoprintf(firm_get_arg_env(), obst, "%+F", irn);
	obstack_1grow(obst, 0);
776
	return (const char*)obstack_finish(obst);
777
778
}

Christian Würdig's avatar
Christian Würdig committed
779
780
781
/**
 * Sets the name of the original ir node.
 */
782
783
784
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
785
786
787
788
789
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->orig_node   = name;
}

#endif /* NDEBUG */
790
791


792
793
/**
 * Returns whether or not the node is an AddrModeS node.
794
 */
795
796
int is_ia32_AddrModeS(const ir_node *node)
{
797
	const ia32_attr_t *attr = get_ia32_attr_const(node);
798
	return (attr->data.tp == ia32_AddrModeS);
799
800
801
}

/**
802
 * Returns whether or not the node is an AddrModeD node.
803
 */
804
805
int is_ia32_AddrModeD(const ir_node *node)
{
806
	const ia32_attr_t *attr = get_ia32_attr_const(node);
807
	return (attr->data.tp == ia32_AddrModeD);
Christian Würdig's avatar
Christian Würdig committed
808
}
809

810
811
void ia32_swap_left_right(ir_node *node)
{
812
813
814
815
	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
816
	assert(is_ia32_commutative(node));
817
	attr->data.ins_permuted = !attr->data.ins_permuted;
818
819
	set_irn_n(node, n_ia32_binary_left,  right);
	set_irn_n(node, n_ia32_binary_right, left);
820
821
}

822
823
824
/**
 * Initializes the nodes attributes.
 */
825
826
827
828
static void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags,
                                 const arch_register_req_t **in_reqs,
                                 const be_execution_unit_t ***execution_units,
                                 int n_res)
829
{
Matthias Braun's avatar
Matthias Braun committed
830
831
832
	ir_graph        *irg  = get_irn_irg(node);
	struct obstack  *obst = get_irg_obstack(irg);
	ia32_attr_t     *attr = get_ia32_attr(node);
833
	backend_info_t  *info;
834

835
	arch_irn_set_flags(node, flags);
836
	arch_set_in_register_reqs(node, in_reqs);
837

838
839
840
841
	attr->exec_units  = execution_units;
#ifndef NDEBUG
	attr->attr_type  |= IA32_ATTR_ia32_attr_t;
#endif
842

843
844
845
	info            = be_get_info(node);
	info->out_infos = NEW_ARR_D(reg_out_info_t, obst, n_res);
	memset(info->out_infos, 0, n_res * sizeof(info->out_infos[0]));
846
847
}

848
static void init_ia32_x87_attributes(ir_node *res)
849
{
850
851
	ir_graph        *irg      = get_irn_irg(res);
	ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
852
853
854
#ifndef NDEBUG
	ia32_attr_t *attr  = get_ia32_attr(res);
	attr->attr_type   |= IA32_ATTR_ia32_x87_attr_t;
Matthias Braun's avatar
Matthias Braun committed
855
856
#else
	(void) res;
857
#endif
858
	irg_data->do_x87_sim = 1;
859
860
}

861
static void init_ia32_asm_attributes(ir_node *res)
862
863
864
865
{
#ifndef NDEBUG
	ia32_attr_t *attr  = get_ia32_attr(res);
	attr->attr_type   |= IA32_ATTR_ia32_asm_attr_t;
Matthias Braun's avatar
Matthias Braun committed
866
867
#else
	(void) res;
868
869
870
#endif
}

871
872
873
static void init_ia32_immediate_attributes(ir_node *res, ir_entity *symconst,
                                           int symconst_sign, int no_pic_adjust,
                                           long offset)
874
{
875
	ia32_immediate_attr_t *attr = (ia32_immediate_attr_t*)get_irn_generic_attr(res);
876

877
#ifndef NDEBUG
Michael Beck's avatar
Michael Beck committed
878
879
	attr->attr.attr_type  |= IA32_ATTR_ia32_immediate_attr_t;
#endif
880
881
882
883
	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
884
885
}

886
887
static void init_ia32_call_attributes(ir_node* res, unsigned pop,
                                      ir_type* call_tp)
888
{
889
	ia32_call_attr_t *attr = (ia32_call_attr_t*)get_irn_generic_attr(res);
890
891
892
893
894
895
896
897

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

898
static void init_ia32_copyb_attributes(ir_node *res, unsigned size)
899
{
900
	ia32_copyb_attr_t *attr = (ia32_copyb_attr_t*)get_irn_generic_attr(res);
Michael Beck's avatar
Michael Beck committed
901
902
903

#ifndef NDEBUG
	attr->attr.attr_type  |= IA32_ATTR_ia32_copyb_attr_t;
904
#endif
Michael Beck's avatar
Michael Beck committed
905
906
907
	attr->size = size;
}

908
909
static void init_ia32_condcode_attributes(ir_node *res,
                                          ia32_condition_code_t cc)
910
{
911
	ia32_condcode_attr_t *attr = (ia32_condcode_attr_t*)get_irn_generic_attr(res);
Michael Beck's avatar
Michael Beck committed
912
913
914
915

#ifndef NDEBUG
	attr->attr.attr_type  |= IA32_ATTR_ia32_condcode_attr_t;
#endif
916
	attr->condition_code = cc;
917
918
}

919
static void init_ia32_climbframe_attributes(ir_node *res, unsigned count)
920
{
921
	ia32_climbframe_attr_t *attr = (ia32_climbframe_attr_t*)get_irn_generic_attr(res);
922
923
924
925
926
927
928

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

929
static void init_ia32_switch_attributes(ir_node *res, long default_pn)
930
931
932
933
934
935
936
937
{
	ia32_switch_attr_t *attr = (ia32_switch_attr_t*) get_irn_generic_attr(res);
#ifndef NDEBUG
	attr->attr.attr_type |= IA32_ATTR_ia32_switch_attr_t;
#endif
	attr->default_pn = default_pn;
}

Christian Würdig's avatar
Christian Würdig committed
938

939
/* default compare operation to compare attributes */
940
static int ia32_compare_attr(const ia32_attr_t *a, const ia32_attr_t *b)
Christoph Mallon's avatar
Christoph Mallon committed
941
{
942
	if (a->data.tp != b->data.tp)
943
944
		return 1;

945
	if (a->data.am_scale != b->data.am_scale
946
947
948
	    || a->data.am_sc_sign != b->data.am_sc_sign
	    || a->am_offs != b->am_offs
	    || a->am_sc != b->am_sc
949
		|| a->data.am_sc_no_pic_adjust != b->data.am_sc_no_pic_adjust
950
	    || a->ls_mode != b->ls_mode)
951
952
		return 1;

953
954
	/* nodes with not yet assigned entities shouldn't be CSEd (important for
	 * unsigned int -> double conversions */
955
	if (a->data.use_frame && a->frame_ent == NULL)
956
		return 1;
957
	if (b->data.use_frame && b->frame_ent == NULL)
958
959
		return 1;

960
	if (a->data.use_frame != b->data.use_frame
961
	    || a->frame_ent != b->frame_ent)
962
963
		return 1;

964
	if (a->data.has_except_label != b->data.has_except_label)
965
966
		return 1;

967
	if (a->data.ins_permuted != b->data.ins_permuted)
968
969
		return 1;

970
	return 0;
Christian Würdig's avatar
Christian Würdig committed