ia32_emitter.c 97.5 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
	const char *reg_name = arch_register_get_name(reg);
157
158
	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
159

160
	be_emit_char('%');
161
	be_emit_char(reg_name[1]); /* get the basic name of the register */
162
163
164
	be_emit_char('l');
}

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

	be_emit_char('%');
175
	be_emit_char(reg_name[1]); /* get the basic name of the register */
Michael Beck's avatar
Michael Beck committed
176
177
178
	be_emit_char('h');
}

179
180
static void emit_16bit_register(const arch_register_t *reg)
{
181
	const char *reg_name = arch_register_get_name(reg);
Christian Würdig's avatar
Christian Würdig committed
182

183
	be_emit_char('%');
184
	be_emit_string(reg_name+1); /* skip the 'e' prefix of the 32bit names */
185
186
}

187
188
189
190
191
192
/**
 * emit a register, possible shortened by a mode
 *
 * @param reg   the register
 * @param mode  the mode of the register or NULL for full register
 */
193
194
195
196
static void emit_register(const arch_register_t *reg, const ir_mode *mode)
{
	const char *reg_name;

Christoph Mallon's avatar
Christoph Mallon committed
197
	if (mode != NULL) {
198
		int size = get_mode_size_bits(mode);
Christoph Mallon's avatar
Christoph Mallon committed
199
200
201
		switch (size) {
			case  8: emit_8bit_register(reg);  return;
			case 16: emit_16bit_register(reg); return;
202
		}
Christoph Mallon's avatar
Christoph Mallon committed
203
		assert(mode_is_float(mode) || size == 32);
204
205
206
	}

	reg_name = arch_register_get_name(reg);
Christian Würdig's avatar
Christian Würdig committed
207

208
209
	be_emit_char('%');
	be_emit_string(reg_name);
Christian Würdig's avatar
Christian Würdig committed
210
211
}

212
213
static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
{
214
	be_gas_emit_entity(entity);
215
216

	if (get_entity_owner(entity) == get_tls_type()) {
Matthias Braun's avatar
Matthias Braun committed
217
		if (!entity_has_definition(entity)) {
218
219
220
221
222
223
			be_emit_cstring("@INDNTPOFF");
		} else {
			be_emit_cstring("@NTPOFF");
		}
	}

224
	if (do_pic && !no_pic_adjust) {
225
226
227
228
229
230
231
232
233
234
235
236
		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('-');
237
		ia32_emit_entity(attr->symconst, attr->no_pic_adjust);
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
	}
	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);
}
253

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

268
static void ia32_emit_x87_mode_suffix(ir_node const *const node)
269
{
270
271
	ir_mode *mode;

272
	/* we only need to emit the mode on address mode */
273
274
275
276
277
278
279
280
	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)) {
281
282
283
284
285
286
287
			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;
288
289
		}
	} else {
290
		assert(mode_is_int(mode) || mode_is_reference(mode));
291
292
293
294
295
296
297
		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;
		}
298
	}
299
	panic("Can't output mode_suffix for %+F", mode);
300
301
}

302
static char get_xmm_mode_suffix(ir_mode *mode)
303
304
{
	assert(mode_is_float(mode));
305
	switch (get_mode_size_bits(mode)) {
Christoph Mallon's avatar
Christoph Mallon committed
306
307
308
	case 32: return 's';
	case 64: return 'd';
	default: panic("Invalid XMM mode");
309
310
311
	}
}

312
static void ia32_emit_xmm_mode_suffix(ir_node const *const node)
313
314
315
{
	ir_mode *mode = get_ia32_ls_mode(node);
	assert(mode != NULL);
316
	be_emit_char(get_xmm_mode_suffix(mode));
317
318
}

Christian Würdig's avatar
Christian Würdig committed
319
/**
320
 * Returns the target block for a control flow node.
Christian Würdig's avatar
Christian Würdig committed
321
 */
322
static ir_node *get_cfop_target_block(const ir_node *irn)
Christoph Mallon's avatar
Christoph Mallon committed
323
{
324
	assert(get_irn_mode(irn) == mode_X);
325
	return (ir_node*)get_irn_link(irn);
326
}
Christian Würdig's avatar
Christian Würdig committed
327

328
329
330
331
332
333
/**
 * 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);
334
	be_gas_emit_block_name(block);
335
336
}

Michael Beck's avatar
Michael Beck committed
337
338
339
/**
 * Emit the suffix for a compare instruction.
 */
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
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;
372
	}
373
	panic("Invalid ia32 condition code");
374
375
}

376
typedef enum ia32_emit_mod_t {
377
	EMIT_NONE         = 0,
378
	EMIT_RESPECT_LS   = 1U << 0,
379
	EMIT_ALTERNATE_AM = 1U << 1,
380
381
	EMIT_LONG         = 1U << 2,
	EMIT_HIGH_REG     = 1U << 3,
382
383
	EMIT_LOW_REG      = 1U << 4,
	EMIT_16BIT_REG    = 1U << 5
384
} ia32_emit_mod_t;
385
ENUM_BITSET(ia32_emit_mod_t)
386

387
388
389
/**
 * Emits address mode.
 */
390
static void ia32_emit_am(ir_node const *const node)
391
392
393
394
395
{
	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);
396
397
	ir_node   *idx       = get_irn_n(node, n_ia32_index);
	int        has_index = !is_ia32_NoReg_GP(idx);
398
399
400
401

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

402
403
404
	if (get_ia32_am_tls_segment(node))
		be_emit_cstring("%gs:");

405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
	/* 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) {
427
			const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_base);
428
429
430
431
432
			emit_register(reg, NULL);
		}

		/* emit index + scale */
		if (has_index) {
433
			const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_index);
434
435
436
437
438
439
440
441
442
443
444
445
446
			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(')');
	}
}

447
448
449
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, ...)
450
451
452
453
{
	va_list ap;
	va_start(ap, fmt);

454
	be_emit_char('\t');
455
	for (;;) {
456
		const char      *start = fmt;
457
		ia32_emit_mod_t  mod   = EMIT_NONE;
458
459
460
461
462
463
464
465

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

		if (*fmt == '\n') {
466
467
468
			be_emit_char('\n');
			be_emit_write_line();
			be_emit_char('\t');
469
470
471
472
473
474
475
			++fmt;
			if (*fmt == '\0')
				break;
			continue;
		}

		if (*fmt == '\0')
Christian Würdig's avatar
Christian Würdig committed
476
			break;
477
478

		++fmt;
479
480
		for (;;) {
			switch (*fmt) {
481
482
483
			case '*': mod |= EMIT_ALTERNATE_AM; break;
			case '#': mod |= EMIT_RESPECT_LS;   break;
			case 'l': mod |= EMIT_LONG;         break;
484
485
			case '>': mod |= EMIT_HIGH_REG;     break;
			case '<': mod |= EMIT_LOW_REG;      break;
486
			case '^': mod |= EMIT_16BIT_REG;    break;
487
488
489
			default:
				goto end_of_mods;
			}
490
491
			++fmt;
		}
492
end_of_mods:
493

494
		switch (*fmt++) {
495
496
497
			arch_register_t const *reg;
			ir_node         const *imm;

498
499
500
501
502
503
			case '%':
				be_emit_char('%');
				break;

			case 'A': {
				switch (*fmt++) {
504
505
506
507
508
509
					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
510
							arch_register_t const *const out      = x87_attr->x87[2];
511
							arch_register_t const *      in       = x87_attr->x87[1];
Christoph Mallon's avatar
Christoph Mallon committed
512
513
							if (out == in)
								in = x87_attr->x87[0];
514
515
516
517
							be_emit_irprintf("%%%s, %%%s", arch_register_get_name(in), arch_register_get_name(out));
							break;
						}

518
emit_AM:
519
					case 'M':
520
521
						if (mod & EMIT_ALTERNATE_AM)
							be_emit_char('*');
522
523
524
						ia32_emit_am(node);
						break;

525
526
					case 'R':
						reg = va_arg(ap, const arch_register_t*);
527
						if (get_ia32_op_type(node) == ia32_AddrModeS) {
528
							goto emit_AM;
529
						} else {
530
							goto emit_R;
531
532
533
534
535
						}

					case 'S':
						if (get_ia32_op_type(node) == ia32_AddrModeS) {
							++fmt;
536
							goto emit_AM;
537
538
539
540
541
542
543
544
545
546
						} else {
							assert(get_ia32_op_type(node) == ia32_Normal);
							goto emit_S;
						}

					default: goto unknown;
				}
				break;
			}

547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
			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;

573
			case 'D':
574
				if (*fmt < '0' || '9' < *fmt)
575
					goto unknown;
576
				reg = arch_get_irn_register_out(node, *fmt++ - '0');
577
				goto emit_R;
578

579
580
581
582
			case 'F':
				if (*fmt == 'M') {
					++fmt;
					ia32_emit_x87_mode_suffix(node);
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
				} 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');
604
605
606
				} else if (*fmt == 'X') {
					++fmt;
					ia32_emit_xmm_mode_suffix(node);
607
				} else if ('0' <= *fmt && *fmt <= '2') {
608
609
610
611
612
613
614
615
					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;

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

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

628
629
630
631
632
633
634
635
636
637
			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);
638
				break;
639
			}
640
641

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

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

emit_S:
			case 'S': {
675
				unsigned pos;
676

677
				if (*fmt < '0' || '9' < *fmt)
678
679
680
					goto unknown;

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

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

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

			default:
unknown:
718
				panic("unknown format conversion");
719
		}
720
721
	}

722
	be_emit_finish_line_gas(node);
723
724
725
	va_end(ap);
}

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

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

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

783
784
static ia32_condition_code_t determine_final_cc(const ir_node *node,
		int flags_pos, ia32_condition_code_t cc)
785
{
786
787
788
789
	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
790
	if (is_ia32_Sahf(flags)) {
791
		ir_node *cmp = get_irn_n(flags, n_ia32_Sahf_val);
Christoph Mallon's avatar
Christoph Mallon committed
792
		if (!(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
793
				|| is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) {
794
			inc_irg_visited(current_ir_graph);
795
			cmp = find_original_value(cmp);
796
			assert(cmp != NULL);
797
			assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
798
			       || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp));
799
		}
800

801
		flags_attr = get_ia32_attr_const(cmp);
802
	} else {
803
		flags_attr = get_ia32_attr_const(flags);
804
	}
805

806
807
808
	if (flags_attr->data.ins_permuted)
		cc = ia32_invert_condition_code(cc);
	return cc;
809
810
}

811
812
813
814
815
816
/**
 * 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());
817
	be_emit_irprintf("%lu", get_ia32_exc_label_id(node));
818
819
}

820
821
822
/**
 * Returns the Proj with projection number proj and NOT mode_M
 */
Christoph Mallon's avatar
Christoph Mallon committed
823
824
static ir_node *get_proj(const ir_node *node, long proj)
{
825
	ir_node *src;
826

827
	assert(get_irn_mode(node) == mode_T && "expected mode_T node");
828

829
	foreach_out_edge(node, edge) {
830
831
832
833
834
835
836
837
838
839
840
841
		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;
}

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

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

861
862
863
	/* get both Projs */
	proj_true = get_proj(node, pn_ia32_Jcc_true);
	assert(proj_true && "Jcc without true Proj");
864

865
866
	proj_false = get_proj(node, pn_ia32_Jcc_false);
	assert(proj_false && "Jcc without false Proj");
867

868
	if (can_be_fallthrough(proj_true)) {
869
		/* exchange both proj's so the second one can be omitted */
870
871
		const ir_node *t = proj_true;

872
873
		proj_true  = proj_false;
		proj_false = t;
874
		cc         = ia32_negate_condition_code(cc);
875
876
	}

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

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

908
909
910
911
912
913
/**
 * Emits an ia32 Setcc. This is mostly easy but some floating point compares
 * are tricky.
 */
static void emit_ia32_Setcc(const ir_node *node)
{
914
	const arch_register_t *dreg = arch_get_irn_register_out(node, pn_ia32_Setcc_res);
915

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

static void emit_ia32_CMovcc(const ir_node *node)
Matthias Braun's avatar
Matthias Braun committed
934
{
935
	const ia32_attr_t     *attr = get_ia32_attr_const(node);
936
	const arch_register_t *out  = arch_get_irn_register_out(node, pn_ia32_res);
937
	ia32_condition_code_t  cc   = get_ia32_condcode(node);
938
939
940
	const arch_register_t *in_true;
	const arch_register_t *in_false;

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

949
950
	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));
951
952

	/* should be same constraint fullfilled? */
Christoph Mallon's avatar
Christoph Mallon committed
953
	if (out == in_false) {
954
		/* yes -> nothing to do */
Christoph Mallon's avatar
Christoph Mallon committed
955
	} else if (out == in_true) {
956
957
		const arch_register_t *tmp;

958
959
		assert(get_ia32_op_type(node) == ia32_Normal);

960
		cc = ia32_negate_condition_code(cc);
961
962
963
964

		tmp      = in_true;
		in_true  = in_false;
		in_false = tmp;
965
	} else {
966
		/* we need a mov */
967
		ia32_emitf(node, "movl %R, %R", in_false, out);
968
	}
969

970
971
	if (cc & ia32_cc_float_parity_cases) {
		panic("CMov with floatingpoint compare/parity not supported yet");
972
	}
973

974
	ia32_emitf(node, "cmov%PX %#AR, %#R", (int)cc, in_true, out);
975
976
}

977
/**
978
 * Emits code for a SwitchJmp
979
980
981
 */
static void emit_ia32_SwitchJmp(const ir_node *node)
{
Matthias Braun's avatar
Matthias Braun committed
982
983
	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
984

985
	ia32_emitf(node, "jmp %*AM");
Matthias Braun's avatar
Matthias Braun committed
986
	be_emit_jump_table(node, table, jump_table, get_cfop_target_block);
Christian Würdig's avatar
Christian Würdig committed
987
988
989
990
991
}

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

Michael Beck's avatar
Michael Beck committed
1003
1004
1005
1006
1007
1008
1009
1010
/**
 * 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
 */
1011