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
			{ "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 },
148
149
            { "name" => "st_NOREG", "type" => 6 },  # we need a dummy register for NoReg nodes
            { "name" => "st_UKNWN", "type" => 6 },  # we need a dummy register for Unknown nodes
150
			{ "mode" => "mode_E" }
151
          ]
152
153
); # %reg_classes

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

Michael Beck's avatar
Michael Beck committed
165
166
167
%operands = (
);

168
169
%nodes = (

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

181
182
# commutative operations

183
184
185
186
187
188
189
# 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
190

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

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

209
210
211
# 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
212
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
213
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "eax in_r3", "edx in_r4" ] },
Michael Beck's avatar
Michael Beck committed
214
215
  "emit"      => '. imul %ia32_emit_binop /* Mulh(%A1, %A2) -> %D1 */',
  "outs"      => [ "EAX", "EDX", "M" ],
216
217
},

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

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

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

"Max" => {
246
247
248
249
  "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"      =>
250
'2. cmp %S1, %S2 /* prepare Max (%S1 - %S2), (%A1, %A2) */
251
  if (mode_is_signed(get_irn_mode(n))) {
252
4.  cmovl %D1, %S2 /* %S1 is less %S2 */
253
254
  }
  else {
255
4.  cmovb %D1, %S2 /* %S1 is below %S2 */
256
257
  }
'
258
259
260
},

"Min" => {
261
262
263
264
  "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"      =>
265
'2. cmp %S1, %S2 /* prepare Min (%S1 - %S2), (%A1, %A2) */
266
  if (mode_is_signed(get_irn_mode(n))) {
267
2.  cmovg %D1, %S2 /* %S1 is greater %S2 */
268
269
  }
  else {
270
2.  cmova %D1, %S2, %D1 /* %S1 is above %S2 */
271
272
  }
'
273
274
},

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

285
286
287
# not commutative operations

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

296
"DivMod" => {
Christian Würdig's avatar
Christian Würdig committed
297
298
299
300
301
302
303
  "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"      =>
304
'  if (mode_is_signed(get_irn_mode(n))) {
305
4.  idiv %S2 /* signed DivMod(%S1, %S2) -> %D1, (%A1, %A2, %A3) */
306
307
  }
  else {
308
4.  div %S2 /* unsigned DivMod(%S1, %S2) -> %D1, (%A1, %A2, %A3) */
309
  }
Michael Beck's avatar
Michael Beck committed
310
311
',
  "outs"      => [ "div_res", "mod_res", "M" ],
312
313
314
},

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

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

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

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

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

359
# unary operations
Christian Würdig's avatar
Christian Würdig committed
360

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

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

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

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

Christian Würdig's avatar
Christian Würdig committed
397
398
# other operations

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

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

"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
420
  "outs"      => [ "false", "true" ],
421
422
423
424
425
},

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

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

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

445
446
447
448
"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
449
450
  "emit"      => '. cdq /* sign extend EAX -> EDX:EAX, (%A1) */',
  "outs"      => [ "EAX", "EDX" ],
451
452
},

Christian Würdig's avatar
Christian Würdig committed
453
454
455
# Load / Store

"Load" => {
456
457
458
459
  "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
460
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
461
  "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "gp" ] },
Christian Würdig's avatar
Christian Würdig committed
462
463
  "emit"      =>
'  if (get_mode_size_bits(get_ia32_ls_mode(n)) < 32) {
464
4.   mov%Mx %D1, %ia32_emit_am /* Load((%A1)) -> %D1 */
Christian Würdig's avatar
Christian Würdig committed
465
466
  }
  else {
467
4.   mov %D1, %ia32_emit_am /* Load((%A1)) -> %D1 */
Christian Würdig's avatar
Christian Würdig committed
468
  }
Michael Beck's avatar
Michael Beck committed
469
470
',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
471
472
473
},

"Store" => {
474
475
476
  "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
477
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
478
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ] },
Michael Beck's avatar
Michael Beck committed
479
480
  "emit"      => '. mov %ia32_emit_binop /* Store(%A3) -> (%A1) */',
  "outs"      => [ "M" ],
Christian Würdig's avatar
Christian Würdig committed
481
482
},

483
484
485
486
487
"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
488
  "reg_req"   => { "in" => [ "gp", "gp", "eax ebx ecx edx", "none" ] },
Michael Beck's avatar
Michael Beck committed
489
490
  "emit"      => '. mov %ia32_emit_binop /* Store(%A3) -> (%A1) */',
  "outs"      => [ "M" ],
491
492
},

Christian Würdig's avatar
Christian Würdig committed
493
"Lea" => {
494
495
  "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
496
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
497
  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] },
498
  "emit"      => '. lea %D1, %ia32_emit_am /* LEA(%A1, %A2) */'
Christian Würdig's avatar
Christian Würdig committed
499
500
},

501
502
"Push" => {
  "comment"   => "push a gp register on the stack",
Michael Beck's avatar
Michael Beck committed
503
504
505
  "reg_req"   => { "in" => [ "esp", "gp", "none" ], "out" => [ "esp" ] },
  "emit"      => '. push %S2 /* Push(%A2) */',
  "outs"      => [ "stack", "M" ],
506
507
508
509
510
},

"Pop" => {
  "comment"   => "pop a gp register from the stack",
  "reg_req"   => { "in" => [ "esp", "none" ], "out" => [ "gp", "esp" ] },
Michael Beck's avatar
Michael Beck committed
511
512
  "emit"      => '. pop %D1 /* Pop -> %D1 */',
  "outs"      => [ "res", "stack", "M" ],
513
514
515
516
517
},

"Enter" => {
  "comment"   => "create stack frame",
  "reg_req"   => { "in" => [ "esp" ], "out" => [ "ebp", "esp" ] },
Michael Beck's avatar
Michael Beck committed
518
519
  "emit"      => '. enter /* Enter */',
  "outs"      => [ "frame", "stack", "M" ],
520
521
522
523
},

"Leave" => {
  "comment"   => "destroy stack frame",
524
  "reg_req"   => { "in" => [ "esp", "ebp" ], "out" => [ "ebp", "esp" ] },
Michael Beck's avatar
Michael Beck committed
525
526
  "emit"      => '. leave /* Leave */',
  "outs"      => [ "frame", "stack", "M" ],
527
528
},

Michael Beck's avatar
Michael Beck committed
529
530
531
532
533
534
535
536
#-----------------------------------------------------------------------------#
#   _____ _____ ______    __ _             _                     _            #
#  / ____/ ____|  ____|  / _| |           | |                   | |           #
# | (___| (___ | |__    | |_| | ___   __ _| |_   _ __   ___   __| | ___  ___  #
#  \___ \\___ \|  __|   |  _| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| #
#  ____) |___) | |____  | | | | (_) | (_| | |_  | | | | (_) | (_| |  __/\__ \ #
# |_____/_____/|______| |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ #
#-----------------------------------------------------------------------------#
Christian Würdig's avatar
Christian Würdig committed
537
538
539

# commutative operations

Christian Würdig's avatar
Christian Würdig committed
540
"xAdd" => {
541
542
  "irn_flags" => "R",
  "comment"   => "construct SSE Add: Add(a, b) = Add(b, a) = a + b",
Christian Würdig's avatar
Christian Würdig committed
543
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
544
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
545
546
  "emit"      => '. adds%M %ia32_emit_binop /* SSE Add(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
547
548
},

Christian Würdig's avatar
Christian Würdig committed
549
"xMul" => {
550
551
  "irn_flags" => "R",
  "comment"   => "construct SSE Mul: Mul(a, b) = Mul(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"      => '. muls%M %ia32_emit_binop /* SSE Mul(%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
"xMax" => {
559
560
  "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
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"      => '. maxs%M %ia32_emit_binop /* SSE Max(%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
"xMin" => {
568
569
  "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
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"      => '. mins%M %ia32_emit_binop /* SSE Min(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
574
575
},

Christian Würdig's avatar
Christian Würdig committed
576
"xAnd" => {
577
578
  "irn_flags" => "R",
  "comment"   => "construct SSE And: And(a, b) = a AND 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"      => '. andp%M %ia32_emit_binop /* SSE And(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
583
584
},

Christian Würdig's avatar
Christian Würdig committed
585
"xOr" => {
586
587
  "irn_flags" => "R",
  "comment"   => "construct SSE Or: Or(a, b) = a OR 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"      => '. orp%M %ia32_emit_binop /* SSE Or(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
592
593
},

Christian Würdig's avatar
Christian Würdig committed
594
"xEor" => {
595
596
  "irn_flags" => "R",
  "comment"   => "construct SSE Eor: Eor(a, b) = a XOR 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"      => '. xorp%M %ia32_emit_binop /* SSE Xor(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
601
602
603
604
},

# not commutative operations

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

Christian Würdig's avatar
Christian Würdig committed
614
"xDiv" => {
615
616
  "irn_flags" => "R",
  "comment"   => "construct SSE Div: Div(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 !in_r4" ] },
Michael Beck's avatar
Michael Beck committed
619
620
  "emit"      => '. divs%M %ia32_emit_binop /* SSE Div(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
621
622
623
624
},

# other operations

Christian Würdig's avatar
Christian Würdig committed
625
"xCondJmp" => {
626
  "op_flags"  => "L|X|Y",
627
  "comment"   => "construct conditional jump: UCOMIS A, B && JMPxx LABEL",
Christian Würdig's avatar
Christian Würdig committed
628
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
629
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "none", "none" ] },
Michael Beck's avatar
Michael Beck committed
630
  "outs"      => [ "false", "true" ],
Christian Würdig's avatar
Christian Würdig committed
631
},
Christian Würdig's avatar
Christian Würdig committed
632

Christian Würdig's avatar
Christian Würdig committed
633
"xConst" => {
634
635
636
  "op_flags"  => "c",
  "irn_flags" => "R",
  "comment"   => "represents a SSE constant",
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" => [ "none" ], "out" => [ "xmm" ] },
639
  "emit"      => '. mov%M %D1, %C /* Load fConst into register */',
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
# Load / Store
Christian Würdig's avatar
Christian Würdig committed
643

Christian Würdig's avatar
Christian Würdig committed
644
"xLoad" => {
645
646
647
648
  "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
649
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
650
  "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "xmm" ] },
Michael Beck's avatar
Michael Beck committed
651
652
  "emit"      => '. movs%M %D1, %ia32_emit_am /* Load((%A1)) -> %D1 */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
653
},
Christian Würdig's avatar
Christian Würdig committed
654

Christian Würdig's avatar
Christian Würdig committed
655
"xStore" => {
Christian Würdig's avatar
Christian Würdig committed
656
657
658
  "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
659
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
660
  "reg_req"  => { "in" => [ "gp", "gp", "xmm", "none" ] },
Michael Beck's avatar
Michael Beck committed
661
662
  "emit"     => '. movs%M %ia32_emit_binop /* Store(%S3) -> (%A1) */',
  "outs"      => [ "M" ],
Christian Würdig's avatar
Christian Würdig committed
663
664
},

665
666
667
# CopyB

"CopyB" => {
Christian Würdig's avatar
Christian Würdig committed
668
669
670
671
  "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
672
673
},

674
"CopyB_i" => {
Christian Würdig's avatar
Christian Würdig committed
675
676
677
678
679
  "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
680
681
},

Christian Würdig's avatar
Christian Würdig committed
682
683
# Conversions

Christian Würdig's avatar
Christian Würdig committed
684
"Conv_I2I" => {
Christian Würdig's avatar
Christian Würdig committed
685
  "reg_req"  => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3", "none" ] },
686
  "cmp_attr"  => "  return ia32_compare_conv_attr(attr_a, attr_b);\n",
Michael Beck's avatar
Michael Beck committed
687
688
  "comment"  => "construct Conv Int -> Int",
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
689
690
691
692
},

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

Christian Würdig's avatar
Christian Würdig committed
698
"Conv_I2FP" => {
699
  "reg_req"  => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "xmm", "none" ] },
700
  "cmp_attr"  => "  return ia32_compare_conv_attr(attr_a, attr_b);\n",
Michael Beck's avatar
Michael Beck committed
701
702
  "comment"  => "construct Conv Int -> Floating Point",
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
703
704
705
},

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

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

Michael Beck's avatar
Michael Beck committed
719
720
721
722
723
724
725
726
727
728
729
730
731
#----------------------------------------------------------#
#        _      _               _    __ _             _    #
#       (_)    | |             | |  / _| |           | |   #
# __   ___ _ __| |_ _   _  __ _| | | |_| | ___   __ _| |_  #
# \ \ / / | '__| __| | | |/ _` | | |  _| |/ _ \ / _` | __| #
#  \ V /| | |  | |_| |_| | (_| | | | | | | (_) | (_| | |_  #
#   \_/ |_|_|   \__|\__,_|\__,_|_| |_| |_|\___/ \__,_|\__| #
#                 | |                                      #
#  _ __   ___   __| | ___  ___                             #
# | '_ \ / _ \ / _` |/ _ \/ __|                            #
# | | | | (_) | (_| |  __/\__ \                            #
# |_| |_|\___/ \__,_|\___||___/                            #
#----------------------------------------------------------#
732
733
734
735
736
737

"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
738
  "outs"      => [ "res", "M" ],
739
740
741
742
743
744
745
},

"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
746
  "outs"      => [ "res", "M" ],
747
748
749
750
751
752
753
},

"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
754
  "outs"      => [ "res", "M" ],
755
756
757
758
759
760
},

"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
761
  "outs"      => [ "res", "M" ],
762
763
764
765
766
767
768
769
770
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
},

"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
802
803
  "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "vfp", "none" ] },
  "outs"      => [ "res", "M" ],
804
805
806
807
808
809
810
811
},

"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
812
  "outs"      => [ "M" ],
813
814
},

815
816
817
818
819
820
# 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
821
822
  "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "vfp", "none" ] },
  "outs"      => [ "res", "M" ],
823
824
825
826
827
828
},

"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
829
  "outs"      => [ "M" ],
830
831
},

832
833
834
835
836
837
838
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
# 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",
881
  "reg_req"   => { "in" => [ "none" ], "out" => [ "vfp" ] },
882
883
},

Michael Beck's avatar
Michael Beck committed
884
885
886
887
888
889
890
891
892
893
# 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
894
895
896
897
898
899
900
#------------------------------------------------------------------------#
#       ___ _____    __ _             _                     _            #
# __  _( _ )___  |  / _| | ___   __ _| |_   _ __   ___   __| | ___  ___  #
# \ \/ / _ \  / /  | |_| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| #
#  >  < (_) |/ /   |  _| | (_) | (_| | |_  | | | | (_) | (_| |  __/\__ \ #
# /_/\_\___//_/    |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ #
#------------------------------------------------------------------------#
901
902

"fadd" => {
903
  "op_flags"  => "R",
904
  "rd_constructor" => "NONE",
905
906
  "comment"   => "x87 Add: Add(a, b) = Add(b, a) = a + b",
  "reg_req"   => { },
Michael Beck's avatar
Michael Beck committed
907
  "emit"      => '. fadd %ia32_emit_x87_binop /* x87 fadd(%A1, %A2) -> %D1 */',
908
909
910
},

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

"fmul" => {
919
  "op_flags"  => "R",
920
  "rd_constructor" => "NONE",