ncginl.pas 30 KB

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