Subversion Repositories Kolibri OS

Rev

Rev 9177 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. (*
  2.     BSD 2-Clause License
  3.  
  4.     Copyright (c) 2020-2022, Anton Krotov
  5.     All rights reserved.
  6. *)
  7.  
  8. MODULE RVMxI;
  9.  
  10. IMPORT
  11.  
  12.     PROG, WR := WRITER, IL, CHL := CHUNKLISTS, REG, UTILS, STRINGS, ERRORS, TARGETS;
  13.  
  14.  
  15. CONST
  16.  
  17.     LTypes   = 0;
  18.     LStrings = 1;
  19.     LGlobal  = 2;
  20.     LHeap    = 3;
  21.     LStack   = 4;
  22.  
  23.     numGPRs = 3;
  24.  
  25.     R0 = 0; R1 = 1;
  26.     BP = 3; SP = 4;
  27.  
  28.     ACC = R0;
  29.  
  30.     GPRs = {0 .. 2} + {5 .. numGPRs + 1};
  31.  
  32.     opSTOP = 0; opRET = 1; opENTER = 2; opNEG = 3; opNOT = 4; opNOP = 5;
  33.     opXCHG = 6; opLDB = 7; opLDH = 8; opLDW = 9; opPUSH = 10; opPUSHC = 11;
  34.     opPOP = 12; opLABEL = 13; opLEA = 14; opLLA = 15;
  35.     opLDD = 16; (* 17, 18 *)
  36.     opJMP = 19; opCALL = 20; opCALLI = 21;
  37.  
  38.     opMOV = 22; opMUL = 24; opADD = 26; opSUB = 28; opDIV = 30; opMOD = 32;
  39.     opSTB = 34; opSTH = 36; opSTW = 38; opSTD = 40; (* 42, 44 *)
  40.     opAND = 46; opOR = 48; opXOR = 50; opASR = 52; opLSR = 54;
  41.     opLSL = 56; opROR = 58; (* 60, 62 *) opCMP = 64;
  42.  
  43.     opMOVC = 23; opMULC = 25; opADDC = 27; opSUBC = 29; opDIVC = 31; opMODC = 33;
  44.     opSTBC = 35; opSTHC = 37; opSTWC = 39; opSTDC = 41; (* 43, 45 *)
  45.     opANDC = 47; opORC = 49; opXORC = 51; opASRC = 53; opLSRC = 55;
  46.     opLSLC = 57; opRORC = 59; (* 61, 63 *) opCMPC = 65;
  47.  
  48.     opBIT = 66; opSYSCALL = 67; opJBT = 68; opADDRC = 69;
  49.  
  50.     opJEQ = 70; opJNE = 71; opJLT = 72; opJGE = 73; opJGT = 74; opJLE = 75;
  51.     opSEQ = 76; opSNE = 77; opSLT = 78; opSGE = 79; opSGT = 80; opSLE = 81;
  52.  
  53.  
  54. VAR
  55.  
  56.     R: REG.REGS; count, szWord: INTEGER;
  57.  
  58.     ldr, str: PROCEDURE (r1, r2: INTEGER);
  59.  
  60.  
  61. PROCEDURE OutByte (n: BYTE);
  62. BEGIN
  63.     WR.WriteByte(n);
  64.     INC(count)
  65. END OutByte;
  66.  
  67.  
  68. PROCEDURE OutInt (n: INTEGER);
  69. BEGIN
  70.     IF szWord = 8 THEN
  71.         WR.Write64LE(n);
  72.         INC(count, 8)
  73.     ELSE (* szWord = 4 *)
  74.         WR.Write32LE(n);
  75.         INC(count, 4)
  76.     END
  77. END OutInt;
  78.  
  79.  
  80. PROCEDURE Emit (op, par1, par2: INTEGER);
  81. BEGIN
  82.     OutInt(op);
  83.     OutInt(par1);
  84.     OutInt(par2)
  85. END Emit;
  86.  
  87.  
  88. PROCEDURE drop;
  89. BEGIN
  90.     REG.Drop(R)
  91. END drop;
  92.  
  93.  
  94. PROCEDURE GetAnyReg (): INTEGER;
  95.     RETURN REG.GetAnyReg(R)
  96. END GetAnyReg;
  97.  
  98.  
  99. PROCEDURE GetAcc;
  100. BEGIN
  101.     ASSERT(REG.GetReg(R, ACC))
  102. END GetAcc;
  103.  
  104.  
  105. PROCEDURE UnOp (VAR r: INTEGER);
  106. BEGIN
  107.     REG.UnOp(R, r)
  108. END UnOp;
  109.  
  110.  
  111. PROCEDURE BinOp (VAR r1, r2: INTEGER);
  112. BEGIN
  113.     REG.BinOp(R, r1, r2)
  114. END BinOp;
  115.  
  116.  
  117. PROCEDURE PushAll (NumberOfParameters: INTEGER);
  118. BEGIN
  119.     REG.PushAll(R);
  120.     DEC(R.pushed, NumberOfParameters)
  121. END PushAll;
  122.  
  123.  
  124. PROCEDURE push (r: INTEGER);
  125. BEGIN
  126.     Emit(opPUSH, r, 0)
  127. END push;
  128.  
  129.  
  130. PROCEDURE pop (r: INTEGER);
  131. BEGIN
  132.     Emit(opPOP, r, 0)
  133. END pop;
  134.  
  135.  
  136. PROCEDURE mov (r1, r2: INTEGER);
  137. BEGIN
  138.     Emit(opMOV, r1, r2)
  139. END mov;
  140.  
  141.  
  142. PROCEDURE xchg (r1, r2: INTEGER);
  143. BEGIN
  144.     Emit(opXCHG, r1, r2)
  145. END xchg;
  146.  
  147.  
  148. PROCEDURE addrc (r, c: INTEGER);
  149. BEGIN
  150.     Emit(opADDC, r, c)
  151. END addrc;
  152.  
  153.  
  154. PROCEDURE subrc (r, c: INTEGER);
  155. BEGIN
  156.     Emit(opSUBC, r, c)
  157. END subrc;
  158.  
  159.  
  160. PROCEDURE movrc (r, c: INTEGER);
  161. BEGIN
  162.     Emit(opMOVC, r, c)
  163. END movrc;
  164.  
  165.  
  166. PROCEDURE pushc (c: INTEGER);
  167. BEGIN
  168.     Emit(opPUSHC, c, 0)
  169. END pushc;
  170.  
  171.  
  172. PROCEDURE add (r1, r2: INTEGER);
  173. BEGIN
  174.     Emit(opADD, r1, r2)
  175. END add;
  176.  
  177.  
  178. PROCEDURE sub (r1, r2: INTEGER);
  179. BEGIN
  180.     Emit(opSUB, r1, r2)
  181. END sub;
  182.  
  183.  
  184. PROCEDURE ldr64 (r1, r2: INTEGER);
  185. BEGIN
  186.     Emit(opLDD, r2 * 256 + r1, 0)
  187. END ldr64;
  188.  
  189.  
  190. PROCEDURE ldr32 (r1, r2: INTEGER);
  191. BEGIN
  192.     Emit(opLDW, r2 * 256 + r1, 0)
  193. END ldr32;
  194.  
  195.  
  196. PROCEDURE ldr16 (r1, r2: INTEGER);
  197. BEGIN
  198.     Emit(opLDH, r2 * 256 + r1, 0)
  199. END ldr16;
  200.  
  201.  
  202. PROCEDURE ldr8 (r1, r2: INTEGER);
  203. BEGIN
  204.     Emit(opLDB, r2 * 256 + r1, 0)
  205. END ldr8;
  206.  
  207.  
  208. PROCEDURE str64 (r1, r2: INTEGER);
  209. BEGIN
  210.     Emit(opSTD, r1 * 256 + r2, 0)
  211. END str64;
  212.  
  213.  
  214. PROCEDURE str32 (r1, r2: INTEGER);
  215. BEGIN
  216.     Emit(opSTW, r1 * 256 + r2, 0)
  217. END str32;
  218.  
  219.  
  220. PROCEDURE str16 (r1, r2: INTEGER);
  221. BEGIN
  222.     Emit(opSTH, r1 * 256 + r2, 0)
  223. END str16;
  224.  
  225.  
  226. PROCEDURE str8 (r1, r2: INTEGER);
  227. BEGIN
  228.     Emit(opSTB, r1 * 256 + r2, 0)
  229. END str8;
  230.  
  231.  
  232. PROCEDURE GlobalAdr (r, offset: INTEGER);
  233. BEGIN
  234.     Emit(opLEA, r + 256 * LGlobal, offset)
  235. END GlobalAdr;
  236.  
  237.  
  238. PROCEDURE StrAdr (r, offset: INTEGER);
  239. BEGIN
  240.     Emit(opLEA, r + 256 * LStrings, offset)
  241. END StrAdr;
  242.  
  243.  
  244. PROCEDURE ProcAdr (r, label: INTEGER);
  245. BEGIN
  246.     Emit(opLLA, r, label)
  247. END ProcAdr;
  248.  
  249.  
  250. PROCEDURE jnz (r, label: INTEGER);
  251. BEGIN
  252.     Emit(opCMPC, r, 0);
  253.     Emit(opJNE, label, 0)
  254. END jnz;
  255.  
  256.  
  257. PROCEDURE CallRTL (proc, par: INTEGER);
  258. BEGIN
  259.     Emit(opCALL, IL.codes.rtl[proc], 0);
  260.     addrc(SP, par * szWord)
  261. END CallRTL;
  262.  
  263.  
  264. PROCEDURE jcc (cc: INTEGER): INTEGER;
  265. BEGIN
  266.     CASE cc OF
  267.     |IL.opEQ, IL.opEQC: cc := opJEQ
  268.     |IL.opNE, IL.opNEC: cc := opJNE
  269.     |IL.opLT, IL.opLTC: cc := opJLT
  270.     |IL.opLE, IL.opLEC: cc := opJLE
  271.     |IL.opGT, IL.opGTC: cc := opJGT
  272.     |IL.opGE, IL.opGEC: cc := opJGE
  273.     END
  274.     RETURN cc
  275. END jcc;
  276.  
  277.  
  278. PROCEDURE shift1 (op, param: INTEGER);
  279. VAR
  280.     r1, r2: INTEGER;
  281.  
  282. BEGIN
  283.     r2 := GetAnyReg();
  284.     Emit(opMOVC, r2, param);
  285.     BinOp(r1, r2);
  286.     Emit(op, r2, r1);
  287.     mov(r1, r2);
  288.     drop
  289. END shift1;
  290.  
  291.  
  292. PROCEDURE shift (op: INTEGER);
  293. VAR
  294.     r1, r2: INTEGER;
  295.  
  296. BEGIN
  297.     BinOp(r1, r2);
  298.     Emit(op, r1, r2);
  299.     drop
  300. END shift;
  301.  
  302.  
  303. PROCEDURE translate (szWord: INTEGER);
  304. VAR
  305.     cmd, next: IL.COMMAND;
  306.  
  307.     opcode, param1, param2, r1, r2, r3,
  308.     a, b, label, opLD, opST, opSTC: INTEGER;
  309.  
  310. BEGIN
  311.     IF szWord = 8 THEN
  312.         opLD  := opLDD;
  313.         opST  := opSTD;
  314.         opSTC := opSTDC
  315.     ELSE
  316.         opLD  := opLDW;
  317.         opST  := opSTW;
  318.         opSTC := opSTWC
  319.     END;
  320.  
  321.     cmd := IL.codes.commands.first(IL.COMMAND);
  322.  
  323.     WHILE cmd # NIL DO
  324.  
  325.         param1 := cmd.param1;
  326.         param2 := cmd.param2;
  327.         opcode := cmd.opcode;
  328.  
  329.         CASE opcode OF
  330.  
  331.         |IL.opJMP:
  332.             Emit(opJMP, param1, 0)
  333.  
  334.         |IL.opLABEL:
  335.             Emit(opLABEL, param1, 0)
  336.  
  337.         |IL.opCALL:
  338.             Emit(opCALL, param1, 0)
  339.  
  340.         |IL.opCALLP:
  341.             UnOp(r1);
  342.             Emit(opCALLI, r1, 0);
  343.             drop;
  344.             ASSERT(R.top = -1)
  345.  
  346.         |IL.opPUSHC:
  347.             pushc(param2)
  348.  
  349.         |IL.opCLEANUP:
  350.             IF param2 # 0 THEN
  351.                 addrc(SP, param2 * szWord)
  352.             END
  353.  
  354.         |IL.opNOP, IL.opAND, IL.opOR:
  355.  
  356.         |IL.opSADR:
  357.             StrAdr(GetAnyReg(), param2)
  358.  
  359.         |IL.opGADR:
  360.             GlobalAdr(GetAnyReg(), param2)
  361.  
  362.         |IL.opLADR:
  363.             param2 := param2 * szWord;
  364.             next := cmd.next(IL.COMMAND);
  365.             IF ((next.opcode = IL.opSAVE) OR (next.opcode = IL.opSAVEF)) & (szWord = 8) OR (next.opcode = IL.opSAVE64) THEN
  366.                 UnOp(r1);
  367.                 Emit(opSTD, BP * 256 + r1, param2);
  368.                 drop;
  369.                 cmd := next
  370.             ELSIF ((next.opcode = IL.opSAVE) OR (next.opcode = IL.opSAVEF)) & (szWord = 4) OR (next.opcode = IL.opSAVE32) THEN
  371.                 UnOp(r1);
  372.                 Emit(opSTW, BP * 256 + r1, param2);
  373.                 drop;
  374.                 cmd := next
  375.             ELSIF next.opcode = IL.opSAVE16 THEN
  376.                 UnOp(r1);
  377.                 Emit(opSTH, BP * 256 + r1, param2);
  378.                 drop;
  379.                 cmd := next
  380.             ELSIF next.opcode = IL.opSAVE8 THEN
  381.                 UnOp(r1);
  382.                 Emit(opSTB, BP * 256 + r1, param2);
  383.                 drop;
  384.                 cmd := next
  385.             ELSE
  386.                 Emit(opADDRC, BP * 256 + GetAnyReg(), param2)
  387.             END
  388.  
  389.         |IL.opPARAM:
  390.             IF param2 = 1 THEN
  391.                 UnOp(r1);
  392.                 push(r1);
  393.                 drop
  394.             ELSE
  395.                 ASSERT(R.top + 1 <= param2);
  396.                 PushAll(param2)
  397.             END
  398.  
  399.         |IL.opONERR:
  400.             pushc(param2);
  401.             Emit(opJMP, param1, 0)
  402.  
  403.         |IL.opPRECALL:
  404.             PushAll(0)
  405.  
  406.         |IL.opRES, IL.opRESF:
  407.             ASSERT(R.top = -1);
  408.             GetAcc
  409.  
  410.         |IL.opENTER:
  411.             ASSERT(R.top = -1);
  412.             Emit(opLABEL, param1, 0);
  413.             Emit(opENTER, param2, 0)
  414.  
  415.         |IL.opLEAVE, IL.opLEAVER, IL.opLEAVEF:
  416.             IF opcode # IL.opLEAVE THEN
  417.                 UnOp(r1);
  418.                 IF r1 # ACC THEN
  419.                     mov(ACC, r1)
  420.                 END;
  421.                 drop
  422.             END;
  423.  
  424.             ASSERT(R.top = -1);
  425.  
  426.             IF param1 > 0 THEN
  427.                 mov(SP, BP)
  428.             END;
  429.  
  430.             pop(BP);
  431.  
  432.             Emit(opRET, 0, 0)
  433.  
  434.         |IL.opLEAVEC:
  435.             Emit(opRET, 0, 0)
  436.  
  437.         |IL.opCONST:
  438.             next := cmd.next(IL.COMMAND);
  439.             IF (next.opcode = IL.opPARAM) & (next.param2 = 1) THEN
  440.                 pushc(param2);
  441.                 cmd := next
  442.             ELSE
  443.                 movrc(GetAnyReg(), param2)
  444.             END
  445.  
  446.         |IL.opDROP:
  447.             UnOp(r1);
  448.             drop
  449.  
  450.         |IL.opSAVEC:
  451.             UnOp(r1);
  452.             Emit(opSTC, r1, param2);
  453.             drop
  454.  
  455.         |IL.opSAVE8C:
  456.             UnOp(r1);
  457.             Emit(opSTBC, r1, param2 MOD 256);
  458.             drop
  459.  
  460.         |IL.opSAVE16C:
  461.             UnOp(r1);
  462.             Emit(opSTHC, r1, param2 MOD 65536);
  463.             drop
  464.  
  465.         |IL.opSAVE, IL.opSAVEF:
  466.             BinOp(r2, r1);
  467.             str(r1, r2);
  468.             drop;
  469.             drop
  470.  
  471.         |IL.opSAVE32:
  472.             BinOp(r2, r1);
  473.             str32(r1, r2);
  474.             drop;
  475.             drop
  476.  
  477.         |IL.opSAVE64:
  478.             BinOp(r2, r1);
  479.             str64(r1, r2);
  480.             drop;
  481.             drop
  482.  
  483.         |IL.opSAVEFI:
  484.             BinOp(r2, r1);
  485.             str(r2, r1);
  486.             drop;
  487.             drop
  488.  
  489.         |IL.opSAVE8:
  490.             BinOp(r2, r1);
  491.             str8(r1, r2);
  492.             drop;
  493.             drop
  494.  
  495.         |IL.opSAVE16:
  496.             BinOp(r2, r1);
  497.             str16(r1, r2);
  498.             drop;
  499.             drop
  500.  
  501.         |IL.opGLOAD32:
  502.             r1 := GetAnyReg();
  503.             GlobalAdr(r1, param2);
  504.             ldr32(r1, r1)
  505.  
  506.         |IL.opGLOAD64:
  507.             r1 := GetAnyReg();
  508.             GlobalAdr(r1, param2);
  509.             ldr64(r1, r1)
  510.  
  511.         |IL.opVADR:
  512.             Emit(opLD, BP * 256 + GetAnyReg(), param2 * szWord)
  513.  
  514.         |IL.opLLOAD32:
  515.             Emit(opLDW, BP * 256 + GetAnyReg(), param2 * szWord)
  516.  
  517.         |IL.opLLOAD64:
  518.             Emit(opLDD, BP * 256 + GetAnyReg(), param2 * szWord)
  519.  
  520.         |IL.opVLOAD32:
  521.             r1 := GetAnyReg();
  522.             Emit(opLD, BP * 256 + r1, param2 * szWord);
  523.             ldr32(r1, r1)
  524.  
  525.         |IL.opVLOAD64:
  526.             r1 := GetAnyReg();
  527.             Emit(opLDD, BP * 256 + r1, param2 * szWord);
  528.             ldr64(r1, r1)
  529.  
  530.         |IL.opGLOAD16:
  531.             r1 := GetAnyReg();
  532.             GlobalAdr(r1, param2);
  533.             ldr16(r1, r1)
  534.  
  535.         |IL.opLLOAD16:
  536.             Emit(opLDH, BP * 256 + GetAnyReg(), param2 * szWord)
  537.  
  538.         |IL.opVLOAD16:
  539.             r1 := GetAnyReg();
  540.             Emit(opLD, BP * 256 + r1, param2 * szWord);
  541.             ldr16(r1, r1)
  542.  
  543.         |IL.opGLOAD8:
  544.             r1 := GetAnyReg();
  545.             GlobalAdr(r1, param2);
  546.             ldr8(r1, r1)
  547.  
  548.         |IL.opLLOAD8:
  549.             Emit(opLDB, BP * 256 + GetAnyReg(), param2 * szWord)
  550.  
  551.         |IL.opVLOAD8:
  552.             r1 := GetAnyReg();
  553.             Emit(opLD, BP * 256 + r1, param2 * szWord);
  554.             ldr8(r1, r1)
  555.  
  556.         |IL.opLOAD8:
  557.             UnOp(r1);
  558.             ldr8(r1, r1)
  559.  
  560.         |IL.opLOAD16:
  561.             UnOp(r1);
  562.             ldr16(r1, r1)
  563.  
  564.         |IL.opLOAD32:
  565.             UnOp(r1);
  566.             ldr32(r1, r1)
  567.  
  568.         |IL.opLOAD64:
  569.             UnOp(r1);
  570.             ldr64(r1, r1)
  571.  
  572.         |IL.opLOADF:
  573.             UnOp(r1);
  574.             ldr(r1, r1)
  575.  
  576.         |IL.opUMINUS:
  577.             UnOp(r1);
  578.             Emit(opNEG, r1, 0)
  579.  
  580.         |IL.opADD:
  581.             BinOp(r1, r2);
  582.             add(r1, r2);
  583.             drop
  584.  
  585.         |IL.opSUB:
  586.             BinOp(r1, r2);
  587.             sub(r1, r2);
  588.             drop
  589.  
  590.         |IL.opADDC:
  591.             UnOp(r1);
  592.             next := cmd.next(IL.COMMAND);
  593.             CASE next.opcode OF
  594.             |IL.opLOADF:
  595.                 Emit(opLD, r1 * 256 + r1, param2);
  596.                 cmd := next
  597.             |IL.opLOAD64:
  598.                 Emit(opLDD, r1 * 256 + r1, param2);
  599.                 cmd := next
  600.             |IL.opLOAD32:
  601.                 Emit(opLDW, r1 * 256 + r1, param2);
  602.                 cmd := next
  603.             |IL.opLOAD16:
  604.                 Emit(opLDH, r1 * 256 + r1, param2);
  605.                 cmd := next
  606.             |IL.opLOAD8:
  607.                 Emit(opLDB, r1 * 256 + r1, param2);
  608.                 cmd := next
  609.             ELSE
  610.                 addrc(r1, param2)
  611.             END
  612.  
  613.         |IL.opSUBR:
  614.             UnOp(r1);
  615.             subrc(r1, param2)
  616.  
  617.         |IL.opSUBL:
  618.             UnOp(r1);
  619.             subrc(r1, param2);
  620.             Emit(opNEG, r1, 0)
  621.  
  622.         |IL.opMULC:
  623.             UnOp(r1);
  624.             Emit(opMULC, r1, param2)
  625.  
  626.         |IL.opMUL:
  627.             BinOp(r1, r2);
  628.             Emit(opMUL, r1, r2);
  629.             drop
  630.  
  631.         |IL.opDIV:
  632.             BinOp(r1, r2);
  633.             Emit(opDIV, r1, r2);
  634.             drop
  635.  
  636.         |IL.opMOD:
  637.             BinOp(r1, r2);
  638.             Emit(opMOD, r1, r2);
  639.             drop
  640.  
  641.         |IL.opDIVR:
  642.             UnOp(r1);
  643.             Emit(opDIVC, r1, param2)
  644.  
  645.         |IL.opMODR:
  646.             UnOp(r1);
  647.             Emit(opMODC, r1, param2)
  648.  
  649.         |IL.opDIVL:
  650.             UnOp(r1);
  651.             r2 := GetAnyReg();
  652.             movrc(r2, param2);
  653.             Emit(opDIV, r2, r1);
  654.             mov(r1, r2);
  655.             drop
  656.  
  657.         |IL.opMODL:
  658.             UnOp(r1);
  659.             r2 := GetAnyReg();
  660.             movrc(r2, param2);
  661.             Emit(opMOD, r2, r1);
  662.             mov(r1, r2);
  663.             drop
  664.  
  665.         |IL.opEQ .. IL.opGE, IL.opEQC .. IL.opGEC:
  666.             IF (IL.opEQ <= opcode) & (opcode <= IL.opGE) THEN
  667.                 BinOp(r1, r2);
  668.                 Emit(opCMP, r1, r2);
  669.                 drop
  670.             ELSE
  671.                 UnOp(r1);
  672.                 Emit(opCMPC, r1, param2)
  673.             END;
  674.             next := cmd.next(IL.COMMAND);
  675.             IF next.opcode = IL.opJZ THEN
  676.                 Emit(ORD(BITS(jcc(opcode)) / {0}), next.param1, 0);
  677.                 cmd := next;
  678.                 drop
  679.             ELSIF next.opcode = IL.opJNZ THEN
  680.                 Emit(jcc(opcode), next.param1, 0);
  681.                 cmd := next;
  682.                 drop
  683.             ELSE
  684.                 Emit(jcc(opcode) + 6, r1, 0)
  685.             END
  686.  
  687.         |IL.opJNZ1:
  688.             UnOp(r1);
  689.             jnz(r1, param1)
  690.  
  691.         |IL.opJG:
  692.             UnOp(r1);
  693.             Emit(opCMPC, r1, 0);
  694.             Emit(opJGT, param1, 0)
  695.  
  696.         |IL.opJNZ:
  697.             UnOp(r1);
  698.             jnz(r1, param1);
  699.             drop
  700.  
  701.         |IL.opJZ:
  702.             UnOp(r1);
  703.             Emit(opCMPC, r1, 0);
  704.             Emit(opJEQ, param1, 0);
  705.             drop
  706.  
  707.         |IL.opMULS:
  708.             BinOp(r1, r2);
  709.             Emit(opAND, r1, r2);
  710.             drop
  711.  
  712.         |IL.opMULSC:
  713.             UnOp(r1);
  714.             Emit(opANDC, r1, param2)
  715.  
  716.         |IL.opDIVS:
  717.             BinOp(r1, r2);
  718.             Emit(opXOR, r1, r2);
  719.             drop
  720.  
  721.         |IL.opDIVSC:
  722.             UnOp(r1);
  723.             Emit(opXORC, r1, param2)
  724.  
  725.         |IL.opADDS:
  726.             BinOp(r1, r2);
  727.             Emit(opOR, r1, r2);
  728.             drop
  729.  
  730.         |IL.opSUBS:
  731.             BinOp(r1, r2);
  732.             Emit(opNOT, r2, 0);
  733.             Emit(opAND, r1, r2);
  734.             drop
  735.  
  736.         |IL.opADDSC:
  737.             UnOp(r1);
  738.             Emit(opORC, r1, param2)
  739.  
  740.         |IL.opSUBSL:
  741.             UnOp(r1);
  742.             Emit(opNOT, r1, 0);
  743.             Emit(opANDC, r1, param2)
  744.  
  745.         |IL.opSUBSR:
  746.             UnOp(r1);
  747.             Emit(opANDC, r1, ORD(-BITS(param2)))
  748.  
  749.         |IL.opUMINS:
  750.             UnOp(r1);
  751.             Emit(opNOT, r1, 0)
  752.  
  753.         |IL.opASR:
  754.             shift(opASR)
  755.  
  756.         |IL.opLSL:
  757.             shift(opLSL)
  758.  
  759.         |IL.opROR:
  760.             shift(opROR)
  761.  
  762.         |IL.opLSR:
  763.             shift(opLSR)
  764.  
  765.         |IL.opASR1:
  766.             shift1(opASR, param2)
  767.  
  768.         |IL.opLSL1:
  769.             shift1(opLSL, param2)
  770.  
  771.         |IL.opROR1:
  772.             shift1(opROR, param2)
  773.  
  774.         |IL.opLSR1:
  775.             shift1(opLSR, param2)
  776.  
  777.         |IL.opASR2:
  778.             UnOp(r1);
  779.             Emit(opASRC, r1, param2 MOD (szWord * 8))
  780.  
  781.         |IL.opLSL2:
  782.             UnOp(r1);
  783.             Emit(opLSLC, r1, param2 MOD (szWord * 8))
  784.  
  785.         |IL.opROR2:
  786.             UnOp(r1);
  787.             Emit(opRORC, r1, param2 MOD (szWord * 8))
  788.  
  789.         |IL.opLSR2:
  790.             UnOp(r1);
  791.             Emit(opLSRC, r1, param2 MOD (szWord * 8))
  792.  
  793.         |IL.opABS:
  794.             UnOp(r1);
  795.             Emit(opCMPC, r1, 0);
  796.             label := IL.NewLabel();
  797.             Emit(opJGE, label, 0);
  798.             Emit(opNEG, r1, 0);
  799.             Emit(opLABEL, label, 0)
  800.  
  801.         |IL.opLEN:
  802.             UnOp(r1);
  803.             drop;
  804.             EXCL(R.regs, r1);
  805.  
  806.             WHILE param2 > 0 DO
  807.                 UnOp(r2);
  808.                 drop;
  809.                 DEC(param2)
  810.             END;
  811.  
  812.             INCL(R.regs, r1);
  813.             ASSERT(REG.GetReg(R, r1))
  814.  
  815.         |IL.opSWITCH:
  816.             UnOp(r1);
  817.             IF param2 = 0 THEN
  818.                 r2 := ACC
  819.             ELSE
  820.                 r2 := R1
  821.             END;
  822.             IF r1 # r2 THEN
  823.                 ASSERT(REG.GetReg(R, r2));
  824.                 ASSERT(REG.Exchange(R, r1, r2));
  825.                 drop
  826.             END;
  827.             drop
  828.  
  829.         |IL.opENDSW:
  830.  
  831.         |IL.opCASEL:
  832.             Emit(opCMPC, ACC, param1);
  833.             Emit(opJLT, param2, 0)
  834.  
  835.         |IL.opCASER:
  836.             Emit(opCMPC, ACC, param1);
  837.             Emit(opJGT, param2, 0)
  838.  
  839.         |IL.opCASELR:
  840.             Emit(opCMPC, ACC, param1);
  841.             IF param2 = cmd.param3 THEN
  842.                 Emit(opJNE, param2, 0)
  843.             ELSE
  844.                 Emit(opJLT, param2, 0);
  845.                 Emit(opJGT, cmd.param3, 0)
  846.             END
  847.  
  848.         |IL.opSBOOL:
  849.             BinOp(r2, r1);
  850.             Emit(opCMPC, r2, 0);
  851.             Emit(opSNE, r2, 0);
  852.             str8(r1, r2);
  853.             drop;
  854.             drop
  855.  
  856.         |IL.opSBOOLC:
  857.             UnOp(r1);
  858.             Emit(opSTBC, r1, ORD(param2 # 0));
  859.             drop
  860.  
  861.         |IL.opINCC:
  862.             UnOp(r1);
  863.             r2 := GetAnyReg();
  864.             ldr(r2, r1);
  865.             addrc(r2, param2);
  866.             str(r1, r2);
  867.             drop;
  868.             drop
  869.  
  870.         |IL.opINCCB, IL.opDECCB:
  871.             IF opcode = IL.opDECCB THEN
  872.                 param2 := -param2
  873.             END;
  874.             UnOp(r1);
  875.             r2 := GetAnyReg();
  876.             ldr8(r2, r1);
  877.             addrc(r2, param2);
  878.             str8(r1, r2);
  879.             drop;
  880.             drop
  881.  
  882.         |IL.opINCB, IL.opDECB:
  883.             BinOp(r2, r1);
  884.             r3 := GetAnyReg();
  885.             ldr8(r3, r1);
  886.             IF opcode = IL.opINCB THEN
  887.                 add(r3, r2)
  888.             ELSE
  889.                 sub(r3, r2)
  890.             END;
  891.             str8(r1, r3);
  892.             drop;
  893.             drop;
  894.             drop
  895.  
  896.         |IL.opINC, IL.opDEC:
  897.             BinOp(r2, r1);
  898.             r3 := GetAnyReg();
  899.             ldr(r3, r1);
  900.             IF opcode = IL.opINC THEN
  901.                 add(r3, r2)
  902.             ELSE
  903.                 sub(r3, r2)
  904.             END;
  905.             str(r1, r3);
  906.             drop;
  907.             drop;
  908.             drop
  909.  
  910.         |IL.opINCL, IL.opEXCL:
  911.             BinOp(r2, r1);
  912.             Emit(opBIT, r2, r2);
  913.             r3 := GetAnyReg();
  914.             ldr(r3, r1);
  915.             IF opcode = IL.opINCL THEN
  916.                 Emit(opOR, r3, r2)
  917.             ELSE
  918.                 Emit(opNOT, r2, 0);
  919.                 Emit(opAND, r3, r2)
  920.             END;
  921.             str(r1, r3);
  922.             drop;
  923.             drop;
  924.             drop
  925.  
  926.         |IL.opINCLC, IL.opEXCLC:
  927.             UnOp(r1);
  928.             r2 := GetAnyReg();
  929.             ldr(r2, r1);
  930.             IF opcode = IL.opINCLC THEN
  931.                 Emit(opORC, r2, ORD({param2}))
  932.             ELSE
  933.                 Emit(opANDC, r2, ORD(-{param2}))
  934.             END;
  935.             str(r1, r2);
  936.             drop;
  937.             drop
  938.  
  939.         |IL.opEQB, IL.opNEB:
  940.             BinOp(r1, r2);
  941.             Emit(opCMPC, r1, 0);
  942.             Emit(opSNE, r1, 0);
  943.             Emit(opCMPC, r2, 0);
  944.             Emit(opSNE, r2, 0);
  945.             Emit(opCMP, r1, r2);
  946.             IF opcode = IL.opEQB THEN
  947.                 Emit(opSEQ, r1, 0)
  948.             ELSE
  949.                 Emit(opSNE, r1, 0)
  950.             END;
  951.             drop
  952.  
  953.         |IL.opCHKIDX:
  954.             UnOp(r1);
  955.             Emit(opCMPC, r1, param2);
  956.             Emit(opJBT, param1, 0)
  957.  
  958.         |IL.opCHKIDX2:
  959.             BinOp(r1, r2);
  960.             IF param2 # -1 THEN
  961.                 Emit(opCMP, r2, r1);
  962.                 Emit(opJBT, param1, 0)
  963.             END;
  964.             INCL(R.regs, r1);
  965.             DEC(R.top);
  966.             R.stk[R.top] := r2
  967.  
  968.         |IL.opEQP, IL.opNEP:
  969.             ProcAdr(GetAnyReg(), param1);
  970.             BinOp(r1, r2);
  971.             Emit(opCMP, r1, r2);
  972.             IF opcode = IL.opEQP THEN
  973.                 Emit(opSEQ, r1, 0)
  974.             ELSE
  975.                 Emit(opSNE, r1, 0)
  976.             END;
  977.             drop
  978.  
  979.         |IL.opSAVEP:
  980.             UnOp(r1);
  981.             r2 := GetAnyReg();
  982.             ProcAdr(r2, param2);
  983.             str(r1, r2);
  984.             drop;
  985.             drop
  986.  
  987.         |IL.opPUSHP:
  988.             ProcAdr(GetAnyReg(), param2)
  989.  
  990.         |IL.opPUSHT:
  991.             UnOp(r1);
  992.             Emit(opLD, r1 * 256 + GetAnyReg(), -szWord)
  993.  
  994.         |IL.opGET, IL.opGETC:
  995.             IF opcode = IL.opGET THEN
  996.                 BinOp(r1, r2)
  997.             ELSIF opcode = IL.opGETC THEN
  998.                 UnOp(r2);
  999.                 r1 := GetAnyReg();
  1000.                 movrc(r1, param1)
  1001.             END;
  1002.             drop;
  1003.             drop;
  1004.  
  1005.             CASE param2 OF
  1006.             |1: ldr8(r1, r1);  str8(r2, r1)
  1007.             |2: ldr16(r1, r1); str16(r2, r1)
  1008.             |4: ldr32(r1, r1); str32(r2, r1)
  1009.             |8: ldr64(r1, r1); str64(r2, r1)
  1010.             END
  1011.  
  1012.         |IL.opNOT:
  1013.             UnOp(r1);
  1014.             Emit(opCMPC, r1, 0);
  1015.             Emit(opSEQ, r1, 0)
  1016.  
  1017.         |IL.opORD:
  1018.             UnOp(r1);
  1019.             Emit(opCMPC, r1, 0);
  1020.             Emit(opSNE, r1, 0)
  1021.  
  1022.         |IL.opMIN, IL.opMAX:
  1023.             BinOp(r1, r2);
  1024.             Emit(opCMP, r1, r2);
  1025.             label := IL.NewLabel();
  1026.             IF opcode = IL.opMIN THEN
  1027.                 Emit(opJLE, label, 0)
  1028.             ELSE
  1029.                 Emit(opJGE, label, 0)
  1030.             END;
  1031.             Emit(opMOV, r1, r2);
  1032.             Emit(opLABEL, label, 0);
  1033.             drop
  1034.  
  1035.         |IL.opMINC, IL.opMAXC:
  1036.             UnOp(r1);
  1037.             Emit(opCMPC, r1, param2);
  1038.             label := IL.NewLabel();
  1039.             IF opcode = IL.opMINC THEN
  1040.                 Emit(opJLE, label, 0)
  1041.             ELSE
  1042.                 Emit(opJGE, label, 0)
  1043.             END;
  1044.             Emit(opMOVC, r1, param2);
  1045.             Emit(opLABEL, label, 0)
  1046.  
  1047.         |IL.opIN:
  1048.             BinOp(r1, r2);
  1049.             Emit(opBIT, r1, r1);
  1050.             Emit(opAND, r1, r2);
  1051.             Emit(opCMPC, r1, 0);
  1052.             Emit(opSNE, r1, 0);
  1053.             drop
  1054.  
  1055.         |IL.opINL:
  1056.             UnOp(r1);
  1057.             Emit(opANDC, r1, ORD({param2}));
  1058.             Emit(opCMPC, r1, 0);
  1059.             Emit(opSNE, r1, 0)
  1060.  
  1061.         |IL.opINR:
  1062.             UnOp(r1);
  1063.             Emit(opBIT, r1, r1);
  1064.             Emit(opANDC, r1, param2);
  1065.             Emit(opCMPC, r1, 0);
  1066.             Emit(opSNE, r1, 0)
  1067.  
  1068.         |IL.opERR:
  1069.             CallRTL(IL._error, 4)
  1070.  
  1071.         |IL.opEQS .. IL.opGES:
  1072.             PushAll(4);
  1073.             pushc(opcode - IL.opEQS);
  1074.             CallRTL(IL._strcmp, 5);
  1075.             GetAcc
  1076.  
  1077.         |IL.opEQSW .. IL.opGESW:
  1078.             PushAll(4);
  1079.             pushc(opcode - IL.opEQSW);
  1080.             CallRTL(IL._strcmpw, 5);
  1081.             GetAcc
  1082.  
  1083.         |IL.opCOPY:
  1084.             PushAll(2);
  1085.             pushc(param2);
  1086.             CallRTL(IL._move, 3)
  1087.  
  1088.         |IL.opMOVE:
  1089.             PushAll(3);
  1090.             CallRTL(IL._move, 3)
  1091.  
  1092.         |IL.opCOPYA:
  1093.             PushAll(4);
  1094.             pushc(param2);
  1095.             CallRTL(IL._arrcpy, 5);
  1096.             GetAcc
  1097.  
  1098.         |IL.opCOPYS:
  1099.             PushAll(4);
  1100.             pushc(param2);
  1101.             CallRTL(IL._strcpy, 5)
  1102.  
  1103.         |IL.opROT:
  1104.             PushAll(0);
  1105.             mov(ACC, SP);
  1106.             push(ACC);
  1107.             pushc(param2);
  1108.             CallRTL(IL._rot, 2)
  1109.  
  1110.         |IL.opLENGTH:
  1111.             PushAll(2);
  1112.             CallRTL(IL._length, 2);
  1113.             GetAcc
  1114.  
  1115.         |IL.opLENGTHW:
  1116.             PushAll(2);
  1117.             CallRTL(IL._lengthw, 2);
  1118.             GetAcc
  1119.  
  1120.         |IL.opSAVES:
  1121.             UnOp(r2);
  1122.             REG.PushAll_1(R);
  1123.             r1 := GetAnyReg();
  1124.             StrAdr(r1, param2);
  1125.             push(r1);
  1126.             drop;
  1127.             push(r2);
  1128.             drop;
  1129.             pushc(param1);
  1130.             CallRTL(IL._move, 3)
  1131.  
  1132.         |IL.opRSET:
  1133.             PushAll(2);
  1134.             CallRTL(IL._set, 2);
  1135.             GetAcc
  1136.  
  1137.         |IL.opRSETR:
  1138.             PushAll(1);
  1139.             pushc(param2);
  1140.             CallRTL(IL._set, 2);
  1141.             GetAcc
  1142.  
  1143.         |IL.opRSETL:
  1144.             UnOp(r1);
  1145.             REG.PushAll_1(R);
  1146.             pushc(param2);
  1147.             push(r1);
  1148.             drop;
  1149.             CallRTL(IL._set, 2);
  1150.             GetAcc
  1151.  
  1152.         |IL.opRSET1:
  1153.             PushAll(1);
  1154.             CallRTL(IL._set1, 1);
  1155.             GetAcc
  1156.  
  1157.         |IL.opNEW:
  1158.             PushAll(1);
  1159.             INC(param2, szWord);
  1160.             ASSERT(UTILS.Align(param2, szWord));
  1161.             pushc(param2);
  1162.             pushc(param1);
  1163.             CallRTL(IL._new, 3)
  1164.  
  1165.         |IL.opTYPEGP:
  1166.             UnOp(r1);
  1167.             PushAll(0);
  1168.             push(r1);
  1169.             pushc(param2);
  1170.             CallRTL(IL._guard, 2);
  1171.             GetAcc
  1172.  
  1173.         |IL.opIS:
  1174.             PushAll(1);
  1175.             pushc(param2);
  1176.             CallRTL(IL._is, 2);
  1177.             GetAcc
  1178.  
  1179.         |IL.opISREC:
  1180.             PushAll(2);
  1181.             pushc(param2);
  1182.             CallRTL(IL._guardrec, 3);
  1183.             GetAcc
  1184.  
  1185.         |IL.opTYPEGR:
  1186.             PushAll(1);
  1187.             pushc(param2);
  1188.             CallRTL(IL._guardrec, 2);
  1189.             GetAcc
  1190.  
  1191.         |IL.opTYPEGD:
  1192.             UnOp(r1);
  1193.             PushAll(0);
  1194.             subrc(r1, szWord);
  1195.             ldr(r1, r1);
  1196.             push(r1);
  1197.             pushc(param2);
  1198.             CallRTL(IL._guardrec, 2);
  1199.             GetAcc
  1200.  
  1201.         |IL.opCASET:
  1202.             push(R1);
  1203.             push(R1);
  1204.             pushc(param2);
  1205.             CallRTL(IL._guardrec, 2);
  1206.             pop(R1);
  1207.             jnz(ACC, param1)
  1208.  
  1209.         |IL.opCONSTF:
  1210.             IF szWord = 8 THEN
  1211.                 movrc(GetAnyReg(), UTILS.splitf(cmd.float, a, b))
  1212.             ELSE (* szWord = 4 *)
  1213.                 movrc(GetAnyReg(), UTILS.d2s(cmd.float))
  1214.             END
  1215.  
  1216.         |IL.opMULF:
  1217.             PushAll(2);
  1218.             CallRTL(IL._fmul, 2);
  1219.             GetAcc
  1220.  
  1221.         |IL.opDIVF:
  1222.             PushAll(2);
  1223.             CallRTL(IL._fdiv, 2);
  1224.             GetAcc
  1225.  
  1226.         |IL.opDIVFI:
  1227.             PushAll(2);
  1228.             CallRTL(IL._fdivi, 2);
  1229.             GetAcc
  1230.  
  1231.         |IL.opADDF:
  1232.             PushAll(2);
  1233.             CallRTL(IL._fadd, 2);
  1234.             GetAcc
  1235.  
  1236.         |IL.opSUBFI:
  1237.             PushAll(2);
  1238.             CallRTL(IL._fsubi, 2);
  1239.             GetAcc
  1240.  
  1241.         |IL.opSUBF:
  1242.             PushAll(2);
  1243.             CallRTL(IL._fsub, 2);
  1244.             GetAcc
  1245.  
  1246.         |IL.opEQF..IL.opGEF:
  1247.             PushAll(2);
  1248.             pushc(opcode - IL.opEQF);
  1249.             CallRTL(IL._fcmp, 3);
  1250.             GetAcc
  1251.  
  1252.         |IL.opFLOOR:
  1253.             PushAll(1);
  1254.             CallRTL(IL._floor, 1);
  1255.             GetAcc
  1256.  
  1257.         |IL.opFLT:
  1258.             PushAll(1);
  1259.             CallRTL(IL._flt, 1);
  1260.             GetAcc
  1261.  
  1262.         |IL.opUMINF:
  1263.             UnOp(r1);
  1264.             Emit(opRORC, r1, -1);
  1265.             Emit(opXORC, r1,  1);
  1266.             Emit(opRORC, r1,  1)
  1267.  
  1268.         |IL.opFABS:
  1269.             UnOp(r1);
  1270.             Emit(opLSLC, r1, 1);
  1271.             Emit(opLSRC, r1, 1)
  1272.  
  1273.         |IL.opINF:
  1274.             r1 := GetAnyReg();
  1275.             Emit(opMOVC, r1, 1);
  1276.             Emit(opRORC, r1, 1);
  1277.             Emit(opASRC, r1, 7 + 3 * ORD(szWord = 8));
  1278.             Emit(opLSRC, r1, 1)
  1279.  
  1280.         |IL.opPUSHF:
  1281.             UnOp(r1);
  1282.             push(r1);
  1283.             drop
  1284.  
  1285.         |IL.opPACK:
  1286.             PushAll(2);
  1287.             CallRTL(IL._pack, 2)
  1288.  
  1289.         |IL.opPACKC:
  1290.             PushAll(1);
  1291.             pushc(param2);
  1292.             CallRTL(IL._pack, 2)
  1293.  
  1294.         |IL.opUNPK:
  1295.             PushAll(2);
  1296.             CallRTL(IL._unpk, 2)
  1297.  
  1298.         |IL.opCODE:
  1299.             OutInt(param2)
  1300.  
  1301.         |IL.opLADR_SAVE:
  1302.             UnOp(r1);
  1303.             Emit(opST, BP * 256 + r1, param2 * szWord);
  1304.             drop
  1305.  
  1306.         |IL.opLADR_INCC:
  1307.             r1 := GetAnyReg();
  1308.             Emit(opLD, BP * 256 + r1, param1 * szWord);
  1309.             Emit(opADDC, r1, param2);
  1310.             Emit(opST, BP * 256 + r1, param1 * szWord);
  1311.             drop
  1312.  
  1313.         END;
  1314.  
  1315.         cmd := cmd.next(IL.COMMAND)
  1316.     END;
  1317.  
  1318.     ASSERT(R.pushed = 0);
  1319.     ASSERT(R.top = -1)
  1320. END translate;
  1321.  
  1322.  
  1323. PROCEDURE prolog;
  1324. BEGIN
  1325.     Emit(opLEA, SP + LStack * 256, 0);
  1326.     Emit(opLEA, ACC + LTypes * 256, 0);
  1327.     push(ACC);
  1328.     Emit(opLEA, ACC + LHeap * 256, 0);
  1329.     push(ACC);
  1330.     pushc(CHL.Length(IL.codes.types));
  1331.     CallRTL(IL._init, 3)
  1332. END prolog;
  1333.  
  1334.  
  1335. PROCEDURE epilog (ram, szWord: INTEGER);
  1336. VAR
  1337.     tcount, dcount, i, offTypes, offStrings,
  1338.     szData, szGlobal, szHeapStack: INTEGER;
  1339.  
  1340. BEGIN
  1341.     Emit(opSTOP, 0, 0);
  1342.  
  1343.     offTypes := count;
  1344.  
  1345.     tcount := CHL.Length(IL.codes.types);
  1346.     FOR i := 0 TO tcount - 1 DO
  1347.         OutInt(CHL.GetInt(IL.codes.types, i))
  1348.     END;
  1349.  
  1350.     offStrings := count;
  1351.     dcount := CHL.Length(IL.codes.data);
  1352.     FOR i := 0 TO dcount - 1 DO
  1353.         OutByte(CHL.GetByte(IL.codes.data, i))
  1354.     END;
  1355.  
  1356.     IF dcount MOD szWord # 0 THEN
  1357.         i := szWord - dcount MOD szWord;
  1358.         WHILE i > 0 DO
  1359.             OutByte(0);
  1360.             DEC(i)
  1361.         END
  1362.     END;
  1363.  
  1364.     szData := count - offTypes;
  1365.     szGlobal := (IL.codes.bss DIV szWord + 1) * szWord;
  1366.     szHeapStack := ram - szData - szGlobal;
  1367.  
  1368.     OutInt(offTypes);
  1369.     OutInt(offStrings);
  1370.     OutInt(szGlobal DIV szWord);
  1371.     OutInt(szHeapStack DIV szWord);
  1372.     FOR i := 1 TO 8 DO
  1373.         OutInt(0)
  1374.     END
  1375. END epilog;
  1376.  
  1377.  
  1378. PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS);
  1379. CONST
  1380.     minRAM = 32*1024;
  1381.     maxRAM = 256*1024;
  1382.  
  1383. VAR
  1384.     szData, szRAM: INTEGER;
  1385.  
  1386. BEGIN
  1387.     szWord := TARGETS.WordSize;
  1388.     IF szWord = 8 THEN
  1389.         ldr := ldr64;
  1390.         str := str64
  1391.     ELSE
  1392.         ldr := ldr32;
  1393.         str := str32
  1394.     END;
  1395.     szData := (CHL.Length(IL.codes.types) + CHL.Length(IL.codes.data) DIV szWord + IL.codes.bss DIV szWord + 2) * szWord;
  1396.     szRAM := MIN(MAX(options.ram, minRAM), maxRAM) * 1024;
  1397.  
  1398.     IF szRAM - szData < 1024*1024 THEN
  1399.         ERRORS.Error(208)
  1400.     END;
  1401.  
  1402.     count := 0;
  1403.     WR.Create(outname);
  1404.  
  1405.     REG.Init(R, push, pop, mov, xchg, GPRs);
  1406.  
  1407.     prolog;
  1408.     translate(szWord);
  1409.     epilog(szRAM, szWord);
  1410.  
  1411.     WR.Close
  1412. END CodeGen;
  1413.  
  1414.  
  1415. END RVMxI.