fixed requirements for ShrD and ShlD
authorChristian Würdig <chriswue@ipd.info.uni-karlsruhe.de>
Fri, 6 Oct 2006 14:26:10 +0000 (14:26 +0000)
committerChristian Würdig <chriswue@ipd.info.uni-karlsruhe.de>
Fri, 6 Oct 2006 14:26:10 +0000 (14:26 +0000)
ir/be/ia32/ia32_spec.pl

index e330994..a02cd31 100644 (file)
@@ -435,7 +435,15 @@ $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" => [ "!ecx in_r3 !in_r4" ] },
+  # 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.
+  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "ecx", "none" ], "out" => [ "!in" ] },
   "emit"      =>
 '
 if (get_ia32_immop_type(n) == ia32_ImmNone) {
@@ -484,7 +492,15 @@ 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" => [ "!ecx in_r3 !in_r4" ] },
+  # 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.
+  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "ecx", "none" ], "out" => [ "!in" ] },
   "emit"      =>
 '
 if (get_ia32_immop_type(n) == ia32_ImmNone) {