[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

More on freepascal armhf porting attempt, some progress made but now stuck.



I've made some progress on armhf porting, i've added the nessacery frameworks (vfpv3_d16 FPU target, EABIVFP ABI target, FPC_ARMHF define) and made a start on actually implementing the new ABI. I decided to start with function results.

However i've now reached a problem which has me stumped.

When I try to build my patched compiler (using make compiler_cycle 'OPT=-dFPC_ARMHF' ) the starting compiler builds the RTL and compiler successfully (as would be expected) but when ppc1 tries to build the RTL things fail with assembler errors. The errors below are a sample of the types of error seen (there are a HUGE number of each)

/fpc/rtl/units/arm-linux/system.s:19075: Error: selected processor does not support ARM mode `mvfd d0,f0' /fpc/rtl/units/arm-linux/system.s:19077: Error: selected processor does not support ARM mode `ldfd f0,[r13]' /fpc/rtl/units/arm-linux/system.s:41169: Error: selected processor does not support ARM mode `ldfs f0,[r13]'

It appears to me (i'm not an expert on arm assembler and I can't seem to find any documentation on FPA) that FPC is generating FPA instructions even though the FPU is set to a VFP type. What i'm really struggling to work out is why the heck that is happening. From telling freepascal to include source lines as comments in the assembler it doesn't look like inline assembler is responsible.

Anyone have any suggestions on where things might be going wrong and how to debug this?

I've attatched a patch containing my efforts so far.
Index: rtl/arm/setjump.inc
===================================================================
--- rtl/arm/setjump.inc	(revision 20511)
+++ rtl/arm/setjump.inc	(working copy)
@@ -16,7 +16,7 @@
 
 function fpc_setjmp(var S : jmp_buf) : longint;assembler;[Public, alias : 'FPC_SETJMP'];nostackframe; compilerproc;
   asm
-    {$if defined(FPUVFPV2) or defined(FPUVFPV3)}
+    {$if defined(FPUVFPV2) or defined(FPUVFPV3) or defined(FPUVFPV3_D16)}
     {$if defined(CPUARMV3) or defined(CPUARMV4) or defined(CPUARMV5)}
     fstmiax r0!, {d8-d15}
     {$else}
@@ -46,7 +46,7 @@
     movs    r0, r1
     it eq
     moveq   r0, #1
-    {$if defined(FPUVFPV2) or defined(FPUVFPV3)}
+    {$if defined(FPUVFPV2) or defined(FPUVFPV3) or defined(FPUVFPV3_D16)}
     fldmiad ip!, {d8-d15}
     {$endif}
     ldmia   ip,{v1-v6, sl, fp}
@@ -57,7 +57,7 @@
     mov     ip, r0
     movs    r0, r1
     moveq   r0, #1
-    {$if defined(FPUVFPV2) or defined(FPUVFPV3)}
+    {$if defined(FPUVFPV2) or defined(FPUVFPV3) or defined(FPUVFPV3_D16)}
     {$if defined(CPUARMV3) or defined(CPUARMV4) or defined(CPUARMV5)}
     fldmiax ip!, {d8-d15}
     {$else}
Index: rtl/arm/math.inc
===================================================================
--- rtl/arm/math.inc	(revision 20511)
+++ rtl/arm/math.inc	(working copy)
@@ -14,7 +14,7 @@
 
  **********************************************************************}
 
-{$if defined(FPUFPA) or defined(FPUFPA10) or defined(FPUFPA11) or defined(FPUVFPV2) or defined(FPUVFPV3)}
+{$if defined(FPUFPA) or defined(FPUFPA10) or defined(FPUFPA11) or defined(FPUVFPV2) or defined(FPUVFPV3) or defined(FPUVFPV3_D16)}
     {$define FPC_SYSTEM_HAS_ABS}
     function fpc_abs_real(d : ValReal) : ValReal;compilerproc;
     begin
Index: rtl/arm/mathu.inc
===================================================================
--- rtl/arm/mathu.inc	(revision 20511)
+++ rtl/arm/mathu.inc	(working copy)
@@ -177,7 +177,7 @@
 begin
 end;
 
-{$elseif defined(darwin) or defined(FPUVFPV2) or defined(FPUVFPV3)}
+{$elseif defined(darwin) or defined(FPUVFPV2) or defined(FPUVFPV3) or defined(FPUVFPV3_d16)}
 
 const
   _VFP_ENABLE_IM  =  1 shl 8;         { invalid operation      }
Index: rtl/arm/arm.inc
===================================================================
--- rtl/arm/arm.inc	(revision 20511)
+++ rtl/arm/arm.inc	(working copy)
@@ -30,7 +30,7 @@
 {$if not(defined(wince)) and not(defined(gba)) and not(defined(nds)) and not(defined(FPUSOFT)) and not(defined(FPULIBGCC))}
 
 {$define FPC_SYSTEM_HAS_SYSINITFPU}
-{$if not defined(darwin) and not defined(FPUVFPV2) and not defined(FPUVFPV3)}
+{$if not defined(darwin) and not defined(FPUVFPV2) and not defined(FPUVFPV3) and not defined(FPUVFPV3_D16)}
 Procedure SysInitFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
 begin
   { Enable FPU exceptions, but disable INEXACT, UNDERFLOW, DENORMAL }
Index: rtl/arm/setjumph.inc
===================================================================
--- rtl/arm/setjumph.inc	(revision 20511)
+++ rtl/arm/setjumph.inc	(working copy)
@@ -16,7 +16,7 @@
 
 type
    jmp_buf = packed record
-{$if defined(FPUVFPV2) or defined(FPUVFPV3)}
+{$if defined(FPUVFPV2) or defined(FPUVFPV3) or defined(FPUVFPV3_D16)}
       d8,d9,d10,d11,d12,d13,d14,d15: double;
 {$endif}
       v1,v2,v3,v4,v5,v6,sl,fp,sp,pc : dword;
Index: compiler/ninl.pas
===================================================================
--- compiler/ninl.pas	(revision 20511)
+++ compiler/ninl.pas	(working copy)
@@ -3094,7 +3094,7 @@
             internalerror(200104047);
 
           in_slice_x:
-            internalerror(2005101501);
+            internalerror(2005101502);
 
           in_ord_x,
           in_chr_byte:
Index: compiler/systems.inc
===================================================================
--- compiler/systems.inc	(revision 20511)
+++ compiler/systems.inc	(working copy)
@@ -210,7 +210,7 @@
 
        tabi = (abi_default
             ,abi_powerpc_sysv,abi_powerpc_aix
-            ,abi_eabi,abi_armeb
+            ,abi_eabi,abi_armeb,abi_eabivfp
        );
 
 
Index: compiler/fpcdefs.inc
===================================================================
--- compiler/fpcdefs.inc	(revision 20511)
+++ compiler/fpcdefs.inc	(working copy)
@@ -130,17 +130,21 @@
   {$define cputargethasfixedstack}
   {$define cpurefshaveindexreg}
   { default to armel }
-  {$if not(defined(CPUARM)) and not(defined(CPUARMEB)) and not(defined(FPC_OARM)) and not(defined(FPC_ARMEB))}
+  {$if not(defined(CPUARM)) and not(defined(CPUARMEB)) and not(defined(FPC_OARM)) and not(defined(FPC_ARMEB)) and not(defined(FPC_ARMHF))}
     {$define FPC_ARMEL}
   {$endif}
   { inherit FPC_ARMEL? }
-  {$if defined(CPUARMEL) and not(defined(FPC_OARM)) and not(defined(FPC_ARMEB))}
+  {$if defined(CPUARMEL) and not(defined(FPC_OARM)) and not(defined(FPC_ARMEB)) and not(defined(FPC_ARMHF))}
     {$define FPC_ARMEL}
   {$endif}
   { inherit FPC_ARMEB? }
-  {$if defined(CPUARMEB) and not(defined(FPC_OARM)) and not(defined(FPC_ARMEL))}
+  {$if defined(CPUARMEB) and not(defined(FPC_OARM)) and not(defined(FPC_ARMEL)) and not(defined(FPC_ARMHF))}
     {$define FPC_ARMEB}
   {$endif}
+  { inherit FPC_ARMHF? }
+  {$if defined(CPUARMHF) and not(defined(FPC_OARM)) and not(defined(FPC_ARMEL)) and not(defined(FPC_ARMEB))}
+    {$define FPC_ARMHF}
+  {$endif}
 {$endif arm}
 
 {$ifdef m68k}
Index: compiler/ncgutil.pas
===================================================================
--- compiler/ncgutil.pas	(revision 20511)
+++ compiler/ncgutil.pas	(working copy)
@@ -1977,6 +1977,10 @@
                         cg64.a_load64_ref_reg(list,href,destloc.register64);
                         unget_para(paraloc^);
                       end;
+                    LOC_FPUREGISTER:
+                      begin
+                        internalerror(2012031001);
+                      end;
                     else
                       internalerror(2005101501);
                   end
@@ -2116,7 +2120,9 @@
         for i:=0 to current_procinfo.procdef.paras.count-1 do
           begin
             currpara:=tparavarsym(current_procinfo.procdef.paras[i]);
+            //writeln('calling gen_load_cgpara_loc from ncgutil.pas');
             gen_load_cgpara_loc(list,currpara.vardef,currpara.paraloc[calleeside],currpara.initialloc,paramanager.param_use_paraloc(currpara.paraloc[calleeside]));
+            //writeln('called gen_load_cgpara_loc from ncgutil.pas');
             { gen_load_cgpara_loc() already allocated the initialloc
               -> don't allocate again }
             if currpara.initialloc.loc in [LOC_CREGISTER,LOC_CFPUREGISTER,LOC_CMMREGISTER] then
Index: compiler/systems.pas
===================================================================
--- compiler/systems.pas	(revision 20511)
+++ compiler/systems.pas	(working copy)
@@ -84,7 +84,7 @@
           id          : tasm;
           idtxt       : string[12];
           asmbin      : string[8];
-          asmcmd      : string[50];
+          asmcmd      : string[100];
           supported_targets : set of tsystem;
           flags        : set of tasmflags;
           labelprefix : string[3];
@@ -314,7 +314,7 @@
              'mips','arm', 'powerpc64', 'avr', 'mipsel');
 
        abi2str : array[tabi] of string[10] =
-         ('DEFAULT','SYSV','AIX','EABI','ARMEB');
+         ('DEFAULT','SYSV','AIX','EABI','ARMEB','EABIVFP');
 
     var
        targetinfos   : array[tsystem] of psysteminfo;
Index: compiler/pp.pas
===================================================================
--- compiler/pp.pas	(revision 20511)
+++ compiler/pp.pas	(working copy)
@@ -43,6 +43,7 @@
   FPC_ARMEB           create an arm big endian compiler
   FPC_OARM            create an arm oabi compiler, only needed when the host
                       compiler is ARMEL or ARMEB
+  FPC_ARMHF           create an armhf (eabi vfp variant) compiler
   -----------------------------------------------------------------
   cpuflags            The target processor has status flags (on by default)
   cpufpemu            The target compiler will also support emitting software
Index: compiler/arm/narminl.pas
===================================================================
--- compiler/arm/narminl.pas	(revision 20511)
+++ compiler/arm/narminl.pas	(working copy)
@@ -89,7 +89,8 @@
                end;
             end;
           fpu_vfpv2,
-          fpu_vfpv3:
+          fpu_vfpv3,
+          fpu_vfpv3_d16:
             begin
               location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,true);
               location_copy(location,left.location);
@@ -118,7 +119,8 @@
               fpu_fpa11:
                 expectloc:=LOC_FPUREGISTER;
               fpu_vfpv2,
-              fpu_vfpv3:
+              fpu_vfpv3,
+              fpu_vfpv3_d16:
                 expectloc:=LOC_MMREGISTER;
               else
                 internalerror(2009112401);
@@ -140,7 +142,8 @@
               fpu_fpa11:
                 expectloc:=LOC_FPUREGISTER;
               fpu_vfpv2,
-              fpu_vfpv3:
+              fpu_vfpv3,
+              fpu_vfpv3_d16:
                 expectloc:=LOC_MMREGISTER;
               else
                 internalerror(2009112402);
@@ -162,7 +165,8 @@
               fpu_fpa11:
                 expectloc:=LOC_FPUREGISTER;
               fpu_vfpv2,
-              fpu_vfpv3:
+              fpu_vfpv3,
+              fpu_vfpv3_d16:
                 expectloc:=LOC_MMREGISTER;
               else
                 internalerror(2009112403);
@@ -213,7 +217,8 @@
           fpu_fpa11:
             current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_ABS,location.register,left.location.register),get_fpu_postfix(resultdef)));
           fpu_vfpv2,
-          fpu_vfpv3:
+          fpu_vfpv3,
+          fpu_vfpv3_d16:
             begin
               if singleprec then
                 op:=A_FABSS
@@ -239,7 +244,8 @@
           fpu_fpa11:
             current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_MUF,location.register,left.location.register,left.location.register),get_fpu_postfix(resultdef)));
           fpu_vfpv2,
-          fpu_vfpv3:
+          fpu_vfpv3,
+          fpu_vfpv3_d16:
             begin
               if singleprec then
                 op:=A_FMULS
@@ -265,7 +271,8 @@
           fpu_fpa11:
             current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_SQT,location.register,left.location.register),get_fpu_postfix(resultdef)));
           fpu_vfpv2,
-          fpu_vfpv3:
+          fpu_vfpv3,
+          fpu_vfpv3_d16:
             begin
               if singleprec then
                 op:=A_FSQRTS
Index: compiler/arm/cgcpu.pas
===================================================================
--- compiler/arm/cgcpu.pas	(revision 20511)
+++ compiler/arm/cgcpu.pas	(working copy)
@@ -226,7 +226,7 @@
           non-overlapping subregs per register, so we can only use
           half the single precision registers for now (as sub registers of the
           double precision ones). }
-        if current_settings.fputype=fpu_vfpv3 then
+        if (current_settings.fputype=fpu_vfpv3) then
           rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBFD,
               [RS_D0,RS_D1,RS_D2,RS_D3,RS_D4,RS_D5,RS_D6,RS_D7,
                RS_D16,RS_D17,RS_D18,RS_D19,RS_D20,RS_D21,RS_D22,RS_D23,RS_D24,RS_D25,RS_D26,RS_D27,RS_D28,RS_D29,RS_D30,RS_D31,
@@ -1438,7 +1438,8 @@
                       end;
                 end;
               fpu_vfpv2,
-              fpu_vfpv3:
+              fpu_vfpv3,
+              fpu_vfpv3_d16:
                 begin;
                   mmregs:=rg[R_MMREGISTER].used_in_proc-paramanager.get_volatile_registers_mm(pocall_stdcall);
                 end;
@@ -1509,7 +1510,7 @@
              begin
                reference_reset(ref,4);
                if (tg.direction*tarmprocinfo(current_procinfo).floatregstart>=1023) or
-                  (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3]) then
+                  (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16]) then
                  begin
                    if not is_shifter_const(tarmprocinfo(current_procinfo).floatregstart,shift) then
                      begin
@@ -1537,7 +1538,8 @@
                        lastfloatreg-firstfloatreg+1,ref));
                    end;
                  fpu_vfpv2,
-                 fpu_vfpv3:
+                 fpu_vfpv3,
+                 fpu_vfpv3_d16:
                    begin
                      ref.index:=ref.base;
                      ref.base:=NR_NO;
@@ -1591,7 +1593,8 @@
                       end;
                 end;
               fpu_vfpv2,
-              fpu_vfpv3:
+              fpu_vfpv3,
+              fpu_vfpv3_d16:
                 begin;
                   { restore vfp registers? }
                   mmregs:=rg[R_MMREGISTER].used_in_proc-paramanager.get_volatile_registers_mm(pocall_stdcall);
@@ -1603,7 +1606,7 @@
               begin
                 reference_reset(ref,4);
                 if (tg.direction*tarmprocinfo(current_procinfo).floatregstart>=1023) or
-                   (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3]) then
+                   (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16]) then
                   begin
                     if not is_shifter_const(tarmprocinfo(current_procinfo).floatregstart,shift) then
                       begin
@@ -1630,7 +1633,8 @@
                         lastfloatreg-firstfloatreg+1,ref));
                     end;
                   fpu_vfpv2,
-                  fpu_vfpv3:
+                  fpu_vfpv3,
+                  fpu_vfpv3_d16:
                     begin
                       ref.index:=ref.base;
                       ref.base:=NR_NO;
Index: compiler/arm/narmcnv.pas
===================================================================
--- compiler/arm/narmcnv.pas	(revision 20511)
+++ compiler/arm/narmcnv.pas	(working copy)
@@ -116,7 +116,8 @@
               fpu_fpa11:
                 expectloc:=LOC_FPUREGISTER;
               fpu_vfpv2,
-              fpu_vfpv3:
+              fpu_vfpv3,
+              fpu_vfpv3_d16:
                 expectloc:=LOC_MMREGISTER;
               else
                 internalerror(2009112702);
@@ -195,7 +196,8 @@
               end;
             end;
           fpu_vfpv2,
-          fpu_vfpv3:
+          fpu_vfpv3,
+          fpu_vfpv3_d16:
             begin
               location_reset(location,LOC_MMREGISTER,def_cgsize(resultdef));
               signed:=left.location.size=OS_S32;
Index: compiler/arm/narmcal.pas
===================================================================
--- compiler/arm/narmcal.pas	(revision 20511)
+++ compiler/arm/narmcal.pas	(working copy)
@@ -41,13 +41,14 @@
     cgbase,
     cpubase,cpuinfo,
     ncgutil,
-    paramgr;
+    paramgr,
+    systems;
 
   procedure tarmcallnode.set_result_location(realresdef: tstoreddef);
     begin
-      if (realresdef.typ=floatdef) and
+      if (realresdef.typ=floatdef) and (target_info.abi <> abi_eabivfp) and
          ((cs_fp_emulation in current_settings.moduleswitches) or
-          (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3])) then
+          (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16])) then
         begin
           { keep the fpu values in integer registers for now, the code
             generator will move them to memory or an mmregister when necessary
Index: compiler/arm/agarmgas.pas
===================================================================
--- compiler/arm/agarmgas.pas	(revision 20511)
+++ compiler/arm/agarmgas.pas	(working copy)
@@ -80,9 +80,14 @@
         result:=inherited MakeCmdLine;
         if (current_settings.fputype = fpu_soft) then
           result:='-mfpu=softvfp '+result;
-
+        if (current_settings.fputype = fpu_vfpv3) then
+          result:='-mfpu=vfpv3 '+result;
+        if (current_settings.fputype = fpu_vfpv3_d16) then
+          result:='-mfpu=vfpv3-d16 '+result;
         if current_settings.cputype = cpu_armv7m then
           result:='-march=armv7m -mthumb -mthumb-interwork '+result;
+        if target_info.abi = abi_eabivfp then 
+          result:='-march=armv7-a -mfloat-abi=hard -meabi=5 '+result;
       end;
 
     procedure TArmGNUAssembler.WriteExtraHeader;
Index: compiler/arm/narmmat.pas
===================================================================
--- compiler/arm/narmmat.pas	(revision 20511)
+++ compiler/arm/narmmat.pas	(working copy)
@@ -331,7 +331,8 @@
                 cgsize2fpuoppostfix[def_cgsize(resultdef)]));
             end;
           fpu_vfpv2,
-          fpu_vfpv3:
+          fpu_vfpv3,
+          fpu_vfpv3_d16:
             begin
               location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,true);
               location:=left.location;
Index: compiler/arm/cpuinfo.pas
===================================================================
--- compiler/arm/cpuinfo.pas	(revision 20511)
+++ compiler/arm/cpuinfo.pas	(working copy)
@@ -56,7 +56,8 @@
       fpu_fpa10,
       fpu_fpa11,
       fpu_vfpv2,
-      fpu_vfpv3
+      fpu_vfpv3,
+      fpu_vfpv3_d16
      );
 
    tcontrollertype =
@@ -197,14 +198,15 @@
      'ARMV7M'
    );
 
-   fputypestr : array[tfputype] of string[6] = ('',
+   fputypestr : array[tfputype] of string[9] = ('',
      'SOFT',
      'LIBGCC',
      'FPA',
      'FPA10',
      'FPA11',
      'VFPV2',
-     'VFPV3'
+     'VFPV3',
+     'VFPV3_D16'
    );
 
 
@@ -1015,7 +1017,7 @@
         )
     );
 
-   vfp_scalar = [fpu_vfpv2,fpu_vfpv3];
+   vfp_scalar = [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16];
 
    { Supported optimizations, only used for information }
    supported_optimizerswitches = genericlevel1optimizerswitches+
Index: compiler/arm/narmadd.pas
===================================================================
--- compiler/arm/narmadd.pas	(revision 20511)
+++ compiler/arm/narmadd.pas	(working copy)
@@ -164,7 +164,8 @@
                  cgsize2fpuoppostfix[def_cgsize(resultdef)]));
             end;
           fpu_vfpv2,
-          fpu_vfpv3:
+          fpu_vfpv3,
+          fpu_vfpv3_d16:
             begin
               { force mmreg as location, left right doesn't matter
                 as both will be in a fpureg }
@@ -248,7 +249,8 @@
                    cgsize2fpuoppostfix[def_cgsize(resultdef)]));
             end;
           fpu_vfpv2,
-          fpu_vfpv3:
+          fpu_vfpv3,
+          fpu_vfpv3_d16:
             begin
               location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,true);
               location_force_mmregscalar(current_asmdata.CurrAsmList,right.location,true);
Index: compiler/arm/cpupi.pas
===================================================================
--- compiler/arm/cpupi.pas	(revision 20511)
+++ compiler/arm/cpupi.pas	(working copy)
@@ -106,7 +106,8 @@
                 floatsavesize:=(lastfloatreg-firstfloatreg+1)*12;
             end;
           fpu_vfpv2,
-          fpu_vfpv3:
+          fpu_vfpv3,
+          fpu_vfpv3_d16:
             begin
               floatsavesize:=0;
               regs:=cg.rg[R_MMREGISTER].used_in_proc-paramanager.get_volatile_registers_mm(pocall_stdcall);
Index: compiler/arm/cpupara.pas
===================================================================
--- compiler/arm/cpupara.pas	(revision 20511)
+++ compiler/arm/cpupara.pas	(working copy)
@@ -46,7 +46,7 @@
          private
           procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
           function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
-            var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword):longint;
+            var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; isvariadic: boolean):longint;
           procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
        end;
 
@@ -121,7 +121,7 @@
             floatdef:
               if (calloption in [pocall_cdecl,pocall_cppdecl,pocall_softfloat]) or
                  (cs_fp_emulation in current_settings.moduleswitches) or
-                 (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3]) then
+                 (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16]) then
                 { the ARM eabi also allows passing VFP values via VFP registers,
                   but at least neither Mac OS X nor Linux seems to do that }
                 getparaloc:=LOC_REGISTER
@@ -223,7 +223,7 @@
 
 
     function tarmparamanager.create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
-        var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword):longint;
+        var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; isvariadic: boolean):longint;
 
       var
         nextintreg,nextfloatreg,nextmmreg : tsuperregister;
@@ -349,7 +349,7 @@
                     LOC_REGISTER:
                       begin
                         { align registers for eabi }
-                        if (target_info.abi=abi_eabi) and
+                        if ((target_info.abi=abi_eabi) or (target_info.abi=abi_eabivfp)) and
                            firstparaloc and
                            (paradef.alignment=8) then
                           begin
@@ -415,7 +415,7 @@
                         else
                           begin
                             { align stack for eabi }
-                            if (target_info.abi=abi_eabi) and
+                            if ((target_info.abi=abi_eabi) or (target_info.abi=abi_eabivfp)) and
                                firstparaloc and
                                (paradef.alignment=8) then
                               stack_offset:=align(stack_offset,8);
@@ -499,9 +499,9 @@
         { Return in FPU register? }
         if def.typ=floatdef then
           begin
-            if (p.proccalloption in [pocall_softfloat]) or
+            if (target_info.abi <> abi_eabivfp) AND((p.proccalloption in [pocall_softfloat]) or
                (cs_fp_emulation in current_settings.moduleswitches) or
-               (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3]) then
+               (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16])) then
               begin
                 case retcgsize of
                   OS_64,
@@ -566,7 +566,7 @@
       begin
         init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset);
 
-        result:=create_paraloc_info_intern(p,side,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset);
+        result:=create_paraloc_info_intern(p,side,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset,false);
 
         create_funcretloc_info(p,side);
      end;
@@ -579,10 +579,10 @@
       begin
         init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset);
 
-        result:=create_paraloc_info_intern(p,callerside,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset);
+        result:=create_paraloc_info_intern(p,callerside,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset,true);
         if (p.proccalloption in [pocall_cdecl,pocall_cppdecl]) then
           { just continue loading the parameters in the registers }
-          result:=create_paraloc_info_intern(p,callerside,varargspara,curintreg,curfloatreg,curmmreg,cur_stack_offset)
+          result:=create_paraloc_info_intern(p,callerside,varargspara,curintreg,curfloatreg,curmmreg,cur_stack_offset,true)
         else
           internalerror(200410231);
       end;
Index: compiler/systems/i_linux.pas
===================================================================
--- compiler/systems/i_linux.pas	(revision 20511)
+++ compiler/systems/i_linux.pas	(working copy)
@@ -534,6 +534,70 @@
             abi : abi_default
           );
 
+{$ifdef FPC_ARMHF}
+       system_arm_linux_info : tsysteminfo =
+          (
+            system       : system_arm_Linux;
+            name         : 'Linux for ARMHF';
+            shortname    : 'Linux';
+            flags        : [tf_needs_symbol_size,tf_needs_symbol_type,tf_files_case_sensitive,
+                            tf_requires_proper_alignment,
+                            tf_smartlink_sections,tf_smartlink_library,tf_has_winlike_resources];
+            cpu          : cpu_arm;
+            unit_env     : 'LINUXUNITS';
+            extradefines : 'UNIX;HASUNIX;CPUARMHF';
+            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_gas;
+            assemextern  : as_gas;
+            link         : nil;
+            linkextern   : nil;
+            ar           : ar_gnu_ar;
+            res          : res_elf;
+            dbg          : dbg_stabs;
+            script       : script_unix;
+            endian       : endian_little;
+            alignment    :
+              (
+                procalign       : 4;
+                loopalign       : 4;
+                jumpalign       : 0;
+                constalignmin   : 0;
+                constalignmax   : 8;
+                varalignmin     : 0;
+                varalignmax     : 8;
+                localalignmin   : 4;
+                localalignmax   : 8;
+                recordalignmin  : 0;
+                recordalignmax  : 8;
+                maxCrecordalign : 8
+              );
+            first_parm_offset : 8;
+            stacksize    : 8*1024*1024;
+            abi : abi_eabivfp
+          );
+{$else FPC_ARMHF}
 {$ifdef FPC_ARMEL}
        system_arm_linux_info : tsysteminfo =
           (
@@ -726,6 +790,7 @@
           );
 {$endif FPC_ARMEB}
 {$endif FPC_ARMEL}
+{$endif FPC_ARMHF}
 
        system_mips_linux_info : tsysteminfo =
           (
Index: compiler/systems/t_linux.pas
===================================================================
--- compiler/systems/t_linux.pas	(revision 20511)
+++ compiler/systems/t_linux.pas	(working copy)
@@ -185,11 +185,15 @@
 {$endif powerpc64}
 
 {$ifdef arm}
+{$ifdef FPC_ARMHF}
+     defdynlinker:='/lib/ld-linux.so.3';
+{$else FPC_ARMHF}
 {$ifdef FPC_ARMEL}
      defdynlinker:='/lib/ld-linux.so.3';
 {$else FPC_ARMEL}
      defdynlinker:='/lib/ld-linux.so.2';
 {$endif FPC_ARMEL}
+{$endif FPC_ARMHF}
 {$endif arm}
 
 {$ifdef mips}
Index: compiler/ncgcal.pas
===================================================================
--- compiler/ncgcal.pas	(revision 20511)
+++ compiler/ncgcal.pas	(working copy)
@@ -369,7 +369,9 @@
             if (cnf_return_value_used in callnodeflags) or
                assigned(funcretnode) then
               begin
+                //writeln('calling gen_load_cgpara_loc from ncgal.pas');
                 gen_load_cgpara_loc(current_asmdata.CurrAsmList,realresdef,retloc,location,false);
+                //writeln('called gen_load_cgpara_loc from ncgal.pas');
 {$ifdef arm}
                 if (resultdef.typ=floatdef) and
                    (location.loc=LOC_REGISTER) and
Index: compiler/options.pas
===================================================================
--- compiler/options.pas	(revision 20511)
+++ compiler/options.pas	(working copy)
@@ -2883,6 +2883,10 @@
     undef_system_macro('FPC_ABI_'+abi2str[abi]);
   def_system_macro('FPC_ABI_'+abi2str[target_info.abi]);
 
+  { Define FPC_ABI_EABI in addition to FPC_ABI_EABIVFP on EABI VFP 
+    systems since most code needs to behave the same on both}
+  if target_info.abi = abi_eabivfp then def_system_macro('FPC_ABI_EABI');
+
   { Write logo }
   if option.ParaLogo then
     option.writelogo;
@@ -3051,6 +3055,22 @@
     end;
 
 {$ifdef arm}
+  if target_info.abi = abi_eabivfp then begin
+    if not(option.FPUSetExplicitly) then begin
+      init_settings.fputype:=fpu_vfpv3_d16
+    end else begin
+      if not (init_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16]) then begin
+        //fixme: figure out how to error out properly
+        writeln('You must use a FPU type of VFPV2, VFPV3 or VFPV3_D16 when using the EABIVFP ABI target');
+        halt;
+      end;
+    end;
+ 
+  end;
+{$endif arm}
+  
+
+{$ifdef arm}
 { set default cpu type to ARMv6 for Darwin unless specified otherwise }
 if (target_info.system=system_arm_darwin) then
   begin
@@ -3059,6 +3079,16 @@
     if not option.OptCPUSetExplicitly then
       init_settings.optimizecputype:=cpu_armv6;
   end;
+
+{ set default cpu type to ARMv7 for ARMHF unless specified otherwise }
+if (target_info.abi = abi_eabivfp) then 
+  begin
+    if not option.CPUSetExplicitly then
+      init_settings.cputype:=cpu_armv7;
+    if not option.OptCPUSetExplicitly then
+      init_settings.optimizecputype:=cpu_armv7;
+  end;
+
 {$endif arm}
 
   { now we can define cpu and fpu type }

Reply to: