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

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

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

65
#include "../besched.h"
66
#include "../benode.h"
Michael Beck's avatar
Michael Beck committed
67
#include "../beabi.h"
68
#include "../be_dbgout.h"
Matthias Braun's avatar
Matthias Braun committed
69
70
#include "../beemitter.h"
#include "../begnuas.h"
71
#include "../beirg.h"
72
#include "../be_dbgout.h"
Christian Würdig's avatar
Christian Würdig committed
73

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

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

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

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

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

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

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

110
	return 1;
111
112
}

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

122
123
124
	if (has_Block_entity(block))
		return 1;

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

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

	return need_label;
}

Christian Würdig's avatar
Christian Würdig committed
140
/**
Christian Würdig's avatar
Christian Würdig committed
141
 * Returns the register at in position pos.
Christian Würdig's avatar
Christian Würdig committed
142
 */
143
static const arch_register_t *get_in_reg(const ir_node *irn, int pos)
144
{
145
146
	ir_node               *op;
	const arch_register_t *reg = NULL;
Christian Würdig's avatar
Christian Würdig committed
147
148
149
150
151
152
153

	assert(get_irn_arity(irn) > pos && "Invalid IN position");

	/* The out register of the operator at position pos is the
	   in register we need. */
	op = get_irn_n(irn, pos);

154
	reg = arch_get_irn_register(op);
Christian Würdig's avatar
Christian Würdig committed
155

Christian Würdig's avatar
Christian Würdig committed
156
	assert(reg && "no in register found");
157

158
	if (reg == &ia32_registers[REG_GP_NOREG])
159
		panic("trying to emit noreg for %+F input %d", irn, pos);
160

Christian Würdig's avatar
Christian Würdig committed
161
162
163
164
165
166
	return reg;
}

/**
 * Returns the register at out position pos.
 */
167
static const arch_register_t *get_out_reg(const ir_node *irn, int pos)
168
169
170
{
	ir_node               *proj;
	const arch_register_t *reg = NULL;
Christian Würdig's avatar
Christian Würdig committed
171
172
173
174
175
176
177

	/* 1st case: irn is not of mode_T, so it has only                 */
	/*           one OUT register -> good                             */
	/* 2nd case: irn is of mode_T -> collect all Projs and ask the    */
	/*           Proj with the corresponding projnum for the register */

	if (get_irn_mode(irn) != mode_T) {
178
		assert(pos == 0);
179
		reg = arch_get_irn_register(irn);
180
	} else if (is_ia32_irn(irn)) {
181
		reg = arch_irn_get_register(irn, pos);
182
	} else {
Christian Würdig's avatar
Christian Würdig committed
183
184
185
186
187
188
		const ir_edge_t *edge;

		foreach_out_edge(irn, edge) {
			proj = get_edge_src_irn(edge);
			assert(is_Proj(proj) && "non-Proj from mode_T node");
			if (get_Proj_proj(proj) == pos) {
189
				reg = arch_get_irn_register(proj);
Christian Würdig's avatar
Christian Würdig committed
190
191
192
193
194
195
				break;
			}
		}
	}

	assert(reg && "no out register found");
Christian Würdig's avatar
Christian Würdig committed
196
197
198
	return reg;
}

Michael Beck's avatar
Michael Beck committed
199
/**
200
 * Add a number to a prefix. This number will not be used a second time.
Michael Beck's avatar
Michael Beck committed
201
 */
202
203
static char *get_unique_label(char *buf, size_t buflen, const char *prefix)
{
204
	static unsigned long id = 0;
205
	snprintf(buf, buflen, "%s%s%lu", be_gas_get_private_prefix(), prefix, ++id);
206
207
208
	return buf;
}

Michael Beck's avatar
Michael Beck committed
209
210
211
/**
 * Emit the name of the 8bit low register
 */
212
213
static void emit_8bit_register(const arch_register_t *reg)
{
214
	const char *reg_name = arch_register_get_name(reg);
215
216
	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
217

218
	be_emit_char('%');
219
	be_emit_char(reg_name[1]); /* get the basic name of the register */
220
221
222
	be_emit_char('l');
}

Michael Beck's avatar
Michael Beck committed
223
224
225
226
227
228
/**
 * 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);
229
230
	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
231
232

	be_emit_char('%');
233
	be_emit_char(reg_name[1]); /* get the basic name of the register */
Michael Beck's avatar
Michael Beck committed
234
235
236
	be_emit_char('h');
}

237
238
static void emit_16bit_register(const arch_register_t *reg)
{
239
	const char *reg_name = arch_register_get_name(reg);
Christian Würdig's avatar
Christian Würdig committed
240

241
	be_emit_char('%');
242
	be_emit_string(reg_name+1); /* skip the 'e' prefix of the 32bit names */
243
244
}

245
246
247
248
249
250
/**
 * emit a register, possible shortened by a mode
 *
 * @param reg   the register
 * @param mode  the mode of the register or NULL for full register
 */
251
252
253
254
static void emit_register(const arch_register_t *reg, const ir_mode *mode)
{
	const char *reg_name;

Christoph Mallon's avatar
Christoph Mallon committed
255
	if (mode != NULL) {
256
		int size = get_mode_size_bits(mode);
Christoph Mallon's avatar
Christoph Mallon committed
257
258
259
		switch (size) {
			case  8: emit_8bit_register(reg);  return;
			case 16: emit_16bit_register(reg); return;
260
		}
Christoph Mallon's avatar
Christoph Mallon committed
261
		assert(mode_is_float(mode) || size == 32);
262
263
264
	}

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

266
267
	be_emit_char('%');
	be_emit_string(reg_name);
Christian Würdig's avatar
Christian Würdig committed
268
269
}

270
void ia32_emit_source_register(const ir_node *node, int pos)
271
{
Christoph Mallon's avatar
Christoph Mallon committed
272
	const arch_register_t *reg = get_in_reg(node, pos);
273

274
	emit_register(reg, NULL);
275
276
}

277
278
static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
{
279
	be_gas_emit_entity(entity);
280
281

	if (get_entity_owner(entity) == get_tls_type()) {
282
		if (get_entity_visibility(entity) == ir_visibility_external) {
283
284
285
286
287
288
			be_emit_cstring("@INDNTPOFF");
		} else {
			be_emit_cstring("@NTPOFF");
		}
	}

289
	if (do_pic && !no_pic_adjust) {
290
291
292
293
294
295
296
297
298
299
300
301
		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('-');
302
		ia32_emit_entity(attr->symconst, attr->no_pic_adjust);
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
	}
	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);
}
318
319
320
321

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
322
	const ir_node         *in = get_irn_n(node, pos);
Christoph Mallon's avatar
Christoph Mallon committed
323
	if (is_ia32_Immediate(in)) {
324
325
326
327
328
329
330
331
		emit_ia32_Immediate(in);
		return;
	}

	reg = get_in_reg(node, pos);
	emit_8bit_register(reg);
}

Michael Beck's avatar
Michael Beck committed
332
333
334
335
336
337
void ia32_emit_8bit_high_source_register(const ir_node *node, int pos)
{
	const arch_register_t *reg = get_in_reg(node, pos);
	emit_8bit_register_high(reg);
}

338
339
340
341
342
343
344
345
346
347
348
349
350
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;
	}

	reg = get_in_reg(node, pos);
	emit_16bit_register(reg);
}

351
352
353
354
355
356
357
void ia32_emit_dest_register(const ir_node *node, int pos)
{
	const arch_register_t *reg  = get_out_reg(node, pos);

	emit_register(reg, NULL);
}

358
359
360
361
362
363
364
void ia32_emit_dest_register_size(const ir_node *node, int pos)
{
	const arch_register_t *reg  = get_out_reg(node, pos);

	emit_register(reg, get_ia32_ls_mode(node));
}

365
366
367
368
369
370
371
372
void ia32_emit_8bit_dest_register(const ir_node *node, int pos)
{
	const arch_register_t *reg  = get_out_reg(node, pos);

	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
373
{
374
	const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
375

Matthias Braun's avatar
Matthias Braun committed
376
	assert(pos < 3);
377
378
	be_emit_char('%');
	be_emit_string(attr->x87[pos]->name);
379
}
Christian Würdig's avatar
Christian Würdig committed
380

Matthias Braun's avatar
Matthias Braun committed
381
static void ia32_emit_mode_suffix_mode(const ir_mode *mode)
382
{
383
384
385
386
387
	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
388
389
		/* gas docu says q is the suffix but gcc, objdump and icc use ll
		 * apparently */
Matthias Braun's avatar
Matthias Braun committed
390
391
		case 64: be_emit_cstring("ll"); return;
	}
392
	panic("Can't output mode_suffix for %+F", mode);
Christian Würdig's avatar
Christian Würdig committed
393
394
}

395
void ia32_emit_mode_suffix(const ir_node *node)
396
397
{
	ir_mode *mode = get_ia32_ls_mode(node);
Christoph Mallon's avatar
Christoph Mallon committed
398
	if (mode == NULL)
Matthias Braun's avatar
Matthias Braun committed
399
400
		mode = mode_Iu;

401
	ia32_emit_mode_suffix_mode(mode);
402
403
}

404
void ia32_emit_x87_mode_suffix(const ir_node *node)
405
{
406
407
	ir_mode *mode;

408
	/* we only need to emit the mode on address mode */
409
410
411
412
413
414
415
416
	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)) {
417
418
419
420
421
422
423
			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;
424
425
		}
	} else {
426
		assert(mode_is_int(mode) || mode_is_reference(mode));
427
428
429
430
431
432
433
		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;
		}
434
	}
435
	panic("Can't output mode_suffix for %+F", mode);
436
437
}

438
static char get_xmm_mode_suffix(ir_mode *mode)
439
440
{
	assert(mode_is_float(mode));
441
	switch (get_mode_size_bits(mode)) {
Christoph Mallon's avatar
Christoph Mallon committed
442
443
444
	case 32: return 's';
	case 64: return 'd';
	default: panic("Invalid XMM mode");
445
446
447
	}
}

448
void ia32_emit_xmm_mode_suffix(const ir_node *node)
449
450
{
	ir_mode *mode = get_ia32_ls_mode(node);
451
	assert(mode != NULL);
452
453
	be_emit_char('s');
	be_emit_char(get_xmm_mode_suffix(mode));
454
455
}

456
void ia32_emit_xmm_mode_suffix_s(const ir_node *node)
457
458
459
{
	ir_mode *mode = get_ia32_ls_mode(node);
	assert(mode != NULL);
460
	be_emit_char(get_xmm_mode_suffix(mode));
461
462
}

463
void ia32_emit_extend_suffix(const ir_node *node)
464
{
465
	ir_mode *mode = get_ia32_ls_mode(node);
Christoph Mallon's avatar
Christoph Mallon committed
466
	if (get_mode_size_bits(mode) == 32)
467
		return;
Christoph Mallon's avatar
Christoph Mallon committed
468
	be_emit_char(mode_is_signed(mode) ? 's' : 'z');
469
	ia32_emit_mode_suffix_mode(mode);
Matthias Braun's avatar
Matthias Braun committed
470
471
}

472
void ia32_emit_source_register_or_immediate(const ir_node *node, int pos)
473
474
{
	ir_node *in = get_irn_n(node, pos);
Christoph Mallon's avatar
Christoph Mallon committed
475
	if (is_ia32_Immediate(in)) {
476
		emit_ia32_Immediate(in);
477
	} else {
478
479
480
		const ir_mode         *mode = get_ia32_ls_mode(node);
		const arch_register_t *reg  = get_in_reg(node, pos);
		emit_register(reg, mode);
481
482
483
	}
}

Christian Würdig's avatar
Christian Würdig committed
484
/**
485
 * Returns the target block for a control flow node.
Christian Würdig's avatar
Christian Würdig committed
486
 */
487
static ir_node *get_cfop_target_block(const ir_node *irn)
Christoph Mallon's avatar
Christoph Mallon committed
488
{
489
	assert(get_irn_mode(irn) == mode_X);
490
	return (ir_node*)get_irn_link(irn);
491
}
Christian Würdig's avatar
Christian Würdig committed
492

493
494
495
496
497
498
/**
 * 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);
499
	be_gas_emit_block_name(block);
500
501
}

Michael Beck's avatar
Michael Beck committed
502
503
504
/**
 * Emit the suffix for a compare instruction.
 */
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
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;
537
	}
538
	panic("Invalid ia32 condition code");
539
540
}

541
typedef enum ia32_emit_mod_t {
542
	EMIT_NONE         = 0,
543
	EMIT_RESPECT_LS   = 1U << 0,
544
	EMIT_ALTERNATE_AM = 1U << 1,
545
546
547
	EMIT_LONG         = 1U << 2,
	EMIT_HIGH_REG     = 1U << 3,
	EMIT_LOW_REG      = 1U << 4
548
} ia32_emit_mod_t;
549
ENUM_BITSET(ia32_emit_mod_t)
550

551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
/**
 * 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);
	ir_node   *index     = get_irn_n(node, n_ia32_index);
	int        has_index = !is_ia32_NoReg_GP(index);

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

566
567
568
	if (get_ia32_am_tls_segment(node))
		be_emit_cstring("%gs:");

569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
	/* 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) {
			const arch_register_t *reg = get_in_reg(node, n_ia32_base);
			emit_register(reg, NULL);
		}

		/* emit index + scale */
		if (has_index) {
			const arch_register_t *reg = get_in_reg(node, n_ia32_index);
			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(')');
	}
}

611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
/**
 * 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
627
 * %d   signed int              signed int
628
629
 *
 * x starts at 0
630
 * # modifier for %ASx, %D, %R, and %S uses ls mode of node to alter register width
631
 * * modifier does not prefix immediates with $, but AM with *
632
 * l modifier for %lu and %ld
633
634
 * > modifier to output high 8bit register (ah, bh)
 * < modifier to output low 8bit register (al, bl)
635
636
637
638
639
640
641
 */
static void ia32_emitf(const ir_node *node, const char *fmt, ...)
{
	va_list ap;
	va_start(ap, fmt);

	for (;;) {
642
		const char      *start = fmt;
643
		ia32_emit_mod_t  mod   = EMIT_NONE;
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659

		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
660
			break;
661
662

		++fmt;
663
664
		for (;;) {
			switch (*fmt) {
665
666
667
			case '*': mod |= EMIT_ALTERNATE_AM; break;
			case '#': mod |= EMIT_RESPECT_LS;   break;
			case 'l': mod |= EMIT_LONG;         break;
668
669
			case '>': mod |= EMIT_HIGH_REG;     break;
			case '<': mod |= EMIT_LOW_REG;      break;
670
671
672
			default:
				goto end_of_mods;
			}
673
674
			++fmt;
		}
675
end_of_mods:
676

677
678
679
680
681
682
683
		switch (*fmt++) {
			case '%':
				be_emit_char('%');
				break;

			case 'A': {
				switch (*fmt++) {
684
emit_AM:
685
					case 'M':
686
687
						if (mod & EMIT_ALTERNATE_AM)
							be_emit_char('*');
688
689
690
691
						ia32_emit_am(node);
						break;

					case 'R': {
692
						const arch_register_t *reg = va_arg(ap, const arch_register_t*);
693
						if (get_ia32_op_type(node) == ia32_AddrModeS) {
694
							goto emit_AM;
695
						} else {
696
697
							if (mod & EMIT_ALTERNATE_AM)
								be_emit_char('*');
698
699
700
701
702
703
704
705
							emit_register(reg, NULL);
						}
						break;
					}

					case 'S':
						if (get_ia32_op_type(node) == ia32_AddrModeS) {
							++fmt;
706
							goto emit_AM;
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
						} else {
							assert(get_ia32_op_type(node) == ia32_Normal);
							goto emit_S;
						}
						break;

					default: goto unknown;
				}
				break;
			}

			case 'D': {
				unsigned               pos;
				const arch_register_t *reg;

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

				pos = *fmt++ - '0';
				reg = get_out_reg(node, pos);
727
				emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
728
729
730
731
				break;
			}

			case 'I':
732
733
734
				if (!(mod & EMIT_ALTERNATE_AM))
					be_emit_char('$');
				emit_ia32_Immediate_no_prefix(node);
735
736
737
738
739
740
741
742
743
744
745
746
				break;

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

			case 'M': {
				ia32_emit_mode_suffix_mode(get_ia32_ls_mode(node));
				break;
			}

			case 'P': {
747
748
				ia32_condition_code_t cc = va_arg(ap, ia32_condition_code_t);
				ia32_emit_condition_code(cc);
749
750
751
752
753
				break;
			}

			case 'R': {
				const arch_register_t *reg = va_arg(ap, const arch_register_t*);
754
755
756
757
758
759
760
				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);
				}
761
762
763
764
765
766
767
768
769
770
771
772
773
774
				break;
			}

emit_S:
			case 'S': {
				unsigned       pos;
				const ir_node *in;

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

				pos = *fmt++ - '0';
				in  = get_irn_n(node, pos);
				if (is_ia32_Immediate(in)) {
775
776
777
					if (!(mod & EMIT_ALTERNATE_AM))
						be_emit_char('$');
					emit_ia32_Immediate_no_prefix(in);
778
				} else {
Michael Beck's avatar
Michael Beck committed
779
780
					const arch_register_t *reg;

781
782
					if (mod & EMIT_ALTERNATE_AM)
						be_emit_char('*');
Michael Beck's avatar
Michael Beck committed
783
					reg = get_in_reg(node, pos);
784
					emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
785
786
787
788
789
790
791
792
793
794
				}
				break;
			}

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

795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
			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);
				}
813
814
815
816
				break;

			default:
unknown:
817
				panic("unknown format conversion in ia32_emitf()");
818
		}
819
820
821
822
823
824
825
826
827
828
829
830
831
832
	}

	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
833
	}
834
835
}

836
837
838
/**
 * Emits registers and/or address mode of a binary operation.
 */
Christoph Mallon's avatar
Christoph Mallon committed
839
840
void ia32_emit_x87_binop(const ir_node *node)
{
841
	switch (get_ia32_op_type(node)) {
842
		case ia32_Normal:
843
			{
844
845
				const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
				const arch_register_t *in1      = x87_attr->x87[0];
846
				const arch_register_t *in       = x87_attr->x87[1];
847
				const arch_register_t *out      = x87_attr->x87[2];
848

849
850
851
852
853
				if (out == NULL) {
					out = in1;
				} else if (out == in) {
					in = in1;
				}
854

855
856
857
858
				be_emit_char('%');
				be_emit_string(arch_register_get_name(in));
				be_emit_cstring(", %");
				be_emit_string(arch_register_get_name(out));
859
860
861
			}
			break;
		case ia32_AddrModeS:
862
			ia32_emit_am(node);
863
			break;
864
		case ia32_AddrModeD:
865
866
867
868
869
		default:
			assert(0 && "unsupported op type");
	}
}

Christian Würdig's avatar
Christian Würdig committed
870
871
872
/**
 * Emits registers and/or address mode of a unary operation.
 */
Christoph Mallon's avatar
Christoph Mallon committed
873
874
void ia32_emit_unop(const ir_node *node, int pos)
{
875
876
877
	char fmt[] = "%ASx";
	fmt[3] = '0' + pos;
	ia32_emitf(node, fmt);
Christian Würdig's avatar
Christian Würdig committed
878
879
}

Matthias Braun's avatar
Matthias Braun committed
880
881
882
883
884
885
static void emit_ia32_IMul(const ir_node *node)
{
	ir_node               *left    = get_irn_n(node, n_ia32_IMul_left);
	const arch_register_t *out_reg = get_out_reg(node, pn_ia32_IMul_res);

	/* do we need the 3-address form? */
Christoph Mallon's avatar
Christoph Mallon committed
886
	if (is_ia32_NoReg_GP(left) ||
Matthias Braun's avatar
Matthias Braun committed
887
			get_in_reg(node, n_ia32_IMul_left) != out_reg) {
888
889
890
		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
891
892
893
	}
}

894
895
896
/**
 * walks up a tree of copies/perms/spills/reloads to find the original value
 * that is moved around
897
 */
898
899
static ir_node *find_original_value(ir_node *node)
{
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
	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));
916
917
918
		} else {
			return node;
		}
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
	} else if (is_ia32_Store(node)) {
		return find_original_value(get_irn_n(node, n_ia32_Store_val));
	} 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;
934
935
936
	}
}

937
static int determine_final_cc(const ir_node *node, int flags_pos, int cc)
938
{
939
940
941
942
	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
943
	if (is_ia32_Sahf(flags)) {
944
		ir_node *cmp = get_irn_n(flags, n_ia32_Sahf_val);
Christoph Mallon's avatar
Christoph Mallon committed
945
		if (!(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
946
				|| is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp))) {
947
			inc_irg_visited(current_ir_graph);
948
			cmp = find_original_value(cmp);
949
			assert(cmp != NULL);
950
			assert(is_ia32_FucomFnstsw(cmp) || is_ia32_FucompFnstsw(cmp)
951
			       || is_ia32_FucomppFnstsw(cmp) || is_ia32_FtstFnstsw(cmp));
952
		}
953

954
		flags_attr = get_ia32_attr_const(cmp);
955
	} else {
956
		flags_attr = get_ia32_attr_const(flags);
957
	}
958

959
960
961
	if (flags_attr->data.ins_permuted)
		cc = ia32_invert_condition_code(cc);
	return cc;
962
963
}

964
void ia32_emit_cmp_suffix_node(const ir_node *node, int flags_pos)
965
{
966
967
	ia32_condition_code_t cc = get_ia32_condcode(node);
	cc = determine_final_cc(node, flags_pos, cc);
968

969
	ia32_emit_condition_code(cc);
970
}
971

972
973
974
975
976
977
/**
 * 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());
978
	be_emit_irprintf("%lu", get_ia32_exc_label_id(node));
979
980
}

981
982
983
/**
 * Returns the Proj with projection number proj and NOT mode_M
 */
Christoph Mallon's avatar
Christoph Mallon committed
984
985
static ir_node *get_proj(const ir_node *node, long proj)
{
986
987
988
	const ir_edge_t *edge;
	ir_node         *src;

989
	assert(get_irn_mode(node) == mode_T && "expected mode_T node");
990

991
	foreach_out_edge(node, edge) {
992
993
994
995
996
997
998
999
1000
1001
1002
1003
		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;
}

1004
static int can_be_fallthrough(const ir_node *node)
1005
1006
1007
1008
1009
1010
{
	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
1011
1012
1013
/**
 * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
 */
1014
static void emit_ia32_Jcc(const ir_node *node)
1015
{
1016
1017
1018
1019
	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
1020

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

1023
1024
1025
	/* get both Projs */
	proj_true = get_proj(node, pn_ia32_Jcc_true);
	assert(proj_true && "Jcc without true Proj");
1026

1027
1028
	proj_false = get_proj(node, pn_ia32_Jcc_false);
	assert(proj_false && "Jcc without false Proj");
1029

1030
	if (can_be_fallthrough(proj_true)) {
1031
		/* exchange both proj's so the second one can be omitted */
1032
1033
		const ir_node *t = proj_true;

1034
1035
		proj_true  = proj_false;
		proj_false = t;
1036
		cc         = ia32_negate_condition_code(cc);
1037
1038
	}

1039
	if (cc & ia32_cc_float_parity_cases) {
1040
1041
		/* Some floating point comparisons require a test of the parity flag,
		 * which indicates that the result is unordered */
1042
		if (cc & ia32_cc_negated) {
1043
			ia32_emitf(proj_true, "\tjp %L\n");
1044
		} else {
1045
1046
1047
1048
1049
1050
1051
1052
			/* 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");
			}
1053
		}
1054
	}
1055
	ia32_emitf(proj_true, "\tj%P %L\n", cc);
Christoph Mallon's avatar
Christoph Mallon committed
1056
	if (need_parity_label) {
1057
		ia32_emitf(NULL, "1:\n");
1058
1059
	}

1060
	/* the second Proj might be a fallthrough */
Matthias Braun's avatar
Matthias Braun committed
1061
	if (can_be_fallthrough(proj_false)) {
1062
		ia32_emitf(proj_false, "\t/* fallthrough to %L */\n");
1063
	} else {
1064
		ia32_emitf(proj_false, "\tjmp %L\n");