naarch64util.pas 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. {
  2. Copyright (c) 1998-2022 by the Free Pascal development team
  3. AArch64 version of some node tree helper routines
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit naarch64util;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. cclasses, ngenutil, fmodule;
  22. type
  23. TAArch64NodeUtils = class(TNodeUtils)
  24. class procedure InsertObjectInfo; override;
  25. class procedure Insert_Init_Final_Table(main: tmodule; Entries: TFPList); override;
  26. end;
  27. implementation
  28. uses
  29. verbose,
  30. systems,
  31. globals,
  32. cpuinfo,cpubase,
  33. cgbase,cgutils,
  34. aasmbase,aasmdata,aasmtai,aasmcpu,
  35. symdef;
  36. class procedure TAArch64NodeUtils.InsertObjectInfo;
  37. begin
  38. inherited InsertObjectInfo;
  39. end;
  40. {
  41. TODO: This is a simple skeleton, not nearly as complex as the
  42. ARM (32-bit) version in compiler/arm/narmutil.pas
  43. }
  44. class procedure TAArch64NodeUtils.Insert_Init_Final_Table(main: tmodule; Entries: TFPList);
  45. procedure GenEntry(List: TAsmList);
  46. var
  47. Ref: TReference;
  48. pairreg: TRegister;
  49. rt: TRegisterType;
  50. sub: TSubRegister;
  51. sr: TSuperRegister;
  52. begin
  53. { generate `stp x29, x30, [sp, #-16]!` }
  54. reference_reset_base(ref, NR_SP, -16, ctempposinvalid, 16, []);
  55. ref.addressmode := AM_PREINDEXED;
  56. rt := R_INTREGISTER;
  57. sub := R_SUBWHOLE;
  58. sr := RS_X29;
  59. pairreg := newreg(rt, sr, sub);
  60. sr := RS_X30;
  61. List.Concat(taicpu.op_reg_reg_ref(A_STP, pairreg, newreg(rt, sr, sub), ref));
  62. { TODO: generate `mov x29, sp` maybe? }
  63. end;
  64. procedure GenExit(List: TAsmList);
  65. var
  66. Ref: TReference;
  67. pairreg: TRegister;
  68. rt: TRegisterType;
  69. sub: TSubRegister;
  70. sr: TSuperRegister;
  71. begin
  72. { generate `ldp x29, x30, [sp], #16` }
  73. reference_reset_base(ref, NR_SP, 16, ctempposinvalid, 16, []);
  74. ref.addressmode := AM_POSTINDEXED;
  75. rt := R_INTREGISTER;
  76. sub := R_SUBWHOLE;
  77. { these are backwards compared to GenEntry intentionally }
  78. sr := RS_X30;
  79. pairreg := newreg(rt, sr, sub);
  80. sr := RS_X29;
  81. List.Concat(taicpu.op_reg_reg_ref(A_LDP, newreg(rt, sr, sub), pairreg, ref));
  82. { generate `ret` }
  83. List.Concat(taicpu.op_none(A_RET));
  84. end;
  85. var
  86. InitList, FinalList, Header: TAsmList;
  87. Entry : PInitFinalEntry;
  88. i : longint;
  89. begin
  90. if not(tf_init_final_units_by_calls in target_info.flags) then
  91. begin
  92. inherited insert_init_final_table(main,Entries);
  93. exit;
  94. end;
  95. InitList := TAsmList.Create;
  96. FinalList := TAsmList.Create;
  97. GenEntry(finalList);
  98. GenEntry(initList);
  99. for i := 0 to Entries.Count - 1 do
  100. begin
  101. Entry := PInitFinalEntry(Entries[i]);
  102. if Entry^.finifunc <> '' then
  103. finalList.Concat(taicpu.op_sym(A_BL, current_asmdata.RefAsmSymbol(entry^.finifunc, AT_FUNCTION)));
  104. if Entry^.initfunc <> '' then
  105. initList.Concat(taicpu.op_sym(A_BL, current_asmdata.RefAsmSymbol(entry^.initfunc, AT_FUNCTION)));
  106. end;
  107. GenExit(finalList);
  108. GenExit(initList);
  109. Header := TAsmList.Create;
  110. New_Section(Header, Sec_Code, 'FPC_INIT_FUNC_TABLE', 1);
  111. Header.Concat(TAI_Symbol.CreateName_Global('FPC_INIT_FUNC_TABLE', AT_FUNCTION, 0, VoidCodePointerType));
  112. InitList.InsertList(Header);
  113. Header.Free;
  114. current_asmdata.AsmLists[al_procedures].concatList(initList);
  115. Header := TAsmList.Create;
  116. New_Section(Header, Sec_Code, 'FPC_FINALIZE_FUNC_TABLE', 1);
  117. Header.Concat(TAI_Symbol.CreateName_Global('FPC_FINALIZE_FUNC_TABLE', AT_FUNCTION, 0, VoidCodePointerType));
  118. FinalList.InsertList(Header);
  119. Header.Free;
  120. current_asmdata.AsmLists[al_procedures].concatList(finalList);
  121. InitList.Free;
  122. FinalList.Free;
  123. inherited Insert_Init_Final_Table(main,entries);
  124. end;
  125. begin
  126. cnodeutils := TAArch64NodeUtils;
  127. end.