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