ia32_emitter.c 83.5 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 <inttypes.h>
Christian Würdig's avatar
Christian Würdig committed
30

31
32
#include "be_t.h"
#include "bearch_ia32_t.h"
33
#include "beasm.h"
34
#include "beblocksched.h"
35
#include "bediagnostic.h"
36
#include "begnuas.h"
37
#include "besched.h"
38
#include "bestack.h"
39
#include "beutil.h"
40
#include "debug.h"
41
#include "execfreq.h"
Christian Würdig's avatar
Christian Würdig committed
42
#include "gen_ia32_emitter.h"
Christian Würdig's avatar
Christian Würdig committed
43
#include "gen_ia32_regalloc_if.h"
44
#include "ia32_architecture.h"
45
46
47
48
49
50
#include "ia32_emitter.h"
#include "ia32_new_nodes.h"
#include "irgwalk.h"
#include "irtools.h"
#include "lc_opts.h"
#include "panic.h"
Christian Würdig's avatar
Christian Würdig committed
51

52
53
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)

54
55
56
static char       pic_base_label[128];
static ir_label_t exc_label_id;
static bool       mark_spill_reload;
57

58
59
60
static bool       sp_relative;
static int        frame_type_size;
static int        callframe_offset;
61

62
63
64
/** Return the next block in Block schedule */
static ir_node *get_prev_block_sched(const ir_node *block)
{
65
	return (ir_node*)get_irn_link(block);
66
67
}

68
/** Checks if the current block is a fall-through target. */
69
static bool is_fallthrough(const ir_node *cfgpred)
70
{
Christoph Mallon's avatar
Christoph Mallon committed
71
	if (!is_Proj(cfgpred))
72
73
		return true;
	ir_node *pred = get_Proj_pred(cfgpred);
Christoph Mallon's avatar
Christoph Mallon committed
74
	if (is_ia32_SwitchJmp(pred))
75
76
		return false;
	return true;
77
78
}

79
80
81
82
/**
 * returns non-zero if the given block needs a label
 * because of being a jump-target (and not a fall-through)
 */
83
static bool block_needs_label(const ir_node *block)
84
{
85
	if (get_Block_entity(block) != NULL)
86
		return true;
87

88
89
	int  n_cfgpreds = get_Block_n_cfgpreds(block);
	bool need_label = true;
90
	if (n_cfgpreds == 0) {
91
		need_label = 0;
92
	} else if (n_cfgpreds == 1) {
Christoph Mallon's avatar
Christoph Mallon committed
93
94
		ir_node *cfgpred       = get_Block_cfgpred(block, 0);
		ir_node *cfgpred_block = get_nodes_block(cfgpred);
95
		if (get_prev_block_sched(block) == cfgpred_block
96
		    && is_fallthrough(cfgpred)) {
97
			need_label = 0;
98
99
100
101
102
103
		}
	}

	return need_label;
}

Michael Beck's avatar
Michael Beck committed
104
/**
105
 * Add a number to a prefix. This number will not be used a second time.
Michael Beck's avatar
Michael Beck committed
106
 */
107
108
static char *get_unique_label(char *buf, size_t buflen, const char *prefix)
{
109
	static unsigned long id = 0;
110
	snprintf(buf, buflen, "%s%s%lu", be_gas_get_private_prefix(), prefix, ++id);
111
112
113
	return buf;
}

114
static const char *get_register_name_8bit_low(const arch_register_t *reg)
115
{
116
117
118
119
120
121
122
	switch (reg->global_index) {
	case REG_EAX: return "al";
	case REG_EBX: return "bl";
	case REG_ECX: return "cl";
	case REG_EDX: return "dl";
	}
	panic("unexpected register");
123
124
}

125
static const char *get_register_name_8bit_high(const arch_register_t *reg)
Michael Beck's avatar
Michael Beck committed
126
{
127
128
129
130
131
132
133
134
	switch (reg->global_index) {
	case REG_EAX: return "ah";
	case REG_EBX: return "bh";
	case REG_ECX: return "ch";
	case REG_EDX: return "dh";
	}
	panic("unexpected register");
}
Michael Beck's avatar
Michael Beck committed
135

136
137
138
139
140
141
142
143
144
145
146
147
148
static const char *get_register_name_16bit(const arch_register_t *reg)
{
	switch (reg->global_index) {
	case REG_EAX: return "ax";
	case REG_EBX: return "bx";
	case REG_ECX: return "cx";
	case REG_EDX: return "dx";
	case REG_ESI: return "si";
	case REG_EDI: return "di";
	case REG_ESP: return "sp";
	case REG_EBP: return "bp";
	}
	panic("unexpected register");
Michael Beck's avatar
Michael Beck committed
149
150
}

151
152
static const char *get_register_name_mode(const arch_register_t *reg,
                                          ir_mode *mode)
153
{
154
155
156
157
158
159
160
161
162
	if (mode == NULL)
		return reg->name;
	unsigned size = get_mode_size_bits(mode);
	if (size == 8)
		return get_register_name_8bit_low(reg);
	else if (size == 16)
		return get_register_name_16bit(reg);
	else
		return reg->name;
163
164
}

165
166
167
168
169
/**
 * emit a register, possible shortened by a mode
 * @param reg   the register
 * @param mode  the mode of the register or NULL for full register
 */
170
static void emit_register(const arch_register_t *reg, ir_mode *mode)
171
{
172
	const char *name = get_register_name_mode(reg, mode);
173
	be_emit_char('%');
174
	be_emit_string(name);
Christian Würdig's avatar
Christian Würdig committed
175
176
}

177
static void ia32_emit_entity(x86_imm32_t const *const imm, bool no_pic_adjust)
178
{
179
	assert(imm->kind != X86_IMM_VALUE);
180
	ir_entity *entity = imm->entity;
181
	be_gas_emit_entity(entity);
182

183
	if (is_tls_entity(entity)) {
Matthias Braun's avatar
Matthias Braun committed
184
		if (!entity_has_definition(entity)) {
185
186
187
188
189
190
			be_emit_cstring("@INDNTPOFF");
		} else {
			be_emit_cstring("@NTPOFF");
		}
	}

191
192
193
	if (imm->kind == X86_IMM_PICBASE_REL) {
		assert(be_options.pic && !no_pic_adjust &&
		       get_entity_type(entity) != get_code_type());
194
195
		be_emit_char('-');
		be_emit_string(pic_base_label);
196
197
198
	} else {
		assert(!be_options.pic || no_pic_adjust ||
		       get_entity_type(entity) == get_code_type());
199
200
201
	}
}

202
203
static void emit_ia32_immediate(bool const prefix, bool const no_pic_adjust,
                                x86_imm32_t const *const imm)
204
{
205
206
	if (prefix)
		be_emit_char('$');
207
208
209
	ir_entity const *const entity = imm->entity;
	int32_t          const offset = imm->offset;
	if (entity != NULL) {
210
		assert(imm->kind != X86_IMM_VALUE);
211
		ia32_emit_entity(imm, no_pic_adjust);
212
213
		if (offset != 0)
			be_emit_irprintf("%+"PRId32, offset);
214
	} else {
215
		assert(imm->kind == X86_IMM_VALUE);
216
		be_emit_irprintf("0x%"PRIX32, (uint32_t)offset);
217
218
219
	}
}

220
static void emit_ia32_immediate_attr(bool const prefix, ir_node const *const node)
221
{
222
	ia32_immediate_attr_t const *const attr = get_ia32_immediate_attr_const(node);
223
	emit_ia32_immediate(prefix, attr->no_pic_adjust, &attr->imm);
224
}
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("cannot 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
	/* we only need to emit the mode on address mode */
243
244
245
	if (get_ia32_op_type(node) == ia32_Normal)
		return;

246
	ir_mode *mode = get_ia32_ls_mode(node);
247
248
249
250
	assert(mode != NULL);

	if (mode_is_float(mode)) {
		switch (get_mode_size_bits(mode)) {
251
252
253
254
255
256
257
			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;
258
259
		}
	} else {
260
		assert(mode_is_int(mode) || mode_is_reference(mode));
261
262
263
264
265
266
267
		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;
		}
268
	}
269
	panic("cannot output mode_suffix for %+F", mode);
270
271
}

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

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

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

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

307
void x86_emit_condition_code(x86_condition_code_t cc)
308
309
{
	switch (cc) {
310
311
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
	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:
338
		break;
339
	}
340
	panic("invalid ia32 condition code");
341
342
}

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

355
356
357
358
359
360
static ir_node const *get_irn_n_reg(ir_node const *const node, int const pos)
{
	ir_node *const in = get_irn_n(node, pos);
	return is_ia32_NoReg_GP(in) ? NULL : in;
}

361
362
363
/**
 * Emits address mode.
 */
364
static void ia32_emit_am(ir_node const *const node)
365
366
{
	/* just to be sure... */
367
	assert(get_ia32_frame_use(node) == IA32_FRAME_USE_NONE || get_ia32_frame_ent(node));
368

369
370
371
	if (get_ia32_am_tls_segment(node))
		be_emit_cstring("%gs:");

372
373
374
	ir_node const *const base = get_irn_n_reg(node, n_ia32_base);
	ir_node const *const idx  = get_irn_n_reg(node, n_ia32_index);

375
	/* emit offset */
376
377
378
379
	ia32_attr_t const *const attr = get_ia32_attr_const(node);
	int32_t          const offset = attr->am_imm.offset;
	ir_entity const *const entity = attr->am_imm.entity;
	if (entity) {
380
		assert(attr->am_imm.kind != X86_IMM_VALUE);
381
		const ia32_attr_t *attr = get_ia32_attr_const(node);
382
383
384
385
		ia32_emit_entity(&attr->am_imm, attr->am_sc_no_pic_adjust);
		if (offset != 0)
			be_emit_irprintf("%+"PRId32, offset);
	} else if (offset != 0 || (!base && !idx)) {
386
		assert(attr->am_imm.kind == X86_IMM_VALUE);
387
		/* also handle special case if nothing is set */
388
		be_emit_irprintf("%"PRId32, offset);
389
390
	}

391
	if (base || idx) {
392
393
394
		be_emit_char('(');

		/* emit base */
395
		if (base) {
396
			arch_register_t const *const reg = arch_get_irn_register(base);
397
398
399
400
			emit_register(reg, NULL);
		}

		/* emit index + scale */
401
		if (idx) {
402
			be_emit_char(',');
403
			arch_register_t const *const reg = arch_get_irn_register(idx);
404
405
			emit_register(reg, NULL);

406
			int const scale = get_ia32_am_scale(node);
407
			if (scale > 0)
408
409
410
411
412
413
				be_emit_irprintf(",%d", 1 << scale);
		}
		be_emit_char(')');
	}
}

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

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

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

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

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

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

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

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

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

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

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

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

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

					default: goto unknown;
				}
				break;
			}

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

535
			case 'D':
536
				if (!is_digit(*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
					 * 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. */
563
					if (get_ia32_x87_attr_const(node)->attr.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->imm.entity == NULL && attr->imm.offset == 1)
583
584
						break;
				}
585
				emit_ia32_immediate_attr(!(mod & EMIT_ALTERNATE_AM), imm);
586
587
588
				if (mod & EMIT_SHIFT_COMMA) {
					be_emit_char(',');
				}
589
590
591
592
593
594
				break;

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

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

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

623
624
625
626
627
			case 'R':
				reg = va_arg(ap, const arch_register_t*);
emit_R:
				if (mod & EMIT_ALTERNATE_AM)
					be_emit_char('*');
628
				const char *name;
629
				if (mod & EMIT_HIGH_REG) {
630
					name = get_register_name_8bit_high(reg);
631
				} else if (mod & EMIT_LOW_REG) {
632
					name = get_register_name_8bit_low(reg);
633
				} else if (mod & EMIT_16BIT_REG) {
634
					name = get_register_name_16bit(reg);
635
				} else {
636
637
638
					name = mod & EMIT_RESPECT_LS
						 ? get_register_name_mode(reg, get_ia32_ls_mode(node))
						 : reg->name;
639
				}
640
641
				be_emit_char('%');
				be_emit_string(name);
642
643
644
				if (mod & EMIT_SHIFT_COMMA) {
					be_emit_char(',');
				}
645
646
647
648
				break;

emit_S:
			case 'S': {
649
				if (!is_digit(*fmt))
650
651
					goto unknown;

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

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

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

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

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

699
700
701
/**
 * walks up a tree of copies/perms/spills/reloads to find the original value
 * that is moved around
702
 */
703
704
static ir_node *find_original_value(ir_node *node)
{
705
706
707
708
709
710
711
712
713
714
715
	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)) {
716
			return find_original_value(get_irn_n(pred, get_Proj_num(node)));
717
		} else if (be_is_MemPerm(pred)) {
718
			return find_original_value(get_irn_n(pred, get_Proj_num(node)));
719
720
		} 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
721
722
		} else if (is_ia32_Store(pred)) {
			return find_original_value(get_irn_n(pred, n_ia32_Store_val));
723
724
725
		} else {
			return node;
		}
726
	} else if (is_Phi(node)) {
727
		foreach_irn_in(node, i, in) {
728
729
730
731
732
733
734
			ir_node *res = find_original_value(in);
			if (res != NULL)
				return res;
		}
		return NULL;
	} else {
		return node;
735
736
737
	}
}

738
static x86_condition_code_t determine_final_cc(ir_node const *const node, int const flags_pos)
739
{
740
741
742
743
744
	ia32_condcode_attr_t const *const attr = get_ia32_condcode_attr_const(node);
	x86_condition_code_t              cc   = attr->condition_code;
	if (attr->attr.ins_permuted)
		cc = x86_negate_condition_code(cc);

745
	ir_node *flags = skip_Proj(get_irn_n(node, flags_pos));
746

747
	/* Permuted operands of a test instruction do not change the result. */
748
	if (is_ia32_Test(flags))
749
750
		return cc;

Christoph Mallon's avatar
Christoph Mallon committed
751
	if (is_ia32_Sahf(flags)) {
752
753
754
		flags = get_irn_n(flags, n_ia32_Sahf_val);
		if (!is_ia32_FucomFnstsw(flags) && !is_ia32_FucomppFnstsw(flags) && !is_ia32_FtstFnstsw(flags)) {
			ir_graph *const irg = get_irn_irg(node);
755
			inc_irg_visited(irg);
756
757
			flags = find_original_value(flags);
			assert(is_ia32_FucomFnstsw(flags) || is_ia32_FucomppFnstsw(flags) || is_ia32_FtstFnstsw(flags));
758
		}
759
	}
760

761
	ia32_attr_t const *const flags_attr = get_ia32_attr_const(flags);
762
	if (flags_attr->ins_permuted)
763
		cc = x86_invert_condition_code(cc);
764
	return cc;
765
766
}

767
768
769
770
771
772
/**
 * 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());
773
	be_emit_irprintf("%lu", get_ia32_exc_label_id(node));
774
775
}

776
static bool fallthrough_possible(const ir_node *block, const ir_node *target)
777
{
778
	return get_prev_block_sched(target) == block;
779
780
}

Christian Würdig's avatar
Christian Würdig committed
781
782
783
/**
 * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
 */
784
static void emit_ia32_Jcc(const ir_node *node)
785
{
786
	x86_condition_code_t cc = determine_final_cc(node, n_ia32_Jcc_eflags);
Christian Würdig's avatar
Christian Würdig committed
787

788
	/* get both Projs */
789
	ir_node const *proj_true   = get_Proj_for_pn(node, pn_ia32_Jcc_true);
790
	ir_node const *target_true = get_cfop_target_block(proj_true);
791
	ir_node const *proj_false  = get_Proj_for_pn(node, pn_ia32_Jcc_false);
792
793
	ir_node const *block       = get_nodes_block(node);
	if (fallthrough_possible(block, target_true)) {
794
		/* exchange both proj's so the second one can be omitted */
795
796
		const ir_node *t = proj_true;

797
798
		proj_true  = proj_false;
		proj_false = t;
799
		cc         = x86_negate_condition_code(cc);
800
	}
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
	const ir_node *target_false = get_cfop_target_block(proj_false);
	bool           fallthrough  = fallthrough_possible(block, target_false);
	/* if we can't have a fallthrough anyway, put the more likely case first */
	if (!fallthrough) {
		/* We would need execfreq for the concrete edge, but don't have it
		 * available here, so we use the block execfreq :-( */
		double freq_true  = get_block_execfreq(target_true);
		double freq_false = get_block_execfreq(target_false);
		if (freq_false > freq_true) {
			const ir_node *t = proj_true;
			proj_true  = proj_false;
			proj_false = t;
			cc         = x86_negate_condition_code(cc);
		}
	}
816

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

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

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

857
	x86_condition_code_t const cc = determine_final_cc(node, n_ia32_Setcc_eflags);
858
859
	if (cc & x86_cc_float_parity_cases) {
		if (cc & x86_cc_negated) {
860
861
862
			ia32_emitf(node, "set%PX %<R", (int)cc, dreg);
			ia32_emitf(node, "setp %>R", dreg);
			ia32_emitf(node, "orb %>R, %<R", dreg, dreg);
863
		} else {
864
865
866
			ia32_emitf(node, "set%PX %<R", (int)cc, dreg);
			ia32_emitf(node, "setnp %>R", dreg);
			ia32_emitf(node, "andb %>R, %<R", dreg, dreg);
867
		}
868
	} else {
869
		ia32_emitf(node, "set%PX %#R", (int)cc, dreg);
870
871
872
	}
}

873
/**
874
 * Emits code for a SwitchJmp
875
876
877
 */
static void emit_ia32_SwitchJmp(const ir_node *node)
{
878
	ir_entity             *jump_table = get_ia32_am_ent(node);
Matthias Braun's avatar
Matthias Braun committed
879
	const ir_switch_table *table      = get_ia32_switch_table(node);
Christian Würdig's avatar
Christian Würdig committed
880

881
	ia32_emitf(node, "jmp %*AM");
Matthias Braun's avatar
Matthias Braun committed
882
	be_emit_jump_table(node, table, jump_table, get_cfop_target_block);
Christian Würdig's avatar
Christian Würdig committed
883
884
885
886
887
}

/**
 * Emits code for a unconditional jump.
 */
888
static void emit_ia32_Jmp(const ir_node *node)
889
{
890
	/* we have a block schedule */
891
892
893
	ir_node *block  = get_nodes_block(node);
	ir_node *target = get_cfop_target_block(node);
	if (fallthrough_possible(block, target)) {