Subversion Repositories Kolibri OS

Rev

Rev 9177 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. (*
  2.     BSD 2-Clause License
  3.  
  4.     Copyright (c) 2020-2021, 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.opCHR:
  794.             UnOp(r1);
  795.             Emit(opANDC, r1, 255)
  796.  
  797.         |IL.opWCHR:
  798.             UnOp(r1);
  799.             Emit(opANDC, r1, 65535)
  800.  
  801.         |IL.opABS:
  802.             UnOp(r1);
  803.             Emit(opCMPC, r1, 0);
  804.             label := IL.NewLabel();
  805.             Emit(opJGE, label, 0);
  806.             Emit(opNEG, r1, 0);
  807.             Emit(opLABEL, label, 0)
  808.  
  809.         |IL.opLEN:
  810.             UnOp(r1);
  811.             drop;
  812.             EXCL(R.regs, r1);
  813.  
  814.             WHILE param2 > 0 DO
  815.                 UnOp(r2);
  816.                 drop;
  817.                 DEC(param2)
  818.             END;
  819.  
  820.             INCL(R.regs, r1);
  821.             ASSERT(REG.GetReg(R, r1))
  822.  
  823.         |IL.opSWITCH:
  824.             UnOp(r1);
  825.             IF param2 = 0 THEN
  826.                 r2 := ACC
  827.             ELSE
  828.                 r2 := R1
  829.             END;
  830.             IF r1 # r2 THEN
  831.                 ASSERT(REG.GetReg(R, r2));
  832.                 ASSERT(REG.Exchange(R, r1, r2));
  833.                 drop
  834.             END;
  835.             drop
  836.  
  837.         |IL.opENDSW:
  838.  
  839.         |IL.opCASEL:
  840.             Emit(opCMPC, ACC, param1);
  841.             Emit(opJLT, param2, 0)
  842.  
  843.         |IL.opCASER:
  844.             Emit(opCMPC, ACC, param1);
  845.             Emit(opJGT, param2, 0)
  846.  
  847.         |IL.opCASELR:
  848.             Emit(opCMPC, ACC, param1);
  849.             IF param2 = cmd.param3 THEN
  850.                 Emit(opJNE, param2, 0)
  851.             ELSE
  852.                 Emit(opJLT, param2, 0);
  853.                 Emit(opJGT, cmd.param3, 0)
  854.             END
  855.  
  856.         |IL.opSBOOL:
  857.             BinOp(r2, r1);
  858.             Emit(opCMPC, r2, 0);
  859.             Emit(opSNE, r2, 0);
  860.             str8(r1, r2);
  861.             drop;
  862.             drop
  863.  
  864.         |IL.opSBOOLC:
  865.             UnOp(r1);
  866.             Emit(opSTBC, r1, ORD(param2 # 0));
  867.             drop
  868.  
  869.         |IL.opINCC:
  870.             UnOp(r1);
  871.             r2 := GetAnyReg();
  872.             ldr(r2, r1);
  873.             addrc(r2, param2);
  874.             str(r1, r2);
  875.             drop;
  876.             drop
  877.  
  878.         |IL.opINCCB, IL.opDECCB:
  879.             IF opcode = IL.opDECCB THEN
  880.                 param2 := -param2
  881.             END;
  882.             UnOp(r1);
  883.             r2 := GetAnyReg();
  884.             ldr8(r2, r1);
  885.             addrc(r2, param2);
  886.             str8(r1, r2);
  887.             drop;
  888.             drop
  889.  
  890.         |IL.opINCB, IL.opDECB:
  891.             BinOp(r2, r1);
  892.             r3 := GetAnyReg();
  893.             ldr8(r3, r1);
  894.             IF opcode = IL.opINCB THEN
  895.                 add(r3, r2)
  896.             ELSE
  897.                 sub(r3, r2)
  898.             END;
  899.             str8(r1, r3);
  900.             drop;
  901.             drop;
  902.             drop
  903.  
  904.         |IL.opINC, IL.opDEC:
  905.             BinOp(r2, r1);
  906.             r3 := GetAnyReg();
  907.             ldr(r3, r1);
  908.             IF opcode = IL.opINC THEN
  909.                 add(r3, r2)
  910.             ELSE
  911.                 sub(r3, r2)
  912.             END;
  913.             str(r1, r3);
  914.             drop;
  915.             drop;
  916.             drop
  917.  
  918.         |IL.opINCL, IL.opEXCL:
  919.             BinOp(r2, r1);
  920.             Emit(opBIT, r2, r2);
  921.             r3 := GetAnyReg();
  922.             ldr(r3, r1);
  923.             IF opcode = IL.opINCL THEN
  924.                 Emit(opOR, r3, r2)
  925.             ELSE
  926.                 Emit(opNOT, r2, 0);
  927.                 Emit(opAND, r3, r2)
  928.             END;
  929.             str(r1, r3);
  930.             drop;
  931.             drop;
  932.             drop
  933.  
  934.         |IL.opINCLC, IL.opEXCLC:
  935.             UnOp(r1);
  936.             r2 := GetAnyReg();
  937.             ldr(r2, r1);
  938.             IF opcode = IL.opINCLC THEN
  939.                 Emit(opORC, r2, ORD({param2}))
  940.             ELSE
  941.                 Emit(opANDC, r2, ORD(-{param2}))
  942.             END;
  943.             str(r1, r2);
  944.             drop;
  945.             drop
  946.  
  947.         |IL.opEQB, IL.opNEB:
  948.             BinOp(r1, r2);
  949.             Emit(opCMPC, r1, 0);
  950.             Emit(opSNE, r1, 0);
  951.             Emit(opCMPC, r2, 0);
  952.             Emit(opSNE, r2, 0);
  953.             Emit(opCMP, r1, r2);
  954.             IF opcode = IL.opEQB THEN
  955.                 Emit(opSEQ, r1, 0)
  956.             ELSE
  957.                 Emit(opSNE, r1, 0)
  958.             END;
  959.             drop
  960.  
  961.         |IL.opCHKBYTE:
  962.             BinOp(r1, r2);
  963.             Emit(opCMPC, r1, 256);
  964.             Emit(opJBT, param1, 0)
  965.  
  966.         |IL.opCHKIDX:
  967.             UnOp(r1);
  968.             Emit(opCMPC, r1, param2);
  969.             Emit(opJBT, param1, 0)
  970.  
  971.         |IL.opCHKIDX2:
  972.             BinOp(r1, r2);
  973.             IF param2 # -1 THEN
  974.                 Emit(opCMP, r2, r1);
  975.                 Emit(opJBT, param1, 0)
  976.             END;
  977.             INCL(R.regs, r1);
  978.             DEC(R.top);
  979.             R.stk[R.top] := r2
  980.  
  981.         |IL.opEQP, IL.opNEP:
  982.             ProcAdr(GetAnyReg(), param1);
  983.             BinOp(r1, r2);
  984.             Emit(opCMP, r1, r2);
  985.             IF opcode = IL.opEQP THEN
  986.                 Emit(opSEQ, r1, 0)
  987.             ELSE
  988.                 Emit(opSNE, r1, 0)
  989.             END;
  990.             drop
  991.  
  992.         |IL.opSAVEP:
  993.             UnOp(r1);
  994.             r2 := GetAnyReg();
  995.             ProcAdr(r2, param2);
  996.             str(r1, r2);
  997.             drop;
  998.             drop
  999.  
  1000.         |IL.opPUSHP:
  1001.             ProcAdr(GetAnyReg(), param2)
  1002.  
  1003.         |IL.opPUSHT:
  1004.             UnOp(r1);
  1005.             Emit(opLD, r1 * 256 + GetAnyReg(), -szWord)
  1006.  
  1007.         |IL.opGET, IL.opGETC:
  1008.             IF opcode = IL.opGET THEN
  1009.                 BinOp(r1, r2)
  1010.             ELSIF opcode = IL.opGETC THEN
  1011.                 UnOp(r2);
  1012.                 r1 := GetAnyReg();
  1013.                 movrc(r1, param1)
  1014.             END;
  1015.             drop;
  1016.             drop;
  1017.  
  1018.             CASE param2 OF
  1019.             |1: ldr8(r1, r1);  str8(r2, r1)
  1020.             |2: ldr16(r1, r1); str16(r2, r1)
  1021.             |4: ldr32(r1, r1); str32(r2, r1)
  1022.             |8: ldr64(r1, r1); str64(r2, r1)
  1023.             END
  1024.  
  1025.         |IL.opNOT:
  1026.             UnOp(r1);
  1027.             Emit(opCMPC, r1, 0);
  1028.             Emit(opSEQ, r1, 0)
  1029.  
  1030.         |IL.opORD:
  1031.             UnOp(r1);
  1032.             Emit(opCMPC, r1, 0);
  1033.             Emit(opSNE, r1, 0)
  1034.  
  1035.         |IL.opMIN, IL.opMAX:
  1036.             BinOp(r1, r2);
  1037.             Emit(opCMP, r1, r2);
  1038.             label := IL.NewLabel();
  1039.             IF opcode = IL.opMIN THEN
  1040.                 Emit(opJLE, label, 0)
  1041.             ELSE
  1042.                 Emit(opJGE, label, 0)
  1043.             END;
  1044.             Emit(opMOV, r1, r2);
  1045.             Emit(opLABEL, label, 0);
  1046.             drop
  1047.  
  1048.         |IL.opMINC, IL.opMAXC:
  1049.             UnOp(r1);
  1050.             Emit(opCMPC, r1, param2);
  1051.             label := IL.NewLabel();
  1052.             IF opcode = IL.opMINC THEN
  1053.                 Emit(opJLE, label, 0)
  1054.             ELSE
  1055.                 Emit(opJGE, label, 0)
  1056.             END;
  1057.             Emit(opMOVC, r1, param2);
  1058.             Emit(opLABEL, label, 0)
  1059.  
  1060.         |IL.opIN:
  1061.             BinOp(r1, r2);
  1062.             Emit(opBIT, r1, r1);
  1063.             Emit(opAND, r1, r2);
  1064.             Emit(opCMPC, r1, 0);
  1065.             Emit(opSNE, r1, 0);
  1066.             drop
  1067.  
  1068.         |IL.opINL:
  1069.             UnOp(r1);
  1070.             Emit(opANDC, r1, ORD({param2}));
  1071.             Emit(opCMPC, r1, 0);
  1072.             Emit(opSNE, r1, 0)
  1073.  
  1074.         |IL.opINR:
  1075.             UnOp(r1);
  1076.             Emit(opBIT, r1, r1);
  1077.             Emit(opANDC, r1, param2);
  1078.             Emit(opCMPC, r1, 0);
  1079.             Emit(opSNE, r1, 0)
  1080.  
  1081.         |IL.opERR:
  1082.             CallRTL(IL._error, 4)
  1083.  
  1084.         |IL.opEQS .. IL.opGES:
  1085.             PushAll(4);
  1086.             pushc(opcode - IL.opEQS);
  1087.             CallRTL(IL._strcmp, 5);
  1088.             GetAcc
  1089.  
  1090.         |IL.opEQSW .. IL.opGESW:
  1091.             PushAll(4);
  1092.             pushc(opcode - IL.opEQSW);
  1093.             CallRTL(IL._strcmpw, 5);
  1094.             GetAcc
  1095.  
  1096.         |IL.opCOPY:
  1097.             PushAll(2);
  1098.             pushc(param2);
  1099.             CallRTL(IL._move, 3)
  1100.  
  1101.         |IL.opMOVE:
  1102.             PushAll(3);
  1103.             CallRTL(IL._move, 3)
  1104.  
  1105.         |IL.opCOPYA:
  1106.             PushAll(4);
  1107.             pushc(param2);
  1108.             CallRTL(IL._arrcpy, 5);
  1109.             GetAcc
  1110.  
  1111.         |IL.opCOPYS:
  1112.             PushAll(4);
  1113.             pushc(param2);
  1114.             CallRTL(IL._strcpy, 5)
  1115.  
  1116.         |IL.opROT:
  1117.             PushAll(0);
  1118.             mov(ACC, SP);
  1119.             push(ACC);
  1120.             pushc(param2);
  1121.             CallRTL(IL._rot, 2)
  1122.  
  1123.         |IL.opLENGTH:
  1124.             PushAll(2);
  1125.             CallRTL(IL._length, 2);
  1126.             GetAcc
  1127.  
  1128.         |IL.opLENGTHW:
  1129.             PushAll(2);
  1130.             CallRTL(IL._lengthw, 2);
  1131.             GetAcc
  1132.  
  1133.         |IL.opSAVES:
  1134.             UnOp(r2);
  1135.             REG.PushAll_1(R);
  1136.             r1 := GetAnyReg();
  1137.             StrAdr(r1, param2);
  1138.             push(r1);
  1139.             drop;
  1140.             push(r2);
  1141.             drop;
  1142.             pushc(param1);
  1143.             CallRTL(IL._move, 3)
  1144.  
  1145.         |IL.opRSET:
  1146.             PushAll(2);
  1147.             CallRTL(IL._set, 2);
  1148.             GetAcc
  1149.  
  1150.         |IL.opRSETR:
  1151.             PushAll(1);
  1152.             pushc(param2);
  1153.             CallRTL(IL._set, 2);
  1154.             GetAcc
  1155.  
  1156.         |IL.opRSETL:
  1157.             UnOp(r1);
  1158.             REG.PushAll_1(R);
  1159.             pushc(param2);
  1160.             push(r1);
  1161.             drop;
  1162.             CallRTL(IL._set, 2);
  1163.             GetAcc
  1164.  
  1165.         |IL.opRSET1:
  1166.             PushAll(1);
  1167.             CallRTL(IL._set1, 1);
  1168.             GetAcc
  1169.  
  1170.         |IL.opNEW:
  1171.             PushAll(1);
  1172.             INC(param2, szWord);
  1173.             ASSERT(UTILS.Align(param2, szWord));
  1174.             pushc(param2);
  1175.             pushc(param1);
  1176.             CallRTL(IL._new, 3)
  1177.  
  1178.         |IL.opTYPEGP:
  1179.             UnOp(r1);
  1180.             PushAll(0);
  1181.             push(r1);
  1182.             pushc(param2);
  1183.             CallRTL(IL._guard, 2);
  1184.             GetAcc
  1185.  
  1186.         |IL.opIS:
  1187.             PushAll(1);
  1188.             pushc(param2);
  1189.             CallRTL(IL._is, 2);
  1190.             GetAcc
  1191.  
  1192.         |IL.opISREC:
  1193.             PushAll(2);
  1194.             pushc(param2);
  1195.             CallRTL(IL._guardrec, 3);
  1196.             GetAcc
  1197.  
  1198.         |IL.opTYPEGR:
  1199.             PushAll(1);
  1200.             pushc(param2);
  1201.             CallRTL(IL._guardrec, 2);
  1202.             GetAcc
  1203.  
  1204.         |IL.opTYPEGD:
  1205.             UnOp(r1);
  1206.             PushAll(0);
  1207.             subrc(r1, szWord);
  1208.             ldr(r1, r1);
  1209.             push(r1);
  1210.             pushc(param2);
  1211.             CallRTL(IL._guardrec, 2);
  1212.             GetAcc
  1213.  
  1214.         |IL.opCASET:
  1215.             push(R1);
  1216.             push(R1);
  1217.             pushc(param2);
  1218.             CallRTL(IL._guardrec, 2);
  1219.             pop(R1);
  1220.             jnz(ACC, param1)
  1221.  
  1222.         |IL.opCONSTF:
  1223.             IF szWord = 8 THEN
  1224.                 movrc(GetAnyReg(), UTILS.splitf(cmd.float, a, b))
  1225.             ELSE (* szWord = 4 *)
  1226.                 movrc(GetAnyReg(), UTILS.d2s(cmd.float))
  1227.             END
  1228.  
  1229.         |IL.opMULF:
  1230.             PushAll(2);
  1231.             CallRTL(IL._fmul, 2);
  1232.             GetAcc
  1233.  
  1234.         |IL.opDIVF:
  1235.             PushAll(2);
  1236.             CallRTL(IL._fdiv, 2);
  1237.             GetAcc
  1238.  
  1239.         |IL.opDIVFI:
  1240.             PushAll(2);
  1241.             CallRTL(IL._fdivi, 2);
  1242.             GetAcc
  1243.  
  1244.         |IL.opADDF:
  1245.             PushAll(2);
  1246.             CallRTL(IL._fadd, 2);
  1247.             GetAcc
  1248.  
  1249.         |IL.opSUBFI:
  1250.             PushAll(2);
  1251.             CallRTL(IL._fsubi, 2);
  1252.             GetAcc
  1253.  
  1254.         |IL.opSUBF:
  1255.             PushAll(2);
  1256.             CallRTL(IL._fsub, 2);
  1257.             GetAcc
  1258.  
  1259.         |IL.opEQF..IL.opGEF:
  1260.             PushAll(2);
  1261.             pushc(opcode - IL.opEQF);
  1262.             CallRTL(IL._fcmp, 3);
  1263.             GetAcc
  1264.  
  1265.         |IL.opFLOOR:
  1266.             PushAll(1);
  1267.             CallRTL(IL._floor, 1);
  1268.             GetAcc
  1269.  
  1270.         |IL.opFLT:
  1271.             PushAll(1);
  1272.             CallRTL(IL._flt, 1);
  1273.             GetAcc
  1274.  
  1275.         |IL.opUMINF:
  1276.             UnOp(r1);
  1277.             Emit(opRORC, r1, -1);
  1278.             Emit(opXORC, r1,  1);
  1279.             Emit(opRORC, r1,  1)
  1280.  
  1281.         |IL.opFABS:
  1282.             UnOp(r1);
  1283.             Emit(opLSLC, r1, 1);
  1284.             Emit(opLSRC, r1, 1)
  1285.  
  1286.         |IL.opINF:
  1287.             r1 := GetAnyReg();
  1288.             Emit(opMOVC, r1, 1);
  1289.             Emit(opRORC, r1, 1);
  1290.             Emit(opASRC, r1, 7 + 3 * ORD(szWord = 8));
  1291.             Emit(opLSRC, r1, 1)
  1292.  
  1293.         |IL.opPUSHF:
  1294.             UnOp(r1);
  1295.             push(r1);
  1296.             drop
  1297.  
  1298.         |IL.opPACK:
  1299.             PushAll(2);
  1300.             CallRTL(IL._pack, 2)
  1301.  
  1302.         |IL.opPACKC:
  1303.             PushAll(1);
  1304.             pushc(param2);
  1305.             CallRTL(IL._pack, 2)
  1306.  
  1307.         |IL.opUNPK:
  1308.             PushAll(2);
  1309.             CallRTL(IL._unpk, 2)
  1310.  
  1311.         |IL.opCODE:
  1312.             OutInt(param2)
  1313.  
  1314.         |IL.opLADR_SAVE:
  1315.             UnOp(r1);
  1316.             Emit(opST, BP * 256 + r1, param2 * szWord);
  1317.             drop
  1318.  
  1319.         |IL.opLADR_INCC:
  1320.             r1 := GetAnyReg();
  1321.             Emit(opLD, BP * 256 + r1, param1 * szWord);
  1322.             Emit(opADDC, r1, param2);
  1323.             Emit(opST, BP * 256 + r1, param1 * szWord);
  1324.             drop
  1325.  
  1326.         END;
  1327.  
  1328.         cmd := cmd.next(IL.COMMAND)
  1329.     END;
  1330.  
  1331.     ASSERT(R.pushed = 0);
  1332.     ASSERT(R.top = -1)
  1333. END translate;
  1334.  
  1335.  
  1336. PROCEDURE prolog;
  1337. BEGIN
  1338.     Emit(opLEA, SP + LStack * 256, 0);
  1339.     Emit(opLEA, ACC + LTypes * 256, 0);
  1340.     push(ACC);
  1341.     Emit(opLEA, ACC + LHeap * 256, 0);
  1342.     push(ACC);
  1343.     pushc(CHL.Length(IL.codes.types));
  1344.     CallRTL(IL._init, 3)
  1345. END prolog;
  1346.  
  1347.  
  1348. PROCEDURE epilog (ram, szWord: INTEGER);
  1349. VAR
  1350.     tcount, dcount, i, offTypes, offStrings,
  1351.     szData, szGlobal, szHeapStack: INTEGER;
  1352.  
  1353. BEGIN
  1354.     Emit(opSTOP, 0, 0);
  1355.  
  1356.     offTypes := count;
  1357.  
  1358.     tcount := CHL.Length(IL.codes.types);
  1359.     FOR i := 0 TO tcount - 1 DO
  1360.         OutInt(CHL.GetInt(IL.codes.types, i))
  1361.     END;
  1362.  
  1363.     offStrings := count;
  1364.     dcount := CHL.Length(IL.codes.data);
  1365.     FOR i := 0 TO dcount - 1 DO
  1366.         OutByte(CHL.GetByte(IL.codes.data, i))
  1367.     END;
  1368.  
  1369.     IF dcount MOD szWord # 0 THEN
  1370.         i := szWord - dcount MOD szWord;
  1371.         WHILE i > 0 DO
  1372.             OutByte(0);
  1373.             DEC(i)
  1374.         END
  1375.     END;
  1376.  
  1377.     szData := count - offTypes;
  1378.     szGlobal := (IL.codes.bss DIV szWord + 1) * szWord;
  1379.     szHeapStack := ram - szData - szGlobal;
  1380.  
  1381.     OutInt(offTypes);
  1382.     OutInt(offStrings);
  1383.     OutInt(szGlobal DIV szWord);
  1384.     OutInt(szHeapStack DIV szWord);
  1385.     FOR i := 1 TO 8 DO
  1386.         OutInt(0)
  1387.     END
  1388. END epilog;
  1389.  
  1390.  
  1391. PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS);
  1392. CONST
  1393.     minRAM = 32*1024;
  1394.     maxRAM = 256*1024;
  1395.  
  1396. VAR
  1397.     szData, szRAM: INTEGER;
  1398.  
  1399. BEGIN
  1400.     szWord := TARGETS.WordSize;
  1401.     IF szWord = 8 THEN
  1402.         ldr := ldr64;
  1403.         str := str64
  1404.     ELSE
  1405.         ldr := ldr32;
  1406.         str := str32
  1407.     END;
  1408.     szData := (CHL.Length(IL.codes.types) + CHL.Length(IL.codes.data) DIV szWord + IL.codes.bss DIV szWord + 2) * szWord;
  1409.     szRAM := MIN(MAX(options.ram, minRAM), maxRAM) * 1024;
  1410.  
  1411.     IF szRAM - szData < 1024*1024 THEN
  1412.         ERRORS.Error(208)
  1413.     END;
  1414.  
  1415.     count := 0;
  1416.     WR.Create(outname);
  1417.  
  1418.     REG.Init(R, push, pop, mov, xchg, GPRs);
  1419.  
  1420.     prolog;
  1421.     translate(szWord);
  1422.     epilog(szRAM, szWord);
  1423.  
  1424.     WR.Close
  1425. END CodeGen;
  1426.  
  1427.  
  1428. END RVMxI.