THUMB.ob07 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452
  1. MODULE THUMB;
  2. IMPORT PROG, LISTS, CHL := CHUNKLISTS, BIN, REG, IL, C := CONSOLE,
  3. UTILS IN "./utils/UTILS.ob07", WR := WRITER, HEX, ERRORS, TARGETS;
  4. CONST
  5. R0 = 0; R1 = 1; R2 = 2; R3 = 3; R4 = 4;
  6. SP = 13; LR = 14; PC = 15;
  7. ACC = R0;
  8. je = 0; jne = 1; jnb = 2; jb = 3; jge = 10; jl = 11; jg = 12; jle = 13;
  9. inf = 7F800000H;
  10. minROM* = 16; maxROM* = 65536;
  11. minRAM* = 4; maxRAM* = 65536;
  12. maxIVT* = 1023;
  13. _THUMB2 = 0; _IT = 1; _SDIV = 2; _CBXZ = 3;
  14. CortexM0 = {};
  15. CortexM1 = {};
  16. CortexM3 = {_THUMB2, _IT, _SDIV, _CBXZ};
  17. CortexM23 = {_SDIV, _CBXZ};
  18. TYPE
  19. COMMAND = IL.COMMAND;
  20. ANYCODE = POINTER TO RECORD (LISTS.ITEM)
  21. offset: INTEGER
  22. END;
  23. CODE = POINTER TO RECORD (ANYCODE)
  24. code: INTEGER
  25. END;
  26. LABEL = POINTER TO RECORD (ANYCODE)
  27. label: INTEGER
  28. END;
  29. JUMP = POINTER TO RECORD (ANYCODE)
  30. label, diff, len, cond: INTEGER;
  31. short: BOOLEAN
  32. END;
  33. JMP = POINTER TO RECORD (JUMP)
  34. END;
  35. JCC = POINTER TO RECORD (JUMP)
  36. END;
  37. CBXZ = POINTER TO RECORD (JUMP)
  38. reg: INTEGER
  39. END;
  40. CALL = POINTER TO RECORD (JUMP)
  41. END;
  42. RELOC = POINTER TO RECORD (ANYCODE)
  43. reg, rel, value: INTEGER
  44. END;
  45. RELOCCODE = ARRAY 7 OF INTEGER;
  46. MEM = RECORD
  47. start, size, startReserve, endReserve: INTEGER
  48. END;
  49. VAR
  50. R: REG.REGS;
  51. tcount: INTEGER;
  52. CodeList: LISTS.LIST;
  53. program: BIN.PROGRAM;
  54. StkCount: INTEGER;
  55. Target: RECORD
  56. flash, sram: MEM;
  57. IVTLen,
  58. MinStkSize: INTEGER;
  59. InstrSet: SET;
  60. isNXP: BOOLEAN
  61. END;
  62. IVT: ARRAY maxIVT + 1 OF INTEGER;
  63. sdivProc, trap, genTrap, entry, emptyProc, int0, genInt: INTEGER;
  64. PROCEDURE Code (code: INTEGER);
  65. VAR
  66. c: CODE;
  67. BEGIN
  68. NEW(c);
  69. c.code := code;
  70. LISTS.push(CodeList, c)
  71. END Code;
  72. PROCEDURE Label (label: INTEGER);
  73. VAR
  74. L: LABEL;
  75. BEGIN
  76. NEW(L);
  77. L.label := label;
  78. LISTS.push(CodeList, L)
  79. END Label;
  80. PROCEDURE jcc (cond, label: INTEGER);
  81. VAR
  82. j: JCC;
  83. BEGIN
  84. NEW(j);
  85. j.label := label;
  86. j.cond := cond;
  87. j.short := FALSE;
  88. j.len := 3;
  89. LISTS.push(CodeList, j)
  90. END jcc;
  91. PROCEDURE cbxz (cond, reg, label: INTEGER);
  92. VAR
  93. j: CBXZ;
  94. BEGIN
  95. NEW(j);
  96. j.label := label;
  97. j.cond := cond;
  98. j.reg := reg;
  99. j.short := FALSE;
  100. j.len := 4;
  101. LISTS.push(CodeList, j)
  102. END cbxz;
  103. PROCEDURE jmp (label: INTEGER);
  104. VAR
  105. j: JMP;
  106. BEGIN
  107. NEW(j);
  108. j.label := label;
  109. j.short := FALSE;
  110. j.len := 2;
  111. LISTS.push(CodeList, j)
  112. END jmp;
  113. PROCEDURE call (label: INTEGER);
  114. VAR
  115. c: CALL;
  116. BEGIN
  117. NEW(c);
  118. c.label := label;
  119. c.short := FALSE;
  120. c.len := 2;
  121. LISTS.push(CodeList, c)
  122. END call;
  123. PROCEDURE reloc (reg, rel, value: INTEGER);
  124. VAR
  125. r: RELOC;
  126. BEGIN
  127. NEW(r);
  128. r.reg := reg;
  129. r.rel := rel;
  130. r.value := value;
  131. LISTS.push(CodeList, r)
  132. END reloc;
  133. PROCEDURE NewLabel (): INTEGER;
  134. BEGIN
  135. BIN.NewLabel(program)
  136. RETURN IL.NewLabel()
  137. END NewLabel;
  138. PROCEDURE range (x, n: INTEGER): BOOLEAN;
  139. RETURN (0 <= x) & (x < LSL(1, n))
  140. END range;
  141. PROCEDURE srange (x, n: INTEGER): BOOLEAN;
  142. RETURN (-LSL(1, n - 1) <= x) & (x < LSL(1, n - 1))
  143. END srange;
  144. PROCEDURE gen1 (op, imm, rs, rd: INTEGER);
  145. BEGIN
  146. ASSERT(op IN {0..2});
  147. ASSERT(range(imm, 5));
  148. ASSERT(range(rs, 3));
  149. ASSERT(range(rd, 3));
  150. Code(LSL(op, 11) + LSL(imm, 6) + LSL(rs, 3) + rd)
  151. END gen1;
  152. PROCEDURE gen2 (i, op: BOOLEAN; imm, rs, rd: INTEGER);
  153. BEGIN
  154. ASSERT(range(imm, 3));
  155. ASSERT(range(rs, 3));
  156. ASSERT(range(rd, 3));
  157. Code(1800H + LSL(ORD(i), 10) + LSL(ORD(op), 9) + LSL(imm, 6) + LSL(rs, 3) + rd)
  158. END gen2;
  159. PROCEDURE gen3 (op, rd, imm: INTEGER);
  160. BEGIN
  161. ASSERT(range(op, 2));
  162. ASSERT(range(rd, 3));
  163. ASSERT(range(imm, 8));
  164. Code(2000H + LSL(op, 11) + LSL(rd, 8) + imm)
  165. END gen3;
  166. PROCEDURE gen4 (op, rs, rd: INTEGER);
  167. BEGIN
  168. ASSERT(range(op, 4));
  169. ASSERT(range(rs, 3));
  170. ASSERT(range(rd, 3));
  171. Code(4000H + LSL(op, 6) + LSL(rs, 3) + rd)
  172. END gen4;
  173. PROCEDURE gen5 (op: INTEGER; h1, h2: BOOLEAN; rs, rd: INTEGER);
  174. BEGIN
  175. ASSERT(range(op, 2));
  176. ASSERT(range(rs, 3));
  177. ASSERT(range(rd, 3));
  178. Code(4400H + LSL(op, 8) + LSL(ORD(h1), 7) + LSL(ORD(h2), 6) + LSL(rs, 3) + rd)
  179. END gen5;
  180. PROCEDURE gen7 (l, b: BOOLEAN; ro, rb, rd: INTEGER);
  181. BEGIN
  182. ASSERT(range(ro, 3));
  183. ASSERT(range(rb, 3));
  184. ASSERT(range(rd, 3));
  185. Code(5000H + LSL(ORD(l), 11) + LSL(ORD(b), 10) + LSL(ro, 6) + LSL(rb, 3) + rd)
  186. END gen7;
  187. PROCEDURE gen8 (h, s: BOOLEAN; ro, rb, rd: INTEGER);
  188. BEGIN
  189. ASSERT(range(ro, 3));
  190. ASSERT(range(rb, 3));
  191. ASSERT(range(rd, 3));
  192. Code(5200H + LSL(ORD(h), 11) + LSL(ORD(s), 10) + LSL(ro, 6) + LSL(rb, 3) + rd)
  193. END gen8;
  194. PROCEDURE gen9 (b, l: BOOLEAN; imm, rb, rd: INTEGER);
  195. BEGIN
  196. ASSERT(range(imm, 5));
  197. ASSERT(range(rb, 3));
  198. ASSERT(range(rd, 3));
  199. Code(6000H + LSL(ORD(b), 12) + LSL(ORD(l), 11) + LSL(imm, 6) + LSL(rb, 3) + rd)
  200. END gen9;
  201. PROCEDURE gen10 (l: BOOLEAN; imm, rb, rd: INTEGER);
  202. BEGIN
  203. ASSERT(range(imm, 5));
  204. ASSERT(range(rb, 3));
  205. ASSERT(range(rd, 3));
  206. Code(8000H + LSL(ORD(l), 11) + LSL(imm, 6) + LSL(rb, 3) + rd)
  207. END gen10;
  208. PROCEDURE gen11 (l: BOOLEAN; rd, imm: INTEGER);
  209. BEGIN
  210. ASSERT(range(rd, 3));
  211. ASSERT(range(imm, 8));
  212. Code(9000H + LSL(ORD(l), 11) + LSL(rd, 8) + imm)
  213. END gen11;
  214. PROCEDURE gen12 (sp: BOOLEAN; rd, imm: INTEGER);
  215. BEGIN
  216. ASSERT(range(rd, 3));
  217. ASSERT(range(imm, 8));
  218. Code(0A000H + LSL(ORD(sp), 11) + LSL(rd, 8) + imm)
  219. END gen12;
  220. PROCEDURE gen14 (l, r: BOOLEAN; rlist: SET);
  221. VAR
  222. i, n: INTEGER;
  223. BEGIN
  224. ASSERT(range(ORD(rlist), 8));
  225. n := ORD(r);
  226. FOR i := 0 TO 7 DO
  227. IF i IN rlist THEN
  228. INC(n)
  229. END
  230. END;
  231. IF l THEN
  232. n := -n
  233. END;
  234. INC(StkCount, n);
  235. Code(0B400H + LSL(ORD(l), 11) + LSL(ORD(r), 8) + ORD(rlist))
  236. END gen14;
  237. PROCEDURE split16 (imm16: INTEGER; VAR imm4, imm1, imm3, imm8: INTEGER);
  238. BEGIN
  239. ASSERT(range(imm16, 16));
  240. imm8 := imm16 MOD 256;
  241. imm4 := LSR(imm16, 12);
  242. imm3 := LSR(imm16, 8) MOD 8;
  243. imm1 := LSR(imm16, 11) MOD 2;
  244. END split16;
  245. PROCEDURE LslImm (r, imm5: INTEGER);
  246. BEGIN
  247. gen1(0, imm5, r, r)
  248. END LslImm;
  249. PROCEDURE LsrImm (r, imm5: INTEGER);
  250. BEGIN
  251. gen1(1, imm5, r, r)
  252. END LsrImm;
  253. PROCEDURE AsrImm (r, imm5: INTEGER);
  254. BEGIN
  255. gen1(2, imm5, r, r)
  256. END AsrImm;
  257. PROCEDURE AddReg (rd, rs, rn: INTEGER);
  258. BEGIN
  259. gen2(FALSE, FALSE, rn, rs, rd)
  260. END AddReg;
  261. PROCEDURE SubReg (rd, rs, rn: INTEGER);
  262. BEGIN
  263. gen2(FALSE, TRUE, rn, rs, rd)
  264. END SubReg;
  265. PROCEDURE AddImm8 (rd, imm8: INTEGER);
  266. BEGIN
  267. IF imm8 # 0 THEN
  268. gen3(2, rd, imm8)
  269. END
  270. END AddImm8;
  271. PROCEDURE SubImm8 (rd, imm8: INTEGER);
  272. BEGIN
  273. IF imm8 # 0 THEN
  274. gen3(3, rd, imm8)
  275. END
  276. END SubImm8;
  277. PROCEDURE AddSubImm12 (r, imm12: INTEGER; sub: BOOLEAN);
  278. VAR
  279. imm4, imm1, imm3, imm8: INTEGER;
  280. BEGIN
  281. split16(imm12, imm4, imm1, imm3, imm8);
  282. Code(0F200H + LSL(imm1, 10) + r + 0A0H * ORD(sub)); (* addw/subw r, r, imm12 *)
  283. Code(LSL(imm3, 12) + LSL(r, 8) + imm8)
  284. END AddSubImm12;
  285. PROCEDURE MovImm8 (rd, imm8: INTEGER);
  286. BEGIN
  287. gen3(0, rd, imm8)
  288. END MovImm8;
  289. PROCEDURE CmpImm8 (rd, imm8: INTEGER);
  290. BEGIN
  291. gen3(1, rd, imm8)
  292. END CmpImm8;
  293. PROCEDURE Neg (r: INTEGER);
  294. BEGIN
  295. gen4(9, r, r)
  296. END Neg;
  297. PROCEDURE Mul (rd, rs: INTEGER);
  298. BEGIN
  299. gen4(13, rs, rd)
  300. END Mul;
  301. PROCEDURE Str32 (rs, rb: INTEGER);
  302. BEGIN
  303. gen9(FALSE, FALSE, 0, rb, rs)
  304. END Str32;
  305. PROCEDURE Ldr32 (rd, rb: INTEGER);
  306. BEGIN
  307. gen9(FALSE, TRUE, 0, rb, rd)
  308. END Ldr32;
  309. PROCEDURE Str16 (rs, rb: INTEGER);
  310. BEGIN
  311. gen10(FALSE, 0, rb, rs)
  312. END Str16;
  313. PROCEDURE Ldr16 (rd, rb: INTEGER);
  314. BEGIN
  315. gen10(TRUE, 0, rb, rd)
  316. END Ldr16;
  317. PROCEDURE Str8 (rs, rb: INTEGER);
  318. BEGIN
  319. gen9(TRUE, FALSE, 0, rb, rs)
  320. END Str8;
  321. PROCEDURE Ldr8 (rd, rb: INTEGER);
  322. BEGIN
  323. gen9(TRUE, TRUE, 0, rb, rd)
  324. END Ldr8;
  325. PROCEDURE Cmp (r1, r2: INTEGER);
  326. BEGIN
  327. gen4(10, r2, r1)
  328. END Cmp;
  329. PROCEDURE Tst (r: INTEGER);
  330. BEGIN
  331. gen3(1, r, 0) (* cmp r, 0 *)
  332. END Tst;
  333. PROCEDURE LdrSp (r, offset: INTEGER);
  334. BEGIN
  335. gen11(TRUE, r, offset)
  336. END LdrSp;
  337. PROCEDURE MovImm32 (r, imm32: INTEGER);
  338. BEGIN
  339. MovImm8(r, LSR(imm32, 24) MOD 256);
  340. LslImm(r, 8);
  341. AddImm8(r, LSR(imm32, 16) MOD 256);
  342. LslImm(r, 8);
  343. AddImm8(r, LSR(imm32, 8) MOD 256);
  344. LslImm(r, 8);
  345. AddImm8(r, imm32 MOD 256)
  346. END MovImm32;
  347. PROCEDURE low (x: INTEGER): INTEGER;
  348. RETURN x MOD 65536
  349. END low;
  350. PROCEDURE high (x: INTEGER): INTEGER;
  351. RETURN (x DIV 65536) MOD 65536
  352. END high;
  353. PROCEDURE movwt (r, imm16, t: INTEGER);
  354. VAR
  355. imm1, imm3, imm4, imm8: INTEGER;
  356. BEGIN
  357. ASSERT(range(r, 3));
  358. ASSERT(range(imm16, 16));
  359. ASSERT(range(t, 1));
  360. split16(imm16, imm4, imm1, imm3, imm8);
  361. Code(0F240H + imm1 * 1024 + t * 128 + imm4);
  362. Code(imm3 * 4096 + r * 256 + imm8);
  363. END movwt;
  364. PROCEDURE inv0 (cond: INTEGER): INTEGER;
  365. RETURN ORD(BITS(cond) / {0})
  366. END inv0;
  367. PROCEDURE fixup (CodeAdr, DataAdr, BssAdr: INTEGER);
  368. VAR
  369. code: ANYCODE;
  370. count: INTEGER;
  371. shorted: BOOLEAN;
  372. jump: JUMP;
  373. reloc, i, diff, len: INTEGER;
  374. RelocCode: RELOCCODE;
  375. PROCEDURE genjcc (cond, offset: INTEGER): INTEGER;
  376. BEGIN
  377. ASSERT(range(cond, 4));
  378. ASSERT(srange(offset, 8))
  379. RETURN 0D000H + cond * 256 + offset MOD 256
  380. END genjcc;
  381. PROCEDURE genjmp (offset: INTEGER): INTEGER;
  382. BEGIN
  383. ASSERT(srange(offset, 11))
  384. RETURN 0E000H + offset MOD 2048
  385. END genjmp;
  386. PROCEDURE movwt (r, imm16, t: INTEGER; VAR code: RELOCCODE);
  387. VAR
  388. imm1, imm3, imm4, imm8: INTEGER;
  389. BEGIN
  390. split16(imm16, imm4, imm1, imm3, imm8);
  391. code[t * 2] := 0F240H + imm1 * 1024 + t * 128 + imm4;
  392. code[t * 2 + 1] := imm3 * 4096 + r * 256 + imm8
  393. END movwt;
  394. PROCEDURE genmovimm32 (r, value: INTEGER; VAR code: RELOCCODE);
  395. BEGIN
  396. IF _THUMB2 IN Target.InstrSet THEN
  397. movwt(r, low(value), 0, code);
  398. movwt(r, high(value), 1, code)
  399. ELSE
  400. code[0] := 2000H + r * 256 + UTILS.Byte(value, 3); (* movs r, imm8 *)
  401. code[1] := 0200H + r * 9; (* lsls r, 8 *)
  402. code[2] := 3000H + r * 256 + UTILS.Byte(value, 2); (* adds r, imm8 *)
  403. code[3] := code[1]; (* lsls r, 8 *)
  404. code[4] := 3000H + r * 256 + UTILS.Byte(value, 1); (* adds r, imm8 *)
  405. code[5] := code[1]; (* lsls r, 8 *)
  406. code[6] := 3000H + r * 256 + UTILS.Byte(value, 0) (* adds r, imm8 *)
  407. END
  408. END genmovimm32;
  409. PROCEDURE PutCode (code: INTEGER);
  410. BEGIN
  411. BIN.PutCode16LE(program, code)
  412. END PutCode;
  413. PROCEDURE genlongjmp (offset: INTEGER);
  414. BEGIN
  415. ASSERT(srange(offset, 22));
  416. PutCode(0F000H + ASR(offset, 11) MOD 2048);
  417. PutCode(0F800H + offset MOD 2048)
  418. END genlongjmp;
  419. PROCEDURE genbc (code: JUMP);
  420. BEGIN
  421. CASE code.len OF
  422. |1: PutCode(genjcc(code.cond, code.diff))
  423. |2: PutCode(genjcc(inv0(code.cond), 0));
  424. PutCode(genjmp(code.diff))
  425. |3: PutCode(genjcc(inv0(code.cond), 1));
  426. genlongjmp(code.diff)
  427. END
  428. END genbc;
  429. PROCEDURE SetIV (idx, label, CodeAdr: INTEGER);
  430. VAR
  431. l, h: LISTS.ITEM;
  432. BEGIN
  433. l := CodeList.first;
  434. h := l.next;
  435. WHILE idx > 0 DO
  436. l := h.next;
  437. h := l.next;
  438. DEC(idx)
  439. END;
  440. label := BIN.GetLabel(program, label) * 2 + CodeAdr + 1;
  441. l(CODE).code := low(label);
  442. h(CODE).code := high(label)
  443. END SetIV;
  444. BEGIN
  445. REPEAT
  446. shorted := FALSE;
  447. count := 0;
  448. code := CodeList.first(ANYCODE);
  449. WHILE code # NIL DO
  450. code.offset := count;
  451. CASE code OF
  452. |CODE: INC(count)
  453. |LABEL: BIN.SetLabel(program, code.label, count)
  454. |JUMP: INC(count, code.len); code.offset := count + ORD(code.short)
  455. |RELOC: INC(count, 7 - ORD(_THUMB2 IN Target.InstrSet) * 3 + code.rel MOD 2)
  456. END;
  457. code := code.next(ANYCODE)
  458. END;
  459. code := CodeList.first(ANYCODE);
  460. WHILE code # NIL DO
  461. IF code IS JUMP THEN
  462. jump := code(JUMP);
  463. jump.diff := BIN.GetLabel(program, jump.label) - jump.offset;
  464. len := jump.len;
  465. diff := jump.diff;
  466. CASE jump OF
  467. |JMP:
  468. IF (len = 2) & srange(diff, 11) THEN
  469. len := 1
  470. END
  471. |JCC:
  472. CASE len OF
  473. |1:
  474. |2: IF srange(diff, 8) THEN DEC(len) END
  475. |3: IF srange(diff, 11) THEN DEC(len) END
  476. END
  477. |CBXZ:
  478. CASE len OF
  479. |1:
  480. |2: IF range(diff, 6) THEN DEC(len) END
  481. |3: IF srange(diff, 8) THEN DEC(len) END
  482. |4: IF srange(diff, 11) THEN DEC(len) END
  483. END
  484. |CALL:
  485. END;
  486. IF len # jump.len THEN
  487. jump.len := len;
  488. jump.short := TRUE;
  489. shorted := TRUE
  490. END
  491. END;
  492. code := code.next(ANYCODE)
  493. END
  494. UNTIL ~shorted;
  495. FOR i := 1 TO Target.IVTLen - 1 DO
  496. SetIV(i, IVT[i], CodeAdr)
  497. END;
  498. code := CodeList.first(ANYCODE);
  499. WHILE code # NIL DO
  500. CASE code OF
  501. |CODE: BIN.PutCode16LE(program, code.code)
  502. |LABEL:
  503. |JMP:
  504. IF code.len = 1 THEN
  505. PutCode(genjmp(code.diff))
  506. ELSE
  507. genlongjmp(code.diff)
  508. END
  509. |JCC: genbc(code)
  510. |CBXZ:
  511. IF code.len > 1 THEN
  512. PutCode(2800H + code.reg * 256); (* cmp code.reg, 0 *)
  513. DEC(code.len);
  514. genbc(code)
  515. ELSE
  516. (* cb(n)z code.reg, L *)
  517. PutCode(0B100H + 800H * ORD(code.cond = jne) + 200H * (code.diff DIV 32) + (code.diff MOD 32) * 8 + code.reg)
  518. END
  519. |CALL: genlongjmp(code.diff)
  520. |RELOC:
  521. CASE code.rel OF
  522. |BIN.RCODE, BIN.PICCODE: reloc := BIN.GetLabel(program, code.value) * 2 + CodeAdr
  523. |BIN.RDATA, BIN.PICDATA: reloc := code.value + DataAdr
  524. |BIN.RBSS, BIN.PICBSS: reloc := code.value + BssAdr
  525. END;
  526. IF code.rel IN {BIN.PICCODE, BIN.PICDATA, BIN.PICBSS} THEN
  527. DEC(reloc, CodeAdr + 2 * (code.offset - 3 * ORD(_THUMB2 IN Target.InstrSet) + 9))
  528. END;
  529. genmovimm32(code.reg, reloc, RelocCode);
  530. FOR i := 0 TO 6 - 3 * ORD(_THUMB2 IN Target.InstrSet) DO
  531. PutCode(RelocCode[i])
  532. END;
  533. IF code.rel IN {BIN.PICCODE, BIN.PICDATA, BIN.PICBSS} THEN
  534. PutCode(4478H + code.reg) (* add code.reg, pc *)
  535. END
  536. END;
  537. code := code.next(ANYCODE)
  538. END
  539. END fixup;
  540. PROCEDURE push (r: INTEGER);
  541. BEGIN
  542. gen14(FALSE, FALSE, {r})
  543. END push;
  544. PROCEDURE pop (r: INTEGER);
  545. BEGIN
  546. gen14(TRUE, FALSE, {r})
  547. END pop;
  548. PROCEDURE mov (r1, r2: INTEGER);
  549. BEGIN
  550. IF (r1 < 8) & (r2 < 8) THEN
  551. gen1(0, 0, r2, r1)
  552. ELSE
  553. gen5(2, r1 >= 8, r2 >= 8, r2 MOD 8, r1 MOD 8)
  554. END
  555. END mov;
  556. PROCEDURE xchg (r1, r2: INTEGER);
  557. BEGIN
  558. push(r1);
  559. mov(r1, r2);
  560. pop(r2)
  561. END xchg;
  562. PROCEDURE drop;
  563. BEGIN
  564. REG.Drop(R)
  565. END drop;
  566. PROCEDURE GetAnyReg (): INTEGER;
  567. RETURN REG.GetAnyReg(R)
  568. END GetAnyReg;
  569. PROCEDURE UnOp (VAR r: INTEGER);
  570. BEGIN
  571. REG.UnOp(R, r)
  572. END UnOp;
  573. PROCEDURE BinOp (VAR r1, r2: INTEGER);
  574. BEGIN
  575. REG.BinOp(R, r1, r2)
  576. END BinOp;
  577. PROCEDURE PushAll (NumberOfParameters: INTEGER);
  578. BEGIN
  579. REG.PushAll(R);
  580. DEC(R.pushed, NumberOfParameters)
  581. END PushAll;
  582. PROCEDURE cond (op: INTEGER): INTEGER;
  583. VAR
  584. res: INTEGER;
  585. BEGIN
  586. CASE op OF
  587. |IL.opGT, IL.opGTC: res := jg
  588. |IL.opGE, IL.opGEC: res := jge
  589. |IL.opLT, IL.opLTC: res := jl
  590. |IL.opLE, IL.opLEC: res := jle
  591. |IL.opEQ, IL.opEQC: res := je
  592. |IL.opNE, IL.opNEC: res := jne
  593. END
  594. RETURN res
  595. END cond;
  596. PROCEDURE GetRegA;
  597. BEGIN
  598. ASSERT(REG.GetReg(R, ACC))
  599. END GetRegA;
  600. PROCEDURE MovConst (r, c: INTEGER);
  601. BEGIN
  602. IF (0 <= c) & (c <= 255) THEN
  603. MovImm8(r, c)
  604. ELSIF (-255 <= c) & (c < 0) THEN
  605. MovImm8(r, -c);
  606. Neg(r)
  607. ELSIF UTILS.Log2(c) >= 0 THEN
  608. MovImm8(r, 1);
  609. LslImm(r, UTILS.Log2(c))
  610. ELSIF c = UTILS.min32 THEN
  611. MovImm8(r, 1);
  612. LslImm(r, 31)
  613. ELSE
  614. IF _THUMB2 IN Target.InstrSet THEN
  615. movwt(r, low(c), 0);
  616. IF (c < 0) OR (c > 65535) THEN
  617. movwt(r, high(c), 1)
  618. END
  619. ELSE
  620. MovImm32(r, c)
  621. END
  622. END
  623. END MovConst;
  624. PROCEDURE CmpConst (r, c: INTEGER);
  625. VAR
  626. r2: INTEGER;
  627. BEGIN
  628. IF (0 <= c) & (c <= 255) THEN
  629. CmpImm8(r, c)
  630. ELSE
  631. r2 := GetAnyReg();
  632. ASSERT(r2 # r);
  633. MovConst(r2, c);
  634. Cmp(r, r2);
  635. drop
  636. END
  637. END CmpConst;
  638. PROCEDURE LocalOffset (offset: INTEGER): INTEGER;
  639. RETURN offset + StkCount - ORD(offset > 0)
  640. END LocalOffset;
  641. PROCEDURE SetCC (cc, r: INTEGER);
  642. VAR
  643. L1, L2: INTEGER;
  644. BEGIN
  645. IF _IT IN Target.InstrSet THEN
  646. Code(0BF00H + cc * 16 + ((cc + 1) MOD 2) * 8 + 4); (* ite cc *)
  647. MovConst(r, 1);
  648. MovConst(r, 0)
  649. ELSE
  650. L1 := NewLabel();
  651. L2 := NewLabel();
  652. jcc(cc, L1);
  653. MovConst(r, 0);
  654. jmp(L2);
  655. Label(L1);
  656. MovConst(r, 1);
  657. Label(L2)
  658. END
  659. END SetCC;
  660. PROCEDURE PushConst (n: INTEGER);
  661. VAR
  662. r: INTEGER;
  663. BEGIN
  664. r := GetAnyReg();
  665. MovConst(r, n);
  666. push(r);
  667. drop
  668. END PushConst;
  669. PROCEDURE AddConst (r, n: INTEGER);
  670. VAR
  671. r2: INTEGER;
  672. BEGIN
  673. IF n # 0 THEN
  674. IF (-255 <= n) & (n <= 255) THEN
  675. IF n > 0 THEN
  676. AddImm8(r, n)
  677. ELSE
  678. SubImm8(r, -n)
  679. END
  680. ELSIF (_THUMB2 IN Target.InstrSet) & (-4095 <= n) & (n <= 4095) THEN
  681. AddSubImm12(r, ABS(n), n < 0)
  682. ELSE
  683. r2 := GetAnyReg();
  684. ASSERT(r2 # r);
  685. IF n > 0 THEN
  686. MovConst(r2, n);
  687. AddReg(r, r, r2)
  688. ELSE
  689. MovConst(r2, -n);
  690. SubReg(r, r, r2)
  691. END;
  692. drop
  693. END
  694. END
  695. END AddConst;
  696. PROCEDURE AddHH (r1, r2: INTEGER);
  697. BEGIN
  698. ASSERT((r1 >= 8) OR (r2 >= 8));
  699. gen5(0, r1 >= 8, r2 >= 8, r2 MOD 8, r1 MOD 8)
  700. END AddHH;
  701. PROCEDURE AddSP (n: INTEGER);
  702. BEGIN
  703. IF n > 0 THEN
  704. IF n < 127 THEN
  705. Code(0B000H + n) (* add sp, n*4 *)
  706. ELSE
  707. ASSERT(R2 IN R.regs);
  708. MovConst(R2, n * 4);
  709. AddHH(SP, R2)
  710. END;
  711. DEC(StkCount, n)
  712. END
  713. END AddSP;
  714. PROCEDURE cbxz2 (c, r, label: INTEGER);
  715. BEGIN
  716. IF _CBXZ IN Target.InstrSet THEN
  717. cbxz(c, r, label)
  718. ELSE
  719. Tst(r);
  720. jcc(c, label)
  721. END
  722. END cbxz2;
  723. PROCEDURE cbz (r, label: INTEGER);
  724. BEGIN
  725. cbxz2(je, r, label)
  726. END cbz;
  727. PROCEDURE cbnz (r, label: INTEGER);
  728. BEGIN
  729. cbxz2(jne, r, label)
  730. END cbnz;
  731. PROCEDURE Shift (op, r1, r2: INTEGER);
  732. VAR
  733. L: INTEGER;
  734. BEGIN
  735. LslImm(r2, 27);
  736. LsrImm(r2, 27);
  737. L := NewLabel();
  738. cbz(r2, L);
  739. CASE op OF
  740. |IL.opLSL, IL.opLSL1: gen4(2, r2, r1)
  741. |IL.opLSR, IL.opLSR1: gen4(3, r2, r1)
  742. |IL.opASR, IL.opASR1: gen4(4, r2, r1)
  743. |IL.opROR, IL.opROR1: gen4(7, r2, r1)
  744. END;
  745. Label(L)
  746. END Shift;
  747. PROCEDURE LocAdr (offs: INTEGER);
  748. VAR
  749. r1, n: INTEGER;
  750. BEGIN
  751. r1 := GetAnyReg();
  752. n := LocalOffset(offs);
  753. IF n <= 255 THEN
  754. gen12(TRUE, r1, n)
  755. ELSE
  756. MovConst(r1, n * 4);
  757. AddHH(r1, SP)
  758. END
  759. END LocAdr;
  760. PROCEDURE CallRTL (proc, par: INTEGER);
  761. BEGIN
  762. call(IL.codes.rtl[proc]);
  763. AddSP(par)
  764. END CallRTL;
  765. PROCEDURE divmod;
  766. BEGIN
  767. call(sdivProc);
  768. AddSP(2)
  769. END divmod;
  770. PROCEDURE cpsid_i;
  771. BEGIN
  772. Code(0B672H) (* cpsid i *)
  773. END cpsid_i;
  774. PROCEDURE cpsie_i;
  775. BEGIN
  776. Code(0B662H) (* cpsie i *)
  777. END cpsie_i;
  778. PROCEDURE translate (pic, stroffs: INTEGER);
  779. VAR
  780. cmd, next: COMMAND;
  781. opcode, param1, param2: INTEGER;
  782. r1, r2, r3: INTEGER;
  783. a, n, cc, L, L2: INTEGER;
  784. BEGIN
  785. cmd := IL.codes.commands.first(COMMAND);
  786. WHILE cmd # NIL DO
  787. param1 := cmd.param1;
  788. param2 := cmd.param2;
  789. opcode := cmd.opcode;
  790. CASE opcode OF
  791. |IL.opJMP:
  792. jmp(param1)
  793. |IL.opLABEL:
  794. Label(param1)
  795. |IL.opHANDLER:
  796. IF param2 = 0 THEN
  797. int0 := param1
  798. ELSIF param2 = 1 THEN
  799. trap := param1
  800. ELSE
  801. IVT[param2] := param1
  802. END
  803. |IL.opCALL:
  804. call(param1)
  805. |IL.opCALLP:
  806. UnOp(r1);
  807. AddImm8(r1, 1); (* Thumb mode *)
  808. gen5(3, TRUE, FALSE, r1, 0); (* blx r1 *)
  809. drop;
  810. ASSERT(R.top = -1)
  811. |IL.opENTER:
  812. ASSERT(R.top = -1);
  813. Label(param1);
  814. gen14(FALSE, TRUE, {}); (* push {lr} *)
  815. n := param2;
  816. IF n >= 5 THEN
  817. MovConst(ACC, 0);
  818. MovConst(R2, n);
  819. L := NewLabel();
  820. Label(L);
  821. push(ACC);
  822. SubImm8(R2, 1);
  823. Tst(R2);
  824. jcc(jne, L)
  825. ELSIF n > 0 THEN
  826. MovConst(ACC, 0);
  827. WHILE n > 0 DO
  828. push(ACC);
  829. DEC(n)
  830. END
  831. END;
  832. StkCount := param2
  833. |IL.opLEAVE, IL.opLEAVER, IL.opLEAVEF:
  834. IF opcode # IL.opLEAVE THEN
  835. UnOp(r1);
  836. IF r1 # ACC THEN
  837. mov(ACC, r1)
  838. END;
  839. drop
  840. END;
  841. ASSERT(R.top = -1);
  842. ASSERT(StkCount = param1);
  843. AddSP(param1);
  844. gen14(TRUE, TRUE, {}) (* pop {pc} *)
  845. |IL.opLEAVEC:
  846. gen5(3, FALSE, TRUE, 6, 0) (* bx lr *)
  847. |IL.opPRECALL:
  848. PushAll(0)
  849. |IL.opPARAM:
  850. IF param2 = 1 THEN
  851. UnOp(r1);
  852. push(r1);
  853. drop
  854. ELSE
  855. ASSERT(R.top + 1 <= param2);
  856. PushAll(param2)
  857. END
  858. |IL.opCLEANUP:
  859. AddSP(param2)
  860. |IL.opRES, IL.opRESF:
  861. ASSERT(R.top = -1);
  862. GetRegA
  863. |IL.opPUSHC:
  864. PushConst(param2)
  865. |IL.opONERR:
  866. cpsid_i;
  867. MovConst(R0, param2);
  868. push(R0);
  869. DEC(StkCount);
  870. jmp(param1)
  871. |IL.opERR:
  872. call(genTrap)
  873. |IL.opNOP, IL.opAND, IL.opOR:
  874. |IL.opSADR:
  875. reloc(GetAnyReg(), BIN.RDATA + pic, stroffs + param2)
  876. |IL.opGADR:
  877. reloc(GetAnyReg(), BIN.RBSS + pic, param2)
  878. |IL.opLADR:
  879. LocAdr(param2)
  880. |IL.opGLOAD32:
  881. r1 := GetAnyReg();
  882. reloc(r1, BIN.RBSS + pic, param2);
  883. Ldr32(r1, r1)
  884. |IL.opGLOAD16:
  885. r1 := GetAnyReg();
  886. reloc(r1, BIN.RBSS + pic, param2);
  887. Ldr16(r1, r1)
  888. |IL.opGLOAD8:
  889. r1 := GetAnyReg();
  890. reloc(r1, BIN.RBSS + pic, param2);
  891. Ldr8(r1, r1)
  892. |IL.opLADR_SAVE:
  893. UnOp(r1);
  894. n := LocalOffset(param2);
  895. IF n <= 255 THEN
  896. gen11(FALSE, r1, n) (* str r1, [sp, n*4] *)
  897. ELSE
  898. LocAdr(param2);
  899. BinOp(r1, r2);
  900. Str32(r1, r2);
  901. drop
  902. END;
  903. drop
  904. |IL.opLADR_INCC:
  905. n := LocalOffset(param1);
  906. IF n <= 255 THEN
  907. r1 := GetAnyReg();
  908. LdrSp(r1, n);
  909. AddConst(r1, param2);
  910. gen11(FALSE, r1, n) (* str r1, [sp, n*4] *)
  911. ELSE
  912. LocAdr(param1);
  913. r1 := GetAnyReg();
  914. BinOp(r2, r1);
  915. Ldr32(r1, r2);
  916. AddConst(r1, param2);
  917. BinOp(r2, r1);
  918. Str32(r1, r2);
  919. drop
  920. END;
  921. drop
  922. |IL.opLLOAD32, IL.opVADR, IL.opVLOAD32:
  923. r1 := GetAnyReg();
  924. n := LocalOffset(param2);
  925. IF n <= 255 THEN
  926. LdrSp(r1, n)
  927. ELSE
  928. drop;
  929. LocAdr(param2);
  930. UnOp(r1);
  931. Ldr32(r1, r1)
  932. END;
  933. IF opcode = IL.opVLOAD32 THEN
  934. Ldr32(r1, r1)
  935. END
  936. |IL.opLLOAD16:
  937. LocAdr(param2);
  938. UnOp(r1);
  939. Ldr16(r1, r1)
  940. |IL.opLLOAD8:
  941. LocAdr(param2);
  942. UnOp(r1);
  943. Ldr8(r1, r1)
  944. |IL.opLOAD32, IL.opLOADF:
  945. UnOp(r1);
  946. Ldr32(r1, r1)
  947. |IL.opLOAD16:
  948. UnOp(r1);
  949. Ldr16(r1, r1)
  950. |IL.opLOAD8:
  951. UnOp(r1);
  952. Ldr8(r1, r1)
  953. |IL.opVLOAD16:
  954. LocAdr(param2);
  955. UnOp(r1);
  956. Ldr32(r1, r1);
  957. Ldr16(r1, r1)
  958. |IL.opVLOAD8:
  959. LocAdr(param2);
  960. UnOp(r1);
  961. Ldr32(r1, r1);
  962. Ldr8(r1, r1)
  963. |IL.opSBOOL:
  964. BinOp(r2, r1);
  965. Tst(r2);
  966. SetCC(jne, r2);
  967. Str8(r2, r1);
  968. drop;
  969. drop
  970. |IL.opSBOOLC:
  971. UnOp(r1);
  972. r2 := GetAnyReg();
  973. MovConst(r2, ORD(param2 # 0));
  974. Str8(r2, r1);
  975. drop;
  976. drop
  977. |IL.opSAVEC:
  978. UnOp(r1);
  979. r2 := GetAnyReg();
  980. MovConst(r2, param2);
  981. Str32(r2, r1);
  982. drop;
  983. drop
  984. |IL.opSAVE16C:
  985. UnOp(r1);
  986. r2 := GetAnyReg();
  987. MovConst(r2, low(param2));
  988. Str16(r2, r1);
  989. drop;
  990. drop
  991. |IL.opSAVE8C:
  992. UnOp(r1);
  993. r2 := GetAnyReg();
  994. MovConst(r2, param2 MOD 256);
  995. Str8(r2, r1);
  996. drop;
  997. drop
  998. |IL.opSAVE, IL.opSAVE32, IL.opSAVEF:
  999. BinOp(r2, r1);
  1000. Str32(r2, r1);
  1001. drop;
  1002. drop
  1003. |IL.opSAVEFI:
  1004. BinOp(r2, r1);
  1005. Str32(r1, r2);
  1006. drop;
  1007. drop
  1008. |IL.opSAVE16:
  1009. BinOp(r2, r1);
  1010. Str16(r2, r1);
  1011. drop;
  1012. drop
  1013. |IL.opSAVE8:
  1014. BinOp(r2, r1);
  1015. Str8(r2, r1);
  1016. drop;
  1017. drop
  1018. |IL.opSAVEP:
  1019. UnOp(r1);
  1020. r2 := GetAnyReg();
  1021. reloc(r2, BIN.RCODE + pic, param2);
  1022. Str32(r2, r1);
  1023. drop;
  1024. drop
  1025. |IL.opPUSHP:
  1026. reloc(GetAnyReg(), BIN.RCODE + pic, param2)
  1027. |IL.opEQB, IL.opNEB:
  1028. BinOp(r1, r2);
  1029. drop;
  1030. L := NewLabel();
  1031. cbz(r1, L);
  1032. MovConst(r1, 1);
  1033. Label(L);
  1034. L := NewLabel();
  1035. cbz(r2, L);
  1036. MovConst(r2, 1);
  1037. Label(L);
  1038. Cmp(r1, r2);
  1039. IF opcode = IL.opEQB THEN
  1040. SetCC(je, r1)
  1041. ELSE
  1042. SetCC(jne, r1)
  1043. END
  1044. |IL.opDROP:
  1045. UnOp(r1);
  1046. drop
  1047. |IL.opJNZ1:
  1048. UnOp(r1);
  1049. cbnz(r1, param1)
  1050. |IL.opJG:
  1051. UnOp(r1);
  1052. Tst(r1);
  1053. jcc(jg, param1)
  1054. |IL.opJNZ:
  1055. UnOp(r1);
  1056. cbnz(r1, param1);
  1057. drop
  1058. |IL.opJZ:
  1059. UnOp(r1);
  1060. cbz(r1, param1);
  1061. drop
  1062. |IL.opSWITCH:
  1063. UnOp(r1);
  1064. IF param2 = 0 THEN
  1065. r2 := ACC
  1066. ELSE
  1067. r2 := R2
  1068. END;
  1069. IF r1 # r2 THEN
  1070. ASSERT(REG.GetReg(R, r2));
  1071. ASSERT(REG.Exchange(R, r1, r2));
  1072. drop
  1073. END;
  1074. drop
  1075. |IL.opENDSW:
  1076. |IL.opCASEL:
  1077. GetRegA;
  1078. CmpConst(ACC, param1);
  1079. jcc(jl, param2);
  1080. drop
  1081. |IL.opCASER:
  1082. GetRegA;
  1083. CmpConst(ACC, param1);
  1084. jcc(jg, param2);
  1085. drop
  1086. |IL.opCASELR:
  1087. GetRegA;
  1088. CmpConst(ACC, param1);
  1089. IF param2 = cmd.param3 THEN
  1090. jcc(jne, param2)
  1091. ELSE
  1092. jcc(jl, param2);
  1093. jcc(jg, cmd.param3)
  1094. END;
  1095. drop
  1096. |IL.opCODE:
  1097. Code(param2)
  1098. |IL.opEQ..IL.opGE,
  1099. IL.opEQC..IL.opGEC:
  1100. IF (IL.opEQ <= opcode) & (opcode <= IL.opGE) THEN
  1101. BinOp(r1, r2);
  1102. Cmp(r1, r2);
  1103. drop
  1104. ELSE
  1105. UnOp(r1);
  1106. CmpConst(r1, param2)
  1107. END;
  1108. drop;
  1109. cc := cond(opcode);
  1110. next := cmd.next(COMMAND);
  1111. IF next.opcode = IL.opJNZ THEN
  1112. jcc(cc, next.param1);
  1113. cmd := next
  1114. ELSIF next.opcode = IL.opJZ THEN
  1115. jcc(inv0(cc), next.param1);
  1116. cmd := next
  1117. ELSE
  1118. SetCC(cc, GetAnyReg())
  1119. END
  1120. |IL.opINCC:
  1121. UnOp(r1);
  1122. r2 := GetAnyReg();
  1123. Ldr32(r2, r1);
  1124. AddConst(r2, param2);
  1125. Str32(r2, r1);
  1126. drop;
  1127. drop
  1128. |IL.opINCCB, IL.opDECCB:
  1129. IF opcode = IL.opDECCB THEN
  1130. param2 := -param2
  1131. END;
  1132. UnOp(r1);
  1133. r2 := GetAnyReg();
  1134. Ldr8(r2, r1);
  1135. AddConst(r2, param2);
  1136. Str8(r2, r1);
  1137. drop;
  1138. drop
  1139. |IL.opUMINUS:
  1140. UnOp(r1);
  1141. Neg(r1)
  1142. |IL.opADD:
  1143. BinOp(r1, r2);
  1144. CASE cmd.next(COMMAND).opcode OF
  1145. |IL.opLOAD32, IL.opLOADF:
  1146. gen7(TRUE, FALSE, r2, r1, r1); (* ldr r1, [r1, r2] *)
  1147. cmd := cmd.next(COMMAND)
  1148. |IL.opLOAD8:
  1149. gen7(TRUE, TRUE, r2, r1, r1); (* ldrb r1, [r1, r2] *)
  1150. cmd := cmd.next(COMMAND)
  1151. |IL.opLOAD16:
  1152. gen8(TRUE, FALSE, r2, r1, r1); (* ldrh r1, [r1, r2] *)
  1153. cmd := cmd.next(COMMAND)
  1154. ELSE
  1155. AddReg(r1, r1, r2)
  1156. END;
  1157. drop
  1158. |IL.opADDC:
  1159. UnOp(r1);
  1160. AddConst(r1, param2)
  1161. |IL.opSUB:
  1162. BinOp(r1, r2);
  1163. SubReg(r1, r1, r2);
  1164. drop
  1165. |IL.opSUBL, IL.opSUBR:
  1166. UnOp(r1);
  1167. AddConst(r1, -param2);
  1168. IF opcode = IL.opSUBL THEN
  1169. Neg(r1)
  1170. END
  1171. |IL.opMUL:
  1172. BinOp(r1, r2);
  1173. Mul(r1, r2);
  1174. drop
  1175. |IL.opMULC:
  1176. UnOp(r1);
  1177. a := param2;
  1178. IF a > 1 THEN
  1179. n := UTILS.Log2(a)
  1180. ELSIF a < -1 THEN
  1181. n := UTILS.Log2(-a)
  1182. ELSE
  1183. n := -1
  1184. END;
  1185. IF a = 1 THEN
  1186. ELSIF a = -1 THEN
  1187. Neg(r1)
  1188. ELSIF a = 0 THEN
  1189. MovConst(r1, 0)
  1190. ELSE
  1191. IF n > 0 THEN
  1192. IF a < 0 THEN
  1193. Neg(r1)
  1194. END;
  1195. LslImm(r1, n)
  1196. ELSE
  1197. r2 := GetAnyReg();
  1198. MovConst(r2, a);
  1199. Mul(r1, r2);
  1200. drop
  1201. END
  1202. END
  1203. |IL.opABS:
  1204. UnOp(r1);
  1205. Tst(r1);
  1206. L := NewLabel();
  1207. jcc(jge, L);
  1208. Neg(r1);
  1209. Label(L)
  1210. |IL.opNOT:
  1211. UnOp(r1);
  1212. Tst(r1);
  1213. SetCC(je, r1)
  1214. |IL.opORD:
  1215. UnOp(r1);
  1216. Tst(r1);
  1217. SetCC(jne, r1)
  1218. |IL.opASR, IL.opROR, IL.opLSL, IL.opLSR:
  1219. BinOp(r1, r2);
  1220. Shift(opcode, r1, r2);
  1221. drop
  1222. |IL.opASR1, IL.opROR1, IL.opLSL1, IL.opLSR1:
  1223. MovConst(GetAnyReg(), param2);
  1224. BinOp(r2, r1);
  1225. Shift(opcode, r1, r2);
  1226. INCL(R.regs, r2);
  1227. DEC(R.top);
  1228. R.stk[R.top] := r1
  1229. |IL.opASR2, IL.opROR2, IL.opLSL2, IL.opLSR2:
  1230. n := param2 MOD 32;
  1231. IF n # 0 THEN
  1232. UnOp(r1);
  1233. CASE opcode OF
  1234. |IL.opASR2: AsrImm(r1, n)
  1235. |IL.opROR2: r2 := GetAnyReg(); MovConst(r2, n); Shift(IL.opROR, r1, r2); drop
  1236. |IL.opLSL2: LslImm(r1, n)
  1237. |IL.opLSR2: LsrImm(r1, n)
  1238. END
  1239. END
  1240. |IL.opCHKIDX:
  1241. UnOp(r1);
  1242. CmpConst(r1, param2);
  1243. jcc(jb, param1)
  1244. |IL.opCHKIDX2:
  1245. BinOp(r1, r2);
  1246. IF param2 # -1 THEN
  1247. Cmp(r2, r1);
  1248. jcc(jb, param1)
  1249. END;
  1250. INCL(R.regs, r1);
  1251. DEC(R.top);
  1252. R.stk[R.top] := r2
  1253. |IL.opLEN:
  1254. n := param2;
  1255. UnOp(r1);
  1256. drop;
  1257. EXCL(R.regs, r1);
  1258. WHILE n > 0 DO
  1259. UnOp(r2);
  1260. drop;
  1261. DEC(n)
  1262. END;
  1263. INCL(R.regs, r1);
  1264. ASSERT(REG.GetReg(R, r1))
  1265. |IL.opINF:
  1266. MovConst(GetAnyReg(), inf)
  1267. |IL.opPUSHF:
  1268. UnOp(r1);
  1269. push(r1);
  1270. drop
  1271. |IL.opCONST:
  1272. MovConst(GetAnyReg(), param2)
  1273. |IL.opEQP, IL.opNEP:
  1274. reloc(GetAnyReg(), BIN.RCODE + pic, param1);
  1275. BinOp(r1, r2);
  1276. Cmp(r1, r2);
  1277. drop;
  1278. IF opcode = IL.opEQP THEN
  1279. SetCC(je, r1)
  1280. ELSE
  1281. SetCC(jne, r1)
  1282. END
  1283. |IL.opPUSHT:
  1284. UnOp(r1);
  1285. r2 := GetAnyReg();
  1286. mov(r2, r1);
  1287. SubImm8(r2, 4);
  1288. Ldr32(r2, r2)
  1289. |IL.opGET, IL.opGETC:
  1290. IF opcode = IL.opGET THEN
  1291. BinOp(r1, r2)
  1292. ELSIF opcode = IL.opGETC THEN
  1293. UnOp(r2);
  1294. r1 := GetAnyReg();
  1295. MovConst(r1, param1)
  1296. END;
  1297. drop;
  1298. drop;
  1299. CASE param2 OF
  1300. |1: Ldr8(r1, r1); Str8(r1, r2)
  1301. |2: Ldr16(r1, r1); Str16(r1, r2)
  1302. |4: Ldr32(r1, r1); Str32(r1, r2)
  1303. END
  1304. |IL.opINC, IL.opDEC:
  1305. BinOp(r2, r1);
  1306. r3 := GetAnyReg();
  1307. Ldr32(r3, r1);
  1308. IF opcode = IL.opINC THEN
  1309. AddReg(r3, r3, r2)
  1310. ELSE
  1311. SubReg(r3, r3, r2)
  1312. END;
  1313. Str32(r3, r1);
  1314. drop;
  1315. drop;
  1316. drop
  1317. |IL.opINCB, IL.opDECB:
  1318. BinOp(r2, r1);
  1319. r3 := GetAnyReg();
  1320. Ldr8(r3, r1);
  1321. IF opcode = IL.opINCB THEN
  1322. AddReg(r3, r3, r2)
  1323. ELSE
  1324. SubReg(r3, r3, r2)
  1325. END;
  1326. Str8(r3, r1);
  1327. drop;
  1328. drop;
  1329. drop
  1330. |IL.opMIN, IL.opMAX:
  1331. BinOp(r1, r2);
  1332. Cmp(r1, r2);
  1333. L := NewLabel();
  1334. IF opcode = IL.opMIN THEN
  1335. cc := jle
  1336. ELSE
  1337. cc := jge
  1338. END;
  1339. jcc(cc, L);
  1340. mov(r1, r2);
  1341. Label(L);
  1342. drop
  1343. |IL.opMINC, IL.opMAXC:
  1344. UnOp(r1);
  1345. CmpConst(r1, param2);
  1346. L := NewLabel();
  1347. IF opcode = IL.opMINC THEN
  1348. cc := jle
  1349. ELSE
  1350. cc := jge
  1351. END;
  1352. jcc(cc, L);
  1353. MovConst(r1, param2);
  1354. Label(L)
  1355. |IL.opMULS:
  1356. BinOp(r1, r2);
  1357. gen4(0, r2, r1); (* ands r1, r2 *)
  1358. drop
  1359. |IL.opMULSC:
  1360. MovConst(GetAnyReg(), param2);
  1361. BinOp(r1, r2);
  1362. gen4(0, r2, r1); (* ands r1, r2 *)
  1363. drop
  1364. |IL.opDIVS:
  1365. BinOp(r1, r2);
  1366. gen4(1, r2, r1); (* eors r1, r2 *)
  1367. drop
  1368. |IL.opDIVSC:
  1369. MovConst(GetAnyReg(), param2);
  1370. BinOp(r1, r2);
  1371. gen4(1, r2, r1); (* eors r1, r2 *)
  1372. drop
  1373. |IL.opADDS:
  1374. BinOp(r1, r2);
  1375. gen4(12, r2, r1); (* orrs r1, r2 *)
  1376. drop
  1377. |IL.opSUBS:
  1378. BinOp(r1, r2);
  1379. gen4(14, r2, r1); (* bics r1, r2 *)
  1380. drop
  1381. |IL.opADDSC:
  1382. MovConst(GetAnyReg(), param2);
  1383. BinOp(r1, r2);
  1384. gen4(12, r2, r1); (* orrs r1, r2 *)
  1385. drop
  1386. |IL.opSUBSL:
  1387. MovConst(GetAnyReg(), param2);
  1388. BinOp(r1, r2);
  1389. gen4(14, r1, r2); (* bics r2, r1 *)
  1390. INCL(R.regs, r1);
  1391. DEC(R.top);
  1392. R.stk[R.top] := r2
  1393. |IL.opSUBSR:
  1394. MovConst(GetAnyReg(), param2);
  1395. BinOp(r1, r2);
  1396. gen4(14, r2, r1); (* bics r1, r2 *)
  1397. drop
  1398. |IL.opUMINS:
  1399. UnOp(r1);
  1400. gen4(15, r1, r1) (* mvns r1, r1 *)
  1401. |IL.opINCL, IL.opEXCL:
  1402. BinOp(r1, r2);
  1403. r3 := GetAnyReg();
  1404. MovConst(r3, 1);
  1405. CmpConst(r1, 32);
  1406. L := NewLabel();
  1407. jcc(jnb, L);
  1408. gen4(2, r1, r3); (* lsls r3, r1 *)
  1409. Ldr32(r1, r2);
  1410. IF opcode = IL.opINCL THEN
  1411. gen4(12, r3, r1) (* orrs r1, r3 *)
  1412. ELSE
  1413. gen4(14, r3, r1) (* bics r1, r3 *)
  1414. END;
  1415. Str32(r1, r2);
  1416. Label(L);
  1417. drop;
  1418. drop;
  1419. drop
  1420. |IL.opINCLC, IL.opEXCLC:
  1421. UnOp(r2);
  1422. r1 := GetAnyReg();
  1423. r3 := GetAnyReg();
  1424. MovConst(r3, 1);
  1425. LslImm(r3, param2);
  1426. Ldr32(r1, r2);
  1427. IF opcode = IL.opINCLC THEN
  1428. gen4(12, r3, r1) (* orrs r1, r3 *)
  1429. ELSE
  1430. gen4(14, r3, r1) (* bics r1, r3 *)
  1431. END;
  1432. Str32(r1, r2);
  1433. drop;
  1434. drop;
  1435. drop
  1436. |IL.opLENGTH:
  1437. PushAll(2);
  1438. CallRTL(IL._length, 2);
  1439. GetRegA
  1440. |IL.opLENGTHW:
  1441. PushAll(2);
  1442. CallRTL(IL._lengthw, 2);
  1443. GetRegA
  1444. |IL.opSAVES:
  1445. UnOp(r2);
  1446. REG.PushAll_1(R);
  1447. r1 := GetAnyReg();
  1448. reloc(r1, BIN.RDATA + pic, stroffs + param2);
  1449. push(r1);
  1450. drop;
  1451. push(r2);
  1452. drop;
  1453. PushConst(param1);
  1454. CallRTL(IL._move, 3)
  1455. |IL.opEQS .. IL.opGES:
  1456. PushAll(4);
  1457. PushConst(opcode - IL.opEQS);
  1458. CallRTL(IL._strcmp, 5);
  1459. GetRegA
  1460. |IL.opEQSW .. IL.opGESW:
  1461. PushAll(4);
  1462. PushConst(opcode - IL.opEQSW);
  1463. CallRTL(IL._strcmpw, 5);
  1464. GetRegA
  1465. |IL.opCOPY:
  1466. PushAll(2);
  1467. PushConst(param2);
  1468. CallRTL(IL._move, 3)
  1469. |IL.opMOVE:
  1470. PushAll(3);
  1471. CallRTL(IL._move, 3)
  1472. |IL.opCOPYA:
  1473. PushAll(4);
  1474. PushConst(param2);
  1475. CallRTL(IL._arrcpy, 5);
  1476. GetRegA
  1477. |IL.opCOPYS:
  1478. PushAll(4);
  1479. PushConst(param2);
  1480. CallRTL(IL._strcpy, 5)
  1481. |IL.opDIV:
  1482. PushAll(2);
  1483. divmod;
  1484. GetRegA
  1485. |IL.opDIVL:
  1486. UnOp(r1);
  1487. REG.PushAll_1(R);
  1488. PushConst(param2);
  1489. push(r1);
  1490. drop;
  1491. divmod;
  1492. GetRegA
  1493. |IL.opDIVR:
  1494. n := UTILS.Log2(param2);
  1495. IF n > 0 THEN
  1496. UnOp(r1);
  1497. AsrImm(r1, n)
  1498. ELSIF n < 0 THEN
  1499. PushAll(1);
  1500. PushConst(param2);
  1501. divmod;
  1502. GetRegA
  1503. END
  1504. |IL.opMOD:
  1505. PushAll(2);
  1506. divmod;
  1507. mov(R0, R1);
  1508. GetRegA
  1509. |IL.opMODR:
  1510. n := UTILS.Log2(param2);
  1511. IF n > 0 THEN
  1512. UnOp(r1);
  1513. IF n = 8 THEN
  1514. Code(0B2C0H + r1 * 9) (* uxtb r1, r1 *)
  1515. ELSIF n = 16 THEN
  1516. Code(0B280H + r1 * 9) (* uxth r1, r1 *)
  1517. ELSE
  1518. LslImm(r1, 32 - n);
  1519. LsrImm(r1, 32 - n)
  1520. END
  1521. ELSIF n < 0 THEN
  1522. PushAll(1);
  1523. PushConst(param2);
  1524. divmod;
  1525. mov(R0, R1);
  1526. GetRegA
  1527. ELSE
  1528. UnOp(r1);
  1529. MovConst(r1, 0)
  1530. END
  1531. |IL.opMODL:
  1532. UnOp(r1);
  1533. REG.PushAll_1(R);
  1534. PushConst(param2);
  1535. push(r1);
  1536. drop;
  1537. divmod;
  1538. mov(R0, R1);
  1539. GetRegA
  1540. |IL.opIN, IL.opINR:
  1541. IF opcode = IL.opINR THEN
  1542. r2 := GetAnyReg();
  1543. MovConst(r2, param2)
  1544. END;
  1545. L := NewLabel();
  1546. L2 := NewLabel();
  1547. BinOp(r1, r2);
  1548. r3 := GetAnyReg();
  1549. CmpConst(r1, 32);
  1550. jcc(jb, L);
  1551. MovConst(r1, 0);
  1552. jmp(L2);
  1553. Label(L);
  1554. MovConst(r3, 1);
  1555. Shift(IL.opLSL, r3, r1);
  1556. gen4(0, r3, r2); (* ands r2, r3 *)
  1557. SetCC(jne, r1);
  1558. Label(L2);
  1559. drop;
  1560. drop
  1561. |IL.opINL:
  1562. UnOp(r1);
  1563. r2 := GetAnyReg();
  1564. MovConst(r2, LSL(1, param2));
  1565. gen4(0, r2, r1); (* ands r1, r2 *)
  1566. SetCC(jne, r1);
  1567. drop
  1568. |IL.opRSET:
  1569. PushAll(2);
  1570. CallRTL(IL._set, 2);
  1571. GetRegA
  1572. |IL.opRSETR:
  1573. PushAll(1);
  1574. PushConst(param2);
  1575. CallRTL(IL._set, 2);
  1576. GetRegA
  1577. |IL.opRSETL:
  1578. UnOp(r1);
  1579. REG.PushAll_1(R);
  1580. PushConst(param2);
  1581. push(r1);
  1582. drop;
  1583. CallRTL(IL._set, 2);
  1584. GetRegA
  1585. |IL.opRSET1:
  1586. PushAll(1);
  1587. CallRTL(IL._set1, 1);
  1588. GetRegA
  1589. |IL.opCONSTF:
  1590. MovConst(GetAnyReg(), UTILS.d2s(cmd.float))
  1591. |IL.opMULF:
  1592. PushAll(2);
  1593. CallRTL(IL._fmul, 2);
  1594. GetRegA
  1595. |IL.opDIVF:
  1596. PushAll(2);
  1597. CallRTL(IL._fdiv, 2);
  1598. GetRegA
  1599. |IL.opDIVFI:
  1600. PushAll(2);
  1601. CallRTL(IL._fdivi, 2);
  1602. GetRegA
  1603. |IL.opADDF:
  1604. PushAll(2);
  1605. CallRTL(IL._fadd, 2);
  1606. GetRegA
  1607. |IL.opSUBFI:
  1608. PushAll(2);
  1609. CallRTL(IL._fsubi, 2);
  1610. GetRegA
  1611. |IL.opSUBF:
  1612. PushAll(2);
  1613. CallRTL(IL._fsub, 2);
  1614. GetRegA
  1615. |IL.opEQF..IL.opGEF:
  1616. PushAll(2);
  1617. PushConst(opcode - IL.opEQF);
  1618. CallRTL(IL._fcmp, 3);
  1619. GetRegA
  1620. |IL.opFLOOR:
  1621. PushAll(1);
  1622. CallRTL(IL._floor, 1);
  1623. GetRegA
  1624. |IL.opFLT:
  1625. PushAll(1);
  1626. CallRTL(IL._flt, 1);
  1627. GetRegA
  1628. |IL.opUMINF:
  1629. UnOp(r1);
  1630. r2 := GetAnyReg();
  1631. MovConst(r2, 1);
  1632. LslImm(r2, 31);
  1633. gen4(1, r2, r1); (* eors r1, r2 *)
  1634. drop
  1635. |IL.opFABS:
  1636. UnOp(r1);
  1637. r2 := GetAnyReg();
  1638. MovConst(r2, 1);
  1639. LslImm(r2, 31);
  1640. gen4(14, r2, r1); (* bics r1, r2 *)
  1641. drop
  1642. |IL.opNEW:
  1643. cpsid_i;
  1644. PushAll(1);
  1645. n := param2 + 4;
  1646. ASSERT(UTILS.Align(n, 4));
  1647. PushConst(n);
  1648. PushConst(param1);
  1649. CallRTL(IL._new, 3);
  1650. cpsie_i
  1651. |IL.opTYPEGP:
  1652. UnOp(r1);
  1653. PushAll(0);
  1654. push(r1);
  1655. PushConst(param2);
  1656. CallRTL(IL._guard, 2);
  1657. GetRegA
  1658. |IL.opIS:
  1659. PushAll(1);
  1660. PushConst(param2);
  1661. CallRTL(IL._is, 2);
  1662. GetRegA
  1663. |IL.opISREC:
  1664. PushAll(2);
  1665. PushConst(param2);
  1666. CallRTL(IL._guardrec, 3);
  1667. GetRegA
  1668. |IL.opTYPEGR:
  1669. PushAll(1);
  1670. PushConst(param2);
  1671. CallRTL(IL._guardrec, 2);
  1672. GetRegA
  1673. |IL.opTYPEGD:
  1674. UnOp(r1);
  1675. PushAll(0);
  1676. SubImm8(r1, 4);
  1677. Ldr32(r1, r1);
  1678. push(r1);
  1679. PushConst(param2);
  1680. CallRTL(IL._guardrec, 2);
  1681. GetRegA
  1682. |IL.opCASET:
  1683. push(R2);
  1684. push(R2);
  1685. PushConst(param2);
  1686. CallRTL(IL._guardrec, 2);
  1687. pop(R2);
  1688. cbnz(ACC, param1)
  1689. |IL.opROT:
  1690. PushAll(0);
  1691. mov(R2, SP);
  1692. push(R2);
  1693. PushConst(param2);
  1694. CallRTL(IL._rot, 2)
  1695. |IL.opPACK:
  1696. PushAll(2);
  1697. CallRTL(IL._pack, 2)
  1698. |IL.opPACKC:
  1699. PushAll(1);
  1700. PushConst(param2);
  1701. CallRTL(IL._pack, 2)
  1702. |IL.opUNPK:
  1703. PushAll(2);
  1704. CallRTL(IL._unpk, 2)
  1705. END;
  1706. cmd := cmd.next(COMMAND)
  1707. END;
  1708. ASSERT(R.pushed = 0);
  1709. ASSERT(R.top = -1)
  1710. END translate;
  1711. PROCEDURE prolog (GlobSize, tcount, pic, sp, ivt_len: INTEGER);
  1712. VAR
  1713. r1, r2, i, dcount: INTEGER;
  1714. BEGIN
  1715. entry := NewLabel();
  1716. emptyProc := NewLabel();
  1717. genInt := NewLabel();
  1718. genTrap := NewLabel();
  1719. sdivProc := NewLabel();
  1720. trap := emptyProc;
  1721. int0 := emptyProc;
  1722. IVT[0] := sp;
  1723. IVT[1] := entry;
  1724. FOR i := 2 TO ivt_len - 1 DO
  1725. IVT[i] := genInt
  1726. END;
  1727. FOR i := 0 TO ivt_len - 1 DO
  1728. Code(low(IVT[i]));
  1729. Code(high(IVT[i]))
  1730. END;
  1731. Label(entry);
  1732. cpsie_i;
  1733. r1 := GetAnyReg();
  1734. r2 := GetAnyReg();
  1735. reloc(r1, BIN.RDATA + pic, 0);
  1736. FOR i := 0 TO tcount - 1 DO
  1737. MovConst(r2, CHL.GetInt(IL.codes.types, i));
  1738. Str32(r2, r1);
  1739. AddImm8(r1, 4)
  1740. END;
  1741. dcount := CHL.Length(IL.codes.data);
  1742. FOR i := 0 TO dcount - 1 BY 4 DO
  1743. MovConst(r2, BIN.get32le(IL.codes.data, i));
  1744. Str32(r2, r1);
  1745. AddImm8(r1, 4)
  1746. END;
  1747. drop;
  1748. drop;
  1749. r1 := GetAnyReg();
  1750. MovConst(r1, sp);
  1751. mov(SP, r1);
  1752. reloc(r1, BIN.RDATA + pic, 0);
  1753. push(r1);
  1754. reloc(r1, BIN.RBSS + pic, 0);
  1755. r2 := GetAnyReg();
  1756. MovConst(r2, GlobSize);
  1757. AddReg(r1, r1, r2);
  1758. drop;
  1759. push(r1);
  1760. drop;
  1761. PushConst(tcount);
  1762. CallRTL(IL._init, 3)
  1763. END prolog;
  1764. PROCEDURE epilog;
  1765. VAR
  1766. L1, L2, L3, L4: INTEGER;
  1767. BEGIN
  1768. (* L2: *)
  1769. Code(0E7FEH); (* b L2 *)
  1770. Label(genInt);
  1771. Code(0F3EFH); Code(08005H); (* mrs r0, ipsr *)
  1772. gen14(FALSE, TRUE, {R0}); (* push {lr, r0} *)
  1773. call(int0);
  1774. gen14(TRUE, TRUE, {R0}); (* pop {pc, r0} *)
  1775. Label(emptyProc);
  1776. Code(04770H); (* bx lr *)
  1777. Label(genTrap);
  1778. call(trap);
  1779. call(entry);
  1780. Label(sdivProc);
  1781. IF _SDIV IN Target.InstrSet THEN
  1782. Code(09800H); (* ldr r0, [sp] *)
  1783. Code(09901H); (* ldr r1, [sp, 4] *)
  1784. Code(0FB91H); (* sdiv r2, r1, r0 *)
  1785. Code(0F2F0H);
  1786. Code(00013H); (* movs r3, r2 *)
  1787. Code(04343H); (* muls r3, r0, r3 *)
  1788. Code(01AC9H); (* subs r1, r1, r3 *)
  1789. Code(0DA01H); (* bge L *)
  1790. Code(01809H); (* adds r1, r1, r0 *)
  1791. Code(03A01H); (* subs r2, 1 *)
  1792. (* L: *)
  1793. Code(00010H); (* movs r0, r2 *)
  1794. Code(04770H); (* bx lr *)
  1795. ELSE
  1796. (* a / b; a >= 0 *)
  1797. L1 := NewLabel();
  1798. L2 := NewLabel();
  1799. L3 := NewLabel();
  1800. L4 := NewLabel();
  1801. LdrSp(R1, 1);
  1802. LdrSp(R2, 0);
  1803. MovConst(R0, 0);
  1804. push(R4);
  1805. Label(L4);
  1806. Cmp(R1, R2);
  1807. jcc(jl, L1);
  1808. MovConst(R3, 2);
  1809. mov(R4, R2);
  1810. LslImm(R4, 1);
  1811. Label(L3);
  1812. Cmp(R1, R4);
  1813. jcc(jl, L2);
  1814. CmpConst(R4, 0);
  1815. jcc(jle, L2);
  1816. LslImm(R4, 1);
  1817. LslImm(R3, 1);
  1818. jmp(L3);
  1819. Label(L2);
  1820. LsrImm(R4, 1);
  1821. LsrImm(R3, 1);
  1822. SubReg(R1, R1, R4);
  1823. AddReg(R0, R0, R3);
  1824. jmp(L4);
  1825. Label(L1);
  1826. (* a / b; a < 0 *)
  1827. L1 := NewLabel();
  1828. L2 := NewLabel();
  1829. L3 := NewLabel();
  1830. L4 := NewLabel();
  1831. Label(L4);
  1832. CmpConst(R1, 0);
  1833. jcc(jge, L1);
  1834. MovConst(R3, 2);
  1835. mov(R4, R2);
  1836. LslImm(R4, 1);
  1837. Neg(R1);
  1838. Label(L3);
  1839. Cmp(R1, R4);
  1840. jcc(jl, L2);
  1841. CmpConst(R4, 0);
  1842. jcc(jle, L2);
  1843. LslImm(R4, 1);
  1844. LslImm(R3, 1);
  1845. jmp(L3);
  1846. Label(L2);
  1847. Neg(R1);
  1848. LsrImm(R4, 1);
  1849. LsrImm(R3, 1);
  1850. AddReg(R1, R1, R4);
  1851. SubReg(R0, R0, R3);
  1852. jmp(L4);
  1853. Label(L1);
  1854. pop(R4);
  1855. Code(04770H); (* bx lr *)
  1856. END
  1857. END epilog;
  1858. PROCEDURE SetTarget (FlashStart, FlashSize, FlashReserve, SRAMStart, SRAMSize, SRAMReserve: INTEGER; InstrSet: SET; isNXP: BOOLEAN);
  1859. BEGIN
  1860. Target.flash.start := FlashStart;
  1861. Target.flash.size := FlashSize;
  1862. (*Target.flash.startReserve := 0;*)
  1863. Target.flash.endReserve := FlashReserve;
  1864. Target.sram.start := SRAMStart;
  1865. Target.sram.size := SRAMSize;
  1866. Target.sram.startReserve := 0;
  1867. Target.sram.endReserve := SRAMReserve;
  1868. Target.InstrSet := InstrSet;
  1869. Target.isNXP := isNXP;
  1870. Target.IVTLen := 256; (* >= 192 *)
  1871. Target.MinStkSize := 256;
  1872. END SetTarget;
  1873. PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS);
  1874. VAR
  1875. opt: PROG.OPTIONS;
  1876. i, j, DataAdr, BssAdr, DataSize, BssSize, CodeSize: INTEGER;
  1877. BEGIN
  1878. IF target = TARGETS.STM32CM3 THEN
  1879. SetTarget(08000000H, MIN(MAX(options.rom, minROM), maxROM) * 1024, 0,
  1880. 20000000H, MIN(MAX(options.ram, minRAM), maxRAM) * 1024, 0,
  1881. CortexM3, FALSE)
  1882. END;
  1883. tcount := CHL.Length(IL.codes.types);
  1884. opt := options;
  1885. CodeList := LISTS.create(NIL);
  1886. program := BIN.create(IL.codes.lcount);
  1887. REG.Init(R, push, pop, mov, xchg, {R0, R1, R2, R3});
  1888. StkCount := 0;
  1889. DataAdr := Target.sram.start + Target.sram.startReserve;
  1890. DataSize := CHL.Length(IL.codes.data) + tcount * 4 + Target.sram.startReserve;
  1891. WHILE DataSize MOD 4 # 0 DO
  1892. CHL.PushByte(IL.codes.data, 0);
  1893. INC(DataSize)
  1894. END;
  1895. BssAdr := DataAdr + DataSize - Target.sram.startReserve;
  1896. IL.set_bss(MAX(IL.codes.bss, MAX(IL.codes.dmin - CHL.Length(IL.codes.data), 4)));
  1897. BssSize := IL.codes.bss;
  1898. ASSERT(UTILS.Align(BssSize, 4));
  1899. prolog(BssSize, tcount, ORD(opt.pic), Target.sram.start + Target.sram.size - Target.sram.endReserve, Target.IVTLen);
  1900. translate(ORD(opt.pic), tcount * 4);
  1901. epilog;
  1902. fixup(Target.flash.start, DataAdr, BssAdr);
  1903. INC(DataSize, BssSize);
  1904. CodeSize := CHL.Length(program.code);
  1905. IF CodeSize > Target.flash.size - Target.flash.endReserve THEN
  1906. ERRORS.Error(203)
  1907. END;
  1908. IF DataSize > Target.sram.size - Target.MinStkSize - Target.sram.endReserve THEN
  1909. ERRORS.Error(204)
  1910. END;
  1911. IF Target.isNXP THEN
  1912. BIN.put32le(program.code, 2FCH, 0H); (* code read protection (CRP) *)
  1913. (* NXP checksum *)
  1914. j := 0;
  1915. FOR i := 0 TO 6 DO
  1916. INC(j, BIN.get32le(program.code, i * 4))
  1917. END;
  1918. BIN.put32le(program.code, 1CH, -j)
  1919. END;
  1920. WR.Create(outname);
  1921. HEX.Data2(program.code, 0, CodeSize, high(Target.flash.start));
  1922. HEX.End;
  1923. WR.Close;
  1924. C.Dashes;
  1925. C.String( " rom: "); C.Int(CodeSize); C.String(" of "); C.Int(Target.flash.size - Target.flash.endReserve);
  1926. C.String(" ("); C.Int(CodeSize * 100 DIV (Target.flash.size - Target.flash.endReserve)); C.StringLn("%)");
  1927. C.Ln;
  1928. C.String( " ram: "); C.Int(DataSize); C.String(" of "); C.Int(Target.sram.size - Target.sram.endReserve);
  1929. C.String(" ("); C.Int(DataSize * 100 DIV (Target.sram.size - Target.sram.endReserve)); C.StringLn("%)")
  1930. END CodeGen;
  1931. PROCEDURE SetIV* (idx: INTEGER): BOOLEAN;
  1932. VAR
  1933. res: BOOLEAN;
  1934. BEGIN
  1935. res := IVT[idx] = 0;
  1936. IVT[idx] := 1
  1937. RETURN res
  1938. END SetIV;
  1939. PROCEDURE init;
  1940. VAR
  1941. i: INTEGER;
  1942. BEGIN
  1943. FOR i := 0 TO LEN(IVT) - 1 DO
  1944. IVT[i] := 0
  1945. END
  1946. END init;
  1947. BEGIN
  1948. init
  1949. END THUMB.