瀏覽代碼

* fixed check regarding whether a field is in the first or second word of
of 2*sizeof(aword) bitpacked record that's kept in registers
(mantis #29669)

git-svn-id: trunk@33177 -

Jonas Maebe 9 年之前
父節點
當前提交
9788bb1316
共有 3 個文件被更改,包括 62 次插入3 次删除
  1. 1 0
      .gitattributes
  2. 9 3
      compiler/ncgmem.pas
  3. 52 0
      tests/webtbs/tw29669.pp

+ 1 - 0
.gitattributes

@@ -14968,6 +14968,7 @@ tests/webtbs/tw2958.pp svneol=native#text/plain
 tests/webtbs/tw29585.pp svneol=native#text/plain
 tests/webtbs/tw29609.pp svneol=native#text/pascal
 tests/webtbs/tw2966.pp svneol=native#text/plain
+tests/webtbs/tw29669.pp svneol=native#text/plain
 tests/webtbs/tw2975.pp svneol=native#text/plain
 tests/webtbs/tw2976.pp svneol=native#text/plain
 tests/webtbs/tw2983.pp svneol=native#text/plain

+ 9 - 3
compiler/ncgmem.pas

@@ -325,6 +325,7 @@ implementation
         paraloc1 : tcgpara;
         tmpref: treference;
         sref: tsubsetreference;
+        awordoffset,
         offsetcorrection : aint;
         pd : tprocdef;
         sym : tsym;
@@ -451,13 +452,18 @@ implementation
                        offsetcorrection:=0;
                        if (left.location.size in [OS_PAIR,OS_SPAIR]) then
                          begin
-                           if (vs.fieldoffset>=sizeof(aword)) xor (target_info.endian=endian_big) then
+                           if not is_packed_record_or_object(left.resultdef) then
+                             awordoffset:=sizeof(aword)
+                           else
+                             awordoffset:=sizeof(aword)*8;
+
+                           if (vs.fieldoffset>=awordoffset) xor (target_info.endian=endian_big) then
                              location.sreg.subsetreg := left.location.registerhi
                            else
                              location.sreg.subsetreg := left.location.register;
 
-                           if (vs.fieldoffset>=sizeof(aword)) then
-                             offsetcorrection:=sizeof(aword)*8;
+                           if vs.fieldoffset>=awordoffset then
+                             offsetcorrection := sizeof(aword)*8;
 
                            location.sreg.subsetregsize := OS_INT;
                          end

+ 52 - 0
tests/webtbs/tw29669.pp

@@ -0,0 +1,52 @@
+{$mode objfpc}
+
+program Project1;
+
+uses
+ SysUtils;
+
+type
+  TPackedIdLevel1 = 0..255;
+  TPackedIdLevel2 = 0..65535;
+  TPackedIdLevel3 = 0..65535;
+  TPackedIdLevel4 = 0..65535;
+  TPackedIdLevel5 = 0..255;
+
+  TPackedId = bitpacked record
+    clusterId : TPackedIdLevel5;
+    agentId : TPackedIdLevel4;
+    dataSourceId : TPackedIdLevel3;
+    deviceId : TPackedIdLevel2;
+    esmId : TPackedIdLevel1;
+  end;
+
+function PackedIdToStr(const ipsid : qword) : string;
+begin
+  result := IntToStr(TPackedId(ipsid).esmId) + '-' +
+            IntToStr(TPackedId(ipsid).deviceId) + '-' +
+            IntToStr(TPackedId(ipsid).dataSourceId) + '-' +
+            IntToStr(TPackedId(ipsid).agentId) + '-' +
+            IntToStr(TPackedId(ipsid).clusterId);
+  if TPackedId(ipsid).clusterid<>123 then
+    halt(1);
+  if TPackedId(ipsid).agentid<>45678 then
+    halt(2);
+  if TPackedId(ipsid).datasourceid<>9012 then
+    halt(3);
+  if TPackedId(ipsid).deviceid<>34567 then
+    halt(4);
+  if TPackedId(ipsid).esmid<>89 then
+    halt(5);
+
+end;
+
+var
+  pi: TPackedId;
+begin
+  pi.clusterid:=123;
+  pi.agentid:=45678;
+  pi.datasourceid:=9012;
+  pi.deviceid:=34567;
+  pi.esmid:=89;
+  writeln(PackedIdToStr(qword(pi)));
+end.