ia32_emitter.c 96.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"
Christian Würdig's avatar
Christian Würdig committed
63

64
65
66
67
68
69
70
71
#include "besched.h"
#include "benode.h"
#include "beabi.h"
#include "be_dbgout.h"
#include "beemitter.h"
#include "begnuas.h"
#include "beirg.h"
#include "be_dbgout.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;)

Christian Würdig's avatar
Christian Würdig committed
84
85
#define SNPRINTF_BUF_LEN 128

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

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

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

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

109
	return 1;
110
111
}

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

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

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

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

	return need_label;
}

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

Michael Beck's avatar
Michael Beck committed
149
150
151
/**
 * Emit the name of the 8bit low register
 */
152
153
static void emit_8bit_register(const arch_register_t *reg)
{
154
	const char *reg_name = arch_register_get_name(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
168
/**
 * 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);
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
static void emit_16bit_register(const arch_register_t *reg)
{
179
	const char *reg_name = arch_register_get_name(reg);
Christian Würdig's avatar
Christian Würdig committed
180

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

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

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

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

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

210
void ia32_emit_source_register(const ir_node *node, int pos)
211
{
212
	const arch_register_t *reg = arch_get_irn_register_in(node, pos);
213

214
	emit_register(reg, NULL);
215
216
}

217
218
static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
{
219
	be_gas_emit_entity(entity);
220
221

	if (get_entity_owner(entity) == get_tls_type()) {
222
		if (get_entity_visibility(entity) == ir_visibility_external) {
223
224
225
226
227
228
			be_emit_cstring("@INDNTPOFF");
		} else {
			be_emit_cstring("@NTPOFF");
		}
	}

229
	if (do_pic && !no_pic_adjust) {
230
231
232
233
234
235
236
237
238
239
240
241
		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('-');
242
		ia32_emit_entity(attr->symconst, attr->no_pic_adjust);
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
	}
	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);
}
258
259
260
261

void ia32_emit_8bit_source_register_or_immediate(const ir_node *node, int pos)
{
	const arch_register_t *reg;
Michael Beck's avatar
Michael Beck committed
262
	const ir_node         *in = get_irn_n(node, pos);
Christoph Mallon's avatar
Christoph Mallon committed
263
	if (is_ia32_Immediate(in)) {
264
265
266
267
		emit_ia32_Immediate(in);
		return;
	}

268
	reg = arch_get_irn_register_in(node, pos);
269
270
271
	emit_8bit_register(reg);
}

Michael Beck's avatar
Michael Beck committed
272
273
void ia32_emit_8bit_high_source_register(const ir_node *node, int pos)
{
274
	const arch_register_t *reg = arch_get_irn_register_in(node, pos);
Michael Beck's avatar
Michael Beck committed
275
276
277
	emit_8bit_register_high(reg);
}

278
279
280
281
282
283
284
285
286
void ia32_emit_16bit_source_register_or_immediate(const ir_node *node, int pos)
{
	const arch_register_t *reg;
	const ir_node         *in = get_irn_n(node, pos);
	if (is_ia32_Immediate(in)) {
		emit_ia32_Immediate(in);
		return;
	}

287
	reg = arch_get_irn_register_in(node, pos);
288
289
290
	emit_16bit_register(reg);
}

291
292
void ia32_emit_dest_register(const ir_node *node, int pos)
{
293
	const arch_register_t *reg  = arch_get_irn_register_out(node, pos);
294
295
296
297

	emit_register(reg, NULL);
}

298
299
void ia32_emit_dest_register_size(const ir_node *node, int pos)
{
300
	const arch_register_t *reg  = arch_get_irn_register_out(node, pos);
301
302
303
304

	emit_register(reg, get_ia32_ls_mode(node));
}

305
306
void ia32_emit_8bit_dest_register(const ir_node *node, int pos)
{
307
	const arch_register_t *reg  = arch_get_irn_register_out(node, pos);
308
309
310
311
312

	emit_register(reg, mode_Bu);
}

void ia32_emit_x87_register(const ir_node *node, int pos)
Christian Würdig's avatar
Christian Würdig committed
313
{
314
	const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
315

Matthias Braun's avatar
Matthias Braun committed
316
	assert(pos < 3);
317
318
	be_emit_char('%');
	be_emit_string(attr->x87[pos]->name);
319
}
Christian Würdig's avatar
Christian Würdig committed
320

Matthias Braun's avatar
Matthias Braun committed
321
static void ia32_emit_mode_suffix_mode(const ir_mode *mode)
322
{
323
324
325
326
327
	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
328
329
		/* gas docu says q is the suffix but gcc, objdump and icc use ll
		 * apparently */
Matthias Braun's avatar
Matthias Braun committed
330
331
		case 64: be_emit_cstring("ll"); return;
	}
332
	panic("Can't output mode_suffix for %+F", mode);
Christian Würdig's avatar
Christian Würdig committed
333
334
}

335
void ia32_emit_mode_suffix(const ir_node *node)
336
337
{
	ir_mode *mode = get_ia32_ls_mode(node);
Christoph Mallon's avatar
Christoph Mallon committed
338
	if (mode == NULL)
Matthias Braun's avatar
Matthias Braun committed
339
340
		mode = mode_Iu;

341
	ia32_emit_mode_suffix_mode(mode);
342
343
}

344
void ia32_emit_x87_mode_suffix(const ir_node *node)
345
{
346
347
	ir_mode *mode;

348
	/* we only need to emit the mode on address mode */
349
350
351
352
353
354
355
356
	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)) {
357
358
359
360
361
362
363
			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;
364
365
		}
	} else {
366
		assert(mode_is_int(mode) || mode_is_reference(mode));
367
368
369
370
371
372
373
		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;
		}
374
	}
375
	panic("Can't output mode_suffix for %+F", mode);
376
377
}

378
static char get_xmm_mode_suffix(ir_mode *mode)
379
380
{
	assert(mode_is_float(mode));
381
	switch (get_mode_size_bits(mode)) {
Christoph Mallon's avatar
Christoph Mallon committed
382
383
384
	case 32: return 's';
	case 64: return 'd';
	default: panic("Invalid XMM mode");
385
386
387
	}
}

388
void ia32_emit_xmm_mode_suffix(const ir_node *node)
389
390
{
	ir_mode *mode = get_ia32_ls_mode(node);
391
	assert(mode != NULL);
392
393
	be_emit_char('s');
	be_emit_char(get_xmm_mode_suffix(mode));
394
395
}

396
void ia32_emit_xmm_mode_suffix_s(const ir_node *node)
397
398
399
{
	ir_mode *mode = get_ia32_ls_mode(node);
	assert(mode != NULL);
400
	be_emit_char(get_xmm_mode_suffix(mode));
401
402
}

403
void ia32_emit_extend_suffix(const ir_node *node)
404
{
405
	ir_mode *mode = get_ia32_ls_mode(node);
Christoph Mallon's avatar
Christoph Mallon committed
406
	if (get_mode_size_bits(mode) == 32)
407
		return;
Christoph Mallon's avatar
Christoph Mallon committed
408
	be_emit_char(mode_is_signed(mode) ? 's' : 'z');
409
	ia32_emit_mode_suffix_mode(mode);
Matthias Braun's avatar
Matthias Braun committed
410
411
}

412
void ia32_emit_source_register_or_immediate(const ir_node *node, int pos)
413
414
{
	ir_node *in = get_irn_n(node, pos);
Christoph Mallon's avatar
Christoph Mallon committed
415
	if (is_ia32_Immediate(in)) {
416
		emit_ia32_Immediate(in);
417
	} else {
418
		const ir_mode         *mode = get_ia32_ls_mode(node);
419
		const arch_register_t *reg  = arch_get_irn_register_in(node, pos);
420
		emit_register(reg, mode);
421
422
423
	}
}

Christian Würdig's avatar
Christian Würdig committed
424
/**
425
 * Returns the target block for a control flow node.
Christian Würdig's avatar
Christian Würdig committed
426
 */
427
static ir_node *get_cfop_target_block(const ir_node *irn)
Christoph Mallon's avatar
Christoph Mallon committed
428
{
429
	assert(get_irn_mode(irn) == mode_X);
430
	return (ir_node*)get_irn_link(irn);
431
}
Christian Würdig's avatar
Christian Würdig committed
432

433
434
435
436
437
438
/**
 * 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);
439
	be_gas_emit_block_name(block);
440
441
}

Michael Beck's avatar
Michael Beck committed
442
443
444
/**
 * Emit the suffix for a compare instruction.
 */
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
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;
477
	}
478
	panic("Invalid ia32 condition code");
479
480
}

481
typedef enum ia32_emit_mod_t {
482
	EMIT_NONE         = 0,
483
	EMIT_RESPECT_LS   = 1U << 0,
484
	EMIT_ALTERNATE_AM = 1U << 1,
485
486
487
	EMIT_LONG         = 1U << 2,
	EMIT_HIGH_REG     = 1U << 3,
	EMIT_LOW_REG      = 1U << 4
488
} ia32_emit_mod_t;
489
ENUM_BITSET(ia32_emit_mod_t)
490

491
492
493
494
495
496
497
498
499
/**
 * Emits address mode.
 */
void ia32_emit_am(const ir_node *node)
{
	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);
500
501
	ir_node   *idx       = get_irn_n(node, n_ia32_index);
	int        has_index = !is_ia32_NoReg_GP(idx);
502
503
504
505

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

506
507
508
	if (get_ia32_am_tls_segment(node))
		be_emit_cstring("%gs:");

509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
	/* 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) {
531
			const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_base);
532
533
534
535
536
			emit_register(reg, NULL);
		}

		/* emit index + scale */
		if (has_index) {
537
			const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_index);
538
539
540
541
542
543
544
545
546
547
548
549
550
			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(')');
	}
}

551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
/**
 * fmt  parameter               output
 * ---- ----------------------  ---------------------------------------------
 * %%                           %
 * %AM  <node>                  address mode of the node
 * %AR  const arch_register_t*  address mode of the node or register
 * %ASx <node>                  address mode of the node or source register x
 * %Dx  <node>                  destination register x
 * %I   <node>                  immediate of the node
 * %L   <node>                  control flow target of the node
 * %M   <node>                  mode suffix of the node
 * %P   int                     condition code
 * %R   const arch_register_t*  register
 * %Sx  <node>                  source register x
 * %s   const char*             string
 * %u   unsigned int            unsigned int
567
 * %d   signed int              signed int
568
569
 *
 * x starts at 0
570
 * # modifier for %ASx, %D, %R, and %S uses ls mode of node to alter register width
571
 * * modifier does not prefix immediates with $, but AM with *
572
 * l modifier for %lu and %ld
573
574
 * > modifier to output high 8bit register (ah, bh)
 * < modifier to output low 8bit register (al, bl)
575
576
577
578
579
580
581
 */
static void ia32_emitf(const ir_node *node, const char *fmt, ...)
{
	va_list ap;
	va_start(ap, fmt);

	for (;;) {
582
		const char      *start = fmt;
583
		ia32_emit_mod_t  mod   = EMIT_NONE;
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599

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

		if (*fmt == '\n') {
			be_emit_finish_line_gas(node);
			++fmt;
			if (*fmt == '\0')
				break;
			continue;
		}

		if (*fmt == '\0')
Christian Würdig's avatar
Christian Würdig committed
600
			break;
601
602

		++fmt;
603
604
		for (;;) {
			switch (*fmt) {
605
606
607
			case '*': mod |= EMIT_ALTERNATE_AM; break;
			case '#': mod |= EMIT_RESPECT_LS;   break;
			case 'l': mod |= EMIT_LONG;         break;
608
609
			case '>': mod |= EMIT_HIGH_REG;     break;
			case '<': mod |= EMIT_LOW_REG;      break;
610
611
612
			default:
				goto end_of_mods;
			}
613
614
			++fmt;
		}
615
end_of_mods:
616

617
		switch (*fmt++) {
618
619
620
			arch_register_t const *reg;
			ir_node         const *imm;

621
622
623
624
625
626
			case '%':
				be_emit_char('%');
				break;

			case 'A': {
				switch (*fmt++) {
627
emit_AM:
628
					case 'M':
629
630
						if (mod & EMIT_ALTERNATE_AM)
							be_emit_char('*');
631
632
633
						ia32_emit_am(node);
						break;

634
635
					case 'R':
						reg = va_arg(ap, const arch_register_t*);
636
						if (get_ia32_op_type(node) == ia32_AddrModeS) {
637
							goto emit_AM;
638
						} else {
639
							goto emit_R;
640
641
642
643
644
						}

					case 'S':
						if (get_ia32_op_type(node) == ia32_AddrModeS) {
							++fmt;
645
							goto emit_AM;
646
647
648
649
650
651
652
653
654
655
						} else {
							assert(get_ia32_op_type(node) == ia32_Normal);
							goto emit_S;
						}

					default: goto unknown;
				}
				break;
			}

656
			case 'D':
657
658
				if (*fmt < '0' || '9' <= *fmt)
					goto unknown;
659
				reg = arch_get_irn_register_out(node, *fmt++ - '0');
660
				goto emit_R;
661
662

			case 'I':
663
664
				imm = node;
emit_I:
665
666
				if (!(mod & EMIT_ALTERNATE_AM))
					be_emit_char('$');
667
				emit_ia32_Immediate_no_prefix(imm);
668
669
670
671
672
673
				break;

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

674
			case 'M':
675
676
677
678
				ia32_emit_mode_suffix_mode(get_ia32_ls_mode(node));
				break;

			case 'P': {
679
680
				ia32_condition_code_t cc = va_arg(ap, ia32_condition_code_t);
				ia32_emit_condition_code(cc);
681
682
683
				break;
			}

684
685
686
687
688
			case 'R':
				reg = va_arg(ap, const arch_register_t*);
emit_R:
				if (mod & EMIT_ALTERNATE_AM)
					be_emit_char('*');
689
690
691
692
693
694
695
				if (mod & EMIT_HIGH_REG) {
					emit_8bit_register_high(reg);
				} else if (mod & EMIT_LOW_REG) {
					emit_8bit_register(reg);
				} else {
					emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
				}
696
697
698
699
				break;

emit_S:
			case 'S': {
700
				unsigned pos;
701
702
703
704
705

				if (*fmt < '0' || '9' <= *fmt)
					goto unknown;

				pos = *fmt++ - '0';
706
707
708
				imm = get_irn_n(node, pos);
				if (is_ia32_Immediate(imm)) {
					goto emit_I;
709
				} else {
710
					reg = arch_get_irn_register_in(node, pos);
711
					goto emit_R;
712
713
714
715
716
717
718
719
720
				}
			}

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

721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
			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);
				}
739
740
741
742
				break;

			default:
unknown:
743
				panic("unknown format conversion in ia32_emitf()");
744
		}
745
746
747
748
749
750
751
752
753
754
755
756
757
758
	}

	va_end(ap);
}

/**
 * Emits registers and/or address mode of a binary operation.
 */
void ia32_emit_binop(const ir_node *node)
{
	if (is_ia32_Immediate(get_irn_n(node, n_ia32_binary_right))) {
		ia32_emitf(node, "%#S4, %#AS3");
	} else {
		ia32_emitf(node, "%#AS4, %#S3");
Christian Würdig's avatar
Christian Würdig committed
759
	}
760
761
}

762
763
764
/**
 * Emits registers and/or address mode of a binary operation.
 */
Christoph Mallon's avatar
Christoph Mallon committed
765
766
void ia32_emit_x87_binop(const ir_node *node)
{
767
	switch (get_ia32_op_type(node)) {
768
		case ia32_Normal:
769
			{
770
771
				const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
				const arch_register_t *in1      = x87_attr->x87[0];
772
				const arch_register_t *in       = x87_attr->x87[1];
773
				const arch_register_t *out      = x87_attr->x87[2];
774

775
776
777
778
779
				if (out == NULL) {
					out = in1;
				} else if (out == in) {
					in = in1;
				}
780

781
782
783
784
				be_emit_char('%');
				be_emit_string(arch_register_get_name(in));
				be_emit_cstring(", %");
				be_emit_string(arch_register_get_name(out));
785
786
787
			}
			break;
		case ia32_AddrModeS:
788
			ia32_emit_am(node);
789
			break;
790
		case ia32_AddrModeD:
791
792
793
794
795
		default:
			assert(0 && "unsupported op type");
	}
}

Christian Würdig's avatar
Christian Würdig committed
796
797
798
/**
 * Emits registers and/or address mode of a unary operation.
 */
Christoph Mallon's avatar
Christoph Mallon committed
799
800
void ia32_emit_unop(const ir_node *node, int pos)
{
801
802
803
	char fmt[] = "%ASx";
	fmt[3] = '0' + pos;
	ia32_emitf(node, fmt);
Christian Würdig's avatar
Christian Würdig committed
804
805
}

Matthias Braun's avatar
Matthias Braun committed
806
807
808
static void emit_ia32_IMul(const ir_node *node)
{
	ir_node               *left    = get_irn_n(node, n_ia32_IMul_left);
809
	const arch_register_t *out_reg = arch_get_irn_register_out(node, pn_ia32_IMul_res);
Matthias Braun's avatar
Matthias Braun committed
810
811

	/* do we need the 3-address form? */
Christoph Mallon's avatar
Christoph Mallon committed
812
	if (is_ia32_NoReg_GP(left) ||
813
			arch_get_irn_register_in(node, n_ia32_IMul_left) != out_reg) {
814
815
816
		ia32_emitf(node, "\timul%M %#S4, %#AS3, %#D0\n");
	} else {
		ia32_emitf(node, "\timul%M %#AS4, %#S3\n");
Matthias Braun's avatar
Matthias Braun committed
817
818
819
	}
}

820
821
822
/**
 * walks up a tree of copies/perms/spills/reloads to find the original value
 * that is moved around
823
 */
824
825
static ir_node *find_original_value(ir_node *node)
{
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
	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
842
843
		} else if (is_ia32_Store(pred)) {
			return find_original_value(get_irn_n(pred, n_ia32_Store_val));
844
845
846
		} else {
			return node;
		}
847
848
849
850
851
852
853
854
855
856
857
858
859
	} 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;
860
861
862
	}
}

863
static int determine_final_cc(const ir_node *node, int flags_pos, int cc)
864
{
865
866
867
868
	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
869
	if (is_ia32_Sahf(flags)) {
870
		ir_node *cmp = get_irn_n(flags, n_ia32_Sahf_val);
Christoph Mallon's avatar
Christoph Mallon committed
871
		if (!(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
872
				|| is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) {
873
			inc_irg_visited(current_ir_graph);
874
			cmp = find_original_value(cmp);
875
			assert(cmp != NULL);
876
			assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
877
			       || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp));
878
		}
879

880
		flags_attr = get_ia32_attr_const(cmp);
881
	} else {
882
		flags_attr = get_ia32_attr_const(flags);
883
	}
884

885
886
887
	if (flags_attr->data.ins_permuted)
		cc = ia32_invert_condition_code(cc);
	return cc;
888
889
}

890
void ia32_emit_cmp_suffix_node(const ir_node *node, int flags_pos)
891
{
892
893
	ia32_condition_code_t cc = get_ia32_condcode(node);
	cc = determine_final_cc(node, flags_pos, cc);
894

895
	ia32_emit_condition_code(cc);
896
}
897

898
899
900
901
902
903
/**
 * 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());
904
	be_emit_irprintf("%lu", get_ia32_exc_label_id(node));
905
906
}

907
908
909
/**
 * Returns the Proj with projection number proj and NOT mode_M
 */
Christoph Mallon's avatar
Christoph Mallon committed
910
911
static ir_node *get_proj(const ir_node *node, long proj)
{
912
913
914
	const ir_edge_t *edge;
	ir_node         *src;

915
	assert(get_irn_mode(node) == mode_T && "expected mode_T node");
916

917
	foreach_out_edge(node, edge) {
918
919
920
921
922
923
924
925
926
927
928
929
		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;
}

930
static int can_be_fallthrough(const ir_node *node)
931
932
933
934
935
936
{
	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
937
938
939
/**
 * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
 */
940
static void emit_ia32_Jcc(const ir_node *node)
941
{
942
943
944
945
	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
946

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

949
950
951
	/* get both Projs */
	proj_true = get_proj(node, pn_ia32_Jcc_true);
	assert(proj_true && "Jcc without true Proj");
952

953
954
	proj_false = get_proj(node, pn_ia32_Jcc_false);
	assert(proj_false && "Jcc without false Proj");
955

956
	if (can_be_fallthrough(proj_true)) {
957
		/* exchange both proj's so the second one can be omitted */
958
959
		const ir_node *t = proj_true;

960
961
		proj_true  = proj_false;
		proj_false = t;
962
		cc         = ia32_negate_condition_code(cc);
963
964
	}

965
	if (cc & ia32_cc_float_parity_cases) {
966
967
		/* Some floating point comparisons require a test of the parity flag,
		 * which indicates that the result is unordered */
968
		if (cc & ia32_cc_negated) {
969
			ia32_emitf(proj_true, "\tjp %L\n");
970
		} else {
971
972
973
974
975
976
977
978
			/* 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;
				ia32_emitf(proj_false, "\tjp 1f\n");
			} else {
				ia32_emitf(proj_false, "\tjp %L\n");
			}
979
		}
980
	}
981
	ia32_emitf(proj_true, "\tj%P %L\n", cc);
Christoph Mallon's avatar
Christoph Mallon committed
982
	if (need_parity_label) {
983
		ia32_emitf(NULL, "1:\n");
984
985
	}

986
	/* the second Proj might be a fallthrough */
Matthias Braun's avatar
Matthias Braun committed
987
	if (can_be_fallthrough(proj_false)) {
988
		ia32_emitf(proj_false, "\t/* fallthrough to %L */\n");
989
	} else {
990
		ia32_emitf(proj_false, "\tjmp %L\n");
991
	}
Michael Beck's avatar
Michael Beck committed
992
993
}

994
995
996
997
998
999
/**
 * Emits an ia32 Setcc. This is mostly easy but some floating point compares
 * are tricky.
 */
static void emit_ia32_Setcc(const ir_node *node)
{
1000
	const arch_register_t *dreg = arch_get_irn_register_out(node, pn_ia32_Setcc_res);
1001

1002
1003
1004
1005
1006
	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) {
			ia32_emitf(node, "\tset%P %<R\n", cc, dreg);
1007
1008
			ia32_emitf(node, "\tsetp %>R\n", dreg);
			ia32_emitf(node, "\torb %>R, %<R\n", dreg, dreg);
1009
1010
1011
1012
		} else {
			ia32_emitf(node, "\tset%P %<R\n", cc, dreg);
			ia32_emitf(node, "\tsetnp %>R\n", dreg);
			ia32_emitf(node, "\tandb %>R, %<R\n", dreg, dreg);
1013
		}