RTL.ob07 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. (*
  2. BSD 2-Clause License
  3. Copyright (c) 2019-2021, Anton Krotov
  4. All rights reserved.
  5. *)
  6. MODULE RTL;
  7. IMPORT SYSTEM, F := FPU;
  8. CONST
  9. WORD = 4;
  10. VAR
  11. Heap, Types, TypesCount: INTEGER;
  12. PROCEDURE _fmul* (b, a: INTEGER): INTEGER;
  13. RETURN F.mul(b, a)
  14. END _fmul;
  15. PROCEDURE _fdiv* (b, a: INTEGER): INTEGER;
  16. RETURN F._div(b, a)
  17. END _fdiv;
  18. PROCEDURE _fdivi* (b, a: INTEGER): INTEGER;
  19. RETURN F._div(a, b)
  20. END _fdivi;
  21. PROCEDURE _fadd* (b, a: INTEGER): INTEGER;
  22. RETURN F.add(b, a)
  23. END _fadd;
  24. PROCEDURE _fsub* (b, a: INTEGER): INTEGER;
  25. RETURN F.sub(b, a)
  26. END _fsub;
  27. PROCEDURE _fsubi* (b, a: INTEGER): INTEGER;
  28. RETURN F.sub(a, b)
  29. END _fsubi;
  30. PROCEDURE _fcmp* (op, b, a: INTEGER): BOOLEAN;
  31. RETURN F.cmp(op, b, a)
  32. END _fcmp;
  33. PROCEDURE _floor* (x: INTEGER): INTEGER;
  34. RETURN F.floor(x)
  35. END _floor;
  36. PROCEDURE _flt* (x: INTEGER): INTEGER;
  37. RETURN F.flt(x)
  38. END _flt;
  39. PROCEDURE [code] _pack* (n: INTEGER; VAR x: INTEGER)
  40. 09800H, (* ldr r0, [sp, 0] *)
  41. 09901H, (* ldr r1, [sp, 4] *)
  42. 0680AH, (* ldr r2, [r1, 0] *)
  43. 00013H, (* movs r3, r2 *)
  44. 00052H, (* lsls r2, 1 *)
  45. 00E12H, (* lsrs r2, 24 *)
  46. 01812H, (* adds r2, r2, r0 *)
  47. 00612H, (* lsls r2, 24 *)
  48. 00852H, (* lsrs r2, 1 *)
  49. 020FFH, (* movs r0, 255 *)
  50. 005C0H, (* lsls r0, 23 *)
  51. 04383H, (* bics r3, r0 *)
  52. 04313H, (* orrs r3, r2 *)
  53. 0600BH; (* str r3, [r1, 0] *)
  54. PROCEDURE [code] _unpk* (VAR n: INTEGER; VAR x: INTEGER)
  55. 09800H, (* ldr r0, [sp, 0] *)
  56. 09901H, (* ldr r1, [sp, 4] *)
  57. 0680AH, (* ldr r2, [r1, 0] *)
  58. 00013H, (* movs r3, r2 *)
  59. 00052H, (* lsls r2, 1 *)
  60. 00E12H, (* lsrs r2, 24 *)
  61. 03A7FH, (* subs r2, 127 *)
  62. 06002H, (* str r2, [r0, 0] *)
  63. 02001H, (* movs r0, 1 *)
  64. 00780H, (* lsls r0, 30 *)
  65. 04383H, (* bics r3, r0 *)
  66. 0207FH, (* movs r0, 127 *)
  67. 005C0H, (* lsls r0, 23 *)
  68. 04303H, (* orrs r3, r0 *)
  69. 0600BH; (* str r3, [r1, 0] *)
  70. PROCEDURE [code] _rot* (VAR A: ARRAY OF INTEGER)
  71. 09801H, (* ldr r0, [sp, 4] *)
  72. 09900H, (* ldr r1, [sp, 0] *)
  73. 06802H, (* ldr r2, [r0, 0] *)
  74. 00003H, (* movs r3, r0 *)
  75. 03004H, (* adds r0, 4 *)
  76. 03901H, (* subs r1, 1 *)
  77. 0DD08H, (* ble L2 *)
  78. 0B404H, (* push {r2} *)
  79. (* L1: *)
  80. 06802H, (* ldr r2, [r0, 0] *)
  81. 0601AH, (* str r2, [r3, 0] *)
  82. 03004H, (* adds r0, 4 *)
  83. 03304H, (* adds r3, 4 *)
  84. 03901H, (* subs r1, 1 *)
  85. 0DCF9H, (* bgt L1 *)
  86. 0BC04H, (* pop {r2} *)
  87. 0601AH; (* str r2, [r3, 0] *)
  88. (* L2: *)
  89. PROCEDURE [code] _set1* (a: INTEGER): INTEGER (* {a} -> r0 *)
  90. 09900H, (* ldr r1, [sp, 0] *) (* r1 <- a *)
  91. 02900H, (* cmp r1, 0 *)
  92. 0DB04H, (* blt L1 *)
  93. 0291FH, (* cmp r1, 31 *)
  94. 0DC02H, (* bgt L1 *)
  95. 02001H, (* movs r0, 1 *)
  96. 04088H, (* lsls r0, r1 *)
  97. 04770H, (* bx lr *)
  98. (* L1: *)
  99. 02000H; (* movs r0, 0 *)
  100. PROCEDURE [code] _set* (b, a: INTEGER): INTEGER (* {a..b} -> r0 *)
  101. 09900H, (* ldr r1, [sp, 0] *) (* r1 <- b *)
  102. 09801H, (* ldr r0, [sp, 4] *) (* r0 <- a *)
  103. 04288H, (* cmp r0, r1 *)
  104. 0DC11H, (* bgt L1 *)
  105. 0281FH, (* cmp r0, 31 *)
  106. 0DC0FH, (* bgt L1 *)
  107. 02900H, (* cmp r1, 0 *)
  108. 0DB0DH, (* blt L1 *)
  109. 0291FH, (* cmp r1, 31 *)
  110. 0DD00H, (* ble L3 *)
  111. 0211FH, (* movs r1, 31 *)
  112. (* L3: *)
  113. 02800H, (* cmp r0, 0 *)
  114. 0DA00H, (* bge L4 *)
  115. 02000H, (* movs r0, 0 *)
  116. (* L4: *)
  117. 01A0AH, (* subs r2, r1, r0 *)
  118. 02001H, (* movs r0, 1 *)
  119. 007C0H, (* lsls r0, 31 *)
  120. 04110H, (* asrs r0, r2 *)
  121. 0391FH, (* subs r1, 31 *)
  122. 04249H, (* negs r1, r1 *)
  123. 040C8H, (* lsrs r0, r1 *)
  124. 04770H, (* bx lr *)
  125. (* L1: *)
  126. 02000H; (* movs r0, 0 *)
  127. PROCEDURE [code] _length* (len, str: INTEGER): INTEGER
  128. 09801H, (* ldr r0, [sp, 4] *)
  129. 09900H, (* ldr r1, [sp, 0] *)
  130. 00003H, (* movs r3, r0 *)
  131. 03801H, (* subs r0, 1 *)
  132. (* L1: *)
  133. 03001H, (* adds r0, 1 *)
  134. 07802H, (* ldrb r2, [r0] *)
  135. 02A00H, (* cmp r2, 0 *)
  136. 0D002H, (* beq L2 *)
  137. 03901H, (* subs r1, 1 *)
  138. 0DCF9H, (* bgt L1 *)
  139. 03001H, (* adds r0, 1 *)
  140. (* L2: *)
  141. 01AC0H; (* subs r0, r0, r3 *)
  142. PROCEDURE [code] _lengthw* (len, str: INTEGER): INTEGER
  143. 09801H, (* ldr r0, [sp, 4] *)
  144. 09900H, (* ldr r1, [sp, 0] *)
  145. 00003H, (* movs r3, r0 *)
  146. 03802H, (* subs r0, 2 *)
  147. (* L1: *)
  148. 03002H, (* adds r0, 2 *)
  149. 08802H, (* ldrh r2, [r0] *)
  150. 02A00H, (* cmp r2, 0 *)
  151. 0D002H, (* beq L2 *)
  152. 03901H, (* subs r1, 1 *)
  153. 0DCF9H, (* bgt L1 *)
  154. 03002H, (* adds r0, 2 *)
  155. (* L2: *)
  156. 01AC0H, (* subs r0, r0, r3 *)
  157. 00840H; (* lsrs r0, 1 *)
  158. PROCEDURE [code] _strcmp* (op, len2, str2, len1, str1: INTEGER): BOOLEAN
  159. 09904H, (* ldr r1, [sp, 16] *) (* r1 <- str1 *)
  160. 09A02H, (* ldr r2, [sp, 8] *) (* r2 <- str2 *)
  161. 09B01H, (* ldr r3, [sp, 4] *) (* r3 <- len2 *)
  162. 09803H, (* ldr r0, [sp, 12] *) (* r0 <- len1 *)
  163. 04298H, (* cmp r0, r3 *)
  164. 0DA00H, (* bge L5 *)
  165. 00003H, (* movs r3, r0 *)
  166. (* L5: *) (* r3 <- min(r0, r3) *)
  167. 0B430H, (* push {r4, r5} *)
  168. (* L3: *)
  169. 02B00H, (* cmp r3, 0 *) (* while r3 > 0 do *)
  170. 0DD09H, (* ble L1 *)
  171. 0780CH, (* ldrb r4, [r1] *)
  172. 03101H, (* adds r1, 1 *)
  173. 07815H, (* ldrb r5, [r2] *)
  174. 03201H, (* adds r2, 1 *)
  175. 03B01H, (* subs r3, 1 *)
  176. 01B60H, (* subs r0, r4, r5 *)
  177. 0D10FH, (* bne L6 *)
  178. 02C00H, (* cmp r4, 0 *)
  179. 0D1F4H, (* bne L3 *) (* end while *)
  180. 0E00CH, (* b L6 *)
  181. (* L1: *)
  182. 09A03H, (* ldr r2, [sp, 12] *) (* r2 <- len2 *)
  183. 09905H, (* ldr r1, [sp, 20] *) (* r1 <- len1 *)
  184. 04291H, (* cmp r1, r2 *)
  185. 0DC02H, (* bgt L9 *)
  186. 0DB04H, (* blt L4 *)
  187. 02000H, (* movs r0, 0 *)
  188. 0E005H, (* b L6 *)
  189. (* L9: *)
  190. 09806H, (* ldr r0, [sp, 24] *) (* r0 <- str1 *)
  191. 05C80H, (* ldrb r0, [r0, r2] *) (* r0 <- str1[len2] *)
  192. 0E002H, (* b L6 *)
  193. (* L4: *)
  194. 09804H, (* ldr r0, [sp, 16] *) (* r0 <- str2 *)
  195. 05C40H, (* ldrb r0, [r0, r1] *) (* r0 <- str2[len1] *)
  196. 04240H, (* negs r0, r0 *)
  197. (* L6: *) (* case op of *)
  198. 09A02H, (* ldr r2, [sp, 8] *) (* r2 <- op *)
  199. 00092H, (* lsls r2, 2 *)
  200. 03A02H, (* subs r2, 2 *)
  201. 02800H, (* cmp r0, 0 *)
  202. 04497H, (* add pc, r2 *)
  203. 0D00AH, (* beq L7 *)
  204. 0E00CH, (* b L8 *)
  205. 0D108H, (* bne L7 *)
  206. 0E00AH, (* b L8 *)
  207. 0DB06H, (* blt L7 *)
  208. 0E008H, (* b L8 *)
  209. 0DD04H, (* ble L7 *)
  210. 0E006H, (* b L8 *)
  211. 0DC02H, (* bgt L7 *)
  212. 0E004H, (* b L8 *)
  213. 0DA00H, (* bge L7 *)
  214. 0E002H, (* b L8 *)
  215. (* L7: *)
  216. 02001H, (* movs r0, 1 *)
  217. 0BC30H, (* pop {r4, r5} *)
  218. 04770H, (* bx lr *)
  219. (* L8: *)
  220. 02000H, (* movs r0, 0 *)
  221. 0BC30H; (* pop {r4, r5} *)
  222. PROCEDURE [code] _strcmpw* (op, len2, str2, len1, str1: INTEGER): BOOLEAN
  223. 09904H, (* ldr r1, [sp, 16] *) (* r1 <- str1 *)
  224. 09A02H, (* ldr r2, [sp, 8] *) (* r2 <- str2 *)
  225. 09B01H, (* ldr r3, [sp, 4] *) (* r3 <- len2 *)
  226. 09803H, (* ldr r0, [sp, 12] *) (* r0 <- len1 *)
  227. 04298H, (* cmp r0, r3 *)
  228. 0DA00H, (* bge L5 *)
  229. 00003H, (* movs r3, r0 *)
  230. (* L5: *) (* r3 <- min(r0, r3) *)
  231. 0B430H, (* push {r4, r5} *)
  232. (* L3: *)
  233. 02B00H, (* cmp r3, 0 *) (* while r3 > 0 do *)
  234. 0DD09H, (* ble L1 *)
  235. 0880CH, (* ldrh r4, [r1] *)
  236. 03102H, (* adds r1, 2 *)
  237. 08815H, (* ldrh r5, [r2] *)
  238. 03202H, (* adds r2, 2 *)
  239. 03B01H, (* subs r3, 1 *)
  240. 01B60H, (* subs r0, r4, r5 *)
  241. 0D111H, (* bne L6 *)
  242. 02C00H, (* cmp r4, 0 *)
  243. 0D1F4H, (* bne L3 *) (* end while *)
  244. 0E00DH, (* b L6 *)
  245. (* L1: *)
  246. 09A03H, (* ldr r2, [sp, 12] *) (* r2 <- len2 *)
  247. 09905H, (* ldr r1, [sp, 20] *) (* r1 <- len1 *)
  248. 00049H, (* lsls r1, 1 *)
  249. 00052H, (* lsls r2, 1 *)
  250. 04291H, (* cmp r1, r2 *)
  251. 0DC02H, (* bgt L9 *)
  252. 0DB04H, (* blt L4 *)
  253. 02000H, (* movs r0, 0 *)
  254. 0E005H, (* b L6 *)
  255. (* L9: *)
  256. 09806H, (* ldr r0, [sp, 24] *) (* r0 <- str1 *)
  257. 05A80H, (* ldrh r0, [r0, r2] *) (* r0 <- str1[len2] *)
  258. 0E002H, (* b L6 *)
  259. (* L4: *)
  260. 09804H, (* ldr r0, [sp, 16] *) (* r0 <- str2 *)
  261. 05A40H, (* ldrh r0, [r0, r1] *) (* r0 <- str2[len1] *)
  262. 04240H, (* negs r0, r0 *)
  263. (* L6: *) (* case op of *)
  264. 09A02H, (* ldr r2, [sp, 8] *) (* r2 <- op *)
  265. 00092H, (* lsls r2, 2 *)
  266. 03A02H, (* subs r2, 2 *)
  267. 02800H, (* cmp r0, 0 *)
  268. 04497H, (* add pc, r2 *)
  269. 0D00AH, (* beq L7 *)
  270. 0E00CH, (* b L8 *)
  271. 0D108H, (* bne L7 *)
  272. 0E00AH, (* b L8 *)
  273. 0DB06H, (* blt L7 *)
  274. 0E008H, (* b L8 *)
  275. 0DD04H, (* ble L7 *)
  276. 0E006H, (* b L8 *)
  277. 0DC02H, (* bgt L7 *)
  278. 0E004H, (* b L8 *)
  279. 0DA00H, (* bge L7 *)
  280. 0E002H, (* b L8 *)
  281. (* L7: *)
  282. 02001H, (* movs r0, 1 *)
  283. 0BC30H, (* pop {r4, r5} *)
  284. 04770H, (* bx lr *)
  285. (* L8: *)
  286. 02000H, (* movs r0, 0 *)
  287. 0BC30H; (* pop {r4, r5} *)
  288. PROCEDURE [code] _move* (bytes, dest, source: INTEGER)
  289. 09802H, (* ldr r0, [sp, 8] *)
  290. 00001H, (* movs r1, r0 *)
  291. 09A01H, (* ldr r2, [sp, 4] *)
  292. 00013H, (* movs r3, r2 *)
  293. 00789H, (* lsls r1, 30 *)
  294. 0D10AH, (* bne L1 *)
  295. 0079BH, (* lsls r3, 30 *)
  296. 0D108H, (* bne L1 *)
  297. 09900H, (* ldr r1, [sp, 0] *)
  298. (* L4: *)
  299. 02904H, (* cmp r1, 4 *)
  300. 0DB06H, (* blt L2 *)
  301. 06803H, (* ldr r3, [r0, 0] *)
  302. 06013H, (* str r3, [r2, 0] *)
  303. 03004H, (* adds r0, 4 *)
  304. 03204H, (* adds r2, 4 *)
  305. 03904H, (* subs r1, 4 *)
  306. 0E7F7H, (* b L4 *)
  307. (* L1: *)
  308. 09900H, (* ldr r1, [sp, 0] *)
  309. (* L2: *)
  310. 02900H, (* cmp r1, 0 *)
  311. 0DD05H, (* ble L3 *)
  312. (* L5: *)
  313. 07803H, (* ldrb r3, [r0, 0] *)
  314. 07013H, (* strb r3, [r2, 0] *)
  315. 03001H, (* adds r0, 1 *)
  316. 03201H, (* adds r2, 1 *)
  317. 03901H, (* subs r1, 1 *)
  318. 0DCF9H; (* bgt L5 *)
  319. (* L3: *)
  320. PROCEDURE _arrcpy* (base_size, len_dst, dst, len_src, src: INTEGER): BOOLEAN;
  321. VAR
  322. res: BOOLEAN;
  323. BEGIN
  324. IF len_src > len_dst THEN
  325. res := FALSE
  326. ELSE
  327. _move(len_src * base_size, dst, src);
  328. res := TRUE
  329. END
  330. RETURN res
  331. END _arrcpy;
  332. PROCEDURE _strcpy* (chr_size, len_src, src, len_dst, dst: INTEGER);
  333. BEGIN
  334. _move(MIN(len_dst, len_src) * chr_size, dst, src)
  335. END _strcpy;
  336. PROCEDURE [code] GetSP (): INTEGER
  337. 04668H; (* mov r0, sp *)
  338. PROCEDURE _new* (t, size: INTEGER; VAR p: INTEGER);
  339. VAR
  340. ptr: INTEGER;
  341. BEGIN
  342. ptr := Heap;
  343. IF ptr + size < GetSP() - 64 THEN
  344. INC(Heap, size);
  345. p := ptr + WORD;
  346. SYSTEM.PUT(ptr, t);
  347. INC(ptr, WORD);
  348. DEC(size, WORD);
  349. WHILE size > 0 DO
  350. SYSTEM.PUT(ptr, 0);
  351. INC(ptr, WORD);
  352. DEC(size, WORD)
  353. END
  354. ELSE
  355. p := 0
  356. END
  357. END _new;
  358. PROCEDURE _guard* (t, p: INTEGER): BOOLEAN;
  359. VAR
  360. _type: INTEGER;
  361. BEGIN
  362. SYSTEM.GET(p, p);
  363. IF p # 0 THEN
  364. SYSTEM.GET(p - WORD, _type);
  365. WHILE (_type # t) & (_type # 0) DO
  366. SYSTEM.GET(Types + _type * WORD, _type)
  367. END
  368. ELSE
  369. _type := t
  370. END
  371. RETURN _type = t
  372. END _guard;
  373. PROCEDURE _is* (t, p: INTEGER): BOOLEAN;
  374. VAR
  375. _type: INTEGER;
  376. BEGIN
  377. _type := 0;
  378. IF p # 0 THEN
  379. SYSTEM.GET(p - WORD, _type);
  380. WHILE (_type # t) & (_type # 0) DO
  381. SYSTEM.GET(Types + _type * WORD, _type)
  382. END
  383. END
  384. RETURN _type = t
  385. END _is;
  386. PROCEDURE _guardrec* (t0, t1: INTEGER): BOOLEAN;
  387. BEGIN
  388. WHILE (t1 # t0) & (t1 # 0) DO
  389. SYSTEM.GET(Types + t1 * WORD, t1)
  390. END
  391. RETURN t1 = t0
  392. END _guardrec;
  393. PROCEDURE _init* (tcount, heap, types: INTEGER);
  394. BEGIN
  395. Heap := heap;
  396. TypesCount := tcount;
  397. Types := types
  398. END _init;
  399. END RTL.