ia32_new_nodes.c 34.9 KB
Newer Older
1
2
/**
 * This file implements the creation of the achitecture specific firm opcodes
Christian Würdig's avatar
Christian Würdig committed
3
 * and the coresponding node constructors for the ia32 assembler irg.
4
5
6
7
8
9
10
11
 * @author Christian Wuerdig
 * $Id$
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

12
#ifdef HAVE_MALLOC_H
13
#include <malloc.h>
14
15
16
#endif

#ifdef HAVE_ALLOCA_H
Christian Würdig's avatar
Christian Würdig committed
17
#include <alloca.h>
18
19
#endif

20
21
22
23
24
25
26
27
#include <stdlib.h>

#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
28
#include "irop.h"
29
30
#include "firm_common_t.h"
#include "irvrfy_t.h"
31
#include "irprintf.h"
32
33
34
35
36

#include "../bearch.h"

#include "ia32_nodes_attr.h"
#include "ia32_new_nodes.h"
Christian Würdig's avatar
Christian Würdig committed
37
#include "gen_ia32_regalloc_if.h"
38
#include "gen_ia32_machine.h"
39
40

/**
41
42
43
 * Returns the ident of a SymConst.
 * @param symc  The SymConst
 * @return The ident of the SymConst
44
 */
45
static ident *get_sc_ident(ir_node *symc) {
46
47
48
	ir_entity *ent;
	ir_type   *owner;
	ident     *id;
49

Christian Würdig's avatar
Christian Würdig committed
50
51
	switch (get_SymConst_kind(symc)) {
		case symconst_addr_name:
52
			return get_SymConst_name(symc);
53

Christian Würdig's avatar
Christian Würdig committed
54
		case symconst_addr_ent:
Michael Beck's avatar
Michael Beck committed
55
56
57
58
			ent   = get_SymConst_entity(symc);
			owner = get_entity_owner(ent);
			id    = get_entity_ld_ident(ent);
			if (owner == get_tls_type()) {
59
60
61
62
				if (get_entity_visibility(ent) == visibility_external_allocated)
					id = mangle(id, new_id_from_chars("@INDNTPOFF", 10));
				else
					id = mangle(id, new_id_from_chars("@NTPOFF", 7));
Michael Beck's avatar
Michael Beck committed
63
64
			}
			return id;
65

Christian Würdig's avatar
Christian Würdig committed
66
67
68
		default:
			assert(0 && "Unsupported SymConst");
	}
Christian Würdig's avatar
Christian Würdig committed
69

Christian Würdig's avatar
Christian Würdig committed
70
	return NULL;
71
72
}

73
74
75
76
77
78
79
/**
 * returns true if a node has x87 registers
 */
int ia32_has_x87_register(const ir_node *n) {
	assert(is_ia32_irn(n) && "Need ia32 node.");
	return is_irn_machine_user(n, 0);
}
80
81
82
83
84
85
86
87
88
89
90
91

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

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/**
 * Returns a string containing the names of all registers within the limited bitset
 */
static char *get_limited_regs(const arch_register_req_t *req, char *buf, int max) {
	bitset_t *bs   = bitset_alloca(req->cls->n_regs);
	char     *p    = buf;
	int       size = 0;
	int       i, cnt;

	req->limited(NULL, bs);

	for (i = 0; i < req->cls->n_regs; i++) {
		if (bitset_is_set(bs, i)) {
			cnt = snprintf(p, max - size, " %s", req->cls->regs[i].name);
			if (cnt < 0) {
				fprintf(stderr, "dumper problem, exiting\n");
				exit(1);
			}

			p    += cnt;
			size += cnt;

			if (size >= max)
				break;
		}
	}

	return buf;
}

/**
 * Dumps the register requirements for either in or out.
 */
static void dump_reg_req(FILE *F, ir_node *n, const ia32_register_req_t **reqs, int inout) {
	char *dir = inout ? "out" : "in";
	int   max = inout ? get_ia32_n_res(n) : get_irn_arity(n);
	char *buf = alloca(1024);
	int   i;

	memset(buf, 0, 1024);

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

			if (reqs[i]->req.type == arch_register_req_type_none) {
				fprintf(F, " n/a");
			}

			if (reqs[i]->req.type & arch_register_req_type_normal) {
				fprintf(F, " %s", reqs[i]->req.cls->name);
			}

			if (reqs[i]->req.type & arch_register_req_type_limited) {
				fprintf(F, " %s", get_limited_regs(&reqs[i]->req, buf, 1024));
			}

			if (reqs[i]->req.type & arch_register_req_type_should_be_same) {
150
				ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->same_pos));
151
152
153
			}

			if (reqs[i]->req.type & arch_register_req_type_should_be_different) {
154
				ir_fprintf(F, " different from %+F", get_irn_n(n, reqs[i]->different_pos));
155
156
157
158
159
160
161
162
163
164
165
166
			}

			fprintf(F, "\n");
		}

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

167
168
169
170
171
172
173
/**
 * 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
 */
174
static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
175
176
	ir_mode     *mode = NULL;
	int          bad  = 0;
177
	int          i, n_res, am_flav, flags;
Christian Würdig's avatar
Christian Würdig committed
178
	const ia32_register_req_t **reqs;
Christian Würdig's avatar
Christian Würdig committed
179
180
181
182
	const arch_register_t     **slots;

	switch (reason) {
		case dump_node_opcode_txt:
183
			fprintf(F, "%s", get_irn_opname(n));
Christian Würdig's avatar
Christian Würdig committed
184
185
186
187
188
			break;

		case dump_node_mode_txt:
			mode = get_irn_mode(n);

Christian Würdig's avatar
Christian Würdig committed
189
			if (is_ia32_Ld(n) || is_ia32_St(n)) {
190
				mode = get_ia32_ls_mode(n);
Christian Würdig's avatar
Christian Würdig committed
191
192
			}

Christian Würdig's avatar
Christian Würdig committed
193
			fprintf(F, "[%s]", mode ? get_mode_name(mode) : "?NOMODE?");
Christian Würdig's avatar
Christian Würdig committed
194
195
196
			break;

		case dump_node_nodeattr_txt:
197
			if (is_ia32_ImmConst(n) || is_ia32_ImmSymConst(n) || is_ia32_Cnst(n)) {
Christian Würdig's avatar
Christian Würdig committed
198
				char       *pref = is_ia32_ImmSymConst(n) || (get_ia32_op_type(n) == ia32_SymConst) ? "SymC " : "";
Michael Beck's avatar
Michael Beck committed
199
				const char *cnst = get_ia32_cnst(n);
200

201
				fprintf(F, "[%s%s]", pref, cnst ? cnst : "NONE");
Christian Würdig's avatar
Christian Würdig committed
202
203
			}

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

			break;

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

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

			/* dump OUT requirements */
226
			if (n_res > 0) {
227
				reqs = get_ia32_out_req_all(n);
228
				dump_reg_req(F, n, reqs, 1);
Christian Würdig's avatar
Christian Würdig committed
229
230
231
232
			}

			/* dump assigned registers */
			slots = get_ia32_slots(n);
233
234
			if (slots && n_res > 0) {
				for (i = 0; i < n_res; i++) {
235
236
237
238
239
240
241
242
243
					const arch_register_t *reg;

					/* retrieve "real" x87 register */
					if (ia32_has_x87_register(n))
						reg = get_ia32_attr(n)->x87[i + 2];
					else
						reg = slots[i];

					fprintf(F, "reg #%d = %s\n", i, reg ? arch_register_get_name(reg) : "n/a");
Christian Würdig's avatar
Christian Würdig committed
244
				}
Christian Würdig's avatar
Christian Würdig committed
245
				fprintf(F, "\n");
Christian Würdig's avatar
Christian Würdig committed
246
			}
247
248
249

			/* dump op type */
			fprintf(F, "op = ");
250
			switch (get_ia32_op_type(n)) {
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
				case ia32_Normal:
					fprintf(F, "Normal");
					break;
				case ia32_Const:
					fprintf(F, "Const");
					break;
				case ia32_SymConst:
					fprintf(F, "SymConst");
					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
266
				default:
267
					fprintf(F, "unknown (%d)", get_ia32_op_type(n));
Christian Würdig's avatar
Christian Würdig committed
268
					break;
269
270
271
			}
			fprintf(F, "\n");

272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
			/* dump immop type */
			fprintf(F, "immediate = ");
			switch (get_ia32_immop_type(n)) {
				case ia32_ImmNone:
					fprintf(F, "None");
					break;
				case ia32_ImmConst:
					fprintf(F, "Const");
					break;
				case ia32_ImmSymConst:
					fprintf(F, "SymConst");
					break;
				default:
					fprintf(F, "unknown (%d)", get_ia32_immop_type(n));
					break;
			}
			fprintf(F, "\n");
289
290
291

			/* dump supported am */
			fprintf(F, "AM support = ");
292
			switch (get_ia32_am_support(n)) {
293
294
295
296
297
298
299
300
301
302
303
304
				case ia32_am_None:
					fprintf(F, "none");
					break;
				case ia32_am_Source:
					fprintf(F, "source only (Load)");
					break;
				case ia32_am_Dest:
					fprintf(F, "dest only (Load+Store)");
					break;
				case ia32_am_Full:
					fprintf(F, "full");
					break;
Christian Würdig's avatar
Christian Würdig committed
305
				default:
306
					fprintf(F, "unknown (%d)", get_ia32_am_support(n));
Christian Würdig's avatar
Christian Würdig committed
307
					break;
308
309
			}
			fprintf(F, "\n");
Christian Würdig's avatar
Christian Würdig committed
310

Christian Würdig's avatar
Christian Würdig committed
311
312
			/* dump am flavour */
			fprintf(F, "AM flavour =");
313
314
			am_flav = get_ia32_am_flavour(n);
			if (am_flav == ia32_am_N) {
Christian Würdig's avatar
Christian Würdig committed
315
316
317
				fprintf(F, " none");
			}
			else {
318
				if (am_flav & ia32_O) {
Christian Würdig's avatar
Christian Würdig committed
319
320
					fprintf(F, " O");
				}
321
				if (am_flav & ia32_B) {
Christian Würdig's avatar
Christian Würdig committed
322
323
					fprintf(F, " B");
				}
324
				if (am_flav & ia32_I) {
Christian Würdig's avatar
Christian Würdig committed
325
326
					fprintf(F, " I");
				}
327
				if (am_flav & ia32_S) {
Christian Würdig's avatar
Christian Würdig committed
328
329
330
					fprintf(F, " S");
				}
			}
331
			fprintf(F, " (%d)\n", am_flav);
Christian Würdig's avatar
Christian Würdig committed
332

333
334
			/* dump AM offset */
			fprintf(F, "AM offset = ");
335
			if (get_ia32_am_offs(n)) {
336
337
338
339
340
341
				fprintf(F, "%s", get_ia32_am_offs(n));
			}
			else {
				fprintf(F, "n/a");
			}
			fprintf(F, "\n");
Christian Würdig's avatar
Christian Würdig committed
342

Matthias Braun's avatar
Matthias Braun committed
343
344
345
346
347
			/* dump AM symconst */
			if(get_ia32_am_sc(n) != NULL) {
				fprintf(F, "AM symconst = %s\n", get_id_str(get_ia32_am_sc(n)));
			}

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

351
			/* dump pn code */
352
			fprintf(F, "pn_code = %ld\n", get_ia32_pncode(n));
Christian Würdig's avatar
Christian Würdig committed
353

354
355
			/* dump n_res */
			fprintf(F, "n_res = %d\n", get_ia32_n_res(n));
Christian Würdig's avatar
Christian Würdig committed
356

357
358
359
360
361
362
			/* dump use_frame */
			fprintf(F, "use_frame = %d\n", is_ia32_use_frame(n));

			/* commutative */
			fprintf(F, "commutative = %d\n", is_ia32_commutative(n));

363
364
365
366
367
368
369
370
371
			/* emit cl */
			fprintf(F, "emit cl instead of ecx = %d\n", is_ia32_emit_cl(n));

			/* got lea */
			fprintf(F, "got loea = %d\n", is_ia32_got_lea(n));

			/* got reload */
			fprintf(F, "got reload = %d\n", is_ia32_got_reload(n));

Christian Würdig's avatar
Christian Würdig committed
372
373
374
			/* dump latency */
			fprintf(F, "latency = %d\n", get_ia32_latency(n));

375
376
			/* dump flags */
			fprintf(F, "flags =");
377
378
			flags = get_ia32_flags(n);
			if (flags == arch_irn_flags_none) {
Christian Würdig's avatar
Christian Würdig committed
379
				fprintf(F, " none");
380
			}
Christian Würdig's avatar
Christian Würdig committed
381
			else {
382
				if (flags & arch_irn_flags_dont_spill) {
Christian Würdig's avatar
Christian Würdig committed
383
384
					fprintf(F, " unspillable");
				}
385
				if (flags & arch_irn_flags_rematerializable) {
Christian Würdig's avatar
Christian Würdig committed
386
387
					fprintf(F, " remat");
				}
388
				if (flags & arch_irn_flags_ignore) {
Christian Würdig's avatar
Christian Würdig committed
389
390
					fprintf(F, " ignore");
				}
391
392
393
				if (flags & arch_irn_flags_modify_sp) {
					fprintf(F, " modify_sp");
				}
Christian Würdig's avatar
Christian Würdig committed
394
			}
395
396
397
398
399
400
401
402
403
404
405
			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");
406

407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
			/* 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");

			fprintf(F, "res_mode = ");
			if (get_ia32_res_mode(n)) {
				ir_fprintf(F, "%+F", get_ia32_res_mode(n));
			}
			else {
				fprintf(F, "n/a");
			}
			fprintf(F, "\n");

			fprintf(F, "src_mode = ");
			if (get_ia32_src_mode(n)) {
				ir_fprintf(F, "%+F", get_ia32_src_mode(n));
			}
			else {
				fprintf(F, "n/a");
			}
			fprintf(F, "\n");

			fprintf(F, "tgt_mode = ");
			if (get_ia32_tgt_mode(n)) {
				ir_fprintf(F, "%+F", get_ia32_tgt_mode(n));
			}
			else {
				fprintf(F, "n/a");
			}
			fprintf(F, "\n");

Christian Würdig's avatar
Christian Würdig committed
444
445
446
447
448
449
450
451
452
453
454
455
#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 */

456
457
			fprintf(F, "=== IA32 attr end ===\n");
			/* end of: case dump_node_info_txt */
Christian Würdig's avatar
Christian Würdig committed
458
			break;
459
	}
460

Christian Würdig's avatar
Christian Würdig committed
461
	return bad;
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
}



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

477
478
479
480
481
/**
 * Returns an ident for the given tarval tv.
 */
static ident *get_ident_for_tv(tarval *tv) {
	char buf[1024];
482
483
	int len = tarval_snprintf(buf, sizeof(buf), tv);
	assert(len);
484
485
	return new_id_from_str(buf);
}
486

487
488
489
490
/**
 * Wraps get_irn_generic_attr() as it takes no const ir_node, so we need to do a cast.
 * Firm was made by people hating const :-(
 */
491
ia32_attr_t *get_ia32_attr(const ir_node *node) {
492
	assert(is_ia32_irn(node) && "need ia32 node to get ia32 attributes");
493
	return (ia32_attr_t *)get_irn_generic_attr((ir_node *)node);
494
495
496
}

/**
497
 * Gets the type of an ia32 node.
498
 */
499
500
ia32_op_type_t get_ia32_op_type(const ir_node *node) {
	ia32_attr_t *attr = get_ia32_attr(node);
501
	return attr->data.tp;
502
503
504
}

/**
505
 * Sets the type of an ia32 node.
506
 */
507
508
void set_ia32_op_type(ir_node *node, ia32_op_type_t tp) {
	ia32_attr_t *attr = get_ia32_attr(node);
509
	attr->data.tp     = tp;
510
511
}

512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
/**
 * Gets the immediate op type of an ia32 node.
 */
ia32_immop_type_t get_ia32_immop_type(const ir_node *node) {
	ia32_attr_t *attr = get_ia32_attr(node);
	return attr->data.imm_tp;
}

/**
 * Sets the immediate op type of an ia32 node.
 */
void set_ia32_immop_type(ir_node *node, ia32_immop_type_t tp) {
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->data.imm_tp = tp;
}

528
/**
529
 * Gets the supported addrmode of an ia32 node
530
 */
531
532
ia32_am_type_t get_ia32_am_support(const ir_node *node) {
	ia32_attr_t *attr = get_ia32_attr(node);
533
	return attr->data.am_support;
534
535
536
}

/**
537
 * Sets the supported addrmode of an ia32 node
538
 */
539
void set_ia32_am_support(ir_node *node, ia32_am_type_t am_tp) {
Christian Würdig's avatar
Christian Würdig committed
540
541
	ia32_attr_t *attr     = get_ia32_attr(node);
	attr->data.am_support = am_tp;
542
543
}

Christian Würdig's avatar
Christian Würdig committed
544
545
546
/**
 * Gets the addrmode flavour of an ia32 node
 */
Christian Würdig's avatar
Christian Würdig committed
547
ia32_am_flavour_t get_ia32_am_flavour(const ir_node *node) {
Christian Würdig's avatar
Christian Würdig committed
548
	ia32_attr_t *attr = get_ia32_attr(node);
549
	return attr->data.am_flavour;
Christian Würdig's avatar
Christian Würdig committed
550
551
552
553
554
555
}

/**
 * Sets the addrmode flavour of an ia32 node
 */
void set_ia32_am_flavour(ir_node *node, ia32_am_flavour_t am_flavour) {
Christian Würdig's avatar
Christian Würdig committed
556
557
	ia32_attr_t *attr     = get_ia32_attr(node);
	attr->data.am_flavour = am_flavour;
Christian Würdig's avatar
Christian Würdig committed
558
559
}

560
/**
561
 * Joins all offsets to one string with adds.
562
 */
563
564
char *get_ia32_am_offs(const ir_node *node) {
	ia32_attr_t *attr = get_ia32_attr(node);
Matthias Braun's avatar
Matthias Braun committed
565
	static char res[64];
566

567
	snprintf(res, sizeof(res), "%+d", attr->am_offs);
568

569
	return res;
570
}
571

572
573
574
/**
 * Gets the addressmode offset as long.
 */
575
int get_ia32_am_offs_int(const ir_node *node) {
576
577
578
579
	ia32_attr_t *attr = get_ia32_attr(node);
	return attr->am_offs;
}

580
/**
581
 * Add an offset for addrmode.
582
 */
583
584
static void extend_ia32_am_offs(ir_node *node, char *offset, char op) {
	ia32_attr_t *attr = get_ia32_attr(node);
Michael Beck's avatar
BugFix:    
Michael Beck committed
585
	int res, o;
586

587
	if (offset == NULL || offset[0] == '\0')
588
589
		return;

590
591
592
593
	if (offset[0] == '-')
		res = sscanf(offset, "%d", &o);
	else
		res = sscanf(offset, "%u", &o);
Michael Beck's avatar
BugFix:    
Michael Beck committed
594
	assert(res == 1);
595

596
597
598
	if (op == '-')
		attr->am_offs -= o;
	else if (op == '+')
Matthias Braun's avatar
Matthias Braun committed
599
		attr->am_offs += o;
600
601
	else
		assert(0);
602
603
604
605
606
}

/**
 * Add an offset for addrmode.
 */
607
608
void add_ia32_am_offs(ir_node *node, const char *offset) {
	extend_ia32_am_offs(node, (char *)offset, '+');
609
610
}

611
612
613
614
615
void add_ia32_am_offs_int(ir_node *node, int offset) {
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->am_offs += offset;
}

616
617
618
/**
 * Sub an offset for addrmode.
 */
619
620
void sub_ia32_am_offs(ir_node *node, const char *offset) {
	extend_ia32_am_offs(node, (char *)offset, '-');
621
}
622

623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
/**
 * Returns the symconst ident associated to addrmode.
 */
ident *get_ia32_am_sc(const ir_node *node) {
	ia32_attr_t *attr = get_ia32_attr(node);
	return attr->am_sc;
}

/**
 * Sets the symconst ident associated to addrmode.
 */
void set_ia32_am_sc(ir_node *node, ident *sc) {
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->am_sc       = sc;
}

/**
 * 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) {
	ia32_attr_t *attr = get_ia32_attr(node);
	return attr->data.am_sc_sign;
}

663
664
665
/**
 * Gets the addr mode const.
 */
666
667
int get_ia32_am_scale(const ir_node *node) {
	ia32_attr_t *attr = get_ia32_attr(node);
668
	return attr->data.am_scale;
669
670
}

Christian Würdig's avatar
Christian Würdig committed
671
/**
672
 * Sets the index register scale for addrmode.
Christian Würdig's avatar
Christian Würdig committed
673
 */
674
void set_ia32_am_scale(ir_node *node, int scale) {
Christian Würdig's avatar
Christian Würdig committed
675
676
	ia32_attr_t *attr   = get_ia32_attr(node);
	attr->data.am_scale = scale;
Christian Würdig's avatar
Christian Würdig committed
677
678
679
}

/**
680
 * Return the tarval of an immediate operation or NULL in case of SymConst
Christian Würdig's avatar
Christian Würdig committed
681
 */
682
tarval *get_ia32_Immop_tarval(const ir_node *node) {
683
	ia32_attr_t *attr = get_ia32_attr(node);
684
    return attr->cnst_val.tv;
Christian Würdig's avatar
Christian Würdig committed
685
686
}

687
688
689
690
/**
 * Sets the attributes of an immediate operation to the specified tarval
 */
void set_ia32_Immop_tarval(ir_node *node, tarval *tv) {
691
	ia32_attr_t *attr = get_ia32_attr(node);
692
693
	attr->cnst_val.tv = tv;
	attr->cnst        = get_ident_for_tv(tv);
694
695
}

696
/**
697
 * Gets the string representation of the internal const (tv or symconst)
698
 */
699
const char *get_ia32_cnst(const ir_node *node) {
700
	ia32_attr_t *attr = get_ia32_attr(node);
701
702
	if (! attr->cnst)
		return NULL;
703
	return get_id_str(attr->cnst);
704
705
}

706
707
708
/**
 * Sets the string representation of the internal const.
 */
Matthias Braun's avatar
Matthias Braun committed
709
void set_ia32_cnst(ir_node *node, const char *cnst) {
710
	ia32_attr_t *attr = get_ia32_attr(node);
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
	attr->cnst        = new_id_from_str(cnst);
}

/**
 * Gets the ident representation of the internal const (tv or symconst)
 */
ident *get_ia32_id_cnst(const ir_node *node) {
	ia32_attr_t *attr = get_ia32_attr(node);
	return attr->cnst;
}

/**
 * Sets the ident representation of the internal const.
 */
void set_ia32_id_cnst(ir_node *node, ident *cnst) {
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->cnst        = cnst;
728
729
}

730
/**
731
732
733
 * Sets the uses_frame flag.
 */
void set_ia32_use_frame(ir_node *node) {
Christian Würdig's avatar
Christian Würdig committed
734
	ia32_attr_t *attr    = get_ia32_attr(node);
735
736
737
738
739
	attr->data.use_frame = 1;
}

/**
 * Clears the uses_frame flag.
740
 */
741
void clear_ia32_use_frame(ir_node *node) {
Christian Würdig's avatar
Christian Würdig committed
742
	ia32_attr_t *attr    = get_ia32_attr(node);
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
	attr->data.use_frame = 0;
}

/**
 * Gets the uses_frame flag.
 */
int is_ia32_use_frame(const ir_node *node) {
	ia32_attr_t *attr = get_ia32_attr(node);
	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;
768
769
770
}

/**
771
 * Checks if node is commutative.
772
 */
773
int is_ia32_commutative(const ir_node *node) {
774
	ia32_attr_t *attr = get_ia32_attr(node);
775
	return attr->data.is_commutative;
776
777
}

Christian Würdig's avatar
Christian Würdig committed
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
/**
 * Sets node emit_cl.
 */
void set_ia32_emit_cl(ir_node *node) {
	ia32_attr_t *attr  = get_ia32_attr(node);
	attr->data.emit_cl = 1;
}

/**
 * Clears node emit_cl.
 */
void clear_ia32_emit_cl(ir_node *node) {
	ia32_attr_t *attr  = get_ia32_attr(node);
	attr->data.emit_cl = 0;
}

/**
795
 * Checks if node needs %cl.
Christian Würdig's avatar
Christian Würdig committed
796
797
798
799
800
801
 */
int is_ia32_emit_cl(const ir_node *node) {
	ia32_attr_t *attr = get_ia32_attr(node);
	return attr->data.emit_cl;
}

802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
/**
 * Sets node got_lea.
 */
void set_ia32_got_lea(ir_node *node) {
	ia32_attr_t *attr  = get_ia32_attr(node);
	attr->data.got_lea = 1;
}

/**
 * Clears node got_lea.
 */
void clear_ia32_got_lea(ir_node *node) {
	ia32_attr_t *attr  = get_ia32_attr(node);
	attr->data.got_lea = 0;
}

/**
 * Checks if node got lea.
 */
int is_ia32_got_lea(const ir_node *node) {
	ia32_attr_t *attr = get_ia32_attr(node);
	return attr->data.got_lea;
}

Christian Würdig's avatar
Christian Würdig committed
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
/**
 * Sets node got_reload.
 */
void set_ia32_got_reload(ir_node *node) {
	ia32_attr_t *attr     = get_ia32_attr(node);
	attr->data.got_reload = 1;
}

/**
 * Clears node got_reload.
 */
void clear_ia32_got_reload(ir_node *node) {
	ia32_attr_t *attr     = get_ia32_attr(node);
	attr->data.got_reload = 0;
}

/**
 * Checks if node got reload.
 */
int is_ia32_got_reload(const ir_node *node) {
	ia32_attr_t *attr = get_ia32_attr(node);
	return attr->data.got_reload;
}

850
851
852
853
/**
 * Gets the mode of the stored/loaded value (only set for Store/Load)
 */
ir_mode *get_ia32_ls_mode(const ir_node *node) {
854
855
	ia32_attr_t *attr = get_ia32_attr(node);
	return attr->ls_mode;
856
857
858
859
860
861
}

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

866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
/**
 * Gets the mode of the result.
 */
ir_mode *get_ia32_res_mode(const ir_node *node) {
	ia32_attr_t *attr = get_ia32_attr(node);
	return attr->res_mode;
}

/**
 * Sets the mode of the result.
 */
void set_ia32_res_mode(ir_node *node, ir_mode *mode) {
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->res_mode    = mode;
}

882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
/**
 * Gets the source mode of conversion.
 */
ir_mode *get_ia32_src_mode(const ir_node *node) {
	ia32_attr_t *attr = get_ia32_attr(node);
	return attr->src_mode;
}

/**
 * Sets the source mode of conversion.
 */
void set_ia32_src_mode(ir_node *node, ir_mode *mode) {
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->src_mode    = mode;
}

/**
 * Gets the target mode of conversion.
 */
ir_mode *get_ia32_tgt_mode(const ir_node *node) {
	ia32_attr_t *attr = get_ia32_attr(node);
	return attr->tgt_mode;
}

/**
 * Sets the target mode of conversion.
 */
void set_ia32_tgt_mode(ir_node *node, ir_mode *mode) {
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->tgt_mode    = mode;
}

914
/**
915
 * Gets the frame entity assigned to this node.
916
 */
917
ir_entity *get_ia32_frame_ent(const ir_node *node) {
918
919
920
921
922
	ia32_attr_t *attr = get_ia32_attr(node);
	return attr->frame_ent;
}

/**
923
 * Sets the frame entity for this node.
924
 */
925
void set_ia32_frame_ent(ir_node *node, ir_entity *ent) {
926
927
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->frame_ent   = ent;
928
	set_ia32_use_frame(node);
929
930
}

Christian Würdig's avatar
Christian Würdig committed
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947

/**
 * Gets the instruction latency.
 */
unsigned get_ia32_latency(const ir_node *node) {
	ia32_attr_t *attr = get_ia32_attr(node);
	return attr->latency;
}

/**
* Sets the instruction latency.
*/
void set_ia32_latency(ir_node *node, unsigned latency) {
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->latency     = latency;
}

948
949
950
/**
 * Returns the argument register requirements of an ia32 node.
 */
Christian Würdig's avatar
Christian Würdig committed
951
const ia32_register_req_t **get_ia32_in_req_all(const ir_node *node) {
952
	ia32_attr_t *attr = get_ia32_attr(node);
Christian Würdig's avatar
Christian Würdig committed
953
	return attr->in_req;
954
955
}

956
957
958
959
960
961
962
963
/**
 * Sets the argument register requirements of an ia32 node.
 */
void set_ia32_in_req_all(ir_node *node, const ia32_register_req_t **reqs) {
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->in_req      = reqs;
}

964
965
966
/**
 * Returns the result register requirements of an ia32 node.
 */
Christian Würdig's avatar
Christian Würdig committed
967
const ia32_register_req_t **get_ia32_out_req_all(const ir_node *node) {
968
	ia32_attr_t *attr = get_ia32_attr(node);
Christian Würdig's avatar
Christian Würdig committed
969
	return attr->out_req;
970
971
}

972
973
974
975
976
977
978
979
/**
 * Sets the result register requirements of an ia32 node.
 */
void set_ia32_out_req_all(ir_node *node, const ia32_register_req_t **reqs) {
	ia32_attr_t *attr = get_ia32_attr(node);
	attr->out_req     = reqs;
}

980
981
982
/**
 * Returns the argument register requirement at position pos of an ia32 node.
 */
Christian Würdig's avatar
Christian Würdig committed
983
const ia32_register_req_t *get_ia32_in_req(const ir_node *node, int pos) {
984
	ia32_attr_t *attr = get_ia32_attr(node);
985
	return attr->in_req != NULL ? attr->in_req[pos] : NULL;
986
987
988
989
990
}

/**
 * Returns the result register requirement at position pos of an ia32 node.
 */
Christian Würdig's avatar
Christian Würdig committed
991
const ia32_register_req_t *get_ia32_out_req(const ir_node *node, int pos) {
992
	ia32_attr_t *attr = get_ia32_attr(node);
993
	return attr->out_req != NULL ? attr->out_req[pos] : NULL;
994
995
}

996
/**
Christian Würdig's avatar
Christian Würdig committed
997
 * Sets the OUT register requirements at position pos.
998
 */
Christian Würdig's avatar
Christian Würdig committed
999
void set_ia32_req_out(ir_node *node, const ia32_register_req_t *req, int pos) {
1000
	ia32_attr_t *attr  = get_ia32_attr(node);
For faster browsing, not all history is shown. View entire blame