4025c8a0695ea9d541a1eb3100b6b7b0195e883d
[libfirm] / ir / be / TEMPLATE / TEMPLATE_spec.pl
1 # Creation: 2006/02/13
2 # $Id$
3
4 # the cpu architecture (ia32, ia64, mips, sparc, ppc, ...)
5
6 $arch = "TEMPLATE";
7
8 #
9 # Modes
10 #
11 $mode_gp  = "mode_Iu"; # mode used by general purpose registers
12 $mode_fp  = "mode_E";  # mode used by floatingpoint registers
13
14 # The node description is done as a perl hash initializer with the
15 # following structure:
16 #
17 # %nodes = (
18 #
19 # <op-name> => {
20 #   arity     => "0|1|2|3 ... |variable|dynamic|any",   # optional
21 #   state     => "floats|pinned|mem_pinned|exc_pinned", # optional
22 #   args      => [
23 #                    { type => "type 1", name => "name 1" },
24 #                    { type => "type 2", name => "name 2" },
25 #                    ...
26 #                  ],
27 #   comment   => "any comment for constructor",  # optional
28 #   reg_req   => { in => [ "reg_class|register" ], out => [ "reg_class|register|in_rX" ] },
29 #   cmp_attr  => "c source code for comparing node attributes", # optional
30 #   outs      => { "out1", "out2" },# optional, creates pn_op_out1, ... consts
31 #   ins       => { "in1", "in2" },  # optional, creates n_op_in1, ... consts
32 #   mode      => "mode_Iu",         # optional, predefines the mode
33 #   emit      => "emit code with templates",   # optional for virtual nodes
34 #   attr      => "additional attribute arguments for constructor", # optional
35 #   init_attr => "emit attribute initialization template",         # optional
36 #   rd_constructor => "c source code which constructs an ir_node", # optional
37 #   hash_func => "name of the hash function for this operation",   # optional, get the default hash function else
38 #   latency   => "latency of this operation (can be float)"        # optional
39 #   attr_type => "name of the attribute struct",                   # optional
40 # },
41 #
42 # ... # (all nodes you need to describe)
43 #
44 # ); # close the %nodes initializer
45
46 # state: state of the operation, OPTIONAL (default is "floats")
47 #
48 # arity: arity of the operation, MUST NOT BE OMITTED
49 #
50 # args:  the OPTIONAL arguments of the node constructor (debug, irg and block
51 #        are always the first 3 arguments and are always autmatically
52 #        created)
53 #        If this key is missing the following arguments will be created:
54 #        for i = 1 .. arity: ir_node *op_i
55 #        ir_mode *mode
56 #
57 # outs:  if a node defines more than one output, the names of the projections
58 #        nodes having outs having automatically the mode mode_T
59 #
60 # comment: OPTIONAL comment for the node constructor
61 #
62 # register types:
63 #   0 - no special type
64 #   1 - caller save (register must be saved by the caller of a function)
65 #   2 - callee save (register must be saved by the called function)
66 #   4 - ignore (do not assign this register)
67 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
68 %reg_classes = (
69         gp => [
70                 { name => "r0", type => 1 },
71                 { name => "r1", type => 1 },
72                 { name => "r2", type => 1 },
73                 { name => "r3", type => 1 },
74                 { name => "r4", type => 1 },
75                 { name => "r5", type => 1 },
76                 { name => "r6", type => 1 },
77                 { name => "r7", type => 2 },
78                 { name => "r8", type => 2 },
79                 { name => "r9", type => 2 },
80                 { name => "r10", type => 2 },
81                 { name => "r11", type => 2 },
82                 { name => "r12", type => 2 },
83                 { name => "r13", type => 2 },
84                 { name => "sp", realname => "r14", type => 4 },  # stackpointer
85                 { name => "bp", realname => "r15", type => 4 },  # basepointer
86                 { mode => $mode_gp }
87         ],
88         fp => [
89                 { name => "f0", type => 1 },
90                 { name => "f1", type => 1 },
91                 { name => "f2", type => 1 },
92                 { name => "f3", type => 1 },
93                 { name => "f4", type => 1 },
94                 { name => "f5", type => 1 },
95                 { name => "f6", type => 1 },
96                 { name => "f7", type => 1 },
97                 { name => "f8", type => 1 },
98                 { name => "f9", type => 1 },
99                 { name => "f10", type => 1 },
100                 { name => "f11", type => 1 },
101                 { name => "f12", type => 1 },
102                 { name => "f13", type => 1 },
103                 { name => "f14", type => 1 },
104                 { name => "f15", type => 1 },
105                 { mode => $mode_fp }
106         ]
107 );
108
109 %emit_templates = (
110         S1 => "${arch}_emit_source_register(node, 0);",
111         S2 => "${arch}_emit_source_register(node, 1);",
112         S3 => "${arch}_emit_source_register(node, 2);",
113         S4 => "${arch}_emit_source_register(node, 3);",
114         S5 => "${arch}_emit_source_register(node, 4);",
115         S6 => "${arch}_emit_source_register(node, 5);",
116         D1 => "${arch}_emit_dest_register(node, 0);",
117         D2 => "${arch}_emit_dest_register(node, 1);",
118         D3 => "${arch}_emit_dest_register(node, 2);",
119         D4 => "${arch}_emit_dest_register(node, 3);",
120         D5 => "${arch}_emit_dest_register(node, 4);",
121         D6 => "${arch}_emit_dest_register(node, 5);",
122         C  => "${arch}_emit_immediate(node);"
123 );
124
125 $default_attr_type = "TEMPLATE_attr_t";
126 $default_copy_attr = "TEMPLATE_copy_attr";
127
128 %nodes = (
129
130 # Integer nodes
131
132 Add => {
133         op_flags  => [ "commutative" ],
134         irn_flags => [ "rematerializable" ],
135         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
136         emit      => '. add %S1, %S2, %D1',
137         mode      => $mode_gp,
138 },
139
140 Mul => {
141         op_flags  => [ "commutative" ],
142         irn_flags => [ "rematerializable" ],
143         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
144         emit      =>'. mul %S1, %S2, %D1',
145         mode      => $mode_gp,
146 },
147
148 And => {
149         op_flags  => [ "commutative" ],
150         irn_flags => [ "rematerializable" ],
151         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
152         emit      => '. and %S1, %S2, %D1',
153         mode      => $mode_gp,
154 },
155
156 Or => {
157         op_flags  => [ "commutative" ],
158         irn_flags => [ "rematerializable" ],
159         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
160         emit      => '. or %S1, %S2, %D1',
161         mode      => $mode_gp,
162 },
163
164 Xor => {
165         op_flags  => [ "commutative" ],
166         irn_flags => [ "rematerializable" ],
167         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
168         emit      => '. xor %S1, %S2, %D1',
169         mode      => $mode_gp,
170 },
171
172 Sub => {
173         irn_flags => [ "rematerializable" ],
174         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
175         emit      => '. sub %S1, %S2, %D1',
176         mode      => $mode_gp,
177 },
178
179 Shl => {
180         irn_flags => [ "rematerializable" ],
181         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
182         emit      => '. shl %S1, %S2, %D1',
183         mode      => $mode_gp,
184 },
185
186 Shr => {
187         irn_flags => [ "rematerializable" ],
188         reg_req   => { in => [ "gp", "gp" ], out => [ "in_r1" ] },
189         emit      => '. shr %S2, %D1',
190         mode      => $mode_gp,
191 },
192
193 Minus => {
194         irn_flags => [ "rematerializable" ],
195         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
196         emit      => '. neg %S1, %D1',
197         mode      => $mode_gp,
198 },
199
200 Not => {
201         arity   => 1,
202         remat   => 1,
203         reg_req => { in => [ "gp" ], out => [ "gp" ] },
204         emit    => '. not %S1, %D1',
205         mode    => $mode_gp,
206 },
207
208 Const => {
209         op_flags   => [ "constlike" ],
210         irn_flags  => [ "rematerializable" ],
211         attr       => "tarval *value",
212         custominit => "set_TEMPLATE_value(res, value);",
213         reg_req    => { out => [ "gp" ] },
214         emit       => '. mov %C, %D1',
215         cmp_attr   =>
216 '
217         /* TODO: compare Const attributes */
218     return 1;
219 ',
220         mode    => $mode_gp,
221 },
222
223 # Control Flow
224
225 Jmp => {
226         state     => "pinned",
227         op_flags  => [ "cfopcode" ],
228         irn_flags => [ "simple_jump" ],
229         reg_req   => { out => [ "none" ] },
230         mode      => "mode_X",
231 },
232
233 # Load / Store
234
235 Load => {
236         op_flags  => [ "labeled", "fragile" ],
237         irn_flags => [ "rematerializable" ],
238         state     => "exc_pinned",
239         reg_req   => { in => [ "gp", "none" ], out => [ "gp" ] },
240         emit      => '. mov (%S1), %D1',
241 },
242
243 Store => {
244         op_flags  => [ "labeled", "fragile" ],
245         irn_flags => [ "rematerializable" ],
246         state     => "exc_pinned",
247         reg_req   => { in => [ "gp", "gp", "none" ] },
248         emit      => '. movl %S2, (%S1)',
249 },
250
251 # Floating Point operations
252
253 fAdd => {
254         op_flags  => [ "commutative" ],
255         irn_flags => [ "rematerializable" ],
256         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
257         emit      => '. fadd %S1, %S2, %D1',
258         mode    => $mode_fp,
259 },
260
261 fMul => {
262         op_flags  => [ "commutative" ],
263         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
264         emit      =>'. fmul %S1, %S2, %D1',
265         mode      => $mode_fp,
266 },
267
268 fSub => {
269         irn_flags => [ "rematerializable" ],
270         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
271         emit      => '. fsub %S1, %S2, %D1',
272         mode      => $mode_fp,
273 },
274
275 fDiv => {
276         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
277         emit      => '. fdiv %S1, %S2, %D1',
278         mode      => $mode_fp,
279 },
280
281 fMinus => {
282         irn_flags => [ "rematerializable" ],
283         reg_req   => { in => [ "fp" ], out => [ "fp" ] },
284         emit      => '. fneg %S1, %D1',
285         mode      => $mode_fp,
286 },
287
288 fConst => {
289         op_flags  => [ "constlike" ],
290         irn_flags => [ "rematerializable" ],
291         reg_req   => { out => [ "fp" ] },
292         emit      => '. fmov %C, %D1',
293         cmp_attr  =>
294 '
295         /* TODO: compare fConst attributes */
296         return 1;
297 ',
298         mode      => $mode_fp,
299 },
300
301 # Load / Store
302
303 fLoad => {
304         op_flags  => [ "labeled", "fragile" ],
305         irn_flags => [ "rematerializable" ],
306         state     => "exc_pinned",
307         reg_req   => { in => [ "gp", "none" ], out => [ "fp" ] },
308         emit      => '. fmov (%S1), %D1',
309 },
310
311 fStore => {
312         op_flags  => [ "labeled", "fragile" ],
313         irn_flags => [ "rematerializable" ],
314         state     => "exc_pinned",
315         reg_req   => { in => [ "gp", "fp", "none" ] },
316         emit      => '. fmov %S2, (%S1)',
317 },
318
319 );