THUMB.ob07 52 KB

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