mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-05 13:46:11 +02:00
+ hardfloat directive (arm only): use hard float calling conventions regardless of the abi, resolves #29715
git-svn-id: trunk@33196 -
This commit is contained in:
parent
7005dec9b4
commit
cb4773432b
@ -499,7 +499,9 @@ Const
|
|||||||
reference, but that's already done for stdcall) }
|
reference, but that's already done for stdcall) }
|
||||||
pocall_mwpascal,
|
pocall_mwpascal,
|
||||||
{ used for interrupt handling }
|
{ used for interrupt handling }
|
||||||
pocall_interrupt
|
pocall_interrupt,
|
||||||
|
{ needed sometimes on android }
|
||||||
|
pocall_hardfloat
|
||||||
];
|
];
|
||||||
|
|
||||||
cputypestr : array[tcputype] of string[8] = ('',
|
cputypestr : array[tcputype] of string[8] = ('',
|
||||||
|
@ -129,7 +129,7 @@ unit cpupara;
|
|||||||
orddef:
|
orddef:
|
||||||
getparaloc:=LOC_REGISTER;
|
getparaloc:=LOC_REGISTER;
|
||||||
floatdef:
|
floatdef:
|
||||||
if (target_info.abi = abi_eabihf) and
|
if ((target_info.abi=abi_eabihf) or (calloption=pocall_hardfloat)) and
|
||||||
(not isvariadic) then
|
(not isvariadic) then
|
||||||
getparaloc:=LOC_MMREGISTER
|
getparaloc:=LOC_MMREGISTER
|
||||||
else if (calloption in [pocall_cdecl,pocall_cppdecl,pocall_softfloat]) or
|
else if (calloption in [pocall_cdecl,pocall_cppdecl,pocall_softfloat]) or
|
||||||
@ -626,7 +626,7 @@ unit cpupara;
|
|||||||
{ Return in FPU register? }
|
{ Return in FPU register? }
|
||||||
if result.def.typ=floatdef then
|
if result.def.typ=floatdef then
|
||||||
begin
|
begin
|
||||||
if target_info.abi = abi_eabihf then
|
if (target_info.abi=abi_eabihf) or (p.proccalloption=pocall_hardfloat) then
|
||||||
begin
|
begin
|
||||||
paraloc^.loc:=LOC_MMREGISTER;
|
paraloc^.loc:=LOC_MMREGISTER;
|
||||||
case retcgsize of
|
case retcgsize of
|
||||||
|
@ -45,7 +45,8 @@ implementation
|
|||||||
procedure tarmcallnode.set_result_location(realresdef: tstoreddef);
|
procedure tarmcallnode.set_result_location(realresdef: tstoreddef);
|
||||||
begin
|
begin
|
||||||
if (realresdef.typ=floatdef) and
|
if (realresdef.typ=floatdef) and
|
||||||
(target_info.abi <> abi_eabihf) and
|
(target_info.abi<>abi_eabihf) and
|
||||||
|
(procdefinition.proccalloption<>pocall_hardfloat) and
|
||||||
((cs_fp_emulation in current_settings.moduleswitches) 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_vfpv2,fpu_vfpv3,fpu_vfpv4,fpu_vfpv3_d16,fpu_fpv4_s16])) then
|
||||||
begin
|
begin
|
||||||
|
@ -1089,7 +1089,8 @@ implementation
|
|||||||
'STDCALL',
|
'STDCALL',
|
||||||
'SOFTFLOAT',
|
'SOFTFLOAT',
|
||||||
'MWPASCAL',
|
'MWPASCAL',
|
||||||
'INTERRUPT'
|
'INTERRUPT',
|
||||||
|
'HARDFLOAT'
|
||||||
);
|
);
|
||||||
var
|
var
|
||||||
t : tproccalloption;
|
t : tproccalloption;
|
||||||
|
@ -523,7 +523,10 @@ interface
|
|||||||
{ constant records by reference. }
|
{ constant records by reference. }
|
||||||
pocall_mwpascal,
|
pocall_mwpascal,
|
||||||
{ Special interrupt handler for embedded systems }
|
{ Special interrupt handler for embedded systems }
|
||||||
pocall_interrupt
|
pocall_interrupt,
|
||||||
|
{ Directive for arm: pass floating point values in (v)float registers
|
||||||
|
regardless of the actual calling conventions }
|
||||||
|
pocall_hardfloat
|
||||||
);
|
);
|
||||||
tproccalloptions = set of tproccalloption;
|
tproccalloptions = set of tproccalloption;
|
||||||
|
|
||||||
@ -541,7 +544,8 @@ interface
|
|||||||
'StdCall',
|
'StdCall',
|
||||||
'SoftFloat',
|
'SoftFloat',
|
||||||
'MWPascal',
|
'MWPascal',
|
||||||
'Interrupt'
|
'Interrupt',
|
||||||
|
'HardFloat'
|
||||||
);
|
);
|
||||||
|
|
||||||
{ Default calling convention }
|
{ Default calling convention }
|
||||||
|
@ -416,7 +416,7 @@ scan_e_illegal_asmcpu_specifier=02099_E_Illegal assembler CPU instruction set sp
|
|||||||
#
|
#
|
||||||
# Parser
|
# Parser
|
||||||
#
|
#
|
||||||
# 03344 is the last used one
|
# 03345 is the last used one
|
||||||
#
|
#
|
||||||
% \section{Parser messages}
|
% \section{Parser messages}
|
||||||
% This section lists all parser messages. The parser takes care of the
|
% This section lists all parser messages. The parser takes care of the
|
||||||
@ -1550,6 +1550,8 @@ parser_e_genfuncs_cannot_be_virtual=03343_E_Generic methods can not be virtual
|
|||||||
parser_e_packages_not_supported=03344_E_Dynamic packages not supported for target OS
|
parser_e_packages_not_supported=03344_E_Dynamic packages not supported for target OS
|
||||||
% Support for dynamic packages is not implemented for the specified target OS
|
% Support for dynamic packages is not implemented for the specified target OS
|
||||||
% or it is at least not tested and thus disabled.
|
% or it is at least not tested and thus disabled.
|
||||||
|
parser_e_cannot_use_hardfloat_in_a_softfloat_environment=03345_E_The HardFloat directive cannot be used if soft float code is generated or fpu emulation is turned on
|
||||||
|
% The \var{HardFloat} directive can only be used if an instruction set is used which supports floating point operations.
|
||||||
%
|
%
|
||||||
%
|
%
|
||||||
% \end{description}
|
% \end{description}
|
||||||
|
@ -448,6 +448,7 @@ const
|
|||||||
parser_e_no_genfuncs_in_interfaces=03342;
|
parser_e_no_genfuncs_in_interfaces=03342;
|
||||||
parser_e_genfuncs_cannot_be_virtual=03343;
|
parser_e_genfuncs_cannot_be_virtual=03343;
|
||||||
parser_e_packages_not_supported=03344;
|
parser_e_packages_not_supported=03344;
|
||||||
|
parser_e_cannot_use_hardfloat_in_a_softfloat_environment=03345;
|
||||||
type_e_mismatch=04000;
|
type_e_mismatch=04000;
|
||||||
type_e_incompatible_types=04001;
|
type_e_incompatible_types=04001;
|
||||||
type_e_not_equal_types=04002;
|
type_e_not_equal_types=04002;
|
||||||
@ -1027,9 +1028,9 @@ const
|
|||||||
option_info=11024;
|
option_info=11024;
|
||||||
option_help_pages=11025;
|
option_help_pages=11025;
|
||||||
|
|
||||||
MsgTxtSize = 76872;
|
MsgTxtSize = 76981;
|
||||||
|
|
||||||
MsgIdxMax : array[1..20] of longint=(
|
MsgIdxMax : array[1..20] of longint=(
|
||||||
27,100,345,124,96,58,130,33,208,64,
|
27,100,346,124,96,58,130,33,208,64,
|
||||||
58,20,1,1,1,1,1,1,1,1
|
58,20,1,1,1,1,1,1,1,1
|
||||||
);
|
);
|
||||||
|
1076
compiler/msgtxt.inc
1076
compiler/msgtxt.inc
File diff suppressed because it is too large
Load Diff
@ -870,7 +870,8 @@ implementation
|
|||||||
{ pocall_stdcall } 3,
|
{ pocall_stdcall } 3,
|
||||||
{ pocall_softfloat } 10,
|
{ pocall_softfloat } 10,
|
||||||
{ pocall_mwpascal } 11,
|
{ pocall_mwpascal } 11,
|
||||||
{ pocall_interrupt } 12
|
{ pocall_interrupt } 12,
|
||||||
|
{ pocall_hardfloat } 13
|
||||||
);
|
);
|
||||||
|
|
||||||
procedure write_param_flag(parasym:tparavarsym);
|
procedure write_param_flag(parasym:tparavarsym);
|
||||||
|
@ -2315,6 +2315,7 @@ begin
|
|||||||
pd_external(pd);
|
pd_external(pd);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure pd_winapi(pd:tabstractprocdef);
|
procedure pd_winapi(pd:tabstractprocdef);
|
||||||
begin
|
begin
|
||||||
if not(target_info.system in systems_wince) then
|
if not(target_info.system in systems_wince) then
|
||||||
@ -2323,6 +2324,17 @@ begin
|
|||||||
pd.proccalloption:=pocall_stdcall;
|
pd.proccalloption:=pocall_stdcall;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure pd_hardfloat(pd:tabstractprocdef);
|
||||||
|
begin
|
||||||
|
if
|
||||||
|
{$if defined(arm)}
|
||||||
|
(current_settings.fputype=fpu_soft) or
|
||||||
|
{$endif defined(arm)}
|
||||||
|
(cs_fp_emulation in current_settings.moduleswitches) then
|
||||||
|
message(parser_e_cannot_use_hardfloat_in_a_softfloat_environment);
|
||||||
|
end;
|
||||||
|
|
||||||
type
|
type
|
||||||
pd_handler=procedure(pd:tabstractprocdef);
|
pd_handler=procedure(pd:tabstractprocdef);
|
||||||
proc_dir_rec=record
|
proc_dir_rec=record
|
||||||
@ -2337,7 +2349,7 @@ type
|
|||||||
end;
|
end;
|
||||||
const
|
const
|
||||||
{Should contain the number of procedure directives we support.}
|
{Should contain the number of procedure directives we support.}
|
||||||
num_proc_directives=45;
|
num_proc_directives=46;
|
||||||
proc_direcdata:array[1..num_proc_directives] of proc_dir_rec=
|
proc_direcdata:array[1..num_proc_directives] of proc_dir_rec=
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
@ -2757,6 +2769,17 @@ const
|
|||||||
mutexclpocall : [];
|
mutexclpocall : [];
|
||||||
mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
|
mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
|
||||||
mutexclpo : [po_interrupt]
|
mutexclpo : [po_interrupt]
|
||||||
|
),(
|
||||||
|
idtok:_HARDFLOAT;
|
||||||
|
pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
|
||||||
|
handler : @pd_hardfloat;
|
||||||
|
pocall : pocall_hardfloat;
|
||||||
|
pooption : [];
|
||||||
|
mutexclpocall : [];
|
||||||
|
mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
|
||||||
|
{ it's available with po_external because the libgcc floating point routines on the arm
|
||||||
|
uses this calling convention }
|
||||||
|
mutexclpo : []
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -246,6 +246,7 @@ type
|
|||||||
_ASSEMBLER,
|
_ASSEMBLER,
|
||||||
_BITPACKED,
|
_BITPACKED,
|
||||||
_BITWISEOR,
|
_BITWISEOR,
|
||||||
|
_HARDFLOAT,
|
||||||
_INHERITED,
|
_INHERITED,
|
||||||
_INTDIVIDE,
|
_INTDIVIDE,
|
||||||
_INTERFACE,
|
_INTERFACE,
|
||||||
@ -566,6 +567,7 @@ const
|
|||||||
(str:'ASSEMBLER' ;special:false;keyword:[m_none];op:NOTOKEN),
|
(str:'ASSEMBLER' ;special:false;keyword:[m_none];op:NOTOKEN),
|
||||||
(str:'BITPACKED' ;special:false;keyword:alllanguagemodes-[m_iso,m_extpas];op:NOTOKEN),
|
(str:'BITPACKED' ;special:false;keyword:alllanguagemodes-[m_iso,m_extpas];op:NOTOKEN),
|
||||||
(str:'BITWISEOR' ;special:false;keyword:[m_none];op:NOTOKEN), { delphi operator name }
|
(str:'BITWISEOR' ;special:false;keyword:[m_none];op:NOTOKEN), { delphi operator name }
|
||||||
|
(str:'HARDFLOAT' ;special:false;keyword:[m_none];op:NOTOKEN),
|
||||||
(str:'INHERITED' ;special:false;keyword:alllanguagemodes-[m_iso,m_extpas];op:NOTOKEN),
|
(str:'INHERITED' ;special:false;keyword:alllanguagemodes-[m_iso,m_extpas];op:NOTOKEN),
|
||||||
(str:'INTDIVIDE' ;special:false;keyword:[m_none];op:NOTOKEN), { delphi operator name }
|
(str:'INTDIVIDE' ;special:false;keyword:[m_none];op:NOTOKEN), { delphi operator name }
|
||||||
(str:'INTERFACE' ;special:false;keyword:alllanguagemodes-[m_iso,m_extpas];op:NOTOKEN),
|
(str:'INTERFACE' ;special:false;keyword:alllanguagemodes-[m_iso,m_extpas];op:NOTOKEN),
|
||||||
|
Loading…
Reference in New Issue
Block a user