nllvmld.pas 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. {
  2. Copyright (c) 2012 by Jonas Maebe
  3. Generate LLVM bytecode for nodes that handle loads and assignments
  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 nllvmld;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. globtype,
  22. cgutils,
  23. symtype,
  24. node,ncgld,ncgnstld;
  25. type
  26. tllvmloadnode = class(tcgnestloadnode)
  27. function pass_1: tnode; override;
  28. procedure pass_generate_code; override;
  29. end;
  30. { tllvmarrayconstructornode }
  31. tllvmarrayconstructornode = class(tcgarrayconstructornode)
  32. protected
  33. procedure makearrayref(var ref: treference; eledef: tdef); override;
  34. end;
  35. implementation
  36. uses
  37. systems,
  38. aasmdata,
  39. nld,
  40. symtable,symconst,symdef,symsym,
  41. tgobj,cgbase,hlcgobj;
  42. function tllvmloadnode.pass_1: tnode;
  43. begin
  44. result:=inherited;
  45. if assigned(result) then
  46. exit;
  47. case symtableentry.typ of
  48. procsym:
  49. begin
  50. if assigned(left) then
  51. expectloc:=LOC_REFERENCE;
  52. end;
  53. end;
  54. end;
  55. procedure tllvmloadnode.pass_generate_code;
  56. var
  57. pvdef: tprocvardef;
  58. href, mpref: treference;
  59. field: tfieldvarsym;
  60. procreg, selfreg: tregister;
  61. selfdef: tdef;
  62. begin
  63. inherited;
  64. case symtableentry.typ of
  65. procsym:
  66. begin
  67. { if the result is returned in two registers, force it to memory into
  68. a single memory location, as we don't use the registerhi/register
  69. location hack for llvm (llvm will put it back into registers itself)
  70. }
  71. if assigned(left) then
  72. begin
  73. pvdef:=tprocvardef(procdef.getcopyas(procvardef,pc_normal));
  74. { on little endian, location.register contains proc and
  75. location.registerhi contains self; on big endian, it's the
  76. other way around }
  77. tg.gethltemp(current_asmdata.CurrAsmList,pvdef,pvdef.size,tt_normal,href);
  78. if target_info.endian=endian_little then
  79. begin
  80. procreg:=location.register;
  81. selfreg:=location.registerhi
  82. end
  83. else
  84. begin
  85. procreg:=location.registerhi;
  86. selfreg:=location.register
  87. end;
  88. { left can be a pointerdef when we take the address of a nested
  89. procedure, as left will then be a pointer to the nestedfpstruct
  90. }
  91. if is_implicit_pointer_object_type(left.resultdef) or
  92. (left.resultdef.typ in [classrefdef,pointerdef]) then
  93. selfdef:=left.resultdef
  94. else
  95. selfdef:=cpointerdef.getreusable(left.resultdef);
  96. mpref:=href;
  97. hlcg.g_ptrtypecast_ref(current_asmdata.CurrAsmList,cpointerdef.getreusable(pvdef),cpointerdef.getreusable(methodpointertype),mpref);
  98. hlcg.g_load_reg_field_by_name(current_asmdata.CurrAsmList,cprocvardef.getreusableprocaddr(procdef),trecorddef(methodpointertype),procreg,'proc',mpref);
  99. hlcg.g_load_reg_field_by_name(current_asmdata.CurrAsmList,selfdef,trecorddef(methodpointertype),selfreg,'self',mpref);
  100. location_reset_ref(location,LOC_REFERENCE,location.size,href.alignment);
  101. location.reference:=href;
  102. end;
  103. end;
  104. end;
  105. end;
  106. { tllvmarrayconstructornode }
  107. procedure tllvmarrayconstructornode.makearrayref(var ref: treference; eledef: tdef);
  108. begin
  109. { the array elements are addressed as pointer to the individual elements ->
  110. convert }
  111. hlcg.g_ptrtypecast_ref(current_asmdata.CurrAsmList,cpointerdef.getreusable(resultdef),cpointerdef.getreusable(eledef),ref);
  112. end;
  113. begin
  114. cloadnode:=tllvmloadnode;
  115. carrayconstructornode:=tllvmarrayconstructornode;
  116. end.