Remove the never read flag irop_flag_dump_noinput.
[libfirm] / ir / be / amd64 / amd64_spec.pl
1 # the cpu architecture (ia32, ia64, mips, sparc, ppc, ...)
2
3 $arch = "amd64";
4
5 # The node description is done as a perl hash initializer with the
6 # following structure:
7 #
8 # %nodes = (
9 #
10 # <op-name> => {
11 #   arity     => "0|1|2|3 ... |variable|dynamic|any",   # optional
12 #   state     => "floats|pinned|mem_pinned|exc_pinned", # optional
13 #   args      => [
14 #                    { type => "type 1", name => "name 1" },
15 #                    { type => "type 2", name => "name 2" },
16 #                    ...
17 #                  ],
18 #   comment   => "any comment for constructor",  # optional
19 #   reg_req   => { in => [ "reg_class|register" ], out => [ "reg_class|register|in_rX" ] },
20 #   cmp_attr  => "c source code for comparing node attributes", # optional
21 #   outs      => { "out1", "out2" },# optional, creates pn_op_out1, ... consts
22 #   ins       => { "in1", "in2" },  # optional, creates n_op_in1, ... consts
23 #   mode      => "mode_Iu",         # optional, predefines the mode
24 #   emit      => "emit code with templates",   # optional for virtual nodes
25 #   attr      => "additional attribute arguments for constructor", # optional
26 #   init_attr => "emit attribute initialization template",         # optional
27 #   rd_constructor => "c source code which constructs an ir_node", # optional
28 #   hash_func => "name of the hash function for this operation",   # optional, get the default hash function else
29 #   latency   => "latency of this operation (can be float)"        # optional
30 #   attr_type => "name of the attribute struct",                   # optional
31 # },
32 #
33 # ... # (all nodes you need to describe)
34 #
35 # ); # close the %nodes initializer
36
37 # state: state of the operation, OPTIONAL (default is "floats")
38 #
39 # arity: arity of the operation, MUST NOT BE OMITTED
40 #
41 # args:  the OPTIONAL arguments of the node constructor (debug, irg and block
42 #        are always the first 3 arguments and are always autmatically
43 #        created)
44 #        If this key is missing the following arguments will be created:
45 #        for i = 1 .. arity: ir_node *op_i
46 #        ir_mode *mode
47 #
48 # outs:  if a node defines more than one output, the names of the projections
49 #        nodes having outs having automatically the mode mode_T
50 #
51 # comment: OPTIONAL comment for the node constructor
52 #
53 # register types:
54 $normal      =  0; # no special type
55 $ignore      =  1; # ignore (do not assign this register)
56 $arbitrary   =  2; # emitter can choose an arbitrary register of this class
57 $virtual     =  4; # the register is a virtual one
58 $state       =  8; # register represents a state
59 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
60 %reg_classes = (
61         gp => [
62                 { name => "rax", dwarf => 0 },
63                 { name => "rcx", dwarf => 2 },
64                 { name => "rdx", dwarf => 1 },
65                 { name => "rsi", dwarf => 4 },
66                 { name => "rdi", dwarf => 5 },
67                 { name => "rbx", dwarf => 3 },
68                 { name => "rbp", dwarf => 6 },
69                 { name => "rsp", dwarf => 7, type => $ignore }, # stackpointer?
70                 { name => "r8",  dwarf => 8 },
71                 { name => "r9",  dwarf => 9 },
72                 { name => "r10", dwarf => 10 },
73                 { name => "r11", dwarf => 11 },
74                 { name => "r12", dwarf => 12 },
75                 { name => "r13", dwarf => 13 },
76                 { name => "r14", dwarf => 14 },
77                 { name => "r15", dwarf => 15 },
78 #               { name => "gp_NOREG", type => $ignore }, # we need a dummy register for NoReg nodes
79                 { mode => "mode_Lu" }
80         ],
81 #       fp => [
82 #               { name => "xmm0",  dwarf => 17 },
83 #               { name => "xmm1",  dwarf => 18 },
84 #               { name => "xmm2",  dwarf => 19 },
85 #               { name => "xmm3",  dwarf => 20 },
86 #               { name => "xmm4",  dwarf => 21 },
87 #               { name => "xmm5",  dwarf => 22 },
88 #               { name => "xmm6",  dwarf => 23 },
89 #               { name => "xmm7",  dwarf => 24 },
90 #               { name => "xmm8",  dwarf => 25 },
91 #               { name => "xmm9",  dwarf => 26 },
92 #               { name => "xmm10", dwarf => 27 },
93 #               { name => "xmm11", dwarf => 28 },
94 #               { name => "xmm12", dwarf => 29 },
95 #               { name => "xmm13", dwarf => 30 },
96 #               { name => "xmm14", dwarf => 31 },
97 #               { name => "xmm15", dwarf => 32 },
98 #               { mode => "mode_D" }
99 #       ]
100         flags => [
101                 { name => "eflags", dwarf => 49 },
102                 { mode => "mode_Iu", flags => "manual_ra" }
103         ],
104 );
105
106 $mode_gp        = "mode_Lu";
107 $mode_flags     = "mode_Iu";
108
109 sub amd64_custom_init_attr {
110         my $constr = shift;
111         my $node   = shift;
112         my $name   = shift;
113         my $res    = "";
114
115         if(defined($node->{modified_flags})) {
116                 $res .= "\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n";
117         }
118         return $res;
119 }
120 $custom_init_attr_func = \&amd64_custom_init_attr;
121
122 $default_copy_attr = "amd64_copy_attr";
123
124 %emit_templates = (
125         S1 => "${arch}_emit_source_register(node, 0);",
126         S2 => "${arch}_emit_source_register(node, 1);",
127         S3 => "${arch}_emit_source_register(node, 2);",
128         S4 => "${arch}_emit_source_register(node, 3);",
129         S5 => "${arch}_emit_source_register(node, 4);",
130         S6 => "${arch}_emit_source_register(node, 5);",
131         D1 => "${arch}_emit_dest_register(node, 0);",
132         D2 => "${arch}_emit_dest_register(node, 1);",
133         D3 => "${arch}_emit_dest_register(node, 2);",
134         D4 => "${arch}_emit_dest_register(node, 3);",
135         D5 => "${arch}_emit_dest_register(node, 4);",
136         D6 => "${arch}_emit_dest_register(node, 5);",
137         C  => "${arch}_emit_immediate(node);",
138         O  => "${arch}_emit_fp_offset(node);",
139 );
140
141 %init_attr = (
142         amd64_attr_t           =>
143                  "\tinit_amd64_attributes(res, irn_flags_, in_reqs, n_res);",
144         amd64_SymConst_attr_t =>
145                 "\tinit_amd64_attributes(res, irn_flags_, in_reqs, n_res);"
146                 . "\tinit_amd64_SymConst_attributes(res, entity);",
147         amd64_condcode_attr_t =>
148                 "\tinit_amd64_attributes(res, irn_flags_, in_reqs, n_res);"
149                 . "\tinit_amd64_condcode_attributes(res, pnc);",
150 );
151
152 %compare_attr = (
153         amd64_attr_t           => "cmp_amd64_attr",
154         amd64_SymConst_attr_t  => "cmp_amd64_attr_SymConst",
155         amd64_condcode_attr_t  => "cmp_amd64_attr_condcode",
156 );
157
158 %nodes = (
159 Push => {
160         state     => "exc_pinned",
161         reg_req   => { in => [ "gp", "gp", "none", "gp", "rsp" ], out => [ "rsp:I|S", "none" ] },
162         ins       => [ "base", "index", "mem", "val", "stack" ],
163         emit      => '. push %S1',
164         outs      => [ "stack", "M" ],
165         am        => "source,unary",
166         latency   => 2,
167 #       units     => [ "GP" ],
168 },
169
170 Add => {
171         op_flags   => [ "commutative" ],
172         irn_flags  => [ "rematerializable" ],
173         state      => "exc_pinned",
174         reg_req    => { in => [ "gp", "gp" ],
175                         out => [ "gp" ] },
176         ins        => [ "left", "right" ],
177         outs       => [ "res" ],
178         mode       => $mode_gp,
179         modified_flags => 1,
180 },
181
182 Mul => {
183         # we should not rematrialize this node. It produces 2 results and has
184         # very strict constraints
185         state     => "exc_pinned",
186         reg_req   => { in  => [ "rax", "gp" ],
187                        out => [ "rax rdx" ] },
188         ins       => [ "left", "right" ],
189         emit      => '. mul %S2',
190         outs      => [ "res" ],
191         mode      => $mode_gp,
192         am        => "source,binary",
193         modified_flags => $status_flags
194 },
195
196 Sub => {
197         irn_flags  => [ "rematerializable" ],
198         state      => "exc_pinned",
199         reg_req    => { in => [ "gp", "gp" ],
200                         out => [ "gp" ] },
201         ins        => [ "left", "right" ],
202         outs       => [ "res" ],
203         mode       => $mode_gp,
204         modified_flags => 1,
205 },
206
207 Neg => {
208         irn_flags => [ "rematerializable" ],
209         reg_req   => { in => [ "gp" ],
210                        out => [ "in_r1", "flags" ] },
211         emit      => '. neg %S1',
212         ins       => [ "val" ],
213         outs      => [ "res", "flags" ],
214         mode      => $mode_gp,
215         modified_flags => $status_flags
216 },
217
218 Immediate => {
219         op_flags  => [ "constlike" ],
220         attr      => "unsigned imm_value",
221         init_attr => "attr->ext.imm_value = imm_value;",
222         reg_req   => { out => [ "gp" ] },
223         emit      => '. mov %C, %D1',
224         mode      => $mode_gp,
225 },
226
227 SymConst => {
228         op_flags  => [ "constlike" ],
229         irn_flags => [ "rematerializable" ],
230         attr      => "ir_entity *entity",
231         attr_type => "amd64_SymConst_attr_t",
232         reg_req   => { out => [ "gp" ] },
233         outs      => [ "res" ],
234         mode      => $mode_gp,
235 },
236
237 Conv => {
238         state     => "exc_pinned",
239         attr      => "ir_mode *smaller_mode",
240         init_attr => "attr->ls_mode = smaller_mode;",
241         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
242         ins       => [ "val" ],
243         outs      => [ "res" ],
244         mode      => $mode_gp,
245 },
246
247 Jmp => {
248         state     => "pinned",
249         op_flags  => [ "cfopcode" ],
250         reg_req   => { out => [ "none" ] },
251         mode      => "mode_X",
252 },
253
254 Cmp => {
255         irn_flags => [ "rematerializable" ],
256         state     => "exc_pinned",
257         reg_req   => { in  => [ "gp", "gp" ],
258                        out => [ "flags" ] },
259         ins       => [ "left", "right" ],
260         outs      => [ "eflags" ],
261         emit      => '. cmp %S1, %S2',
262         attr      => "int ins_permuted, int cmp_unsigned",
263         init_attr => "attr->data.ins_permuted   = ins_permuted;\n".
264                      "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
265         mode      => $mode_flags,
266         modified_flags => 1,
267 },
268
269 Jcc => {
270         state     => "pinned",
271         op_flags  => [ "cfopcode", "forking" ],
272         reg_req   => { in  => [ "eflags" ], out => [ "none", "none" ] },
273         ins       => [ "eflags" ],
274         outs      => [ "false", "true" ],
275         attr      => "ir_relation relation",
276         init_attr => "attr->ext.relation = relation;",
277         mode      => "mode_T",
278 },
279
280 Load => {
281         op_flags  => [ "uses_memory" ],
282         state     => "exc_pinned",
283         reg_req   => { in => [ "gp", "none" ],
284                        out => [ "gp", "none" ] },
285         ins       => [ "ptr", "mem" ],
286         outs      => [ "res",  "M" ],
287         attr      => "ir_entity *entity",
288         attr_type => "amd64_SymConst_attr_t",
289         emit      => ". mov %O(%S1), %D1"
290 },
291
292 FrameAddr => {
293         op_flags  => [ "constlike" ],
294         irn_flags => [ "rematerializable" ],
295         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
296         ins       => [ "base" ],
297         attr      => "ir_entity *entity",
298         attr_type => "amd64_SymConst_attr_t",
299         mode      => $mode_gp,
300 },
301
302 Store => {
303         op_flags  => [ "uses_memory" ],
304         state     => "exc_pinned",
305         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
306         ins       => [ "ptr", "val", "mem" ],
307         outs      => [ "M" ],
308         attr      => "ir_entity *entity",
309         attr_type => "amd64_SymConst_attr_t",
310         mode      => "mode_M",
311         emit      => ". mov %S2, %O(%S1)"
312 },
313
314 #NoReg_GP => {
315 #       state     => "pinned",
316 #       op_flags  => [ "constlike", "dump_noblcok" ],
317 #       reg_req   => { out => [ "gp_NOREG:I" ] },
318 #       units     => [],
319 #       emit      => "",
320 #       latency   => 0,
321 #       mode      => $mode_gp,
322 #},
323 );