ad-hoc fix for lfoat compares (this is not mallons optimal solution yet)
[libfirm] / ir / be / ia32 / ia32_spec.pl
index 51ba13b..99991fc 100644 (file)
@@ -294,6 +294,7 @@ $arch = "ia32";
 #--------------------------------------------------#
 
 $default_attr_type = "ia32_attr_t";
+$default_copy_attr = "ia32_copy_attr";
 
 %init_attr = (
        ia32_attr_t     => "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);",
@@ -333,7 +334,7 @@ Immediate => {
        op_flags  => "c",
        irn_flags => "I",
        reg_req   => { out => [ "gp_NOREG" ] },
-       attr      => "ir_entity *symconst, int symconst_sign, tarval *offset",
+       attr      => "ir_entity *symconst, int symconst_sign, long offset",
        attr_type => "ia32_immediate_attr_t",
        mode      => $mode_gp,
 },
@@ -770,8 +771,12 @@ Not => {
 CondJmp => {
        state     => "pinned",
        op_flags  => "L|X|Y",
-       reg_req   => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "none", "none"] },
+       reg_req   => { in  => [ "gp", "gp", "gp", "gp", "none" ],
+                      out => [ "none", "none"] },
+       ins       => [ "base", "index", "left", "right", "mem" ],
        outs      => [ "false", "true" ],
+       attr      => "long pnc",
+       init_attr => "attr->pn_code = pnc;",
        latency   => 3,
        units     => [ "BRANCH" ],
 },
@@ -779,33 +784,23 @@ CondJmp => {
 TestJmp => {
        state     => "pinned",
        op_flags  => "L|X|Y",
-       reg_req  => { in => [ "gp", "gp" ], out => [ "none", "none" ] },
+       reg_req   => { in  => [ "gp", "gp", "gp", "gp", "none" ],
+                      out => [ "none", "none" ] },
+       ins       => [ "base", "index", "left", "right", "mem" ],
        outs      => [ "false", "true" ],
+       attr      => "long pnc",
+       init_attr => "attr->pn_code = pnc;",
        latency   => 3,
        units     => [ "BRANCH" ],
 },
 
-CJmpAM => {
-       state     => "pinned",
-       op_flags  => "L|X|Y",
-       reg_req   => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "none", "none" ] },
-       outs      => [ "false", "true" ],
-       units     => [ "BRANCH" ],
-},
-
-CJmp => {
-       state     => "pinned",
-       op_flags  => "L|X|Y",
-       reg_req   => { in => [ "gp", "gp" ] },
-       units     => [ "BRANCH" ],
-},
-
 SwitchJmp => {
        state     => "pinned",
        op_flags  => "L|X|Y",
        reg_req   => { in => [ "gp" ], out => [ "none" ] },
        latency   => 3,
        units     => [ "BRANCH" ],
+       mode      => "mode_T",
 },
 
 Const => {
@@ -891,7 +886,7 @@ ChangeCW => {
 
 FldCW => {
        op_flags  => "L|F",
-       state     => "exc_pinned",
+       state     => "pinned",
        reg_req   => { in => [ "gp", "gp", "none" ], out => [ "fp_cw" ] },
        latency   => 5,
        emit      => ". fldcw %AM",
@@ -902,7 +897,7 @@ FldCW => {
 
 FnstCW => {
        op_flags  => "L|F",
-       state     => "exc_pinned",
+       state     => "pinned",
        reg_req   => { in => [ "gp", "gp", "fp_cw", "none" ], out => [ "none" ] },
        latency   => 5,
        emit      => ". fnstcw %AM",
@@ -913,21 +908,26 @@ FnstCW => {
 Cltd => {
        # we should not rematrialize this node. It produces 2 results and has
        # very strict constrains
-       reg_req   => { in => [ "gp" ], out => [ "eax in_r1", "edx" ] },
+       reg_req   => { in => [ "eax" ], out => [ "edx" ] },
+       ins       => [ "val" ],
        emit      => '. cltd',
-       outs      => [ "EAX", "EDX" ],
+       mode      => $mode_gp,
        units     => [ "GP" ],
 },
 
 # Load / Store
+#
+# Note that we add additional latency values depending on address mode, so a
+# lateny of 0 for load is correct
 
 Load => {
        op_flags  => "L|F",
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none" ], out => [ "gp", "none" ] },
-       latency   => 3,
-       emit      => ". mov%SE%ME%.l %AM, %D0",
+       ins       => [ "base", "index", "mem" ],
        outs      => [ "res", "M" ],
+       latency   => 0,
+       emit      => ". mov%SE%ME%.l %AM, %D0",
        units     => [ "GP" ],
 },
 
@@ -950,8 +950,9 @@ Store => {
        op_flags  => "L|F",
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "gp", "none" ], out => [ "none" ] },
+       ins       => [ "base", "index", "val", "mem" ],
        emit      => '. mov%M %binop',
-       latency   => 3,
+       latency   => 2,
        units     => [ "GP" ],
        mode      => "mode_M",
 },
@@ -961,14 +962,14 @@ Store8Bit => {
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "eax ebx ecx edx", "none" ], out => ["none" ] },
        emit      => '. mov%M %binop',
-       latency   => 3,
+       latency   => 2,
        units     => [ "GP" ],
        mode      => "mode_M",
 },
 
 Lea => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp" ], out => [ "in_r1" ] },
+       reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
        emit      => '. leal %AM, %D0',
        latency   => 2,
        units     => [ "GP" ],
@@ -981,7 +982,7 @@ Push => {
        emit      => '. push%M %unop2',
        ins       => [ "base", "index", "val", "stack", "mem" ],
        outs      => [ "stack:I|S", "M" ],
-       latency   => 3,
+       latency   => 2,
        units     => [ "GP" ],
        modified_flags => [],
 },
@@ -991,7 +992,7 @@ Pop => {
        emit      => '. pop%M %DAM1',
        outs      => [ "stack:I|S", "res", "M" ],
        ins       => [ "base", "index", "stack", "mem" ],
-       latency   => 4,
+       latency   => 3, # Pop is more expensive than Push on Athlon
        units     => [ "GP" ],
        modified_flags => [],
 },
@@ -1164,7 +1165,10 @@ xCondJmp => {
        state     => "pinned",
        op_flags  => "L|X|Y",
        reg_req   => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "none", "none" ] },
+       ins       => [ "base", "index", "left", "right", "mem" ],
        outs      => [ "false", "true" ],
+       attr      => "long pnc",
+       init_attr => "attr->pn_code = pnc;",
        latency   => 5,
        units     => [ "SSE" ],
 },
@@ -1246,7 +1250,7 @@ l_SSEtoX87 => {
 GetST0 => {
        op_flags => "L|F",
        irn_flags => "I",
-       state    => "exc_pinned",
+       state    => "pinned",
        reg_req  => { in => [ "gp", "gp", "none" ] },
        emit     => '. fstp%XM %AM',
        latency  => 4,
@@ -1257,7 +1261,7 @@ GetST0 => {
 SetST0 => {
        op_flags => "L|F",
        irn_flags => "I",
-       state    => "exc_pinned",
+       state    => "pinned",
        reg_req  => { in => [ "gp", "gp", "none" ], out => [ "vf0", "none" ] },
        ins      => [ "base", "index", "mem" ],
        emit     => '. fld%XM %AM',
@@ -1327,8 +1331,19 @@ Conv_FP2FP => {
 
 CmpCMov => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "gp", "gp" ], out => [ "in_r4" ] },
-       ins       => [ "cmp_left", "cmp_right", "val_true", "val_false" ],
+       reg_req   => { in => [ "gp", "gp", "gp", "gp", "none", "gp", "gp" ], out => [ "in_r7" ] },
+       ins       => [ "base", "index", "cmp_left", "cmp_right", "mem", "val_true", "val_false" ],
+       attr      => "pn_Cmp pn_code",
+       init_attr => "attr->pn_code = pn_code;",
+       latency   => 2,
+       units     => [ "GP" ],
+       mode      => $mode_gp,
+},
+
+TestCMov => {
+       irn_flags => "R",
+       reg_req   => { in => [ "gp", "gp", "gp", "gp", "none", "gp", "gp" ], out => [ "in_r7" ] },
+       ins       => [ "base", "index", "cmp_left", "cmp_right", "mem", "val_true", "val_false" ],
        attr      => "pn_Cmp pn_code",
        init_attr => "attr->pn_code = pn_code;",
        latency   => 2,
@@ -1364,6 +1379,17 @@ CmpSet => {
        mode      => $mode_gp,
 },
 
+TestSet => {
+       irn_flags => "R",
+       reg_req   => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "eax ebx ecx edx" ] },
+       ins       => [ "base", "index", "cmp_left", "cmp_right", "mem" ],
+       attr      => "pn_Cmp pn_code",
+       init_attr => "attr->pn_code = pn_code;",
+       latency   => 2,
+       units     => [ "GP" ],
+       mode      => $mode_gp,
+},
+
 xCmpSet => {
        irn_flags => "R",
        reg_req   => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "eax ebx ecx edx" ] },
@@ -1406,7 +1432,8 @@ vfCMov => {
 
 vfadd => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] },
+       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] },
+       ins       => [ "base", "index", "left", "right", "mem", "fpcw" ],
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
@@ -1415,7 +1442,8 @@ vfadd => {
 
 vfmul => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] },
+       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] },
+       ins       => [ "base", "index", "left", "right", "mem", "fpcw" ],
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
@@ -1430,7 +1458,8 @@ l_vfmul => {
 
 vfsub => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] },
+       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] },
+       ins       => [ "base", "index", "left", "right", "mem", "fpcw" ],
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
@@ -1443,7 +1472,8 @@ l_vfsub => {
 },
 
 vfdiv => {
-       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp", "none" ] },
+       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp", "none" ] },
+       ins       => [ "base", "index", "left", "right", "mem", "fpcw" ],
        outs      => [ "res", "M" ],
        latency   => 20,
        units     => [ "VFP" ],
@@ -1457,7 +1487,8 @@ l_vfdiv => {
 },
 
 vfprem => {
-       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] },
+       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] },
+       ins       => [ "base", "index", "left", "right", "mem", "fpcw" ],
        latency   => 20,
        units     => [ "VFP" ],
        mode      => "mode_E",
@@ -1472,6 +1503,7 @@ l_vfprem => {
 vfabs => {
        irn_flags => "R",
        reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
+       ins       => [ "value" ],
        latency   => 2,
        units     => [ "VFP" ],
        mode      => "mode_E",
@@ -1481,46 +1513,23 @@ vfabs => {
 vfchs => {
        irn_flags => "R",
        reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
+       ins       => [ "value" ],
        latency   => 2,
        units     => [ "VFP" ],
        mode      => "mode_E",
        attr_type => "ia32_x87_attr_t",
 },
 
-vfsin => {
-       irn_flags => "R",
-       reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
-       latency   => 150,
-       units     => [ "VFP" ],
-       mode      => "mode_E",
-       attr_type => "ia32_x87_attr_t",
-},
-
-vfcos => {
-       irn_flags => "R",
-       reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
-       latency   => 150,
-       units     => [ "VFP" ],
-       mode      => "mode_E",
-       attr_type => "ia32_x87_attr_t",
-},
-
-vfsqrt => {
-       irn_flags => "R",
-       reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
-       latency   => 30,
-       units     => [ "VFP" ],
-       mode      => "mode_E",
-       attr_type => "ia32_x87_attr_t",
-},
-
 # virtual Load and Store
 
 vfld => {
        op_flags  => "L|F",
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none" ] },
+       ins       => [ "base", "index", "mem" ],
        outs      => [ "res", "M" ],
+       attr      => "ir_mode *store_mode",
+       init_attr => "attr->attr.ls_mode = store_mode;",
        latency   => 2,
        units     => [ "VFP" ],
        attr_type => "ia32_x87_attr_t",
@@ -1530,6 +1539,9 @@ vfst => {
        op_flags  => "L|F",
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "vfp", "none" ] },
+       ins       => [ "base", "index", "val", "mem" ],
+       attr      => "ir_mode *store_mode",
+       init_attr => "attr->attr.ls_mode = store_mode;",
        latency   => 2,
        units     => [ "VFP" ],
        mode      => "mode_M",
@@ -1539,8 +1551,10 @@ vfst => {
 # Conversions
 
 vfild => {
+       state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none" ] },
        outs      => [ "res", "M" ],
+       ins       => [ "base", "index", "mem" ],
        latency   => 4,
        units     => [ "VFP" ],
        attr_type => "ia32_x87_attr_t",
@@ -1553,8 +1567,9 @@ l_vfild => {
 },
 
 vfist => {
-       reg_req   => { in => [ "gp", "gp", "vfp", "fpcw", "none" ] },
        state     => "exc_pinned",
+       reg_req   => { in => [ "gp", "gp", "vfp", "fpcw", "none" ] },
+       ins       => [ "base", "index", "val", "fpcw", "mem" ],
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_M",
@@ -1649,8 +1664,11 @@ vfConst => {
 vfCondJmp => {
        state     => "pinned",
        op_flags  => "L|X|Y",
-       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "none", "none", "eax" ] },
+       reg_req   => { in => [ "vfp", "vfp" ], out => [ "none", "none", "eax" ] },
+       ins       => [ "left", "right" ],
        outs      => [ "false", "true", "temp_reg_eax" ],
+       attr      => "long pnc",
+       init_attr => "attr->attr.pn_code = pnc;",
        latency   => 10,
        units     => [ "VFP" ],
        attr_type => "ia32_x87_attr_t",
@@ -1679,7 +1697,7 @@ faddp => {
        op_flags  => "R",
        rd_constructor => "NONE",
        reg_req   => { },
-       emit      => '. faddp %x87_binop',
+       emit      => '. faddp%XM %x87_binop',
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -1695,7 +1713,7 @@ fmulp => {
        op_flags  => "R",
        rd_constructor => "NONE",
        reg_req   => { },
-       emit      => '. fmulp %x87_binop',,
+       emit      => '. fmulp%XM %x87_binop',,
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -1712,7 +1730,7 @@ fsubp => {
        rd_constructor => "NONE",
        reg_req   => { },
 # see note about gas bugs
-       emit      => '. fsubrp %x87_binop',
+       emit      => '. fsubrp%XM %x87_binop',
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -1731,7 +1749,7 @@ fsubrp => {
        irn_flags => "R",
        reg_req   => { },
 # see note about gas bugs
-       emit      => '. fsubp %x87_binop',
+       emit      => '. fsubp%XM %x87_binop',
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -1766,7 +1784,7 @@ fdivp => {
        rd_constructor => "NONE",
        reg_req   => { },
 # see note about gas bugs
-       emit      => '. fdivrp %x87_binop',
+       emit      => '. fdivrp%XM %x87_binop',
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -1783,7 +1801,7 @@ fdivrp => {
        rd_constructor => "NONE",
        reg_req   => { },
 # see note about gas bugs
-       emit      => '. fdivp %x87_binop',
+       emit      => '. fdivp%XM %x87_binop',
        attr_type => "ia32_x87_attr_t",
 },
 
@@ -1803,30 +1821,6 @@ fchs => {
        attr_type => "ia32_x87_attr_t",
 },
 
-fsin => {
-       op_flags  => "R",
-       rd_constructor => "NONE",
-       reg_req   => { },
-       emit      => '. fsin',
-       attr_type => "ia32_x87_attr_t",
-},
-
-fcos => {
-       op_flags  => "R",
-       rd_constructor => "NONE",
-       reg_req   => { },
-       emit      => '. fcos',
-       attr_type => "ia32_x87_attr_t",
-},
-
-fsqrt => {
-       op_flags  => "R",
-       rd_constructor => "NONE",
-       reg_req   => { },
-       emit      => '. fsqrt $',
-       attr_type => "ia32_x87_attr_t",
-},
-
 # x87 Load and Store
 
 fld => {