be: remove remnants of machine description
[libfirm] / ir / be / ia32 / ia32_spec.pl
index 199a7d4..f907451 100644 (file)
@@ -1,30 +1,33 @@
-# Creation: 2005/10/19
-# $Id$
 # This is the specification for the ia32 assembler Firm-operations
 
 $arch = "ia32";
 
+$mode_xmm           = "mode_D";
+$mode_mmx           = "mode_D";
+$mode_fp87          = "ia32_mode_E";
+$mode_gp            = "mode_Iu";
+$mode_flags         = "mode_Iu";
+$mode_fpcw          = "ia32_mode_fpcw";
+
 # register types:
 $normal      =  0; # no special type
-$caller_save =  1; # caller save (register must be saved by the caller of a function)
-$callee_save =  2; # callee save (register must be saved by the called function)
-$ignore      =  4; # ignore (do not assign this register)
-$arbitrary   =  8; # emitter can choose an arbitrary register of this class
-$virtual     = 16; # the register is a virtual one
-$state       = 32; # register represents a state
+$ignore      =  1; # ignore (do not assign this register)
+$arbitrary   =  2; # emitter can choose an arbitrary register of this class
+$virtual     =  4; # the register is a virtual one
+$state       =  8; # register represents a state
 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
 %reg_classes = (
        gp => [
-               { name => "edx", type => $caller_save },
-               { name => "ecx", type => $caller_save },
-               { name => "eax", type => $caller_save },
-               { name => "ebx", type => $callee_save },
-               { name => "esi", type => $callee_save },
-               { name => "edi", type => $callee_save },
-               { name => "ebp", type => $callee_save },
+               { name => "edx" },
+               { name => "ecx" },
+               { name => "eax" },
+               { name => "ebx" },
+               { name => "esi" },
+               { name => "edi" },
+               { name => "ebp" },
                { name => "esp", type => $ignore },
                { name => "gp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg nodes
-               { mode => "mode_Iu" }
+               { mode => $mode_gp }
        ],
        mmx => [
                { name => "mm0", type => $ignore },
@@ -35,31 +38,31 @@ $state       = 32; # register represents a state
                { name => "mm5", type => $ignore },
                { name => "mm6", type => $ignore },
                { name => "mm7", type => $ignore },
-               { mode => "mode_E", flags => "manual_ra" }
+               { mode => $mode_mmx, flags => "manual_ra" }
        ],
        xmm => [
-               { name => "xmm0", type => $caller_save },
-               { name => "xmm1", type => $caller_save },
-               { name => "xmm2", type => $caller_save },
-               { name => "xmm3", type => $caller_save },
-               { name => "xmm4", type => $caller_save },
-               { name => "xmm5", type => $caller_save },
-               { name => "xmm6", type => $caller_save },
-               { name => "xmm7", type => $caller_save },
+               { name => "xmm0" },
+               { name => "xmm1" },
+               { name => "xmm2" },
+               { name => "xmm3" },
+               { name => "xmm4" },
+               { name => "xmm5" },
+               { name => "xmm6" },
+               { name => "xmm7" },
                { name => "xmm_NOREG", type => $ignore | $virtual },     # we need a dummy register for NoReg nodes
-               { mode => "mode_E" }
+               { mode => $mode_xmm }
        ],
        vfp => [
-               { name => "vf0", type => $caller_save },
-               { name => "vf1", type => $caller_save },
-               { name => "vf2", type => $caller_save },
-               { name => "vf3", type => $caller_save },
-               { name => "vf4", type => $caller_save },
-               { name => "vf5", type => $caller_save },
-               { name => "vf6", type => $caller_save },
-               { name => "vf7", type => $caller_save },
+               { name => "vf0" },
+               { name => "vf1" },
+               { name => "vf2" },
+               { name => "vf3" },
+               { name => "vf4" },
+               { name => "vf5" },
+               { name => "vf6" },
+               { name => "vf7" },
                { name => "vfp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg nodes
-               { mode => "mode_E" }
+               { mode => $mode_fp87 }
        ],
        st => [
                { name => "st0", realname => "st",    type => $ignore },
@@ -70,11 +73,11 @@ $state       = 32; # register represents a state
                { name => "st5", realname => "st(5)", type => $ignore },
                { name => "st6", realname => "st(6)", type => $ignore },
                { name => "st7", realname => "st(7)", type => $ignore },
-               { mode => "mode_E", flags => "manual_ra" }
+               { mode => $mode_fp87, flags => "manual_ra" }
        ],
        fp_cw => [      # the floating point control word
                { name => "fpcw", type => $ignore | $state },
-               { mode => "ia32_mode_fpcw", flags => "manual_ra|state" }
+               { mode => $mode_fpcw, flags => "manual_ra|state" }
        ],
        flags => [
                { name => "eflags", type => 0 },
@@ -141,7 +144,7 @@ sub ia32_custom_init_attr {
        my $res    = "";
 
        if(defined($node->{modified_flags})) {
-               $res .= "\tarch_irn_add_flags(res, arch_irn_flags_modify_flags);\n";
+               $res .= "\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n";
        }
        if(defined($node->{am})) {
                my $am = $node->{am};
@@ -167,31 +170,31 @@ $custom_init_attr_func = \&ia32_custom_init_attr;
 
 %init_attr = (
        ia32_asm_attr_t =>
-               "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
+               "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
                "\tinit_ia32_x87_attributes(res);".
                "\tinit_ia32_asm_attributes(res);",
        ia32_attr_t     =>
-               "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);",
+               "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);",
        ia32_call_attr_t =>
-               "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
+               "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
                "\tinit_ia32_call_attributes(res, pop, call_tp);",
        ia32_condcode_attr_t =>
-               "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
+               "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
                "\tinit_ia32_condcode_attributes(res, condition_code);",
        ia32_switch_attr_t =>
-               "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
-               "\tinit_ia32_switch_attributes(res, default_pn);",
+               "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
+               "\tinit_ia32_switch_attributes(res, switch_table);",
        ia32_copyb_attr_t =>
-               "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
+               "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
                "\tinit_ia32_copyb_attributes(res, size);",
        ia32_immediate_attr_t =>
-               "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
+               "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
                "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, no_pic_adjust, offset);",
        ia32_x87_attr_t =>
-               "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
+               "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
                "\tinit_ia32_x87_attributes(res);",
        ia32_climbframe_attr_t =>
-               "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
+               "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
                "\tinit_ia32_climbframe_attributes(res, count);",
 );
 
@@ -200,8 +203,8 @@ $custom_init_attr_func = \&ia32_custom_init_attr;
        ia32_attr_t            => "ia32_compare_nodes_attr",
        ia32_call_attr_t       => "ia32_compare_call_attr",
        ia32_condcode_attr_t   => "ia32_compare_condcode_attr",
-       ia32_switch_attr_t     => "ia32_compare_switch_attr",
        ia32_copyb_attr_t      => "ia32_compare_copyb_attr",
+       ia32_switch_attr_t     => "ia32_compare_nodes_attr",
        ia32_immediate_attr_t  => "ia32_compare_immediate_attr",
        ia32_x87_attr_t        => "ia32_compare_x87_attr",
        ia32_climbframe_attr_t => "ia32_compare_climbframe_attr",
@@ -210,10 +213,6 @@ $custom_init_attr_func = \&ia32_custom_init_attr;
 %operands = (
 );
 
-$mode_xmm           = "mode_E";
-$mode_gp            = "mode_Iu";
-$mode_flags         = "mode_Iu";
-$mode_fpcw          = "ia32_mode_fpcw";
 $status_flags       = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
 $status_flags_wo_cf = [       "PF", "AF", "ZF", "SF", "OF" ];
 $fpcw_flags         = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
@@ -311,14 +310,15 @@ Adc => {
 },
 
 l_Add => {
-       op_flags  => [ "constlike" ],
-       reg_req   => { in => [ "none", "none" ], out => [ "none" ] },
        ins       => [ "left", "right" ],
+       attr_type => "",
+       dump_func => "NULL",
 },
 
 l_Adc => {
-       reg_req   => { in => [ "none", "none", "none" ], out => [ "none" ] },
        ins       => [ "left", "right", "eflags" ],
+       attr_type => "",
+       dump_func => "NULL",
 },
 
 Mul => {
@@ -337,14 +337,10 @@ Mul => {
 },
 
 l_Mul => {
-       # we should not rematrialize this node. It produces 2 results and has
-       # very strict constraints
-       op_flags  => [ "constlike" ],
-       cmp_attr  => "return 1;",
-       reg_req   => { in => [ "none", "none" ],
-                      out => [ "none", "none", "none", "none" ] },
        ins       => [ "left", "right" ],
        outs      => [ "res_low", "flags", "M", "res_high" ],
+       attr_type => "",
+       dump_func => "NULL",
 },
 
 IMul => {
@@ -378,12 +374,10 @@ IMul1OP => {
 },
 
 l_IMul => {
-       op_flags  => [ "constlike" ],
-       cmp_attr  => "return 1;",
-       reg_req   => { in => [ "none", "none" ],
-                      out => [ "none", "none", "none", "none" ] },
        ins       => [ "left", "right" ],
        outs      => [ "res_low", "flags", "M", "res_high" ],
+       attr_type => "",
+       dump_func => "NULL",
 },
 
 And => {
@@ -557,7 +551,7 @@ SubMem8Bit => {
 Sbb => {
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
-                      out => [ "in_r4 !in_r5", "flags", "none" ] },
+                      out => [ "in_r4", "flags", "none" ] },
        ins       => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ],
        outs      => [ "res", "flags", "M" ],
        am        => "source,binary",
@@ -581,13 +575,15 @@ Sbb0 => {
 },
 
 l_Sub => {
-       reg_req   => { in => [ "none", "none" ], out => [ "none" ] },
        ins       => [ "minuend", "subtrahend" ],
+       attr_type => "",
+       dump_func => "NULL",
 },
 
 l_Sbb => {
-       reg_req   => { in => [ "none", "none", "none" ], out => [ "none" ] },
        ins       => [ "minuend", "subtrahend", "eflags" ],
+       attr_type => "",
+       dump_func => "NULL",
 },
 
 IDiv => {
@@ -990,7 +986,7 @@ Setcc => {
        # (when we emit the setX; setp; orb and the setX;setnp;andb sequences)
        init_attr => "set_ia32_ls_mode(res, mode_Bu);\n"
                . "\tif (condition_code & ia32_cc_additional_float_cases) {\n"
-               . "\t\tarch_irn_add_flags(res, arch_irn_flags_modify_flags);\n"
+               . "\t\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n"
                . "\t\t/* attr->latency = 3; */\n"
                . "\t}\n",
        latency   => 1,
@@ -1044,14 +1040,13 @@ Jcc => {
 SwitchJmp => {
        state     => "pinned",
        op_flags  => [ "labeled", "cfopcode", "forking" ],
-       reg_req   => { in => [ "gp" ] },
-       mode      => "mode_T",
+       reg_req   => { in => [ "gp", "gp" ] },
+       ins       => [ "base", "index" ],
+       out_arity => "variable",
        attr_type => "ia32_switch_attr_t",
-       attr      => "long default_pn",
-       latency   => 3,
+       attr      => "const ir_switch_table *switch_table",
+       latency   => 2,
        units     => [ "BRANCH" ],
-       modified_flags => $status_flags,
-       init_attr => "info->out_infos = NULL;", # XXX ugly hack for out requirements
 },
 
 Jmp => {
@@ -1124,7 +1119,7 @@ NoReg_VFP => {
        reg_req   => { out => [ "vfp_NOREG:I" ] },
        units     => [],
        emit      => "",
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        latency   => 0,
        attr_type => "ia32_x87_attr_t",
 },
@@ -1137,7 +1132,7 @@ NoReg_XMM => {
        units     => [],
        emit      => "",
        latency   => 0,
-       mode      => "mode_E"
+       mode      => $mode_xmm,
 },
 
 ChangeCW => {
@@ -1221,7 +1216,6 @@ Store => {
        emit      => '. mov%M %SI3, %AM',
        latency   => 2,
        units     => [ "GP" ],
-       mode      => "mode_M",
 },
 
 Store8Bit => {
@@ -1234,7 +1228,6 @@ Store8Bit => {
        emit      => '. mov%M %SB3, %AM',
        latency   => 2,
        units     => [ "GP" ],
-       mode      => "mode_M",
 },
 
 Lea => {
@@ -1436,13 +1429,14 @@ Popcnt => {
 },
 
 Call => {
+       op_flags  => [ "fragile" ],
        state     => "exc_pinned",
        reg_req   => {
                in  => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
-               out => [ "esp:I|S", "fpcw:I", "none", "eax", "ecx", "edx", "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" ]
+               out => [ "esp:I|S", "fpcw:I", "none", "eax", "ecx", "edx", "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "none", "none" ]
        },
        ins       => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
-       outs      => [ "stack", "fpcw", "M", "eax", "ecx", "edx", "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" ],
+       outs      => [ "stack", "fpcw", "M", "eax", "ecx", "edx", "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "X_regular", "X_except" ],
        attr_type => "ia32_call_attr_t",
        attr      => "unsigned pop, ir_type *call_tp",
        am        => "source,unary",
@@ -1882,7 +1876,6 @@ xStore => {
        emit     => '. mov%XXM %S3, %AM',
        latency  => 0,
        units    => [ "SSE" ],
-       mode     => "mode_M",
 },
 
 xStoreSimple => {
@@ -1895,7 +1888,6 @@ xStoreSimple => {
        emit     => '. mov%XXM %S3, %AM',
        latency  => 0,
        units    => [ "SSE" ],
-       mode     => "mode_M",
 },
 
 CvtSI2SS => {
@@ -1924,18 +1916,16 @@ CvtSI2SD => {
 
 
 l_LLtoFloat => {
-       op_flags => [ "labeled" ],
-       cmp_attr => "return 1;",
        ins      => [ "val_high", "val_low" ],
-       reg_req  => { in => [ "none", "none" ], out => [ "none" ] }
+       attr_type => "",
+       dump_func => "NULL",
 },
 
 l_FloattoLL => {
-       op_flags => [ "labeled" ],
-       cmp_attr => "return 1;",
        ins      => [ "val" ],
        outs     => [ "res_high", "res_low" ],
-       reg_req  => { in => [ "none" ], out => [ "none", "none" ] }
+       attr_type => "",
+       dump_func => "NULL",
 },
 
 CopyB => {
@@ -1980,11 +1970,12 @@ Cwtl => {
 },
 
 Conv_I2I => {
+       op_flags  => [ "fragile" ],
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none", "gp" ],
-                      out => [ "gp", "none", "none" ] },
+                      out => [ "gp", "none", "none", "none", "none" ] },
        ins       => [ "base", "index", "mem", "val" ],
-       outs      => [ "res", "flags", "M" ],
+       outs      => [ "res", "flags", "M", "X_regular", "X_except" ],
        am        => "source,unary",
        units     => [ "GP" ],
        latency   => 1,
@@ -1994,11 +1985,12 @@ Conv_I2I => {
 },
 
 Conv_I2I8Bit => {
+       op_flags  => [ "fragile" ],
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
-                      out => [ "gp", "none", "none" ] },
+                      out => [ "gp", "none", "none", "none", "none" ] },
        ins       => [ "base", "index", "mem", "val" ],
-       outs      => [ "res", "flags", "M" ],
+       outs      => [ "res", "flags", "M", "X_regular", "X_except" ],
        am        => "source,unary",
        units     => [ "GP" ],
        latency   => 1,
@@ -2050,7 +2042,7 @@ vfadd => {
        am        => "source,binary",
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2064,7 +2056,7 @@ vfmul => {
        am        => "source,binary",
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2078,7 +2070,7 @@ vfsub => {
        am        => "source,binary",
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2099,7 +2091,7 @@ vfprem => {
        ins       => [ "left", "right", "fpcw" ],
        latency   => 20,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2109,7 +2101,7 @@ vfabs => {
        ins       => [ "value" ],
        latency   => 2,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2119,7 +2111,7 @@ vfchs => {
        ins       => [ "value" ],
        latency   => 2,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2150,7 +2142,6 @@ vfst => {
        init_attr => "attr->attr.ls_mode = store_mode;",
        latency   => 2,
        units     => [ "VFP" ],
-       mode      => "mode_M",
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2166,22 +2157,25 @@ vfild => {
 },
 
 vfist => {
+       op_flags  => [ "fragile" ],
        state     => "exc_pinned",
-       reg_req   => { in => [ "gp", "gp", "none", "vfp", "fpcw" ], out => [ "none" ] },
+       reg_req   => { in => [ "gp", "gp", "none", "vfp", "fpcw" ],
+                      out => [ "none", "none", "none", "none" ] },
        ins       => [ "base", "index", "mem", "val", "fpcw" ],
-       outs      => [ "M" ],
+       outs      => [ "dummy", "M", "X_regular", "X_except" ],
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_M",
        attr_type => "ia32_x87_attr_t",
 },
 
 # SSE3 fisttp instruction
 vfisttp => {
+       op_flags  => [ "fragile" ],
        state     => "exc_pinned",
-       reg_req   => { in => [ "gp", "gp", "none", "vfp" ], out => [ "in_r4", "none" ]},
+       reg_req   => { in => [ "gp", "gp", "none", "vfp" ],
+                      out => [ "in_r4", "none", "none", "none" ]},
        ins       => [ "base", "index", "mem", "val" ],
-       outs      => [ "res", "M" ],
+       outs      => [ "res", "M", "X_regular", "X_except" ],
        latency   => 4,
        units     => [ "VFP" ],
        attr_type => "ia32_x87_attr_t",
@@ -2193,7 +2187,7 @@ vfldz => {
        outs      => [ "res" ],
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2203,7 +2197,7 @@ vfld1 => {
        outs      => [ "res" ],
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2213,7 +2207,7 @@ vfldpi => {
        outs      => [ "res" ],
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2223,7 +2217,7 @@ vfldln2 => {
        outs      => [ "res" ],
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2233,7 +2227,7 @@ vfldlg2 => {
        outs      => [ "res" ],
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2243,7 +2237,7 @@ vfldl2t => {
        outs      => [ "res" ],
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2253,7 +2247,7 @@ vfldl2e => {
        outs      => [ "res" ],
        latency   => 4,
        units     => [ "VFP" ],
-       mode      => "mode_E",
+       mode      => $mode_fp87,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -2720,7 +2714,6 @@ xxStore => {
        emit     => '. movdqu %binop',
        units    => [ "SSE" ],
        latency  => 1,
-       mode     => "mode_M",
 },
 
 ); # end of %nodes