ia32_spec.pl 41 KB
Newer Older
1
2
3
4
5
6
7
# Creation: 2005/10/19
# $Id$
# This is the specification for the ia32 assembler Firm-operations

# the cpu architecture (ia32, ia64, mips, sparc, ppc, ...)
$arch = "ia32";

Christian Würdig's avatar
Christian Würdig committed
8
# this string marks the beginning of a comment in emit
9
$comment_string = "/*";
Christian Würdig's avatar
Christian Würdig committed
10

11
# the number of additional opcodes you want to register
12
#$additional_opcodes = 0;
13

14
15
16
17
18
19
# The node description is done as a perl hash initializer with the
# following structure:
#
# %nodes = (
#
# <op-name> => {
20
21
#   "op_flags"  => "N|L|C|X|I|F|Y|H|c|K",
#   "irn_flags" => "R|N|I"
Christian Würdig's avatar
Christian Würdig committed
22
23
#   "arity"     => "0|1|2|3 ... |variable|dynamic|any",
#   "state"     => "floats|pinned|mem_pinned|exc_pinned",
24
25
26
27
28
29
#   "args"      => [
#                    { "type" => "type 1", "name" => "name 1" },
#                    { "type" => "type 2", "name" => "name 2" },
#                    ...
#                  ],
#   "comment"   => "any comment for constructor",
30
31
#   "reg_req"   => { "in" => [ "reg_class|register" ], "out" => [ "reg_class|register|in_rX" ] },
#   "cmp_attr"  => "c source code for comparing node attributes",
32
#   "emit"      => "emit code with templates",
33
34
#   "attr"      => "attitional attribute arguments for constructor"
#   "init_attr" => "emit attribute initialization template"
Christian Würdig's avatar
Christian Würdig committed
35
#   "rd_constructor" => "c source code which constructs an ir_node"
36
37
38
39
40
41
# },
#
# ... # (all nodes you need to describe)
#
# ); # close the %nodes initializer

42
# op_flags: flags for the operation, OPTIONAL (default is "N")
43
44
45
46
47
48
49
50
51
52
# the op_flags correspond to the firm irop_flags:
#   N   irop_flag_none
#   L   irop_flag_labeled
#   C   irop_flag_commutative
#   X   irop_flag_cfopcode
#   I   irop_flag_ip_cfopcode
#   F   irop_flag_fragile
#   Y   irop_flag_forking
#   H   irop_flag_highlevel
#   c   irop_flag_constlike
Michael Beck's avatar
Michael Beck committed
53
#   K   irop_flag_keep
54
#
55
56
57
58
59
# irn_flags: special node flags, OPTIONAL (default is 0)
# following irn_flags are supported:
#   R   rematerializeable
#   N   not spillable
#   I   ignore for register allocation
Christian Würdig's avatar
Christian Würdig committed
60
#
Christian Würdig's avatar
Christian Würdig committed
61
# state: state of the operation, OPTIONAL (default is "floats")
Christian Würdig's avatar
Christian Würdig committed
62
63
64
65
#
# arity: arity of the operation, MUST NOT BE OMITTED
#
# args:  the OPTIONAL arguments of the node constructor (debug, irg and block
66
67
#        are always the first 3 arguments and are always autmatically
#        created)
Christian Würdig's avatar
Christian Würdig committed
68
#        If this key is missing the following arguments will be created:
69
70
#        for i = 1 .. arity: ir_node *op_i
#        ir_mode *mode
Christian Würdig's avatar
Christian Würdig committed
71
#
Michael Beck's avatar
Michael Beck committed
72
73
74
# outs:  if a node defines more than one output, the names of the projections
#        nodes having outs having automatically the mode mode_T
#
Christian Würdig's avatar
Christian Würdig committed
75
76
# comment: OPTIONAL comment for the node constructor
#
77
78
79
80
81
# rd_constructor: for every operation there will be a
#      new_rd_<arch>_<op-name> function with the arguments from above
#      which creates the ir_node corresponding to the defined operation
#      you can either put the complete source code of this function here
#
Christian Würdig's avatar
Christian Würdig committed
82
83
#      This key is OPTIONAL. If omitted, the following constructor will
#      be created:
84
85
86
87
#      if (!op_<arch>_<op-name>) assert(0);
#      for i = 1 to arity
#         set in[i] = op_i
#      done
Christian Würdig's avatar
Christian Würdig committed
88
#      res = new_ir_node(db, irg, block, op_<arch>_<op-name>, mode, arity, in)
89
90
#      return res
#
Christian Würdig's avatar
Christian Würdig committed
91
# NOTE: rd_constructor and args are only optional if and only if arity is 0,1,2 or 3
92

Christian Würdig's avatar
Christian Würdig committed
93
94
# register types:
#   0 - no special type
95
96
#   1 - caller save (register must be saved by the caller of a function)
#   2 - callee save (register must be saved by the called function)
Christian Würdig's avatar
Christian Würdig committed
97
#   4 - ignore (do not assign this register)
Christian Würdig's avatar
Christian Würdig committed
98
# NOTE: Last entry of each class is the largest Firm-Mode a register can hold
99
%reg_classes = (
100
  "gp" => [
101
102
103
104
105
106
107
            { "name" => "eax", "type" => 1 },
            { "name" => "edx", "type" => 1 },
            { "name" => "ebx", "type" => 2 },
            { "name" => "ecx", "type" => 1 },
            { "name" => "esi", "type" => 2 },
            { "name" => "edi", "type" => 2 },
            { "name" => "ebp", "type" => 2 },
Christian Würdig's avatar
Christian Würdig committed
108
            { "name" => "esp", "type" => 4 },
109
110
            { "name" => "gp_NOREG", "type" => 6 },  # we need a dummy register for NoReg nodes
            { "name" => "gp_UKNWN", "type" => 6 },  # we need a dummy register for Unknown nodes
111
			{ "mode" => "mode_P" }
112
          ],
113
  "xmm" => [
114
115
116
117
118
119
120
121
            { "name" => "xmm0", "type" => 1 },
            { "name" => "xmm1", "type" => 1 },
            { "name" => "xmm2", "type" => 1 },
            { "name" => "xmm3", "type" => 1 },
            { "name" => "xmm4", "type" => 1 },
            { "name" => "xmm5", "type" => 1 },
            { "name" => "xmm6", "type" => 1 },
            { "name" => "xmm7", "type" => 1 },
122
123
            { "name" => "xmm_NOREG", "type" => 6 },  # we need a dummy register for NoReg nodes
            { "name" => "xmm_UKNWN", "type" => 6 },  # we need a dummy register for Unknown nodes
124
			{ "mode" => "mode_D" }
125
126
127
128
129
130
131
132
133
          ],
  "vfp" => [
            { "name" => "vf0", "type" => 1 },
            { "name" => "vf1", "type" => 1 },
            { "name" => "vf2", "type" => 1 },
            { "name" => "vf3", "type" => 1 },
            { "name" => "vf4", "type" => 1 },
            { "name" => "vf5", "type" => 1 },
            { "name" => "vf6", "type" => 1 },
134
            { "name" => "vf7", "type" => 1 },
135
136
            { "name" => "vfp_NOREG", "type" => 6 },  # we need a dummy register for NoReg nodes
            { "name" => "vfp_UKNWN", "type" => 6 },  # we need a dummy register for Unknown nodes
137
138
139
140
141
142
143
144
145
146
147
148
			{ "mode" => "mode_E" }
          ],
  "st" => [
            { "name" => "st0", "type" => 1 },
            { "name" => "st1", "type" => 1 },
            { "name" => "st2", "type" => 1 },
            { "name" => "st3", "type" => 1 },
            { "name" => "st4", "type" => 1 },
            { "name" => "st5", "type" => 1 },
            { "name" => "st6", "type" => 1 },
            { "name" => "st7", "type" => 1 },
			{ "mode" => "mode_E" }
149
          ]
150
151
); # %reg_classes

152
153
154
155
156
157
158
159
160
161
162
#--------------------------------------------------#
#                        _                         #
#                       (_)                        #
#  _ __   _____      __  _ _ __    ___  _ __  ___  #
# | '_ \ / _ \ \ /\ / / | | '__|  / _ \| '_ \/ __| #
# | | | |  __/\ V  V /  | | |    | (_) | |_) \__ \ #
# |_| |_|\___| \_/\_/   |_|_|     \___/| .__/|___/ #
#                                      | |         #
#                                      |_|         #
#--------------------------------------------------#

Michael Beck's avatar
Michael Beck committed
163
164
165
%operands = (
);

166
167
%nodes = (

Christian Würdig's avatar
Christian Würdig committed
168
169
170
171
172
173
174
175
176
177
#-----------------------------------------------------------------#
#  _       _                                         _            #
# (_)     | |                                       | |           #
#  _ _ __ | |_ ___  __ _  ___ _ __   _ __   ___   __| | ___  ___  #
# | | '_ \| __/ _ \/ _` |/ _ \ '__| | '_ \ / _ \ / _` |/ _ \/ __| #
# | | | | | ||  __/ (_| |  __/ |    | | | | (_) | (_| |  __/\__ \ #
# |_|_| |_|\__\___|\__, |\___|_|    |_| |_|\___/ \__,_|\___||___/ #
#                   __/ |                                         #
#                  |___/                                          #
#-----------------------------------------------------------------#
Christian Würdig's avatar
Christian Würdig committed
178

179
180
# commutative operations

181
182
183
184
185
186
187
# NOTE:
# All nodes supporting Addressmode have 5 INs:
# 1 - base    r1 == NoReg in case of no AM or no base
# 2 - index   r2 == NoReg in case of no AM or no index
# 3 - op1     r3 == always present
# 4 - op2     r4 == NoReg in case of immediate operation
# 5 - mem     NoMem in case of no AM otherwise it takes the mem from the Load
188

189
190
191
"Add" => {
  "irn_flags" => "R",
  "comment"   => "construct Add: Add(a, b) = Add(b, a) = a + b",
Christian Würdig's avatar
Christian Würdig committed
192
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
193
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
Christian Würdig's avatar
cleanup    
Christian Würdig committed
194
  "emit"      => '. add %ia32_emit_binop /* Add(%A1, %A2) -> %D1 */',
Michael Beck's avatar
Michael Beck committed
195
  "outs"      => [ "res", "M" ],
196
197
198
},

"Mul" => {
Michael Beck's avatar
Michael Beck committed
199
  "irn_flags" => "R",
200
  "comment"   => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
Christian Würdig's avatar
Christian Würdig committed
201
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
202
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
203
204
  "emit"      => '. imul %ia32_emit_binop /* Mul(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
205
206
},

207
208
209
# Mulh is an exception from the 4 INs with AM because the target is always EAX:EDX
"Mulh" => {
  "comment"   => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
Christian Würdig's avatar
Christian Würdig committed
210
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
211
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "eax in_r3", "edx in_r4" ] },
Michael Beck's avatar
Michael Beck committed
212
213
  "emit"      => '. imul %ia32_emit_binop /* Mulh(%A1, %A2) -> %D1 */',
  "outs"      => [ "EAX", "EDX", "M" ],
214
215
},

216
"And" => {
217
218
  "irn_flags" => "R",
  "comment"   => "construct And: And(a, b) = And(b, a) = a AND b",
Christian Würdig's avatar
Christian Würdig committed
219
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
220
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
221
222
  "emit"      => '. and %ia32_emit_binop /* And(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
223
224
225
},

"Or" => {
226
227
  "irn_flags" => "R",
  "comment"   => "construct Or: Or(a, b) = Or(b, a) = a OR b",
Christian Würdig's avatar
Christian Würdig committed
228
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
229
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
230
231
  "emit"      => '. or %ia32_emit_binop /* Or(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
232
233
234
},

"Eor" => {
235
236
  "irn_flags" => "R",
  "comment"   => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b",
Christian Würdig's avatar
Christian Würdig committed
237
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
238
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
239
240
  "emit"      => '. xor %ia32_emit_binop /* Xor(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
241
242
243
},

"Max" => {
244
245
246
247
  "irn_flags" => "R",
  "comment"   => "construct Max: Max(a, b) = Max(b, a) = a > b ? a : b",
  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] },
  "emit"      =>
248
'2. cmp %S1, %S2 /* prepare Max (%S1 - %S2), (%A1, %A2) */
249
  if (mode_is_signed(get_irn_mode(n))) {
250
4.  cmovl %D1, %S2 /* %S1 is less %S2 */
251
252
  }
  else {
253
4.  cmovb %D1, %S2 /* %S1 is below %S2 */
254
255
  }
'
256
257
258
},

"Min" => {
259
260
261
262
  "irn_flags" => "R",
  "comment"   => "construct Min: Min(a, b) = Min(b, a) = a < b ? a : b",
  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] },
  "emit"      =>
263
'2. cmp %S1, %S2 /* prepare Min (%S1 - %S2), (%A1, %A2) */
264
  if (mode_is_signed(get_irn_mode(n))) {
265
2.  cmovg %D1, %S2 /* %S1 is greater %S2 */
266
267
  }
  else {
268
2.  cmova %D1, %S2, %D1 /* %S1 is above %S2 */
269
270
  }
'
271
272
},

273
274
275
"CMov" => {
  "irn_flags" => "R",
  "comment"   => "construct Mux: Mux(sel, a, b) == sel ? a : b",
276
  "reg_req"   => { "in" => [ "gp", "gp", "gp" ], "out" => [ "in_r2" ] },
277
  "emit"      =>
278
279
'. cmp %S1, 0 /* compare Sel for CMov (%A2, %A3) */
. cmovne %D1, %S3 /* sel == true -> return %S3 */
280
281
282
'
},

283
284
285
# not commutative operations

"Sub" => {
286
287
  "irn_flags" => "R",
  "comment"   => "construct Sub: Sub(a, b) = a - b",
Christian Würdig's avatar
Christian Würdig committed
288
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
289
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
290
291
  "emit"      => '. sub %ia32_emit_binop /* Sub(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
292
293
},

294
"DivMod" => {
Christian Würdig's avatar
Christian Würdig committed
295
296
297
298
299
300
301
  "op_flags"  => "F|L",
  "state"     => "exc_pinned",
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "eax in_r1", "edx in_r3" ] },
  "attr"      => "ia32_op_flavour_t dm_flav",
  "init_attr" => "  attr->data.op_flav = dm_flav;",
  "cmp_attr"  => "  return attr_a->data.op_flav != attr_b->data.op_flav;\n",
  "emit"      =>
302
'  if (mode_is_signed(get_irn_mode(n))) {
303
4.  idiv %S2 /* signed DivMod(%S1, %S2) -> %D1, (%A1, %A2, %A3) */
304
305
  }
  else {
306
4.  div %S2 /* unsigned DivMod(%S1, %S2) -> %D1, (%A1, %A2, %A3) */
307
  }
Michael Beck's avatar
Michael Beck committed
308
309
',
  "outs"      => [ "div_res", "mod_res", "M" ],
310
311
312
},

"Shl" => {
313
314
  "irn_flags" => "R",
  "comment"   => "construct Shl: Shl(a, b) = a << b",
Christian Würdig's avatar
Christian Würdig committed
315
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
316
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
Michael Beck's avatar
Michael Beck committed
317
318
  "emit"      => '. shl %ia32_emit_binop /* Shl(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
319
320
321
},

"Shr" => {
322
323
  "irn_flags" => "R",
  "comment"   => "construct Shr: Shr(a, b) = a >> b",
Christian Würdig's avatar
Christian Würdig committed
324
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
325
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
Michael Beck's avatar
Michael Beck committed
326
327
  "emit"      => '. shr %ia32_emit_binop /* Shr(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
328
329
330
},

"Shrs" => {
331
332
  "irn_flags" => "R",
  "comment"   => "construct Shrs: Shrs(a, b) = a >> b",
Christian Würdig's avatar
Christian Würdig committed
333
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
334
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
Michael Beck's avatar
Michael Beck committed
335
336
  "emit"      => '. sar %ia32_emit_binop /* Shrs(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
337
338
339
},

"RotR" => {
340
  "irn_flags" => "R",
341
  "comment"     => "construct RotR: RotR(a, b) = a ROTR b",
Christian Würdig's avatar
Christian Würdig committed
342
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
343
  "reg_req"     => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
Michael Beck's avatar
Michael Beck committed
344
345
  "emit"        => '. ror %ia32_emit_binop /* RotR(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
346
347
},

348
"RotL" => {
349
350
  "irn_flags" => "R",
  "comment"   => "construct RotL: RotL(a, b) = a ROTL b",
Christian Würdig's avatar
Christian Würdig committed
351
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
352
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
Michael Beck's avatar
Michael Beck committed
353
354
  "emit"      => '. rol %ia32_emit_binop /* RotL(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
355
356
},

357
# unary operations
Christian Würdig's avatar
Christian Würdig committed
358

Christian Würdig's avatar
Christian Würdig committed
359
"Minus" => {
360
361
  "irn_flags" => "R",
  "comment"   => "construct Minus: Minus(a) = -a",
Christian Würdig's avatar
Christian Würdig committed
362
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
363
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
364
365
  "emit"      => '. neg %ia32_emit_unop /* Neg(%A1) -> %D1, (%A1) */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
366
367
368
},

"Inc" => {
369
370
  "irn_flags" => "R",
  "comment"   => "construct Increment: Inc(a) = a++",
Christian Würdig's avatar
Christian Würdig committed
371
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
372
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
373
374
  "emit"      => '. inc %ia32_emit_unop /* Inc(%S1) -> %D1, (%A1) */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
375
376
377
},

"Dec" => {
378
379
  "irn_flags" => "R",
  "comment"   => "construct Decrement: Dec(a) = a--",
Christian Würdig's avatar
Christian Würdig committed
380
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
381
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
382
383
  "emit"      => '. dec %ia32_emit_unop /* Dec(%S1) -> %D1, (%A1) */',
  "outs"      => [ "res", "M" ],
384
385
386
},

"Not" => {
387
388
  "irn_flags" => "R",
  "comment"   => "construct Not: Not(a) = !a",
Christian Würdig's avatar
Christian Würdig committed
389
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
390
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
391
392
  "emit"      => '. not %ia32_emit_unop /* Not(%S1) -> %D1, (%A1) */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
393
394
},

Christian Würdig's avatar
Christian Würdig committed
395
396
# other operations

Christian Würdig's avatar
Christian Würdig committed
397
"CondJmp" => {
398
  "op_flags"  => "L|X|Y",
399
  "comment"   => "construct conditional jump: CMP A, B && JMPxx LABEL",
Christian Würdig's avatar
Christian Würdig committed
400
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
401
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ] },
Michael Beck's avatar
Michael Beck committed
402
  "outs"      => [ "false", "true" ],
Christian Würdig's avatar
Christian Würdig committed
403
404
},

405
406
407
"TestJmp" => {
  "op_flags"  => "L|X|Y",
  "comment"   => "construct conditional jump: TEST A, B && JMPxx LABEL",
408
409
  "reg_req"  => { "in" => [ "gp", "gp" ] },
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
Michael Beck's avatar
Michael Beck committed
410
  "outs"      => [ "false", "true" ],
411
412
413
414
415
416
417
},

"CJmpAM" => {
  "op_flags"  => "L|X|Y",
  "comment"   => "construct conditional jump without CMP (replaces CondJmp): JMPxx LABEL",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "none", "none" ] },
Michael Beck's avatar
Michael Beck committed
418
  "outs"      => [ "false", "true" ],
419
420
421
422
423
},

"CJmp" => {
  "op_flags"  => "L|X|Y",
  "comment"   => "construct conditional jump without CMP (replaces TestJmp): JMPxx LABEL",
424
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
425
  "reg_req"   => { "in" => [ "gp", "gp" ] },
426
427
},

Christian Würdig's avatar
Christian Würdig committed
428
"SwitchJmp" => {
429
430
  "op_flags"  => "L|X|Y",
  "comment"   => "construct switch",
Christian Würdig's avatar
Christian Würdig committed
431
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
Christian Würdig's avatar
Christian Würdig committed
432
  "reg_req"   => { "in" => [ "gp" ], "out" => [ "none" ] },
433
434
435
},

"Const" => {
436
437
438
  "op_flags"  => "c",
  "irn_flags" => "R",
  "comment"   => "represents an integer constant",
Christian Würdig's avatar
Christian Würdig committed
439
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
440
  "reg_req"   => { "in" => [ "none" ], "out" => [ "gp" ] },
441
442
},

443
444
445
446
"Cdq" => {
  "irn_flags" => "R",
  "comment"   => "construct CDQ: sign extend EAX -> EDX:EAX",
  "reg_req"   => { "in" => [ "gp" ], "out" => [ "eax in_r1", "edx" ] },
Michael Beck's avatar
Michael Beck committed
447
448
  "emit"      => '. cdq /* sign extend EAX -> EDX:EAX, (%A1) */',
  "outs"      => [ "EAX", "EDX" ],
449
450
},

Christian Würdig's avatar
Christian Würdig committed
451
452
453
# Load / Store

"Load" => {
454
455
456
457
  "op_flags"  => "L|F",
  "irn_flags" => "R",
  "state"     => "exc_pinned",
  "comment"   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
Christian Würdig's avatar
Christian Würdig committed
458
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
459
  "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "gp" ] },
Christian Würdig's avatar
Christian Würdig committed
460
461
  "emit"      =>
'  if (get_mode_size_bits(get_ia32_ls_mode(n)) < 32) {
462
4.   mov%Mx %D1, %ia32_emit_am /* Load((%A1)) -> %D1 */
Christian Würdig's avatar
Christian Würdig committed
463
464
  }
  else {
465
4.   mov %D1, %ia32_emit_am /* Load((%A1)) -> %D1 */
Christian Würdig's avatar
Christian Würdig committed
466
  }
Michael Beck's avatar
Michael Beck committed
467
468
',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
469
470
471
},

"Store" => {
472
473
474
  "op_flags"  => "L|F",
  "state"     => "exc_pinned",
  "comment"   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
Christian Würdig's avatar
Christian Würdig committed
475
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
476
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ] },
Michael Beck's avatar
Michael Beck committed
477
478
  "emit"      => '. mov %ia32_emit_binop /* Store(%A3) -> (%A1) */',
  "outs"      => [ "M" ],
Christian Würdig's avatar
Christian Würdig committed
479
480
},

481
482
483
484
485
"Store8Bit" => {
  "op_flags"  => "L|F",
  "state"     => "exc_pinned",
  "comment"   => "construct 8Bit Store: Store(ptr, val, mem) = ST ptr,val",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
Christian Würdig's avatar
Christian Würdig committed
486
  "reg_req"   => { "in" => [ "gp", "gp", "eax ebx ecx edx", "none" ] },
Michael Beck's avatar
Michael Beck committed
487
488
  "emit"      => '. mov %ia32_emit_binop /* Store(%A3) -> (%A1) */',
  "outs"      => [ "M" ],
489
490
},

Christian Würdig's avatar
Christian Würdig committed
491
"Lea" => {
492
493
  "irn_flags" => "R",
  "comment"   => "construct Lea: Lea(a,b) = lea [a+b*const+offs] | res = a + b * const + offs with const = 0,1,2,4,8",
Christian Würdig's avatar
Christian Würdig committed
494
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
495
  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] },
496
  "emit"      => '. lea %D1, %ia32_emit_am /* LEA(%A1, %A2) */'
Christian Würdig's avatar
Christian Würdig committed
497
498
},

499
500
"Push" => {
  "comment"   => "push a gp register on the stack",
Michael Beck's avatar
Michael Beck committed
501
  "reg_req"   => { "in" => [ "esp", "gp", "none" ], "out" => [ "esp" ] },
502
503
504
505
506
507
508
509
510
511
512
513
  "emit"      => '
if (get_ia32_id_cnst(n)) {
	if (get_ia32_immop_type(n) == ia32_ImmConst) {
. push %C /* Push(%A2) */
	} else {
. push OFFSET FLAT:%C /* Push(%A2) */
	}
}
else {
. push %S2 /* Push(%A2) */
}
',
Michael Beck's avatar
Michael Beck committed
514
  "outs"      => [ "stack", "M" ],
515
516
517
518
519
},

"Pop" => {
  "comment"   => "pop a gp register from the stack",
  "reg_req"   => { "in" => [ "esp", "none" ], "out" => [ "gp", "esp" ] },
Michael Beck's avatar
Michael Beck committed
520
521
  "emit"      => '. pop %D1 /* Pop -> %D1 */',
  "outs"      => [ "res", "stack", "M" ],
522
523
524
525
526
},

"Enter" => {
  "comment"   => "create stack frame",
  "reg_req"   => { "in" => [ "esp" ], "out" => [ "ebp", "esp" ] },
Michael Beck's avatar
Michael Beck committed
527
528
  "emit"      => '. enter /* Enter */',
  "outs"      => [ "frame", "stack", "M" ],
529
530
531
532
},

"Leave" => {
  "comment"   => "destroy stack frame",
533
  "reg_req"   => { "in" => [ "esp", "ebp" ], "out" => [ "ebp", "esp" ] },
Michael Beck's avatar
Michael Beck committed
534
535
  "emit"      => '. leave /* Leave */',
  "outs"      => [ "frame", "stack", "M" ],
536
537
},

Michael Beck's avatar
Michael Beck committed
538
539
540
541
542
543
544
545
#-----------------------------------------------------------------------------#
#   _____ _____ ______    __ _             _                     _            #
#  / ____/ ____|  ____|  / _| |           | |                   | |           #
# | (___| (___ | |__    | |_| | ___   __ _| |_   _ __   ___   __| | ___  ___  #
#  \___ \\___ \|  __|   |  _| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| #
#  ____) |___) | |____  | | | | (_) | (_| | |_  | | | | (_) | (_| |  __/\__ \ #
# |_____/_____/|______| |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ #
#-----------------------------------------------------------------------------#
Christian Würdig's avatar
Christian Würdig committed
546
547
548

# commutative operations

Christian Würdig's avatar
Christian Würdig committed
549
"xAdd" => {
550
551
  "irn_flags" => "R",
  "comment"   => "construct SSE Add: Add(a, b) = Add(b, a) = a + b",
Christian Würdig's avatar
Christian Würdig committed
552
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
553
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
554
555
  "emit"      => '. adds%M %ia32_emit_binop /* SSE Add(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
556
557
},

Christian Würdig's avatar
Christian Würdig committed
558
"xMul" => {
559
560
  "irn_flags" => "R",
  "comment"   => "construct SSE Mul: Mul(a, b) = Mul(b, a) = a * b",
Christian Würdig's avatar
Christian Würdig committed
561
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
562
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
563
564
  "emit"      => '. muls%M %ia32_emit_binop /* SSE Mul(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
565
566
},

Christian Würdig's avatar
Christian Würdig committed
567
"xMax" => {
568
569
  "irn_flags" => "R",
  "comment"   => "construct SSE Max: Max(a, b) = Max(b, a) = a > b ? a : b",
Christian Würdig's avatar
Christian Würdig committed
570
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
571
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
572
573
  "emit"      => '. maxs%M %ia32_emit_binop /* SSE Max(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
574
575
},

Christian Würdig's avatar
Christian Würdig committed
576
"xMin" => {
577
578
  "irn_flags" => "R",
  "comment"   => "construct SSE Min: Min(a, b) = Min(b, a) = a < b ? a : b",
Christian Würdig's avatar
Christian Würdig committed
579
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
580
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
581
582
  "emit"      => '. mins%M %ia32_emit_binop /* SSE Min(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
583
584
},

Christian Würdig's avatar
Christian Würdig committed
585
"xAnd" => {
586
587
  "irn_flags" => "R",
  "comment"   => "construct SSE And: And(a, b) = a AND b",
Christian Würdig's avatar
Christian Würdig committed
588
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
589
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
590
591
  "emit"      => '. andp%M %ia32_emit_binop /* SSE And(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
592
593
},

Christian Würdig's avatar
Christian Würdig committed
594
"xOr" => {
595
596
  "irn_flags" => "R",
  "comment"   => "construct SSE Or: Or(a, b) = a OR b",
Christian Würdig's avatar
Christian Würdig committed
597
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
598
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
599
600
  "emit"      => '. orp%M %ia32_emit_binop /* SSE Or(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
601
602
},

Christian Würdig's avatar
Christian Würdig committed
603
"xEor" => {
604
605
  "irn_flags" => "R",
  "comment"   => "construct SSE Eor: Eor(a, b) = a XOR b",
Christian Würdig's avatar
Christian Würdig committed
606
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
607
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
608
609
  "emit"      => '. xorp%M %ia32_emit_binop /* SSE Xor(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
610
611
612
613
},

# not commutative operations

Christian Würdig's avatar
Christian Würdig committed
614
"xSub" => {
615
616
  "irn_flags" => "R",
  "comment"   => "construct SSE Sub: Sub(a, b) = a - b",
Christian Würdig's avatar
Christian Würdig committed
617
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
618
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
619
620
  "emit"      => '. subs%M %ia32_emit_binop /* SSE Sub(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
621
622
},

Christian Würdig's avatar
Christian Würdig committed
623
"xDiv" => {
624
625
  "irn_flags" => "R",
  "comment"   => "construct SSE Div: Div(a, b) = a / b",
Christian Würdig's avatar
Christian Würdig committed
626
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
627
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3 !in_r4" ] },
Michael Beck's avatar
Michael Beck committed
628
629
  "emit"      => '. divs%M %ia32_emit_binop /* SSE Div(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
630
631
632
633
},

# other operations

Christian Würdig's avatar
Christian Würdig committed
634
"xCondJmp" => {
635
  "op_flags"  => "L|X|Y",
636
  "comment"   => "construct conditional jump: UCOMIS A, B && JMPxx LABEL",
Christian Würdig's avatar
Christian Würdig committed
637
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
638
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "none", "none" ] },
Michael Beck's avatar
Michael Beck committed
639
  "outs"      => [ "false", "true" ],
Christian Würdig's avatar
Christian Würdig committed
640
},
Christian Würdig's avatar
Christian Würdig committed
641

Christian Würdig's avatar
Christian Würdig committed
642
"xConst" => {
643
644
645
  "op_flags"  => "c",
  "irn_flags" => "R",
  "comment"   => "represents a SSE constant",
Christian Würdig's avatar
Christian Würdig committed
646
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
647
  "reg_req"   => { "in" => [ "none" ], "out" => [ "xmm" ] },
648
  "emit"      => '. mov%M %D1, %C /* Load fConst into register */',
Christian Würdig's avatar
Christian Würdig committed
649
},
Christian Würdig's avatar
Christian Würdig committed
650

Christian Würdig's avatar
Christian Würdig committed
651
# Load / Store
Christian Würdig's avatar
Christian Würdig committed
652

Christian Würdig's avatar
Christian Würdig committed
653
"xLoad" => {
654
655
656
657
  "op_flags"  => "L|F",
  "irn_flags" => "R",
  "state"     => "exc_pinned",
  "comment"   => "construct SSE Load: Load(ptr, mem) = LD ptr",
Christian Würdig's avatar
Christian Würdig committed
658
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
659
  "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "xmm" ] },
Michael Beck's avatar
Michael Beck committed
660
661
  "emit"      => '. movs%M %D1, %ia32_emit_am /* Load((%A1)) -> %D1 */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
662
},
Christian Würdig's avatar
Christian Würdig committed
663

Christian Würdig's avatar
Christian Würdig committed
664
"xStore" => {
Christian Würdig's avatar
Christian Würdig committed
665
666
667
  "op_flags" => "L|F",
  "state"    => "exc_pinned",
  "comment"  => "construct Store: Store(ptr, val, mem) = ST ptr,val",
Christian Würdig's avatar
Christian Würdig committed
668
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
669
  "reg_req"  => { "in" => [ "gp", "gp", "xmm", "none" ] },
Michael Beck's avatar
Michael Beck committed
670
671
  "emit"     => '. movs%M %ia32_emit_binop /* Store(%S3) -> (%A1) */',
  "outs"      => [ "M" ],
Christian Würdig's avatar
Christian Würdig committed
672
673
},

674
675
676
# CopyB

"CopyB" => {
Christian Würdig's avatar
Christian Würdig committed
677
678
679
680
  "op_flags" => "F|H",
  "state"    => "pinned",
  "comment"  => "implements a memcopy: CopyB(dst, src, size, mem) == memcpy(dst, src, size)",
  "reg_req"  => { "in" => [ "edi", "esi", "ecx", "none" ], "out" => [ "none" ] },
Christian Würdig's avatar
Christian Würdig committed
681
682
},

683
"CopyB_i" => {
Christian Würdig's avatar
Christian Würdig committed
684
685
686
687
688
  "op_flags" => "F|H",
  "state"    => "pinned",
  "comment"  => "implements a memcopy: CopyB(dst, src, mem) == memcpy(dst, src, attr(size))",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
  "reg_req"  => { "in" => [ "edi", "esi", "none" ], "out" => [ "none" ] },
Christian Würdig's avatar
Christian Würdig committed
689
690
},

Christian Würdig's avatar
Christian Würdig committed
691
692
# Conversions

Christian Würdig's avatar
Christian Würdig committed
693
"Conv_I2I" => {
Christian Würdig's avatar
Christian Würdig committed
694
  "reg_req"  => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3", "none" ] },
695
  "cmp_attr"  => "  return ia32_compare_conv_attr(attr_a, attr_b);\n",
Michael Beck's avatar
Michael Beck committed
696
697
  "comment"  => "construct Conv Int -> Int",
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
698
699
700
701
},

"Conv_I2I8Bit" => {
  "reg_req"  => { "in" => [ "gp", "gp", "eax ebx ecx edx", "none" ], "out" => [ "in_r3", "none" ] },
702
  "cmp_attr"  => "  return ia32_compare_conv_attr(attr_a, attr_b);\n",
Michael Beck's avatar
Michael Beck committed
703
704
  "comment"  => "construct Conv Int -> Int",
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
705
706
},

Christian Würdig's avatar
Christian Würdig committed
707
"Conv_I2FP" => {
708
  "reg_req"  => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "xmm", "none" ] },
709
  "cmp_attr"  => "  return ia32_compare_conv_attr(attr_a, attr_b);\n",
Michael Beck's avatar
Michael Beck committed
710
711
  "comment"  => "construct Conv Int -> Floating Point",
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
712
713
714
},

"Conv_FP2I" => {
715
  "reg_req"  => { "in" => [ "gp", "gp", "xmm", "none" ], "out" => [ "gp", "none" ] },
716
  "cmp_attr"  => "  return ia32_compare_conv_attr(attr_a, attr_b);\n",
Michael Beck's avatar
Michael Beck committed
717
718
  "comment"  => "construct Conv Floating Point -> Int",
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
719
720
721
},

"Conv_FP2FP" => {
722
  "reg_req"  => { "in" => [ "gp", "gp", "xmm", "none" ], "out" => [ "xmm", "none" ] },
723
  "cmp_attr"  => "  return ia32_compare_conv_attr(attr_a, attr_b);\n",
724
  "comment"  => "construct Conv Floating Point -> Floating Point",
Michael Beck's avatar
Michael Beck committed
725
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
726
727
},

Michael Beck's avatar
Michael Beck committed
728
729
730
731
732
733
734
735
736
737
738
739
740
#----------------------------------------------------------#
#        _      _               _    __ _             _    #
#       (_)    | |             | |  / _| |           | |   #
# __   ___ _ __| |_ _   _  __ _| | | |_| | ___   __ _| |_  #
# \ \ / / | '__| __| | | |/ _` | | |  _| |/ _ \ / _` | __| #
#  \ V /| | |  | |_| |_| | (_| | | | | | | (_) | (_| | |_  #
#   \_/ |_|_|   \__|\__,_|\__,_|_| |_| |_|\___/ \__,_|\__| #
#                 | |                                      #
#  _ __   ___   __| | ___  ___                             #
# | '_ \ / _ \ / _` |/ _ \/ __|                            #
# | | | | (_) | (_| |  __/\__ \                            #
# |_| |_|\___/ \__,_|\___||___/                            #
#----------------------------------------------------------#
741
742
743
744
745
746

"vfadd" => {
  "irn_flags" => "R",
  "comment"   => "virtual fp Add: Add(a, b) = Add(b, a) = a + b",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
  "reg_req"   => { "in" => [ "gp", "gp", "vfp", "vfp", "none" ], "out" => [ "vfp" ] },
Michael Beck's avatar
Michael Beck committed
747
  "outs"      => [ "res", "M" ],
748
749
750
751
752
753
754
},

"vfmul" => {
  "irn_flags" => "R",
  "comment"   => "virtual fp Mul: Mul(a, b) = Mul(b, a) = a + b",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
  "reg_req"   => { "in" => [ "gp", "gp", "vfp", "vfp", "none" ], "out" => [ "vfp" ] },
Michael Beck's avatar
Michael Beck committed
755
  "outs"      => [ "res", "M" ],
756
757
758
759
760
761
762
},

"vfsub" => {
  "irn_flags" => "R",
  "comment"   => "virtual fp Sub: Sub(a, b) = a - b",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
  "reg_req"   => { "in" => [ "gp", "gp", "vfp", "vfp", "none" ], "out" => [ "vfp" ] },
Michael Beck's avatar
Michael Beck committed
763
  "outs"      => [ "res", "M" ],
764
765
766
767
768
769
},

"vfdiv" => {
  "comment"   => "virtual fp Div: Div(a, b) = a / b",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
  "reg_req"   => { "in" => [ "gp", "gp", "vfp", "vfp", "none" ], "out" => [ "vfp" ] },
Michael Beck's avatar
Michael Beck committed
770
  "outs"      => [ "res", "M" ],
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
},

"vfabs" => {
  "irn_flags" => "R",
  "comment"   => "virtual fp Abs: Abs(a) = |a|",
  "reg_req"   => { "in" => [ "vfp"], "out" => [ "vfp" ] },
},

"vfchs" => {
  "irn_flags" => "R",
  "comment"   => "virtual fp Chs: Chs(a) = -a",
  "reg_req"   => { "in" => [ "vfp"], "out" => [ "vfp" ] },
},

"vfsin" => {
  "irn_flags" => "R",
  "comment"   => "virtual fp Sin: Sin(a) = sin(a)",
  "reg_req"   => { "in" => [ "vfp"], "out" => [ "vfp" ] },
},

"vfcos" => {
  "irn_flags" => "R",
  "comment"   => "virtual fp Cos: Cos(a) = cos(a)",
  "reg_req"   => { "in" => [ "vfp"], "out" => [ "vfp" ] },
},

"vfsqrt" => {
  "irn_flags" => "R",
  "comment"   => "virtual fp Sqrt: Sqrt(a) = a ^ 0.5",
  "reg_req"   => { "in" => [ "vfp"], "out" => [ "vfp" ] },
},

# virtual Load and Store

"vfld" => {
  "op_flags"  => "L|F",
  "irn_flags" => "R",
  "state"     => "exc_pinned",
  "comment"   => "virtual fp Load: Load(ptr, mem) = LD ptr -> reg",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
Michael Beck's avatar
Michael Beck committed
811
812
  "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "vfp", "none" ] },
  "outs"      => [ "res", "M" ],
813
814
815
816
817
818
819
820
},

"vfst" => {
  "op_flags"  => "L|F",
  "state"     => "exc_pinned",
  "comment"   => "virtual fp Store: Store(ptr, val, mem) = ST ptr,val",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
  "reg_req"   => { "in" => [ "gp", "gp", "vfp", "none" ] },
Michael Beck's avatar
Michael Beck committed
821
  "outs"      => [ "M" ],
822
823
},

824
825
826
827
828
829
# Conversions

"vfild" => {
  "irn_flags" => "R",
  "comment"   => "virtual fp integer Load: Load(ptr, mem) = iLD ptr -> reg",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
Michael Beck's avatar
Michael Beck committed
830
831
  "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "vfp", "none" ] },
  "outs"      => [ "res", "M" ],
832
833
834
835
836
837
},

"vfist" => {
  "comment"   => "virtual fp integer Store: Store(ptr, val, mem) = iST ptr,val",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
  "reg_req"   => { "in" => [ "gp", "gp", "vfp", "none" ] },
Michael Beck's avatar
Michael Beck committed
838
  "outs"      => [ "M" ],
839
840
},

841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
# constants

"vfldz" => {
  "irn_flags" => "R",
  "comment"   => "virtual fp Load 0.0: Ld 0.0 -> reg",
  "reg_req"   => { "out" => [ "vfp" ] },
},

"vfld1" => {
  "irn_flags" => "R",
  "comment"   => "virtual fp Load 1.0: Ld 1.0 -> reg",
  "reg_req"   => { "out" => [ "vfp" ] },
},

"vfldpi" => {
  "irn_flags" => "R",
  "comment"   => "virtual fp Load pi: Ld pi -> reg",
  "reg_req"   => { "out" => [ "vfp" ] },
},

"vfldln2" => {
  "irn_flags" => "R",
  "comment"   => "virtual fp Load ln 2: Ld ln 2 -> reg",
  "reg_req"   => { "out" => [ "vfp" ] },
},

"vfldlg2" => {
  "irn_flags" => "R",
  "comment"   => "virtual fp Load lg 2: Ld lg 2 -> reg",
  "reg_req"   => { "out" => [ "vfp" ] },
},

"vfldl2t" => {
  "irn_flags" => "R",
  "comment"   => "virtual fp Load ld 10: Ld ld 10 -> reg",
  "reg_req"   => { "out" => [ "vfp" ] },
},

"vfldl2e" => {
  "irn_flags" => "R",
  "comment"   => "virtual fp Load ld e: Ld ld e -> reg",
  "reg_req"   => { "out" => [ "vfp" ] },
},

"vfConst" => {
  "op_flags"  => "c",
  "irn_flags" => "R",
  "comment"   => "represents a virtual floating point constant",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
890
  "reg_req"   => { "in" => [ "none" ], "out" => [ "vfp" ] },
891
892
},

Michael Beck's avatar
Michael Beck committed
893
894
895
896
897
898
899
900
901
902
# other

"vfCondJmp" => {
  "op_flags"  => "L|X|Y",
  "comment"   => "represents a virtual floating point compare",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
  "reg_req"   => { "in" => [ "gp", "gp", "vfp", "vfp", "none" ], "out" => [ "none", "none", "eax" ] },
  "outs"      => [ "false", "true", "temp_reg_eax" ],
},

Michael Beck's avatar
Michael Beck committed
903
904
905
906
907
908
909
#------------------------------------------------------------------------#
#       ___ _____    __ _             _                     _            #
# __  _( _ )___  |  / _| | ___   __ _| |_   _ __   ___   __| | ___  ___  #
# \ \/ / _ \  / /  | |_| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| #
#  >  < (_) |/ /   |  _| | (_) | (_| | |_  | | | | (_) | (_| |  __/\__ \ #
# /_/\_\___//_/    |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ #
#------------------------------------------------------------------------#
910
911

"fadd" => {
912
  "op_flags"  => "R",
913
  "rd_constructor" => "NONE",
914
915
  "comment"   => "x87 Add: Add(a, b) = Add(b, a) = a + b",
  "reg_req"   => { },
Michael Beck's avatar
Michael Beck committed
916
  "emit"      => '. fadd %ia32_emit_x87_binop /* x87 fadd(%A1, %A2) -> %D1 */',
917
918
919
},

"faddp" => {
920
  "op_flags"  => "R",
921
922
923
  "rd_constructor" => "NONE",
  "comment"   => "x87 Add: Add(a, b) = Add(b, a) = a + b",
  "reg_req"   => { },
Michael Beck's avatar
Michael Beck committed
924
  "emit"      => '. faddp %ia32_emit_x87_binop /* x87 fadd(%A1, %A2) -> %D1 */',
925
926
927
},

"fmul" => {
928
  "op_flags"  => "R",
929
  "rd_constructor"