ncginl.pas 31 KB

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