arm_spec.pl 25.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
# Creation: 2006/02/13
# $Id$
# This is a template specification for the Firm-Backend

# the cpu architecture (ia32, ia64, mips, sparc, ppc, ...)

$arch = "arm";

# $comment_string = 'WIRHABENKEINEKOMMENTARE';
$comment_string = '/*';

# the number of additional opcodes you want to register
Michael Beck's avatar
Michael Beck committed
13
#$additional_opcodes = 0;
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

# The node description is done as a perl hash initializer with the
# following structure:
#
# %nodes = (
#
# <op-name> => {
#   "op_flags"  => "N|L|C|X|I|F|Y|H|c|K",
#   "irn_flags" => "R|N|I"
#   "arity"     => "0|1|2|3 ... |variable|dynamic|any",
#   "state"     => "floats|pinned|mem_pinned|exc_pinned",
#   "args"      => [
#                    { "type" => "type 1", "name" => "name 1" },
#                    { "type" => "type 2", "name" => "name 2" },
#                    ...
#                  ],
#   "comment"   => "any comment for constructor",
#   "reg_req"   => { "in" => [ "reg_class|register" ], "out" => [ "reg_class|register|in_rX" ] },
#   "cmp_attr"  => "c source code for comparing node attributes",
#   "emit"      => "emit code with templates",
#   "rd_constructor" => "c source code which constructs an ir_node"
# },
#
# ... # (all nodes you need to describe)
#
# ); # close the %nodes initializer

# op_flags: flags for the operation, OPTIONAL (default is "N")
# 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
#   K   irop_flag_keep
#
# irn_flags: special node flags, OPTIONAL (default is 0)
# following irn_flags are supported:
#   R   rematerializeable
#   N   not spillable
#   I   ignore for register allocation
#
# state: state of the operation, OPTIONAL (default is "floats")
#
# arity: arity of the operation, MUST NOT BE OMITTED
#
# args:  the OPTIONAL arguments of the node constructor (debug, irg and block
#        are always the first 3 arguments and are always autmatically
#        created)
#        If this key is missing the following arguments will be created:
#        for i = 1 .. arity: ir_node *op_i
#        ir_mode *mode
#
# comment: OPTIONAL comment for the node constructor
#
# 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
#
#      This key is OPTIONAL. If omitted, the following constructor will
#      be created:
#      if (!op_<arch>_<op-name>) assert(0);
#      for i = 1 to arity
#         set in[i] = op_i
#      done
#      res = new_ir_node(db, irg, block, op_<arch>_<op-name>, mode, arity, in)
#      return res
#
# NOTE: rd_constructor and args are only optional if and only if arity is 0,1,2 or 3

# register types:
#   0 - no special type
#   1 - caller save (register must be saved by the caller of a function)
#   2 - callee save (register must be saved by the called function)
#   4 - ignore (do not assign this register)
# NOTE: Last entry of each class is the largest Firm-Mode a register can hold
%reg_classes = (
Michael Beck's avatar
Michael Beck committed
96
  "gp" => [
97
98
99
100
101
102
103
104
105
106
107
108
109
                         { "name" => "r0", "type" => 1 },
                         { "name" => "r1", "type" => 1 },
                         { "name" => "r2", "type" => 1 },
                         { "name" => "r3", "type" => 1 },
                         { "name" => "r4", "type" => 2 },
                         { "name" => "r5", "type" => 2 },
                         { "name" => "r6", "type" => 2 },
                         { "name" => "r7", "type" => 2 },
                         { "name" => "r8", "type" => 2 },
                         { "name" => "r9", "type" => 2 },
                         { "name" => "r10", "type" => 2 },
                         { "name" => "r11", "type" => 2 },
                         { "name" => "r12", "type" => 6 }, # reserved for linker
Michael Beck's avatar
Michael Beck committed
110
111
112
113
114
                         { "name" => "sp", "type" => 6 }, # this is our stack pointer
                         { "name" => "lr", "type" => 3 }, # this is our return address
                         { "name" => "pc", "type" => 6 }, # this is our program counter
                         { "name" => "rxx", "type" => 6 }, # dummy register for no_mem
                         { "mode" => "mode_Iu" }
115
                       ],
Michael Beck's avatar
Michael Beck committed
116
  "fp"  => [
117
118
119
120
121
122
123
124
                         { "name" => "f0", "type" => 1 },
                         { "name" => "f1", "type" => 1 },
                         { "name" => "f2", "type" => 1 },
                         { "name" => "f3", "type" => 1 },
                         { "name" => "f4", "type" => 2 },
                         { "name" => "f5", "type" => 2 },
                         { "name" => "f6", "type" => 2 },
                         { "name" => "f7", "type" => 2 },
Michael Beck's avatar
Michael Beck committed
125
                         { "name" => "fxx", "type" => 6 }, # dummy register for no_mem
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
                         { "mode" => "mode_D" }
                       ]
); # %reg_classes

#--------------------------------------------------#
#                        _                         #
#                       (_)                        #
#  _ __   _____      __  _ _ __    ___  _ __  ___  #
# | '_ \ / _ \ \ /\ / / | | '__|  / _ \| '_ \/ __| #
# | | | |  __/\ V  V /  | | |    | (_) | |_) \__ \ #
# |_| |_|\___| \_/\_/   |_|_|     \___/| .__/|___/ #
#                                      | |         #
#                                      |_|         #
#--------------------------------------------------#

%nodes = (

#-----------------------------------------------------------------#
#  _       _                                         _            #
# (_)     | |                                       | |           #
#  _ _ __ | |_ ___  __ _  ___ _ __   _ __   ___   __| | ___  ___  #
# | | '_ \| __/ _ \/ _` |/ _ \ '__| | '_ \ / _ \ / _` |/ _ \/ __| #
# | | | | | ||  __/ (_| |  __/ |    | | | | (_) | (_| |  __/\__ \ #
# |_|_| |_|\__\___|\__, |\___|_|    |_| |_|\___/ \__,_|\___||___/ #
#                   __/ |                                         #
#                  |___/                                          #
#-----------------------------------------------------------------#

# commutative operations

"Add" => {
  "op_flags"  => "C",
  "irn_flags" => "R",
  "comment"   => "construct Add: Add(a, b) = Add(b, a) = a + b",
Michael Beck's avatar
Michael Beck committed
160
161
162
163
164
  "attr"      => "arm_shift_modifier mod, tarval *shf",
  "init_attr" => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;',
  "cmp_attr"  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);',
  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
  "emit"      => '. ADD %D1, %S1, %S2%X0 /* Add(%S1, %S2) -> %D1, (%A1, %A2) */'
165
166
167
168
169
},

"Add_i" => {
  "irn_flags" => "R",
  "comment"   => "construct Add: Add(a, const) = Add(const, a) = a + const",
Michael Beck's avatar
Michael Beck committed
170
171
172
173
174
  "attr"      => "tarval *tv",
  "init_attr" => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;',
  "cmp_attr"  => 'return attr_a->value != attr_b->value;',
  "reg_req"   => { "in" => [ "gp" ], "out" => [ "gp" ] },
  "emit"      => '. ADD %D1, %S1, %C /* Add(%C, %S1) -> %D1, (%A1, const) */'
175
176
177
178
179
180
},

"Mul" => {
  #"op_flags"  => "C",
  "irn_flags" => "R",
  "comment"   => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
Michael Beck's avatar
Michael Beck committed
181
182
183
184
185
186
187
188
189
190
  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "!in_r1" ] },
  "emit"      =>'. MUL %D1, %S1, %S2 /* Mul(%S1, %S2) -> %D1, (%A1, %A2) */'
},

"Mla" => {
  #"op_flags"  => "C",
  "irn_flags" => "R",
  "comment"   => "construct Mla: Mla(a, b, c) = a * b + c",
  "reg_req"   => { "in" => [ "gp", "gp", "gp" ], "out" => [ "!in_r1" ] },
  "emit"      =>'. MLA %D1, %S1, %S2, %S3 /* Mla(%S1, %S2, %S3) -> %D1, (%A1, %A2, %A3) */'
191
192
193
194
195
196
},

"And" => {
  "op_flags"  => "C",
  "irn_flags" => "R",
  "comment"   => "construct And: And(a, b) = And(b, a) = a AND b",
Michael Beck's avatar
Michael Beck committed
197
198
199
200
201
  "attr"      => "arm_shift_modifier mod, tarval *shf",
  "init_attr" => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;',
  "cmp_attr"  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);',
  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
  "emit"      => '. AND %D1, %S1, %S2%X0 /* And(%S1, %S2) -> %D1, (%A1, %A2) */'
202
203
204
205
206
},

"And_i" => {
  "irn_flags" => "R",
  "comment"   => "construct And: And(a, const) = And(const, a) = a AND const",
Michael Beck's avatar
Michael Beck committed
207
208
209
210
211
  "attr"      => "tarval *tv",
  "init_attr" => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;',
  "reg_req"   => { "in" => [ "gp" ], "out" => [ "gp" ] },
  "emit"      => '. AND %D1, %S1, %C /* And(%C, %S1) -> %D1, (%A1, const) */',
  "cmp_attr"  => 'return attr_a->value != attr_b->value;'
212
213
214
215
216
217
},

"Or" => {
  "op_flags"  => "C",
  "irn_flags" => "R",
  "comment"   => "construct Or: Or(a, b) = Or(b, a) = a OR b",
Michael Beck's avatar
Michael Beck committed
218
219
220
221
222
  "attr"      => "arm_shift_modifier mod, tarval *shf",
  "init_attr" => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;',
  "cmp_attr"  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);',
  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
  "emit"      => '. ORR %D1, %S1, %S2%X0 /* Or(%S1, %S2) -> %D1, (%A1, %A2) */'
223
224
225
226
227
},

"Or_i" => {
  "irn_flags" => "R",
  "comment"   => "construct Or: Or(a, const) = Or(const, a) = a OR const",
Michael Beck's avatar
Michael Beck committed
228
229
230
231
232
  "attr"      => "tarval *tv",
  "init_attr" => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;',
  "reg_req"   => { "in" => [ "gp" ], "out" => [ "gp" ] },
  "cmp_attr"  => 'return attr_a->value != attr_b->value;',
  "emit"      => '. ORR %D1, %S1, %C /* Or(%C, %S1) -> %D1, (%A1, const) */'
233
234
235
236
237
238
},

"Eor" => {
  "op_flags"  => "C",
  "irn_flags" => "R",
  "comment"   => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b",
Michael Beck's avatar
Michael Beck committed
239
240
241
242
243
  "attr"      => "arm_shift_modifier mod, tarval *shf",
  "init_attr" => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;',
  "cmp_attr"  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);',
  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
  "emit"      => '. EOR %D1, %S1, %S2%X0 /* Xor(%S1, %S2) -> %D1, (%A1, %A2) */'
244
245
246
247
248
},

"Eor_i" => {
  "irn_flags" => "R",
  "comment"   => "construct Eor: Eor(a, const) = Eor(const, a) = a EOR const",
Michael Beck's avatar
Michael Beck committed
249
250
251
252
253
  "attr"      => "tarval *tv",
  "init_attr" => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;',
  "reg_req"   => { "in" => [ "gp" ], "out" => [ "gp" ] },
  "cmp_attr"  => 'return attr_a->value != attr_b->value;',
  "emit"      => '. EOR %D1, %S1, %C /* Xor(%C, %S1) -> %D1, (%A1, const) */'
254
255
256
257
},

# not commutative operations

Michael Beck's avatar
Michael Beck committed
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
"Bic" => {
  "irn_flags" => "R",
  "comment"   => "construct Bic: Bic(a, b) = a AND ~b",
  "attr"      => "arm_shift_modifier mod, tarval *shf",
  "init_attr" => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;',
  "cmp_attr"  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);',
  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
  "emit"      => '. BIC %D1, %S1, %S2%X0 /* AndNot(%S1, %S2) -> %D1, (%A1, %A2) */'
},

"Bic_i" => {
  "irn_flags" => "R",
  "comment"   => "construct Bic: Bic(a, const) = a AND ~const",
  "attr"      => "tarval *tv",
  "init_attr" => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;',
  "reg_req"   => { "in" => [ "gp" ], "out" => [ "gp" ] },
  "emit"      => '. BIC %D1, %S1, %C /* AndNot(%C, %S1) -> %D1, (%A1, const) */',
  "cmp_attr"  => 'return attr_a->value != attr_b->value;'
},

278
279
280
"Sub" => {
  "irn_flags" => "R",
  "comment"   => "construct Sub: Sub(a, b) = a - b",
Michael Beck's avatar
Michael Beck committed
281
282
283
284
285
  "attr"      => "arm_shift_modifier mod, tarval *shf",
  "init_attr" => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;',
  "cmp_attr"  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);',
  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
  "emit"      => '. SUB %D1, %S1, %S2%X0 /* Sub(%S1, %S2) -> %D1, (%A1, %A2) */'
286
287
288
289
290
},

"Sub_i" => {
  "irn_flags" => "R",
  "comment"   => "construct Sub: Sub(a, const) = a - const",
Michael Beck's avatar
Michael Beck committed
291
292
293
294
295
  "attr"      => "tarval *tv",
  "init_attr" => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;',
  "cmp_attr"  => 'return attr_a->value != attr_b->value;',
  "reg_req"   => { "in" => [ "gp" ], "out" => [ "gp" ] },
  "emit"      => '. SUB %D1, %S1, %C /* Sub(%S1, %C) -> %D1, (%A1, const) */',
296
297
},

Michael Beck's avatar
Michael Beck committed
298
"Rsb" => {
299
  "irn_flags" => "R",
Michael Beck's avatar
Michael Beck committed
300
301
302
303
304
305
  "comment"   => "construct Rsb: Rsb(a, b) = b - a",
  "attr"      => "arm_shift_modifier mod, tarval *shf",
  "init_attr" => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;',
  "cmp_attr"  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);',
  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
  "emit"      => '. RSB %D1, %S1, %S2%X0 /* Rsb(%S1, %S2) -> %D1, (%A1, %A2) */'
306
307
},

Michael Beck's avatar
Michael Beck committed
308
"Rsb_i" => {
309
  "irn_flags" => "R",
Michael Beck's avatar
Michael Beck committed
310
311
312
313
314
315
  "comment"   => "construct Rsb: Rsb(a, const) = const - a",
  "attr"      => "tarval *tv",
  "init_attr" => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;',
  "reg_req"   => { "in" => [ "gp" ], "out" => [ "gp" ] },
  "emit"      => '. RSB %D1, %S1, %C /* Rsb(%S1, %C) -> %D1, (%A1, const) */',
  "cmp_attr"  => 'return attr_a->value != attr_b->value;'
316
317
},

Michael Beck's avatar
Michael Beck committed
318
"Shl" => {
319
  "irn_flags" => "R",
Michael Beck's avatar
Michael Beck committed
320
321
322
  "comment"   => "construct Shl: Shl(a, b) = a << b",
  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
  "emit"      => '. MOV %D1, %S1, LSL %S2\t/* Shl(%S1, %S2) -> %D1, (%A1, %A2) */'
323
324
},

Michael Beck's avatar
Michael Beck committed
325
"Shr" => {
326
  "irn_flags" => "R",
Michael Beck's avatar
Michael Beck committed
327
328
329
  "comment"   => "construct Shr: Shr(a, b) = a >> b",
  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] },
  "emit"      => '. MOV %D1, %S1, LSR %S2 /* Shr(%S1, %S2) -> %D1, (%A1, %A2) */'
330
331
332
333
334
},

"Shrs" => {
  "irn_flags" => "R",
  "comment"   => "construct Shrs: Shrs(a, b) = a >> b",
Michael Beck's avatar
Michael Beck committed
335
336
  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] },
  "emit"      => '. MOV %D1, %S1, ASR %S2\t\t /* Shrs(%S1, %S2) -> %D1, (%A1, %A2) */'
337
338
339
340
341
},

#"RotR" => {
#  "irn_flags" => "R",
#  "comment"   => "construct RotR: RotR(a, b) = a ROTR b",
Michael Beck's avatar
Michael Beck committed
342
343
344
#  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
#  "emit"      => '. MOV %D1, %S1, ROR %S2 /* RotR(%S1, %S2) -> %D1, (%A1, %A2) */'
##  "emit"      => '. ror %S1, %S2, %D1 /* RotR(%S1, %S2) -> %D1, (%A1, %A2) */'
345
346
347
348
349
#},

#"RotL" => {
#  "irn_flags" => "R",
#  "comment"   => "construct RotL: RotL(a, b) = a ROTL b",
Michael Beck's avatar
Michael Beck committed
350
351
#  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
#  "emit"      => '. rol %S1, %S2, %D1 /* RotL(%S1, %S2) -> %D1, (%A1, %A2) */'
352
353
354
355
356
#},

#"RotL_i" => {
#  "irn_flags" => "R",
#  "comment"   => "construct RotL: RotL(a, const) = a ROTL const",
Michael Beck's avatar
Michael Beck committed
357
358
#  "reg_req"   => { "in" => [ "gp" ], "out" => [ "gp" ] },
#  "emit"      => '. rol %S1, %C, %D1 /* RotL(%S1, %C) -> %D1, (%A1, const) */'
359
360
#},

Michael Beck's avatar
Michael Beck committed
361
"Mov" => {
362
  "irn_flags" => "R",
Michael Beck's avatar
Michael Beck committed
363
364
365
366
367
368
  "comment"   => "construct Mov: a = b",
  "attr"      => "arm_shift_modifier mod, tarval *shf",
  "init_attr" => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;',
  "cmp_attr"  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);',
  "reg_req"   => { "in" => [ "gp" ], "out" => [ "gp" ] },
  "emit"      => '. MOV %D1, %S1%X0\t/* Mov(%S1%X0) -> %D1, (%A1) */'
369
370
},

Michael Beck's avatar
Michael Beck committed
371
372
373
374
375
376
377
378
379
"Mov_i" => {
  "irn_flags" => "R",
  "comment"   => "represents an integer constant",
  "attr"      => "tarval *tv",
  "init_attr" => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;',
  "reg_req"   => { "out" => [ "gp" ] },
  "emit"      => '. MOV %D1, %C   /* Mov Const into register */',
  "cmp_attr"  => 'return attr_a->value != attr_b->value;'
},
380

Michael Beck's avatar
Michael Beck committed
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
"Mvn" => {
  "irn_flags" => "R",
  "comment"   => "construct Not: Not(a) = !a",
  "attr"      => "arm_shift_modifier mod, tarval *shf",
  "init_attr" => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;',
  "cmp_attr"  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);',
  "reg_req"   => { "in" => [ "gp" ], "out" => [ "gp" ] },
  "emit"      => '. MVN %D1, %S1%X0 /* ~(%S1%X0) -> %D1, (%A1) */'
},

"Mvn_i" => {
  "irn_flags" => "R",
  "comment"   => "represents a negated integer constant",
  "attr"      => "tarval *tv",
  "init_attr" => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;',
  "cmp_attr"  => 'return attr_a->value != attr_b->value;',
  "reg_req"   => { "out" => [ "gp" ] },
  "emit"      => '. MVN %D1, %C   /* Mov ~Const into register */',
399
400
401
402
403
},

"Abs" => {
  "irn_flags" => "R",
  "comment"   => "construct Abs: Abs(a) = |a|",
Michael Beck's avatar
Michael Beck committed
404
  "reg_req"   => { "in" => [ "gp" ], "out" => [ "gp" ] },
405
  "emit"      =>
Michael Beck's avatar
Michael Beck committed
406
407
'. MOVS %S1, %S1, #0 /* set condition flag */\n
. RSBMI %D1, %S1, #0 /* Neg(%S1) -> %D1, (%A1) */'
408
409
410
411
412
413
414
},

# other operations

"EmptyReg" => {
  "op_flags"  => "c",
  "irn_flags" => "R",
Michael Beck's avatar
Michael Beck committed
415
416
  "comment"  => "just to get an empty register for calculations",
  "reg_req"  => { "out" => [ "gp" ] },
417
418
419
420
421
422
  "emit"      => '. /* %D1 now available for calculations */',
  "cmp_attr"  => 'return 1;'
},

"Copy" => {
  "comment"  => "implements a register copy",
Michael Beck's avatar
Michael Beck committed
423
  "reg_req"  => { "in" => [ "gp" ], "out" => [ "gp" ] },
424
425
426
427
428
429
},

"CopyB" => {
  "op_flags" => "F|H",
  "state"    => "pinned",
  "comment"  => "implements a memcopy: CopyB(dst, src, size, mem) == memcpy(dst, src, size)",
Michael Beck's avatar
Michael Beck committed
430
  "reg_req"  => { "in" => [ "!sp", "!sp", "gp", "gp", "gp", "none" ], "out" => [ "none" ] },
431
432
433
434
435
436
},

"SymConst" => {
  "op_flags"  => "c",
  "irn_flags" => "R",
  "comment"   => "represents a symbolic constant",
Michael Beck's avatar
Michael Beck committed
437
438
439
440
  "attr"      => "const char *label",
  "init_attr" => '  attr->symconst_label = label;',
  "reg_req"   => { "out" => [ "gp" ] },
#  "emit"      => '. LDR %D1, %C /* Mov Const into register */',
441
  "cmp_attr"  =>
Michael Beck's avatar
Michael Beck committed
442
443
'  /* should be identical but ...*/
   return strcmp(attr_a->symconst_label, attr_b->symconst_label);'
444
445
446
447
448
449
},

"CondJmp" => {
  "op_flags"  => "L|X|Y",
  "comment"   => "construct conditional jump: CMP A, B && JMPxx LABEL",
  "cmp_attr"  => "  return arm_comp_condJmp(attr_a, attr_b);\n",
Michael Beck's avatar
Michael Beck committed
450
  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "none", "none"] },
451
452
453
454
455
},

"SwitchJmp" => {
  "op_flags"  => "L|X|Y",
  "comment"   => "construct switch",
Michael Beck's avatar
Michael Beck committed
456
  "reg_req"   => { "in" => [ "gp" ], "out" => [ "none" ] },
457
458
459
460
461
462
463
464
465
466
  "cmp_attr"  => "  return 0;\n",
},

# Load / Store

"Load" => {
  "op_flags"  => "L|F",
  "irn_flags" => "R",
  "state"     => "exc_pinned",
  "comment"   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
Michael Beck's avatar
Michael Beck committed
467
468
469
  "reg_req"   => { "in" => [ "gp", "none" ], "out" => [ "gp" ] },
  "emit"      => '. LDR %D1, [%S1, #0] /* Load((%S1)) -> %D1, (%A1) */'
#  "emit"      => '. LDR %D1, %S1, %O /* Load((%S1)) -> %D1, (%A1) */'
470
471
472
473
474
475
476
},

"Loadb" => {
  "op_flags"  => "L|F",
  "irn_flags" => "R",
  "state"     => "exc_pinned",
  "comment"   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
Michael Beck's avatar
Michael Beck committed
477
478
479
  "reg_req"   => { "in" => [ "gp", "none" ], "out" => [ "gp" ] },
  "emit"      => '. LDRB %D1, [%S1, #0] /* Load((%S1)) -> %D1, (%A1) */'
#  "emit"      => '. LDRB %D1, %S1, %O /* Load((%S1)) -> %D1, (%A1) */'
480
481
482
483
484
485
486
},

"Loadbs" => {
  "op_flags"  => "L|F",
  "irn_flags" => "R",
  "state"     => "exc_pinned",
  "comment"   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
Michael Beck's avatar
Michael Beck committed
487
488
489
  "reg_req"   => { "in" => [ "gp", "none" ], "out" => [ "gp" ] },
  "emit"      => '. LDRSB %D1, [%S1, #0] /* Load((%S1)) -> %D1, (%A1) */'
#  "emit"      => '. LDRSB %D1, %S1, %O /* Load((%S1)) -> %D1, (%A1) */'
490
491
492
493
494
495
496
},

"Loadh" => {
  "op_flags"  => "L|F",
  "irn_flags" => "R",
  "state"     => "exc_pinned",
  "comment"   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
Michael Beck's avatar
Michael Beck committed
497
498
499
  "reg_req"   => { "in" => [ "gp", "none" ], "out" => [ "gp" ] },
  "emit"      => '. LDRH %D1, [%S1, #0] /* Load((%S1)) -> %D1, (%A1) */'
#  "emit"      => '. LDRH %D1, %S1, %O /* Load((%S1)) -> %D1, (%A1) */'
500
501
502
503
504
505
506
},

"Loadhs" => {
  "op_flags"  => "L|F",
  "irn_flags" => "R",
  "state"     => "exc_pinned",
  "comment"   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
Michael Beck's avatar
Michael Beck committed
507
508
509
  "reg_req"   => { "in" => [ "gp", "none" ], "out" => [ "gp" ] },
  "emit"      => '. LDRSH %D1, [%S1, #0] /* Load((%S1)) -> %D1, (%A1) */'
#  "emit"      => '. LDRSH %D1, %S1, %O /* Load((%S1)) -> %D1, (%A1) */'
510
511
512
513
514
515
516
},

"Storeb" => {
  "op_flags"  => "L|F",
  "irn_flags" => "R",
  "state"     => "exc_pinned",
  "comment"   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
Michael Beck's avatar
Michael Beck committed
517
518
519
  "reg_req"   => { "in" => [ "gp", "gp", "none" ] },
  "emit"      => '. STRB %S2, [%S1, #0] /* Store(%S2) -> (%S1), (%A1, %A2) */'
#  "emit"      => '. movl %S2, %O(%S1) /* Store(%S2) -> (%S1), (%A1, %A2) */'
520
521
522
523
524
525
526
},

"Storebs" => {
  "op_flags"  => "L|F",
  "irn_flags" => "R",
  "state"     => "exc_pinned",
  "comment"   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
Michael Beck's avatar
Michael Beck committed
527
528
529
  "reg_req"   => { "in" => [ "gp", "gp", "none" ] },
  "emit"      => '. STRSB %S2, [%S1, #0] /* Store(%S2) -> (%S1), (%A1, %A2) */'
#  "emit"      => '. movl %S2, %O(%S1) /* Store(%S2) -> (%S1), (%A1, %A2) */'
530
531
532
533
534
535
536
},

"Storeh" => {
  "op_flags"  => "L|F",
  "irn_flags" => "R",
  "state"     => "exc_pinned",
  "comment"   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
Michael Beck's avatar
Michael Beck committed
537
538
539
  "reg_req"   => { "in" => [ "gp", "gp", "none" ] },
  "emit"      => '. STRH %S2, [%S1, #0] /* Store(%S2) -> (%S1), (%A1, %A2) */'
#  "emit"      => '. movl %S2, %O(%S1) /* Store(%S2) -> (%S1), (%A1, %A2) */'
540
541
542
543
544
545
546
},

"Storehs" => {
  "op_flags"  => "L|F",
  "irn_flags" => "R",
  "state"     => "exc_pinned",
  "comment"   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
Michael Beck's avatar
Michael Beck committed
547
548
549
  "reg_req"   => { "in" => [ "gp", "gp", "none" ] },
  "emit"      => '. STRSH%S2, [%S1, #0] /* Store(%S2) -> (%S1), (%A1, %A2) */'
#  "emit"      => '. movl %S2, %O(%S1) /* Store(%S2) -> (%S1), (%A1, %A2) */'
550
551
552
553
554
555
556
},

"Store" => {
  "op_flags"  => "L|F",
  "irn_flags" => "R",
  "state"     => "exc_pinned",
  "comment"   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
Michael Beck's avatar
Michael Beck committed
557
558
559
  "reg_req"   => { "in" => [ "gp", "gp", "none" ] },
  "emit"      => '. STR %S2, [%S1, #0] /* Store(%S2) -> (%S1), (%A1, %A2) */'
#  "emit"      => '. movl %S2, %O(%S1) /* Store(%S2) -> (%S1), (%A1, %A2) */'
560
561
562
563
564
565
566
},

"StoreStackM4Inc" => {
  "op_flags"  => "L|F",
  "irn_flags" => "R",
  "state"     => "exc_pinned",
  "comment"   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
Michael Beck's avatar
Michael Beck committed
567
568
  "reg_req"   => { "in" => [ "sp", "gp", "gp", "gp", "gp", "none" ], "out" => [ "gp", "none" ] },
  "emit"      => '. STMFD %S1!, {%S2, %S3, %S4, %S5} /* Store multiple on Stack*/'
569
570
571
572
573
574
575
},

"LoadStackM3" => {
  "op_flags"  => "L|F",
  "irn_flags" => "R",
  "state"     => "exc_pinned",
  "comment"   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
Michael Beck's avatar
Michael Beck committed
576
577
  "reg_req"   => { "in" => [ "sp", "none" ], "out" => [ "gp", "gp", "gp", "none" ] },
  "emit"      => '. LDMFD %S1, {%D1, %D2, %D3} /* Load multiple from Stack */'
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
},








#--------------------------------------------------------#
#    __ _             _                     _            #
#   / _| |           | |                   | |           #
#  | |_| | ___   __ _| |_   _ __   ___   __| | ___  ___  #
#  |  _| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| #
#  | | | | (_) | (_| | |_  | | | | (_) | (_| |  __/\__ \ #
#  |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ #
#--------------------------------------------------------#

# commutative operations

Michael Beck's avatar
Michael Beck committed
598
"fAdd" => {
599
600
  "op_flags"  => "C",
  "irn_flags" => "R",
Michael Beck's avatar
Michael Beck committed
601
602
603
  "comment"   => "construct FP Add: Add(a, b) = Add(b, a) = a + b",
  "reg_req"   => { "in" => [ "fp", "fp" ], "out" => [ "fp" ] },
  "emit"      => '. FADD%Mx %D1, %S1, %S2 /* FP Add(%S1, %S2) -> %D1 */'
604
605
},

Michael Beck's avatar
Michael Beck committed
606
"fMul" => {
607
608
  "op_flags"  => "C",
  "comment"   => "construct FP Mul: Mul(a, b) = Mul(b, a) = a * b",
Michael Beck's avatar
Michael Beck committed
609
610
  "reg_req"   => { "in" => [ "fp", "fp" ], "out" => [ "fp" ] },
  "emit"      =>'. FMUL%Mx %D1, %S1, %S2 /* FP Mul(%S1, %S2) -> %D1 */'
611
612
613
614
},

"fDiv" => {
  "comment"   => "construct FP Div: Div(a, b) = a / b",
Michael Beck's avatar
Michael Beck committed
615
616
  "reg_req"   => { "in" => [ "fp", "fp" ], "out" => [ "fp" ] },
  "emit"      =>'. FDIV%Mx %D1, %S1, %S2 /* FP Div(%S1, %S2) -> %D1 */'
617
618
619
620
621
622
},

"fMax" => {
  "op_flags"  => "C",
  "irn_flags" => "R",
  "comment"   => "construct FP Max: Max(a, b) = Max(b, a) = a > b ? a : b",
Michael Beck's avatar
Michael Beck committed
623
624
  "reg_req"   => { "in" => [ "fp", "fp" ], "out" => [ "fp" ] },
  "emit"      =>'. fmax %S1, %S2, %D1 /* FP Max(%S1, %S2) -> %D1 */'
625
626
627
628
629
630
},

"fMin" => {
  "op_flags"  => "C",
  "irn_flags" => "R",
  "comment"   => "construct FP Min: Min(a, b) = Min(b, a) = a < b ? a : b",
Michael Beck's avatar
Michael Beck committed
631
632
  "reg_req"   => { "in" => [ "fp", "fp" ], "out" => [ "fp" ] },
  "emit"      =>'. fmin %S1, %S2, %D1 /* FP Min(%S1, %S2) -> %D1 */'
633
634
635
636
},

# not commutative operations

Michael Beck's avatar
Michael Beck committed
637
"fSub" => {
638
639
  "irn_flags" => "R",
  "comment"   => "construct FP Sub: Sub(a, b) = a - b",
Michael Beck's avatar
Michael Beck committed
640
641
  "reg_req"   => { "in" => [ "fp", "fp" ], "out" => [ "fp" ] },
  "emit"      => '. FSUB%Mx %D1, %S1, %S2 /* FP Sub(%S1, %S2) -> %D1 */'
642
643
644
645
646
},

"fMinus" => {
  "irn_flags" => "R",
  "comment"   => "construct FP Minus: Minus(a) = -a",
Michael Beck's avatar
Michael Beck committed
647
648
  "reg_req"   => { "in" => [ "fp" ], "out" => [ "fp" ] },
  "emit"      => '. fneg %S1, %D1 /* FP Minus(%S1) -> %D1 */'
649
650
},

Michael Beck's avatar
Michael Beck committed
651
"fAbs" => {
652
653
  "irn_flags" => "R",
  "comment"   => "construct FP Absolute value: fAbsd(a) = |a|",
Michael Beck's avatar
Michael Beck committed
654
655
  "reg_req"   => { "in" => [ "fp" ], "out" => [ "fp" ] },
  "emit"      => '. FABS%Mx %D1, %S1 /* FP Absd(%S1) -> %D1 */'
656
657
658
659
660
661
662
663
},

# other operations

"fConst" => {
  "op_flags"  => "c",
  "irn_flags" => "R",
  "comment"   => "represents a FP constant",
Michael Beck's avatar
Michael Beck committed
664
665
666
  "reg_req"   => { "out" => [ "fp" ] },
  "emit"      => '. FMOV %D1, %C /* Mov fConst into register */',
  "cmp_attr"  => 'return attr_a->value != attr_b->value;'
667
668
669
670
671
},

"fConvD2S" => {
  "irn_flags" => "R",
  "comment"   => "convert double to single",
Michael Beck's avatar
Michael Beck committed
672
673
  "reg_req"   => { "in" => [ "fp" ], "out" => [ "fp" ] },
  "emit"      => '. FCVTSD %D1, %S1 /* Convert double to single */',
674
675
676
677
678
},

"fConvS2D" => {
  "irn_flags" => "R",
  "comment"   => "convert single to double",
Michael Beck's avatar
Michael Beck committed
679
680
  "reg_req"   => { "in" => [ "fp" ], "out" => [ "fp" ] },
  "emit"      => '. FCVTDS %D1, %S1 /* Convert single to double */',
681
682
683
684
685
},


# Load / Store

Michael Beck's avatar
Michael Beck committed
686
"fLoad" => {
687
688
689
690
  "op_flags"  => "L|F",
  "irn_flags" => "R",
  "state"     => "exc_pinned",
  "comment"   => "construct FP Load: Load(ptr, mem) = LD ptr",
Michael Beck's avatar
Michael Beck committed
691
692
  "reg_req"   => { "in" => [ "gp", "none" ], "out" => [ "fp" ] },
  "emit"      => '. FLD%Mx %D1, %S1 /* Load((%S1)) -> %D1 */'
693
694
},

Michael Beck's avatar
Michael Beck committed
695
"fStore" => {
696
697
698
699
  "op_flags"  => "L|F",
  "irn_flags" => "R",
  "state"     => "exc_pinned",
  "comment"   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
Michael Beck's avatar
Michael Beck committed
700
701
  "reg_req"   => { "in" => [ "gp", "fp", "none" ] },
  "emit"      => '. FST%Mx %S2, %S1 /* Store(%S2) -> (%S1), (%A1, %A2) */'
702
703
704
},

); # end of %nodes