Selaa lähdekoodia

* fixed optimized division of signed values by constant power of 2 if the
constant is > high(longint), because then it must be loaded into a register
first since such values cannot be encoded directly in non-mov x86-64
instructions (mantis #17836)

git-svn-id: trunk@16305 -

Jonas Maebe 14 vuotta sitten
vanhempi
commit
d1264eeb3a
3 muutettua tiedostoa jossa 25 lisäystä ja 1 poistoa
  1. 1 0
      .gitattributes
  2. 3 1
      compiler/x86_64/nx64mat.pas
  3. 21 0
      tests/webtbs/tw17836.pp

+ 1 - 0
.gitattributes

@@ -10734,6 +10734,7 @@ tests/webtbs/tw17714.pp svneol=native#text/plain
 tests/webtbs/tw17715.pp svneol=native#text/plain
 tests/webtbs/tw1779.pp svneol=native#text/plain
 tests/webtbs/tw1780.pp svneol=native#text/plain
+tests/webtbs/tw17836.pp svneol=native#text/plain
 tests/webtbs/tw1792.pp svneol=native#text/plain
 tests/webtbs/tw1792a.pp svneol=native#text/plain
 tests/webtbs/tw1798.pp svneol=native#text/plain

+ 3 - 1
compiler/x86_64/nx64mat.pas

@@ -93,7 +93,9 @@ implementation
                   {If the left value is signed, hreg2=$ffffffff, otherwise 0.}
                   emit_const_reg(A_SAR,S_Q,63,hreg2);
                   {If signed, hreg2=right value-1, otherwise 0.}
-                  emit_const_reg(A_AND,S_Q,tordconstnode(right).value-1,hreg2);
+                  { (don't use emit_const_reg, because if value>high(longint)
+                     then it must first be loaded into a register) }
+                  cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_AND,OS_S64,tordconstnode(right).value-1,hreg2);
                   { add to the left value }
                   emit_reg_reg(A_ADD,S_Q,hreg2,hreg1);
                   { do the shift }

+ 21 - 0
tests/webtbs/tw17836.pp

@@ -0,0 +1,21 @@
+  var
+    w,w1: int64;
+  begin
+    w1:=-1;
+    w:=w1 div (int64(1) shl 33);
+    system.writeln(w);
+    if w<>0 then
+      halt(1);
+    w:=w1 div (int64(1) shl 32);
+    system.writeln(w);
+    if w<>0 then
+      halt(2);
+    w:=w1 div (int64(1) shl 31);
+    system.writeln(w);
+    if w<>0 then
+      halt(3);
+    w:=w1 div (int64(1) shl 5);
+    system.writeln(w);
+    if w<>0 then
+      halt(4);
+    end.