don't use xmm register in calling conventions when sse is not available, simplified...
[libfirm] / ir / be / ia32 / ia32_spec.pl
index 68c1963..8331e3a 100644 (file)
@@ -121,6 +121,17 @@ $arch = "ia32";
                { name => "gp_UKNWN", type => 4 | 8 | 16 },  # we need a dummy register for Unknown 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 },
+               { mode => "mode_E" }
+       ],
        xmm => [
                { name => "xmm0", type => 1 },
                { name => "xmm1", type => 1 },
@@ -275,9 +286,25 @@ $arch = "ia32";
 #                                      |_|         #
 #--------------------------------------------------#
 
-$default_cmp_attr  = "return ia32_compare_attr(attr_a, attr_b);";
 $default_attr_type = "ia32_attr_t";
 
+%init_attr = (
+       ia32_attr_t     => "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);",
+       ia32_x87_attr_t =>
+               "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);\n".
+               "\tinit_ia32_x87_attributes(res);",
+       ia32_asm_attr_t =>
+               "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);\n".
+               "\tinit_ia32_x87_attributes(res);".
+               "\tinit_ia32_asm_attributes(res);"
+);
+
+%compare_attr = (
+       ia32_attr_t     => "ia32_compare_nodes_attr",
+       ia32_x87_attr_t => "ia32_compare_x87_attr",
+       ia32_asm_attr_t => "ia32_compare_asm_attr",
+);
+
 %operands = (
 );
 
@@ -302,6 +329,7 @@ Asm => {
        mode      => "mode_T",
        arity     => "variable",
        out_arity => "variable",
+       attr_type => "ia32_asm_attr_t",
 },
 
 #-----------------------------------------------------------------#
@@ -524,6 +552,9 @@ Div => {
 
 Shl => {
        irn_flags => "R",
+       # "in_r3" would be enough as out requirement, but the register allocator
+       # does strange things then and doesn't respect the constraint for in4
+       # if the same value is attached to in3 and in4 (if you have "i << i" in C)
        reg_req   => { in => [ "gp", "gp", "gp", "ecx", "none" ], out => [ "in_r3 !in_r4" ] },
        ins       => [ "base", "index", "left", "right", "mem" ],
        emit      => '. shl%M %binop',
@@ -542,11 +573,12 @@ ShlD => {
        # Out requirements is: different from all in
        # This is because, out must be different from LowPart and ShiftCount.
        # We could say "!ecx !in_r4" but it can occur, that all values live through
-       # this Shift and the only value dying is the ShiftCount. Then there would be a
-       # register missing, as result must not be ecx and all other registers are
-       # occupied. What we should write is "!in_r4 !in_r5", but this is not supported
-       # (and probably never will). So we create artificial interferences of the result
-       # with all inputs, so the spiller can always assure a free register.
+       # this Shift and the only value dying is the ShiftCount. Then there would be
+       # a register missing, as result must not be ecx and all other registers are
+       # occupied. What we should write is "!in_r4 !in_r5", but this is not
+       # supported (and probably never will). So we create artificial interferences
+       # of the result with all inputs, so the spiller can always assure a free
+       # register.
        reg_req   => { in => [ "gp", "gp", "gp", "gp", "ecx", "none" ], out => [ "!in" ] },
        emit      =>
 '
@@ -784,7 +816,8 @@ Unknown_VFP => {
        reg_req   => { out => [ "vfp_UKNWN" ] },
        units     => [],
        emit      => "",
-       mode      => "mode_E"
+       mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 Unknown_XMM => {
@@ -814,7 +847,8 @@ NoReg_VFP => {
        reg_req   => { out => [ "vfp_NOREG" ] },
        units     => [],
        emit      => "",
-       mode      => "mode_E"
+       mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 NoReg_XMM => {
@@ -1300,6 +1334,7 @@ vfCmpCMov => {
        latency   => 10,
        units     => [ "VFP" ],
        mode      => $mode_gp,
+       attr_type => "ia32_x87_attr_t",
 },
 
 CmpSet => {
@@ -1332,6 +1367,7 @@ vfCmpSet => {
        latency   => 10,
        units     => [ "VFP" ],
        mode      => $mode_gp,
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfCMov => {
@@ -1340,6 +1376,7 @@ vfCMov => {
        latency   => 10,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 #----------------------------------------------------------#
@@ -1362,6 +1399,7 @@ vfadd => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfmul => {
@@ -1370,6 +1408,7 @@ vfmul => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 l_vfmul => {
@@ -1384,6 +1423,7 @@ vfsub => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 l_vfsub => {
@@ -1396,6 +1436,7 @@ vfdiv => {
        outs      => [ "res", "M" ],
        latency   => 20,
        units     => [ "VFP" ],
+       attr_type => "ia32_x87_attr_t",
 },
 
 l_vfdiv => {
@@ -1409,6 +1450,7 @@ vfprem => {
        latency   => 20,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 l_vfprem => {
@@ -1422,6 +1464,7 @@ vfabs => {
        latency   => 2,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfchs => {
@@ -1430,6 +1473,7 @@ vfchs => {
        latency   => 2,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfsin => {
@@ -1438,6 +1482,7 @@ vfsin => {
        latency   => 150,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfcos => {
@@ -1446,6 +1491,7 @@ vfcos => {
        latency   => 150,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfsqrt => {
@@ -1454,6 +1500,7 @@ vfsqrt => {
        latency   => 30,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 # virtual Load and Store
@@ -1465,6 +1512,7 @@ vfld => {
        outs      => [ "res", "M" ],
        latency   => 2,
        units     => [ "VFP" ],
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfst => {
@@ -1474,6 +1522,7 @@ vfst => {
        latency   => 2,
        units     => [ "VFP" ],
        mode      => "mode_M",
+       attr_type => "ia32_x87_attr_t",
 },
 
 # Conversions
@@ -1483,6 +1532,7 @@ vfild => {
        outs      => [ "res", "M" ],
        latency   => 4,
        units     => [ "VFP" ],
+       attr_type => "ia32_x87_attr_t",
 },
 
 l_vfild => {
@@ -1496,6 +1546,7 @@ vfist => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_M",
+       attr_type => "ia32_x87_attr_t",
 },
 
 l_vfist => {
@@ -1513,6 +1564,7 @@ vfldz => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfld1 => {
@@ -1521,6 +1573,7 @@ vfld1 => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfldpi => {
@@ -1529,6 +1582,7 @@ vfldpi => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfldln2 => {
@@ -1537,6 +1591,7 @@ vfldln2 => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfldlg2 => {
@@ -1545,6 +1600,7 @@ vfldlg2 => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfldl2t => {
@@ -1553,6 +1609,7 @@ vfldl2t => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfldl2e => {
@@ -1561,16 +1618,17 @@ vfldl2e => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfConst => {
        op_flags  => "c",
        irn_flags => "R",
-#  init_attr => "  set_ia32_ls_mode(res, mode);",
        reg_req   => { out => [ "vfp" ] },
        latency   => 3,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 # other
@@ -1582,6 +1640,7 @@ vfCondJmp => {
        outs      => [ "false", "true", "temp_reg_eax" ],
        latency   => 10,
        units     => [ "VFP" ],
+       attr_type => "ia32_x87_attr_t",
 },
 
 #------------------------------------------------------------------------#
@@ -1600,6 +1659,7 @@ fadd => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fadd%XM %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 faddp => {
@@ -1607,6 +1667,7 @@ faddp => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. faddp %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fmul => {
@@ -1614,6 +1675,7 @@ fmul => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fmul%XM %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fmulp => {
@@ -1621,6 +1683,7 @@ fmulp => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fmulp %x87_binop',,
+       attr_type => "ia32_x87_attr_t",
 },
 
 fsub => {
@@ -1628,6 +1691,7 @@ fsub => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fsub%XM %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fsubp => {
@@ -1636,6 +1700,7 @@ fsubp => {
        reg_req   => { },
 # see note about gas bugs
        emit      => '. fsubrp %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fsubr => {
@@ -1644,6 +1709,7 @@ fsubr => {
        irn_flags => "R",
        reg_req   => { },
        emit      => '. fsubr%XM %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fsubrp => {
@@ -1653,6 +1719,7 @@ fsubrp => {
        reg_req   => { },
 # see note about gas bugs
        emit      => '. fsubp %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fprem => {
@@ -1660,6 +1727,7 @@ fprem => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fprem1',
+       attr_type => "ia32_x87_attr_t",
 },
 
 # this node is just here, to keep the simulator running
@@ -1669,6 +1737,7 @@ fpremp => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fprem1',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fdiv => {
@@ -1676,6 +1745,7 @@ fdiv => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fdiv%XM %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fdivp => {
@@ -1684,6 +1754,7 @@ fdivp => {
        reg_req   => { },
 # see note about gas bugs
        emit      => '. fdivrp %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fdivr => {
@@ -1691,6 +1762,7 @@ fdivr => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fdivr%XM %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fdivrp => {
@@ -1699,6 +1771,7 @@ fdivrp => {
        reg_req   => { },
 # see note about gas bugs
        emit      => '. fdivp %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fabs => {
@@ -1706,6 +1779,7 @@ fabs => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fabs',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fchs => {
@@ -1713,6 +1787,7 @@ fchs => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fchs',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fsin => {
@@ -1720,6 +1795,7 @@ fsin => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fsin',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fcos => {
@@ -1727,6 +1803,7 @@ fcos => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fcos',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fsqrt => {
@@ -1734,6 +1811,7 @@ fsqrt => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fsqrt $',
+       attr_type => "ia32_x87_attr_t",
 },
 
 # x87 Load and Store
@@ -1744,6 +1822,7 @@ fld => {
        state     => "exc_pinned",
        reg_req   => { },
        emit      => '. fld%XM %AM',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fst => {
@@ -1753,6 +1832,7 @@ fst => {
        reg_req   => { },
        emit      => '. fst%XM %AM',
        mode      => "mode_M",
+       attr_type => "ia32_x87_attr_t",
 },
 
 fstp => {
@@ -1762,6 +1842,7 @@ fstp => {
        reg_req   => { },
        emit      => '. fstp%XM %AM',
        mode      => "mode_M",
+       attr_type => "ia32_x87_attr_t",
 },
 
 # Conversions
@@ -1771,6 +1852,7 @@ fild => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fild%XM %AM',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fist => {
@@ -1779,6 +1861,7 @@ fist => {
        reg_req   => { },
        emit      => '. fist%XM %AM',
        mode      => "mode_M",
+       attr_type => "ia32_x87_attr_t",
 },
 
 fistp => {
@@ -1787,6 +1870,7 @@ fistp => {
        reg_req   => { },
        emit      => '. fistp%XM %AM',
        mode      => "mode_M",
+       attr_type => "ia32_x87_attr_t",
 },
 
 # constants
@@ -1796,6 +1880,7 @@ fldz => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fldz',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fld1 => {
@@ -1803,6 +1888,7 @@ fld1 => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fld1',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fldpi => {
@@ -1810,6 +1896,7 @@ fldpi => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fldpi',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fldln2 => {
@@ -1817,6 +1904,7 @@ fldln2 => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fldln2',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fldlg2 => {
@@ -1824,6 +1912,7 @@ fldlg2 => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fldlg2',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fldl2t => {
@@ -1831,6 +1920,7 @@ fldl2t => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fldll2t',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fldl2e => {
@@ -1838,6 +1928,7 @@ fldl2e => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fldl2e',
+       attr_type => "ia32_x87_attr_t",
 },
 
 # fxch, fpush, fpop
@@ -1849,6 +1940,7 @@ fxch => {
        reg_req   => { },
        cmp_attr  => "return 1;",
        emit      => '. fxch %X0',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fpush => {
@@ -1856,6 +1948,7 @@ fpush => {
        reg_req   => {},
        cmp_attr  => "return 1;",
        emit      => '. fld %X0',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fpushCopy => {
@@ -1863,6 +1956,7 @@ fpushCopy => {
        reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
        cmp_attr  => "return 1;",
        emit      => '. fld %X0',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fpop => {
@@ -1870,6 +1964,7 @@ fpop => {
        reg_req   => { },
        cmp_attr  => "return 1;",
        emit      => '. fstp %X0',
+       attr_type => "ia32_x87_attr_t",
 },
 
 # compare
@@ -1877,31 +1972,37 @@ fpop => {
 fcomJmp => {
        op_flags  => "L|X|Y",
        reg_req   => { },
+       attr_type => "ia32_x87_attr_t",
 },
 
 fcompJmp => {
        op_flags  => "L|X|Y",
        reg_req   => { },
+       attr_type => "ia32_x87_attr_t",
 },
 
 fcomppJmp => {
        op_flags  => "L|X|Y",
        reg_req   => { },
+       attr_type => "ia32_x87_attr_t",
 },
 
 fcomrJmp => {
        op_flags  => "L|X|Y",
        reg_req   => { },
+       attr_type => "ia32_x87_attr_t",
 },
 
 fcomrpJmp => {
        op_flags  => "L|X|Y",
        reg_req   => { },
+       attr_type => "ia32_x87_attr_t",
 },
 
 fcomrppJmp => {
        op_flags  => "L|X|Y",
        reg_req   => { },
+       attr_type => "ia32_x87_attr_t",
 },