ncgld.pas 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. Generate assembler for nodes that handle loads and assignments which
  5. are the same for all (most) processors
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. unit ncgld;
  20. {$i defines.inc}
  21. interface
  22. uses
  23. node,nld;
  24. type
  25. tcgarrayconstructornode = class(tarrayconstructornode)
  26. procedure pass_2;override;
  27. end;
  28. implementation
  29. uses
  30. systems,
  31. verbose,globals,
  32. symconst,symtype,symdef,symsym,symtable,aasm,types,
  33. cginfo,cgbase,pass_2,
  34. cpubase,cpuasm,
  35. cga,tgobj,ncgutil,regvars,cgobj,cg64f32,rgobj,rgcpu;
  36. {*****************************************************************************
  37. SecondArrayConstruct
  38. *****************************************************************************}
  39. const
  40. vtInteger = 0;
  41. vtBoolean = 1;
  42. vtChar = 2;
  43. vtExtended = 3;
  44. vtString = 4;
  45. vtPointer = 5;
  46. vtPChar = 6;
  47. vtObject = 7;
  48. vtClass = 8;
  49. vtWideChar = 9;
  50. vtPWideChar = 10;
  51. vtAnsiString = 11;
  52. vtCurrency = 12;
  53. vtVariant = 13;
  54. vtInterface = 14;
  55. vtWideString = 15;
  56. vtInt64 = 16;
  57. vtQWord = 17;
  58. procedure tcgarrayconstructornode.pass_2;
  59. var
  60. hp : tarrayconstructornode;
  61. href : treference;
  62. lt : tdef;
  63. vaddr : boolean;
  64. vtype : longint;
  65. freetemp,
  66. dovariant : boolean;
  67. elesize : longint;
  68. tmpreg : tregister;
  69. begin
  70. dovariant:=(nf_forcevaria in flags) or tarraydef(resulttype.def).isvariant;
  71. if dovariant then
  72. elesize:=8
  73. else
  74. elesize:=tarraydef(resulttype.def).elesize;
  75. if not(nf_cargs in flags) then
  76. begin
  77. location_reset(location,LOC_REFERENCE,OS_NO);
  78. { Allocate always a temp, also if no elements are required, to
  79. be sure that location is valid (PFV) }
  80. if tarraydef(resulttype.def).highrange=-1 then
  81. tg.gettempofsizereference(exprasmlist,elesize,location.reference)
  82. else
  83. tg.gettempofsizereference(exprasmlist,(tarraydef(resulttype.def).highrange+1)*elesize,location.reference);
  84. href:=location.reference;
  85. end;
  86. hp:=self;
  87. while assigned(hp) do
  88. begin
  89. if assigned(hp.left) then
  90. begin
  91. freetemp:=true;
  92. secondpass(hp.left);
  93. if codegenerror then
  94. exit;
  95. if dovariant then
  96. begin
  97. { find the correct vtype value }
  98. vtype:=$ff;
  99. vaddr:=false;
  100. lt:=hp.left.resulttype.def;
  101. case lt.deftype of
  102. enumdef,
  103. orddef :
  104. begin
  105. if is_64bitint(lt) then
  106. begin
  107. case torddef(lt).typ of
  108. s64bit:
  109. vtype:=vtInt64;
  110. u64bit:
  111. vtype:=vtQWord;
  112. end;
  113. freetemp:=false;
  114. vaddr:=true;
  115. end
  116. else if (lt.deftype=enumdef) or
  117. is_integer(lt) then
  118. vtype:=vtInteger
  119. else
  120. if is_boolean(lt) then
  121. vtype:=vtBoolean
  122. else
  123. if (lt.deftype=orddef) and (torddef(lt).typ=uchar) then
  124. vtype:=vtChar;
  125. end;
  126. floatdef :
  127. begin
  128. vtype:=vtExtended;
  129. vaddr:=true;
  130. freetemp:=false;
  131. end;
  132. procvardef,
  133. pointerdef :
  134. begin
  135. if is_pchar(lt) then
  136. vtype:=vtPChar
  137. else
  138. vtype:=vtPointer;
  139. end;
  140. classrefdef :
  141. vtype:=vtClass;
  142. objectdef :
  143. begin
  144. vtype:=vtObject;
  145. end;
  146. stringdef :
  147. begin
  148. if is_shortstring(lt) then
  149. begin
  150. vtype:=vtString;
  151. vaddr:=true;
  152. freetemp:=false;
  153. end
  154. else
  155. if is_ansistring(lt) then
  156. begin
  157. vtype:=vtAnsiString;
  158. freetemp:=false;
  159. end
  160. else
  161. if is_widestring(lt) then
  162. begin
  163. vtype:=vtWideString;
  164. freetemp:=false;
  165. end;
  166. end;
  167. end;
  168. if vtype=$ff then
  169. internalerror(14357);
  170. { write C style pushes or an pascal array }
  171. if nf_cargs in flags then
  172. begin
  173. if vaddr then
  174. begin
  175. location_force_mem(hp.left.location);
  176. cg.a_paramaddr_ref(exprasmlist,hp.left.location.reference,-1);
  177. location_release(exprasmlist,hp.left.location);
  178. if freetemp then
  179. location_freetemp(exprasmlist,hp.left.location);
  180. end
  181. else
  182. cg.a_param_loc(exprasmlist,hp.left.location,-1);
  183. inc(pushedparasize,4);
  184. end
  185. else
  186. begin
  187. { write changing field update href to the next element }
  188. inc(href.offset,4);
  189. if vaddr then
  190. begin
  191. location_force_mem(hp.left.location);
  192. tmpreg:=cg.get_scratch_reg(exprasmlist);
  193. cg.a_loadaddr_ref_reg(exprasmlist,hp.left.location.reference,tmpreg);
  194. cg.a_load_reg_ref(exprasmlist,cg.reg_cgsize(tmpreg),tmpreg,href);
  195. cg.free_scratch_reg(exprasmlist,tmpreg);
  196. location_release(exprasmlist,hp.left.location);
  197. if freetemp then
  198. location_freetemp(exprasmlist,hp.left.location);
  199. end
  200. else
  201. begin
  202. location_release(exprasmlist,left.location);
  203. cg.a_load_loc_ref(exprasmlist,hp.left.location,href);
  204. end;
  205. { update href to the vtype field and write it }
  206. dec(href.offset,4);
  207. cg.a_load_const_ref(exprasmlist, OS_INT,vtype,href);
  208. { goto next array element }
  209. inc(href.offset,8);
  210. end;
  211. end
  212. else
  213. { normal array constructor of the same type }
  214. begin
  215. case elesize of
  216. 1,2,4 :
  217. begin
  218. location_release(exprasmlist,left.location);
  219. cg.a_load_loc_ref(exprasmlist,hp.left.location,href);
  220. end;
  221. 8 :
  222. begin
  223. if hp.left.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
  224. tcg64f32(cg).a_load64_loc_ref(exprasmlist,hp.left.location,href)
  225. else
  226. cg.g_concatcopy(exprasmlist,hp.left.location.reference,href,elesize,freetemp,false);
  227. end;
  228. else
  229. begin
  230. { concatcopy only supports reference }
  231. if not(hp.left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
  232. internalerror(200108012);
  233. cg.g_concatcopy(exprasmlist,hp.left.location.reference,href,elesize,freetemp,false);
  234. end;
  235. end;
  236. inc(href.offset,elesize);
  237. end;
  238. end;
  239. { load next entry }
  240. hp:=tarrayconstructornode(hp.right);
  241. end;
  242. end;
  243. begin
  244. carrayconstructornode:=tcgarrayconstructornode;
  245. end.
  246. {
  247. $Log$
  248. Revision 1.2 2002-04-21 15:24:38 carl
  249. + a_jmp_cond -> a_jmp_always (a_jmp_cond is NOT portable)
  250. + changeregsize -> rg.makeregsize
  251. Revision 1.1 2002/04/19 15:39:34 peter
  252. * removed some more routines from cga
  253. * moved location_force_reg/mem to ncgutil
  254. * moved arrayconstructnode secondpass to ncgld
  255. }