ia32_emitter.c 95.7 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
71
#include "beemitter.h"
#include "begnuas.h"
#include "beirg.h"
Christian Würdig's avatar
Christian Würdig committed
72

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

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

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

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

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

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

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

111
	return 1;
112
113
}

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

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

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

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

	return need_label;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Michael Beck's avatar
Michael Beck committed
329
330
331
/**
 * Emit the suffix for a compare instruction.
 */
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
363
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;
364
	}
365
	panic("Invalid ia32 condition code");
366
367
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

			case 'A': {
				switch (*fmt++) {
496
497
498
499
500
501
					case 'F':
						if (get_ia32_op_type(node) == ia32_AddrModeS) {
							goto emit_AM;
						} else {
							assert(get_ia32_op_type(node) == ia32_Normal);
							ia32_x87_attr_t const *const x87_attr = get_ia32_x87_attr_const(node);
Christoph Mallon's avatar
Christoph Mallon committed
502
							arch_register_t const *const out      = x87_attr->x87[2];
503
							arch_register_t const *      in       = x87_attr->x87[1];
Christoph Mallon's avatar
Christoph Mallon committed
504
505
							if (out == in)
								in = x87_attr->x87[0];
506
							be_emit_irprintf("%%%s, %%%s", in->name, out->name);
507
508
509
							break;
						}

510
emit_AM:
511
					case 'M':
512
513
						if (mod & EMIT_ALTERNATE_AM)
							be_emit_char('*');
514
515
516
						ia32_emit_am(node);
						break;

517
518
					case 'R':
						reg = va_arg(ap, const arch_register_t*);
519
						if (get_ia32_op_type(node) == ia32_AddrModeS) {
520
							goto emit_AM;
521
						} else {
522
							goto emit_R;
523
524
525
526
527
						}

					case 'S':
						if (get_ia32_op_type(node) == ia32_AddrModeS) {
							++fmt;
528
							goto emit_AM;
529
530
531
532
533
534
535
536
537
538
						} else {
							assert(get_ia32_op_type(node) == ia32_Normal);
							goto emit_S;
						}

					default: goto unknown;
				}
				break;
			}

539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
			case 'B':
				imm = get_irn_n(node, n_ia32_binary_right);
				if (is_ia32_Immediate(imm)) {
					emit_ia32_Immediate(imm);
					be_emit_cstring(", ");
					if (get_ia32_op_type(node) == ia32_AddrModeS) {
						ia32_emit_am(node);
					} else {
						assert(get_ia32_op_type(node) == ia32_Normal);
						reg = arch_get_irn_register_in(node, n_ia32_binary_left);
						emit_register(reg, get_ia32_ls_mode(node));
					}
				} else {
					if (get_ia32_op_type(node) == ia32_AddrModeS) {
						ia32_emit_am(node);
					} else {
						assert(get_ia32_op_type(node) == ia32_Normal);
						reg = arch_get_irn_register_in(node, n_ia32_binary_right);
						emit_register(reg, get_ia32_ls_mode(node));
					}
					be_emit_cstring(", ");
					reg = arch_get_irn_register_in(node, n_ia32_binary_left);
					emit_register(reg, get_ia32_ls_mode(node));
				}
				break;

565
			case 'D':
566
				if (*fmt < '0' || '9' < *fmt)
567
					goto unknown;
568
				reg = arch_get_irn_register_out(node, *fmt++ - '0');
569
				goto emit_R;
570

571
572
573
574
			case 'F':
				if (*fmt == 'M') {
					++fmt;
					ia32_emit_x87_mode_suffix(node);
575
576
577
578
579
				} else if (*fmt == 'P') {
					++fmt;
					ia32_x87_attr_t const *const attr = get_ia32_x87_attr_const(node);
					if (attr->pop)
						be_emit_char('p');
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
				} else if (*fmt == 'R') {
					++fmt;
					/* 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).
					 * This results in testing whether the left operand register is %st0
					 * instead of the expected test whether the output register equals the
					 * left operand register. */
					ia32_x87_attr_t const *const attr = get_ia32_x87_attr_const(node);
					if (get_ia32_op_type(node) == ia32_Normal ?
					    attr->x87[0] != &ia32_registers[REG_ST0] :
					    attr->attr.data.ins_permuted)
						be_emit_char('r');
601
602
603
				} else if (*fmt == 'X') {
					++fmt;
					ia32_emit_xmm_mode_suffix(node);
604
				} else if ('0' <= *fmt && *fmt <= '2') {
605
606
607
608
609
610
611
612
					const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
					be_emit_char('%');
					be_emit_string(attr->x87[*fmt++ - '0']->name);
				} else {
					goto unknown;
				}
				break;

613
			case 'I':
614
615
				imm = node;
emit_I:
616
617
				if (!(mod & EMIT_ALTERNATE_AM))
					be_emit_char('$');
618
				emit_ia32_Immediate_no_prefix(imm);
619
620
621
622
623
624
				break;

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

625
626
627
628
629
630
631
632
633
634
			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);
635
				break;
636
			}
637
638

			case 'P': {
639
640
641
642
643
644
645
				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
646
					++fmt;
647
648
649
				} else {
					goto unknown;
				}
650
				ia32_emit_condition_code(cc);
651
652
653
				break;
			}

654
655
656
657
658
			case 'R':
				reg = va_arg(ap, const arch_register_t*);
emit_R:
				if (mod & EMIT_ALTERNATE_AM)
					be_emit_char('*');
659
660
661
662
				if (mod & EMIT_HIGH_REG) {
					emit_8bit_register_high(reg);
				} else if (mod & EMIT_LOW_REG) {
					emit_8bit_register(reg);
663
664
				} else if (mod & EMIT_16BIT_REG) {
					emit_16bit_register(reg);
665
666
667
				} else {
					emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
				}
668
669
670
671
				break;

emit_S:
			case 'S': {
672
				unsigned pos;
673

674
				if (*fmt < '0' || '9' < *fmt)
675
676
677
					goto unknown;

				pos = *fmt++ - '0';
678
679
680
				imm = get_irn_n(node, pos);
				if (is_ia32_Immediate(imm)) {
					goto emit_I;
681
				} else {
682
					reg = arch_get_irn_register_in(node, pos);
683
					goto emit_R;
684
685
686
687
688
689
690
691
692
				}
			}

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

693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
			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);
				}
711
712
713
714
				break;

			default:
unknown:
715
				panic("unknown format conversion");
716
		}
717
718
	}

719
	be_emit_finish_line_gas(node);
720
721
722
	va_end(ap);
}

Matthias Braun's avatar
Matthias Braun committed
723
724
725
static void emit_ia32_IMul(const ir_node *node)
{
	ir_node               *left    = get_irn_n(node, n_ia32_IMul_left);
726
	const arch_register_t *out_reg = arch_get_irn_register_out(node, pn_ia32_IMul_res);
Matthias Braun's avatar
Matthias Braun committed
727
728

	/* do we need the 3-address form? */
Christoph Mallon's avatar
Christoph Mallon committed
729
	if (is_ia32_NoReg_GP(left) ||
730
			arch_get_irn_register_in(node, n_ia32_IMul_left) != out_reg) {
731
		ia32_emitf(node, "imul%M %#S4, %#AS3, %#D0");
732
	} else {
733
		ia32_emitf(node, "imul%M %#AS4, %#S3");
Matthias Braun's avatar
Matthias Braun committed
734
735
736
	}
}

737
738
739
/**
 * walks up a tree of copies/perms/spills/reloads to find the original value
 * that is moved around
740
 */
741
742
static ir_node *find_original_value(ir_node *node)
{
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
	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
759
760
		} else if (is_ia32_Store(pred)) {
			return find_original_value(get_irn_n(pred, n_ia32_Store_val));
761
762
763
		} else {
			return node;
		}
764
765
766
767
768
769
770
771
772
773
774
775
776
	} 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;
777
778
779
	}
}

780
781
static ia32_condition_code_t determine_final_cc(const ir_node *node,
		int flags_pos, ia32_condition_code_t cc)
782
{
783
784
785
786
	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
787
	if (is_ia32_Sahf(flags)) {
788
		ir_node *cmp = get_irn_n(flags, n_ia32_Sahf_val);
789
		if (!(is_ia32_FucomFnstsw(cmp) || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) {
790
			inc_irg_visited(current_ir_graph);
791
			cmp = find_original_value(cmp);
792
			assert(cmp != NULL);
793
			assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp));
794
		}
795

796
		flags_attr = get_ia32_attr_const(cmp);
797
	} else {
798
		flags_attr = get_ia32_attr_const(flags);
799
	}
800

801
802
803
	if (flags_attr->data.ins_permuted)
		cc = ia32_invert_condition_code(cc);
	return cc;
804
805
}

806
807
808
809
810
811
/**
 * 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());
812
	be_emit_irprintf("%lu", get_ia32_exc_label_id(node));
813
814
}

815
816
817
/**
 * Returns the Proj with projection number proj and NOT mode_M
 */
Christoph Mallon's avatar
Christoph Mallon committed
818
819
static ir_node *get_proj(const ir_node *node, long proj)
{
820
	ir_node *src;
821

822
	assert(get_irn_mode(node) == mode_T && "expected mode_T node");
823

824
	foreach_out_edge(node, edge) {
825
826
827
828
829
830
831
832
833
834
835
836
		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;
}

837
static int can_be_fallthrough(const ir_node *node)
838
839
840
841
842
843
{
	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
844
845
846
/**
 * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
 */
847
static void emit_ia32_Jcc(const ir_node *node)
848
{
849
850
851
852
	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
853

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

856
857
858
	/* get both Projs */
	proj_true = get_proj(node, pn_ia32_Jcc_true);
	assert(proj_true && "Jcc without true Proj");
859

860
861
	proj_false = get_proj(node, pn_ia32_Jcc_false);
	assert(proj_false && "Jcc without false Proj");
862

863
	if (can_be_fallthrough(proj_true)) {
864
		/* exchange both proj's so the second one can be omitted */
865
866
		const ir_node *t = proj_true;

867
868
		proj_true  = proj_false;
		proj_false = t;
869
		cc         = ia32_negate_condition_code(cc);
870
871
	}

872
	if (cc & ia32_cc_float_parity_cases) {
873
874
		/* Some floating point comparisons require a test of the parity flag,
		 * which indicates that the result is unordered */
875
		if (cc & ia32_cc_negated) {
876
			ia32_emitf(proj_true, "jp %L");
877
		} else {
878
879
880
881
			/* 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;
882
				ia32_emitf(proj_false, "jp 1f");
883
			} else {
884
				ia32_emitf(proj_false, "jp %L");
885
			}
886
		}
887
	}
888
	ia32_emitf(proj_true, "j%PX %L", (int)cc);
Christoph Mallon's avatar
Christoph Mallon committed
889
	if (need_parity_label) {
890
891
		be_emit_cstring("1:\n");
		be_emit_write_line();
892
893
	}

894
	/* the second Proj might be a fallthrough */
Matthias Braun's avatar
Matthias Braun committed
895
	if (can_be_fallthrough(proj_false)) {
896
		if (be_options.verbose_asm)
897
			ia32_emitf(proj_false, "/* fallthrough to %L */");
898
	} else {
899
		ia32_emitf(proj_false, "jmp %L");
900
	}
Michael Beck's avatar
Michael Beck committed
901
902
}

903
904
905
906
907
908
/**
 * Emits an ia32 Setcc. This is mostly easy but some floating point compares
 * are tricky.
 */
static void emit_ia32_Setcc(const ir_node *node)
{
909
	const arch_register_t *dreg = arch_get_irn_register_out(node, pn_ia32_Setcc_res);
910

911
912
913
914
	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) {
915
916
917
			ia32_emitf(node, "set%PX %<R", (int)cc, dreg);
			ia32_emitf(node, "setp %>R", dreg);
			ia32_emitf(node, "orb %>R, %<R", dreg, dreg);
918
		} else {
919
920
921
			ia32_emitf(node, "set%PX %<R", (int)cc, dreg);
			ia32_emitf(node, "setnp %>R", dreg);
			ia32_emitf(node, "andb %>R, %<R", dreg, dreg);
922
		}
923
	} else {
924
		ia32_emitf(node, "set%PX %#R", (int)cc, dreg);
925
926
927
928
	}
}

static void emit_ia32_CMovcc(const ir_node *node)
Matthias Braun's avatar
Matthias Braun committed
929
{
930
	const ia32_attr_t     *attr = get_ia32_attr_const(node);
931
	const arch_register_t *out  = arch_get_irn_register_out(node, pn_ia32_res);
932
	ia32_condition_code_t  cc   = get_ia32_condcode(node);
933
934
935
	const arch_register_t *in_true;
	const arch_register_t *in_false;

936
	cc = determine_final_cc(node, n_ia32_CMovcc_eflags, cc);
937
	/* although you can't set ins_permuted in the constructor it might still
938
939
940
	 * be set by memory operand folding
	 * Permuting inputs of a cmov means the condition is negated!
	 */
941
	if (attr->data.ins_permuted)
942
		cc = ia32_negate_condition_code(cc);
943

944
945
	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));
946
947

	/* should be same constraint fullfilled? */
Christoph Mallon's avatar
Christoph Mallon committed
948
	if (out == in_false) {
949
		/* yes -> nothing to do */
Christoph Mallon's avatar
Christoph Mallon committed
950
	} else if (out == in_true) {
951
952
		const arch_register_t *tmp;

953
954
		assert(get_ia32_op_type(node) == ia32_Normal);

955
		cc = ia32_negate_condition_code(cc);
956
957
958
959

		tmp      = in_true;
		in_true  = in_false;
		in_false = tmp;
960
	} else {
961
		/* we need a mov */
962
		ia32_emitf(node, "movl %R, %R", in_false, out);
963
	}
964

965
966
	if (cc & ia32_cc_float_parity_cases) {
		panic("CMov with floatingpoint compare/parity not supported yet");
967
	}
968

969
	ia32_emitf(node, "cmov%PX %#AR, %#R", (int)cc, in_true, out);
970
971
}

972
/**
973
 * Emits code for a SwitchJmp
974
975
976
 */
static void emit_ia32_SwitchJmp(const ir_node *node)
{
Matthias Braun's avatar
Matthias Braun committed
977
978
	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
979

980
	ia32_emitf(node, "jmp %*AM");
Matthias Braun's avatar
Matthias Braun committed
981
	be_emit_jump_table(node, table, jump_table, get_cfop_target_block);
Christian Würdig's avatar
Christian Würdig committed
982
983
984
985
986
}

/**
 * Emits code for a unconditional jump.
 */
987
static void emit_ia32_Jmp(const ir_node *node)
988
{
989
	/* we have a block schedule */
990
	if (can_be_fallthrough(node)) {
991
		if (be_options.verbose_asm)
992
			ia32_emitf(node, "/* fallthrough to %L */");
993
	} else {
994
		ia32_emitf(node, "jmp %L");
Christian Würdig's avatar
Christian Würdig committed
995
996
997
	}
}

Michael Beck's avatar
Michael Beck committed
998
999
1000
1001
1002
1003
1004
1005
/**
 * Emit an inline assembler operand.
 *
 * @param node  the ia32_ASM node
 * @param s     points to the operand (a %c)
 *
 * @return  pointer to the first char in s NOT in the current operand
 */
1006
static const char* emit_asm_operand(const ir_node *node, const char *s)
1007
{
1008
1009
1010
	const ia32_attr_t     *ia32_attr = get_ia32_attr_const(node);
	const ia32_asm_attr_t *attr      = CONST_CAST_IA32_ATTR(ia32_asm_attr_t,
                                                            ia32_attr);
1011
	const arch_register_t *reg;
1012
1013
	const ia32_asm_reg_t  *asm_regs =