2
0
Эх сурвалжийг харах

* fixed assembling of movd with 64 bit registers
* fixed passing of floats to c varargs

git-svn-id: trunk@5477 -

florian 18 жил өмнө
parent
commit
6118c3e477

+ 1 - 1
compiler/i386/i386nop.inc

@@ -1,2 +1,2 @@
 { don't edit, this file is generated from x86ins.dat }
-1368;
+1370;

+ 16 - 2
compiler/i386/i386tab.inc

@@ -3150,18 +3150,32 @@
     code    : #3#102#15#126#65;
     flags   : if_willamette or if_sse2
   ),
+  (
+    opcode  : A_MOVD;
+    ops     : 2;
+    optypes : (ot_xmmreg,ot_reg64,ot_none);
+    code    : #1#102#214#2#15#110#72;
+    flags   : if_willamette or if_sse2
+  ),
+  (
+    opcode  : A_MOVD;
+    ops     : 2;
+    optypes : (ot_reg64,ot_xmmreg,ot_none);
+    code    : #1#102#214#2#15#126#65;
+    flags   : if_willamette or if_sse2
+  ),
   (
     opcode  : A_MOVD;
     ops     : 2;
     optypes : (ot_memory,ot_xmmreg,ot_none);
-    code    : #192#3#102#15#126#65;
+    code    : #1#102#214#2#15#126#65;
     flags   : if_willamette or if_sse2
   ),
   (
     opcode  : A_MOVD;
     ops     : 2;
     optypes : (ot_xmmreg,ot_memory,ot_none);
-    code    : #193#3#102#15#110#72;
+    code    : #1#102#214#2#15#110#72;
     flags   : if_willamette or if_sse2
   ),
   (

+ 8 - 1
compiler/ncgcal.pas

@@ -82,7 +82,7 @@ implementation
       aasmbase,aasmtai,aasmdata,
       nbas,nmem,nld,ncnv,nutils,
 {$ifdef x86}
-      cga,cgx86,
+      cga,cgx86,aasmcpu,
 {$endif x86}
       ncgutil,
       cgobj,tgobj,
@@ -193,6 +193,13 @@ implementation
                  LOC_MMREGISTER,
                  LOC_CMMREGISTER:
                    cg.a_parammm_reg(current_asmdata.CurrAsmList,left.location.size,left.location.register,tempcgpara,mms_movescalar);
+{$ifdef x86_64}
+                 LOC_REGISTER,
+                 LOC_CREGISTER :
+                   begin
+                     current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_MOVD,S_NO,left.location.register,tempcgpara.location^.register));
+                   end;
+{$endif x86_64}
                  LOC_FPUREGISTER,
                  LOC_CFPUREGISTER:
                    begin

+ 2 - 0
compiler/ncnv.pas

@@ -564,6 +564,8 @@ implementation
                      not(nf_explicit in p.flags) then
                     MessagePos(p.fileinfo,type_w_double_c_varargs);
                   if (tfloatdef(p.resultdef).floattype in [{$ifndef x86_64}s32real,{$endif}s64currency]) or
+                    { win64 requires the double type cast for singles as well }
+                     ((tfloatdef(p.resultdef).floattype=s32real) and (target_info.system=system_x86_64_win64)) or
                      (is_constrealnode(p) and
                       not(nf_explicit in p.flags)) then
                     p:=ctypeconvnode.create(p,s64floattype);

+ 4 - 2
compiler/x86/x86ins.dat

@@ -1054,8 +1054,10 @@ mem,mmxreg            \300\2\x0F\x7E\101              PENT,MMX,SD
 reg32,mmxreg          \2\x0F\x7E\101                  PENT,MMX
 xmmreg,reg32          \3\x66\x0F\x6E\110              WILLAMETTE,SSE2
 reg32,xmmreg          \3\x66\x0F\x7E\101              WILLAMETTE,SSE2
-mem,xmmreg            \300\3\x66\x0F\x7E\101          WILLAMETTE,SSE2
-xmmreg,mem            \301\3\x66\x0F\x6E\110          WILLAMETTE,SSE2
+xmmreg,reg64          \1\x66\326\2\x0F\x6E\110        WILLAMETTE,SSE2
+reg64,xmmreg          \1\x66\326\2\x0F\x7E\101        WILLAMETTE,SSE2
+mem,xmmreg            \1\x66\326\2\x0F\x7E\101        WILLAMETTE,SSE2
+xmmreg,mem            \1\x66\326\2\x0F\x6E\110        WILLAMETTE,SSE2
 
 [MOVQ,movq]
 (Ch_Rop1, Ch_Wop2, Ch_None)

+ 19 - 5
compiler/x86_64/cpupara.pas

@@ -37,7 +37,7 @@ unit cpupara;
        private
           procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
           procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee;paras:tparalist;
-                                               var intparareg,mmparareg,parasize:longint);
+                                               var intparareg,mmparareg,parasize:longint;varargsparas: boolean);
        public
           function param_use_paraloc(const cgpara:tcgpara):boolean;override;
           function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
@@ -364,7 +364,7 @@ unit cpupara;
 
 
     procedure tx86_64paramanager.create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee;paras:tparalist;
-                                                            var intparareg,mmparareg,parasize:longint);
+                                                            var intparareg,mmparareg,parasize:longint;varargsparas: boolean);
       var
         hp         : tparavarsym;
         paraloc    : pcgparalocation;
@@ -397,6 +397,20 @@ unit cpupara;
                 paralen:=push_size(hp.varspez,hp.vardef,p.proccalloption);
                 paracgsize:=def_cgsize(hp.vardef);
               end;
+
+            { cheat for now, we should copy the value to an mm reg as well (FK) }
+            if varargsparas and
+               (target_info.system = system_x86_64_win64) and
+               (hp.vardef.typ = floatdef) then
+              begin
+                loc[1] := LOC_REGISTER;
+                loc[2] := LOC_INVALID;
+                if paracgsize = OS_F64 then
+                  paracgsize := OS_64
+                else
+                  paracgsize := OS_32;
+              end;
+
             hp.paraloc[side].reset;
             hp.paraloc[side].size:=paracgsize;
             hp.paraloc[side].intsize:=paralen;
@@ -542,9 +556,9 @@ unit cpupara;
         else
           parasize:=0;
         { calculate the registers for the normal parameters }
-        create_paraloc_info_intern(p,callerside,p.paras,intparareg,mmparareg,parasize);
+        create_paraloc_info_intern(p,callerside,p.paras,intparareg,mmparareg,parasize,false);
         { append the varargs }
-        create_paraloc_info_intern(p,callerside,varargspara,intparareg,mmparareg,parasize);
+        create_paraloc_info_intern(p,callerside,varargspara,intparareg,mmparareg,parasize,true);
         { store used no. of SSE registers, that needs to be passed in %AL }
         varargspara.mmregsused:=mmparareg;
         result:=parasize;
@@ -562,7 +576,7 @@ unit cpupara;
           parasize:=4*8
         else
           parasize:=0;
-        create_paraloc_info_intern(p,side,p.paras,intparareg,mmparareg,parasize);
+        create_paraloc_info_intern(p,side,p.paras,intparareg,mmparareg,parasize,false);
         { Create Function result paraloc }
         create_funcretloc_info(p,side);
         { We need to return the size allocated on the stack }

+ 2 - 1
compiler/x86_64/nx64cal.pas

@@ -38,6 +38,7 @@ implementation
 
     uses
       globtype,
+      systems,
       cpubase,
       aasmtai,aasmdata,aasmcpu;
 
@@ -46,7 +47,7 @@ implementation
         mmregs : aint;
       begin
         { x86_64 requires %al to contain the no. SSE regs passed }
-        if cnf_uses_varargs in callnodeflags then
+        if (cnf_uses_varargs in callnodeflags) and (target_info.system<>system_x86_64_win64) then
           begin
             if assigned(varargsparas) then
               mmregs:=varargsparas.mmregsused

+ 1 - 1
compiler/x86_64/x8664nop.inc

@@ -1,2 +1,2 @@
 { don't edit, this file is generated from x86ins.dat }
-1366;
+1368;

+ 16 - 2
compiler/x86_64/x8664tab.inc

@@ -3108,18 +3108,32 @@
     code    : #3#102#15#126#65;
     flags   : if_willamette or if_sse2
   ),
+  (
+    opcode  : A_MOVD;
+    ops     : 2;
+    optypes : (ot_xmmreg,ot_reg64,ot_none);
+    code    : #1#102#214#2#15#110#72;
+    flags   : if_willamette or if_sse2
+  ),
+  (
+    opcode  : A_MOVD;
+    ops     : 2;
+    optypes : (ot_reg64,ot_xmmreg,ot_none);
+    code    : #1#102#214#2#15#126#65;
+    flags   : if_willamette or if_sse2
+  ),
   (
     opcode  : A_MOVD;
     ops     : 2;
     optypes : (ot_memory,ot_xmmreg,ot_none);
-    code    : #192#3#102#15#126#65;
+    code    : #1#102#214#2#15#126#65;
     flags   : if_willamette or if_sse2
   ),
   (
     opcode  : A_MOVD;
     ops     : 2;
     optypes : (ot_xmmreg,ot_memory,ot_none);
-    code    : #193#3#102#15#110#72;
+    code    : #1#102#214#2#15#110#72;
     flags   : if_willamette or if_sse2
   ),
   (