ncginl.pas 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902
  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,rgobj
  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. hregister:=cg.makeregsize(left.location.register,OS_32);
  308. cg.a_load_ref_reg(exprasmlist,OS_32,OS_32,href,hregister);
  309. cg.a_label(exprasmlist,lengthlab);
  310. location_reset(location,LOC_REGISTER,OS_32);
  311. location.register:=hregister;
  312. end;
  313. end;
  314. {*****************************************************************************
  315. PRED/SUCC GENERIC HANDLING
  316. *****************************************************************************}
  317. procedure tcginlinenode.second_PredSucc;
  318. var
  319. cgsize : TCGSize;
  320. cgop : topcg;
  321. begin
  322. secondpass(left);
  323. if inlinenumber=in_pred_x then
  324. cgop:=OP_SUB
  325. else
  326. cgop:=OP_ADD;
  327. cgsize:=def_cgsize(resulttype.def);
  328. { we need a value in a register }
  329. location_copy(location,left.location);
  330. location_force_reg(exprasmlist,location,cgsize,false);
  331. if cgsize in [OS_64,OS_S64] then
  332. cg64.a_op64_const_reg(exprasmlist,cgop,1,
  333. location.register64)
  334. else
  335. cg.a_op_const_reg(exprasmlist,cgop,location.size,1,location.register);
  336. cg.g_rangecheck(exprasmlist,location,resulttype.def,resulttype.def);
  337. end;
  338. {*****************************************************************************
  339. INC/DEC GENERIC HANDLING
  340. *****************************************************************************}
  341. procedure tcginlinenode.second_IncDec;
  342. const
  343. addsubop:array[in_inc_x..in_dec_x] of TOpCG=(OP_ADD,OP_SUB);
  344. var
  345. addvalue : TConstExprInt;
  346. addconstant : boolean;
  347. {$ifndef cpu64bit}
  348. hregisterhi,
  349. {$endif cpu64bit}
  350. hregister : tregister;
  351. cgsize : tcgsize;
  352. begin
  353. { set defaults }
  354. addconstant:=true;
  355. { load first parameter, must be a reference }
  356. secondpass(tcallparanode(left).left);
  357. cgsize:=def_cgsize(tcallparanode(left).left.resulttype.def);
  358. { get addvalue }
  359. case tcallparanode(left).left.resulttype.def.deftype of
  360. orddef,
  361. enumdef :
  362. addvalue:=1;
  363. pointerdef :
  364. begin
  365. if is_void(tpointerdef(tcallparanode(left).left.resulttype.def).pointertype.def) then
  366. addvalue:=1
  367. else
  368. addvalue:=tpointerdef(tcallparanode(left).left.resulttype.def).pointertype.def.size;
  369. end;
  370. else
  371. internalerror(10081);
  372. end;
  373. { second_ argument specified?, must be a s32bit in register }
  374. if assigned(tcallparanode(left).right) then
  375. begin
  376. secondpass(tcallparanode(tcallparanode(left).right).left);
  377. { when constant, just multiply the addvalue }
  378. if is_constintnode(tcallparanode(tcallparanode(left).right).left) then
  379. addvalue:=addvalue*get_ordinal_value(tcallparanode(tcallparanode(left).right).left)
  380. else
  381. begin
  382. location_force_reg(exprasmlist,tcallparanode(tcallparanode(left).right).left.location,cgsize,false);
  383. hregister:=tcallparanode(tcallparanode(left).right).left.location.register;
  384. {$ifndef cpu64bit}
  385. hregisterhi:=tcallparanode(tcallparanode(left).right).left.location.registerhigh;
  386. {$endif cpu64bit}
  387. { insert multiply with addvalue if its >1 }
  388. if addvalue>1 then
  389. cg.a_op_const_reg(exprasmlist,OP_IMUL,cgsize,addvalue,hregister);
  390. addconstant:=false;
  391. end;
  392. end;
  393. { write the add instruction }
  394. if addconstant then
  395. begin
  396. if cgsize in [OS_64,OS_S64] then
  397. cg64.a_op64_const_loc(exprasmlist,addsubop[inlinenumber],
  398. addvalue,tcallparanode(left).left.location)
  399. else
  400. cg.a_op_const_loc(exprasmlist,addsubop[inlinenumber],
  401. aword(addvalue),tcallparanode(left).left.location);
  402. end
  403. else
  404. begin
  405. {$ifndef cpu64bit}
  406. if cgsize in [OS_64,OS_S64] then
  407. cg64.a_op64_reg_loc(exprasmlist,addsubop[inlinenumber],
  408. joinreg64(hregister,hregisterhi),tcallparanode(left).left.location)
  409. else
  410. {$endif cpu64bit}
  411. cg.a_op_reg_loc(exprasmlist,addsubop[inlinenumber],
  412. hregister,tcallparanode(left).left.location);
  413. location_release(exprasmlist,tcallparanode(tcallparanode(left).right).left.location);
  414. end;
  415. location_release(exprasmlist,tcallparanode(left).left.location);
  416. cg.g_overflowcheck(exprasmlist,tcallparanode(left).left.location,tcallparanode(left).resulttype.def);
  417. cg.g_rangecheck(exprasmlist,tcallparanode(left).left.location,tcallparanode(left).left.resulttype.def,
  418. tcallparanode(left).left.resulttype.def);
  419. end;
  420. {*****************************************************************************
  421. TYPEINFO GENERIC HANDLING
  422. *****************************************************************************}
  423. procedure tcginlinenode.second_typeinfo;
  424. var
  425. href : treference;
  426. begin
  427. location_reset(location,LOC_REGISTER,OS_ADDR);
  428. location.register:=cg.getaddressregister(exprasmlist);
  429. reference_reset_symbol(href,tstoreddef(left.resulttype.def).get_rtti_label(fullrtti),0);
  430. cg.a_loadaddr_ref_reg(exprasmlist,href,location.register);
  431. end;
  432. {*****************************************************************************
  433. INCLUDE/EXCLUDE GENERIC HANDLING
  434. *****************************************************************************}
  435. procedure tcginlinenode.second_IncludeExclude;
  436. var
  437. L : longint;
  438. cgop : topcg;
  439. addrreg2,addrreg,
  440. hregister,hregister2: tregister;
  441. use_small : boolean;
  442. cgsize : tcgsize;
  443. href : treference;
  444. begin
  445. secondpass(tcallparanode(left).left);
  446. if tcallparanode(tcallparanode(left).right).left.nodetype=ordconstn then
  447. begin
  448. { calculate bit position }
  449. l:=1 shl (tordconstnode(tcallparanode(tcallparanode(left).right).left).value mod 32);
  450. { determine operator }
  451. if inlinenumber=in_include_x_y then
  452. cgop:=OP_OR
  453. else
  454. begin
  455. cgop:=OP_AND;
  456. l:=not(l);
  457. end;
  458. if (tcallparanode(left).left.location.loc=LOC_REFERENCE) then
  459. begin
  460. inc(tcallparanode(left).left.location.reference.offset,
  461. (tordconstnode(tcallparanode(tcallparanode(left).right).left).value div 32)*4);
  462. cg.a_op_const_ref(exprasmlist,cgop,OS_INT,aword(l),tcallparanode(left).left.location.reference);
  463. location_release(exprasmlist,tcallparanode(left).left.location);
  464. end
  465. else
  466. { LOC_CREGISTER }
  467. begin
  468. cg.a_op_const_reg(exprasmlist,cgop,tcallparanode(left).left.location.size,aword(l),tcallparanode(left).left.location.register);
  469. end;
  470. end
  471. else
  472. begin
  473. use_small:=
  474. { set type }
  475. (tsetdef(tcallparanode(left).left.resulttype.def).settype=smallset)
  476. and
  477. { elemenut number between 1 and 32 }
  478. ((tcallparanode(tcallparanode(left).right).left.resulttype.def.deftype=orddef) and
  479. (torddef(tcallparanode(tcallparanode(left).right).left.resulttype.def).high<=32) or
  480. (tcallparanode(tcallparanode(left).right).left.resulttype.def.deftype=enumdef) and
  481. (tenumdef(tcallparanode(tcallparanode(left).right).left.resulttype.def).max<=32));
  482. { generate code for the element to set }
  483. secondpass(tcallparanode(tcallparanode(left).right).left);
  484. { bitnumber - which must be loaded into register }
  485. hregister:=cg.getintregister(exprasmlist,OS_32);
  486. hregister2:=cg.getintregister(exprasmlist,OS_32);
  487. cg.a_load_loc_reg(exprasmlist,OS_32,
  488. tcallparanode(tcallparanode(left).right).left.location,hregister);
  489. if use_small then
  490. begin
  491. { hregister contains the bitnumber to add }
  492. cg.a_load_const_reg(exprasmlist, OS_32, 1, hregister2);
  493. cg.a_op_reg_reg(exprasmlist, OP_SHL, OS_32, hregister, hregister2);
  494. { possiblities :
  495. bitnumber : LOC_REFERENCE, LOC_REGISTER, LOC_CREGISTER
  496. set value : LOC_REFERENCE, LOC_REGISTER
  497. }
  498. { location of set }
  499. if (tcallparanode(left).left.location.loc=LOC_REFERENCE) then
  500. begin
  501. if inlinenumber=in_include_x_y then
  502. begin
  503. cg.a_op_reg_ref(exprasmlist, OP_OR, OS_32, hregister2,
  504. tcallparanode(left).left.location.reference);
  505. end
  506. else
  507. begin
  508. cg.a_op_reg_reg(exprasmlist, OP_NOT, OS_32, hregister2,hregister2);
  509. cg.a_op_reg_ref(exprasmlist, OP_AND, OS_32, hregister2,
  510. tcallparanode(left).left.location.reference);
  511. end;
  512. end
  513. else
  514. internalerror(20020728);
  515. end
  516. else
  517. begin
  518. { possiblities :
  519. bitnumber : LOC_REFERENCE, LOC_REGISTER, LOC_CREGISTER
  520. set value : LOC_REFERENCE
  521. }
  522. { hregister contains the bitnumber (div 32 to get the correct offset) }
  523. { hregister contains the bitnumber to add }
  524. cg.a_op_const_reg_reg(exprasmlist, OP_SHR, OS_32, 5, hregister,hregister2);
  525. cg.a_op_const_reg(exprasmlist, OP_SHL, OS_32, 2, hregister2);
  526. addrreg:=cg.getaddressregister(exprasmlist);
  527. { we need an extra address register to be able to do an ADD operation }
  528. addrreg2:=cg.getaddressregister(exprasmlist);
  529. cg.a_load_reg_reg(exprasmlist,OS_32,OS_ADDR,hregister2,addrreg2);
  530. { calculate the correct address of the operand }
  531. cg.a_loadaddr_ref_reg(exprasmlist, tcallparanode(left).left.location.reference,addrreg);
  532. cg.a_op_reg_reg(exprasmlist, OP_ADD, OS_32, addrreg2, addrreg);
  533. cg.ungetregister(exprasmlist,addrreg2);
  534. { hregister contains the bitnumber to add }
  535. cg.a_load_const_reg(exprasmlist, OS_32, 1, hregister2);
  536. cg.a_op_const_reg(exprasmlist, OP_AND, OS_32, 31, hregister);
  537. cg.a_op_reg_reg(exprasmlist, OP_SHL, OS_32, hregister, hregister2);
  538. reference_reset_base(href,addrreg,0);
  539. if inlinenumber=in_include_x_y then
  540. cg.a_op_reg_ref(exprasmlist, OP_OR, OS_32, hregister2, href)
  541. else
  542. begin
  543. cg.a_op_reg_reg(exprasmlist, OP_NOT, OS_32, hregister2, hregister2);
  544. cg.a_op_reg_ref(exprasmlist, OP_AND, OS_32, hregister2, href);
  545. end;
  546. cg.ungetregister(exprasmlist,addrreg);
  547. end;
  548. cg.ungetregister(exprasmlist,hregister);
  549. cg.ungetregister(exprasmlist,hregister2);
  550. end;
  551. end;
  552. {*****************************************************************************
  553. FLOAT GENERIC HANDLING
  554. *****************************************************************************}
  555. {
  556. These routines all call internal RTL routines, so if they are
  557. called here, they give an internal error
  558. }
  559. procedure tcginlinenode.second_pi;
  560. begin
  561. internalerror(20020718);
  562. end;
  563. procedure tcginlinenode.second_arctan_real;
  564. begin
  565. internalerror(20020718);
  566. end;
  567. procedure tcginlinenode.second_abs_real;
  568. begin
  569. internalerror(20020718);
  570. end;
  571. procedure tcginlinenode.second_sqr_real;
  572. begin
  573. internalerror(20020718);
  574. end;
  575. procedure tcginlinenode.second_sqrt_real;
  576. begin
  577. internalerror(20020718);
  578. end;
  579. procedure tcginlinenode.second_ln_real;
  580. begin
  581. internalerror(20020718);
  582. end;
  583. procedure tcginlinenode.second_cos_real;
  584. begin
  585. internalerror(20020718);
  586. end;
  587. procedure tcginlinenode.second_sin_real;
  588. begin
  589. internalerror(20020718);
  590. end;
  591. procedure tcginlinenode.second_prefetch;
  592. begin
  593. end;
  594. {*****************************************************************************
  595. ASSIGNED GENERIC HANDLING
  596. *****************************************************************************}
  597. procedure tcginlinenode.second_assigned;
  598. begin
  599. secondpass(tcallparanode(left).left);
  600. { force left to be an OS_ADDR, since in case of method procvars }
  601. { the size is 2*OS_ADDR (JM) }
  602. cg.a_cmp_const_loc_label(exprasmlist,OS_ADDR,OC_NE,0,tcallparanode(left).left.location,truelabel);
  603. cg.a_jmp_always(exprasmlist,falselabel);
  604. location_reset(location,LOC_JUMP,OS_NO);
  605. end;
  606. begin
  607. cinlinenode:=tcginlinenode;
  608. end.
  609. {
  610. $Log$
  611. Revision 1.54 2004-02-05 16:58:43 florian
  612. * fixed (hopefully) the ansistring length bug
  613. Revision 1.53 2004/02/05 01:24:08 florian
  614. * several fixes to compile x86-64 system
  615. Revision 1.52 2004/02/02 20:41:59 florian
  616. + added prefetch(const mem) support
  617. Revision 1.51 2004/01/31 17:45:17 peter
  618. * Change several $ifdef i386 to x86
  619. * Change several OS_32 to OS_INT/OS_ADDR
  620. Revision 1.50 2003/12/31 20:47:02 jonas
  621. * properly fixed assigned() mess (by handling it separately in ncginl)
  622. -> all assigned()-related tests in the test suite work again
  623. Revision 1.49 2003/12/06 01:15:22 florian
  624. * reverted Peter's alloctemp patch; hopefully properly
  625. Revision 1.48 2003/12/03 23:13:20 peter
  626. * delayed paraloc allocation, a_param_*() gets extra parameter
  627. if it needs to allocate temp or real paralocation
  628. * optimized/simplified int-real loading
  629. Revision 1.47 2003/10/10 17:48:13 peter
  630. * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
  631. * tregisteralloctor renamed to trgobj
  632. * removed rgobj from a lot of units
  633. * moved location_* and reference_* to cgobj
  634. * first things for mmx register allocation
  635. Revision 1.46 2003/10/09 21:31:37 daniel
  636. * Register allocator splitted, ans abstract now
  637. Revision 1.45 2003/10/08 19:19:45 peter
  638. * set_varstate cleanup
  639. Revision 1.44 2003/10/05 21:21:52 peter
  640. * c style array of const generates callparanodes
  641. * varargs paraloc fixes
  642. Revision 1.43 2003/10/01 20:34:48 peter
  643. * procinfo unit contains tprocinfo
  644. * cginfo renamed to cgbase
  645. * moved cgmessage to verbose
  646. * fixed ppc and sparc compiles
  647. Revision 1.42 2003/09/10 08:31:47 marco
  648. * Patch from Peter for paraloc
  649. Revision 1.41 2003/09/07 22:09:35 peter
  650. * preparations for different default calling conventions
  651. * various RA fixes
  652. Revision 1.40 2003/09/03 15:55:00 peter
  653. * NEWRA branch merged
  654. Revision 1.39.2.1 2003/08/29 17:28:59 peter
  655. * next batch of updates
  656. Revision 1.39 2003/07/23 11:01:14 jonas
  657. * several rg.allocexplicitregistersint/rg.deallocexplicitregistersint
  658. pairs round calls to helpers
  659. Revision 1.38 2003/07/05 20:07:24 jonas
  660. * fixed range check errors
  661. Revision 1.37 2003/06/13 21:19:30 peter
  662. * current_procdef removed, use current_procinfo.procdef instead
  663. Revision 1.36 2003/06/07 18:57:04 jonas
  664. + added freeintparaloc
  665. * ppc get/freeintparaloc now check whether the parameter regs are
  666. properly allocated/deallocated (and get an extra list para)
  667. * ppc a_call_* now internalerrors if pi_do_call is not yet set
  668. * fixed lot of missing pi_do_call's
  669. Revision 1.35 2003/06/03 21:11:09 peter
  670. * cg.a_load_* get a from and to size specifier
  671. * makeregsize only accepts newregister
  672. * i386 uses generic tcgnotnode,tcgunaryminus
  673. Revision 1.34 2003/06/01 21:38:06 peter
  674. * getregisterfpu size parameter added
  675. * op_const_reg size parameter added
  676. * sparc updates
  677. Revision 1.33 2003/05/24 17:15:59 jonas
  678. - removed bogus location_copy for include/exclude
  679. Revision 1.32 2003/05/23 21:10:38 jonas
  680. * fixed exclude
  681. Revision 1.31 2003/05/23 14:27:35 peter
  682. * remove some unit dependencies
  683. * current_procinfo changes to store more info
  684. Revision 1.30 2003/05/09 17:47:02 peter
  685. * self moved to hidden parameter
  686. * removed hdisposen,hnewn,selfn
  687. Revision 1.29 2003/05/01 12:27:08 jonas
  688. * fixed include/exclude for normalsets
  689. Revision 1.28 2003/04/27 11:21:33 peter
  690. * aktprocdef renamed to current_procinfo.procdef
  691. * procinfo renamed to current_procinfo
  692. * procinfo will now be stored in current_module so it can be
  693. cleaned up properly
  694. * gen_main_procsym changed to create_main_proc and release_main_proc
  695. to also generate a tprocinfo structure
  696. * fixed unit implicit initfinal
  697. Revision 1.27 2003/04/25 08:25:26 daniel
  698. * Ifdefs around a lot of calls to cleartempgen
  699. * Fixed registers that are allocated but not freed in several nodes
  700. * Tweak to register allocator to cause less spills
  701. * 8-bit registers now interfere with esi,edi and ebp
  702. Compiler can now compile rtl successfully when using new register
  703. allocator
  704. Revision 1.26 2003/04/24 22:29:57 florian
  705. * fixed a lot of PowerPC related stuff
  706. Revision 1.25 2003/04/22 23:50:22 peter
  707. * firstpass uses expectloc
  708. * checks if there are differences between the expectloc and
  709. location.loc from secondpass in EXTDEBUG
  710. Revision 1.24 2003/04/22 10:09:35 daniel
  711. + Implemented the actual register allocator
  712. + Scratch registers unavailable when new register allocator used
  713. + maybe_save/maybe_restore unavailable when new register allocator used
  714. Revision 1.23 2003/04/06 21:11:23 olle
  715. * changed newasmsymbol to newasmsymboldata for data symbols
  716. Revision 1.22 2003/03/28 19:16:56 peter
  717. * generic constructor working for i386
  718. * remove fixed self register
  719. * esi added as address register for i386
  720. Revision 1.21 2003/02/19 22:00:14 daniel
  721. * Code generator converted to new register notation
  722. - Horribily outdated todo.txt removed
  723. Revision 1.20 2003/01/31 22:47:27 peter
  724. * fix previous typeof change
  725. Revision 1.19 2003/01/30 21:46:57 peter
  726. * self fixes for static methods (merged)
  727. Revision 1.18 2003/01/08 18:43:56 daniel
  728. * Tregister changed into a record
  729. Revision 1.17 2002/11/25 17:43:18 peter
  730. * splitted defbase in defutil,symutil,defcmp
  731. * merged isconvertable and is_equal into compare_defs(_ext)
  732. * made operator search faster by walking the list only once
  733. Revision 1.16 2002/10/05 12:43:25 carl
  734. * fixes for Delphi 6 compilation
  735. (warning : Some features do not work under Delphi)
  736. Revision 1.15 2002/09/30 07:00:46 florian
  737. * fixes to common code to get the alpha compiler compiled applied
  738. Revision 1.14 2002/09/17 18:54:02 jonas
  739. * a_load_reg_reg() now has two size parameters: source and dest. This
  740. allows some optimizations on architectures that don't encode the
  741. register size in the register name.
  742. Revision 1.13 2002/08/13 18:01:52 carl
  743. * rename swatoperands to swapoperands
  744. + m68k first compilable version (still needs a lot of testing):
  745. assembler generator, system information , inline
  746. assembler reader.
  747. Revision 1.12 2002/08/11 14:32:26 peter
  748. * renamed current_library to objectlibrary
  749. Revision 1.11 2002/08/11 13:24:11 peter
  750. * saving of asmsymbols in ppu supported
  751. * asmsymbollist global is removed and moved into a new class
  752. tasmlibrarydata that will hold the info of a .a file which
  753. corresponds with a single module. Added librarydata to tmodule
  754. to keep the library info stored for the module. In the future the
  755. objectfiles will also be stored to the tasmlibrarydata class
  756. * all getlabel/newasmsymbol and friends are moved to the new class
  757. Revision 1.10 2002/08/05 18:27:48 carl
  758. + more more more documentation
  759. + first version include/exclude (can't test though, not enough scratch for i386 :()...
  760. Revision 1.9 2002/08/04 19:06:41 carl
  761. + added generic exception support (still does not work!)
  762. + more documentation
  763. Revision 1.8 2002/07/31 07:54:59 jonas
  764. * re-enabled second_assigned()
  765. Revision 1.7 2002/07/30 20:50:43 florian
  766. * the code generator knows now if parameters are in registers
  767. Revision 1.6 2002/07/29 21:23:42 florian
  768. * more fixes for the ppc
  769. + wrappers for the tcnvnode.first_* stuff introduced
  770. Revision 1.5 2002/07/28 20:45:22 florian
  771. + added direct assembler reader for PowerPC
  772. Revision 1.4 2002/07/26 09:45:20 florian
  773. * fixed a mistake in yesterday's commit, forgot to commit it
  774. Revision 1.3 2002/07/25 22:58:30 florian
  775. no message
  776. Revision 1.2 2002/07/25 17:55:41 carl
  777. + First working revision
  778. Revision 1.1 2002/07/24 04:07:49 carl
  779. + first revision (incomplete)
  780. }