* 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,
IF_VFPv2 or IF_VFPv3, IF_VFPv2 or IF_VFPv3,
IF_VFPv2 or IF_VFPv3, IF_VFPv2 or IF_VFPv3,
IF_VFPv2 or IF_VFPv3,
IF_NONE, IF_NONE,
IF_VFPv2 or IF_VFPv3 or IF_VFPv4,
IF_VFPv2 or IF_VFPv3 or IF_VFPv4 IF_VFPv2 or IF_VFPv3 or IF_VFPv4
); );
begin begin

View File

@ -104,18 +104,26 @@ unit agarmgas;
function TArmGNUAssembler.MakeCmdLine: TCmdStr; function TArmGNUAssembler.MakeCmdLine: TCmdStr;
begin begin
result:=inherited MakeCmdLine; result:=inherited MakeCmdLine;
if (current_settings.fputype = fpu_soft) then case current_settings.fputype of
result:='-mfpu=softvfp '+result; fpu_soft:
if (current_settings.fputype = fpu_vfpv2) then result:='-mfpu=softvfp '+result;
result:='-mfpu=vfpv2 '+result; fpu_vfpv2:
if (current_settings.fputype = fpu_vfpv3) then result:='-mfpu=vfpv2 '+result;
result:='-mfpu=vfpv3 '+result; fpu_vfpv3:
if (current_settings.fputype = fpu_vfpv3_d16) then result:='-mfpu=vfpv3 '+result;
result:='-mfpu=vfpv3-d16 '+result; fpu_neon_vfpv3:
if (current_settings.fputype = fpu_fpv4_s16) then result:='-mfpu=neon-vfpv3 '+result;
result:='-mfpu=fpv4-sp-d16 '+result; fpu_vfpv3_d16:
if (current_settings.fputype = fpu_vfpv4) then result:='-mfpu=vfpv3-d16 '+result;
result:='-mfpu=vfpv4 '+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 if GenerateThumb2Code then
result:='-march='+cputype_to_gas_march[current_settings.cputype]+' -mthumb -mthumb-interwork '+result 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 non-overlapping subregs per register, so we can only use
half the single precision registers for now (as sub registers of the half the single precision registers for now (as sub registers of the
double precision ones). } 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, 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_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_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); inc(registerarea,12);
end; end;
end; end;
fpu_vfpv2, else if FPUARM_HAS_32REGS in fpu_capabilities[current_settings.fputype] then
fpu_vfpv3,
fpu_vfpv4,
fpu_vfpv3_d16:
begin; begin;
{ the *[0..31] is a hack to prevent that the compiler tries to save odd single-type 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 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 } 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]; mmregs:=(rg[R_MMREGISTER].used_in_proc-paramanager.get_volatile_registers_mm(pocall_stdcall))*[0..31];
end; end
else else
internalerror(2019050924); internalerror(2019050924);
end; end;
@ -2080,7 +2077,7 @@ unit cgcpu;
begin begin
reference_reset(ref,4,[]); reference_reset(ref,4,[]);
if (tg.direction*tcpuprocinfo(current_procinfo).floatregstart>=1023) or 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 begin
if not is_shifter_const(tcpuprocinfo(current_procinfo).floatregstart,shift) then if not is_shifter_const(tcpuprocinfo(current_procinfo).floatregstart,shift) then
begin begin
@ -2107,10 +2104,7 @@ unit cgcpu;
list.concat(taicpu.op_reg_const_ref(A_SFM,newreg(R_FPUREGISTER,firstfloatreg,R_SUBWHOLE), list.concat(taicpu.op_reg_const_ref(A_SFM,newreg(R_FPUREGISTER,firstfloatreg,R_SUBWHOLE),
lastfloatreg-firstfloatreg+1,ref)); lastfloatreg-firstfloatreg+1,ref));
end; end;
fpu_vfpv2, else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype] then
fpu_vfpv3,
fpu_vfpv4,
fpu_vfpv3_d16:
begin begin
ref.index:=ref.base; ref.index:=ref.base;
ref.base:=NR_NO; ref.base:=NR_NO;
@ -2121,7 +2115,7 @@ unit cgcpu;
postfix:=PF_IAD;} postfix:=PF_IAD;}
if mmregs<>[] then if mmregs<>[] then
list.concat(taicpu.op_ref_regset(A_VSTM,ref,R_MMREGISTER,R_SUBFD,mmregs)); list.concat(taicpu.op_ref_regset(A_VSTM,ref,R_MMREGISTER,R_SUBFD,mmregs));
end; end
else else
internalerror(2019050923); internalerror(2019050923);
end; end;
@ -2175,17 +2169,14 @@ unit cgcpu;
} }
end; end;
end; end;
fpu_vfpv2, else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype] then
fpu_vfpv3, begin
fpu_vfpv4,
fpu_vfpv3_d16:
begin;
{ restore vfp registers? } { restore vfp registers? }
{ the *[0..31] is a hack to prevent that the compiler tries to save odd single-type 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 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 } 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]; mmregs:=(rg[R_MMREGISTER].used_in_proc-paramanager.get_volatile_registers_mm(pocall_stdcall))*[0..31];
end; end
else else
internalerror(2019050926); internalerror(2019050926);
end; end;
@ -2195,7 +2186,7 @@ unit cgcpu;
begin begin
reference_reset(ref,4,[]); reference_reset(ref,4,[]);
if (tg.direction*tcpuprocinfo(current_procinfo).floatregstart>=1023) or 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 begin
if not is_shifter_const(tcpuprocinfo(current_procinfo).floatregstart,shift) then if not is_shifter_const(tcpuprocinfo(current_procinfo).floatregstart,shift) then
begin begin
@ -2221,10 +2212,7 @@ unit cgcpu;
list.concat(taicpu.op_reg_const_ref(A_LFM,newreg(R_FPUREGISTER,firstfloatreg,R_SUBWHOLE), list.concat(taicpu.op_reg_const_ref(A_LFM,newreg(R_FPUREGISTER,firstfloatreg,R_SUBWHOLE),
lastfloatreg-firstfloatreg+1,ref)); lastfloatreg-firstfloatreg+1,ref));
end; end;
fpu_vfpv2, else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype] then
fpu_vfpv3,
fpu_vfpv4,
fpu_vfpv3_d16:
begin begin
ref.index:=ref.base; ref.index:=ref.base;
ref.base:=NR_NO; ref.base:=NR_NO;
@ -2235,7 +2223,7 @@ unit cgcpu;
mmpostfix:=PF_IAD;} mmpostfix:=PF_IAD;}
if mmregs<>[] then if mmregs<>[] then
list.concat(taicpu.op_ref_regset(A_VLDM,ref,R_MMREGISTER,R_SUBFD,mmregs)); list.concat(taicpu.op_ref_regset(A_VLDM,ref,R_MMREGISTER,R_SUBFD,mmregs));
end; end
else else
internalerror(2019050921); internalerror(2019050921);
end; end;
@ -4313,13 +4301,13 @@ unit cgcpu;
rg[R_FPUREGISTER]:=trgcpu.create(R_FPUREGISTER,R_SUBNONE, 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,[]); [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, 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_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_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 RS_D8,RS_D9,RS_D10,RS_D11,RS_D12,RS_D13,RS_D14,RS_D15
],first_mm_imreg,[]) ],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, 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_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 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_fpa11,
fpu_vfpv2, fpu_vfpv2,
fpu_vfpv3, fpu_vfpv3,
fpu_neon_vfpv3,
fpu_vfpv3_d16, fpu_vfpv3_d16,
fpu_fpv4_s16, fpu_fpv4_s16,
fpu_vfpv4 fpu_vfpv4,
fpu_neon_vfpv4
{ when new elements added afterwards, update also fpu_vfp_last below } { when new elements added afterwards, update also fpu_vfp_last below }
); );
Const Const
fpu_vfp_first = fpu_vfpv2; 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=vfpv2',
'fpu=vfpv3', 'fpu=vfpv3',
'fpu=neon-vfpv3',
'fpu=vfpv3-d16', 'fpu=vfpv3-d16',
'fpu=vfpv4-s16', 'fpu=vfpv4-s16',
'fpu=vfpv4' 'fpu=vfpv4',
'fpu=neon-vfpv4'
); );
Type Type
@ -559,7 +563,7 @@ Const
'ARMV7EM' 'ARMV7EM'
); );
fputypestr : array[tfputype] of string[9] = ('', fputypestr : array[tfputype] of string[10] = ('',
'SOFT', 'SOFT',
'LIBGCC', 'LIBGCC',
'FPA', 'FPA',
@ -567,9 +571,11 @@ Const
'FPA11', 'FPA11',
'VFPV2', 'VFPV2',
'VFPV3', 'VFPV3',
'NEON_VFPV3',
'VFPV3_D16', 'VFPV3_D16',
'FPV4_S16', '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) (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 optimizations, only used for information }
supported_optimizerswitches = genericlevel1optimizerswitches+ supported_optimizerswitches = genericlevel1optimizerswitches+
genericlevel2optimizerswitches+ genericlevel2optimizerswitches+
@ -1055,9 +1059,14 @@ Const
tfpuflags = tfpuflags =
( (
FPUARM_HAS_VFP_EXTENSION, { fpu is a vfp extension } FPUARM_HAS_VFP_EXTENSION, { fpu is a vfp extension }
FPUARM_HAS_VMOV_CONST, { vmov supports (some) real constants } FPUARM_HAS_VFP_DOUBLE, { vfp has double support }
FPUARM_HAS_EXCEPTION_TRAPPING { vfp does exceptions trapping } 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 const
@ -1084,17 +1093,19 @@ Const
); );
fpu_capabilities : array[tfputype] of set of tfpuflags = fpu_capabilities : array[tfputype] of set of tfpuflags =
( { fpu_none } [], ( { fpu_none } [],
{ fpu_soft } [], { fpu_soft } [],
{ fpu_libgcc } [], { fpu_libgcc } [],
{ fpu_fpa } [], { fpu_fpa } [],
{ fpu_fpa10 } [], { fpu_fpa10 } [],
{ fpu_fpa11 } [], { fpu_fpa11 } [],
{ fpu_vfpv2 } [FPUARM_HAS_VFP_EXTENSION], { fpu_vfpv2 } [FPUARM_HAS_VFP_EXTENSION,FPUARM_HAS_VFP_DOUBLE],
{ fpu_vfpv3 } [FPUARM_HAS_VFP_EXTENSION,FPUARM_HAS_VMOV_CONST], { fpu_vfpv3 } [FPUARM_HAS_VFP_EXTENSION,FPUARM_HAS_VFP_DOUBLE,FPUARM_HAS_32REGS,FPUARM_HAS_VMOV_CONST],
{ fpu_vfpv3_d16 } [FPUARM_HAS_VFP_EXTENSION,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_fpv4_s16 } [FPUARM_HAS_VFP_EXTENSION,FPUARM_HAS_VMOV_CONST], { fpu_vfpv3_d16 } [FPUARM_HAS_VFP_EXTENSION,FPUARM_HAS_VFP_DOUBLE,FPUARM_HAS_VMOV_CONST],
{ fpu_vfpv4 } [FPUARM_HAS_VFP_EXTENSION,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 } { contains all CPU supporting any kind of thumb instruction set }

View File

@ -178,18 +178,15 @@ unit cpupi;
if firstfloatreg<>RS_NO then if firstfloatreg<>RS_NO then
floatsavesize:=(lastfloatreg-firstfloatreg+1)*12; floatsavesize:=(lastfloatreg-firstfloatreg+1)*12;
end; end;
fpu_vfpv2, else if FPUARM_HAS_32REGS in fpu_capabilities[current_settings.fputype] then
fpu_vfpv3,
fpu_vfpv4,
fpu_vfpv3_d16:
begin begin
floatsavesize:=0; floatsavesize:=0;
regs:=cg.rg[R_MMREGISTER].used_in_proc-paramanager.get_volatile_registers_mm(pocall_stdcall); regs:=cg.rg[R_MMREGISTER].used_in_proc-paramanager.get_volatile_registers_mm(pocall_stdcall);
for r:=RS_D0 to RS_D31 do for r:=RS_D0 to RS_D31 do
if r in regs then if r in regs then
inc(floatsavesize,8); inc(floatsavesize,8);
end; end
fpu_fpv4_s16: else
begin begin
floatsavesize:=0; floatsavesize:=0;
regs:=cg.rg[R_MMREGISTER].used_in_proc-paramanager.get_volatile_registers_mm(pocall_stdcall); 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; function tarmaddnode.use_fma : boolean;
begin begin
Result:=current_settings.fputype in [fpu_vfpv4]; Result:=FPUARM_HAS_FMA in fpu_capabilities[current_settings.fputype];
end; end;
@ -205,10 +205,10 @@ interface
location.register,left.location.register,right.location.register), location.register,left.location.register,right.location.register),
cgsize2fpuoppostfix[def_cgsize(resultdef)])); cgsize2fpuoppostfix[def_cgsize(resultdef)]));
end; end;
fpu_vfpv2, fpu_soft:
fpu_vfpv3, { this case should be handled already by pass1 }
fpu_vfpv4, internalerror(200308252);
fpu_vfpv3_d16: else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype] then
begin begin
{ force mmreg as location, left right doesn't matter { force mmreg as location, left right doesn't matter
as both will be in a fpureg } as both will be in a fpureg }
@ -239,8 +239,8 @@ interface
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(op, current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(op,
location.register,left.location.register,right.location.register),pf)); location.register,left.location.register,right.location.register),pf));
cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList); cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
end; end
fpu_fpv4_s16: else if FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[current_settings.fputype] then
begin begin
{ force mmreg as location, left right doesn't matter { force mmreg as location, left right doesn't matter
as both will be in a fpureg } 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)); 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); cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
end; end
fpu_soft:
{ this case should be handled already by pass1 }
internalerror(200308252);
else else
internalerror(200308251); internalerror(200308251);
end; end;
@ -307,10 +304,7 @@ interface
left.location.register,right.location.register), left.location.register,right.location.register),
cgsize2fpuoppostfix[def_cgsize(resultdef)])); cgsize2fpuoppostfix[def_cgsize(resultdef)]));
end; end;
fpu_vfpv2, else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype] then
fpu_vfpv3,
fpu_vfpv4,
fpu_vfpv3_d16:
begin begin
hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true); hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,right.location,right.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); cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_VMRS,NR_APSR_nzcv,NR_FPSCR)); current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_VMRS,NR_APSR_nzcv,NR_FPSCR));
location.resflags:=GetFpuResFlags; location.resflags:=GetFpuResFlags;
end; end
fpu_fpv4_s16: else if FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[current_settings.fputype] then
begin begin
hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true); hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,right.location,right.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.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS); cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg(A_VMRS, NR_APSR_nzcv, NR_FPSCR)); current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg(A_VMRS, NR_APSR_nzcv, NR_FPSCR));
end; end
else else
{ this case should be handled already by pass1 } { this case should be handled already by pass1 }
internalerror(2009112404); internalerror(2009112404);
@ -592,7 +586,7 @@ interface
result := nil; result := nil;
notnode := false; notnode := false;
if current_settings.fputype = fpu_fpv4_s16 then if FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[current_settings.fputype] then
begin begin
case tfloatdef(left.resultdef).floattype of case tfloatdef(left.resultdef).floattype of
s32real: s32real:

View File

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

View File

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

View File

@ -367,7 +367,7 @@ implementation
exit; exit;
end; 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 (tfloatdef(resultdef).floattype=s32real) then
exit(inherited pass_1); exit(inherited pass_1);
@ -418,10 +418,20 @@ implementation
location.register,left.location.register,0), location.register,left.location.register,0),
cgsize2fpuoppostfix[def_cgsize(resultdef)])); cgsize2fpuoppostfix[def_cgsize(resultdef)]));
end; end;
fpu_vfpv2, fpu_soft:
fpu_vfpv3, begin
fpu_vfpv4, hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
fpu_vfpv3_d16: 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 begin
hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true); hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
location:=left.location; location:=left.location;
@ -436,8 +446,8 @@ implementation
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VNEG, current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VNEG,
location.register,left.location.register), pf)); location.register,left.location.register), pf));
cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList); cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
end; end
fpu_fpv4_s16: else if FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[init_settings.fputype] then
begin begin
hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true); hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
location:=left.location; location:=left.location;
@ -446,19 +456,6 @@ implementation
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VNEG, current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VNEG,
location.register,left.location.register), PF_F32)); location.register,left.location.register), PF_F32));
cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList); 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 end
else else
internalerror(2009112602); internalerror(2009112602);

View File

@ -4244,7 +4244,7 @@ begin
end end
else else
begin 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 begin
Message(option_illegal_fpu_eabihf); Message(option_illegal_fpu_eabihf);
StopOptions(1); StopOptions(1);

View File

@ -8678,7 +8678,7 @@ implementation
{$endif x86} {$endif x86}
{$ifdef arm} {$ifdef arm}
{$define use_vectorfpuimplemented} {$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} {$endif arm}
{$ifdef aarch64} {$ifdef aarch64}
{$define use_vectorfpuimplemented} {$define use_vectorfpuimplemented}