Browse Source

* fixed bug when assigning a negative value in a register to certain
fields of record regvars + test

git-svn-id: trunk@3641 -

Jonas Maebe 19 years ago
parent
commit
b5ce7e454c
3 changed files with 35 additions and 3 deletions
  1. 1 0
      .gitattributes
  2. 4 3
      compiler/cgobj.pas
  3. 30 0
      tests/test/trecreg2.pp

+ 1 - 0
.gitattributes

@@ -5755,6 +5755,7 @@ tests/test/trange4.pp svneol=native#text/plain
 tests/test/trange5.pp svneol=native#text/plain
 tests/test/trangeob.pp svneol=native#text/plain
 tests/test/trecreg.pp -text
+tests/test/trecreg2.pp svneol=native#text/plain
 tests/test/tresstr.pp svneol=native#text/plain
 tests/test/trtti1.pp svneol=native#text/plain
 tests/test/trtti2.pp svneol=native#text/plain

+ 4 - 3
compiler/cgobj.pas

@@ -897,15 +897,16 @@ implementation
        tmpreg: tregister;
        stopbit: byte;
      begin
-       tmpreg:=getintregister(list,subsetregsize);
-       a_load_reg_reg(list,fromsize,subsetregsize,fromreg,tmpreg);
-       a_op_const_reg(list,OP_SHL,subsetregsize,startbit,tmpreg);
        stopbit := startbit+(tcgsize2size[subsetsize] * 8);
        // on x86(64), 1 shl 32(64) = 1 instead of 0
        if (stopbit <> AIntBits) then
          bitmask := not(((1 shl stopbit)-1) xor ((1 shl startbit)-1))
        else
          bitmask := not(-1 xor ((1 shl startbit)-1));
+       tmpreg:=getintregister(list,subsetregsize);
+       a_load_reg_reg(list,fromsize,subsetregsize,fromreg,tmpreg);
+       a_op_const_reg(list,OP_SHL,subsetregsize,startbit,tmpreg);
+       a_op_const_reg(list,OP_AND,subsetregsize,not(bitmask),tmpreg);
        a_op_const_reg(list,OP_AND,subsetregsize,bitmask,subsetreg);
        a_op_reg_reg(list,OP_OR,subsetregsize,tmpreg,subsetreg);
      end;

+ 30 - 0
tests/test/trecreg2.pp

@@ -0,0 +1,30 @@
+type
+  tr = record
+    b1, b2, b3, b4: shortint;
+  end;
+
+procedure t;
+var
+  r: tr;
+  l: longint;
+begin
+  r.b1 := 1;
+  r.b2 := 2;
+  r.b3 := 3;
+  r.b4 := 4;
+  l := -1;
+  r.b2 := l;
+  if (r.b1 <> 1) or
+     (r.b2 <> -1) or
+     (r.b3 <> 3) or
+     (r.b4 <> 4) then
+    begin
+      writeln('error');
+      halt(1);
+    end;
+end;
+
+begin
+  t;
+end.
+