amd64: Added Load and FrameAddr transformation. And fixed some corruption bugs w...
[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         SI1 => "${arch}_emit_source_register_or_immediate(node, 1);",
57         D0  => "${arch}_emit_dest_register(node, 0);",
58         A0  => "${arch}_emit_load_store_address(node, 0);",
59         I   => "${arch}_emit_immediate_suffix(node, 1);",
60         C   => "${arch}_emit_immediate(node);",
61         JumpTarget => "${arch}_emit_jump_target(node);",
62         JumpTarget1 => "${arch}_emit_jump_target_proj(node, 1);",
63         JumpOrFallthrough => "${arch}_emit_jump_or_fallthrough(node, 0);",
64 );
65
66 $default_attr_type = "mips_attr_t";
67 $default_copy_attr = "mips_copy_attr";
68
69 $mode_gp = "mode_Iu";
70
71 %init_attr = (
72         mips_attr_t            => "\tinit_mips_attributes(res, flags, in_reqs, exec_units, n_res);",
73
74         mips_immediate_attr_t  => "\tinit_mips_attributes(res, flags, in_reqs, exec_units, n_res);\n".
75                                  "\tinit_mips_immediate_attributes(res, imm_type, entity, val);",
76
77         mips_load_store_attr_t => "\tinit_mips_attributes(res, flags, in_reqs, exec_units, n_res);\n".
78                                  "\tinit_mips_load_store_attributes(res, entity, offset);",
79 );
80
81 %compare_attr = (
82         mips_attr_t            => "mips_compare_nodes_attr",
83         mips_immediate_attr_t  => "mips_compare_immediate_attr",
84         mips_load_store_attr_t => "mips_compare_load_store_attr",
85 );
86
87 #--------------------------------------------------#
88 #                        _                         #
89 #                       (_)                        #
90 #  _ __   _____      __  _ _ __    ___  _ __  ___  #
91 # | '_ \ / _ \ \ /\ / / | | '__|  / _ \| '_ \/ __| #
92 # | | | |  __/\ V  V /  | | |    | (_) | |_) \__ \ #
93 # |_| |_|\___| \_/\_/   |_|_|     \___/| .__/|___/ #
94 #                                      | |         #
95 #                                      |_|         #
96 #--------------------------------------------------#
97
98 %nodes = (
99
100 Immediate => {
101         state     => "pinned",
102         op_flags  => "c",
103         reg_req   => { out => [ "gp_NOREG:I" ] },
104         attr      => "mips_immediate_type_t imm_type, ir_entity *entity, long val",
105         attr_type => "mips_immediate_attr_t",
106         mode      => $mode_gp,
107 },
108
109 #-----------------------------------------------------------------#
110 #  _       _                                         _            #
111 # (_)     | |                                       | |           #
112 #  _ _ __ | |_ ___  __ _  ___ _ __   _ __   ___   __| | ___  ___  #
113 # | | '_ \| __/ _ \/ _` |/ _ \ '__| | '_ \ / _ \ / _` |/ _ \/ __| #
114 # | | | | | ||  __/ (_| |  __/ |    | | | | (_) | (_| |  __/\__ \ #
115 # |_|_| |_|\__\___|\__, |\___|_|    |_| |_|\___/ \__,_|\___||___/ #
116 #                   __/ |                                         #
117 #                  |___/                                          #
118 #-----------------------------------------------------------------#
119
120 # commutative operations
121
122 addu => {
123         op_flags  => "R",
124         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
125         ins       => [ "left", "right" ],
126         emit      => '. add%I%.u %D0, %S0, %SI1',
127         mode      => $mode_gp,
128 },
129
130 and => {
131         op_flags  => "R",
132         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
133         ins       => [ "left", "right" ],
134         emit      => '. and%I %D0, %S0, %SI1',
135         mode      => $mode_gp,
136 },
137
138 div => {
139         reg_req   => { in => [ "gp", "gp" ], out => [ "none", "none" ] },
140         ins       => [ "left", "right" ],
141         outs      => [ "lohi", "M" ],
142         emit      => '. div %S0, %S1',
143         mode      => "mode_M",
144 },
145
146 divu => {
147         reg_req   => { in => [ "gp", "gp" ], out => [ "none", "none" ] },
148         ins       => [ "left", "right" ],
149         outs      => [ "lohi", "M" ],
150         emit      => '. divu %S0, %S1',
151         mode      => "mode_M",
152 },
153
154 mult => {
155         reg_req   => { in => [ "gp", "gp" ], out => [ "none" ] },
156         ins       => [ "left", "right" ],
157         emit      => '. mult %S0, %S1',
158         mode      => "mode_M"
159 },
160
161 multu => {
162         reg_req   => { in => [ "gp", "gp" ], out => [ "none" ] },
163         ins       => [ "left", "right" ],
164         emit      => '. multu %S0, %S1',
165         mode      => "mode_M",
166 },
167
168 nor => {
169         op_flags  => "R",
170         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
171         emit      => '. nor%I %D0, %S0, %SI1',
172         mode      => $mode_gp
173 },
174
175 or => {
176         op_flags  => "R",
177         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
178         ins       => [ "left", "right" ],
179         emit      => '. or%I %D0, %S0, %SI1',
180         mode      => $mode_gp
181 },
182
183 sll => {
184         op_flags  => "R",
185         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
186         ins       => [ "left", "right" ],
187         emit      => '. sll %D0, %S0, %SI1',
188         mode      => $mode_gp,
189 },
190
191 sra => {
192         op_flags  => "R",
193         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
194         ins       => [ "left", "right" ],
195         emit      => '. sra %D0, %S0, %SI1',
196         mode      => $mode_gp
197 },
198
199 srl => {
200         op_flags  => "R",
201         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
202         ins       => [ "left", "right" ],
203         emit      => '. srl %D0, %S0, %SI1',
204         mode      => $mode_gp,
205 },
206
207 subu => {
208         op_flags  => "R",
209         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
210         ins       => [ "left", "right" ],
211         emit      => '. subu %D0, %S0, %S1',
212         mode      => $mode_gp
213 },
214
215 xor => {
216         op_flags  => "R",
217         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
218         ins       => [ "left", "right" ],
219         emit      => '. xor%I %D0, %S0, %SI1',
220         mode      => $mode_gp,
221 },
222
223 seb => {
224         op_flags  => "R",
225         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
226         ins       => [ "val" ],
227         emit      => '.seb %D0, %S0',
228         mode      => $mode_gp,
229 },
230
231 seh => {
232         op_flags  => "R",
233         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
234         ins       => [ "val" ],
235         emit      => '.seh %D0, %S0',
236         mode      => $mode_gp,
237 },
238
239 lui => {
240         op_flags  => "c",
241         irn_flags => "R",
242         reg_req   => { out => [ "gp" ] },
243         emit      => '.lui %D0, %C',
244         attr_type => "mips_immediate_attr_t",
245         attr      => "mips_immediate_type_t imm_type, ir_entity *entity, long val",
246         mode      => $mode_gp,
247 },
248
249 mflo => {
250         irn_flags => "R",
251         reg_req   => { in => [ "none" ], out => [ "gp" ] },
252         ins       => [ "lohi" ],
253         emit      => '. mflo %D0',
254         mode      => $mode_gp
255 },
256
257 mfhi => {
258         irn_flags => "R",
259         reg_req   => { in => [ "none" ], out => [ "gp" ] },
260         ins       => [ "lohi" ],
261         emit      => '. mfhi %D0',
262         mode      => $mode_gp
263 },
264
265 zero => {
266         state     => "pinned",
267         op_flags  => "c",
268         reg_req   => { out => [ "zero:I" ] },
269         emit      => '',
270         mode      => $mode_gp
271 },
272
273 #
274 #  ____                       _        __  _
275 # | __ ) _ __ __ _ _ __   ___| |__    / / | |_   _ _ __ ___  _ __
276 # |  _ \| '__/ _` | '_ \ / __| '_ \  / /  | | | | | '_ ` _ \| '_ \
277 # | |_) | | | (_| | | | | (__| | | |/ / |_| | |_| | | | | | | |_) |
278 # |____/|_|  \__,_|_| |_|\___|_| |_/_/ \___/ \__,_|_| |_| |_| .__/
279 #                                                           |_|
280 #
281
282 slt => {
283         op_flags => "R",
284         reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
285         emit    => '. slt%I %D0, %S0, %SI1',
286         mode    => $mode_gp,
287 },
288
289 sltu => {
290         op_flags => "R",
291         reg_req  => { in => [ "gp", "gp" ], out => [ "gp" ] },
292         emit     => '. slt%I%.u %D0, %S0, %SI1',
293         mode     => $mode_gp,
294 },
295
296 beq => {
297         op_flags => "X|Y",
298         reg_req  => { in => [ "gp", "gp" ], out => [ "none", "none" ] },
299         outs     => [ "false", "true" ],
300         emit     => '. beq %S0, %S1, %JumpTarget1
301                      . %JumpOrFallthrough'
302 },
303
304 bne => {
305         op_flags => "X|Y",
306         reg_req  => { in => [ "gp", "gp" ], out => [ "none", "none" ] },
307         outs     => [ "false", "true" ],
308         emit     => '. bne %S0, %S1, %JumpTarget1
309                      . %JumpOrFallthrough'
310 },
311
312 bgtz => {
313         op_flags => "X|Y",
314         reg_req  => { in => [ "gp" ], out => [ "none", "none" ] },
315         outs     => [ "false", "true" ],
316         emit     => '. bgtz %S0, %JumpTarget1
317                      . %JumpOrFallthrough'
318 },
319
320 blez => {
321         op_flags => "X|Y",
322         reg_req  => { in => [ "gp" ], out => [ "none", "none" ] },
323         outs     => [ "false", "true" ],
324         emit     => '. blez %S0, %JumpTarget1
325                      . %JumpOrFallthrough'
326 },
327
328 b => {
329         op_flags => "X",
330         reg_req  => { in => [ ], out => [ "none" ] },
331         emit     => '. b %JumpTarget',
332         mode     => 'mode_X'
333 },
334
335 jr => {
336         op_flags => "X",
337         reg_req  => { in => [ "gp" ], out => [ "none" ] },
338         emit     => '. jr %S0',
339         mode     => 'mode_X'
340 },
341
342 SwitchJump => {
343         op_flags => "X",
344         reg_req  => { in => [ "gp" ], out => [ "none" ] },
345         emit     => '. jr %S0'
346 },
347
348 #  _                    _    ______  _
349 # | |    ___   __ _  __| |  / / ___|| |_ ___  _ __ ___
350 # | |   / _ \ / _` |/ _` | / /\___ \| __/ _ \| '__/ _ \
351 # | |__| (_) | (_| | (_| |/ /  ___) | || (_) | | |  __/
352 # |_____\___/ \__,_|\__,_/_/  |____/ \__\___/|_|  \___|
353 #
354
355 lw => {
356         op_flags  => "L|F",
357         state     => "exc_pinned",
358         reg_req   => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
359         ins       => [ "ptr", "mem" ],
360         outs      => [ "res", "M" ],
361         emit      => '. lw %D0, %A0',
362         attr_type => "mips_load_store_attr_t",
363         attr      => "ir_entity *entity, long offset",
364 },
365
366 lh => {
367         op_flags  => "L|F",
368         state     => "exc_pinned",
369         reg_req   => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
370         ins       => [ "ptr", "mem" ],
371         outs      => [ "res", "M" ],
372         emit      => '. lh %D0, %A0',
373         attr_type => "mips_load_store_attr_t",
374         attr      => "ir_entity *entity, long offset",
375 },
376
377 lhu => {
378         op_flags  => "L|F",
379         state     => "exc_pinned",
380         reg_req   => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
381         ins       => [ "ptr", "mem" ],
382         outs      => [ "res", "M" ],
383         emit      => '. lhu %D0, %A0',
384         attr_type => "mips_load_store_attr_t",
385         attr      => "ir_entity *entity, long offset",
386 },
387
388 lb => {
389         op_flags  => "L|F",
390         state     => "exc_pinned",
391         reg_req   => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
392         ins       => [ "ptr", "mem" ],
393         outs      => [ "res", "M" ],
394         emit      => '. lb %D0, %A0',
395         attr_type => "mips_load_store_attr_t",
396         attr      => "ir_entity *entity, long offset",
397 },
398
399 lbu => {
400         op_flags  => "L|F",
401         state     => "exc_pinned",
402         reg_req   => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
403         ins       => [ "ptr", "mem" ],
404         outs      => [ "res", "M" ],
405         emit      => '. lbu %D0, %A0',
406         attr_type => "mips_load_store_attr_t",
407         attr      => "ir_entity *entity, long offset",
408 },
409
410 sw => {
411         op_flags  => "L|F",
412         state     => "exc_pinned",
413         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
414         ins       => [ "ptr", "val", "mem" ],
415         emit      => '. sw %S1, %A0',
416         mode      => 'mode_M',
417         attr_type => "mips_load_store_attr_t",
418         attr      => "ir_entity *entity, long offset",
419 },
420
421 sh => {
422         op_flags  => "L|F",
423         state     => "exc_pinned",
424         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
425         ins       => [ "ptr", "val", "mem" ],
426         emit      => '. sh %S1, %A0',
427         mode      => 'mode_M',
428         attr_type => "mips_load_store_attr_t",
429         attr      => "ir_entity *entity, long offset",
430 },
431
432 sb => {
433         op_flags  => "L|F",
434         state     => "exc_pinned",
435         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
436         ins       => [ "ptr", "val", "mem" ],
437         emit      => '. sb %S1, %A0',
438         mode      => 'mode_M',
439         attr_type => "mips_load_store_attr_t",
440         attr      => "ir_entity *entity, long offset",
441 },
442
443 #
444 # Miscelaneous
445 #
446
447 nop => {
448         op_flags => "K",
449         reg_req  => { in => [], out => [ "none" ] },
450         emit     => '. nop',
451 },
452
453 ); # end of %nodes