nllvmcon.pas 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. {
  2. Copyright (c) 2013 by Jonas Maebe, member of the Free Pascal Compiler
  3. development team
  4. Generate llvm bitcode for constants
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit nllvmcon;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. node,ncgcon;
  23. type
  24. tllvmrealconstnode = class(tcgrealconstnode)
  25. function pass_1 : tnode;override;
  26. procedure pass_generate_code;override;
  27. end;
  28. tllvmstringconstnode = class(tcgstringconstnode)
  29. procedure pass_generate_code; override;
  30. end;
  31. implementation
  32. uses
  33. globtype,verbose,cutils,
  34. symtype,symdef,defutil,
  35. aasmdata,
  36. ncon,
  37. llvmbase,aasmllvm,hlcgobj,
  38. cgbase,cgutils;
  39. {*****************************************************************************
  40. tllvmstringconstnode
  41. *****************************************************************************}
  42. procedure tllvmstringconstnode.pass_generate_code;
  43. var
  44. datadef, resptrdef: tdef;
  45. hreg: tregister;
  46. begin
  47. inherited pass_generate_code;
  48. if cst_type in [cst_conststring,cst_shortstring] then
  49. begin
  50. if location.loc<>LOC_CREFERENCE then
  51. internalerror(2014071202);
  52. case cst_type of
  53. cst_conststring:
  54. { this kind of string const is used both for array of char
  55. constants (-> excludes terminating #0) and pchars (-> includes
  56. terminating #0). The resultdef excludes the #0 while the data
  57. includes it -> insert typecast from datadef to resultdef }
  58. datadef:=getarraydef(cansichartype,len+2);
  59. cst_shortstring:
  60. { the resultdef of the string constant is the type of the
  61. string to which it is assigned, which can be longer or shorter
  62. than the length of the string itself -> typecast it to the
  63. correct string type }
  64. datadef:=getarraydef(cansichartype,min(len,255)+1);
  65. else
  66. internalerror(2014071203);
  67. end;
  68. { get address of array as pchar }
  69. resptrdef:=getpointerdef(resultdef);
  70. hreg:=hlcg.getaddressregister(current_asmdata.CurrAsmList,resptrdef);
  71. hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,datadef,resptrdef,location.reference,hreg);
  72. hlcg.reference_reset_base(location.reference,resptrdef,hreg,0,location.reference.alignment);
  73. end;
  74. end;
  75. {*****************************************************************************
  76. tllvmrealconstnode
  77. *****************************************************************************}
  78. function tllvmrealconstnode.pass_1 : tnode;
  79. begin
  80. result:=nil;
  81. expectloc:=LOC_FPUREGISTER;
  82. end;
  83. procedure tllvmrealconstnode.pass_generate_code;
  84. begin
  85. { llvm supports floating point constants directly }
  86. location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
  87. location.register:=hlcg.getfpuregister(current_asmdata.CurrAsmList,resultdef);
  88. case tfloatdef(resultdef).floattype of
  89. s32real,s64real:
  90. current_asmdata.CurrAsmList.concat(taillvm.op_reg_size_fpconst_size(la_bitcast,location.register,resultdef,value_real,resultdef));
  91. { comp and currency are handled as int64 at the llvm level }
  92. s64comp,
  93. s64currency:
  94. { sc80floattype instead of resultdef, see comment in thlcgllvm.a_loadfpu_ref_reg }
  95. current_asmdata.CurrAsmList.concat(taillvm.op_reg_size_const_size(la_sitofp,location.register,s64inttype,trunc(value_real),sc80floattype));
  96. {$ifdef cpuextended}
  97. s80real,sc80real:
  98. current_asmdata.CurrAsmList.concat(taillvm.op_reg_size_fpconst80_size(la_bitcast,location.register,resultdef,value_real,resultdef));
  99. {$endif cpuextended}
  100. else
  101. internalerror(2013102501);
  102. end;
  103. end;
  104. begin
  105. cstringconstnode:=tllvmstringconstnode;
  106. crealconstnode:=tllvmrealconstnode;
  107. end.