Browse Source

* do not use voidtype for temporary parameter/result locations when
inlining, because that results in alignment settings of "0"
(voidtype.savesize = 0 -> size2align(0) = 0), which is interpreted
by the code generators as unaligned (and is actually even invalid
nowadays). This caused errors on NDS when writing to memory mapped
I/O devices (mantis #13343)

git-svn-id: trunk@12916 -

Jonas Maebe 16 years ago
parent
commit
630aa5c493
3 changed files with 35 additions and 3 deletions
  1. 1 0
      .gitattributes
  2. 8 3
      compiler/ncal.pas
  3. 26 0
      tests/webtbs/tw13343.pp

+ 1 - 0
.gitattributes

@@ -8803,6 +8803,7 @@ tests/webtbs/tw1331.pp svneol=native#text/plain
 tests/webtbs/tw13313.pp svneol=native#text/plain
 tests/webtbs/tw13313a.pp svneol=native#text/plain
 tests/webtbs/tw1333.pp svneol=native#text/plain
+tests/webtbs/tw13343.pp svneol=native#text/plain
 tests/webtbs/tw1348.pp svneol=native#text/plain
 tests/webtbs/tw1351.pp svneol=native#text/plain
 tests/webtbs/tw1364.pp svneol=native#text/plain

+ 8 - 3
compiler/ncal.pas

@@ -3079,6 +3079,8 @@ implementation
         para: tcallparanode;
         tempnode: ttempcreatenode;
         n: tnode;
+        paraaddr: taddrnode;
+        ptrtype: tpointerdef;
         paracomplexity: longint;
       begin
         { parameters }
@@ -3197,15 +3199,18 @@ implementation
                 { temp                                                        }
                 else if (paracomplexity > 1) then
                   begin
-                    tempnode := ctempcreatenode.create(voidpointertype,voidpointertype.size,tt_persistent,tparavarsym(para.parasym).is_regvar(true));
+                    ptrtype:=tpointerdef.create(para.left.resultdef);
+                    tempnode := ctempcreatenode.create(ptrtype,ptrtype.size,tt_persistent,tparavarsym(para.parasym).is_regvar(true));
                     addstatement(inlineinitstatement,tempnode);
                     addstatement(inlinecleanupstatement,ctempdeletenode.create(tempnode));
                     { inherit addr_taken flag }
                     if (tabstractvarsym(para.parasym).addr_taken) then
                       include(tempnode.tempinfo^.flags,ti_addr_taken);
+                    paraaddr:=caddrnode.create_internal(para.left);
+                    include(paraaddr.flags,nf_typedaddr);
                     addstatement(inlineinitstatement,cassignmentnode.create(ctemprefnode.create(tempnode),
-                      caddrnode.create_internal(para.left)));
-                    para.left := ctypeconvnode.create_internal(cderefnode.create(ctemprefnode.create(tempnode)),para.left.resultdef);
+                      paraaddr));
+                    para.left:=cderefnode.create(ctemprefnode.create(tempnode));
                   end;
               end;
             para := tcallparanode(para.right);

+ 26 - 0
tests/webtbs/tw13343.pp

@@ -0,0 +1,26 @@
+{ %interactive }
+
+{$inline on}
+uses
+  ctypes;
+const
+  MATRIX_TRANSLATE      : pcint32 = pointer($04000470);
+
+function floattof32(n: cfloat): cint32; inline;
+  begin
+    floattof32 := cint32(n);
+  end;
+
+procedure glTranslate3f32({ x, y,} z: cint32); inline; 
+  begin 
+    MATRIX_TRANSLATE^ := z;
+  end;
+
+begin
+    { check that the inlined version of glTranslate3f32 does *NOT* perform
+      an unaligned store (i.e., make sure it performs one 4 byte store
+      rather than 4 one byte stores on platforms that require aligned memory
+      accesses)
+    }
+    glTranslate3f32(floattof32(-1.0));
+end.