be: remove remnants of machine description
[libfirm] / ir / be / arm / arm_spec.pl
1 # Arm Architecure Specification
2 # Author: Matthias Braun, Michael Beck, Oliver Richter, Tobias Gneist
3
4 $arch = "arm";
5
6 #
7 # Modes
8 #
9 $mode_gp    = "mode_Iu";
10 $mode_flags = "mode_Bu";
11 $mode_fp    = "mode_F";
12
13 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
14 %reg_classes = (
15         gp => [
16                 { name => "r0" },
17                 { name => "r1" },
18                 { name => "r2" },
19                 { name => "r3" },
20                 { name => "r4" },
21                 { name => "r5" },
22                 { name => "r6" },
23                 { name => "r7" },
24                 { name => "r8" },
25                 { name => "r9" },
26                 { name => "r10" },
27                 { name => "r11" },
28                 { name => "r12" },
29                 { name => "sp" },
30                 { name => "lr" },
31                 { name => "pc" },
32                 { mode => $mode_gp }
33         ],
34         fpa => [
35                 { name => "f0" },
36                 { name => "f1" },
37                 { name => "f2" },
38                 { name => "f3" },
39                 { name => "f4" },
40                 { name => "f5" },
41                 { name => "f6" },
42                 { name => "f7" },
43                 { mode => $mode_fp }
44         ],
45         flags => [
46                 { name => "fl" },
47                 { mode => $mode_flags, flags => "manual_ra" }
48         ],
49 );
50
51 %emit_templates = (
52         FM  => "${arch}_emit_float_load_store_mode(node);",
53         AM  => "${arch}_emit_float_arithmetic_mode(node);",
54         LM  => "${arch}_emit_load_mode(node);",
55         SM  => "${arch}_emit_store_mode(node);",
56         SO  => "${arch}_emit_shifter_operand(node);",
57         S0  => "${arch}_emit_source_register(node, 0);",
58         SC  => "${arch}_emit_symconst(node);",
59         S1  => "${arch}_emit_source_register(node, 1);",
60         S2  => "${arch}_emit_source_register(node, 2);",
61         S3  => "${arch}_emit_source_register(node, 3);",
62         S4  => "${arch}_emit_source_register(node, 4);",
63         D0  => "${arch}_emit_dest_register(node, 0);",
64         D1  => "${arch}_emit_dest_register(node, 1);",
65         D2  => "${arch}_emit_dest_register(node, 2);",
66         O   => "${arch}_emit_offset(node);",
67 );
68
69 $default_attr_type = "arm_attr_t";
70 $default_copy_attr = "arm_copy_attr";
71
72 %init_attr = (
73         arm_attr_t           => "\tinit_arm_attributes(res, irn_flags_, in_reqs, n_res);",
74         arm_SymConst_attr_t  =>
75                 "\tinit_arm_attributes(res, irn_flags_, in_reqs, n_res);\n".
76                 "\tinit_arm_SymConst_attributes(res, entity, symconst_offset);",
77         arm_CondJmp_attr_t   => "\tinit_arm_attributes(res, irn_flags_, in_reqs, n_res);",
78         arm_SwitchJmp_attr_t => "\tinit_arm_attributes(res, irn_flags_, in_reqs, n_res);",
79         arm_fConst_attr_t    => "\tinit_arm_attributes(res, irn_flags_, in_reqs, n_res);",
80         arm_load_store_attr_t =>
81                 "\tinit_arm_attributes(res, irn_flags_, in_reqs, n_res);\n".
82                 "\tinit_arm_load_store_attributes(res, ls_mode, entity, entity_sign, offset, is_frame_entity);",
83         arm_shifter_operand_t =>
84                 "\tinit_arm_attributes(res, irn_flags_, in_reqs, n_res);\n",
85         arm_cmp_attr_t =>
86                 "\tinit_arm_attributes(res, irn_flags_, in_reqs, n_res);\n",
87         arm_farith_attr_t =>
88                 "\tinit_arm_attributes(res, irn_flags_, in_reqs, n_res);\n".
89                 "\tinit_arm_farith_attributes(res, op_mode);",
90         arm_CopyB_attr_t =>
91                 "\tinit_arm_attributes(res, irn_flags_, in_reqs, n_res);\n".
92                 "\tinit_arm_CopyB_attributes(res, size);",
93 );
94
95 %compare_attr = (
96         arm_attr_t            => "cmp_attr_arm",
97         arm_SymConst_attr_t   => "cmp_attr_arm_SymConst",
98         arm_CondJmp_attr_t    => "cmp_attr_arm_CondJmp",
99         arm_SwitchJmp_attr_t  => "cmp_attr_arm_SwitchJmp",
100         arm_fConst_attr_t     => "cmp_attr_arm_fConst",
101         arm_load_store_attr_t => "cmp_attr_arm_load_store",
102         arm_shifter_operand_t => "cmp_attr_arm_shifter_operand",
103         arm_CopyB_attr_t      => "cmp_attr_arm_CopyB",
104         arm_cmp_attr_t        => "cmp_attr_arm_cmp",
105         arm_farith_attr_t     => "cmp_attr_arm_farith",
106 );
107
108 my %unop_shifter_operand_constructors = (
109         imm => {
110                 attr       => "unsigned char immediate_value, unsigned char immediate_rot",
111                 custominit => "init_arm_shifter_operand(res, immediate_value, ARM_SHF_IMM, immediate_rot);",
112                 reg_req    => { in => [], out => [ "gp" ] },
113         },
114         reg => {
115                 custominit => "init_arm_shifter_operand(res, 0, ARM_SHF_REG, 0);",
116                 reg_req    => { in => [ "gp" ], out => [ "gp" ] },
117         },
118         reg_shift_reg => {
119                 attr       => "arm_shift_modifier_t shift_modifier",
120                 custominit => "init_arm_shifter_operand(res, 0, shift_modifier, 0);",
121                 reg_req    => { in => [ "gp", "gp" ], out => [ "gp" ] },
122         },
123         reg_shift_imm => {
124                 attr       => "arm_shift_modifier_t shift_modifier, unsigned shift_immediate",
125                 custominit => "init_arm_shifter_operand(res, 0, shift_modifier, shift_immediate);",
126                 reg_req    => { in => [ "gp" ], out => [ "gp" ] },
127         },
128 );
129
130 my %binop_shifter_operand_constructors = (
131         imm => {
132                 attr       => "unsigned char immediate_value, unsigned char immediate_rot",
133                 custominit => "init_arm_shifter_operand(res, immediate_value, ARM_SHF_IMM, immediate_rot);",
134                 reg_req    => { in => [ "gp" ], out => [ "gp" ] },
135                 ins        => [ "left" ],
136         },
137         reg => {
138                 custominit => "init_arm_shifter_operand(res, 0, ARM_SHF_REG, 0);",
139                 reg_req    => { in => [ "gp", "gp" ], out => [ "gp" ] },
140                 ins        => [ "left", "right" ],
141         },
142         reg_shift_reg => {
143                 attr       => "arm_shift_modifier_t shift_modifier",
144                 custominit => "init_arm_shifter_operand(res, 0, shift_modifier, 0);",
145                 reg_req    => { in => [ "gp", "gp", "gp" ], out => [ "gp" ] },
146                 ins        => [ "left", "right", "shift" ],
147         },
148         reg_shift_imm => {
149                 attr       => "arm_shift_modifier_t shift_modifier, unsigned shift_immediate",
150                 custominit => "init_arm_shifter_operand(res, 0, shift_modifier, shift_immediate);",
151                 reg_req    => { in => [ "gp", "gp" ], out => [ "gp" ] },
152                 ins        => [ "left", "right" ],
153         },
154 );
155
156 my %cmp_shifter_operand_constructors = (
157         imm => {
158                 attr       => "unsigned char immediate_value, unsigned char immediate_rot, bool ins_permuted, bool is_unsigned",
159                 custominit =>
160                         "init_arm_shifter_operand(res, immediate_value, ARM_SHF_IMM, immediate_rot);\n".
161                         "\tinit_arm_cmp_attr(res, ins_permuted, is_unsigned);",
162                 reg_req    => { in => [ "gp" ], out => [ "flags" ] },
163                 ins        => [ "left" ],
164         },
165         reg => {
166                 attr       => "bool ins_permuted, bool is_unsigned",
167                 custominit =>
168                         "init_arm_shifter_operand(res, 0, ARM_SHF_REG, 0);\n".
169                         "\tinit_arm_cmp_attr(res, ins_permuted, is_unsigned);",
170                 reg_req    => { in => [ "gp", "gp" ], out => [ "flags" ] },
171                 ins        => [ "left", "right" ],
172         },
173         reg_shift_reg => {
174                 attr       => "arm_shift_modifier_t shift_modifier, bool ins_permuted, bool is_unsigned",
175                 custominit =>
176                         "init_arm_shifter_operand(res, 0, shift_modifier, 0);\n".
177                         "\tinit_arm_cmp_attr(res, ins_permuted, is_unsigned);",
178                 reg_req    => { in => [ "gp", "gp", "gp" ], out => [ "flags" ] },
179                 ins        => [ "left", "right", "shift" ],
180         },
181         reg_shift_imm => {
182                 attr       => "arm_shift_modifier_t shift_modifier, unsigned shift_immediate, bool ins_permuted, bool is_unsigned",
183                 custominit =>
184                         "init_arm_shifter_operand(res, 0, shift_modifier, shift_immediate);\n".
185                         "\tinit_arm_cmp_attr(res, ins_permuted, is_unsigned);",
186                 reg_req    => { in => [ "gp", "gp" ], out => [ "flags" ] },
187                 ins        => [ "left", "right" ],
188         },
189 );
190
191
192 %nodes = (
193
194 Add => {
195         irn_flags => [ "rematerializable" ],
196         emit      => '. add %D0, %S0, %SO',
197         mode      => $mode_gp,
198         attr_type => "arm_shifter_operand_t",
199         constructors => \%binop_shifter_operand_constructors,
200 },
201
202 Mul => {
203         irn_flags => [ "rematerializable" ],
204         reg_req   => { in => [ "gp", "gp" ], out => [ "!in_r1" ] },
205         emit      =>'. mul %D0, %S0, %S1',
206         mode      => $mode_gp,
207 },
208
209 Smull => {
210         irn_flags => [ "rematerializable" ],
211         reg_req   => { in => [ "gp", "gp" ], out => [ "gp", "gp" ] },
212         emit      =>'. smull %D0, %D1, %S0, %S1',
213         outs      => [ "low", "high" ],
214 },
215
216 Umull => {
217         irn_flags => [ "rematerializable" ],
218         reg_req   => { in => [ "gp", "gp" ], out => [ "gp", "gp" ] },
219         emit      =>'. umull %D0, %D1, %S0, %S1',
220         outs      => [ "low", "high" ],
221         mode      => $mode_gp,
222 },
223
224 Mla => {
225         irn_flags => [ "rematerializable" ],
226         reg_req   => { in => [ "gp", "gp", "gp" ], out => [ "!in_r1" ] },
227         emit      =>'. mla %D0, %S0, %S1, %S2',
228         mode      => $mode_gp,
229 },
230
231 And => {
232         irn_flags => [ "rematerializable" ],
233         emit      => '. and %D0, %S0, %SO',
234         mode      => $mode_gp,
235         attr_type => "arm_shifter_operand_t",
236         constructors => \%binop_shifter_operand_constructors,
237 },
238
239 Or => {
240         irn_flags => [ "rematerializable" ],
241         emit      => '. orr %D0, %S0, %SO',
242         mode      => $mode_gp,
243         attr_type => "arm_shifter_operand_t",
244         constructors => \%binop_shifter_operand_constructors,
245 },
246
247 Eor => {
248         irn_flags => [ "rematerializable" ],
249         emit      => '. eor %D0, %S0, %SO',
250         mode      => $mode_gp,
251         attr_type => "arm_shifter_operand_t",
252         constructors => \%binop_shifter_operand_constructors,
253 },
254
255 Bic => {
256         irn_flags => [ "rematerializable" ],
257         emit      => '. bic %D0, %S0, %SO',
258         mode      => $mode_gp,
259         attr_type => "arm_shifter_operand_t",
260         constructors => \%binop_shifter_operand_constructors,
261 },
262
263 Sub => {
264         irn_flags => [ "rematerializable" ],
265         emit      => '. sub %D0, %S0, %SO',
266         mode      => $mode_gp,
267         attr_type => "arm_shifter_operand_t",
268         constructors => \%binop_shifter_operand_constructors,
269 },
270
271 Rsb => {
272         irn_flags => [ "rematerializable" ],
273         emit      => '. rsb %D0, %S0, %SO',
274         mode      => $mode_gp,
275         attr_type => "arm_shifter_operand_t",
276         constructors => \%binop_shifter_operand_constructors,
277 },
278
279 Mov => {
280         irn_flags => [ "rematerializable" ],
281         arity     => "variable",
282         emit      => '. mov %D0, %SO',
283         mode      => $mode_gp,
284         attr_type => "arm_shifter_operand_t",
285         constructors => \%unop_shifter_operand_constructors,
286 },
287
288 Mvn => {
289         irn_flags => [ "rematerializable" ],
290         attr_type => "arm_shifter_operand_t",
291         arity     => "variable",
292         emit      => '. mvn %D0, %SO',
293         mode      => $mode_gp,
294         constructors => \%unop_shifter_operand_constructors,
295 },
296
297 Clz => {
298         irn_flags => [ "rematerializable" ],
299         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
300         emit      =>'. clz %D0, %S0',
301         mode      => $mode_gp,
302 },
303
304 # mov lr, pc\n mov pc, XXX -- This combination is used for calls to function
305 # pointers
306 LinkMovPC => {
307         state        => "exc_pinned",
308         arity        => "variable",
309         out_arity    => "variable",
310         attr_type    => "arm_shifter_operand_t",
311         attr         => "arm_shift_modifier_t shift_modifier, unsigned char immediate_value, unsigned char immediate_rot",
312         custominit   => "init_arm_shifter_operand(res, immediate_value, shift_modifier, immediate_rot);\n".
313                         "\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);",
314         emit         => ". mov lr, pc\n".
315                         ". mov pc, %SO",
316 },
317
318 # mov lr, pc\n ldr pc, XXX -- This combination is used for calls to function
319 # pointers
320 LinkLdrPC => {
321         state        => "exc_pinned",
322         arity        => "variable",
323         out_arity    => "variable",
324         attr_type    => "arm_load_store_attr_t",
325         attr         => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
326         custominit   => "arch_add_irn_flags(res, arch_irn_flags_modify_flags);",
327         emit         => ". mov lr, pc\n".
328                         ". ldr pc, %SO",
329 },
330
331 Bl => {
332         state      => "exc_pinned",
333         arity      => "variable",
334         out_arity  => "variable",
335         attr_type  => "arm_SymConst_attr_t",
336         attr       => "ir_entity *entity, int symconst_offset",
337         custominit => "arch_add_irn_flags(res, arch_irn_flags_modify_flags);",
338         emit       => '. bl %SC',
339 },
340
341 # this node produces ALWAYS an empty (tempary) gp reg and cannot be CSE'd
342 EmptyReg => {
343         op_flags  => [ "constlike" ],
344         irn_flags => [ "rematerializable" ],
345         reg_req   => { out => [ "gp" ] },
346         emit      => '. /* %D0 now available for calculations */',
347         cmp_attr  => 'return 1;',
348         mode      => $mode_gp,
349 },
350
351 CopyB => {
352         state     => "pinned",
353         attr      => "unsigned size",
354         attr_type => "arm_CopyB_attr_t",
355         reg_req   => { in => [ "!sp", "!sp", "gp", "gp", "gp", "none" ], out => [ "none" ] },
356         outs      => [ "M" ],
357 },
358
359 FrameAddr => {
360         op_flags  => [ "constlike" ],
361         irn_flags => [ "rematerializable" ],
362         attr      => "ir_entity *entity, int symconst_offset",
363         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
364         ins       => [ "base" ],
365         attr_type => "arm_SymConst_attr_t",
366         mode      => $mode_gp,
367 },
368
369 SymConst => {
370         op_flags  => [ "constlike" ],
371         irn_flags => [ "rematerializable" ],
372         attr      => "ir_entity *entity, int symconst_offset",
373         reg_req   => { out => [ "gp" ] },
374         attr_type => "arm_SymConst_attr_t",
375         mode      => $mode_gp,
376 },
377
378 Cmp => {
379         irn_flags    => [ "rematerializable", "modify_flags" ],
380         emit         => '. cmp %S0, %SO',
381         mode         => $mode_flags,
382         attr_type    => "arm_cmp_attr_t",
383         constructors => \%cmp_shifter_operand_constructors,
384 },
385
386 Tst => {
387         irn_flags    => [ "rematerializable", "modify_flags" ],
388         emit         => '. tst %S0, %SO',
389         mode         => $mode_flags,
390         attr_type    => "arm_cmp_attr_t",
391         constructors => \%cmp_shifter_operand_constructors,
392 },
393
394 B => {
395         op_flags  => [ "labeled", "cfopcode", "forking" ],
396         state     => "pinned",
397         mode      => "mode_T",
398         reg_req   => { in => [ "flags" ], out => [ "none", "none" ] },
399         attr      => "ir_relation relation",
400         attr_type => "arm_CondJmp_attr_t",
401         init_attr => "\tset_arm_CondJmp_relation(res, relation);",
402 },
403
404 Jmp => {
405         state     => "pinned",
406         op_flags  => [ "cfopcode" ],
407         irn_flags => [ "simple_jump" ],
408         reg_req   => { out => [ "none" ] },
409         mode      => "mode_X",
410 },
411
412 SwitchJmp => {
413         op_flags  => [ "labeled", "cfopcode", "forking" ],
414         state     => "pinned",
415         mode      => "mode_T",
416         attr      => "const ir_switch_table *table",
417         init_attr => "init_arm_SwitchJmp_attributes(res, table);",
418         reg_req   => { in => [ "gp" ], out => [ "none" ] },
419         out_arity => "variable",
420         attr_type => "arm_SwitchJmp_attr_t",
421 },
422
423 Ldr => {
424         op_flags  => [ "labeled" ],
425         state     => "exc_pinned",
426         ins       => [ "ptr", "mem" ],
427         outs      => [ "res", "M" ],
428         reg_req   => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
429         emit      => '. ldr%LM %D0, [%S0, #%O]',
430         attr_type => "arm_load_store_attr_t",
431         attr      => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
432 },
433
434 Str => {
435         op_flags  => [ "labeled" ],
436         state     => "exc_pinned",
437         ins       => [ "ptr", "val", "mem" ],
438         outs      => [ "M" ],
439         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
440         emit      => '. str%SM %S1, [%S0, #%O]',
441         mode      => "mode_M",
442         attr_type => "arm_load_store_attr_t",
443         attr      => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
444 },
445
446 StoreStackM4Inc => {
447         op_flags  => [ "labeled" ],
448         irn_flags => [ "rematerializable" ],
449         state     => "exc_pinned",
450         reg_req   => { in => [ "sp", "gp", "gp", "gp", "gp", "none" ], out => [ "sp:I|S", "none" ] },
451         emit      => '. stmfd %S0!, {%S1, %S2, %S3, %S4}',
452         outs      => [ "ptr", "M" ],
453 },
454
455 LoadStackM3Epilogue => {
456         op_flags  => [ "labeled" ],
457         irn_flags => [ "rematerializable" ],
458         state     => "exc_pinned",
459         reg_req   => { in => [ "sp", "none" ], out => [ "r11:I", "sp:I|S", "pc:I", "none" ] },
460         emit      => '. ldmfd %S0, {%D0, %D1, %D2}',
461         outs      => [ "res0", "res1", "res2", "M" ],
462 },
463
464
465
466 Adf => {
467         irn_flags => [ "rematerializable" ],
468         reg_req   => { in => [ "fpa", "fpa" ], out => [ "fpa" ] },
469         emit      => '. adf%AM %D0, %S0, %S1',
470         attr_type => "arm_farith_attr_t",
471         attr      => "ir_mode *op_mode",
472         mode      => $mode_fp,
473 },
474
475 Muf => {
476         irn_flags => [ "rematerializable" ],
477         reg_req   => { in => [ "fpa", "fpa" ], out => [ "fpa" ] },
478         emit      =>'. muf%AM %D0, %S0, %S1',
479         attr_type => "arm_farith_attr_t",
480         attr      => "ir_mode *op_mode",
481         mode      => $mode_fp,
482 },
483
484 Suf => {
485         irn_flags => [ "rematerializable" ],
486         reg_req   => { in => [ "fpa", "fpa" ], out => [ "fpa" ] },
487         emit      => '. suf%AM %D0, %S0, %S1',
488         attr_type => "arm_farith_attr_t",
489         attr      => "ir_mode *op_mode",
490         mode      => $mode_fp,
491 },
492
493 Dvf => {
494         reg_req   => { in => [ "fpa", "fpa" ], out => [ "fpa", "none" ] },
495         emit      =>'. dvf%AM %D0, %S0, %S1',
496         outs      => [ "res", "M" ],
497         attr_type => "arm_farith_attr_t",
498         attr      => "ir_mode *op_mode",
499         mode      => $mode_fp,
500 },
501
502 Mvf => {
503         irn_flags => [ "rematerializable" ],
504         reg_req   => { in => [ "fpa" ], out => [ "fpa" ] },
505         emit      => '. mvf%AM %S0, %D0',
506         attr_type => "arm_farith_attr_t",
507         attr      => "ir_mode *op_mode",
508         mode      => $mode_fp,
509 },
510
511 FltX => {
512         irn_flags => [ "rematerializable" ],
513         reg_req   => { in => [ "gp" ], out => [ "fpa" ] },
514         emit      => '. flt%AM %D0, %S0',
515         attr_type => "arm_farith_attr_t",
516         attr      => "ir_mode *op_mode",
517         mode      => $mode_fp,
518 },
519
520 Cmfe => {
521         irn_flags => [ "rematerializable", "modify_flags" ],
522         mode      => $mode_flags,
523         attr_type => "arm_cmp_attr_t",
524         attr      => "bool ins_permuted",
525         init_attr => "init_arm_cmp_attr(res, ins_permuted, false);",
526         reg_req   => { in => [ "fpa", "fpa" ], out => [ "flags" ] },
527         emit      => '. cmfe %S0, %S1',
528 },
529
530 Ldf => {
531         op_flags  => [ "labeled" ],
532         state     => "exc_pinned",
533         ins       => [ "ptr", "mem" ],
534         outs      => [ "res", "M" ],
535         reg_req   => { in => [ "gp", "none" ], out => [ "fpa", "none" ] },
536         emit      => '. ldf%FM %D0, [%S0, #%O]',
537         attr_type => "arm_load_store_attr_t",
538         attr      => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
539 },
540
541 Stf => {
542         op_flags  => [ "labeled" ],
543         state     => "exc_pinned",
544         ins       => [ "ptr", "val", "mem" ],
545         outs      => [ "M" ],
546         mode      => "mode_M",
547         reg_req   => { in => [ "gp", "fpa", "none" ], out => [ "none" ] },
548         emit      => '. stf%FM %S1, [%S0, #%O]',
549         attr_type => "arm_load_store_attr_t",
550         attr      => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
551 },
552
553 #
554 # floating point constants
555 #
556 fConst => {
557         op_flags  => [ "constlike" ],
558         irn_flags => [ "rematerializable" ],
559         attr      => "ir_tarval *tv",
560         init_attr => "attr->tv = tv;",
561         mode      => "get_tarval_mode(tv)",
562         reg_req   => { out => [ "fpa" ] },
563         attr_type => "arm_fConst_attr_t",
564 }
565
566 ); # end of %nodes