amd64: added be_Spill and be_Reload transformation.
[libfirm] / ir / be / amd64 / amd64_spec.pl
index 5862e96..8d81010 100644 (file)
@@ -101,9 +101,9 @@ $arch = "amd64";
                { name => "rax", type => 1 },
                { name => "rcx", type => 1 },
                { name => "rdx", type => 1 },
+               { name => "rsi", type => 1 },
+               { name => "rdi", type => 1 },
                { name => "rbx", type => 2 },
-               { name => "rsi", type => 2 },
-               { name => "rdi", type => 2 },
                { name => "rbp", type => 2 },
                { name => "rsp", type => 4 }, # stackpointer?
                { name => "r8",  type => 1 },
@@ -114,29 +114,50 @@ $arch = "amd64";
                { name => "r13", type => 2 },
                { name => "r14", type => 2 },
                { name => "r15", type => 2 },
-               { mode => "mode_Iu" }
+#              { name => "gp_NOREG", type => 4 }, # we need a dummy register for NoReg nodes
+               { mode => "mode_Lu" }
+       ],
+#      fp => [
+#              { name => "xmm0", type => 1 },
+#              { name => "xmm1", type => 1 },
+#              { name => "xmm2", type => 1 },
+#              { name => "xmm3", type => 1 },
+#              { name => "xmm4", type => 1 },
+#              { name => "xmm5", type => 1 },
+#              { name => "xmm6", type => 1 },
+#              { name => "xmm7", type => 1 },
+#              { name => "xmm8", type => 1 },
+#              { name => "xmm9", type => 1 },
+#              { name => "xmm10", type => 1 },
+#              { name => "xmm11", type => 1 },
+#              { name => "xmm12", type => 1 },
+#              { name => "xmm13", type => 1 },
+#              { name => "xmm14", type => 1 },
+#              { name => "xmm15", type => 1 },
+#              { mode => "mode_D" }
+#      ]
+       flags => [
+               { name => "eflags", type => 0 },
+               { mode => "mode_Iu", flags => "manual_ra" }
        ],
-       fp => [
-               { name => "xmm0", type => 1 },
-               { name => "xmm1", type => 1 },
-               { name => "xmm2", type => 1 },
-               { name => "xmm3", type => 1 },
-               { name => "xmm4", type => 1 },
-               { name => "xmm5", type => 1 },
-               { name => "xmm6", type => 1 },
-               { name => "xmm7", type => 1 },
-               { name => "xmm8", type => 1 },
-               { name => "xmm9", type => 1 },
-               { name => "xmm10", type => 1 },
-               { name => "xmm11", type => 1 },
-               { name => "xmm12", type => 1 },
-               { name => "xmm13", type => 1 },
-               { name => "xmm14", type => 1 },
-               { name => "xmm15", type => 1 },
-               { mode => "mode_D" }
-       ]
 );
 
+$mode_gp        = "mode_Lu";
+$mode_flags     = "mode_Iu";
+
+sub amd64_custom_init_attr {
+       my $constr = shift;
+       my $node   = shift;
+       my $name   = shift;
+       my $res    = "";
+
+       if(defined($node->{modified_flags})) {
+               $res .= "\tarch_irn_add_flags(res, arch_irn_flags_modify_flags);\n";
+       }
+       return $res;
+}
+$custom_init_attr_func = \&amd64_custom_init_attr;
+
 %emit_templates = (
        S1 => "${arch}_emit_source_register(node, 0);",
        S2 => "${arch}_emit_source_register(node, 1);",
@@ -156,18 +177,18 @@ $arch = "amd64";
 %init_attr = (
        amd64_attr_t           =>
                 "\tinit_amd64_attributes(res, flags, in_reqs, exec_units, n_res);",
-       amd64_immediate_attr_t =>
-               "\tinit_amd64_attributes(res, flags, in_reqs, exec_units, n_res);"
-               . "\tinit_amd64_immediate_attributes(res, imm_value);",
        amd64_SymConst_attr_t =>
                "\tinit_amd64_attributes(res, flags, in_reqs, exec_units, n_res);"
                . "\tinit_amd64_SymConst_attributes(res, entity);",
+       amd64_condcode_attr_t =>
+               "\tinit_amd64_attributes(res, flags, in_reqs, exec_units, n_res);"
+               . "\tinit_amd64_condcode_attributes(res, pnc);",
 );
 
 %compare_attr = (
        amd64_attr_t           => "cmp_amd64_attr",
-       amd64_immediate_attr_t => "cmp_amd64_attr_immediate",
        amd64_SymConst_attr_t  => "cmp_amd64_attr_SymConst",
+       amd64_condcode_attr_t  => "cmp_amd64_attr_condcode",
 );
 
 %nodes = (
@@ -182,23 +203,46 @@ Push => {
 #      units     => [ "GP" ],
 },
 Add => {
+       op_flags   => "C",
+       irn_flags  => "R",
+       state      => "exc_pinned",
+       reg_req    => { in => [ "gp", "gp" ],
+                       out => [ "gp" ] },
+       in         => [ "left", "right" ],
+       outs       => [ "res" ],
+       mode       => $mode_gp,
+       modified_flags => 1,
+},
+Mul => {
+       # we should not rematrialize this node. It produces 2 results and has
+       # very strict constraints
+       state     => "exc_pinned",
+       reg_req   => { in  => [ "rax", "gp" ],
+                      out => [ "rax rdx" ] },
+       ins       => [ "left", "right" ],
+       emit      => '. mul %S2',
+       outs      => [ "res" ],
+       mode      => $mode_gp,
+       am        => "source,binary",
+       modified_flags => $status_flags
+},
+Sub => {
        irn_flags  => "R",
        state      => "exc_pinned",
        reg_req    => { in => [ "gp", "gp" ],
                        out => [ "gp" ] },
        in         => [ "left", "right" ],
-       emit       => ". mov %S2, %D1\n"
-                    . ". add %S1, %D1\n",
        outs       => [ "res" ],
-       mode       => "mode_Iu",
+       mode       => $mode_gp,
+       modified_flags => 1,
 },
 Immediate => {
        op_flags  => "c",
        attr      => "unsigned imm_value",
-       attr_type => "amd64_immediate_attr_t",
+       init_attr => "attr->ext.imm_value = imm_value;",
        reg_req   => { out => [ "gp" ] },
-       emit      => '. movq %C, %D1',
-       mode      => "mode_Iu",
+       emit      => '. mov %C, %D1',
+       mode      => $mode_gp,
 },
 SymConst => {
        op_flags  => "c",
@@ -206,6 +250,82 @@ SymConst => {
        attr      => "ir_entity *entity",
        attr_type => "amd64_SymConst_attr_t",
        reg_req   => { out => [ "gp" ] },
-       mode      => 'mode_Iu',
+       mode      => $mode_gp,
+},
+Conv => {
+       state     => "exc_pinned",
+       attr      => "ir_mode *smaller_mode",
+       init_attr => "attr->ls_mode = smaller_mode;",
+       reg_req   => { in => [ "gp" ], out => [ "gp" ] },
+       ins       => [ "val" ],
+       outs      => [ "res" ],
+       mode      => $mode_gp,
+},
+Jmp => {
+       state     => "pinned",
+       op_flags  => "X",
+       reg_req   => { out => [ "none" ] },
+       mode      => "mode_X",
+},
+Cmp => {
+       irn_flags => "R",
+       state     => "exc_pinned",
+       reg_req   => { in  => [ "gp", "gp" ],
+                      out => [ "flags" ] },
+       ins       => [ "left", "right" ],
+       outs      => [ "eflags" ],
+       emit      => '. cmp %S1, %S2',
+       attr      => "int ins_permuted, int cmp_unsigned",
+       init_attr => "attr->data.ins_permuted   = ins_permuted;\n".
+                    "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
+       mode      => $mode_flags,
+       modified_flags => 1,
+},
+Jcc => {
+       state     => "pinned",
+       op_flags  => "L|X|Y",
+       reg_req   => { in  => [ "eflags" ], out => [ "none", "none" ] },
+       ins       => [ "eflags" ],
+       outs      => [ "false", "true" ],
+       attr      => "pn_Cmp pnc",
+       init_attr => "attr->ext.pnc = pnc;",
+       mode      => "mode_T",
+},
+Load => {
+       op_flags  => "L|F",
+       state     => "exc_pinned",
+       reg_req   => { in => [ "gp", "none" ],
+                      out => [ "gp", "none" ] },
+       ins       => [ "ptr", "mem" ],
+       outs      => [ "res",  "M" ],
+       emit      => ". mov (%S1), %D1"
 },
+FrameAddr => {
+       op_flags  => "c",
+       irn_flags => "R",
+       reg_req   => { in => [ "gp" ], out => [ "gp" ] },
+       ins       => [ "base" ],
+       attr      => "ir_entity *entity",
+       attr_type => "amd64_SymConst_attr_t",
+       mode      => $mode_gp,
+},
+Store => {
+       op_flags  => "L|F",
+       state     => "exc_pinned",
+       reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
+       ins       => [ "ptr", "val", "mem" ],
+       outs      => [ "M" ],
+       mode      => "mode_M",
+       emit      => ". mov %S2, (%S1)"
+},
+
+#NoReg_GP => {
+#      state     => "pinned",
+#      op_flags  => "c|NB|NI",
+#      reg_req   => { out => [ "gp_NOREG:I" ] },
+#      units     => [],
+#      emit      => "",
+#      latency   => 0,
+#      mode      => $mode_gp,
+#},
 );