becopyilp: fix size_reduction code
[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 $normal      =  0; # no special type
58 $ignore      =  1; # ignore (do not assign this register)
59 $arbitrary   =  2; # emitter can choose an arbitrary register of this class
60 $virtual     =  4; # the register is a virtual one
61 $state       =  8; # register represents a state
62 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
63 %reg_classes = (
64         gp => [
65                 { name => "rax" },
66                 { name => "rcx" },
67                 { name => "rdx" },
68                 { name => "rsi" },
69                 { name => "rdi" },
70                 { name => "rbx" },
71                 { name => "rbp" },
72                 { name => "rsp", type => $ignore }, # stackpointer?
73                 { name => "r8" },
74                 { name => "r9" },
75                 { name => "r10" },
76                 { name => "r11" },
77                 { name => "r12" },
78                 { name => "r13" },
79                 { name => "r14" },
80                 { name => "r15" },
81 #               { name => "gp_NOREG", type => $ignore }, # we need a dummy register for NoReg nodes
82                 { mode => "mode_Lu" }
83         ],
84 #       fp => [
85 #               { name => "xmm0" },
86 #               { name => "xmm1" },
87 #               { name => "xmm2" },
88 #               { name => "xmm3" },
89 #               { name => "xmm4" },
90 #               { name => "xmm5" },
91 #               { name => "xmm6" },
92 #               { name => "xmm7" },
93 #               { name => "xmm8" },
94 #               { name => "xmm9" },
95 #               { name => "xmm10" },
96 #               { name => "xmm11" },
97 #               { name => "xmm12" },
98 #               { name => "xmm13" },
99 #               { name => "xmm14" },
100 #               { name => "xmm15" },
101 #               { mode => "mode_D" }
102 #       ]
103         flags => [
104                 { name => "eflags" },
105                 { mode => "mode_Iu", flags => "manual_ra" }
106         ],
107 );
108
109 $mode_gp        = "mode_Lu";
110 $mode_flags     = "mode_Iu";
111
112 sub amd64_custom_init_attr {
113         my $constr = shift;
114         my $node   = shift;
115         my $name   = shift;
116         my $res    = "";
117
118         if(defined($node->{modified_flags})) {
119                 $res .= "\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n";
120         }
121         return $res;
122 }
123 $custom_init_attr_func = \&amd64_custom_init_attr;
124
125 $default_copy_attr = "amd64_copy_attr";
126
127 %emit_templates = (
128         S1 => "${arch}_emit_source_register(node, 0);",
129         S2 => "${arch}_emit_source_register(node, 1);",
130         S3 => "${arch}_emit_source_register(node, 2);",
131         S4 => "${arch}_emit_source_register(node, 3);",
132         S5 => "${arch}_emit_source_register(node, 4);",
133         S6 => "${arch}_emit_source_register(node, 5);",
134         D1 => "${arch}_emit_dest_register(node, 0);",
135         D2 => "${arch}_emit_dest_register(node, 1);",
136         D3 => "${arch}_emit_dest_register(node, 2);",
137         D4 => "${arch}_emit_dest_register(node, 3);",
138         D5 => "${arch}_emit_dest_register(node, 4);",
139         D6 => "${arch}_emit_dest_register(node, 5);",
140         C  => "${arch}_emit_immediate(node);",
141         O  => "${arch}_emit_fp_offset(node);",
142 );
143
144 %init_attr = (
145         amd64_attr_t           =>
146                  "\tinit_amd64_attributes(res, irn_flags_, in_reqs, n_res);",
147         amd64_SymConst_attr_t =>
148                 "\tinit_amd64_attributes(res, irn_flags_, in_reqs, n_res);"
149                 . "\tinit_amd64_SymConst_attributes(res, entity);",
150         amd64_condcode_attr_t =>
151                 "\tinit_amd64_attributes(res, irn_flags_, in_reqs, n_res);"
152                 . "\tinit_amd64_condcode_attributes(res, pnc);",
153 );
154
155 %compare_attr = (
156         amd64_attr_t           => "cmp_amd64_attr",
157         amd64_SymConst_attr_t  => "cmp_amd64_attr_SymConst",
158         amd64_condcode_attr_t  => "cmp_amd64_attr_condcode",
159 );
160
161 %nodes = (
162 Push => {
163         state     => "exc_pinned",
164         reg_req   => { in => [ "gp", "gp", "none", "gp", "rsp" ], out => [ "rsp:I|S", "none" ] },
165         ins       => [ "base", "index", "mem", "val", "stack" ],
166         emit      => '. push %S1',
167         outs      => [ "stack", "M" ],
168         am        => "source,unary",
169         latency   => 2,
170 #       units     => [ "GP" ],
171 },
172 Add => {
173         op_flags   => [ "commutative" ],
174         irn_flags  => [ "rematerializable" ],
175         state      => "exc_pinned",
176         reg_req    => { in => [ "gp", "gp" ],
177                         out => [ "gp" ] },
178         in         => [ "left", "right" ],
179         outs       => [ "res" ],
180         mode       => $mode_gp,
181         modified_flags => 1,
182 },
183 Mul => {
184         # we should not rematrialize this node. It produces 2 results and has
185         # very strict constraints
186         state     => "exc_pinned",
187         reg_req   => { in  => [ "rax", "gp" ],
188                        out => [ "rax rdx" ] },
189         ins       => [ "left", "right" ],
190         emit      => '. mul %S2',
191         outs      => [ "res" ],
192         mode      => $mode_gp,
193         am        => "source,binary",
194         modified_flags => $status_flags
195 },
196 Sub => {
197         irn_flags  => [ "rematerializable" ],
198         state      => "exc_pinned",
199         reg_req    => { in => [ "gp", "gp" ],
200                         out => [ "gp" ] },
201         in         => [ "left", "right" ],
202         outs       => [ "res" ],
203         mode       => $mode_gp,
204         modified_flags => 1,
205 },
206 Neg => {
207         irn_flags => [ "rematerializable" ],
208         reg_req   => { in => [ "gp" ],
209                        out => [ "in_r1", "flags" ] },
210         emit      => '. neg %S1',
211         ins       => [ "val" ],
212         outs      => [ "res", "flags" ],
213         mode      => $mode_gp,
214         modified_flags => $status_flags
215 },
216 Immediate => {
217         op_flags  => [ "constlike" ],
218         attr      => "unsigned imm_value",
219         init_attr => "attr->ext.imm_value = imm_value;",
220         reg_req   => { out => [ "gp" ] },
221         emit      => '. mov %C, %D1',
222         mode      => $mode_gp,
223 },
224 SymConst => {
225         op_flags  => [ "constlike" ],
226         irn_flags => [ "rematerializable" ],
227         attr      => "ir_entity *entity",
228         attr_type => "amd64_SymConst_attr_t",
229         reg_req   => { out => [ "gp" ] },
230         outs      => [ "res" ],
231         mode      => $mode_gp,
232 },
233 Conv => {
234         state     => "exc_pinned",
235         attr      => "ir_mode *smaller_mode",
236         init_attr => "attr->ls_mode = smaller_mode;",
237         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
238         ins       => [ "val" ],
239         outs      => [ "res" ],
240         mode      => $mode_gp,
241 },
242 Jmp => {
243         state     => "pinned",
244         op_flags  => [ "cfopcode" ],
245         reg_req   => { out => [ "none" ] },
246         mode      => "mode_X",
247 },
248 Cmp => {
249         irn_flags => [ "rematerializable" ],
250         state     => "exc_pinned",
251         reg_req   => { in  => [ "gp", "gp" ],
252                        out => [ "flags" ] },
253         ins       => [ "left", "right" ],
254         outs      => [ "eflags" ],
255         emit      => '. cmp %S1, %S2',
256         attr      => "int ins_permuted, int cmp_unsigned",
257         init_attr => "attr->data.ins_permuted   = ins_permuted;\n".
258                      "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
259         mode      => $mode_flags,
260         modified_flags => 1,
261 },
262 Jcc => {
263         state     => "pinned",
264         op_flags  => [ "labeled", "cfopcode", "forking" ],
265         reg_req   => { in  => [ "eflags" ], out => [ "none", "none" ] },
266         ins       => [ "eflags" ],
267         outs      => [ "false", "true" ],
268         attr      => "ir_relation relation",
269         init_attr => "attr->ext.relation = relation;",
270         mode      => "mode_T",
271 },
272 Load => {
273         op_flags  => [ "labeled" ],
274         state     => "exc_pinned",
275         reg_req   => { in => [ "gp", "none" ],
276                        out => [ "gp", "none" ] },
277         ins       => [ "ptr", "mem" ],
278         outs      => [ "res",  "M" ],
279         attr      => "ir_entity *entity",
280         attr_type => "amd64_SymConst_attr_t",
281         emit      => ". mov %O(%S1), %D1"
282 },
283 FrameAddr => {
284         op_flags  => [ "constlike" ],
285         irn_flags => [ "rematerializable" ],
286         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
287         ins       => [ "base" ],
288         attr      => "ir_entity *entity",
289         attr_type => "amd64_SymConst_attr_t",
290         mode      => $mode_gp,
291 },
292 Store => {
293         op_flags  => [ "labeled" ],
294         state     => "exc_pinned",
295         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
296         ins       => [ "ptr", "val", "mem" ],
297         outs      => [ "M" ],
298         attr      => "ir_entity *entity",
299         attr_type => "amd64_SymConst_attr_t",
300         mode      => "mode_M",
301         emit      => ". mov %S2, %O(%S1)"
302 },
303
304 #NoReg_GP => {
305 #       state     => "pinned",
306 #       op_flags  => [ "constlike", "dump_noblcok", "dump_noinput" ],
307 #       reg_req   => { out => [ "gp_NOREG:I" ] },
308 #       units     => [],
309 #       emit      => "",
310 #       latency   => 0,
311 #       mode      => $mode_gp,
312 #},
313 );