ncginl.pas 31 KB

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