瀏覽代碼

Merged revisions 10505-10506 via svnmerge from
svn+ssh://[email protected]/FPC/svn/fpc/trunk

........
r10505 | jonas | 2008-03-18 21:10:22 +0100 (Tue, 18 Mar 2008) | 2 lines

* fixed a_param_ref for source sizes < 8 bytes

........
r10506 | jonas | 2008-03-19 00:09:12 +0100 (Wed, 19 Mar 2008) | 3 lines

* fixed widestring range checking on win64 (mantis #10450, fix also
depends on r10505)

........

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

Jonas Maebe 17 年之前
父節點
當前提交
424e0f7b9d
共有 2 個文件被更改,包括 46 次插入6 次删除
  1. 27 4
      compiler/ncgmem.pas
  2. 19 2
      compiler/x86_64/cgcpu.pas

+ 27 - 4
compiler/ncgmem.pas

@@ -758,9 +758,19 @@ implementation
                               paramanager.allocparaloc(current_asmdata.CurrAsmList,paraloc2);
                               cg.a_param_const(current_asmdata.CurrAsmList,OS_INT,tordconstnode(right).value,paraloc2);
                               href:=location.reference;
-                              dec(href.offset,sizeof(aint)-offsetdec);
                               paramanager.allocparaloc(current_asmdata.CurrAsmList,paraloc1);
-                              cg.a_param_ref(current_asmdata.CurrAsmList,OS_INT,href,paraloc1);
+                              if not(tf_winlikewidestring in target_info.flags) or
+                                 (tstringdef(left.resultdef).stringtype<>st_widestring) then
+                                begin
+                                  dec(href.offset,sizeof(aint)-offsetdec);
+                                  cg.a_param_ref(current_asmdata.CurrAsmList,OS_ADDR,href,paraloc1);
+                                end
+                              else
+                                begin
+                                  { winlike widestrings have a 4 byte length }
+                                  dec(href.offset,4-offsetdec);
+                                  cg.a_param_ref(current_asmdata.CurrAsmList,OS_32,href,paraloc1);
+                                end;
                               paramanager.freeparaloc(current_asmdata.CurrAsmList,paraloc1);
                               paramanager.freeparaloc(current_asmdata.CurrAsmList,paraloc2);
                               cg.allocallcpuregisters(current_asmdata.CurrAsmList);
@@ -929,9 +939,22 @@ implementation
                               cg.a_param_reg(current_asmdata.CurrAsmList,OS_INT,right.location.register,paraloc2);
                               href:=location.reference;
                               dec(href.offset,sizeof(aint)-offsetdec);
-                              //dec(href.offset,7);
+
+                              href:=location.reference;
                               paramanager.allocparaloc(current_asmdata.CurrAsmList,paraloc1);
-                              cg.a_param_ref(current_asmdata.CurrAsmList,OS_INT,href,paraloc1);
+                              if not(tf_winlikewidestring in target_info.flags) or
+                                 (tstringdef(left.resultdef).stringtype<>st_widestring) then
+                                begin
+                                  dec(href.offset,sizeof(aint)-offsetdec);
+                                  cg.a_param_ref(current_asmdata.CurrAsmList,OS_ADDR,href,paraloc1);
+                                end
+                              else
+                                begin
+                                  { winlike widestrings have a 4 byte length }
+                                  dec(href.offset,4-offsetdec);
+                                  cg.a_param_ref(current_asmdata.CurrAsmList,OS_32,href,paraloc1);
+                                end;
+
                               paramanager.freeparaloc(current_asmdata.CurrAsmList,paraloc1);
                               paramanager.freeparaloc(current_asmdata.CurrAsmList,paraloc2);
                               cg.allocallcpuregisters(current_asmdata.CurrAsmList);

+ 19 - 2
compiler/x86_64/cgcpu.pas

@@ -109,15 +109,32 @@ unit cgcpu;
         tmpref, ref: treference;
         location: pcgparalocation;
         sizeleft: aint;
+        sourcesize: tcgsize;
       begin
         location := paraloc.location;
         tmpref := r;
-        sizeleft := paraloc.intsize;
+        { make sure we handle passing a 32 bit value in memory to a }
+        { 64 bit register location etc. correctly                   }
+        if (size<>OS_NO) and
+           (tcgsize2size[size]<paraloc.intsize) then
+          begin
+            paraloc.check_simple_location;
+            if not(location^.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+              internalerror(2008031801);
+            sizeleft:=tcgsize2size[size]
+          end
+        else
+          sizeleft:=paraloc.intsize;
         while assigned(location) do
           begin
             case location^.loc of
               LOC_REGISTER,LOC_CREGISTER:
-                a_load_ref_reg(list,location^.size,location^.size,tmpref,location^.register);
+                begin
+                  sourcesize:=int_cgsize(sizeleft);
+                  if (sourcesize=OS_NO) then
+                    sourcesize:=location^.size;
+                  a_load_ref_reg(list,sourcesize,location^.size,tmpref,location^.register);
+                end;
               LOC_REFERENCE:
                 begin
                   reference_reset_base(ref,location^.reference.index,location^.reference.offset);