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