소스 검색

* Fix for win64 GNU AS bug

git-svn-id: trunk@15939 -
pierre 15 년 전
부모
커밋
973c23e12c
3개의 변경된 파일66개의 추가작업 그리고 0개의 파일을 삭제
  1. 1 0
      .gitattributes
  2. 33 0
      compiler/x86/agx86att.pas
  3. 32 0
      tests/webtbs/tw17337.pp

+ 1 - 0
.gitattributes

@@ -10640,6 +10640,7 @@ tests/webtbs/tw17220.pp svneol=native#text/plain
 tests/webtbs/tw17220a.pp svneol=native#text/plain
 tests/webtbs/tw17236.pp svneol=native#text/pascal
 tests/webtbs/tw17283.pp svneol=native#text/plain
+tests/webtbs/tw17337.pp svneol=native#text/plain
 tests/webtbs/tw1735.pp svneol=native#text/plain
 tests/webtbs/tw1737.pp svneol=native#text/plain
 tests/webtbs/tw1744.pp svneol=native#text/plain

+ 33 - 0
compiler/x86/agx86att.pas

@@ -60,6 +60,7 @@ interface
   implementation
 
     uses
+      globtype,
       cutils,systems,
       verbose,
       itcpugas,
@@ -228,14 +229,40 @@ interface
     procedure Tx86InstrWriter.WriteInstruction(hp: tai);
       var
        op       : tasmop;
+       val      : aint;
        calljmp  : boolean;
+       need_second_mov : boolean;
        i        : integer;
+       comment  : tai_comment;
       begin
         if hp.typ <> ait_instruction then
           exit;
         taicpu(hp).SetOperandOrder(op_att);
         op:=taicpu(hp).opcode;
         calljmp:=is_calljmp(op);
+        { constant values in the 32 bit range are sign-extended to
+          64 bits, but this is not what we want.  PM 2010-09-02
+          the fix consists of simply setting only the 4-byte register
+          as the upper 4-bytes will be zeroed at the same time. }
+        need_second_mov:=false;
+        if (op=A_MOV) and (taicpu(hp).opsize=S_Q) and
+           (taicpu(hp).oper[0]^.typ = top_const) then
+           begin
+             val := taicpu(hp).oper[0]^.val;
+	     if (val > int64($7fffffff)) and (val < int64($100000000)) then
+               begin
+                 owner.AsmWrite(target_asm.comment);
+                 owner.AsmWritePChar('Fix for Win64-GAS bug');
+                 owner.AsmLn;
+                 taicpu(hp).opsize:=S_L;
+                 if taicpu(hp).oper[1]^.typ = top_reg then
+                   setsubreg(taicpu(hp).oper[1]^.reg,R_SUBD)
+                 else if taicpu(hp).oper[1]^.typ = top_ref then
+                   need_second_mov:=true
+                 else
+                   internalerror(20100902011);
+               end;
+           end;
         owner.AsmWrite(#9);
         { movsd should not be translated to movsl when there
           are (xmm) arguments }
@@ -284,6 +311,12 @@ interface
              end;
           end;
         owner.AsmLn;
+        if need_second_mov then
+          begin
+            taicpu(hp).oper[0]^.val:=0;
+            inc(taicpu(hp).oper[1]^.ref^.offset,4);
+            WriteInstruction(hp);
+          end;
       end;
 
 {*****************************************************************************

+ 32 - 0
tests/webtbs/tw17337.pp

@@ -0,0 +1,32 @@
+{ %target=win64, linux, freebsd }
+{ %cpu=x86_64 }
+{ %opt=-Aas }
+
+{$asmmode att}
+
+procedure test_gas;   
+var
+  test : qword;
+begin
+  test:=$5ffffffff;
+  if (test < qword($2ffffffff)) then
+    runerror(1);
+  if (test < qword($ffffffff)) then
+    runerror(2);
+asm
+  movq $0xffffffff,test
+end;
+  if test <> $ffffffff then
+    runerror(5);
+end ;
+  
+var
+  test : qword;
+begin
+  test:=$5ffffffff;
+  if (test < qword($2ffffffff)) then
+    runerror(3);
+  if (test < qword($ffffffff)) then
+    runerror(4);
+  test_gas;
+end.