fpc/compiler/aarch64/naarch64util.pas
2024-03-05 07:56:14 +00:00

165 lines
4.5 KiB
ObjectPascal

{
Copyright (c) 1998-2022 by the Free Pascal development team
AArch64 version of some node tree helper routines
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit naarch64util;
{$i fpcdefs.inc}
interface
uses
cclasses, ngenutil, fmodule;
type
TAArch64NodeUtils = class(TNodeUtils)
class procedure InsertObjectInfo; override;
class procedure Insert_Init_Final_Table(main: tmodule; Entries: TFPList); override;
end;
implementation
uses
verbose,
systems,
globals,
cpuinfo,cpubase,
cgbase,cgutils,
aasmbase,aasmdata,aasmtai,aasmcpu,
symdef;
class procedure TAArch64NodeUtils.InsertObjectInfo;
begin
inherited InsertObjectInfo;
end;
{
TODO: This is a simple skeleton, not nearly as complex as the
ARM (32-bit) version in compiler/arm/narmutil.pas
}
class procedure TAArch64NodeUtils.Insert_Init_Final_Table(main: tmodule; Entries: TFPList);
procedure GenEntry(List: TAsmList);
var
Ref: TReference;
pairreg: TRegister;
rt: TRegisterType;
sub: TSubRegister;
sr: TSuperRegister;
begin
{ generate `stp x29, x30, [sp, #-16]!` }
reference_reset_base(ref, NR_SP, -16, ctempposinvalid, 16, []);
ref.addressmode := AM_PREINDEXED;
rt := R_INTREGISTER;
sub := R_SUBWHOLE;
sr := RS_X29;
pairreg := newreg(rt, sr, sub);
sr := RS_X30;
List.Concat(taicpu.op_reg_reg_ref(A_STP, pairreg, newreg(rt, sr, sub), ref));
{ TODO: generate `mov x29, sp` maybe? }
end;
procedure GenExit(List: TAsmList);
var
Ref: TReference;
pairreg: TRegister;
rt: TRegisterType;
sub: TSubRegister;
sr: TSuperRegister;
begin
{ generate `ldp x29, x30, [sp], #16` }
reference_reset_base(ref, NR_SP, 16, ctempposinvalid, 16, []);
ref.addressmode := AM_POSTINDEXED;
rt := R_INTREGISTER;
sub := R_SUBWHOLE;
{ these are backwards compared to GenEntry intentionally }
sr := RS_X30;
pairreg := newreg(rt, sr, sub);
sr := RS_X29;
List.Concat(taicpu.op_reg_reg_ref(A_LDP, newreg(rt, sr, sub), pairreg, ref));
{ generate `ret` }
List.Concat(taicpu.op_none(A_RET));
end;
var
InitList, FinalList, Header: TAsmList;
Entry : PInitFinalEntry;
i : longint;
begin
if not(tf_init_final_units_by_calls in target_info.flags) then
begin
inherited insert_init_final_table(main,Entries);
exit;
end;
InitList := TAsmList.Create;
FinalList := TAsmList.Create;
GenEntry(finalList);
GenEntry(initList);
for i := 0 to Entries.Count - 1 do
begin
Entry := PInitFinalEntry(Entries[i]);
if Entry^.finifunc <> '' then
finalList.Concat(taicpu.op_sym(A_BL, current_asmdata.RefAsmSymbol(entry^.finifunc, AT_FUNCTION)));
if Entry^.initfunc <> '' then
initList.Concat(taicpu.op_sym(A_BL, current_asmdata.RefAsmSymbol(entry^.initfunc, AT_FUNCTION)));
end;
GenExit(finalList);
GenExit(initList);
Header := TAsmList.Create;
New_Section(Header, Sec_Code, 'FPC_INIT_FUNC_TABLE', 1);
Header.Concat(TAI_Symbol.CreateName_Global('FPC_INIT_FUNC_TABLE', AT_FUNCTION, 0, VoidCodePointerType));
InitList.InsertList(Header);
Header.Free;
current_asmdata.AsmLists[al_procedures].concatList(initList);
Header := TAsmList.Create;
New_Section(Header, Sec_Code, 'FPC_FINALIZE_FUNC_TABLE', 1);
Header.Concat(TAI_Symbol.CreateName_Global('FPC_FINALIZE_FUNC_TABLE', AT_FUNCTION, 0, VoidCodePointerType));
FinalList.InsertList(Header);
Header.Free;
current_asmdata.AsmLists[al_procedures].concatList(finalList);
InitList.Free;
FinalList.Free;
inherited Insert_Init_Final_Table(main,entries);
end;
begin
cnodeutils := TAArch64NodeUtils;
end.