Jelajahi Sumber

+ started to implement x32 support (x86-64 with 32 bit addresses/pointers)

florian 12 tahun lalu
induk
melakukan
9caacc624e

+ 17 - 0
compiler/fpcdefs.inc

@@ -233,6 +233,23 @@
   {$define cpurefshaveindexreg}
 {$endif aarch64}
 
+{$ifdef x32}
+  {$define x86}
+  {$define cpuflags}
+  {$define cpu64bitalu}
+  {$define cpu32bitaddr}
+  {$define cpuextended}
+  {$define cpufloat128}
+  {$define cputargethasfixedstack}
+  {$define cpumm}
+  {$define cpurox}
+  {$define cpurefshaveindexreg}
+  {$define SUPPORT_SAFECALL}
+  {$define NOTARGETFREEBSD}
+  {$define NOTARGETWIN}
+  {$define NOTARGETSUNOS}
+{$endif x32}
+
 {$IFDEF MACOS}
 {$DEFINE USE_FAKE_SYSUTILS}
 {$ENDIF MACOS}

+ 1 - 1
compiler/globals.pas

@@ -430,7 +430,7 @@ interface
         optimizecputype : cpu_armv3;
         fputype : fpu_fpa;
   {$endif arm}
-  {$ifdef x86_64}
+  {$if defined(x86_64) or defined(x32)}
         cputype : cpu_athlon64;
         optimizecputype : cpu_athlon64;
         fputype : fpu_sse64;

+ 1 - 1
compiler/globtype.pas

@@ -492,7 +492,7 @@ interface
        { Default calling convention }
 {$if defined(i8086)}
        pocall_default = pocall_pascal;
-{$elseif defined(i386) or defined(x86_64)}
+{$elseif defined(i386) or defined(x86_64) or defined(x32)}
        pocall_default = pocall_register;
 {$else}
        pocall_default = pocall_stdcall;

+ 1 - 1
compiler/nadd.pas

@@ -1073,7 +1073,7 @@ implementation
         else
           resultrealdef:=pbestrealtype^;
   {$endif i386 or i8086}
-  {$ifdef x86_64}
+  {$if defined(x86_64) or defined(x32)}
         { x86-64 has no x87 only mode, so use always double as default }
         resultrealdef:=s64floattype;
   {$endif x86_6}

+ 2 - 2
compiler/ogbase.pas

@@ -47,7 +47,7 @@ interface
       TObjRelocationType = (
          { Relocation to absolute address }
          RELOC_ABSOLUTE,
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
          { 32bit Relocation to absolute address }
          RELOC_ABSOLUTE32,
          { 64 bit coff only }
@@ -88,7 +88,7 @@ interface
          RELOC_RAW
       );
 
-{$ifndef x86_64}
+{$if not(defined(x86_64) or defined(x32))}
     const
       RELOC_ABSOLUTE32 = RELOC_ABSOLUTE;
 {$endif x86_64}

+ 10 - 10
compiler/ogcoff.pas

@@ -265,7 +265,7 @@ interface
        COFF_OPT_MAGIC   = $10b;
        TLSDIR_SIZE      = $18;
 {$endif arm}
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
        COFF_MAGIC       = $8664;
        COFF_OPT_MAGIC   = $20b;
        TLSDIR_SIZE      = $28;
@@ -381,7 +381,7 @@ implementation
        PE_DATADIR_IMPORTADDRESSTABLE = 12;
        PE_DATADIR_DELAYIMPORT = 13;
 
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
        IMAGE_REL_AMD64_ABSOLUTE    = $0000;  { Reference is absolute, no relocation is necessary }
        IMAGE_REL_AMD64_ADDR64      = $0001;  { 64-bit address (VA). }
        IMAGE_REL_AMD64_ADDR32      = $0002;  { 32-bit address (VA). }
@@ -912,7 +912,7 @@ const pemagic : array[0..3] of byte = (
                       internalerror(200606085);  { offset overflow }
                   end;
 {$endif arm}
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                 { 64 bit coff only }
                 RELOC_RELATIVE_1:
                   begin
@@ -1288,7 +1288,7 @@ const pemagic : array[0..3] of byte = (
               RELOC_SECREL32 :
                 rel.reloctype:=IMAGE_REL_I386_SECREL32;
 {$endif i386}
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
               RELOC_NONE :
                 rel.reloctype:=IMAGE_REL_AMD64_ABSOLUTE;
               RELOC_RELATIVE :
@@ -1473,7 +1473,7 @@ const pemagic : array[0..3] of byte = (
            header.syms:=symidx;
            if win32 then
              begin
-{$ifndef x86_64}
+{$if not(defined(x86_64) or defined(x32))}
                header.flag:=PE_FILE_32BIT_MACHINE or
                             PE_FILE_LINE_NUMS_STRIPPED or PE_FILE_LOCAL_SYMS_STRIPPED;
 {$else x86_64}
@@ -1606,7 +1606,7 @@ const pemagic : array[0..3] of byte = (
              IMAGE_REL_I386_SECREL32 :
                rel_type:=RELOC_SECREL32;
 {$endif i386}
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
              IMAGE_REL_AMD64_ABSOLUTE:
                rel_type:=RELOC_NONE;
              IMAGE_REL_AMD64_REL32:
@@ -1886,7 +1886,7 @@ const pemagic : array[0..3] of byte = (
                  begin
                    if (Pos('.edata',secname)=1) or
                       (Pos('.rsrc',secname)=1) or
-{$ifndef x86_64}
+{$if not(defined(x86_64) or defined(x32))}
                       (Pos('.pdata',secname)=1) or
 {$endif}
                       (Pos('.fpc',secname)=1) then
@@ -2612,7 +2612,7 @@ const pemagic : array[0..3] of byte = (
               textobjsection.writezeros(align_aword(textobjsection.size,16)-textobjsection.size);
               result:=internalobjdata.SymbolDefine('_'+amangledname,AB_GLOBAL,AT_FUNCTION);
               textobjsection.write(jmpopcode,sizeof(jmpopcode));
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
               textobjsection.writereloc_internal(idata5objsection,idata5objsection.size,4,RELOC_RELATIVE);
 {$else}
               textobjsection.writereloc_internal(idata5objsection,idata5objsection.size,4,RELOC_ABSOLUTE32);
@@ -3012,7 +3012,7 @@ const pemagic : array[0..3] of byte = (
             dollarsign: '$';
           );
 {$endif i386}
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
     const
        as_x86_64_pecoff_info : tasminfo =
           (
@@ -3069,7 +3069,7 @@ initialization
   RegisterAssembler(as_i386_pecoffwdosx_info,TPECoffAssembler);
   RegisterAssembler(as_i386_pecoffwince_info,TPECoffAssembler);
 {$endif i386}
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
   RegisterAssembler(as_x86_64_pecoff_info,TPECoffAssembler);
 {$endif x86_64}
 {$ifdef arm}

+ 3 - 3
compiler/ogelf.pas

@@ -711,7 +711,7 @@ implementation
         ObjRelocations.Add(reloc);
         if reltype=RELOC_RELATIVE then
 { ARM does not require this adjustment, other CPUs must be checked }
-{$if defined(i386) or defined(x86_64)}
+{$if defined(i386) or defined(x86_64) or defined(x32)}
           dec(offset,len)
 {$endif i386 or x86_64}
         else if reltype<>RELOC_ABSOLUTE then
@@ -847,7 +847,7 @@ implementation
            symaddr:=p.address;
            { Local ObjSymbols can be resolved already or need a section reloc }
            if (p.bind=AB_LOCAL) and
-              (reltype in [RELOC_RELATIVE,RELOC_ABSOLUTE{$ifdef x86_64},RELOC_ABSOLUTE32{$endif x86_64}]) then
+              (reltype in [RELOC_RELATIVE,RELOC_ABSOLUTE{$if defined(x86_64) or defined(x32)},RELOC_ABSOLUTE32{$endif x86_64}]) then
              begin
                { For a reltype relocation in the same section the
                  value can be calculated }
@@ -875,7 +875,7 @@ implementation
         if assigned(objreloc) then
           begin
             objreloc.size:=len;
-            if reltype in [RELOC_RELATIVE{$ifdef x86},RELOC_PLT32{$endif}{$ifdef x86_64},RELOC_GOTPCREL{$endif}] then
+            if reltype in [RELOC_RELATIVE{$ifdef x86},RELOC_PLT32{$endif}{$if defined(x86_64) or defined(x32)},RELOC_GOTPCREL{$endif}] then
               dec(data,len);
             if ElfTarget.relocs_use_addend then
               begin

+ 1 - 1
compiler/ogmacho.pas

@@ -282,7 +282,7 @@ implementation
             symaddr:=p.address;
             { Local ObjSymbols can be resolved already or need a section reloc }
             if (p.bind=AB_LOCAL) and
-               (reltype in [RELOC_RELATIVE,RELOC_ABSOLUTE{$ifdef x86_64},RELOC_ABSOLUTE32{$endif x86_64}]) then
+               (reltype in [RELOC_RELATIVE,RELOC_ABSOLUTE{$if defined(x86_64) or defined(x32)},RELOC_ABSOLUTE32{$endif x86_64}]) then
               begin
                 { For a reltype relocation in the same section the value can be calculated }
                 if (p.objsection=CurrObjSec) and

+ 5 - 5
compiler/options.pas

@@ -393,7 +393,7 @@ begin
 {$ifdef i386}
       '3',
 {$endif}
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
       '4',
 {$endif}
 {$ifdef m68k}
@@ -2801,7 +2801,7 @@ begin
   def_system_macro('FPC_HAS_UNICODESTRING');
   def_system_macro('FPC_RTTI_PACKSET1');
   def_system_macro('FPC_HAS_CPSTRING');
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
   def_system_macro('FPC_HAS_RIP_RELATIVE');
 {$endif x86_64}
   def_system_macro('FPC_HAS_CEXTENDED');
@@ -3329,13 +3329,13 @@ if (target_info.abi = abi_eabihf) then
 {$endif}
       def_system_macro('FPC_HAS_TYPE_SINGLE');
       def_system_macro('FPC_HAS_TYPE_DOUBLE');
-{$if not defined(i386) and not defined(x86_64) and not defined(i8086)}
+{$if not defined(i386) and not defined(x86_64) and not defined(i8086) and not defined(x32)}
       def_system_macro('FPC_INCLUDE_SOFTWARE_INT64_TO_DOUBLE');
 {$endif}
 {$if defined(m68k)}
       def_system_macro('FPC_INCLUDE_SOFTWARE_LONGWORD_TO_DOUBLE');
 {$endif}
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
 {$ifndef FPC_SUPPORT_X87_TYPES_ON_WIN64}
       { normally, win64 doesn't support the legacy fpu }
       if target_info.system=system_x86_64_win64 then
@@ -3364,7 +3364,7 @@ if (target_info.abi = abi_eabihf) then
 {$endif ARM}
 
 { inline bsf/bsr implementation }
-{$if defined(x86) or defined(x86_64)}
+{$if defined(x86) or defined(x86_64) or defined(x32)}
   def_system_macro('FPC_HAS_INTERNAL_BSF');
   def_system_macro('FPC_HAS_INTERNAL_BSR');
 {$endif}

+ 1 - 1
compiler/parabase.pas

@@ -105,7 +105,7 @@ unit parabase;
 
        tvarargsparalist = class(tparalist)
           varargsinfo : set of tvarargsinfo;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
           { x86_64 requires %al to contain the no. SSE regs passed }
           mmregsused  : longint;
 {$endif x86_64}

+ 6 - 0
compiler/pp.pas

@@ -153,6 +153,12 @@ program pp;
   {$endif CPUDEFINED}
   {$define CPUDEFINED}
 {$endif AARCH64}
+{$ifdef X32}
+  {$ifdef CPUDEFINED}
+    {$fatal ONLY one of the switches for the CPU type must be defined}
+  {$endif CPUDEFINED}
+  {$define CPUDEFINED}
+{$endif X32}
 {$ifndef CPUDEFINED}
   {$fatal A CPU type switch must be defined}
 {$endif CPUDEFINED}

+ 77 - 0
compiler/ppx32.lpi

@@ -0,0 +1,77 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <MainUnitHasUsesSectionForAllUnits Value="False"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <MainUnitHasTitleStatement Value="False"/>
+        <LRSInOutputDirectory Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <Title Value="ppcx32"/>
+    </General>
+    <BuildModes Count="1">
+      <Item1 Name="default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <DestinationDirectory Value="$(TestDir)\publishedproject\"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="pp.pas"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="pp"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="x86\aasmcpu.pas"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="aasmcpu"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <PathDelim Value="\"/>
+    <Target>
+      <Filename Value="x32\pp"/>
+    </Target>
+    <SearchPaths>
+      <IncludeFiles Value="x86_64"/>
+      <OtherUnitFiles Value="x86_64;x86;systems"/>
+      <UnitOutputDirectory Value="x86_64\lazbuild"/>
+    </SearchPaths>
+    <Parsing>
+      <SyntaxOptions>
+        <CStyleOperator Value="False"/>
+        <AllowLabel Value="False"/>
+        <CPPInline Value="False"/>
+        <UseAnsiStrings Value="False"/>
+      </SyntaxOptions>
+    </Parsing>
+    <Other>
+      <Verbosity>
+        <ShowWarn Value="False"/>
+        <ShowNotes Value="False"/>
+        <ShowHints Value="False"/>
+      </Verbosity>
+      <ConfigFile>
+        <StopAfterErrCount Value="50"/>
+      </ConfigFile>
+      <CustomOptions Value="-dx32"/>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+</CONFIG>

+ 1 - 1
compiler/psub.pas

@@ -940,7 +940,7 @@ implementation
       begin
         tg:=tgobjclass.create;
 
-{$if defined(i386) or defined(x86_64) or defined(arm)}
+{$if defined(i386) or defined(x86_64) or defined(arm) or defined(x32)}
 {$if defined(arm)}
         { frame and stack pointer must be always the same on arm thumb so it makes no
           sense to fiddle with a frame pointer }

+ 1 - 1
compiler/regvars.pas

@@ -260,7 +260,7 @@ implementation
                        {$error fixme x86 fpuregvars}
 {                       regvarinfo^.fpuregvars[i].localloc.register:=trgcpu(rg).correct_fpuregister(NR_ST0,i);}
 {$else i386}
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
 {$endif x86_64}
                        begin
                          tvarsym(regvarinfo^.fpuregvars[i]).localloc.register:=cg.getfpuregister(current_asmdata.CurrAsmList,OS_F64);

+ 1 - 1
compiler/symdef.pas

@@ -947,7 +947,7 @@ interface
 {$ifdef i386}
        pbestrealtype : ^tdef = @s80floattype;
 {$endif}
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
        pbestrealtype : ^tdef = @s80floattype;
 {$endif}
 {$ifdef m68k}

+ 5 - 2
compiler/systems.inc

@@ -49,7 +49,8 @@
              cpu_avr,                      { 12 }
              cpu_mipsel,                   { 13 }
              cpu_jvm,                      { 14 }
-             cpu_i8086                     { 15 }
+             cpu_i8086,                    { 15 }
+             cpu_x32                       { 16 }
        );
 
        tasmmode= (asmmode_none
@@ -159,7 +160,8 @@
              system_jvm_android32,      { 76 }
              system_arm_android,        { 77 }
              system_i386_android,       { 78 }
-             system_i8086_msdos         { 79 }
+             system_i8086_msdos,        { 79 }
+             system_x32_linux           { 80 }
        );
 
      type
@@ -195,6 +197,7 @@
              ,as_i386_nlmcoff
              ,as_powerpc_xcoff
              ,as_jvm_jasmin
+             ,as_x32_elf64
        );
 
        tar = (ar_none

+ 14 - 2
compiler/systems.pas

@@ -228,7 +228,7 @@ interface
        systems_android = [system_arm_android, system_i386_android];
        systems_linux = [system_i386_linux,system_x86_64_linux,system_powerpc_linux,system_powerpc64_linux,
                        system_arm_linux,system_sparc_linux,system_alpha_linux,system_m68k_linux,
-                       system_x86_6432_linux,system_mipseb_linux,system_mipsel_linux];
+                       system_x86_6432_linux,system_mipseb_linux,system_mipsel_linux,system_x32_linux];
        systems_freebsd = [system_i386_freebsd,
                           system_x86_64_freebsd];
        systems_netbsd  = [system_i386_netbsd,
@@ -348,7 +348,7 @@ interface
 
        cpu2str : array[TSystemCpu] of string[10] =
             ('','i386','m68k','alpha','powerpc','sparc','vm','ia64','x86_64',
-             'mipseb','arm', 'powerpc64', 'avr', 'mipsel','jvm', 'i8086');
+             'mipseb','arm', 'powerpc64', 'avr', 'mipsel','jvm', 'i8086', 'x32');
 
        abiinfo : array[tabi] of tabiinfo = (
          (name: 'DEFAULT'; supported: true),
@@ -937,6 +937,18 @@ begin
 {$ifdef i8086}
   default_target(system_i8086_msdos);
 {$endif i8086}
+
+{$ifdef x32}
+  {$ifdef cpux32}
+    default_target(source_info.system);
+    {$define default_target_set}
+  {$endif cpux86_64}
+  { default is linux }
+  {$ifndef default_target_set}
+   default_target(system_x32_linux);
+  {$endif default_target_set}
+{$endif x86_64}
+
 end;
 
 

+ 64 - 0
compiler/systems/i_linux.pas

@@ -479,6 +479,70 @@ unit i_linux;
             abi : abi_default
           );
 
+       system_x32_linux_info : tsysteminfo =
+          (
+            system       : system_x32_linux;
+            name         : 'Linux for x32';
+            shortname    : 'Linux';
+            flags        : [tf_smartlink_sections,tf_needs_symbol_size,tf_needs_dwarf_cfi,tf_smartlink_library,
+                            tf_library_needs_pic,tf_needs_symbol_type,tf_files_case_sensitive,
+                            tf_has_winlike_resources,tf_safecall_exceptions,tf_safecall_clearstack];
+            cpu          : cpu_x32;
+            unit_env     : 'LINUXUNITS';
+            extradefines : 'UNIX;HASUNIX';
+            exeext       : '';
+            defext       : '.def';
+            scriptext    : '.sh';
+            smartext     : '.sl';
+            unitext      : '.ppu';
+            unitlibext   : '.ppl';
+            asmext       : '.s';
+            objext       : '.o';
+            resext       : '.res';
+            resobjext    : '.or';
+            sharedlibext : '.so';
+            staticlibext : '.a';
+            staticlibprefix : 'libp';
+            sharedlibprefix : 'lib';
+            sharedClibext : '.so';
+            staticClibext : '.a';
+            staticClibprefix : 'lib';
+            sharedClibprefix : 'lib';
+            importlibprefix : 'libimp';
+            importlibext : '.a';
+            Cprefix      : '';
+            newline      : #10;
+            dirsep       : '/';
+            assem        : as_x32_elf64;
+            assemextern  : as_gas;
+            link         : nil;
+            linkextern   : nil;
+            ar           : ar_gnu_ar;
+            res          : res_elf;
+            dbg          : dbg_dwarf2;
+            script       : script_unix;
+            endian       : endian_little;
+            alignment    :
+              (
+                procalign       : 16;
+                loopalign       : 8;
+                jumpalign       : 0;
+                constalignmin   : 0;
+                constalignmax   : 8;
+                varalignmin     : 0;
+                varalignmax     : 16;
+                localalignmin   : 4;
+                localalignmax   : 16;
+                recordalignmin  : 0;
+                recordalignmax  : 16;
+                maxCrecordalign : 16
+              );
+            first_parm_offset : 16;
+            stacksize    : 8*1024*1024;
+            stackalign   : 16;
+            abi : abi_default
+          );
+
        system_sparc_linux_info : tsysteminfo =
           (
             system       : system_SPARC_Linux;

+ 17 - 6
compiler/systems/t_linux.pas

@@ -124,15 +124,15 @@ implementation
 procedure SetupLibrarySearchPath;
 begin
   if not Dontlinkstdlibpath Then
-{$ifdef x86_64}
+{$if defined(x86_64)}
     LibrarySearchPath.AddPath(sysrootpath,'/lib64;/usr/lib64;/usr/X11R6/lib64',true);
-{$else}
-{$ifdef powerpc64}
+{$elseif defined(powerpc64)}
     LibrarySearchPath.AddPath(sysrootpath,'/lib64;/usr/lib64;/usr/X11R6/lib64',true);
-{$else powerpc64}
+{$elseif defined(x32)}
+    LibrarySearchPath.AddPath(sysrootpath,'/libx32;/usr/libx32;/usr/X11R6/libx32',true);
+{$else}
     LibrarySearchPath.AddPath(sysrootpath,'/lib;/usr/lib;/usr/X11R6/lib',true);
-{$endif powerpc64}
-{$endif x86_64}
+{$endif}
 
 {$ifdef arm}
   { some newver Debian have the crt*.o files at uncommon locations,
@@ -188,6 +188,10 @@ end;
   const defdynlinker='/lib/ld.so.1';
 {$endif mips}
 
+{$ifdef x32}
+  const defdynlinker='/lib64/ld-linux-x32.so.2';
+{$endif x32}
+
 procedure SetupDynlinker(out DynamicLinker:string;out libctype:TLibcType);
 begin
   {
@@ -270,6 +274,7 @@ procedure TLinkerLinux.SetDefaultInfo;
 const
 {$ifdef i386}      platform_select='-b elf32-i386 -m elf_i386';{$endif}
 {$ifdef x86_64}    platform_select='-b elf64-x86-64 -m elf_x86_64';{$endif}
+{$ifdef x32}       platform_select='-b elf32-x32 -m elf_x32';{$endif}
 {$ifdef powerpc}   platform_select='-b elf32-powerpc -m elf32ppclinux';{$endif}
 {$ifdef POWERPC64} platform_select='-b elf64-powerpc -m elf64ppc';{$endif}
 {$ifdef sparc}     platform_select='-b elf32-sparc -m elf32_sparc';{$endif}
@@ -1577,5 +1582,11 @@ initialization
   RegisterTarget(system_mipseb_linux_info);
 {$endif MIPSEL}
 {$endif MIPS}
+{$ifdef x32}
+  RegisterExternalLinker(system_x32_linux_info,TLinkerLinux);
+  RegisterImport(system_x32_linux,timportliblinux);
+  RegisterExport(system_x32_linux,texportliblinux);
+  RegisterTarget(system_x32_linux_info);
+{$endif x32}
   RegisterRes(res_elf_info,TWinLikeResourceFile);
 end.

+ 4 - 0
compiler/utils/fpc.pp

@@ -155,6 +155,10 @@ program fpc;
      ppcbin:='ppcx64';
      processorname:='x86_64';
 {$endif x86_64}
+{$ifdef x32}
+     ppcbin:='ppcx64';
+     processorname:='x86_64';
+{$endif x32}
 {$ifdef mipsel}
      ppcbin:='ppcmipsel';
      processorname:='mipsel';

+ 48 - 47
compiler/x86/aasmcpu.pas

@@ -96,7 +96,7 @@ interface
 
       OT_REG_TYPMASK = otf_reg_cdt or otf_reg_gpr or otf_reg_sreg or otf_reg_fpu or otf_reg_mmx or otf_reg_xmm or otf_reg_ymm;
       { register class 0: CRx, DRx and TRx }
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
       OT_REG_CDT   = OT_REGISTER or otf_reg_cdt or OT_BITS64;
 {$else x86_64}
       OT_REG_CDT   = OT_REGISTER or otf_reg_cdt or OT_BITS32;
@@ -119,7 +119,7 @@ interface
       OT_REG_AL    = OT_REG_ACCUM or OT_BITS8;
       OT_REG_AX    = OT_REG_ACCUM or OT_BITS16;
       OT_REG_EAX   = OT_REG_ACCUM or OT_BITS32;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
       OT_REG_RAX   = OT_REG_ACCUM or OT_BITS64;
 {$endif x86_64}
       { GPR subclass 1: counter: CL, CX, ECX or RCX }
@@ -127,7 +127,7 @@ interface
       OT_REG_CL    = OT_REG_COUNT or OT_BITS8;
       OT_REG_CX    = OT_REG_COUNT or OT_BITS16;
       OT_REG_ECX   = OT_REG_COUNT or OT_BITS32;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
       OT_REG_RCX   = OT_REG_COUNT or OT_BITS64;
 {$endif x86_64}
       { GPR subclass 2: data register: DL, DX, EDX or RDX }
@@ -181,7 +181,7 @@ interface
       OT_UNITY     = OT_IMMEDIATE or OT_ONENESS;  { for shift/rotate instructions  }
 
       { Size of the instruction table converted by nasmconv.pas }
-{$if defined(x86_64)}
+{$if defined(x86_64) or defined(x32)}
       instabentries = {$i x8664nop.inc}
 {$elseif defined(i386)}
       instabentries = {$i i386nop.inc}
@@ -246,7 +246,7 @@ interface
 
 
       InsProp : array[tasmop] of TInsProp =
-{$if defined(x86_64)}
+{$if defined(x86_64) or defined(x32)}
         {$i x8664pro.inc}
 {$elseif defined(i386)}
         {$i i386prop.inc}
@@ -345,7 +345,7 @@ interface
          insoffset : longint;
          LastInsOffset : longint; { need to be public to be reset }
          inssize   : shortint;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
          rex       : byte;
 {$endif x86_64}
          function  InsEnd:longint;
@@ -456,7 +456,7 @@ implementation
        PInsTabMemRefSizeInfoCache=^TInsTabMemRefSizeInfoCache;
 
      const
-{$if defined(x86_64)}
+{$if defined(x86_64) or defined(x32)}
        InsTab:array[0..instabentries-1] of TInsEntry={$i x8664tab.inc}
 {$elseif defined(i386)}
        InsTab:array[0..instabentries-1] of TInsEntry={$i i386tab.inc}
@@ -467,7 +467,7 @@ implementation
        InsTabCache : PInsTabCache;
        InsTabMemRefSizeInfoCache: PInsTabMemRefSizeInfoCache;
      const
-{$if defined(x86_64)}
+{$if defined(x86_64) or defined(x32)}
        { Intel style operands ! }
        opsize_2_type:array[0..2,topsize] of longint=(
          (OT_NONE,
@@ -615,7 +615,7 @@ implementation
 
     function tai_align.calculatefillbuf(var buf : tfillbuffer;executable : boolean):pchar;
       const
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         alignarray:array[0..3] of string[4]=(
           #$66#$66#$66#$90,
           #$66#$66#$90,
@@ -1087,7 +1087,7 @@ implementation
         size  : byte;
         modrm : byte;
         sib   : byte;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         rex   : byte;
 {$endif x86_64}
       end;
@@ -1123,7 +1123,7 @@ implementation
                          (ref^.base<>NR_NO)) or (ref^.base=NR_EBX))
                         )
 {$endif i386}
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                      or (
                          (ref^.refaddr in [addr_pic,addr_pic_no_got]) and
                          (ref^.base<>NR_NO)
@@ -1534,7 +1534,7 @@ implementation
       begin
         result:=(oper[opidx]^.typ=top_ref) and
                 (oper[opidx]^.ref^.refaddr=addr_no) and
-    {$ifdef x86_64}
+    {$if defined(x86_64) or defined(x32)}
                 (oper[opidx]^.ref^.base<>NR_RIP) and
     {$endif x86_64}
                 (
@@ -1552,7 +1552,7 @@ implementation
 
     function regval(r:Tregister):byte;
       const
-    {$if defined(x86_64)}
+    {$if defined(x86_64) or defined(x32)}
         opcode_table:array[tregisterindex] of tregisterindex = (
           {$i r8664op.inc}
         );
@@ -1579,7 +1579,7 @@ implementation
       end;
 
 
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
     function rexbits(r: tregister): byte;
       begin
         result:=0;
@@ -1905,7 +1905,7 @@ implementation
         exists_prefix_66: boolean;
         exists_prefix_F2: boolean;
         exists_prefix_F3: boolean;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         omit_rexw : boolean;
 {$endif x86_64}
       begin
@@ -1916,7 +1916,7 @@ implementation
         exists_prefix_66 := false;
         exists_prefix_F2 := false;
         exists_prefix_F3 := false;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         rex:=0;
         omit_rexw:=false;
 {$endif x86_64}
@@ -1933,7 +1933,7 @@ implementation
               end;
             8,9,10 :
               begin
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                 rex:=rex or (rexbits(oper[c-8]^.reg) and $F1);
 {$endif x86_64}
                 inc(codes);
@@ -1982,7 +1982,7 @@ implementation
                 case (oper[c-208]^.ot and OT_SIZE_MASK) of
                   OT_BITS16:
                     inc(len);
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                   OT_BITS64:
                     begin
                       rex:=rex or $48;
@@ -1991,14 +1991,14 @@ implementation
                 end;
               end;
             200 :
-{$ifndef x86_64}
+{$if not(defined(x86_64) or defined(x32))}
               inc(len);
 {$else x86_64}
               { every insentry with code 0310 must be marked with NOX86_64 }
               InternalError(2011051301);
 {$endif x86_64}
             201 :
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
               inc(len)
 {$endif x86_64}
               ;
@@ -2006,7 +2006,7 @@ implementation
               inc(len);
             214 :
               begin
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                 rex:=rex or $48;
 {$endif x86_64}
               end;
@@ -2031,13 +2031,13 @@ implementation
                 exists_prefix_66 := true;
               end;
             221:
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
               omit_rexw:=true
 {$endif x86_64}
               ;
             64..151 :
               begin
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                  if (c<127) then
                   begin
                     if (oper[c and 7]^.typ=top_reg) then
@@ -2051,7 +2051,7 @@ implementation
                   Message(asmw_e_invalid_effective_address)
                 else
                   inc(len,ea_data.size);
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                 rex:=rex or ea_data.rex;
 {$endif x86_64}
 
@@ -2092,7 +2092,7 @@ implementation
              InternalError(200603141);
           end;
         until false;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         if ((rex and $80)<>0) and ((rex and $4F)<>0) then
           Message(asmw_e_bad_reg_with_rex);
         rex:=rex and $4F;      { reset extra bits in upper nibble }
@@ -2115,7 +2115,7 @@ implementation
           if exists_prefix_F2 then dec(len);
           if exists_prefix_F3 then dec(len);
 
-  {$ifdef x86_64}
+  {$if defined(x86_64) or defined(x32)}
           if not(exists_vex_extention) then
             if rex and $0B <> 0 then inc(len);  // REX.WXB <> 0 =>> needed VEX-Extention
   {$endif x86_64}
@@ -2198,7 +2198,7 @@ implementation
         currrelreloc,
         currabsreloc,
         currabsreloc32 : TObjRelocationType;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         rexwritten : boolean;
 {$endif x86_64}
 
@@ -2219,7 +2219,7 @@ implementation
                     end
                   else
 {$endif i386}
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                   if oper[opidx]^.ref^.refaddr=addr_pic then
                     begin
                       currrelreloc:=RELOC_PLT32;
@@ -2252,7 +2252,7 @@ implementation
             end;
           end;
 
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
        procedure maybewriterex;
        begin
           if (rex<>0) and not(rexwritten) then
@@ -2311,7 +2311,7 @@ implementation
            internalerror(200130121);
         { load data to write }
         codes:=insentry^.code;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         rexwritten:=false;
 {$endif x86_64}
         { Force word push/pop for registers }
@@ -2378,7 +2378,7 @@ implementation
           begin
             VEXvvvv := VEXvvvv or ((not(regval(oper[opmode]^.reg)) and $07) shl 3);
 
-            {$ifdef x86_64}
+            {$if defined(x86_64) or defined(x32)}
               if rexbits(oper[opmode]^.reg) = 0 then VEXvvvv := VEXvvvv or (1 shl 6);
             {$else}
               VEXvvvv := VEXvvvv or (1 shl 6);
@@ -2388,7 +2388,7 @@ implementation
 
           if not(needed_VEX_Extention) then
           begin
-            {$ifdef x86_64}
+            {$if defined(x86_64) or defined(x32)}
               if rex and $0B <> 0 then needed_VEX_Extention := true;
             {$endif x86_64}
           end;
@@ -2399,7 +2399,7 @@ implementation
             bytes[0]:=$C4;
             objdata.writebytes(bytes,1);
 
-            {$ifdef x86_64}
+            {$if defined(x86_64) or defined(x32)}
               VEXmmmmm := VEXmmmmm or ((not(rex) and $07) shl 5);  // set REX.rxb
             {$else}
               VEXmmmmm := VEXmmmmm or (7 shl 5);  //
@@ -2408,7 +2408,7 @@ implementation
               bytes[0] := VEXmmmmm;
               objdata.writebytes(bytes,1);
 
-            {$ifdef x86_64}
+            {$if defined(x86_64) or defined(x32)}
               VEXvvvv  := VEXvvvv OR ((rex and $08) shl 7);   // set REX.w
             {$endif x86_64}
             bytes[0] := VEXvvvv;
@@ -2420,7 +2420,7 @@ implementation
             bytes[0]:=$C5;
             objdata.writebytes(bytes,1);
 
-            {$ifdef x86_64}
+            {$if defined(x86_64) or defined(x32)}
               if rex and $04 = 0 then
             {$endif x86_64}
             begin
@@ -2448,7 +2448,7 @@ implementation
               break;
             1,2,3 :
               begin
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                 if not(needed_VEX) then  // TG
                   maybewriterex;
 {$endif x86_64}
@@ -2490,7 +2490,7 @@ implementation
               end;
             8,9,10 :
               begin
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                 if not(needed_VEX) then  // TG
                   maybewriterex;
 {$endif x86_64}
@@ -2578,7 +2578,7 @@ implementation
             36,37,38 :   // 044..046 - select between word/dword/qword depending on
               begin      // address size (we support only default address sizes).
                 getvalsym(c-36);
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                 if assigned(currsym) then
                   objdata_writereloc(currval,8,currsym,currabsreloc)
                 else
@@ -2632,7 +2632,7 @@ implementation
             172,173,174 :  // 0254..0256 - dword implicitly sign-extended to 64-bit (x86_64 only)
               begin
                 getvalsym(c-172);
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                 { for i386 as aint type is longint the
                   following test is useless }
                 if (currval<low(longint)) or (currval>high(longint)) then
@@ -2645,7 +2645,7 @@ implementation
                   objdata.writebytes(currval,4);
               end;
             200 :   { fixed 16-bit addr }
-{$ifndef x86_64}
+{$if not(defined(x86_64) or defined(x32))}
               begin
                 bytes[0]:=$67;
                 objdata.writebytes(bytes,1);
@@ -2655,7 +2655,7 @@ implementation
               InternalError(2011051302);
 {$endif}
             201 :   { fixed 32-bit addr }
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
               begin
                 bytes[0]:=$67;
                 objdata.writebytes(bytes,1);
@@ -2670,7 +2670,7 @@ implementation
                       bytes[0]:=$66;
                       objdata.writebytes(bytes,1);
                     end;
-{$ifndef x86_64}
+{$if not(defined(x86_64) or defined(x32))}
                   OT_BITS64 :
                       Message(asmw_e_64bit_not_supported);
 {$endif x86_64}
@@ -2690,7 +2690,7 @@ implementation
               end;
             214 :
               begin
-{$ifndef x86_64}
+{$if not(defined(x86_64) or defined(x32))}
                 Message(asmw_e_64bit_not_supported);
 {$endif x86_64}
               end;
@@ -2750,7 +2750,7 @@ implementation
             else
               begin
                 { rex should be written at this point }
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                 if not(needed_VEX) then  // TG
                   if (rex<>0) and not(rexwritten) then
                     internalerror(200603191);
@@ -2795,7 +2795,7 @@ implementation
                                currabsreloc:=RELOC_GOT32
                              else
 {$endif i386}
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                              if oper[opidx]^.ref^.refaddr=addr_pic then
                                currabsreloc:=RELOC_GOTPCREL
                              else
@@ -2814,7 +2814,7 @@ implementation
                        begin
                          currsym:=objdata.symbolref(oper[opidx]^.ref^.symbol);
                          currval:=oper[opidx]^.ref^.offset;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                          if oper[opidx]^.ref^.refaddr=addr_pic then
                            currabsreloc:=RELOC_GOTPCREL
                          else
@@ -2990,7 +2990,7 @@ implementation
               if getsubreg(r)=R_SUBH then
                 inc(tmpref.offset);
               size:=reg2opsize(r);
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
               { even if it's a 32 bit reg, we still have to spill 64 bits
                 because we often perform 64 bit operations on them }
               if (size=S_L) then
@@ -3352,3 +3352,4 @@ begin
   cai_align:=tai_align;
   cai_cpu:=taicpu;
 end.
+

+ 23 - 11
compiler/x86/agx86att.pas

@@ -121,7 +121,7 @@ interface
            if assigned(relsymbol) then
              owner.AsmWrite('-'+relsymbol.name);
            if ref.refaddr=addr_pic then
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
              begin
                { local symbols don't have to (and in case of Mac OS X: cannot)
                  be accessed via the GOT
@@ -233,7 +233,7 @@ interface
     procedure Tx86InstrWriter.WriteInstruction(hp: tai);
       var
        op       : tasmop;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
        val      : aint;
 {$endif}
        calljmp  : boolean;
@@ -273,7 +273,7 @@ interface
               taicpu(hp).oper[0]^.reg := gas_regnum_search('%x' + copy(sreg, 3, length(sreg) - 2));
           end;
         end;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         if (op=A_MOV) and (taicpu(hp).opsize=S_Q) and
            (taicpu(hp).oper[0]^.typ = top_const) then
            begin
@@ -391,7 +391,7 @@ interface
 *****************************************************************************}
 
     const
-{$ifdef x86_64}
+{$if defined(x86_64)}
        as_x86_64_as_info : tasminfo =
           (
             id     : as_gas;
@@ -420,8 +420,6 @@ interface
             dollarsign: '$';
           );
 
-
-
        as_x86_64_gas_darwin_info : tasminfo =
           (
             id     : as_darwin;
@@ -434,8 +432,20 @@ interface
             comment : '# ';
             dollarsign: '$';
           );
-
-{$else x86_64}
+{$elseif defined(x32)}
+       as_x32_as_info : tasminfo =
+          (
+            id     : as_gas;
+            idtxt  : 'AS';
+            asmbin : 'as';
+            asmcmd : '--64 -o $OBJ $ASM';
+            supported_targets : [system_x32_linux];
+            flags : [af_needar,af_smartlink_sections,af_supports_dwarf];
+            labelprefix : '.L';
+            comment : '# ';
+            dollarsign: '$';
+          );
+{$elseif defined(i386)}
        as_i386_as_info : tasminfo =
           (
             id     : as_gas;
@@ -495,14 +505,16 @@ interface
             comment : '# ';
             dollarsign: '$';
           );
-{$endif x86_64}
+{$endif}
 
 initialization
-{$ifdef x86_64}
+{$if defined(x86_64)}
   RegisterAssembler(as_x86_64_as_info,Tx86ATTAssembler);
   RegisterAssembler(as_x86_64_gas_info,Tx86ATTAssembler);
   RegisterAssembler(as_x86_64_gas_darwin_info,Tx86AppleGNUAssembler);
-{$else x86_64}
+{$elseif defined(x32)}
+  RegisterAssembler(as_x32_as_info,Tx86ATTAssembler);
+{$else}
   RegisterAssembler(as_i386_as_info,Tx86ATTAssembler);
   RegisterAssembler(as_i386_gas_info,Tx86ATTAssembler);
   RegisterAssembler(as_i386_gas_darwin_info,Tx86AppleGNUAssembler);

+ 2 - 1
compiler/x86/agx86int.pas

@@ -955,8 +955,8 @@ implementation
                                   Initialize
 *****************************************************************************}
 
-    const
 {$ifdef i386}
+    const
        as_i386_tasm_info : tasminfo =
           (
             id           : as_i386_tasm;
@@ -997,6 +997,7 @@ implementation
           );
 {$endif i386}
 {$ifdef x86_64}
+    const
        as_x86_64_masm_info : tasminfo =
           (
             id     : as_x86_64_masm;

+ 3 - 3
compiler/x86/agx86nsm.pas

@@ -68,7 +68,7 @@ interface
 
       nasm_regname_table : array[tregisterindex] of string[7] = (
         {r386nasm.inc contains the Nasm name of each register.}
-{$if defined(x86_64)}
+{$if defined(x86_64) or defined(x32)}
         {$fatal nasm support not yet implemented for x86_64 }
 {$elseif defined(i386)}
         {$i r386nasm.inc}
@@ -372,7 +372,7 @@ interface
 {$ifdef x86_64}
                   asmwrite('qword ');
 {$endif}
-{$ifdef i386}
+{$if defined(i386) or defined(x32)}
                   asmwrite('dword ');
 {$endif i386}
 {$ifdef i8086}
@@ -411,7 +411,7 @@ interface
 {$ifndef i8086}
                 if not(
                        (op=A_JCXZ) or (op=A_JECXZ) or
-    {$ifdef x86_64}
+    {$if defined(x86_64) or defined(x32)}
                        (op=A_JRCXZ) or
     {$endif x86_64}
                        (op=A_LOOP) or (op=A_LOOPE) or

+ 26 - 26
compiler/x86/cgx86.pas

@@ -132,7 +132,7 @@ unit cgx86;
       end;
 
    const
-{$if defined(x86_64)}
+{$if defined(x86_64) or defined(x32)}
       TCGSize2OpSize: Array[tcgsize] of topsize =
         (S_NO,S_B,S_W,S_L,S_Q,S_XMM,S_B,S_W,S_L,S_Q,S_XMM,
          S_FS,S_FL,S_FX,S_IQ,S_FXX,
@@ -324,7 +324,7 @@ unit cgx86;
                else
                  internalerror(200109223);
              end;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
            OS_64,OS_S64:
              case s1 of
                OS_8:
@@ -353,7 +353,7 @@ unit cgx86;
          else if s1 in [OS_8,OS_16,OS_32,OS_64] then
            op := A_MOVZX
          else
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
            if s3 in [S_LQ] then
              op := A_MOVSXD
          else
@@ -366,7 +366,7 @@ unit cgx86;
       var
         hreg : tregister;
         href : treference;
-{$ifndef x86_64}
+{$if not(defined(x86_64) or defined(x32))}
         add_hreg: boolean;
 {$endif not  x86_64}
       begin
@@ -375,7 +375,7 @@ unit cgx86;
         if (ref.refaddr in [addr_pic,addr_pic_no_got]) then
           exit;
 
-{$if defined(x86_64)}
+{$if defined(x86_64) or defined(x32)}
         { Only 32bit is allowed }
         { Note that this isn't entirely correct: for RIP-relative targets/memory models,
           it is actually (offset+@symbol-RIP) that should fit into 32 bits. Since two last
@@ -809,7 +809,7 @@ unit cgx86;
       begin
         tmpref:=ref;
         make_simple_ref(list,tmpref);
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         { x86_64 only supports signed 32 bits constants directly }
         if (tosize in [OS_S64,OS_64]) and
            ((a<low(longint)) or (a>high(longint))) then
@@ -837,13 +837,13 @@ unit cgx86;
         check_register_size(fromsize,reg);
         sizes2load(fromsize,tosize,op,s);
         case s of
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
           S_BQ,S_WQ,S_LQ,
 {$endif x86_64}
           S_BW,S_BL,S_WL :
             begin
               tmpreg:=getintregister(list,tosize);
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
               { zero extensions to 64 bit on the x86_64 are simply done by writting to the lower 32 bit
                 which clears the upper 64 bit too, so it could be that s is S_L while the reg is
                 64 bit (FK) }
@@ -874,7 +874,7 @@ unit cgx86;
         make_simple_ref(list,tmpref);
         check_register_size(tosize,reg);
         sizes2load(fromsize,tosize,op,s);
- {$ifdef x86_64}
+ {$if defined(x86_64) or defined(x32)}
         { zero extensions to 64 bit on the x86_64 are simply done by writting to the lower 32 bit
           which clears the upper 64 bit too, so it could be that s is S_L while the reg is
           64 bit (FK) }
@@ -901,7 +901,7 @@ unit cgx86;
           end
         else
           sizes2load(fromsize,tosize,op,s);
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         { zero extensions to 64 bit on the x86_64 are simply done by writting to the lower 32 bit
           which clears the upper 64 bit too, so it could be that s is S_L while the reg is
           64 bit (FK)
@@ -918,7 +918,7 @@ unit cgx86;
               add_move_instruction(instr);
             list.concat(instr);
           end;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         { avoid merging of registers and killing the zero extensions (FK) }
         if (tosize in [OS_64,OS_S64]) and (s=S_L) then
           list.concat(taicpu.op_const_reg(A_AND,S_L,$ffffffff,reg2));
@@ -959,12 +959,12 @@ unit cgx86;
                          end;
                       end
                     else if (cs_create_pic in current_settings.moduleswitches)
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                              and not(ref.symbol.bind=AB_LOCAL)
 {$endif x86_64}
                             then
                       begin
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                         reference_reset_symbol(tmpref,ref.symbol,0,ref.alignment);
                         tmpref.refaddr:=addr_pic;
                         tmpref.base:=NR_RIP;
@@ -979,7 +979,7 @@ unit cgx86;
                         if offset<>0 then
                           a_op_const_reg(list,OP_ADD,OS_ADDR,offset,r);
                       end
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                     else if (target_info.system in (systems_all_windows+[system_x86_64_darwin]))
 			 or (cs_create_pic in current_settings.moduleswitches)
 			 then
@@ -1186,7 +1186,7 @@ unit cgx86;
              if fromsize=OS_M64 then
                list.concat(taicpu.op_ref_reg(A_MOVQ,S_NO,tmpref,reg))
              else
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                { x86-64 has always properly aligned data }
                list.concat(taicpu.op_ref_reg(A_MOVDQA,S_NO,tmpref,reg));
 {$else x86_64}
@@ -1212,7 +1212,7 @@ unit cgx86;
              if fromsize=OS_M64 then
                list.concat(taicpu.op_reg_ref(A_MOVQ,S_NO,reg,tmpref))
              else
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                { x86-64 has always properly aligned data }
                list.concat(taicpu.op_reg_ref(A_MOVDQA,S_NO,reg,tmpref))
 {$else x86_64}
@@ -1337,12 +1337,12 @@ unit cgx86;
       var
         opcode : tasmop;
         power  : longint;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         tmpreg : tregister;
 {$endif x86_64}
       begin
         optimize_op_const(op, a);
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         { x86_64 only supports signed 32 bits constants directly }
         if not(op in [OP_NONE,OP_MOVE]) and
            (size in [OS_S64,OS_64]) and
@@ -1426,7 +1426,7 @@ unit cgx86;
               list.concat(taicpu.op_const_reg(TOpCG2AsmOp[op],TCgSize2OpSize[size],aint(a),reg));
           OP_SHL,OP_SHR,OP_SAR,OP_ROL,OP_ROR:
             begin
-{$if defined(x86_64)}
+{$if defined(x86_64) or defined(x32)}
               if (a and 63) <> 0 Then
                 list.concat(taicpu.op_const_reg(TOpCG2AsmOp[op],TCgSize2OpSize[size],a and 63,reg));
               if (a shr 6) <> 0 Then
@@ -1463,7 +1463,7 @@ unit cgx86;
       var
         opcode: tasmop;
         power: longint;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         tmpreg : tregister;
 {$endif x86_64}
         tmpref  : treference;
@@ -1471,7 +1471,7 @@ unit cgx86;
         optimize_op_const(op, a);
         tmpref:=ref;
         make_simple_ref(list,tmpref);
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         { x86_64 only supports signed 32 bits constants directly }
         if not(op in [OP_NONE,OP_MOVE]) and
            (size in [OS_S64,OS_64]) and
@@ -1691,12 +1691,12 @@ unit cgx86;
     procedure tcgx86.a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : tcgint;reg : tregister;
       l : tasmlabel);
 
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
       var
         tmpreg : tregister;
 {$endif x86_64}
       begin
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         { x86_64 only supports signed 32 bits constants directly }
         if (size in [OS_S64,OS_64]) and
             ((a<low(longint)) or (a>high(longint))) then
@@ -1719,14 +1719,14 @@ unit cgx86;
       l : tasmlabel);
 
       var
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         tmpreg : tregister;
 {$endif x86_64}
         tmpref  : treference;
       begin
         tmpref:=ref;
         make_simple_ref(list,tmpref);
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         { x86_64 only supports signed 32 bits constants directly }
         if (size in [OS_S64,OS_64]) and
            ((a<low(longint)) or (a>high(longint))) then
@@ -2167,7 +2167,7 @@ unit cgx86;
            else
 {$endif NOTARGETWIN}
 {$endif i386}
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
 {$ifndef NOTARGETWIN}
            { windows guards only a few pages for stack growing,
              so we have to access every page first              }

+ 11 - 11
compiler/x86/cpubase.pas

@@ -45,7 +45,7 @@ uses
 *****************************************************************************}
 
     type
-{$if defined(x86_64)}
+{$if defined(x86_64) or defined(x32)}
       TAsmOp={$i x8664op.inc}
 {$elseif defined(i386)}
       TAsmOp={$i i386op.inc}
@@ -140,14 +140,14 @@ uses
       RS_FLAGS       = $07;
 
       { Number of first imaginary register }
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
       first_mm_imreg     = $10;
 {$else x86_64}
       first_mm_imreg     = $08;
 {$endif x86_64}
 
       { The subregister that specifies the entire register and an address }
-{$if defined(x86_64)}
+{$if defined(x86_64) or defined(x32)}
       { Hammer }
       R_SUBWHOLE    = R_SUBQ;
       R_SUBADDR     = R_SUBQ;
@@ -162,7 +162,7 @@ uses
 {$endif}
 
       { Available Registers }
-{$if defined(x86_64)}
+{$if defined(x86_64) or defined(x32)}
       {$i r8664con.inc}
 {$elseif defined(i386)}
       {$i r386con.inc}
@@ -172,7 +172,7 @@ uses
 
     type
       { Number of registers used for indexing in tables }
-{$if defined(x86_64)}
+{$if defined(x86_64) or defined(x32)}
       tregisterindex=0..{$i r8664nor.inc}-1;
 {$elseif defined(i386)}
       tregisterindex=0..{$i r386nor.inc}-1;
@@ -185,7 +185,7 @@ uses
       regnumber_count_bsstart = 64;
 
       regnumber_table : array[tregisterindex] of tregister = (
-{$if defined(x86_64)}
+{$if defined(x86_64) or defined(x32)}
         {$i r8664num.inc}
 {$elseif defined(i386)}
         {$i r386num.inc}
@@ -195,7 +195,7 @@ uses
       );
 
       regstabs_table : array[tregisterindex] of shortint = (
-{$if defined(x86_64)}
+{$if defined(x86_64) or defined(x32)}
         {$i r8664stab.inc}
 {$elseif defined(i386)}
         {$i r386stab.inc}
@@ -205,7 +205,7 @@ uses
       );
 
       regdwarf_table : array[tregisterindex] of shortint = (
-{$if defined(x86_64)}
+{$if defined(x86_64) or defined(x32)}
         {$i r8664dwrf.inc}
 {$elseif defined(i386)}
         {$i r386dwrf.inc}
@@ -297,7 +297,7 @@ implementation
       rgbase,verbose;
 
     const
-    {$if defined(x86_64)}
+    {$if defined(x86_64) or defined(x32)}
       std_regname_table : TRegNameTable = (
         {$i r8664std.inc}
       );
@@ -395,7 +395,7 @@ implementation
             case reg of
               NR_CS,NR_DS,NR_ES,NR_SS,NR_FS,NR_GS:
                 reg_cgsize:=OS_16;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
               NR_DR0..NR_TR7:
                 reg_cgsize:=OS_64;
 {$endif x86_64}
@@ -444,7 +444,7 @@ implementation
           A_JCXZ,
 {$endif i386}
           A_JECXZ,
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
           A_JRCXZ,
 {$endif x86_64}
           A_JMP,

+ 3 - 3
compiler/x86/itcpugas.pas

@@ -33,7 +33,7 @@ interface
 
     const
       { include mnemonic strings }
-{$if defined(x86_64)}
+{$if defined(x86_64) or defined(x32)}
       gas_op2str:op2strtable={$i x8664att.inc}
       gas_needsuffix:array[tasmop] of TAttSuffix={$i x8664ats.inc}
 {$elseif defined(i386)}
@@ -44,7 +44,7 @@ interface
       gas_needsuffix:array[tasmop] of TAttSuffix={$i i8086atts.inc}
 {$endif}
 
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
      gas_opsize2str : array[topsize] of string[2] = ('',
        'b','w','l','q','bw','bl','wl','bq','wq','lq',
        's','l','q',
@@ -108,7 +108,7 @@ implementation
       cutils,verbose;
 
     const
-    {$if defined(x86_64)}
+    {$if defined(x86_64) or defined(x32)}
       att_regname_table : array[tregisterindex] of string[7] = (
         {r8664att.inc contains the AT&T name of each register.}
         {$i r8664att.inc}

+ 1 - 1
compiler/x86/itx86int.pas

@@ -39,7 +39,7 @@ implementation
       cpubase;
 
     const
-    {$if defined(x86_64)}
+    {$if defined(x86_64) or defined(x32)}
       int_regname_table : array[tregisterindex] of string[7] = (
         {$i r8664int.inc}
       );

+ 3 - 3
compiler/x86/nx86add.pas

@@ -247,7 +247,7 @@ unit nx86add;
 
 
     procedure tx86addnode.emit_op_right_left(op:TAsmOp;opsize:TCgsize);
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
       var
         tmpreg : tregister;
 {$endif x86_64}
@@ -267,7 +267,7 @@ unit nx86add;
             end;
           LOC_CONSTANT :
             begin
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
               { x86_64 only supports signed 32 bits constants directly }
               if (opsize in [OS_S64,OS_64]) and
                  ((right.location.value<low(longint)) or (right.location.value>high(longint))) then
@@ -966,7 +966,7 @@ unit nx86add;
         pass_left_right;
         check_left_and_right_fpureg(true);
 
-{$ifndef x86_64}
+{$if not(defined(x86_64) or defined(x32))}
         if current_settings.cputype<cpu_Pentium2 then
           begin
             emit_none(A_FCOMPP,S_NO);

+ 5 - 5
compiler/x86/nx86inl.pas

@@ -144,7 +144,7 @@ implementation
 
      function tx86inlinenode.first_round_real : tnode;
       begin
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
         if use_vectorfpu(left.resultdef) then
           expectloc:=LOC_REGISTER
         else
@@ -157,14 +157,14 @@ implementation
      function tx86inlinenode.first_trunc_real: tnode;
        begin
          if (cs_opt_size in current_settings.optimizerswitches)
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
            and not(use_vectorfpu(left.resultdef))
 {$endif x86_64}
            then
            result:=inherited
          else
            begin
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
              if use_vectorfpu(left.resultdef) then
                expectloc:=LOC_REGISTER
              else
@@ -266,7 +266,7 @@ implementation
 
      procedure tx86inlinenode.second_round_real;
        begin
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
          if use_vectorfpu(left.resultdef) then
            begin
              secondpass(left);
@@ -299,7 +299,7 @@ implementation
        var
          oldcw,newcw : treference;
        begin
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
          if use_vectorfpu(left.resultdef) and
            not((left.location.loc=LOC_FPUREGISTER) and (current_settings.fputype>=fpu_sse3)) then
            begin

+ 6 - 6
compiler/x86/rax86.pas

@@ -267,7 +267,7 @@ begin
             end
           else
             begin
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
               { should probably be extended to i386, but there the situation
                 is more complex and ELF-style PIC still need to be
                 tested/debugged }
@@ -306,7 +306,7 @@ begin
 end;
 
 const
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
   topsize2memsize: array[topsize] of integer =
     (0, 8,16,32,64,8,8,16,8,16,32,
      16,32,64,
@@ -664,7 +664,7 @@ begin
       operands[i].SetCorrectSize(opcode);
       if tx86operand(operands[i]).opsize=S_NO then
         begin
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
           if (opcode=A_MOVQ) and
              (ops=2) and
              (operands[1].opr.typ=OPR_CONSTANT) then
@@ -739,7 +739,7 @@ begin
                      operands[i].opr.ref.symbol:=s;
                      operands[i].opr.ref.offset:=so;
                    end;
-  {$ifdef x86_64}
+  {$if defined(x86_64) or defined(x32)}
                   tx86operand(operands[i]).opsize:=S_Q;
   {$else x86_64}
                   tx86operand(operands[i]).opsize:=S_L;
@@ -788,7 +788,7 @@ begin
                   case tx86operand(operands[2]).opsize of
                     S_L :
                       opsize:=S_WL;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                     S_Q :
                       opsize:=S_WQ;
 {$endif}
@@ -800,7 +800,7 @@ begin
                         opsize:=S_BW;
                       S_L :
                         opsize:=S_BL;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                       S_Q :
                         opsize:=S_BQ;
 {$endif}

+ 3 - 3
compiler/x86/rax86att.pas

@@ -106,7 +106,7 @@ Implementation
             begin
               { May be either real 'movq' or a generic 'mov' with 'q' suffix. Convert to mov
                 if source is a constant, or if neither operand is an mmx/xmm register }
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
               if (ops=2) and
                 (
                   (operands[1].opr.typ=OPR_CONSTANT) or not
@@ -238,7 +238,7 @@ Implementation
                  ((oper.opr.typ=OPR_LOCAL) and (oper.opr.localsym.localloc.loc<>LOC_REGISTER)) then
                 message(asmr_e_cannot_index_relative_var);
               oper.opr.ref.base:=actasmregister;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
               { non-GOT based RIP-relative accesses are also position-independent }
               if (oper.opr.ref.base=NR_RIP) and
                  (oper.opr.ref.refaddr<>addr_pic) then
@@ -345,7 +345,7 @@ Implementation
               consume(AS_AT);
               if actasmtoken=AS_ID then
                 begin
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                   if (actasmpattern='GOTPCREL') or
 		     (actasmpattern='PLT') then
 {$endif x86_64}

+ 4 - 4
compiler/x86/rax86int.pas

@@ -592,7 +592,7 @@ Unit Rax86int;
              '.' :
                begin
                  c:=current_scanner.asmgetchar;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                  if c='.' then
                    begin
                      actasmpattern:='..';
@@ -1260,7 +1260,7 @@ Unit Rax86int;
                          oper.opr.localforceref:=true
                        else
                          begin
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                            if actasmtoken=AS_WRT then
                              begin
                                if (oper.opr.typ=OPR_REFERENCE) then
@@ -1454,7 +1454,7 @@ Unit Rax86int;
                       else
                         begin
                           oper.opr.ref.base:=hreg;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                           { non-GOT based RIP-relative accesses are also position-independent }
                           if (oper.opr.ref.base=NR_RIP) and
                              (oper.opr.ref.refaddr<>addr_pic) then
@@ -1685,7 +1685,7 @@ Unit Rax86int;
               begin
                 case oper.opr.typ of
                   OPR_REFERENCE :
-{$ifndef x86_64}
+{$if not(defined(x86_64) or defined(x32))}
                     { this is for the i386 scenario where you have
                         <load got into ebx>
                         mov eax, [ebx].offset globalvar

+ 2 - 2
compiler/x86/rgx86.pas

@@ -248,7 +248,7 @@ implementation
                           A_SHUFPS:
 
                             replaceoper:=-1;
-{$ifdef x86_64}
+{$if defined(x86_64) or defined(x32)}
                           A_MOV:
                              { 64 bit constants can only be moved into registers }
                              if (oper[0]^.typ=top_const) and
@@ -263,7 +263,7 @@ implementation
                 end;
              end;
 
-            {$ifdef x86_64}
+            {$if defined(x86_64) or defined(x32)}
             { 32 bit operations on 32 bit registers on x86_64 can result in
               zeroing the upper 32 bits of the register. This does not happen
               with memory operations, so we have to perform these calculations

+ 4 - 4
utils/fpcm/fpcmmain.pp

@@ -67,7 +67,7 @@ interface
 
     type
       TCpu=(
-        c_i386,c_m68k,c_powerpc,c_sparc,c_x86_64,c_arm,c_powerpc64,c_avr,c_armeb,c_armel,c_mips,c_mipsel,c_mips64,c_mips64el,c_jvm,c_i8086
+        c_i386,c_m68k,c_powerpc,c_sparc,c_x86_64,c_arm,c_powerpc64,c_avr,c_armeb,c_armel,c_mips,c_mipsel,c_mips64,c_mips64el,c_jvm,c_i8086,c_x32
       );
 
       TOS=(
@@ -82,15 +82,15 @@ interface
 
     const
       CpuStr : array[TCpu] of string=(
-        'i386','m68k','powerpc','sparc','x86_64','arm','powerpc64','avr','armeb', 'armel', 'mips', 'mipsel', 'mips64', 'mips64el', 'jvm','i8086'
+        'i386','m68k','powerpc','sparc','x86_64','arm','powerpc64','avr','armeb', 'armel', 'mips', 'mipsel', 'mips64', 'mips64el', 'jvm','i8086', 'x32'
       );
 
       CpuSuffix : array[TCpu] of string=(
-        '_i386','_m68k','_powerpc','_sparc','_x86_64','_arm','_powerpc64','avr','_armeb', '_armel', '_mips', '_mipsel', '_mips64', '_mips64el', '_jvm','_i8086'
+        '_i386','_m68k','_powerpc','_sparc','_x86_64','_arm','_powerpc64','avr','_armeb', '_armel', '_mips', '_mipsel', '_mips64', '_mips64el', '_jvm','_i8086','_x32'
       );
 
       ppcSuffix : array[TCpu] of string=(
-        '386','m68k','ppc','sparc','x86_64','arm','ppc64','avr','armeb', 'armel', 'mips', 'mipsel', 'mips64', 'mips64el', 'jvm','8086'
+        '386','m68k','ppc','sparc','x86_64','arm','ppc64','avr','armeb', 'armel', 'mips', 'mipsel', 'mips64', 'mips64el', 'jvm','8086', 'x32'
       );
 
       OSStr : array[TOS] of string=(