ia32_emitter.c 88.8 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
 */
Christian Würdig's avatar
Christian Würdig committed
29
30
#include <limits.h>

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

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

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

65
66
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)

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

73
74
75
76
static bool              sp_relative;
static int               frame_type_size;
static int               callframe_offset;

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

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

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

94
	return 1;
95
96
}

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

106
	if (get_Block_entity(block) != NULL)
107
108
		return 1;

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

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

	return need_label;
}

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

Michael Beck's avatar
Michael Beck committed
134
135
136
/**
 * Emit the name of the 8bit low register
 */
137
138
static void emit_8bit_register(const arch_register_t *reg)
{
139
140
	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
141

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

Michael Beck's avatar
Michael Beck committed
147
148
149
150
151
/**
 * Emit the name of the 8bit high register
 */
static void emit_8bit_register_high(const arch_register_t *reg)
{
152
153
	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
154
155

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

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

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

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

187
188
static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
{
189
	be_gas_emit_entity(entity);
190

191
	if (is_tls_entity(entity)) {
Matthias Braun's avatar
Matthias Braun committed
192
		if (!entity_has_definition(entity)) {
193
194
195
196
197
198
			be_emit_cstring("@INDNTPOFF");
		} else {
			be_emit_cstring("@NTPOFF");
		}
	}

199
	if (do_pic && !no_pic_adjust && get_entity_type(entity) != get_code_type()) {
200
201
202
203
204
205
206
207
208
		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);

209
210
211
	ir_entity *const entity = attr->entity;
	if (entity != NULL) {
		ia32_emit_entity(entity, attr->no_pic_adjust);
212
		if (attr->offset != 0) {
213
214
			be_emit_irprintf("%+d", attr->offset);
		}
215
216
	} else {
		be_emit_irprintf("0x%lX", attr->offset);
217
218
219
220
221
222
223
224
	}
}

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

Matthias Braun's avatar
Matthias Braun committed
226
static void ia32_emit_mode_suffix_mode(const ir_mode *mode)
227
{
228
229
230
231
232
	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
233
234
		/* gas docu says q is the suffix but gcc, objdump and icc use ll
		 * apparently */
Matthias Braun's avatar
Matthias Braun committed
235
236
		case 64: be_emit_cstring("ll"); return;
	}
237
	panic("Can't output mode_suffix for %+F", mode);
Christian Würdig's avatar
Christian Würdig committed
238
239
}

240
static void ia32_emit_x87_mode_suffix(ir_node const *const node)
241
{
242
243
	ir_mode *mode;

244
	/* we only need to emit the mode on address mode */
245
246
247
248
249
250
251
252
	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)) {
253
254
255
256
257
258
259
			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;
260
261
		}
	} else {
262
		assert(mode_is_int(mode) || mode_is_reference(mode));
263
264
265
266
267
268
269
		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;
		}
270
	}
271
	panic("Can't output mode_suffix for %+F", mode);
272
273
}

274
static char get_xmm_mode_suffix(ir_mode *mode)
275
276
{
	assert(mode_is_float(mode));
277
	switch (get_mode_size_bits(mode)) {
Christoph Mallon's avatar
Christoph Mallon committed
278
279
280
	case 32: return 's';
	case 64: return 'd';
	default: panic("Invalid XMM mode");
281
282
283
	}
}

284
static void ia32_emit_xmm_mode_suffix(ir_node const *const node)
285
286
287
{
	ir_mode *mode = get_ia32_ls_mode(node);
	assert(mode != NULL);
288
	be_emit_char(get_xmm_mode_suffix(mode));
289
290
}

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

300
301
302
303
304
305
/**
 * 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);
306
	be_gas_emit_block_name(block);
307
308
}

309
void x86_emit_condition_code(x86_condition_code_t cc)
310
311
{
	switch (cc) {
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
	case x86_cc_overflow:      be_emit_cstring("o");  return;
	case x86_cc_not_overflow:  be_emit_cstring("no"); return;
	case x86_cc_float_below:
	case x86_cc_float_unordered_below:
	case x86_cc_below:         be_emit_cstring("b");  return;
	case x86_cc_float_above_equal:
	case x86_cc_float_unordered_above_equal:
	case x86_cc_above_equal:   be_emit_cstring("ae"); return;
	case x86_cc_float_equal:
	case x86_cc_equal:         be_emit_cstring("e");  return;
	case x86_cc_float_not_equal:
	case x86_cc_not_equal:     be_emit_cstring("ne"); return;
	case x86_cc_float_below_equal:
	case x86_cc_float_unordered_below_equal:
	case x86_cc_below_equal:   be_emit_cstring("be"); return;
	case x86_cc_float_above:
	case x86_cc_float_unordered_above:
	case x86_cc_above:         be_emit_cstring("a");  return;
	case x86_cc_sign:          be_emit_cstring("s");  return;
	case x86_cc_not_sign:      be_emit_cstring("ns"); return;
	case x86_cc_parity:        be_emit_cstring("p");  return;
	case x86_cc_not_parity:    be_emit_cstring("np"); return;
	case x86_cc_less:          be_emit_cstring("l");  return;
	case x86_cc_greater_equal: be_emit_cstring("ge"); return;
	case x86_cc_less_equal:    be_emit_cstring("le"); return;
	case x86_cc_greater:       be_emit_cstring("g");  return;
	case x86_cc_float_parity_cases:
	case x86_cc_additional_float_cases:
340
		break;
341
	}
342
	panic("Invalid ia32 condition code");
343
344
}

345
typedef enum ia32_emit_mod_t {
346
	EMIT_NONE         = 0,
347
	EMIT_RESPECT_LS   = 1U << 0,
348
	EMIT_ALTERNATE_AM = 1U << 1,
349
350
	EMIT_LONG         = 1U << 2,
	EMIT_HIGH_REG     = 1U << 3,
351
	EMIT_LOW_REG      = 1U << 4,
352
353
	EMIT_16BIT_REG    = 1U << 5,
	EMIT_SHIFT_COMMA  = 1U << 6,
354
} ia32_emit_mod_t;
355
ENUM_BITSET(ia32_emit_mod_t)
356

357
358
359
/**
 * Emits address mode.
 */
360
static void ia32_emit_am(ir_node const *const node)
361
{
362
	ir_entity *ent       = get_ia32_am_ent(node);
363
364
365
	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);
366
367
	ir_node   *idx       = get_irn_n(node, n_ia32_index);
	int        has_index = !is_ia32_NoReg_GP(idx);
368
369
370
371

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

372
373
374
	if (get_ia32_am_tls_segment(node))
		be_emit_cstring("%gs:");

375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
	/* emit offset */
	if (ent != NULL) {
		const ia32_attr_t *attr = get_ia32_attr_const(node);
		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) {
395
			const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_base);
396
397
398
399
400
			emit_register(reg, NULL);
		}

		/* emit index + scale */
		if (has_index) {
401
			const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_index);
402
403
404
405
406
407
408
409
410
411
412
413
414
			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(')');
	}
}

415
static x86_condition_code_t determine_final_cc(ir_node const *node, int flags_pos, x86_condition_code_t cc);
416
417

void ia32_emitf(ir_node const *const node, char const *fmt, ...)
418
419
420
421
{
	va_list ap;
	va_start(ap, fmt);

422
	be_emit_char('\t');
423
	for (;;) {
424
		const char      *start = fmt;
425
		ia32_emit_mod_t  mod   = EMIT_NONE;
426
427
428
429
430
431
432
433

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

		if (*fmt == '\n') {
434
435
436
			be_emit_char('\n');
			be_emit_write_line();
			be_emit_char('\t');
437
438
439
440
441
442
443
			++fmt;
			if (*fmt == '\0')
				break;
			continue;
		}

		if (*fmt == '\0')
Christian Würdig's avatar
Christian Würdig committed
444
			break;
445
446

		++fmt;
447
448
		for (;;) {
			switch (*fmt) {
449
450
451
			case '*': mod |= EMIT_ALTERNATE_AM; break;
			case '#': mod |= EMIT_RESPECT_LS;   break;
			case 'l': mod |= EMIT_LONG;         break;
452
453
			case '>': mod |= EMIT_HIGH_REG;     break;
			case '<': mod |= EMIT_LOW_REG;      break;
454
			case '^': mod |= EMIT_16BIT_REG;    break;
455
			case ',': mod |= EMIT_SHIFT_COMMA;  break;
456
457
458
			default:
				goto end_of_mods;
			}
459
460
			++fmt;
		}
461
end_of_mods:
462

463
		switch (*fmt++) {
464
465
466
			arch_register_t const *reg;
			ir_node         const *imm;

467
468
469
470
471
472
			case '%':
				be_emit_char('%');
				break;

			case 'A': {
				switch (*fmt++) {
473
					case 'F':
474
						if (get_ia32_op_type(node) == ia32_Normal) {
475
476
477
							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);
478
							break;
479
480
						} else {
							goto emit_AM;
481
482
						}

483
emit_AM:
484
					case 'M':
485
486
						if (mod & EMIT_ALTERNATE_AM)
							be_emit_char('*');
487
488
489
						ia32_emit_am(node);
						break;

490
491
					case 'R':
						reg = va_arg(ap, const arch_register_t*);
492
						if (get_ia32_op_type(node) == ia32_Normal) {
493
							goto emit_R;
494
495
						} else {
							goto emit_AM;
496
497
498
						}

					case 'S':
499
500
501
						if (get_ia32_op_type(node) == ia32_Normal) {
							goto emit_S;
						} else {
502
							++fmt;
503
							goto emit_AM;
504
505
506
507
508
509
510
						}

					default: goto unknown;
				}
				break;
			}

511
512
513
514
515
			case 'B':
				imm = get_irn_n(node, n_ia32_binary_right);
				if (is_ia32_Immediate(imm)) {
					emit_ia32_Immediate(imm);
					be_emit_cstring(", ");
516
517
					if (get_ia32_op_type(node) == ia32_Normal) {
						goto destination_operand;
518
					} else {
519
						ia32_emit_am(node);
520
521
					}
				} else {
522
					if (get_ia32_op_type(node) == ia32_Normal) {
523
524
						reg = arch_get_irn_register_in(node, n_ia32_binary_right);
						emit_register(reg, get_ia32_ls_mode(node));
525
526
					} else {
						ia32_emit_am(node);
527
528
					}
					be_emit_cstring(", ");
529
destination_operand:
530
531
532
533
534
					reg = arch_get_irn_register_in(node, n_ia32_binary_left);
					emit_register(reg, get_ia32_ls_mode(node));
				}
				break;

535
			case 'D':
536
				if (*fmt < '0' || '9' < *fmt)
537
					goto unknown;
538
				reg = arch_get_irn_register_out(node, *fmt++ - '0');
539
				goto emit_R;
540

541
542
543
			case 'F':
				if (*fmt == 'M') {
					ia32_emit_x87_mode_suffix(node);
544
545
546
547
				} else if (*fmt == 'P') {
					ia32_x87_attr_t const *const attr = get_ia32_x87_attr_const(node);
					if (attr->pop)
						be_emit_char('p');
548
549
550
551
552
553
554
555
556
557
558
559
				} 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).
560
561
562
563
					 * 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)
564
						be_emit_char('r');
565
566
				} else if (*fmt == 'X') {
					ia32_emit_xmm_mode_suffix(node);
567
				} else if (*fmt == '0') {
568
					be_emit_char('%');
569
					be_emit_string(get_ia32_x87_attr_const(node)->reg->name);
570
571
572
				} else {
					goto unknown;
				}
573
				++fmt;
574
575
				break;

576
			case 'I':
577
578
				imm = node;
emit_I:
579
580
581
				if (mod & EMIT_SHIFT_COMMA) {
					const ia32_immediate_attr_t *attr
						= get_ia32_immediate_attr_const(imm);
582
					if (attr->entity == NULL && attr->offset == 1)
583
584
						break;
				}
585
586
				if (!(mod & EMIT_ALTERNATE_AM))
					be_emit_char('$');
587
				emit_ia32_Immediate_no_prefix(imm);
588
589
590
				if (mod & EMIT_SHIFT_COMMA) {
					be_emit_char(',');
				}
591
592
593
594
595
596
				break;

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

597
598
599
			case 'M': {
				ir_mode *mode = get_ia32_ls_mode(node);
				if (!mode)
600
					mode = ia32_mode_gp;
601
602
603
604
605
606
				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);
607
				break;
608
			}
609
610

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

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

emit_S:
			case 'S': {
647
				unsigned pos;
648

649
				if (*fmt < '0' || '9' < *fmt)
650
651
652
					goto unknown;

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

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

668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
			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);
				}
686
687
688
689
				break;

			default:
unknown:
690
				panic("unknown format conversion");
691
		}
692
693
	}

694
	be_emit_finish_line_gas(node);
695
696
697
	va_end(ap);
}

Matthias Braun's avatar
Matthias Braun committed
698
699
700
static void emit_ia32_IMul(const ir_node *node)
{
	ir_node               *left    = get_irn_n(node, n_ia32_IMul_left);
701
	const arch_register_t *out_reg = arch_get_irn_register_out(node, pn_ia32_IMul_res);
Matthias Braun's avatar
Matthias Braun committed
702
703

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

712
713
714
/**
 * walks up a tree of copies/perms/spills/reloads to find the original value
 * that is moved around
715
 */
716
717
static ir_node *find_original_value(ir_node *node)
{
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
	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
734
735
		} else if (is_ia32_Store(pred)) {
			return find_original_value(get_irn_n(pred, n_ia32_Store_val));
736
737
738
		} else {
			return node;
		}
739
740
741
742
743
744
745
746
747
748
749
750
751
	} 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;
752
753
754
	}
}

755
756
757
static x86_condition_code_t determine_final_cc(const ir_node *node,
                                               int flags_pos,
                                               x86_condition_code_t cc)
758
{
759
760
761
762
	ir_node           *flags = get_irn_n(node, flags_pos);
	const ia32_attr_t *flags_attr;
	flags = skip_Proj(flags);

763
764
765
766
767
	/* Permuted operands of a test instruction do not change the result. */
	if (is_ia32_Test(flags)) {
		return cc;
	}

Christoph Mallon's avatar
Christoph Mallon committed
768
	if (is_ia32_Sahf(flags)) {
769
		ir_node *cmp = get_irn_n(flags, n_ia32_Sahf_val);
770
		if (!(is_ia32_FucomFnstsw(cmp) || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) {
771
772
			ir_graph *irg = get_irn_irg(node);
			inc_irg_visited(irg);
773
			cmp = find_original_value(cmp);
774
			assert(cmp != NULL);
775
			assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp));
776
		}
777

778
		flags_attr = get_ia32_attr_const(cmp);
779
	} else {
780
		flags_attr = get_ia32_attr_const(flags);
781
	}
782

783
	if (flags_attr->data.ins_permuted)
784
		cc = x86_invert_condition_code(cc);
785
	return cc;
786
787
}

788
789
790
791
792
793
/**
 * 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());
794
	be_emit_irprintf("%lu", get_ia32_exc_label_id(node));
795
796
}

797
static int can_be_fallthrough(const ir_node *node)
798
799
800
801
802
803
{
	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
804
805
806
/**
 * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
 */
807
static void emit_ia32_Jcc(const ir_node *node)
808
{
809
810
	int                  need_parity_label = 0;
	x86_condition_code_t cc                = get_ia32_condcode(node);
Christian Würdig's avatar
Christian Würdig committed
811

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

814
	/* get both Projs */
815
	ir_node const *proj_true = be_get_Proj_for_pn(node, pn_ia32_Jcc_true);
816
	assert(proj_true && "Jcc without true Proj");
817

818
	ir_node const *proj_false = be_get_Proj_for_pn(node, pn_ia32_Jcc_false);
819
	assert(proj_false && "Jcc without false Proj");
820

821
	if (can_be_fallthrough(proj_true)) {
822
		/* exchange both proj's so the second one can be omitted */
823
824
		const ir_node *t = proj_true;

825
826
		proj_true  = proj_false;
		proj_false = t;
827
		cc         = x86_negate_condition_code(cc);
828
829
	}

830
	if (cc & x86_cc_float_parity_cases) {
831
832
		/* Some floating point comparisons require a test of the parity flag,
		 * which indicates that the result is unordered */
833
		if (cc & x86_cc_negated) {
834
			ia32_emitf(proj_true, "jp %L");
835
		} else {
836
837
838
839
			/* 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;
840
				ia32_emitf(proj_false, "jp 1f");
841
			} else {
842
				ia32_emitf(proj_false, "jp %L");
843
			}
844
		}
845
	}
846
	ia32_emitf(proj_true, "j%PX %L", (int)cc);
Christoph Mallon's avatar
Christoph Mallon committed
847
	if (need_parity_label) {
848
849
		be_emit_cstring("1:\n");
		be_emit_write_line();
850
851
	}

852
	/* the second Proj might be a fallthrough */
Matthias Braun's avatar
Matthias Braun committed
853
	if (can_be_fallthrough(proj_false)) {
854
		if (be_options.verbose_asm)
855
			ia32_emitf(proj_false, "/* fallthrough to %L */");
856
	} else {
857
		ia32_emitf(proj_false, "jmp %L");
858
	}
Michael Beck's avatar
Michael Beck committed
859
860
}

861
862
863
864
865
866
/**
 * Emits an ia32 Setcc. This is mostly easy but some floating point compares
 * are tricky.
 */
static void emit_ia32_Setcc(const ir_node *node)
{
867
	const arch_register_t *dreg = arch_get_irn_register_out(node, pn_ia32_Setcc_res);
868

869
	x86_condition_code_t cc = get_ia32_condcode(node);
870
	cc = determine_final_cc(node, n_ia32_Setcc_eflags, cc);
871
872
	if (cc & x86_cc_float_parity_cases) {
		if (cc & x86_cc_negated) {
873
874
875
			ia32_emitf(node, "set%PX %<R", (int)cc, dreg);
			ia32_emitf(node, "setp %>R", dreg);
			ia32_emitf(node, "orb %>R, %<R", dreg, dreg);
876
		} else {
877
878
879
			ia32_emitf(node, "set%PX %<R", (int)cc, dreg);
			ia32_emitf(node, "setnp %>R", dreg);
			ia32_emitf(node, "andb %>R, %<R", dreg, dreg);
880
		}
881
	} else {
882
		ia32_emitf(node, "set%PX %#R", (int)cc, dreg);
883
884
885
886
	}
}

static void emit_ia32_CMovcc(const ir_node *node)
Matthias Braun's avatar
Matthias Braun committed
887
{
888
	const ia32_attr_t     *attr = get_ia32_attr_const(node);
889
	const arch_register_t *out  = arch_get_irn_register_out(node, pn_ia32_res);
890
	x86_condition_code_t   cc   = get_ia32_condcode(node);
891
892
893
	const arch_register_t *in_true;
	const arch_register_t *in_false;

894
	cc = determine_final_cc(node, n_ia32_CMovcc_eflags, cc);
895
	/* although you can't set ins_permuted in the constructor it might still
896
897
898
	 * be set by memory operand folding
	 * Permuting inputs of a cmov means the condition is negated!
	 */
899
	if (attr->data.ins_permuted)
900
		cc = x86_negate_condition_code(cc);
901

902
903
	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));
904
905

	/* should be same constraint fullfilled? */
Christoph Mallon's avatar
Christoph Mallon committed
906
	if (out == in_false) {
907
		/* yes -> nothing to do */
Christoph Mallon's avatar
Christoph Mallon committed
908
	} else if (out == in_true) {
909
910
		const arch_register_t *tmp;

911
912
		assert(get_ia32_op_type(node) == ia32_Normal);

913
		cc = x86_negate_condition_code(cc);
914
915
916
917

		tmp      = in_true;
		in_true  = in_false;
		in_false = tmp;
918
	} else {
919
		/* we need a mov */
920
		ia32_emitf(node, "movl %R, %R", in_false, out);
921
	}
922

923
	if (cc & x86_cc_float_parity_cases) {
924
		panic("CMov with floatingpoint compare/parity not supported yet");
925
	}
926

927
	ia32_emitf(node, "cmov%PX %#AR, %#R", (int)cc, in_true, out);
928
929
}

930
/**
931
 * Emits code for a SwitchJmp