3 # This is a template specification for the Firm-Backend
5 # the cpu architecture (ia32, ia64, mips, sparc, ppc, ...)
12 # 1 - caller save (register must be saved by the caller of a function)
13 # 2 - callee save (register must be saved by the called function)
14 # 4 - ignore (do not assign this register)
15 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold\
18 { name => "zero", type => 4 }, # always zero
19 { name => "at", type => 4 }, # reserved for assembler
20 { name => "v0", realname => "2", type => 1 }, # first return value
21 { name => "v1", realname => "3", type => 1 }, # second return value
22 { name => "a0", realname => "4", type => 1 }, # first argument
23 { name => "a1", realname => "5", type => 1 }, # second argument
24 { name => "a2", realname => "6", type => 1 }, # third argument
25 { name => "a3", realname => "7", type => 1 }, # fourth argument
26 { name => "t0", realname => "8", type => 1 },
27 { name => "t1", realname => "9", type => 1 },
28 { name => "t2", realname => "10", type => 1 },
29 { name => "t3", realname => "11", type => 1 },
30 { name => "t4", realname => "12", type => 1 },
31 { name => "t5", realname => "13", type => 1 },
32 { name => "t6", realname => "14", type => 1 },
33 { name => "t7", realname => "15", type => 1 },
34 { name => "s0", realname => "16", type => 2 },
35 { name => "s1", realname => "17", type => 2 },
36 { name => "s2", realname => "18", type => 2 },
37 { name => "s3", realname => "19", type => 2 },
38 { name => "s4", realname => "20", type => 2 },
39 { name => "s5", realname => "21", type => 2 },
40 { name => "s6", realname => "22", type => 2 },
41 { name => "s7", realname => "23", type => 2 },
42 { name => "t8", realname => "24", type => 1 },
43 { name => "t9", realname => "25", type => 1 },
44 { name => "kt0", type => 4 }, # reserved for OS
45 { name => "kt1", type => 4 }, # reserved for OS
46 { name => "gp", type => 4 }, # general purpose
47 { name => "sp", type => 4 }, # stack pointer
48 { name => "fp", type => 4 }, # frame pointer
49 { name => "ra", type => 2+1 }, # return address
50 { name => "gp_NOREG", realname => "!NOREG_INVALID!", type => 4 | 8 | 16 }, #dummy register for immediate nodes
56 S0 => "${arch}_emit_source_register(node, 0);",
57 S1 => "${arch}_emit_source_register(node, 1);",
58 S2 => "${arch}_emit_source_register(node, 2);",
59 SI1 => "${arch}_emit_source_register_or_immediate(node, 1);",
60 D0 => "${arch}_emit_dest_register(node, 0);",
61 D1 => "${arch}_emit_dest_register(node, 1);",
62 D2 => "${arch}_emit_dest_register(node, 2);",
63 A0 => "${arch}_emit_load_store_address(node, 0);",
64 I => "${arch}_emit_immediate_suffix(node, 1);",
65 C => "${arch}_emit_immediate(node);",
66 JumpTarget => "${arch}_emit_jump_target(node);",
67 JumpTarget1 => "${arch}_emit_jump_target_proj(node, 1);",
68 JumpOrFallthrough => "${arch}_emit_jump_or_fallthrough(node, 0);",
71 $default_attr_type = "mips_attr_t";
72 $default_copy_attr = "mips_copy_attr";
77 mips_attr_t => "\tinit_mips_attributes(res, flags, in_reqs, exec_units, n_res);",
79 mips_immediate_attr_t => "\tinit_mips_attributes(res, flags, in_reqs, exec_units, n_res);\n".
80 "\tinit_mips_immediate_attributes(res, imm_type, entity, val);",
82 mips_load_store_attr_t => "\tinit_mips_attributes(res, flags, in_reqs, exec_units, n_res);\n".
83 "\tinit_mips_load_store_attributes(res, entity, offset);",
87 mips_attr_t => "mips_compare_nodes_attr",
88 mips_immediate_attr_t => "mips_compare_immediate_attr",
89 mips_load_store_attr_t => "mips_compare_load_store_attr",
92 #--------------------------------------------------#
95 # _ __ _____ __ _ _ __ ___ _ __ ___ #
96 # | '_ \ / _ \ \ /\ / / | | '__| / _ \| '_ \/ __| #
97 # | | | | __/\ V V / | | | | (_) | |_) \__ \ #
98 # |_| |_|\___| \_/\_/ |_|_| \___/| .__/|___/ #
101 #--------------------------------------------------#
108 reg_req => { out => [ "gp_NOREG:I" ] },
109 attr => "mips_immediate_type_t imm_type, ir_entity *entity, long val",
110 attr_type => "mips_immediate_attr_t",
114 #-----------------------------------------------------------------#
117 # _ _ __ | |_ ___ __ _ ___ _ __ _ __ ___ __| | ___ ___ #
118 # | | '_ \| __/ _ \/ _` |/ _ \ '__| | '_ \ / _ \ / _` |/ _ \/ __| #
119 # | | | | | || __/ (_| | __/ | | | | | (_) | (_| | __/\__ \ #
120 # |_|_| |_|\__\___|\__, |\___|_| |_| |_|\___/ \__,_|\___||___/ #
123 #-----------------------------------------------------------------#
125 # commutative operations
129 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
130 ins => [ "left", "right" ],
131 emit => '. add%I%.u %D0, %S0, %SI1',
137 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
138 ins => [ "left", "right" ],
139 emit => '. and%I %D0, %S0, %SI1',
144 reg_req => { in => [ "gp", "gp" ], out => [ "none", "none" ] },
145 ins => [ "left", "right" ],
146 outs => [ "lohi", "M" ],
147 emit => '. div %S0, %S1',
152 reg_req => { in => [ "gp", "gp" ], out => [ "none", "none" ] },
153 ins => [ "left", "right" ],
154 outs => [ "lohi", "M" ],
155 emit => '. divu %S0, %S1',
160 reg_req => { in => [ "gp", "gp" ], out => [ "none" ] },
161 ins => [ "left", "right" ],
162 emit => '. mult %S0, %S1',
167 reg_req => { in => [ "gp", "gp" ], out => [ "none" ] },
168 ins => [ "left", "right" ],
169 emit => '. multu %S0, %S1',
175 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
176 emit => '. nor%I %D0, %S0, %SI1',
182 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
183 ins => [ "left", "right" ],
184 emit => '. or%I %D0, %S0, %SI1',
190 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
191 ins => [ "left", "right" ],
192 emit => '. sll %D0, %S0, %SI1',
198 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
199 ins => [ "left", "right" ],
200 emit => '. sra %D0, %S0, %SI1',
206 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
207 ins => [ "left", "right" ],
208 emit => '. srl %D0, %S0, %SI1',
214 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
215 ins => [ "left", "right" ],
216 emit => '. subu %D0, %S0, %S1',
222 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
223 ins => [ "left", "right" ],
224 emit => '. xor%I %D0, %S0, %SI1',
230 reg_req => { in => [ "gp" ], out => [ "gp" ] },
232 emit => '.seb %D0, %S0',
238 reg_req => { in => [ "gp" ], out => [ "gp" ] },
240 emit => '.seh %D0, %S0',
247 reg_req => { out => [ "gp" ] },
248 emit => '.lui %D0, %C',
249 attr_type => "mips_immediate_attr_t",
250 attr => "mips_immediate_type_t imm_type, ir_entity *entity, long val",
256 reg_req => { in => [ "none" ], out => [ "gp" ] },
258 emit => '. mflo %D0',
264 reg_req => { in => [ "none" ], out => [ "gp" ] },
266 emit => '. mfhi %D0',
273 reg_req => { out => [ "zero:I" ] },
280 # | __ ) _ __ __ _ _ __ ___| |__ / / | |_ _ _ __ ___ _ __
281 # | _ \| '__/ _` | '_ \ / __| '_ \ / / | | | | | '_ ` _ \| '_ \
282 # | |_) | | | (_| | | | | (__| | | |/ / |_| | |_| | | | | | | |_) |
283 # |____/|_| \__,_|_| |_|\___|_| |_/_/ \___/ \__,_|_| |_| |_| .__/
289 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
290 emit => '. slt%I %D0, %S0, %SI1',
296 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
297 emit => '. slt%I%.u %D0, %S0, %SI1',
303 reg_req => { in => [ "gp", "gp" ], out => [ "none", "none" ] },
304 outs => [ "false", "true" ],
305 emit => '. beq %S0, %S1, %JumpTarget1
306 . %JumpOrFallthrough'
311 reg_req => { in => [ "gp", "gp" ], out => [ "none", "none" ] },
312 outs => [ "false", "true" ],
313 emit => '. bne %S0, %S1, %JumpTarget1
314 . %JumpOrFallthrough'
319 reg_req => { in => [ "gp" ], out => [ "none", "none" ] },
320 outs => [ "false", "true" ],
321 emit => '. bgtz %S0, %JumpTarget1
322 . %JumpOrFallthrough'
327 reg_req => { in => [ "gp" ], out => [ "none", "none" ] },
328 outs => [ "false", "true" ],
329 emit => '. blez %S0, %JumpTarget1
330 . %JumpOrFallthrough'
335 reg_req => { in => [ ], out => [ "none" ] },
336 emit => '. b %JumpTarget',
342 reg_req => { in => [ "gp" ], out => [ "none" ] },
349 reg_req => { in => [ "gp" ], out => [ "none" ] },
354 # | | ___ __ _ __| | / / ___|| |_ ___ _ __ ___
355 # | | / _ \ / _` |/ _` | / /\___ \| __/ _ \| '__/ _ \
356 # | |__| (_) | (_| | (_| |/ / ___) | || (_) | | | __/
357 # |_____\___/ \__,_|\__,_/_/ |____/ \__\___/|_| \___|
362 state => "exc_pinned",
363 reg_req => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
364 ins => [ "ptr", "mem" ],
365 outs => [ "res", "M" ],
366 emit => '. lw %D0, %A0',
367 attr_type => "mips_load_store_attr_t",
368 attr => "ir_entity *entity, long offset",
373 state => "exc_pinned",
374 reg_req => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
375 ins => [ "ptr", "mem" ],
376 outs => [ "res", "M" ],
377 emit => '. lh %D0, %A0',
378 attr_type => "mips_load_store_attr_t",
379 attr => "ir_entity *entity, long offset",
384 state => "exc_pinned",
385 reg_req => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
386 ins => [ "ptr", "mem" ],
387 outs => [ "res", "M" ],
388 emit => '. lhu %D0, %A0',
389 attr_type => "mips_load_store_attr_t",
390 attr => "ir_entity *entity, long offset",
395 state => "exc_pinned",
396 reg_req => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
397 ins => [ "ptr", "mem" ],
398 outs => [ "res", "M" ],
399 emit => '. lb %D0, %A0',
400 attr_type => "mips_load_store_attr_t",
401 attr => "ir_entity *entity, long offset",
406 state => "exc_pinned",
407 reg_req => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
408 ins => [ "ptr", "mem" ],
409 outs => [ "res", "M" ],
410 emit => '. lbu %D0, %A0',
411 attr_type => "mips_load_store_attr_t",
412 attr => "ir_entity *entity, long offset",
417 state => "exc_pinned",
418 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
419 ins => [ "ptr", "val", "mem" ],
420 emit => '. sw %S1, %A0',
422 attr_type => "mips_load_store_attr_t",
423 attr => "ir_entity *entity, long offset",
428 state => "exc_pinned",
429 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
430 ins => [ "ptr", "val", "mem" ],
431 emit => '. sh %S1, %A0',
433 attr_type => "mips_load_store_attr_t",
434 attr => "ir_entity *entity, long offset",
439 state => "exc_pinned",
440 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
441 ins => [ "ptr", "val", "mem" ],
442 emit => '. sb %S1, %A0',
444 attr_type => "mips_load_store_attr_t",
445 attr => "ir_entity *entity, long offset",
454 reg_req => { in => [], out => [ "none" ] },