allow backend to specify endianess, rewrite bitfield emitter to handle little and...
[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 %nodes = (
126
127 # Integer nodes
128
129 Add => {
130         op_flags  => [ "commutative" ],
131         irn_flags => [ "rematerializable" ],
132         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
133         emit      => '. add %S1, %S2, %D1',
134         mode      => $mode_gp,
135 },
136
137 Mul => {
138         op_flags  => [ "commutative" ],
139         irn_flags => [ "rematerializable" ],
140         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
141         emit      =>'. mul %S1, %S2, %D1',
142         mode      => $mode_gp,
143 },
144
145 And => {
146         op_flags  => [ "commutative" ],
147         irn_flags => [ "rematerializable" ],
148         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
149         emit      => '. and %S1, %S2, %D1',
150         mode      => $mode_gp,
151 },
152
153 Or => {
154         op_flags  => [ "commutative" ],
155         irn_flags => [ "rematerializable" ],
156         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
157         emit      => '. or %S1, %S2, %D1',
158         mode      => $mode_gp,
159 },
160
161 Xor => {
162         op_flags  => [ "commutative" ],
163         irn_flags => [ "rematerializable" ],
164         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
165         emit      => '. xor %S1, %S2, %D1',
166         mode      => $mode_gp,
167 },
168
169 Sub => {
170         irn_flags => [ "rematerializable" ],
171         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
172         emit      => '. sub %S1, %S2, %D1',
173         mode      => $mode_gp,
174 },
175
176 Shl => {
177         irn_flags => [ "rematerializable" ],
178         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
179         emit      => '. shl %S1, %S2, %D1',
180         mode      => $mode_gp,
181 },
182
183 Shr => {
184         irn_flags => [ "rematerializable" ],
185         reg_req   => { in => [ "gp", "gp" ], out => [ "in_r1" ] },
186         emit      => '. shr %S2, %D1',
187         mode      => $mode_gp,
188 },
189
190 Minus => {
191         irn_flags => [ "rematerializable" ],
192         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
193         emit      => '. neg %S1, %D1',
194         mode      => $mode_gp,
195 },
196
197 Not => {
198         arity   => 1,
199         remat   => 1,
200         reg_req => { in => [ "gp" ], out => [ "gp" ] },
201         emit    => '. not %S1, %D1',
202         mode    => $mode_gp,
203 },
204
205 Const => {
206         op_flags   => [ "constlike" ],
207         irn_flags  => [ "rematerializable" ],
208         attr       => "tarval *value",
209         custominit => "set_TEMPLATE_value(res, value);",
210         reg_req    => { out => [ "gp" ] },
211         emit       => '. mov %C, %D1',
212         cmp_attr   =>
213 '
214         /* TODO: compare Const attributes */
215     return 1;
216 ',
217         mode    => $mode_gp,
218 },
219
220 # Control Flow
221
222 Jmp => {
223         state     => "pinned",
224         op_flags  => [ "cfopcode" ],
225         irn_flags => [ "simple_jump" ],
226         reg_req   => { out => [ "none" ] },
227         mode      => "mode_X",
228 },
229
230 # Load / Store
231
232 Load => {
233         op_flags  => [ "labeled", "fragile" ],
234         irn_flags => [ "rematerializable" ],
235         state     => "exc_pinned",
236         reg_req   => { in => [ "gp", "none" ], out => [ "gp" ] },
237         emit      => '. mov (%S1), %D1',
238 },
239
240 Store => {
241         op_flags  => [ "labeled", "fragile" ],
242         irn_flags => [ "rematerializable" ],
243         state     => "exc_pinned",
244         reg_req   => { in => [ "gp", "gp", "none" ] },
245         emit      => '. movl %S2, (%S1)',
246 },
247
248 # Floating Point operations
249
250 fAdd => {
251         op_flags  => [ "commutative" ],
252         irn_flags => [ "rematerializable" ],
253         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
254         emit      => '. fadd %S1, %S2, %D1',
255         mode    => $mode_fp,
256 },
257
258 fMul => {
259         op_flags  => [ "commutative" ],
260         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
261         emit      =>'. fmul %S1, %S2, %D1',
262         mode      => $mode_fp,
263 },
264
265 fSub => {
266         irn_flags => [ "rematerializable" ],
267         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
268         emit      => '. fsub %S1, %S2, %D1',
269         mode      => $mode_fp,
270 },
271
272 fDiv => {
273         reg_req   => { in => [ "fp", "fp" ], out => [ "fp" ] },
274         emit      => '. fdiv %S1, %S2, %D1',
275         mode      => $mode_fp,
276 },
277
278 fMinus => {
279         irn_flags => [ "rematerializable" ],
280         reg_req   => { in => [ "fp" ], out => [ "fp" ] },
281         emit      => '. fneg %S1, %D1',
282         mode      => $mode_fp,
283 },
284
285 fConst => {
286         op_flags  => [ "constlike" ],
287         irn_flags => [ "rematerializable" ],
288         reg_req   => { out => [ "fp" ] },
289         emit      => '. fmov %C, %D1',
290         cmp_attr  =>
291 '
292         /* TODO: compare fConst attributes */
293         return 1;
294 ',
295         mode      => $mode_fp,
296 },
297
298 # Load / Store
299
300 fLoad => {
301         op_flags  => [ "labeled", "fragile" ],
302         irn_flags => [ "rematerializable" ],
303         state     => "exc_pinned",
304         reg_req   => { in => [ "gp", "none" ], out => [ "fp" ] },
305         emit      => '. fmov (%S1), %D1',
306 },
307
308 fStore => {
309         op_flags  => [ "labeled", "fragile" ],
310         irn_flags => [ "rematerializable" ],
311         state     => "exc_pinned",
312         reg_req   => { in => [ "gp", "fp", "none" ] },
313         emit      => '. fmov %S2, (%S1)',
314 },
315
316 );