O7ARMv7M.Mod 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057
  1. MODULE O7ARMv7M;
  2. (*
  3. Alexander Shiryaev, 2015.01, 2019.11, 2020.08
  4. ARMv7-M Architecture Reference Manual
  5. https://web.eecs.umich.edu/~prabal/teaching/eecs373-f10/readings/ARMv7-M_ARM.pdf
  6. *)
  7. IMPORT SYSTEM, Strings := VT100, ARMv6M := O7ARMv6M;
  8. CONST
  9. (* registers *)
  10. R0* = 0; R1* = 1; R2* = 2; R3* = 3;
  11. R4* = 4; R5* = 5; R6* = 6; R7* = 7;
  12. R8* = 8; R9* = 9; R10* = 10; R11* = 11; R12* = 12;
  13. SP* = 13; LR* = 14; PC* = 15;
  14. (* conditions *)
  15. EQ* = 0; NE* = 1; CS* = 2; CC* = 3;
  16. MI* = 4; PL* = 5; VS* = 6; VC* = 7;
  17. HI* = 8; LS* = 9; GE* = 10; LT* = 11;
  18. GT* = 12; LE* = 13; AL* = 14;
  19. PROCEDURE LSL (x, n: INTEGER): INTEGER;
  20. BEGIN
  21. RETURN SYSTEM.LSH(x, n)
  22. END LSL;
  23. PROCEDURE BITS (x: INTEGER): SET;
  24. BEGIN
  25. RETURN SYSTEM.VAL(SET, x)
  26. END BITS;
  27. PROCEDURE ORDSET (x: SET): INTEGER;
  28. BEGIN
  29. RETURN SYSTEM.VAL(INTEGER, x)
  30. END ORDSET;
  31. PROCEDURE Emit2 (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; c: INTEGER);
  32. BEGIN
  33. code[pc] := c MOD 10000H; INC(pc);
  34. code[pc] := c DIV 10000H MOD 10000H; INC(pc)
  35. END Emit2;
  36. (* A5.3: emit 32-bit Thumb instruction *)
  37. (* 111 op1:2 op2:7 x0:4 op:1 x1:15 *)
  38. PROCEDURE EmitThumb2 (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; op1, op2, x0, op, x1: INTEGER);
  39. BEGIN
  40. ASSERT(op1 IN {1,2,3}, 20);
  41. ASSERT(op2 >= 0, 21);
  42. ASSERT(op2 < 80H, 22);
  43. ASSERT(x0 IN {0..15}, 23);
  44. ASSERT(op IN {0,1}, 24);
  45. ASSERT(x1 >= 0, 25);
  46. ASSERT(x1 < 8000H, 26);
  47. Emit2(code, pc, LSL(op, 31) + x1 * 10000H + 0E000H + op1 * 800H + op2 * 10H + x0)
  48. END EmitThumb2;
  49. (* A5.3.5: emit Thumb-2 Load Multiple and Store Multiple instruction *)
  50. (* 111 0100 op:2 0 W:1 L:1 Rn:4 x0:16 *)
  51. PROCEDURE EmitLMASM (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; op, W, L, Rn, x0: INTEGER);
  52. BEGIN
  53. ASSERT(op IN {1,2}, 20);
  54. ASSERT(W IN {0,1}, 21);
  55. ASSERT(L IN {0,1}, 22);
  56. ASSERT(Rn IN {0..15}, 23);
  57. ASSERT(x0 DIV 10000H = 0, 24);
  58. EmitThumb2(code, pc, 1, op * 8 + W * 2 + L, Rn, x0 DIV 8000H, x0 MOD 8000H)
  59. END EmitLMASM;
  60. (* A5.3.11: emit Thumb-2 data processing (shifted register) instruction *)
  61. (* 111 0101 op:4 S:1 Rn:4 x0:4 Rd:4 x1:8 *)
  62. PROCEDURE EmitDPSR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; op, S, Rn, x0, Rd, x1: INTEGER);
  63. BEGIN
  64. ASSERT(op IN {0..15}, 20);
  65. ASSERT(S IN {0,1}, 21);
  66. ASSERT(Rn IN {0..15}, 22);
  67. ASSERT(x0 IN {0..15}, 23);
  68. ASSERT(Rd IN {0..15}, 24);
  69. ASSERT(x1 >= 0, 25);
  70. ASSERT(x1 < 100H, 26);
  71. EmitThumb2(code, pc, 1, 20H + op * 2 + S, Rn, x0 DIV 8, x0 MOD 8 * 1000H + Rd * 100H + x1)
  72. END EmitDPSR;
  73. (* A7.7.114: ROR (immediate); encoding T1 ARMv7-M *)
  74. PROCEDURE EmitRORIm* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; S, Rd, Rm, im: INTEGER);
  75. BEGIN
  76. ASSERT(S DIV 2 = 0, 20);
  77. ASSERT(Rd IN {0..12,14}, 21);
  78. ASSERT(Rm IN {0..12,14}, 22);
  79. ASSERT(im IN {1..31}, 23);
  80. EmitDPSR(code, pc, 2, S, 0FH, im DIV 4, Rd, (im MOD 4) * 40H + 30H + Rm)
  81. END EmitRORIm;
  82. (* A5.3.1: emit Thumb-2 data processing (modified immediate) instruction *)
  83. (* 111 10 x0:1 0 op:5 Rn:4 0 x1:3 Rd:4 x2:8 *)
  84. PROCEDURE EmitDPMI* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; x0, op, Rn, x1, Rd, x2: INTEGER);
  85. BEGIN
  86. ASSERT(x0 IN {0,1}, 20);
  87. ASSERT(op IN {0..31}, 21);
  88. ASSERT(Rn IN {0..15}, 22);
  89. ASSERT(x1 IN {0..7}, 23);
  90. ASSERT(Rd IN {0..15}, 24);
  91. ASSERT(x2 >= 0, 25);
  92. ASSERT(x2 < 100H, 26);
  93. EmitThumb2(code, pc, 2, x0 * 40H + op, Rn, 0, x1 * 1000H + Rd * 100H + x2)
  94. END EmitDPMI;
  95. (* A7.7.185: TST (immediate); encoding T1 ARMv7-M *)
  96. PROCEDURE EmitTSTIm* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Rn, i, imm3, imm8: INTEGER);
  97. BEGIN
  98. ASSERT(Rn IN {0..12,14}, 20);
  99. EmitDPMI(code, pc, i, 1, Rn, imm3, 0FH, imm8)
  100. END EmitTSTIm;
  101. (* A7.7.27: CMP (immediate); encoding T2 ARMv7-M *)
  102. PROCEDURE EmitCMPImW* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Rn, i, imm3, imm8: INTEGER);
  103. BEGIN
  104. ASSERT(Rn IN {0..14}, 20);
  105. EmitDPMI(code, pc, i, 16 + 8 + 2 + 1, Rn, imm3, 0FH, imm8)
  106. END EmitCMPImW;
  107. (* A7.7.117: RSB (immediate); encoding T2 ARMv7-M *)
  108. PROCEDURE EmitRSBImW* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; S, Rd, Rn, i, imm3, imm8: INTEGER);
  109. BEGIN
  110. ASSERT(Rd IN {0..12,14}, 20);
  111. ASSERT(Rn IN {0..12,14}, 20);
  112. EmitDPMI(code, pc, i, 28 + S, Rn, imm3, Rd, imm8)
  113. END EmitRSBImW;
  114. (* A5.3.3: emit Thumb-2 data processing (plain binary immediate) instruction *)
  115. (* 111 10 x0:1 1 op:5 Rn:4 0 x1:15 *)
  116. PROCEDURE EmitDPPBI* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; x0, op, Rn, x1: INTEGER);
  117. BEGIN
  118. ASSERT(x0 IN {0,1}, 20);
  119. ASSERT(op IN {0..31}, 21);
  120. ASSERT(Rn IN {0..15}, 22);
  121. ASSERT(x1 >= 0, 23);
  122. ASSERT(x1 < 8000H, 24);
  123. EmitThumb2(code, pc, 2, x0 * 40H + 20H + op, Rn, 0, x1)
  124. END EmitDPPBI;
  125. (* A5.3.12: emit Thumb-2 data processing (register) instruction *)
  126. (* 111 1101 0 op1:4 Rn:4 1111 x0:4 op2:4 x1:4 *)
  127. PROCEDURE EmitDPR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; op1, Rn, x0, op2, x1: INTEGER);
  128. BEGIN
  129. ASSERT(op1 IN {0..15}, 20);
  130. ASSERT(Rn IN {0..15}, 21);
  131. ASSERT(x0 IN {0..15}, 22);
  132. ASSERT(op2 IN {0..15}, 23);
  133. ASSERT(x1 IN {0..15}, 24);
  134. EmitThumb2(code, pc, 3, 20H + op1, Rn, 1, 7000H + x0 * 100H + op2 * 10H + x1)
  135. END EmitDPR;
  136. (* A5.3.16: Multiply, multiply accumulate, and absolute difference *)
  137. PROCEDURE EmitMMAAAD* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; op1, x0, Ra, x1, op2, x2: INTEGER);
  138. BEGIN
  139. ASSERT(op1 IN {0..7}, 20);
  140. ASSERT(x0 IN {0..15}, 21);
  141. ASSERT(Ra IN {0..15}, 22);
  142. ASSERT(x1 IN {0..15}, 23);
  143. ASSERT(op2 IN {0..3}, 24);
  144. ASSERT(x2 IN {0..15}, 25);
  145. EmitThumb2(code, pc, 3, 30H + op1, x0, Ra DIV 8, Ra MOD 8 * 1000H + x1 * 100H + op2 * 10H + x2)
  146. END EmitMMAAAD;
  147. (* A7.7.73: MLA; encoding T1 ARMv7-M *)
  148. PROCEDURE EmitMLA* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Rd, Rn, Rm, Ra: INTEGER);
  149. BEGIN
  150. ASSERT(Rd IN {0..12,14}, 20);
  151. ASSERT(Rn IN {0..12,14}, 21);
  152. ASSERT(Rm IN {0..12,14}, 22);
  153. ASSERT(Ra IN {0..12,14}, 23);
  154. EmitMMAAAD(code, pc, 0, Rn, Ra, Rd, 0, Rm)
  155. END EmitMLA;
  156. (* A7.7.74: MLS; encoding T1 ARMv7-M *)
  157. PROCEDURE EmitMLS* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Rd, Rn, Rm, Ra: INTEGER);
  158. BEGIN
  159. ASSERT(Rd IN {0..12,14}, 20);
  160. ASSERT(Rn IN {0..12,14}, 21);
  161. ASSERT(Rm IN {0..12,14}, 22);
  162. ASSERT(Ra IN {0..12,14}, 23);
  163. EmitMMAAAD(code, pc, 0, Rn, Ra, Rd, 1, Rm)
  164. END EmitMLS;
  165. (* A7.7.83: MUL; encoding T2 ARMv7-M *)
  166. PROCEDURE EmitMUL* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Rd, Rn, Rm: INTEGER);
  167. BEGIN
  168. ASSERT(Rd IN {0..12,14}, 20);
  169. ASSERT(Rn IN {0..12,14}, 21);
  170. ASSERT(Rm IN {0..12,14}, 22);
  171. EmitMMAAAD(code, pc, 0, Rn, 0FH, Rd, 0, Rm)
  172. END EmitMUL;
  173. (* A5.3.15: Long multiply, long multiply accumulate, and divide *)
  174. PROCEDURE EmitLMLMAAD* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; op1, x0, x1, op2, x2: INTEGER);
  175. BEGIN
  176. ASSERT(op1 IN {0..7}, 20);
  177. ASSERT(x0 IN {0..15}, 21);
  178. ASSERT(x1 >= 0, 22);
  179. ASSERT(x1 < 100H, 23);
  180. ASSERT(op2 IN {0..15}, 24);
  181. ASSERT(x2 IN {0..15}, 25);
  182. EmitThumb2(code, pc, 3, 38H + op1, x0, x1 DIV 80H, x1 MOD 80H * 100H + op2 * 10H + x2)
  183. END EmitLMLMAAD;
  184. (* A5.3.7: emit Thumb-2 load word instruction *)
  185. (* 111 1100 op1:2 10 1 Rn:4 x0:4 op2:6 x1:6 *)
  186. PROCEDURE EmitLW (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; op1, Rn, x0, op2, x1: INTEGER);
  187. BEGIN
  188. ASSERT(op1 IN {0..3}, 20);
  189. ASSERT(Rn IN {0..15}, 21);
  190. ASSERT(x0 IN {0..15}, 22);
  191. ASSERT(op2 >= 0, 23);
  192. ASSERT(op2 < 40H, 24);
  193. ASSERT(x1 >= 0, 25);
  194. ASSERT(x1 < 40H, 26);
  195. EmitThumb2(code, pc, 3, op1 * 8 + 5, Rn, x0 DIV 8, x0 MOD 8 * 1000H + op2 * 40H + x1)
  196. END EmitLW;
  197. (* A7.7.42: LDR (immediate); encoding T3 ARMv7-M *)
  198. PROCEDURE EmitLWImW* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Rt, Rn, imm12: INTEGER);
  199. BEGIN
  200. ASSERT(Rn IN {0..14}, 20);
  201. ASSERT(Rt IN {0..14}, 21);
  202. ASSERT(imm12 >= 0, 22);
  203. ASSERT(imm12 < 1000H, 23);
  204. EmitLW(code, pc, 1, Rn, Rt, imm12 DIV 40H, imm12 MOD 40H)
  205. END EmitLWImW;
  206. (* A7.7.42: LDR (immediate); encoding T4 ARMv7-M *)
  207. PROCEDURE EmitLWImWT4 (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Rt, Rn, imm8, P, U, W: INTEGER);
  208. BEGIN
  209. ASSERT(Rn IN {0..14}, 20);
  210. ASSERT(Rt IN {0..15}, 21);
  211. ASSERT(imm8 DIV 100H = 0, 22);
  212. ASSERT(P DIV 2 = 0, 23);
  213. ASSERT(U DIV 2 = 0, 24);
  214. ASSERT(W DIV 2 = 0, 25);
  215. ASSERT(~((P = 1) & (U = 1) & (W = 0)), 26);
  216. ASSERT(~((Rn = 13) & (P = 0) & (U = 1) & (W = 1) & (imm8 = 4)), 27);
  217. ASSERT(~((P = 0) & (W = 0)), 28);
  218. EmitLW(code, pc, 0, Rn, Rt, imm8 DIV 40H + W * 4 + U * 8 + P * 16 + 32, imm8 MOD 40H)
  219. END EmitLWImWT4;
  220. PROCEDURE EmitLWImWNeg* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Rt, Rn, imm8: INTEGER);
  221. BEGIN
  222. EmitLWImWT4(code, pc, Rt, Rn, imm8, 1, 0, 0)
  223. END EmitLWImWNeg;
  224. (* A7.7.44: LDR (register); encoding T2 ARMv7-M *)
  225. PROCEDURE EmitLWRW* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Rt, Rn, Rm, imm2: INTEGER);
  226. BEGIN
  227. ASSERT(Rt IN {0..15}, 20);
  228. ASSERT(Rn IN {0..14}, 21);
  229. ASSERT(Rm IN {0..12,14}, 22);
  230. ASSERT(imm2 DIV 4 = 0, 23);
  231. EmitLW(code, pc, 0, Rn, Rt, 0, imm2 * 10H + Rm)
  232. END EmitLWRW;
  233. (* A5.3.: emit Thumb-2 load byte, memory hints instruction *)
  234. (* 111 1100 op1:2 00 1 Rn:4 Rt:4 op2:6 x0:6 *)
  235. PROCEDURE EmitLBMH (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; op1, Rn, Rt, op2, x0: INTEGER);
  236. BEGIN
  237. ASSERT(op1 IN {0..3}, 20);
  238. ASSERT(Rn IN {0..15}, 21);
  239. ASSERT(Rt IN {0..15}, 22);
  240. ASSERT(op2 >= 0, 23);
  241. ASSERT(op2 < 40H, 24);
  242. ASSERT(x0 >= 0, 25);
  243. ASSERT(x0 < 40H, 26);
  244. EmitThumb2(code, pc, 3, op1 * 8 + 1, Rn, Rt DIV 8, Rt MOD 8 * 1000H + op2 * 40H + x0)
  245. END EmitLBMH;
  246. (* A7.7.45: LDRB (immediate); encoding T2 ARMv7-M *)
  247. PROCEDURE EmitLBImW* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Rt, Rn, imm12: INTEGER);
  248. BEGIN
  249. ASSERT(Rt IN {0..12,14}, 20);
  250. ASSERT(Rn IN {0..14}, 21);
  251. ASSERT(imm12 >= 0, 22);
  252. ASSERT(imm12 < 1000H, 23);
  253. EmitLBMH(code, pc, 1, Rn, Rt, imm12 DIV 40H, imm12 MOD 40H)
  254. END EmitLBImW;
  255. (* A7.7.47: LDRB (register); encoding T2 ARMv7-M *)
  256. PROCEDURE EmitLBRW* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Rt, Rn, Rm, imm2: INTEGER);
  257. BEGIN
  258. ASSERT(Rt IN {0..12,14}, 20);
  259. ASSERT(Rn IN {0..14}, 21);
  260. ASSERT(Rm IN {0..12,14}, 22);
  261. ASSERT(imm2 DIV 4 = 0, 23);
  262. EmitLBMH(code, pc, 0, Rn, Rt, 0, imm2 * 10H + Rm)
  263. END EmitLBRW;
  264. (* A5.3.10: emit Thumb-2 store single data item instruction *)
  265. (* 111 1100 0 op1:3 0 x0:4 x1:4 op2:6 x2:6 *)
  266. PROCEDURE EmitSSDI (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; op1, x0, x1, op2, x2: INTEGER);
  267. BEGIN
  268. ASSERT(op1 IN {0..7}, 20);
  269. ASSERT(x0 IN {0..15}, 21);
  270. ASSERT(x1 IN {0..15}, 22);
  271. ASSERT(op2 >= 0, 23);
  272. ASSERT(op2 < 40H, 24);
  273. ASSERT(x2 >= 0, 25);
  274. ASSERT(x2 < 40H, 26);
  275. EmitThumb2(code, pc, 3, op1 * 2, x0, x1 DIV 8, x1 MOD 8 * 1000H + op2 * 40H + x2)
  276. END EmitSSDI;
  277. (* A7.7.160: STRB (immediate); encoding T2 ARMv7-M *)
  278. PROCEDURE EmitSBImW* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Rt, Rn, imm12: INTEGER);
  279. BEGIN
  280. ASSERT(Rt IN {0..12,14}, 20);
  281. ASSERT(Rn IN {0..14}, 21);
  282. ASSERT(imm12 >= 0, 110);
  283. ASSERT(imm12 < 1000H, 111);
  284. EmitSSDI(code, pc, 4, Rn, Rt, imm12 DIV 40H, imm12 MOD 40H)
  285. END EmitSBImW;
  286. (* A7.7.161: STRB (register); encoding T2 ARMv7-M *)
  287. PROCEDURE EmitSBRW* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Rt, Rn, Rm, imm2: INTEGER);
  288. BEGIN
  289. ASSERT(Rt IN {0..12,14}, 20);
  290. ASSERT(Rn IN {0..14}, 21);
  291. ASSERT(Rm IN {0..12,14}, 22);
  292. ASSERT(imm2 IN {0..3}, 23);
  293. EmitSSDI(code, pc, 0, Rn, Rt, 0, imm2 * 10H + Rm)
  294. END EmitSBRW;
  295. (* A7.7.158: STR (immediate); encoding T3 ARMv7-M *)
  296. PROCEDURE EmitSWImW* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Rt, Rn, imm12: INTEGER);
  297. BEGIN
  298. ASSERT(Rt IN {0..14}, 20);
  299. ASSERT(Rn IN {0..14}, 21);
  300. ASSERT(imm12 >= 0, 110);
  301. ASSERT(imm12 < 1000H, 111);
  302. EmitSSDI(code, pc, 6, Rn, Rt, imm12 DIV 40H, imm12 MOD 40H)
  303. END EmitSWImW;
  304. (* A7.7.159: STR (register); encoding T2 ARMv7-M *)
  305. PROCEDURE EmitSWRW* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Rt, Rn, Rm, imm2: INTEGER);
  306. BEGIN
  307. ASSERT(Rt IN {0..14}, 20);
  308. ASSERT(Rn IN {0..14}, 21);
  309. ASSERT(Rm IN {0..12,14}, 22);
  310. ASSERT(imm2 IN {0..3}, 23);
  311. EmitSSDI(code, pc, 2, Rn, Rt, 0, imm2 * 10H + Rm)
  312. END EmitSWRW;
  313. (* A7.7.79: PUSH *)
  314. PROCEDURE EmitPUSHW* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; regs: SET);
  315. VAR i, n, r: INTEGER;
  316. BEGIN
  317. ASSERT(regs * {13,15..31} = {}, 20);
  318. ASSERT(regs # {}, 21);
  319. i := 16; n := 0;
  320. REPEAT DEC(i); IF i IN regs THEN INC(n); r := i END UNTIL i = 0;
  321. IF n = 1 THEN (* encoding T3 ARMv7-M *)
  322. EmitSSDI(code, pc, 2, 13, r, 32 + 16 + 4, 4)
  323. ELSE (* encoding T2 ARMv7-M *)
  324. EmitLMASM(code, pc, 2, 1, 0, 13, ORDSET(regs))
  325. END
  326. END EmitPUSHW;
  327. (* A7.7.98: POP *)
  328. PROCEDURE EmitPOPW* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; regs: SET);
  329. VAR i, n, r: INTEGER;
  330. BEGIN
  331. ASSERT(regs * {13,16..31} = {}, 20);
  332. ASSERT(regs # {}, 21);
  333. i := 16; n := 0;
  334. REPEAT DEC(i); IF i IN regs THEN INC(n); r := i END UNTIL i = 0;
  335. IF n = 1 THEN (* encoding T3 ARMv7-M *)
  336. EmitLW(code, pc, 0, 13, r, 32 + 8 + 4, 4)
  337. ELSE (* encoding T2 ARMv7-M *)
  338. EmitLMASM(code, pc, 1, 1, 1, 13, ORDSET(regs))
  339. END
  340. END EmitPOPW;
  341. PROCEDURE DecodeBLabel20 (S, imm6, J1, J2, imm11: INTEGER): INTEGER;
  342. BEGIN
  343. RETURN ((S * 100000H + J2 * 80000H + J1 * 40000H + imm6 * 1000H + imm11 * 2) * 800H) DIV 800H
  344. END DecodeBLabel20;
  345. PROCEDURE EncodeBLabel20* (off: INTEGER; (*OUT*)VAR S, imm6, J1, J2, imm11: INTEGER);
  346. VAR test: INTEGER;
  347. BEGIN
  348. ASSERT(off * 2 >= -1048576, 21);
  349. ASSERT(off * 2 <= 1048574, 22);
  350. imm11 := off MOD 800H;
  351. imm6 := off DIV 800H MOD 40H;
  352. S := off DIV 80000H MOD 2;
  353. J2 := off DIV 40000H MOD 2;
  354. J1 := off DIV 20000H MOD 2;
  355. off := off * 2;
  356. test := DecodeBLabel20(S, imm6, J1, J2, imm11);
  357. ASSERT(off = test, 100)
  358. END EncodeBLabel20;
  359. (* A5.3.4: emit Thumb-2 branch and miscellaneous control instruction *)
  360. (* 111 10 op:7 x0:4 1 op1:3 x1:12 *)
  361. PROCEDURE EmitBAMC* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; op, x0, op1, x1: INTEGER);
  362. BEGIN
  363. ASSERT(op >= 0, 20);
  364. ASSERT(op < 80H, 21);
  365. ASSERT(x0 IN {0..15}, 22);
  366. ASSERT(op1 IN {0..7}, 23);
  367. ASSERT(x1 >= 0, 24);
  368. ASSERT(x1 < 1000H, 25);
  369. EmitThumb2(code, pc, 2, op, x0, 1, op1 * 1000H + x1)
  370. END EmitBAMC;
  371. (* A7.7.236: emit VMOV (between ARM core register and single-precision register) instruction; encoding T1 FPv4-SP *)
  372. PROCEDURE EmitVMOVSPR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; op, n, t: INTEGER);
  373. BEGIN
  374. ASSERT(op IN {0,1}, 20);
  375. ASSERT(n IN {0..31}, 21);
  376. ASSERT(t IN {0..12,14}, 22);
  377. Emit2(code, pc, 0A10EE00H + op * 10H + n DIV 2 + n MOD 2 * 800000H + t * 10000000H)
  378. END EmitVMOVSPR;
  379. (* A7.7.239: emit VMRS instruction; encoding T1 FPv4-SP *)
  380. PROCEDURE EmitVMRS* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Rt: INTEGER);
  381. BEGIN
  382. ASSERT(Rt IN {0..12,14,15}, 20);
  383. Emit2(code, pc, 0A10EEF1H + Rt * 10000000H)
  384. END EmitVMRS;
  385. (* A7.7.240: emit VMSR instruction; encoding T1 FPv4-SP *)
  386. PROCEDURE EmitVMSR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Rt: INTEGER);
  387. BEGIN
  388. ASSERT(Rt IN {0..12,14}, 20);
  389. Emit2(code, pc, 0A10EEE1H + Rt * 10000000H)
  390. END EmitVMSR;
  391. (* A6.4: emit Floating-point data-processing instruction *)
  392. (* 111 0 1110 opc1:4 opc2:4 x0:4 101 0 opc3:2 x1:1 0 opc4:4 *)
  393. PROCEDURE EmitFPDP (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; opc1, opc2, x0, opc3, x1, opc4: INTEGER);
  394. BEGIN
  395. ASSERT(opc1 IN {0..15}, 20);
  396. ASSERT(opc2 IN {0..15}, 21);
  397. ASSERT(x0 IN {0..15}, 22);
  398. ASSERT(opc3 IN {0..3}, 23);
  399. ASSERT(x1 IN {0,1}, 24);
  400. ASSERT(opc4 IN {0..15}, 25);
  401. Emit2(code, pc, 0A00EE00H + opc1 * 10H + opc2 + x0 * 10000000H + opc3 * 400000H + x1 * 200000H + opc4 * 10000H)
  402. END EmitFPDP;
  403. (* A7.7.241: emit VMUL instruction; encoding T1 FPv4-SP *)
  404. PROCEDURE EmitVMUL* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Sd, Sn, Sm: INTEGER);
  405. BEGIN
  406. ASSERT(Sd IN {0..31}, 20);
  407. ASSERT(Sn IN {0..31}, 21);
  408. ASSERT(Sm IN {0..31}, 22);
  409. EmitFPDP(code, pc, 2 + Sd MOD 2 * 4, Sn DIV 2, Sd DIV 2, Sn MOD 2 * 2, Sm MOD 2, Sm DIV 2)
  410. END EmitVMUL;
  411. (* A7.7.221: emit VADD instruction; encoding T1 FPv4-SP *)
  412. PROCEDURE EmitVADD* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Sd, Sn, Sm: INTEGER);
  413. BEGIN
  414. ASSERT(Sd IN {0..31}, 20);
  415. ASSERT(Sn IN {0..31}, 21);
  416. ASSERT(Sm IN {0..31}, 22);
  417. EmitFPDP(code, pc, 3 + Sd MOD 2 * 4, Sn DIV 2, Sd DIV 2, Sn MOD 2 * 2, Sm MOD 2, Sm DIV 2)
  418. END EmitVADD;
  419. (* A7.7.249: emit VSUB instruction; encoding T1 FPv4-SP *)
  420. PROCEDURE EmitVSUB* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Sd, Sn, Sm: INTEGER);
  421. BEGIN
  422. ASSERT(Sd IN {0..31}, 20);
  423. ASSERT(Sn IN {0..31}, 21);
  424. ASSERT(Sm IN {0..31}, 22);
  425. EmitFPDP(code, pc, 3 + Sd MOD 2 * 4, Sn DIV 2, Sd DIV 2, Sn MOD 2 * 2 + 1, Sm MOD 2, Sm DIV 2)
  426. END EmitVSUB;
  427. (* A7.7.226: emit VDIV instruction; encoding T1 FPv4-SP *)
  428. PROCEDURE EmitVDIV* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Sd, Sn, Sm: INTEGER);
  429. BEGIN
  430. ASSERT(Sd IN {0..31}, 20);
  431. ASSERT(Sn IN {0..31}, 21);
  432. ASSERT(Sm IN {0..31}, 22);
  433. EmitFPDP(code, pc, 8 + Sd MOD 2 * 4, Sn DIV 2, Sd DIV 2, Sn MOD 2 * 2, Sm MOD 2, Sm DIV 2)
  434. END EmitVDIV;
  435. (* A7.7.220: emit VABS instruction; encoding T1 FPv4-SP *)
  436. PROCEDURE EmitVABS* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Sd, Sm: INTEGER);
  437. BEGIN
  438. ASSERT(Sd IN {0..31}, 20);
  439. ASSERT(Sm IN {0..31}, 21);
  440. EmitFPDP(code, pc, 11 + Sd MOD 2 * 4, 0, Sd DIV 2, 3, Sm MOD 2, Sm DIV 2)
  441. END EmitVABS;
  442. (* A7.7.242: emit VNEG instruction; encoding T1 FPv4-SP *)
  443. PROCEDURE EmitVNEG* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Sd, Sm: INTEGER);
  444. BEGIN
  445. ASSERT(Sd IN {0..31}, 20);
  446. ASSERT(Sm IN {0..31}, 21);
  447. EmitFPDP(code, pc, 11 + Sd MOD 2 * 4, 1, Sd DIV 2, 1, Sm MOD 2, Sm DIV 2)
  448. END EmitVNEG;
  449. (* A7.7.246: emit VSQRT instruction; encoding T1 FPv4-SP *)
  450. PROCEDURE EmitVSQRT* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Sd, Sm: INTEGER);
  451. BEGIN
  452. ASSERT(Sd IN {0..31}, 20);
  453. ASSERT(Sm IN {0..31}, 21);
  454. EmitFPDP(code, pc, 11 + Sd MOD 2 * 4, 1, Sd DIV 2, 3, Sm MOD 2, Sm DIV 2)
  455. END EmitVSQRT;
  456. (* A7.7.222: emit VCMP{E} instruction; encoding T1 FPv4-SP *)
  457. PROCEDURE EmitVCMPER* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; E, Sd, Sm: INTEGER);
  458. BEGIN
  459. ASSERT(E IN {0,1}, 20);
  460. ASSERT(Sd IN {0..31}, 21);
  461. ASSERT(Sm IN {0..31}, 22);
  462. EmitFPDP(code, pc, 11 + Sd MOD 2 * 4, 4, Sd DIV 2, E * 2 + 1, Sm MOD 2, Sm DIV 2)
  463. END EmitVCMPER;
  464. (* A7.7.222: emit VCMP{E} instruction; encoding T2 FPv4-SP *)
  465. PROCEDURE EmitVCMPE0* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; E, Sd: INTEGER);
  466. BEGIN
  467. ASSERT(E IN {0,1}, 20);
  468. ASSERT(Sd IN {0..31}, 21);
  469. EmitFPDP(code, pc, 11 + Sd MOD 2 * 4, 5, Sd DIV 2, E * 2 + 1, 0, 0)
  470. END EmitVCMPE0;
  471. (* A7.7.223: emit VCVT, VCVTR (between floating-point and integer) instruction; encoding T1 FPv4-SP *)
  472. PROCEDURE EmitVCVTRInt* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; toInteger, R, signed: BOOLEAN; Sd, Sm: INTEGER);
  473. VAR opc2, op: INTEGER;
  474. BEGIN
  475. ASSERT(Sd IN {0..31}, 20);
  476. ASSERT(Sm IN {0..31}, 21);
  477. IF toInteger THEN
  478. IF signed THEN opc2 := 5 ELSE opc2 := 4 END;
  479. IF R THEN op := 0 ELSE op := 1 END
  480. ELSE
  481. ASSERT(~R, 22);
  482. opc2 := 0;
  483. IF signed THEN op := 1 ELSE op := 0 END
  484. END;
  485. EmitFPDP(code, pc, 11 + Sd MOD 2 * 4, 8 + opc2, Sd DIV 2, op * 2 + 1, Sm MOD 2, Sm DIV 2)
  486. END EmitVCVTRInt;
  487. (* A6.5: emit Floating-point extension register load and store instruction *)
  488. (* 111 0 110 opcode:5 Rn:4 x0:4 101 x1:9 *)
  489. PROCEDURE EmitFPERLOS (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; opcode, Rn, x0, x1: INTEGER);
  490. BEGIN
  491. ASSERT(opcode DIV 32 = 0, 20);
  492. ASSERT(Rn DIV 16 = 0, 21);
  493. ASSERT(x0 DIV 16 = 0, 22);
  494. ASSERT(x1 DIV 200H = 0, 23);
  495. Emit2(code, pc, 0A00EC00H + Rn + opcode * 10H + x1 * 10000H + x0 * 10000000H)
  496. END EmitFPERLOS;
  497. (* A7.7.248: emit VSTR instruction; encoding T2 FPv4-SP *)
  498. PROCEDURE EmitVSTR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Sd, Rn, U, imm8: INTEGER);
  499. BEGIN
  500. ASSERT(Sd IN {0..31}, 20);
  501. ASSERT(Rn IN {0..14}, 21);
  502. ASSERT(U IN {0,1}, 22);
  503. ASSERT(imm8 DIV 100H = 0, 23);
  504. EmitFPERLOS(code, pc, 16 + U * 8 + Sd MOD 2 * 4, Rn, Sd DIV 2, imm8)
  505. END EmitVSTR;
  506. (* A7.7.230: emit VLDR instruction; encoding T2 FPv4-SP *)
  507. PROCEDURE EmitVLDR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; Sd, Rn, U, imm8: INTEGER);
  508. BEGIN
  509. ASSERT(Sd IN {0..31}, 20);
  510. ASSERT(Rn IN {0..15}, 21);
  511. ASSERT(U IN {0,1}, 22);
  512. ASSERT(imm8 DIV 100H = 0, 23);
  513. EmitFPERLOS(code, pc, 16 + U * 8 + Sd MOD 2 * 4 + 1, Rn, Sd DIV 2, imm8)
  514. END EmitVLDR;
  515. (* try to encode to 12-bit modified immediate *)
  516. PROCEDURE EncodeMI12* (x: INTEGER; (*OUT*)VAR i, imm3, imm8: INTEGER; (*OUT*)VAR ok: BOOLEAN);
  517. VAR j, y: INTEGER; imm12: INTEGER;
  518. BEGIN
  519. IF x DIV 100H = 0 THEN
  520. imm12 := x;
  521. ok := TRUE
  522. ELSIF (x MOD 10000H DIV 100H = 0) & (x DIV 10000H MOD 10000H = x MOD 10000H) THEN
  523. imm12 := 100H + x MOD 100H;
  524. ok := TRUE
  525. ELSIF (x MOD 100H = 0) & (x DIV 10000H MOD 10000H = x MOD 10000H) THEN
  526. imm12 := 200H + x DIV 100H MOD 100H;
  527. ok := TRUE
  528. ELSIF (x MOD 100H = x DIV 100H MOD 100H) & (x MOD 100H = x DIV 10000H MOD 100H) & (x MOD 100H = x DIV 1000000H MOD 100H) THEN
  529. imm12 := 300H + x MOD 100H;
  530. ok := TRUE
  531. ELSE
  532. j := 0; y := x;
  533. WHILE (j < 24) & ~((31 IN BITS(y)) & (y MOD 1000000H = 0)) DO
  534. INC(j); y := SYSTEM.ROT(x, j)
  535. END;
  536. IF j < 24 THEN
  537. imm12 := (j + 8) * 80H + y DIV 1000000H MOD 80H;
  538. ok := TRUE
  539. ELSE
  540. ok := FALSE
  541. END
  542. END;
  543. IF ok THEN
  544. i := imm12 DIV 800H;
  545. imm3 := imm12 DIV 100H MOD 8;
  546. imm8 := imm12 MOD 100H
  547. END
  548. END EncodeMI12;
  549. (* A5.4.2 *)
  550. PROCEDURE DecodeMI12 (i, imm3, imm8: INTEGER; (*OUT*)VAR im: INTEGER; (*OUT*)VAR ok: BOOLEAN);
  551. VAR imm12: INTEGER;
  552. BEGIN
  553. ASSERT(i IN {0,1}, 20);
  554. ASSERT(imm3 IN {0..7}, 21);
  555. ASSERT(imm8 >= 0, 22);
  556. ASSERT(imm8 < 100H, 23);
  557. imm12 := i * 800H + imm3 * 100H + imm8;
  558. IF imm12 DIV 400H = 0 THEN
  559. CASE imm12 DIV 100H MOD 4 OF 0:
  560. im := imm8; ok := TRUE
  561. | 1:
  562. IF imm8 = 0 THEN ok := FALSE
  563. ELSE im := imm8 * 10000H + imm8; ok := TRUE
  564. END
  565. | 2:
  566. IF imm8 = 0 THEN ok := FALSE
  567. ELSE im := imm8 * 1000000H + imm8 * 100H; ok := TRUE
  568. END
  569. | 3:
  570. IF imm8 = 0 THEN ok := FALSE
  571. ELSE im := imm8 * 1000000H + imm8 * 10000H + imm8 * 100H + imm8; ok := TRUE
  572. END
  573. END
  574. ELSE
  575. im := 80H + imm8 MOD 80H;
  576. im := SYSTEM.ROT(im, -(imm12 DIV 80H));
  577. ok := TRUE
  578. END
  579. END DecodeMI12;
  580. (* A5.3 *)
  581. PROCEDURE IsLMASM (c: INTEGER): BOOLEAN;
  582. BEGIN
  583. RETURN BITS(c) * {6,9..15} = {11,13..15}
  584. END IsLMASM;
  585. (* A7.7.79: PUSH; encoding T2 *)
  586. PROCEDURE IsPUSHMany (c: INTEGER): BOOLEAN;
  587. BEGIN
  588. RETURN BITS(c) * {0..15,29,31} = {0,2,3,5,8,11,13..15}
  589. END IsPUSHMany;
  590. (* A7.7.98: POP; encoding T2 *)
  591. PROCEDURE IsPOPMany (c: INTEGER): BOOLEAN;
  592. BEGIN
  593. RETURN BITS(c) * {0..15,29} = {0,2..5,7,11,13..15}
  594. END IsPOPMany;
  595. (* A7.7.79: PUSH; encoding T3 *)
  596. PROCEDURE IsPUSHOne (c: INTEGER): BOOLEAN;
  597. BEGIN
  598. RETURN BITS(c) * {0..27} = {0,2,3,6,11..15,18,24,26,27}
  599. END IsPUSHOne;
  600. (* A7.7.98: POP; encoding T3 *)
  601. PROCEDURE IsPOPOne (c: INTEGER): BOOLEAN;
  602. BEGIN
  603. RETURN BITS(c) * {0..27} = {0,2..4,6,11..15,18,24,25,27}
  604. END IsPOPOne;
  605. (* A5.3 *)
  606. PROCEDURE IsDPSR (c: INTEGER): BOOLEAN;
  607. BEGIN
  608. RETURN BITS(c) * {9..15} = {9,11,13..15}
  609. END IsDPSR;
  610. (* A7.7.85: MVN (register); encoding T2 *)
  611. PROCEDURE IsMVNR (c: INTEGER): BOOLEAN;
  612. BEGIN
  613. RETURN BITS(c) * {0..3,5..15,31} = {0..3,5,6,9,11,13..15}
  614. END IsMVNR;
  615. (* A7.7.76: MOVR (register); encoding T3 *)
  616. PROCEDURE IsMOVR (c: INTEGER): BOOLEAN;
  617. BEGIN
  618. RETURN BITS(c) * {0..3,5..15,20..23,28..31} = {0..3,6,9,11,13..15}
  619. END IsMOVR;
  620. (* A7.7.9: AND (register); encoding T2 *)
  621. PROCEDURE IsANDR (c: INTEGER): BOOLEAN;
  622. BEGIN
  623. RETURN (BITS(c) * {5..15,31} = {9,11,13..15}) & ~((BITS(c) * {24..27} = {24..27}) & (4 IN BITS(c)))
  624. END IsANDR;
  625. (* A7.7.16: BIC (register); encoding T2 *)
  626. PROCEDURE IsBICR (c: INTEGER): BOOLEAN;
  627. BEGIN
  628. RETURN BITS(c) * {5..15,31} = {5,9,11,13..15}
  629. END IsBICR;
  630. (* A7.7.91: ORR (register); encoding T2 *)
  631. PROCEDURE IsORRR (c: INTEGER): BOOLEAN;
  632. BEGIN
  633. RETURN (BITS(c) * {5..15,31} = {6,9,11,13..15}) & (BITS(c) * {0..3} # {0..3})
  634. END IsORRR;
  635. (* A7.7.25: EOR (register); encoding T2 *)
  636. PROCEDURE IsEORR (c: INTEGER): BOOLEAN;
  637. BEGIN
  638. RETURN (BITS(c) * {5..15,31} = {7,9,11,13..15}) & ~((BITS(c) * {24..27} = {24..27}) & (4 IN BITS(c)))
  639. END IsEORR;
  640. (* A7.7.4: ADD (register); encoding T3 *)
  641. PROCEDURE IsADDR (c: INTEGER): BOOLEAN;
  642. BEGIN
  643. RETURN (BITS(c) * {5..15,31} = {8,9,11,13..15}) & ~((BITS(c) * {24..27} = {24..27}) & (4 IN BITS(c))) & (BITS(c) * {0,2,3} # {0,2,3})
  644. END IsADDR;
  645. (* A7.7.6: ADD (SP plus register); encoding T3 *)
  646. PROCEDURE IsADDSPR (c: INTEGER): BOOLEAN;
  647. BEGIN
  648. RETURN BITS(c) * {0..3,5..15,31} = {0,2,3,8,9,11,13..15}
  649. END IsADDSPR;
  650. (* A7.7.2: ADC (register); encoding T2 *)
  651. PROCEDURE IsADCR (c: INTEGER): BOOLEAN;
  652. BEGIN
  653. RETURN BITS(c) * {5..15,31} = {6,8,9,11,13..15}
  654. END IsADCR;
  655. (* A7.7.172: SUB (register); encoding T2 *)
  656. PROCEDURE IsSUBR (c: INTEGER): BOOLEAN;
  657. BEGIN
  658. RETURN (BITS(c) * {5..15,31} = {5,7..9,11,13..15}) & ~((BITS(c) * {24..27} = {24..27}) & (4 IN BITS(c))) & (BITS(c) * {0,2,3} # {0,2,3})
  659. END IsSUBR;
  660. (* A7.7.174: SUB (SP minus register); encoding T1 *)
  661. PROCEDURE IsSUBSPR (c: INTEGER): BOOLEAN;
  662. BEGIN
  663. RETURN BITS(c) * {0..3,5..15,31} = {0,2,3,5,7..9,11,13..15}
  664. END IsSUBSPR;
  665. (* A7.7.123: SBC (register); encoding T2 *)
  666. PROCEDURE IsSBCR (c: INTEGER): BOOLEAN;
  667. BEGIN
  668. RETURN BITS(c) * {5..15,31} = {5,6,8,9,11,13..15}
  669. END IsSBCR;
  670. (* A7.7.67: LSL (immediate); encoding T2 *)
  671. PROCEDURE IsLSLIm (c: INTEGER): BOOLEAN;
  672. BEGIN
  673. RETURN (BITS(c) * {0..3,5..15,20,21,31} = {0..3,6,9,11,13..15}) & (BITS(c) * {22,23,28..30} # {})
  674. END IsLSLIm;
  675. (* A7.7.10: ASR (immediate); encoding T2 *)
  676. PROCEDURE IsASRIm (c: INTEGER): BOOLEAN;
  677. BEGIN
  678. RETURN BITS(c) * {0..3,5..15,20,21,31} = {0..3,6,9,11,13..15,21}
  679. END IsASRIm;
  680. (* A7.7.114: ROR (immediate); encoding T1 *)
  681. PROCEDURE IsRORIm (c: INTEGER): BOOLEAN;
  682. BEGIN
  683. RETURN (BITS(c) * {0..3,5..15,20,21,31} = {0..3,6,9,11,13..15,20,21}) & (BITS(c) * {22,23,28..30} # {})
  684. END IsRORIm;
  685. (* A5.3 *)
  686. PROCEDURE IsDPMI (c: INTEGER): BOOLEAN;
  687. BEGIN
  688. RETURN BITS(c) * {9,11..15,31} = {12..15}
  689. END IsDPMI;
  690. (* A7.7.185: TST (immediate), encoding T1 *)
  691. PROCEDURE IsTSTIm (c: INTEGER): BOOLEAN;
  692. BEGIN
  693. RETURN BITS(c) * {4..9,11..15,24..27,31} = {4,12..15,24..27}
  694. END IsTSTIm;
  695. (* A7.7.75: MOV (immediate), encoding T2 *)
  696. PROCEDURE IsMOVMI (c: INTEGER): BOOLEAN;
  697. BEGIN
  698. RETURN BITS(c) * {0..3,5..9,11..15,31} = {0..3,6,12..15}
  699. END IsMOVMI;
  700. (* A7.7.84: MVN (immediate), encoding T1 *)
  701. PROCEDURE IsMVNIm (c: INTEGER): BOOLEAN;
  702. BEGIN
  703. RETURN BITS(c) * {0..3,5..9,11..15,31} = {0..3,5,6,12..15}
  704. END IsMVNIm;
  705. (* A7.7.8: AND (immediate), encoding T1 *)
  706. PROCEDURE IsANDIm (c: INTEGER): BOOLEAN;
  707. BEGIN
  708. RETURN BITS(c) * {5..9,11..15,31} = {12..15}
  709. END IsANDIm;
  710. (* A7.7.90: ORR (immediate), encoding T1 *)
  711. PROCEDURE IsORRIm (c: INTEGER): BOOLEAN;
  712. BEGIN
  713. RETURN (BITS(c) * {5..9,11..15,31} = {6,12..15}) & (BITS(c) * {0..3} # {0..3})
  714. END IsORRIm;
  715. (* A7.7.15: BIC (immediate), encoding T1 *)
  716. PROCEDURE IsBICIm (c: INTEGER): BOOLEAN;
  717. BEGIN
  718. RETURN BITS(c) * {5..9,11..15,31} = {5,12..15}
  719. END IsBICIm;
  720. (* A7.7.88: ORN (immediate), encoding T1 *)
  721. PROCEDURE IsORNIm (c: INTEGER): BOOLEAN;
  722. BEGIN
  723. RETURN (BITS(c) * {5..9,11..15,31} = {5,6,12..15}) & (BITS(c) * {0..3} # {0..3})
  724. END IsORNIm;
  725. (* A7.7.34: EOR (immediate), encoding T1 *)
  726. PROCEDURE IsEORIm (c: INTEGER): BOOLEAN;
  727. BEGIN
  728. RETURN (BITS(c) * {5..9,11..15,31} = {7,12..15}) & ~((BITS(c) * {24..27} = {24..27}) & (4 IN BITS(c)))
  729. END IsEORIm;
  730. (* A7.7.3: ADD (immediate), encoding T3 *)
  731. PROCEDURE IsADDMI (c: INTEGER): BOOLEAN;
  732. BEGIN
  733. RETURN (BITS(c) * {5..9,11..15,31} = {8,12..15}) & ~((BITS(c) * {24..27} = {24..27}) & (4 IN BITS(c))) & (BITS(c) * {0..3} # {0,2,3})
  734. END IsADDMI;
  735. (* A7.7.5: ADD (SP plus immediate), encoding T3 *)
  736. PROCEDURE IsADDSPMI (c: INTEGER): BOOLEAN;
  737. BEGIN
  738. RETURN (BITS(c) * {0..3,5..9,11..15,31} = {0,2,3,8,12..15}) & ~((BITS(c) * {24..27} = {24..27}) & (4 IN BITS(c)))
  739. END IsADDSPMI;
  740. (* A7.7.171: SUB (immediate), encoding T3 *)
  741. PROCEDURE IsSUBMI (c: INTEGER): BOOLEAN;
  742. BEGIN
  743. RETURN (BITS(c) * {5..9,11..15,31} = {5,7,8,12..15}) & ~((BITS(c) * {24..27} = {24..27}) & (4 IN BITS(c))) & (BITS(c) * {0..3} # {0,2,3})
  744. END IsSUBMI;
  745. (* A7.7.173: SUB (SP minus immediate), encoding T2 *)
  746. PROCEDURE IsSUBSPMI (c: INTEGER): BOOLEAN;
  747. BEGIN
  748. RETURN (BITS(c) * {0..3,5..9,11..15,31} = {0,2,3,5,7,8,12..15}) & ~((BITS(c) * {24..27} = {24..27}) & (4 IN BITS(c)))
  749. END IsSUBSPMI;
  750. (* A7.7.27: CMP (immediate), encoding T2 *)
  751. PROCEDURE IsCMPImW* (c: INTEGER): BOOLEAN;
  752. BEGIN
  753. RETURN BITS(c) * {4..9,11..15,24..27,31} = {4,5,7,8,12..15,24..27}
  754. END IsCMPImW;
  755. (* A7.7.117: RSB (immediate), encoding T2 *)
  756. PROCEDURE IsRSBImW (c: INTEGER): BOOLEAN;
  757. BEGIN
  758. RETURN BITS(c) * {5..9,11..15,31} = {6..8,12..15}
  759. END IsRSBImW;
  760. (* A5.3 *)
  761. PROCEDURE IsDPPBI (c: INTEGER): BOOLEAN;
  762. BEGIN
  763. RETURN BITS(c) * {9,11..15,31} = {9,12..15}
  764. END IsDPPBI;
  765. (* A7.7.75: MOV (immediate), encoding T3 *)
  766. PROCEDURE IsMOVPBI (c: INTEGER): BOOLEAN;
  767. BEGIN
  768. RETURN BITS(c) * {4..9,11..15,31} = {6,9,12..15}
  769. END IsMOVPBI;
  770. (* A7.7.75: MOVT, encoding T1 *)
  771. PROCEDURE IsMOVT (c: INTEGER): BOOLEAN;
  772. BEGIN
  773. RETURN BITS(c) * {4..9,11..15,31} = {6,7,9,12..15}
  774. END IsMOVT;
  775. (* A7.7.3: ADD (immediate), encoding T4 *)
  776. PROCEDURE IsADDPBI (c: INTEGER): BOOLEAN;
  777. BEGIN
  778. RETURN (BITS(c) * {4..9,11..15,31} = {9,12..15}) & (BITS(c) * {0..3} # {0..3}) & (BITS(c) * {0..3} # {0,2,3})
  779. END IsADDPBI;
  780. (* A7.7.5: ADD (SP plus immediate), encoding T4 *)
  781. PROCEDURE IsADDSPPBI (c: INTEGER): BOOLEAN;
  782. BEGIN
  783. RETURN BITS(c) * {0..9,11..15,31} = {0,2,3,9,12..15}
  784. END IsADDSPPBI;
  785. (* A7.7.171: SUB (immediate), encoding T4 *)
  786. PROCEDURE IsSUBPBI (c: INTEGER): BOOLEAN;
  787. BEGIN
  788. RETURN (BITS(c) * {4..9,11..15,31} = {5,7,9,12..15}) & (BITS(c) * {0..3} # {0..3}) & (BITS(c) * {0..3} # {0,2,3})
  789. END IsSUBPBI;
  790. (* A7.7.173: SUB (SP minus immediate), encoding T3 *)
  791. PROCEDURE IsSUBSPPBI (c: INTEGER): BOOLEAN;
  792. BEGIN
  793. RETURN BITS(c) * {0..9,11..15,31} = {0,2,3,5,7,9,12..15}
  794. END IsSUBSPPBI;
  795. (* A5.3 *)
  796. PROCEDURE IsBAMC (c: INTEGER): BOOLEAN;
  797. BEGIN
  798. RETURN BITS(c) * {11..15,31} = {12..15,31}
  799. END IsBAMC;
  800. (* A7.7.12, encoding T3 *)
  801. PROCEDURE IsBC (c: INTEGER): BOOLEAN;
  802. BEGIN
  803. RETURN BITS(c) * {11..15,28,30,31} = {12..15,31}
  804. END IsBC;
  805. (* A7.7.12, encoding T4 *)
  806. PROCEDURE IsB (c: INTEGER): BOOLEAN;
  807. BEGIN
  808. RETURN BITS(c) * {11..15,28,30,31} = {12..15,28,31}
  809. END IsB;
  810. (* A7.7.18: BL, encoding T1 *)
  811. PROCEDURE IsBL (c: INTEGER): BOOLEAN;
  812. BEGIN
  813. RETURN BITS(c) * {11..15,28,30,31} = {12..15,28,30,31}
  814. END IsBL;
  815. (* A5.3 *)
  816. PROCEDURE IsSSDI (c: INTEGER): BOOLEAN;
  817. BEGIN
  818. RETURN BITS(c) * {4,8..15} = {11..15}
  819. END IsSSDI;
  820. (* A7.7.158: STR (immediate), encoding T3 *)
  821. PROCEDURE IsSWImW (c: INTEGER): BOOLEAN;
  822. BEGIN
  823. RETURN (BITS(c) * {4..15} = {6,7,11..15}) & (BITS(c) * {0..3} # {0..3})
  824. END IsSWImW;
  825. (* A7.7.159: STR (register), encoding T2 *)
  826. PROCEDURE IsSWRW (c: INTEGER): BOOLEAN;
  827. BEGIN
  828. RETURN (BITS(c) * {4..15,22..27} = {6,11..15}) & (BITS(c) * {0..3} # {0..3})
  829. END IsSWRW;
  830. (* A7.7.160: STRB (immediate), encoding T2 *)
  831. PROCEDURE IsSBImW (c: INTEGER): BOOLEAN;
  832. BEGIN
  833. RETURN (BITS(c) * {4..15} = {7,11..15}) & (BITS(c) * {0..3} # {0..3})
  834. END IsSBImW;
  835. (* A7.7.161: STRB (register), encoding T2 *)
  836. PROCEDURE IsSBRW (c: INTEGER): BOOLEAN;
  837. BEGIN
  838. RETURN (BITS(c) * {4..15,22..27} = {11..15}) & (BITS(c) * {0..3} # {0..3})
  839. END IsSBRW;
  840. (* A5.3 *)
  841. PROCEDURE IsLBMH (c: INTEGER): BOOLEAN;
  842. BEGIN
  843. RETURN BITS(c) * {4..6,9..15} = {4,11..15}
  844. END IsLBMH;
  845. (* A7.7.45: LDRB (immediate), encoding T2 *)
  846. PROCEDURE IsLBImW (c: INTEGER): BOOLEAN;
  847. BEGIN
  848. RETURN (BITS(c) * {4..15} = {4,7,11..15}) & (BITS(c) * {28..31} # {28..31}) & (BITS(c) * {0..3} # {0..3})
  849. END IsLBImW;
  850. (* A7.7.47: LDRB (register), encoding T2 *)
  851. PROCEDURE IsLBRW (c: INTEGER): BOOLEAN;
  852. BEGIN
  853. RETURN (BITS(c) * {4..15,22..27} = {4,11..15}) & (BITS(c) * {28..31} # {28..31}) & (BITS(c) * {0..3} # {0..3})
  854. END IsLBRW;
  855. (* A5.3 *)
  856. PROCEDURE IsLW (c: INTEGER): BOOLEAN;
  857. BEGIN
  858. RETURN BITS(c) * {4..6,9..15} = {4,6,11..15}
  859. END IsLW;
  860. (* A7.7.42: LDR (immediate), encoding T3 *)
  861. PROCEDURE IsLWImW (c: INTEGER): BOOLEAN;
  862. BEGIN
  863. RETURN (BITS(c) * {4..15} = {4,6,7,11..15}) & (BITS(c) * {0..3} # {0..3})
  864. END IsLWImW;
  865. (* A7.7.42: LDR (immediate), encoding T4, P = 1, U = 0, W = 0 *)
  866. PROCEDURE IsLWImWNeg (c: INTEGER): BOOLEAN;
  867. BEGIN
  868. RETURN (BITS(c) * {4..15,24..27} = {4,6,11..15,26,27}) & (BITS(c) * {0..3} # {0..3})
  869. END IsLWImWNeg;
  870. (* A7.7.43: LDR (literal); encoding T2 *)
  871. PROCEDURE IsLWLt (c: INTEGER): BOOLEAN;
  872. BEGIN
  873. RETURN BITS(c) * {0..6,8..15} = {0..4,6,11..15}
  874. END IsLWLt;
  875. (* A7.7.44: LDR (register); encoding T2 *)
  876. PROCEDURE IsLWRW (c: INTEGER): BOOLEAN;
  877. BEGIN
  878. RETURN (BITS(c) * {4..15,22..27} = {4,6,11..15}) & (BITS(c) * {0..3} # {0..3})
  879. END IsLWRW;
  880. (* A5.3 *)
  881. PROCEDURE IsDPR (c: INTEGER): BOOLEAN;
  882. BEGIN
  883. RETURN BITS(c) * {8..15} = {9,11..15}
  884. END IsDPR;
  885. (* A7.7.68: LSL (register); encoding T2 *)
  886. PROCEDURE IsLSLR (c: INTEGER): BOOLEAN;
  887. BEGIN
  888. RETURN BITS(c) * {5..15,20..23,28..31} = {9,11..15,28..31}
  889. END IsLSLR;
  890. (* A7.7.11: ASR (register); encoding T2 *)
  891. PROCEDURE IsASRR (c: INTEGER): BOOLEAN;
  892. BEGIN
  893. RETURN BITS(c) * {5..15,20..23,28..31} = {6,9,11..15,28..31}
  894. END IsASRR;
  895. (* A7.7.115: ROR (register); encoding T2 *)
  896. PROCEDURE IsRORR (c: INTEGER): BOOLEAN;
  897. BEGIN
  898. RETURN BITS(c) * {5..15,20..23,28..31} = {5,6,9,11..15,28..31}
  899. END IsRORR;
  900. (* A5.3 *)
  901. PROCEDURE IsMMAAAD (c: INTEGER): BOOLEAN;
  902. BEGIN
  903. RETURN BITS(c) * {7..15} = {8,9,11..15}
  904. END IsMMAAAD;
  905. (* A7.7.73: MLA; encoding T1 *)
  906. PROCEDURE IsMLA (c: INTEGER): BOOLEAN;
  907. BEGIN
  908. RETURN (BITS(c) * {4..15,20..23} = {8,9,11..15}) & (BITS(c) * {28..31} # {28..31})
  909. END IsMLA;
  910. (* A7.7.74: MLS; encoding T1 *)
  911. PROCEDURE IsMLS (c: INTEGER): BOOLEAN;
  912. BEGIN
  913. RETURN BITS(c) * {4..15,20..23} = {8,9,11..15,20}
  914. END IsMLS;
  915. (* A7.7.83: MUL; encoding T2 *)
  916. PROCEDURE IsMUL (c: INTEGER): BOOLEAN;
  917. BEGIN
  918. RETURN BITS(c) * {4..15,20..23,28..31} = {8,9,11..15,28..31}
  919. END IsMUL;
  920. (* A5.3 *)
  921. PROCEDURE IsLMLMAAD (c: INTEGER): BOOLEAN;
  922. BEGIN
  923. RETURN BITS(c) * {7..15} = {7..9,11..15}
  924. END IsLMLMAAD;
  925. (* A7.7.125: SDIV; encoding T1 *)
  926. PROCEDURE IsSDIV (c: INTEGER): BOOLEAN;
  927. BEGIN
  928. RETURN BITS(c) * {4..15,20..23,28..31} = {4,7..9,11..15,20..23,28..31}
  929. END IsSDIV;
  930. (* A6.4: Floating-point data-processing instructions *)
  931. PROCEDURE IsFPDP (c: INTEGER): BOOLEAN;
  932. BEGIN
  933. RETURN BITS(c) * {8..11,13..15,20,25..27} = {9..11,13..15,25,27}
  934. END IsFPDP;
  935. (* A7.7.227: VFMA: encoding T1 *)
  936. PROCEDURE IsVFMA (c: INTEGER): BOOLEAN;
  937. BEGIN
  938. RETURN BITS(c) * {4,5,7..15,20,22,24..27} = {5,7,9..11,13..15,25,27}
  939. END IsVFMA;
  940. (* A7.7.227: VFMS: encoding T1 *)
  941. PROCEDURE IsVFMS (c: INTEGER): BOOLEAN;
  942. BEGIN
  943. RETURN BITS(c) * {4,5,7..15,20,22,24..27} = {5,7,9..11,13..15,22,25,27}
  944. END IsVFMS;
  945. (* A7.7.228: VFNMA: encoding T1 *)
  946. PROCEDURE IsVFNMA (c: INTEGER): BOOLEAN;
  947. BEGIN
  948. RETURN BITS(c) * {4,5,7..15,20,22,24..27} = {4,7,9..11,13..15,25,27}
  949. END IsVFNMA;
  950. (* A7.7.228: VFNMS: encoding T1 *)
  951. PROCEDURE IsVFNMS (c: INTEGER): BOOLEAN;
  952. BEGIN
  953. RETURN BITS(c) * {4,5,7..15,20,22,24..27} = {4,7,9..11,13..15,22,25,27}
  954. END IsVFNMS;
  955. (* A7.7.241: VMUL; encoding T1 *)
  956. PROCEDURE IsVMUL (c: INTEGER): BOOLEAN;
  957. BEGIN
  958. RETURN BITS(c) * {4,5,7..15,20,22,24..27} = {5,9..11,13..15,25,27}
  959. END IsVMUL;
  960. (* A7.7.243: VNMUL; encoding T2 *)
  961. PROCEDURE IsVNMUL (c: INTEGER): BOOLEAN;
  962. BEGIN
  963. RETURN BITS(c) * {4,5,7..15,20,22,24..27} = {5,9..11,13..15,22,25,27}
  964. END IsVNMUL;
  965. (* A7.7.221: VADD; encoding T1 *)
  966. PROCEDURE IsVADD (c: INTEGER): BOOLEAN;
  967. BEGIN
  968. RETURN BITS(c) * {4,5,7..15,20,22,24..27} = {4,5,9..11,13..15,25,27}
  969. END IsVADD;
  970. (* A7.7.249: VSUB; encoding T1 *)
  971. PROCEDURE IsVSUB (c: INTEGER): BOOLEAN;
  972. BEGIN
  973. RETURN BITS(c) * {4,5,7..15,20,22,24..27} = {4,5,9..11,13..15,22,25,27}
  974. END IsVSUB;
  975. (* A7.7.226: VDIV; encoding T1 *)
  976. PROCEDURE IsVDIV (c: INTEGER): BOOLEAN;
  977. BEGIN
  978. RETURN BITS(c) * {4,5,7..15,20,22,24..27} = {7,9..11,13..15,25,27}
  979. END IsVDIV;
  980. (* A7.7.220: VABS; encoding T1 *)
  981. PROCEDURE IsVABS (c: INTEGER): BOOLEAN;
  982. BEGIN
  983. RETURN BITS(c) * {0..5,7..15,20,22..27} = {4,5,7,9..11,13..15,22,23,25,27}
  984. END IsVABS;
  985. (* A7.7.242: VNEG; encoding T1 *)
  986. PROCEDURE IsVNEG (c: INTEGER): BOOLEAN;
  987. BEGIN
  988. RETURN BITS(c) * {0..5,7..15,20,22..27} = {0,4,5,7,9..11,13..15,22,25,27}
  989. END IsVNEG;
  990. (* A7.7.246: VSQRT; encoding T1 *)
  991. PROCEDURE IsVSQRT (c: INTEGER): BOOLEAN;
  992. BEGIN
  993. RETURN BITS(c) * {0..5,7..15,20,22..27} = {0,4,5,7,9..11,13..15,22,23,25,27}
  994. END IsVSQRT;
  995. (* A7.7.222: VCMP{E}; encoding T1 *)
  996. PROCEDURE IsVCMPER (c: INTEGER): BOOLEAN;
  997. BEGIN
  998. RETURN BITS(c) * {0..5,7..15,20,22,24..27} = {2,4,5,7,9..11,13..15,22,25,27}
  999. END IsVCMPER;
  1000. (* A7.7.222: VCMP{E}; encoding T2 *)
  1001. PROCEDURE IsVCMPE0 (c: INTEGER): BOOLEAN;
  1002. BEGIN
  1003. RETURN BITS(c) * {0..5,7..15,16..22,24..27} = {0,2,4,5,7,9..11,13..15,22,25,27}
  1004. END IsVCMPE0;
  1005. (* A7.7.223: VCVT, VCVTR (between floating-point and integer); encoding T1 *)
  1006. PROCEDURE IsVCVTRInt (c: INTEGER): BOOLEAN;
  1007. BEGIN
  1008. RETURN BITS(c) * {1,3..5,7..15,20,22,24..27} = {3..5,7,9..11,13..15,22,25,27}
  1009. END IsVCVTRInt;
  1010. (* A6.5: (Floating-point) Extension register load or store instructions *)
  1011. PROCEDURE IsFPERLOS (c: INTEGER): BOOLEAN;
  1012. BEGIN
  1013. RETURN BITS(c) * {9..11,13..15,25..27} = {10,11,13..15,25,27}
  1014. END IsFPERLOS;
  1015. (* A7.7.248: VSTR; encoding T2 *)
  1016. PROCEDURE IsVSTR (c: INTEGER): BOOLEAN;
  1017. BEGIN
  1018. RETURN BITS(c) * {4,5,8..15,24..27} = {8,10,11,13..15,25,27}
  1019. END IsVSTR;
  1020. (* A7.7.230: VLDR; encoding T2 *)
  1021. PROCEDURE IsVLDR (c: INTEGER): BOOLEAN;
  1022. BEGIN
  1023. RETURN BITS(c) * {4,5,8..15,24..27} = {4,8,10,11,13..15,25,27}
  1024. END IsVLDR;
  1025. (* A6.6: (Floating-point) 32-bit transfer between ARM core and extension registers *)
  1026. PROCEDURE IsFP32TBACAER (c: INTEGER): BOOLEAN;
  1027. BEGIN
  1028. RETURN BITS(c) * {8..11,13..15,20,25..27} = {9..11,13..15,20,25,27}
  1029. END IsFP32TBACAER;
  1030. (* A7.7.236: VMOV (between ARM core register and single-precision register); encoding T1 *)
  1031. PROCEDURE IsVMOVSPR (c: INTEGER): BOOLEAN;
  1032. BEGIN
  1033. RETURN BITS(c) * {5..22,24..27} = {9..11,13..15,20,25,27}
  1034. END IsVMOVSPR;
  1035. (* A7.7.239: VMRS; encoding T1 *)
  1036. PROCEDURE IsVMRS (c: INTEGER): BOOLEAN;
  1037. BEGIN
  1038. RETURN BITS(c) * {0..27} = {0,4..7,9..11,13..15,20,25,27}
  1039. END IsVMRS;
  1040. (* A7.7.240: VMSR; encoding T1 *)
  1041. PROCEDURE IsVMSR (c: INTEGER): BOOLEAN;
  1042. BEGIN
  1043. RETURN BITS(c) * {0..27} = {0,5..7,9..11,13..15,20,25,27}
  1044. END IsVMSR;
  1045. PROCEDURE IsWFIW (c: INTEGER): BOOLEAN;
  1046. BEGIN
  1047. RETURN c = 8003F3AFH
  1048. END IsWFIW;
  1049. PROCEDURE EmitWFIW* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER);
  1050. BEGIN
  1051. Emit2(code, pc, -2147224657 (*8003F3AFH*))
  1052. END EmitWFIW;
  1053. (* A7.7.12, encoding T3 *)
  1054. PROCEDURE DecodeBC (c: INTEGER; (*OUT*)VAR cond, label: INTEGER);
  1055. VAR S, imm6, J1, J2, imm11: INTEGER;
  1056. BEGIN
  1057. ASSERT(IsBC(c), 20);
  1058. imm11 := c DIV 10000H MOD 800H;
  1059. J2 := c DIV 8000000H MOD 2;
  1060. J1 := c DIV 20000000H MOD 2;
  1061. imm6 := c MOD 40H;
  1062. cond := c DIV 40H MOD 10H;
  1063. S := c DIV 400H MOD 2;
  1064. label := DecodeBLabel20(S, imm6, J1, J2, imm11)
  1065. END DecodeBC;
  1066. (* A7.7.12, encoding T4 *)
  1067. PROCEDURE DecodeB (c: INTEGER): INTEGER;
  1068. VAR S, imm10, J1, J2, imm11: INTEGER;
  1069. BEGIN
  1070. ASSERT(IsB(c), 20);
  1071. imm11 := c DIV 10000H MOD 800H;
  1072. J2 := c DIV 8000000H MOD 2;
  1073. J1 := c DIV 20000000H MOD 2;
  1074. imm10 := c MOD 400H;
  1075. S := c DIV 400H MOD 2;
  1076. RETURN ARMv6M.DecodeBLabel24(S, imm10, J1, J2, imm11)
  1077. END DecodeB;
  1078. PROCEDURE OpcodeRepr2 (c: INTEGER; (*OUT*)VAR s: ARRAY OF CHAR);
  1079. VAR w: INTEGER;
  1080. PROCEDURE WStr ((*OUT*)VAR s: ARRAY OF CHAR; VAR w: INTEGER; (*IN*) s0: ARRAY OF CHAR);
  1081. VAR i: INTEGER;
  1082. BEGIN
  1083. i := 0;
  1084. WHILE (i < LEN(s0(*$*))) & (s0[i] # 0X) DO
  1085. s[w] := s0[i]; INC(w);
  1086. INC(i)
  1087. END
  1088. END WStr;
  1089. PROCEDURE WReg ((*OUT*)VAR s: ARRAY OF CHAR; VAR w: INTEGER; r: INTEGER);
  1090. VAR s0: ARRAY 4 OF CHAR;
  1091. BEGIN
  1092. ARMv6M.RegRepr(r, s0);
  1093. WStr(s, w, s0)
  1094. END WReg;
  1095. PROCEDURE WInt ((*OUT*)VAR s: ARRAY OF CHAR; VAR w: INTEGER; x: INTEGER);
  1096. VAR s0: ARRAY 12 OF CHAR;
  1097. BEGIN
  1098. Strings.IntToStr(x, s0);
  1099. WStr(s, w, s0)
  1100. END WInt;
  1101. PROCEDURE WHex32 ((*OUT*)VAR s: ARRAY OF CHAR; VAR w: INTEGER; x: INTEGER);
  1102. VAR i, a: INTEGER;
  1103. BEGIN i := 8;
  1104. REPEAT
  1105. a := x DIV 10000000H MOD 10H; x := x * 10H;
  1106. IF a < 10 THEN s[w] := CHR(ORD('0') + a)
  1107. ELSE s[w] := CHR(ORD('A') - 10 + a)
  1108. END; INC(w);
  1109. DEC(i)
  1110. UNTIL i = 0
  1111. END WHex32;
  1112. PROCEDURE WHex16L ((*OUT*)VAR s: ARRAY OF CHAR; VAR w: INTEGER; x: INTEGER);
  1113. VAR i, a: INTEGER;
  1114. BEGIN i := 4;
  1115. REPEAT
  1116. a := x DIV 1000H MOD 10H; x := x * 10H;
  1117. IF a < 10 THEN s[w] := CHR(ORD('0') + a)
  1118. ELSE s[w] := CHR(ORD('A') - 10 + a)
  1119. END; INC(w);
  1120. DEC(i)
  1121. UNTIL i = 0
  1122. END WHex16L;
  1123. PROCEDURE WHex12L ((*OUT*)VAR s: ARRAY OF CHAR; VAR w: INTEGER; x: INTEGER);
  1124. VAR i, a: INTEGER;
  1125. BEGIN i := 3;
  1126. REPEAT
  1127. a := x DIV 100H MOD 10H; x := x * 10H;
  1128. IF a < 10 THEN s[w] := CHR(ORD('0') + a)
  1129. ELSE s[w] := CHR(ORD('A') - 10 + a)
  1130. END; INC(w);
  1131. DEC(i)
  1132. UNTIL i = 0
  1133. END WHex12L;
  1134. PROCEDURE LMASM;
  1135. PROCEDURE Op0 ((*IN*) op: ARRAY OF CHAR; unpr: BOOLEAN);
  1136. VAR i, j: INTEGER;
  1137. BEGIN
  1138. WStr(s, w, op); WStr(s, w, ".W {");
  1139. i := 0; j := 0;
  1140. WHILE i < 16 DO
  1141. IF (16 + i) IN BITS(c) THEN
  1142. IF j # 0 THEN WStr(s, w, ", ") END;
  1143. WReg(s, w, i);
  1144. INC(j)
  1145. END;
  1146. INC(i)
  1147. END;
  1148. s[w] := '}'; INC(w);
  1149. IF (j < 2) OR unpr THEN
  1150. WStr(s, w, " (UNPREDICTABLE)")
  1151. END
  1152. END Op0;
  1153. BEGIN
  1154. IF IsPUSHMany(c) THEN
  1155. Op0("PUSH", FALSE)
  1156. ELSIF IsPOPMany(c) THEN
  1157. Op0("POP", c DIV 40000000H = -1)
  1158. END
  1159. END LMASM;
  1160. PROCEDURE PUSHPOPOne;
  1161. VAR Rt: INTEGER;
  1162. PROCEDURE Op1 ((*IN*) op: ARRAY OF CHAR; unpr: BOOLEAN);
  1163. BEGIN
  1164. WStr(s, w, op); WStr(s, w, ".W {"); WReg(s, w, Rt);
  1165. s[w] := '}'; INC(w);
  1166. IF unpr THEN
  1167. WStr(s, w, " (UNPREDICTABLE)")
  1168. END
  1169. END Op1;
  1170. BEGIN
  1171. IF IsPUSHOne(c) THEN (* SSDI *)
  1172. Rt := c DIV 10000000H MOD 10H;
  1173. Op1("PUSH", Rt IN {SP,PC})
  1174. ELSIF IsPOPOne(c) THEN (* LW *)
  1175. Rt := c DIV 10000000H MOD 10H;
  1176. Op1("POP", Rt = SP)
  1177. END
  1178. END PUSHPOPOne;
  1179. PROCEDURE DPSR;
  1180. VAR S, Rd, Rn, Rm, shift: INTEGER;
  1181. PROCEDURE WDPSR0 ((*IN*) op: ARRAY OF CHAR; W: BOOLEAN; shift: INTEGER; unpr: BOOLEAN);
  1182. BEGIN
  1183. ASSERT(S IN {0,1}, 20);
  1184. WStr(s, w, op);
  1185. IF S = 1 THEN s[w] := 'S'; INC(w) END;
  1186. IF W THEN WStr(s, w, ".W") END;
  1187. s[w] := ' '; INC(w);
  1188. WReg(s, w, Rd); WStr(s, w, ", "); WReg(s, w, Rm);
  1189. IF shift # 0 THEN
  1190. WStr(s, w, ", #");
  1191. WInt(s, w, shift)
  1192. END;
  1193. IF unpr THEN WStr(s, w, " (UNPREDICTABLE)") END
  1194. END WDPSR0;
  1195. PROCEDURE WDPSR1 ((*IN*) op: ARRAY OF CHAR; W: BOOLEAN; shift: INTEGER; unpr: BOOLEAN);
  1196. BEGIN
  1197. ASSERT(S IN {0,1}, 20);
  1198. WStr(s, w, op);
  1199. IF S = 1 THEN s[w] := 'S'; INC(w) END;
  1200. IF W THEN WStr(s, w, ".W") END;
  1201. s[w] := ' '; INC(w);
  1202. WReg(s, w, Rd); WStr(s, w, ", ");
  1203. WReg(s, w, Rn); WStr(s, w, ", "); WReg(s, w, Rm);
  1204. IF shift # 0 THEN
  1205. WStr(s, w, ", #");
  1206. WInt(s, w, shift)
  1207. END;
  1208. IF unpr THEN WStr(s, w, " (UNPREDICTABLE)") END
  1209. END WDPSR1;
  1210. BEGIN
  1211. S := c DIV 10H MOD 2;
  1212. Rd := c DIV 1000000H MOD 10H;
  1213. Rn := c MOD 10H;
  1214. Rm := c DIV 10000H MOD 10H;
  1215. IF IsMVNR(c) THEN
  1216. (* TODO: DecodeImmShift *)
  1217. IF (c DIV 100000H MOD 10H = 0) & (c DIV 10000000H MOD 8 = 0) THEN
  1218. WDPSR0("MVN", TRUE, 0, (Rd IN {SP,PC}) OR (Rm IN {SP,PC}))
  1219. END
  1220. ELSIF IsMOVR(c) THEN
  1221. WDPSR0("MOV", TRUE, 0, ((S = 1) & ((Rd IN {SP,PC}) OR (Rm IN {SP,PC}))) OR ((S = 0) & ((Rd = PC) OR (Rm = PC) OR (Rd = SP) & (Rm = SP))))
  1222. ELSIF IsANDR(c) THEN ASSERT(~((Rd = PC) & (S = 1)), 100);
  1223. (* TODO: DecodeImmShift *)
  1224. IF (c DIV 100000H MOD 10H = 0) & (c DIV 10000000H MOD 8 = 0) THEN
  1225. WDPSR1("AND", TRUE, 0, (Rd = SP) OR (Rd = PC) & (S = 0) OR (Rn IN {SP,PC}) OR (Rm IN {SP,PC}))
  1226. END
  1227. ELSIF IsBICR(c) THEN
  1228. (* TODO: DecodeImmShift *)
  1229. IF (c DIV 100000H MOD 10H = 0) & (c DIV 10000000H MOD 8 = 0) THEN
  1230. WDPSR1("BIC", TRUE, 0, (Rd IN {SP,PC}) OR (Rn IN {SP,PC}) OR (Rm IN {SP,PC}))
  1231. END
  1232. ELSIF IsORRR(c) THEN ASSERT(Rn # PC, 101);
  1233. (* TODO: DecodeImmShift *)
  1234. IF (c DIV 100000H MOD 10H = 0) & (c DIV 10000000H MOD 8 = 0) THEN
  1235. WDPSR1("ORR", TRUE, 0, (Rd IN {SP,PC}) OR (Rn = SP) OR (Rm IN {SP,PC}))
  1236. END
  1237. ELSIF IsEORR(c) THEN ASSERT(~((Rd = PC) & (S = 1)), 102);
  1238. (* TODO: DecodeImmShift *)
  1239. IF (c DIV 100000H MOD 10H = 0) & (c DIV 10000000H MOD 8 = 0) THEN
  1240. WDPSR1("EOR", TRUE, 0, (Rd = SP) OR (Rd = PC) & (S = 0) OR (Rn IN {SP,PC}) OR (Rm IN {SP,PC}))
  1241. END
  1242. ELSIF IsADDR(c) THEN
  1243. ASSERT(~((Rd = PC) & (S = 1)), 103); ASSERT(Rn # SP, 104);
  1244. (* TODO: DecodeImmShift *)
  1245. IF (c DIV 100000H MOD 10H = 0) & (c DIV 10000000H MOD 8 = 0) THEN
  1246. WDPSR1("ADD", TRUE, 0, (Rd = SP) OR (Rd = PC) & (S = 0) OR (Rn = PC) OR (Rm IN {SP,PC}))
  1247. END
  1248. ELSIF IsADDSPR(c) THEN
  1249. (* TODO: DecodeImmShift *)
  1250. IF (c DIV 100000H MOD 10H = 0) & (c DIV 10000000H MOD 8 = 0) THEN
  1251. WDPSR1("ADD", TRUE, 0, (Rd = PC) OR (Rm IN {SP,PC})) (* TODO: unpr depend on shift *)
  1252. END
  1253. ELSIF IsADCR(c) THEN
  1254. (* TODO: DecodeImmShift *)
  1255. IF (c DIV 100000H MOD 10H = 0) & (c DIV 10000000H MOD 8 = 0) THEN
  1256. WDPSR1("ADC", TRUE, 0, (Rd IN {SP,PC}) OR (Rn IN {SP,PC}) OR (Rm IN {SP,PC}))
  1257. END
  1258. ELSIF IsSUBR(c) THEN
  1259. ASSERT(~((Rd = PC) & (S = 1)), 105); ASSERT(Rn # SP, 106);
  1260. (* TODO: DecodeImmShift *)
  1261. IF (c DIV 100000H MOD 10H = 0) & (c DIV 10000000H MOD 8 = 0) THEN
  1262. WDPSR1("SUB", TRUE, 0, (Rd = SP) OR (Rd = PC) & (S = 0) OR (Rn = PC) OR (Rm IN {SP,PC}))
  1263. END
  1264. ELSIF IsSUBSPR(c) THEN
  1265. (* TODO: DecodeImmShift *)
  1266. IF (c DIV 100000H MOD 10H = 0) & (c DIV 10000000H MOD 8 = 0) THEN
  1267. WDPSR1("SUB", FALSE, 0, (Rd = PC) OR (Rm IN {SP,PC})) (* TODO: unpr depend on shift *)
  1268. END
  1269. ELSIF IsSBCR(c) THEN
  1270. (* TODO: DecodeImmShift *)
  1271. IF (c DIV 100000H MOD 10H = 0) & (c DIV 10000000H MOD 8 = 0) THEN
  1272. WDPSR1("SBC", TRUE, 0, (Rd IN {SP,PC}) OR (Rn IN {SP,PC}) OR (Rm IN {SP,PC}))
  1273. END
  1274. ELSIF IsLSLIm(c) THEN
  1275. shift := c DIV 10000000H MOD 8 * 4 + c DIV 400000H MOD 4;
  1276. ASSERT(shift # 0, 107);
  1277. WDPSR0("LSL", TRUE, shift, (Rd IN {SP,PC}) OR (Rm IN {SP,PC}))
  1278. ELSIF IsASRIm(c) THEN
  1279. shift := c DIV 10000000H MOD 8 * 4 + c DIV 400000H MOD 4;
  1280. WDPSR0("ASR", TRUE, shift, (Rd IN {SP,PC}) OR (Rm IN {SP,PC}))
  1281. ELSIF IsRORIm(c) THEN
  1282. shift := c DIV 10000000H MOD 8 * 4 + c DIV 400000H MOD 4;
  1283. ASSERT(shift # 0, 108);
  1284. WDPSR0("ROR", FALSE, shift, (Rd IN {SP,PC}) OR (Rm IN {SP,PC}))
  1285. END
  1286. END DPSR;
  1287. PROCEDURE DPMI;
  1288. VAR i, imm3, imm8, im, S, Rn, Rd: INTEGER;
  1289. ok: BOOLEAN;
  1290. PROCEDURE WOp0 ((*IN*) op: ARRAY OF CHAR; unpr: BOOLEAN);
  1291. BEGIN
  1292. WStr(s, w, op);
  1293. s[w] := ' '; INC(w);
  1294. WReg(s, w, Rn); WStr(s, w, ", #");
  1295. IF ok THEN
  1296. IF (im >= -1) & (im <= 255) THEN
  1297. WInt(s, w, im)
  1298. ELSE
  1299. WStr(s, w, "0x"); WHex32(s, w, im)
  1300. END
  1301. ELSE WStr(s, w, "(UNPREDICTABLE)")
  1302. END;
  1303. IF unpr THEN
  1304. WStr(s, w, " (UNPREDICTABLE)")
  1305. END
  1306. END WOp0;
  1307. PROCEDURE WOp1 ((*IN*) op: ARRAY OF CHAR; W: BOOLEAN; unpr: BOOLEAN);
  1308. BEGIN
  1309. WStr(s, w, op);
  1310. IF S = 1 THEN s[w] := 'S'; INC(w) END;
  1311. IF W THEN WStr(s, w, ".W") END;
  1312. s[w] := ' '; INC(w);
  1313. WReg(s, w, Rd); WStr(s, w, ", #");
  1314. IF ok THEN
  1315. IF (im >= -1) & (im <= 255) THEN
  1316. WInt(s, w, im)
  1317. ELSE
  1318. WStr(s, w, "0x"); WHex32(s, w, im)
  1319. END
  1320. ELSE WStr(s, w, "(UNPREDICTABLE)")
  1321. END;
  1322. IF unpr THEN
  1323. WStr(s, w, " (UNPREDICTABLE)")
  1324. END
  1325. END WOp1;
  1326. PROCEDURE WOp2 ((*IN*) op: ARRAY OF CHAR; W: BOOLEAN; unpr: BOOLEAN);
  1327. BEGIN
  1328. WStr(s, w, op);
  1329. IF S = 1 THEN s[w] := 'S'; INC(w) END;
  1330. IF W THEN WStr(s, w, ".W") END;
  1331. s[w] := ' '; INC(w);
  1332. WReg(s, w, Rd); WStr(s, w, ", ");
  1333. WReg(s, w, Rn); WStr(s, w, ", #");
  1334. IF ok THEN
  1335. IF (im >= -1) & (im <= 255) THEN
  1336. WInt(s, w, im)
  1337. ELSE
  1338. WStr(s, w, "0x"); WHex32(s, w, im)
  1339. END
  1340. ELSE WStr(s, w, "(UNPREDICTABLE)")
  1341. END;
  1342. IF unpr THEN
  1343. WStr(s, w, " (UNPREDICTABLE)")
  1344. END
  1345. END WOp2;
  1346. BEGIN
  1347. i := c DIV 400H MOD 2;
  1348. S := c DIV 10H MOD 2;
  1349. Rn := c MOD 10H;
  1350. imm3 := c DIV 10000000H MOD 8;
  1351. Rd := c DIV 1000000H MOD 10H;
  1352. imm8 := c DIV 10000H MOD 100H;
  1353. DecodeMI12(i, imm3, imm8, im, ok);
  1354. IF IsTSTIm(c) THEN
  1355. WOp0("TST", Rn IN {SP,PC})
  1356. ELSIF IsCMPImW(c) THEN
  1357. WOp0("CMP.W", Rn = PC)
  1358. ELSIF IsMOVMI(c) THEN
  1359. WOp1("MOV", TRUE, Rd IN {SP,PC})
  1360. ELSIF IsMVNIm(c) THEN
  1361. WOp1("MVN", FALSE, Rd IN {SP,PC})
  1362. ELSIF IsANDIm(c) THEN
  1363. ASSERT(~((Rd = PC) & (S = 1)), 100);
  1364. WOp2("AND", FALSE, (Rd = SP) OR (Rd = PC) & (S = 0) OR (Rn IN {SP,PC}))
  1365. ELSIF IsORRIm(c) THEN
  1366. ASSERT(Rn # PC, 101);
  1367. WOp2("ORR", FALSE, (Rd IN {SP,PC}) OR (Rn = SP))
  1368. ELSIF IsORNIm(c) THEN
  1369. ASSERT(Rn # PC, 102);
  1370. WOp2("ORN", FALSE, (Rd IN {SP,PC}) OR (Rn = SP))
  1371. ELSIF IsBICIm(c) THEN
  1372. WOp2("BIC", FALSE, (Rd IN {SP,PC}) OR (Rn IN {SP,PC}))
  1373. ELSIF IsEORIm(c) THEN
  1374. ASSERT(~((Rd = PC) & (S = 1)), 103);
  1375. WOp2("EOR", FALSE, (Rd = SP) OR (Rd = PC) & (S = 0) OR (Rn IN {SP,PC}))
  1376. ELSIF IsADDMI(c) THEN
  1377. ASSERT(~((Rd = PC) & (S = 1)), 104);
  1378. ASSERT(Rn # SP, 105);
  1379. WOp2("ADD", TRUE, (Rd = SP) OR (Rd = PC) & (S = 0) OR (Rn = PC))
  1380. ELSIF IsADDSPMI(c) THEN
  1381. ASSERT(~((Rd = PC) & (S = 1)), 106);
  1382. WOp2("ADD", TRUE, (Rd = PC) & (S = 0))
  1383. ELSIF IsSUBMI(c) THEN
  1384. ASSERT(~((Rd = PC) & (S = 1)), 107);
  1385. ASSERT(Rn # SP, 108);
  1386. WOp2("SUB", TRUE, (Rd = SP) OR (Rd = PC) & (S = 0) OR (Rn = PC))
  1387. ELSIF IsSUBSPMI(c) THEN
  1388. ASSERT(~((Rd = PC) & (S = 1)), 109);
  1389. WOp2("SUB", TRUE, (Rd = PC) & (S = 0))
  1390. ELSIF IsRSBImW(c) THEN
  1391. WOp2("RSB", TRUE, (Rd IN {SP,PC}) OR (Rn IN {SP,PC}))
  1392. END
  1393. END DPMI;
  1394. PROCEDURE DPPBI;
  1395. VAR Rd, Rn: INTEGER;
  1396. PROCEDURE OpMovx ((*IN*) op: ARRAY OF CHAR);
  1397. VAR im: INTEGER;
  1398. BEGIN
  1399. im := c MOD 10H * 1000H + c DIV 400H MOD 2 * 800H + c DIV 10000000H MOD 8 * 100H + c DIV 10000H MOD 100H;
  1400. WStr(s, w, op); s[w] := ' '; INC(w);
  1401. WReg(s, w, Rd);
  1402. WStr(s, w, ", #"); WInt(s, w, im);
  1403. WStr(s, w, " ; 0x"); WHex16L(s, w, im);
  1404. IF Rd IN {SP,PC} THEN
  1405. WStr(s, w, " (UNPREDICTABLE)")
  1406. END
  1407. END OpMovx;
  1408. PROCEDURE Op0 ((*IN*) op: ARRAY OF CHAR; unpr: BOOLEAN);
  1409. VAR im: INTEGER;
  1410. BEGIN
  1411. im := c DIV 400H MOD 2 * 800H + c DIV 10000000H MOD 8 * 100H + c DIV 10000H MOD 100H;
  1412. WStr(s, w, op); s[w] := ' '; INC(w);
  1413. WReg(s, w, Rd); WStr(s, w, ", ");
  1414. WReg(s, w, Rn); WStr(s, w, ", #");
  1415. WInt(s, w, im);
  1416. WStr(s, w, " ; 0x"); WHex12L(s, w, im);
  1417. IF unpr THEN
  1418. WStr(s, w, " (UNPREDICTABLE)")
  1419. END
  1420. END Op0;
  1421. BEGIN
  1422. Rd := c DIV 1000000H MOD 10H;
  1423. Rn := c MOD 10H;
  1424. IF IsMOVPBI(c) THEN
  1425. OpMovx("MOVW")
  1426. ELSIF IsMOVT(c) THEN
  1427. OpMovx("MOVT")
  1428. ELSIF IsADDPBI(c) THEN
  1429. ASSERT(~(Rn IN {SP,PC}), 100);
  1430. Op0("ADDW", Rd IN {SP,PC})
  1431. ELSIF IsADDSPPBI(c) THEN
  1432. Op0("ADDW", Rd = PC)
  1433. ELSIF IsSUBPBI(c) THEN
  1434. ASSERT(~(Rn IN {SP,PC}), 101);
  1435. Op0("SUBW", Rd IN {SP,PC})
  1436. ELSIF IsSUBSPPBI(c) THEN
  1437. Op0("SUBW", Rd = PC)
  1438. END
  1439. END DPPBI;
  1440. PROCEDURE B (L: BOOLEAN);
  1441. VAR label: INTEGER;
  1442. BEGIN
  1443. IF L THEN label := ARMv6M.DecodeBL(c)
  1444. ELSE label := DecodeB(c)
  1445. END;
  1446. ASSERT(label MOD 2 = 0, 100);
  1447. IF L THEN
  1448. WStr(s, w, "BL ")
  1449. ELSE
  1450. WStr(s, w, "B.W ")
  1451. END;
  1452. WInt(s, w, label);
  1453. IF label # 0 THEN
  1454. WStr(s, w, " ; "); WInt(s, w, label DIV 2)
  1455. END
  1456. END B;
  1457. PROCEDURE BC;
  1458. VAR cond, label: INTEGER;
  1459. s0: ARRAY 3 OF CHAR;
  1460. BEGIN
  1461. DecodeBC(c, cond, label);
  1462. ASSERT(label MOD 2 = 0, 100);
  1463. ARMv6M.CondRepr(cond, s0);
  1464. s[w] := 'B'; INC(w);
  1465. WStr(s, w, s0); WStr(s, w, ".W "); WInt(s, w, label);
  1466. IF label # 0 THEN
  1467. WStr(s, w, " ; "); WInt(s, w, label DIV 2)
  1468. END
  1469. END BC;
  1470. PROCEDURE LSWBImW (S, B: BOOLEAN);
  1471. VAR imm12: INTEGER;
  1472. Rt: INTEGER;
  1473. BEGIN
  1474. IF S THEN
  1475. WStr(s, w, "STR")
  1476. ELSE
  1477. WStr(s, w, "LDR")
  1478. END;
  1479. IF B THEN s[w] := 'B'; INC(w) END;
  1480. WStr(s, w, ".W ");
  1481. Rt := c DIV 10000000H MOD 10H;
  1482. WReg(s, w, Rt);
  1483. WStr(s, w, ", [");
  1484. WReg(s, w, c MOD 10H);
  1485. imm12 := c DIV 10000H MOD 1000H;
  1486. IF imm12 # 0 THEN
  1487. WStr(s, w, ", #");
  1488. WInt(s, w, imm12)
  1489. END;
  1490. s[w] := ']'; INC(w);
  1491. IF (~S & ~B & (Rt = PC))
  1492. OR (~S & B & (Rt = SP))
  1493. OR (S & ~B & (Rt = PC))
  1494. OR (S & B & (Rt IN {SP,PC})) THEN
  1495. WStr(s, w, " (UNPREDICTABLE)")
  1496. END
  1497. END LSWBImW;
  1498. PROCEDURE LSWBImWNeg (S, B: BOOLEAN);
  1499. VAR imm8: INTEGER;
  1500. Rt: INTEGER;
  1501. BEGIN
  1502. IF S THEN
  1503. WStr(s, w, "STR")
  1504. ELSE
  1505. WStr(s, w, "LDR")
  1506. END;
  1507. IF B THEN s[w] := 'B'; INC(w) END;
  1508. WStr(s, w, ".W ");
  1509. Rt := c DIV 10000000H MOD 10H;
  1510. WReg(s, w, Rt);
  1511. WStr(s, w, ", [");
  1512. WReg(s, w, c MOD 10H);
  1513. imm8 := c DIV 10000H MOD 100H;
  1514. IF imm8 # 0 THEN
  1515. WStr(s, w, ", #-");
  1516. WInt(s, w, imm8)
  1517. END;
  1518. s[w] := ']'; INC(w);
  1519. (*
  1520. IF (~S & ~B & (Rt = PC))
  1521. OR (~S & B & (Rt = SP))
  1522. OR (S & ~B & (Rt = PC))
  1523. OR (S & B & (Rt IN {SP,PC})) THEN
  1524. WStr(s, w, " (UNPREDICTABLE)")
  1525. END
  1526. *)
  1527. END LSWBImWNeg;
  1528. PROCEDURE LSWBRW (S, B: BOOLEAN);
  1529. VAR Rt, Rm, imm2: INTEGER;
  1530. BEGIN
  1531. IF S THEN
  1532. WStr(s, w, "STR")
  1533. ELSE
  1534. WStr(s, w, "LDR")
  1535. END;
  1536. IF B THEN s[w] := 'B'; INC(w) END;
  1537. WStr(s, w, ".W ");
  1538. Rt := c DIV 10000000H MOD 10H;
  1539. WReg(s, w, Rt);
  1540. WStr(s, w, ", [");
  1541. WReg(s, w, c MOD 10H);
  1542. imm2 := c DIV 100000H MOD 4;
  1543. Rm := c DIV 10000H MOD 10H;
  1544. WStr(s, w, ", "); WReg(s, w, Rm);
  1545. IF imm2 # 0 THEN
  1546. WStr(s, w, ", LSL #");
  1547. WInt(s, w, imm2)
  1548. END;
  1549. s[w] := ']'; INC(w);
  1550. IF (Rm IN {SP,PC})
  1551. OR (~S & ~B & (Rt = PC))
  1552. OR (~S & B & (Rt = SP))
  1553. OR (S & ~B & (Rt = PC))
  1554. OR (S & B & (Rt IN {SP,PC})) THEN
  1555. WStr(s, w, " (UNPREDICTABLE)")
  1556. END
  1557. END LSWBRW;
  1558. PROCEDURE LW;
  1559. VAR Rt, U, imm12, label: INTEGER;
  1560. BEGIN
  1561. IF IsLWImW(c) THEN
  1562. LSWBImW(FALSE, FALSE)
  1563. ELSIF IsLWImWNeg(c) THEN
  1564. LSWBImWNeg(FALSE, FALSE)
  1565. ELSIF IsLWRW(c) THEN
  1566. LSWBRW(FALSE, FALSE)
  1567. ELSIF IsLWLt(c) THEN
  1568. Rt := c DIV 10000000H MOD 10H;
  1569. U := c DIV 80H MOD 2;
  1570. imm12 := c DIV 10000H MOD 1000H;
  1571. IF U = 1 THEN label := imm12 ELSE label := -imm12 END;
  1572. WStr(s, w, "LDR.W "); WReg(s, w, Rt); WStr(s, w, ", ");
  1573. (* WInt(s, w, label); *)
  1574. WStr(s, w, "[PC, #"); WInt(s, w, label); s[w] := ']'; INC(w);
  1575. IF label MOD 4 = 0 THEN
  1576. WStr(s, w, " ; "); WInt(s, w, label DIV 4)
  1577. END
  1578. END
  1579. END LW;
  1580. PROCEDURE DPR;
  1581. VAR S, Rd, Rn, Rm: INTEGER;
  1582. PROCEDURE WDPRW ((*IN*) op: ARRAY OF CHAR; unpr: BOOLEAN);
  1583. BEGIN
  1584. WStr(s, w, op);
  1585. IF S = 1 THEN s[w] := 'S'; INC(w) END;
  1586. WStr(s, w, ".W ");
  1587. WReg(s, w, Rd); WStr(s, w, ", ");
  1588. WReg(s, w, Rn); WStr(s, w, ", ");
  1589. WReg(s, w, Rm);
  1590. IF unpr THEN WStr(s, w, " (UNPREDICTABLE)") END
  1591. END WDPRW;
  1592. BEGIN
  1593. S := c DIV 10H MOD 2;
  1594. Rd := c DIV 1000000H MOD 10H;
  1595. Rn := c MOD 10H;
  1596. Rm := c DIV 10000H MOD 10H;
  1597. IF IsLSLR(c) THEN
  1598. WDPRW("LSL", (Rd IN {SP,PC}) OR (Rn IN {SP,PC}) OR (Rm IN {SP,PC}))
  1599. ELSIF IsASRR(c) THEN
  1600. WDPRW("ASR", (Rd IN {SP,PC}) OR (Rn IN {SP,PC}) OR (Rm IN {SP,PC}))
  1601. ELSIF IsRORR(c) THEN
  1602. WDPRW("ROR", (Rd IN {SP,PC}) OR (Rn IN {SP,PC}) OR (Rm IN {SP,PC}))
  1603. END
  1604. END DPR;
  1605. PROCEDURE MMAAAD;
  1606. VAR Rd, Rn, Rm, Ra: INTEGER;
  1607. BEGIN
  1608. Rn := c MOD 10H;
  1609. Ra := c DIV 10000000H MOD 10H;
  1610. Rd := c DIV 1000000H MOD 10H;
  1611. Rm := c DIV 10000H MOD 10H;
  1612. IF IsMUL(c) THEN
  1613. WStr(s, w, "MUL "); WReg(s, w, Rd); WStr(s, w, ", ");
  1614. WReg(s, w, Rn); WStr(s, w, ", ");
  1615. WReg(s, w, Rm);
  1616. IF (Rd IN {SP,PC}) OR (Rn IN {SP,PC}) OR (Rm IN {SP,PC}) THEN
  1617. WStr(s, w, " (UNPREDICTABLE)")
  1618. END
  1619. ELSIF IsMLS(c) THEN
  1620. WStr(s, w, "MLS "); WReg(s, w, Rd); WStr(s, w, ", ");
  1621. WReg(s, w, Rn); WStr(s, w, ", ");
  1622. WReg(s, w, Rm); WStr(s, w, ", ");
  1623. WReg(s, w, Ra);
  1624. IF (Rd IN {SP,PC}) OR (Rn IN {SP,PC}) OR (Rm IN {SP,PC}) OR (Ra IN {SP,PC}) THEN
  1625. WStr(s, w, " (UNPREDICTABLE)")
  1626. END
  1627. ELSIF IsMLA(c) THEN
  1628. WStr(s, w, "MLA "); WReg(s, w, Rd); WStr(s, w, ", ");
  1629. WReg(s, w, Rn); WStr(s, w, ", ");
  1630. WReg(s, w, Rm); WStr(s, w, ", ");
  1631. WReg(s, w, Ra);
  1632. IF (Rd IN {SP,PC}) OR (Rn IN {SP,PC}) OR (Rm IN {SP,PC}) OR (Ra = SP) THEN
  1633. WStr(s, w, " (UNPREDICTABLE)")
  1634. END
  1635. END
  1636. END MMAAAD;
  1637. PROCEDURE LMLMAAD;
  1638. VAR Rd, Rn, Rm: INTEGER;
  1639. BEGIN
  1640. IF IsSDIV(c) THEN
  1641. Rn := c MOD 10H;
  1642. Rd := c DIV 1000000H MOD 10H;
  1643. Rm := c DIV 10000H MOD 10H;
  1644. WStr(s, w, "SDIV "); WReg(s, w, Rd); WStr(s, w, ", ");
  1645. WReg(s, w, Rn); WStr(s, w, ", ");
  1646. WReg(s, w, Rm);
  1647. IF (Rd IN {SP,PC}) OR (Rn IN {SP,PC}) OR (Rm IN {SP,PC}) THEN
  1648. WStr(s, w, " (UNPREDICTABLE)")
  1649. END
  1650. END
  1651. END LMLMAAD;
  1652. PROCEDURE FPDP;
  1653. VAR d, n, m: INTEGER;
  1654. T, sz: INTEGER;
  1655. PROCEDURE Op0 ((*IN*) op: ARRAY OF CHAR);
  1656. BEGIN
  1657. WStr(s, w, op); WStr(s, w, ".F32 S"); WInt(s, w, d);
  1658. WStr(s, w, ", S"); WInt(s, w, n); WStr(s, w, ", S");
  1659. WInt(s, w, m)
  1660. END Op0;
  1661. PROCEDURE Op1 ((*IN*) op: ARRAY OF CHAR);
  1662. BEGIN
  1663. WStr(s, w, op); WStr(s, w, ".F32 S"); WInt(s, w, d);
  1664. WStr(s, w, ", S"); WInt(s, w, m)
  1665. END Op1;
  1666. BEGIN
  1667. d := c DIV 10000000H MOD 10H * 2 + c DIV 40H MOD 2;
  1668. n := c MOD 10H * 2 + c DIV 800000H MOD 2;
  1669. m := c DIV 10000H MOD 10H * 2 + c DIV 200000H MOD 2;
  1670. IF IsVMUL(c) THEN
  1671. Op0("VMUL")
  1672. ELSIF IsVADD(c) THEN
  1673. Op0("VADD")
  1674. ELSIF IsVSUB(c) THEN
  1675. Op0("VSUB")
  1676. ELSIF IsVDIV(c) THEN
  1677. Op0("VDIV")
  1678. ELSIF IsVFMA(c) THEN
  1679. Op0("VFMA")
  1680. ELSIF IsVFMS(c) THEN
  1681. Op0("VFMS")
  1682. ELSIF IsVFNMA(c) THEN
  1683. Op0("VFNMA")
  1684. ELSIF IsVFNMS(c) THEN
  1685. Op0("VFNMS")
  1686. ELSIF IsVNMUL(c) THEN
  1687. Op0("VNMUL")
  1688. ELSIF IsVABS(c) THEN
  1689. Op1("VABS")
  1690. ELSIF IsVNEG(c) THEN
  1691. Op1("VNEG")
  1692. ELSIF IsVSQRT(c) THEN
  1693. Op1("VSQRT")
  1694. ELSIF IsVCMPER(c) THEN
  1695. WStr(s, w, "VCMP");
  1696. IF 23 IN BITS(c) THEN s[w] := 'E'; INC(w) END;
  1697. WStr(s, w, ".F32 S"); WInt(s, w, d);
  1698. WStr(s, w, ", S"); WInt(s, w, m)
  1699. ELSIF IsVCMPE0(c) THEN
  1700. WStr(s, w, "VCMP");
  1701. IF 23 IN BITS(c) THEN s[w] := 'E'; INC(w) END;
  1702. WStr(s, w, ".F32 S"); WInt(s, w, d); WStr(s, w, ", #0.0")
  1703. ELSIF IsVCVTRInt(c) THEN ASSERT(~ODD(c DIV 2), 100);
  1704. WStr(s, w, "VCVT");
  1705. IF ODD(c DIV 4) THEN (* to integer *)
  1706. IF ~(23 IN BITS(c)) THEN s[w] := 'R'; INC(w) END;
  1707. s[w] := '.'; INC(w);
  1708. IF ODD(c) THEN s[w] := 'S' ELSE s[w] := 'U' END;
  1709. INC(w); WStr(s, w, "32.F32 S")
  1710. ELSE
  1711. WStr(s, w, ".F32.");
  1712. IF 23 IN BITS(c) THEN s[w] := 'S' ELSE s[w] := 'U' END;
  1713. INC(w); WStr(s, w, "32 S")
  1714. END;
  1715. WInt(s, w, d); WStr(s, w, ", S"); WInt(s, w, m);
  1716. IF c MOD 8 = 1 THEN
  1717. WStr(s, w, " ; opc2 = 1")
  1718. END
  1719. ELSE
  1720. T := c DIV 1000H MOD 2;
  1721. sz := c DIV 1000000H MOD 2;
  1722. IF (T = 1) OR (sz = 1) THEN
  1723. WStr(s, w, "FP UNDEFINED")
  1724. END
  1725. END
  1726. END FPDP;
  1727. PROCEDURE FPERLOS;
  1728. VAR T: INTEGER;
  1729. Rn: INTEGER;
  1730. PROCEDURE Op0 ((*IN*) op: ARRAY OF CHAR);
  1731. VAR Sd, imm32: INTEGER;
  1732. BEGIN
  1733. Sd := c DIV 10000000H MOD 10H * 2 + c DIV 40H MOD 2;
  1734. imm32 := c DIV 10000H MOD 100H * 4;
  1735. WStr(s, w, op); WStr(s, w, " S"); WInt(s, w, Sd); WStr(s, w, ", [");
  1736. WReg(s, w, Rn); WStr(s, w, ", #");
  1737. IF 7 IN BITS(c) THEN s[w] := '+' ELSE s[w] := '-' END; INC(w);
  1738. WInt(s, w, imm32); s[w] := ']'; INC(w)
  1739. END Op0;
  1740. BEGIN
  1741. Rn := c MOD 10H;
  1742. IF IsVSTR(c) THEN
  1743. Op0("VSTR")
  1744. ELSIF IsVLDR(c) THEN
  1745. Op0("VLDR")
  1746. ELSE
  1747. T := c DIV 1000H MOD 2;
  1748. IF T = 1 THEN
  1749. WStr(s, w, "FP UNDEFINED")
  1750. END
  1751. END
  1752. END FPERLOS;
  1753. PROCEDURE FP32TBACAER;
  1754. VAR n, Rt, op: INTEGER;
  1755. T: INTEGER;
  1756. BEGIN
  1757. Rt := c DIV 10000000H MOD 10H;
  1758. IF IsVMOVSPR(c) THEN
  1759. n := c MOD 10H * 2 + c DIV 800000H MOD 2;
  1760. op := c DIV 10H MOD 2;
  1761. IF op = 1 THEN (* to ARM register *)
  1762. WStr(s, w, "VMOV "); WReg(s, w, Rt); WStr(s, w, ", S");
  1763. WInt(s, w, n)
  1764. ELSE
  1765. WStr(s, w, "VMOV S"); WInt(s, w, n); WStr(s, w, ", ");
  1766. WReg(s, w, Rt)
  1767. END;
  1768. IF Rt IN {SP,PC} THEN
  1769. WStr(s, w, " (UNPREDICTABLE)")
  1770. END
  1771. ELSIF IsVMRS(c) THEN
  1772. WStr(s, w, "VMRS ");
  1773. IF Rt = 15 THEN WStr(s, w, "APSR_nzcv") ELSE WReg(s, w, Rt) END;
  1774. WStr(s, w, ", FPSCR")
  1775. ELSIF IsVMSR(c) THEN
  1776. WStr(s, w, "VMSR FPSCR, ");
  1777. WReg(s, w, Rt)
  1778. ELSE
  1779. T := c DIV 1000H MOD 2;
  1780. IF T = 1 THEN
  1781. WStr(s, w, "FP UNDEFINED")
  1782. END
  1783. END
  1784. END FP32TBACAER;
  1785. BEGIN
  1786. w := 0;
  1787. PUSHPOPOne;
  1788. IF IsWFIW(c) THEN
  1789. WStr(s, w, "WFI")
  1790. ELSIF IsLMASM(c) THEN
  1791. LMASM
  1792. ELSIF IsDPSR(c) THEN
  1793. DPSR
  1794. ELSIF IsDPMI(c) THEN
  1795. DPMI
  1796. ELSIF IsDPPBI(c) THEN
  1797. DPPBI
  1798. ELSIF IsBAMC(c) THEN
  1799. IF IsB(c) THEN
  1800. B(FALSE)
  1801. ELSIF IsBC(c) THEN
  1802. BC
  1803. ELSIF IsBL(c) THEN
  1804. B(TRUE)
  1805. END
  1806. ELSIF IsSSDI(c) THEN
  1807. IF IsSWImW(c) THEN
  1808. LSWBImW(TRUE, FALSE)
  1809. ELSIF IsSBImW(c) THEN
  1810. LSWBImW(TRUE, TRUE)
  1811. ELSIF IsSWRW(c) THEN
  1812. LSWBRW(TRUE, FALSE)
  1813. ELSIF IsSBRW(c) THEN
  1814. LSWBRW(TRUE, TRUE)
  1815. END
  1816. ELSIF IsLBMH(c) THEN
  1817. IF IsLBImW(c) THEN
  1818. LSWBImW(FALSE, TRUE)
  1819. ELSIF IsLBRW(c) THEN
  1820. LSWBRW(FALSE, TRUE)
  1821. END
  1822. ELSIF IsLW(c) THEN
  1823. LW
  1824. ELSIF IsDPR(c) THEN
  1825. DPR
  1826. ELSIF IsMMAAAD(c) THEN
  1827. MMAAAD
  1828. ELSIF IsLMLMAAD(c) THEN
  1829. LMLMAAD
  1830. ELSIF IsFPDP(c) THEN
  1831. FPDP
  1832. ELSIF IsFPERLOS(c) THEN
  1833. FPERLOS
  1834. ELSIF IsFP32TBACAER(c) THEN
  1835. FP32TBACAER
  1836. END;
  1837. s[w] := 0X
  1838. END OpcodeRepr2;
  1839. (* d: decoder state *)
  1840. PROCEDURE OpcodeRepr* (VAR d: INTEGER; c: INTEGER; (*OUT*)VAR s: ARRAY OF CHAR);
  1841. BEGIN
  1842. ASSERT(c DIV 10000H = 0, 20);
  1843. IF d = 0 THEN
  1844. ARMv6M.OpcodeRepr(d, c, s)
  1845. ELSIF d DIV 10000H = 1 THEN
  1846. c := 10000H * c + d MOD 10000H; d := 0;
  1847. OpcodeRepr2(c, s)
  1848. ELSE HALT(1)
  1849. END
  1850. END OpcodeRepr;
  1851. END O7ARMv7M.