Browse Source

Merged revisions 8484,8486-8488,8490,8493,8496,8506,8535-8537,8539-8546,8554,8560,8575-8576,8581-8587,8590,8593-8594,8596,8600,8605,8607,8625,8630-8638,8640-8641,8659,8665,8667,8681-8682,8686-8687,8702,8705,8710-8714,8719,8721-8723,8727,8730-8731,8743,8747-8751,8766-8769,8797,8822,8831,8848-8849,8851,8862,8879,8885-8889,8891-8893,8895,8897,8912,8917,8942,8950,8972 via svnmerge from
http://svn.freepascal.org/svn/fpc/trunk

........
r8484 | florian | 2007-09-14 21:26:09 +0200 (Fri, 14 Sep 2007) | 2 lines

* pass classes and interfaces by value if const is used, resolves #9674
........
r8862 | micha | 2007-10-20 16:31:08 +0200 (Sat, 20 Oct 2007) | 1 line

* fix big endian arm loading (fixes issue #8752)
........
r8972 | florian | 2007-10-28 16:30:50 +0100 (Sun, 28 Oct 2007) | 2 lines

* fixes unaligned load_ref_reg on little endian arm
........

git-svn-id: branches/fixes_2_2@10298 -

florian 17 years ago
parent
commit
ae6c79a06d
2 changed files with 32 additions and 11 deletions
  1. 30 10
      compiler/arm/cgcpu.pas
  2. 2 1
      compiler/arm/cpupara.pas

+ 30 - 10
compiler/arm/cgcpu.pas

@@ -774,6 +774,7 @@ unit cgcpu;
          usedtmpref: treference;
          tmpreg : tregister;
          so : tshifterop;
+         dir : integer;
        begin
          case ToSize of
            { signed integer registers }
@@ -791,13 +792,20 @@ unit cgcpu;
          end;
          if ref.alignment<>0 then
            begin
+             if target_info.endian=endian_big then
+               dir:=-1
+             else
+               dir:=1;
              case FromSize of
                OS_16,OS_S16:
                  begin
                    shifterop_reset(so);so.shiftmode:=SM_LSR;so.shiftimm:=8;
                    tmpreg:=getintregister(list,OS_INT);
-                   usedtmpref:=a_internal_load_reg_ref(list,OS_8,OS_8,reg,Ref);
-                   inc(usedtmpref.offset);
+                   usedtmpref:=ref;
+                   if target_info.endian=endian_big then
+                     inc(usedtmpref.offset,1);
+                   usedtmpref:=a_internal_load_reg_ref(list,OS_8,OS_8,reg,usedtmpref);
+                   inc(usedtmpref.offset,dir);
                    list.concat(taicpu.op_reg_reg_shifterop(A_MOV,tmpreg,reg,so));
                    a_internal_load_reg_ref(list,OS_8,OS_8,tmpreg,usedtmpref);
                  end;
@@ -805,15 +813,18 @@ unit cgcpu;
                  begin
                    shifterop_reset(so);so.shiftmode:=SM_LSR;so.shiftimm:=8;
                    tmpreg:=getintregister(list,OS_INT);
-                   usedtmpref:=a_internal_load_reg_ref(list,OS_8,OS_8,reg,Ref);
+                   usedtmpref:=ref;
+                   if target_info.endian=endian_big then
+                     inc(usedtmpref.offset,3);
+                   usedtmpref:=a_internal_load_reg_ref(list,OS_8,OS_8,reg,usedtmpref);
                    list.concat(taicpu.op_reg_reg_shifterop(A_MOV,tmpreg,reg,so));
-                   inc(usedtmpref.offset);
+                   inc(usedtmpref.offset,dir);
                    a_internal_load_reg_ref(list,OS_8,OS_8,tmpreg,usedtmpref);
                    list.concat(taicpu.op_reg_reg_shifterop(A_MOV,tmpreg,tmpreg,so));
-                   inc(usedtmpref.offset);
+                   inc(usedtmpref.offset,dir);
                    a_internal_load_reg_ref(list,OS_8,OS_8,tmpreg,usedtmpref);
                    list.concat(taicpu.op_reg_reg_shifterop(A_MOV,tmpreg,tmpreg,so));
-                   inc(usedtmpref.offset);
+                   inc(usedtmpref.offset,dir);
                    a_internal_load_reg_ref(list,OS_8,OS_8,tmpreg,usedtmpref);
                  end
                else
@@ -831,6 +842,7 @@ unit cgcpu;
          usedtmpref: treference;
          tmpreg,tmpreg2,tmpreg3 : tregister;
          so : tshifterop;
+         dir : integer;
        begin
          case FromSize of
            { signed integer registers }
@@ -850,6 +862,10 @@ unit cgcpu;
          end;
          if Ref.alignment<>0 then
            begin
+             if target_info.endian=endian_big then
+               dir:=-1
+             else
+               dir:=1;
              case FromSize of
                OS_16,OS_S16:
                  begin
@@ -869,10 +885,12 @@ unit cgcpu;
                    else
                      usedtmpref:=ref;
 
+                   if target_info.endian=endian_big then
+                     inc(usedtmpref.offset,1);
                    shifterop_reset(so);so.shiftmode:=SM_LSL;so.shiftimm:=8;
                    tmpreg:=getintregister(list,OS_INT);
                    a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,tmpreg);
-                   inc(usedtmpref.offset);
+                   inc(usedtmpref.offset,dir);
                    tmpreg2:=getintregister(list,OS_INT);
                    if FromSize=OS_16 then
                      a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,tmpreg2)
@@ -901,16 +919,18 @@ unit cgcpu;
                    else
                      usedtmpref:=ref;
 
+                   if target_info.endian=endian_big then
+                     inc(usedtmpref.offset,3);
                    shifterop_reset(so);so.shiftmode:=SM_LSL;so.shiftimm:=8;
                    a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,reg);
-                   inc(usedtmpref.offset);
+                   inc(usedtmpref.offset,dir);
                    a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,tmpreg);
                    list.concat(taicpu.op_reg_reg_reg_shifterop(A_ORR,tmpreg2,reg,tmpreg,so));
-                   inc(usedtmpref.offset);
+                   inc(usedtmpref.offset,dir);
                    a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,reg);
                    so.shiftimm:=16;
                    list.concat(taicpu.op_reg_reg_reg_shifterop(A_ORR,tmpreg,tmpreg2,reg,so));
-                   inc(usedtmpref.offset);
+                   inc(usedtmpref.offset,dir);
                    a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,tmpreg2);
                    so.shiftimm:=24;
                    list.concat(taicpu.op_reg_reg_reg_shifterop(A_ORR,reg,tmpreg,tmpreg2,so));

+ 2 - 1
compiler/arm/cpupara.pas

@@ -160,7 +160,8 @@ unit cpupara;
             exit;
           end;
         case def.typ of
-          objectdef,
+          objectdef:
+            result:=is_object(def) and ((varspez=vs_const) or (def.size=0));
           recorddef:
             result:=(varspez=vs_const) or (def.size=0);
           variantdef,