9a11e7bc2fbfc2eb7b6e440767999412cdfbb9bf
[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 %init_attr = (
125         amd64_attr_t           =>
126                  "\tinit_amd64_attributes(res, irn_flags_, in_reqs, n_res);",
127         amd64_SymConst_attr_t =>
128                 "\tinit_amd64_attributes(res, irn_flags_, in_reqs, n_res);"
129                 . "\tinit_amd64_SymConst_attributes(res, entity);",
130         amd64_condcode_attr_t =>
131                 "\tinit_amd64_attributes(res, irn_flags_, in_reqs, n_res);"
132                 . "\tinit_amd64_condcode_attributes(res, pnc);",
133 );
134
135 %compare_attr = (
136         amd64_attr_t           => "cmp_amd64_attr",
137         amd64_SymConst_attr_t  => "cmp_amd64_attr_SymConst",
138         amd64_condcode_attr_t  => "cmp_amd64_attr_condcode",
139 );
140
141 %nodes = (
142 Push => {
143         state     => "exc_pinned",
144         reg_req   => { in => [ "gp", "gp", "none", "gp", "rsp" ], out => [ "rsp:I|S", "none" ] },
145         ins       => [ "base", "index", "mem", "val", "stack" ],
146         emit      => 'push %S0',
147         outs      => [ "stack", "M" ],
148         am        => "source,unary",
149         latency   => 2,
150 #       units     => [ "GP" ],
151 },
152
153 Add => {
154         op_flags   => [ "commutative" ],
155         irn_flags  => [ "rematerializable" ],
156         state      => "exc_pinned",
157         reg_req    => { in => [ "gp", "gp" ],
158                         out => [ "gp" ] },
159         ins        => [ "left", "right" ],
160         outs       => [ "res" ],
161         mode       => $mode_gp,
162         modified_flags => 1,
163 },
164
165 Mul => {
166         # we should not rematrialize this node. It produces 2 results and has
167         # very strict constraints
168         state     => "exc_pinned",
169         reg_req   => { in  => [ "rax", "gp" ],
170                        out => [ "rax rdx" ] },
171         ins       => [ "left", "right" ],
172         emit      => 'mul %S1',
173         outs      => [ "res" ],
174         mode      => $mode_gp,
175         am        => "source,binary",
176         modified_flags => $status_flags
177 },
178
179 Sub => {
180         irn_flags  => [ "rematerializable" ],
181         state      => "exc_pinned",
182         reg_req    => { in => [ "gp", "gp" ],
183                         out => [ "gp" ] },
184         ins        => [ "left", "right" ],
185         outs       => [ "res" ],
186         mode       => $mode_gp,
187         modified_flags => 1,
188 },
189
190 Neg => {
191         irn_flags => [ "rematerializable" ],
192         reg_req   => { in => [ "gp" ],
193                        out => [ "in_r1", "flags" ] },
194         emit      => 'neg %S0',
195         ins       => [ "val" ],
196         outs      => [ "res", "flags" ],
197         mode      => $mode_gp,
198         modified_flags => $status_flags
199 },
200
201 Immediate => {
202         op_flags  => [ "constlike" ],
203         attr      => "unsigned imm_value",
204         init_attr => "attr->ext.imm_value = imm_value;",
205         reg_req   => { out => [ "gp" ] },
206         emit      => 'mov %C, %D0',
207         mode      => $mode_gp,
208 },
209
210 SymConst => {
211         op_flags  => [ "constlike" ],
212         irn_flags => [ "rematerializable" ],
213         attr      => "ir_entity *entity",
214         attr_type => "amd64_SymConst_attr_t",
215         reg_req   => { out => [ "gp" ] },
216         outs      => [ "res" ],
217         mode      => $mode_gp,
218 },
219
220 Conv => {
221         state     => "exc_pinned",
222         attr      => "ir_mode *smaller_mode",
223         init_attr => "attr->ls_mode = smaller_mode;",
224         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
225         ins       => [ "val" ],
226         outs      => [ "res" ],
227         mode      => $mode_gp,
228 },
229
230 Jmp => {
231         state     => "pinned",
232         op_flags  => [ "cfopcode" ],
233         reg_req   => { out => [ "none" ] },
234         mode      => "mode_X",
235 },
236
237 Cmp => {
238         irn_flags => [ "rematerializable" ],
239         state     => "exc_pinned",
240         reg_req   => { in  => [ "gp", "gp" ],
241                        out => [ "flags" ] },
242         ins       => [ "left", "right" ],
243         outs      => [ "eflags" ],
244         emit      => 'cmp %S0, %S1',
245         attr      => "int ins_permuted, int cmp_unsigned",
246         init_attr => "attr->data.ins_permuted   = ins_permuted;\n".
247                      "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
248         mode      => $mode_flags,
249         modified_flags => 1,
250 },
251
252 Jcc => {
253         state     => "pinned",
254         op_flags  => [ "cfopcode", "forking" ],
255         reg_req   => { in  => [ "eflags" ], out => [ "none", "none" ] },
256         ins       => [ "eflags" ],
257         outs      => [ "false", "true" ],
258         attr      => "ir_relation relation",
259         init_attr => "attr->ext.relation = relation;",
260         mode      => "mode_T",
261 },
262
263 Load => {
264         op_flags  => [ "uses_memory" ],
265         state     => "exc_pinned",
266         reg_req   => { in => [ "gp", "none" ],
267                        out => [ "gp", "none" ] },
268         ins       => [ "ptr", "mem" ],
269         outs      => [ "res",  "M" ],
270         attr      => "ir_entity *entity",
271         attr_type => "amd64_SymConst_attr_t",
272         emit      => "mov %O(%S0), %D0"
273 },
274
275 FrameAddr => {
276         op_flags  => [ "constlike" ],
277         irn_flags => [ "rematerializable" ],
278         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
279         ins       => [ "base" ],
280         attr      => "ir_entity *entity",
281         attr_type => "amd64_SymConst_attr_t",
282         mode      => $mode_gp,
283 },
284
285 Store => {
286         op_flags  => [ "uses_memory" ],
287         state     => "exc_pinned",
288         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
289         ins       => [ "ptr", "val", "mem" ],
290         outs      => [ "M" ],
291         attr      => "ir_entity *entity",
292         attr_type => "amd64_SymConst_attr_t",
293         mode      => "mode_M",
294         emit      => "mov %S1, %O(%S0)"
295 },
296
297 #NoReg_GP => {
298 #       state     => "pinned",
299 #       op_flags  => [ "constlike", "dump_noblcok" ],
300 #       reg_req   => { out => [ "gp_NOREG:I" ] },
301 #       units     => [],
302 #       emit      => "",
303 #       latency   => 0,
304 #       mode      => $mode_gp,
305 #},
306 );