ia32_emitter.c 89 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
/*
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
Christian Würdig's avatar
Christian Würdig committed
4
5
 */

6
/**
7
 * @file
Christian Würdig's avatar
Christian Würdig committed
8
9
 * @brief       This file implements the ia32 node emitter.
 * @author      Christian Wuerdig, Matthias Braun
10
11
 *
 * Summary table for x86 floatingpoint compares:
12
13
 * (remember effect of unordered on x86: ZF=1, PF=1, CF=1)
 *
14
15
16
17
18
 *   pnc_Eq  => !P && E
 *   pnc_Lt  => !P && B
 *   pnc_Le  => !P && BE
 *   pnc_Gt  => A
 *   pnc_Ge  => AE
19
 *   pnc_Lg  => NE
20
21
22
23
24
25
26
 *   pnc_Leg => NP  (ordered)
 *   pnc_Uo  => P
 *   pnc_Ue  => E
 *   pnc_Ul  => B
 *   pnc_Ule => BE
 *   pnc_Ug  => P || A
 *   pnc_Uge => P || AE
27
 *   pnc_Ne  => P || NE
28
 */
29
#include "config.h"
Christian Würdig's avatar
Christian Würdig committed
30

Christian Würdig's avatar
Christian Würdig committed
31
32
#include <limits.h>

33
#include "xmalloc.h"
34
35
#include "tv.h"
#include "iredges.h"
Christian Würdig's avatar
Christian Würdig committed
36
37
38
39
#include "debug.h"
#include "irgwalk.h"
#include "irprintf.h"
#include "irop_t.h"
Christian Würdig's avatar
Christian Würdig committed
40
#include "irargs_t.h"
41
#include "irprog_t.h"
42
#include "iredges_t.h"
43
#include "irtools.h"
44
#include "execfreq.h"
45
#include "error.h"
46
#include "dbginfo.h"
47
#include "lc_opts.h"
48
#include "ircons.h"
Christian Würdig's avatar
Christian Würdig committed
49

50
51
52
#include "besched.h"
#include "benode.h"
#include "beabi.h"
53
#include "bedwarf.h"
54
55
#include "beemitter.h"
#include "begnuas.h"
56
#include "beutil.h"
Christian Würdig's avatar
Christian Würdig committed
57

58
#include "ia32_emitter.h"
59
#include "ia32_common_transform.h"
Christian Würdig's avatar
Christian Würdig committed
60
#include "gen_ia32_emitter.h"
Christian Würdig's avatar
Christian Würdig committed
61
#include "gen_ia32_regalloc_if.h"
62
63
#include "ia32_nodes_attr.h"
#include "ia32_new_nodes.h"
64
#include "ia32_architecture.h"
Christian Würdig's avatar
Christian Würdig committed
65
#include "bearch_ia32_t.h"
Christian Würdig's avatar
Christian Würdig committed
66

67
68
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)

69
static const ia32_isa_t *isa;
70
static char              pic_base_label[128];
71
static ir_label_t        exc_label_id;
72
static int               mark_spill_reload = 0;
73
static int               do_pic;
74

75
76
77
78
static bool              sp_relative;
static int               frame_type_size;
static int               callframe_offset;

79
80
81
/** Return the next block in Block schedule */
static ir_node *get_prev_block_sched(const ir_node *block)
{
82
	return (ir_node*)get_irn_link(block);
83
84
}

85
/** Checks if the current block is a fall-through target. */
86
static int is_fallthrough(const ir_node *cfgpred)
87
88
89
{
	ir_node *pred;

Christoph Mallon's avatar
Christoph Mallon committed
90
	if (!is_Proj(cfgpred))
91
		return 1;
92
	pred = get_Proj_pred(cfgpred);
Christoph Mallon's avatar
Christoph Mallon committed
93
	if (is_ia32_SwitchJmp(pred))
94
		return 0;
95

96
	return 1;
97
98
}

99
100
101
102
/**
 * returns non-zero if the given block needs a label
 * because of being a jump-target (and not a fall-through)
 */
103
static int block_needs_label(const ir_node *block)
104
{
105
	int need_label = 1;
106
107
	int  n_cfgpreds = get_Block_n_cfgpreds(block);

108
	if (get_Block_entity(block) != NULL)
109
110
		return 1;

111
	if (n_cfgpreds == 0) {
112
		need_label = 0;
113
	} else if (n_cfgpreds == 1) {
Christoph Mallon's avatar
Christoph Mallon committed
114
115
		ir_node *cfgpred       = get_Block_cfgpred(block, 0);
		ir_node *cfgpred_block = get_nodes_block(cfgpred);
116
117
118

		if (get_prev_block_sched(block) == cfgpred_block
				&& is_fallthrough(cfgpred)) {
119
			need_label = 0;
120
121
122
123
124
125
		}
	}

	return need_label;
}

Michael Beck's avatar
Michael Beck committed
126
/**
127
 * Add a number to a prefix. This number will not be used a second time.
Michael Beck's avatar
Michael Beck committed
128
 */
129
130
static char *get_unique_label(char *buf, size_t buflen, const char *prefix)
{
131
	static unsigned long id = 0;
132
	snprintf(buf, buflen, "%s%s%lu", be_gas_get_private_prefix(), prefix, ++id);
133
134
135
	return buf;
}

Michael Beck's avatar
Michael Beck committed
136
137
138
/**
 * Emit the name of the 8bit low register
 */
139
140
static void emit_8bit_register(const arch_register_t *reg)
{
141
142
	assert(reg->index == REG_GP_EAX || reg->index == REG_GP_EBX
			|| reg->index == REG_GP_ECX || reg->index == REG_GP_EDX);
Christian Würdig's avatar
Christian Würdig committed
143

144
	be_emit_char('%');
145
	be_emit_char(reg->name[1]); /* get the basic name of the register */
146
147
148
	be_emit_char('l');
}

Michael Beck's avatar
Michael Beck committed
149
150
151
152
153
/**
 * Emit the name of the 8bit high register
 */
static void emit_8bit_register_high(const arch_register_t *reg)
{
154
155
	assert(reg->index == REG_GP_EAX || reg->index == REG_GP_EBX
			|| reg->index == REG_GP_ECX || reg->index == REG_GP_EDX);
Michael Beck's avatar
Michael Beck committed
156
157

	be_emit_char('%');
158
	be_emit_char(reg->name[1]); /* get the basic name of the register */
Michael Beck's avatar
Michael Beck committed
159
160
161
	be_emit_char('h');
}

162
163
164
static void emit_16bit_register(const arch_register_t *reg)
{
	be_emit_char('%');
165
	be_emit_string(reg->name + 1); /* skip the 'e' prefix of the 32bit names */
166
167
}

168
169
170
171
172
173
/**
 * emit a register, possible shortened by a mode
 *
 * @param reg   the register
 * @param mode  the mode of the register or NULL for full register
 */
174
175
static void emit_register(const arch_register_t *reg, const ir_mode *mode)
{
Christoph Mallon's avatar
Christoph Mallon committed
176
	if (mode != NULL) {
177
		int size = get_mode_size_bits(mode);
Christoph Mallon's avatar
Christoph Mallon committed
178
179
180
		switch (size) {
			case  8: emit_8bit_register(reg);  return;
			case 16: emit_16bit_register(reg); return;
181
		}
Christoph Mallon's avatar
Christoph Mallon committed
182
		assert(mode_is_float(mode) || size == 32);
183
184
185
	}

	be_emit_char('%');
186
	be_emit_string(reg->name);
Christian Würdig's avatar
Christian Würdig committed
187
188
}

189
190
static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
{
191
	be_gas_emit_entity(entity);
192
193

	if (get_entity_owner(entity) == get_tls_type()) {
Matthias Braun's avatar
Matthias Braun committed
194
		if (!entity_has_definition(entity)) {
195
196
197
198
199
200
			be_emit_cstring("@INDNTPOFF");
		} else {
			be_emit_cstring("@NTPOFF");
		}
	}

201
	if (do_pic && !no_pic_adjust && get_entity_type(entity) != get_code_type()) {
202
203
204
205
206
207
208
209
210
211
212
213
		be_emit_char('-');
		be_emit_string(pic_base_label);
	}
}

static void emit_ia32_Immediate_no_prefix(const ir_node *node)
{
	const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);

	if (attr->symconst != NULL) {
		if (attr->sc_sign)
			be_emit_char('-');
214
		ia32_emit_entity(attr->symconst, attr->no_pic_adjust);
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
	}
	if (attr->symconst == NULL || attr->offset != 0) {
		if (attr->symconst != NULL) {
			be_emit_irprintf("%+d", attr->offset);
		} else {
			be_emit_irprintf("0x%X", attr->offset);
		}
	}
}

static void emit_ia32_Immediate(const ir_node *node)
{
	be_emit_char('$');
	emit_ia32_Immediate_no_prefix(node);
}
230

Matthias Braun's avatar
Matthias Braun committed
231
static void ia32_emit_mode_suffix_mode(const ir_mode *mode)
232
{
233
234
235
236
237
	assert(mode_is_int(mode) || mode_is_reference(mode));
	switch (get_mode_size_bits(mode)) {
		case 8:  be_emit_char('b');     return;
		case 16: be_emit_char('w');     return;
		case 32: be_emit_char('l');     return;
Christoph Mallon's avatar
Christoph Mallon committed
238
239
		/* gas docu says q is the suffix but gcc, objdump and icc use ll
		 * apparently */
Matthias Braun's avatar
Matthias Braun committed
240
241
		case 64: be_emit_cstring("ll"); return;
	}
242
	panic("Can't output mode_suffix for %+F", mode);
Christian Würdig's avatar
Christian Würdig committed
243
244
}

245
static void ia32_emit_x87_mode_suffix(ir_node const *const node)
246
{
247
248
	ir_mode *mode;

249
	/* we only need to emit the mode on address mode */
250
251
252
253
254
255
256
257
	if (get_ia32_op_type(node) == ia32_Normal)
		return;

	mode = get_ia32_ls_mode(node);
	assert(mode != NULL);

	if (mode_is_float(mode)) {
		switch (get_mode_size_bits(mode)) {
258
259
260
261
262
263
264
			case  32: be_emit_char('s'); return;
			case  64: be_emit_char('l'); return;
			/* long doubles have different sizes due to alignment on different
			 * platforms. */
			case  80:
			case  96:
			case 128: be_emit_char('t'); return;
265
266
		}
	} else {
267
		assert(mode_is_int(mode) || mode_is_reference(mode));
268
269
270
271
272
273
274
		switch (get_mode_size_bits(mode)) {
			case 16: be_emit_char('s');     return;
			case 32: be_emit_char('l');     return;
			/* gas docu says q is the suffix but gcc, objdump and icc use ll
			 * apparently */
			case 64: be_emit_cstring("ll"); return;
		}
275
	}
276
	panic("Can't output mode_suffix for %+F", mode);
277
278
}

279
static char get_xmm_mode_suffix(ir_mode *mode)
280
281
{
	assert(mode_is_float(mode));
282
	switch (get_mode_size_bits(mode)) {
Christoph Mallon's avatar
Christoph Mallon committed
283
284
285
	case 32: return 's';
	case 64: return 'd';
	default: panic("Invalid XMM mode");
286
287
288
	}
}

289
static void ia32_emit_xmm_mode_suffix(ir_node const *const node)
290
291
292
{
	ir_mode *mode = get_ia32_ls_mode(node);
	assert(mode != NULL);
293
	be_emit_char(get_xmm_mode_suffix(mode));
294
295
}

Christian Würdig's avatar
Christian Würdig committed
296
/**
297
 * Returns the target block for a control flow node.
Christian Würdig's avatar
Christian Würdig committed
298
 */
299
static ir_node *get_cfop_target_block(const ir_node *irn)
Christoph Mallon's avatar
Christoph Mallon committed
300
{
301
	assert(get_irn_mode(irn) == mode_X);
302
	return (ir_node*)get_irn_link(irn);
303
}
Christian Würdig's avatar
Christian Würdig committed
304

305
306
307
308
309
310
/**
 * Emits the target label for a control flow node.
 */
static void ia32_emit_cfop_target(const ir_node *node)
{
	ir_node *block = get_cfop_target_block(node);
311
	be_gas_emit_block_name(block);
312
313
}

Michael Beck's avatar
Michael Beck committed
314
315
316
/**
 * Emit the suffix for a compare instruction.
 */
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
static void ia32_emit_condition_code(ia32_condition_code_t cc)
{
	switch (cc) {
	case ia32_cc_overflow:      be_emit_cstring("o");  return;
	case ia32_cc_not_overflow:  be_emit_cstring("no"); return;
	case ia32_cc_float_below:
	case ia32_cc_float_unordered_below:
	case ia32_cc_below:         be_emit_cstring("b");  return;
	case ia32_cc_float_above_equal:
	case ia32_cc_float_unordered_above_equal:
	case ia32_cc_above_equal:   be_emit_cstring("ae"); return;
	case ia32_cc_float_equal:
	case ia32_cc_equal:         be_emit_cstring("e");  return;
	case ia32_cc_float_not_equal:
	case ia32_cc_not_equal:     be_emit_cstring("ne"); return;
	case ia32_cc_float_below_equal:
	case ia32_cc_float_unordered_below_equal:
	case ia32_cc_below_equal:   be_emit_cstring("be"); return;
	case ia32_cc_float_above:
	case ia32_cc_float_unordered_above:
	case ia32_cc_above:         be_emit_cstring("a");  return;
	case ia32_cc_sign:          be_emit_cstring("s");  return;
	case ia32_cc_not_sign:      be_emit_cstring("ns"); return;
	case ia32_cc_parity:        be_emit_cstring("p");  return;
	case ia32_cc_not_parity:    be_emit_cstring("np"); return;
	case ia32_cc_less:          be_emit_cstring("l");  return;
	case ia32_cc_greater_equal: be_emit_cstring("ge"); return;
	case ia32_cc_less_equal:    be_emit_cstring("le"); return;
	case ia32_cc_greater:       be_emit_cstring("g");  return;
	case ia32_cc_float_parity_cases:
	case ia32_cc_additional_float_cases:
		break;
349
	}
350
	panic("Invalid ia32 condition code");
351
352
}

353
typedef enum ia32_emit_mod_t {
354
	EMIT_NONE         = 0,
355
	EMIT_RESPECT_LS   = 1U << 0,
356
	EMIT_ALTERNATE_AM = 1U << 1,
357
358
	EMIT_LONG         = 1U << 2,
	EMIT_HIGH_REG     = 1U << 3,
359
360
	EMIT_LOW_REG      = 1U << 4,
	EMIT_16BIT_REG    = 1U << 5
361
} ia32_emit_mod_t;
362
ENUM_BITSET(ia32_emit_mod_t)
363

364
365
366
/**
 * Emits address mode.
 */
367
static void ia32_emit_am(ir_node const *const node)
368
369
370
371
372
{
	ir_entity *ent       = get_ia32_am_sc(node);
	int        offs      = get_ia32_am_offs_int(node);
	ir_node   *base      = get_irn_n(node, n_ia32_base);
	int        has_base  = !is_ia32_NoReg_GP(base);
373
374
	ir_node   *idx       = get_irn_n(node, n_ia32_index);
	int        has_index = !is_ia32_NoReg_GP(idx);
375
376
377
378

	/* just to be sure... */
	assert(!is_ia32_use_frame(node) || get_ia32_frame_ent(node) != NULL);

379
380
381
	if (get_ia32_am_tls_segment(node))
		be_emit_cstring("%gs:");

382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
	/* emit offset */
	if (ent != NULL) {
		const ia32_attr_t *attr = get_ia32_attr_const(node);
		if (is_ia32_am_sc_sign(node))
			be_emit_char('-');
		ia32_emit_entity(ent, attr->data.am_sc_no_pic_adjust);
	}

	/* also handle special case if nothing is set */
	if (offs != 0 || (ent == NULL && !has_base && !has_index)) {
		if (ent != NULL) {
			be_emit_irprintf("%+d", offs);
		} else {
			be_emit_irprintf("%d", offs);
		}
	}

	if (has_base || has_index) {
		be_emit_char('(');

		/* emit base */
		if (has_base) {
404
			const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_base);
405
406
407
408
409
			emit_register(reg, NULL);
		}

		/* emit index + scale */
		if (has_index) {
410
			const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_index);
411
412
413
414
415
416
417
418
419
420
421
422
423
			int scale;
			be_emit_char(',');
			emit_register(reg, NULL);

			scale = get_ia32_am_scale(node);
			if (scale > 0) {
				be_emit_irprintf(",%d", 1 << scale);
			}
		}
		be_emit_char(')');
	}
}

424
425
426
static ia32_condition_code_t determine_final_cc(ir_node const *node, int flags_pos, ia32_condition_code_t cc);

void ia32_emitf(ir_node const *const node, char const *fmt, ...)
427
428
429
430
{
	va_list ap;
	va_start(ap, fmt);

431
	be_emit_char('\t');
432
	for (;;) {
433
		const char      *start = fmt;
434
		ia32_emit_mod_t  mod   = EMIT_NONE;
435
436
437
438
439
440
441
442

		while (*fmt != '%' && *fmt != '\n' && *fmt != '\0')
			++fmt;
		if (fmt != start) {
			be_emit_string_len(start, fmt - start);
		}

		if (*fmt == '\n') {
443
444
445
			be_emit_char('\n');
			be_emit_write_line();
			be_emit_char('\t');
446
447
448
449
450
451
452
			++fmt;
			if (*fmt == '\0')
				break;
			continue;
		}

		if (*fmt == '\0')
Christian Würdig's avatar
Christian Würdig committed
453
			break;
454
455

		++fmt;
456
457
		for (;;) {
			switch (*fmt) {
458
459
460
			case '*': mod |= EMIT_ALTERNATE_AM; break;
			case '#': mod |= EMIT_RESPECT_LS;   break;
			case 'l': mod |= EMIT_LONG;         break;
461
462
			case '>': mod |= EMIT_HIGH_REG;     break;
			case '<': mod |= EMIT_LOW_REG;      break;
463
			case '^': mod |= EMIT_16BIT_REG;    break;
464
465
466
			default:
				goto end_of_mods;
			}
467
468
			++fmt;
		}
469
end_of_mods:
470

471
		switch (*fmt++) {
472
473
474
			arch_register_t const *reg;
			ir_node         const *imm;

475
476
477
478
479
480
			case '%':
				be_emit_char('%');
				break;

			case 'A': {
				switch (*fmt++) {
481
					case 'F':
482
						if (get_ia32_op_type(node) == ia32_Normal) {
483
484
485
							ia32_x87_attr_t const *const attr = get_ia32_x87_attr_const(node);
							char            const *const fmt  = attr->res_in_reg ? "%%st, %%%s" : "%%%s, %%st";
							be_emit_irprintf(fmt, attr->reg->name);
486
							break;
487
488
						} else {
							goto emit_AM;
489
490
						}

491
emit_AM:
492
					case 'M':
493
494
						if (mod & EMIT_ALTERNATE_AM)
							be_emit_char('*');
495
496
497
						ia32_emit_am(node);
						break;

498
499
					case 'R':
						reg = va_arg(ap, const arch_register_t*);
500
						if (get_ia32_op_type(node) == ia32_Normal) {
501
							goto emit_R;
502
503
						} else {
							goto emit_AM;
504
505
506
						}

					case 'S':
507
508
509
						if (get_ia32_op_type(node) == ia32_Normal) {
							goto emit_S;
						} else {
510
							++fmt;
511
							goto emit_AM;
512
513
514
515
516
517
518
						}

					default: goto unknown;
				}
				break;
			}

519
520
521
522
523
			case 'B':
				imm = get_irn_n(node, n_ia32_binary_right);
				if (is_ia32_Immediate(imm)) {
					emit_ia32_Immediate(imm);
					be_emit_cstring(", ");
524
525
					if (get_ia32_op_type(node) == ia32_Normal) {
						goto destination_operand;
526
					} else {
527
						ia32_emit_am(node);
528
529
					}
				} else {
530
					if (get_ia32_op_type(node) == ia32_Normal) {
531
532
						reg = arch_get_irn_register_in(node, n_ia32_binary_right);
						emit_register(reg, get_ia32_ls_mode(node));
533
534
					} else {
						ia32_emit_am(node);
535
536
					}
					be_emit_cstring(", ");
537
destination_operand:
538
539
540
541
542
					reg = arch_get_irn_register_in(node, n_ia32_binary_left);
					emit_register(reg, get_ia32_ls_mode(node));
				}
				break;

543
			case 'D':
544
				if (*fmt < '0' || '9' < *fmt)
545
					goto unknown;
546
				reg = arch_get_irn_register_out(node, *fmt++ - '0');
547
				goto emit_R;
548

549
550
551
			case 'F':
				if (*fmt == 'M') {
					ia32_emit_x87_mode_suffix(node);
552
553
554
555
				} else if (*fmt == 'P') {
					ia32_x87_attr_t const *const attr = get_ia32_x87_attr_const(node);
					if (attr->pop)
						be_emit_char('p');
556
557
558
559
560
561
562
563
564
565
566
567
				} else if (*fmt == 'R') {
					/* NOTE: Work around a gas quirk for non-commutative operations if the
					 * destination register is not %st0.  In this case r/non-r is swapped.
					 * %st0 = %st0 - %st1 -> fsub  %st1, %st0 (as expected)
					 * %st0 = %st1 - %st0 -> fsubr %st1, %st0 (as expected)
					 * %st1 = %st0 - %st1 -> fsub  %st0, %st1 (expected: fsubr)
					 * %st1 = %st1 - %st0 -> fsubr %st0, %st1 (expected: fsub)
					 * In fact this corresponds to the encoding of the instruction:
					 * - The r suffix selects whether %st0 is on the left (no r) or on the
					 *   right (r) side of the executed operation.
					 * - The placement of %st0 selects whether the result is written to
					 *   %st0 (right) or the other register (left).
568
569
570
571
					 * This means that it is sufficient to test whether the operands are
					 * permuted.  In particular it is not necessary to consider wether the
					 * result is to be placed into the explicit register operand. */
					if (get_ia32_x87_attr_const(node)->attr.data.ins_permuted)
572
						be_emit_char('r');
573
574
				} else if (*fmt == 'X') {
					ia32_emit_xmm_mode_suffix(node);
575
				} else if (*fmt == '0') {
576
					be_emit_char('%');
577
					be_emit_string(get_ia32_x87_attr_const(node)->reg->name);
578
579
580
				} else {
					goto unknown;
				}
581
				++fmt;
582
583
				break;

584
			case 'I':
585
586
				imm = node;
emit_I:
587
588
				if (!(mod & EMIT_ALTERNATE_AM))
					be_emit_char('$');
589
				emit_ia32_Immediate_no_prefix(imm);
590
591
592
593
594
595
				break;

			case 'L':
				ia32_emit_cfop_target(node);
				break;

596
597
598
599
600
601
602
603
604
605
			case 'M': {
				ir_mode *mode = get_ia32_ls_mode(node);
				if (!mode)
					mode = mode_Iu;
				if (mod & EMIT_RESPECT_LS) {
					if (get_mode_size_bits(mode) == 32)
						break;
					be_emit_char(mode_is_signed(mode) ? 's' : 'z');
				}
				ia32_emit_mode_suffix_mode(mode);
606
				break;
607
			}
608
609

			case 'P': {
610
611
612
613
614
615
616
				ia32_condition_code_t cc;
				if (*fmt == 'X') {
					++fmt;
					cc = (ia32_condition_code_t)va_arg(ap, int);
				} else if ('0' <= *fmt && *fmt <= '9') {
					cc = get_ia32_condcode(node);
					cc = determine_final_cc(node, *fmt - '0', cc);
yb9976's avatar
yb9976 committed
617
					++fmt;
618
619
620
				} else {
					goto unknown;
				}
621
				ia32_emit_condition_code(cc);
622
623
624
				break;
			}

625
626
627
628
629
			case 'R':
				reg = va_arg(ap, const arch_register_t*);
emit_R:
				if (mod & EMIT_ALTERNATE_AM)
					be_emit_char('*');
630
631
632
633
				if (mod & EMIT_HIGH_REG) {
					emit_8bit_register_high(reg);
				} else if (mod & EMIT_LOW_REG) {
					emit_8bit_register(reg);
634
635
				} else if (mod & EMIT_16BIT_REG) {
					emit_16bit_register(reg);
636
637
638
				} else {
					emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
				}
639
640
641
642
				break;

emit_S:
			case 'S': {
643
				unsigned pos;
644

645
				if (*fmt < '0' || '9' < *fmt)
646
647
648
					goto unknown;

				pos = *fmt++ - '0';
649
650
651
				imm = get_irn_n(node, pos);
				if (is_ia32_Immediate(imm)) {
					goto emit_I;
652
				} else {
653
					reg = arch_get_irn_register_in(node, pos);
654
					goto emit_R;
655
656
657
658
659
660
661
662
663
				}
			}

			case 's': {
				const char *str = va_arg(ap, const char*);
				be_emit_string(str);
				break;
			}

664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
			case 'u':
				if (mod & EMIT_LONG) {
					unsigned long num = va_arg(ap, unsigned long);
					be_emit_irprintf("%lu", num);
				} else {
					unsigned num = va_arg(ap, unsigned);
					be_emit_irprintf("%u", num);
				}
				break;

			case 'd':
				if (mod & EMIT_LONG) {
					long num = va_arg(ap, long);
					be_emit_irprintf("%ld", num);
				} else {
					int num = va_arg(ap, int);
					be_emit_irprintf("%d", num);
				}
682
683
684
685
				break;

			default:
unknown:
686
				panic("unknown format conversion");
687
		}
688
689
	}

690
	be_emit_finish_line_gas(node);
691
692
693
	va_end(ap);
}

Matthias Braun's avatar
Matthias Braun committed
694
695
696
static void emit_ia32_IMul(const ir_node *node)
{
	ir_node               *left    = get_irn_n(node, n_ia32_IMul_left);
697
	const arch_register_t *out_reg = arch_get_irn_register_out(node, pn_ia32_IMul_res);
Matthias Braun's avatar
Matthias Braun committed
698
699

	/* do we need the 3-address form? */
Christoph Mallon's avatar
Christoph Mallon committed
700
	if (is_ia32_NoReg_GP(left) ||
701
			arch_get_irn_register_in(node, n_ia32_IMul_left) != out_reg) {
702
		ia32_emitf(node, "imul%M %#S4, %#AS3, %#D0");
703
	} else {
704
		ia32_emitf(node, "imul%M %#AS4, %#S3");
Matthias Braun's avatar
Matthias Braun committed
705
706
707
	}
}

708
709
710
/**
 * walks up a tree of copies/perms/spills/reloads to find the original value
 * that is moved around
711
 */
712
713
static ir_node *find_original_value(ir_node *node)
{
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
	if (irn_visited(node))
		return NULL;

	mark_irn_visited(node);
	if (be_is_Copy(node)) {
		return find_original_value(be_get_Copy_op(node));
	} else if (be_is_CopyKeep(node)) {
		return find_original_value(be_get_CopyKeep_op(node));
	} else if (is_Proj(node)) {
		ir_node *pred = get_Proj_pred(node);
		if (be_is_Perm(pred)) {
			return find_original_value(get_irn_n(pred, get_Proj_proj(node)));
		} else if (be_is_MemPerm(pred)) {
			return find_original_value(get_irn_n(pred, get_Proj_proj(node) + 1));
		} else if (is_ia32_Load(pred)) {
			return find_original_value(get_irn_n(pred, n_ia32_Load_mem));
Andreas Zwinkau's avatar
Andreas Zwinkau committed
730
731
		} else if (is_ia32_Store(pred)) {
			return find_original_value(get_irn_n(pred, n_ia32_Store_val));
732
733
734
		} else {
			return node;
		}
735
736
737
738
739
740
741
742
743
744
745
746
747
	} else if (is_Phi(node)) {
		int i, arity;
		arity = get_irn_arity(node);
		for (i = 0; i < arity; ++i) {
			ir_node *in  = get_irn_n(node, i);
			ir_node *res = find_original_value(in);

			if (res != NULL)
				return res;
		}
		return NULL;
	} else {
		return node;
748
749
750
	}
}

751
752
static ia32_condition_code_t determine_final_cc(const ir_node *node,
		int flags_pos, ia32_condition_code_t cc)
753
{
754
755
756
757
	ir_node           *flags = get_irn_n(node, flags_pos);
	const ia32_attr_t *flags_attr;
	flags = skip_Proj(flags);

Christoph Mallon's avatar
Christoph Mallon committed
758
	if (is_ia32_Sahf(flags)) {
759
		ir_node *cmp = get_irn_n(flags, n_ia32_Sahf_val);
760
		if (!(is_ia32_FucomFnstsw(cmp) || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) {
761
			inc_irg_visited(current_ir_graph);
762
			cmp = find_original_value(cmp);
763
			assert(cmp != NULL);
764
			assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp));
765
		}
766

767
		flags_attr = get_ia32_attr_const(cmp);
768
	} else {
769
		flags_attr = get_ia32_attr_const(flags);
770
	}
771

772
773
774
	if (flags_attr->data.ins_permuted)
		cc = ia32_invert_condition_code(cc);
	return cc;
775
776
}

777
778
779
780
781
782
/**
 * Emits an exception label for a given node.
 */
static void ia32_emit_exc_label(const ir_node *node)
{
	be_emit_string(be_gas_insn_label_prefix());
783
	be_emit_irprintf("%lu", get_ia32_exc_label_id(node));
784
785
}

786
static int can_be_fallthrough(const ir_node *node)
787
788
789
790
791
792
{
	ir_node *target_block = get_cfop_target_block(node);
	ir_node *block        = get_nodes_block(node);
	return get_prev_block_sched(target_block) == block;
}

Christian Würdig's avatar
Christian Würdig committed
793
794
795
/**
 * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
 */
796
static void emit_ia32_Jcc(const ir_node *node)
797
{
798
799
	int                   need_parity_label = 0;
	ia32_condition_code_t cc                = get_ia32_condcode(node);
Christian Würdig's avatar
Christian Würdig committed
800

801
	cc = determine_final_cc(node, 0, cc);
Christian Würdig's avatar
Christian Würdig committed
802

803
	/* get both Projs */
804
	ir_node const *proj_true = be_get_Proj_for_pn(node, pn_ia32_Jcc_true);
805
	assert(proj_true && "Jcc without true Proj");
806

807
	ir_node const *proj_false = be_get_Proj_for_pn(node, pn_ia32_Jcc_false);
808
	assert(proj_false && "Jcc without false Proj");
809

810
	if (can_be_fallthrough(proj_true)) {
811
		/* exchange both proj's so the second one can be omitted */
812
813
		const ir_node *t = proj_true;

814
815
		proj_true  = proj_false;
		proj_false = t;
816
		cc         = ia32_negate_condition_code(cc);
817
818
	}

819
	if (cc & ia32_cc_float_parity_cases) {
820
821
		/* Some floating point comparisons require a test of the parity flag,
		 * which indicates that the result is unordered */
822
		if (cc & ia32_cc_negated) {
823
			ia32_emitf(proj_true, "jp %L");
824
		} else {
825
826
827
828
			/* we need a local label if the false proj is a fallthrough
			 * as the falseblock might have no label emitted then */
			if (can_be_fallthrough(proj_false)) {
				need_parity_label = 1;
829
				ia32_emitf(proj_false, "jp 1f");
830
			} else {
831
				ia32_emitf(proj_false, "jp %L");
832
			}
833
		}
834
	}
835
	ia32_emitf(proj_true, "j%PX %L", (int)cc);
Christoph Mallon's avatar
Christoph Mallon committed
836
	if (need_parity_label) {
837
838
		be_emit_cstring("1:\n");
		be_emit_write_line();
839
840
	}

841
	/* the second Proj might be a fallthrough */
Matthias Braun's avatar
Matthias Braun committed
842
	if (can_be_fallthrough(proj_false)) {
843
		if (be_options.verbose_asm)
844
			ia32_emitf(proj_false, "/* fallthrough to %L */");
845
	} else {
846
		ia32_emitf(proj_false, "jmp %L");
847
	}
Michael Beck's avatar
Michael Beck committed
848
849
}

850
851
852
853
854
855
/**
 * Emits an ia32 Setcc. This is mostly easy but some floating point compares
 * are tricky.
 */
static void emit_ia32_Setcc(const ir_node *node)
{
856
	const arch_register_t *dreg = arch_get_irn_register_out(node, pn_ia32_Setcc_res);
857

858
859
860
861
	ia32_condition_code_t cc = get_ia32_condcode(node);
	cc = determine_final_cc(node, n_ia32_Setcc_eflags, cc);
	if (cc & ia32_cc_float_parity_cases) {
		if (cc & ia32_cc_negated) {
862
863
864
			ia32_emitf(node, "set%PX %<R", (int)cc, dreg);
			ia32_emitf(node, "setp %>R", dreg);
			ia32_emitf(node, "orb %>R, %<R", dreg, dreg);
865
		} else {
866
867
868
			ia32_emitf(node, "set%PX %<R", (int)cc, dreg);
			ia32_emitf(node, "setnp %>R", dreg);
			ia32_emitf(node, "andb %>R, %<R", dreg, dreg);
869
		}
870
	} else {
871
		ia32_emitf(node, "set%PX %#R", (int)cc, dreg);
872
873
874
875
	}
}

static void emit_ia32_CMovcc(const ir_node *node)
Matthias Braun's avatar
Matthias Braun committed
876
{
877
	const ia32_attr_t     *attr = get_ia32_attr_const(node);
878
	const arch_register_t *out  = arch_get_irn_register_out(node, pn_ia32_res);
879
	ia32_condition_code_t  cc   = get_ia32_condcode(node);
880
881
882
	const arch_register_t *in_true;
	const arch_register_t *in_false;

883
	cc = determine_final_cc(node, n_ia32_CMovcc_eflags, cc);
884
	/* although you can't set ins_permuted in the constructor it might still
885
886
887
	 * be set by memory operand folding
	 * Permuting inputs of a cmov means the condition is negated!
	 */
888
	if (attr->data.ins_permuted)
889
		cc = ia32_negate_condition_code(cc);
890

891
892
	in_true  = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_true));
	in_false = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_false));
893
894

	/* should be same constraint fullfilled? */
Christoph Mallon's avatar
Christoph Mallon committed
895
	if (out == in_false) {
896
		/* yes -> nothing to do */
Christoph Mallon's avatar
Christoph Mallon committed
897
	} else if (out == in_true) {
898
899
		const arch_register_t *tmp;

900
901
		assert(get_ia32_op_type(node) == ia32_Normal);

902
		cc = ia32_negate_condition_code(cc);
903
904
905
906

		tmp      = in_true;
		in_true  = in_false;
		in_false = tmp;
907
	} else {
908
		/* we need a mov */
909
		ia32_emitf(node, "movl %R, %R", in_false, out);
910
	}
911

912
913
	if (cc & ia32_cc_float_parity_cases) {
		panic("CMov with floatingpoint compare/parity not supported yet");
914
	}
915

916
	ia32_emitf(node, "cmov%PX %#AR, %#R", (int)cc, in_true, out);
917
918
}

919
/**
920
 * Emits code for a SwitchJmp
921
922
923
 */
static void emit_ia32_SwitchJmp(const ir_node *node)
{
Matthias Braun's avatar
Matthias Braun committed
924
925
	ir_entity             *jump_table = get_ia32_am_sc(node);
	const ir_switch_table *table      = get_ia32_switch_table(node);
Christian Würdig's avatar
Christian Würdig committed
926

927
	ia32_emitf(node, "jmp %*AM");
Matthias Braun's avatar
Matthias Braun committed
928
	be_emit_jump_table(node, table, jump_table, get_cfop_target_block);
Christian Würdig's avatar
Christian Würdig committed
929
930
931
932
933
}

/**
 * Emits code for a unconditional jump.
 */
934
static void emit_ia32_Jmp(const ir_node *node)
935
{
936
	/* we have a block schedule */
937
	if (can_be_fallthrough(node)) {
938
		if (be_options.verbose_asm)
939
			ia32_emitf(node, "/* fallthrough to %L */");
940
	} else {
941
		ia32_emitf(node, "jmp %L");
Christian Würdig's avatar
Christian Würdig committed
942
943
944
	}
}

Michael Beck's avatar
Michael Beck committed
945
946
947
948
949
950
951
952
/**
 * Emit an inline assembler operand.
 *
 * @param node  the ia32_ASM node
 * @param s     points to the operand (a %c)
 *
 * @return  pointer to the first char in s NOT in the current operand
 */
953
static const char* emit_asm_operand(const ir_node *node, const char *s)
954
{
955
956
957
	const ia32_attr_t     *ia32_attr = get_ia32_attr_const(node);
	const ia32_asm_attr_t *attr      = CONST_CAST_IA32_ATTR(ia32_asm_attr_t,
                                                            ia32_attr);
Matthias Braun's avatar