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

Matthias Braun's avatar
Matthias Braun committed
5
6
$new_emit_syntax = 1;

7
8
9
10
11
12
13
14
15
16
# the cpu architecture (ia32, ia64, mips, sparc, ppc, ...)

$arch = "TEMPLATE";

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

Christian Würdig's avatar
Christian Würdig committed
40
# op_flags: flags for the operation, OPTIONAL (default is "N")
41
42
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
#   K   irop_flag_keep
#
Christian Würdig's avatar
Christian Würdig committed
53
54
55
56
57
# irn_flags: special node flags, OPTIONAL (default is 0)
# following irn_flags are supported:
#   R   rematerializeable
#   N   not spillable
#   I   ignore for register allocation
58
#
Christian Würdig's avatar
Christian Würdig committed
59
# state: state of the operation, OPTIONAL (default is "floats")
60
61
62
63
64
65
66
67
68
69
#
# 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
#
70
71
72
# outs:  if a node defines more than one output, the names of the projections
#        nodes having outs having automatically the mode mode_T
#
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# 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
Christian Würdig's avatar
Christian Würdig committed
93
94
#   1 - caller save (register must be saved by the caller of a function)
#   2 - callee save (register must be saved by the called function)
95
#   4 - ignore (do not assign this register)
Christian Würdig's avatar
Christian Würdig committed
96
# NOTE: Last entry of each class is the largest Firm-Mode a register can hold
97
%reg_classes = (
Matthias Braun's avatar
Matthias Braun committed
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
	general_purpose => [
		{ name => "r0", type => 1 },
		{ name => "r1", type => 1 },
		{ name => "r2", type => 1 },
		{ name => "r3", type => 1 },
		{ name => "r4", type => 1 },
		{ name => "r5", type => 1 },
		{ name => "r6", type => 1 },
		{ name => "r7", type => 2 },
		{ name => "r8", type => 2 },
		{ name => "r9", type => 2 },
		{ name => "r10", type => 2 },
		{ name => "r11", type => 2 },
		{ name => "r12", type => 2 },
		{ name => "r13", type => 2 },
		{ name => "sp", realname => "r14", type => 4 },  # this is our stackpointer
		{ name => "bp", realname => "r15", type => 4 },  # this is out basepointer
		{ mode => "mode_Iu" }
	],
	floating_point  => [
		{ 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 => "f8", type => 1 },
		{ name => "f9", type => 1 },
		{ name => "f10", type => 1 },
		{ name => "f11", type => 1 },
		{ name => "f12", type => 1 },
		{ name => "f13", type => 1 },
		{ name => "f14", type => 1 },
		{ name => "f15", type => 1 },
		{ mode => "mode_D" }
	]
136
137
); # %reg_classes

Matthias Braun's avatar
Matthias Braun committed
138
%emit_templates = (
139
140
141
142
143
144
145
146
147
148
149
150
151
    S1 => "${arch}_emit_source_register(node, 0);",
    S2 => "${arch}_emit_source_register(node, 1);",
    S3 => "${arch}_emit_source_register(node, 2);",
    S4 => "${arch}_emit_source_register(node, 3);",
    S5 => "${arch}_emit_source_register(node, 4);",
    S6 => "${arch}_emit_source_register(node, 5);",
    D1 => "${arch}_emit_dest_register(node, 0);",
    D2 => "${arch}_emit_dest_register(node, 1);",
    D3 => "${arch}_emit_dest_register(node, 2);",
    D4 => "${arch}_emit_dest_register(node, 3);",
    D5 => "${arch}_emit_dest_register(node, 4);",
    D6 => "${arch}_emit_dest_register(node, 5);",
	C  => "${arch}_emit_immediate(node);"
Matthias Braun's avatar
Matthias Braun committed
152
153
);

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#--------------------------------------------------#
#                        _                         #
#                       (_)                        #
#  _ __   _____      __  _ _ __    ___  _ __  ___  #
# | '_ \ / _ \ \ /\ / / | | '__|  / _ \| '_ \/ __| #
# | | | |  __/\ V  V /  | | |    | (_) | |_) \__ \ #
# |_| |_|\___| \_/\_/   |_|_|     \___/| .__/|___/ #
#                                      | |         #
#                                      |_|         #
#--------------------------------------------------#

%nodes = (

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

# commutative operations

Matthias Braun's avatar
Matthias Braun committed
180
181
182
183
184
185
Add => {
  op_flags  => "C",
  irn_flags => "R",
  comment   => "construct Add: Add(a, b) = Add(b, a) = a + b",
  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. add %S1, %S2, %D1'
186
187
},

Matthias Braun's avatar
Matthias Braun committed
188
189
190
191
192
Add_i => {
  irn_flags => "R",
  comment   => "construct Add: Add(a, const) = Add(const, a) = a + const",
  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. add %S1, %C, %D1'
193
194
},

Matthias Braun's avatar
Matthias Braun committed
195
196
197
198
199
200
Mul => {
  op_flags  => "C",
  irn_flags => "R",
  comment   => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "general_purpose" ] },
  emit      =>'. mul %S1, %S2, %D1'
201
202
},

Matthias Braun's avatar
Matthias Braun committed
203
204
205
206
207
Mul_i => {
  irn_flags => "R",
  comment   => "construct Mul: Mul(a, const) = Mul(const, a) = a * const",
  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. mul %S1, %C, %D1'
208
209
},

Matthias Braun's avatar
Matthias Braun committed
210
211
212
213
214
215
And => {
  op_flags  => "C",
  irn_flags => "R",
  comment   => "construct And: And(a, b) = And(b, a) = a AND b",
  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. and %S1, %S2, %D1'
216
217
},

Matthias Braun's avatar
Matthias Braun committed
218
219
220
221
222
And_i => {
  irn_flags => "R",
  comment   => "construct And: And(a, const) = And(const, a) = a AND const",
  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. and %S1, %C, %D1'
223
224
},

Matthias Braun's avatar
Matthias Braun committed
225
226
227
228
229
230
Or => {
  op_flags  => "C",
  irn_flags => "R",
  comment   => "construct Or: Or(a, b) = Or(b, a) = a OR b",
  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. or %S1, %S2, %D1'
231
232
},

Matthias Braun's avatar
Matthias Braun committed
233
234
235
236
237
238
Or_i => {
  op_flags  => "C",
  irn_flags => "R",
  comment   => "construct Or: Or(a, const) = Or(const, a) = a OR const",
  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. or %S1, %C, %D1'
239
240
},

Matthias Braun's avatar
Matthias Braun committed
241
242
243
244
245
246
Eor => {
  op_flags  => "C",
  irn_flags => "R",
  comment   => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b",
  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. xor %S1, %S2, %D1'
247
248
},

Matthias Braun's avatar
Matthias Braun committed
249
250
251
252
253
Eor_i => {
  irn_flags => "R",
  comment   => "construct Eor: Eor(a, const) = Eor(const, a) = a EOR const",
  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. xor %S1, %C, %D1'
254
255
256
257
},

# not commutative operations

Matthias Braun's avatar
Matthias Braun committed
258
259
260
261
262
Sub => {
  irn_flags => "R",
  comment   => "construct Sub: Sub(a, b) = a - b",
  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. sub %S1, %S2, %D1'
263
264
},

Matthias Braun's avatar
Matthias Braun committed
265
266
267
268
269
Sub_i => {
  irn_flags => "R",
  comment   => "construct Sub: Sub(a, const) = a - const",
  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. subl %S1, %C, %D1'
270
271
},

Matthias Braun's avatar
Matthias Braun committed
272
273
274
275
276
Shl => {
  irn_flags => "R",
  comment   => "construct Shl: Shl(a, b) = a << b",
  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. shl %S1, %S2, %D1'
277
278
},

Matthias Braun's avatar
Matthias Braun committed
279
280
281
282
283
Shl_i => {
  irn_flags => "R",
  comment   => "construct Shl: Shl(a, const) = a << const",
  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. shl %S1, %C, %D1'
284
285
},

Matthias Braun's avatar
Matthias Braun committed
286
287
288
289
290
Shr => {
  irn_flags => "R",
  comment   => "construct Shr: Shr(a, b) = a >> b",
  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "in_r1" ] },
  emit      => '. shr %S2, %D1'
291
292
},

Matthias Braun's avatar
Matthias Braun committed
293
294
295
296
297
Shr_i => {
  irn_flags => "R",
  comment   => "construct Shr: Shr(a, const) = a >> const",
  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. shr %S1, %C, %D1'
298
299
},

Matthias Braun's avatar
Matthias Braun committed
300
301
302
303
304
RotR => {
  irn_flags => "R",
  comment   => "construct RotR: RotR(a, b) = a ROTR b",
  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. ror %S1, %S2, %D1'
305
306
},

Matthias Braun's avatar
Matthias Braun committed
307
308
309
310
311
RotL => {
  irn_flags => "R",
  comment   => "construct RotL: RotL(a, b) = a ROTL b",
  reg_req   => { in => [ "general_purpose", "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. rol %S1, %S2, %D1'
312
313
},

Matthias Braun's avatar
Matthias Braun committed
314
315
316
317
318
RotL_i => {
  irn_flags => "R",
  comment   => "construct RotL: RotL(a, const) = a ROTL const",
  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. rol %S1, %C, %D1'
319
320
},

Matthias Braun's avatar
Matthias Braun committed
321
322
323
324
325
Minus => {
  irn_flags => "R",
  comment   => "construct Minus: Minus(a) = -a",
  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. neg %S1, %D1'
326
327
},

Matthias Braun's avatar
Matthias Braun committed
328
329
330
331
332
Inc => {
  irn_flags => "R",
  comment   => "construct Increment: Inc(a) = a++",
  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. inc %S1, %D1'
333
334
},

Matthias Braun's avatar
Matthias Braun committed
335
336
337
338
339
Dec => {
  irn_flags => "R",
  comment   => "construct Decrement: Dec(a) = a--",
  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. dec %S1, %D1'
340
341
},

Matthias Braun's avatar
Matthias Braun committed
342
343
344
345
346
347
Not => {
  arity       => 1,
  remat       => 1,
  comment     => "construct Not: Not(a) = !a",
  reg_req     => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
  emit        => '. not %S1, %D1'
348
349
350
351
},

# other operations

Matthias Braun's avatar
Matthias Braun committed
352
353
354
355
356
357
358
Const => {
  op_flags  => "c",
  irn_flags => "R",
  comment   => "represents an integer constant",
  reg_req   => { out => [ "general_purpose" ] },
  emit      => '. mov %C, %D1',
  cmp_attr  =>
359
'
Christian Würdig's avatar
Christian Würdig committed
360
	/* TODO: compare Const attributes */
361
362
363
364
365
366
    return 1;
'
},

# Load / Store

Matthias Braun's avatar
Matthias Braun committed
367
368
369
370
371
372
373
Load => {
  op_flags  => "L|F",
  irn_flags => "R",
  state     => "exc_pinned",
  comment   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
  reg_req   => { in => [ "general_purpose", "none" ], out => [ "general_purpose" ] },
  emit      => '. mov (%S1), %D1'
374
375
},

Matthias Braun's avatar
Matthias Braun committed
376
377
378
379
380
381
382
Store => {
  op_flags  => "L|F",
  irn_flags => "R",
  state     => "exc_pinned",
  comment   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
  reg_req   => { in => [ "general_purpose", "general_purpose", "none" ] },
  emit      => '. movl %S2, (%S1)'
383
384
385
386
387
388
389
390
391
392
393
394
395
},

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

# commutative operations

Matthias Braun's avatar
Matthias Braun committed
396
397
398
399
400
401
fAdd => {
  op_flags  => "C",
  irn_flags => "R",
  comment   => "construct FP Add: Add(a, b) = Add(b, a) = a + b",
  reg_req   => { in => [ "floating_point", "floating_point" ], out => [ "floating_point" ] },
  emit      => '. fadd %S1, %S2, %D1'
402
403
},

Matthias Braun's avatar
Matthias Braun committed
404
405
406
407
408
fMul => {
  op_flags  => "C",
  comment   => "construct FP Mul: Mul(a, b) = Mul(b, a) = a * b",
  reg_req   => { in => [ "floating_point", "floating_point" ], out => [ "floating_point" ] },
  emit      =>'. fmul %S1, %S2, %D1'
409
410
},

Matthias Braun's avatar
Matthias Braun committed
411
412
413
414
415
416
fMax => {
  op_flags  => "C",
  irn_flags => "R",
  comment   => "construct FP Max: Max(a, b) = Max(b, a) = a > b ? a : b",
  reg_req   => { in => [ "floating_point", "floating_point" ], out => [ "floating_point" ] },
  emit      =>'. fmax %S1, %S2, %D1'
417
418
},

Matthias Braun's avatar
Matthias Braun committed
419
420
421
422
423
424
fMin => {
  op_flags  => "C",
  irn_flags => "R",
  comment   => "construct FP Min: Min(a, b) = Min(b, a) = a < b ? a : b",
  reg_req   => { in => [ "floating_point", "floating_point" ], out => [ "floating_point" ] },
  emit      =>'. fmin %S1, %S2, %D1'
425
426
427
428
},

# not commutative operations

Matthias Braun's avatar
Matthias Braun committed
429
430
431
432
433
fSub => {
  irn_flags => "R",
  comment   => "construct FP Sub: Sub(a, b) = a - b",
  reg_req   => { in => [ "floating_point", "floating_point" ], out => [ "floating_point" ] },
  emit      => '. fsub %S1, %S2, %D1'
434
435
},

Matthias Braun's avatar
Matthias Braun committed
436
437
438
439
fDiv => {
  comment   => "construct FP Div: Div(a, b) = a / b",
  reg_req   => { in => [ "floating_point", "floating_point" ], out => [ "floating_point" ] },
  emit      => '. fdiv %S1, %S2, %D1'
440
441
},

Matthias Braun's avatar
Matthias Braun committed
442
443
444
445
446
fMinus => {
  irn_flags => "R",
  comment   => "construct FP Minus: Minus(a) = -a",
  reg_req   => { in => [ "floating_point" ], out => [ "floating_point" ] },
  emit      => '. fneg %S1, %D1'
447
448
449
450
},

# other operations

Matthias Braun's avatar
Matthias Braun committed
451
452
453
454
455
456
457
fConst => {
  op_flags  => "c",
  irn_flags => "R",
  comment   => "represents a FP constant",
  reg_req   => { out => [ "floating_point" ] },
  emit      => '. fmov %C, %D1',
  cmp_attr  =>
458
'
Christian Würdig's avatar
Christian Würdig committed
459
460
	/* TODO: compare fConst attributes */
	return 1;
461
462
463
464
465
'
},

# Load / Store

Matthias Braun's avatar
Matthias Braun committed
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
fLoad => {
  op_flags  => "L|F",
  irn_flags => "R",
  state     => "exc_pinned",
  comment   => "construct FP Load: Load(ptr, mem) = LD ptr",
  reg_req   => { in => [ "general_purpose", "none" ], out => [ "floating_point" ] },
  emit      => '. fmov (%S1), %D1'
},

fStore => {
  op_flags  => "L|F",
  irn_flags => "R",
  state     => "exc_pinned",
  comment   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
  reg_req   => { in => [ "general_purpose", "floating_point", "none" ] },
  emit      => '. fmov %S2, (%S1)'
Christian Würdig's avatar
Christian Würdig committed
482
},
483
484

); # end of %nodes