ncginl.pas 32 KB

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