ncginl.pas 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl and Carl Eric Codere
  4. Generate generic inline nodes
  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 ncginl;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. node,ninl;
  23. type
  24. tcginlinenode = class(tinlinenode)
  25. procedure pass_2;override;
  26. procedure second_assert;virtual;
  27. procedure second_sizeoftypeof;virtual;
  28. procedure second_length;virtual;
  29. procedure second_predsucc;virtual;
  30. procedure second_incdec;virtual;
  31. procedure second_typeinfo;virtual;
  32. procedure second_includeexclude;virtual;
  33. procedure second_pi; virtual;
  34. procedure second_arctan_real; virtual;
  35. procedure second_abs_real; virtual;
  36. procedure second_sqr_real; virtual;
  37. procedure second_sqrt_real; virtual;
  38. procedure second_ln_real; virtual;
  39. procedure second_cos_real; virtual;
  40. procedure second_sin_real; virtual;
  41. procedure second_assigned; virtual;
  42. procedure second_prefetch; virtual;
  43. end;
  44. implementation
  45. uses
  46. globtype,systems,
  47. cutils,verbose,globals,fmodule,
  48. symconst,symdef,defutil,symsym,
  49. aasmbase,aasmtai,aasmcpu,
  50. cgbase,pass_1,pass_2,
  51. cpuinfo,cpubase,paramgr,procinfo,
  52. nbas,ncon,ncal,ncnv,nld,
  53. tgobj,ncgutil,cgobj
  54. {$ifndef cpu64bit}
  55. ,cg64f32
  56. {$endif cpu64bit}
  57. ;
  58. {*****************************************************************************
  59. TCGINLINENODE
  60. *****************************************************************************}
  61. procedure tcginlinenode.pass_2;
  62. begin
  63. location_reset(location,LOC_VOID,OS_NO);
  64. case inlinenumber of
  65. in_assert_x_y:
  66. begin
  67. second_Assert;
  68. end;
  69. in_sizeof_x,
  70. in_typeof_x :
  71. begin
  72. second_SizeofTypeOf;
  73. end;
  74. in_length_x :
  75. begin
  76. second_Length;
  77. end;
  78. in_pred_x,
  79. in_succ_x:
  80. begin
  81. second_PredSucc;
  82. end;
  83. in_dec_x,
  84. in_inc_x :
  85. begin
  86. second_IncDec;
  87. end;
  88. in_typeinfo_x:
  89. begin
  90. second_TypeInfo;
  91. end;
  92. in_include_x_y,
  93. in_exclude_x_y:
  94. begin
  95. second_IncludeExclude;
  96. end;
  97. in_pi:
  98. begin
  99. second_pi;
  100. end;
  101. in_sin_extended:
  102. begin
  103. second_sin_real;
  104. end;
  105. in_arctan_extended:
  106. begin
  107. second_arctan_real;
  108. end;
  109. in_abs_extended:
  110. begin
  111. second_abs_real;
  112. end;
  113. in_sqr_extended:
  114. begin
  115. second_sqr_real;
  116. end;
  117. in_sqrt_extended:
  118. begin
  119. second_sqrt_real;
  120. end;
  121. in_ln_extended:
  122. begin
  123. second_ln_real;
  124. end;
  125. in_cos_extended:
  126. begin
  127. second_cos_real;
  128. end;
  129. in_prefetch_var:
  130. begin
  131. second_prefetch;
  132. end;
  133. in_assigned_x:
  134. begin
  135. second_assigned;
  136. end;
  137. {$ifdef SUPPORT_MMX}
  138. in_mmx_pcmpeqb..in_mmx_pcmpgtw:
  139. begin
  140. location_reset(location,LOC_MMXREGISTER,OS_NO);
  141. if left.location.loc=LOC_REGISTER then
  142. begin
  143. {!!!!!!!}
  144. end
  145. else if tcallparanode(left).left.location.loc=LOC_REGISTER then
  146. begin
  147. {!!!!!!!}
  148. end
  149. else
  150. begin
  151. {!!!!!!!}
  152. end;
  153. end;
  154. {$endif SUPPORT_MMX}
  155. else internalerror(9);
  156. end;
  157. end;
  158. {*****************************************************************************
  159. ASSERT GENERIC HANDLING
  160. *****************************************************************************}
  161. procedure tcginlinenode.second_Assert;
  162. var
  163. hp2 : tstringconstnode;
  164. otlabel,oflabel : tasmlabel;
  165. paraloc1,paraloc2,
  166. paraloc3,paraloc4 : tparalocation;
  167. begin
  168. { the node should be removed in the firstpass }
  169. if not (cs_do_assertion in aktlocalswitches) then
  170. internalerror(7123458);
  171. paraloc1:=paramanager.getintparaloc(pocall_default,1);
  172. paraloc2:=paramanager.getintparaloc(pocall_default,2);
  173. paraloc3:=paramanager.getintparaloc(pocall_default,3);
  174. paraloc4:=paramanager.getintparaloc(pocall_default,4);
  175. otlabel:=truelabel;
  176. oflabel:=falselabel;
  177. objectlibrary.getlabel(truelabel);
  178. objectlibrary.getlabel(falselabel);
  179. secondpass(tcallparanode(left).left);
  180. maketojumpbool(exprasmlist,tcallparanode(left).left,lr_load_regvars);
  181. cg.a_label(exprasmlist,falselabel);
  182. { erroraddr }
  183. paramanager.allocparaloc(exprasmlist,paraloc4);
  184. cg.a_param_reg(exprasmlist,OS_ADDR,NR_FRAME_POINTER_REG,paraloc4);
  185. { lineno }
  186. paramanager.allocparaloc(exprasmlist,paraloc3);
  187. cg.a_param_const(exprasmlist,OS_INT,aktfilepos.line,paraloc3);
  188. { filename string }
  189. hp2:=cstringconstnode.createstr(current_module.sourcefiles.get_file_name(aktfilepos.fileindex),st_shortstring);
  190. firstpass(tnode(hp2));
  191. secondpass(tnode(hp2));
  192. if codegenerror then
  193. exit;
  194. paramanager.allocparaloc(exprasmlist,paraloc2);
  195. cg.a_paramaddr_ref(exprasmlist,hp2.location.reference,paraloc2);
  196. hp2.free;
  197. { push msg }
  198. secondpass(tcallparanode(tcallparanode(left).right).left);
  199. paramanager.allocparaloc(exprasmlist,paraloc1);
  200. cg.a_paramaddr_ref(exprasmlist,tcallparanode(tcallparanode(left).right).left.location.reference,paraloc1);
  201. { call }
  202. paramanager.freeparaloc(exprasmlist,paraloc1);
  203. paramanager.freeparaloc(exprasmlist,paraloc2);
  204. paramanager.freeparaloc(exprasmlist,paraloc3);
  205. paramanager.freeparaloc(exprasmlist,paraloc4);
  206. cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  207. cg.a_call_name(exprasmlist,'FPC_ASSERT');
  208. cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  209. cg.a_label(exprasmlist,truelabel);
  210. truelabel:=otlabel;
  211. falselabel:=oflabel;
  212. end;
  213. {*****************************************************************************
  214. SIZEOF / TYPEOF GENERIC HANDLING
  215. *****************************************************************************}
  216. { second_handle_ the sizeof and typeof routines }
  217. procedure tcginlinenode.second_SizeOfTypeOf;
  218. var
  219. href,
  220. hrefvmt : treference;
  221. hregister : tregister;
  222. begin
  223. location_reset(location,LOC_REGISTER,OS_ADDR);
  224. { for both cases load vmt }
  225. if left.nodetype=typen then
  226. begin
  227. hregister:=cg.getaddressregister(exprasmlist);
  228. reference_reset_symbol(href,objectlibrary.newasmsymboldata(tobjectdef(left.resulttype.def).vmt_mangledname),0);
  229. cg.a_loadaddr_ref_reg(exprasmlist,href,hregister);
  230. end
  231. else
  232. begin
  233. secondpass(left);
  234. location_release(exprasmlist,left.location);
  235. hregister:=cg.getaddressregister(exprasmlist);
  236. { handle self inside a method of a class }
  237. case left.location.loc of
  238. LOC_CREGISTER,
  239. LOC_REGISTER :
  240. begin
  241. if (left.resulttype.def.deftype=classrefdef) or
  242. (po_staticmethod in current_procinfo.procdef.procoptions) then
  243. cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.register,hregister)
  244. else
  245. begin
  246. { load VMT pointer }
  247. reference_reset_base(hrefvmt,left.location.register,tobjectdef(left.resulttype.def).vmt_offset);
  248. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,hrefvmt,hregister);
  249. end
  250. end;
  251. LOC_REFERENCE,
  252. LOC_CREFERENCE :
  253. begin
  254. if is_class(left.resulttype.def) then
  255. begin
  256. { deref class }
  257. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.reference,hregister);
  258. cg.g_maybe_testself(exprasmlist,hregister);
  259. { load VMT pointer }
  260. reference_reset_base(hrefvmt,hregister,tobjectdef(left.resulttype.def).vmt_offset);
  261. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,hrefvmt,hregister);
  262. end
  263. else
  264. begin
  265. { load VMT pointer, but not for classrefdefs }
  266. if (left.resulttype.def.deftype=objectdef) then
  267. inc(left.location.reference.offset,tobjectdef(left.resulttype.def).vmt_offset);
  268. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.reference,hregister);
  269. end;
  270. end;
  271. else
  272. internalerror(200301301);
  273. end;
  274. end;
  275. { in sizeof load size }
  276. if inlinenumber=in_sizeof_x then
  277. begin
  278. reference_reset_base(href,hregister,0);
  279. cg.ungetregister(exprasmlist,hregister);
  280. hregister:=cg.getintregister(exprasmlist,OS_INT);
  281. cg.a_load_ref_reg(exprasmlist,OS_INT,OS_INT,href,hregister);
  282. end;
  283. location.register:=hregister;
  284. end;
  285. {*****************************************************************************
  286. LENGTH GENERIC HANDLING
  287. *****************************************************************************}
  288. procedure tcginlinenode.second_Length;
  289. var
  290. lengthlab : tasmlabel;
  291. hregister : tregister;
  292. href : treference;
  293. begin
  294. secondpass(left);
  295. if is_shortstring(left.resulttype.def) then
  296. begin
  297. location_copy(location,left.location);
  298. location.size:=OS_8;
  299. end
  300. else
  301. begin
  302. { length in ansi strings is at offset -8 }
  303. location_force_reg(exprasmlist,left.location,OS_ADDR,false);
  304. objectlibrary.getlabel(lengthlab);
  305. cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,left.location.register,lengthlab);
  306. reference_reset_base(href,left.location.register,-8);
  307. reference_release(exprasmlist,href);
  308. hregister:=cg.getintregister(exprasmlist,OS_32);
  309. cg.a_load_ref_reg(exprasmlist,OS_32,OS_32,href,hregister);
  310. cg.a_label(exprasmlist,lengthlab);
  311. location_reset(location,LOC_REGISTER,OS_32);
  312. location.register:=hregister;
  313. end;
  314. end;
  315. {*****************************************************************************
  316. PRED/SUCC GENERIC HANDLING
  317. *****************************************************************************}
  318. procedure tcginlinenode.second_PredSucc;
  319. var
  320. cgsize : TCGSize;
  321. cgop : topcg;
  322. begin
  323. secondpass(left);
  324. if inlinenumber=in_pred_x then
  325. cgop:=OP_SUB
  326. else
  327. cgop:=OP_ADD;
  328. cgsize:=def_cgsize(resulttype.def);
  329. { we need a value in a register }
  330. location_copy(location,left.location);
  331. location_force_reg(exprasmlist,location,cgsize,false);
  332. if cgsize in [OS_64,OS_S64] then
  333. cg64.a_op64_const_reg(exprasmlist,cgop,1,
  334. location.register64)
  335. else
  336. cg.a_op_const_reg(exprasmlist,cgop,location.size,1,location.register);
  337. cg.g_rangecheck(exprasmlist,location,resulttype.def,resulttype.def);
  338. end;
  339. {*****************************************************************************
  340. INC/DEC GENERIC HANDLING
  341. *****************************************************************************}
  342. procedure tcginlinenode.second_IncDec;
  343. const
  344. addsubop:array[in_inc_x..in_dec_x] of TOpCG=(OP_ADD,OP_SUB);
  345. var
  346. addvalue : TConstExprInt;
  347. addconstant : boolean;
  348. {$ifndef cpu64bit}
  349. hregisterhi,
  350. {$endif cpu64bit}
  351. hregister : tregister;
  352. cgsize : tcgsize;
  353. begin
  354. { set defaults }
  355. addconstant:=true;
  356. { load first parameter, must be a reference }
  357. secondpass(tcallparanode(left).left);
  358. cgsize:=def_cgsize(tcallparanode(left).left.resulttype.def);
  359. { get addvalue }
  360. case tcallparanode(left).left.resulttype.def.deftype of
  361. orddef,
  362. enumdef :
  363. addvalue:=1;
  364. pointerdef :
  365. begin
  366. if is_void(tpointerdef(tcallparanode(left).left.resulttype.def).pointertype.def) then
  367. addvalue:=1
  368. else
  369. addvalue:=tpointerdef(tcallparanode(left).left.resulttype.def).pointertype.def.size;
  370. end;
  371. else
  372. internalerror(10081);
  373. end;
  374. { second_ argument specified?, must be a s32bit in register }
  375. if assigned(tcallparanode(left).right) then
  376. begin
  377. secondpass(tcallparanode(tcallparanode(left).right).left);
  378. { when constant, just multiply the addvalue }
  379. if is_constintnode(tcallparanode(tcallparanode(left).right).left) then
  380. addvalue:=addvalue*get_ordinal_value(tcallparanode(tcallparanode(left).right).left)
  381. else
  382. begin
  383. location_force_reg(exprasmlist,tcallparanode(tcallparanode(left).right).left.location,cgsize,false);
  384. hregister:=tcallparanode(tcallparanode(left).right).left.location.register;
  385. {$ifndef cpu64bit}
  386. hregisterhi:=tcallparanode(tcallparanode(left).right).left.location.registerhigh;
  387. {$endif cpu64bit}
  388. { insert multiply with addvalue if its >1 }
  389. if addvalue>1 then
  390. cg.a_op_const_reg(exprasmlist,OP_IMUL,cgsize,addvalue,hregister);
  391. addconstant:=false;
  392. end;
  393. end;
  394. { write the add instruction }
  395. if addconstant then
  396. begin
  397. if cgsize in [OS_64,OS_S64] then
  398. cg64.a_op64_const_loc(exprasmlist,addsubop[inlinenumber],
  399. addvalue,tcallparanode(left).left.location)
  400. else
  401. cg.a_op_const_loc(exprasmlist,addsubop[inlinenumber],
  402. aword(addvalue),tcallparanode(left).left.location);
  403. end
  404. else
  405. begin
  406. {$ifndef cpu64bit}
  407. if cgsize in [OS_64,OS_S64] then
  408. cg64.a_op64_reg_loc(exprasmlist,addsubop[inlinenumber],
  409. joinreg64(hregister,hregisterhi),tcallparanode(left).left.location)
  410. else
  411. {$endif cpu64bit}
  412. cg.a_op_reg_loc(exprasmlist,addsubop[inlinenumber],
  413. hregister,tcallparanode(left).left.location);
  414. location_release(exprasmlist,tcallparanode(tcallparanode(left).right).left.location);
  415. end;
  416. location_release(exprasmlist,tcallparanode(left).left.location);
  417. cg.g_overflowcheck(exprasmlist,tcallparanode(left).left.location,tcallparanode(left).resulttype.def);
  418. cg.g_rangecheck(exprasmlist,tcallparanode(left).left.location,tcallparanode(left).left.resulttype.def,
  419. tcallparanode(left).left.resulttype.def);
  420. end;
  421. {*****************************************************************************
  422. TYPEINFO GENERIC HANDLING
  423. *****************************************************************************}
  424. procedure tcginlinenode.second_typeinfo;
  425. var
  426. href : treference;
  427. begin
  428. location_reset(location,LOC_REGISTER,OS_ADDR);
  429. location.register:=cg.getaddressregister(exprasmlist);
  430. reference_reset_symbol(href,tstoreddef(left.resulttype.def).get_rtti_label(fullrtti),0);
  431. cg.a_loadaddr_ref_reg(exprasmlist,href,location.register);
  432. end;
  433. {*****************************************************************************
  434. INCLUDE/EXCLUDE GENERIC HANDLING
  435. *****************************************************************************}
  436. procedure tcginlinenode.second_IncludeExclude;
  437. var
  438. L : longint;
  439. cgop : topcg;
  440. addrreg2,addrreg,
  441. hregister,hregister2: tregister;
  442. use_small : boolean;
  443. cgsize : tcgsize;
  444. href : treference;
  445. begin
  446. secondpass(tcallparanode(left).left);
  447. if tcallparanode(tcallparanode(left).right).left.nodetype=ordconstn then
  448. begin
  449. { calculate bit position }
  450. l:=1 shl (tordconstnode(tcallparanode(tcallparanode(left).right).left).value mod 32);
  451. { determine operator }
  452. if inlinenumber=in_include_x_y then
  453. cgop:=OP_OR
  454. else
  455. begin
  456. cgop:=OP_AND;
  457. l:=not(l);
  458. end;
  459. if (tcallparanode(left).left.location.loc=LOC_REFERENCE) then
  460. begin
  461. inc(tcallparanode(left).left.location.reference.offset,
  462. (tordconstnode(tcallparanode(tcallparanode(left).right).left).value div 32)*4);
  463. cg.a_op_const_ref(exprasmlist,cgop,OS_INT,aword(l),tcallparanode(left).left.location.reference);
  464. location_release(exprasmlist,tcallparanode(left).left.location);
  465. end
  466. else
  467. { LOC_CREGISTER }
  468. begin
  469. cg.a_op_const_reg(exprasmlist,cgop,tcallparanode(left).left.location.size,aword(l),tcallparanode(left).left.location.register);
  470. end;
  471. end
  472. else
  473. begin
  474. use_small:=
  475. { set type }
  476. (tsetdef(tcallparanode(left).left.resulttype.def).settype=smallset)
  477. and
  478. { elemenut number between 1 and 32 }
  479. ((tcallparanode(tcallparanode(left).right).left.resulttype.def.deftype=orddef) and
  480. (torddef(tcallparanode(tcallparanode(left).right).left.resulttype.def).high<=32) or
  481. (tcallparanode(tcallparanode(left).right).left.resulttype.def.deftype=enumdef) and
  482. (tenumdef(tcallparanode(tcallparanode(left).right).left.resulttype.def).max<=32));
  483. { generate code for the element to set }
  484. secondpass(tcallparanode(tcallparanode(left).right).left);
  485. { bitnumber - which must be loaded into register }
  486. hregister:=cg.getintregister(exprasmlist,OS_32);
  487. hregister2:=cg.getintregister(exprasmlist,OS_32);
  488. cg.a_load_loc_reg(exprasmlist,OS_32,
  489. tcallparanode(tcallparanode(left).right).left.location,hregister);
  490. if use_small then
  491. begin
  492. { hregister contains the bitnumber to add }
  493. cg.a_load_const_reg(exprasmlist, OS_32, 1, hregister2);
  494. cg.a_op_reg_reg(exprasmlist, OP_SHL, OS_32, hregister, hregister2);
  495. { possiblities :
  496. bitnumber : LOC_REFERENCE, LOC_REGISTER, LOC_CREGISTER
  497. set value : LOC_REFERENCE, LOC_REGISTER
  498. }
  499. { location of set }
  500. if (tcallparanode(left).left.location.loc=LOC_REFERENCE) then
  501. begin
  502. if inlinenumber=in_include_x_y then
  503. begin
  504. cg.a_op_reg_ref(exprasmlist, OP_OR, OS_32, hregister2,
  505. tcallparanode(left).left.location.reference);
  506. end
  507. else
  508. begin
  509. cg.a_op_reg_reg(exprasmlist, OP_NOT, OS_32, hregister2,hregister2);
  510. cg.a_op_reg_ref(exprasmlist, OP_AND, OS_32, hregister2,
  511. tcallparanode(left).left.location.reference);
  512. end;
  513. end
  514. else
  515. internalerror(20020728);
  516. end
  517. else
  518. begin
  519. { possiblities :
  520. bitnumber : LOC_REFERENCE, LOC_REGISTER, LOC_CREGISTER
  521. set value : LOC_REFERENCE
  522. }
  523. { hregister contains the bitnumber (div 32 to get the correct offset) }
  524. { hregister contains the bitnumber to add }
  525. cg.a_op_const_reg_reg(exprasmlist, OP_SHR, OS_32, 5, hregister,hregister2);
  526. cg.a_op_const_reg(exprasmlist, OP_SHL, OS_32, 2, hregister2);
  527. addrreg:=cg.getaddressregister(exprasmlist);
  528. { we need an extra address register to be able to do an ADD operation }
  529. addrreg2:=cg.getaddressregister(exprasmlist);
  530. cg.a_load_reg_reg(exprasmlist,OS_32,OS_ADDR,hregister2,addrreg2);
  531. { calculate the correct address of the operand }
  532. cg.a_loadaddr_ref_reg(exprasmlist, tcallparanode(left).left.location.reference,addrreg);
  533. cg.a_op_reg_reg(exprasmlist, OP_ADD, OS_32, addrreg2, addrreg);
  534. cg.ungetregister(exprasmlist,addrreg2);
  535. { hregister contains the bitnumber to add }
  536. cg.a_load_const_reg(exprasmlist, OS_32, 1, hregister2);
  537. cg.a_op_const_reg(exprasmlist, OP_AND, OS_32, 31, hregister);
  538. cg.a_op_reg_reg(exprasmlist, OP_SHL, OS_32, hregister, hregister2);
  539. reference_reset_base(href,addrreg,0);
  540. if inlinenumber=in_include_x_y then
  541. cg.a_op_reg_ref(exprasmlist, OP_OR, OS_32, hregister2, href)
  542. else
  543. begin
  544. cg.a_op_reg_reg(exprasmlist, OP_NOT, OS_32, hregister2, hregister2);
  545. cg.a_op_reg_ref(exprasmlist, OP_AND, OS_32, hregister2, href);
  546. end;
  547. cg.ungetregister(exprasmlist,addrreg);
  548. end;
  549. cg.ungetregister(exprasmlist,hregister);
  550. cg.ungetregister(exprasmlist,hregister2);
  551. end;
  552. end;
  553. {*****************************************************************************
  554. FLOAT GENERIC HANDLING
  555. *****************************************************************************}
  556. {
  557. These routines all call internal RTL routines, so if they are
  558. called here, they give an internal error
  559. }
  560. procedure tcginlinenode.second_pi;
  561. begin
  562. internalerror(20020718);
  563. end;
  564. procedure tcginlinenode.second_arctan_real;
  565. begin
  566. internalerror(20020718);
  567. end;
  568. procedure tcginlinenode.second_abs_real;
  569. begin
  570. internalerror(20020718);
  571. end;
  572. procedure tcginlinenode.second_sqr_real;
  573. begin
  574. internalerror(20020718);
  575. end;
  576. procedure tcginlinenode.second_sqrt_real;
  577. begin
  578. internalerror(20020718);
  579. end;
  580. procedure tcginlinenode.second_ln_real;
  581. begin
  582. internalerror(20020718);
  583. end;
  584. procedure tcginlinenode.second_cos_real;
  585. begin
  586. internalerror(20020718);
  587. end;
  588. procedure tcginlinenode.second_sin_real;
  589. begin
  590. internalerror(20020718);
  591. end;
  592. procedure tcginlinenode.second_prefetch;
  593. begin
  594. end;
  595. {*****************************************************************************
  596. ASSIGNED GENERIC HANDLING
  597. *****************************************************************************}
  598. procedure tcginlinenode.second_assigned;
  599. begin
  600. secondpass(tcallparanode(left).left);
  601. { force left to be an OS_ADDR, since in case of method procvars }
  602. { the size is 2*OS_ADDR (JM) }
  603. cg.a_cmp_const_loc_label(exprasmlist,OS_ADDR,OC_NE,0,tcallparanode(left).left.location,truelabel);
  604. cg.a_jmp_always(exprasmlist,falselabel);
  605. location_reset(location,LOC_JUMP,OS_NO);
  606. end;
  607. begin
  608. cinlinenode:=tcginlinenode;
  609. end.
  610. {
  611. $Log$
  612. Revision 1.53 2004-02-05 01:24:08 florian
  613. * several fixes to compile x86-64 system
  614. Revision 1.52 2004/02/02 20:41:59 florian
  615. + added prefetch(const mem) support
  616. Revision 1.51 2004/01/31 17:45:17 peter
  617. * Change several $ifdef i386 to x86
  618. * Change several OS_32 to OS_INT/OS_ADDR
  619. Revision 1.50 2003/12/31 20:47:02 jonas
  620. * properly fixed assigned() mess (by handling it separately in ncginl)
  621. -> all assigned()-related tests in the test suite work again
  622. Revision 1.49 2003/12/06 01:15:22 florian
  623. * reverted Peter's alloctemp patch; hopefully properly
  624. Revision 1.48 2003/12/03 23:13:20 peter
  625. * delayed paraloc allocation, a_param_*() gets extra parameter
  626. if it needs to allocate temp or real paralocation
  627. * optimized/simplified int-real loading
  628. Revision 1.47 2003/10/10 17:48:13 peter
  629. * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
  630. * tregisteralloctor renamed to trgobj
  631. * removed rgobj from a lot of units
  632. * moved location_* and reference_* to cgobj
  633. * first things for mmx register allocation
  634. Revision 1.46 2003/10/09 21:31:37 daniel
  635. * Register allocator splitted, ans abstract now
  636. Revision 1.45 2003/10/08 19:19:45 peter
  637. * set_varstate cleanup
  638. Revision 1.44 2003/10/05 21:21:52 peter
  639. * c style array of const generates callparanodes
  640. * varargs paraloc fixes
  641. Revision 1.43 2003/10/01 20:34:48 peter
  642. * procinfo unit contains tprocinfo
  643. * cginfo renamed to cgbase
  644. * moved cgmessage to verbose
  645. * fixed ppc and sparc compiles
  646. Revision 1.42 2003/09/10 08:31:47 marco
  647. * Patch from Peter for paraloc
  648. Revision 1.41 2003/09/07 22:09:35 peter
  649. * preparations for different default calling conventions
  650. * various RA fixes
  651. Revision 1.40 2003/09/03 15:55:00 peter
  652. * NEWRA branch merged
  653. Revision 1.39.2.1 2003/08/29 17:28:59 peter
  654. * next batch of updates
  655. Revision 1.39 2003/07/23 11:01:14 jonas
  656. * several rg.allocexplicitregistersint/rg.deallocexplicitregistersint
  657. pairs round calls to helpers
  658. Revision 1.38 2003/07/05 20:07:24 jonas
  659. * fixed range check errors
  660. Revision 1.37 2003/06/13 21:19:30 peter
  661. * current_procdef removed, use current_procinfo.procdef instead
  662. Revision 1.36 2003/06/07 18:57:04 jonas
  663. + added freeintparaloc
  664. * ppc get/freeintparaloc now check whether the parameter regs are
  665. properly allocated/deallocated (and get an extra list para)
  666. * ppc a_call_* now internalerrors if pi_do_call is not yet set
  667. * fixed lot of missing pi_do_call's
  668. Revision 1.35 2003/06/03 21:11:09 peter
  669. * cg.a_load_* get a from and to size specifier
  670. * makeregsize only accepts newregister
  671. * i386 uses generic tcgnotnode,tcgunaryminus
  672. Revision 1.34 2003/06/01 21:38:06 peter
  673. * getregisterfpu size parameter added
  674. * op_const_reg size parameter added
  675. * sparc updates
  676. Revision 1.33 2003/05/24 17:15:59 jonas
  677. - removed bogus location_copy for include/exclude
  678. Revision 1.32 2003/05/23 21:10:38 jonas
  679. * fixed exclude
  680. Revision 1.31 2003/05/23 14:27:35 peter
  681. * remove some unit dependencies
  682. * current_procinfo changes to store more info
  683. Revision 1.30 2003/05/09 17:47:02 peter
  684. * self moved to hidden parameter
  685. * removed hdisposen,hnewn,selfn
  686. Revision 1.29 2003/05/01 12:27:08 jonas
  687. * fixed include/exclude for normalsets
  688. Revision 1.28 2003/04/27 11:21:33 peter
  689. * aktprocdef renamed to current_procinfo.procdef
  690. * procinfo renamed to current_procinfo
  691. * procinfo will now be stored in current_module so it can be
  692. cleaned up properly
  693. * gen_main_procsym changed to create_main_proc and release_main_proc
  694. to also generate a tprocinfo structure
  695. * fixed unit implicit initfinal
  696. Revision 1.27 2003/04/25 08:25:26 daniel
  697. * Ifdefs around a lot of calls to cleartempgen
  698. * Fixed registers that are allocated but not freed in several nodes
  699. * Tweak to register allocator to cause less spills
  700. * 8-bit registers now interfere with esi,edi and ebp
  701. Compiler can now compile rtl successfully when using new register
  702. allocator
  703. Revision 1.26 2003/04/24 22:29:57 florian
  704. * fixed a lot of PowerPC related stuff
  705. Revision 1.25 2003/04/22 23:50:22 peter
  706. * firstpass uses expectloc
  707. * checks if there are differences between the expectloc and
  708. location.loc from secondpass in EXTDEBUG
  709. Revision 1.24 2003/04/22 10:09:35 daniel
  710. + Implemented the actual register allocator
  711. + Scratch registers unavailable when new register allocator used
  712. + maybe_save/maybe_restore unavailable when new register allocator used
  713. Revision 1.23 2003/04/06 21:11:23 olle
  714. * changed newasmsymbol to newasmsymboldata for data symbols
  715. Revision 1.22 2003/03/28 19:16:56 peter
  716. * generic constructor working for i386
  717. * remove fixed self register
  718. * esi added as address register for i386
  719. Revision 1.21 2003/02/19 22:00:14 daniel
  720. * Code generator converted to new register notation
  721. - Horribily outdated todo.txt removed
  722. Revision 1.20 2003/01/31 22:47:27 peter
  723. * fix previous typeof change
  724. Revision 1.19 2003/01/30 21:46:57 peter
  725. * self fixes for static methods (merged)
  726. Revision 1.18 2003/01/08 18:43:56 daniel
  727. * Tregister changed into a record
  728. Revision 1.17 2002/11/25 17:43:18 peter
  729. * splitted defbase in defutil,symutil,defcmp
  730. * merged isconvertable and is_equal into compare_defs(_ext)
  731. * made operator search faster by walking the list only once
  732. Revision 1.16 2002/10/05 12:43:25 carl
  733. * fixes for Delphi 6 compilation
  734. (warning : Some features do not work under Delphi)
  735. Revision 1.15 2002/09/30 07:00:46 florian
  736. * fixes to common code to get the alpha compiler compiled applied
  737. Revision 1.14 2002/09/17 18:54:02 jonas
  738. * a_load_reg_reg() now has two size parameters: source and dest. This
  739. allows some optimizations on architectures that don't encode the
  740. register size in the register name.
  741. Revision 1.13 2002/08/13 18:01:52 carl
  742. * rename swatoperands to swapoperands
  743. + m68k first compilable version (still needs a lot of testing):
  744. assembler generator, system information , inline
  745. assembler reader.
  746. Revision 1.12 2002/08/11 14:32:26 peter
  747. * renamed current_library to objectlibrary
  748. Revision 1.11 2002/08/11 13:24:11 peter
  749. * saving of asmsymbols in ppu supported
  750. * asmsymbollist global is removed and moved into a new class
  751. tasmlibrarydata that will hold the info of a .a file which
  752. corresponds with a single module. Added librarydata to tmodule
  753. to keep the library info stored for the module. In the future the
  754. objectfiles will also be stored to the tasmlibrarydata class
  755. * all getlabel/newasmsymbol and friends are moved to the new class
  756. Revision 1.10 2002/08/05 18:27:48 carl
  757. + more more more documentation
  758. + first version include/exclude (can't test though, not enough scratch for i386 :()...
  759. Revision 1.9 2002/08/04 19:06:41 carl
  760. + added generic exception support (still does not work!)
  761. + more documentation
  762. Revision 1.8 2002/07/31 07:54:59 jonas
  763. * re-enabled second_assigned()
  764. Revision 1.7 2002/07/30 20:50:43 florian
  765. * the code generator knows now if parameters are in registers
  766. Revision 1.6 2002/07/29 21:23:42 florian
  767. * more fixes for the ppc
  768. + wrappers for the tcnvnode.first_* stuff introduced
  769. Revision 1.5 2002/07/28 20:45:22 florian
  770. + added direct assembler reader for PowerPC
  771. Revision 1.4 2002/07/26 09:45:20 florian
  772. * fixed a mistake in yesterday's commit, forgot to commit it
  773. Revision 1.3 2002/07/25 22:58:30 florian
  774. no message
  775. Revision 1.2 2002/07/25 17:55:41 carl
  776. + First working revision
  777. Revision 1.1 2002/07/24 04:07:49 carl
  778. + first revision (incomplete)
  779. }