ncginl.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  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,parabase,
  50. cgbase,pass_1,pass_2,
  51. cpuinfo,cpubase,paramgr,procinfo,
  52. nbas,ncon,ncal,ncnv,nld,
  53. tgobj,ncgutil,
  54. cgutils,cgobj
  55. {$ifndef cpu64bit}
  56. ,cg64f32
  57. {$endif cpu64bit}
  58. ;
  59. {*****************************************************************************
  60. TCGINLINENODE
  61. *****************************************************************************}
  62. procedure tcginlinenode.pass_2;
  63. begin
  64. location_reset(location,LOC_VOID,OS_NO);
  65. case inlinenumber of
  66. in_assert_x_y:
  67. begin
  68. second_Assert;
  69. end;
  70. in_sizeof_x,
  71. in_typeof_x :
  72. begin
  73. second_SizeofTypeOf;
  74. end;
  75. in_length_x :
  76. begin
  77. second_Length;
  78. end;
  79. in_pred_x,
  80. in_succ_x:
  81. begin
  82. second_PredSucc;
  83. end;
  84. in_dec_x,
  85. in_inc_x :
  86. begin
  87. second_IncDec;
  88. end;
  89. in_typeinfo_x:
  90. begin
  91. second_TypeInfo;
  92. end;
  93. in_include_x_y,
  94. in_exclude_x_y:
  95. begin
  96. second_IncludeExclude;
  97. end;
  98. in_pi_real:
  99. begin
  100. second_pi;
  101. end;
  102. in_sin_real:
  103. begin
  104. second_sin_real;
  105. end;
  106. in_arctan_real:
  107. begin
  108. second_arctan_real;
  109. end;
  110. in_abs_real:
  111. begin
  112. second_abs_real;
  113. end;
  114. in_sqr_real:
  115. begin
  116. second_sqr_real;
  117. end;
  118. in_sqrt_real:
  119. begin
  120. second_sqrt_real;
  121. end;
  122. in_ln_real:
  123. begin
  124. second_ln_real;
  125. end;
  126. in_cos_real:
  127. begin
  128. second_cos_real;
  129. end;
  130. in_prefetch_var:
  131. begin
  132. second_prefetch;
  133. end;
  134. in_assigned_x:
  135. begin
  136. second_assigned;
  137. end;
  138. {$ifdef SUPPORT_MMX}
  139. in_mmx_pcmpeqb..in_mmx_pcmpgtw:
  140. begin
  141. location_reset(location,LOC_MMXREGISTER,OS_NO);
  142. if left.location.loc=LOC_REGISTER then
  143. begin
  144. {!!!!!!!}
  145. end
  146. else if tcallparanode(left).left.location.loc=LOC_REGISTER then
  147. begin
  148. {!!!!!!!}
  149. end
  150. else
  151. begin
  152. {!!!!!!!}
  153. end;
  154. end;
  155. {$endif SUPPORT_MMX}
  156. else internalerror(9);
  157. end;
  158. end;
  159. {*****************************************************************************
  160. ASSERT GENERIC HANDLING
  161. *****************************************************************************}
  162. procedure tcginlinenode.second_Assert;
  163. var
  164. hp2 : tstringconstnode;
  165. otlabel,oflabel : tasmlabel;
  166. paraloc1,paraloc2,
  167. paraloc3,paraloc4 : tcgpara;
  168. begin
  169. { the node should be removed in the firstpass }
  170. if not (cs_do_assertion in aktlocalswitches) then
  171. internalerror(7123458);
  172. paraloc1.init;
  173. paraloc2.init;
  174. paraloc3.init;
  175. paraloc4.init;
  176. paramanager.getintparaloc(pocall_default,1,paraloc1);
  177. paramanager.getintparaloc(pocall_default,2,paraloc2);
  178. paramanager.getintparaloc(pocall_default,3,paraloc3);
  179. paramanager.getintparaloc(pocall_default,4,paraloc4);
  180. otlabel:=truelabel;
  181. oflabel:=falselabel;
  182. objectlibrary.getlabel(truelabel);
  183. objectlibrary.getlabel(falselabel);
  184. secondpass(tcallparanode(left).left);
  185. maketojumpbool(exprasmlist,tcallparanode(left).left,lr_load_regvars);
  186. cg.a_label(exprasmlist,falselabel);
  187. { erroraddr }
  188. paramanager.allocparaloc(exprasmlist,paraloc4);
  189. cg.a_param_reg(exprasmlist,OS_ADDR,NR_FRAME_POINTER_REG,paraloc4);
  190. { lineno }
  191. paramanager.allocparaloc(exprasmlist,paraloc3);
  192. cg.a_param_const(exprasmlist,OS_INT,aktfilepos.line,paraloc3);
  193. { filename string }
  194. hp2:=cstringconstnode.createstr(current_module.sourcefiles.get_file_name(aktfilepos.fileindex),st_shortstring);
  195. firstpass(tnode(hp2));
  196. secondpass(tnode(hp2));
  197. if codegenerror then
  198. exit;
  199. paramanager.allocparaloc(exprasmlist,paraloc2);
  200. cg.a_paramaddr_ref(exprasmlist,hp2.location.reference,paraloc2);
  201. hp2.free;
  202. { push msg }
  203. secondpass(tcallparanode(tcallparanode(left).right).left);
  204. paramanager.allocparaloc(exprasmlist,paraloc1);
  205. cg.a_paramaddr_ref(exprasmlist,tcallparanode(tcallparanode(left).right).left.location.reference,paraloc1);
  206. { call }
  207. paramanager.freeparaloc(exprasmlist,paraloc1);
  208. paramanager.freeparaloc(exprasmlist,paraloc2);
  209. paramanager.freeparaloc(exprasmlist,paraloc3);
  210. paramanager.freeparaloc(exprasmlist,paraloc4);
  211. cg.alloccpuregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  212. cg.a_call_name(exprasmlist,'FPC_ASSERT');
  213. cg.dealloccpuregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  214. cg.a_label(exprasmlist,truelabel);
  215. truelabel:=otlabel;
  216. falselabel:=oflabel;
  217. paraloc1.done;
  218. paraloc2.done;
  219. paraloc3.done;
  220. paraloc4.done;
  221. end;
  222. {*****************************************************************************
  223. SIZEOF / TYPEOF GENERIC HANDLING
  224. *****************************************************************************}
  225. { second_handle_ the sizeof and typeof routines }
  226. procedure tcginlinenode.second_SizeOfTypeOf;
  227. var
  228. href,
  229. hrefvmt : treference;
  230. hregister : tregister;
  231. begin
  232. if inlinenumber=in_sizeof_x then
  233. location_reset(location,LOC_REGISTER,OS_INT)
  234. else
  235. location_reset(location,LOC_REGISTER,OS_ADDR);
  236. { for both cases load vmt }
  237. if left.nodetype=typen then
  238. begin
  239. hregister:=cg.getaddressregister(exprasmlist);
  240. reference_reset_symbol(href,objectlibrary.newasmsymbol(tobjectdef(left.resulttype.def).vmt_mangledname,AB_EXTERNAL,AT_DATA),0);
  241. cg.a_loadaddr_ref_reg(exprasmlist,href,hregister);
  242. end
  243. else
  244. begin
  245. secondpass(left);
  246. hregister:=cg.getaddressregister(exprasmlist);
  247. { handle self inside a method of a class }
  248. case left.location.loc of
  249. LOC_CREGISTER,
  250. LOC_REGISTER :
  251. begin
  252. if (left.resulttype.def.deftype=classrefdef) or
  253. (po_staticmethod in current_procinfo.procdef.procoptions) then
  254. cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.register,hregister)
  255. else
  256. begin
  257. { load VMT pointer }
  258. reference_reset_base(hrefvmt,left.location.register,tobjectdef(left.resulttype.def).vmt_offset);
  259. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,hrefvmt,hregister);
  260. end
  261. end;
  262. LOC_REFERENCE,
  263. LOC_CREFERENCE :
  264. begin
  265. if is_class(left.resulttype.def) then
  266. begin
  267. { deref class }
  268. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.reference,hregister);
  269. cg.g_maybe_testself(exprasmlist,hregister);
  270. { load VMT pointer }
  271. reference_reset_base(hrefvmt,hregister,tobjectdef(left.resulttype.def).vmt_offset);
  272. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,hrefvmt,hregister);
  273. end
  274. else
  275. begin
  276. { load VMT pointer, but not for classrefdefs }
  277. if (left.resulttype.def.deftype=objectdef) then
  278. inc(left.location.reference.offset,tobjectdef(left.resulttype.def).vmt_offset);
  279. cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.reference,hregister);
  280. end;
  281. end;
  282. else
  283. internalerror(200301301);
  284. end;
  285. end;
  286. { in sizeof load size }
  287. if inlinenumber=in_sizeof_x then
  288. begin
  289. reference_reset_base(href,hregister,0);
  290. hregister:=cg.getintregister(exprasmlist,OS_INT);
  291. cg.a_load_ref_reg(exprasmlist,OS_INT,OS_INT,href,hregister);
  292. end;
  293. location.register:=hregister;
  294. end;
  295. {*****************************************************************************
  296. LENGTH GENERIC HANDLING
  297. *****************************************************************************}
  298. procedure tcginlinenode.second_Length;
  299. var
  300. lengthlab : tasmlabel;
  301. hregister : tregister;
  302. href : treference;
  303. begin
  304. secondpass(left);
  305. if is_shortstring(left.resulttype.def) then
  306. begin
  307. location_copy(location,left.location);
  308. location.size:=OS_8;
  309. end
  310. else
  311. begin
  312. { length in ansi/wide strings is at offset -sizeof(aint) }
  313. location_force_reg(exprasmlist,left.location,OS_ADDR,false);
  314. objectlibrary.getlabel(lengthlab);
  315. cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,left.location.register,lengthlab);
  316. reference_reset_base(href,left.location.register,-sizeof(aint));
  317. hregister:=cg.makeregsize(exprasmlist,left.location.register,OS_INT);
  318. cg.a_load_ref_reg(exprasmlist,OS_INT,OS_INT,href,hregister);
  319. cg.a_label(exprasmlist,lengthlab);
  320. location_reset(location,LOC_REGISTER,OS_INT);
  321. location.register:=hregister;
  322. end;
  323. end;
  324. {*****************************************************************************
  325. PRED/SUCC GENERIC HANDLING
  326. *****************************************************************************}
  327. procedure tcginlinenode.second_PredSucc;
  328. var
  329. cgsize : TCGSize;
  330. cgop : topcg;
  331. begin
  332. secondpass(left);
  333. if inlinenumber=in_pred_x then
  334. cgop:=OP_SUB
  335. else
  336. cgop:=OP_ADD;
  337. cgsize:=def_cgsize(resulttype.def);
  338. { we need a value in a register }
  339. location_copy(location,left.location);
  340. location_force_reg(exprasmlist,location,cgsize,false);
  341. {$ifndef cpu64bit}
  342. if cgsize in [OS_64,OS_S64] then
  343. cg64.a_op64_const_reg(exprasmlist,cgop,1,location.register64)
  344. else
  345. {$endif cpu64bit}
  346. cg.a_op_const_reg(exprasmlist,cgop,location.size,1,location.register);
  347. cg.g_rangecheck(exprasmlist,location,resulttype.def,resulttype.def);
  348. end;
  349. {*****************************************************************************
  350. INC/DEC GENERIC HANDLING
  351. *****************************************************************************}
  352. procedure tcginlinenode.second_IncDec;
  353. const
  354. addsubop:array[in_inc_x..in_dec_x] of TOpCG=(OP_ADD,OP_SUB);
  355. var
  356. addvalue : TConstExprInt;
  357. addconstant : boolean;
  358. {$ifndef cpu64bit}
  359. hregisterhi,
  360. {$endif cpu64bit}
  361. hregister : tregister;
  362. cgsize : tcgsize;
  363. begin
  364. { set defaults }
  365. addconstant:=true;
  366. { load first parameter, must be a reference }
  367. secondpass(tcallparanode(left).left);
  368. cgsize:=def_cgsize(tcallparanode(left).left.resulttype.def);
  369. { get addvalue }
  370. case tcallparanode(left).left.resulttype.def.deftype of
  371. orddef,
  372. enumdef :
  373. addvalue:=1;
  374. pointerdef :
  375. begin
  376. if is_void(tpointerdef(tcallparanode(left).left.resulttype.def).pointertype.def) then
  377. addvalue:=1
  378. else
  379. addvalue:=tpointerdef(tcallparanode(left).left.resulttype.def).pointertype.def.size;
  380. end;
  381. else
  382. internalerror(10081);
  383. end;
  384. { second_ argument specified?, must be a s32bit in register }
  385. if assigned(tcallparanode(left).right) then
  386. begin
  387. secondpass(tcallparanode(tcallparanode(left).right).left);
  388. { when constant, just multiply the addvalue }
  389. if is_constintnode(tcallparanode(tcallparanode(left).right).left) then
  390. addvalue:=addvalue*get_ordinal_value(tcallparanode(tcallparanode(left).right).left)
  391. else
  392. begin
  393. location_force_reg(exprasmlist,tcallparanode(tcallparanode(left).right).left.location,cgsize,addvalue<=1);
  394. hregister:=tcallparanode(tcallparanode(left).right).left.location.register;
  395. {$ifndef cpu64bit}
  396. hregisterhi:=tcallparanode(tcallparanode(left).right).left.location.register64.reghi;
  397. {$endif cpu64bit}
  398. { insert multiply with addvalue if its >1 }
  399. if addvalue>1 then
  400. cg.a_op_const_reg(exprasmlist,OP_IMUL,cgsize,addvalue,hregister);
  401. addconstant:=false;
  402. end;
  403. end;
  404. { write the add instruction }
  405. if addconstant then
  406. begin
  407. {$ifndef cpu64bit}
  408. if cgsize in [OS_64,OS_S64] then
  409. cg64.a_op64_const_loc(exprasmlist,addsubop[inlinenumber],addvalue,tcallparanode(left).left.location)
  410. else
  411. {$endif cpu64bit}
  412. cg.a_op_const_loc(exprasmlist,addsubop[inlinenumber],
  413. aint(addvalue),tcallparanode(left).left.location);
  414. end
  415. else
  416. begin
  417. {$ifndef cpu64bit}
  418. if cgsize in [OS_64,OS_S64] then
  419. cg64.a_op64_reg_loc(exprasmlist,addsubop[inlinenumber],
  420. joinreg64(hregister,hregisterhi),tcallparanode(left).left.location)
  421. else
  422. {$endif cpu64bit}
  423. cg.a_op_reg_loc(exprasmlist,addsubop[inlinenumber],
  424. hregister,tcallparanode(left).left.location);
  425. end;
  426. cg.g_overflowcheck(exprasmlist,tcallparanode(left).left.location,tcallparanode(left).resulttype.def);
  427. cg.g_rangecheck(exprasmlist,tcallparanode(left).left.location,tcallparanode(left).left.resulttype.def,
  428. tcallparanode(left).left.resulttype.def);
  429. end;
  430. {*****************************************************************************
  431. TYPEINFO GENERIC HANDLING
  432. *****************************************************************************}
  433. procedure tcginlinenode.second_typeinfo;
  434. var
  435. href : treference;
  436. begin
  437. location_reset(location,LOC_REGISTER,OS_ADDR);
  438. location.register:=cg.getaddressregister(exprasmlist);
  439. reference_reset_symbol(href,tstoreddef(left.resulttype.def).get_rtti_label(fullrtti),0);
  440. cg.a_loadaddr_ref_reg(exprasmlist,href,location.register);
  441. end;
  442. {*****************************************************************************
  443. INCLUDE/EXCLUDE GENERIC HANDLING
  444. *****************************************************************************}
  445. procedure tcginlinenode.second_IncludeExclude;
  446. var
  447. bitsperop,l : longint;
  448. opsize : tcgsize;
  449. cgop : topcg;
  450. addrreg2,addrreg,
  451. hregister,hregister2: tregister;
  452. use_small : boolean;
  453. href : treference;
  454. begin
  455. opsize:=OS_32;
  456. bitsperop:=(8*tcgsize2size[opsize]);
  457. secondpass(tcallparanode(left).left);
  458. if tcallparanode(tcallparanode(left).right).left.nodetype=ordconstn then
  459. begin
  460. { calculate bit position }
  461. l:=1 shl (tordconstnode(tcallparanode(tcallparanode(left).right).left).value mod bitsperop);
  462. { determine operator }
  463. if inlinenumber=in_include_x_y then
  464. cgop:=OP_OR
  465. else
  466. begin
  467. cgop:=OP_AND;
  468. l:=not(l);
  469. end;
  470. case tcallparanode(left).left.location.loc of
  471. LOC_REFERENCE :
  472. begin
  473. inc(tcallparanode(left).left.location.reference.offset,
  474. (tordconstnode(tcallparanode(tcallparanode(left).right).left).value div bitsperop)*tcgsize2size[opsize]);
  475. cg.a_op_const_ref(exprasmlist,cgop,opsize,l,tcallparanode(left).left.location.reference);
  476. end;
  477. LOC_CREGISTER :
  478. cg.a_op_const_reg(exprasmlist,cgop,tcallparanode(left).left.location.size,l,tcallparanode(left).left.location.register);
  479. else
  480. internalerror(200405021);
  481. end;
  482. end
  483. else
  484. begin
  485. use_small:=
  486. { set type }
  487. (tsetdef(tcallparanode(left).left.resulttype.def).settype=smallset)
  488. and
  489. { elemenut number between 1 and 32 }
  490. ((tcallparanode(tcallparanode(left).right).left.resulttype.def.deftype=orddef) and
  491. (torddef(tcallparanode(tcallparanode(left).right).left.resulttype.def).high<=32) or
  492. (tcallparanode(tcallparanode(left).right).left.resulttype.def.deftype=enumdef) and
  493. (tenumdef(tcallparanode(tcallparanode(left).right).left.resulttype.def).max<=32));
  494. { generate code for the element to set }
  495. secondpass(tcallparanode(tcallparanode(left).right).left);
  496. { bitnumber - which must be loaded into register }
  497. hregister:=cg.getintregister(exprasmlist,opsize);
  498. hregister2:=cg.getintregister(exprasmlist,opsize);
  499. cg.a_load_loc_reg(exprasmlist,opsize,
  500. tcallparanode(tcallparanode(left).right).left.location,hregister);
  501. if use_small then
  502. begin
  503. { hregister contains the bitnumber to add }
  504. cg.a_load_const_reg(exprasmlist, opsize, 1, hregister2);
  505. cg.a_op_reg_reg(exprasmlist, OP_SHL, opsize, hregister, hregister2);
  506. { possiblities :
  507. bitnumber : LOC_REFERENCE, LOC_REGISTER, LOC_CREGISTER
  508. set value : LOC_REFERENCE, LOC_REGISTER
  509. }
  510. { location of set }
  511. if inlinenumber=in_include_x_y then
  512. begin
  513. cg.a_op_reg_loc(exprasmlist, OP_OR, hregister2,
  514. tcallparanode(left).left.location);
  515. end
  516. else
  517. begin
  518. cg.a_op_reg_reg(exprasmlist, OP_NOT, opsize, hregister2,hregister2);
  519. cg.a_op_reg_loc(exprasmlist, OP_AND, hregister2,
  520. tcallparanode(left).left.location);
  521. end;
  522. end
  523. else
  524. begin
  525. { possiblities :
  526. bitnumber : LOC_REFERENCE, LOC_REGISTER, LOC_CREGISTER
  527. set value : LOC_REFERENCE
  528. }
  529. { hregister contains the bitnumber (div 32 to get the correct offset) }
  530. { hregister contains the bitnumber to add }
  531. cg.a_op_const_reg_reg(exprasmlist, OP_SHR, opsize, 5, hregister,hregister2);
  532. cg.a_op_const_reg(exprasmlist, OP_SHL, opsize, 2, hregister2);
  533. addrreg:=cg.getaddressregister(exprasmlist);
  534. { we need an extra address register to be able to do an ADD operation }
  535. addrreg2:=cg.getaddressregister(exprasmlist);
  536. cg.a_load_reg_reg(exprasmlist,opsize,OS_ADDR,hregister2,addrreg2);
  537. { calculate the correct address of the operand }
  538. cg.a_loadaddr_ref_reg(exprasmlist, tcallparanode(left).left.location.reference,addrreg);
  539. cg.a_op_reg_reg(exprasmlist, OP_ADD, OS_ADDR, addrreg2, addrreg);
  540. { hregister contains the bitnumber to add }
  541. cg.a_load_const_reg(exprasmlist, opsize, 1, hregister2);
  542. cg.a_op_const_reg(exprasmlist, OP_AND, opsize, 31, hregister);
  543. cg.a_op_reg_reg(exprasmlist, OP_SHL, opsize, hregister, hregister2);
  544. reference_reset_base(href,addrreg,0);
  545. if inlinenumber=in_include_x_y then
  546. cg.a_op_reg_ref(exprasmlist, OP_OR, opsize, hregister2, href)
  547. else
  548. begin
  549. cg.a_op_reg_reg(exprasmlist, OP_NOT, opsize, hregister2, hregister2);
  550. cg.a_op_reg_ref(exprasmlist, OP_AND, opsize, hregister2, href);
  551. end;
  552. end;
  553. end;
  554. end;
  555. {*****************************************************************************
  556. FLOAT GENERIC HANDLING
  557. *****************************************************************************}
  558. {
  559. These routines all call internal RTL routines, so if they are
  560. called here, they give an internal error
  561. }
  562. procedure tcginlinenode.second_pi;
  563. begin
  564. internalerror(20020718);
  565. end;
  566. procedure tcginlinenode.second_arctan_real;
  567. begin
  568. internalerror(20020718);
  569. end;
  570. procedure tcginlinenode.second_abs_real;
  571. begin
  572. internalerror(20020718);
  573. end;
  574. procedure tcginlinenode.second_sqr_real;
  575. begin
  576. internalerror(20020718);
  577. end;
  578. procedure tcginlinenode.second_sqrt_real;
  579. begin
  580. internalerror(20020718);
  581. end;
  582. procedure tcginlinenode.second_ln_real;
  583. begin
  584. internalerror(20020718);
  585. end;
  586. procedure tcginlinenode.second_cos_real;
  587. begin
  588. internalerror(20020718);
  589. end;
  590. procedure tcginlinenode.second_sin_real;
  591. begin
  592. internalerror(20020718);
  593. end;
  594. procedure tcginlinenode.second_prefetch;
  595. begin
  596. end;
  597. {*****************************************************************************
  598. ASSIGNED GENERIC HANDLING
  599. *****************************************************************************}
  600. procedure tcginlinenode.second_assigned;
  601. begin
  602. secondpass(tcallparanode(left).left);
  603. { force left to be an OS_ADDR, since in case of method procvars }
  604. { the size is 2*OS_ADDR (JM) }
  605. cg.a_cmp_const_loc_label(exprasmlist,OS_ADDR,OC_NE,0,tcallparanode(left).left.location,truelabel);
  606. cg.a_jmp_always(exprasmlist,falselabel);
  607. location_reset(location,LOC_JUMP,OS_NO);
  608. end;
  609. begin
  610. cinlinenode:=tcginlinenode;
  611. end.
  612. {
  613. $Log$
  614. Revision 1.67 2004-11-21 15:35:23 peter
  615. * float routines all use internproc and compilerproc helpers
  616. Revision 1.66 2004/11/08 21:59:34 florian
  617. * include/exclude for sets in registers fixed
  618. Revision 1.65 2004/10/31 21:45:03 peter
  619. * generic tlocation
  620. * move tlocation to cgutils
  621. Revision 1.64 2004/09/25 14:23:54 peter
  622. * ungetregister is now only used for cpuregisters, renamed to
  623. ungetcpuregister
  624. * renamed (get|unget)explicitregister(s) to ..cpuregister
  625. * removed location-release/reference_release
  626. Revision 1.63 2004/09/21 17:25:12 peter
  627. * paraloc branch merged
  628. Revision 1.62.4.1 2004/08/31 20:43:06 peter
  629. * paraloc patch
  630. Revision 1.62 2004/08/16 21:00:15 peter
  631. * range checks fixed
  632. Revision 1.61 2004/07/12 17:58:19 peter
  633. * remove maxlen field from ansistring/widestrings
  634. Revision 1.60 2004/06/20 08:55:29 florian
  635. * logs truncated
  636. Revision 1.59 2004/06/16 20:07:08 florian
  637. * dwarf branch merged
  638. Revision 1.58 2004/05/30 21:18:22 jonas
  639. * some optimizations and associated fixes for better regvar code
  640. Revision 1.57 2004/05/22 23:34:28 peter
  641. tai_regalloc.allocation changed to ratype to notify rgobj of register size changes
  642. Revision 1.56.2.4 2004/05/02 16:49:12 peter
  643. * 64 bit fixes
  644. Revision 1.56.2.3 2004/05/01 16:35:51 florian
  645. * fixed length(<ansi/widestring>) for 64 Bit CPUs
  646. }