RVMxI.ob07 34 KB

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