Browse Source

* handle assignments of qword bools with LOC_FLAGS correctly, resolves #20874

git-svn-id: trunk@19912 -
florian 13 years ago
parent
commit
a59a37dddd
4 changed files with 39 additions and 5 deletions
  1. 1 0
      .gitattributes
  2. 20 4
      compiler/ncgld.pas
  3. 1 1
      compiler/x86/cgx86.pas
  4. 17 0
      tests/webtbs/tw20874.pp

+ 1 - 0
.gitattributes

@@ -11975,6 +11975,7 @@ tests/webtbs/tw20836.pp svneol=native#text/pascal
 tests/webtbs/tw20872a.pp svneol=native#text/pascal
 tests/webtbs/tw20872b.pp svneol=native#text/pascal
 tests/webtbs/tw20872c.pp svneol=native#text/pascal
+tests/webtbs/tw20874.pp svneol=native#text/pascal
 tests/webtbs/tw20889.pp svneol=native#text/pascal
 tests/webtbs/tw2109.pp svneol=native#text/plain
 tests/webtbs/tw2110.pp svneol=native#text/plain

+ 20 - 4
compiler/ncgld.pas

@@ -570,6 +570,7 @@ implementation
          alignmentrequirement,
          len : aint;
          r : tregister;
+         r64 : tregister64;
          oldflowcontrol : tflowcontrol;
       begin
         location_reset(location,LOC_VOID,OS_NO);
@@ -958,10 +959,25 @@ implementation
                     end
                   else
                     begin
-                      r:=cg.getintregister(current_asmdata.CurrAsmList,left.location.size);
-                      cg.g_flags2reg(current_asmdata.CurrAsmList,left.location.size,right.location.resflags,r);
-                      cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_NEG,left.location.size,r,r);
-                      cg.a_load_reg_loc(current_asmdata.CurrAsmList,left.location.size,r,left.location);
+{$ifdef cpu32bitalu}
+                      if left.location.size in [OS_S64,OS_64] then
+                        begin
+                          r64.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+                          r64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+                          cg.g_flags2reg(current_asmdata.CurrAsmList,OS_32,right.location.resflags,r64.reglo);
+                          cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_32,0,r64.reghi);
+                          cg64.a_op64_reg_reg(current_asmdata.CurrAsmList,OP_NEG,OS_S64,
+                            r64,r64);
+                          cg64.a_load64_reg_loc(current_asmdata.CurrAsmList,r64,left.location);
+                        end
+                      else
+{$endif cpu32bitalu}
+                        begin
+                          r:=cg.getintregister(current_asmdata.CurrAsmList,left.location.size);
+                          cg.g_flags2reg(current_asmdata.CurrAsmList,left.location.size,right.location.resflags,r);
+                          cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_NEG,left.location.size,r,r);
+                          cg.a_load_reg_loc(current_asmdata.CurrAsmList,left.location.size,r,left.location);
+                        end
                     end;
                 end;
 {$endif cpuflags}

+ 1 - 1
compiler/x86/cgx86.pas

@@ -1770,7 +1770,7 @@ unit cgx86;
         ai:=Taicpu.op_reg(A_SETcc,S_B,hreg);
         ai.setcondition(flags_to_cond(f));
         list.concat(ai);
-        if (reg<>hreg) then
+        if reg<>hreg then
           a_load_reg_reg(list,OS_8,size,hreg,reg);
       end;
 

+ 17 - 0
tests/webtbs/tw20874.pp

@@ -0,0 +1,17 @@
+program qwordbooltest;
+
+{$mode objfpc}{$H+}
+
+var
+  A, B : QWordBool;
+begin
+  A := True;
+
+  // here it fails: qwordbooltest.pas(12,3) Fatal: Internal error 200109227
+  B := not A;
+
+  if B then
+    halt(1);
+
+  writeln('ok');
+end.