remove old+unused code
[libfirm] / ir / be / ia32 / ia32_spec.pl
index 35e8d99..ebffcad 100644 (file)
 
 $arch = "ia32";
 
-# The node description is done as a perl hash initializer with the
-# following structure:
-#
-# %nodes = (
-#
-# <op-name> => {
-#   op_flags  => "N|L|C|X|I|F|Y|H|c|K|n",
-#   irn_flags => "R|N"
-#   arity     => "0|1|2|3 ... |variable|dynamic|any",
-#   state     => "floats|pinned|mem_pinned|exc_pinned",
-#   args      => [
-#                    { type => "type 1", name => "name 1" },
-#                    { type => "type 2", name => "name 2" },
-#                    ...
-#                  ],
-#   comment   => "any comment for constructor",
-#   reg_req   => { in => [ "reg_class|register" ], out => [ "reg_class|register|in_rX" ] },
-#   cmp_attr  => "c source code for comparing node attributes",
-#   outs      => { "out1", "out2" } # optional, creates pn_op_out1, ... consts
-#   ins       => { "in1", "in2" }   # optional, creates n_op_in1, ... consts
-#   mode      => "mode_Iu"          # optional, predefines the mode
-#   emit      => "emit code with templates",
-#   attr      => "additional attribute arguments for constructor",
-#   init_attr => "emit attribute initialization template",
-#   hash_func => "name of the hash function for this operation",
-#   latency   => "latency of this operation (can be float)"
-#   attr_type => "name of the attribute struct",
-#   modified_flags =>  [ "CF", ... ] # optional, list of modified flags
-# },
-#
-# ... # (all nodes you need to describe)
-#
-# ); # close the %nodes initializer
-
-# state: state of the operation, OPTIONAL (default is "floats")
-#
-# arity: arity of the operation, MUST NOT BE OMITTED
-#
-# args:  the OPTIONAL arguments of the node constructor (debug, irg and block
-#        are always the first 3 arguments and are always autmatically
-#        created)
-#        If this key is missing the following arguments will be created:
-#        for i = 1 .. arity: ir_node *op_i
-#        ir_mode *mode
-#
-# outs:  if a node defines more than one output, the names of the projections
-#        nodes having outs having automatically the mode mode_T
-#        example: [ "frame", "stack", "M" ]
-#
-# comment: OPTIONAL comment for the node constructor
-#
-# rd_constructor: for every operation there will be a
-#      new_rd_<arch>_<op-name> function with the arguments from above
-#      which creates the ir_node corresponding to the defined operation
-#      you can either put the complete source code of this function here
-#
-#      This key is OPTIONAL. If omitted, the following constructor will
-#      be created:
-#      if (!op_<arch>_<op-name>) assert(0);
-#      for i = 1 to arity
-#         set in[i] = op_i
-#      done
-#      res = new_ir_node(db, irg, block, op_<arch>_<op-name>, mode, arity, in)
-#      return res
-#
-# NOTE: rd_constructor and args are only optional if and only if arity is 0,1,2 or 3
-#
-
 # register types:
-#   0 - no special type
-#   1 - caller save (register must be saved by the caller of a function)
-#   2 - callee save (register must be saved by the called function)
-#   4 - ignore (do not automatically assign this register)
-#   8 - emitter can choose an arbitrary register of this class
-#  16 - the register is a virtual one
-#  32 - register represents a state
+$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
 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
 %reg_classes = (
        gp => [
-               { name => "edx", type => 1 },
-               { name => "ecx", type => 1 },
-               { name => "eax", type => 1 },
-               { name => "ebx", type => 2 },
-               { name => "esi", type => 2 },
-               { name => "edi", type => 2 },
-               { name => "ebp", type => 2 },
-               { name => "esp", type => 4 },
-               { name => "gp_NOREG", type => 4 | 8 | 16 }, # we need a dummy register for NoReg nodes
+               { 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 => "esp", type => $ignore },
+               { name => "gp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg nodes
                { mode => "mode_Iu" }
        ],
        mmx => [
-               { name => "mm0", type => 4 },
-               { name => "mm1", type => 4 },
-               { name => "mm2", type => 4 },
-               { name => "mm3", type => 4 },
-               { name => "mm4", type => 4 },
-               { name => "mm5", type => 4 },
-               { name => "mm6", type => 4 },
-               { name => "mm7", type => 4 },
+               { name => "mm0", type => $ignore },
+               { name => "mm1", type => $ignore },
+               { name => "mm2", type => $ignore },
+               { name => "mm3", type => $ignore },
+               { name => "mm4", type => $ignore },
+               { name => "mm5", type => $ignore },
+               { name => "mm6", type => $ignore },
+               { name => "mm7", type => $ignore },
                { mode => "mode_E", flags => "manual_ra" }
        ],
        xmm => [
-               { 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 => "xmm_NOREG", type => 4 | 16 },     # we need a dummy register for NoReg nodes
+               { 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 => "xmm_NOREG", type => $ignore | $virtual },     # we need a dummy register for NoReg nodes
                { mode => "mode_E" }
        ],
        vfp => [
-               { name => "vf0", type => 1 },
-               { name => "vf1", type => 1 },
-               { name => "vf2", type => 1 },
-               { name => "vf3", type => 1 },
-               { name => "vf4", type => 1 },
-               { name => "vf5", type => 1 },
-               { name => "vf6", type => 1 },
-               { name => "vf7", type => 1 },
-               { name => "vfp_NOREG", type => 4 | 8 | 16 }, # we need a dummy register for NoReg nodes
+               { 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 => "vfp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg nodes
                { mode => "mode_E" }
        ],
        st => [
-               { name => "st0", realname => "st",    type => 4 },
-               { name => "st1", realname => "st(1)", type => 4 },
-               { name => "st2", realname => "st(2)", type => 4 },
-               { name => "st3", realname => "st(3)", type => 4 },
-               { name => "st4", realname => "st(4)", type => 4 },
-               { name => "st5", realname => "st(5)", type => 4 },
-               { name => "st6", realname => "st(6)", type => 4 },
-               { name => "st7", realname => "st(7)", type => 4 },
+               { name => "st0", realname => "st",    type => $ignore },
+               { name => "st1", realname => "st(1)", type => $ignore },
+               { name => "st2", realname => "st(2)", type => $ignore },
+               { name => "st3", realname => "st(3)", type => $ignore },
+               { name => "st4", realname => "st(4)", type => $ignore },
+               { 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" }
        ],
        fp_cw => [      # the floating point control word
-               { name => "fpcw", type => 4|32 },
-               { mode => "mode_fpcw", flags => "manual_ra|state" }
+               { name => "fpcw", type => $ignore | $state },
+               { mode => "ia32_mode_fpcw", flags => "manual_ra|state" }
        ],
        flags => [
                { name => "eflags", type => 0 },
@@ -245,7 +177,10 @@ $custom_init_attr_func = \&ia32_custom_init_attr;
                "\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_condcode_attributes(res, pnc);",
+               "\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);",
        ia32_copyb_attr_t =>
                "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
                "\tinit_ia32_copyb_attributes(res, size);",
@@ -261,10 +196,11 @@ $custom_init_attr_func = \&ia32_custom_init_attr;
 );
 
 %compare_attr = (
-       ia32_asm_attr_t       => "ia32_compare_asm_attr",
+       ia32_asm_attr_t        => "ia32_compare_asm_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_immediate_attr_t  => "ia32_compare_immediate_attr",
        ia32_x87_attr_t        => "ia32_compare_x87_attr",
@@ -277,7 +213,7 @@ $custom_init_attr_func = \&ia32_custom_init_attr;
 $mode_xmm           = "mode_E";
 $mode_gp            = "mode_Iu";
 $mode_flags         = "mode_Iu";
-$mode_fpcw          = "mode_fpcw";
+$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",
@@ -288,6 +224,7 @@ $fpcw_flags         = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
 Immediate => {
        state     => "pinned",
        op_flags  => [ "constlike" ],
+       irn_flags => [ "not_scheduled" ],
        reg_req   => { out => [ "gp_NOREG:I" ] },
        attr      => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
        attr_type => "ia32_immediate_attr_t",
@@ -999,9 +936,8 @@ Cmp => {
        outs      => [ "eflags", "unused", "M" ],
        am        => "source,binary",
        emit      => '. cmp%M %binop',
-       attr      => "int ins_permuted, int cmp_unsigned",
-       init_attr => "attr->data.ins_permuted   = ins_permuted;\n".
-                    "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
+       attr      => "bool ins_permuted",
+       init_attr => "attr->data.ins_permuted   = ins_permuted;",
        latency   => 1,
        units     => [ "GP" ],
        mode      => $mode_flags,
@@ -1017,15 +953,28 @@ Cmp8Bit => {
        outs      => [ "eflags", "unused", "M" ],
        am        => "source,binary",
        emit      => '. cmpb %binop',
-       attr      => "int ins_permuted, int cmp_unsigned",
-       init_attr => "attr->data.ins_permuted   = ins_permuted;\n".
-                    "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
+       attr      => "bool ins_permuted",
+       init_attr => "attr->data.ins_permuted   = ins_permuted;",
        latency   => 1,
        units     => [ "GP" ],
        mode      => $mode_flags,
        modified_flags => $status_flags
 },
 
+XorHighLow => {
+       irn_flags => [ "rematerializable" ],
+       state     => "exc_pinned",
+       reg_req   => { in => [ "eax ebx ecx edx" ],
+                      out => [ "in_r1", "flags" ] },
+       emit      => '. xorb %SH0, %SB0',
+       ins       => [ "value" ],
+       outs      => [ "res", "flags" ],
+       units     => [ "GP" ],
+       latency   => 1,
+       mode      => $mode_gp,
+       modified_flags => $status_flags,
+},
+
 Test => {
        irn_flags => [ "rematerializable" ],
        state     => "exc_pinned",
@@ -1035,9 +984,8 @@ Test => {
        outs      => [ "eflags", "unused", "M" ],
        am        => "source,binary",
        emit      => '. test%M %binop',
-       attr      => "int ins_permuted, int cmp_unsigned",
-       init_attr => "attr->data.ins_permuted = ins_permuted;\n".
-                    "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
+       attr      => "bool ins_permuted",
+       init_attr => "attr->data.ins_permuted = ins_permuted;",
        latency   => 1,
        units     => [ "GP" ],
        mode      => $mode_flags,
@@ -1053,9 +1001,8 @@ Test8Bit => {
        outs      => [ "eflags", "unused", "M" ],
        am        => "source,binary",
        emit      => '. testb %binop',
-       attr      => "int ins_permuted, int cmp_unsigned",
-       init_attr => "attr->data.ins_permuted = ins_permuted;\n".
-                    "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
+       attr      => "bool ins_permuted",
+       init_attr => "attr->data.ins_permuted = ins_permuted;",
        latency   => 1,
        units     => [ "GP" ],
        mode      => $mode_flags,
@@ -1068,11 +1015,11 @@ Setcc => {
        ins       => [ "eflags" ],
        outs      => [ "res" ],
        attr_type => "ia32_condcode_attr_t",
-       attr      => "pn_Cmp pnc",
+       attr      => "ia32_condition_code_t condition_code",
        # The way we handle Setcc with float nodes (potentially) destroys the flags
        # (when we emit the setX; setp; orb and the setX;setnp;andb sequences)
        init_attr => "set_ia32_ls_mode(res, mode_Bu);\n"
-               . "\tif ((pnc & ia32_pn_Cmp_float) && ((pnc & 0xf) != pn_Cmp_Uo) && ((pnc & 0xf) != pn_Cmp_Leg)) {\n"
+               . "\tif (condition_code & ia32_cc_additional_float_cases) {\n"
                . "\t\tarch_irn_add_flags(res, arch_irn_flags_modify_flags);\n"
                . "\t\t/* attr->latency = 3; */\n"
                . "\t}\n",
@@ -1087,7 +1034,7 @@ SetccMem => {
        reg_req   => { in => [ "gp", "gp", "none", "eflags" ], out => [ "none" ] },
        ins       => [ "base", "index", "mem","eflags" ],
        attr_type => "ia32_condcode_attr_t",
-       attr      => "pn_Cmp pnc",
+       attr      => "ia32_condition_code_t condition_code",
        init_attr => "set_ia32_ls_mode(res, mode_Bu);\n",
        emit      => '. set%CMP3 %AM',
        latency   => 1,
@@ -1106,7 +1053,7 @@ CMovcc => {
        outs      => [ "res", "flags", "M" ],
        am        => "source,binary",
        attr_type => "ia32_condcode_attr_t",
-       attr      => "pn_Cmp pnc",
+       attr      => "ia32_condition_code_t condition_code",
        latency   => 1,
        units     => [ "GP" ],
        mode      => $mode_gp,
@@ -1119,7 +1066,7 @@ Jcc => {
        ins       => [ "eflags" ],
        outs      => [ "false", "true" ],
        attr_type => "ia32_condcode_attr_t",
-       attr      => "pn_Cmp pnc",
+       attr      => "ia32_condition_code_t condition_code",
        latency   => 2,
        units     => [ "BRANCH" ],
 },
@@ -1129,8 +1076,8 @@ SwitchJmp => {
        op_flags  => [ "labeled", "cfopcode", "forking" ],
        reg_req   => { in => [ "gp" ] },
        mode      => "mode_T",
-       attr_type => "ia32_condcode_attr_t",
-       attr      => "long pnc",
+       attr_type => "ia32_switch_attr_t",
+       attr      => "long default_pn",
        latency   => 3,
        units     => [ "BRANCH" ],
        modified_flags => $status_flags,
@@ -1192,6 +1139,7 @@ GetEIP => {
 NoReg_GP => {
        state     => "pinned",
        op_flags  => [ "constlike", "dump_noblock", "dump_noinput" ],
+       irn_flags => [ "not_scheduled" ],
        reg_req   => { out => [ "gp_NOREG:I" ] },
        units     => [],
        emit      => "",
@@ -1202,6 +1150,7 @@ NoReg_GP => {
 NoReg_VFP => {
        state     => "pinned",
        op_flags  => [ "constlike", "dump_noblock", "dump_noinput" ],
+       irn_flags => [ "not_scheduled" ],
        reg_req   => { out => [ "vfp_NOREG:I" ] },
        units     => [],
        emit      => "",
@@ -1213,6 +1162,7 @@ NoReg_VFP => {
 NoReg_XMM => {
        state     => "pinned",
        op_flags  => [ "constlike", "dump_noblock", "dump_noinput" ],
+       irn_flags => [ "not_scheduled" ],
        reg_req   => { out => [ "xmm_NOREG:I" ] },
        units     => [],
        emit      => "",
@@ -1223,6 +1173,7 @@ NoReg_XMM => {
 ChangeCW => {
        state     => "pinned",
        op_flags  => [ "constlike" ],
+       irn_flags => [ "not_scheduled" ],
        reg_req   => { out => [ "fpcw:I" ] },
        mode      => $mode_fpcw,
        latency   => 3,
@@ -1369,6 +1320,17 @@ PopEbp => {
        units     => [ "GP" ],
 },
 
+CopyEbpEsp => {
+       state     => "exc_pinned",
+       reg_req   => { in => [ "ebp" ], out => [ "esp:I|S" ] },
+       ins       => [ "ebp" ],
+       outs      => [ "esp" ],
+       emit      => '. movl %S0, %D0',
+       latency   => 1,
+       units     => [ "GP" ],
+       mode      => $mode_gp,
+},
+
 PopMem => {
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
@@ -1393,6 +1355,7 @@ Leave => {
        outs      => [ "frame", "stack" ],
        latency   => 3,
        units     => [ "GP" ],
+       state     => "exc_pinned",
 },
 
 AddSP => {
@@ -1432,6 +1395,8 @@ LdTls => {
        irn_flags => [ "rematerializable" ],
        reg_req   => { out => [ "gp" ] },
        units     => [ "GP" ],
+       emit      => ". movl %%gs:0, %D0",
+       mode      => $mode_gp,
        latency   => 1,
 },
 
@@ -1912,7 +1877,7 @@ Ucomi => {
        ins       => [ "base", "index", "mem", "left", "right" ],
        outs      => [ "flags" ],
        am        => "source,binary",
-       attr      => "int ins_permuted",
+       attr      => "bool ins_permuted",
        init_attr => "attr->data.ins_permuted = ins_permuted;",
        emit      => ' .ucomi%XXM %binop',
        latency   => 3,
@@ -2321,7 +2286,7 @@ vFucomFnstsw => {
        reg_req   => { in => [ "vfp", "vfp" ], out => [ "eax" ] },
        ins       => [ "left", "right" ],
        outs      => [ "flags" ],
-       attr      => "int ins_permuted",
+       attr      => "bool ins_permuted",
        init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
        latency   => 3,
        units     => [ "VFP" ],
@@ -2334,7 +2299,7 @@ vFucomi => {
        reg_req   => { in => [ "vfp", "vfp" ], out => [ "eflags" ] },
        ins       => [ "left", "right" ],
        outs      => [ "flags" ],
-       attr      => "int ins_permuted",
+       attr      => "bool ins_permuted",
        init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
        latency   => 3,
        units     => [ "VFP" ],
@@ -2347,7 +2312,7 @@ vFtstFnstsw => {
        reg_req   => { in => [ "vfp" ], out => [ "eax" ] },
        ins       => [ "left" ],
        outs      => [ "flags" ],
-       attr      => "int ins_permuted",
+       attr      => "bool ins_permuted",
        init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
        latency   => 3,
        units     => [ "VFP" ],