ncginl.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  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,defbase,
  47. aasmbase,aasmtai,aasmcpu,
  48. cginfo,cgbase,pass_1,pass_2,
  49. cpubase,paramgr,
  50. nbas,ncon,ncal,ncnv,nld,
  51. tgobj,ncgutil,cgobj,cg64f32,rgobj,rgcpu;
  52. {*****************************************************************************
  53. TCGINLINENODE
  54. *****************************************************************************}
  55. procedure tcginlinenode.pass_2;
  56. var
  57. asmop : tasmop;
  58. l : longint;
  59. oldpushedparasize : longint;
  60. begin
  61. { save & reset pushedparasize }
  62. oldpushedparasize:=pushedparasize;
  63. pushedparasize:=0;
  64. case inlinenumber of
  65. in_assert_x_y:
  66. begin
  67. second_Assert;
  68. end;
  69. in_sizeof_x,
  70. in_typeof_x :
  71. begin
  72. second_SizeofTypeOf;
  73. end;
  74. in_length_x :
  75. begin
  76. second_Length;
  77. end;
  78. in_pred_x,
  79. in_succ_x:
  80. begin
  81. second_PredSucc;
  82. end;
  83. in_dec_x,
  84. in_inc_x :
  85. begin
  86. second_IncDec;
  87. end;
  88. in_typeinfo_x:
  89. begin
  90. second_TypeInfo;
  91. end;
  92. in_include_x_y,
  93. in_exclude_x_y:
  94. begin
  95. second_IncludeExclude;
  96. end;
  97. in_pi:
  98. begin
  99. second_pi;
  100. end;
  101. in_sin_extended:
  102. begin
  103. second_sin_real;
  104. end;
  105. in_arctan_extended:
  106. begin
  107. second_arctan_real;
  108. end;
  109. in_abs_extended:
  110. begin
  111. second_abs_real;
  112. end;
  113. in_sqr_extended:
  114. begin
  115. second_sqr_real;
  116. end;
  117. in_sqrt_extended:
  118. begin
  119. second_sqrt_real;
  120. end;
  121. in_ln_extended:
  122. begin
  123. second_ln_real;
  124. end;
  125. in_cos_extended:
  126. begin
  127. second_cos_real;
  128. end;
  129. {$ifdef SUPPORT_MMX}
  130. in_mmx_pcmpeqb..in_mmx_pcmpgtw:
  131. begin
  132. location_reset(location,LOC_MMXREGISTER,OS_NO);
  133. if left.location.loc=LOC_REGISTER then
  134. begin
  135. {!!!!!!!}
  136. end
  137. else if tcallparanode(left).left.location.loc=LOC_REGISTER then
  138. begin
  139. {!!!!!!!}
  140. end
  141. else
  142. begin
  143. {!!!!!!!}
  144. end;
  145. end;
  146. {$endif SUPPORT_MMX}
  147. else internalerror(9);
  148. end;
  149. { reset pushedparasize }
  150. pushedparasize:=oldpushedparasize;
  151. end;
  152. {*****************************************************************************
  153. ASSERT GENERIC HANDLING
  154. *****************************************************************************}
  155. procedure tcginlinenode.second_Assert;
  156. var
  157. hp2 : tstringconstnode;
  158. otlabel,oflabel{,l1} : tasmlabel;
  159. begin
  160. { the node should be removed in the firstpass }
  161. if not (cs_do_assertion in aktlocalswitches) then
  162. internalerror(7123458);
  163. otlabel:=truelabel;
  164. oflabel:=falselabel;
  165. objectlibrary.getlabel(truelabel);
  166. objectlibrary.getlabel(falselabel);
  167. secondpass(tcallparanode(left).left);
  168. maketojumpbool(exprasmlist,tcallparanode(left).left,lr_load_regvars);
  169. cg.a_label(exprasmlist,falselabel);
  170. { erroraddr }
  171. cg.a_param_reg(exprasmlist,OS_ADDR,FRAME_POINTER_REG,paramanager.getintparaloc(4));
  172. { lineno }
  173. cg.a_param_const(exprasmlist,OS_INT,aktfilepos.line,paramanager.getintparaloc(3));
  174. { filename string }
  175. hp2:=cstringconstnode.createstr(current_module.sourcefiles.get_file_name(aktfilepos.fileindex),st_shortstring);
  176. firstpass(hp2);
  177. secondpass(hp2);
  178. if codegenerror then
  179. exit;
  180. cg.a_paramaddr_ref(exprasmlist,hp2.location.reference,paramanager.getintparaloc(2));
  181. hp2.free;
  182. { push msg }
  183. secondpass(tcallparanode(tcallparanode(left).right).left);
  184. cg.a_paramaddr_ref(exprasmlist,tcallparanode(tcallparanode(left).right).left.location.reference,paramanager.getintparaloc(1));
  185. { call }
  186. cg.a_call_name(exprasmlist,'FPC_ASSERT');
  187. cg.a_label(exprasmlist,truelabel);
  188. truelabel:=otlabel;
  189. falselabel:=oflabel;
  190. end;
  191. {*****************************************************************************
  192. SIZEOF / TYPEOF GENERIC HANDLING
  193. *****************************************************************************}
  194. { second_handle_ the sizeof and typeof routines }
  195. procedure tcginlinenode.second_SizeOfTypeOf;
  196. var
  197. href : treference;
  198. hregister : tregister;
  199. begin
  200. location_reset(location,LOC_REGISTER,OS_ADDR);
  201. { for both cases load vmt }
  202. if left.nodetype=typen then
  203. begin
  204. hregister:=rg.getaddressregister(exprasmlist);
  205. reference_reset_symbol(href,objectlibrary.newasmsymbol(tobjectdef(left.resulttype.def).vmt_mangledname),0);
  206. cg.a_loadaddr_ref_reg(exprasmlist,href,hregister);
  207. end
  208. else
  209. begin
  210. secondpass(left);
  211. location_release(exprasmlist,left.location);
  212. hregister:=rg.getaddressregister(exprasmlist);
  213. { load VMT pointer }
  214. inc(left.location.reference.offset,tobjectdef(left.resulttype.def).vmt_offset);
  215. cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,hregister);
  216. end;
  217. { in sizeof load size }
  218. if inlinenumber=in_sizeof_x then
  219. begin
  220. reference_reset_base(href,hregister,0);
  221. rg.ungetaddressregister(exprasmlist,hregister);
  222. hregister:=rg.getregisterint(exprasmlist);
  223. cg.a_load_ref_reg(exprasmlist,OS_INT,href,hregister);
  224. end;
  225. location.register:=hregister;
  226. end;
  227. {*****************************************************************************
  228. LENGTH GENERIC HANDLING
  229. *****************************************************************************}
  230. procedure tcginlinenode.second_Length;
  231. var
  232. lengthlab : tasmlabel;
  233. hregister : tregister;
  234. href : treference;
  235. begin
  236. secondpass(left);
  237. { length in ansi strings is at offset -8 }
  238. if is_ansistring(left.resulttype.def) or
  239. is_widestring(left.resulttype.def) then
  240. begin
  241. location_force_reg(exprasmlist,left.location,OS_ADDR,false);
  242. hregister:=left.location.register;
  243. objectlibrary.getlabel(lengthlab);
  244. cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,hregister,lengthlab);
  245. reference_reset_base(href,hregister,-8);
  246. cg.a_load_ref_reg(exprasmlist,OS_32,href,hregister);
  247. cg.a_label(exprasmlist,lengthlab);
  248. location_reset(location,LOC_REGISTER,OS_32);
  249. location.register:=hregister;
  250. end
  251. else
  252. begin
  253. location_copy(location,left.location);
  254. location.size:=OS_8;
  255. end;
  256. end;
  257. {*****************************************************************************
  258. PRED/SUCC GENERIC HANDLING
  259. *****************************************************************************}
  260. procedure tcginlinenode.second_PredSucc;
  261. var
  262. cgsize : TCGSize;
  263. cgop : topcg;
  264. begin
  265. secondpass(left);
  266. if inlinenumber=in_pred_x then
  267. cgop:=OP_SUB
  268. else
  269. cgop:=OP_ADD;
  270. cgsize:=def_cgsize(resulttype.def);
  271. { we need a value in a register }
  272. location_copy(location,left.location);
  273. location_force_reg(exprasmlist,location,cgsize,false);
  274. if cgsize in [OS_64,OS_S64] then
  275. cg64.a_op64_const_reg(exprasmlist,cgop,1,
  276. location.register64)
  277. else
  278. cg.a_op_const_reg(exprasmlist,cgop,1,location.register);
  279. cg.g_overflowcheck(exprasmlist,self);
  280. cg.g_rangecheck(exprasmlist,self,resulttype.def);
  281. end;
  282. {*****************************************************************************
  283. INC/DEC GENERIC HANDLING
  284. *****************************************************************************}
  285. procedure tcginlinenode.second_IncDec;
  286. const
  287. addsubop:array[in_inc_x..in_dec_x] of TOpCG=(OP_ADD,OP_SUB);
  288. var
  289. addvalue : longint;
  290. addconstant : boolean;
  291. hregisterhi,
  292. hregister : tregister;
  293. cgsize : tcgsize;
  294. pushedregs : tmaybesave;
  295. begin
  296. { set defaults }
  297. addconstant:=true;
  298. { load first parameter, must be a reference }
  299. secondpass(tcallparanode(left).left);
  300. cgsize:=def_cgsize(tcallparanode(left).left.resulttype.def);
  301. { get addvalue }
  302. case tcallparanode(left).left.resulttype.def.deftype of
  303. orddef,
  304. enumdef :
  305. addvalue:=1;
  306. pointerdef :
  307. begin
  308. if is_void(tpointerdef(tcallparanode(left).left.resulttype.def).pointertype.def) then
  309. addvalue:=1
  310. else
  311. addvalue:=tpointerdef(tcallparanode(left).left.resulttype.def).pointertype.def.size;
  312. end;
  313. else
  314. internalerror(10081);
  315. end;
  316. { second_ argument specified?, must be a s32bit in register }
  317. if assigned(tcallparanode(left).right) then
  318. begin
  319. maybe_save(exprasmlist,tcallparanode(tcallparanode(left).right).left.registers32,
  320. tcallparanode(left).left.location,pushedregs);
  321. secondpass(tcallparanode(tcallparanode(left).right).left);
  322. maybe_restore(exprasmlist,tcallparanode(left).left.location,pushedregs);
  323. { when constant, just multiply the addvalue }
  324. if is_constintnode(tcallparanode(tcallparanode(left).right).left) then
  325. addvalue:=addvalue*get_ordinal_value(tcallparanode(tcallparanode(left).right).left)
  326. else
  327. begin
  328. location_force_reg(exprasmlist,tcallparanode(tcallparanode(left).right).left.location,cgsize,false);
  329. hregister:=tcallparanode(tcallparanode(left).right).left.location.register;
  330. hregisterhi:=tcallparanode(tcallparanode(left).right).left.location.registerhigh;
  331. { insert multiply with addvalue if its >1 }
  332. if addvalue>1 then
  333. cg.a_op_const_reg(exprasmlist,OP_IMUL,addvalue,hregister);
  334. addconstant:=false;
  335. end;
  336. end;
  337. { write the add instruction }
  338. if addconstant then
  339. begin
  340. if cgsize in [OS_64,OS_S64] then
  341. cg64.a_op64_const_loc(exprasmlist,addsubop[inlinenumber],
  342. addvalue,tcallparanode(left).left.location)
  343. else
  344. cg.a_op_const_loc(exprasmlist,addsubop[inlinenumber],
  345. addvalue,tcallparanode(left).left.location);
  346. end
  347. else
  348. begin
  349. if cgsize in [OS_64,OS_S64] then
  350. cg64.a_op64_reg_loc(exprasmlist,addsubop[inlinenumber],
  351. joinreg64(hregister,hregisterhi),tcallparanode(left).left.location)
  352. else
  353. cg.a_op_reg_loc(exprasmlist,addsubop[inlinenumber],
  354. hregister,tcallparanode(left).left.location);
  355. location_release(exprasmlist,tcallparanode(tcallparanode(left).right).left.location);
  356. end;
  357. cg.g_overflowcheck(exprasmlist,tcallparanode(left).left);
  358. cg.g_rangecheck(exprasmlist,tcallparanode(left).left,tcallparanode(left).left.resulttype.def);
  359. end;
  360. {*****************************************************************************
  361. TYPEINFO GENERIC HANDLING
  362. *****************************************************************************}
  363. procedure tcginlinenode.second_typeinfo;
  364. var
  365. href : treference;
  366. begin
  367. location_reset(location,LOC_REGISTER,OS_ADDR);
  368. location.register:=rg.getaddressregister(exprasmlist);
  369. reference_reset_symbol(href,tstoreddef(ttypenode(tcallparanode(left).left).resulttype.def).get_rtti_label(fullrtti),0);
  370. cg.a_loadaddr_ref_reg(exprasmlist,href,location.register);
  371. end;
  372. {*****************************************************************************
  373. INCLUDE/EXCLUDE GENERIC HANDLING
  374. *****************************************************************************}
  375. procedure tcginlinenode.second_IncludeExclude;
  376. var
  377. scratch_reg : boolean;
  378. hregister : tregister;
  379. asmop : tasmop;
  380. L : longint;
  381. pushedregs : TMaybesave;
  382. cgop : topcg;
  383. addrreg, hregister2: tregister;
  384. use_small : boolean;
  385. cgsize : tcgsize;
  386. href : treference;
  387. begin
  388. location_copy(location,left.location);
  389. secondpass(tcallparanode(left).left);
  390. if tcallparanode(tcallparanode(left).right).left.nodetype=ordconstn then
  391. begin
  392. { calculate bit position }
  393. l:=1 shl (tordconstnode(tcallparanode(tcallparanode(left).right).left).value mod 32);
  394. { determine operator }
  395. if inlinenumber=in_include_x_y then
  396. cgop:=OP_OR
  397. else
  398. begin
  399. cgop:=OP_AND;
  400. l:=not(l);
  401. end;
  402. if (tcallparanode(left).left.location.loc=LOC_REFERENCE) then
  403. begin
  404. inc(tcallparanode(left).left.location.reference.offset,
  405. (tordconstnode(tcallparanode(tcallparanode(left).right).left).value div 32)*4);
  406. cg.a_op_const_ref(exprasmlist,cgop,OS_INT,l,tcallparanode(left).left.location.reference);
  407. location_release(exprasmlist,tcallparanode(left).left.location);
  408. end
  409. else
  410. { LOC_CREGISTER }
  411. begin
  412. cg.a_op_const_reg(exprasmlist,cgop,l,tcallparanode(left).left.location.register);
  413. end;
  414. end
  415. else
  416. begin
  417. use_small:=
  418. { set type }
  419. (tsetdef(tcallparanode(left).left.resulttype.def).settype=smallset)
  420. and
  421. { elemenut number between 1 and 32 }
  422. ((tcallparanode(tcallparanode(left).right).left.resulttype.def.deftype=orddef) and
  423. (torddef(tcallparanode(tcallparanode(left).right).left.resulttype.def).high<=32) or
  424. (tcallparanode(tcallparanode(left).right).left.resulttype.def.deftype=enumdef) and
  425. (tenumdef(tcallparanode(tcallparanode(left).right).left.resulttype.def).max<=32));
  426. { generate code for the element to set }
  427. maybe_save(exprasmlist,tcallparanode(tcallparanode(left).right).left.registers32,
  428. tcallparanode(left).left.location,pushedregs);
  429. secondpass(tcallparanode(tcallparanode(left).right).left);
  430. maybe_restore(exprasmlist,tcallparanode(left).left.location,pushedregs);
  431. { bitnumber - which must be loaded into register }
  432. hregister := cg.get_scratch_reg_int(exprasmlist);
  433. hregister2 := rg.getregisterint(exprasmlist);
  434. case tcallparanode(tcallparanode(left).right).left.location.loc of
  435. LOC_CREGISTER,
  436. LOC_REGISTER:
  437. begin
  438. cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,
  439. tcallparanode(tcallparanode(left).right).left.location.register,hregister);
  440. end;
  441. LOC_REFERENCE:
  442. begin
  443. cgsize := def_cgsize(tcallparanode(tcallparanode(left).right).left.resulttype.def);
  444. cg.a_load_ref_reg(exprasmlist,cgsize,
  445. tcallparanode(tcallparanode(left).right).left.location.reference,hregister);
  446. end;
  447. else
  448. internalerror(20020727);
  449. end;
  450. { hregister contains the bitnumber to add }
  451. cg.a_load_const_reg(exprasmlist, OS_INT, 1, hregister2);
  452. cg.a_op_reg_reg(exprasmlist, OP_SHL, OS_INT, hregister, hregister2);
  453. if use_small then
  454. begin
  455. { possiblities :
  456. bitnumber : LOC_REFERENCE, LOC_REGISTER, LOC_CREGISTER
  457. set value : LOC_REFERENCE, LOC_REGISTER
  458. }
  459. { location of set }
  460. if (tcallparanode(left).left.location.loc=LOC_REFERENCE) then
  461. begin
  462. if inlinenumber=in_include_x_y then
  463. begin
  464. cg.a_op_reg_ref(exprasmlist, OP_OR, OS_32, hregister2,
  465. tcallparanode(left).left.location.reference);
  466. end
  467. else
  468. begin
  469. cg.a_op_reg_reg(exprasmlist, OP_NOT, OS_32, hregister2,
  470. hregister2);
  471. cg.a_op_reg_ref(exprasmlist, OP_AND, OS_32, hregister2,
  472. tcallparanode(left).left.location.reference);
  473. end;
  474. end
  475. else
  476. internalerror(20020728);
  477. end
  478. else
  479. begin
  480. { possiblities :
  481. bitnumber : LOC_REFERENCE, LOC_REGISTER, LOC_CREGISTER
  482. set value : LOC_REFERENCE
  483. }
  484. { hregister contains the bitnumber (div 32 to get the correct offset) }
  485. cg.a_op_const_reg(exprasmlist, OP_SHR, 5, hregister);
  486. addrreg := cg.get_scratch_reg_address(exprasmlist);
  487. { calculate the correct address of the operand }
  488. cg.a_loadaddr_ref_reg(exprasmlist, tcallparanode(left).left.location.reference,addrreg);
  489. cg.a_op_reg_reg(exprasmlist, OP_ADD, OS_INT, hregister, addrreg);
  490. reference_reset_base(href,addrreg,0);
  491. if inlinenumber=in_include_x_y then
  492. begin
  493. cg.a_op_reg_ref(exprasmlist, OP_OR, OS_32, hregister2, href);
  494. end
  495. else
  496. begin
  497. cg.a_op_reg_reg(exprasmlist, OP_NOT, OS_32, hregister2, hregister2);
  498. cg.a_op_reg_ref(exprasmlist, OP_AND, OS_32, hregister2, href);
  499. end;
  500. cg.free_scratch_reg(exprasmlist, addrreg);
  501. end;
  502. cg.free_scratch_reg(exprasmlist,hregister);
  503. rg.ungetregisterint(exprasmlist,hregister2);
  504. end;
  505. end;
  506. {*****************************************************************************
  507. FLOAT GENERIC HANDLING
  508. *****************************************************************************}
  509. {
  510. These routines all call internal RTL routines, so if they are
  511. called here, they give an internal error
  512. }
  513. procedure tcginlinenode.second_pi;
  514. begin
  515. internalerror(20020718);
  516. end;
  517. procedure tcginlinenode.second_arctan_real;
  518. begin
  519. internalerror(20020718);
  520. end;
  521. procedure tcginlinenode.second_abs_real;
  522. begin
  523. internalerror(20020718);
  524. end;
  525. procedure tcginlinenode.second_sqr_real;
  526. begin
  527. internalerror(20020718);
  528. end;
  529. procedure tcginlinenode.second_sqrt_real;
  530. begin
  531. internalerror(20020718);
  532. end;
  533. procedure tcginlinenode.second_ln_real;
  534. begin
  535. internalerror(20020718);
  536. end;
  537. procedure tcginlinenode.second_cos_real;
  538. begin
  539. internalerror(20020718);
  540. end;
  541. procedure tcginlinenode.second_sin_real;
  542. begin
  543. internalerror(20020718);
  544. end;
  545. begin
  546. cinlinenode:=tcginlinenode;
  547. end.
  548. {
  549. $Log$
  550. Revision 1.14 2002-09-17 18:54:02 jonas
  551. * a_load_reg_reg() now has two size parameters: source and dest. This
  552. allows some optimizations on architectures that don't encode the
  553. register size in the register name.
  554. Revision 1.13 2002/08/13 18:01:52 carl
  555. * rename swatoperands to swapoperands
  556. + m68k first compilable version (still needs a lot of testing):
  557. assembler generator, system information , inline
  558. assembler reader.
  559. Revision 1.12 2002/08/11 14:32:26 peter
  560. * renamed current_library to objectlibrary
  561. Revision 1.11 2002/08/11 13:24:11 peter
  562. * saving of asmsymbols in ppu supported
  563. * asmsymbollist global is removed and moved into a new class
  564. tasmlibrarydata that will hold the info of a .a file which
  565. corresponds with a single module. Added librarydata to tmodule
  566. to keep the library info stored for the module. In the future the
  567. objectfiles will also be stored to the tasmlibrarydata class
  568. * all getlabel/newasmsymbol and friends are moved to the new class
  569. Revision 1.10 2002/08/05 18:27:48 carl
  570. + more more more documentation
  571. + first version include/exclude (can't test though, not enough scratch for i386 :()...
  572. Revision 1.9 2002/08/04 19:06:41 carl
  573. + added generic exception support (still does not work!)
  574. + more documentation
  575. Revision 1.8 2002/07/31 07:54:59 jonas
  576. * re-enabled second_assigned()
  577. Revision 1.7 2002/07/30 20:50:43 florian
  578. * the code generator knows now if parameters are in registers
  579. Revision 1.6 2002/07/29 21:23:42 florian
  580. * more fixes for the ppc
  581. + wrappers for the tcnvnode.first_* stuff introduced
  582. Revision 1.5 2002/07/28 20:45:22 florian
  583. + added direct assembler reader for PowerPC
  584. Revision 1.4 2002/07/26 09:45:20 florian
  585. * fixed a mistake in yesterday's commit, forgot to commit it
  586. Revision 1.3 2002/07/25 22:58:30 florian
  587. no message
  588. Revision 1.2 2002/07/25 17:55:41 carl
  589. + First working revision
  590. Revision 1.1 2002/07/24 04:07:49 carl
  591. + first revision (incomplete)
  592. }