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

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

$arch = "arm";
Michael Beck's avatar
Michael Beck committed
8
$new_emit_syntax = 1;
9
10

# the number of additional opcodes you want to register
Michael Beck's avatar
Michael Beck committed
11
#$additional_opcodes = 0;
12
13
14
15
16
17
18

# The node description is done as a perl hash initializer with the
# following structure:
#
# %nodes = (
#
# <op-name> => {
Michael Beck's avatar
Michael Beck committed
19
20
21
22
23
24
25
#   op_flags  => "N|L|C|X|I|F|Y|H|c|K",
#   irn_flags => "R|N|I|S"
#   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" },
26
27
#                    ...
#                  ],
Michael Beck's avatar
Michael Beck committed
28
29
30
31
32
33
34
35
36
#   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",
#   attr      => "attitional attribute arguments for constructor"
#   init_attr => "emit attribute initialization template"
#   rd_constructor => "c source code which constructs an ir_node"
#   latency   => "latency of this operation (can be float)"
#   attr_type => "name of the attribute struct",
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# },
#
# ... # (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
Michael Beck's avatar
Michael Beck committed
61
#   S   modifies stack pointer
62
63
64
65
66
67
68
69
70
71
72
73
#
# 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
#
Michael Beck's avatar
Michael Beck committed
74
75
# outs:  if a node defines more than one output, the names of the projections
#        nodes having outs having automatically the mode mode_T
Michael Beck's avatar
Michael Beck committed
76
77
78
79
#        One can also annotate some flags for each out, additional to irn_flags.
#        They are separated from name with a colon ':', and concatenated by pipe '|'
#        Only I and S are available at the moment (same meaning as in irn_flags).
#        example: [ "frame:I", "stack:I|S", "M" ]
Michael Beck's avatar
Michael Beck committed
80
#
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# 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
Michael Beck's avatar
Michael Beck committed
98
99
100
#
# latency: the latency of the operation, default is 1
#
101

Michael Beck's avatar
Michael Beck committed
102
103
104
105
106
107
#
# Modes
#
$mode_gp      = "mode_Iu";
$mode_fpa     = "mode_E";

108
# register types:
109
110
111
112
113
114
115
$normal      =  0; # no special type
$caller_save =  1; # caller save (register must be saved by the caller of a function)
$callee_save =  2; # callee save (register must be saved by the called function)
$ignore      =  4; # ignore (do not assign this register)
$arbitrary   =  8; # emitter can choose an arbitrary register of this class
$virtual     = 16; # the register is a virtual one
$state       = 32; # register represents a state
116
117
# NOTE: Last entry of each class is the largest Firm-Mode a register can hold
%reg_classes = (
Michael Beck's avatar
Michael Beck committed
118
	gp => [
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
		{ "name" => "r0", "type"  => $caller_save },
		{ "name" => "r1", "type"  => $caller_save },
		{ "name" => "r2", "type"  => $caller_save },
		{ "name" => "r3", "type"  => $caller_save },
		{ "name" => "r4", "type"  => $callee_save },
		{ "name" => "r5", "type"  => $callee_save },
		{ "name" => "r6", "type"  => $callee_save },
		{ "name" => "r7", "type"  => $callee_save },
		{ "name" => "r8", "type"  => $callee_save },
		{ "name" => "r9", "type"  => $callee_save },
		{ "name" => "r10", "type" => $callee_save },
		{ "name" => "r11", "type" => $callee_save },
		{ "name" => "r12", "type" => $ignore | $callee_save }, # reserved for linker
		{ "name" => "sp", "type"  => $ignore | $callee_save }, # this is our stack pointer
		{ "name" => "lr", "type"  => $callee_save | $caller_save }, # this is our return address
		{ "name" => "pc", "type"  => $ignore | $callee_save }, # this is our program counter
		{ name => "gp_UKNWN", type => $ignore | $arbitrary | $virtual },  # we need a dummy register for Unknown nodes
Michael Beck's avatar
Michael Beck committed
136
137
138
139
140
141
142
143
144
145
146
147
148
149
		{ "mode" => $mode_gp }
	],
	fpa  => [
		{ "name" => "f0", "type" => 1 },
		{ "name" => "f1", "type" => 1 },
		{ "name" => "f2", "type" => 1 },
		{ "name" => "f3", "type" => 1 },
		{ "name" => "f4", "type" => 1 },
		{ "name" => "f5", "type" => 1 },
		{ "name" => "f6", "type" => 1 },
		{ "name" => "f7", "type" => 1 },
		{ name => "fpa_UKNWN", type => 4 | 8 | 16 },  # we need a dummy register for Unknown nodes
		{ "mode" => $mode_fpa }
	]
150
151
); # %reg_classes

Michael Beck's avatar
Michael Beck committed
152
%emit_templates = (
153
154
155
156
157
158
159
160
161
162
163
164
	M  => "${arch}_emit_mode(node);",
	X  => "${arch}_emit_shift(node);",
	S0 => "${arch}_emit_source_register(node, 0);",
	S1 => "${arch}_emit_source_register(node, 1);",
	S2 => "${arch}_emit_source_register(node, 2);",
	S3 => "${arch}_emit_source_register(node, 3);",
	S4 => "${arch}_emit_source_register(node, 4);",
	D0 => "${arch}_emit_dest_register(node, 0);",
	D1 => "${arch}_emit_dest_register(node, 1);",
	D2 => "${arch}_emit_dest_register(node, 2);",
	C  => "${arch}_emit_immediate(node);",
	O  => "${arch}_emit_offset(mode);",
Michael Beck's avatar
Michael Beck committed
165
166
);

167
168
169
170
171
172
173
174
175
176
177
#--------------------------------------------------#
#                        _                         #
#                       (_)                        #
#  _ __   _____      __  _ _ __    ___  _ __  ___  #
# | '_ \ / _ \ \ /\ / / | | '__|  / _ \| '_ \/ __| #
# | | | |  __/\ V  V /  | | |    | (_) | |_) \__ \ #
# |_| |_|\___| \_/\_/   |_|_|     \___/| .__/|___/ #
#                                      | |         #
#                                      |_|         #
#--------------------------------------------------#

Michael Beck's avatar
Michael Beck committed
178
$default_attr_type = "arm_attr_t";
Matthias Braun's avatar
fix    
Matthias Braun committed
179
$default_copy_attr = "arm_copy_attr";
Michael Beck's avatar
Michael Beck committed
180
181

%init_attr = (
182
183
184
185
	arm_attr_t           => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);",
	arm_SymConst_attr_t  => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);",
	arm_CondJmp_attr_t   => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);",
	arm_SwitchJmp_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);",
Michael Beck's avatar
Michael Beck committed
186
	arm_fpaConst_attr_t  => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);",
Michael Beck's avatar
Michael Beck committed
187
188
189
190
191
192
193
);

%compare_attr = (
	arm_attr_t           => "cmp_attr_arm",
	arm_SymConst_attr_t  => "cmp_attr_arm_SymConst",
	arm_CondJmp_attr_t   => "cmp_attr_arm_CondJmp",
	arm_SwitchJmp_attr_t => "cmp_attr_arm_SwitchJmp",
Michael Beck's avatar
Michael Beck committed
194
	arm_fpaConst_attr_t  => "cmp_attr_arm_fpaConst",
Michael Beck's avatar
Michael Beck committed
195
);
196

197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#%operands = (
#
#Immediate => {
#	comment   => "blup di dup",
#	irn_flags => "R",
#	emit      => ". [%S0]-10",
#	reg_req   => { },
#	attr      => "tarval *tv",
#	init_attr => "(void) attri;",
#	# op_flags => O
#	# cmp => "return 1;"
#},
#
#ShfOp_I => {
#	irn_flags => "R",
#	emit      => ". ...",
#	reg_req   => { in => [ "gp" ] },
#	attr      => "tarval *tv",
#	init_attr => "(void) tv;",
#},
#
#ShfOp => {
#	irn_flags => "R",
#	emit      => ". ...",
#	reg_req   => { in => [ "gp", "gp" ] },
#},
#
#);
225

226
227
%nodes = (

Michael Beck's avatar
Michael Beck committed
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
Unknown_GP => {
	state     => "pinned",
	op_flags  => "c",
	irn_flags => "I",
	reg_req   => { out => [ "gp_UKNWN" ] },
	emit      => "",
	mode      => $mode_gp,
},

Unknown_FPA => {
	state     => "pinned",
	op_flags  => "c",
	irn_flags => "I",
	reg_req   => { out => [ "fpa_UKNWN" ] },
	emit      => "",
	mode      => $mode_fpa,
},

246
247
248
249
250
251
252
253
254
255
256
257
258
#-----------------------------------------------------------------#
#  _       _                                         _            #
# (_)     | |                                       | |           #
#  _ _ __ | |_ ___  __ _  ___ _ __   _ __   ___   __| | ___  ___  #
# | | '_ \| __/ _ \/ _` |/ _ \ '__| | '_ \ / _ \ / _` |/ _ \/ __| #
# | | | | | ||  __/ (_| |  __/ |    | | | | (_) | (_| |  __/\__ \ #
# |_|_| |_|\__\___|\__, |\___|_|    |_| |_|\___/ \__,_|\___||___/ #
#                   __/ |                                         #
#                  |___/                                          #
#-----------------------------------------------------------------#

# commutative operations

Michael Beck's avatar
Michael Beck committed
259
Add => {
Michael Beck's avatar
Michael Beck committed
260
261
262
	op_flags  => "C",
	irn_flags => "R",
	comment   => "construct Add: Add(a, b) = Add(b, a) = a + b",
Michael Beck's avatar
Michael Beck committed
263
264
265
	attr      => "arm_shift_modifier mod, long shf",
	init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
	cmp_attr  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);',
Michael Beck's avatar
Michael Beck committed
266
267
	reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
	emit      => '. add %D0, %S0, %S1%X'
Michael Beck's avatar
Michael Beck committed
268
269
270
},

Add_i => {
Michael Beck's avatar
Michael Beck committed
271
272
	irn_flags => "R",
	comment   => "construct Add: Add(a, const) = Add(const, a) = a + const",
Michael Beck's avatar
Michael Beck committed
273
274
275
	attr      => "long imm",
	init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;',
Michael Beck's avatar
Michael Beck committed
276
277
	reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
	emit      => '. add %D0, %S0, %C'
Michael Beck's avatar
Michael Beck committed
278
279
280
},

Mul => {
Michael Beck's avatar
Michael Beck committed
281
282
283
284
285
	#op_flags  => "C",
	irn_flags => "R",
	comment   => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
	reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "!in_r1" ] },
	emit      =>'. mul %D0, %S0, %S1'
Michael Beck's avatar
Michael Beck committed
286
287
288
},

Smull => {
Michael Beck's avatar
Michael Beck committed
289
290
291
292
293
294
	#op_flags  => "C",
	irn_flags => "R",
	comment   => "construct signed 64bit Mul: Mul(a, b) = Mul(b, a) = a * b",
	reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp", "gp" ] },
	emit      =>'. smull %D0, %D1, %S0, %S1',
	outs      => [ "low", "high" ],
Michael Beck's avatar
Michael Beck committed
295
296
297
},

Umull => {
Michael Beck's avatar
Michael Beck committed
298
299
300
301
302
303
	#op_flags  => "C",
	irn_flags => "R",
	comment   => "construct unsigned 64bit Mul: Mul(a, b) = Mul(b, a) = a * b",
	reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp", "gp" ] },
	emit      =>'. umull %D0, %D1, %S0, %S1',
	outs      => [ "low", "high" ],
Michael Beck's avatar
Michael Beck committed
304
305
306
},

Mla => {
Michael Beck's avatar
Michael Beck committed
307
308
309
310
311
	#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 %D0, %S0, %S1, %S2'
Michael Beck's avatar
Michael Beck committed
312
313
314
},

And => {
Michael Beck's avatar
Michael Beck committed
315
316
317
	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
318
319
320
	attr      => "arm_shift_modifier mod, long shf",
	init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
	cmp_attr  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);',
Michael Beck's avatar
Michael Beck committed
321
322
	reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
	emit      => '. and %D0, %S0, %S1%X'
Michael Beck's avatar
Michael Beck committed
323
324
325
},

And_i => {
Michael Beck's avatar
Michael Beck committed
326
327
	irn_flags => "R",
	comment   => "construct And: And(a, const) = And(const, a) = a AND const",
Michael Beck's avatar
Michael Beck committed
328
329
	attr      => "long imm",
	init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
Michael Beck's avatar
Michael Beck committed
330
331
	reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
	emit      => '. and %D0, %S0, %C',
Michael Beck's avatar
Michael Beck committed
332
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;'
Michael Beck's avatar
Michael Beck committed
333
334
335
},

Or => {
Michael Beck's avatar
Michael Beck committed
336
337
338
	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
339
340
341
	attr      => "arm_shift_modifier mod, long shf",
	init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
	cmp_attr  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);',
Michael Beck's avatar
Michael Beck committed
342
343
	reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
	emit      => '. orr %D0, %S0, %S1%X'
Michael Beck's avatar
Michael Beck committed
344
345
346
},

Or_i => {
Michael Beck's avatar
Michael Beck committed
347
348
	irn_flags => "R",
	comment   => "construct Or: Or(a, const) = Or(const, a) = a OR const",
Michael Beck's avatar
Michael Beck committed
349
350
	attr      => "long imm",
	init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
Michael Beck's avatar
Michael Beck committed
351
	reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
Michael Beck's avatar
Michael Beck committed
352
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;',
Michael Beck's avatar
Michael Beck committed
353
	emit      => '. orr %D0, %S0, %C'
Michael Beck's avatar
Michael Beck committed
354
355
356
},

Eor => {
Michael Beck's avatar
Michael Beck committed
357
358
359
	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
360
361
362
	attr      => "arm_shift_modifier mod, long shf",
	init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
	cmp_attr  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);',
Michael Beck's avatar
Michael Beck committed
363
364
	reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
	emit      => '. eor %D0, %S0, %S1%X'
Michael Beck's avatar
Michael Beck committed
365
366
367
},

Eor_i => {
Michael Beck's avatar
Michael Beck committed
368
369
	irn_flags => "R",
	comment   => "construct Eor: Eor(a, const) = Eor(const, a) = a EOR const",
Michael Beck's avatar
Michael Beck committed
370
371
	attr      => "long imm",
	init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
Michael Beck's avatar
Michael Beck committed
372
	reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
Michael Beck's avatar
Michael Beck committed
373
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;',
Michael Beck's avatar
Michael Beck committed
374
	emit      => '. eor %D0, %S0, %C'
375
376
377
378
},

# not commutative operations

Michael Beck's avatar
Michael Beck committed
379
Bic => {
Michael Beck's avatar
Michael Beck committed
380
381
	irn_flags => "R",
	comment   => "construct Bic: Bic(a, b) = a AND ~b",
Michael Beck's avatar
Michael Beck committed
382
383
384
	attr      => "arm_shift_modifier mod, long shf",
	init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
	cmp_attr  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);',
Michael Beck's avatar
Michael Beck committed
385
386
	reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
	emit      => '. bic %D0, %S0, %S1%X'
Michael Beck's avatar
Michael Beck committed
387
388
389
},

Bic_i => {
Michael Beck's avatar
Michael Beck committed
390
391
	irn_flags => "R",
	comment   => "construct Bic: Bic(a, const) = a AND ~const",
Michael Beck's avatar
Michael Beck committed
392
393
	attr      => "long imm",
	init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
Michael Beck's avatar
Michael Beck committed
394
395
	reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
	emit      => '. bic %D0, %S0, %C',
Michael Beck's avatar
Michael Beck committed
396
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;'
Michael Beck's avatar
Michael Beck committed
397
398
399
},

Sub => {
Michael Beck's avatar
Michael Beck committed
400
401
	irn_flags => "R",
	comment   => "construct Sub: Sub(a, b) = a - b",
Michael Beck's avatar
Michael Beck committed
402
403
404
	attr      => "arm_shift_modifier mod, long shf",
	init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
	cmp_attr  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);',
Michael Beck's avatar
Michael Beck committed
405
406
	reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
	emit      => '. sub %D0, %S0, %S1%X'
Michael Beck's avatar
Michael Beck committed
407
408
409
},

Sub_i => {
Michael Beck's avatar
Michael Beck committed
410
411
	irn_flags => "R",
	comment   => "construct Sub: Sub(a, const) = a - const",
Michael Beck's avatar
Michael Beck committed
412
413
414
	attr      => "long imm",
	init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;',
Michael Beck's avatar
Michael Beck committed
415
416
	reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
	emit      => '. sub %D0, %S0, %C',
Michael Beck's avatar
Michael Beck committed
417
418
419
},

Rsb => {
Michael Beck's avatar
Michael Beck committed
420
421
	irn_flags => "R",
	comment   => "construct Rsb: Rsb(a, b) = b - a",
Michael Beck's avatar
Michael Beck committed
422
423
424
	attr      => "arm_shift_modifier mod, long shf",
	init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
	cmp_attr  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);',
Michael Beck's avatar
Michael Beck committed
425
426
	reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
	emit      => '. rsb %D0, %S0, %S1%X'
Michael Beck's avatar
Michael Beck committed
427
428
429
},

Rsb_i => {
Michael Beck's avatar
Michael Beck committed
430
431
	irn_flags => "R",
	comment   => "construct Rsb: Rsb(a, const) = const - a",
Michael Beck's avatar
Michael Beck committed
432
433
	attr      => "long imm",
	init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
Michael Beck's avatar
Michael Beck committed
434
435
	reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
	emit      => '. rsb %D0, %S0, %C',
Michael Beck's avatar
Michael Beck committed
436
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;'
Michael Beck's avatar
Michael Beck committed
437
438
439
},

Shl => {
Michael Beck's avatar
Michael Beck committed
440
441
442
443
	irn_flags => "R",
	comment   => "construct Shl: Shl(a, b) = a << b",
	reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
	emit      => '. mov %D0, %S0, lsl %S1'
Michael Beck's avatar
Michael Beck committed
444
445
446
},

Shr => {
Michael Beck's avatar
Michael Beck committed
447
	irn_flags => "R",
Michael Beck's avatar
Michael Beck committed
448
449
	comment   => "construct Shr: Shr(a, b) = a >>u b",
	reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
Michael Beck's avatar
Michael Beck committed
450
	emit      => '. mov %D0, %S0, lsr %S1'
Michael Beck's avatar
Michael Beck committed
451
452
453
},

Shrs => {
Michael Beck's avatar
Michael Beck committed
454
	irn_flags => "R",
Michael Beck's avatar
Michael Beck committed
455
456
	comment   => "construct Shrs: Shrs(a, b) = a >>s b",
	reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
Michael Beck's avatar
Michael Beck committed
457
	emit      => '. mov %D0, %S0, asr %S1'
Michael Beck's avatar
Michael Beck committed
458
459
},

Michael Beck's avatar
Michael Beck committed
460
461
462
463
464
465
Ror => {
	irn_flags => "R",
	comment   => "construct Ror: Ror(a, b) = a <<r>> b",
	reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
	emit      => '. mov %D0, %S0, ror %S1'
},
466

Michael Beck's avatar
Michael Beck committed
467
468
469
470
471
#RotL => {
#  irn_flags => "R",
#  comment   => "construct RotL: RotL(a, b) = a ROTL b",
#  reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
#  emit      => '. rol %S0, %S1, %D0'
472
473
#},

Michael Beck's avatar
Michael Beck committed
474
#RotL_i => {
Michael Beck's avatar
Michael Beck committed
475
476
477
478
#	irn_flags => "R",
#	comment   => "construct RotL: RotL(a, const) = a ROTL const",
#	reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
#	emit      => '. rol %S0, %C, %D0'
479
480
#},

Michael Beck's avatar
Michael Beck committed
481
Mov => {
Michael Beck's avatar
Michael Beck committed
482
483
	irn_flags => "R",
	comment   => "construct Mov: a = b",
Michael Beck's avatar
Michael Beck committed
484
485
486
	attr      => "arm_shift_modifier mod, long shf",
	init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
	cmp_attr  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);',
Michael Beck's avatar
Michael Beck committed
487
488
	reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
	emit      => '. mov %D0, %S0%X'
Michael Beck's avatar
Michael Beck committed
489
490
491
},

Mov_i => {
Michael Beck's avatar
Michael Beck committed
492
493
	irn_flags => "R",
	comment   => "represents an integer constant",
Michael Beck's avatar
Michael Beck committed
494
495
	attr      => "long imm",
	init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
Michael Beck's avatar
Michael Beck committed
496
497
	reg_req   => { "out" => [ "gp" ] },
	emit      => '. mov %D0, %C',
Michael Beck's avatar
Michael Beck committed
498
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;'
Michael Beck's avatar
Michael Beck committed
499
500
501
},

Mvn => {
Michael Beck's avatar
Michael Beck committed
502
503
	irn_flags => "R",
	comment   => "construct Not: Not(a) = !a",
Michael Beck's avatar
Michael Beck committed
504
505
506
	attr      => "arm_shift_modifier mod, long shf",
	init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
	cmp_attr  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);',
Michael Beck's avatar
Michael Beck committed
507
508
	reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
	emit      => '. mvn %D0, %S0%X'
Michael Beck's avatar
Michael Beck committed
509
510
511
},

Mvn_i => {
Michael Beck's avatar
Michael Beck committed
512
513
	irn_flags => "R",
	comment   => "represents a negated integer constant",
Michael Beck's avatar
Michael Beck committed
514
515
516
	attr      => "long imm",
	init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;',
Michael Beck's avatar
Michael Beck committed
517
518
	reg_req   => { "out" => [ "gp" ] },
	emit      => '. mvn %D0, %C',
Michael Beck's avatar
Michael Beck committed
519
520
521
},

Abs => {
Michael Beck's avatar
Michael Beck committed
522
523
524
525
	irn_flags => "R",
	comment   => "construct Abs: Abs(a) = |a|",
	reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
	emit      =>
Michael Beck's avatar
Michael Beck committed
526
'. movs %S0, %S0, #0
527
. rsbmi %D0, %S0, #0'
528
529
530
531
},

# other operations

532
533
534
#
# this node produces ALWAYS an empty (tempary) gp reg and cannot be CSE'd
#
Michael Beck's avatar
Michael Beck committed
535
EmptyReg => {
Michael Beck's avatar
Michael Beck committed
536
537
538
539
540
541
	op_flags  => "c",
	irn_flags => "R",
	comment   => "allocate an empty register for calculations",
	reg_req   => { "out" => [ "gp" ] },
	emit      => '. /* %D0 now available for calculations */',
	cmp_attr  => 'return 1;'
542
543
},

Michael Beck's avatar
Michael Beck committed
544
Copy => {
Michael Beck's avatar
Michael Beck committed
545
546
	comment  => "implements a register copy",
	reg_req  => { "in" => [ "gp" ], "out" => [ "gp" ] },
547
548
},

Michael Beck's avatar
Michael Beck committed
549
CopyB => {
Michael Beck's avatar
Michael Beck committed
550
551
552
	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
553
554
555
	attr      => "long imm",
	init_attr => 'attr->imm_value = imm;',
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;',
Michael Beck's avatar
Michael Beck committed
556
557
	reg_req   => { "in" => [ "!sp", "!sp", "gp", "gp", "gp", "none" ], "out" => [ "none" ] },
	outs      => [ "M" ],
558
559
},

Michael Beck's avatar
Michael Beck committed
560
SymConst => {
Michael Beck's avatar
Michael Beck committed
561
562
563
564
565
566
567
	op_flags  => "c",
	irn_flags => "R",
	comment   => "represents a symbolic constant",
	attr      => "ident *id",
	init_attr => "\tset_arm_symconst_id(res, id);",
	reg_req   => { "out" => [ "gp" ] },
	attr_type   => "arm_SymConst_attr_t",
568
569
},

570
CmpBra => {
Michael Beck's avatar
Michael Beck committed
571
572
	op_flags  => "L|X|Y",
	state     => "pinned",
573
	comment   => "construct conditional branch: CMP A, B && JMPxx LABEL",
Michael Beck's avatar
Michael Beck committed
574
575
576
577
578
	mode      => "mode_T",
	attr      => "int proj_num",
	init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);",
	reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "none", "none"] },
	attr_type => "arm_CondJmp_attr_t",
579
580
},

Michael Beck's avatar
Michael Beck committed
581
SwitchJmp => {
Michael Beck's avatar
Michael Beck committed
582
583
584
585
586
587
588
589
590
	op_flags  => "L|X|Y",
	state     => "pinned",
	comment   => "construct switch",
	mode      => "mode_T",
	attr      => "int n_projs, long def_proj_num",
	init_attr => "\tset_arm_SwitchJmp_n_projs(res, n_projs);\n".
	             "\tset_arm_SwitchJmp_default_proj_num(res, def_proj_num);",
	reg_req   => { "in" => [ "gp" ], "out" => [ "none" ] },
	attr_type => "arm_SwitchJmp_attr_t",
591
592
593
594
},

# Load / Store

Michael Beck's avatar
Michael Beck committed
595
Load => {
Michael Beck's avatar
Michael Beck committed
596
597
598
599
600
601
602
	op_flags  => "L|F",
	irn_flags => "R",
	state     => "exc_pinned",
	comment   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
	reg_req   => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] },
	emit      => '. ldr %D0, [%S0, #0]',
	outs      => [ "res", "M" ],
Michael Beck's avatar
Michael Beck committed
603
604
605
},

Loadb => {
Michael Beck's avatar
Michael Beck committed
606
607
608
609
610
611
612
	op_flags  => "L|F",
	irn_flags => "R",
	state     => "exc_pinned",
	comment   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
	reg_req   => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] },
	emit      => '. ldrb %D0, [%S0, #0]',
	outs      => [ "res", "M" ],
Michael Beck's avatar
Michael Beck committed
613
614
615
},

Loadbs => {
Michael Beck's avatar
Michael Beck committed
616
617
618
619
620
621
622
	op_flags  => "L|F",
	irn_flags => "R",
	state     => "exc_pinned",
	comment   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
	reg_req   => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] },
	emit      => '. ldrsb %D0, [%S0, #0]',
	outs      => [ "res", "M" ],
Michael Beck's avatar
Michael Beck committed
623
624
625
},

Loadh => {
Michael Beck's avatar
Michael Beck committed
626
627
628
629
630
631
632
	op_flags  => "L|F",
	irn_flags => "R",
	state     => "exc_pinned",
	comment   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
	reg_req   => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] },
	emit      => '. ldrh %D0, [%S0, #0]',
	outs      => [ "res", "M" ],
Michael Beck's avatar
Michael Beck committed
633
634
635
},

Loadhs => {
Michael Beck's avatar
Michael Beck committed
636
637
638
639
640
641
642
	op_flags  => "L|F",
	irn_flags => "R",
	state     => "exc_pinned",
	comment   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
	reg_req   => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] },
	emit      => '. ldrsh %D0, [%S0, #0]',
	outs      => [ "res", "M" ],
Michael Beck's avatar
Michael Beck committed
643
644
645
},

Storeb => {
Michael Beck's avatar
Michael Beck committed
646
647
648
649
650
651
652
	op_flags  => "L|F",
	irn_flags => "R",
	state     => "exc_pinned",
	comment   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
	reg_req   => { "in" => [ "gp", "gp", "none" ], "out" => [ "none" ] },
	emit      => '. strb %S1, [%S0, #0]',
	mode      => "mode_M",
Michael Beck's avatar
Michael Beck committed
653
654
655
},

Storeh => {
Michael Beck's avatar
Michael Beck committed
656
657
658
659
660
661
662
	op_flags  => "L|F",
	irn_flags => "R",
	state     => "exc_pinned",
	comment   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
	reg_req   => { "in" => [ "gp", "gp", "none" ], out => [ "none" ] },
	emit      => '. strh %S1, [%S0, #0]',
	mode      => "mode_M",
Michael Beck's avatar
Michael Beck committed
663
664
665
},

Store => {
Michael Beck's avatar
Michael Beck committed
666
667
668
669
670
671
672
	op_flags  => "L|F",
	irn_flags => "R",
	state     => "exc_pinned",
	comment   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
	reg_req   => { "in" => [ "gp", "gp", "none" ], out => [ "none" ] },
	emit      => '. str %S1, [%S0, #0]',
	mode      => "mode_M",
Michael Beck's avatar
Michael Beck committed
673
674
675
},

StoreStackM4Inc => {
Michael Beck's avatar
Michael Beck committed
676
677
678
679
680
681
682
	op_flags  => "L|F",
	irn_flags => "R",
	state     => "exc_pinned",
	comment   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
	reg_req   => { "in" => [ "sp", "gp", "gp", "gp", "gp", "none" ], "out" => [ "gp", "none" ] },
	emit      => '. stmfd %S0!, {%S1, %S2, %S3, %S4}',
	outs      => [ "ptr", "M" ],
Michael Beck's avatar
Michael Beck committed
683
684
685
},

LoadStackM3 => {
Michael Beck's avatar
Michael Beck committed
686
687
688
689
690
691
692
	op_flags  => "L|F",
	irn_flags => "R",
	state     => "exc_pinned",
	comment   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
	reg_req   => { "in" => [ "sp", "none" ], "out" => [ "gp", "gp", "gp", "none" ] },
	emit      => '. ldmfd %S0, {%D0, %D1, %D2}',
	outs      => [ "res0", "res1", "res2", "M" ],
693
694
695
},


Michael Beck's avatar
Michael Beck committed
696
697
698
699
700
701
702
703
704
705
#---------------------------------------------------#
#    __                               _             #
#   / _|                             | |            #
#  | |_ _ __   __ _   _ __   ___   __| | ___  ___   #
#  |  _| '_ \ / _` | | '_ \ / _ \ / _` |/ _ \/ __|  #
#  | | | |_) | (_| | | | | | (_) | (_| |  __/\__ \  #
#  |_| | .__/ \__,_| |_| |_|\___/ \__,_|\___||___/  #
#      | |                                          #
#      |_|                                          #
#---------------------------------------------------#
706
707
708

# commutative operations

709
fpaAdf => {
Michael Beck's avatar
Michael Beck committed
710
711
712
713
714
	op_flags  => "C",
	irn_flags => "R",
	comment   => "construct FPA Add: Add(a, b) = Add(b, a) = a + b",
	reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
	emit      => '. adf%M %D0, %S0, %S1',
715
716
},

717
718
719
fpaAdf_i => {
	irn_flags => "R",
	comment   => "construct FPA Add: Add(a, b) = Add(b, a) = a + b",
Michael Beck's avatar
Michael Beck committed
720
721
722
	attr      => "long imm",
	init_attr => 'ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;',
723
724
725
726
727
728
729
	reg_req   => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
	emit      => '. adf%M %D0, %S0, %C',
},

fpaMuf => {
	op_flags  => "C",
	irn_flags => "R",
Michael Beck's avatar
Michael Beck committed
730
731
732
	comment   => "construct FPA Mul: Mul(a, b) = Mul(b, a) = a * b",
	reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
	emit      =>'. muf%M %D0, %S0, %S1',
733
734
},

735
736
737
fpaMuf_i => {
	irn_flags => "R",
	comment   => "construct FPA Mul: Mul(a, b) = Mul(b, a) = a * b",
Michael Beck's avatar
Michael Beck committed
738
739
740
	attr      => "long imm",
	init_attr => 'ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;',
741
742
743
744
745
	reg_req   => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
	emit      => '. muf%M %D0, %S0, %C',
},

fpaFml => {
Michael Beck's avatar
Michael Beck committed
746
	op_flags  => "C",
747
	irn_flags => "R",
Michael Beck's avatar
Michael Beck committed
748
749
750
	comment   => "construct FPA Fast Mul: Mul(a, b) = Mul(b, a) = a * b",
	reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
	emit      =>'. fml%M %D0, %S0, %S1',
751
752
},

Michael Beck's avatar
Michael Beck committed
753
fpaMax => {
Michael Beck's avatar
Michael Beck committed
754
755
756
757
758
	op_flags  => "C",
	irn_flags => "R",
	comment   => "construct FPA Max: Max(a, b) = Max(b, a) = a > b ? a : b",
	reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
	emit      =>'. fmax %S0, %S1, %D0',
759
760
},

Michael Beck's avatar
Michael Beck committed
761
fpaMin => {
Michael Beck's avatar
Michael Beck committed
762
763
764
765
766
	op_flags  => "C",
	irn_flags => "R",
	comment   => "construct FPA Min: Min(a, b) = Min(b, a) = a < b ? a : b",
	reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
	emit      =>'. fmin %S0, %S1, %D0',
767
768
769
770
},

# not commutative operations

771
fpaSuf => {
Michael Beck's avatar
Michael Beck committed
772
773
774
775
	irn_flags => "R",
	comment   => "construct FPA Sub: Sub(a, b) = a - b",
	reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
	emit      => '. suf%M %D0, %S0, %S1'
Michael Beck's avatar
Michael Beck committed
776
777
},

778
779
780
fpaSuf_i => {
	irn_flags => "R",
	comment   => "construct FPA Sub: Sub(a, b) = a - b",
Michael Beck's avatar
Michael Beck committed
781
782
783
	attr      => "long imm",
	init_attr => 'ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;',
784
785
786
787
788
	reg_req   => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
	emit      => '. suf%M %D0, %S0, %C'
},

fpaRsf => {
Michael Beck's avatar
Michael Beck committed
789
790
791
792
	irn_flags => "R",
	comment   => "construct FPA reverse Sub: Sub(a, b) = b - a",
	reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
	emit      => '. rsf%M %D0, %S0, %S1'
Michael Beck's avatar
Michael Beck committed
793
794
},

795
796
797
fpaRsf_i => {
	irn_flags => "R",
	comment   => "construct FPA reverse Sub: Sub(a, b) = b - a",
Michael Beck's avatar
Michael Beck committed
798
799
800
	attr      => "long imm",
	init_attr => 'ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;',
801
802
803
804
805
	reg_req   => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
	emit      => '. rsf%M %D0, %S0, %C'
},

fpaDvf => {
Michael Beck's avatar
Michael Beck committed
806
807
808
809
810
811
	comment   => "construct FPA Div: Div(a, b) = a / b",
	attr      => "ir_mode *op_mode",
	init_attr => "attr->op_mode = op_mode;",
	reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] },
	emit      =>'. dvf%M %D0, %S0, %S1',
	outs      => [ "res", "M" ],
Michael Beck's avatar
Michael Beck committed
812
813
},

814
815
fpaDvf_i => {
	comment   => "construct FPA Div: Div(a, b) = a / b",
Michael Beck's avatar
Michael Beck committed
816
817
818
	attr      => "ir_mode *op_mode, long imm",
	init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;',
819
820
821
822
823
824
	reg_req   => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] },
	emit      =>'. dvf%M %D0, %S0, %C',
	outs      => [ "res", "M" ],
},

fpaRdf => {
Michael Beck's avatar
Michael Beck committed
825
826
827
828
829
830
	comment   => "construct FPA reverse Div: Div(a, b) = b / a",
	attr      => "ir_mode *op_mode",
	init_attr => "attr->op_mode = op_mode;",
	reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] },
	emit      =>'. rdf%M %D0, %S0, %S1',
	outs      => [ "res", "M" ],
Michael Beck's avatar
Michael Beck committed
831
832
},

833
834
fpaRdf_i => {
	comment   => "construct FPA reverse Div: Div(a, b) = b / a",
Michael Beck's avatar
Michael Beck committed
835
836
837
	attr      => "ir_mode *op_mode, long imm",
	init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;',
838
839
840
841
842
843
	reg_req   => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] },
	emit      =>'. rdf%M %D0, %S0, %S1',
	outs      => [ "res", "M" ],
},

fpaFdv => {
Michael Beck's avatar
Michael Beck committed
844
845
846
847
848
849
	comment   => "construct FPA Fast Div: Div(a, b) = a / b",
	attr      => "ir_mode *op_mode",
	init_attr => "attr->op_mode = op_mode;",
	reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] },
	emit      =>'. fdv%M %D0, %S0, %S1',
	outs      => [ "res", "M" ],
Michael Beck's avatar
Michael Beck committed
850
851
},

852
853
fpaFdv_i => {
	comment   => "construct FPA Fast Div: Div(a, b) = a / b",
Michael Beck's avatar
Michael Beck committed
854
855
856
	attr      => "ir_mode *op_mode, long imm",
	init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;',
857
858
859
860
861
862
	reg_req   => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] },
	emit      =>'. fdv%M %D0, %S0, %C',
	outs      => [ "res", "M" ],
},

fpaFrd => {
Michael Beck's avatar
Michael Beck committed
863
864
865
866
867
868
	comment   => "construct FPA Fast reverse Div: Div(a, b) = b / a",
	attr      => "ir_mode *op_mode",
	init_attr => "attr->op_mode = op_mode;",
	reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] },
	emit      =>'. frd%M %D0, %S0, %S1',
	outs      => [ "res", "M" ],
Michael Beck's avatar
Michael Beck committed
869
870
},

871
872
fpaFrd_i => {
	comment   => "construct FPA Fast reverse Div: Div(a, b) = b / a",
Michael Beck's avatar
Michael Beck committed
873
874
875
	attr      => "ir_mode *op_mode, long imm",
	init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;',
876
877
878
879
880
881
	reg_req   => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] },
	emit      =>'. frd%M %D0, %S0, %C',
	outs      => [ "res", "M" ],
},

fpaMvf => {
Michael Beck's avatar
Michael Beck committed
882
883
884
885
	irn_flags => "R",
	comment   => "construct FPA Move: b = a",
	reg_req   => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
	emit      => '. mvf%M %S0, %D0',
886
887
},

888
889
890
fpaMvf_i => {
	irn_flags => "R",
	comment   => "represents a float constant",
Michael Beck's avatar
Michael Beck committed
891
892
	attr      => "long imm",
	init_attr => 'ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
893
	reg_req   => { "out" => [ "fpa" ] },
Michael Beck's avatar
Michael Beck committed
894
	emit      => '. mvf%M %D0, %C',
Michael Beck's avatar
Michael Beck committed
895
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;'
896
897
898
},

fpaMnf => {
Michael Beck's avatar
Michael Beck committed
899
900
901
902
	irn_flags => "R",
	comment   => "construct FPA Move Negated: b = -a",
	reg_req   => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
	emit      => '. mnf%M %S0, %D0',
903
904
},

905
906
907
fpaMnf_i => {
	irn_flags => "R",
	comment   => "represents a float constant",
Michael Beck's avatar
Michael Beck committed
908
909
	attr      => "long imm",
	init_attr => 'ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
910
	reg_req   => { "out" => [ "fpa" ] },
Michael Beck's avatar
Michael Beck committed
911
	emit      => '. mnf%M %D0, %C',
Michael Beck's avatar
Michael Beck committed
912
	cmp_attr  => 'return attr_a->imm_value != attr_b->imm_value;'
913
914
},

Michael Beck's avatar
Michael Beck committed
915
fpaAbs => {
Michael Beck's avatar
Michael Beck committed
916
917
918
919
	irn_flags => "R",
	comment   => "construct FPA Absolute value: fAbsd(a) = |a|",
	reg_req   => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
	emit      => '. abs%M %D0, %S0',
920
921
922
923
},

# other operations

Michael Beck's avatar
Michael Beck committed
924
fpaFlt => {
Michael Beck's avatar
Michael Beck committed
925
926
927
928
	irn_flags => "R",
	comment   => "construct a FPA integer->float conversion",
	reg_req   => { "in" => ["gp"], "out" => [ "fpa" ] },
	emit      => '. flt%M %D0, %S0',
929
930
},

Michael Beck's avatar
Michael Beck committed
931
fpaFix => {
Michael Beck's avatar
Michael Beck committed
932
933
934
935
	irn_flags => "R",
	comment   => "construct a FPA float->integer conversion",
	reg_req   => { "in" => ["fpa"], "out" => [ "gp" ] },
	emit      => '. fix %D0, %S0',
936
937
},

938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
fpaCmfBra => {
	op_flags  => "L|X|Y",
	state     => "pinned",
	comment   => "construct floating point Compare and Branch: CMF A, B && JMPxx LABEL",
	mode      => "mode_T",
	attr      => "int proj_num",
	init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);",
	reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "none", "none"] },
	attr_type => "arm_CondJmp_attr_t",
},

fpaCnfBra => {
	op_flags  => "L|X|Y",
	state     => "pinned",
	comment   => "construct floating point Compare negative and Branch: CMF A, -B && JMPxx LABEL",
	mode      => "mode_T",
	attr      => "int proj_num",
	init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);",
	reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "none", "none"] },
	attr_type => "arm_CondJmp_attr_t",
},

fpaCmfeBra => {
	op_flags  => "L|X|Y",
	state     => "pinned",
	comment   => "construct floating point Compare and Branch: CMF A, -B && JMPxx LABEL",
	mode      => "mode_T",
	attr      => "int proj_num",
	init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);",
	reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "none", "none"] },
	attr_type => "arm_CondJmp_attr_t",
},

fpaCnfeBra => {
	op_flags  => "L|X|Y",
	state     => "pinned",
	comment   => "construct floating point Compare and Branch: CMF A, -B && JMPxx LABEL",
	mode      => "mode_T",
	attr      => "int proj_num",
	init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);",
	reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "none", "none"] },
	attr_type => "arm_CondJmp_attr_t",
},

982
983
# Load / Store

Michael Beck's avatar
Michael Beck committed
984
fpaLdf => {
Michael Beck's avatar
Michael Beck committed
985
986
987
988
989
990
991
	op_flags  => "L|F",
	irn_flags => "R",
	state     => "exc_pinned",
	comment   => "construct FPA Load: Load(ptr, mem) = LD ptr",
	attr      => "ir_mode *op_mode",
	init_attr => "attr->op_mode = op_mode;",
	reg_req   => { "in" => [ "gp", "none" ], "out" => [ "fpa", "none" ] },
992
	emit      => '. ldf%M %D0, [%S0]',
Michael Beck's avatar
Michael Beck committed
993
	outs      => [ "res", "M" ],
Michael Beck's avatar
Michael Beck committed
994
995
996
},

fpaStf => {
Michael Beck's avatar
Michael Beck committed
997
998
999
1000
1001
1002
1003
	op_flags  => "L|F",
	irn_flags => "R",
	state     => "exc_pinned",
	comment   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
	attr      => "ir_mode *op_mode",
	init_attr => "attr->op_mode = op_mode;",
	reg_req   => { "in" => [ "gp", "fpa", "none" ], "out" => [ "none" ] },
1004
	emit      => '. stf%M %S1, [%S0]',
Michael Beck's avatar
Michael Beck committed
1005
	mode      => "mode_M",
Michael Beck's avatar
Michael Beck committed
1006
1007
1008
},

fpaDbl2GP => {
Michael Beck's avatar
Michael Beck committed
1009
1010
1011
1012
1013
	op_flags  => "L|F",
	irn_flags => "R",
	comment   => "construct fp double to 2 gp register transfer",
	reg_req   => { "in" => [ "fpa", "none" ], "out" => [ "gp", "gp", "none" ] },
	outs      => [ "low", "high", "M" ],
Michael Beck's avatar
Michael Beck committed
1014
1015
},

1016
AddSP => {
Michael Beck's avatar
Michael Beck committed
1017
1018
1019
1020
	irn_flags => "I",
	comment   => "construct Add to stack pointer",
	reg_req   => { in => [ "sp", "gp", "none" ], out => [ "in_r1", "none" ] },
	emit      => '. add %D0, %S0, %S1',
Michael Beck's avatar
Michael Beck committed
1021
	outs      => [ "stack:I|S", "M" ],
1022
1023
},

1024
SubSPandCopy => {
Michael Beck's avatar
Michael Beck committed
1025
#irn_flags => "I",
1026
	comment   => "construct Sub from stack pointer and copy to Register",
Michael Beck's avatar
Michael Beck committed
1027
1028
	reg_req   => { in => [ "sp", "gp", "none" ], out => [ "in_r1", "gp", "none" ] },
	ins       => [ "stack", "size", "mem" ],
1029
1030
	emit      => ". sub %D0, %S0, %S1\n".
	             ". mov sp, %D1",
Michael Beck's avatar
Michael Beck committed
1031
	outs      => [ "stack:I|S", "addr", "M" ],
1032
1033
1034
},

LdTls => {
Michael Beck's avatar
Michael Beck committed
1035
1036
1037
	irn_flags => "R",
	comment   => "load the TLS address",
	reg_req   => { out => [ "gp" ] },
1038
1039
1040
},


Michael Beck's avatar
Michael Beck committed
1041
1042
1043
1044
#
# floating point constants
#
fpaConst => {
Michael Beck's avatar
Michael Beck committed
1045
1046
1047
	op_flags  => "c",
	irn_flags => "R",
	comment   => "construct a floating point constant",
1048
	attr      => "tarval *tv",
Michael Beck's avatar
Michael Beck committed
1049
	init_attr => "attr->tv = tv;",
Michael Beck's avatar
Michael Beck committed
1050
1051
	mode      => "get_tarval_mode(tv)",
	reg_req   => { "out" => [ "fpa" ] },
Michael Beck's avatar
Michael Beck committed
1052
	attr_type => "arm_fpaConst_attr_t",
Michael Beck's avatar
Michael Beck committed
1053
}
Michael Beck's avatar
Michael Beck committed
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065

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

1066
); # end of %nodes