ia32_emitter.c 98.8 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
void ia32_emit_source_register(const ir_node *node, int pos)
213
{
214
	const arch_register_t *reg = arch_get_irn_register_in(node, pos);
215

216
	emit_register(reg, NULL);
217
218
}

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

	if (get_entity_owner(entity) == get_tls_type()) {
Matthias Braun's avatar
Matthias Braun committed
224
		if (!entity_has_definition(entity)) {
225
226
227
228
229
230
			be_emit_cstring("@INDNTPOFF");
		} else {
			be_emit_cstring("@NTPOFF");
		}
	}

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

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
264
	const ir_node         *in = get_irn_n(node, pos);
Christoph Mallon's avatar
Christoph Mallon committed
265
	if (is_ia32_Immediate(in)) {
266
267
268
269
		emit_ia32_Immediate(in);
		return;
	}

270
	reg = arch_get_irn_register_in(node, pos);
271
272
273
	emit_8bit_register(reg);
}

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

280
281
282
283
284
285
286
287
288
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;
	}

289
	reg = arch_get_irn_register_in(node, pos);
290
291
292
	emit_16bit_register(reg);
}

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

	emit_register(reg, NULL);
}

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

	emit_register(reg, get_ia32_ls_mode(node));
}

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

	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
315
{
316
	const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
317

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

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

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

343
	ia32_emit_mode_suffix_mode(mode);
344
345
}

346
void ia32_emit_x87_mode_suffix(const ir_node *node)
347
{
348
349
	ir_mode *mode;

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

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

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

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

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

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

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

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

Michael Beck's avatar
Michael Beck committed
444
445
446
/**
 * Emit the suffix for a compare instruction.
 */
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
477
478
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;
479
	}
480
	panic("Invalid ia32 condition code");
481
482
}

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

493
494
495
496
497
498
499
500
501
/**
 * 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);
502
503
	ir_node   *idx       = get_irn_n(node, n_ia32_index);
	int        has_index = !is_ia32_NoReg_GP(idx);
504
505
506
507

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

508
509
510
	if (get_ia32_am_tls_segment(node))
		be_emit_cstring("%gs:");

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

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

553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
/**
 * 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
569
 * %d   signed int              signed int
570
571
 *
 * x starts at 0
572
 * # modifier for %ASx, %D, %R, and %S uses ls mode of node to alter register width
573
 * * modifier does not prefix immediates with $, but AM with *
574
 * l modifier for %lu and %ld
575
576
 * > modifier to output high 8bit register (ah, bh)
 * < modifier to output low 8bit register (al, bl)
577
578
579
580
581
582
583
 */
static void ia32_emitf(const ir_node *node, const char *fmt, ...)
{
	va_list ap;
	va_start(ap, fmt);

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

		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
602
			break;
603
604

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

619
		switch (*fmt++) {
620
621
622
			arch_register_t const *reg;
			ir_node         const *imm;

623
624
625
626
627
628
			case '%':
				be_emit_char('%');
				break;

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

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

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

					default: goto unknown;
				}
				break;
			}

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

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

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

676
			case 'M':
677
678
679
680
				ia32_emit_mode_suffix_mode(get_ia32_ls_mode(node));
				break;

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

686
687
688
689
690
			case 'R':
				reg = va_arg(ap, const arch_register_t*);
emit_R:
				if (mod & EMIT_ALTERNATE_AM)
					be_emit_char('*');
691
692
693
694
695
696
697
				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);
				}
698
699
700
701
				break;

emit_S:
			case 'S': {
702
				unsigned pos;
703
704
705
706
707

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

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

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

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

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

	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
761
	}
762
763
}

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

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

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

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

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

	/* do we need the 3-address form? */
Christoph Mallon's avatar
Christoph Mallon committed
814
	if (is_ia32_NoReg_GP(left) ||
815
			arch_get_irn_register_in(node, n_ia32_IMul_left) != out_reg) {
816
817
818
		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
819
820
821
	}
}

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

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

882
		flags_attr = get_ia32_attr_const(cmp);
883
	} else {
884
		flags_attr = get_ia32_attr_const(flags);
885
	}
886

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

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

897
	ia32_emit_condition_code(cc);
898
}
899

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

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

917
	assert(get_irn_mode(node) == mode_T && "expected mode_T node");
918

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

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

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

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

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

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

962
963
		proj_true  = proj_false;
		proj_false = t;
964
		cc         = ia32_negate_condition_code(cc);
965
966
	}

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

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

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

1004
1005
1006
1007
1008
	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);
1009
1010
			ia32_emitf(node, "\tsetp %>R\n", dreg);
			ia32_emitf(node, "\torb %>R, %<R\n", dreg, dreg);