fixed SetST0 register settings
[libfirm] / ir / be / ia32 / ia32_spec.pl
index 9ad42a3..489e7f5 100644 (file)
@@ -246,6 +246,8 @@ $comment_string = "/*";
 },
 
 "MulS" => {
+  # we should not rematrialize this node. It produces 2 results and has
+  # very strict constrains
   "comment"   => "construct MulS: MulS(a, b) = MulS(b, a) = a * b",
   "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "eax", "gp", "none" ], "out" => [ "eax", "edx" ] },
@@ -255,6 +257,8 @@ $comment_string = "/*";
 },
 
 "l_MulS" => {
+  # we should not rematrialize this node. It produces 2 results and has
+  # very strict constrains
   "op_flags"  => "C",
   "cmp_attr"  => "  return 1;\n",
   "comment"   => "construct lowered MulS: MulS(a, b) = MulS(b, a) = a * b",
@@ -281,6 +285,8 @@ $comment_string = "/*";
 
 # Mulh is an exception from the 4 INs with AM because the target is always EAX:EDX
 "Mulh" => {
+  # we should not rematrialize this node. It produces 2 results and has
+  # very strict constrains
   "comment"   => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
   "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "eax", "gp", "none" ], "out" => [ "eax", "edx" ] },
@@ -410,7 +416,7 @@ $comment_string = "/*";
   "irn_flags" => "R",
   "comment"   => "construct Shl: Shl(a, b) = a << b",
   "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
-  "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
+  "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx gp_NOREG", "none" ], "out" => [ "in_r3 !in_r4" ] },
   "emit"      => '. shl %ia32_emit_binop /* Shl(%A1, %A2) -> %D1 */',
   "outs"      => [ "res", "M" ],
 },
@@ -425,7 +431,7 @@ $comment_string = "/*";
   "irn_flags" => "R",
   "comment"   => "construct ShlD: ShlD(a, b, c) = a, b << count (shift left count bits from b into a)",
   "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
-  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r5" ] },
+  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "ecx", "none" ], "out" => [ "!ecx in_r3 !in_r4" ] },
   "emit"      =>
 '
 if (get_ia32_immop_type(n) == ia32_ImmNone) {
@@ -459,7 +465,7 @@ else {
   "irn_flags" => "R",
   "comment"   => "construct Shr: Shr(a, b) = a >> b",
   "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
-  "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
+  "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx gp_NOREG", "none" ], "out" => [ "in_r3 !in_r4" ] },
   "emit"      => '. shr %ia32_emit_binop /* Shr(%A1, %A2) -> %D1 */',
   "outs"      => [ "res", "M" ],
 },
@@ -474,7 +480,7 @@ else {
   "irn_flags" => "R",
   "comment"   => "construct ShrD: ShrD(a, b, c) = a, b >> count (shift rigth count bits from a into b)",
   "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
-  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r5" ] },
+  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "ecx", "none" ], "out" => [ "!ecx in_r3 !in_r4" ] },
   "emit"      =>
 '
 if (get_ia32_immop_type(n) == ia32_ImmNone) {
@@ -508,7 +514,7 @@ else {
   "irn_flags" => "R",
   "comment"   => "construct Shrs: Shrs(a, b) = a >> b",
   "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
-  "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
+  "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx gp_NOREG", "none" ], "out" => [ "in_r3 !in_r4" ] },
   "emit"      => '. sar %ia32_emit_binop /* Shrs(%A1, %A2) -> %D1 */',
   "outs"      => [ "res", "M" ],
 },
@@ -633,7 +639,8 @@ else {
 },
 
 "Cdq" => {
-  "irn_flags" => "R",
+  # we should not rematrialize this node. It produces 2 results and has
+  # very strict constrains
   "comment"   => "construct CDQ: sign extend EAX -> EDX:EAX",
   "reg_req"   => { "in" => [ "gp" ], "out" => [ "eax in_r1", "edx" ] },
   "emit"      => '. cdq /* sign extend EAX -> EDX:EAX, (%A1) */',
@@ -648,6 +655,7 @@ else {
   "comment"   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
   "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "gp" ] },
+  "latency"   => 3,
   "emit"      =>
 '  if (get_mode_size_bits(get_ia32_ls_mode(n)) < 32) {
 4.   mov%Mx %D1, %ia32_emit_am /* Load((%A1)) -> %D1 */
@@ -684,6 +692,7 @@ else {
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ] },
   "emit"      => '. mov %ia32_emit_binop /* Store(%A3) -> (%A1) */',
   "outs"      => [ "M" ],
+  "latency"   => 3,
 },
 
 "Store8Bit" => {
@@ -691,9 +700,10 @@ else {
   "state"     => "exc_pinned",
   "comment"   => "construct 8Bit Store: Store(ptr, val, mem) = ST ptr,val",
   "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
-  "reg_req"   => { "in" => [ "gp", "gp", "eax ebx ecx edx", "none" ] },
+  "reg_req"   => { "in" => [ "gp", "gp", "eax ebx ecx edx gp_NOREG", "none" ] },
   "emit"      => '. mov %ia32_emit_binop /* Store(%A3) -> (%A1) */',
   "outs"      => [ "M" ],
+  "latency"   => 3,
 },
 
 "Lea" => {
@@ -707,23 +717,9 @@ else {
 
 "Push" => {
   # We don't set class modify_stack here (but we will do this on proj 0)
-  "comment"   => "push a gp register on the stack",
-  "reg_req"   => { "in" => [ "esp", "gp", "none" ], "out" => [ "esp" ] },
-  "emit"      => '
-if (get_ia32_id_cnst(n)) {
-       if (get_ia32_immop_type(n) == ia32_ImmConst) {
-4. push %C /* Push const on stack */
-} else {
-4. push OFFSET FLAT:%C /* Push symconst on stack */
-       }
-}
-else if (get_ia32_op_type(n) == ia32_Normal) {
-2. push %S2 /* Push(%A2) */
-}
-else {
-2. push %ia32_emit_am /* Push memory to stack */
-};
-',
+  "comment"   => "push on the stack",
+  "reg_req"   => { "in" => [ "gp", "gp", "gp", "esp", "none" ], "out" => [ "esp" ] },
+  "emit"      => '. push %ia32_emit_unop /* PUSH(%A1) */',
   "outs"      => [ "stack", "M" ],
   "latency"   => 3,
 },
@@ -731,15 +727,8 @@ else {
 "Pop" => {
   # We don't set class modify stack here (but we will do this on proj 1)
   "comment"   => "pop a gp register from the stack",
-  "reg_req"   => { "in" => [ "esp", "none" ], "out" => [ "gp", "esp" ] },
-  "emit"      => '
-if (get_ia32_op_type(n) == ia32_Normal) {
-2. pop %D1 /* Pop from stack into %D1 */
-}
-else {
-2. pop %ia32_emit_am /* Pop from stack into memory */
-}
-',
+  "reg_req"   => { "in" => [ "gp", "gp", "esp", "none" ], "out" => [ "gp", "esp" ] },
+  "emit"      => '. pop %ia32_emit_unop /* POP(%A1) */',
   "outs"      => [ "res", "stack", "M" ],
   "latency"   => 4,
 },
@@ -761,12 +750,27 @@ else {
 },
 
 "AddSP" => {
-  "irn_flags" => "S|I",
+  "irn_flags" => "I",
   "comment"   => "allocate space on stack",
   "reg_req"   => { "in" => [ "esp", "gp" ], "out" => [ "esp", "none" ] },
   "outs"      => [ "stack", "M" ],
 },
 
+"SubSP" => {
+  "irn_flags" => "I",
+  "comment"   => "free space on stack",
+  "reg_req"   => { "in" => [ "esp", "gp" ], "out" => [ "esp", "none" ] },
+  "outs"      => [ "stack", "M" ],
+},
+
+"LdTls" => {
+  "irn_flags" => "R",
+  "comment"   => "get the TLS base address",
+  "reg_req"   => { "out" => [ "gp" ] },
+},
+
+
+
 #-----------------------------------------------------------------------------#
 #   _____ _____ ______    __ _             _                     _            #
 #  / ____/ ____|  ____|  / _| |           | |                   | |           #
@@ -975,7 +979,7 @@ else {
   "state"    => "exc_pinned",
   "comment"  => "load ST0 from stack",
   "cmp_attr" => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
-  "reg_req"  => { "in" => [ "gp", "none" ], "out" => [ "st0", "none" ] },
+  "reg_req"  => { "in" => [ "gp", "none" ], "out" => [ "vf0", "none" ] },
   "emit"     => '. fld %ia32_emit_am /* load ST0 from stack */',
   "outs"     => [ "res", "M" ],
   "latency"  => 2,
@@ -1540,63 +1544,56 @@ else {
 # constants
 
 "fldz" => {
-  "op_flags"  => "R",
+  "op_flags"  => "R|c",
   "irn_flags"  => "R",
-  "rd_constructor" => "NONE",
   "comment"   => "x87 fp Load 0.0: Ld 0.0 -> reg",
   "reg_req"   => { },
   "emit"      => '. fldz /* x87 0.0 -> %D1 */',
 },
 
 "fld1" => {
-  "op_flags"  => "R",
+  "op_flags"  => "R|c",
   "irn_flags"  => "R",
-  "rd_constructor" => "NONE",
   "comment"   => "x87 fp Load 1.0: Ld 1.0 -> reg",
   "reg_req"   => { },
   "emit"      => '. fld1 /* x87 1.0 -> %D1 */',
 },
 
 "fldpi" => {
-  "op_flags"  => "R",
+  "op_flags"  => "R|c",
   "irn_flags"  => "R",
-  "rd_constructor" => "NONE",
   "comment"   => "x87 fp Load pi: Ld pi -> reg",
   "reg_req"   => { },
   "emit"      => '. fldpi /* x87 pi -> %D1 */',
 },
 
 "fldln2" => {
-  "op_flags"  => "R",
+  "op_flags"  => "R|c",
   "irn_flags"  => "R",
-  "rd_constructor" => "NONE",
   "comment"   => "x87 fp Load ln 2: Ld ln 2 -> reg",
   "reg_req"   => { },
   "emit"      => '. fldln2 /* x87 ln(2) -> %D1 */',
 },
 
 "fldlg2" => {
-  "op_flags"  => "R",
+  "op_flags"  => "R|c",
   "irn_flags"  => "R",
-  "rd_constructor" => "NONE",
   "comment"   => "x87 fp Load lg 2: Ld lg 2 -> reg",
   "reg_req"   => { },
   "emit"      => '. fldlg2 /* x87 log(2) -> %D1 */',
 },
 
 "fldl2t" => {
-  "op_flags"  => "R",
+  "op_flags"  => "R|c",
   "irn_flags"  => "R",
-  "rd_constructor" => "NONE",
   "comment"   => "x87 fp Load ld 10: Ld ld 10 -> reg",
   "reg_req"   => { },
   "emit"      => '. fldll2t /* x87 ld(10) -> %D1 */',
 },
 
 "fldl2e" => {
-  "op_flags"  => "R",
+  "op_flags"  => "R|c",
   "irn_flags"  => "R",
-  "rd_constructor" => "NONE",
   "comment"   => "x87 fp Load ld e: Ld ld e -> reg",
   "reg_req"   => { },
   "emit"      => '. fldl2e /* x87 ld(e) -> %D1 */',
@@ -1634,7 +1631,7 @@ else {
 "fpop" => {
   "op_flags"  => "R|K",
   "comment"   => "x87 stack pop",
-  "reg_req"   => { "in" => [ "st"], "out" => [ "st" ] },
+  "reg_req"   => { "out" => [ "st" ] },
   "cmp_attr"  => "  return 1;\n",
   "emit"      => '. fstp %X1 /* x87 pop %X1 */',
 },