- Improved addressmode optimisation for conv nodes
[libfirm] / ir / be / ia32 / ia32_spec.pl
index a02cd31..f4c6328 100644 (file)
@@ -104,6 +104,8 @@ $comment_string = "/*";
 #   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 assign this register)
+#   8 - emitter can choose an arbitrary register of this class
+#  16 - the register is a virtual one
 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
 %reg_classes = (
   "gp" => [
@@ -137,8 +139,8 @@ $comment_string = "/*";
 #            { "name" => "r32", "type" => 1 },
             { "name" => "ebp", "type" => 2 },
             { "name" => "esp", "type" => 4 },
-            { "name" => "gp_NOREG", "type" => 2 | 4 },      # we need a dummy register for NoReg nodes
-            { "name" => "gp_UKNWN", "type" => 2 | 4 | 8 },  # we need a dummy register for Unknown nodes
+            { "name" => "gp_NOREG", "type" => 2 | 4 | 16 },     # we need a dummy register for NoReg nodes
+            { "name" => "gp_UKNWN", "type" => 2 | 4 | 8 | 16},  # we need a dummy register for Unknown nodes
                        { "mode" => "mode_P" }
           ],
   "xmm" => [
@@ -150,21 +152,21 @@ $comment_string = "/*";
             { "name" => "xmm5", "type" => 1 },
             { "name" => "xmm6", "type" => 1 },
             { "name" => "xmm7", "type" => 1 },
-            { "name" => "xmm_NOREG", "type" => 2 | 4 },      # we need a dummy register for NoReg nodes
-            { "name" => "xmm_UKNWN", "type" => 2 | 4 | 8 },  # we need a dummy register for Unknown nodes
+            { "name" => "xmm_NOREG", "type" => 2 | 4 | 16 },     # we need a dummy register for NoReg nodes
+            { "name" => "xmm_UKNWN", "type" => 2 | 4 | 8 | 16},  # we need a dummy register for Unknown nodes
                        { "mode" => "mode_D" }
           ],
   "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" => 2 | 4 },      # we need a dummy register for NoReg nodes
-            { "name" => "vfp_UKNWN", "type" => 2 | 4 | 8 },  # we need a dummy register for Unknown nodes
+            { "name" => "vf0", "type" => 1 | 16 },
+            { "name" => "vf1", "type" => 1 | 16 },
+            { "name" => "vf2", "type" => 1 | 16 },
+            { "name" => "vf3", "type" => 1 | 16 },
+            { "name" => "vf4", "type" => 1 | 16 },
+            { "name" => "vf5", "type" => 1 | 16 },
+            { "name" => "vf6", "type" => 1 | 16 },
+            { "name" => "vf7", "type" => 1 | 16 },
+            { "name" => "vfp_NOREG", "type" => 2 | 4 | 16 },     # we need a dummy register for NoReg nodes
+            { "name" => "vfp_UKNWN", "type" => 2 | 4 | 8 | 16},  # we need a dummy register for Unknown nodes
                        { "mode" => "mode_E" }
           ],
   "st" => [
@@ -655,7 +657,7 @@ else {
   "irn_flags" => "R",
   "comment"   => "represents an integer constant",
   "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
-  "reg_req"   => { "in" => [ "none" ], "out" => [ "gp" ] },
+  "reg_req"   => { "out" => [ "gp" ] },
 },
 
 "Cdq" => {
@@ -926,7 +928,7 @@ else {
   "irn_flags" => "R",
   "comment"   => "represents a SSE constant",
   "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
-  "reg_req"   => { "in" => [ "none" ], "out" => [ "xmm" ] },
+  "reg_req"   => { "out" => [ "xmm" ] },
   "emit"      => '. movs%M %D1, %C /* Load fConst into register */',
   "latency"   => 2,
 },
@@ -1344,7 +1346,7 @@ else {
   "init_attr" => "  set_ia32_ls_mode(res, mode);",
   "comment"   => "represents a virtual floating point constant",
   "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
-  "reg_req"   => { "in" => [ "none" ], "out" => [ "vfp" ] },
+  "reg_req"   => { "out" => [ "vfp" ] },
   "latency"   => 3,
 },
 
@@ -1566,7 +1568,7 @@ else {
   "op_flags"  => "R|c",
   "irn_flags"  => "R",
   "comment"   => "x87 fp Load 0.0: Ld 0.0 -> reg",
-  "reg_req"   => { },
+  "reg_req"   => { "out" => [ "vfp" ] },
   "emit"      => '. fldz /* x87 0.0 -> %D1 */',
 },
 
@@ -1574,7 +1576,7 @@ else {
   "op_flags"  => "R|c",
   "irn_flags"  => "R",
   "comment"   => "x87 fp Load 1.0: Ld 1.0 -> reg",
-  "reg_req"   => { },
+  "reg_req"   => { "out" => [ "vfp" ] },
   "emit"      => '. fld1 /* x87 1.0 -> %D1 */',
 },
 
@@ -1582,7 +1584,7 @@ else {
   "op_flags"  => "R|c",
   "irn_flags"  => "R",
   "comment"   => "x87 fp Load pi: Ld pi -> reg",
-  "reg_req"   => { },
+  "reg_req"   => { "out" => [ "vfp" ] },
   "emit"      => '. fldpi /* x87 pi -> %D1 */',
 },
 
@@ -1590,7 +1592,7 @@ else {
   "op_flags"  => "R|c",
   "irn_flags"  => "R",
   "comment"   => "x87 fp Load ln 2: Ld ln 2 -> reg",
-  "reg_req"   => { },
+  "reg_req"   => { "out" => [ "vfp" ] },
   "emit"      => '. fldln2 /* x87 ln(2) -> %D1 */',
 },
 
@@ -1598,7 +1600,7 @@ else {
   "op_flags"  => "R|c",
   "irn_flags"  => "R",
   "comment"   => "x87 fp Load lg 2: Ld lg 2 -> reg",
-  "reg_req"   => { },
+  "reg_req"   => { "out" => [ "vfp" ] },
   "emit"      => '. fldlg2 /* x87 log(2) -> %D1 */',
 },
 
@@ -1606,7 +1608,7 @@ else {
   "op_flags"  => "R|c",
   "irn_flags"  => "R",
   "comment"   => "x87 fp Load ld 10: Ld ld 10 -> reg",
-  "reg_req"   => { },
+  "reg_req"   => { "out" => [ "vfp" ] },
   "emit"      => '. fldll2t /* x87 ld(10) -> %D1 */',
 },
 
@@ -1614,7 +1616,7 @@ else {
   "op_flags"  => "R|c",
   "irn_flags"  => "R",
   "comment"   => "x87 fp Load ld e: Ld ld e -> reg",
-  "reg_req"   => { },
+  "reg_req"   => { "out" => [ "vfp" ] },
   "emit"      => '. fldl2e /* x87 ld(e) -> %D1 */',
 },
 
@@ -1624,25 +1626,34 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "represents a x87 constant",
   "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
-  "reg_req"   => { "out" => [ "st" ] },
+  "reg_req"   => { "out" => [ "vfp" ] },
   "emit"      => '. fld %ia32_emit_adr /* Load fConst into register -> %D1 */',
 },
 
 # fxch, fpush, fpop
 # Note that it is NEVER allowed to do CSE on these nodes
+# Moreover, note the virtual register requierements!
 
 "fxch" => {
   "op_flags"  => "R|K",
   "comment"   => "x87 stack exchange",
-  "reg_req"   => { "in" => [ "st"], "out" => [ "st" ] },
+  "reg_req"   => { },
   "cmp_attr"  => "  return 1;\n",
   "emit"      => '. fxch %X1 /* x87 swap %X1, %X3 */',
 },
 
 "fpush" => {
+  "op_flags"  => "R|K",
+  "comment"   => "x87 stack push",
+  "reg_req"   => {},
+  "cmp_attr"  => "  return 1;\n",
+  "emit"      => '. fld %X1 /* x87 push %X1 */',
+},
+
+"fpushCopy" => {
   "op_flags"  => "R",
   "comment"   => "x87 stack push",
-  "reg_req"   => { "in" => [ "st"], "out" => [ "st" ] },
+  "reg_req"   => { "in" => [ "vfp"], "out" => [ "vfp" ] },
   "cmp_attr"  => "  return 1;\n",
   "emit"      => '. fld %X1 /* x87 push %X1 */',
 },
@@ -1650,7 +1661,7 @@ else {
 "fpop" => {
   "op_flags"  => "R|K",
   "comment"   => "x87 stack pop",
-  "reg_req"   => { "out" => [ "st" ] },
+  "reg_req"   => { },
   "cmp_attr"  => "  return 1;\n",
   "emit"      => '. fstp %X1 /* x87 pop %X1 */',
 },