ia32_spec.pl 51.7 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
            { "name" => "eax", "type" => 1 },
            { "name" => "edx", "type" => 1 },
            { "name" => "ebx", "type" => 2 },
            { "name" => "ecx", "type" => 1 },
            { "name" => "esi", "type" => 2 },
            { "name" => "edi", "type" => 2 },
Christian Würdig's avatar
Christian Würdig committed
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#            { "name" => "r11", "type" => 1 },
#            { "name" => "r12", "type" => 1 },
#            { "name" => "r13", "type" => 1 },
#            { "name" => "r14", "type" => 1 },
#            { "name" => "r15", "type" => 1 },
#            { "name" => "r16", "type" => 1 },
#            { "name" => "r17", "type" => 1 },
#            { "name" => "r18", "type" => 1 },
#            { "name" => "r19", "type" => 1 },
#            { "name" => "r20", "type" => 1 },
#            { "name" => "r21", "type" => 1 },
#            { "name" => "r22", "type" => 1 },
#            { "name" => "r23", "type" => 1 },
#            { "name" => "r24", "type" => 1 },
#            { "name" => "r25", "type" => 1 },
#            { "name" => "r26", "type" => 1 },
#            { "name" => "r27", "type" => 1 },
#            { "name" => "r28", "type" => 1 },
#            { "name" => "r29", "type" => 1 },
#            { "name" => "r30", "type" => 1 },
#            { "name" => "r31", "type" => 1 },
#            { "name" => "r32", "type" => 1 },
129
            { "name" => "ebp", "type" => 2 },
Christian Würdig's avatar
Christian Würdig committed
130
            { "name" => "esp", "type" => 4 },
131
132
            { "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
133
			{ "mode" => "mode_P" }
134
          ],
135
  "xmm" => [
136
137
138
139
140
141
142
143
            { "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 },
144
145
            { "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
146
			{ "mode" => "mode_D" }
147
148
149
150
151
152
153
154
155
          ],
  "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 },
156
            { "name" => "vf7", "type" => 1 },
157
158
            { "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
159
160
161
162
163
164
165
166
167
168
169
170
			{ "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" }
171
          ]
172
173
); # %reg_classes

174
175
176
177
178
179
180
181
182
183
184
#--------------------------------------------------#
#                        _                         #
#                       (_)                        #
#  _ __   _____      __  _ _ __    ___  _ __  ___  #
# | '_ \ / _ \ \ /\ / / | | '__|  / _ \| '_ \/ __| #
# | | | |  __/\ V  V /  | | |    | (_) | |_) \__ \ #
# |_| |_|\___| \_/\_/   |_|_|     \___/| .__/|___/ #
#                                      | |         #
#                                      |_|         #
#--------------------------------------------------#

Michael Beck's avatar
Michael Beck committed
185
186
187
%operands = (
);

188
189
%nodes = (

Christian Würdig's avatar
Christian Würdig committed
190
191
192
193
194
195
196
197
198
199
#-----------------------------------------------------------------#
#  _       _                                         _            #
# (_)     | |                                       | |           #
#  _ _ __ | |_ ___  __ _  ___ _ __   _ __   ___   __| | ___  ___  #
# | | '_ \| __/ _ \/ _` |/ _ \ '__| | '_ \ / _ \ / _` |/ _ \/ __| #
# | | | | | ||  __/ (_| |  __/ |    | | | | (_) | (_| |  __/\__ \ #
# |_|_| |_|\__\___|\__, |\___|_|    |_| |_|\___/ \__,_|\___||___/ #
#                   __/ |                                         #
#                  |___/                                          #
#-----------------------------------------------------------------#
Christian Würdig's avatar
Christian Würdig committed
200

201
202
# commutative operations

203
204
205
206
207
208
209
# 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
210

211
212
213
"Add" => {
  "irn_flags" => "R",
  "comment"   => "construct Add: Add(a, b) = Add(b, a) = a + b",
Christian Würdig's avatar
Christian Würdig committed
214
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
215
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
216
  "emit"      => '. add %ia32_emit_binop /* Add(%A3, %A4) -> %D1 */',
Michael Beck's avatar
Michael Beck committed
217
  "outs"      => [ "res", "M" ],
218
219
},

220
221
222
223
224
225
226
227
228
229
230
"AddC" => {
  "comment"   => "construct Add with Carry: AddC(a, b) = Add(b, a) = a + b + carry",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
  "emit"      => '. adc %ia32_emit_binop /* AddC(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
},

"l_Add" => {
  "op_flags"  => "C",
  "irn_flags" => "R",
231
  "cmp_attr"  => "  return 1;\n",
232
233
234
235
236
237
  "comment"   => "construct lowered Add: Add(a, b) = Add(b, a) = a + b",
  "arity"     => 2,
},

"l_AddC" => {
  "op_flags"  => "C",
238
  "cmp_attr"  => "  return 1;\n",
239
240
241
242
  "comment"   => "construct lowered Add with Carry: AddC(a, b) = Add(b, a) = a + b + carry",
  "arity"     => 2,
},

243
244
245
"MulS" => {
  "comment"   => "construct MulS: MulS(a, b) = MulS(b, a) = a * b",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
Christian Würdig's avatar
Christian Würdig committed
246
  "reg_req"   => { "in" => [ "gp", "gp", "eax", "gp", "none" ], "out" => [ "eax", "edx" ] },
247
  "emit"      => '. mul %ia32_emit_unop /* Mul(%A1, %A2) -> %D1 */',
248
249
250
251
252
  "outs"      => [ "EAX", "EDX", "M" ],
},

"l_MulS" => {
  "op_flags"  => "C",
253
  "cmp_attr"  => "  return 1;\n",
254
255
256
257
258
  "comment"   => "construct lowered MulS: MulS(a, b) = MulS(b, a) = a * b",
  "outs"      => [ "EAX", "EDX", "M" ],
  "arity"     => 2
},

259
"Mul" => {
Michael Beck's avatar
Michael Beck committed
260
  "irn_flags" => "R",
261
  "comment"   => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
Christian Würdig's avatar
Christian Würdig committed
262
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
263
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
264
265
  "emit"      => '. imul %ia32_emit_binop /* Mul(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
266
267
},

268
269
"l_Mul" => {
  "op_flags"  => "C",
270
  "cmp_attr"  => "  return 1;\n",
271
272
273
274
  "comment"   => "construct lowered Mul: Mul(a, b) = Mul(b, a) = a * b",
  "arity"     => 2
},

275
276
277
# 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
278
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
Christian Würdig's avatar
Christian Würdig committed
279
  "reg_req"   => { "in" => [ "gp", "gp", "eax", "gp", "none" ], "out" => [ "eax", "edx" ] },
280
  "emit"      => '. imul %ia32_emit_unop /* Mulh(%A1, %A2) -> %D1 */',
Michael Beck's avatar
Michael Beck committed
281
  "outs"      => [ "EAX", "EDX", "M" ],
282
283
},

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

"Or" => {
294
295
  "irn_flags" => "R",
  "comment"   => "construct Or: Or(a, b) = Or(b, a) = a OR b",
Christian Würdig's avatar
Christian Würdig committed
296
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
297
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
298
299
  "emit"      => '. or %ia32_emit_binop /* Or(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
300
301
302
},

"Eor" => {
303
304
  "irn_flags" => "R",
  "comment"   => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b",
Christian Würdig's avatar
Christian Würdig committed
305
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
306
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
307
308
  "emit"      => '. xor %ia32_emit_binop /* Xor(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
309
310
},

311
312
"l_Eor" => {
  "op_flags"  => "C",
313
  "cmp_attr"  => "  return 1;\n",
314
315
316
317
  "comment"   => "construct lowered Eor: Eor(a, b) = Eor(b, a) = a EOR b",
  "arity"     => 2
},

318
"Max" => {
319
320
321
322
  "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"      =>
323
'2. cmp %S1, %S2 /* prepare Max (%S1 - %S2), (%A1, %A2) */
324
  if (mode_is_signed(get_irn_mode(n))) {
325
4.  cmovl %D1, %S2 /* %S1 is less %S2 */
326
327
  }
  else {
328
4.  cmovb %D1, %S2 /* %S1 is below %S2 */
329
330
  }
'
331
332
333
},

"Min" => {
334
335
336
337
  "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"      =>
338
'2. cmp %S1, %S2 /* prepare Min (%S1 - %S2), (%A1, %A2) */
339
  if (mode_is_signed(get_irn_mode(n))) {
340
2.  cmovg %D1, %S2 /* %S1 is greater %S2 */
341
342
  }
  else {
343
2.  cmova %D1, %S2, %D1 /* %S1 is above %S2 */
344
345
  }
'
346
347
348
349
350
},

# not commutative operations

"Sub" => {
351
352
  "irn_flags" => "R",
  "comment"   => "construct Sub: Sub(a, b) = a - 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", "gp", "none" ], "out" => [ "in_r3" ] },
355
  "emit"      => '. sub %ia32_emit_binop /* Sub(%A3, %A4) -> %D1 */',
Michael Beck's avatar
Michael Beck committed
356
  "outs"      => [ "res", "M" ],
357
358
},

359
360
361
362
363
364
365
366
367
368
"SubC" => {
  "comment"   => "construct Sub with Carry: SubC(a, b) = a - b - carry",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
  "emit"      => '. sbb %ia32_emit_binop /* SubC(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
},

"l_Sub" => {
  "irn_flags" => "R",
369
  "cmp_attr"  => "  return 1;\n",
370
371
372
373
374
  "comment"   => "construct lowered Sub: Sub(a, b) = a - b",
  "arity"     => 2,
},

"l_SubC" => {
375
  "cmp_attr"  => "  return 1;\n",
376
377
378
379
  "comment"   => "construct lowered Sub with Carry: SubC(a, b) = a - b - carry",
  "arity"     => 2,
},

380
"DivMod" => {
Christian Würdig's avatar
Christian Würdig committed
381
382
  "op_flags"  => "F|L",
  "state"     => "exc_pinned",
Christian Würdig's avatar
Christian Würdig committed
383
  "reg_req"   => { "in" => [ "eax", "gp", "edx", "none" ], "out" => [ "eax", "edx" ] },
Christian Würdig's avatar
Christian Würdig committed
384
385
386
387
  "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"      =>
388
'  if (mode_is_signed(get_ia32_res_mode(n))) {
389
4.  idiv %S2 /* signed DivMod(%S1, %S2) -> %D1, (%A1, %A2, %A3) */
390
391
  }
  else {
392
4.  div %S2 /* unsigned DivMod(%S1, %S2) -> %D1, (%A1, %A2, %A3) */
393
  }
Michael Beck's avatar
Michael Beck committed
394
395
',
  "outs"      => [ "div_res", "mod_res", "M" ],
396
397
398
},

"Shl" => {
399
400
  "irn_flags" => "R",
  "comment"   => "construct Shl: Shl(a, b) = a << b",
Christian Würdig's avatar
Christian Würdig committed
401
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
402
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
Michael Beck's avatar
Michael Beck committed
403
404
  "emit"      => '. shl %ia32_emit_binop /* Shl(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
405
406
},

407
"l_Shl" => {
408
  "cmp_attr"  => "  return 1;\n",
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
  "comment"   => "construct lowered Shl: Shl(a, b) = a << b",
  "arity"     => 2
},

"ShlD" => {
  "irn_flags" => "R",
  "comment"   => "construct ShlD: ShlD(a, b, c) = a, b << count (shift left count bits from b into a)",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r5" ] },
  "emit"      =>
'
if (get_ia32_immop_type(n) == ia32_ImmNone) {
  if (get_ia32_op_type(n) == ia32_AddrModeD) {
4. shld %ia32_emit_am, %S4, %%cl /* ShlD(%A3, %A4, %A5) -> %D1 */
  }
  else {
4. shld %S3, %S4, %%cl /* ShlD(%A3, %A4, %A5) -> %D1 */
  }
}
else {
  if (get_ia32_op_type(n) == ia32_AddrModeD) {
4. shld %ia32_emit_am, %S4, %C /* ShlD(%A3, %A4, %A5) -> %D1 */
  }
  else {
4. shld %S3, %S4, %C /* ShlD(%A3, %A4, %A5) -> %D1 */
  }
}
',
  "outs"      => [ "res", "M" ],
},

"l_ShlD" => {
441
  "cmp_attr"  => "  return 1;\n",
442
443
444
445
  "comment"   => "construct lowered ShlD: ShlD(a, b, c) = a, b << count (shift left count bits from b into a)",
  "arity"     => 3
},

446
"Shr" => {
447
448
  "irn_flags" => "R",
  "comment"   => "construct Shr: Shr(a, b) = a >> b",
Christian Würdig's avatar
Christian Würdig committed
449
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
450
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
Michael Beck's avatar
Michael Beck committed
451
452
  "emit"      => '. shr %ia32_emit_binop /* Shr(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
453
454
},

455
"l_Shr" => {
456
  "cmp_attr"  => "  return 1;\n",
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
  "comment"   => "construct lowered Shr: Shr(a, b) = a << b",
  "arity"     => 2
},

"ShrD" => {
  "irn_flags" => "R",
  "comment"   => "construct ShrD: ShrD(a, b, c) = a, b >> count (shift rigth count bits from a into b)",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r5" ] },
  "emit"      =>
'
if (get_ia32_immop_type(n) == ia32_ImmNone) {
  if (get_ia32_op_type(n) == ia32_AddrModeD) {
4. shrd %ia32_emit_am, %S4, %%cl /* ShrD(%A3, %A4, %A5) -> %D1 */
  }
  else {
4. shrd %S3, %S4, %%cl /* ShrD(%A3, %A4, %A5) -> %D1 */
  }
}
else {
  if (get_ia32_op_type(n) == ia32_AddrModeD) {
4. shrd %ia32_emit_am, %S4, %C /* ShrD(%A3, %A4, %A5) -> %D1 */
  }
  else {
4. shrd %S3, %S4, %C /* ShrD(%A3, %A4, %A5) -> %D1 */
  }
}
',
  "outs"      => [ "res", "M" ],
},

"l_ShrD" => {
489
  "cmp_attr"  => "  return 1;\n",
490
491
492
493
  "comment"   => "construct lowered ShrD: ShrD(a, b, c) = a, b >> count (shift rigth count bits from a into b)",
  "arity"     => 3
},

494
"Shrs" => {
495
496
  "irn_flags" => "R",
  "comment"   => "construct Shrs: Shrs(a, b) = a >> b",
Christian Würdig's avatar
Christian Würdig committed
497
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
498
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
Michael Beck's avatar
Michael Beck committed
499
500
  "emit"      => '. sar %ia32_emit_binop /* Shrs(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
501
502
},

503
"l_Shrs" => {
504
  "cmp_attr"  => "  return 1;\n",
505
506
507
508
  "comment"   => "construct lowered Shrs: Shrs(a, b) = a << b",
  "arity"     => 2
},

509
"RotR" => {
510
  "irn_flags" => "R",
511
  "comment"     => "construct RotR: RotR(a, b) = a ROTR b",
Christian Würdig's avatar
Christian Würdig committed
512
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
513
  "reg_req"     => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
Michael Beck's avatar
Michael Beck committed
514
515
  "emit"        => '. ror %ia32_emit_binop /* RotR(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
516
517
},

518
"RotL" => {
519
520
  "irn_flags" => "R",
  "comment"   => "construct RotL: RotL(a, b) = a ROTL b",
Christian Würdig's avatar
Christian Würdig committed
521
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
522
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
Michael Beck's avatar
Michael Beck committed
523
524
  "emit"      => '. rol %ia32_emit_binop /* RotL(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
525
526
},

527
# unary operations
Christian Würdig's avatar
Christian Würdig committed
528

Christian Würdig's avatar
Christian Würdig committed
529
"Minus" => {
530
531
  "irn_flags" => "R",
  "comment"   => "construct Minus: Minus(a) = -a",
Christian Würdig's avatar
Christian Würdig committed
532
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
533
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
534
535
  "emit"      => '. neg %ia32_emit_unop /* Neg(%A1) -> %D1, (%A1) */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
536
537
},

538
"l_Minus" => {
539
  "cmp_attr"  => "  return 1;\n",
540
541
542
543
  "comment"   => "construct lowered Minus: Minus(a) = -a",
  "arity"     => 1,
},

Christian Würdig's avatar
Christian Würdig committed
544
"Inc" => {
545
546
  "irn_flags" => "R",
  "comment"   => "construct Increment: Inc(a) = a++",
Christian Würdig's avatar
Christian Würdig committed
547
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
548
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
549
550
  "emit"      => '. inc %ia32_emit_unop /* Inc(%S1) -> %D1, (%A1) */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
551
552
553
},

"Dec" => {
554
555
  "irn_flags" => "R",
  "comment"   => "construct Decrement: Dec(a) = a--",
Christian Würdig's avatar
Christian Würdig committed
556
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
557
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
558
559
  "emit"      => '. dec %ia32_emit_unop /* Dec(%S1) -> %D1, (%A1) */',
  "outs"      => [ "res", "M" ],
560
561
562
},

"Not" => {
563
564
  "irn_flags" => "R",
  "comment"   => "construct Not: Not(a) = !a",
Christian Würdig's avatar
Christian Würdig committed
565
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
566
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
567
568
  "emit"      => '. not %ia32_emit_unop /* Not(%S1) -> %D1, (%A1) */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
569
570
},

Christian Würdig's avatar
Christian Würdig committed
571
572
# other operations

Christian Würdig's avatar
Christian Würdig committed
573
"CondJmp" => {
574
  "op_flags"  => "L|X|Y",
575
  "comment"   => "construct conditional jump: CMP A, B && JMPxx LABEL",
Christian Würdig's avatar
Christian Würdig committed
576
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
577
  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ] },
Michael Beck's avatar
Michael Beck committed
578
  "outs"      => [ "false", "true" ],
Christian Würdig's avatar
Christian Würdig committed
579
580
},

581
582
583
"TestJmp" => {
  "op_flags"  => "L|X|Y",
  "comment"   => "construct conditional jump: TEST A, B && JMPxx LABEL",
584
585
  "reg_req"  => { "in" => [ "gp", "gp" ] },
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
Michael Beck's avatar
Michael Beck committed
586
  "outs"      => [ "false", "true" ],
587
588
589
590
591
592
593
},

"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
594
  "outs"      => [ "false", "true" ],
595
596
597
598
599
},

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

Christian Würdig's avatar
Christian Würdig committed
604
"SwitchJmp" => {
605
606
  "op_flags"  => "L|X|Y",
  "comment"   => "construct switch",
Christian Würdig's avatar
Christian Würdig committed
607
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
Christian Würdig's avatar
Christian Würdig committed
608
  "reg_req"   => { "in" => [ "gp" ], "out" => [ "none" ] },
609
610
611
},

"Const" => {
612
613
614
  "op_flags"  => "c",
  "irn_flags" => "R",
  "comment"   => "represents an integer constant",
Christian Würdig's avatar
Christian Würdig committed
615
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
616
  "reg_req"   => { "in" => [ "none" ], "out" => [ "gp" ] },
617
618
},

619
620
621
622
"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
623
624
  "emit"      => '. cdq /* sign extend EAX -> EDX:EAX, (%A1) */',
  "outs"      => [ "EAX", "EDX" ],
625
626
},

Christian Würdig's avatar
Christian Würdig committed
627
628
629
# Load / Store

"Load" => {
630
631
632
633
  "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
634
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
635
  "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "gp" ] },
Christian Würdig's avatar
Christian Würdig committed
636
637
  "emit"      =>
'  if (get_mode_size_bits(get_ia32_ls_mode(n)) < 32) {
638
4.   mov%Mx %D1, %ia32_emit_am /* Load((%A1)) -> %D1 */
Christian Würdig's avatar
Christian Würdig committed
639
640
  }
  else {
641
4.   mov %D1, %ia32_emit_am /* Load((%A1)) -> %D1 */
Christian Würdig's avatar
Christian Würdig committed
642
  }
Michael Beck's avatar
Michael Beck committed
643
644
',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
645
646
},

647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
"l_Load" => {
  "op_flags"  => "L|F",
  "cmp_attr"  => "  return 1;\n",
  "comment"   => "construct lowered Load: Load(ptr, mem) = LD ptr -> reg",
  "outs"      => [ "res", "M" ],
  "arity"     => 2,
},

"l_Store" => {
  "op_flags"  => "L|F",
  "cmp_attr"  => "  return 1;\n",
  "state"     => "exc_pinned",
  "comment"   => "construct lowered Store: Store(ptr, val, mem) = ST ptr,val",
  "arity"     => 3,
  "outs"      => [ "M" ],
},

Christian Würdig's avatar
Christian Würdig committed
664
"Store" => {
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", "gp", "none" ] },
Michael Beck's avatar
Michael Beck committed
670
671
  "emit"      => '. mov %ia32_emit_binop /* Store(%A3) -> (%A1) */',
  "outs"      => [ "M" ],
Christian Würdig's avatar
Christian Würdig committed
672
673
},

674
675
676
677
678
"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
679
  "reg_req"   => { "in" => [ "gp", "gp", "eax ebx ecx edx", "none" ] },
Michael Beck's avatar
Michael Beck committed
680
681
  "emit"      => '. mov %ia32_emit_binop /* Store(%A3) -> (%A1) */',
  "outs"      => [ "M" ],
682
683
},

Christian Würdig's avatar
Christian Würdig committed
684
"Lea" => {
685
686
  "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
687
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
688
  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] },
689
  "emit"      => '. lea %D1, %ia32_emit_am /* LEA(%A1, %A2) */'
Christian Würdig's avatar
Christian Würdig committed
690
691
},

692
693
"Push" => {
  "comment"   => "push a gp register on the stack",
Michael Beck's avatar
Michael Beck committed
694
  "reg_req"   => { "in" => [ "esp", "gp", "none" ], "out" => [ "esp" ] },
695
696
697
698
699
700
701
702
703
704
705
706
  "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
707
  "outs"      => [ "stack", "M" ],
708
709
710
711
712
},

"Pop" => {
  "comment"   => "pop a gp register from the stack",
  "reg_req"   => { "in" => [ "esp", "none" ], "out" => [ "gp", "esp" ] },
Michael Beck's avatar
Michael Beck committed
713
714
  "emit"      => '. pop %D1 /* Pop -> %D1 */',
  "outs"      => [ "res", "stack", "M" ],
715
716
717
718
719
},

"Enter" => {
  "comment"   => "create stack frame",
  "reg_req"   => { "in" => [ "esp" ], "out" => [ "ebp", "esp" ] },
Michael Beck's avatar
Michael Beck committed
720
721
  "emit"      => '. enter /* Enter */',
  "outs"      => [ "frame", "stack", "M" ],
722
723
724
725
},

"Leave" => {
  "comment"   => "destroy stack frame",
726
  "reg_req"   => { "in" => [ "esp", "ebp" ], "out" => [ "ebp", "esp" ] },
Michael Beck's avatar
Michael Beck committed
727
728
  "emit"      => '. leave /* Leave */',
  "outs"      => [ "frame", "stack", "M" ],
729
730
},

Michael Beck's avatar
Michael Beck committed
731
732
733
734
735
736
737
738
#-----------------------------------------------------------------------------#
#   _____ _____ ______    __ _             _                     _            #
#  / ____/ ____|  ____|  / _| |           | |                   | |           #
# | (___| (___ | |__    | |_| | ___   __ _| |_   _ __   ___   __| | ___  ___  #
#  \___ \\___ \|  __|   |  _| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| #
#  ____) |___) | |____  | | | | (_) | (_| | |_  | | | | (_) | (_| |  __/\__ \ #
# |_____/_____/|______| |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ #
#-----------------------------------------------------------------------------#
Christian Würdig's avatar
Christian Würdig committed
739
740
741

# commutative operations

Christian Würdig's avatar
Christian Würdig committed
742
"xAdd" => {
743
744
  "irn_flags" => "R",
  "comment"   => "construct SSE Add: Add(a, b) = Add(b, a) = a + b",
Christian Würdig's avatar
Christian Würdig committed
745
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
746
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
747
748
  "emit"      => '. adds%M %ia32_emit_binop /* SSE Add(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
749
750
},

Christian Würdig's avatar
Christian Würdig committed
751
"xMul" => {
752
753
  "irn_flags" => "R",
  "comment"   => "construct SSE Mul: Mul(a, b) = Mul(b, a) = a * b",
Christian Würdig's avatar
Christian Würdig committed
754
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
755
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
756
757
  "emit"      => '. muls%M %ia32_emit_binop /* SSE Mul(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
758
759
},

Christian Würdig's avatar
Christian Würdig committed
760
"xMax" => {
761
762
  "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
763
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
764
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
765
766
  "emit"      => '. maxs%M %ia32_emit_binop /* SSE Max(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
767
768
},

Christian Würdig's avatar
Christian Würdig committed
769
"xMin" => {
770
771
  "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
772
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
773
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
774
775
  "emit"      => '. mins%M %ia32_emit_binop /* SSE Min(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
776
777
},

Christian Würdig's avatar
Christian Würdig committed
778
"xAnd" => {
779
780
  "irn_flags" => "R",
  "comment"   => "construct SSE And: And(a, b) = a AND b",
Christian Würdig's avatar
Christian Würdig committed
781
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
782
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
783
784
  "emit"      => '. andp%M %ia32_emit_binop /* SSE And(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
785
786
},

Christian Würdig's avatar
Christian Würdig committed
787
"xOr" => {
788
789
  "irn_flags" => "R",
  "comment"   => "construct SSE Or: Or(a, b) = a OR b",
Christian Würdig's avatar
Christian Würdig committed
790
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
791
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
792
793
  "emit"      => '. orp%M %ia32_emit_binop /* SSE Or(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
794
795
},

Christian Würdig's avatar
Christian Würdig committed
796
"xEor" => {
797
798
  "irn_flags" => "R",
  "comment"   => "construct SSE Eor: Eor(a, b) = a XOR b",
Christian Würdig's avatar
Christian Würdig committed
799
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
800
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
801
802
  "emit"      => '. xorp%M %ia32_emit_binop /* SSE Xor(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
803
804
805
806
},

# not commutative operations

807
808
809
810
811
812
813
814
815
"xAndNot" => {
  "irn_flags" => "R",
  "comment"   => "construct SSE AndNot: AndNot(a, b) = a AND NOT b",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3 !in_r4" ] },
  "emit"      => '. andnp%M %ia32_emit_binop /* SSE AndNot(%A3, %A4) -> %D1 */',
  "outs"      => [ "res", "M" ],
},

Christian Würdig's avatar
Christian Würdig committed
816
"xSub" => {
817
818
  "irn_flags" => "R",
  "comment"   => "construct SSE Sub: Sub(a, b) = a - b",
Christian Würdig's avatar
Christian Würdig committed
819
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
820
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
Michael Beck's avatar
Michael Beck committed
821
822
  "emit"      => '. subs%M %ia32_emit_binop /* SSE Sub(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
823
824
},

Christian Würdig's avatar
Christian Würdig committed
825
"xDiv" => {
826
827
  "irn_flags" => "R",
  "comment"   => "construct SSE Div: Div(a, b) = a / b",
Christian Würdig's avatar
Christian Würdig committed
828
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
829
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3 !in_r4" ] },
Michael Beck's avatar
Michael Beck committed
830
831
  "emit"      => '. divs%M %ia32_emit_binop /* SSE Div(%A1, %A2) -> %D1 */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
832
833
834
835
},

# other operations

836
837
838
839
840
841
842
"xCmp" => {
  "irn_flags" => "R",
  "comment"   => "construct SSE Compare: Cmp(a, b) == a = a cmp b",
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3 !in_r4" ] },
  "outs"      => [ "res", "M" ],
},

Christian Würdig's avatar
Christian Würdig committed
843
"xCondJmp" => {
844
  "op_flags"  => "L|X|Y",
845
  "comment"   => "construct conditional jump: UCOMIS A, B && JMPxx LABEL",
Christian Würdig's avatar
Christian Würdig committed
846
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
847
  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "none", "none" ] },
Michael Beck's avatar
Michael Beck committed
848
  "outs"      => [ "false", "true" ],
Christian Würdig's avatar
Christian Würdig committed
849
},
Christian Würdig's avatar
Christian Würdig committed
850

Christian Würdig's avatar
Christian Würdig committed
851
"xConst" => {
852
853
854
  "op_flags"  => "c",
  "irn_flags" => "R",
  "comment"   => "represents a SSE constant",
Christian Würdig's avatar
Christian Würdig committed
855
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
856
  "reg_req"   => { "in" => [ "none" ], "out" => [ "xmm" ] },
Michael Beck's avatar
Michael Beck committed
857
  "emit"      => '. movs%M %D1, %C /* Load fConst into register */',
Christian Würdig's avatar
Christian Würdig committed
858
},
Christian Würdig's avatar
Christian Würdig committed
859

Christian Würdig's avatar
Christian Würdig committed
860
# Load / Store
Christian Würdig's avatar
Christian Würdig committed
861

Christian Würdig's avatar
Christian Würdig committed
862
"xLoad" => {
863
864
865
866
  "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
867
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
868
  "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "xmm" ] },
Michael Beck's avatar
Michael Beck committed
869
870
  "emit"      => '. movs%M %D1, %ia32_emit_am /* Load((%A1)) -> %D1 */',
  "outs"      => [ "res", "M" ],
Christian Würdig's avatar
Christian Würdig committed
871
},
Christian Würdig's avatar
Christian Würdig committed
872

Christian Würdig's avatar
Christian Würdig committed
873
"xStore" => {
Christian Würdig's avatar
Christian Würdig committed
874
875
876
  "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
877
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
878
  "reg_req"  => { "in" => [ "gp", "gp", "xmm", "none" ] },
Michael Beck's avatar
Michael Beck committed
879
880
  "emit"     => '. movs%M %ia32_emit_binop /* Store(%S3) -> (%A1) */',
  "outs"      => [ "M" ],
Christian Würdig's avatar
Christian Würdig committed
881
882
},

883
884
885
886
887
888
889
890
891
892
"xStoreSimple" => {
  "op_flags" => "L|F",
  "state"    => "exc_pinned",
  "comment"  => "construct Store without index: Store(ptr, val, mem) = ST ptr,val",
  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
  "reg_req"  => { "in" => [ "gp", "xmm", "none" ] },
  "emit"     => '. movs%M %ia32_emit_am, %S2 /* store XMM0 onto stack */',
  "outs"      => [ "M" ],
},

893
894
895
896
897
898
899
900
901
902
903
904
905
906
"l_X87toSSE" => {
  "op_flags" => "L|F",
  "comment"  => "construct: transfer a value from x87 FPU into a SSE register",
  "cmp_attr" => "  return 1;\n",
  "arity"    => 3,
},

"l_SSEtoX87" => {
  "op_flags" => "L|F",
  "comment"  => "construct: transfer a value from SSE register to x87 FPU",
  "cmp_attr" => "  return 1;\n",
  "arity"    => 3,
},

907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
"GetST0" => {
  "op_flags" => "L|F",
  "irn_flags" => "I",
  "state"    => "exc_pinned",
  "comment"  => "store ST0 onto stack",
  "cmp_attr" => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
  "reg_req"  => { "in" => [ "gp", "none" ] },
  "emit"     => '. fstp %ia32_emit_am /* store ST0 onto stack */',
  "outs"     => [ "M" ],
},

"SetST0" => {
  "op_flags" => "L|F",
  "irn_flags" => "I",
  "state"    => "exc_pinned",
  "comment"  => "load ST0 from stack",
  "cmp_attr" => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
  "reg_req"  => { "in" => [ "gp", "none" ], "out" => [ "st0", "none" ] },
  "emit"     => '. fld %ia32_emit_am /* load ST0 from stack */',
  "outs"     => [ "res", "M" ],
},

929
930
931
# CopyB

"CopyB" => {
Christian Würdig's avatar
Christian Würdig committed
932
933
934
  "op_flags" => "F|H",
  "state"    => "pinned",
  "comment"  => "implements a memcopy: CopyB(dst, src, size, mem) == memcpy(dst, src, size)",
Christian Würdig's avatar
Christian Würdig committed
935
  "reg_req"  => { "in" => [ "edi", "esi", "ecx", "none" ], "out" => [ "edi", "esi", "ecx", "none" ] },
Christian Würdig's avatar
Christian Würdig committed
936
  "outs"     => [ "DST", "SRC", "CNT", "M" ],
Christian Würdig's avatar
Christian Würdig committed
937
938
},

939
"CopyB_i" => {
Christian Würdig's avatar
Christian Würdig committed
940
941
942
943
  "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",
Christian Würdig's avatar
Christian Würdig committed
944
  "reg_req"  => { "in" => [ "edi", "esi", "none" ], "out" => [  "edi", "esi", "none" ] },
Christian Würdig's avatar
Christian Würdig committed
945
  "outs"     => [ "DST", "SRC", "M" ],
Christian Würdig's avatar
Christian Würdig committed
946
947
},

Christian Würdig's avatar
Christian Würdig committed
948
949
# Conversions

Christian Würdig's avatar
Christian Würdig committed
950
"Conv_I2I" => {
Christian Würdig's avatar
Christian Würdig committed
951
  "reg_req"  => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3", "none" ] },