O7ARMv6M.Mod 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872
  1. MODULE O7ARMv6M;
  2. (*
  3. Alexander Shiryaev, 2014.09
  4. ARMv6-M Architecture Reference Manual
  5. http://ecee.colorado.edu/ecen3000/labs/lab3/files/DDI0419C_arm_architecture_v6m_reference_manual.pdf
  6. *)
  7. IMPORT SYSTEM, Strings := VT100, Out;
  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 BITS (x: INTEGER): SET;
  20. BEGIN
  21. RETURN SYSTEM.VAL(SET, x)
  22. END BITS;
  23. PROCEDURE ORDSET (x: SET): INTEGER;
  24. BEGIN
  25. RETURN SYSTEM.VAL(INTEGER, x)
  26. END ORDSET;
  27. (* A6.7.1 *)
  28. PROCEDURE EmitADCSR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; dn, m: INTEGER);
  29. BEGIN
  30. ASSERT(m DIV 8 = 0, 20);
  31. ASSERT(dn DIV 8 = 0, 21);
  32. code[pc] := 4140H + m * 8 + dn; INC(pc)
  33. END EmitADCSR;
  34. (* A6.7.2 *)
  35. PROCEDURE EmitADDSIm* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; d, n, im: INTEGER);
  36. BEGIN
  37. ASSERT(d DIV 8 = 0, 20);
  38. ASSERT(n DIV 8 = 0, 21);
  39. IF im DIV 8 = 0 THEN
  40. code[pc] := 1C00H + im * 40H + n * 8 + d; INC(pc)
  41. ELSIF (im DIV 100H = 0) & (d = n) THEN
  42. code[pc] := 3000H + d * 100H + im; INC(pc)
  43. ELSE HALT(1)
  44. END
  45. END EmitADDSIm;
  46. (* A6.7.3, encoding T1 *)
  47. PROCEDURE EmitADDSR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; d, n, m: INTEGER);
  48. BEGIN
  49. ASSERT(d DIV 8 = 0, 20);
  50. ASSERT(n DIV 8 = 0, 21);
  51. ASSERT(m DIV 8 = 0, 22);
  52. code[pc] := 1800H + m * 40H + n * 8 + d; INC(pc)
  53. END EmitADDSR;
  54. (* A6.7.3, encoding T2 *)
  55. PROCEDURE EmitADDR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; dn, m: INTEGER);
  56. BEGIN
  57. ASSERT(dn IN {0..12,14..15}, 20);
  58. ASSERT(m IN {0..12,14..15}, 21);
  59. ASSERT(~((dn = PC) & (m = PC)), 22);
  60. ASSERT(dn # PC, 23);
  61. code[pc] := 4400H + dn DIV 8 * 80H + m * 8 + dn MOD 8; INC(pc)
  62. END EmitADDR;
  63. (* A6.7.4 *)
  64. PROCEDURE EmitADDSPIm* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; d, im: INTEGER);
  65. BEGIN
  66. IF d = SP THEN
  67. ASSERT(im DIV 80H = 0, 20);
  68. code[pc] := 0B000H + im; INC(pc)
  69. ELSE
  70. ASSERT(d DIV 8 = 0, 21);
  71. ASSERT(im DIV 100H = 0, 22);
  72. code[pc] := 0A800H + d * 100H + im; INC(pc)
  73. END
  74. END EmitADDSPIm;
  75. (* A6.7.5 *)
  76. PROCEDURE EmitADDSPR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; d, m: INTEGER);
  77. BEGIN
  78. ASSERT(d DIV 10H = 0, 20);
  79. ASSERT(m DIV 10H = 0, 21);
  80. IF d = SP THEN
  81. code[pc] := 4485H + m * 8; INC(pc)
  82. ELSE
  83. ASSERT(d = m, 22);
  84. ASSERT(d # PC, 22);
  85. code[pc] := 4468H + d DIV 8 * 80H + d MOD 8; INC(pc)
  86. END
  87. END EmitADDSPR;
  88. (* A6.7.7 *)
  89. PROCEDURE EmitANDSR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; dn, m: INTEGER);
  90. BEGIN
  91. ASSERT(dn DIV 8 = 0, 20);
  92. ASSERT(m DIV 8 = 0, 21);
  93. code[pc] := 4000H + m * 8 + dn; INC(pc)
  94. END EmitANDSR;
  95. (* A6.7.8 *)
  96. PROCEDURE EmitASRSIm* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; d, m, im: INTEGER);
  97. BEGIN
  98. ASSERT(d DIV 8 = 0, 20);
  99. ASSERT(m DIV 8 = 0, 21);
  100. ASSERT(im DIV 32 = 0, 22);
  101. code[pc] := 1000H + im * 40H + m * 8 + d; INC(pc)
  102. END EmitASRSIm;
  103. (* A6.7.9 *)
  104. PROCEDURE EmitASRSR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; dn, m: INTEGER);
  105. BEGIN
  106. ASSERT(dn DIV 8 = 0, 20);
  107. ASSERT(m DIV 8 = 0, 21);
  108. code[pc] := 4100H + m * 8 + dn; INC(pc)
  109. END EmitASRSR;
  110. (* A6.7.10, encoding T1 *)
  111. PROCEDURE EmitBC* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; cond, im: INTEGER);
  112. BEGIN
  113. ASSERT(cond IN {0..13}, 20);
  114. ASSERT(im >= -128, 21);
  115. ASSERT(im <= 127, 22);
  116. code[pc] := 0D000H + cond * 100H + im MOD 100H; INC(pc)
  117. END EmitBC;
  118. (* A6.7.10, encoding T2 *)
  119. PROCEDURE EmitB* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; im: INTEGER);
  120. BEGIN
  121. ASSERT(im >= -1024, 21);
  122. ASSERT(im <= 1023, 22);
  123. code[pc] := 0E000H + im MOD 800H; INC(pc)
  124. END EmitB;
  125. (* A6.7.11 *)
  126. PROCEDURE EmitBICSR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; dn, m: INTEGER);
  127. BEGIN
  128. ASSERT(dn DIV 8 = 0, 20);
  129. ASSERT(m DIV 8 = 0, 21);
  130. code[pc] := 4380H + m * 8 + dn; INC(pc)
  131. END EmitBICSR;
  132. PROCEDURE DecodeBLabel24* (S, imm10, J1, J2, imm11: INTEGER): INTEGER;
  133. BEGIN
  134. RETURN ((S * 1000000H + (J1 + S + 1) MOD 2 * 800000H + (J2 + S + 1) MOD 2 * 400000H + imm10 * 1000H + imm11 * 2) * 80H) DIV 80H
  135. END DecodeBLabel24;
  136. PROCEDURE EncodeBLabel24* (off: INTEGER; (*OUT*)VAR S, imm10, J1, J2, imm11: INTEGER);
  137. VAR test: INTEGER;
  138. BEGIN
  139. ASSERT(off * 2 >= -16777216, 20);
  140. ASSERT(off * 2 <= 16777214, 21);
  141. imm11 := off MOD 800H;
  142. imm10 := off DIV 800H MOD 400H;
  143. S := off DIV 800000H MOD 2;
  144. J1 := (off DIV 400000H + S + 1) MOD 2;
  145. J2 := (off DIV 200000H + S + 1) MOD 2;
  146. off := off * 2;
  147. test := DecodeBLabel24(S, imm10, J1, J2, imm11);
  148. IF off # test THEN
  149. Out.String("O7ARMv6M.EncodeBLabel24: off="); Out.Int(off, 0); Out.String(" test="); Out.Int(test, 0); Out.Ln;
  150. Out.String(" S="); Out.Int(S, 0); Out.String(" imm10="); Out.Int(imm10, 0);
  151. Out.String(" J1="); Out.Int(J1, 0); Out.String(" J2="); Out.Int(J2, 0);
  152. Out.String(" imm11="); Out.Int(imm11, 0); Out.Ln
  153. END;
  154. ASSERT(off = test, 100)
  155. END EncodeBLabel24;
  156. (* A6.7.13 *)
  157. PROCEDURE EmitBL* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; off: INTEGER);
  158. VAR S, imm10, J1, J2, imm11: INTEGER;
  159. BEGIN
  160. EncodeBLabel24(off, S, imm10, J1, J2, imm11);
  161. code[pc] := 0F000H + S * 400H + imm10; INC(pc);
  162. code[pc] := 0D000H + J1 * 2000H + J2 * 800H + imm11; INC(pc)
  163. END EmitBL;
  164. PROCEDURE DecodeBL* (c: INTEGER): INTEGER;
  165. VAR S, imm10, J1, J2, imm11: INTEGER;
  166. PROCEDURE IsBL (c: INTEGER): BOOLEAN;
  167. BEGIN
  168. RETURN BITS(c) * {11..15,28,30,31} = {12..15,28,30,31}
  169. END IsBL;
  170. BEGIN
  171. ASSERT(IsBL(c), 20);
  172. imm11 := c DIV 10000H MOD 800H;
  173. J2 := c DIV 8000000H MOD 2;
  174. J1 := c DIV 20000000H MOD 2;
  175. imm10 := c MOD 400H;
  176. S := c DIV 400H MOD 2;
  177. RETURN DecodeBLabel24(S, imm10, J1, J2, imm11)
  178. END DecodeBL;
  179. (* A6.7.14 *)
  180. PROCEDURE EmitBLX* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; m: INTEGER);
  181. BEGIN
  182. ASSERT(m IN {0..14}, 20);
  183. code[pc] := 4780H + m * 8; INC(pc)
  184. END EmitBLX;
  185. (* A6.7.15 *)
  186. PROCEDURE EmitBX* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; m: INTEGER);
  187. BEGIN
  188. ASSERT(m IN {0..14}, 20);
  189. code[pc] := 4700H + m * 8; INC(pc)
  190. END EmitBX;
  191. (* A6.7.17 *)
  192. PROCEDURE EmitCMPIm* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; n, im: INTEGER);
  193. BEGIN
  194. ASSERT(n DIV 8 = 0, 20);
  195. ASSERT(im DIV 100H = 0, 21);
  196. code[pc] := 2800H + n * 100H + im; INC(pc)
  197. END EmitCMPIm;
  198. (* A6.7.23 *)
  199. PROCEDURE EmitEORSR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; dn, m: INTEGER);
  200. BEGIN
  201. ASSERT(m DIV 8 = 0, 20);
  202. ASSERT(dn DIV 8 = 0, 21);
  203. code[pc] := 4040H + m * 8 + dn; INC(pc)
  204. END EmitEORSR;
  205. (* A6.7.26 *)
  206. PROCEDURE EmitLDRIm* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; t, n, im: INTEGER);
  207. BEGIN
  208. ASSERT(t DIV 8 = 0, 20);
  209. IF n = SP THEN
  210. ASSERT(im DIV 100H = 0, 21);
  211. code[pc] := 9800H + t * 100H + im; INC(pc)
  212. ELSE
  213. ASSERT(n DIV 8 = 0, 22);
  214. ASSERT(im DIV 32 = 0, 23);
  215. code[pc] := 6800H + im * 40H + n * 8 + t; INC(pc)
  216. END
  217. END EmitLDRIm;
  218. (* A6.7.28 *)
  219. PROCEDURE EmitLDRR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; t, n, m: INTEGER);
  220. BEGIN
  221. ASSERT(t DIV 8 = 0, 20);
  222. ASSERT(n DIV 8 = 0, 21);
  223. ASSERT(m DIV 8 = 0, 22);
  224. code[pc] := 5800H + m * 40H + n * 8 + t; INC(pc)
  225. END EmitLDRR;
  226. (* A6.7.29 *)
  227. PROCEDURE EmitLDRBIm* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; t, n, im: INTEGER);
  228. BEGIN
  229. ASSERT(t DIV 8 = 0, 20);
  230. ASSERT(n DIV 8 = 0, 21);
  231. ASSERT(im DIV 32 = 0, 22);
  232. code[pc] := 7800H + im * 40H + n * 8 + t; INC(pc)
  233. END EmitLDRBIm;
  234. (* A6.7.30 *)
  235. PROCEDURE EmitLDRBR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; t, n, m: INTEGER);
  236. BEGIN
  237. ASSERT(t DIV 8 = 0, 20);
  238. ASSERT(n DIV 8 = 0, 21);
  239. ASSERT(m DIV 8 = 0, 22);
  240. code[pc] := 5C00H + m * 40H + n * 8 + t; INC(pc)
  241. END EmitLDRBR;
  242. (* A6.7.35 *)
  243. PROCEDURE EmitLSLSIm* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; d, m, im: INTEGER);
  244. BEGIN
  245. ASSERT(d DIV 8 = 0, 20);
  246. ASSERT(m DIV 8 = 0, 21);
  247. ASSERT(im IN {1..31}, 22);
  248. code[pc] := im * 40H + m * 8 + d; INC(pc)
  249. END EmitLSLSIm;
  250. (* A6.7.36 *)
  251. PROCEDURE EmitLSLSR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; dn, m: INTEGER);
  252. BEGIN
  253. ASSERT(dn DIV 8 = 0, 20);
  254. ASSERT(m DIV 8 = 0, 21);
  255. code[pc] := 4080H + m * 8 + dn; INC(pc)
  256. END EmitLSLSR;
  257. (* A6.7.37 *)
  258. PROCEDURE EmitLSRSIm* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; d, m, im: INTEGER);
  259. BEGIN
  260. ASSERT(d DIV 8 = 0, 20);
  261. ASSERT(m DIV 8 = 0, 21);
  262. ASSERT(im DIV 32 = 0, 22);
  263. code[pc] := 800H + im * 40H + m * 8 + d; INC(pc)
  264. END EmitLSRSIm;
  265. (* A6.7.38 *)
  266. PROCEDURE EmitLSRSR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; dn, m: INTEGER);
  267. BEGIN
  268. ASSERT(dn DIV 8 = 0, 20);
  269. ASSERT(m DIV 8 = 0, 21);
  270. code[pc] := 40C0H + m * 8 + dn; INC(pc)
  271. END EmitLSRSR;
  272. (* A6.7.39 *)
  273. PROCEDURE EmitMOVSIm* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; d, im: INTEGER);
  274. BEGIN
  275. ASSERT(d DIV 8 = 0, 20);
  276. ASSERT(im DIV 100H = 0, 21);
  277. code[pc] := 2000H + d * 100H + im; INC(pc)
  278. END EmitMOVSIm;
  279. (* A6.7.40, encoding T2 *)
  280. PROCEDURE EmitMOVSR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; d, m: INTEGER);
  281. BEGIN
  282. ASSERT(d DIV 8 = 0, 20);
  283. ASSERT(m DIV 8 = 0, 21);
  284. code[pc] := m * 8 + d; INC(pc)
  285. END EmitMOVSR;
  286. (* A6.7.44 *)
  287. PROCEDURE EmitMULSR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; dm, n: INTEGER);
  288. BEGIN
  289. ASSERT(dm DIV 8 = 0, 20);
  290. ASSERT(n DIV 8 = 0, 21);
  291. code[pc] := 4340H + n * 8 + dm; INC(pc)
  292. END EmitMULSR;
  293. (* A6.7.45 *)
  294. PROCEDURE EmitMVNSR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; d, m: INTEGER);
  295. BEGIN
  296. ASSERT(d DIV 8 = 0, 20);
  297. ASSERT(m DIV 8 = 0, 21);
  298. code[pc] := 43C0H + m * 8 + d; INC(pc)
  299. END EmitMVNSR;
  300. (* A6.7.47 *)
  301. PROCEDURE EmitNOP* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER);
  302. BEGIN
  303. code[pc] := 0BF00H; INC(pc)
  304. END EmitNOP;
  305. (* A6.7.48 *)
  306. PROCEDURE EmitORRSR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; dn, m: INTEGER);
  307. BEGIN
  308. ASSERT(dn DIV 8 = 0, 20);
  309. ASSERT(m DIV 8 = 0, 21);
  310. code[pc] := 4300H + m * 8 + dn; INC(pc)
  311. END EmitORRSR;
  312. (* A6.7.49 *)
  313. PROCEDURE EmitPOP* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; regs: SET);
  314. VAR P: INTEGER;
  315. BEGIN
  316. ASSERT(regs * {8..14,16..31} = {}, 20);
  317. ASSERT(regs # {}, 21);
  318. IF PC IN regs THEN EXCL(regs, PC); P := 1 ELSE P := 0 END;
  319. code[pc] := 0BC00H + P * 100H + ORDSET(regs); INC(pc)
  320. END EmitPOP;
  321. (* A6.7.50 *)
  322. PROCEDURE EmitPUSH* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; regs: SET);
  323. VAR M: INTEGER;
  324. BEGIN
  325. ASSERT(regs * {8..13,15..31} = {}, 20);
  326. ASSERT(regs # {}, 21);
  327. IF LR IN regs THEN EXCL(regs, LR); M := 1 ELSE M := 0 END;
  328. code[pc] := 0B400H + M * 100H + ORDSET(regs); INC(pc)
  329. END EmitPUSH;
  330. (* A6.7.54 *)
  331. PROCEDURE EmitRORSR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; dn, m: INTEGER);
  332. BEGIN
  333. ASSERT(dn DIV 8 = 0, 20);
  334. ASSERT(m DIV 8 = 0, 21);
  335. code[pc] := 41C0H + m * 8 + dn; INC(pc)
  336. END EmitRORSR;
  337. (* A6.7.55 *)
  338. PROCEDURE EmitRSBS0* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; d, n: INTEGER);
  339. BEGIN
  340. ASSERT(d DIV 8 = 0, 20);
  341. ASSERT(n DIV 8 = 0, 21);
  342. code[pc] := 4240H + n * 8 + d; INC(pc)
  343. END EmitRSBS0;
  344. (* A6.7.56 *)
  345. PROCEDURE EmitSBCSR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; dn, m: INTEGER);
  346. BEGIN
  347. ASSERT(dn DIV 8 = 0, 20);
  348. ASSERT(m DIV 8 = 0, 21);
  349. code[pc] := 4180H + m * 8 + dn; INC(pc)
  350. END EmitSBCSR;
  351. (* A6.7.59 *)
  352. PROCEDURE EmitSTRIm* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; t, n, im: INTEGER);
  353. BEGIN
  354. ASSERT(t DIV 8 = 0, 20);
  355. IF n = SP THEN
  356. ASSERT(im DIV 100H = 0, 21);
  357. code[pc] := 9000H + t * 100H + im; INC(pc)
  358. ELSE
  359. ASSERT(n DIV 8 = 0, 22);
  360. ASSERT(im DIV 32 = 0, 23);
  361. code[pc] := 6000H + im * 40H + n * 8 + t; INC(pc)
  362. END
  363. END EmitSTRIm;
  364. (* A6.7.60 *)
  365. PROCEDURE EmitSTRR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; t, n, m: INTEGER);
  366. BEGIN
  367. ASSERT(t DIV 8 = 0, 20);
  368. ASSERT(n DIV 8 = 0, 21);
  369. ASSERT(m DIV 8 = 0, 22);
  370. code[pc] := 5000H + m * 40H + n * 8 + t; INC(pc)
  371. END EmitSTRR;
  372. (* A6.7.61 *)
  373. PROCEDURE EmitSTRBIm* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; t, n, im: INTEGER);
  374. BEGIN
  375. ASSERT(t DIV 8 = 0, 20);
  376. ASSERT(n DIV 8 = 0, 21);
  377. ASSERT(im DIV 32 = 0, 22);
  378. code[pc] := 7000H + im * 40H + n * 8 + t; INC(pc)
  379. END EmitSTRBIm;
  380. (* A6.7.62 *)
  381. PROCEDURE EmitSTRBR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; t, n, m: INTEGER);
  382. BEGIN
  383. ASSERT(t DIV 8 = 0, 20);
  384. ASSERT(n DIV 8 = 0, 21);
  385. ASSERT(m DIV 8 = 0, 22);
  386. code[pc] := 5400H + m * 40H + n * 8 + t; INC(pc)
  387. END EmitSTRBR;
  388. (* A6.7.65 *)
  389. PROCEDURE EmitSUBSIm* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; d, n, im: INTEGER);
  390. BEGIN
  391. ASSERT(d DIV 8 = 0, 20);
  392. ASSERT(n DIV 8 = 0, 21);
  393. IF im DIV 8 = 0 THEN
  394. code[pc] := 1E00H + im * 40H + n * 8 + d; INC(pc)
  395. ELSIF (im DIV 100H = 0) & (d = n) THEN
  396. code[pc] := 3800H + d * 100H + im; INC(pc)
  397. ELSE HALT(1)
  398. END
  399. END EmitSUBSIm;
  400. (* A6.7.66 *)
  401. PROCEDURE EmitSUBSR* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; d, n, m: INTEGER);
  402. BEGIN
  403. ASSERT(d DIV 8 = 0, 20);
  404. ASSERT(n DIV 8 = 0, 21);
  405. ASSERT(m DIV 8 = 0, 22);
  406. code[pc] := 1A00H + m * 40H + n * 8 + d; INC(pc)
  407. END EmitSUBSR;
  408. (* A6.7.67 *)
  409. PROCEDURE EmitSUBSPIm* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; imm7: INTEGER);
  410. BEGIN
  411. ASSERT(imm7 DIV 80H = 0, 20);
  412. code[pc] := 0B080H + imm7; INC(pc)
  413. END EmitSUBSPIm;
  414. (* A6.7.68 *)
  415. PROCEDURE EmitSVC* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; im: INTEGER);
  416. BEGIN
  417. ASSERT(im DIV 100H = 0, 20);
  418. code[pc] := 0DF00H + im; INC(pc)
  419. END EmitSVC;
  420. (* A6.7.76 *)
  421. PROCEDURE EmitWFI* (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER);
  422. BEGIN
  423. code[pc] := 0BF30H; INC(pc)
  424. END EmitWFI;
  425. PROCEDURE RegRepr* (r: INTEGER; (*OUT*)VAR s: ARRAY OF CHAR);
  426. BEGIN
  427. CASE r OF R0: COPY("r0", s)
  428. | R1: COPY("r1", s)
  429. | R2: COPY("r2", s)
  430. | R3: COPY("r3", s)
  431. | R4: COPY("r4", s)
  432. | R5: COPY("r5", s)
  433. | R6: COPY("r6", s)
  434. | R7: COPY("r7", s)
  435. | R8: COPY("r8", s)
  436. | R9: COPY("r9", s)
  437. | R10: COPY("r10", s)
  438. | R11: COPY("r11", s)
  439. | R12: COPY("r12", s)
  440. | SP: COPY("SP", s)
  441. | LR: COPY("LR", s)
  442. | PC: COPY("PC", s)
  443. END
  444. END RegRepr;
  445. PROCEDURE CondRepr* (cond: INTEGER; (*OUT*)VAR s: ARRAY OF CHAR);
  446. BEGIN
  447. CASE cond OF EQ: COPY("EQ", s)
  448. | NE: COPY("NE", s)
  449. | CS: COPY("CS", s)
  450. | CC: COPY("CC", s)
  451. | MI: COPY("MI", s)
  452. | PL: COPY("PL", s)
  453. | VS: COPY("VS", s)
  454. | VC: COPY("VC", s)
  455. | HI: COPY("HI", s)
  456. | LS: COPY("LS", s)
  457. | GE: COPY("GE", s)
  458. | LT: COPY("LT", s)
  459. | GT: COPY("GT", s)
  460. | LE: COPY("LE", s)
  461. ELSE COPY("?", s)
  462. END
  463. END CondRepr;
  464. PROCEDURE IsLThumb32* (c: INTEGER): BOOLEAN;
  465. BEGIN
  466. RETURN (c DIV 2000H = 7) & (c DIV 800H MOD 4 # 0)
  467. END IsLThumb32;
  468. (* d: decoder state *)
  469. PROCEDURE OpcodeRepr* (VAR d: INTEGER; c: INTEGER; (*OUT*)VAR s: ARRAY OF CHAR);
  470. VAR w: INTEGER;
  471. s0: ARRAY 3 OF CHAR;
  472. a, b: INTEGER;
  473. PROCEDURE WStr ((*IN*) s0: ARRAY OF CHAR);
  474. VAR i: INTEGER;
  475. BEGIN
  476. i := 0;
  477. WHILE (i < LEN(s0(*$*))) & (s0[i] # 0X) DO
  478. s[w] := s0[i]; INC(w);
  479. INC(i)
  480. END
  481. END WStr;
  482. PROCEDURE WReg (r: INTEGER);
  483. VAR s0: ARRAY 4 OF CHAR;
  484. BEGIN
  485. RegRepr(r, s0);
  486. WStr(s0)
  487. END WReg;
  488. PROCEDURE WInt (x: INTEGER);
  489. VAR s0: ARRAY 12 OF CHAR;
  490. BEGIN
  491. Strings.IntToStr(x, s0);
  492. WStr(s0)
  493. END WInt;
  494. BEGIN
  495. ASSERT(c DIV 10000H = 0, 20);
  496. w := 0;
  497. IF d = 0 THEN
  498. IF c DIV 4000H = 0 THEN
  499. (* shift (immediate), add, substract, move, and compare *)
  500. IF c DIV 800H = 0 THEN (* MOVSR | LSLSIm *)
  501. IF c DIV 40H = 0 THEN (* MOVSR *)
  502. WStr("MOVS "); WReg(c MOD 8);
  503. WStr(", "); WReg(c DIV 8 MOD 8)
  504. ELSE (* LSLSIm *)
  505. WStr("LSLS "); WReg(c MOD 8);
  506. WStr(", "); WReg(c DIV 8 MOD 8);
  507. WStr(", #"); WInt(c DIV 40H)
  508. END
  509. ELSIF c DIV 800H = 1 THEN (* LSRSIm *)
  510. WStr("LSRS "); WReg(c MOD 8); WStr(", "); WReg(c DIV 8 MOD 8);
  511. WStr(", #"); WInt(c DIV 40H MOD 32)
  512. ELSIF c DIV 800H = 2 THEN (* ASRSIm *)
  513. WStr("ASRS "); WReg(c MOD 8); WStr(", "); WReg(c DIV 8 MOD 8);
  514. WStr(", #"); WInt(c DIV 40H MOD 32)
  515. ELSIF c DIV 200H = 12 THEN (* ADDSR *)
  516. WStr("ADDS "); WReg(c MOD 8); WStr(", "); WReg(c DIV 8 MOD 8);
  517. WStr(", "); WReg(c DIV 40H MOD 8)
  518. ELSIF c DIV 200H = 13 THEN (* SUBSR *)
  519. WStr("SUBS "); WReg(c MOD 8); WStr(", "); WReg(c DIV 8 MOD 8);
  520. WStr(", "); WReg(c DIV 40H MOD 8)
  521. ELSIF c DIV 200H = 14 THEN (* ADDSIm (3-bit) *)
  522. WStr("ADDS "); WReg(c MOD 8); WStr(", "); WReg(c DIV 8 MOD 8);
  523. WStr(", #"); WInt(c DIV 40H MOD 8)
  524. ELSIF c DIV 200H = 15 THEN (* SUBSIm (3-bit) *)
  525. WStr("SUBS "); WReg(c MOD 8); WStr(", "); WReg(c DIV 8 MOD 8);
  526. WStr(", #"); WInt(c DIV 40H MOD 8)
  527. ELSIF c DIV 800H = 4 THEN (* MOVSIm *)
  528. WStr("MOVS "); WReg(c DIV 100H MOD 8);
  529. WStr(", #"); WInt(c MOD 100H)
  530. ELSIF c DIV 800H = 5 THEN (* CMPIm *)
  531. WStr("CMP "); WReg(c DIV 100H MOD 8);
  532. WStr(", #"); WInt(c MOD 100H)
  533. ELSIF c DIV 800H = 6 THEN (* ADDSIm (8-bit) *)
  534. WStr("ADDS "); WReg(c DIV 100H MOD 8);
  535. WStr(", #"); WInt(c MOD 100H)
  536. ELSIF c DIV 800H = 7 THEN (* SUBSIm (8-bit) *)
  537. WStr("SUBS "); WReg(c DIV 100H MOD 8);
  538. WStr(", #"); WInt(c MOD 100H)
  539. END
  540. ELSIF c DIV 400H = 16 THEN (* data processing *)
  541. CASE c DIV 40H MOD 16 OF 0: WStr("ANDS")
  542. | 1: WStr("EORS")
  543. | 2: WStr("LSLS")
  544. | 3: WStr("LSRS")
  545. | 4: WStr("ASRS")
  546. | 5: WStr("ADCS")
  547. | 6: WStr("SBCS")
  548. | 7: WStr("RORS")
  549. | 8: WStr("TST")
  550. | 9: WStr("RSBS")
  551. | 10: WStr("CMP")
  552. | 11: WStr("CMN")
  553. | 12: WStr("ORRS")
  554. | 13: WStr("MULS")
  555. | 14: WStr("BICS")
  556. | 15: WStr("MVNS")
  557. END; s[w] := ' '; INC(w);
  558. WReg(c MOD 8); WStr(", "); WReg(c DIV 8 MOD 8);
  559. IF c DIV 40H MOD 16 = 9 THEN (* RSBS *)
  560. WStr(", #0")
  561. ELSIF c DIV 40H MOD 16 = 13 THEN (* MULS *)
  562. WStr(", "); WReg(c MOD 8)
  563. END
  564. ELSIF c DIV 400H = 17 THEN
  565. (* special data instructions and branch and exchange *)
  566. IF c DIV 100H MOD 4 = 0 THEN (* ADDR *)
  567. a := c DIV 80H MOD 2 * 8 + c MOD 8;
  568. b := c DIV 8 MOD 10H;
  569. IF b = SP THEN (* A6.7.5: ADD (SP plus register), encoding T1 *)
  570. WStr("ADD "); WReg(a); WStr(", SP, "); WReg(a)
  571. ELSIF a = SP THEN
  572. (* A6.7.5: ADD (SP plus register), encoding T2 *)
  573. WStr("ADD SP, "); WReg(b)
  574. ELSE
  575. WStr("ADD "); WReg(a); WStr(", "); WReg(b);
  576. IF (a = PC) & (b = PC) THEN WStr(" (UNPREDICTABLE)") END
  577. END
  578. ELSIF c DIV 40H MOD 10H = 0 THEN
  579. WStr("UNPREDICTABLE")
  580. ELSIF (c DIV 40H MOD 10H = 5) OR (c DIV 80H MOD 8H = 3) THEN
  581. (* CMPR, encoding T2 *)
  582. ELSIF c DIV 100H MOD 4 = 2 THEN (* MOVR *)
  583. ELSIF c DIV 80H MOD 8 = 6 THEN (* BX *)
  584. IF c MOD 8 = 0 THEN
  585. WStr("BX "); WReg(c DIV 8 MOD 10H);
  586. IF c DIV 8 MOD 10H = 15 THEN
  587. WStr(" (UNPREDICTABLE)")
  588. END
  589. END
  590. ELSIF c DIV 80H MOD 8 = 7 THEN (* BLX *)
  591. IF c MOD 8 = 0 THEN
  592. WStr("BLX "); WReg(c DIV 8 MOD 10H);
  593. IF c DIV 8 MOD 10H = 15 THEN
  594. WStr(" (UNPREDICTABLE)")
  595. END
  596. END
  597. END
  598. ELSIF c DIV 800H = 9 THEN (* load from literal pool *)
  599. WStr("LDR "); WReg(c DIV 100H MOD 8); WStr(", [PC, #");
  600. WInt(c MOD 100H * 4); WStr("] ; "); WInt(c MOD 100H * 2)
  601. ELSIF (c DIV 1000H = 5) OR (c DIV 2000H IN {3,4}) THEN
  602. (* load/store single data item *)
  603. IF c DIV 200H = 28H THEN (* STRR *)
  604. WStr("STR "); WReg(c MOD 8); WStr(", ["); WReg(c DIV 8 MOD 8);
  605. WStr(", "); WReg(c DIV 40H MOD 8); s[w] := ']'; INC(w)
  606. ELSIF c DIV 200H = 29H THEN (* STRHR *)
  607. WStr("STRH "); WReg(c MOD 8); WStr(", [");
  608. WReg(c DIV 8 MOD 8);
  609. WStr(", "); WReg(c DIV 40H MOD 8); s[w] := ']'; INC(w)
  610. ELSIF c DIV 200H = 2AH THEN (* STRBR *)
  611. WStr("STRB "); WReg(c MOD 8); WStr(", [");
  612. WReg(c DIV 8 MOD 8);
  613. WStr(", "); WReg(c DIV 40H MOD 8); s[w] := ']'; INC(w)
  614. ELSIF c DIV 200H = 2BH THEN (* LDRSBR *)
  615. WStr("LDRSB "); WReg(c MOD 8); WStr(", [");
  616. WReg(c DIV 8 MOD 8);
  617. WStr(", "); WReg(c DIV 40H MOD 8); s[w] := ']'; INC(w)
  618. ELSIF c DIV 200H = 2CH THEN (* LDRR *)
  619. WStr("LDR "); WReg(c MOD 8); WStr(", ["); WReg(c DIV 8 MOD 8);
  620. WStr(", "); WReg(c DIV 40H MOD 8); s[w] := ']'; INC(w)
  621. ELSIF c DIV 200H = 2DH THEN (* LDRHR *)
  622. WStr("LDRH "); WReg(c MOD 8); WStr(", [");
  623. WReg(c DIV 8 MOD 8);
  624. WStr(", "); WReg(c DIV 40H MOD 8); s[w] := ']'; INC(w)
  625. ELSIF c DIV 200H = 2EH THEN (* LDRBR *)
  626. WStr("LDRB "); WReg(c MOD 8); WStr(", [");
  627. WReg(c DIV 8 MOD 8);
  628. WStr(", "); WReg(c DIV 40H MOD 8); s[w] := ']'; INC(w)
  629. ELSIF c DIV 200H = 2FH THEN (* LDRSHR *)
  630. WStr("LDRSH "); WReg(c MOD 8); WStr(", [");
  631. WReg(c DIV 8 MOD 8);
  632. WStr(", "); WReg(c DIV 40H MOD 8); s[w] := ']'; INC(w)
  633. ELSIF c DIV 800H = 0CH THEN (* STRIm *)
  634. WStr("STR "); WReg(c MOD 8); WStr(", ["); WReg(c DIV 8 MOD 8);
  635. IF c DIV 40H MOD 32 # 0 THEN
  636. WStr(", #"); WInt(c DIV 40H MOD 32); WStr("] ; ");
  637. WInt(c DIV 40H MOD 32 * 4)
  638. ELSE s[w] := ']'; INC(w)
  639. END
  640. ELSIF c DIV 800H = 0DH THEN (* LDRIm *)
  641. WStr("LDR "); WReg(c MOD 8); WStr(", ["); WReg(c DIV 8 MOD 8);
  642. IF c DIV 40H MOD 32 # 0 THEN
  643. WStr(", #"); WInt(c DIV 40H MOD 32); WStr("] ; ");
  644. WInt(c DIV 40H MOD 32 * 4)
  645. ELSE s[w] := ']'; INC(w)
  646. END
  647. ELSIF c DIV 800H = 0EH THEN (* STRBIm *)
  648. WStr("STRB "); WReg(c MOD 8);
  649. WStr(", ["); WReg(c DIV 8 MOD 8);
  650. IF c DIV 40H MOD 32 # 0 THEN
  651. WStr(", #"); WInt(c DIV 40H MOD 32)
  652. END; s[w] := ']'; INC(w)
  653. ELSIF c DIV 800H = 0FH THEN (* LDRBIm *)
  654. WStr("LDRB "); WReg(c MOD 8);
  655. WStr(", ["); WReg(c DIV 8 MOD 8);
  656. IF c DIV 40H MOD 32 # 0 THEN
  657. WStr(", #"); WInt(c DIV 40H MOD 32)
  658. END; s[w] := ']'; INC(w)
  659. ELSIF c DIV 800H = 10H THEN (* STRHIm *)
  660. ELSIF c DIV 800H = 11H THEN (* LDRHIm *)
  661. ELSIF c DIV 800H = 12H THEN (* STRIm, SP *)
  662. WStr("STR "); WReg(c DIV 100H MOD 8); WStr(", [SP");
  663. IF c MOD 100H # 0 THEN WStr(", #");
  664. WInt(c MOD 100H); WStr("] ; "); WInt(c MOD 100H * 4)
  665. ELSE s[w] := ']'; INC(w)
  666. END
  667. ELSIF c DIV 800H = 13H THEN (* LDRIm, SP *)
  668. WStr("LDR "); WReg(c DIV 100H MOD 8); WStr(", [SP");
  669. IF c MOD 100H # 0 THEN WStr(", #");
  670. WInt(c MOD 100H); WStr("] ; "); WInt(c MOD 100H * 4)
  671. ELSE s[w] := ']'; INC(w)
  672. END
  673. END
  674. ELSIF c DIV 800H = 16 + 4 THEN (* ADR *)
  675. ELSIF c DIV 800H = 16 + 5 THEN (* ADDSPIm, encoding T1 *)
  676. WStr("ADD "); WReg(c DIV 100H MOD 8); WStr(", SP, #");
  677. WInt(c MOD 100H);
  678. IF c MOD 100H # 0 THEN
  679. WStr(" ; "); WInt(c MOD 100H * 4)
  680. END
  681. ELSIF c DIV 1000H = 0BH THEN (* miscellaneous 16-bit instructions *)
  682. c := c MOD 1000H;
  683. IF c DIV 80H = 0 THEN (* ADDSPIm, encoding T2 *)
  684. WStr("ADD SP, SP, #"); WInt(c MOD 80H);
  685. IF c MOD 80H # 0 THEN
  686. WStr(" ; "); WInt(c MOD 80H * 4)
  687. END
  688. ELSIF c DIV 80H = 1 THEN (* SUBSPIm *)
  689. WStr("SUB SP, SP, #"); WInt(c MOD 80H);
  690. IF c MOD 80H # 0 THEN
  691. WStr(" ; "); WInt(c MOD 80H * 4)
  692. END
  693. ELSIF c DIV 40H = 8 THEN (* SXTH *)
  694. ELSIF c DIV 40H = 9 THEN (* SXTB *)
  695. ELSIF c DIV 40H = 10 THEN (* UXTH *)
  696. ELSIF c DIV 40H = 11 THEN (* UXTB *)
  697. ELSIF c DIV 200H = 2 THEN (* PUSH *)
  698. WStr("PUSH {");
  699. a := 0; b := 0;
  700. WHILE a < 8 DO
  701. IF a IN BITS(c MOD 100H) THEN
  702. IF b # 0 THEN WStr(", ") END;
  703. WReg(a);
  704. INC(b)
  705. END;
  706. INC(a)
  707. END;
  708. IF ODD(c DIV 100H) THEN
  709. IF b # 0 THEN WStr(", ") END;
  710. WReg(LR);
  711. INC(b)
  712. END;
  713. s[w] := '}'; INC(w);
  714. IF b < 1 THEN
  715. WStr(" (UNPREDICTABLE)")
  716. END
  717. ELSIF c DIV 20H = 32 + 16 + 3 THEN (* CPS *)
  718. ELSIF c DIV 40H = 40 THEN (* REV *)
  719. ELSIF c DIV 40H = 41 THEN (* REV16 *)
  720. ELSIF c DIV 40H = 43 THEN (* REVSH *)
  721. ELSIF c DIV 200H = 6 THEN (* POP *)
  722. WStr("POP {");
  723. a := 0; b := 0;
  724. WHILE a < 8 DO
  725. IF a IN BITS(c MOD 100H) THEN
  726. IF b # 0 THEN WStr(", ") END;
  727. WReg(a);
  728. INC(b)
  729. END;
  730. INC(a)
  731. END;
  732. IF ODD(c DIV 100H) THEN
  733. IF b # 0 THEN WStr(", ") END;
  734. WReg(PC);
  735. INC(b)
  736. END;
  737. s[w] := '}'; INC(w);
  738. IF b < 1 THEN
  739. WStr(" (UNPREDICTABLE)")
  740. END
  741. ELSIF c DIV 100H = 14 THEN (* BKPT *)
  742. ELSIF c DIV 100H = 15 THEN (* hint instructions *)
  743. IF c MOD 10H # 0 THEN WStr("UNDEFINED")
  744. ELSE
  745. CASE c DIV 10H MOD 10H OF 0: WStr("NOP")
  746. | 1: WStr("YIELD")
  747. | 2: WStr("WFE")
  748. | 3: WStr("WFI")
  749. | 4: WStr("SEV")
  750. ELSE
  751. END
  752. END
  753. END
  754. ELSIF c DIV 800H = 16 + 8 THEN (* store multiple registers *)
  755. ELSIF c DIV 800H = 16 + 9 THEN (* load multiple registers *)
  756. ELSIF c DIV 1000H = 0DH THEN (* conditional branch, and SVC *)
  757. IF c DIV 100H MOD 10H = 15 THEN
  758. WStr("SVC #"); WInt(c MOD 100H)
  759. ELSIF c DIV 100H MOD 10H = 14 THEN
  760. WStr("UNDEFINED")
  761. ELSE s[w] := 'B'; INC(w);
  762. CondRepr(c DIV 100H MOD 10H, s0);
  763. WStr(s0); s[w] := ' '; INC(w);
  764. WInt((c * 1000000H) DIV 1000000H); WStr(" ; ");
  765. WInt((c * 1000000H) DIV 1000000H + 1)
  766. END
  767. ELSIF c DIV 800H = 16 + 12 THEN (* unconditional branch *)
  768. WStr("B "); WInt((c * 200000H) DIV 200000H);
  769. WStr(" ; "); WInt((c * 200000H) DIV 200000H + 1)
  770. ELSIF IsLThumb32(c) THEN (* 32-bit Thumb instruction *)
  771. d := 10000H + c;
  772. WStr("...")
  773. END
  774. ELSIF d DIV 10000H = 1 THEN
  775. c := 10000H * c + d MOD 10000H; d := 0;
  776. IF c DIV 800H MOD 2 = 1 THEN
  777. WStr("UNDEFINED")
  778. ELSIF 31 IN BITS(c) THEN (* branch and miscellaneous control *)
  779. a := DecodeBL(c);
  780. ASSERT(a MOD 2 = 0, 102);
  781. WStr("BL "); WInt(a);
  782. IF a # 0 THEN WStr(" ; "); WInt(a DIV 2) END
  783. ELSE
  784. WStr("UNDEFINED")
  785. END
  786. ELSE HALT(1)
  787. END;
  788. s[w] := 0X
  789. END OpcodeRepr;
  790. END O7ARMv6M.