n386add.pas 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. {
  2. $Id$
  3. Copyright (c) 2000-2002 by Florian Klaempfl
  4. Code generation for add nodes on the i386
  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 n386add;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. node,nadd,cpubase,nx86add;
  23. type
  24. ti386addnode = class(tx86addnode)
  25. {$ifdef SUPPORT_MMX}
  26. procedure second_addmmxset;override;
  27. procedure second_addmmx;override;
  28. {$endif SUPPORT_MMX}
  29. procedure second_add64bit;override;
  30. procedure second_cmp64bit;override;
  31. procedure second_mul;override;
  32. end;
  33. implementation
  34. uses
  35. globtype,systems,
  36. cutils,verbose,globals,
  37. cpuinfo,
  38. symconst,symdef,paramgr,
  39. aasmbase,aasmtai,aasmcpu,
  40. cgbase,
  41. ncon,nset,
  42. cga,ncgutil,cgobj,cg64f32;
  43. {*****************************************************************************
  44. addmmxset
  45. *****************************************************************************}
  46. {$ifdef SUPPORT_MMX}
  47. procedure ti386addnode.second_addmmxset;
  48. var opsize : TCGSize;
  49. op : TAsmOp;
  50. cmpop,
  51. pushedfpu,
  52. noswap : boolean;
  53. begin
  54. pass_left_and_right(pushedfpu);
  55. cmpop:=false;
  56. noswap:=false;
  57. opsize:=OS_32;
  58. case nodetype of
  59. addn:
  60. begin
  61. { are we adding set elements ? }
  62. if right.nodetype=setelementn then
  63. begin
  64. { adding elements is not commutative }
  65. { if nf_swaped in flags then
  66. swapleftright;}
  67. { bts requires both elements to be registers }
  68. { location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],false);
  69. location_force_reg(exprasmlist,right.location,opsize_2_cgsize[opsize],true);
  70. op:=A_BTS;
  71. noswap:=true;}
  72. end
  73. else
  74. op:=A_POR;
  75. end;
  76. symdifn :
  77. op:=A_PXOR;
  78. muln:
  79. op:=A_PAND;
  80. subn:
  81. op:=A_PANDN;
  82. equaln,
  83. unequaln :
  84. begin
  85. op:=A_PCMPEQD;
  86. cmpop:=true;
  87. end;
  88. lten,gten:
  89. begin
  90. if (not(nf_swaped in flags) and (nodetype = lten)) or
  91. ((nf_swaped in flags) and (nodetype = gten)) then
  92. swapleftright;
  93. location_force_reg(exprasmlist,left.location,opsize,true);
  94. emit_op_right_left(A_AND,TCGSize2Opsize[opsize]);
  95. op:=A_PCMPEQD;
  96. cmpop:=true;
  97. { warning: ugly hack, we need a JE so change the node to equaln }
  98. nodetype:=equaln;
  99. end;
  100. xorn :
  101. op:=A_PXOR;
  102. orn :
  103. op:=A_POR;
  104. andn :
  105. op:=A_PAND;
  106. else
  107. internalerror(2003042215);
  108. end;
  109. { left must be a register }
  110. left_must_be_reg(opsize,noswap);
  111. { emit_generic_code(op,opsize,true,extra_not,false);}
  112. location_freetemp(exprasmlist,right.location);
  113. if cmpop then
  114. location_freetemp(exprasmlist,left.location);
  115. set_result_location(cmpop,true);
  116. end;
  117. {$endif SUPPORT_MMX}
  118. {*****************************************************************************
  119. Add64bit
  120. *****************************************************************************}
  121. procedure ti386addnode.second_add64bit;
  122. var
  123. op : TOpCG;
  124. op1,op2 : TAsmOp;
  125. opsize : TOpSize;
  126. hregister,
  127. hregister2 : tregister;
  128. hl4 : tasmlabel;
  129. mboverflow,
  130. unsigned:boolean;
  131. r:Tregister;
  132. begin
  133. firstcomplex(self);
  134. pass_left_right;
  135. op1:=A_NONE;
  136. op2:=A_NONE;
  137. mboverflow:=false;
  138. opsize:=S_L;
  139. unsigned:=((left.resulttype.def.deftype=orddef) and
  140. (torddef(left.resulttype.def).typ=u64bit)) or
  141. ((right.resulttype.def.deftype=orddef) and
  142. (torddef(right.resulttype.def).typ=u64bit));
  143. case nodetype of
  144. addn :
  145. begin
  146. op:=OP_ADD;
  147. mboverflow:=true;
  148. end;
  149. subn :
  150. begin
  151. op:=OP_SUB;
  152. op1:=A_SUB;
  153. op2:=A_SBB;
  154. mboverflow:=true;
  155. end;
  156. xorn:
  157. op:=OP_XOR;
  158. orn:
  159. op:=OP_OR;
  160. andn:
  161. op:=OP_AND;
  162. else
  163. begin
  164. { everything should be handled in pass_1 (JM) }
  165. internalerror(200109051);
  166. end;
  167. end;
  168. { left and right no register? }
  169. { then one must be demanded }
  170. if (left.location.loc<>LOC_REGISTER) then
  171. begin
  172. if (right.location.loc<>LOC_REGISTER) then
  173. begin
  174. hregister:=cg.getintregister(exprasmlist,OS_INT);
  175. hregister2:=cg.getintregister(exprasmlist,OS_INT);
  176. cg64.a_load64_loc_reg(exprasmlist,left.location,joinreg64(hregister,hregister2));
  177. location_reset(left.location,LOC_REGISTER,OS_64);
  178. left.location.registerlow:=hregister;
  179. left.location.registerhigh:=hregister2;
  180. end
  181. else
  182. begin
  183. location_swap(left.location,right.location);
  184. toggleflag(nf_swaped);
  185. end;
  186. end;
  187. { at this point, left.location.loc should be LOC_REGISTER }
  188. if right.location.loc=LOC_REGISTER then
  189. begin
  190. { when swapped another result register }
  191. if (nodetype=subn) and (nf_swaped in flags) then
  192. begin
  193. cg64.a_op64_reg_reg(exprasmlist,op,
  194. left.location.register64,
  195. right.location.register64);
  196. location_swap(left.location,right.location);
  197. toggleflag(nf_swaped);
  198. end
  199. else
  200. begin
  201. cg64.a_op64_reg_reg(exprasmlist,op,
  202. right.location.register64,
  203. left.location.register64);
  204. end;
  205. end
  206. else
  207. begin
  208. { right.location<>LOC_REGISTER }
  209. if (nodetype=subn) and (nf_swaped in flags) then
  210. begin
  211. r:=cg.getintregister(exprasmlist,OS_INT);
  212. cg64.a_load64low_loc_reg(exprasmlist,right.location,r);
  213. emit_reg_reg(op1,opsize,left.location.registerlow,r);
  214. emit_reg_reg(A_MOV,opsize,r,left.location.registerlow);
  215. cg64.a_load64high_loc_reg(exprasmlist,right.location,r);
  216. { the carry flag is still ok }
  217. emit_reg_reg(op2,opsize,left.location.registerhigh,r);
  218. emit_reg_reg(A_MOV,opsize,r,left.location.registerhigh);
  219. end
  220. else
  221. begin
  222. cg64.a_op64_loc_reg(exprasmlist,op,right.location,
  223. left.location.register64);
  224. end;
  225. location_freetemp(exprasmlist,right.location);
  226. end;
  227. { only in case of overflow operations }
  228. { produce overflow code }
  229. { we must put it here directly, because sign of operation }
  230. { is in unsigned VAR!! }
  231. if mboverflow then
  232. begin
  233. if cs_check_overflow in aktlocalswitches then
  234. begin
  235. objectlibrary.getlabel(hl4);
  236. if unsigned then
  237. cg.a_jmp_flags(exprasmlist,F_AE,hl4)
  238. else
  239. cg.a_jmp_flags(exprasmlist,F_NO,hl4);
  240. cg.a_call_name(exprasmlist,'FPC_OVERFLOW');
  241. cg.a_label(exprasmlist,hl4);
  242. end;
  243. end;
  244. location_copy(location,left.location);
  245. end;
  246. procedure ti386addnode.second_cmp64bit;
  247. var
  248. hregister,
  249. hregister2 : tregister;
  250. href : treference;
  251. unsigned : boolean;
  252. procedure firstjmp64bitcmp;
  253. var
  254. oldnodetype : tnodetype;
  255. begin
  256. {$ifdef OLDREGVARS}
  257. load_all_regvars(exprasmlist);
  258. {$endif OLDREGVARS}
  259. { the jump the sequence is a little bit hairy }
  260. case nodetype of
  261. ltn,gtn:
  262. begin
  263. cg.a_jmp_flags(exprasmlist,getresflags(unsigned),truelabel);
  264. { cheat a little bit for the negative test }
  265. toggleflag(nf_swaped);
  266. cg.a_jmp_flags(exprasmlist,getresflags(unsigned),falselabel);
  267. toggleflag(nf_swaped);
  268. end;
  269. lten,gten:
  270. begin
  271. oldnodetype:=nodetype;
  272. if nodetype=lten then
  273. nodetype:=ltn
  274. else
  275. nodetype:=gtn;
  276. cg.a_jmp_flags(exprasmlist,getresflags(unsigned),truelabel);
  277. { cheat for the negative test }
  278. if nodetype=ltn then
  279. nodetype:=gtn
  280. else
  281. nodetype:=ltn;
  282. cg.a_jmp_flags(exprasmlist,getresflags(unsigned),falselabel);
  283. nodetype:=oldnodetype;
  284. end;
  285. equaln:
  286. cg.a_jmp_flags(exprasmlist,F_NE,falselabel);
  287. unequaln:
  288. cg.a_jmp_flags(exprasmlist,F_NE,truelabel);
  289. end;
  290. end;
  291. procedure secondjmp64bitcmp;
  292. begin
  293. { the jump the sequence is a little bit hairy }
  294. case nodetype of
  295. ltn,gtn,lten,gten:
  296. begin
  297. { the comparisaion of the low dword have to be }
  298. { always unsigned! }
  299. cg.a_jmp_flags(exprasmlist,getresflags(true),truelabel);
  300. cg.a_jmp_always(exprasmlist,falselabel);
  301. end;
  302. equaln:
  303. begin
  304. cg.a_jmp_flags(exprasmlist,F_NE,falselabel);
  305. cg.a_jmp_always(exprasmlist,truelabel);
  306. end;
  307. unequaln:
  308. begin
  309. cg.a_jmp_flags(exprasmlist,F_NE,truelabel);
  310. cg.a_jmp_always(exprasmlist,falselabel);
  311. end;
  312. end;
  313. end;
  314. begin
  315. firstcomplex(self);
  316. pass_left_right;
  317. unsigned:=((left.resulttype.def.deftype=orddef) and
  318. (torddef(left.resulttype.def).typ=u64bit)) or
  319. ((right.resulttype.def.deftype=orddef) and
  320. (torddef(right.resulttype.def).typ=u64bit));
  321. { left and right no register? }
  322. { then one must be demanded }
  323. if (left.location.loc<>LOC_REGISTER) then
  324. begin
  325. if (right.location.loc<>LOC_REGISTER) then
  326. begin
  327. { we can reuse a CREGISTER for comparison }
  328. if (left.location.loc<>LOC_CREGISTER) then
  329. begin
  330. hregister:=cg.getintregister(exprasmlist,OS_INT);
  331. hregister2:=cg.getintregister(exprasmlist,OS_INT);
  332. cg64.a_load64_loc_reg(exprasmlist,left.location,joinreg64(hregister,hregister2));
  333. location_reset(left.location,LOC_REGISTER,OS_64);
  334. left.location.registerlow:=hregister;
  335. left.location.registerhigh:=hregister2;
  336. end;
  337. end
  338. else
  339. begin
  340. location_swap(left.location,right.location);
  341. toggleflag(nf_swaped);
  342. end;
  343. end;
  344. { at this point, left.location.loc should be LOC_REGISTER }
  345. if right.location.loc=LOC_REGISTER then
  346. begin
  347. emit_reg_reg(A_CMP,S_L,right.location.registerhigh,left.location.registerhigh);
  348. firstjmp64bitcmp;
  349. emit_reg_reg(A_CMP,S_L,right.location.registerlow,left.location.registerlow);
  350. secondjmp64bitcmp;
  351. end
  352. else
  353. begin
  354. case right.location.loc of
  355. LOC_CREGISTER :
  356. begin
  357. emit_reg_reg(A_CMP,S_L,right.location.registerhigh,left.location.registerhigh);
  358. firstjmp64bitcmp;
  359. emit_reg_reg(A_CMP,S_L,right.location.registerlow,left.location.registerlow);
  360. secondjmp64bitcmp;
  361. end;
  362. LOC_CREFERENCE,
  363. LOC_REFERENCE :
  364. begin
  365. href:=right.location.reference;
  366. inc(href.offset,4);
  367. emit_ref_reg(A_CMP,S_L,href,left.location.registerhigh);
  368. firstjmp64bitcmp;
  369. emit_ref_reg(A_CMP,S_L,right.location.reference,left.location.registerlow);
  370. secondjmp64bitcmp;
  371. cg.a_jmp_always(exprasmlist,falselabel);
  372. location_freetemp(exprasmlist,right.location);
  373. end;
  374. LOC_CONSTANT :
  375. begin
  376. exprasmlist.concat(taicpu.op_const_reg(A_CMP,S_L,aint(hi(right.location.value64)),left.location.registerhigh));
  377. firstjmp64bitcmp;
  378. exprasmlist.concat(taicpu.op_const_reg(A_CMP,S_L,aint(lo(right.location.value64)),left.location.registerlow));
  379. secondjmp64bitcmp;
  380. end;
  381. else
  382. internalerror(200203282);
  383. end;
  384. end;
  385. location_freetemp(exprasmlist,left.location);
  386. { we have LOC_JUMP as result }
  387. location_reset(location,LOC_JUMP,OS_NO)
  388. end;
  389. {*****************************************************************************
  390. AddMMX
  391. *****************************************************************************}
  392. {$ifdef SUPPORT_MMX}
  393. procedure ti386addnode.second_addmmx;
  394. var
  395. op : TAsmOp;
  396. pushedfpu,
  397. cmpop : boolean;
  398. mmxbase : tmmxtype;
  399. hreg,
  400. hregister : tregister;
  401. begin
  402. pass_left_and_right(pushedfpu);
  403. cmpop:=false;
  404. mmxbase:=mmx_type(left.resulttype.def);
  405. case nodetype of
  406. addn :
  407. begin
  408. if (cs_mmx_saturation in aktlocalswitches) then
  409. begin
  410. case mmxbase of
  411. mmxs8bit:
  412. op:=A_PADDSB;
  413. mmxu8bit:
  414. op:=A_PADDUSB;
  415. mmxs16bit,mmxfixed16:
  416. op:=A_PADDSB;
  417. mmxu16bit:
  418. op:=A_PADDUSW;
  419. end;
  420. end
  421. else
  422. begin
  423. case mmxbase of
  424. mmxs8bit,mmxu8bit:
  425. op:=A_PADDB;
  426. mmxs16bit,mmxu16bit,mmxfixed16:
  427. op:=A_PADDW;
  428. mmxs32bit,mmxu32bit:
  429. op:=A_PADDD;
  430. end;
  431. end;
  432. end;
  433. muln :
  434. begin
  435. case mmxbase of
  436. mmxs16bit,mmxu16bit:
  437. op:=A_PMULLW;
  438. mmxfixed16:
  439. op:=A_PMULHW;
  440. end;
  441. end;
  442. subn :
  443. begin
  444. if (cs_mmx_saturation in aktlocalswitches) then
  445. begin
  446. case mmxbase of
  447. mmxs8bit:
  448. op:=A_PSUBSB;
  449. mmxu8bit:
  450. op:=A_PSUBUSB;
  451. mmxs16bit,mmxfixed16:
  452. op:=A_PSUBSB;
  453. mmxu16bit:
  454. op:=A_PSUBUSW;
  455. end;
  456. end
  457. else
  458. begin
  459. case mmxbase of
  460. mmxs8bit,mmxu8bit:
  461. op:=A_PSUBB;
  462. mmxs16bit,mmxu16bit,mmxfixed16:
  463. op:=A_PSUBW;
  464. mmxs32bit,mmxu32bit:
  465. op:=A_PSUBD;
  466. end;
  467. end;
  468. end;
  469. xorn:
  470. op:=A_PXOR;
  471. orn:
  472. op:=A_POR;
  473. andn:
  474. op:=A_PAND;
  475. else
  476. internalerror(2003042214);
  477. end;
  478. { left and right no register? }
  479. { then one must be demanded }
  480. if (left.location.loc<>LOC_MMXREGISTER) then
  481. begin
  482. if (right.location.loc=LOC_MMXREGISTER) then
  483. begin
  484. location_swap(left.location,right.location);
  485. toggleflag(nf_swaped);
  486. end
  487. else
  488. begin
  489. { register variable ? }
  490. if (left.location.loc=LOC_CMMXREGISTER) then
  491. begin
  492. hregister:=cg.getmmxregister(exprasmlist,OS_M64);
  493. emit_reg_reg(A_MOVQ,S_NO,left.location.register,hregister);
  494. end
  495. else
  496. begin
  497. if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
  498. internalerror(200203245);
  499. hregister:=cg.getmmxregister(exprasmlist,OS_M64);
  500. emit_ref_reg(A_MOVQ,S_NO,left.location.reference,hregister);
  501. end;
  502. location_reset(left.location,LOC_MMXREGISTER,OS_NO);
  503. left.location.register:=hregister;
  504. end;
  505. end;
  506. { at this point, left.location.loc should be LOC_MMXREGISTER }
  507. if right.location.loc<>LOC_MMXREGISTER then
  508. begin
  509. if (nodetype=subn) and (nf_swaped in flags) then
  510. begin
  511. if right.location.loc=LOC_CMMXREGISTER then
  512. begin
  513. hreg:=cg.getmmxregister(exprasmlist,OS_M64);
  514. emit_reg_reg(A_MOVQ,S_NO,right.location.register,hreg);
  515. emit_reg_reg(op,S_NO,left.location.register,hreg);
  516. cg.ungetregister(exprasmlist,hreg);
  517. emit_reg_reg(A_MOVQ,S_NO,hreg,left.location.register);
  518. end
  519. else
  520. begin
  521. if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
  522. internalerror(200203247);
  523. hreg:=cg.getmmxregister(exprasmlist,OS_M64);
  524. emit_ref_reg(A_MOVQ,S_NO,right.location.reference,hreg);
  525. emit_reg_reg(op,S_NO,left.location.register,hreg);
  526. cg.ungetregister(exprasmlist,hreg);
  527. emit_reg_reg(A_MOVQ,S_NO,hreg,left.location.register);
  528. end;
  529. end
  530. else
  531. begin
  532. if (right.location.loc=LOC_CMMXREGISTER) then
  533. emit_reg_reg(op,S_NO,right.location.register,left.location.register)
  534. else
  535. begin
  536. if not(right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
  537. internalerror(200203246);
  538. emit_ref_reg(op,S_NO,right.location.reference,left.location.register);
  539. end;
  540. end;
  541. end
  542. else
  543. begin
  544. { right.location=LOC_MMXREGISTER }
  545. if (nodetype=subn) and (nf_swaped in flags) then
  546. begin
  547. emit_reg_reg(op,S_NO,left.location.register,right.location.register);
  548. location_swap(left.location,right.location);
  549. toggleflag(nf_swaped);
  550. end
  551. else
  552. begin
  553. emit_reg_reg(op,S_NO,right.location.register,left.location.register);
  554. end;
  555. end;
  556. location_freetemp(exprasmlist,right.location);
  557. if cmpop then
  558. location_freetemp(exprasmlist,left.location);
  559. set_result_location(cmpop,true);
  560. end;
  561. {$endif SUPPORT_MMX}
  562. {*****************************************************************************
  563. x86 MUL
  564. *****************************************************************************}
  565. procedure ti386addnode.second_mul;
  566. var r:Tregister;
  567. hl4 : tasmlabel;
  568. begin
  569. {The location.register will be filled in later (JM)}
  570. location_reset(location,LOC_REGISTER,OS_INT);
  571. {Get a temp register and load the left value into it
  572. and free the location.}
  573. r:=cg.getintregister(exprasmlist,OS_INT);
  574. cg.a_load_loc_reg(exprasmlist,OS_INT,left.location,r);
  575. {Allocate EAX.}
  576. cg.getcpuregister(exprasmlist,NR_EAX);
  577. {Load the right value.}
  578. cg.a_load_loc_reg(exprasmlist,OS_INT,right.location,NR_EAX);
  579. {Also allocate EDX, since it is also modified by a mul (JM).}
  580. cg.getcpuregister(exprasmlist,NR_EDX);
  581. emit_reg(A_MUL,S_L,r);
  582. if cs_check_overflow in aktlocalswitches then
  583. begin
  584. objectlibrary.getlabel(hl4);
  585. cg.a_jmp_flags(exprasmlist,F_AE,hl4);
  586. cg.a_call_name(exprasmlist,'FPC_OVERFLOW');
  587. cg.a_label(exprasmlist,hl4);
  588. end;
  589. {Free EAX,EDX}
  590. cg.ungetcpuregister(exprasmlist,NR_EDX);
  591. cg.ungetcpuregister(exprasmlist,NR_EAX);
  592. {Allocate a new register and store the result in EAX in it.}
  593. location.register:=cg.getintregister(exprasmlist,OS_INT);
  594. cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,NR_EAX,location.register);
  595. location_freetemp(exprasmlist,left.location);
  596. location_freetemp(exprasmlist,right.location);
  597. end;
  598. begin
  599. caddnode:=ti386addnode;
  600. end.
  601. {
  602. $Log$
  603. Revision 1.99 2004-09-25 14:23:54 peter
  604. * ungetregister is now only used for cpuregisters, renamed to
  605. ungetcpuregister
  606. * renamed (get|unget)explicitregister(s) to ..cpuregister
  607. * removed location-release/reference_release
  608. Revision 1.98 2004/06/20 08:55:31 florian
  609. * logs truncated
  610. Revision 1.97 2004/06/16 20:07:10 florian
  611. * dwarf branch merged
  612. Revision 1.96 2004/05/19 23:30:18 peter
  613. * extra typecast to prevent range check
  614. Revision 1.95.2.1 2004/04/29 19:07:22 peter
  615. * compile fixes
  616. Revision 1.95 2004/02/04 19:22:27 peter
  617. *** empty log message ***
  618. Revision 1.94 2004/01/20 12:59:37 florian
  619. * common addnode code for x86-64 and i386
  620. }