瀏覽代碼

* fixed more xmm stuff
+ some win64 stuff added

git-svn-id: trunk@330 -

florian 20 年之前
父節點
當前提交
21ae782854

+ 3 - 1
.gitattributes

@@ -102,7 +102,6 @@ compiler/globtype.pas svneol=native#text/plain
 compiler/html/i386/readme.txt svneol=native#text/plain
 compiler/html/powerpc/readme.txt svneol=native#text/plain
 compiler/htypechk.pas svneol=native#text/plain
-compiler/i386/ag386int.pas svneol=native#text/plain
 compiler/i386/ag386nsm.pas svneol=native#text/plain
 compiler/i386/aopt386.pas svneol=native#text/plain
 compiler/i386/cgcpu.pas svneol=native#text/plain
@@ -459,6 +458,7 @@ compiler/vis/cpupara.pas svneol=native#text/plain
 compiler/widestr.pas svneol=native#text/plain
 compiler/x86/aasmcpu.pas svneol=native#text/plain
 compiler/x86/agx86att.pas svneol=native#text/plain
+compiler/x86/agx86int.pas svneol=native#text/plain
 compiler/x86/cga.pas svneol=native#text/plain
 compiler/x86/cgx86.pas svneol=native#text/plain
 compiler/x86/cpubase.pas svneol=native#text/plain
@@ -493,6 +493,8 @@ compiler/x86_64/r8664ari.inc svneol=native#text/plain
 compiler/x86_64/r8664att.inc svneol=native#text/plain
 compiler/x86_64/r8664con.inc svneol=native#text/plain
 compiler/x86_64/r8664dwrf.inc svneol=native#text/plain
+compiler/x86_64/r8664int.inc svneol=native#text/plain
+compiler/x86_64/r8664iri.inc svneol=native#text/plain
 compiler/x86_64/r8664nor.inc svneol=native#text/plain
 compiler/x86_64/r8664num.inc svneol=native#text/plain
 compiler/x86_64/r8664op.inc svneol=native#text/plain

+ 1 - 1
compiler/cgobj.pas

@@ -563,7 +563,7 @@ implementation
     function tcg.getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;
       begin
         if not assigned(rg[R_MMREGISTER]) then
-          internalerror(200312124);
+          internalerror(2003121214);
         result:=rg[R_MMREGISTER].getregister(list,cgsize2subreg(size));
       end;
 

+ 1 - 1
compiler/i386/cgcpu.pas

@@ -164,7 +164,7 @@ unit cgcpu;
         if use_push(cgpara) then
           begin
             { Record copy? }
-            if (cgpara.size in [OS_NO,OS_F64,OS_F80]) or (size=OS_NO) then
+            if (cgpara.size in [OS_NO,OS_F64]) or (size=OS_NO) then
               begin
                 cgpara.check_simple_location;
                 len:=align(cgpara.intsize,cgpara.alignment);

+ 2 - 1
compiler/i386/cpubase.inc

@@ -33,7 +33,8 @@
         S_FS,S_FL,S_FX,S_FV,S_FXX,
         S_MD,
         S_NEAR,S_FAR,S_SHORT,
-        S_T
+        S_T,
+        S_XMM
       );
 
 

+ 3 - 3
compiler/i386/cpupara.pas

@@ -410,8 +410,8 @@ unit cpupara;
                   begin
                     paraloc:=hp.paraloc[side].add_location;
                     paraloc^.loc:=LOC_REFERENCE;
-                    { Extended and double need a single location }
-                    if (paracgsize in [OS_F80,OS_F64,OS_F32]) then
+                    { single and double need a single location }
+                    if (paracgsize in [OS_F64,OS_F32]) then
                       begin
                         paraloc^.size:=paracgsize;
                         l:=paralen;
@@ -524,7 +524,7 @@ unit cpupara;
                         paraloc:=hp.paraloc[side].add_location;
                         paraloc^.loc:=LOC_REFERENCE;
                         { Extended and double need a single location }
-                        if (paracgsize in [OS_F80,OS_F64,OS_F32]) then
+                        if (paracgsize in [OS_F64,OS_F32]) then
                           begin
                             paraloc^.size:=paracgsize;
                             l:=paralen;

+ 1 - 1
compiler/i386/cputarg.pas

@@ -83,7 +83,7 @@ implementation
       ,ag386nsm
     {$endif}
     {$ifndef NOAG386INT}
-      ,ag386int
+      ,agx86int
     {$endif}
 
       ,ogcoff

+ 1 - 0
compiler/i386/daopt386.pas

@@ -57,6 +57,7 @@ const
     OS_F32,OS_F64,OS_F80,OS_C64,OS_F128,
     OS_M32,
     OS_ADDR,OS_NO,OS_NO,
+    OS_NO,
     OS_NO);
 
 

+ 11 - 1
compiler/options.pas

@@ -1868,7 +1868,17 @@ begin
   def_system_macro('CPU64');
   { not supported for now, afaik (FK)
    def_system_macro('FPC_HAS_TYPE_FLOAT128'); }
-  def_system_macro('FPC_HAS_TYPE_EXTENDED');
+
+  { win64 doesn't support the legacy fpu }
+  if target_info.system<>system_x86_64_win64 then
+    def_system_macro('FPC_HAS_TYPE_EXTENDED')
+  else
+    begin
+      def_system_macro('FPC_CURRENCY_IS_INT64');
+      def_system_macro('FPC_COMP_IS_INT64');
+      undef_system_macro('FPC_HAS_TYPE_EXTENDED');
+    end;
+
   def_system_macro('FPC_HAS_TYPE_DOUBLE');
   def_system_macro('FPC_HAS_TYPE_SINGLE');
 {$endif}

+ 10 - 2
compiler/psystem.pas

@@ -42,6 +42,7 @@ implementation
 
     uses
       globals,globtype,verbose,
+      systems,
       symconst,symtype,symsym,symdef,symtable,
       aasmtai,aasmcpu,ncgutil,fmodule,
 {$ifdef GDB}
@@ -120,6 +121,9 @@ implementation
       var
         hrecst : trecordsymtable;
       begin
+        if target_info.system=system_x86_64_win64 then
+          pbestrealtype:=@s64floattype;
+
 {$ifdef cpufpemu}
         { Normal types }
         if (cs_fp_emulation in aktmoduleswitches) then
@@ -141,7 +145,8 @@ implementation
             addtype('Real',s64floattype);
           end;
 {$ifdef x86}
-        adddef('Comp',tfloatdef.create(s64comp));
+        if target_info.system<>system_x86_64_win64 then
+          adddef('Comp',tfloatdef.create(s64comp));
 {$endif x86}
         addtype('Currency',s64currencytype);
         addtype('Pointer',voidpointertype);
@@ -358,7 +363,10 @@ implementation
         s32floattype.setdef(tfloatdef.create(s32real));
         s64floattype.setdef(tfloatdef.create(s64real));
         s80floattype.setdef(tfloatdef.create(s80real));
-        s64currencytype.setdef(tfloatdef.create(s64currency));
+        if target_info.system<>system_x86_64_win64 then
+          s64currencytype.setdef(tfloatdef.create(s64currency))
+        else
+          s64currencytype.setdef(torddef.create(scurrency,low(int64),high(int64)));
 {$endif x86}
 {$ifdef powerpc}
         s32floattype.setdef(tfloatdef.create(s32real));

+ 8 - 2
compiler/symdef.pas

@@ -2320,10 +2320,16 @@ implementation
 {$ifdef cpu64bit}
         case filetyp of
           ft_text :
-            savesize:=628;
+            if target_info.system in [system_x86_64_win64,system_ia64_win64] then
+              savesize:=632
+            else
+              savesize:=628;
           ft_typed,
           ft_untyped :
-            savesize:=368;
+            if target_info.system in [system_x86_64_win64,system_ia64_win64] then
+              savesize:=372
+            else
+              savesize:=368;
         end;
 {$else cpu64bit}
         case filetyp of

+ 7 - 2
compiler/systems.pas

@@ -112,7 +112,10 @@ interface
              system_powerpc_MorphOS,    { 33 }
              system_x86_64_freebsd,     { 34 }
              system_i386_netwlibc,      { 35 }
-	     system_powerpc_Amiga	{ 36 }
+	     system_powerpc_Amiga,      { 36 }
+             system_x86_64_win64,       { 37 }
+             system_arm_wince,          { 38 }
+             system_ia64_win64          { 39 }
        );
 
        tasm = (as_none
@@ -134,6 +137,8 @@ interface
              ,as_m68k_mit
              ,as_powerpc_mpw
              ,as_darwin
+             ,as_x86_64_masm
+             ,as_x86_64_pecoff
        );
 
        tar = (ar_none
@@ -243,7 +248,7 @@ interface
           flags        : set of tsystemflags;
           cpu          : tsystemcpu;
           unit_env     : string[16];
-          extradefines : string[40]; 
+          extradefines : string[40];
           exeext,
           defext,
           scriptext,

+ 69 - 0
compiler/systems/i_win.pas

@@ -96,6 +96,67 @@ unit i_win;
             use_function_relative_addresses : true
           );
 
+       system_x64_win64_info : tsysteminfo =
+          (
+            system       : system_x86_64_win64;
+            name         : 'Win64 for x64';
+            shortname    : 'Win64';
+            flags        : [];
+            cpu          : cpu_x86_64;
+            unit_env     : 'WIN64UNITS';
+            extradefines : 'MSWINDOWS';
+            exeext       : '.exe';
+            defext       : '.def';
+            scriptext    : '.bat';
+            smartext     : '.sl';
+            unitext      : '.ppu';
+            unitlibext   : '.ppl';
+            asmext       : '.s';
+            objext       : '.o';
+            resext       : '.rc';
+            resobjext    : '.or';
+            sharedlibext : '.dll';
+            staticlibext : '.a';
+            staticlibprefix : 'libp';
+            sharedlibprefix : '';
+            sharedClibext : '.dll';
+            staticClibext : '.a';
+            staticClibprefix : 'lib';
+            sharedClibprefix : '';
+            p_ext_support : false;
+            Cprefix      : '_';
+            newline      : #13#10;
+            dirsep       : '\';
+            files_case_relevent : true;
+            assem        : as_x86_64_pecoff;
+            assemextern  : as_x86_64_masm;
+            link         : nil;
+            linkextern   : nil;
+            ar           : ar_gnu_ar;
+            res          : res_gnu_windres;
+            script       : script_dos;
+            endian       : endian_little;
+            alignment    :
+              (
+                procalign       : 8;
+                loopalign       : 8;
+                jumpalign       : 0;
+                constalignmin   : 0;
+                constalignmax   : 8;
+                varalignmin     : 0;
+                varalignmax     : 8;
+                localalignmin   : 8;
+                localalignmax   : 8;
+                recordalignmin  : 0;
+                recordalignmax  : 8;
+                maxCrecordalign : 16
+              );
+            first_parm_offset : 16;
+            stacksize    : 262144;
+            DllScanSupported:true;
+            use_function_relative_addresses : true
+          );
+
   implementation
 
 initialization
@@ -106,4 +167,12 @@ initialization
     {$endif WDOSX}
   {$endif WIN32}
 {$endif CPU86}
+
+{$ifdef CPUX86_64}
+  {$ifdef WIN64}
+    {$ifndef WDOSX}
+      set_source_info(system_x64_win64_info);
+    {$endif WDOSX}
+  {$endif WIN64}
+{$endif CPUX86_64}
 end.

+ 8 - 0
compiler/systems/t_win.pas

@@ -1619,4 +1619,12 @@ initialization
   RegisterRes(res_gnu_windres_info);
   RegisterTarget(system_i386_win32_info);
 {$endif i386}
+{$ifdef x86_64}
+  RegisterExternalLinker(system_x64_win64_info,TLinkerWin32);
+  RegisterImport(system_x86_64_win64,TImportLibWin32);
+  RegisterExport(system_x86_64_win64,TExportLibWin32);
+  RegisterDLLScanner(system_x86_64_win64,TDLLScannerWin32);
+  RegisterRes(res_gnu_windres_info);
+  RegisterTarget(system_x64_win64_info);
+{$endif x86_64}
 end.

+ 8 - 9
compiler/utils/mkx86reg.pp

@@ -343,9 +343,9 @@ begin
   openinc(numfile,fileprefix+'num.inc');
   openinc(stdfile,fileprefix+'std.inc');
   openinc(attfile,fileprefix+'att.inc');
+  openinc(intfile,fileprefix+'int.inc');
   if not(x86_64) then
     begin
-      openinc(intfile,fileprefix+'int.inc');
       openinc(nasmfile,fileprefix+'nasm.inc');
     end;
   openinc(stabfile,fileprefix+'stab.inc');
@@ -356,10 +356,10 @@ begin
   openinc(rnifile,fileprefix+'rni.inc');
   openinc(srifile,fileprefix+'sri.inc');
   openinc(arifile,fileprefix+'ari.inc');
+  openinc(irifile,fileprefix+'iri.inc');
   if not(x86_64) then
     begin
       openinc(nrifile,fileprefix+'nri.inc');
-      openinc(irifile,fileprefix+'iri.inc');
     end;
   first:=true;
   for i:=0 to regcount-1 do
@@ -369,9 +369,9 @@ begin
           writeln(numfile,',');
           writeln(stdfile,',');
           writeln(attfile,',');
+          writeln(intfile,',');
           if not(x86_64) then
             begin
-              writeln(intfile,',');
               writeln(nasmfile,',');
             end;
           writeln(stabfile,',');
@@ -381,9 +381,9 @@ begin
           writeln(rnifile,',');
           writeln(srifile,',');
           writeln(arifile,',');
+          writeln(irifile,',');
           if not(x86_64) then
             begin
-              writeln(irifile,',');
               writeln(nrifile,',');
             end;
         end
@@ -393,9 +393,9 @@ begin
       write(numfile,'tregister(',numbers[i],')');
       write(stdfile,'''',stdnames[i],'''');
       write(attfile,'''',attnames[i],'''');
+      write(intfile,'''',intnames[i],'''');
       if not(x86_64) then
         begin
-          write(intfile,'''',intnames[i],'''');
           write(nasmfile,'''',nasmnames[i],'''');
         end;
       write(stabfile,stabs[i]);
@@ -408,10 +408,9 @@ begin
       write(rnifile,regnumber_index[i]);
       write(srifile,std_regname_index[i]);
       write(arifile,att_regname_index[i]);
-
+      write(irifile,int_regname_index[i]);
       if not(x86_64) then
         begin
-          write(irifile,int_regname_index[i]);
           write(nrifile,nasm_regname_index[i]);
         end;
     end;
@@ -420,9 +419,9 @@ begin
   closeinc(numfile);
   closeinc(attfile);
   closeinc(stdfile);
+  closeinc(intfile);
   if not(x86_64) then
     begin
-      closeinc(intfile);
       closeinc(nasmfile);
     end;
   closeinc(stabfile);
@@ -433,10 +432,10 @@ begin
   closeinc(rnifile);
   closeinc(srifile);
   closeinc(arifile);
+  closeinc(irifile);
   if not(x86_64) then
     begin
       closeinc(nrifile);
-      closeinc(irifile);
     end;
   writeln('Done!');
   writeln(regcount,' registers procesed');

+ 6 - 0
compiler/x86/aasmcpu.pas

@@ -359,6 +359,7 @@ implementation
           OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_NONE,
           OT_BITS64,
           OT_NEAR,OT_FAR,OT_SHORT,
+          OT_NONE,
           OT_NONE
          ),
          (OT_NONE,
@@ -367,6 +368,7 @@ implementation
           OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_NONE,
           OT_BITS64,
           OT_NEAR,OT_FAR,OT_SHORT,
+          OT_NONE,
           OT_NONE
          ),
          (OT_NONE,
@@ -375,6 +377,7 @@ implementation
           OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_NONE,
           OT_BITS64,
           OT_NEAR,OT_FAR,OT_SHORT,
+          OT_NONE,
           OT_NONE
          )
        );
@@ -391,6 +394,7 @@ implementation
           OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_NONE,
           OT_BITS64,
           OT_NEAR,OT_FAR,OT_SHORT,
+          OT_NONE,
           OT_NONE
          ),
          (OT_NONE,
@@ -399,6 +403,7 @@ implementation
           OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_NONE,
           OT_BITS64,
           OT_NEAR,OT_FAR,OT_SHORT,
+          OT_NONE,
           OT_NONE
          ),
          (OT_NONE,
@@ -407,6 +412,7 @@ implementation
           OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_NONE,
           OT_BITS64,
           OT_NEAR,OT_FAR,OT_SHORT,
+          OT_NONE,
           OT_NONE
          )
       );

+ 119 - 47
compiler/i386/ag386int.pas → compiler/x86/agx86int.pas

@@ -22,7 +22,7 @@
 {
   This unit implements an asmoutput class for Intel syntax with Intel i386+
 }
-unit ag386int;
+unit agx86int;
 
 {$i fpcdefs.inc}
 
@@ -33,7 +33,7 @@ interface
       aasmbase,aasmtai,aasmcpu,assemble,cgutils;
 
     type
-      T386IntelAssembler = class(TExternalAssembler)
+      Tx86IntelAssembler = class(TExternalAssembler)
       private
         procedure WriteReference(var ref : treference);
         procedure WriteOper(const o:toper;s : topsize; opcode: tasmop;dest : boolean);
@@ -64,6 +64,13 @@ implementation
         '','','','','',''
       );
 
+      secnamesml64 : array[TAsmSectionType] of string[7] = ('',
+        '_TEXT','_DATE','_DATA','_BSS',
+        '','','','',
+        'idata$2','idata$4','idata$5','idata$6','idata$7','edata',
+        '',''
+      );
+
     function single2str(d : single) : string;
       var
          hs : string;
@@ -151,10 +158,10 @@ implementation
 
 
 {****************************************************************************
-                               T386IntelAssembler
+                               tx86IntelAssembler
  ****************************************************************************}
 
-    procedure T386IntelAssembler.WriteReference(var ref : treference);
+    procedure tx86IntelAssembler.WriteReference(var ref : treference);
       var
         first : boolean;
       begin
@@ -207,7 +214,7 @@ implementation
       end;
 
 
-    procedure T386IntelAssembler.WriteOper(const o:toper;s : topsize; opcode: tasmop;dest : boolean);
+    procedure tx86IntelAssembler.WriteOper(const o:toper;s : topsize; opcode: tasmop;dest : boolean);
       begin
         case o.typ of
           top_reg :
@@ -226,6 +233,7 @@ implementation
                       S_B : AsmWrite('byte ptr ');
                       S_W : AsmWrite('word ptr ');
                       S_L : AsmWrite('dword ptr ');
+                      S_Q : AsmWrite('qword ptr ');
                      S_IS : AsmWrite('word ptr ');
                      S_IL : AsmWrite('dword ptr ');
                      S_IQ : AsmWrite('qword ptr ');
@@ -245,6 +253,22 @@ implementation
                              AsmWrite('dword ptr ')
                             else
                              AsmWrite('word ptr ');
+{$ifdef x86_64}
+                     S_BQ : if dest then
+                             AsmWrite('qword ptr ')
+                            else
+                             AsmWrite('byte ptr ');
+                     S_WQ : if dest then
+                             AsmWrite('qword ptr ')
+                            else
+                             AsmWrite('word ptr ');
+                     S_LQ : if dest then
+                             AsmWrite('qword ptr ')
+                            else
+                             AsmWrite('dword ptr ');
+                     S_XMM: AsmWrite('xmmword ptr ');
+
+{$endif x86_64}
                      end;
                    end;
                   WriteReference(o.ref^);
@@ -265,12 +289,12 @@ implementation
                 end;
             end;
           else
-            internalerror(10001);
+            internalerror(2005060510);
         end;
       end;
 
 
-    procedure T386IntelAssembler.WriteOper_jmp(const o:toper;s : topsize);
+    procedure tx86IntelAssembler.WriteOper_jmp(const o:toper;s : topsize);
     begin
       case o.typ of
         top_reg :
@@ -287,7 +311,11 @@ implementation
                     if s=S_FAR then
                       AsmWrite('far ptr ')
                     else
+{$ifdef x86_64}
+                      AsmWrite('qword ptr ');
+{$else x86_64}
                       AsmWrite('dword ptr ');
+{$endif x86_64}
                   end;
                 WriteReference(o.ref^);
               end
@@ -302,7 +330,7 @@ implementation
               end;
           end;
         else
-          internalerror(10001);
+          internalerror(2005060511);
       end;
     end;
 
@@ -315,9 +343,9 @@ implementation
 
     const
       ait_const2str : array[ait_const_128bit..ait_const_indirect_symbol] of string[20]=(
-        #9'FIXME128',#9'FIXME64',#9'DD'#9,#9'DW'#9,#9'DB'#9,
+        #9''#9,#9'DQ'#9,#9'DD'#9,#9'DW'#9,#9'DB'#9,
         #9'FIXMESLEB',#9'FIXEMEULEB',
-        #9'RVA'#9,#9'FIXMEINDIRECT'#9
+        #9'DD RVA'#9,#9'FIXMEINDIRECT'#9
       );
 
     Function PadTabs(const p:string;addch:char):string;
@@ -339,7 +367,7 @@ implementation
        PadTabs:=s+#9;
     end;
 
-    procedure T386IntelAssembler.WriteTree(p:TAAsmoutput);
+    procedure tx86IntelAssembler.WriteTree(p:TAAsmoutput);
     const
       regallocstr : array[tregalloctype] of string[10]=(' allocated',' released',' sync',' resized');
       tempallocstr : array[boolean] of string[10]=(' released',' allocated');
@@ -444,14 +472,24 @@ implementation
              end;
 
        ait_section : begin
-                       if LasTSecType<>sec_none then
-                        AsmWriteLn('_'+secnames[LasTSecType]+#9#9'ENDS');
                        if tai_section(hp).sectype<>sec_none then
                         begin
-                          AsmLn;
-                          AsmWriteLn('_'+secnames[tai_section(hp).sectype]+#9#9+
-                                     'SEGMENT'#9'PARA PUBLIC USE32 '''+
-                                     secnames[tai_section(hp).sectype]+'''');
+                          if aktoutputformat=as_x86_64_masm then
+                            begin
+                              if LasTSecType<>sec_none then
+                                AsmWriteLn(secnamesml64[LasTSecType]+#9#9'ENDS');
+                              AsmLn;
+                              AsmWriteLn(secnamesml64[tai_section(hp).sectype]+#9+'SEGMENT')
+                            end
+                          else
+                            begin
+                              if LasTSecType<>sec_none then
+                                AsmWriteLn('_'+secnames[LasTSecType]+#9#9'ENDS');
+                              AsmLn;
+                              AsmWriteLn('_'+secnames[tai_section(hp).sectype]+#9#9+
+                                         'SEGMENT'#9'PARA PUBLIC USE32 '''+
+                                         secnames[tai_section(hp).sectype]+'''');
+                            end;
                         end;
                        LasTSecType:=tai_section(hp).sectype;
                      end;
@@ -462,11 +500,12 @@ implementation
                        if tai_align(hp).aligntype>1 then
                          AsmWriteLn(#9'ALIGN '+tostr(tai_align(hp).aligntype));
                      end;
-     ait_datablock : begin
-                       if tai_datablock(hp).is_global then
-                         AsmWriteLn(#9'PUBLIC'#9+tai_datablock(hp).sym.name);
-                       AsmWriteLn(PadTabs(tai_datablock(hp).sym.name,#0)+'DB'#9+tostr(tai_datablock(hp).size)+' DUP(?)');
-                     end;
+           ait_datablock :
+             begin
+               if tai_datablock(hp).is_global then
+                 AsmWriteLn(#9'PUBLIC'#9+tai_datablock(hp).sym.name);
+               AsmWriteLn(PadTabs(tai_datablock(hp).sym.name,#0)+'DB'#9+tostr(tai_datablock(hp).size)+' DUP(?)');
+             end;
            ait_const_uleb128bit,
            ait_const_sleb128bit,
            ait_const_128bit,
@@ -661,13 +700,16 @@ implementation
                        else
                         prefix:= '';
                        if (aktoutputformat = as_i386_wasm) and
-                        (taicpu(hp).opsize=S_W) and
-                        (taicpu(hp).opcode=A_PUSH) and
-                        (taicpu(hp).oper[0]^.typ=top_const) then
-                        begin
-                          AsmWriteln(#9#9'DB 66h,68h ; pushw imm16');
-                          AsmWrite(#9#9'DW');
-                        end
+                         (taicpu(hp).opsize=S_W) and
+                         (taicpu(hp).opcode=A_PUSH) and
+                         (taicpu(hp).oper[0]^.typ=top_const) then
+                         begin
+                           AsmWriteln(#9#9'DB 66h,68h ; pushw imm16');
+                           AsmWrite(#9#9'DW');
+                         end
+                       else if (aktoutputformat=as_x86_64_masm) and
+                         (taicpu(hp).opcode=A_MOVQ) then
+                         AsmWrite(#9#9'mov')
                        else
                          AsmWrite(#9#9+prefix+std_op2str[taicpu(hp).opcode]+cond2str[taicpu(hp).condition]+suffix);
                        if taicpu(hp).ops<>0 then
@@ -751,22 +793,27 @@ ait_stab_function_name : ;
       begin
         if tasmsymbol(p).defbind=AB_EXTERNAL then
           begin
-            if (aktoutputformat in [as_i386_masm,as_i386_wasm]) then
-              currentasmlist.AsmWriteln(#9'EXTRN'#9+p.name
-                +': NEAR')
-            else
-              currentasmlist.AsmWriteln(#9'EXTRN'#9+p.name);
+            case aktoutputformat of
+              as_i386_masm,as_i386_wasm:
+                currentasmlist.AsmWriteln(#9'EXTRN'#9+p.name
+                  +': NEAR');
+              as_x86_64_masm:
+                currentasmlist.AsmWriteln(#9'EXTRN'#9+p.name
+                  +': PROC');
+              else
+                currentasmlist.AsmWriteln(#9'EXTRN'#9+p.name);
+            end;
           end;
       end;
 
-    procedure T386IntelAssembler.WriteExternals;
+    procedure tx86IntelAssembler.WriteExternals;
       begin
         currentasmlist:=self;
         objectlibrary.symbolsearch.foreach_static(@writeexternal,nil);
       end;
 
 
-    function t386intelassembler.DoAssemble : boolean;
+    function tx86intelassembler.DoAssemble : boolean;
     var f : file;
     begin
       DoAssemble:=Inherited DoAssemble;
@@ -788,22 +835,25 @@ ait_stab_function_name : ;
     end;
 
 
-    procedure T386IntelAssembler.WriteAsmList;
+    procedure tx86IntelAssembler.WriteAsmList;
     begin
 {$ifdef EXTDEBUG}
       if assigned(current_module.mainsource) then
        comment(v_info,'Start writing intel-styled assembler output for '+current_module.mainsource^);
 {$endif}
       LasTSecType:=sec_none;
-      AsmWriteLn(#9'.386p');
-      { masm 6.11 does not seem to like LOCALS PM }
-      if (aktoutputformat = as_i386_tasm) then
+      if aktoutputformat<>as_x86_64_masm then
         begin
-          AsmWriteLn(#9'LOCALS '+target_asm.labelprefix);
+          AsmWriteLn(#9'.386p');
+          { masm 6.11 does not seem to like LOCALS PM }
+          if (aktoutputformat = as_i386_tasm) then
+            begin
+              AsmWriteLn(#9'LOCALS '+target_asm.labelprefix);
+            end;
+          AsmWriteLn('DGROUP'#9'GROUP'#9'_BSS,_DATA');
+          AsmWriteLn(#9'ASSUME'#9'CS:_CODE,ES:DGROUP,DS:DGROUP,SS:DGROUP');
+          AsmLn;
         end;
-      AsmWriteLn('DGROUP'#9'GROUP'#9'_BSS,_DATA');
-      AsmWriteLn(#9'ASSUME'#9'CS:_CODE,ES:DGROUP,DS:DGROUP,SS:DGROUP');
-      AsmLn;
 
       WriteExternals;
 
@@ -816,6 +866,11 @@ ait_stab_function_name : ;
       WriteTree(rttilist);
       WriteTree(resourcestringlist);
       WriteTree(bsssegment);
+      Writetree(importssection);
+      { exports are written by DLLTOOL
+        if we use it so don't insert it twice (PM) }
+      if not UseDeffileForExports and assigned(exportssection) then
+        Writetree(exportssection);
 
       AsmWriteLn(#9'END');
       AsmLn;
@@ -868,8 +923,25 @@ ait_stab_function_name : ;
             comment : '; ';
           );
 
+       as_x86_64_masm_info : tasminfo =
+          (
+            id     : as_x86_64_masm;
+            idtxt  : 'MASM';
+            asmbin : 'ml64';
+            asmcmd : '/c /Cp $ASM /Fo$OBJ';
+            supported_target : system_any; { what should I write here ?? }
+            flags : [af_allowdirect,af_needar];
+            labelprefix : '@@';
+            comment : '; ';
+          );
+
 initialization
-  RegisterAssembler(as_i386_tasm_info,T386IntelAssembler);
-  RegisterAssembler(as_i386_masm_info,T386IntelAssembler);
-  RegisterAssembler(as_i386_wasm_info,T386IntelAssembler);
+{$ifdef x86_64}
+  RegisterAssembler(as_x86_64_masm_info,tx86IntelAssembler);
+{$endif x86_64}
+{$ifdef i386}
+  RegisterAssembler(as_i386_tasm_info,tx86IntelAssembler);
+  RegisterAssembler(as_i386_masm_info,tx86IntelAssembler);
+  RegisterAssembler(as_i386_wasm_info,tx86IntelAssembler);
+{$endif i386}
 end.

+ 4 - 2
compiler/x86/itcpugas.pas

@@ -49,7 +49,8 @@ interface
        's','l','t','v','x',
        'd',
        '','','',
-       't'
+       't',
+       ''
      );
 {$else x86_64}
      gas_opsize2str : array[topsize] of string[2] = ('',
@@ -58,7 +59,8 @@ interface
        's','l','t','v','',
        'd',
        '','','',
-       't'
+       't',
+       ''
      );
 {$endif x86_64}
 

+ 10 - 0
compiler/x86/itx86int.pas

@@ -39,6 +39,15 @@ implementation
       cpubase;
 
     const
+    {$ifdef x86_64}
+      int_regname_table : array[tregisterindex] of string[7] = (
+        {$i r8664int.inc}
+      );
+
+      int_regname_index : array[tregisterindex] of tregisterindex = (
+        {$i r8664iri.inc}
+      );
+    {$else x86_64}
       int_regname_table : array[tregisterindex] of string[7] = (
         {$i r386int.inc}
       );
@@ -46,6 +55,7 @@ implementation
       int_regname_index : array[tregisterindex] of tregisterindex = (
         {$i r386iri.inc}
       );
+    {$endif x86_64}
 
 
     function findreg_by_intname(const s:string):byte;

+ 101 - 2
compiler/x86/nx86cnv.pas

@@ -198,14 +198,113 @@ implementation
          hregister : tregister;
          l1,l2 : tasmlabel;
          signtested : boolean;
+         hreg : tregister;
+         op : tasmop;
       begin
-      {
+{$ifdef x86_64}
         if use_sse(resulttype.def) then
           begin
+            if is_double(resulttype.def) then
+              op:=A_CVTSI2SD
+            else if is_single(resulttype.def) then
+              op:=A_CVTSI2SS
+            else
+              internalerror(200506061);
+
+            location_reset(location,LOC_MMREGISTER,def_cgsize(resulttype.def));
+            location.register:=cg.getmmregister(exprasmlist,def_cgsize(resulttype.def));
+            if (left.location.loc=LOC_REGISTER) and (torddef(left.resulttype.def).typ=u64bit) then
+              begin
+{$ifdef cpu64bit}
+                emit_const_reg(A_BT,S_Q,63,left.location.register);
+{$else cpu64bit}
+                emit_const_reg(A_BT,S_L,31,left.location.register64.reghi);
+{$endif cpu64bit}
+                signtested:=true;
+              end
+            else
+              signtested:=false;
+
+            case torddef(left.resulttype.def).typ of
+              u64bit:
+                begin
+                   { unsigned 64 bit ints are harder to handle:
+                     we load bits 0..62 and then check bit 63:
+                     if it is 1 then we add $80000000 000000000
+                     as double                                  }
+                   objectlibrary.getdatalabel(l1);
+                   objectlibrary.getlabel(l2);
 
+                   if not(signtested) then
+                     begin
+                       inc(left.location.reference.offset,4);
+                       emit_const_ref(A_BT,S_L,31,left.location.reference);
+                       dec(left.location.reference.offset,4);
+                     end;
+
+                   exprasmlist.concat(taicpu.op_ref_reg(op,S_Q,left.location.reference,location.register));
+
+                   cg.a_jmp_flags(exprasmlist,F_NC,l2);
+                   Consts.concat(Tai_label.Create(l1));
+                   reference_reset_symbol(href,l1,0);
+
+                   { I got these constant from a test program (FK) }
+                   if is_double(resulttype.def) then
+                     begin
+                       { double (2^64) }
+                       consts.concat(Tai_const.Create_32bit(0));
+                       consts.concat(Tai_const.Create_32bit($43f00000));
+                       exprasmlist.concat(taicpu.op_ref_reg(A_ADDSD,S_NO,href,location.register));
+                     end
+                   else if is_single(resulttype.def) then
+                     begin
+                       { single(2^64) }
+                       consts.concat(Tai_const.Create_32bit($5f800000));
+                       exprasmlist.concat(taicpu.op_ref_reg(A_ADDSS,S_NO,href,location.register));
+                     end
+                   else
+                     internalerror(200506071);
+                   cg.a_label(exprasmlist,l2);
+                end
+              else
+                begin
+                  if (left.resulttype.def.size=4) and not(torddef(left.resulttype.def).typ=u32bit) then
+                    begin
+                      case left.location.loc of
+                        LOC_CREFERENCE,
+                        LOC_REFERENCE :
+                          exprasmList.concat(Taicpu.op_ref_reg(op,S_L,left.location.reference,location.register));
+                        LOC_CREGISTER,
+                        LOC_REGISTER :
+                          exprasmList.concat(Taicpu.op_reg_reg(op,S_L,left.location.register,location.register));
+                        else
+                          internalerror(200506072);
+                      end;
+                    end
+                  else if left.resulttype.def.size=8 then
+                    begin
+                      case left.location.loc of
+                        LOC_CREFERENCE,
+                        LOC_REFERENCE :
+                          exprasmList.concat(Taicpu.op_ref_reg(op,S_Q,left.location.reference,location.register));
+                        LOC_CREGISTER,
+                        LOC_REGISTER :
+                          exprasmList.concat(Taicpu.op_reg_reg(op,S_Q,left.location.register,location.register));
+                        else
+                          internalerror(200506073);
+                      end;
+                    end
+                  else
+                    begin
+                      hreg:=cg.getintregister(exprasmlist,OS_64);
+                      cg.a_load_loc_reg(exprasmlist,OS_64,left.location,hreg);
+                      exprasmList.concat(Taicpu.Op_reg_reg(op,S_NO,hreg,location.register));
+                    end
+                end;
+            end;
           end
         else
-      }
+{$endif x86_64}
           begin
             location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
             if (left.location.loc=LOC_REGISTER) and (torddef(left.resulttype.def).typ=u64bit) then

+ 42 - 9
compiler/x86/nx86inl.pas

@@ -64,11 +64,13 @@ implementation
       systems,
       globals,
       cutils,verbose,
+      symconst,
       defutil,
-      aasmtai,aasmcpu,
+      aasmbase,aasmtai,aasmcpu,
+      symdef,
       cgbase,pass_2,
       cpuinfo,cpubase,paramgr,
-      nbas,ncon,ncal,ncnv,nld,
+      nbas,ncon,ncal,ncnv,nld,ncgutil,
       cga,cgutils,cgx86,cgobj;
 
 
@@ -96,10 +98,18 @@ implementation
       end;
 
      function tx86inlinenode.first_abs_real : tnode;
-      begin
-        expectloc:=LOC_FPUREGISTER;
+       begin
+         if use_sse(resulttype.def) then
+           begin
+             expectloc:=LOC_MMREGISTER;
+             registersmm:=max(left.registersmm,1);
+           end
+         else
+           begin
+             expectloc:=LOC_FPUREGISTER;
+             registersfpu:=max(left.registersfpu,1);
+          end;
         registersint:=left.registersint;
-        registersfpu:=max(left.registersfpu,1);
 {$ifdef SUPPORT_MMX}
         registersmmx:=left.registersmmx;
 {$endif SUPPORT_MMX}
@@ -190,8 +200,8 @@ implementation
                   def_cgsize(left.resulttype.def),
                   left.location.reference,location.register);
              end
-         else
-            internalerror(309991);
+           else
+             internalerror(309991);
          end;
        end;
 
@@ -203,10 +213,33 @@ implementation
          emit_none(A_FPATAN,S_NO);
        end;
 
+
      procedure tx86inlinenode.second_abs_real;
+       var
+         href : treference;
        begin
-         load_fpu_location;
-         emit_none(A_FABS,S_NO);
+         if use_sse(resulttype.def) then
+           begin
+             secondpass(left);
+             location_force_mmregscalar(exprasmlist,left.location,false);
+             location:=left.location;
+             case tfloatdef(resulttype.def).typ of
+               s32real:
+                 reference_reset_symbol(href,
+                   objectlibrary.newasmsymbol('FPC_ABSMASK_SINGLE',AB_EXTERNAL,AT_DATA),0);
+               s64real:
+                 reference_reset_symbol(href,
+                   objectlibrary.newasmsymbol('FPC_ABSMASK_DOUBLE',AB_EXTERNAL,AT_DATA),0);
+               else
+                 internalerror(200506081);
+             end;
+             exprasmlist.concat(taicpu.op_ref_reg(A_ANDPS,S_XMM,href,location.register))
+           end
+         else
+           begin
+             load_fpu_location;
+             emit_none(A_FABS,S_NO);
+           end;
        end;
 
 

+ 1 - 1
compiler/x86/x86ins.dat

@@ -3415,6 +3415,6 @@ reg32,imm               \321\10\xB8\41                  X86_64
 reg64,mem             \321\301\1\x63\110              X86_64
 reg64,reg32           \321\301\1\x63\110              X86_64
 
-[CDO,cqto]
+[CQO,cqto]
 (Ch_MRAX, Ch_WRDX, Ch_None)
 void                  \321\1\x99                      X86_64

+ 2 - 1
compiler/x86_64/cpubase.inc

@@ -33,7 +33,8 @@ type
     S_FS,S_FL,S_FX,S_FV,S_FXX,
     S_MD,
     S_NEAR,S_FAR,S_SHORT,
-    S_T
+    S_T,
+    S_XMM
   );
 
 {*****************************************************************************

+ 3 - 0
compiler/x86_64/cputarg.pas

@@ -50,6 +50,9 @@ implementation
              Assemblers
 **************************************}
 
+    {$ifndef NOAGX86_64INT}
+      ,agx86int
+    {$endif}
     {$ifndef NOAGX86_64ATT}
       ,agx86att
     {$endif}

+ 1 - 1
compiler/x86_64/nx64mat.pas

@@ -113,7 +113,7 @@ implementation
             if torddef(left.resulttype.def).typ=u64bit then
               emit_reg_reg(A_XOR,S_Q,NR_RDX,NR_RDX)
             else
-              emit_none(A_CDO,S_NO);
+              emit_none(A_CQO,S_NO);
 
             {Division depends on the right type.}
             if Torddef(right.resulttype.def).typ=u64bit then

+ 126 - 0
compiler/x86_64/r8664int.inc

@@ -0,0 +1,126 @@
+{ don't edit, this file is generated from x86reg.dat }
+'INVALID',
+'al',
+'ah',
+'ax',
+'eax',
+'rax',
+'cl',
+'ch',
+'cx',
+'ecx',
+'rcx',
+'dl',
+'dh',
+'dx',
+'edx',
+'rdx',
+'bl',
+'bh',
+'bx',
+'ebx',
+'rbx',
+'sil',
+'si',
+'esi',
+'rsi',
+'dil',
+'di',
+'edi',
+'rdi',
+'bpl',
+'bp',
+'ebp',
+'rbp',
+'spl',
+'sp',
+'esp',
+'rsp',
+'r8',
+'r8b',
+'r8w',
+'r8d',
+'r9',
+'r9b',
+'r9w',
+'r9d',
+'r10',
+'r10b',
+'r10w',
+'r10d',
+'r11',
+'r11b',
+'r11w',
+'r11d',
+'r12',
+'r12b',
+'r12w',
+'r12d',
+'r13',
+'r13b',
+'r13w',
+'r13d',
+'r14',
+'r14b',
+'r14w',
+'r14d',
+'r15',
+'r15b',
+'r15w',
+'r15d',
+'rip',
+'eip',
+'cs',
+'ds',
+'es',
+'ss',
+'fs',
+'gs',
+'dr0',
+'dr1',
+'dr2',
+'dr3',
+'dr6',
+'dr7',
+'cr0',
+'cr2',
+'cr3',
+'cr4',
+'tr3',
+'tr4',
+'tr5',
+'tr6',
+'tr7',
+'st(0)',
+'st(1)',
+'st(2)',
+'st(3)',
+'st(4)',
+'st(5)',
+'st(6)',
+'st(7)',
+'st',
+'mm0',
+'mm1',
+'mm2',
+'mm3',
+'mm4',
+'mm5',
+'mm6',
+'mm7',
+'xmm0',
+'xmm1',
+'xmm2',
+'xmm3',
+'xmm4',
+'xmm5',
+'xmm6',
+'xmm7',
+'xmm8',
+'xmm9',
+'xmm10',
+'xmm11',
+'xmm12',
+'xmm13',
+'xmm14',
+'xmm15'

+ 126 - 0
compiler/x86_64/r8664iri.inc

@@ -0,0 +1,126 @@
+{ don't edit, this file is generated from x86reg.dat }
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0

+ 1 - 1
compiler/x86_64/x8664int.inc

@@ -565,5 +565,5 @@
 'movsldup',
 'movabs',
 'movsxd',
-'cdo'
+'cqo'
 );

+ 1 - 1
compiler/x86_64/x8664op.inc

@@ -565,5 +565,5 @@ A_MOVSHDUP,
 A_MOVSLDUP,
 A_MOVABS,
 A_MOVSXD,
-A_CDO
+A_CQO
 );

+ 1 - 1
compiler/x86_64/x8664tab.inc

@@ -11481,7 +11481,7 @@
     flags   : if_x86_64
   ),
   (
-    opcode  : A_CDO;
+    opcode  : A_CQO;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none);
     code    : #209#1#153;