ia32_new_nodes.c 33.2 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
Christian Würdig's avatar
Christian Würdig committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

20
/**
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$
 *
26
 * This file implements the creation of the achitecture 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
32

#include <stdlib.h>

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 "irvrfy_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
#include "../bearch.h"
49
#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
#include "gen_ia32_machine.h"
57

58
59
60
61
62
63
64
65
66
67
68
/***********************************************************************************
 *      _                                   _       _             __
 *     | |                                 (_)     | |           / _|
 *   __| |_   _ _ __ ___  _ __   ___ _ __   _ _ __ | |_ ___ _ __| |_ __ _  ___ ___
 *  / _` | | | | '_ ` _ \| '_ \ / _ \ '__| | | '_ \| __/ _ \ '__|  _/ _` |/ __/ _ \
 * | (_| | |_| | | | | | | |_) |  __/ |    | | | | | ||  __/ |  | || (_| | (_|  __/
 *  \__,_|\__,_|_| |_| |_| .__/ \___|_|    |_|_| |_|\__\___|_|  |_| \__,_|\___\___|
 *                       | |
 *                       |_|
 ***********************************************************************************/

69
70
71
/**
 * Dumps the register requirements for either in or out.
 */
Matthias Braun's avatar
Matthias Braun committed
72
73
static void dump_reg_req(FILE *F, ir_node *n, const arch_register_req_t **reqs,
                         int inout) {
74
	char *dir = inout ? "out" : "in";
75
	int   max = inout ? (int) arch_irn_get_n_outs(n) : get_irn_arity(n);
Matthias Braun's avatar
Matthias Braun committed
76
	char  buf[1024];
77
78
	int   i;

Matthias Braun's avatar
Matthias Braun committed
79
	memset(buf, 0, sizeof(buf));
80
81
82
83
84

	if (reqs) {
		for (i = 0; i < max; i++) {
			fprintf(F, "%sreq #%d =", dir, i);

Matthias Braun's avatar
Matthias Braun committed
85
			if (reqs[i]->type == arch_register_req_type_none) {
86
87
88
				fprintf(F, " n/a");
			}

Matthias Braun's avatar
Matthias Braun committed
89
90
			if (reqs[i]->type & arch_register_req_type_normal) {
				fprintf(F, " %s", reqs[i]->cls->name);
91
92
			}

Matthias Braun's avatar
Matthias Braun committed
93
94
95
			if (reqs[i]->type & arch_register_req_type_limited) {
				fprintf(F, " %s",
				        arch_register_req_format(buf, sizeof(buf), reqs[i], n));
96
97
			}

Matthias Braun's avatar
Matthias Braun committed
98
			if (reqs[i]->type & arch_register_req_type_should_be_same) {
99
100
101
102
103
104
105
106
107
				unsigned other = reqs[i]->other_same;
				int i;

				ir_fprintf(F, " same as");
				for (i = 0; 1U << i <= other; ++i) {
					if (other & (1U << i)) {
						ir_fprintf(F, " %+F", get_irn_n(n, i));
					}
				}
108
109
			}

110
			if (reqs[i]->type & arch_register_req_type_must_be_different) {
111
112
113
114
115
116
117
118
119
				unsigned other = reqs[i]->other_different;
				int i;

				ir_fprintf(F, " different from");
				for (i = 0; 1U << i <= other; ++i) {
					if (other & (1U << i)) {
						ir_fprintf(F, " %+F", get_irn_n(n, i));
					}
				}
120
121
122
123
124
125
126
127
128
129
130
131
			}

			fprintf(F, "\n");
		}

		fprintf(F, "\n");
	}
	else {
		fprintf(F, "%sreq = N/A\n", dir);
	}
}

132
133
134
135
136
137
138
/**
 * 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
 */
139
static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
140
141
	ir_mode     *mode = NULL;
	int          bad  = 0;
142
	int          i, n_res, flags;
Matthias Braun's avatar
Matthias Braun committed
143
	const arch_register_req_t **reqs;
Christian Würdig's avatar
Christian Würdig committed
144
145
146

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

149
			if(is_ia32_Immediate(n) || is_ia32_Const(n)) {
150
151
152
153
154
				const ia32_immediate_attr_t *attr
					= get_ia32_immediate_attr_const(n);

				fputc(' ', F);
				if(attr->symconst) {
Michael Beck's avatar
Michael Beck committed
155
					if(attr->sc_sign) {
156
157
158
159
						fputc('-', F);
					}
					fputs(get_entity_name(attr->symconst), F);
				}
160
				if(attr->offset != 0 || attr->symconst == NULL) {
161
162
163
164
					if(attr->offset > 0 && attr->symconst != NULL) {
						fputc('+', F);
					}
					fprintf(F, "%ld", attr->offset);
165
166
167
					if (attr->no_pic_adjust) {
						fputs("(no_pic_adjust)", F);
					}
168
				}
Christian Würdig's avatar
Christian Würdig committed
169
			}
Michael Beck's avatar
Michael Beck committed
170
			else {
171
172
173
174
175
176
177
178
179
180
				const ia32_attr_t *attr = get_ia32_attr_const(n);

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

				if(attr->am_sc != NULL) {
					if(attr->data.am_sc_sign) {
						fputc('-', F);
					}
					fputs(get_entity_name(attr->am_sc), F);
181
182
183
					if(attr->data.am_sc_no_pic_adjust) {
						fputs("(no_pic_adjust)", F);
					}
184
185
186
187
188
189
190
191
192
193
194
				}
				if(attr->am_offs != 0) {
					if(attr->am_offs > 0 && attr->am_sc != NULL) {
						fputc('+', F);
					}
					fprintf(F, "%d", attr->am_offs);
				}

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

197
		case dump_node_mode_txt:
198
199
200
			mode = get_ia32_ls_mode(n);
			if (mode != NULL)
				fprintf(F, "[%s]", get_mode_name(mode));
201
			break;
Christian Würdig's avatar
Christian Würdig committed
202

203
		case dump_node_nodeattr_txt:
204
205
206
			if (! is_ia32_Lea(n)) {
				if (is_ia32_AddrModeS(n)) {
					fprintf(F, "[AM S] ");
207
				} else if (is_ia32_AddrModeD(n)) {
208
209
					fprintf(F, "[AM D] ");
				}
Christian Würdig's avatar
Christian Würdig committed
210
211
212
213
214
			}

			break;

		case dump_node_info_txt:
215
			fprintf(F, "=== IA32 attr begin ===\n");
Christian Würdig's avatar
Christian Würdig committed
216
217
218

			/* dump IN requirements */
			if (get_irn_arity(n) > 0) {
219
				reqs = get_ia32_in_req_all(n);
220
				dump_reg_req(F, n, reqs, 0);
Christian Würdig's avatar
Christian Würdig committed
221
222
			}

Michael Beck's avatar
Michael Beck committed
223
			n_res = arch_irn_get_n_outs(n);
224
			if (n_res > 0) {
Michael Beck's avatar
Michael Beck committed
225
				/* dump OUT requirements */
226
				reqs = get_ia32_out_req_all(n);
227
				dump_reg_req(F, n, reqs, 1);
Christian Würdig's avatar
Christian Würdig committed
228

Michael Beck's avatar
Michael Beck committed
229
				/* dump assigned registers */
230
				for (i = 0; i < n_res; i++) {
231
					const arch_register_t *reg = arch_irn_get_register(n, i);
232
233

					fprintf(F, "reg #%d = %s\n", i, reg ? arch_register_get_name(reg) : "n/a");
Christian Würdig's avatar
Christian Würdig committed
234
				}
Christian Würdig's avatar
Christian Würdig committed
235
				fprintf(F, "\n");
Christian Würdig's avatar
Christian Würdig committed
236
			}
237
238
239

			/* dump op type */
			fprintf(F, "op = ");
240
			switch (get_ia32_op_type(n)) {
241
242
243
244
245
246
247
248
249
				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
250
				default:
251
					fprintf(F, "unknown (%d)", get_ia32_op_type(n));
Christian Würdig's avatar
Christian Würdig committed
252
					break;
253
254
255
256
257
			}
			fprintf(F, "\n");

			/* dump supported am */
			fprintf(F, "AM support = ");
258
			switch (get_ia32_am_support(n)) {
259
260
261
262
				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
263
				default:
264
					fprintf(F, "unknown (%d)\n", get_ia32_am_support(n));
Christian Würdig's avatar
Christian Würdig committed
265
					break;
266
			}
Christian Würdig's avatar
Christian Würdig committed
267

268
			/* dump AM offset */
269
270
			if(get_ia32_am_offs_int(n) != 0) {
				fprintf(F, "AM offset = %d\n", get_ia32_am_offs_int(n));
271
			}
Christian Würdig's avatar
Christian Würdig committed
272

Matthias Braun's avatar
Matthias Braun committed
273
274
			/* dump AM symconst */
			if(get_ia32_am_sc(n) != NULL) {
275
276
277
				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
278
279
			}

280
281
			/* dump AM scale */
			fprintf(F, "AM scale = %d\n", get_ia32_am_scale(n));
Christian Würdig's avatar
Christian Würdig committed
282

283
			/* dump pn code */
Michael Beck's avatar
Michael Beck committed
284
285
286
			if (is_ia32_SwitchJmp(n)) {
				fprintf(F, "pn_code = %ld\n", get_ia32_condcode(n));
			} else if (is_ia32_CMov(n) || is_ia32_Set(n) || is_ia32_Jcc(n)) {
Michael Beck's avatar
Michael Beck committed
287
				ia32_attr_t *attr = get_ia32_attr(n);
Michael Beck's avatar
Michael Beck committed
288
				long pnc = get_ia32_condcode(n);
Matthias Braun's avatar
Matthias Braun committed
289
				fprintf(F, "pn_code = 0x%lX (%s)\n", pnc, get_pnc_string(pnc & pn_Cmp_True));
290
291
				fprintf(F, "ins_permuted = %u \n", attr->data.ins_permuted);
				fprintf(F, "cmp_unsigned = %u \n", attr->data.cmp_unsigned);
Michael Beck's avatar
Michael Beck committed
292
293
			}
			else if (is_ia32_CopyB(n) || is_ia32_CopyB_i(n)) {
Michael Beck's avatar
Michael Beck committed
294
				fprintf(F, "size = %u\n", get_ia32_copyb_size(n));
295
			}
Christian Würdig's avatar
Christian Würdig committed
296

Michael Beck's avatar
Michael Beck committed
297
298
299
			fprintf(F, "n_res = %d\n",         n_res);
			fprintf(F, "use_frame = %d\n",     is_ia32_use_frame(n));
			fprintf(F, "commutative = %d\n",   is_ia32_commutative(n));
300
			fprintf(F, "need stackent = %d\n", is_ia32_need_stackent(n));
Michael Beck's avatar
Michael Beck committed
301
302
			fprintf(F, "is reload = %d\n",     is_ia32_is_reload(n));
			fprintf(F, "latency = %d\n",       get_ia32_latency(n));
Christian Würdig's avatar
Christian Würdig committed
303

304
305
			/* dump flags */
			fprintf(F, "flags =");
306
			flags = arch_irn_get_flags(n);
307
			if (flags == arch_irn_flags_none) {
Christian Würdig's avatar
Christian Würdig committed
308
				fprintf(F, " none");
309
			}
Christian Würdig's avatar
Christian Würdig committed
310
			else {
311
				if (flags & arch_irn_flags_dont_spill) {
Christian Würdig's avatar
Christian Würdig committed
312
313
					fprintf(F, " unspillable");
				}
314
				if (flags & arch_irn_flags_rematerializable) {
Christian Würdig's avatar
Christian Würdig committed
315
316
					fprintf(F, " remat");
				}
317
318
319
				if (flags & arch_irn_flags_modify_flags) {
					fprintf(F, " modify_flags");
				}
Christian Würdig's avatar
Christian Würdig committed
320
			}
321
322
323
324
325
326
327
328
329
330
331
			fprintf(F, " (%d)\n", flags);

			/* 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");
332

333
334
335
336
337
338
339
340
341
342
			/* 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
343
344
345
346
347
348
349
350
351
352
353
354
#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 */

355
356
			fprintf(F, "=== IA32 attr end ===\n");
			/* end of: case dump_node_info_txt */
Christian Würdig's avatar
Christian Würdig committed
357
			break;
358
	}
359

Christian Würdig's avatar
Christian Würdig committed
360
	return bad;
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
}



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

376
ia32_attr_t *get_ia32_attr(ir_node *node) {
377
	assert(is_ia32_irn(node) && "need ia32 node to get ia32 attributes");
378
	return (ia32_attr_t *)get_irn_generic_attr(node);
379
380
}

381
382
383
384
385
const ia32_attr_t *get_ia32_attr_const(const ir_node *node) {
	assert(is_ia32_irn(node) && "need ia32 node to get ia32 attributes");
	return (const ia32_attr_t*) get_irn_generic_attr_const(node);
}

386
387
388
389
390
391
392
393
394
395
396
397
ia32_x87_attr_t *get_ia32_x87_attr(ir_node *node) {
	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;
}

const ia32_x87_attr_t *get_ia32_x87_attr_const(const ir_node *node) {
	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;
}

398
399
400
401
402
403
404
const ia32_asm_attr_t *get_ia32_asm_attr_const(const ir_node *node) {
	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;
}

405
406
407
408
409
410
411
ia32_immediate_attr_t *get_ia32_immediate_attr(ir_node *node) {
	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;
}

412
413
const ia32_immediate_attr_t *get_ia32_immediate_attr_const(const ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
414
415
	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);
416

Michael Beck's avatar
Michael Beck committed
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
	return imm_attr;
}

ia32_condcode_attr_t *get_ia32_condcode_attr(ir_node *node) {
	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;
}

const ia32_condcode_attr_t *get_ia32_condcode_attr_const(const ir_node *node) {
	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;
}

434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
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;
}

Michael Beck's avatar
Michael Beck committed
450
451
452
453
454
455
456
457
458
459
460
461
ia32_copyb_attr_t *get_ia32_copyb_attr(ir_node *node) {
	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;
}

const ia32_copyb_attr_t *get_ia32_copyb_attr_const(const ir_node *node) {
	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;
462
463
}

464
465
466
467
468
469
470
471
472
473
474
475
476
477
ia32_climbframe_attr_t *get_ia32_climbframe_attr(ir_node *node) {
	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;
}

const ia32_climbframe_attr_t *get_ia32_climbframe_attr_const(const ir_node *node) {
	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;
}

478
/**
479
 * Gets the type of an ia32 node.
480
 */
481
ia32_op_type_t get_ia32_op_type(const ir_node *node) {
482
	const ia32_attr_t *attr = get_ia32_attr_const(node);
483
	return attr->data.tp;
484
485
486
}

/**
487
 * Sets the type of an ia32 node.
488
 */
489
490
void set_ia32_op_type(ir_node *node, ia32_op_type_t tp) {
	ia32_attr_t *attr = get_ia32_attr(node);
491
	attr->data.tp     = tp;
492
493
}

494
495
ia32_am_type_t get_ia32_am_support(const ir_node *node)
{
Matthias Braun's avatar
Matthias Braun committed
496
497
498
499
	const ia32_attr_t *attr = get_ia32_attr_const(node);
	return attr->data.am_arity;
}

500
/**
501
 * Sets the supported address mode of an ia32 node
502
 */
503
504
505
506
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
507
508
}

509
/**
510
 * Gets the address mode offset as int.
511
 */
512
int get_ia32_am_offs_int(const ir_node *node) {
513
	const ia32_attr_t *attr = get_ia32_attr_const(node);
514
515
516
	return attr->am_offs;
}

517
/**
518
 * Sets the address mode offset from an int.
519
520
521
522
523
524
 */
void set_ia32_am_offs_int(ir_node *node, int offset) {
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->am_offs = offset;
}

525
526
527
528
529
void add_ia32_am_offs_int(ir_node *node, int offset) {
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->am_offs += offset;
}

530
/**
531
 * Returns the symconst entity associated to address mode.
532
 */
533
ir_entity *get_ia32_am_sc(const ir_node *node) {
534
	const ia32_attr_t *attr = get_ia32_attr_const(node);
535
536
537
538
	return attr->am_sc;
}

/**
539
 * Sets the symconst entity associated to address mode.
540
 */
541
void set_ia32_am_sc(ir_node *node, ir_entity *entity) {
542
	ia32_attr_t *attr = get_ia32_attr(node);
543
	attr->am_sc       = entity;
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
}

/**
 * Sets the sign bit for address mode symconst.
 */
void set_ia32_am_sc_sign(ir_node *node) {
	ia32_attr_t *attr     = get_ia32_attr(node);
	attr->data.am_sc_sign = 1;
}

/**
 * Clears the sign bit for address mode symconst.
 */
void clear_ia32_am_sc_sign(ir_node *node) {
	ia32_attr_t *attr     = get_ia32_attr(node);
	attr->data.am_sc_sign = 0;
}

/**
 * Returns the sign bit for address mode symconst.
 */
int is_ia32_am_sc_sign(const ir_node *node) {
566
	const ia32_attr_t *attr = get_ia32_attr_const(node);
567
568
569
	return attr->data.am_sc_sign;
}

570
571
572
/**
 * Gets the addr mode const.
 */
Michael Beck's avatar
Michael Beck committed
573
unsigned get_ia32_am_scale(const ir_node *node) {
574
	const ia32_attr_t *attr = get_ia32_attr_const(node);
575
	return attr->data.am_scale;
576
577
}

Christian Würdig's avatar
Christian Würdig committed
578
/**
579
 * Sets the index register scale for address mode.
Christian Würdig's avatar
Christian Würdig committed
580
 */
Michael Beck's avatar
Michael Beck committed
581
void set_ia32_am_scale(ir_node *node, unsigned scale) {
582
	ia32_attr_t *attr = get_ia32_attr(node);
Michael Beck's avatar
Michael Beck committed
583
	assert(scale <= 3 && "AM scale out of range [0 ... 3]");
Christian Würdig's avatar
Christian Würdig committed
584
	attr->data.am_scale = scale;
Christian Würdig's avatar
Christian Würdig committed
585
586
}

587
588
589
590
591
592
593
594
595
596
597
598
599
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));
	if(is_ia32_am_sc_sign(from))
		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);
}

600
/**
601
602
603
 * Sets the uses_frame flag.
 */
void set_ia32_use_frame(ir_node *node) {
Christian Würdig's avatar
Christian Würdig committed
604
	ia32_attr_t *attr    = get_ia32_attr(node);
605
606
607
608
609
	attr->data.use_frame = 1;
}

/**
 * Clears the uses_frame flag.
610
 */
611
void clear_ia32_use_frame(ir_node *node) {
Christian Würdig's avatar
Christian Würdig committed
612
	ia32_attr_t *attr    = get_ia32_attr(node);
613
614
615
616
617
618
619
	attr->data.use_frame = 0;
}

/**
 * Gets the uses_frame flag.
 */
int is_ia32_use_frame(const ir_node *node) {
620
	const ia32_attr_t *attr = get_ia32_attr_const(node);
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
	return attr->data.use_frame;
}

/**
 * Sets node to commutative.
 */
void set_ia32_commutative(ir_node *node) {
	ia32_attr_t *attr         = get_ia32_attr(node);
	attr->data.is_commutative = 1;
}

/**
 * Sets node to non-commutative.
 */
void clear_ia32_commutative(ir_node *node) {
	ia32_attr_t *attr         = get_ia32_attr(node);
	attr->data.is_commutative = 0;
638
639
640
}

/**
641
 * Checks if node is commutative.
642
 */
643
int is_ia32_commutative(const ir_node *node) {
644
	const ia32_attr_t *attr = get_ia32_attr_const(node);
645
	return attr->data.is_commutative;
646
647
}

648
void set_ia32_need_stackent(ir_node *node) {
Christian Würdig's avatar
Christian Würdig committed
649
	ia32_attr_t *attr     = get_ia32_attr(node);
650
	attr->data.need_stackent = 1;
Christian Würdig's avatar
Christian Würdig committed
651
652
}

653
void clear_ia32_need_stackent(ir_node *node) {
Christian Würdig's avatar
Christian Würdig committed
654
	ia32_attr_t *attr     = get_ia32_attr(node);
655
	attr->data.need_stackent = 0;
Christian Würdig's avatar
Christian Würdig committed
656
657
}

658
int is_ia32_need_stackent(const ir_node *node) {
659
	const ia32_attr_t *attr = get_ia32_attr_const(node);
660
	return attr->data.need_stackent;
Christian Würdig's avatar
Christian Würdig committed
661
662
}

663
664
665
666
667
668
669
670
671
672
void set_ia32_is_reload(ir_node *node) {
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->data.is_reload = 1;
}

int is_ia32_is_reload(const ir_node *node) {
	const ia32_attr_t *attr = get_ia32_attr_const(node);
	return attr->data.is_reload;
}

673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
void set_ia32_is_spill(ir_node *node) {
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->data.is_spill = 1;
}

int is_ia32_is_spill(const ir_node *node) {
	const ia32_attr_t *attr = get_ia32_attr_const(node);
	return attr->data.is_spill;
}

void set_ia32_is_remat(ir_node *node) {
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->data.is_remat = 1;
}

int is_ia32_is_remat(const ir_node *node) {
	const ia32_attr_t *attr = get_ia32_attr_const(node);
	return attr->data.is_remat;
}

693
694
695
696
/**
 * Gets the mode of the stored/loaded value (only set for Store/Load)
 */
ir_mode *get_ia32_ls_mode(const ir_node *node) {
697
	const ia32_attr_t *attr = get_ia32_attr_const(node);
698
	return attr->ls_mode;
699
700
701
702
703
704
}

/**
 * Sets the mode of the stored/loaded value (only set for Store/Load)
 */
void set_ia32_ls_mode(ir_node *node, ir_mode *mode) {
705
706
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->ls_mode     = mode;
707
708
}

709
/**
710
 * Gets the frame entity assigned to this node.
711
 */
712
ir_entity *get_ia32_frame_ent(const ir_node *node) {
713
	const ia32_attr_t *attr = get_ia32_attr_const(node);
714
715
716
717
	return attr->frame_ent;
}

/**
718
 * Sets the frame entity for this node.
719
 */
720
void set_ia32_frame_ent(ir_node *node, ir_entity *ent) {
721
722
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->frame_ent   = ent;
723
724
725
726
	if(ent != NULL)
		set_ia32_use_frame(node);
	else
		clear_ia32_use_frame(node);
727
728
}

Christian Würdig's avatar
Christian Würdig committed
729
730
731
732
733

/**
 * Gets the instruction latency.
 */
unsigned get_ia32_latency(const ir_node *node) {
734
735
736
	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
737
738
}

739
740
741
/**
 * Returns the argument register requirements of an ia32 node.
 */
Matthias Braun's avatar
Matthias Braun committed
742
const arch_register_req_t **get_ia32_in_req_all(const ir_node *node) {
743
	const ia32_attr_t *attr = get_ia32_attr_const(node);
Christian Würdig's avatar
Christian Würdig committed
744
	return attr->in_req;
745
746
}

747
748
749
/**
 * Sets the argument register requirements of an ia32 node.
 */
Matthias Braun's avatar
Matthias Braun committed
750
void set_ia32_in_req_all(ir_node *node, const arch_register_req_t **reqs) {
751
752
753
754
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->in_req      = reqs;
}

755
756
757
/**
 * Returns the result register requirements of an ia32 node.
 */
Matthias Braun's avatar
Matthias Braun committed
758
const arch_register_req_t **get_ia32_out_req_all(const ir_node *node) {
759
	const ia32_attr_t *attr = get_ia32_attr_const(node);
Christian Würdig's avatar
Christian Würdig committed
760
	return attr->out_req;
761
762
}

763
764
765
/**
 * Sets the result register requirements of an ia32 node.
 */
Matthias Braun's avatar
Matthias Braun committed
766
void set_ia32_out_req_all(ir_node *node, const arch_register_req_t **reqs) {
767
768
769
770
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->out_req     = reqs;
}

771
772
773
/**
 * Returns the argument register requirement at position pos of an ia32 node.
 */
Matthias Braun's avatar
Matthias Braun committed
774
const arch_register_req_t *get_ia32_in_req(const ir_node *node, int pos) {
775
	const ia32_attr_t *attr = get_ia32_attr_const(node);
Matthias Braun's avatar
Matthias Braun committed
776
777
778
779
	if(attr->in_req == NULL)
		return arch_no_register_req;

	return attr->in_req[pos];
780
781
782
783
784
}

/**
 * Returns the result register requirement at position pos of an ia32 node.
 */
Matthias Braun's avatar
Matthias Braun committed
785
const arch_register_req_t *get_ia32_out_req(const ir_node *node, int pos) {
786
	const ia32_attr_t *attr = get_ia32_attr_const(node);
Matthias Braun's avatar
Matthias Braun committed
787
788
789
790
	if(attr->out_req == NULL)
		return arch_no_register_req;

	return attr->out_req[pos];
791
792
}

793
/**
Christian Würdig's avatar
Christian Würdig committed
794
 * Sets the OUT register requirements at position pos.
795
 */
Matthias Braun's avatar
Matthias Braun committed
796
void set_ia32_req_out(ir_node *node, const arch_register_req_t *req, int pos) {
797
	ia32_attr_t *attr  = get_ia32_attr(node);
Christian Würdig's avatar
Christian Würdig committed
798
	attr->out_req[pos] = req;
799
800
801
}

/**
Christian Würdig's avatar
Christian Würdig committed
802
 * Sets the IN register requirements at position pos.
803
 */
Matthias Braun's avatar
Matthias Braun committed
804
void set_ia32_req_in(ir_node *node, const arch_register_req_t *req, int pos) {
805
	ia32_attr_t *attr = get_ia32_attr(node);
Christian Würdig's avatar
Christian Würdig committed
806
	attr->in_req[pos] = req;
807
808
}

Christian Würdig's avatar
Christian Würdig committed
809
/**
Michael Beck's avatar
Michael Beck committed
810
 * Returns the condition code of a node.
Christian Würdig's avatar
Christian Würdig committed
811
 */
Michael Beck's avatar
Michael Beck committed
812
long get_ia32_condcode(const ir_node *node)
Matthias Braun's avatar
Matthias Braun committed
813
{
Michael Beck's avatar
Michael Beck committed
814
	const ia32_condcode_attr_t *attr = get_ia32_condcode_attr_const(node);
Christian Würdig's avatar
Christian Würdig committed
815
816
817
818
	return attr->pn_code;
}

/**
Michael Beck's avatar
Michael Beck committed
819
 * Sets the condition code of a node
Christian Würdig's avatar
Christian Würdig committed
820
 */
Michael Beck's avatar
Michael Beck committed
821
void set_ia32_condcode(ir_node *node, long code)
Matthias Braun's avatar
Matthias Braun committed
822
{
Michael Beck's avatar
Michael Beck committed
823
824
825
826
827
828
829
830
831
832
833
	ia32_condcode_attr_t *attr = get_ia32_condcode_attr(node);
	attr->pn_code = code;
}

/**
 * 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;
834
835
}

836
/**
837
 * Get the list of available execution units.
838
 */
839
const be_execution_unit_t ***get_ia32_exec_units(const ir_node *node) {
840
	const ia32_attr_t *attr = get_ia32_attr_const(node);
841
	return attr->exec_units;
842
843
}

844
845
846
847
/**
 * Get the exception label attribute.
 */
unsigned get_ia32_exc_label(const ir_node *node) {
848
	const ia32_attr_t *attr = get_ia32_attr_const(node);
849
	return attr->data.has_except_label;
850
851
852
853
854
855
856
}

/**
 * Set the exception label attribute.
 */
void set_ia32_exc_label(ir_node *node, unsigned flag) {
	ia32_attr_t *attr = get_ia32_attr(node);
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
	attr->data.has_except_label = flag;
}

/**
 * Return the exception label id.
 */
ir_label_t get_ia32_exc_label_id(const ir_node *node) {
	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.
 */
void set_ia32_exc_label_id(ir_node *node, ir_label_t id) {
	ia32_attr_t *attr = get_ia32_attr(node);

	assert(attr->data.has_except_label);
	attr->exc_label = id;
878
879
}

Christian Würdig's avatar
Christian Würdig committed
880
881
882
883
884
#ifndef NDEBUG

/**
 * Returns the name of the original ir node.
 */
885
886
const char *get_ia32_orig_node(const ir_node *node)
{
887
	const ia32_attr_t *attr = get_ia32_attr_const(node);
Christian Würdig's avatar
Christian Würdig committed
888
889
890
	return attr->orig_node;
}

891
892
893
894
895
896
897
898
899
static const char *ia32_get_old_node_name(const ir_node *irn)
{
	struct obstack *obst = env_cg->isa->name_obst;

	lc_eoprintf(firm_get_arg_env(), obst, "%+F", irn);
	obstack_1grow(obst, 0);
	return obstack_finish(obst);
}

Christian Würdig's avatar
Christian Würdig committed
900
901
902
/**
 * Sets the name of the original ir node.
 */
903
904
905
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
906
907
908
909
910
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->orig_node   = name;
}

#endif /* NDEBUG */
911
912
913
914
915
916
917
918
919
920
921
922

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

923
924
/**
 * Returns whether or not the node is an AddrModeS node.
925
 */
Christian Würdig's avatar
Christian Würdig committed
926
int is_ia32_AddrModeS(const ir_node *node) {
927
	const ia32_attr_t *attr = get_ia32_attr_const(node);
928
	return (attr->data.tp == ia32_AddrModeS);
929
930
931
}

/**
932
 * Returns whether or not the node is an AddrModeD node.
933
 */
Christian Würdig's avatar
Christian Würdig committed
934
int is_ia32_AddrModeD(const ir_node *node) {
935
	const ia32_attr_t *attr = get_ia32_attr_const(node);
936
	return (attr->data.tp == ia32_AddrModeD);
Christian Würdig's avatar
Christian Würdig committed
937
}
938

939
940
void ia32_swap_left_right(ir_node *node)
{
941
942
943
944
	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
945
	assert(is_ia32_commutative(node));
946
	attr->data.ins_permuted = !attr->data.ins_permuted;
947
948
	set_irn_n(node, n_ia32_binary_left,  right);
	set_irn_n(node, n_ia32_binary_right, left);
949
950
}

951
952
953
/**
 * Initializes the nodes attributes.
 */
Matthias Braun's avatar
Matthias Braun committed
954
955
956
957
void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags,
                          const arch_register_req_t **in_reqs,
                          const arch_register_req_t **out_reqs,
                          const be_execution_unit_t ***execution_units,
958
                          int n_res)
959
{
Matthias Braun's avatar
Matthias Braun committed
960
961
962
	ir_graph        *irg  = get_irn_irg(node);
	struct obstack  *obst = get_irg_obstack(irg);
	ia32_attr_t     *attr = get_ia32_attr(node);
963
	backend_info_t  *info;
964

965
	arch_irn_set_flags(node, flags);
966
967
	set_ia32_in_req_all(node, in_reqs);
	set_ia32_out_req_all(node, out_reqs);
968

969
970
971
972
	attr->exec_units  = execution_units;
#ifndef NDEBUG
	attr->attr_type  |= IA32_ATTR_ia32_attr_t;
#endif
973

974
975
976
	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]));
977
978
}

979
980
981
982
983
984
void
init_ia32_x87_attributes(ir_node *res)
{
#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
985
986
#else
	(void) res;
987
#endif
988
	ia32_current_cg->do_x87_sim = 1;
989
990
}

991
992
993
994
995
996
void
init_ia32_asm_attributes(ir_node *res)
{
#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
997
998
#else
	(void) res;
999
1000
#endif
}