Remove stale $Id$.
[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 Add => {
170         op_flags   => [ "commutative" ],
171         irn_flags  => [ "rematerializable" ],
172         state      => "exc_pinned",
173         reg_req    => { in => [ "gp", "gp" ],
174                         out => [ "gp" ] },
175         in         => [ "left", "right" ],
176         outs       => [ "res" ],
177         mode       => $mode_gp,
178         modified_flags => 1,
179 },
180 Mul => {
181         # we should not rematrialize this node. It produces 2 results and has
182         # very strict constraints
183         state     => "exc_pinned",
184         reg_req   => { in  => [ "rax", "gp" ],
185                        out => [ "rax rdx" ] },
186         ins       => [ "left", "right" ],
187         emit      => '. mul %S2',
188         outs      => [ "res" ],
189         mode      => $mode_gp,
190         am        => "source,binary",
191         modified_flags => $status_flags
192 },
193 Sub => {
194         irn_flags  => [ "rematerializable" ],
195         state      => "exc_pinned",
196         reg_req    => { in => [ "gp", "gp" ],
197                         out => [ "gp" ] },
198         in         => [ "left", "right" ],
199         outs       => [ "res" ],
200         mode       => $mode_gp,
201         modified_flags => 1,
202 },
203 Neg => {
204         irn_flags => [ "rematerializable" ],
205         reg_req   => { in => [ "gp" ],
206                        out => [ "in_r1", "flags" ] },
207         emit      => '. neg %S1',
208         ins       => [ "val" ],
209         outs      => [ "res", "flags" ],
210         mode      => $mode_gp,
211         modified_flags => $status_flags
212 },
213 Immediate => {
214         op_flags  => [ "constlike" ],
215         attr      => "unsigned imm_value",
216         init_attr => "attr->ext.imm_value = imm_value;",
217         reg_req   => { out => [ "gp" ] },
218         emit      => '. mov %C, %D1',
219         mode      => $mode_gp,
220 },
221 SymConst => {
222         op_flags  => [ "constlike" ],
223         irn_flags => [ "rematerializable" ],
224         attr      => "ir_entity *entity",
225         attr_type => "amd64_SymConst_attr_t",
226         reg_req   => { out => [ "gp" ] },
227         outs      => [ "res" ],
228         mode      => $mode_gp,
229 },
230 Conv => {
231         state     => "exc_pinned",
232         attr      => "ir_mode *smaller_mode",
233         init_attr => "attr->ls_mode = smaller_mode;",
234         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
235         ins       => [ "val" ],
236         outs      => [ "res" ],
237         mode      => $mode_gp,
238 },
239 Jmp => {
240         state     => "pinned",
241         op_flags  => [ "cfopcode" ],
242         reg_req   => { out => [ "none" ] },
243         mode      => "mode_X",
244 },
245 Cmp => {
246         irn_flags => [ "rematerializable" ],
247         state     => "exc_pinned",
248         reg_req   => { in  => [ "gp", "gp" ],
249                        out => [ "flags" ] },
250         ins       => [ "left", "right" ],
251         outs      => [ "eflags" ],
252         emit      => '. cmp %S1, %S2',
253         attr      => "int ins_permuted, int cmp_unsigned",
254         init_attr => "attr->data.ins_permuted   = ins_permuted;\n".
255                      "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
256         mode      => $mode_flags,
257         modified_flags => 1,
258 },
259 Jcc => {
260         state     => "pinned",
261         op_flags  => [ "labeled", "cfopcode", "forking" ],
262         reg_req   => { in  => [ "eflags" ], out => [ "none", "none" ] },
263         ins       => [ "eflags" ],
264         outs      => [ "false", "true" ],
265         attr      => "ir_relation relation",
266         init_attr => "attr->ext.relation = relation;",
267         mode      => "mode_T",
268 },
269 Load => {
270         op_flags  => [ "labeled" ],
271         state     => "exc_pinned",
272         reg_req   => { in => [ "gp", "none" ],
273                        out => [ "gp", "none" ] },
274         ins       => [ "ptr", "mem" ],
275         outs      => [ "res",  "M" ],
276         attr      => "ir_entity *entity",
277         attr_type => "amd64_SymConst_attr_t",
278         emit      => ". mov %O(%S1), %D1"
279 },
280 FrameAddr => {
281         op_flags  => [ "constlike" ],
282         irn_flags => [ "rematerializable" ],
283         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
284         ins       => [ "base" ],
285         attr      => "ir_entity *entity",
286         attr_type => "amd64_SymConst_attr_t",
287         mode      => $mode_gp,
288 },
289 Store => {
290         op_flags  => [ "labeled" ],
291         state     => "exc_pinned",
292         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
293         ins       => [ "ptr", "val", "mem" ],
294         outs      => [ "M" ],
295         attr      => "ir_entity *entity",
296         attr_type => "amd64_SymConst_attr_t",
297         mode      => "mode_M",
298         emit      => ". mov %S2, %O(%S1)"
299 },
300
301 #NoReg_GP => {
302 #       state     => "pinned",
303 #       op_flags  => [ "constlike", "dump_noblcok", "dump_noinput" ],
304 #       reg_req   => { out => [ "gp_NOREG:I" ] },
305 #       units     => [],
306 #       emit      => "",
307 #       latency   => 0,
308 #       mode      => $mode_gp,
309 #},
310 );