cpubase.pas 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by the Free Pascal dev. team
  4. Contains the base types for the virtual instruction set
  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. { This Unit contains the base types for the Virtual Instruction machine
  19. }
  20. unit cpubase;
  21. {$i fpcdefs.inc}
  22. interface
  23. uses
  24. strings,cutils,cclasses,aasmbase,cpuinfo,cginfo;
  25. {*****************************************************************************
  26. Assembler Opcodes
  27. *****************************************************************************}
  28. type
  29. TAsmOp=(a_none,a_beqs,a_bges,a_bgts,a_bles,a_blts,a_bnes,
  30. a_bras,a_rets,a_bccs,a_bcss,a_bvcs,a_bvss,a_bbss,
  31. a_bass,a_bats,a_bbts,a_beql,a_bgel,a_bgtl,a_blel,
  32. a_bltl,a_bnel,a_bral,a_bsrl,a_bbsl,a_basl,a_batl,
  33. a_bbtl,a_add,a_addc,a_and,a_asr,a_lsl,a_lsr,a_cmp,
  34. a_sub,a_subb,a_divs,a_divu,a_mod,a_move,a_muls,a_mulu,
  35. a_neg,a_not,a_or,a_xor,a_fadd,a_fcmp,a_fdiv,a_fmove,
  36. a_fmul,a_fneg,a_fsub,a_fldd,a_flds,a_lbzx,a_lbsx,a_llsx,
  37. a_llzx,a_lwsx,a_lwzx,a_fstd,a_fsts,a_stb,a_stl,a_stw,
  38. a_syscall,a_nop,a_lims,a_orhi,a_lilo,a_call,a_popl,
  39. a_pushl,
  40. { these are simplified mnemonics }
  41. a_lea,a_limm,a_bxx
  42. );
  43. {# This should define the array of instructions as string }
  44. op2strtable=array[tasmop] of string[8];
  45. Const
  46. {# First value of opcode enumeration }
  47. firstop = low(tasmop);
  48. {# Last value of opcode enumeration }
  49. lastop = high(tasmop);
  50. {*****************************************************************************
  51. Registers
  52. *****************************************************************************}
  53. type
  54. toldregister = (R_NO,R_R0,R_R1,R_R2,R_R3,
  55. R_R4,R_R5,R_R6,R_R7,
  56. R_R8,R_R9,R_R10,R_R11,
  57. R_CCR,R_SP,R_FP,R_PC,
  58. R_FP0,R_FP1,R_FP2,R_FP3,
  59. R_FP4,R_FP5,R_FP6,R_FP7,
  60. R_FP8,R_FP9,R_FP10,R_FP11,
  61. R_FP12,R_FP13,R_FP14,R_FP15,
  62. R_INTREGISTER,R_FPUREGISTER
  63. );
  64. {# Set type definition for registers }
  65. tregisterset = set of Toldregister;
  66. Tnewregister=word;
  67. tregister=record
  68. enum:toldregister;
  69. number:Tnewregister;
  70. end;
  71. { A type to store register locations for 64 Bit values. }
  72. tregister64 = packed record
  73. reglo,reghi : tregister;
  74. end;
  75. Tsuperregister=byte;
  76. Tsubregister=byte;
  77. Tsupregset=set of Tsuperregister;
  78. { alias for compact code }
  79. treg64 = tregister64;
  80. {# Type definition for the array of string of register nnames }
  81. treg2strtable = array[toldregister] of string[5];
  82. Const
  83. {Special registers:}
  84. NR_NO = $0000; {Invalid register}
  85. {Normal registers:}
  86. {General purpose registers:}
  87. NR_R0 = $0100; NR_R1 = $0200; NR_R2 = $0300;
  88. NR_R3 = $0400; NR_R4 = $0500; NR_R5 = $0600;
  89. NR_R6 = $0700; NR_R7 = $0800; NR_R8 = $0900;
  90. NR_R9 = $0A00; NR_R10 = $0B00; NR_R11 = $0C00;
  91. NR_SP = $0D00; NR_FP = $0E00;
  92. {Super registers:}
  93. RS_R0 = $01; RS_R1 = $02; RS_R2 = $03;
  94. RS_R3 = $04; RS_R4 = $05; RS_R5 = $06;
  95. RS_R6 = $07; RS_R7 = $08; RS_R8 = $09;
  96. RS_R9 = $0A; RS_R10 = $0B; RS_R11 = $0C;
  97. RS_SP = $0D; RS_FP = $0E;
  98. {Subregisters:}
  99. R_SUBL = $00;
  100. R_SUBW = $01;
  101. R_SUBD = $02;
  102. {# First register in the tregister enumeration }
  103. firstreg = low(toldregister);
  104. {# Last register in the tregister enumeration }
  105. lastreg = high(toldregister);
  106. first_supreg = $01;
  107. last_supreg = $0c;
  108. std_reg2str : treg2strtable = ('',
  109. 'r0','r1','r2','r3','r4','r5','r6','r7','r8','r9','r10','r11','ccr',
  110. 'sp','fp','pc','fp0','fp1','fp2','fp3','fp4','fp5','fp6','fp7',
  111. 'fp8','fp9','fp10','fp11','fp12','fp13','fp14','fp15','',''
  112. );
  113. {*****************************************************************************
  114. Conditions
  115. *****************************************************************************}
  116. type
  117. TAsmCond=(C_None,
  118. C_EQ, { equal }
  119. C_NE, { not equal }
  120. C_GE, { greater or equal (signed) }
  121. C_GT, { greater than (signed) }
  122. C_LE, { less or equal (signed) }
  123. C_LT, { less than (signed) }
  124. C_LS, { lower or same (unordered) }
  125. C_AS, { above or same (unordered) }
  126. C_AT, { above than (unordered) }
  127. C_BT, { below than (unordered) }
  128. C_CC, { carry clear }
  129. C_CS { carry set }
  130. );
  131. const
  132. cond2str:array[TAsmCond] of string[3]=('',
  133. 'eq','ne','ge','gt','le','lt','ls','as',
  134. 'at','bt','cc','cs');
  135. {*****************************************************************************
  136. Flags
  137. *****************************************************************************}
  138. type
  139. TResFlags = (
  140. F_E, { zero flag = equal }
  141. F_NE, { !zero_flag = not equal }
  142. F_G, { greater (signed) }
  143. F_L, { less (signed) }
  144. F_GE,
  145. F_LE,
  146. F_C, { carry flag }
  147. F_NC, { !carry flag }
  148. F_A, { greater (unsigned) }
  149. F_AE,
  150. F_B, { less (unsigned) }
  151. F_BE
  152. );
  153. {*****************************************************************************
  154. Reference
  155. *****************************************************************************}
  156. type
  157. trefoptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
  158. { reference record }
  159. preference = ^treference;
  160. treference = packed record
  161. base,
  162. index : tregister;
  163. offset : longint;
  164. symbol : tasmsymbol;
  165. offsetfixup : longint;
  166. options : trefoptions;
  167. alignment : byte;
  168. end;
  169. { reference record }
  170. pparareference = ^tparareference;
  171. tparareference = packed record
  172. index : tregister;
  173. offset : aword;
  174. end;
  175. {*****************************************************************************
  176. Operand
  177. *****************************************************************************}
  178. type
  179. toptype=(top_none,top_reg,top_ref,top_const,top_symbol,top_bool);
  180. toper=record
  181. ot : longint;
  182. case typ : toptype of
  183. top_none : ();
  184. top_reg : (reg:tregister);
  185. top_ref : (ref:^treference);
  186. top_const : (val:aword);
  187. top_symbol : (sym:tasmsymbol;symofs:longint);
  188. top_bool : (b: boolean);
  189. end;
  190. {*****************************************************************************
  191. Operand Sizes
  192. *****************************************************************************}
  193. { S_NO = No Size of operand }
  194. { S_B = 8-bit size operand }
  195. { S_W = 16-bit size operand }
  196. { S_L = 32-bit size operand }
  197. { Floating point types }
  198. { S_FS = single type (32 bit) }
  199. { S_FD = double/64bit integer }
  200. { S_FX = Extended type }
  201. topsize = (S_NO,S_B,S_W,S_L,S_FS,S_FD,S_FX,S_IQ);
  202. {*****************************************************************************
  203. Generic Location
  204. *****************************************************************************}
  205. type
  206. TLoc=(
  207. { added for tracking problems}
  208. LOC_INVALID,
  209. { ordinal constant }
  210. LOC_CONSTANT,
  211. { in a processor register }
  212. LOC_REGISTER,
  213. { Constant register which shouldn't be modified }
  214. LOC_CREGISTER,
  215. { FPU register}
  216. LOC_FPUREGISTER,
  217. { Constant FPU register which shouldn't be modified }
  218. LOC_CFPUREGISTER,
  219. { multimedia register }
  220. LOC_MMREGISTER,
  221. { Constant multimedia reg which shouldn't be modified }
  222. LOC_CMMREGISTER,
  223. { in memory }
  224. LOC_REFERENCE,
  225. { in memory (constant) }
  226. LOC_CREFERENCE,
  227. { boolean results only, jump to false or true label }
  228. LOC_JUMP,
  229. { boolean results only, flags are set }
  230. LOC_FLAGS
  231. );
  232. { tparamlocation describes where a parameter for a procedure is stored.
  233. References are given from the caller's point of view. The usual
  234. TLocation isn't used, because contains a lot of unnessary fields.
  235. }
  236. tparalocation = packed record
  237. size : TCGSize;
  238. { The location type where the parameter is passed, usually
  239. LOC_REFERENCE,LOC_REGISTER or LOC_FPUREGISTER
  240. }
  241. loc : TLoc;
  242. { The stack pointer must be decreased by this value before
  243. the parameter is copied to the given destination.
  244. This allows to "encode" pushes with tparalocation.
  245. On the PowerPC, this field is unsed but it is there
  246. because several generic code accesses it.
  247. }
  248. sp_fixup : longint;
  249. case TLoc of
  250. LOC_REFERENCE : (reference : tparareference);
  251. LOC_FPUREGISTER, LOC_CFPUREGISTER, LOC_MMREGISTER, LOC_CMMREGISTER,
  252. LOC_REGISTER,LOC_CREGISTER : (
  253. case longint of
  254. 1 : (register,registerhigh : tregister);
  255. { overlay a registerlow }
  256. 2 : (registerlow : tregister);
  257. { overlay a 64 Bit register type }
  258. 3 : (reg64 : tregister64);
  259. 4 : (register64 : tregister64);
  260. );
  261. end;
  262. treglocation = packed record
  263. case longint of
  264. 1 : (register,registerhigh : tregister);
  265. { overlay a registerlow }
  266. 2 : (registerlow : tregister);
  267. { overlay a 64 Bit register type }
  268. 3 : (reg64 : tregister64);
  269. 4 : (register64 : tregister64);
  270. end;
  271. tlocation = packed record
  272. size : TCGSize;
  273. loc : tloc;
  274. case tloc of
  275. LOC_CREFERENCE,LOC_REFERENCE : (reference : treference);
  276. LOC_CONSTANT : (
  277. case longint of
  278. 1 : (value : AWord);
  279. { can't do this, this layout depends on the host cpu. Use }
  280. { lo(valueqword)/hi(valueqword) instead (JM) }
  281. { 2 : (valuelow, valuehigh:AWord); }
  282. { overlay a complete 64 Bit value }
  283. 3 : (valueqword : qword);
  284. );
  285. LOC_FPUREGISTER, LOC_CFPUREGISTER, LOC_MMREGISTER, LOC_CMMREGISTER,
  286. LOC_REGISTER,LOC_CREGISTER : (
  287. case longint of
  288. 1 : (registerlow,registerhigh : tregister);
  289. 2 : (register : tregister);
  290. { overlay a 64 Bit register type }
  291. 3 : (reg64 : tregister64);
  292. 4 : (register64 : tregister64);
  293. );
  294. LOC_FLAGS : (resflags : tresflags);
  295. end;
  296. {*****************************************************************************
  297. Constants
  298. *****************************************************************************}
  299. const
  300. max_operands = 2;
  301. lvaluelocations = [LOC_REFERENCE, LOC_CREGISTER, LOC_CFPUREGISTER,
  302. LOC_CMMREGISTER];
  303. {# Constant defining possibly all registers which might require saving }
  304. ALL_REGISTERS = [R_FP0..R_FP15];
  305. general_registers = [R_R0..R_R11];
  306. {# low and high of the available maximum width integer general purpose }
  307. { registers }
  308. LoGPReg = R_R0;
  309. HiGPReg = R_R11;
  310. {# low and high of every possible width general purpose register (same as }
  311. { above on most architctures apart from the 80x86) }
  312. LoReg = R_R0;
  313. HiReg = R_R11;
  314. {# Table of registers which can be allocated by the code generator
  315. internally, when generating the code.
  316. }
  317. { legend: }
  318. { xxxregs = set of all possibly used registers of that type in the code }
  319. { generator }
  320. { usableregsxxx = set of all 32bit components of registers that can be }
  321. { possible allocated to a regvar or using getregisterxxx (this }
  322. { excludes registers which can be only used for parameter }
  323. { passing on ABI's that define this) }
  324. { c_countusableregsxxx = amount of registers in the usableregsxxx set }
  325. maxintregs = 12;
  326. intregs = [R_R0..R_R11];
  327. usableregsint = [R_R2..R_R11];
  328. c_countusableregsint = 18;
  329. maxfpuregs = 16;
  330. fpuregs = [R_FP0..R_FP15];
  331. usableregsfpu = [R_FP1..R_FP15];
  332. c_countusableregsfpu = 15;
  333. mmregs = [];
  334. usableregsmm = [];
  335. c_countusableregsmm = 0;
  336. { no distinction on this platform }
  337. maxaddrregs = 0;
  338. addrregs = [];
  339. usableregsaddr = [];
  340. c_countusableregsaddr = 0;
  341. firstsaveintreg = R_R2;
  342. lastsaveintreg = R_R11;
  343. firstsavefpureg = R_FP1;
  344. lastsavefpureg = R_FP15;
  345. firstsavemmreg = R_NO;
  346. lastsavemmreg = R_NO;
  347. maxvarregs = 10;
  348. varregs : Array [1..maxvarregs] of toldregister =
  349. (R_R2,R_R3,R_R4,R_R5,R_R6,R_R7,R_R8,R_R9,R_R10,R_R11);
  350. maxfpuvarregs = 15;
  351. fpuvarregs : Array [1..maxfpuvarregs] of toldregister =
  352. (R_FP1,R_FP2,R_FP3,
  353. R_FP4,R_FP5,R_FP6,
  354. R_FP7,R_FP8,R_FP9,
  355. R_FP10,R_FP11,R_FP12,
  356. R_FP13,R_FP14,R_FP15);
  357. max_param_regs_int = 0;
  358. max_param_regs_fpu = 0;
  359. max_param_regs_mm = 0;
  360. {# Registers which are defined as scratch and no need to save across
  361. routine calls or in assembler blocks.
  362. }
  363. max_scratch_regs = 2;
  364. scratch_regs: Array[1..max_scratch_regs] of Tsuperregister = (RS_R0,RS_R1);
  365. {*****************************************************************************
  366. Default generic sizes
  367. *****************************************************************************}
  368. {# Defines the default address size for a processor, }
  369. OS_ADDR = OS_32;
  370. {# the natural int size for a processor, }
  371. OS_INT = OS_32;
  372. {# the maximum float size for a processor, }
  373. OS_FLOAT = OS_F64;
  374. {# the size of a vector register for a processor }
  375. OS_VECTOR = OS_NO;
  376. {*****************************************************************************
  377. GDB Information
  378. *****************************************************************************}
  379. {# Register indexes for stabs information, when some
  380. parameters or variables are stored in registers.
  381. Currently unsupported by abstract machine
  382. }
  383. stab_regindex : array[toldregister] of shortint =
  384. (-1,
  385. { r0..r11 }
  386. -1,-1,-1,-1,-1,-1,
  387. -1,-1,-1,-1,-1,-1,
  388. { sp,fp,ccr,pc }
  389. -1,-1,-1,-1,
  390. { FP0..FP7 }
  391. -1,-1,-1,-1,-1,-1,-1,-1,
  392. { FP8..FP15 }
  393. -1,-1,-1,-1,-1,-1,-1,-1,
  394. { invalid }
  395. -1,-1
  396. );
  397. {*****************************************************************************
  398. Generic Register names
  399. *****************************************************************************}
  400. {# Stack pointer register }
  401. stack_pointer_reg = R_SP;
  402. NR_STACK_POINTER_REG = NR_SP;
  403. RS_STACK_POINTER_REG = RS_SP;
  404. {# Frame pointer register }
  405. frame_pointer_reg = R_FP;
  406. NR_FRAME_POINTER_REG = NR_FP;
  407. RS_FRAME_POINTER_REG = RS_FP;
  408. {# Self pointer register : contains the instance address of an
  409. object or class. }
  410. self_pointer_reg = R_R11;
  411. NR_SELF_POINTER_REG = NR_R11;
  412. RS_SELF_POINTER_REG = RS_R11;
  413. {# Register for addressing absolute data in a position independant way,
  414. such as in PIC code. The exact meaning is ABI specific.
  415. }
  416. pic_offset_reg = R_R10;
  417. {# Results are returned in this register (32-bit values) }
  418. accumulator = R_R0;
  419. NR_ACCUMULATOR = NR_R0;
  420. RS_ACCUMULATOR = RS_R0;
  421. {the return_result_reg, is used inside the called function to store its return
  422. value when that is a scalar value otherwise a pointer to the address of the
  423. result is placed inside it}
  424. return_result_reg = accumulator;
  425. {the function_result_reg contains the function result after a call to a scalar
  426. function othewise it contains a pointer to the returned result}
  427. function_result_reg = accumulator;
  428. {# Hi-Results are returned in this register (64-bit value high register) }
  429. accumulatorhigh = R_R1;
  430. NR_ACCUMULATORHIGH = NR_R1;
  431. RS_ACCUMULATORHIGH = RS_R1;
  432. fpu_result_reg = R_FP0;
  433. mmresultreg = R_NO;
  434. {*****************************************************************************
  435. GCC /ABI linking information
  436. *****************************************************************************}
  437. {# Registers which must be saved when calling a routine declared as
  438. cppdecl, cdecl, stdcall, safecall, palmossyscall. The registers
  439. saved should be the ones as defined in the target ABI and / or GCC.
  440. This value can be deduced from CALLED_USED_REGISTERS array in the
  441. GCC source.
  442. }
  443. std_saved_registers = [RS_R0,RS_R1,RS_R10,RS_R11];
  444. {# Required parameter alignment when calling a routine declared as
  445. stdcall and cdecl. The alignment value should be the one defined
  446. by GCC or the target ABI.
  447. The value of this constant is equal to the constant
  448. PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.
  449. }
  450. std_param_align = 4; { for 32-bit version only }
  451. {*****************************************************************************
  452. Helpers
  453. *****************************************************************************}
  454. function is_calljmp(o:tasmop):boolean;
  455. procedure inverse_flags(var r : TResFlags);
  456. function flags_to_cond(const f: TResFlags) : TAsmCond;
  457. procedure convert_register_to_enum(var r:Tregister);
  458. function cgsize2subreg(s:Tcgsize):Tsubregister;
  459. implementation
  460. uses
  461. verbose;
  462. {*****************************************************************************
  463. Helpers
  464. *****************************************************************************}
  465. function is_calljmp(o:tasmop):boolean;
  466. begin
  467. is_calljmp := false;
  468. if o in [a_bxx,a_call,a_beqs..a_bbtl] then
  469. is_calljmp := true;
  470. end;
  471. procedure inverse_flags(var r: TResFlags);
  472. const flagsinvers : array[F_E..F_BE] of tresflags =
  473. (F_NE,F_E,
  474. F_LE,F_GE,
  475. F_L,F_G,
  476. F_NC,F_C,
  477. F_BE,F_B,
  478. F_AE,F_A);
  479. begin
  480. r:=flagsinvers[r];
  481. end;
  482. function flags_to_cond(const f: TResFlags) : TAsmCond;
  483. const flags2cond : array[tresflags] of tasmcond =
  484. (
  485. {F_E} C_EQ,
  486. {F_NE} C_NE,
  487. {F_G } C_GT,
  488. {F_L } C_LT,
  489. {F_GE} C_GE,
  490. {F_LE} C_LE,
  491. {F_C} C_CS,
  492. {F_NC} C_CC,
  493. {F_A} C_AT,
  494. {F_AE} C_AS,
  495. {F_B} C_BT,
  496. {F_BE} C_LS);
  497. begin
  498. flags_to_cond := flags2cond[f];
  499. end;
  500. procedure convert_register_to_enum(var r:Tregister);
  501. begin
  502. if r.enum = R_INTREGISTER then
  503. case r.number of
  504. NR_NO: r.enum:= R_NO;
  505. NR_R0: r.enum:= R_R0;
  506. NR_R1: r.enum:= R_R1;
  507. NR_R2: r.enum:= R_R2;
  508. NR_R3: r.enum:= R_R3;
  509. NR_R4: r.enum:= R_R4;
  510. NR_R5: r.enum:= R_R5;
  511. NR_R6: r.enum:= R_R6;
  512. NR_R7: r.enum:= R_R7;
  513. NR_R8: r.enum:= R_R8;
  514. NR_R9: r.enum:= R_R9;
  515. NR_R10: r.enum:= R_R10;
  516. NR_R11: r.enum:= R_R11;
  517. else
  518. internalerror(200301082);
  519. end;
  520. end;
  521. function cgsize2subreg(s:Tcgsize):Tsubregister;
  522. begin
  523. case s of
  524. OS_8,OS_S8:
  525. cgsize2subreg:=R_SUBL;
  526. OS_16,OS_S16:
  527. cgsize2subreg:=R_SUBW;
  528. OS_32,OS_S32:
  529. cgsize2subreg:=R_SUBD;
  530. else
  531. internalerror(200301231);
  532. end;
  533. end;
  534. end.
  535. {
  536. $Log$
  537. Revision 1.5 2003-02-19 22:00:17 daniel
  538. * Code generator converted to new register notation
  539. - Horribily outdated todo.txt removed
  540. Revision 1.4 2003/02/02 19:25:54 carl
  541. * Several bugfixes for m68k target (register alloc., opcode emission)
  542. + VIS target
  543. + Generic add more complete (still not verified)
  544. Revision 1.3 2002/11/17 18:26:16 mazen
  545. * fixed a compilation bug accmulator-->accumulator, in definition of return_result_reg
  546. Revision 1.2 2002/11/17 17:49:09 mazen
  547. + return_result_reg and function_result_reg are now used, in all plateforms, to pass functions result between called function and its caller. See the explanation of each one
  548. Revision 1.1 2002/10/14 16:31:52 carl
  549. + first revision of vm
  550. }