123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- {
- 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.
|