diff --git a/compiler/arm/cgcpu.pas b/compiler/arm/cgcpu.pas index 1f0809efe5..6e0b809619 100644 --- a/compiler/arm/cgcpu.pas +++ b/compiler/arm/cgcpu.pas @@ -1729,6 +1729,7 @@ unit cgcpu; l: TAsmLabel; begin if ((cs_check_fpu_exceptions in current_settings.localswitches) and + not(FPUARM_HAS_EXCEPTION_TRAPPING in fpu_capabilities[current_settings.fputype]) and (force or current_procinfo.FPUExceptionCheckNeeded)) then begin r:=getintregister(list,OS_INT); diff --git a/compiler/arm/cpuinfo.pas b/compiler/arm/cpuinfo.pas index f0ab792d3b..ab7850c340 100644 --- a/compiler/arm/cpuinfo.pas +++ b/compiler/arm/cpuinfo.pas @@ -71,9 +71,13 @@ Type fpu_vfpv3_d16, fpu_fpv4_s16, fpu_vfpv4 + { when new elements added afterwards, update also fpu_vfp_last below } ); Const + fpu_vfp_first = fpu_vfpv2; + fpu_vfp_last = fpu_vfpv4; + fputypestrllvm : array[tfputype] of string[13] = ('', '', '', @@ -1049,6 +1053,13 @@ Const CPUARM_HAS_UMULL ); + tfpuflags = + ( + FPUARM_HAS_VFP_EXTENSION, { fpu is a vfp extension } + FPUARM_HAS_VMOV_CONST, { vmov supports (some) real constants } + FPUARM_HAS_EXCEPTION_TRAPPING { vfp does exceptions trapping } + ); + const cpu_capabilities : array[tcputype] of set of tcpuflags = ( { cpu_none } [], @@ -1072,6 +1083,20 @@ Const { cpu_armv7em } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL] ); + fpu_capabilities : array[tfputype] of set of tfpuflags = + ( { fpu_none } [], + { fpu_soft } [], + { fpu_libgcc } [], + { fpu_fpa } [], + { fpu_fpa10 } [], + { fpu_fpa11 } [], + { fpu_vfpv2 } [FPUARM_HAS_VFP_EXTENSION], + { fpu_vfpv3 } [FPUARM_HAS_VFP_EXTENSION,FPUARM_HAS_VMOV_CONST], + { fpu_vfpv3_d16 } [FPUARM_HAS_VFP_EXTENSION,FPUARM_HAS_VMOV_CONST], + { fpu_fpv4_s16 } [FPUARM_HAS_VFP_EXTENSION,FPUARM_HAS_VMOV_CONST], + { fpu_vfpv4 } [FPUARM_HAS_VFP_EXTENSION,FPUARM_HAS_VMOV_CONST] + ); + { contains all CPU supporting any kind of thumb instruction set } cpu_has_thumb = [cpu_armv4t,cpu_armv5t,cpu_armv5te,cpu_armv5tej,cpu_armv6t2,cpu_armv6z,cpu_armv6m,cpu_armv7a,cpu_armv7r,cpu_armv7m,cpu_armv7em]; diff --git a/compiler/arm/cpupara.pas b/compiler/arm/cpupara.pas index 7480506887..b8dc761de9 100644 --- a/compiler/arm/cpupara.pas +++ b/compiler/arm/cpupara.pas @@ -149,7 +149,7 @@ unit cpupara; getparaloc:=LOC_MMREGISTER else if (calloption in cdecl_pocalls) or (cs_fp_emulation in current_settings.moduleswitches) or - (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv4,fpu_vfpv3_d16,fpu_fpv4_s16]) then + (current_settings.fputype in [fpu_vfp_first..fpu_vfp_last]) then { the ARM eabi also allows passing VFP values via VFP registers, but Mac OS X doesn't seem to do that and linux only does it if built with the "-mfloat-abi=hard" option } @@ -757,7 +757,7 @@ unit cpupara; end else if (p.proccalloption in [pocall_softfloat]) or (cs_fp_emulation in current_settings.moduleswitches) or - (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv4,fpu_vfpv3_d16,fpu_fpv4_s16]) then + (current_settings.fputype in [fpu_vfp_first..fpu_vfp_last]) then begin case retcgsize of OS_64, diff --git a/compiler/arm/narmcal.pas b/compiler/arm/narmcal.pas index cffe4deaac..5fb2f73f3c 100644 --- a/compiler/arm/narmcal.pas +++ b/compiler/arm/narmcal.pas @@ -83,7 +83,7 @@ implementation (target_info.abi<>abi_eabihf) and (procdefinition.proccalloption<>pocall_hardfloat) and ((cs_fp_emulation in current_settings.moduleswitches) or - (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv4,fpu_vfpv3_d16,fpu_fpv4_s16])) then + (current_settings.fputype in [fpu_vfp_first..fpu_vfp_last])) then begin { keep the fpu values in integer registers for now, the code generator will move them to memory or an mmregister when necessary diff --git a/compiler/arm/narmcnv.pas b/compiler/arm/narmcnv.pas index 3779729174..d666b73bbc 100644 --- a/compiler/arm/narmcnv.pas +++ b/compiler/arm/narmcnv.pas @@ -117,11 +117,7 @@ implementation fpu_fpa10, fpu_fpa11: expectloc:=LOC_FPUREGISTER; - fpu_vfpv2, - fpu_vfpv3, - fpu_vfpv4, - fpu_vfpv3_d16, - fpu_fpv4_s16: + fpu_vfp_first..fpu_vfp_last: expectloc:=LOC_MMREGISTER; else internalerror(2009112702); diff --git a/compiler/arm/narmcon.pas b/compiler/arm/narmcon.pas index 318431429d..29f96db770 100644 --- a/compiler/arm/narmcon.pas +++ b/compiler/arm/narmcon.pas @@ -54,7 +54,7 @@ interface function tarmrealconstnode.pass_1 : tnode; begin result:=nil; - if (current_settings.fputype in [fpu_vfpv3,fpu_vfpv4,fpu_vfpv3_d16,fpu_fpv4_s16]) and + if (FPUARM_HAS_VMOV_CONST in fpu_capabilities[current_settings.fputype]) and IsVFPFloatImmediate(tfloatdef(resultdef).floattype,value_real) then expectloc:=LOC_MMREGISTER else @@ -75,7 +75,7 @@ interface pf : TOpPostfix; begin - if (current_settings.fputype in [fpu_vfpv3,fpu_vfpv4,fpu_vfpv3_d16,fpu_fpv4_s16]) and + if (FPUARM_HAS_VMOV_CONST in fpu_capabilities[current_settings.fputype]) and IsVFPFloatImmediate(tfloatdef(resultdef).floattype,value_real) then begin location_reset(location,LOC_MMREGISTER,def_cgsize(resultdef)); diff --git a/compiler/arm/narminl.pas b/compiler/arm/narminl.pas index fbb9dfad31..b9282129b7 100644 --- a/compiler/arm/narminl.pas +++ b/compiler/arm/narminl.pas @@ -86,11 +86,7 @@ implementation location.loc := LOC_FPUREGISTER; end; end; - fpu_vfpv2, - fpu_vfpv3, - fpu_vfpv4, - fpu_vfpv3_d16, - fpu_fpv4_s16: + fpu_vfp_first..fpu_vfp_last: begin hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true); location_copy(location,left.location);