Remove address name SymConsts.
[libfirm] / ir / be / mips / mips_spec.pl
1 # Creation: 2006/02/13
2 # $Id$
3
4 # the cpu architecture (ia32, ia64, mips, sparc, ppc, ...)
5
6 $arch = "mips";
7
8 # register types:
9 #   0 - no special type
10 #   1 - caller save (register must be saved by the caller of a function)
11 #   2 - callee save (register must be saved by the called function)
12 #   4 - ignore (do not assign this register)
13 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold\
14 %reg_classes = (
15         "gp" => [
16                 { name => "zero", type => 4 },  # always zero
17                 { name => "at", type => 4 }, # reserved for assembler
18                 { name => "v0", realname => "2", type => 1 }, # first return value
19                 { name => "v1", realname => "3", type => 1 }, # second return value
20                 { name => "a0", realname => "4", type => 1 }, # first argument
21                 { name => "a1", realname => "5", type => 1 }, # second argument
22                 { name => "a2", realname => "6", type => 1 }, # third argument
23                 { name => "a3", realname => "7", type => 1 }, # fourth argument
24                 { name => "t0", realname => "8", type => 1 },
25                 { name => "t1", realname => "9", type => 1 },
26                 { name => "t2", realname => "10", type => 1 },
27                 { name => "t3", realname => "11", type => 1 },
28                 { name => "t4", realname => "12", type => 1 },
29                 { name => "t5", realname => "13", type => 1 },
30                 { name => "t6", realname => "14", type => 1 },
31                 { name => "t7", realname => "15", type => 1 },
32                 { name => "s0", realname => "16", type => 2 },
33                 { name => "s1", realname => "17", type => 2 },
34                 { name => "s2", realname => "18", type => 2 },
35                 { name => "s3", realname => "19", type => 2 },
36                 { name => "s4", realname => "20", type => 2 },
37                 { name => "s5", realname => "21", type => 2 },
38                 { name => "s6", realname => "22", type => 2 },
39                 { name => "s7", realname => "23", type => 2 },
40                 { name => "t8", realname => "24", type => 1 },
41                 { name => "t9", realname => "25", type => 1 },
42                 { name => "kt0", type => 4 }, # reserved for OS
43                 { name => "kt1", type => 4 }, # reserved for OS
44                 { name => "gp", type => 4 }, # general purpose
45                 { name => "sp", type => 4 }, # stack pointer
46                 { name => "fp", type => 4 }, # frame pointer
47                 { name => "ra", type => 2+1 }, # return address
48                 { name => "gp_NOREG", realname => "!NOREG_INVALID!", type => 4 | 8 | 16 }, #dummy register for immediate nodes
49                 { mode => "mode_Iu" }
50         ],
51 ); # %reg_classes
52
53 %emit_templates = (
54     S0  => "${arch}_emit_source_register(node, 0);",
55     S1  => "${arch}_emit_source_register(node, 1);",
56     S2  => "${arch}_emit_source_register(node, 2);",
57         SI1 => "${arch}_emit_source_register_or_immediate(node, 1);",
58     D0  => "${arch}_emit_dest_register(node, 0);",
59     D1  => "${arch}_emit_dest_register(node, 1);",
60     D2  => "${arch}_emit_dest_register(node, 2);",
61         A0  => "${arch}_emit_load_store_address(node, 0);",
62         I   => "${arch}_emit_immediate_suffix(node, 1);",
63         C   => "${arch}_emit_immediate(node);",
64         JumpTarget => "${arch}_emit_jump_target(node);",
65         JumpTarget1 => "${arch}_emit_jump_target_proj(node, 1);",
66         JumpOrFallthrough => "${arch}_emit_jump_or_fallthrough(node, 0);",
67 );
68
69 $default_attr_type = "mips_attr_t";
70 $default_copy_attr = "mips_copy_attr";
71
72 $mode_gp = "mode_Iu";
73
74 %init_attr = (
75         mips_attr_t            => "\tinit_mips_attributes(res, flags, in_reqs, exec_units, n_res);",
76
77         mips_immediate_attr_t  => "\tinit_mips_attributes(res, flags, in_reqs, exec_units, n_res);\n".
78                                  "\tinit_mips_immediate_attributes(res, imm_type, entity, val);",
79
80         mips_load_store_attr_t => "\tinit_mips_attributes(res, flags, in_reqs, exec_units, n_res);\n".
81                                  "\tinit_mips_load_store_attributes(res, entity, offset);",
82 );
83
84 %compare_attr = (
85         mips_attr_t            => "mips_compare_nodes_attr",
86         mips_immediate_attr_t  => "mips_compare_immediate_attr",
87         mips_load_store_attr_t => "mips_compare_load_store_attr",
88 );
89
90 #--------------------------------------------------#
91 #                        _                         #
92 #                       (_)                        #
93 #  _ __   _____      __  _ _ __    ___  _ __  ___  #
94 # | '_ \ / _ \ \ /\ / / | | '__|  / _ \| '_ \/ __| #
95 # | | | |  __/\ V  V /  | | |    | (_) | |_) \__ \ #
96 # |_| |_|\___| \_/\_/   |_|_|     \___/| .__/|___/ #
97 #                                      | |         #
98 #                                      |_|         #
99 #--------------------------------------------------#
100
101 %nodes = (
102
103 Immediate => {
104         state     => "pinned",
105         op_flags  => "c",
106         reg_req   => { out => [ "gp_NOREG:I" ] },
107         attr      => "mips_immediate_type_t imm_type, ir_entity *entity, long val",
108         attr_type => "mips_immediate_attr_t",
109         mode      => $mode_gp,
110 },
111
112 #-----------------------------------------------------------------#
113 #  _       _                                         _            #
114 # (_)     | |                                       | |           #
115 #  _ _ __ | |_ ___  __ _  ___ _ __   _ __   ___   __| | ___  ___  #
116 # | | '_ \| __/ _ \/ _` |/ _ \ '__| | '_ \ / _ \ / _` |/ _ \/ __| #
117 # | | | | | ||  __/ (_| |  __/ |    | | | | (_) | (_| |  __/\__ \ #
118 # |_|_| |_|\__\___|\__, |\___|_|    |_| |_|\___/ \__,_|\___||___/ #
119 #                   __/ |                                         #
120 #                  |___/                                          #
121 #-----------------------------------------------------------------#
122
123 # commutative operations
124
125 addu => {
126         op_flags  => "R",
127         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
128         ins       => [ "left", "right" ],
129         emit      => '. add%I%.u %D0, %S0, %SI1',
130         mode      => $mode_gp,
131 },
132
133 and => {
134         op_flags  => "R",
135         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
136         ins       => [ "left", "right" ],
137         emit      => '. and%I %D0, %S0, %SI1',
138         mode      => $mode_gp,
139 },
140
141 div => {
142         reg_req   => { in => [ "gp", "gp" ], out => [ "none", "none" ] },
143         ins       => [ "left", "right" ],
144         outs      => [ "lohi", "M" ],
145         emit      => '. div %S0, %S1',
146         mode      => "mode_M",
147 },
148
149 divu => {
150         reg_req   => { in => [ "gp", "gp" ], out => [ "none", "none" ] },
151         ins       => [ "left", "right" ],
152         outs      => [ "lohi", "M" ],
153         emit      => '. divu %S0, %S1',
154         mode      => "mode_M",
155 },
156
157 mult => {
158         reg_req   => { in => [ "gp", "gp" ], out => [ "none" ] },
159         ins       => [ "left", "right" ],
160         emit      => '. mult %S0, %S1',
161         mode      => "mode_M"
162 },
163
164 multu => {
165         reg_req   => { in => [ "gp", "gp" ], out => [ "none" ] },
166         ins       => [ "left", "right" ],
167         emit      => '. multu %S0, %S1',
168         mode      => "mode_M",
169 },
170
171 nor => {
172         op_flags  => "R",
173         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
174         emit      => '. nor%I %D0, %S0, %SI1',
175         mode      => $mode_gp
176 },
177
178 or => {
179         op_flags  => "R",
180         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
181         ins       => [ "left", "right" ],
182         emit      => '. or%I %D0, %S0, %SI1',
183         mode      => $mode_gp
184 },
185
186 sll => {
187         op_flags  => "R",
188         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
189         ins       => [ "left", "right" ],
190         emit      => '. sll %D0, %S0, %SI1',
191         mode      => $mode_gp,
192 },
193
194 sra => {
195         op_flags  => "R",
196         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
197         ins       => [ "left", "right" ],
198         emit      => '. sra %D0, %S0, %SI1',
199         mode      => $mode_gp
200 },
201
202 srl => {
203         op_flags  => "R",
204         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
205         ins       => [ "left", "right" ],
206         emit      => '. srl %D0, %S0, %SI1',
207         mode      => $mode_gp,
208 },
209
210 subu => {
211         op_flags  => "R",
212         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
213         ins       => [ "left", "right" ],
214         emit      => '. subu %D0, %S0, %S1',
215         mode      => $mode_gp
216 },
217
218 xor => {
219         op_flags  => "R",
220         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
221         ins       => [ "left", "right" ],
222         emit      => '. xor%I %D0, %S0, %SI1',
223         mode      => $mode_gp,
224 },
225
226 seb => {
227         op_flags  => "R",
228         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
229         ins       => [ "val" ],
230         emit      => '.seb %D0, %S0',
231         mode      => $mode_gp,
232 },
233
234 seh => {
235         op_flags  => "R",
236         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
237         ins       => [ "val" ],
238         emit      => '.seh %D0, %S0',
239         mode      => $mode_gp,
240 },
241
242 lui => {
243         op_flags  => "c",
244         irn_flags => "R",
245         reg_req   => { out => [ "gp" ] },
246         emit      => '.lui %D0, %C',
247         attr_type => "mips_immediate_attr_t",
248         attr      => "mips_immediate_type_t imm_type, ir_entity *entity, long val",
249         mode      => $mode_gp,
250 },
251
252 mflo => {
253         irn_flags => "R",
254         reg_req   => { in => [ "none" ], out => [ "gp" ] },
255         ins       => [ "lohi" ],
256         emit      => '. mflo %D0',
257         mode      => $mode_gp
258 },
259
260 mfhi => {
261         irn_flags => "R",
262         reg_req   => { in => [ "none" ], out => [ "gp" ] },
263         ins       => [ "lohi" ],
264         emit      => '. mfhi %D0',
265         mode      => $mode_gp
266 },
267
268 zero => {
269         state     => "pinned",
270         op_flags  => "c",
271         reg_req   => { out => [ "zero:I" ] },
272         emit      => '',
273         mode      => $mode_gp
274 },
275
276 #
277 #  ____                       _        __  _
278 # | __ ) _ __ __ _ _ __   ___| |__    / / | |_   _ _ __ ___  _ __
279 # |  _ \| '__/ _` | '_ \ / __| '_ \  / /  | | | | | '_ ` _ \| '_ \
280 # | |_) | | | (_| | | | | (__| | | |/ / |_| | |_| | | | | | | |_) |
281 # |____/|_|  \__,_|_| |_|\___|_| |_/_/ \___/ \__,_|_| |_| |_| .__/
282 #                                                           |_|
283 #
284
285 slt => {
286         op_flags => "R",
287         reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
288         emit    => '. slt%I %D0, %S0, %SI1',
289         mode    => $mode_gp,
290 },
291
292 sltu => {
293         op_flags => "R",
294         reg_req  => { in => [ "gp", "gp" ], out => [ "gp" ] },
295         emit     => '. slt%I%.u %D0, %S0, %SI1',
296         mode     => $mode_gp,
297 },
298
299 beq => {
300         op_flags => "X|Y",
301         reg_req  => { in => [ "gp", "gp" ], out => [ "none", "none" ] },
302         outs     => [ "false", "true" ],
303         emit     => '. beq %S0, %S1, %JumpTarget1
304                      . %JumpOrFallthrough'
305 },
306
307 bne => {
308         op_flags => "X|Y",
309         reg_req  => { in => [ "gp", "gp" ], out => [ "none", "none" ] },
310         outs     => [ "false", "true" ],
311         emit     => '. bne %S0, %S1, %JumpTarget1
312                      . %JumpOrFallthrough'
313 },
314
315 bgtz => {
316         op_flags => "X|Y",
317         reg_req  => { in => [ "gp" ], out => [ "none", "none" ] },
318         outs     => [ "false", "true" ],
319         emit     => '. bgtz %S0, %JumpTarget1
320                      . %JumpOrFallthrough'
321 },
322
323 blez => {
324         op_flags => "X|Y",
325         reg_req  => { in => [ "gp" ], out => [ "none", "none" ] },
326         outs     => [ "false", "true" ],
327         emit     => '. blez %S0, %JumpTarget1
328                      . %JumpOrFallthrough'
329 },
330
331 b => {
332         op_flags => "X",
333         reg_req  => { in => [ ], out => [ "none" ] },
334         emit     => '. b %JumpTarget',
335         mode     => 'mode_X'
336 },
337
338 jr => {
339         op_flags => "X",
340         reg_req  => { in => [ "gp" ], out => [ "none" ] },
341         emit     => '. jr %S0',
342         mode     => 'mode_X'
343 },
344
345 SwitchJump => {
346         op_flags => "X",
347         reg_req  => { in => [ "gp" ], out => [ "none" ] },
348         emit     => '. jr %S0'
349 },
350
351 #  _                    _    ______  _
352 # | |    ___   __ _  __| |  / / ___|| |_ ___  _ __ ___
353 # | |   / _ \ / _` |/ _` | / /\___ \| __/ _ \| '__/ _ \
354 # | |__| (_) | (_| | (_| |/ /  ___) | || (_) | | |  __/
355 # |_____\___/ \__,_|\__,_/_/  |____/ \__\___/|_|  \___|
356 #
357
358 lw => {
359         op_flags  => "L|F",
360         state     => "exc_pinned",
361         reg_req   => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
362         ins       => [ "ptr", "mem" ],
363         outs      => [ "res", "M" ],
364         emit      => '. lw %D0, %A0',
365         attr_type => "mips_load_store_attr_t",
366         attr      => "ir_entity *entity, long offset",
367 },
368
369 lh => {
370         op_flags  => "L|F",
371         state     => "exc_pinned",
372         reg_req   => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
373         ins       => [ "ptr", "mem" ],
374         outs      => [ "res", "M" ],
375         emit      => '. lh %D0, %A0',
376         attr_type => "mips_load_store_attr_t",
377         attr      => "ir_entity *entity, long offset",
378 },
379
380 lhu => {
381         op_flags  => "L|F",
382         state     => "exc_pinned",
383         reg_req   => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
384         ins       => [ "ptr", "mem" ],
385         outs      => [ "res", "M" ],
386         emit      => '. lhu %D0, %A0',
387         attr_type => "mips_load_store_attr_t",
388         attr      => "ir_entity *entity, long offset",
389 },
390
391 lb => {
392         op_flags  => "L|F",
393         state     => "exc_pinned",
394         reg_req   => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
395         ins       => [ "ptr", "mem" ],
396         outs      => [ "res", "M" ],
397         emit      => '. lb %D0, %A0',
398         attr_type => "mips_load_store_attr_t",
399         attr      => "ir_entity *entity, long offset",
400 },
401
402 lbu => {
403         op_flags  => "L|F",
404         state     => "exc_pinned",
405         reg_req   => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
406         ins       => [ "ptr", "mem" ],
407         outs      => [ "res", "M" ],
408         emit      => '. lbu %D0, %A0',
409         attr_type => "mips_load_store_attr_t",
410         attr      => "ir_entity *entity, long offset",
411 },
412
413 sw => {
414         op_flags  => "L|F",
415         state     => "exc_pinned",
416         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
417         ins       => [ "ptr", "val", "mem" ],
418         emit      => '. sw %S1, %A0',
419         mode      => 'mode_M',
420         attr_type => "mips_load_store_attr_t",
421         attr      => "ir_entity *entity, long offset",
422 },
423
424 sh => {
425         op_flags  => "L|F",
426         state     => "exc_pinned",
427         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
428         ins       => [ "ptr", "val", "mem" ],
429         emit      => '. sh %S1, %A0',
430         mode      => 'mode_M',
431         attr_type => "mips_load_store_attr_t",
432         attr      => "ir_entity *entity, long offset",
433 },
434
435 sb => {
436         op_flags  => "L|F",
437         state     => "exc_pinned",
438         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
439         ins       => [ "ptr", "val", "mem" ],
440         emit      => '. sb %S1, %A0',
441         mode      => 'mode_M',
442         attr_type => "mips_load_store_attr_t",
443         attr      => "ir_entity *entity, long offset",
444 },
445
446 #
447 # Miscelaneous
448 #
449
450 nop => {
451         op_flags => "K",
452         reg_req  => { in => [], out => [ "none" ] },
453         emit     => '. nop',
454 },
455
456 ); # end of %nodes