MSP430.ob07 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771
  1. (*
  2. BSD 2-Clause License
  3. Copyright (c) 2019-2022, Anton Krotov
  4. All rights reserved.
  5. *)
  6. MODULE MSP430;
  7. IMPORT IL, LISTS, REG, CHL := CHUNKLISTS, ERRORS, WR := WRITER, HEX,
  8. UTILS, C := CONSOLE, PROG, RTL := MSP430RTL;
  9. CONST
  10. chkSTK* = 6;
  11. minRAM* = 128; maxRAM* = 2048;
  12. minROM* = 2048; maxROM* = 24576;
  13. StkReserve = RTL.StkReserve;
  14. IntVectorSize* = RTL.IntVectorSize;
  15. PC = 0; SP = 1; SR = 2; CG = 3;
  16. R4 = 4; R5 = 5; R6 = 6; R7 = 7;
  17. HP = RTL.HP;
  18. ACC = R4;
  19. opRRC = 1000H; opSWPB = 1080H; opRRA = 1100H; opSXT = 1180H;
  20. opPUSH = 1200H; opCALL = 1280H; opRETI = 1300H;
  21. opMOV = 04000H; opADD = 05000H; opADDC = 06000H; opSUBC = 07000H;
  22. opSUB = 08000H; opCMP = 09000H; opDADD = 0A000H; opBIT = 0B000H;
  23. opBIC = 0C000H; opBIS = 0D000H; opXOR = 0E000H; opAND = 0F000H;
  24. opJNE = 2000H; opJEQ = 2400H; opJNC = 2800H; opJC = 2C00H;
  25. opJN = 3000H; opJGE = 3400H; opJL = 3800H; opJMP = 3C00H;
  26. sREG = 0; sIDX = 16; sINDIR = 32; sINCR = 48; BW = 64; dIDX = 128;
  27. NOWORD = 10000H;
  28. RCODE = 0; RDATA = 1; RBSS = 2;
  29. je = 0; jne = je + 1;
  30. jge = 2; jl = jge + 1;
  31. jle = 4; jg = jle + 1;
  32. jb = 6;
  33. TYPE
  34. ANYCODE = POINTER TO RECORD (LISTS.ITEM)
  35. offset: INTEGER
  36. END;
  37. WORD = POINTER TO RECORD (ANYCODE)
  38. val: INTEGER
  39. END;
  40. LABEL = POINTER TO RECORD (ANYCODE)
  41. num: INTEGER
  42. END;
  43. JMP = POINTER TO RECORD (ANYCODE)
  44. cc, label: INTEGER;
  45. short: BOOLEAN
  46. END;
  47. CALL = POINTER TO RECORD (ANYCODE)
  48. label: INTEGER
  49. END;
  50. COMMAND = IL.COMMAND;
  51. RELOC = POINTER TO RECORD (LISTS.ITEM)
  52. section: INTEGER;
  53. WordPtr: WORD
  54. END;
  55. VAR
  56. R: REG.REGS;
  57. CodeList: LISTS.LIST;
  58. RelList: LISTS.LIST;
  59. mem: ARRAY 65536 OF BYTE;
  60. Labels: CHL.INTLIST;
  61. IV: ARRAY RTL.LenIV OF INTEGER;
  62. IdxWords: RECORD src, dst: INTEGER END;
  63. StkCnt, MaxStkCnt: INTEGER;
  64. PROCEDURE CheckProcDataSize* (VarSize, RamSize: INTEGER): BOOLEAN;
  65. RETURN (VarSize + 1) * 2 + StkReserve + RTL.VarSize < RamSize
  66. END CheckProcDataSize;
  67. PROCEDURE EmitLabel (L: INTEGER);
  68. VAR
  69. label: LABEL;
  70. BEGIN
  71. NEW(label);
  72. label.num := L;
  73. LISTS.push(CodeList, label)
  74. END EmitLabel;
  75. PROCEDURE EmitWord (val: INTEGER);
  76. VAR
  77. word: WORD;
  78. BEGIN
  79. IF val < 0 THEN
  80. ASSERT(val >= -32768);
  81. val := val MOD 65536
  82. ELSE
  83. ASSERT(val <= 65535)
  84. END;
  85. NEW(word);
  86. word.val := val;
  87. LISTS.push(CodeList, word)
  88. END EmitWord;
  89. PROCEDURE EmitJmp (cc, label: INTEGER);
  90. VAR
  91. jmp: JMP;
  92. BEGIN
  93. NEW(jmp);
  94. jmp.cc := cc;
  95. jmp.label := label;
  96. jmp.short := FALSE;
  97. LISTS.push(CodeList, jmp)
  98. END EmitJmp;
  99. PROCEDURE EmitCall (label: INTEGER);
  100. VAR
  101. call: CALL;
  102. BEGIN
  103. NEW(call);
  104. call.label := label;
  105. LISTS.push(CodeList, call)
  106. END EmitCall;
  107. PROCEDURE IncStk;
  108. BEGIN
  109. INC(StkCnt);
  110. MaxStkCnt := MAX(StkCnt, MaxStkCnt)
  111. END IncStk;
  112. PROCEDURE bw (b: BOOLEAN): INTEGER;
  113. RETURN BW * ORD(b)
  114. END bw;
  115. PROCEDURE src_x (x, Rn: INTEGER): INTEGER;
  116. VAR
  117. res: INTEGER;
  118. BEGIN
  119. IF (x = 0) & ~(Rn IN {PC, SR, CG}) THEN
  120. res := Rn * 256 + sINDIR
  121. ELSE
  122. IdxWords.src := x;
  123. res := Rn * 256 + sIDX
  124. END
  125. RETURN res
  126. END src_x;
  127. PROCEDURE dst_x (x, Rn: INTEGER): INTEGER;
  128. BEGIN
  129. IdxWords.dst := x
  130. RETURN Rn + dIDX
  131. END dst_x;
  132. PROCEDURE indir (Rn: INTEGER): INTEGER;
  133. RETURN Rn * 256 + sINDIR
  134. END indir;
  135. PROCEDURE incr (Rn: INTEGER): INTEGER;
  136. RETURN Rn * 256 + sINCR
  137. END incr;
  138. PROCEDURE imm (x: INTEGER): INTEGER;
  139. VAR
  140. res: INTEGER;
  141. BEGIN
  142. CASE x OF
  143. | 0: res := CG * 256
  144. | 1: res := CG * 256 + sIDX
  145. | 2: res := indir(CG)
  146. | 4: res := indir(SR)
  147. | 8: res := incr(SR)
  148. |-1: res := incr(CG)
  149. ELSE
  150. res := incr(PC);
  151. IdxWords.src := x
  152. END
  153. RETURN res
  154. END imm;
  155. PROCEDURE Op2 (op, src, dst: INTEGER);
  156. BEGIN
  157. ASSERT(BITS(op) - {6, 12..15} = {});
  158. ASSERT(BITS(src) - {4, 5, 8..11} = {});
  159. ASSERT(BITS(dst) - {0..3, 7} = {});
  160. EmitWord(op + src + dst);
  161. IF IdxWords.src # NOWORD THEN
  162. EmitWord(IdxWords.src);
  163. IdxWords.src := NOWORD
  164. END;
  165. IF IdxWords.dst # NOWORD THEN
  166. EmitWord(IdxWords.dst);
  167. IdxWords.dst := NOWORD
  168. END
  169. END Op2;
  170. PROCEDURE Op1 (op, reg, As: INTEGER);
  171. BEGIN
  172. EmitWord(op + reg + As)
  173. END Op1;
  174. PROCEDURE MovRR (src, dst: INTEGER);
  175. BEGIN
  176. Op2(opMOV, src * 256, dst)
  177. END MovRR;
  178. PROCEDURE PushImm (imm: INTEGER);
  179. BEGIN
  180. imm := UTILS.Long(imm);
  181. CASE imm OF
  182. | 0: Op1(opPUSH, CG, sREG)
  183. | 1: Op1(opPUSH, CG, sIDX)
  184. | 2: Op1(opPUSH, CG, sINDIR)
  185. |-1: Op1(opPUSH, CG, sINCR)
  186. ELSE
  187. Op1(opPUSH, PC, sINCR);
  188. EmitWord(imm)
  189. END;
  190. IncStk
  191. END PushImm;
  192. PROCEDURE PutWord (word: INTEGER; VAR adr: INTEGER);
  193. BEGIN
  194. ASSERT(~ODD(adr));
  195. ASSERT((0 <= word) & (word <= 65535));
  196. mem[adr] := word MOD 256;
  197. mem[adr + 1] := word DIV 256;
  198. INC(adr, 2)
  199. END PutWord;
  200. PROCEDURE NewLabel (): INTEGER;
  201. BEGIN
  202. CHL.PushInt(Labels, 0)
  203. RETURN IL.NewLabel()
  204. END NewLabel;
  205. PROCEDURE LabelOffs (n: INTEGER): INTEGER;
  206. RETURN CHL.GetInt(Labels, n)
  207. END LabelOffs;
  208. PROCEDURE Fixup (CodeAdr, IntVectorSize: INTEGER): INTEGER;
  209. VAR
  210. cmd: ANYCODE;
  211. adr: INTEGER;
  212. offset: INTEGER;
  213. diff: INTEGER;
  214. cc: INTEGER;
  215. shorted: BOOLEAN;
  216. BEGIN
  217. REPEAT
  218. shorted := FALSE;
  219. offset := CodeAdr DIV 2;
  220. cmd := CodeList.first(ANYCODE);
  221. WHILE cmd # NIL DO
  222. cmd.offset := offset;
  223. CASE cmd OF
  224. |LABEL: CHL.SetInt(Labels, cmd.num, offset)
  225. |JMP: INC(offset);
  226. IF ~cmd.short THEN
  227. INC(offset);
  228. IF cmd.cc # opJMP THEN
  229. INC(offset)
  230. END
  231. END
  232. |CALL: INC(offset, 2)
  233. |WORD: INC(offset)
  234. END;
  235. cmd := cmd.next(ANYCODE)
  236. END;
  237. cmd := CodeList.first(ANYCODE);
  238. WHILE cmd # NIL DO
  239. IF (cmd IS JMP) & ~cmd(JMP).short THEN
  240. diff := LabelOffs(cmd(JMP).label) - cmd.offset - 1;
  241. IF ABS(diff) <= 512 THEN
  242. cmd(JMP).short := TRUE;
  243. shorted := TRUE
  244. END
  245. END;
  246. cmd := cmd.next(ANYCODE)
  247. END
  248. UNTIL ~shorted;
  249. IF offset * 2 > 10000H - IntVectorSize THEN
  250. ERRORS.Error(203)
  251. END;
  252. adr := CodeAdr;
  253. cmd := CodeList.first(ANYCODE);
  254. WHILE cmd # NIL DO
  255. CASE cmd OF
  256. |LABEL:
  257. |JMP: IF ~cmd.short THEN
  258. CASE cmd.cc OF
  259. |opJNE: cc := opJEQ
  260. |opJEQ: cc := opJNE
  261. |opJNC: cc := opJC
  262. |opJC: cc := opJNC
  263. |opJGE: cc := opJL
  264. |opJL: cc := opJGE
  265. |opJMP: cc := opJMP
  266. END;
  267. IF cc # opJMP THEN
  268. PutWord(cc + 2, adr) (* jcc L *)
  269. END;
  270. PutWord(4030H, adr); (* MOV @PC+, PC *)
  271. PutWord(LabelOffs(cmd.label) * 2, adr)
  272. (* L: *)
  273. ELSE
  274. diff := LabelOffs(cmd.label) - cmd.offset - 1;
  275. ASSERT((-512 <= diff) & (diff <= 511));
  276. PutWord(cmd.cc + diff MOD 1024, adr)
  277. END
  278. |CALL: PutWord(12B0H, adr); (* CALL @PC+ *)
  279. PutWord(LabelOffs(cmd.label) * 2, adr)
  280. |WORD: PutWord(cmd.val, adr)
  281. END;
  282. cmd := cmd.next(ANYCODE)
  283. END
  284. RETURN adr - CodeAdr
  285. END Fixup;
  286. PROCEDURE Push (reg: INTEGER);
  287. BEGIN
  288. Op1(opPUSH, reg, sREG);
  289. IncStk
  290. END Push;
  291. PROCEDURE Pop (reg: INTEGER);
  292. BEGIN
  293. Op2(opMOV, incr(SP), reg);
  294. DEC(StkCnt)
  295. END Pop;
  296. PROCEDURE Test (reg: INTEGER);
  297. BEGIN
  298. Op2(opCMP, imm(0), reg)
  299. END Test;
  300. PROCEDURE Clear (reg: INTEGER);
  301. BEGIN
  302. Op2(opMOV, imm(0), reg)
  303. END Clear;
  304. PROCEDURE mov (dst, src: INTEGER);
  305. BEGIN
  306. MovRR(src, dst)
  307. END mov;
  308. PROCEDURE xchg (reg1, reg2: INTEGER);
  309. BEGIN
  310. Push(reg1);
  311. mov(reg1, reg2);
  312. Pop(reg2)
  313. END xchg;
  314. PROCEDURE Reloc (section: INTEGER);
  315. VAR
  316. reloc: RELOC;
  317. BEGIN
  318. NEW(reloc);
  319. reloc.section := section;
  320. reloc.WordPtr := CodeList.last(WORD);
  321. LISTS.push(RelList, reloc)
  322. END Reloc;
  323. PROCEDURE CallRTL (proc, params: INTEGER);
  324. BEGIN
  325. IncStk;
  326. DEC(StkCnt);
  327. EmitCall(RTL.rtl[proc].label);
  328. RTL.Used(proc);
  329. IF params > 0 THEN
  330. Op2(opADD, imm(params * 2), SP);
  331. DEC(StkCnt, params)
  332. END
  333. END CallRTL;
  334. PROCEDURE UnOp (VAR reg: INTEGER);
  335. BEGIN
  336. REG.UnOp(R, reg)
  337. END UnOp;
  338. PROCEDURE BinOp (VAR reg1, reg2: INTEGER);
  339. BEGIN
  340. REG.BinOp(R, reg1, reg2)
  341. END BinOp;
  342. PROCEDURE GetRegA;
  343. BEGIN
  344. ASSERT(REG.GetReg(R, ACC))
  345. END GetRegA;
  346. PROCEDURE drop;
  347. BEGIN
  348. REG.Drop(R)
  349. END drop;
  350. PROCEDURE GetAnyReg (): INTEGER;
  351. RETURN REG.GetAnyReg(R)
  352. END GetAnyReg;
  353. PROCEDURE PushAll (NumberOfParameters: INTEGER);
  354. BEGIN
  355. REG.PushAll(R);
  356. DEC(R.pushed, NumberOfParameters)
  357. END PushAll;
  358. PROCEDURE PushAll_1;
  359. BEGIN
  360. REG.PushAll_1(R)
  361. END PushAll_1;
  362. PROCEDURE cond (op: INTEGER): INTEGER;
  363. VAR
  364. res: INTEGER;
  365. BEGIN
  366. CASE op OF
  367. |IL.opGT, IL.opGTC: res := jg
  368. |IL.opGE, IL.opGEC: res := jge
  369. |IL.opLT, IL.opLTC: res := jl
  370. |IL.opLE, IL.opLEC: res := jle
  371. |IL.opEQ, IL.opEQC: res := je
  372. |IL.opNE, IL.opNEC: res := jne
  373. END
  374. RETURN res
  375. END cond;
  376. PROCEDURE jcc (cc, label: INTEGER);
  377. VAR
  378. L: INTEGER;
  379. BEGIN
  380. CASE cc OF
  381. |jne:
  382. EmitJmp(opJNE, label)
  383. |je:
  384. EmitJmp(opJEQ, label)
  385. |jge:
  386. EmitJmp(opJGE, label)
  387. |jl:
  388. EmitJmp(opJL, label)
  389. |jle:
  390. EmitJmp(opJL, label);
  391. EmitJmp(opJEQ, label)
  392. |jg:
  393. L := NewLabel();
  394. EmitJmp(opJEQ, L);
  395. EmitJmp(opJGE, label);
  396. EmitLabel(L)
  397. |jb:
  398. EmitJmp(opJNC, label)
  399. END
  400. END jcc;
  401. PROCEDURE setcc (cc, reg: INTEGER);
  402. VAR
  403. L: INTEGER;
  404. BEGIN
  405. L := NewLabel();
  406. Op2(opMOV, imm(1), reg);
  407. jcc(cc, L);
  408. Clear(reg);
  409. EmitLabel(L)
  410. END setcc;
  411. PROCEDURE Shift2 (op, reg, n: INTEGER);
  412. VAR
  413. reg2: INTEGER;
  414. BEGIN
  415. IF n >= 8 THEN
  416. CASE op OF
  417. |IL.opASR2: Op1(opSWPB, reg, sREG); Op1(opSXT, reg, sREG)
  418. |IL.opROR2: Op1(opSWPB, reg, sREG)
  419. |IL.opLSL2: Op1(opSWPB, reg, sREG); Op2(opBIC, imm(255), reg)
  420. |IL.opLSR2: Op2(opBIC, imm(255), reg); Op1(opSWPB, reg, sREG)
  421. END;
  422. DEC(n, 8)
  423. END;
  424. IF (op = IL.opROR2) & (n > 0) THEN
  425. reg2 := GetAnyReg();
  426. MovRR(reg, reg2)
  427. ELSE
  428. reg2 := -1
  429. END;
  430. WHILE n > 0 DO
  431. CASE op OF
  432. |IL.opASR2: Op1(opRRA, reg, sREG)
  433. |IL.opROR2: Op1(opRRC, reg2, sREG); Op1(opRRC, reg, sREG)
  434. |IL.opLSL2: Op2(opADD, reg * 256, reg)
  435. |IL.opLSR2: Op2(opBIC, imm(1), SR); Op1(opRRC, reg, sREG)
  436. END;
  437. DEC(n)
  438. END;
  439. IF reg2 # -1 THEN
  440. drop
  441. END
  442. END Shift2;
  443. PROCEDURE Neg (reg: INTEGER);
  444. BEGIN
  445. Op2(opXOR, imm(-1), reg);
  446. Op2(opADD, imm(1), reg)
  447. END Neg;
  448. PROCEDURE LocalOffset (offset: INTEGER): INTEGER;
  449. RETURN (offset + StkCnt - ORD(offset > 0)) * 2
  450. END LocalOffset;
  451. PROCEDURE LocalDst (offset: INTEGER): INTEGER;
  452. RETURN dst_x(LocalOffset(offset), SP)
  453. END LocalDst;
  454. PROCEDURE LocalSrc (offset: INTEGER): INTEGER;
  455. RETURN src_x(LocalOffset(offset), SP)
  456. END LocalSrc;
  457. PROCEDURE translate (chk_stk: BOOLEAN);
  458. VAR
  459. cmd, next: COMMAND;
  460. opcode, param1, param2, L, a, n, c1, c2: INTEGER;
  461. reg1, reg2: INTEGER;
  462. cc: INTEGER;
  463. word: WORD;
  464. BEGIN
  465. cmd := IL.codes.commands.first(COMMAND);
  466. WHILE cmd # NIL DO
  467. param1 := cmd.param1;
  468. param2 := cmd.param2;
  469. opcode := cmd.opcode;
  470. CASE opcode OF
  471. |IL.opJMP:
  472. EmitJmp(opJMP, param1)
  473. |IL.opCALL:
  474. IncStk;
  475. DEC(StkCnt);
  476. EmitCall(param1)
  477. |IL.opCALLP:
  478. IncStk;
  479. DEC(StkCnt);
  480. UnOp(reg1);
  481. Op1(opCALL, reg1, sREG);
  482. drop;
  483. ASSERT(R.top = -1)
  484. |IL.opPRECALL:
  485. PushAll(0)
  486. |IL.opLABEL:
  487. EmitLabel(param1)
  488. |IL.opSADR_PARAM:
  489. Op1(opPUSH, PC, sINCR);
  490. IncStk;
  491. EmitWord(param2);
  492. Reloc(RDATA)
  493. |IL.opERR:
  494. CallRTL(RTL._error, 2)
  495. |IL.opPUSHC:
  496. PushImm(param2)
  497. |IL.opONERR:
  498. DEC(StkCnt);
  499. EmitWord(0C232H); (* BIC #8, SR; DINT *)
  500. EmitWord(4303H); (* MOV R3, R3; NOP *)
  501. PushImm(param2);
  502. EmitJmp(opJMP, param1)
  503. |IL.opLEAVEC:
  504. Pop(PC)
  505. |IL.opENTER:
  506. ASSERT(R.top = -1);
  507. EmitLabel(param1);
  508. n := param2 MOD 65536;
  509. param2 := param2 DIV 65536;
  510. StkCnt := 0;
  511. IF chk_stk THEN
  512. L := NewLabel();
  513. Op2(opMOV, SP * 256, R4);
  514. Op2(opSUB, HP * 256, R4);
  515. Op2(opCMP, imm(StkReserve), R4);
  516. word := CodeList.last(WORD);
  517. jcc(jge, L);
  518. DEC(StkCnt);
  519. EmitWord(0C232H); (* BIC #8, SR; DINT *)
  520. EmitWord(4303H); (* MOV R3, R3; NOP *)
  521. PushImm(n);
  522. EmitJmp(opJMP, cmd.param3);
  523. EmitLabel(L)
  524. END;
  525. IF param2 > 8 THEN
  526. Op2(opMOV, imm(param2), R4);
  527. L := NewLabel();
  528. EmitLabel(L);
  529. Push(CG);
  530. Op2(opSUB, imm(1), R4);
  531. jcc(jne, L)
  532. ELSE
  533. FOR n := 1 TO param2 DO
  534. Push(CG)
  535. END
  536. END;
  537. StkCnt := param2;
  538. MaxStkCnt := StkCnt
  539. |IL.opLEAVE, IL.opLEAVER:
  540. ASSERT(param2 = 0);
  541. IF opcode = IL.opLEAVER THEN
  542. UnOp(reg1);
  543. IF reg1 # ACC THEN
  544. mov(ACC, reg1)
  545. END;
  546. drop
  547. END;
  548. ASSERT(R.top = -1);
  549. ASSERT(StkCnt = param1);
  550. IF chk_stk THEN
  551. INC(word.val, MaxStkCnt * 2)
  552. END;
  553. IF param1 > 0 THEN
  554. Op2(opADD, imm(param1 * 2), SP)
  555. END;
  556. Pop(PC)
  557. |IL.opRES:
  558. ASSERT(R.top = -1);
  559. GetRegA
  560. |IL.opCLEANUP:
  561. IF param2 # 0 THEN
  562. Op2(opADD, imm(param2 * 2), SP);
  563. DEC(StkCnt, param2)
  564. END
  565. |IL.opCONST:
  566. next := cmd.next(COMMAND);
  567. IF next.opcode = IL.opCONST THEN
  568. c1 := param2;
  569. c2 := next.param2;
  570. next := next.next(COMMAND);
  571. IF (next.opcode = IL.opSAVE) OR (next.opcode = IL.opSAVE16) OR (next.opcode = IL.opSAVE8) THEN
  572. Op2(opMOV + bw(next.opcode = IL.opSAVE8), imm(c1), dst_x(c2, SR));
  573. cmd := next
  574. ELSE
  575. Op2(opMOV, imm(param2), GetAnyReg())
  576. END
  577. ELSIF (next.opcode = IL.opSAVE) OR (next.opcode = IL.opSAVE16) OR (next.opcode = IL.opSAVE8) THEN
  578. UnOp(reg1);
  579. Op2(opMOV + bw(next.opcode = IL.opSAVE8), reg1 * 256, dst_x(param2, SR));
  580. drop;
  581. cmd := next
  582. ELSE
  583. Op2(opMOV, imm(param2), GetAnyReg())
  584. END
  585. |IL.opSADR:
  586. Op2(opMOV, incr(PC), GetAnyReg());
  587. EmitWord(param2);
  588. Reloc(RDATA)
  589. |IL.opGADR:
  590. Op2(opMOV, incr(PC), GetAnyReg());
  591. EmitWord(param2);
  592. Reloc(RBSS)
  593. |IL.opLADR:
  594. reg1 := GetAnyReg();
  595. n := LocalOffset(param2);
  596. Op2(opMOV, SP * 256, reg1);
  597. IF n # 0 THEN
  598. Op2(opADD, imm(n), reg1)
  599. END
  600. |IL.opLLOAD8:
  601. Op2(opMOV + BW, LocalSrc(param2), GetAnyReg())
  602. |IL.opLLOAD16, IL.opVADR:
  603. Op2(opMOV, LocalSrc(param2), GetAnyReg())
  604. |IL.opGLOAD8:
  605. Op2(opMOV + BW, src_x(param2, SR), GetAnyReg());
  606. Reloc(RBSS)
  607. |IL.opGLOAD16:
  608. Op2(opMOV, src_x(param2, SR), GetAnyReg());
  609. Reloc(RBSS)
  610. |IL.opLOAD8:
  611. UnOp(reg1);
  612. Op2(opMOV + BW, indir(reg1), reg1)
  613. |IL.opLOAD16:
  614. UnOp(reg1);
  615. Op2(opMOV, indir(reg1), reg1)
  616. |IL.opVLOAD8:
  617. reg1 := GetAnyReg();
  618. Op2(opMOV, LocalSrc(param2), reg1);
  619. Op2(opMOV + BW, indir(reg1), reg1)
  620. |IL.opVLOAD16:
  621. reg1 := GetAnyReg();
  622. Op2(opMOV, LocalSrc(param2), reg1);
  623. Op2(opMOV, indir(reg1), reg1)
  624. |IL.opSAVE, IL.opSAVE16:
  625. BinOp(reg2, reg1);
  626. Op2(opMOV, reg2 * 256, dst_x(0, reg1));
  627. drop;
  628. drop
  629. |IL.opSAVE8:
  630. BinOp(reg2, reg1);
  631. Op2(opMOV + BW, reg2 * 256, dst_x(0, reg1));
  632. drop;
  633. drop
  634. |IL.opSAVE8C:
  635. UnOp(reg1);
  636. Op2(opMOV + BW, imm(param2), dst_x(0, reg1));
  637. drop
  638. |IL.opSAVE16C, IL.opSAVEC:
  639. UnOp(reg1);
  640. Op2(opMOV, imm(param2), dst_x(0, reg1));
  641. drop
  642. |IL.opUMINUS:
  643. UnOp(reg1);
  644. Neg(reg1)
  645. |IL.opADD:
  646. BinOp(reg1, reg2);
  647. Op2(opADD, reg2 * 256, reg1);
  648. drop
  649. |IL.opADDC:
  650. IF param2 # 0 THEN
  651. UnOp(reg1);
  652. Op2(opADD, imm(param2), reg1)
  653. END
  654. |IL.opSUB:
  655. BinOp(reg1, reg2);
  656. Op2(opSUB, reg2 * 256, reg1);
  657. drop
  658. |IL.opSUBR, IL.opSUBL:
  659. UnOp(reg1);
  660. IF param2 # 0 THEN
  661. Op2(opSUB, imm(param2), reg1)
  662. END;
  663. IF opcode = IL.opSUBL THEN
  664. Neg(reg1)
  665. END
  666. |IL.opLADR_SAVEC:
  667. Op2(opMOV, imm(param2), LocalDst(param1))
  668. |IL.opLADR_SAVE:
  669. UnOp(reg1);
  670. Op2(opMOV, reg1 * 256, LocalDst(param2));
  671. drop
  672. |IL.opGADR_SAVEC:
  673. Op2(opMOV, imm(param2), dst_x(param1, SR));
  674. Reloc(RBSS)
  675. |IL.opCONST_PARAM:
  676. PushImm(param2)
  677. |IL.opPARAM:
  678. IF param2 = 1 THEN
  679. UnOp(reg1);
  680. Push(reg1);
  681. drop
  682. ELSE
  683. ASSERT(R.top + 1 <= param2);
  684. PushAll(param2)
  685. END
  686. |IL.opEQ..IL.opGE,
  687. IL.opEQC..IL.opGEC:
  688. IF (IL.opEQ <= opcode) & (opcode <= IL.opGE) THEN
  689. BinOp(reg1, reg2);
  690. Op2(opCMP, reg2 * 256, reg1);
  691. drop
  692. ELSE
  693. UnOp(reg1);
  694. Op2(opCMP, imm(param2), reg1)
  695. END;
  696. drop;
  697. cc := cond(opcode);
  698. next := cmd.next(COMMAND);
  699. IF next.opcode = IL.opJNZ THEN
  700. jcc(cc, next.param1);
  701. cmd := next
  702. ELSIF next.opcode = IL.opJZ THEN
  703. jcc(ORD(BITS(cc) / {0}), next.param1);
  704. cmd := next
  705. ELSE
  706. setcc(cc, GetAnyReg())
  707. END
  708. |IL.opNOP, IL.opAND, IL.opOR:
  709. |IL.opCODE:
  710. EmitWord(param2)
  711. |IL.opDROP:
  712. UnOp(reg1);
  713. drop
  714. |IL.opJNZ1:
  715. UnOp(reg1);
  716. Test(reg1);
  717. jcc(jne, param1)
  718. |IL.opJG:
  719. UnOp(reg1);
  720. Test(reg1);
  721. jcc(jg, param1)
  722. |IL.opJNZ:
  723. UnOp(reg1);
  724. Test(reg1);
  725. jcc(jne, param1);
  726. drop
  727. |IL.opJZ:
  728. UnOp(reg1);
  729. Test(reg1);
  730. jcc(je, param1);
  731. drop
  732. |IL.opNOT:
  733. UnOp(reg1);
  734. Test(reg1);
  735. setcc(je, reg1)
  736. |IL.opORD:
  737. UnOp(reg1);
  738. Test(reg1);
  739. setcc(jne, reg1)
  740. |IL.opGET:
  741. BinOp(reg1, reg2);
  742. drop;
  743. drop;
  744. Op2(opMOV + bw(param2 = 1), indir(reg1), dst_x(0, reg2))
  745. |IL.opGETC:
  746. UnOp(reg2);
  747. drop;
  748. Op2(opMOV + bw(param2 = 1), src_x(param1, SR), dst_x(0, reg2))
  749. |IL.opCHKIDX:
  750. UnOp(reg1);
  751. Op2(opCMP, imm(param2), reg1);
  752. jcc(jb, param1)
  753. |IL.opCHKIDX2:
  754. BinOp(reg1, reg2);
  755. IF param2 # -1 THEN
  756. Op2(opCMP, reg1 * 256, reg2);
  757. jcc(jb, param1)
  758. END;
  759. INCL(R.regs, reg1);
  760. DEC(R.top);
  761. R.stk[R.top] := reg2
  762. |IL.opINCC, IL.opINCCB:
  763. UnOp(reg1);
  764. Op2(opADD + bw(opcode = IL.opINCCB), imm(param2), dst_x(0, reg1));
  765. drop
  766. |IL.opDECCB:
  767. UnOp(reg1);
  768. Op2(opSUB + BW, imm(param2), dst_x(0, reg1));
  769. drop
  770. |IL.opINC, IL.opINCB:
  771. BinOp(reg1, reg2);
  772. Op2(opADD + bw(opcode = IL.opINCB), reg1 * 256, dst_x(0, reg2));
  773. drop;
  774. drop
  775. |IL.opDEC, IL.opDECB:
  776. BinOp(reg1, reg2);
  777. Op2(opSUB + bw(opcode = IL.opDECB), reg1 * 256, dst_x(0, reg2));
  778. drop;
  779. drop
  780. |IL.opLADR_INCC, IL.opLADR_INCCB:
  781. Op2(opADD + bw(opcode = IL.opLADR_INCCB), imm(param2), LocalDst(param1))
  782. |IL.opLADR_DECCB:
  783. Op2(opSUB + BW, imm(param2), LocalDst(param1))
  784. |IL.opLADR_INC, IL.opLADR_INCB:
  785. UnOp(reg1);
  786. Op2(opADD + bw(opcode = IL.opLADR_INCB), reg1 * 256, LocalDst(param2));
  787. drop
  788. |IL.opLADR_DEC, IL.opLADR_DECB:
  789. UnOp(reg1);
  790. Op2(opSUB + bw(opcode = IL.opLADR_DECB), reg1 * 256, LocalDst(param2));
  791. drop
  792. |IL.opPUSHT:
  793. UnOp(reg1);
  794. Op2(opMOV, src_x(-2, reg1), GetAnyReg())
  795. |IL.opISREC:
  796. PushAll(2);
  797. PushImm(param2);
  798. CallRTL(RTL._guardrec, 3);
  799. GetRegA
  800. |IL.opIS:
  801. PushAll(1);
  802. PushImm(param2);
  803. CallRTL(RTL._is, 2);
  804. GetRegA
  805. |IL.opTYPEGR:
  806. PushAll(1);
  807. PushImm(param2);
  808. CallRTL(RTL._guardrec, 2);
  809. GetRegA
  810. |IL.opTYPEGP:
  811. UnOp(reg1);
  812. PushAll(0);
  813. Push(reg1);
  814. PushImm(param2);
  815. CallRTL(RTL._guard, 2);
  816. GetRegA
  817. |IL.opTYPEGD:
  818. UnOp(reg1);
  819. PushAll(0);
  820. Op1(opPUSH, reg1, sIDX);
  821. IncStk;
  822. EmitWord(-2);
  823. PushImm(param2);
  824. CallRTL(RTL._guardrec, 2);
  825. GetRegA
  826. |IL.opMULS:
  827. BinOp(reg1, reg2);
  828. Op2(opAND, reg2 * 256, reg1);
  829. drop
  830. |IL.opMULSC:
  831. UnOp(reg1);
  832. Op2(opAND, imm(param2), reg1)
  833. |IL.opDIVS:
  834. BinOp(reg1, reg2);
  835. Op2(opXOR, reg2 * 256, reg1);
  836. drop
  837. |IL.opDIVSC:
  838. UnOp(reg1);
  839. Op2(opXOR, imm(param2), reg1)
  840. |IL.opADDS:
  841. BinOp(reg1, reg2);
  842. Op2(opBIS, reg2 * 256, reg1);
  843. drop
  844. |IL.opSUBS:
  845. BinOp(reg1, reg2);
  846. Op2(opBIC, reg2 * 256, reg1);
  847. drop
  848. |IL.opADDSC:
  849. UnOp(reg1);
  850. Op2(opBIS, imm(param2), reg1)
  851. |IL.opSUBSL:
  852. UnOp(reg1);
  853. Op2(opXOR, imm(-1), reg1);
  854. Op2(opAND, imm(param2), reg1)
  855. |IL.opSUBSR:
  856. UnOp(reg1);
  857. Op2(opBIC, imm(param2), reg1)
  858. |IL.opUMINS:
  859. UnOp(reg1);
  860. Op2(opXOR, imm(-1), reg1)
  861. |IL.opLENGTH:
  862. PushAll(2);
  863. CallRTL(RTL._length, 2);
  864. GetRegA
  865. |IL.opMAX,IL.opMIN:
  866. BinOp(reg1, reg2);
  867. Op2(opCMP, reg2 * 256, reg1);
  868. IF opcode = IL.opMIN THEN
  869. cc := opJL + 1
  870. ELSE
  871. cc := opJGE + 1
  872. END;
  873. EmitWord(cc); (* jge/jl L *)
  874. MovRR(reg2, reg1);
  875. (* L: *)
  876. drop
  877. |IL.opMAXC, IL.opMINC:
  878. UnOp(reg1);
  879. Op2(opCMP, imm(param2), reg1);
  880. L := NewLabel();
  881. IF opcode = IL.opMINC THEN
  882. cc := jl
  883. ELSE
  884. cc := jge
  885. END;
  886. jcc(cc, L);
  887. Op2(opMOV, imm(param2), reg1);
  888. EmitLabel(L)
  889. |IL.opSWITCH:
  890. UnOp(reg1);
  891. IF param2 = 0 THEN
  892. reg2 := ACC
  893. ELSE
  894. reg2 := R5
  895. END;
  896. IF reg1 # reg2 THEN
  897. ASSERT(REG.GetReg(R, reg2));
  898. ASSERT(REG.Exchange(R, reg1, reg2));
  899. drop
  900. END;
  901. drop
  902. |IL.opENDSW:
  903. |IL.opCASEL:
  904. Op2(opCMP, imm(param1), ACC);
  905. jcc(jl, param2)
  906. |IL.opCASER:
  907. Op2(opCMP, imm(param1), ACC);
  908. jcc(jg, param2)
  909. |IL.opCASELR:
  910. Op2(opCMP, imm(param1), ACC);
  911. IF param2 = cmd.param3 THEN
  912. jcc(jne, param2)
  913. ELSE
  914. jcc(jl, param2);
  915. jcc(jg, cmd.param3)
  916. END
  917. |IL.opSBOOL:
  918. BinOp(reg2, reg1);
  919. Test(reg2);
  920. setcc(jne, reg2);
  921. Op2(opMOV + BW, reg2 * 256, dst_x(0, reg1));
  922. drop;
  923. drop
  924. |IL.opSBOOLC:
  925. UnOp(reg1);
  926. Op2(opMOV + BW, imm(param2), dst_x(0, reg1));
  927. drop
  928. |IL.opEQS .. IL.opGES:
  929. PushAll(4);
  930. PushImm((opcode - IL.opEQS) * 12);
  931. CallRTL(RTL._strcmp, 5);
  932. GetRegA
  933. |IL.opLEN:
  934. UnOp(reg1);
  935. drop;
  936. EXCL(R.regs, reg1);
  937. WHILE param2 > 0 DO
  938. UnOp(reg2);
  939. drop;
  940. DEC(param2)
  941. END;
  942. INCL(R.regs, reg1);
  943. ASSERT(REG.GetReg(R, reg1))
  944. |IL.opLSL, IL.opASR, IL.opROR, IL.opLSR:
  945. PushAll(2);
  946. CASE opcode OF
  947. |IL.opLSL: CallRTL(RTL._lsl, 2)
  948. |IL.opASR: CallRTL(RTL._asr, 2)
  949. |IL.opROR: CallRTL(RTL._ror, 2)
  950. |IL.opLSR: CallRTL(RTL._lsr, 2)
  951. END;
  952. GetRegA
  953. |IL.opLSL1, IL.opASR1, IL.opROR1, IL.opLSR1:
  954. UnOp(reg1);
  955. PushAll_1;
  956. PushImm(param2);
  957. Push(reg1);
  958. drop;
  959. CASE opcode OF
  960. |IL.opLSL1: CallRTL(RTL._lsl, 2)
  961. |IL.opASR1: CallRTL(RTL._asr, 2)
  962. |IL.opROR1: CallRTL(RTL._ror, 2)
  963. |IL.opLSR1: CallRTL(RTL._lsr, 2)
  964. END;
  965. GetRegA
  966. |IL.opASR2, IL.opROR2, IL.opLSL2, IL.opLSR2:
  967. param2 := param2 MOD 16;
  968. IF param2 # 0 THEN
  969. UnOp(reg1);
  970. Shift2(opcode, reg1, param2)
  971. END
  972. |IL.opMUL:
  973. PushAll(2);
  974. CallRTL(RTL._mul, 2);
  975. GetRegA
  976. |IL.opMULC:
  977. UnOp(reg1);
  978. a := param2;
  979. IF a > 1 THEN
  980. n := UTILS.Log2(a)
  981. ELSIF a < -1 THEN
  982. n := UTILS.Log2(-a)
  983. ELSE
  984. n := -1
  985. END;
  986. IF a = 1 THEN
  987. ELSIF a = -1 THEN
  988. Neg(reg1)
  989. ELSIF a = 0 THEN
  990. Clear(reg1)
  991. ELSE
  992. IF n > 0 THEN
  993. IF a < 0 THEN
  994. Neg(reg1)
  995. END;
  996. Shift2(IL.opLSL2, reg1, n)
  997. ELSE
  998. PushAll(1);
  999. PushImm(a);
  1000. CallRTL(RTL._mul, 2);
  1001. GetRegA
  1002. END
  1003. END
  1004. |IL.opDIV:
  1005. PushAll(2);
  1006. CallRTL(RTL._divmod, 2);
  1007. GetRegA
  1008. |IL.opDIVR:
  1009. ASSERT(param2 > 0);
  1010. IF param2 > 1 THEN
  1011. n := UTILS.Log2(param2);
  1012. IF n > 0 THEN
  1013. UnOp(reg1);
  1014. Shift2(IL.opASR2, reg1, n)
  1015. ELSE
  1016. PushAll(1);
  1017. PushImm(param2);
  1018. CallRTL(RTL._divmod, 2);
  1019. GetRegA
  1020. END
  1021. END
  1022. |IL.opDIVL:
  1023. UnOp(reg1);
  1024. PushAll_1;
  1025. PushImm(param2);
  1026. Push(reg1);
  1027. drop;
  1028. CallRTL(RTL._divmod, 2);
  1029. GetRegA
  1030. |IL.opMOD:
  1031. PushAll(2);
  1032. CallRTL(RTL._divmod, 2);
  1033. ASSERT(REG.GetReg(R, R5))
  1034. |IL.opMODR:
  1035. ASSERT(param2 > 0);
  1036. IF param2 = 1 THEN
  1037. UnOp(reg1);
  1038. Clear(reg1)
  1039. ELSE
  1040. IF UTILS.Log2(param2) > 0 THEN
  1041. UnOp(reg1);
  1042. Op2(opAND, imm(param2 - 1), reg1)
  1043. ELSE
  1044. PushAll(1);
  1045. PushImm(param2);
  1046. CallRTL(RTL._divmod, 2);
  1047. ASSERT(REG.GetReg(R, R5))
  1048. END
  1049. END
  1050. |IL.opMODL:
  1051. UnOp(reg1);
  1052. PushAll_1;
  1053. PushImm(param2);
  1054. Push(reg1);
  1055. drop;
  1056. CallRTL(RTL._divmod, 2);
  1057. ASSERT(REG.GetReg(R, R5))
  1058. |IL.opCOPYS:
  1059. ASSERT(R.top = 3);
  1060. Push(R.stk[2]);
  1061. Push(R.stk[0]);
  1062. Op2(opCMP, R.stk[1] * 256, R.stk[3]);
  1063. EmitWord(3801H); (* JL L1 *)
  1064. MovRR(R.stk[1], R.stk[3]);
  1065. (* L1: *)
  1066. Push(R.stk[3]);
  1067. drop;
  1068. drop;
  1069. drop;
  1070. drop;
  1071. CallRTL(RTL._move, 3)
  1072. |IL.opCOPY:
  1073. PushAll(2);
  1074. PushImm(param2);
  1075. CallRTL(RTL._move, 3)
  1076. |IL.opMOVE:
  1077. PushAll(3);
  1078. CallRTL(RTL._move, 3)
  1079. |IL.opCOPYA:
  1080. PushAll(4);
  1081. PushImm(param2);
  1082. CallRTL(RTL._arrcpy, 5);
  1083. GetRegA
  1084. |IL.opROT:
  1085. PushAll(0);
  1086. MovRR(SP, ACC);
  1087. Push(ACC);
  1088. PushImm(param2);
  1089. CallRTL(RTL._rot, 2)
  1090. |IL.opSAVES:
  1091. UnOp(reg1);
  1092. PushAll_1;
  1093. Op1(opPUSH, PC, sINCR);
  1094. IncStk;
  1095. EmitWord(param2);
  1096. Reloc(RDATA);
  1097. Push(reg1);
  1098. drop;
  1099. PushImm(param1);
  1100. CallRTL(RTL._move, 3)
  1101. |IL.opCASET:
  1102. Push(R5);
  1103. Push(R5);
  1104. PushImm(param2);
  1105. CallRTL(RTL._guardrec, 2);
  1106. Pop(R5);
  1107. Test(ACC);
  1108. jcc(jne, param1)
  1109. |IL.opABS:
  1110. UnOp(reg1);
  1111. Test(reg1);
  1112. L := NewLabel();
  1113. jcc(jge, L);
  1114. Neg(reg1);
  1115. EmitLabel(L)
  1116. |IL.opEQB, IL.opNEB:
  1117. BinOp(reg1, reg2);
  1118. drop;
  1119. Test(reg1);
  1120. L := NewLabel();
  1121. jcc(je, L);
  1122. Op2(opMOV, imm(1), reg1);
  1123. EmitLabel(L);
  1124. Test(reg2);
  1125. L := NewLabel();
  1126. jcc(je, L);
  1127. Op2(opMOV, imm(1), reg2);
  1128. EmitLabel(L);
  1129. Op2(opCMP, reg2 * 256, reg1);
  1130. IF opcode = IL.opEQB THEN
  1131. setcc(je, reg1)
  1132. ELSE
  1133. setcc(jne, reg1)
  1134. END
  1135. |IL.opSAVEP:
  1136. UnOp(reg1);
  1137. Op2(opMOV, incr(PC), reg1 + dIDX);
  1138. EmitWord(param2);
  1139. Reloc(RCODE);
  1140. EmitWord(0);
  1141. drop
  1142. |IL.opPUSHP:
  1143. Op2(opMOV, incr(PC), GetAnyReg());
  1144. EmitWord(param2);
  1145. Reloc(RCODE)
  1146. |IL.opEQP, IL.opNEP:
  1147. UnOp(reg1);
  1148. Op2(opCMP, incr(PC), reg1);
  1149. EmitWord(param1);
  1150. Reloc(RCODE);
  1151. drop;
  1152. reg1 := GetAnyReg();
  1153. IF opcode = IL.opEQP THEN
  1154. setcc(je, reg1)
  1155. ELSIF opcode = IL.opNEP THEN
  1156. setcc(jne, reg1)
  1157. END
  1158. |IL.opVADR_PARAM:
  1159. reg1 := GetAnyReg();
  1160. Op2(opMOV, LocalSrc(param2), reg1);
  1161. Push(reg1);
  1162. drop
  1163. |IL.opNEW:
  1164. PushAll(1);
  1165. n := param2 + 2;
  1166. ASSERT(UTILS.Align(n, 2));
  1167. PushImm(n);
  1168. PushImm(param1);
  1169. CallRTL(RTL._new, 3)
  1170. |IL.opRSET:
  1171. PushAll(2);
  1172. CallRTL(RTL._set, 2);
  1173. GetRegA
  1174. |IL.opRSETR:
  1175. PushAll(1);
  1176. PushImm(param2);
  1177. CallRTL(RTL._set, 2);
  1178. GetRegA
  1179. |IL.opRSETL:
  1180. UnOp(reg1);
  1181. PushAll_1;
  1182. PushImm(param2);
  1183. Push(reg1);
  1184. drop;
  1185. CallRTL(RTL._set, 2);
  1186. GetRegA
  1187. |IL.opRSET1:
  1188. PushAll(1);
  1189. CallRTL(RTL._set1, 1);
  1190. GetRegA
  1191. |IL.opINCLC:
  1192. UnOp(reg1);
  1193. Op2(opBIS, imm(ORD({param2})), dst_x(0, reg1));
  1194. drop
  1195. |IL.opEXCLC:
  1196. UnOp(reg1);
  1197. Op2(opBIC, imm(ORD({param2})), dst_x(0, reg1));
  1198. drop
  1199. |IL.opIN:
  1200. PushAll(2);
  1201. CallRTL(RTL._in, 2);
  1202. GetRegA
  1203. |IL.opINR:
  1204. PushAll(1);
  1205. PushImm(param2);
  1206. CallRTL(RTL._in, 2);
  1207. GetRegA
  1208. |IL.opINL:
  1209. PushAll(1);
  1210. PushImm(param2);
  1211. CallRTL(RTL._in2, 2);
  1212. GetRegA
  1213. |IL.opINCL:
  1214. PushAll(2);
  1215. CallRTL(RTL._incl, 2)
  1216. |IL.opEXCL:
  1217. PushAll(2);
  1218. CallRTL(RTL._excl, 2)
  1219. |IL.opLADR_INCL, IL.opLADR_EXCL:
  1220. PushAll(1);
  1221. MovRR(SP, ACC);
  1222. n := LocalOffset(param2);
  1223. IF n # 0 THEN
  1224. Op2(opADD, imm(n), ACC)
  1225. END;
  1226. Push(ACC);
  1227. IF opcode = IL.opLADR_INCL THEN
  1228. CallRTL(RTL._incl, 2)
  1229. ELSIF opcode = IL.opLADR_EXCL THEN
  1230. CallRTL(RTL._excl, 2)
  1231. END
  1232. |IL.opLADR_INCLC:
  1233. Op2(opBIS, imm(ORD({param2})), LocalDst(param1))
  1234. |IL.opLADR_EXCLC:
  1235. Op2(opBIC, imm(ORD({param2})), LocalDst(param1))
  1236. END;
  1237. cmd := cmd.next(COMMAND)
  1238. END;
  1239. ASSERT(R.pushed = 0);
  1240. ASSERT(R.top = -1)
  1241. END translate;
  1242. PROCEDURE prolog;
  1243. VAR
  1244. i: INTEGER;
  1245. BEGIN
  1246. RTL.Init(EmitLabel, EmitWord, EmitCall);
  1247. FOR i := 0 TO LEN(RTL.rtl) - 1 DO
  1248. RTL.Set(i, NewLabel())
  1249. END;
  1250. IV[LEN(IV) - 1] := NewLabel();
  1251. EmitLabel(IV[LEN(IV) - 1]);
  1252. Op2(opMOV, incr(PC), SP);
  1253. EmitWord(0);
  1254. Op2(opMOV, incr(PC), HP);
  1255. EmitWord(0);
  1256. Op2(opMOV, imm(5A80H), dst_x(0120H, SR)); (* stop WDT *)
  1257. Op2(opMOV, imm(RTL.empty_proc), dst_x(0, SP));
  1258. Op2(opMOV, imm(RTL.empty_proc), dst_x(2, SP));
  1259. END prolog;
  1260. PROCEDURE epilog;
  1261. VAR
  1262. L1, i, n: INTEGER;
  1263. BEGIN
  1264. Op2(opBIS, imm(10H), SR); (* CPUOFF *)
  1265. L1 := NewLabel();
  1266. FOR i := 0 TO LEN(IV) - 2 DO
  1267. IV[i] := NewLabel();
  1268. EmitLabel(IV[i]);
  1269. PushImm(i);
  1270. IF i # LEN(IV) - 2 THEN
  1271. EmitJmp(opJMP, L1)
  1272. END
  1273. END;
  1274. EmitLabel(L1);
  1275. n := 0;
  1276. FOR i := 0 TO 15 DO
  1277. IF i IN R.regs THEN
  1278. Push(i);
  1279. INC(n)
  1280. END
  1281. END;
  1282. MovRR(SP, R4);
  1283. Op2(opADD, imm(n * 2), R4);
  1284. Push(R4);
  1285. Op1(opPUSH, R4, sINDIR);
  1286. Op1(opCALL, SR, sIDX); EmitWord(-RTL.VarSize); Reloc(RBSS); (* call int *)
  1287. Op2(opADD, imm(4), SP);
  1288. FOR i := 15 TO 0 BY -1 DO
  1289. IF i IN R.regs THEN
  1290. Pop(i)
  1291. END
  1292. END;
  1293. Op2(opADD, imm(2), SP);
  1294. Op1(opRETI, 0, 0);
  1295. RTL.Gen
  1296. END epilog;
  1297. PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS);
  1298. VAR
  1299. i, adr, heap, stack, TextSize, TypesSize, bits, n, val: INTEGER;
  1300. Code, Data, Bss: RECORD address, size: INTEGER END;
  1301. ram, rom: INTEGER;
  1302. reloc: RELOC;
  1303. BEGIN
  1304. IdxWords.src := NOWORD;
  1305. IdxWords.dst := NOWORD;
  1306. ram := options.ram;
  1307. rom := options.rom;
  1308. IF ODD(ram) THEN DEC(ram) END;
  1309. IF ODD(rom) THEN DEC(rom) END;
  1310. ram := MIN(MAX(ram, minRAM), maxRAM);
  1311. rom := MIN(MAX(rom, minROM), maxROM);
  1312. IF IL.codes.bss > ram - StkReserve - RTL.VarSize THEN
  1313. ERRORS.Error(204)
  1314. END;
  1315. Labels := CHL.CreateIntList();
  1316. FOR i := 1 TO IL.codes.lcount DO
  1317. CHL.PushInt(Labels, 0)
  1318. END;
  1319. CodeList := LISTS.create(NIL);
  1320. RelList := LISTS.create(NIL);
  1321. REG.Init(R, Push, Pop, mov, xchg, {R4, R5, R6, R7});
  1322. prolog;
  1323. translate(chkSTK IN options.checking);
  1324. epilog;
  1325. TypesSize := CHL.Length(IL.codes.types) * 2;
  1326. Data.size := CHL.Length(IL.codes.data);
  1327. IF ODD(Data.size) THEN
  1328. CHL.PushByte(IL.codes.data, 0);
  1329. INC(Data.size)
  1330. END;
  1331. Code.size := Fixup(0, IntVectorSize + TypesSize + Data.size);
  1332. Code.address := 10000H - (IntVectorSize + TypesSize + Data.size + Code.size);
  1333. IF Code.address < 10000H - rom THEN
  1334. ERRORS.Error(203)
  1335. END;
  1336. Code.size := Fixup(Code.address, IntVectorSize + TypesSize + Data.size);
  1337. Data.address := Code.address + Code.size;
  1338. TextSize := Code.size + Data.size;
  1339. IF Code.address + TextSize + MAX(IL.codes.dmin - Data.size, IntVectorSize + TypesSize) > 10000H THEN
  1340. ERRORS.Error(203)
  1341. END;
  1342. stack := RTL.ram + ram;
  1343. Bss.size := IL.codes.bss + IL.codes.bss MOD 2;
  1344. DEC(stack, Bss.size);
  1345. Bss.address := stack;
  1346. DEC(stack, RTL.VarSize);
  1347. heap := RTL.ram;
  1348. ASSERT(stack - heap >= StkReserve);
  1349. adr := Code.address + 2;
  1350. PutWord(stack, adr);
  1351. adr := Code.address + 6;
  1352. PutWord(heap, adr);
  1353. reloc := RelList.first(RELOC);
  1354. WHILE reloc # NIL DO
  1355. adr := reloc.WordPtr.offset * 2;
  1356. val := reloc.WordPtr.val;
  1357. CASE reloc.section OF
  1358. |RCODE: PutWord(LabelOffs(val) * 2, adr)
  1359. |RDATA: PutWord(val + Data.address, adr)
  1360. |RBSS: PutWord((val + Bss.address) MOD 65536, adr)
  1361. END;
  1362. reloc := reloc.next(RELOC)
  1363. END;
  1364. adr := Data.address;
  1365. FOR i := 0 TO Data.size - 1 DO
  1366. mem[adr] := CHL.GetByte(IL.codes.data, i);
  1367. INC(adr)
  1368. END;
  1369. FOR i := TypesSize DIV 2 - 1 TO 0 BY -1 DO
  1370. PutWord(CHL.GetInt(IL.codes.types, i), adr)
  1371. END;
  1372. FOR i := 0 TO 15 DO
  1373. PutWord((33 - i) * i, adr);
  1374. END;
  1375. FOR n := 0 TO 15 DO
  1376. bits := ORD({0 .. n});
  1377. FOR i := 0 TO 15 - n DO
  1378. PutWord(bits, adr);
  1379. bits := LSL(bits, 1)
  1380. END
  1381. END;
  1382. PutWord(4130H, adr); (* RET *)
  1383. PutWord(stack, adr);
  1384. PutWord(0001H, adr); (* bsl signature (adr 0FFBEH) *)
  1385. FOR i := 0 TO LEN(IV) - 1 DO
  1386. PutWord(LabelOffs(IV[i]) * 2, adr)
  1387. END;
  1388. INC(TextSize, IntVectorSize + TypesSize + Code.address MOD 16);
  1389. INC(Bss.size, StkReserve + RTL.VarSize);
  1390. WR.Create(outname);
  1391. HEX.Data(mem, Code.address - Code.address MOD 16, TextSize);
  1392. HEX.End;
  1393. WR.Close;
  1394. C.Dashes;
  1395. C.String(" rom: "); C.Int(TextSize); C.String(" of "); C.Int(rom); C.String(" ("); C.Int(TextSize * 100 DIV rom); C.StringLn("%)");
  1396. C.Ln;
  1397. C.String(" ram: "); C.Int(Bss.size); C.String(" of "); C.Int(ram); C.String(" ("); C.Int(Bss.size * 100 DIV ram); C.StringLn("%)")
  1398. END CodeGen;
  1399. END MSP430.