ia32_spec.pl 73.9 KB
Newer Older
1
2
3
4
# This is the specification for the ia32 assembler Firm-operations

$arch = "ia32";

5
6
7
8
9
10
11
$mode_xmm           = "mode_D";
$mode_mmx           = "mode_D";
$mode_fp87          = "ia32_mode_E";
$mode_gp            = "mode_Iu";
$mode_flags         = "mode_Iu";
$mode_fpcw          = "ia32_mode_fpcw";

Christian Würdig's avatar
Christian Würdig committed
12
# register types:
13
$normal      =  0; # no special type
14
15
16
17
$ignore      =  1; # ignore (do not assign this register)
$arbitrary   =  2; # emitter can choose an arbitrary register of this class
$virtual     =  4; # the register is a virtual one
$state       =  8; # register represents a state
Christian Würdig's avatar
Christian Würdig committed
18
# NOTE: Last entry of each class is the largest Firm-Mode a register can hold
19
%reg_classes = (
20
	gp => [
21
22
23
24
25
26
27
		{ name => "edx" },
		{ name => "ecx" },
		{ name => "eax" },
		{ name => "ebx" },
		{ name => "esi" },
		{ name => "edi" },
		{ name => "ebp" },
28
29
		{ name => "esp", type => $ignore },
		{ name => "gp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg nodes
30
		{ mode => $mode_gp }
31
	],
32
	mmx => [
33
34
35
36
37
38
39
40
		{ name => "mm0", type => $ignore },
		{ name => "mm1", type => $ignore },
		{ name => "mm2", type => $ignore },
		{ name => "mm3", type => $ignore },
		{ name => "mm4", type => $ignore },
		{ name => "mm5", type => $ignore },
		{ name => "mm6", type => $ignore },
		{ name => "mm7", type => $ignore },
41
		{ mode => $mode_mmx, flags => "manual_ra" }
42
	],
43
	xmm => [
44
45
46
47
48
49
50
51
		{ name => "xmm0" },
		{ name => "xmm1" },
		{ name => "xmm2" },
		{ name => "xmm3" },
		{ name => "xmm4" },
		{ name => "xmm5" },
		{ name => "xmm6" },
		{ name => "xmm7" },
52
		{ name => "xmm_NOREG", type => $ignore | $virtual },     # we need a dummy register for NoReg nodes
53
		{ mode => $mode_xmm }
54
	],
55
	vfp => [
56
57
58
59
60
61
62
63
		{ name => "vf0" },
		{ name => "vf1" },
		{ name => "vf2" },
		{ name => "vf3" },
		{ name => "vf4" },
		{ name => "vf5" },
		{ name => "vf6" },
		{ name => "vf7" },
64
		{ name => "vfp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg nodes
65
		{ mode => $mode_fp87 }
66
	],
67
	st => [
68
69
70
71
72
73
74
75
		{ name => "st0", realname => "st",    type => $ignore },
		{ name => "st1", realname => "st(1)", type => $ignore },
		{ name => "st2", realname => "st(2)", type => $ignore },
		{ name => "st3", realname => "st(3)", type => $ignore },
		{ name => "st4", realname => "st(4)", type => $ignore },
		{ name => "st5", realname => "st(5)", type => $ignore },
		{ name => "st6", realname => "st(6)", type => $ignore },
		{ name => "st7", realname => "st(7)", type => $ignore },
76
		{ mode => $mode_fp87, flags => "manual_ra" }
77
	],
78
	fp_cw => [	# the floating point control word
79
		{ name => "fpcw", type => $ignore | $state },
80
		{ mode => $mode_fpcw, flags => "manual_ra|state" }
81
	],
82
	flags => [
83
84
		{ name => "eflags", type => 0 },
		{ mode => "mode_Iu", flags => "manual_ra" }
85
	],
86
87
); # %reg_classes

88
%cpu = (
89
90
91
92
	GP     => [ 1, "GP_EAX", "GP_EBX", "GP_ECX", "GP_EDX", "GP_ESI", "GP_EDI", "GP_EBP" ],
	SSE    => [ 1, "SSE_XMM0", "SSE_XMM1", "SSE_XMM2", "SSE_XMM3", "SSE_XMM4", "SSE_XMM5", "SSE_XMM6", "SSE_XMM7" ],
	VFP    => [ 1, "VFP_VF0", "VFP_VF1", "VFP_VF2", "VFP_VF3", "VFP_VF4", "VFP_VF5", "VFP_VF6", "VFP_VF7" ],
	BRANCH => [ 1, "BRANCH1", "BRANCH2" ],
93
94
); # %cpu

95
%vliw = (
96
97
	bundle_size       => 1,
	bundels_per_cycle => 1
98
99
); # vliw

100
%emit_templates = (
101
102
103
104
	S0 => "${arch}_emit_source_register(node, 0);",
	S1 => "${arch}_emit_source_register(node, 1);",
	S2 => "${arch}_emit_source_register(node, 2);",
	S3 => "${arch}_emit_source_register(node, 3);",
Michael Beck's avatar
Michael Beck committed
105
	SB0 => "${arch}_emit_8bit_source_register_or_immediate(node, 0);",
106
107
108
	SB1 => "${arch}_emit_8bit_source_register_or_immediate(node, 1);",
	SB2 => "${arch}_emit_8bit_source_register_or_immediate(node, 2);",
	SB3 => "${arch}_emit_8bit_source_register_or_immediate(node, 3);",
Michael Beck's avatar
Michael Beck committed
109
	SH0 => "${arch}_emit_8bit_high_source_register(node, 0);",
110
111
	SS0 => "${arch}_emit_16bit_source_register_or_immediate(node, 0);",
	SI0 => "${arch}_emit_source_register_or_immediate(node, 0);",
112
	SI1 => "${arch}_emit_source_register_or_immediate(node, 1);",
113
114
115
	SI3 => "${arch}_emit_source_register_or_immediate(node, 3);",
	D0 => "${arch}_emit_dest_register(node, 0);",
	D1 => "${arch}_emit_dest_register(node, 1);",
116
	DS0 => "${arch}_emit_dest_register_size(node, 0);",
117
118
119
	DB0 => "${arch}_emit_8bit_dest_register(node, 0);",
	X0 => "${arch}_emit_x87_register(node, 0);",
	X1 => "${arch}_emit_x87_register(node, 1);",
120
	EX => "${arch}_emit_extend_suffix(node);",
121
122
123
124
125
	M  => "${arch}_emit_mode_suffix(node);",
	XM => "${arch}_emit_x87_mode_suffix(node);",
	XXM => "${arch}_emit_xmm_mode_suffix(node);",
	XSD => "${arch}_emit_xmm_mode_suffix_s(node);",
	AM => "${arch}_emit_am(node);",
Christoph Mallon's avatar
Christoph Mallon committed
126
127
	unop3 => "${arch}_emit_unop(node, n_ia32_unary_op);",
	unop4 => "${arch}_emit_unop(node, n_ia32_binary_right);",
128
	binop => "${arch}_emit_binop(node);",
129
	x87_binop => "${arch}_emit_x87_binop(node);",
Matthias Braun's avatar
Matthias Braun committed
130
	CMP3  => "${arch}_emit_cmp_suffix_node(node, 3);",
131
132
);

133
134


135

136
137
138
$default_op_attr_type = "ia32_op_attr_t";
$default_attr_type    = "ia32_attr_t";
$default_copy_attr    = "ia32_copy_attr";
139

140
sub ia32_custom_init_attr {
141
142
143
144
	my $constr = shift;
	my $node   = shift;
	my $name   = shift;
	my $res    = "";
145

146
	if(defined($node->{modified_flags})) {
147
		$res .= "\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n";
148
149
150
	}
	if(defined($node->{am})) {
		my $am = $node->{am};
Christoph Mallon's avatar
Christoph Mallon committed
151
		if($am eq "source,unary") {
152
			$res .= "\tset_ia32_am_support(res, ia32_am_unary);";
153
		} elsif($am eq "source,binary") {
154
			$res .= "\tset_ia32_am_support(res, ia32_am_binary);";
155
156
157
158
159
		} elsif($am eq "none") {
			# nothing to do
		} else {
			die("Invalid address mode '$am' specified on op $name");
		}
160
161
162
163
164
165
		if($am ne "none") {
			if($node->{state} ne "exc_pinned"
					and $node->{state} ne "pinned") {
				die("AM nodes must have pinned or AM pinned state ($name)");
			}
		}
166
167
168
169
170
	}
	return $res;
}
$custom_init_attr_func = \&ia32_custom_init_attr;

171
%init_attr = (
172
	ia32_asm_attr_t =>
173
		"\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
174
		"\tinit_ia32_x87_attributes(res);".
175
		"\tinit_ia32_asm_attributes(res);",
Christoph Mallon's avatar
Christoph Mallon committed
176
	ia32_attr_t     =>
177
		"\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);",
178
	ia32_call_attr_t =>
179
		"\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
180
		"\tinit_ia32_call_attributes(res, pop, call_tp);",
Christoph Mallon's avatar
Christoph Mallon committed
181
	ia32_condcode_attr_t =>
182
		"\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
183
184
		"\tinit_ia32_condcode_attributes(res, condition_code);",
	ia32_switch_attr_t =>
185
		"\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
Matthias Braun's avatar
Matthias Braun committed
186
		"\tinit_ia32_switch_attributes(res, switch_table);",
Michael Beck's avatar
Michael Beck committed
187
	ia32_copyb_attr_t =>
188
		"\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
Michael Beck's avatar
Michael Beck committed
189
		"\tinit_ia32_copyb_attributes(res, size);",
Christoph Mallon's avatar
Christoph Mallon committed
190
	ia32_immediate_attr_t =>
191
		"\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
192
		"\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, no_pic_adjust, offset);",
Christoph Mallon's avatar
Christoph Mallon committed
193
	ia32_x87_attr_t =>
194
		"\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
Christoph Mallon's avatar
Christoph Mallon committed
195
		"\tinit_ia32_x87_attributes(res);",
196
	ia32_climbframe_attr_t =>
197
		"\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
198
		"\tinit_ia32_climbframe_attributes(res, count);",
199
200
201
);

%compare_attr = (
202
	ia32_asm_attr_t        => "ia32_compare_asm_attr",
203
204
205
206
	ia32_attr_t            => "ia32_compare_nodes_attr",
	ia32_call_attr_t       => "ia32_compare_call_attr",
	ia32_condcode_attr_t   => "ia32_compare_condcode_attr",
	ia32_copyb_attr_t      => "ia32_compare_copyb_attr",
Matthias Braun's avatar
Matthias Braun committed
207
	ia32_switch_attr_t     => "ia32_compare_nodes_attr",
208
209
210
	ia32_immediate_attr_t  => "ia32_compare_immediate_attr",
	ia32_x87_attr_t        => "ia32_compare_x87_attr",
	ia32_climbframe_attr_t => "ia32_compare_climbframe_attr",
211
212
);

Michael Beck's avatar
Michael Beck committed
213
214
215
%operands = (
);

216
217
218
219
$status_flags       = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
$status_flags_wo_cf = [       "PF", "AF", "ZF", "SF", "OF" ];
$fpcw_flags         = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
                        "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ];
220

221
222
%nodes = (

223
224
Immediate => {
	state     => "pinned",
225
	op_flags  => [ "constlike" ],
226
	irn_flags => [ "not_scheduled" ],
227
	reg_req   => { out => [ "gp_NOREG:I" ] },
228
	attr      => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
229
	attr_type => "ia32_immediate_attr_t",
230
	hash_func => "ia32_hash_Immediate",
231
	latency   => 0,
232
233
	mode      => $mode_gp,
},
234

235
236
237
238
Asm => {
	mode      => "mode_T",
	arity     => "variable",
	out_arity => "variable",
239
	attr_type => "ia32_asm_attr_t",
240
241
242
243
	attr      => "ident *asm_text, const ia32_asm_reg_t *register_map",
	init_attr => "attr->asm_text = asm_text;\n".
	             "\tattr->register_map = register_map;\n",
	latency   => 10,
244
	modified_flags => $status_flags,
245
246
},

247
248
# "allocates" a free register
ProduceVal => {
249
250
	op_flags  => [ "constlike", "cse_neutral" ],
	irn_flags => [ "rematerializable" ],
251
252
253
254
255
256
257
258
	reg_req   => { out => [ "gp" ] },
	emit      => "",
	units     => [ ],
	latency   => 0,
	mode      => $mode_gp,
	cmp_attr  => "return 1;",
},

259
Add => {
260
	irn_flags => [ "rematerializable" ],
261
	state     => "exc_pinned",
262
263
	reg_req   => { in  => [ "gp", "gp", "none", "gp", "gp" ],
	               out => [ "in_r4 in_r5", "flags", "none" ] },
264
	ins       => [ "base", "index", "mem", "left", "right" ],
265
	outs      => [ "res", "flags", "M" ],
266
	emit      => '. add%M %binop',
Christoph Mallon's avatar
Christoph Mallon committed
267
	am        => "source,binary",
268
	units     => [ "GP" ],
269
	latency   => 1,
270
271
	mode      => $mode_gp,
	modified_flags => $status_flags
272
273
},

274
AddMem => {
275
	irn_flags => [ "rematerializable" ],
276
	state     => "exc_pinned",
277
278
279
	reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
	ins       => [ "base", "index", "mem", "val" ],
	emit      => ". add%M %SI3, %AM",
280
	units     => [ "GP" ],
281
	latency   => 1,
282
283
284
285
	mode      => "mode_M",
	modified_flags => $status_flags
},

286
AddMem8Bit => {
287
	irn_flags => [ "rematerializable" ],
288
	state     => "exc_pinned",
289
290
291
292
	reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
	ins       => [ "base", "index", "mem", "val" ],
	emit      => ". add%M %SB3, %AM",
	units     => [ "GP" ],
293
	latency   => 1,
294
295
296
297
	mode      => "mode_M",
	modified_flags => $status_flags
},

298
Adc => {
299
	state     => "exc_pinned",
300
301
	reg_req   => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
	               out => [ "in_r4 in_r5", "flags", "none" ] },
302
	ins       => [ "base", "index", "mem", "left", "right", "eflags" ],
303
	outs      => [ "res", "flags", "M" ],
304
	emit      => '. adc%M %binop',
Christoph Mallon's avatar
Christoph Mallon committed
305
	am        => "source,binary",
306
	units     => [ "GP" ],
307
	latency   => 1,
308
309
	mode      => $mode_gp,
	modified_flags => $status_flags
310
311
},

312
313
l_Add => {
	ins       => [ "left", "right" ],
314
315
	attr_type => "",
	dump_func => "NULL",
316
317
318
319
},

l_Adc => {
	ins       => [ "left", "right", "eflags" ],
320
321
	attr_type => "",
	dump_func => "NULL",
322
323
},

324
Mul => {
325
	# we should not rematrialize this node. It produces 2 results and has
Christoph Mallon's avatar
Christoph Mallon committed
326
	# very strict constraints
327
	state     => "exc_pinned",
328
	reg_req   => { in => [ "gp", "gp", "none", "eax", "gp" ],
329
	               out => [ "eax", "flags", "none", "edx" ] },
Christoph Mallon's avatar
Christoph Mallon committed
330
	ins       => [ "base", "index", "mem", "left", "right" ],
331
	emit      => '. mul%M %unop4',
332
	outs      => [ "res_low", "flags", "M", "res_high" ],
333
	am        => "source,binary",
334
335
	latency   => 10,
	units     => [ "GP" ],
336
	modified_flags => $status_flags
337
338
},

339
l_Mul => {
340
	ins       => [ "left", "right" ],
341
	outs      => [ "res_low", "flags", "M", "res_high" ],
342
343
	attr_type => "",
	dump_func => "NULL",
344
345
346
},

IMul => {
347
	irn_flags => [ "rematerializable" ],
348
	state     => "exc_pinned",
Matthias Braun's avatar
Matthias Braun committed
349
350
351
	# TODO: adjust out requirements for the 3 operand form
	# (no need for should_be_same then)
	reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
352
		           out => [ "in_r4 in_r5", "flags", "none" ] },
353
	ins       => [ "base", "index", "mem", "left", "right" ],
354
	outs      => [ "res", "flags", "M" ],
355
	am        => "source,binary",
356
357
	latency   => 5,
	units     => [ "GP" ],
358
359
	mode      => $mode_gp,
	modified_flags => $status_flags
360
361
362
},

IMul1OP => {
363
	irn_flags => [ "rematerializable" ],
364
	state     => "exc_pinned",
365
	reg_req   => { in => [ "gp", "gp", "none", "eax", "gp" ],
366
	               out => [ "eax", "flags", "none", "edx" ] },
Christoph Mallon's avatar
Christoph Mallon committed
367
	ins       => [ "base", "index", "mem", "left", "right" ],
368
	emit      => '. imul%M %unop4',
369
	outs      => [ "res_low", "flags", "M", "res_high" ],
370
	am        => "source,binary",
371
372
	latency   => 5,
	units     => [ "GP" ],
373
	modified_flags => $status_flags
374
375
376
},

l_IMul => {
377
	ins       => [ "left", "right" ],
378
	outs      => [ "res_low", "flags", "M", "res_high" ],
379
380
	attr_type => "",
	dump_func => "NULL",
381
382
383
},

And => {
384
	irn_flags => [ "rematerializable" ],
385
	state     => "exc_pinned",
386
387
	reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
		           out => [ "in_r4 in_r5", "flags", "none" ] },
388
	ins       => [ "base", "index", "mem", "left", "right" ],
389
	outs      => [ "res", "flags", "M" ],
Christoph Mallon's avatar
Christoph Mallon committed
390
	am        => "source,binary",
391
	emit      => '. and%M %binop',
392
	units     => [ "GP" ],
393
	latency   => 1,
394
395
	mode      => $mode_gp,
	modified_flags => $status_flags
396
397
},

398
AndMem => {
399
	irn_flags => [ "rematerializable" ],
400
	state     => "exc_pinned",
401
402
403
	reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
	ins       => [ "base", "index", "mem", "val" ],
	emit      => '. and%M %SI3, %AM',
404
	units     => [ "GP" ],
405
	latency   => 1,
406
407
408
409
	mode      => "mode_M",
	modified_flags => $status_flags
},

410
AndMem8Bit => {
411
	irn_flags => [ "rematerializable" ],
412
	state     => "exc_pinned",
413
414
415
416
	reg_req   => { in => [ "gp", "gp", "none",  "eax ebx ecx edx" ], out => [ "none" ] },
	ins       => [ "base", "index", "mem", "val" ],
	emit      => '. and%M %SB3, %AM',
	units     => [ "GP" ],
417
	latency   => 1,
418
419
420
421
	mode      => "mode_M",
	modified_flags => $status_flags
},

422
Or => {
423
	irn_flags => [ "rematerializable" ],
424
	state     => "exc_pinned",
425
426
	reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
	               out => [ "in_r4 in_r5", "flags", "none" ] },
427
	ins       => [ "base", "index", "mem", "left", "right" ],
428
	outs      => [ "res", "flags", "M" ],
Christoph Mallon's avatar
Christoph Mallon committed
429
	am        => "source,binary",
Matthias Braun's avatar
Matthias Braun committed
430
	emit      => '. or%M %binop',
431
	units     => [ "GP" ],
432
	latency   => 1,
433
434
	mode      => $mode_gp,
	modified_flags => $status_flags
435
436
},

437
OrMem => {
438
	irn_flags => [ "rematerializable" ],
439
	state     => "exc_pinned",
440
441
442
	reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
	ins       => [ "base", "index", "mem", "val" ],
	emit      => '. or%M %SI3, %AM',
443
	units     => [ "GP" ],
444
	latency   => 1,
445
446
447
448
	mode      => "mode_M",
	modified_flags => $status_flags
},

449
OrMem8Bit => {
450
	irn_flags => [ "rematerializable" ],
451
	state     => "exc_pinned",
452
453
454
455
	reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
	ins       => [ "base", "index", "mem", "val" ],
	emit      => '. or%M %SB3, %AM',
	units     => [ "GP" ],
456
	latency   => 1,
457
458
459
460
	mode      => "mode_M",
	modified_flags => $status_flags
},

461
Xor => {
462
	irn_flags => [ "rematerializable" ],
463
	state     => "exc_pinned",
464
465
	reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
	               out => [ "in_r4 in_r5", "flags", "none" ] },
466
	ins       => [ "base", "index", "mem", "left", "right" ],
467
	outs      => [ "res", "flags", "M" ],
Christoph Mallon's avatar
Christoph Mallon committed
468
	am        => "source,binary",
469
	emit      => '. xor%M %binop',
470
	units     => [ "GP" ],
471
	latency   => 1,
472
473
	mode      => $mode_gp,
	modified_flags => $status_flags
474
475
},

476
Xor0 => {
477
478
	op_flags  => [ "constlike" ],
	irn_flags => [ "rematerializable" ],
479
480
481
482
483
484
485
486
487
	reg_req   => { out => [ "gp", "flags" ] },
	outs      => [ "res", "flags" ],
	emit      => ". xor%M %D0, %D0",
	units     => [ "GP" ],
	latency   => 1,
	mode      => $mode_gp,
	modified_flags => $status_flags
},

488
XorMem => {
489
	irn_flags => [ "rematerializable" ],
490
	state     => "exc_pinned",
491
492
493
	reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
	ins       => [ "base", "index", "mem", "val" ],
	emit      => '. xor%M %SI3, %AM',
494
	units     => [ "GP" ],
495
	latency   => 1,
496
497
498
499
	mode      => "mode_M",
	modified_flags => $status_flags
},

500
XorMem8Bit => {
501
	irn_flags => [ "rematerializable" ],
502
	state     => "exc_pinned",
503
504
505
506
	reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
	ins       => [ "base", "index", "mem", "val" ],
	emit      => '. xor%M %SB3, %AM',
	units     => [ "GP" ],
507
	latency   => 1,
508
509
510
511
	mode      => "mode_M",
	modified_flags => $status_flags
},

512
Sub => {
513
	irn_flags => [ "rematerializable" ],
514
	state     => "exc_pinned",
515
516
	reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
	               out => [ "in_r4", "flags", "none" ] },
517
	ins       => [ "base", "index", "mem", "minuend", "subtrahend" ],
518
	outs      => [ "res", "flags", "M" ],
Christoph Mallon's avatar
Christoph Mallon committed
519
	am        => "source,binary",
520
	emit      => '. sub%M %binop',
521
	units     => [ "GP" ],
522
	latency   => 1,
523
524
	mode      => $mode_gp,
	modified_flags => $status_flags
525
526
},

527
SubMem => {
528
	irn_flags => [ "rematerializable" ],
529
	state     => "exc_pinned",
530
	reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
531
	ins       => [ "base", "index", "mem", "subtrahend" ],
532
	emit      => '. sub%M %SI3, %AM',
533
	units     => [ "GP" ],
534
	latency   => 1,
535
536
537
538
	mode      => 'mode_M',
	modified_flags => $status_flags
},

539
SubMem8Bit => {
540
	irn_flags => [ "rematerializable" ],
541
	state     => "exc_pinned",
542
	reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
543
	ins       => [ "base", "index", "mem", "subtrahend" ],
544
545
	emit      => '. sub%M %SB3, %AM',
	units     => [ "GP" ],
546
	latency   => 1,
547
548
549
550
	mode      => 'mode_M',
	modified_flags => $status_flags
},

551
Sbb => {
552
	state     => "exc_pinned",
553
	reg_req   => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
554
	               out => [ "in_r4", "flags", "none" ] },
555
	ins       => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ],
556
	outs      => [ "res", "flags", "M" ],
Christoph Mallon's avatar
Christoph Mallon committed
557
	am        => "source,binary",
558
	emit      => '. sbb%M %binop',
559
	units     => [ "GP" ],
560
	latency   => 1,
561
562
	mode      => $mode_gp,
	modified_flags => $status_flags
563
564
},

565
Sbb0 => {
566
	# Spiller currently fails when rematerializing flag consumers
567
	# irn_flags => [ "rematerializable" ],
568
569
570
571
572
573
574
575
576
	reg_req   => { in => [ "flags" ], out => [ "gp", "flags" ] },
	outs      => [ "res", "flags" ],
	emit      => ". sbb%M %D0, %D0",
	units     => [ "GP" ],
	latency   => 1,
	mode      => $mode_gp,
	modified_flags => $status_flags
},

577
l_Sub => {
578
	ins       => [ "minuend", "subtrahend" ],
579
580
	attr_type => "",
	dump_func => "NULL",
581
582
583
},

l_Sbb => {
584
	ins       => [ "minuend", "subtrahend", "eflags" ],
585
586
	attr_type => "",
	dump_func => "NULL",
587
588
},

589
IDiv => {
590
	op_flags  => [ "fragile", "uses_memory", "labeled" ],
591
	state     => "exc_pinned",
592
	reg_req   => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
Matthias Braun's avatar
Matthias Braun committed
593
	               out => [ "eax", "flags", "none", "edx", "none", "none" ] },
594
	ins       => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
Matthias Braun's avatar
Matthias Braun committed
595
	outs      => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
596
	am        => "source,unary",
597
	emit      => ". idiv%M %unop3",
598
599
	latency   => 25,
	units     => [ "GP" ],
600
	modified_flags => $status_flags
601
602
},

603
Div => {
604
	op_flags  => [ "fragile", "uses_memory", "labeled" ],
605
	state     => "exc_pinned",
606
	reg_req   => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
Matthias Braun's avatar
Matthias Braun committed
607
	               out => [ "eax", "flags", "none", "edx", "none", "none" ] },
608
	ins       => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
Matthias Braun's avatar
Matthias Braun committed
609
	outs      => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
610
	am        => "source,unary",
611
	emit      => ". div%M %unop3",
612
613
	latency   => 25,
	units     => [ "GP" ],
614
	modified_flags => $status_flags
615
616
},

617
Shl => {
618
	irn_flags => [ "rematerializable" ],
619
620
621
622
	reg_req   => { in => [ "gp", "ecx" ],
	               out => [ "in_r1 !in_r2", "flags" ] },
	ins       => [ "val", "count" ],
	outs      => [ "res", "flags" ],
623
	emit      => '. shl%M %SB1, %S0',
624
	units     => [ "GP" ],
625
	latency   => 1,
626
627
	mode      => $mode_gp,
	modified_flags => $status_flags
628
629
},

630
ShlMem => {
631
	irn_flags => [ "rematerializable" ],
632
	state     => "exc_pinned",
633
634
635
	reg_req   => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
	ins       => [ "base", "index", "mem", "count" ],
	emit      => '. shl%M %SB3, %AM',
636
	units     => [ "GP" ],
637
	latency   => 1,
638
639
640
641
	mode      => "mode_M",
	modified_flags => $status_flags
},

642
ShlD => {
643
	irn_flags => [ "rematerializable" ],
644
645
646
647
	reg_req   => { in => [ "gp", "gp", "ecx" ],
	               out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
	ins       => [ "val_high", "val_low", "count" ],
	outs      => [ "res", "flags" ],
648
	emit      => ". shld%M %SB2, %S1, %D0",
649
650
	latency   => 6,
	units     => [ "GP" ],
651
652
	mode      => $mode_gp,
	modified_flags => $status_flags
653
654
},

655
Shr => {
656
	irn_flags => [ "rematerializable" ],
657
658
	reg_req   => { in => [ "gp", "ecx" ],
	               out => [ "in_r1 !in_r2", "flags" ] },
659
	ins       => [ "val", "count" ],
660
	outs      => [ "res", "flags" ],
661
	emit      => '. shr%M %SB1, %S0',
662
	units     => [ "GP" ],
663
	mode      => $mode_gp,
664
	latency   => 1,
665
	modified_flags => $status_flags
666
667
},

668
ShrMem => {
669
	irn_flags => [ "rematerializable" ],
670
	state     => "exc_pinned",
671
672
673
	reg_req   => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
	ins       => [ "base", "index", "mem", "count" ],
	emit      => '. shr%M %SB3, %AM',
674
675
	units     => [ "GP" ],
	mode      => "mode_M",
676
	latency   => 1,
677
678
679
	modified_flags => $status_flags
},

680
ShrD => {
681
	irn_flags => [ "rematerializable" ],
682
683
684
685
	reg_req   => { in => [ "gp", "gp", "ecx" ],
	               out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
	ins       => [ "val_high", "val_low", "count" ],
	outs      => [ "res", "flags" ],
686
	emit      => ". shrd%M %SB2, %S1, %D0",
687
688
	latency   => 6,
	units     => [ "GP" ],
689
690
	mode      => $mode_gp,
	modified_flags => $status_flags
691
692
},

693
Sar => {
694
	irn_flags => [ "rematerializable" ],
695
696
	reg_req   => { in => [ "gp", "ecx" ],
	               out => [ "in_r1 !in_r2", "flags" ] },
697
	ins       => [ "val", "count" ],
698
	outs      => [ "res", "flags" ],
699
	emit      => '. sar%M %SB1, %S0',
700
	units     => [ "GP" ],
701
	latency   => 1,
702
703
	mode      => $mode_gp,
	modified_flags => $status_flags
704
705
},

706
SarMem => {
707
	irn_flags => [ "rematerializable" ],
708
	state     => "exc_pinned",
709
710
711
	reg_req   => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
	ins       => [ "base", "index", "mem", "count" ],
	emit      => '. sar%M %SB3, %AM',
712
	units     => [ "GP" ],
713
	latency   => 1,
714
715
716
717
	mode      => "mode_M",
	modified_flags => $status_flags
},

718
Ror => {
719
	irn_flags => [ "rematerializable" ],
720
721
	reg_req   => { in => [ "gp", "ecx" ],
	               out => [ "in_r1 !in_r2", "flags" ] },
722
	ins       => [ "val", "count" ],
723
	outs      => [ "res", "flags" ],
724
	emit      => '. ror%M %SB1, %S0',
725
	units     => [ "GP" ],
726
	latency   => 1,
727
728
	mode      => $mode_gp,
	modified_flags => $status_flags
729
730
},

731
RorMem => {
732
	irn_flags => [ "rematerializable" ],
733
	state     => "exc_pinned",
734
735
736
	reg_req   => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
	ins       => [ "base", "index", "mem", "count" ],
	emit      => '. ror%M %SB3, %AM',
737
	units     => [ "GP" ],
738
	latency   => 1,
739
740
741
742
	mode      => "mode_M",
	modified_flags => $status_flags
},

743
Rol => {
744
	irn_flags => [ "rematerializable" ],
745
746