mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-13 07:34:28 +02:00
165 lines
4.5 KiB
ObjectPascal
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.
|