ra386.pas 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Carl Eric Codere and Peter Vreman
  4. Handles the common i386 assembler reader routines
  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 Ra386;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. aasm,cpubase,RAUtils;
  23. { Parser helpers }
  24. function is_prefix(t:tasmop):boolean;
  25. function is_override(t:tasmop):boolean;
  26. Function CheckPrefix(prefixop,op:tasmop): Boolean;
  27. Function CheckOverride(overrideop,op:tasmop): Boolean;
  28. Procedure FWaitWarning;
  29. type
  30. P386Operand=^T386Operand;
  31. T386Operand=object(TOperand)
  32. Procedure SetCorrectSize(opcode:tasmop);virtual;
  33. Function SetupResult : boolean;virtual;
  34. end;
  35. P386Instruction=^T386Instruction;
  36. T386Instruction=object(TInstruction)
  37. { Operand sizes }
  38. procedure AddReferenceSizes;
  39. procedure SetInstructionOpsize;
  40. procedure CheckOperandSizes;
  41. procedure CheckNonCommutativeOpcodes;
  42. { opcode adding }
  43. procedure ConcatInstruction(p : taasmoutput);virtual;
  44. end;
  45. implementation
  46. uses
  47. {$ifdef NEWCG}
  48. cgbase,
  49. {$else}
  50. hcodegen,
  51. {$endif}
  52. globtype,symconst,symdef,systems,types,globals,verbose,cpuasm;
  53. {$define ATTOP}
  54. {$define INTELOP}
  55. {$ifdef NORA386INT}
  56. {$ifdef NOAG386NSM}
  57. {$ifdef NOAG386INT}
  58. {$undef INTELOP}
  59. {$endif}
  60. {$endif}
  61. {$endif}
  62. {$ifdef NORA386ATT}
  63. {$ifdef NOAG386ATT}
  64. {$undef ATTOP}
  65. {$endif}
  66. {$endif}
  67. {*****************************************************************************
  68. Parser Helpers
  69. *****************************************************************************}
  70. function is_prefix(t:tasmop):boolean;
  71. var
  72. i : longint;
  73. Begin
  74. is_prefix:=false;
  75. for i:=1 to AsmPrefixes do
  76. if t=AsmPrefix[i-1] then
  77. begin
  78. is_prefix:=true;
  79. exit;
  80. end;
  81. end;
  82. function is_override(t:tasmop):boolean;
  83. var
  84. i : longint;
  85. Begin
  86. is_override:=false;
  87. for i:=1 to AsmOverrides do
  88. if t=AsmOverride[i-1] then
  89. begin
  90. is_override:=true;
  91. exit;
  92. end;
  93. end;
  94. Function CheckPrefix(prefixop,op:tasmop): Boolean;
  95. { Checks if the prefix is valid with the following opcode }
  96. { return false if not, otherwise true }
  97. Begin
  98. CheckPrefix := TRUE;
  99. (* Case prefix of
  100. A_REP,A_REPNE,A_REPE:
  101. Case opcode Of
  102. A_SCASB,A_SCASW,A_SCASD,
  103. A_INS,A_OUTS,A_MOVS,A_CMPS,A_LODS,A_STOS:;
  104. Else
  105. Begin
  106. CheckPrefix := FALSE;
  107. exit;
  108. end;
  109. end; { case }
  110. A_LOCK:
  111. Case opcode Of
  112. A_BT,A_BTS,A_BTR,A_BTC,A_XCHG,A_ADD,A_OR,A_ADC,A_SBB,A_AND,A_SUB,
  113. A_XOR,A_NOT,A_NEG,A_INC,A_DEC:;
  114. Else
  115. Begin
  116. CheckPrefix := FALSE;
  117. Exit;
  118. end;
  119. end; { case }
  120. A_NONE: exit; { no prefix here }
  121. else
  122. CheckPrefix := FALSE;
  123. end; { end case } *)
  124. end;
  125. Function CheckOverride(overrideop,op:tasmop): Boolean;
  126. { Check if the override is valid, and if so then }
  127. { update the instr variable accordingly. }
  128. Begin
  129. CheckOverride := true;
  130. { Case instr.getinstruction of
  131. A_MOVS,A_XLAT,A_CMPS:
  132. Begin
  133. CheckOverride := TRUE;
  134. Message(assem_e_segment_override_not_supported);
  135. end
  136. end }
  137. end;
  138. Procedure FWaitWarning;
  139. begin
  140. if (target_info.target=target_i386_GO32V2) and (cs_fp_emulation in aktmoduleswitches) then
  141. Message(asmr_w_fwait_emu_prob);
  142. end;
  143. {*****************************************************************************
  144. T386Operand
  145. *****************************************************************************}
  146. Procedure T386Operand.SetCorrectSize(opcode:tasmop);
  147. begin
  148. if att_needsuffix[opcode]=attsufFPU then
  149. begin
  150. case size of
  151. S_L : size:=S_FS;
  152. S_IQ : size:=S_FL;
  153. end;
  154. end
  155. else if att_needsuffix[opcode]=attsufFPUint then
  156. begin
  157. case size of
  158. S_W : size:=S_IS;
  159. S_L : size:=S_IL;
  160. end;
  161. end;
  162. end;
  163. Function T386Operand.SetupResult:boolean;
  164. var
  165. Res : boolean;
  166. Begin
  167. Res:=TOperand.setupResult;
  168. { replace by ref by register if not place was
  169. reserved on stack }
  170. if res and (procinfo^.return_offset=0) then
  171. begin
  172. opr.typ:=OPR_REGISTER;
  173. if is_fpu(procinfo^.returntype.def) then
  174. begin
  175. opr.reg:=R_ST0;
  176. case pfloatdef(procinfo^.returntype.def)^.typ of
  177. s32real : size:=S_FS;
  178. s64real : size:=S_FL;
  179. s80real : size:=S_FX;
  180. s64comp : size:=S_IQ;
  181. else
  182. begin
  183. Message(asmr_e_cannot_use_RESULT_here);
  184. res:=false;
  185. end;
  186. end;
  187. end
  188. else if ret_in_acc(procinfo^.returntype.def) then
  189. case procinfo^.returntype.def^.size of
  190. 1 : begin
  191. opr.reg:=R_AL;
  192. size:=S_B;
  193. end;
  194. 2 : begin
  195. opr.reg:=R_AX;
  196. size:=S_W;
  197. end;
  198. 3,4 : begin
  199. opr.reg:=R_EAX;
  200. size:=S_L;
  201. end;
  202. else
  203. begin
  204. Message(asmr_e_cannot_use_RESULT_here);
  205. res:=false;
  206. end;
  207. end;
  208. Message1(asmr_h_RESULT_is_reg,reg2str(opr.reg));
  209. end;
  210. SetupResult:=res;
  211. end;
  212. {*****************************************************************************
  213. T386Instruction
  214. *****************************************************************************}
  215. procedure T386Instruction.AddReferenceSizes;
  216. { this will add the sizes for references like [esi] which do not
  217. have the size set yet, it will take only the size if the other
  218. operand is a register }
  219. var
  220. operand2,i : longint;
  221. s : pasmsymbol;
  222. so : longint;
  223. begin
  224. for i:=1to ops do
  225. begin
  226. operands[i]^.SetCorrectSize(opcode);
  227. if (operands[i]^.size=S_NO) then
  228. begin
  229. case operands[i]^.Opr.Typ of
  230. OPR_REFERENCE :
  231. begin
  232. if i=2 then
  233. operand2:=1
  234. else
  235. operand2:=2;
  236. if operand2<ops then
  237. begin
  238. { Only allow register as operand to take the size from }
  239. if operands[operand2]^.opr.typ=OPR_REGISTER then
  240. operands[i]^.size:=operands[operand2]^.size
  241. else
  242. begin
  243. { if no register then take the opsize (which is available with ATT),
  244. if not availble then give an error }
  245. if opsize<>S_NO then
  246. operands[i]^.size:=opsize
  247. else
  248. begin
  249. Message(asmr_e_unable_to_determine_reference_size);
  250. { recovery }
  251. operands[i]^.size:=S_L;
  252. end;
  253. end;
  254. end
  255. else
  256. begin
  257. if opsize<>S_NO then
  258. operands[i]^.size:=opsize
  259. end;
  260. end;
  261. OPR_SYMBOL :
  262. begin
  263. { Fix lea which need a reference }
  264. if opcode=A_LEA then
  265. begin
  266. s:=operands[i]^.opr.symbol;
  267. so:=operands[i]^.opr.symofs;
  268. operands[i]^.opr.typ:=OPR_REFERENCE;
  269. reset_reference(operands[i]^.opr.ref);
  270. operands[i]^.opr.ref.symbol:=s;
  271. operands[i]^.opr.ref.offset:=so;
  272. end;
  273. operands[i]^.size:=S_L;
  274. end;
  275. end;
  276. end;
  277. end;
  278. end;
  279. procedure T386Instruction.SetInstructionOpsize;
  280. begin
  281. if opsize<>S_NO then
  282. exit;
  283. case ops of
  284. 0 : ;
  285. 1 :
  286. { "push es" must be stored as a long PM }
  287. if ((opcode=A_PUSH) or
  288. (opcode=A_POP)) and
  289. (operands[1]^.opr.typ=OPR_REGISTER) and
  290. ((operands[1]^.opr.reg>=firstsreg) and
  291. (operands[1]^.opr.reg<=lastsreg)) then
  292. opsize:=S_L
  293. else
  294. opsize:=operands[1]^.size;
  295. 2 :
  296. begin
  297. case opcode of
  298. A_MOVZX,A_MOVSX :
  299. begin
  300. case operands[1]^.size of
  301. S_W :
  302. case operands[2]^.size of
  303. S_L :
  304. opsize:=S_WL;
  305. end;
  306. S_B :
  307. case operands[2]^.size of
  308. S_W :
  309. opsize:=S_BW;
  310. S_L :
  311. opsize:=S_BL;
  312. end;
  313. end;
  314. end;
  315. A_OUT :
  316. opsize:=operands[1]^.size;
  317. else
  318. opsize:=operands[2]^.size;
  319. end;
  320. end;
  321. 3 :
  322. opsize:=operands[3]^.size;
  323. end;
  324. end;
  325. procedure T386Instruction.CheckOperandSizes;
  326. var
  327. sizeerr : boolean;
  328. i : longint;
  329. begin
  330. { Check only the most common opcodes here, the others are done in
  331. the assembler pass }
  332. case opcode of
  333. A_PUSH,A_POP,A_DEC,A_INC,A_NOT,A_NEG,
  334. A_CMP,A_MOV,
  335. A_ADD,A_SUB,A_ADC,A_SBB,
  336. A_AND,A_OR,A_TEST,A_XOR: ;
  337. else
  338. exit;
  339. end;
  340. { Handle the BW,BL,WL separatly }
  341. sizeerr:=false;
  342. { special push/pop selector case }
  343. if ((opcode=A_PUSH) or
  344. (opcode=A_POP)) and
  345. (operands[1]^.opr.typ=OPR_REGISTER) and
  346. ((operands[1]^.opr.reg>=firstsreg) and
  347. (operands[1]^.opr.reg<=lastsreg)) then
  348. exit;
  349. if opsize in [S_BW,S_BL,S_WL] then
  350. begin
  351. if ops<>2 then
  352. sizeerr:=true
  353. else
  354. begin
  355. case opsize of
  356. S_BW :
  357. sizeerr:=(operands[1]^.size<>S_B) or (operands[2]^.size<>S_W);
  358. S_BL :
  359. sizeerr:=(operands[1]^.size<>S_B) or (operands[2]^.size<>S_L);
  360. S_WL :
  361. sizeerr:=(operands[1]^.size<>S_W) or (operands[2]^.size<>S_L);
  362. end;
  363. end;
  364. end
  365. else
  366. begin
  367. for i:=1to ops do
  368. begin
  369. if (operands[i]^.opr.typ<>OPR_CONSTANT) and
  370. (operands[i]^.size in [S_B,S_W,S_L]) and
  371. (operands[i]^.size<>opsize) then
  372. sizeerr:=true;
  373. end;
  374. end;
  375. if sizeerr then
  376. begin
  377. { if range checks are on then generate an error }
  378. if (cs_compilesystem in aktmoduleswitches) or
  379. not (cs_check_range in aktlocalswitches) then
  380. Message(asmr_w_size_suffix_and_dest_dont_match)
  381. else
  382. Message(asmr_e_size_suffix_and_dest_dont_match);
  383. end;
  384. end;
  385. { This check must be done with the operand in ATT order
  386. i.e.after swapping in the intel reader
  387. but before swapping in the NASM and TASM writers PM }
  388. procedure T386Instruction.CheckNonCommutativeOpcodes;
  389. begin
  390. if ((ops=2) and
  391. (operands[1]^.opr.typ=OPR_REGISTER) and
  392. (operands[2]^.opr.typ=OPR_REGISTER) and
  393. { if the first is ST and the second is also a register
  394. it is necessarily ST1 .. ST7 }
  395. (operands[1]^.opr.reg=R_ST)) or
  396. (ops=0) then
  397. if opcode=A_FSUBR then
  398. opcode:=A_FSUB
  399. else if opcode=A_FSUB then
  400. opcode:=A_FSUBR
  401. else if opcode=A_FDIVR then
  402. opcode:=A_FDIV
  403. else if opcode=A_FDIV then
  404. opcode:=A_FDIVR
  405. else if opcode=A_FSUBRP then
  406. opcode:=A_FSUBP
  407. else if opcode=A_FSUBP then
  408. opcode:=A_FSUBRP
  409. else if opcode=A_FDIVRP then
  410. opcode:=A_FDIVP
  411. else if opcode=A_FDIVP then
  412. opcode:=A_FDIVRP;
  413. if ((ops=1) and
  414. (operands[1]^.opr.typ=OPR_REGISTER) and
  415. (operands[1]^.opr.reg in [R_ST1..R_ST7])) then
  416. if opcode=A_FSUBRP then
  417. opcode:=A_FSUBP
  418. else if opcode=A_FSUBP then
  419. opcode:=A_FSUBRP
  420. else if opcode=A_FDIVRP then
  421. opcode:=A_FDIVP
  422. else if opcode=A_FDIVP then
  423. opcode:=A_FDIVRP;
  424. end;
  425. {*****************************************************************************
  426. opcode Adding
  427. *****************************************************************************}
  428. procedure T386Instruction.ConcatInstruction(p : taasmoutput);
  429. var
  430. siz : topsize;
  431. i : longint;
  432. ai : taicpu;
  433. begin
  434. { Get Opsize }
  435. if (opsize<>S_NO) or (Ops=0) then
  436. siz:=opsize
  437. else
  438. begin
  439. if (Ops=2) and (operands[1]^.opr.typ=OPR_REGISTER) then
  440. siz:=operands[1]^.size
  441. else
  442. siz:=operands[Ops]^.size;
  443. end;
  444. { NASM does not support FADD without args
  445. as alias of FADDP
  446. and GNU AS interprets FADD without operand differently
  447. for version 2.9.1 and 2.9.5 !! }
  448. if (ops=0) and
  449. ((opcode=A_FADD) or
  450. (opcode=A_FMUL) or
  451. (opcode=A_FSUB) or
  452. (opcode=A_FSUBR) or
  453. (opcode=A_FDIV) or
  454. (opcode=A_FDIVR)) then
  455. begin
  456. if opcode=A_FADD then
  457. opcode:=A_FADDP
  458. else if opcode=A_FMUL then
  459. opcode:=A_FMULP
  460. else if opcode=A_FSUB then
  461. opcode:=A_FSUBP
  462. else if opcode=A_FSUBR then
  463. opcode:=A_FSUBRP
  464. else if opcode=A_FDIV then
  465. opcode:=A_FDIVP
  466. else if opcode=A_FDIVR then
  467. opcode:=A_FDIVRP;
  468. {$ifdef ATTOP}
  469. message1(asmr_w_fadd_to_faddp,att_op2str[opcode]);
  470. {$else}
  471. {$ifdef INTELOP}
  472. message1(asmr_w_fadd_to_faddp,int_op2str[opcode]);
  473. {$else}
  474. message1(asmr_w_fadd_to_faddp,'fXX');
  475. {$endif INTELOP}
  476. {$endif ATTOP}
  477. end;
  478. { GNU AS interprets FDIV without operand differently
  479. for version 2.9.1 and 2.10
  480. we add explicit args to it !! }
  481. if (ops=0) and
  482. ((opcode=A_FSUBP) or
  483. (opcode=A_FSUBRP) or
  484. (opcode=A_FDIVP) or
  485. (opcode=A_FDIVRP) or
  486. (opcode=A_FSUB) or
  487. (opcode=A_FSUBR) or
  488. (opcode=A_FDIV) or
  489. (opcode=A_FDIVR)) then
  490. begin
  491. {$ifdef ATTOP}
  492. message1(asmr_w_adding_explicit_args_fXX,att_op2str[opcode]);
  493. {$else}
  494. {$ifdef INTELOP}
  495. message1(asmr_w_adding_explicit_args_fXX,int_op2str[opcode]);
  496. {$else}
  497. message1(asmr_w_adding_explicit_args_fXX,'fXX');
  498. {$endif INTELOP}
  499. {$endif ATTOP}
  500. ops:=2;
  501. operands[1]^.opr.typ:=OPR_REGISTER;
  502. operands[2]^.opr.typ:=OPR_REGISTER;
  503. operands[1]^.opr.reg:=R_ST;
  504. operands[2]^.opr.reg:=R_ST1;
  505. end;
  506. if (ops=1) and
  507. ((operands[1]^.opr.typ=OPR_REGISTER) and
  508. (operands[1]^.opr.reg in [R_ST1..R_ST7])) and
  509. ((opcode=A_FSUBP) or
  510. (opcode=A_FSUBRP) or
  511. (opcode=A_FDIVP) or
  512. (opcode=A_FDIVRP)) then
  513. begin
  514. {$ifdef ATTOP}
  515. message1(asmr_w_adding_explicit_first_arg_fXX,att_op2str[opcode]);
  516. {$else}
  517. {$ifdef INTELOP}
  518. message1(asmr_w_adding_explicit_first_arg_fXX,int_op2str[opcode]);
  519. {$else}
  520. message1(asmr_w_adding_explicit_first_arg_fXX,'fXX');
  521. {$endif INTELOP}
  522. {$endif ATTOP}
  523. ops:=2;
  524. operands[2]^.opr.typ:=OPR_REGISTER;
  525. operands[2]^.opr.reg:=operands[1]^.opr.reg;
  526. operands[1]^.opr.reg:=R_ST;
  527. end;
  528. if (ops=1) and
  529. ((operands[1]^.opr.typ=OPR_REGISTER) and
  530. (operands[1]^.opr.reg in [R_ST1..R_ST7])) and
  531. ((opcode=A_FSUB) or
  532. (opcode=A_FSUBR) or
  533. (opcode=A_FDIV) or
  534. (opcode=A_FDIVR)) then
  535. begin
  536. {$ifdef ATTOP}
  537. message1(asmr_w_adding_explicit_second_arg_fXX,att_op2str[opcode]);
  538. {$else}
  539. {$ifdef INTELOP}
  540. message1(asmr_w_adding_explicit_second_arg_fXX,int_op2str[opcode]);
  541. {$else}
  542. message1(asmr_w_adding_explicit_second_arg_fXX,'fXX');
  543. {$endif INTELOP}
  544. {$endif ATTOP}
  545. ops:=2;
  546. operands[2]^.opr.typ:=OPR_REGISTER;
  547. operands[2]^.opr.reg:=R_ST;
  548. end;
  549. { I tried to convince Linus Torwald to add
  550. code to support ENTER instruction
  551. (when raising a stack page fault)
  552. but he replied that ENTER is a bad instruction and
  553. Linux does not need to support it
  554. So I think its at least a good idea to add a warning
  555. if someone uses this in assembler code
  556. FPC itself does not use it at all PM }
  557. if (opcode=A_ENTER) and ((target_info.target=target_i386_linux) or
  558. (target_info.target=target_i386_FreeBSD)) then
  559. begin
  560. message(asmr_w_enter_not_supported_by_linux);
  561. end;
  562. ai:=taicpu.op_none(opcode,siz);
  563. ai.Ops:=Ops;
  564. for i:=1to Ops do
  565. begin
  566. case operands[i]^.opr.typ of
  567. OPR_CONSTANT :
  568. ai.loadconst(i-1,operands[i]^.opr.val);
  569. OPR_REGISTER:
  570. ai.loadreg(i-1,operands[i]^.opr.reg);
  571. OPR_SYMBOL:
  572. ai.loadsymbol(i-1,operands[i]^.opr.symbol,operands[i]^.opr.symofs);
  573. OPR_REFERENCE:
  574. ai.loadref(i-1,newreference(operands[i]^.opr.ref));
  575. end;
  576. end;
  577. if (opcode=A_CALL) and (opsize=S_FAR) then
  578. opcode:=A_LCALL;
  579. if (opcode=A_JMP) and (opsize=S_FAR) then
  580. opcode:=A_LJMP;
  581. if (opcode=A_LCALL) or (opcode=A_LJMP) then
  582. opsize:=S_FAR;
  583. { Condition ? }
  584. if condition<>C_None then
  585. ai.SetCondition(condition);
  586. { Concat the opcode or give an error }
  587. if assigned(ai) then
  588. begin
  589. { Check the instruction if it's valid }
  590. {$ifndef NOAG386BIN}
  591. ai.CheckIfValid;
  592. {$endif NOAG386BIN}
  593. p.concat(ai);
  594. end
  595. else
  596. Message(asmr_e_invalid_opcode_and_operand);
  597. end;
  598. end.
  599. {
  600. $Log$
  601. Revision 1.7 2001-03-05 21:49:44 peter
  602. * noag386bin fix
  603. Revision 1.6 2001/02/20 21:51:36 peter
  604. * fpu fixes (merged)
  605. Revision 1.5 2001/01/12 19:18:42 peter
  606. * check for valid asm instructions
  607. Revision 1.4 2000/12/25 00:07:34 peter
  608. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  609. tlinkedlist objects)
  610. Revision 1.3 2000/11/29 00:30:50 florian
  611. * unused units removed from uses clause
  612. * some changes for widestrings
  613. Revision 1.2 2000/10/31 22:30:14 peter
  614. * merged asm result patch part 2
  615. Revision 1.1 2000/10/15 09:47:43 peter
  616. * moved to i386/
  617. Revision 1.7 2000/10/08 10:26:33 peter
  618. * merged @result fix from Pierre
  619. Revision 1.6 2000/09/24 21:33:47 peter
  620. * message updates merges
  621. Revision 1.5 2000/09/24 15:06:25 peter
  622. * use defines.inc
  623. Revision 1.4 2000/09/16 12:22:52 peter
  624. * freebsd support merged
  625. Revision 1.3 2000/09/03 11:44:00 peter
  626. * error for not specified operand size, which is now required for
  627. newer binutils (merged)
  628. * previous commit fix for tcflw (merged)
  629. Revision 1.2 2000/07/13 11:32:47 michael
  630. + removed logs
  631. }