* reworked arm vfp capability handling to use fpu_capabilites

git-svn-id: trunk@42679 -
This commit is contained in:
florian 2019-08-13 18:41:15 +00:00
parent 3ddefe999e
commit 85edf1c1eb
11 changed files with 151 additions and 175 deletions

View File

@ -2220,7 +2220,9 @@ implementation
IF_VFPv2,
IF_VFPv2 or IF_VFPv3,
IF_VFPv2 or IF_VFPv3,
IF_VFPv2 or IF_VFPv3,
IF_NONE,
IF_VFPv2 or IF_VFPv3 or IF_VFPv4,
IF_VFPv2 or IF_VFPv3 or IF_VFPv4
);
begin

View File

@ -104,18 +104,26 @@ unit agarmgas;
function TArmGNUAssembler.MakeCmdLine: TCmdStr;
begin
result:=inherited MakeCmdLine;
if (current_settings.fputype = fpu_soft) then
result:='-mfpu=softvfp '+result;
if (current_settings.fputype = fpu_vfpv2) then
result:='-mfpu=vfpv2 '+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.fputype = fpu_fpv4_s16) then
result:='-mfpu=fpv4-sp-d16 '+result;
if (current_settings.fputype = fpu_vfpv4) then
result:='-mfpu=vfpv4 '+result;
case current_settings.fputype of
fpu_soft:
result:='-mfpu=softvfp '+result;
fpu_vfpv2:
result:='-mfpu=vfpv2 '+result;
fpu_vfpv3:
result:='-mfpu=vfpv3 '+result;
fpu_neon_vfpv3:
result:='-mfpu=neon-vfpv3 '+result;
fpu_vfpv3_d16:
result:='-mfpu=vfpv3-d16 '+result;
fpu_fpv4_s16:
result:='-mfpu=fpv4-sp-d16 '+result;
fpu_vfpv4:
result:='-mfpu=vfpv4 '+result;
fpu_neon_vfpv4:
result:='-mfpu=neon-vfpv4 '+result;
else
;
end;
if GenerateThumb2Code then
result:='-march='+cputype_to_gas_march[current_settings.cputype]+' -mthumb -mthumb-interwork '+result

View File

@ -300,7 +300,7 @@ unit cgcpu;
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 in [fpu_vfpv3,fpu_vfpv4] then
if FPUARM_HAS_32REGS in fpu_capabilities[current_settings.fputype] 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,
@ -1926,16 +1926,13 @@ unit cgcpu;
inc(registerarea,12);
end;
end;
fpu_vfpv2,
fpu_vfpv3,
fpu_vfpv4,
fpu_vfpv3_d16:
else if FPUARM_HAS_32REGS in fpu_capabilities[current_settings.fputype] then
begin;
{ the *[0..31] is a hack to prevent that the compiler tries to save odd single-type registers,
they have numbers>$1f which is not really correct as they should simply have the same numbers
as the even ones by with a different subtype as it is done on x86 with al/ah }
mmregs:=(rg[R_MMREGISTER].used_in_proc-paramanager.get_volatile_registers_mm(pocall_stdcall))*[0..31];
end;
end
else
internalerror(2019050924);
end;
@ -2080,7 +2077,7 @@ unit cgcpu;
begin
reference_reset(ref,4,[]);
if (tg.direction*tcpuprocinfo(current_procinfo).floatregstart>=1023) or
(current_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv4,fpu_vfpv3_d16]) then
(FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype]) then
begin
if not is_shifter_const(tcpuprocinfo(current_procinfo).floatregstart,shift) then
begin
@ -2107,10 +2104,7 @@ unit cgcpu;
list.concat(taicpu.op_reg_const_ref(A_SFM,newreg(R_FPUREGISTER,firstfloatreg,R_SUBWHOLE),
lastfloatreg-firstfloatreg+1,ref));
end;
fpu_vfpv2,
fpu_vfpv3,
fpu_vfpv4,
fpu_vfpv3_d16:
else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype] then
begin
ref.index:=ref.base;
ref.base:=NR_NO;
@ -2121,7 +2115,7 @@ unit cgcpu;
postfix:=PF_IAD;}
if mmregs<>[] then
list.concat(taicpu.op_ref_regset(A_VSTM,ref,R_MMREGISTER,R_SUBFD,mmregs));
end;
end
else
internalerror(2019050923);
end;
@ -2175,17 +2169,14 @@ unit cgcpu;
}
end;
end;
fpu_vfpv2,
fpu_vfpv3,
fpu_vfpv4,
fpu_vfpv3_d16:
begin;
else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype] then
begin
{ restore vfp registers? }
{ the *[0..31] is a hack to prevent that the compiler tries to save odd single-type registers,
they have numbers>$1f which is not really correct as they should simply have the same numbers
as the even ones by with a different subtype as it is done on x86 with al/ah }
mmregs:=(rg[R_MMREGISTER].used_in_proc-paramanager.get_volatile_registers_mm(pocall_stdcall))*[0..31];
end;
end
else
internalerror(2019050926);
end;
@ -2195,7 +2186,7 @@ unit cgcpu;
begin
reference_reset(ref,4,[]);
if (tg.direction*tcpuprocinfo(current_procinfo).floatregstart>=1023) or
(current_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv4,fpu_vfpv3_d16]) then
(FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype]) then
begin
if not is_shifter_const(tcpuprocinfo(current_procinfo).floatregstart,shift) then
begin
@ -2221,10 +2212,7 @@ unit cgcpu;
list.concat(taicpu.op_reg_const_ref(A_LFM,newreg(R_FPUREGISTER,firstfloatreg,R_SUBWHOLE),
lastfloatreg-firstfloatreg+1,ref));
end;
fpu_vfpv2,
fpu_vfpv3,
fpu_vfpv4,
fpu_vfpv3_d16:
else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype] then
begin
ref.index:=ref.base;
ref.base:=NR_NO;
@ -2235,7 +2223,7 @@ unit cgcpu;
mmpostfix:=PF_IAD;}
if mmregs<>[] then
list.concat(taicpu.op_ref_regset(A_VLDM,ref,R_MMREGISTER,R_SUBFD,mmregs));
end;
end
else
internalerror(2019050921);
end;
@ -4313,13 +4301,13 @@ unit cgcpu;
rg[R_FPUREGISTER]:=trgcpu.create(R_FPUREGISTER,R_SUBNONE,
[RS_F0,RS_F1,RS_F2,RS_F3,RS_F4,RS_F5,RS_F6,RS_F7],first_fpu_imreg,[]);
if current_settings.fputype in [fpu_vfpv3,fpu_vfpv4] then
if FPUARM_HAS_32REGS in fpu_capabilities[current_settings.fputype] 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,
RS_D8,RS_D9,RS_D10,RS_D11,RS_D12,RS_D13,RS_D14,RS_D15
],first_mm_imreg,[])
else if current_settings.fputype in [fpu_fpv4_s16,fpu_vfpv3_d16] then
else if FPUARM_HAS_VFP_EXTENSION in fpu_capabilities[current_settings.fputype] 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_D8,RS_D9,RS_D10,RS_D11,RS_D12,RS_D13,RS_D14,RS_D15

View File

@ -68,17 +68,19 @@ Type
fpu_fpa11,
fpu_vfpv2,
fpu_vfpv3,
fpu_neon_vfpv3,
fpu_vfpv3_d16,
fpu_fpv4_s16,
fpu_vfpv4
fpu_vfpv4,
fpu_neon_vfpv4
{ when new elements added afterwards, update also fpu_vfp_last below }
);
Const
fpu_vfp_first = fpu_vfpv2;
fpu_vfp_last = fpu_vfpv4;
fpu_vfp_last = fpu_neon_vfpv4;
fputypestrllvm : array[tfputype] of string[13] = ('',
fputypestrllvm : array[tfputype] of string[14] = ('',
'',
'',
'',
@ -86,9 +88,11 @@ Const
'',
'fpu=vfpv2',
'fpu=vfpv3',
'fpu=neon-vfpv3',
'fpu=vfpv3-d16',
'fpu=vfpv4-s16',
'fpu=vfpv4'
'fpu=vfpv4',
'fpu=neon-vfpv4'
);
Type
@ -559,7 +563,7 @@ Const
'ARMV7EM'
);
fputypestr : array[tfputype] of string[9] = ('',
fputypestr : array[tfputype] of string[10] = ('',
'SOFT',
'LIBGCC',
'FPA',
@ -567,9 +571,11 @@ Const
'FPA11',
'VFPV2',
'VFPV3',
'NEON_VFPV3',
'VFPV3_D16',
'FPV4_S16',
'VFPV4'
'VFPV4',
'NEON_VFPV4'
);
@ -1018,8 +1024,6 @@ Const
(controllertypestr:'THUMB2_BARE'; controllerunitstr:'THUMB2_BARE'; cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000; flashsize:$00002000; srambase:$20000000; sramsize:$00000400)
);
vfp_scalar = [fpu_vfpv2,fpu_vfpv3,fpu_vfpv4,fpu_vfpv3_d16,fpu_fpv4_s16];
{ Supported optimizations, only used for information }
supported_optimizerswitches = genericlevel1optimizerswitches+
genericlevel2optimizerswitches+
@ -1055,9 +1059,14 @@ Const
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 }
FPUARM_HAS_VFP_EXTENSION, { fpu is a vfp extension }
FPUARM_HAS_VFP_DOUBLE, { vfp has double support }
FPUARM_HAS_VFP_SINGLE_ONLY, { vfp has only single support, disjunct to FPUARM_HAS_VFP_DOUBLE, for error checking }
FPUARM_HAS_32REGS, { vfp has 32 regs, without this flag, 16 are assumed }
FPUARM_HAS_VMOV_CONST, { vmov supports (some) real constants }
FPUARM_HAS_EXCEPTION_TRAPPING, { vfp does exceptions trapping }
FPUARM_HAS_NEON, { fpu has neon extensions }
FPUARM_HAS_FMA { fpu has fused multiply/add instructions }
);
const
@ -1084,17 +1093,19 @@ Const
);
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]
( { fpu_none } [],
{ fpu_soft } [],
{ fpu_libgcc } [],
{ fpu_fpa } [],
{ fpu_fpa10 } [],
{ fpu_fpa11 } [],
{ fpu_vfpv2 } [FPUARM_HAS_VFP_EXTENSION,FPUARM_HAS_VFP_DOUBLE],
{ fpu_vfpv3 } [FPUARM_HAS_VFP_EXTENSION,FPUARM_HAS_VFP_DOUBLE,FPUARM_HAS_32REGS,FPUARM_HAS_VMOV_CONST],
{ fpu_neon_vfpv3 } [FPUARM_HAS_VFP_EXTENSION,FPUARM_HAS_VFP_DOUBLE,FPUARM_HAS_32REGS,FPUARM_HAS_VMOV_CONST,FPUARM_HAS_NEON],
{ fpu_vfpv3_d16 } [FPUARM_HAS_VFP_EXTENSION,FPUARM_HAS_VFP_DOUBLE,FPUARM_HAS_VMOV_CONST],
{ fpu_fpv4_s16 } [FPUARM_HAS_VFP_EXTENSION,FPUARM_HAS_VFP_SINGLE_ONLY,FPUARM_HAS_VMOV_CONST],
{ fpu_vfpv4 } [FPUARM_HAS_VFP_EXTENSION,FPUARM_HAS_VFP_DOUBLE,FPUARM_HAS_32REGS,FPUARM_HAS_VMOV_CONST,FPUARM_HAS_FMA],
{ fpu_neon_vfpv4 } [FPUARM_HAS_VFP_EXTENSION,FPUARM_HAS_VFP_DOUBLE,FPUARM_HAS_32REGS,FPUARM_HAS_VMOV_CONST,FPUARM_HAS_NEON,FPUARM_HAS_FMA]
);
{ contains all CPU supporting any kind of thumb instruction set }

View File

@ -178,18 +178,15 @@ unit cpupi;
if firstfloatreg<>RS_NO then
floatsavesize:=(lastfloatreg-firstfloatreg+1)*12;
end;
fpu_vfpv2,
fpu_vfpv3,
fpu_vfpv4,
fpu_vfpv3_d16:
else if FPUARM_HAS_32REGS in fpu_capabilities[current_settings.fputype] then
begin
floatsavesize:=0;
regs:=cg.rg[R_MMREGISTER].used_in_proc-paramanager.get_volatile_registers_mm(pocall_stdcall);
for r:=RS_D0 to RS_D31 do
if r in regs then
inc(floatsavesize,8);
end;
fpu_fpv4_s16:
end
else
begin
floatsavesize:=0;
regs:=cg.rg[R_MMREGISTER].used_in_proc-paramanager.get_volatile_registers_mm(pocall_stdcall);

View File

@ -161,7 +161,7 @@ interface
function tarmaddnode.use_fma : boolean;
begin
Result:=current_settings.fputype in [fpu_vfpv4];
Result:=FPUARM_HAS_FMA in fpu_capabilities[current_settings.fputype];
end;
@ -205,10 +205,10 @@ interface
location.register,left.location.register,right.location.register),
cgsize2fpuoppostfix[def_cgsize(resultdef)]));
end;
fpu_vfpv2,
fpu_vfpv3,
fpu_vfpv4,
fpu_vfpv3_d16:
fpu_soft:
{ this case should be handled already by pass1 }
internalerror(200308252);
else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype] then
begin
{ force mmreg as location, left right doesn't matter
as both will be in a fpureg }
@ -239,8 +239,8 @@ interface
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(op,
location.register,left.location.register,right.location.register),pf));
cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
end;
fpu_fpv4_s16:
end
else if FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[current_settings.fputype] then
begin
{ force mmreg as location, left right doesn't matter
as both will be in a fpureg }
@ -265,10 +265,7 @@ interface
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(op, location.register,left.location.register,right.location.register), PF_F32));
cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
end;
fpu_soft:
{ this case should be handled already by pass1 }
internalerror(200308252);
end
else
internalerror(200308251);
end;
@ -307,10 +304,7 @@ interface
left.location.register,right.location.register),
cgsize2fpuoppostfix[def_cgsize(resultdef)]));
end;
fpu_vfpv2,
fpu_vfpv3,
fpu_vfpv4,
fpu_vfpv3_d16:
else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype] then
begin
hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,right.location,right.resultdef,true);
@ -331,8 +325,8 @@ interface
cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_VMRS,NR_APSR_nzcv,NR_FPSCR));
location.resflags:=GetFpuResFlags;
end;
fpu_fpv4_s16:
end
else if FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[current_settings.fputype] then
begin
hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,right.location,right.resultdef,true);
@ -347,7 +341,7 @@ interface
cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg(A_VMRS, NR_APSR_nzcv, NR_FPSCR));
end;
end
else
{ this case should be handled already by pass1 }
internalerror(2009112404);
@ -592,7 +586,7 @@ interface
result := nil;
notnode := false;
if current_settings.fputype = fpu_fpv4_s16 then
if FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[current_settings.fputype] then
begin
case tfloatdef(left.resultdef).floattype of
s32real:

View File

@ -78,7 +78,7 @@ implementation
{$ifdef cpufpemu}
(current_settings.fputype=fpu_soft) or
{$endif cpufpemu}
(current_settings.fputype=fpu_fpv4_s16) then
(FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[current_settings.fputype]) then
result:=inherited first_int_to_real
else
begin
@ -127,7 +127,7 @@ implementation
function tarmtypeconvnode.first_real_to_real: tnode;
begin
if (current_settings.fputype=fpu_fpv4_s16) then
if FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[current_settings.fputype] then
begin
case tfloatdef(left.resultdef).floattype of
s32real:
@ -240,10 +240,7 @@ implementation
end;
end;
end;
fpu_vfpv2,
fpu_vfpv3,
fpu_vfpv4,
fpu_vfpv3_d16:
else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype] then
begin
location_reset(location,LOC_MMREGISTER,def_cgsize(resultdef));
signed:=left.location.size=OS_S32;
@ -257,8 +254,8 @@ implementation
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VCVT,
location.register,left.location.register),
signedprec2vfppf[signed,location.size]));
end;
fpu_fpv4_s16:
end
else if FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[current_settings.fputype] then
begin
location_reset(location,LOC_MMREGISTER,def_cgsize(resultdef));
signed:=left.location.size=OS_S32;
@ -273,7 +270,7 @@ implementation
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VCVT,location.register,left.location.register), PF_F32S32))
else
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VCVT,location.register,left.location.register), PF_F32U32));
end;
end
else
{ should be handled in pass 1 }
internalerror(2019050934);

View File

@ -123,18 +123,15 @@ implementation
fpu_fpa10,
fpu_fpa11:
expectloc:=LOC_FPUREGISTER;
fpu_vfpv2,
fpu_vfpv3,
fpu_vfpv4,
fpu_vfpv3_d16:
expectloc:=LOC_MMREGISTER;
fpu_fpv4_s16:
else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype] then
expectloc:=LOC_MMREGISTER
else if FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[current_settings.fputype] then
begin
if tfloatdef(left.resultdef).floattype=s32real then
expectloc:=LOC_MMREGISTER
else
exit(inherited first_abs_real);
end;
end
else
internalerror(2009112401);
end;
@ -154,18 +151,15 @@ implementation
fpu_fpa10,
fpu_fpa11:
expectloc:=LOC_FPUREGISTER;
fpu_vfpv2,
fpu_vfpv3,
fpu_vfpv4,
fpu_vfpv3_d16:
expectloc:=LOC_MMREGISTER;
fpu_fpv4_s16:
else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype] then
expectloc:=LOC_MMREGISTER
else if FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[current_settings.fputype] then
begin
if tfloatdef(left.resultdef).floattype=s32real then
expectloc:=LOC_MMREGISTER
else
exit(inherited first_sqr_real);
end;
end
else
internalerror(2009112402);
end;
@ -185,18 +179,15 @@ implementation
fpu_fpa10,
fpu_fpa11:
expectloc:=LOC_FPUREGISTER;
fpu_vfpv2,
fpu_vfpv3,
fpu_vfpv4,
fpu_vfpv3_d16:
expectloc:=LOC_MMREGISTER;
fpu_fpv4_s16:
else if FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[current_settings.fputype] then
expectloc:=LOC_MMREGISTER
else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype] then
begin
if tfloatdef(left.resultdef).floattype=s32real then
expectloc:=LOC_MMREGISTER
else
exit(inherited first_sqrt_real);
end;
end
else
internalerror(2009112403);
end;
@ -258,23 +249,6 @@ implementation
fpu_fpa10,
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_vfpv4,
fpu_vfpv3_d16:
begin
if singleprec then
pf:=PF_F32
else
pf:=PF_F64;
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VABS,location.register,left.location.register),pf));
cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
end;
fpu_fpv4_s16:
begin
current_asmdata.CurrAsmList.Concat(setoppostfix(taicpu.op_reg_reg(A_VABS,location.register,left.location.register), PF_F32));
cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
end;
fpu_soft:
begin
if singleprec then
@ -282,8 +256,22 @@ implementation
else
cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_AND,OS_32,tcgint($7fffffff),location.registerhi);
end
else
internalerror(2009111402);
else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype] then
begin
if singleprec then
pf:=PF_F32
else
pf:=PF_F64;
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VABS,location.register,left.location.register),pf));
cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
end
else if FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[current_settings.fputype] then
begin
current_asmdata.CurrAsmList.Concat(setoppostfix(taicpu.op_reg_reg(A_VABS,location.register,left.location.register), PF_F32));
cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
end
else
internalerror(2009111402);
end;
end;
@ -299,10 +287,7 @@ implementation
fpu_fpa10,
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_vfpv4,
fpu_vfpv3_d16:
else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype] then
begin
if singleprec then
pf:=PF_F32
@ -310,14 +295,14 @@ implementation
pf:=PF_F64;
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_VMUL,location.register,left.location.register,left.location.register),pf));
cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
end;
fpu_fpv4_s16:
end
else if FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[current_settings.fputype] then
begin
current_asmdata.CurrAsmList.Concat(setoppostfix(taicpu.op_reg_reg_reg(A_VMUL,location.register,left.location.register,left.location.register), PF_F32));
cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
end;
else
internalerror(2009111403);
end
else
internalerror(2009111403);
end;
end;
@ -333,10 +318,7 @@ implementation
fpu_fpa10,
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_vfpv4,
fpu_vfpv3_d16:
else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype] then
begin
if singleprec then
pf:=PF_F32
@ -344,14 +326,14 @@ implementation
pf:=PF_F64;
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VSQRT,location.register,left.location.register),pf));
cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
end;
fpu_fpv4_s16:
end
else if FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[current_settings.fputype] then
begin
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VSQRT,location.register,left.location.register), PF_F32));
cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
end;
else
internalerror(2009111402);
end
else
internalerror(2009111402);
end;
end;
@ -465,7 +447,7 @@ implementation
negproduct : boolean;
oppostfix : TOpPostfix;
begin
if current_settings.fputype in [fpu_vfpv4] then
if FPUARM_HAS_FMA in fpu_capabilities[current_settings.fputype] then
begin
negop3:=false;
negproduct:=false;

View File

@ -367,7 +367,7 @@ implementation
exit;
end;
if (current_settings.fputype<>fpu_fpv4_s16) or
if (FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype]) or
(tfloatdef(resultdef).floattype=s32real) then
exit(inherited pass_1);
@ -418,10 +418,20 @@ implementation
location.register,left.location.register,0),
cgsize2fpuoppostfix[def_cgsize(resultdef)]));
end;
fpu_vfpv2,
fpu_vfpv3,
fpu_vfpv4,
fpu_vfpv3_d16:
fpu_soft:
begin
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
location:=left.location;
case location.size of
OS_32:
cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.register);
OS_64:
cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.registerhi);
else
internalerror(2014033101);
end;
end
else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[init_settings.fputype] then
begin
hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
location:=left.location;
@ -436,8 +446,8 @@ implementation
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VNEG,
location.register,left.location.register), pf));
cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
end;
fpu_fpv4_s16:
end
else if FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[init_settings.fputype] then
begin
hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
location:=left.location;
@ -446,19 +456,6 @@ implementation
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VNEG,
location.register,left.location.register), PF_F32));
cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
end;
fpu_soft:
begin
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
location:=left.location;
case location.size of
OS_32:
cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.register);
OS_64:
cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.registerhi);
else
internalerror(2014033101);
end;
end
else
internalerror(2009112602);

View File

@ -4244,7 +4244,7 @@ begin
end
else
begin
if not (init_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16,fpu_vfpv4]) then
if not(FPUARM_HAS_VFP_EXTENSION in fpu_capabilities[init_settings.fputype]) then
begin
Message(option_illegal_fpu_eabihf);
StopOptions(1);

View File

@ -8678,7 +8678,7 @@ implementation
{$endif x86}
{$ifdef arm}
{$define use_vectorfpuimplemented}
use_vectorfpu:=(current_settings.fputype in vfp_scalar);
use_vectorfpu:=FPUARM_HAS_VFP_EXTENSION in fpu_capabilities[current_settings.fputype];
{$endif arm}
{$ifdef aarch64}
{$define use_vectorfpuimplemented}