Fixed r26620.
[libfirm] / ir / be / TEMPLATE / TEMPLATE_spec.pl
1 # Creation: 2006/02/13
2 # $Id$
3 # This is a template specification for the Firm-Backend
4
5 $new_emit_syntax = 1;
6
7 # the cpu architecture (ia32, ia64, mips, sparc, ppc, ...)
8
9 $arch = "TEMPLATE";
10
11 # The node description is done as a perl hash initializer with the
12 # following structure:
13 #
14 # %nodes = (
15 #
16 # <op-name> => {
17 #   op_flags  => "N|L|C|X|I|F|Y|H|c|K",                 # optional
18 #   irn_flags => "R|N|I"                                # optional
19 #   arity     => "0|1|2|3 ... |variable|dynamic|any",   # optional
20 #   state     => "floats|pinned|mem_pinned|exc_pinned", # optional
21 #   args      => [
22 #                    { type => "type 1", name => "name 1" },
23 #                    { type => "type 2", name => "name 2" },
24 #                    ...
25 #                  ],
26 #   comment   => "any comment for constructor",  # optional
27 #   reg_req   => { in => [ "reg_class|register" ], out => [ "reg_class|register|in_rX" ] },
28 #   cmp_attr  => "c source code for comparing node attributes", # optional
29 #   outs      => { "out1", "out2" },# optional, creates pn_op_out1, ... consts
30 #   ins       => { "in1", "in2" },  # optional, creates n_op_in1, ... consts
31 #   mode      => "mode_Iu",         # optional, predefines the mode
32 #   emit      => "emit code with templates",   # optional for virtual nodes
33 #   attr      => "additional attribute arguments for constructor", # optional
34 #   init_attr => "emit attribute initialization template",         # optional
35 #   rd_constructor => "c source code which constructs an ir_node", # optional
36 #   hash_func => "name of the hash function for this operation",   # optional, get the default hash function else
37 #   latency   => "latency of this operation (can be float)"        # optional
38 #   attr_type => "name of the attribute struct",                   # optional
39 # },
40 #
41 # ... # (all nodes you need to describe)
42 #
43 # ); # close the %nodes initializer
44
45 # op_flags: flags for the operation, OPTIONAL (default is "N")
46 # the op_flags correspond to the firm irop_flags:
47 #   N   irop_flag_none
48 #   L   irop_flag_labeled
49 #   C   irop_flag_commutative
50 #   X   irop_flag_cfopcode
51 #   I   irop_flag_ip_cfopcode
52 #   F   irop_flag_fragile
53 #   Y   irop_flag_forking
54 #   H   irop_flag_highlevel
55 #   c   irop_flag_constlike
56 #   K   irop_flag_keep
57 #
58 # irn_flags: special node flags, OPTIONAL (default is 0)
59 # following irn_flags are supported:
60 #   R   rematerializeable
61 #   N   not spillable
62 #   I   ignore for register allocation
63 #
64 # state: state of the operation, OPTIONAL (default is "floats")
65 #
66 # arity: arity of the operation, MUST NOT BE OMITTED
67 #
68 # args:  the OPTIONAL arguments of the node constructor (debug, irg and block
69 #        are always the first 3 arguments and are always autmatically
70 #        created)
71 #        If this key is missing the following arguments will be created:
72 #        for i = 1 .. arity: ir_node *op_i
73 #        ir_mode *mode
74 #
75 # outs:  if a node defines more than one output, the names of the projections
76 #        nodes having outs having automatically the mode mode_T
77 #
78 # comment: OPTIONAL comment for the node constructor
79 #
80 # rd_constructor: for every operation there will be a
81 #      new_rd_<arch>_<op-name> function with the arguments from above
82 #      which creates the ir_node corresponding to the defined operation
83 #      you can either put the complete source code of this function here
84 #
85 #      This key is OPTIONAL. If omitted, the following constructor will
86 #      be created:
87 #      if (!op_<arch>_<op-name>) assert(0);
88 #      for i = 1 to arity
89 #         set in[i] = op_i
90 #      done
91 #      res = new_ir_node(db, irg, block, op_<arch>_<op-name>, mode, arity, in)
92 #      return res
93 #
94 # NOTE: rd_constructor and args are only optional if and only if arity is 0,1,2 or 3
95
96 # register types:
97 #   0 - no special type
98 #   1 - caller save (register must be saved by the caller of a function)
99 #   2 - callee save (register must be saved by the called function)
100 #   4 - ignore (do not assign this register)
101 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
102 %reg_classes = (
103         gp => [
104                 { name => "r0", type => 1 },
105                 { name => "r1", type => 1 },
106                 { name => "r2", type => 1 },
107                 { name => "r3", type => 1 },
108                 { name => "r4", type => 1 },
109                 { name => "r5", type => 1 },
110                 { name => "r6", type => 1 },
111                 { name => "r7", type => 2 },
112                 { name => "r8", type => 2 },
113                 { name => "r9", type => 2 },
114                 { name => "r10", type => 2 },
115                 { name => "r11", type => 2 },
116                 { name => "r12", type => 2 },
117                 { name => "r13", type => 2 },
118                 { name => "sp", realname => "r14", type => 4 },  # stackpointer
119                 { name => "bp", realname => "r15", type => 4 },  # basepointer
120                 { mode => "mode_Iu" }
121         ],
122         fp => [
123                 { name => "f0", type => 1 },
124                 { name => "f1", type => 1 },
125                 { name => "f2", type => 1 },
126                 { name => "f3", type => 1 },
127                 { name => "f4", type => 1 },
128                 { name => "f5", type => 1 },
129                 { name => "f6", type => 1 },
130                 { name => "f7", type => 1 },
131                 { name => "f8", type => 1 },
132                 { name => "f9", type => 1 },
133                 { name => "f10", type => 1 },
134                 { name => "f11", type => 1 },
135                 { name => "f12", type => 1 },
136                 { name => "f13", type => 1 },
137                 { name => "f14", type => 1 },
138                 { name => "f15", type => 1 },
139                 { mode => "mode_D" }
140         ]
141 );
142
143 %emit_templates = (
144         S1 => "${arch}_emit_source_register(node, 0);",
145         S2 => "${arch}_emit_source_register(node, 1);",
146         S3 => "${arch}_emit_source_register(node, 2);",
147         S4 => "${arch}_emit_source_register(node, 3);",
148         S5 => "${arch}_emit_source_register(node, 4);",
149         S6 => "${arch}_emit_source_register(node, 5);",
150         D1 => "${arch}_emit_dest_register(node, 0);",
151         D2 => "${arch}_emit_dest_register(node, 1);",
152         D3 => "${arch}_emit_dest_register(node, 2);",
153         D4 => "${arch}_emit_dest_register(node, 3);",
154         D5 => "${arch}_emit_dest_register(node, 4);",
155         D6 => "${arch}_emit_dest_register(node, 5);",
156         C  => "${arch}_emit_immediate(node);"
157 );
158
159 %nodes = (
160
161 # Integer nodes
162
163 Add => {
164         op_flags  => "C",
165         irn_flags => "R",
166         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
167         emit      => '. add %S1, %S2, %D1'
168 },
169
170 Add_i => {
171         irn_flags => "R",
172         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
173         emit      => '. add %S1, %C, %D1'
174 },
175
176 Mul => {
177         op_flags  => "C",
178         irn_flags => "R",
179         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
180         emit      =>'. mul %S1, %S2, %D1'
181 },
182
183 Mul_i => {
184         irn_flags => "R",
185         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
186         emit      => '. mul %S1, %C, %D1'
187 },
188
189 And => {
190         op_flags  => "C",
191         irn_flags => "R",
192         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
193         emit      => '. and %S1, %S2, %D1'
194 },
195
196 And_i => {
197         irn_flags => "R",
198         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
199         emit      => '. and %S1, %C, %D1'
200 },
201
202 Or => {
203         op_flags  => "C",
204         irn_flags => "R",
205         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
206         emit      => '. or %S1, %S2, %D1'
207 },
208
209 Or_i => {
210         op_flags  => "C",
211         irn_flags => "R",
212         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
213         emit      => '. or %S1, %C, %D1'
214 },
215
216 Eor => {
217         op_flags  => "C",
218         irn_flags => "R",
219         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
220         emit      => '. xor %S1, %S2, %D1'
221 },
222
223 Eor_i => {
224         irn_flags => "R",
225         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
226         emit      => '. xor %S1, %C, %D1'
227 },
228
229 Sub => {
230         irn_flags => "R",
231         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
232         emit      => '. sub %S1, %S2, %D1'
233 },
234
235 Sub_i => {
236         irn_flags => "R",
237         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
238         emit      => '. subl %S1, %C, %D1'
239 },
240
241 Shl => {
242         irn_flags => "R",
243         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
244         emit      => '. shl %S1, %S2, %D1'
245 },
246
247 Shl_i => {
248         irn_flags => "R",
249         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
250         emit      => '. shl %S1, %C, %D1'
251 },
252
253 Shr => {
254         irn_flags => "R",
255         reg_req   => { in => [ "gp", "gp" ], out => [ "in_r1" ] },
256         emit      => '. shr %S2, %D1'
257 },
258
259 Shr_i => {
260         irn_flags => "R",
261         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
262         emit      => '. shr %S1, %C, %D1'
263 },
264
265 RotR => {
266         irn_flags => "R",
267         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
268         emit      => '. ror %S1, %S2, %D1'
269 },
270
271 RotL => {
272         irn_flags => "R",
273         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
274         emit      => '. rol %S1, %S2, %D1'
275 },
276
277 RotL_i => {
278         irn_flags => "R",
279         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
280         emit      => '. rol %S1, %C, %D1'
281 },
282
283 Minus => {
284         irn_flags => "R",
285         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
286         emit      => '. neg %S1, %D1'
287 },
288
289 Inc => {
290         irn_flags => "R",
291         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
292         emit      => '. inc %S1, %D1'
293 },
294
295 Dec => {
296         irn_flags => "R",
297         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
298         emit      => '. dec %S1, %D1'
299 },
300
301 Not => {
302         arity       => 1,
303         remat       => 1,
304         reg_req     => { in => [ "gp" ], out => [ "gp" ] },
305         emit        => '. not %S1, %D1'
306 },
307
308 Const => {
309         op_flags  => "c",
310         irn_flags => "R",
311         reg_req   => { out => [ "gp" ] },
312         emit      => '. mov %C, %D1',
313         cmp_attr  =>
314 '
315         /* TODO: compare Const attributes */
316     return 1;
317 '
318 },
319
320 # Control Flow
321
322 Jmp => {
323         state    => "pinned",
324         op_flags => "X",
325         reg_req  => { out => [ "none" ] },
326         mode     => "mode_X",
327 },
328
329 # Load / Store
330
331 Load => {
332         op_flags  => "L|F",
333         irn_flags => "R",
334         state     => "exc_pinned",
335         reg_req   => { in => [ "gp", "none" ], out => [ "gp" ] },
336         emit      => '. mov (%S1), %D1'
337 },
338
339 Store => {
340         op_flags  => "L|F",
341         irn_flags => "R",
342         state     => "exc_pinned",
343         reg_req   => { in => [ "gp", "gp", "none" ] },
344         emit      => '. movl %S2, (%S1)'
345 },
346
347 # Floating Point operations
348
349 fAdd => {
350         op_flags  => "C",
351         irn_flags => "R",
352         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
353         emit      => '. fadd %S1, %S2, %D1'
354 },
355
356 fMul => {
357         op_flags  => "C",
358         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
359         emit      =>'. fmul %S1, %S2, %D1'
360 },
361
362 fMax => {
363         op_flags  => "C",
364         irn_flags => "R",
365         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
366         emit      =>'. fmax %S1, %S2, %D1'
367 },
368
369 fMin => {
370         op_flags  => "C",
371         irn_flags => "R",
372         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
373         emit      =>'. fmin %S1, %S2, %D1'
374 },
375
376 fSub => {
377         irn_flags => "R",
378         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
379         emit      => '. fsub %S1, %S2, %D1'
380 },
381
382 fDiv => {
383         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
384         emit      => '. fdiv %S1, %S2, %D1'
385 },
386
387 fMinus => {
388         irn_flags => "R",
389         reg_req   => { in => [ "fp" ], out => [ "fp" ] },
390         emit      => '. fneg %S1, %D1'
391 },
392
393 fConst => {
394         op_flags  => "c",
395         irn_flags => "R",
396         reg_req   => { out => [ "fp" ] },
397         emit      => '. fmov %C, %D1',
398         cmp_attr  =>
399 '
400         /* TODO: compare fConst attributes */
401         return 1;
402 '
403 },
404
405 # Load / Store
406
407 fLoad => {
408         op_flags  => "L|F",
409         irn_flags => "R",
410         state     => "exc_pinned",
411         reg_req   => { in => [ "gp", "none" ], out => [ "fp" ] },
412         emit      => '. fmov (%S1), %D1'
413 },
414
415 fStore => {
416         op_flags  => "L|F",
417         irn_flags => "R",
418         state     => "exc_pinned",
419         reg_req   => { in => [ "gp", "fp", "none" ] },
420         emit      => '. fmov %S2, (%S1)'
421 },
422
423 );