ncginl.pas 32 KB

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