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

20
/**
21
 * @file
Christian Würdig's avatar
Christian Würdig committed
22
23
 * @brief       This file implements the ia32 node emitter.
 * @author      Christian Wuerdig, Matthias Braun
24
25
 *
 * Summary table for x86 floatingpoint compares:
26
27
 * (remember effect of unordered on x86: ZF=1, PF=1, CF=1)
 *
28
29
30
31
32
 *   pnc_Eq  => !P && E
 *   pnc_Lt  => !P && B
 *   pnc_Le  => !P && BE
 *   pnc_Gt  => A
 *   pnc_Ge  => AE
33
 *   pnc_Lg  => NE
34
35
36
37
38
39
40
 *   pnc_Leg => NP  (ordered)
 *   pnc_Uo  => P
 *   pnc_Ue  => E
 *   pnc_Ul  => B
 *   pnc_Ule => BE
 *   pnc_Ug  => P || A
 *   pnc_Uge => P || AE
41
 *   pnc_Ne  => P || NE
42
 */
43
#include "config.h"
Christian Würdig's avatar
Christian Würdig committed
44

Christian Würdig's avatar
Christian Würdig committed
45
46
#include <limits.h>

47
#include "xmalloc.h"
48
49
#include "tv.h"
#include "iredges.h"
Christian Würdig's avatar
Christian Würdig committed
50
51
52
53
#include "debug.h"
#include "irgwalk.h"
#include "irprintf.h"
#include "irop_t.h"
Christian Würdig's avatar
Christian Würdig committed
54
#include "irargs_t.h"
55
#include "irprog_t.h"
56
#include "iredges_t.h"
57
#include "irtools.h"
58
#include "execfreq.h"
59
#include "error.h"
Matthias Braun's avatar
Matthias Braun committed
60
#include "raw_bitset.h"
61
#include "dbginfo.h"
62
#include "lc_opts.h"
63
#include "ircons.h"
Christian Würdig's avatar
Christian Würdig committed
64

65
66
67
#include "besched.h"
#include "benode.h"
#include "beabi.h"
68
#include "bedwarf.h"
69
70
#include "beemitter.h"
#include "begnuas.h"
Christian Würdig's avatar
Christian Würdig committed
71

72
#include "ia32_emitter.h"
73
#include "ia32_common_transform.h"
Christian Würdig's avatar
Christian Würdig committed
74
#include "gen_ia32_emitter.h"
Christian Würdig's avatar
Christian Würdig committed
75
#include "gen_ia32_regalloc_if.h"
76
77
#include "ia32_nodes_attr.h"
#include "ia32_new_nodes.h"
78
#include "ia32_architecture.h"
Christian Würdig's avatar
Christian Würdig committed
79
#include "bearch_ia32_t.h"
Christian Würdig's avatar
Christian Würdig committed
80

81
82
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)

83
static const ia32_isa_t *isa;
84
static char              pic_base_label[128];
85
static ir_label_t        exc_label_id;
86
static int               mark_spill_reload = 0;
87
static int               do_pic;
88

89
90
91
92
static bool              sp_relative;
static int               frame_type_size;
static int               callframe_offset;

93
94
95
/** Return the next block in Block schedule */
static ir_node *get_prev_block_sched(const ir_node *block)
{
96
	return (ir_node*)get_irn_link(block);
97
98
}

99
/** Checks if the current block is a fall-through target. */
100
static int is_fallthrough(const ir_node *cfgpred)
101
102
103
{
	ir_node *pred;

Christoph Mallon's avatar
Christoph Mallon committed
104
	if (!is_Proj(cfgpred))
105
		return 1;
106
	pred = get_Proj_pred(cfgpred);
Christoph Mallon's avatar
Christoph Mallon committed
107
	if (is_ia32_SwitchJmp(pred))
108
		return 0;
109

110
	return 1;
111
112
}

113
114
115
116
/**
 * returns non-zero if the given block needs a label
 * because of being a jump-target (and not a fall-through)
 */
117
static int block_needs_label(const ir_node *block)
118
{
119
	int need_label = 1;
120
121
	int  n_cfgpreds = get_Block_n_cfgpreds(block);

122
	if (get_Block_entity(block) != NULL)
123
124
		return 1;

125
	if (n_cfgpreds == 0) {
126
		need_label = 0;
127
	} else if (n_cfgpreds == 1) {
Christoph Mallon's avatar
Christoph Mallon committed
128
129
		ir_node *cfgpred       = get_Block_cfgpred(block, 0);
		ir_node *cfgpred_block = get_nodes_block(cfgpred);
130
131
132

		if (get_prev_block_sched(block) == cfgpred_block
				&& is_fallthrough(cfgpred)) {
133
			need_label = 0;
134
135
136
137
138
139
		}
	}

	return need_label;
}

Michael Beck's avatar
Michael Beck committed
140
/**
141
 * Add a number to a prefix. This number will not be used a second time.
Michael Beck's avatar
Michael Beck committed
142
 */
143
144
static char *get_unique_label(char *buf, size_t buflen, const char *prefix)
{
145
	static unsigned long id = 0;
146
	snprintf(buf, buflen, "%s%s%lu", be_gas_get_private_prefix(), prefix, ++id);
147
148
149
	return buf;
}

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

158
	be_emit_char('%');
159
	be_emit_char(reg->name[1]); /* get the basic name of the register */
160
161
162
	be_emit_char('l');
}

Michael Beck's avatar
Michael Beck committed
163
164
165
166
167
/**
 * Emit the name of the 8bit high register
 */
static void emit_8bit_register_high(const arch_register_t *reg)
{
168
169
	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
170
171

	be_emit_char('%');
172
	be_emit_char(reg->name[1]); /* get the basic name of the register */
Michael Beck's avatar
Michael Beck committed
173
174
175
	be_emit_char('h');
}

176
177
178
static void emit_16bit_register(const arch_register_t *reg)
{
	be_emit_char('%');
179
	be_emit_string(reg->name + 1); /* skip the 'e' prefix of the 32bit names */
180
181
}

182
183
184
185
186
187
/**
 * emit a register, possible shortened by a mode
 *
 * @param reg   the register
 * @param mode  the mode of the register or NULL for full register
 */
188
189
static void emit_register(const arch_register_t *reg, const ir_mode *mode)
{
Christoph Mallon's avatar
Christoph Mallon committed
190
	if (mode != NULL) {
191
		int size = get_mode_size_bits(mode);
Christoph Mallon's avatar
Christoph Mallon committed
192
193
194
		switch (size) {
			case  8: emit_8bit_register(reg);  return;
			case 16: emit_16bit_register(reg); return;
195
		}
Christoph Mallon's avatar
Christoph Mallon committed
196
		assert(mode_is_float(mode) || size == 32);
197
198
199
	}

	be_emit_char('%');
200
	be_emit_string(reg->name);
Christian Würdig's avatar
Christian Würdig committed
201
202
}

203
204
static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
{
205
	be_gas_emit_entity(entity);
206
207

	if (get_entity_owner(entity) == get_tls_type()) {
Matthias Braun's avatar
Matthias Braun committed
208
		if (!entity_has_definition(entity)) {
209
210
211
212
213
214
			be_emit_cstring("@INDNTPOFF");
		} else {
			be_emit_cstring("@NTPOFF");
		}
	}

215
	if (do_pic && !no_pic_adjust) {
216
217
218
219
220
221
222
223
224
225
226
227
		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('-');
228
		ia32_emit_entity(attr->symconst, attr->no_pic_adjust);
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
	}
	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);
}
244

Matthias Braun's avatar
Matthias Braun committed
245
static void ia32_emit_mode_suffix_mode(const ir_mode *mode)
246
{
247
248
249
250
251
	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
252
253
		/* gas docu says q is the suffix but gcc, objdump and icc use ll
		 * apparently */
Matthias Braun's avatar
Matthias Braun committed
254
255
		case 64: be_emit_cstring("ll"); return;
	}
256
	panic("Can't output mode_suffix for %+F", mode);
Christian Würdig's avatar
Christian Würdig committed
257
258
}

259
static void ia32_emit_x87_mode_suffix(ir_node const *const node)
260
{
261
262
	ir_mode *mode;

263
	/* we only need to emit the mode on address mode */
264
265
266
267
268
269
270
271
	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)) {
272
273
274
275
276
277
278
			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;
279
280
		}
	} else {
281
		assert(mode_is_int(mode) || mode_is_reference(mode));
282
283
284
285
286
287
288
		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;
		}
289
	}
290
	panic("Can't output mode_suffix for %+F", mode);
291
292
}

293
static char get_xmm_mode_suffix(ir_mode *mode)
294
295
{
	assert(mode_is_float(mode));
296
	switch (get_mode_size_bits(mode)) {
Christoph Mallon's avatar
Christoph Mallon committed
297
298
299
	case 32: return 's';
	case 64: return 'd';
	default: panic("Invalid XMM mode");
300
301
302
	}
}

303
static void ia32_emit_xmm_mode_suffix(ir_node const *const node)
304
305
306
{
	ir_mode *mode = get_ia32_ls_mode(node);
	assert(mode != NULL);
307
	be_emit_char(get_xmm_mode_suffix(mode));
308
309
}

Christian Würdig's avatar
Christian Würdig committed
310
/**
311
 * Returns the target block for a control flow node.
Christian Würdig's avatar
Christian Würdig committed
312
 */
313
static ir_node *get_cfop_target_block(const ir_node *irn)
Christoph Mallon's avatar
Christoph Mallon committed
314
{
315
	assert(get_irn_mode(irn) == mode_X);
316
	return (ir_node*)get_irn_link(irn);
317
}
Christian Würdig's avatar
Christian Würdig committed
318

319
320
321
322
323
324
/**
 * 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);
325
	be_gas_emit_block_name(block);
326
327
}

Michael Beck's avatar
Michael Beck committed
328
329
330
/**
 * Emit the suffix for a compare instruction.
 */
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
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;
363
	}
364
	panic("Invalid ia32 condition code");
365
366
}

367
typedef enum ia32_emit_mod_t {
368
	EMIT_NONE         = 0,
369
	EMIT_RESPECT_LS   = 1U << 0,
370
	EMIT_ALTERNATE_AM = 1U << 1,
371
372
	EMIT_LONG         = 1U << 2,
	EMIT_HIGH_REG     = 1U << 3,
373
374
	EMIT_LOW_REG      = 1U << 4,
	EMIT_16BIT_REG    = 1U << 5
375
} ia32_emit_mod_t;
376
ENUM_BITSET(ia32_emit_mod_t)
377

378
379
380
/**
 * Emits address mode.
 */
381
static void ia32_emit_am(ir_node const *const node)
382
383
384
385
386
{
	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);
387
388
	ir_node   *idx       = get_irn_n(node, n_ia32_index);
	int        has_index = !is_ia32_NoReg_GP(idx);
389
390
391
392

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

393
394
395
	if (get_ia32_am_tls_segment(node))
		be_emit_cstring("%gs:");

396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
	/* 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) {
418
			const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_base);
419
420
421
422
423
			emit_register(reg, NULL);
		}

		/* emit index + scale */
		if (has_index) {
424
			const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_index);
425
426
427
428
429
430
431
432
433
434
435
436
437
			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(')');
	}
}

438
439
440
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, ...)
441
442
443
444
{
	va_list ap;
	va_start(ap, fmt);

445
	be_emit_char('\t');
446
	for (;;) {
447
		const char      *start = fmt;
448
		ia32_emit_mod_t  mod   = EMIT_NONE;
449
450
451
452
453
454
455
456

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

		if (*fmt == '\n') {
457
458
459
			be_emit_char('\n');
			be_emit_write_line();
			be_emit_char('\t');
460
461
462
463
464
465
466
			++fmt;
			if (*fmt == '\0')
				break;
			continue;
		}

		if (*fmt == '\0')
Christian Würdig's avatar
Christian Würdig committed
467
			break;
468
469

		++fmt;
470
471
		for (;;) {
			switch (*fmt) {
472
473
474
			case '*': mod |= EMIT_ALTERNATE_AM; break;
			case '#': mod |= EMIT_RESPECT_LS;   break;
			case 'l': mod |= EMIT_LONG;         break;
475
476
			case '>': mod |= EMIT_HIGH_REG;     break;
			case '<': mod |= EMIT_LOW_REG;      break;
477
			case '^': mod |= EMIT_16BIT_REG;    break;
478
479
480
			default:
				goto end_of_mods;
			}
481
482
			++fmt;
		}
483
end_of_mods:
484

485
		switch (*fmt++) {
486
487
488
			arch_register_t const *reg;
			ir_node         const *imm;

489
490
491
492
493
494
			case '%':
				be_emit_char('%');
				break;

			case 'A': {
				switch (*fmt++) {
495
					case 'F':
496
						if (get_ia32_op_type(node) == ia32_Normal) {
497
498
499
							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);
500
							break;
501
502
						} else {
							goto emit_AM;
503
504
						}

505
emit_AM:
506
					case 'M':
507
508
						if (mod & EMIT_ALTERNATE_AM)
							be_emit_char('*');
509
510
511
						ia32_emit_am(node);
						break;

512
513
					case 'R':
						reg = va_arg(ap, const arch_register_t*);
514
						if (get_ia32_op_type(node) == ia32_Normal) {
515
							goto emit_R;
516
517
						} else {
							goto emit_AM;
518
519
520
						}

					case 'S':
521
522
523
						if (get_ia32_op_type(node) == ia32_Normal) {
							goto emit_S;
						} else {
524
							++fmt;
525
							goto emit_AM;
526
527
528
529
530
531
532
						}

					default: goto unknown;
				}
				break;
			}

533
534
535
536
537
			case 'B':
				imm = get_irn_n(node, n_ia32_binary_right);
				if (is_ia32_Immediate(imm)) {
					emit_ia32_Immediate(imm);
					be_emit_cstring(", ");
538
539
					if (get_ia32_op_type(node) == ia32_Normal) {
						goto destination_operand;
540
					} else {
541
						ia32_emit_am(node);
542
543
					}
				} else {
544
					if (get_ia32_op_type(node) == ia32_Normal) {
545
546
						reg = arch_get_irn_register_in(node, n_ia32_binary_right);
						emit_register(reg, get_ia32_ls_mode(node));
547
548
					} else {
						ia32_emit_am(node);
549
550
					}
					be_emit_cstring(", ");
551
destination_operand:
552
553
554
555
556
					reg = arch_get_irn_register_in(node, n_ia32_binary_left);
					emit_register(reg, get_ia32_ls_mode(node));
				}
				break;

557
			case 'D':
558
				if (*fmt < '0' || '9' < *fmt)
559
					goto unknown;
560
				reg = arch_get_irn_register_out(node, *fmt++ - '0');
561
				goto emit_R;
562

563
564
565
			case 'F':
				if (*fmt == 'M') {
					ia32_emit_x87_mode_suffix(node);
566
567
568
569
				} else if (*fmt == 'P') {
					ia32_x87_attr_t const *const attr = get_ia32_x87_attr_const(node);
					if (attr->pop)
						be_emit_char('p');
570
571
572
573
574
575
576
577
578
579
580
581
				} 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).
582
583
584
585
					 * 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)
586
						be_emit_char('r');
587
588
				} else if (*fmt == 'X') {
					ia32_emit_xmm_mode_suffix(node);
589
				} else if (*fmt == '0') {
590
					be_emit_char('%');
591
					be_emit_string(get_ia32_x87_attr_const(node)->reg->name);
592
593
594
				} else {
					goto unknown;
				}
595
				++fmt;
596
597
				break;

598
			case 'I':
599
600
				imm = node;
emit_I:
601
602
				if (!(mod & EMIT_ALTERNATE_AM))
					be_emit_char('$');
603
				emit_ia32_Immediate_no_prefix(imm);
604
605
606
607
608
609
				break;

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

610
611
612
613
614
615
616
617
618
619
			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);
620
				break;
621
			}
622
623

			case 'P': {
624
625
626
627
628
629
630
				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
631
					++fmt;
632
633
634
				} else {
					goto unknown;
				}
635
				ia32_emit_condition_code(cc);
636
637
638
				break;
			}

639
640
641
642
643
			case 'R':
				reg = va_arg(ap, const arch_register_t*);
emit_R:
				if (mod & EMIT_ALTERNATE_AM)
					be_emit_char('*');
644
645
646
647
				if (mod & EMIT_HIGH_REG) {
					emit_8bit_register_high(reg);
				} else if (mod & EMIT_LOW_REG) {
					emit_8bit_register(reg);
648
649
				} else if (mod & EMIT_16BIT_REG) {
					emit_16bit_register(reg);
650
651
652
				} else {
					emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
				}
653
654
655
656
				break;

emit_S:
			case 'S': {
657
				unsigned pos;
658

659
				if (*fmt < '0' || '9' < *fmt)
660
661
662
					goto unknown;

				pos = *fmt++ - '0';
663
664
665
				imm = get_irn_n(node, pos);
				if (is_ia32_Immediate(imm)) {
					goto emit_I;
666
				} else {
667
					reg = arch_get_irn_register_in(node, pos);
668
					goto emit_R;
669
670
671
672
673
674
675
676
677
				}
			}

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

678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
			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);
				}
696
697
698
699
				break;

			default:
unknown:
700
				panic("unknown format conversion");
701
		}
702
703
	}

704
	be_emit_finish_line_gas(node);
705
706
707
	va_end(ap);
}

Matthias Braun's avatar
Matthias Braun committed
708
709
710
static void emit_ia32_IMul(const ir_node *node)
{
	ir_node               *left    = get_irn_n(node, n_ia32_IMul_left);
711
	const arch_register_t *out_reg = arch_get_irn_register_out(node, pn_ia32_IMul_res);
Matthias Braun's avatar
Matthias Braun committed
712
713

	/* do we need the 3-address form? */
Christoph Mallon's avatar
Christoph Mallon committed
714
	if (is_ia32_NoReg_GP(left) ||
715
			arch_get_irn_register_in(node, n_ia32_IMul_left) != out_reg) {
716
		ia32_emitf(node, "imul%M %#S4, %#AS3, %#D0");
717
	} else {
718
		ia32_emitf(node, "imul%M %#AS4, %#S3");
Matthias Braun's avatar
Matthias Braun committed
719
720
721
	}
}

722
723
724
/**
 * walks up a tree of copies/perms/spills/reloads to find the original value
 * that is moved around
725
 */
726
727
static ir_node *find_original_value(ir_node *node)
{
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
	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
744
745
		} else if (is_ia32_Store(pred)) {
			return find_original_value(get_irn_n(pred, n_ia32_Store_val));
746
747
748
		} else {
			return node;
		}
749
750
751
752
753
754
755
756
757
758
759
760
761
	} 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;
762
763
764
	}
}

765
766
static ia32_condition_code_t determine_final_cc(const ir_node *node,
		int flags_pos, ia32_condition_code_t cc)
767
{
768
769
770
771
	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
772
	if (is_ia32_Sahf(flags)) {
773
		ir_node *cmp = get_irn_n(flags, n_ia32_Sahf_val);
774
		if (!(is_ia32_FucomFnstsw(cmp) || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) {
775
			inc_irg_visited(current_ir_graph);
776
			cmp = find_original_value(cmp);
777
			assert(cmp != NULL);
778
			assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp));
779
		}
780

781
		flags_attr = get_ia32_attr_const(cmp);
782
	} else {
783
		flags_attr = get_ia32_attr_const(flags);
784
	}
785

786
787
788
	if (flags_attr->data.ins_permuted)
		cc = ia32_invert_condition_code(cc);
	return cc;
789
790
}

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

800
801
802
/**
 * Returns the Proj with projection number proj and NOT mode_M
 */
Christoph Mallon's avatar
Christoph Mallon committed
803
804
static ir_node *get_proj(const ir_node *node, long proj)
{
805
	ir_node *src;
806

807
	assert(get_irn_mode(node) == mode_T && "expected mode_T node");
808

809
	foreach_out_edge(node, edge) {
810
811
812
813
814
815
816
817
818
819
820
821
		src = get_edge_src_irn(edge);

		assert(is_Proj(src) && "Proj expected");
		if (get_irn_mode(src) == mode_M)
			continue;

		if (get_Proj_proj(src) == proj)
			return src;
	}
	return NULL;
}

822
static int can_be_fallthrough(const ir_node *node)
823
824
825
826
827
828
{
	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
829
830
831
/**
 * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
 */
832
static void emit_ia32_Jcc(const ir_node *node)
833
{
834
835
836
837
	int                   need_parity_label = 0;
	ia32_condition_code_t cc                = get_ia32_condcode(node);
	const ir_node        *proj_true;
	const ir_node        *proj_false;
Christian Würdig's avatar
Christian Würdig committed
838

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

841
842
843
	/* get both Projs */
	proj_true = get_proj(node, pn_ia32_Jcc_true);
	assert(proj_true && "Jcc without true Proj");
844

845
846
	proj_false = get_proj(node, pn_ia32_Jcc_false);
	assert(proj_false && "Jcc without false Proj");
847

848
	if (can_be_fallthrough(proj_true)) {
849
		/* exchange both proj's so the second one can be omitted */
850
851
		const ir_node *t = proj_true;

852
853
		proj_true  = proj_false;
		proj_false = t;
854
		cc         = ia32_negate_condition_code(cc);
855
856
	}

857
	if (cc & ia32_cc_float_parity_cases) {
858
859
		/* Some floating point comparisons require a test of the parity flag,
		 * which indicates that the result is unordered */
860
		if (cc & ia32_cc_negated) {
861
			ia32_emitf(proj_true, "jp %L");
862
		} else {
863
864
865
866
			/* 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;
867
				ia32_emitf(proj_false, "jp 1f");
868
			} else {
869
				ia32_emitf(proj_false, "jp %L");
870
			}
871
		}
872
	}
873
	ia32_emitf(proj_true, "j%PX %L", (int)cc);
Christoph Mallon's avatar
Christoph Mallon committed
874
	if (need_parity_label) {
875
876
		be_emit_cstring("1:\n");
		be_emit_write_line();
877
878
	}

879
	/* the second Proj might be a fallthrough */
Matthias Braun's avatar
Matthias Braun committed
880
	if (can_be_fallthrough(proj_false)) {
881
		if (be_options.verbose_asm)
882
			ia32_emitf(proj_false, "/* fallthrough to %L */");
883
	} else {
884
		ia32_emitf(proj_false, "jmp %L");
885
	}
Michael Beck's avatar
Michael Beck committed
886
887
}

888
889
890
891
892
893
/**
 * Emits an ia32 Setcc. This is mostly easy but some floating point compares
 * are tricky.
 */
static void emit_ia32_Setcc(const ir_node *node)
{
894
	const arch_register_t *dreg = arch_get_irn_register_out(node, pn_ia32_Setcc_res);
895

896
897
898
899
	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) {
900
901
902
			ia32_emitf(node, "set%PX %<R", (int)cc, dreg);
			ia32_emitf(node, "setp %>R", dreg);
			ia32_emitf(node, "orb %>R, %<R", dreg, dreg);
903
		} else {
904
905
906
			ia32_emitf(node, "set%PX %<R", (int)cc, dreg);
			ia32_emitf(node, "setnp %>R", dreg);
			ia32_emitf(node, "andb %>R, %<R", dreg, dreg);
907
		}
908
	} else {
909
		ia32_emitf(node, "set%PX %#R", (int)cc, dreg);
910
911
912
913
	}
}

static void emit_ia32_CMovcc(const ir_node *node)
Matthias Braun's avatar
Matthias Braun committed
914
{
915
	const ia32_attr_t     *attr = get_ia32_attr_const(node);
916
	const arch_register_t *out  = arch_get_irn_register_out(node, pn_ia32_res);
917
	ia32_condition_code_t  cc   = get_ia32_condcode(node);
918
919
920
	const arch_register_t *in_true;
	const arch_register_t *in_false;

921
	cc = determine_final_cc(node, n_ia32_CMovcc_eflags, cc);
922
	/* although you can't set ins_permuted in the constructor it might still
923
924
925
	 * be set by memory operand folding
	 * Permuting inputs of a cmov means the condition is negated!
	 */
926
	if (attr->data.ins_permuted)
927
		cc = ia32_negate_condition_code(cc);
928

929
930
	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));
931
932

	/* should be same constraint fullfilled? */
Christoph Mallon's avatar
Christoph Mallon committed
933
	if (out == in_false) {
934
		/* yes -> nothing to do */
Christoph Mallon's avatar
Christoph Mallon committed
935
	} else if (out == in_true) {
936
937
		const arch_register_t *tmp;

938
939
		assert(get_ia32_op_type(node) == ia32_Normal);

940
		cc = ia32_negate_condition_code(cc);
941
942
943
944

		tmp      = in_true;
		in_true  = in_false;
		in_false = tmp;
945
	} else {
946
		/* we need a mov */
947
		ia32_emitf(node, "movl %R, %R", in_false, out);
948
	}
949

950
951
	if (cc & ia32_cc_float_parity_cases) {
		panic("CMov with floatingpoint compare/parity not supported yet");
952
	}
953

954
	ia32_emitf(node, "cmov%PX %#AR, %#R", (int)cc, in_true, out);
955
956
}

957
/**
958
 * Emits code for a SwitchJmp
959
960
961
 */
static void emit_ia32_SwitchJmp(const ir_node *node)
{
Matthias Braun's avatar
Matthias Braun committed
962
963
	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
964

965
	ia32_emitf(node, "jmp %*AM");
Matthias Braun's avatar
Matthias Braun committed
966
	be_emit_jump_table(node, table, jump_table, get_cfop_target_block);
Christian Würdig's avatar
Christian Würdig committed
967
968
969
970
971
}

/**
 * Emits code for a unconditional jump.
 */
972
static void emit_ia32_Jmp(const ir_node *node)
973
{
974
	/* we have a block schedule */
975
	if (can_be_fallthrough(node)) {
976
		if (be_options.verbose_asm)
977
			ia32_emitf(node, "/* fallthrough to