TEMPLATE_spec.pl 15.8 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
#   cmp_attr  => "c source code for comparing node attributes", # optional
29
30
31
#   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
Matthias Braun's avatar
Matthias Braun committed
32
#   emit      => "emit code with templates",   # optional for virtual nodes
33
#   attr      => "additional attribute arguments for constructor", # optional
34
35
36
37
38
#   init_attr => "emit attribute initialization template",         # optional
#   rd_constructor => "c source code which constructs an ir_node", # optional
#   hash_func => "name of the hash function for this operation",   # optional, get the default hash function else
#   latency   => "latency of this operation (can be float)"        # optional
#   attr_type => "name of the attribute struct",                   # optional
39
40
41
42
43
44
# },
#
# ... # (all nodes you need to describe)
#
# ); # close the %nodes initializer

Christian Würdig's avatar
Christian Würdig committed
45
# op_flags: flags for the operation, OPTIONAL (default is "N")
46
47
48
49
50
51
52
53
54
55
56
57
# 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
58
59
60
61
62
# irn_flags: special node flags, OPTIONAL (default is 0)
# following irn_flags are supported:
#   R   rematerializeable
#   N   not spillable
#   I   ignore for register allocation
63
#
Christian Würdig's avatar
Christian Würdig committed
64
# state: state of the operation, OPTIONAL (default is "floats")
65
66
67
68
69
70
71
72
73
74
#
# 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
#
75
76
77
# outs:  if a node defines more than one output, the names of the projections
#        nodes having outs having automatically the mode mode_T
#
78
79
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

# register types:
#   0 - no special type
Christian Würdig's avatar
Christian Würdig committed
98
99
#   1 - caller save (register must be saved by the caller of a function)
#   2 - callee save (register must be saved by the called function)
100
#   4 - ignore (do not assign this register)
Christian Würdig's avatar
Christian Würdig committed
101
# NOTE: Last entry of each class is the largest Firm-Mode a register can hold
102
%reg_classes = (
Matthias Braun's avatar
Matthias Braun committed
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
136
137
138
139
140
	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" }
	]
141
142
); # %reg_classes

Matthias Braun's avatar
Matthias Braun committed
143
%emit_templates = (
144
145
146
147
148
149
150
151
152
153
154
155
156
    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
157
158
);

159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#--------------------------------------------------#
#                        _                         #
#                       (_)                        #
#  _ __   _____      __  _ _ __    ___  _ __  ___  #
# | '_ \ / _ \ \ /\ / / | | '__|  / _ \| '_ \/ __| #
# | | | |  __/\ V  V /  | | |    | (_) | |_) \__ \ #
# |_| |_|\___| \_/\_/   |_|_|     \___/| .__/|___/ #
#                                      | |         #
#                                      |_|         #
#--------------------------------------------------#

%nodes = (

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

# commutative operations

Matthias Braun's avatar
Matthias Braun committed
185
186
187
188
189
190
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'
191
192
},

Matthias Braun's avatar
Matthias Braun committed
193
194
195
196
197
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'
198
199
},

Matthias Braun's avatar
Matthias Braun committed
200
201
202
203
204
205
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'
206
207
},

Matthias Braun's avatar
Matthias Braun committed
208
209
210
211
212
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'
213
214
},

Matthias Braun's avatar
Matthias Braun committed
215
216
217
218
219
220
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'
221
222
},

Matthias Braun's avatar
Matthias Braun committed
223
224
225
226
227
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'
228
229
},

Matthias Braun's avatar
Matthias Braun committed
230
231
232
233
234
235
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'
236
237
},

Matthias Braun's avatar
Matthias Braun committed
238
239
240
241
242
243
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'
244
245
},

Matthias Braun's avatar
Matthias Braun committed
246
247
248
249
250
251
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'
252
253
},

Matthias Braun's avatar
Matthias Braun committed
254
255
256
257
258
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'
259
260
261
262
},

# not commutative operations

Matthias Braun's avatar
Matthias Braun committed
263
264
265
266
267
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'
268
269
},

Matthias Braun's avatar
Matthias Braun committed
270
271
272
273
274
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'
275
276
},

Matthias Braun's avatar
Matthias Braun committed
277
278
279
280
281
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'
282
283
},

Matthias Braun's avatar
Matthias Braun committed
284
285
286
287
288
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'
289
290
},

Matthias Braun's avatar
Matthias Braun committed
291
292
293
294
295
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'
296
297
},

Matthias Braun's avatar
Matthias Braun committed
298
299
300
301
302
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'
303
304
},

Matthias Braun's avatar
Matthias Braun committed
305
306
307
308
309
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'
310
311
},

Matthias Braun's avatar
Matthias Braun committed
312
313
314
315
316
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'
317
318
},

Matthias Braun's avatar
Matthias Braun committed
319
320
321
322
323
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'
324
325
},

Matthias Braun's avatar
Matthias Braun committed
326
327
328
329
330
Minus => {
  irn_flags => "R",
  comment   => "construct Minus: Minus(a) = -a",
  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. neg %S1, %D1'
331
332
},

Matthias Braun's avatar
Matthias Braun committed
333
334
335
336
337
Inc => {
  irn_flags => "R",
  comment   => "construct Increment: Inc(a) = a++",
  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. inc %S1, %D1'
338
339
},

Matthias Braun's avatar
Matthias Braun committed
340
341
342
343
344
Dec => {
  irn_flags => "R",
  comment   => "construct Decrement: Dec(a) = a--",
  reg_req   => { in => [ "general_purpose" ], out => [ "general_purpose" ] },
  emit      => '. dec %S1, %D1'
345
346
},

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

# other operations

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

# Load / Store

Matthias Braun's avatar
Matthias Braun committed
372
373
374
375
376
377
378
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'
379
380
},

Matthias Braun's avatar
Matthias Braun committed
381
382
383
384
385
386
387
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)'
388
389
390
391
392
393
394
395
396
397
398
399
400
},

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

# commutative operations

Matthias Braun's avatar
Matthias Braun committed
401
402
403
404
405
406
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'
407
408
},

Matthias Braun's avatar
Matthias Braun committed
409
410
411
412
413
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'
414
415
},

Matthias Braun's avatar
Matthias Braun committed
416
417
418
419
420
421
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'
422
423
},

Matthias Braun's avatar
Matthias Braun committed
424
425
426
427
428
429
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'
430
431
432
433
},

# not commutative operations

Matthias Braun's avatar
Matthias Braun committed
434
435
436
437
438
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'
439
440
},

Matthias Braun's avatar
Matthias Braun committed
441
442
443
444
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'
445
446
},

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

# other operations

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

# Load / Store

Matthias Braun's avatar
Matthias Braun committed
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
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
487
},
488
489

); # end of %nodes