as.scm 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. ;;; GNU Mes --- Maxwell Equations of Software
  2. ;;; Copyright © 2016,2017,2018,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
  3. ;;; Copyright © 2019 Danny Milosavljevic <dannym@scratchpost.org>
  4. ;;;
  5. ;;; This file is part of GNU Mes.
  6. ;;;
  7. ;;; GNU Mes is free software; you can redistribute it and/or modify it
  8. ;;; under the terms of the GNU General Public License as published by
  9. ;;; the Free Software Foundation; either version 3 of the License, or (at
  10. ;;; your option) any later version.
  11. ;;;
  12. ;;; GNU Mes is distributed in the hope that it will be useful, but
  13. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. ;;; GNU General Public License for more details.
  16. ;;;
  17. ;;; You should have received a copy of the GNU General Public License
  18. ;;; along with GNU Mes. If not, see <http://www.gnu.org/licenses/>.
  19. ;;; Commentary:
  20. ;;; define armv4 assembly
  21. ;;; Code:
  22. (define-module (mescc armv4 as)
  23. #:use-module (mes guile)
  24. #:use-module (mescc as)
  25. #:use-module (mescc info)
  26. #:export (
  27. armv4:instructions
  28. ))
  29. ;; If 0 <= exp < #x100, use positive-body.
  30. ;; If #x-100 < exp < 0, use negative-body.
  31. ;; Otherwise, use general-body.
  32. (define-macro (optimize-immediate exp positive-body negative-body
  33. general-body)
  34. `(let ((exp ,exp))
  35. (if (>= exp 0)
  36. (if (< exp #x100)
  37. ,positive-body
  38. ,general-body)
  39. (if (> exp #x-100)
  40. ,negative-body
  41. ,general-body))))
  42. (define (armv4:function-preamble . rest)
  43. "Note: Pretends to be on x86 a lot"
  44. '(("push___%lr")
  45. ("push___%ebp")
  46. ("mov____%esp,%ebp")))
  47. (define (armv4:function-locals . rest)
  48. `(("allocate_stack_4180"))) ; 4*1024 buf, 20 local vars
  49. (define (armv4:r->local info n)
  50. (or n (error "invalid value: armv4:r->local: " n))
  51. (let ((r (get-r info))
  52. (n (- 0 (* 4 n))))
  53. `(,`(,(string-append "mov____%" r ",0x32(%ebp)") (#:immediate ,n)))))
  54. (define (immediate->r0 v)
  55. (optimize-immediate v
  56. `(((#:immediate1 ,v) "mov____$i8,%r0"))
  57. `(((#:immediate1 ,(- -1 v)) "mvn____%r0,$i8"))
  58. `(("mov____$i32,%r0" (#:immediate ,v)))))
  59. (define (armv4:value->r info v)
  60. (let ((r (get-r info)))
  61. (optimize-immediate v
  62. `(((#:immediate1 ,v) ,(string-append "mov____$i8,%" r)))
  63. `(((#:immediate1 ,(- -1 v)) ,(string-append "mvn____%" r ",$i8")))
  64. `((,(string-append "mov____$i32,%" r) (#:immediate ,v))))))
  65. (define (armv4:ret . rest)
  66. "Note: Pretends to be on x86 a lot"
  67. '(("mov____%ebp,%esp")
  68. ("pop____%ebp")
  69. ("ret")))
  70. (define (armv4:r-zero? info)
  71. (let ((r (get-r info)))
  72. `(((#:immediate1 #x00) ,(string-append "cmp____$i8,%" r)))))
  73. (define (armv4:local->r info n)
  74. (let ((r (get-r info))
  75. (n (- 0 (* 4 n))))
  76. (optimize-immediate n
  77. `(((#:immediate1 ,n)
  78. ,(string-append "ldr____%" r ",(%fp,+#$i8)")))
  79. `(((#:immediate1 ,(- n))
  80. ,(string-append "ldr____%" r ",(%fp,-#$i8)")))
  81. `((,(string-append "mov____0x32(%ebp),%" r)
  82. (#:immediate ,n))))))
  83. (define (armv4:r0+r1 info)
  84. (let ((r0 (get-r0 info))
  85. (r1 (get-r1 info)))
  86. `((,(string-append "add____%" r1 ",%" r0)))))
  87. (define (armv4:call-label info label n)
  88. `(((#:offset3 ,label) bl)
  89. ((#:immediate1 ,(* n 4)) "add____$i8,%esp")))
  90. (define (armv4:r->arg info i)
  91. (let ((r (get-r info)))
  92. `((,(string-append "push___%" r)))))
  93. (define (armv4:label->arg info label i)
  94. `(("push___$i32" (#:address ,label))))
  95. ;; Register--register value subtraction
  96. (define (armv4:r0-r1 info)
  97. (let ((r0 (get-r0 info))
  98. (r1 (get-r1 info)))
  99. `((,(string-append "sub____%" r1 ",%" r0)))))
  100. ;; Zero flag to register.
  101. (define (armv4:zf->r info)
  102. (let* ((r (get-r info)))
  103. `(((#:immediate1 #x00) ,(string-append "mov____$i8,%" r))
  104. ((#:immediate1 #x01) ,(string-append "moveq__%" r ",$i8")))))
  105. ;; C NOT Register value.
  106. (define (armv4:r-negate info)
  107. (armv4:zf->r info))
  108. (define (armv4:xor-zf info)
  109. '(((#:immediate1 #x00) "mov____$i8,%r0")
  110. ((#:immediate1 #x01) "moveq__%r0,$i8")
  111. ((#:immediate1 #x00) "cmp____$i8,%r0")))
  112. (define (armv4:r->local+n info id n)
  113. (let ((n (+ (- 0 (* 4 id)) n))
  114. (r (get-r info)))
  115. (optimize-immediate n
  116. `(((#:immediate1 ,n)
  117. ,(string-append "str____%" r ",(%fp,+#$i8)")))
  118. `(((#:immediate1 ,(- n))
  119. ,(string-append "str____%" r ",(%fp,-#$i8)")))
  120. `((,(string-append "mov____%" r ",0x32(%ebp)")
  121. (#:immediate ,n))))))
  122. (define (armv4:r-mem-add info v)
  123. (let ((r (get-r info)))
  124. `((,(string-append "add____$i32,(%" r ")") (#:immediate ,v)))))
  125. (define (armv4:r-byte-mem-add info v)
  126. (let ((r (get-r info)))
  127. `((,(string-append "push___%r0"))
  128. (,(string-append "ldrsb__%r0,(%" r ")"))
  129. ,(optimize-immediate v
  130. `((#:immediate1 ,v) ,(string-append "add____$i8,%r0"))
  131. `((#:immediate1 ,(- v)) ,(string-append "sub____$i8,%r0"))
  132. (error "armv4:r-byte-mem-add got immediate that doesn't fit into 8 bits."))
  133. (,(string-append "strb___%r0,(%" r ")"))
  134. (,(string-append "pop____%r0")))))
  135. (define (armv4:r-word-mem-add info v)
  136. (let ((r (get-r info)))
  137. `((,(string-append "push___%r0"))
  138. (,(string-append "ldrsh__%r0,(%" r ")"))
  139. ,(optimize-immediate v
  140. `((#:immediate1 ,v) ,(string-append "add____$i8,%r0"))
  141. `((#:immediate1 ,(- v)) ,(string-append "sub____$i8,%r0"))
  142. `(("add____$i32,(%r0)" (#:immediate ,v))))
  143. (,(string-append "strh___%r0,(%" r ")"))
  144. (,(string-append "pop____%r0")))))
  145. (define (armv4:local-ptr->r info n)
  146. (let ((r (get-r info)))
  147. (let ((n (- 0 (* 4 n))))
  148. `((,(string-append "mov____%ebp,%" r))
  149. ,(optimize-immediate n
  150. `((#:immediate1 ,n) ,(string-append "add____$i8,%" r))
  151. `((#:immediate1 ,(- n)) ,(string-append "sub____$i8,%" r))
  152. `(,(string-append "add____$i32,%" r) (#:immediate ,n)))))))
  153. (define (armv4:label->r info label)
  154. (let ((r (get-r info)))
  155. `((,(string-append "mov____$i32,%" r) (#:address ,label)))))
  156. (define (armv4:r0->r1 info)
  157. (let ((r0 (get-r0 info))
  158. (r1 (get-r1 info)))
  159. `((,(string-append "mov____%" r0 ",%" r1)))))
  160. (define (armv4:byte-mem->r info)
  161. (let ((r (get-r info)))
  162. `((,(string-append "ldrsb__%" r ",(%" r ")"))
  163. ((#:immediate1 #xFF) ,(string-append "and____$i8,%" r)))))
  164. (define (armv4:byte-r info)
  165. (let* ((r (get-r info)))
  166. `((,(string-append "uxtb__%" r ",%" r)))))
  167. (define (armv4:byte-signed-r info)
  168. (let* ((r (get-r info)))
  169. `((,(string-append "sxtb__%" r ",%" r)))))
  170. (define (armv4:word-r info)
  171. (let* ((r (get-r info)))
  172. `((,(string-append "uxth__%" r ",%" r)))))
  173. (define (armv4:word-signed-r info)
  174. (let* ((r (get-r info)))
  175. `((,(string-append "sxth__%" r ",%" r)))))
  176. (define (armv4:jump info label)
  177. `(((#:offset3 ,label) "b")))
  178. (define (armv4:jump-z info label)
  179. `(((#:offset3 ,label) "je")))
  180. (define (armv4:jump-nz info label)
  181. `(((#:offset3 ,label) "jne")))
  182. (define (armv4:jump-byte-z info label)
  183. `(("test___%r0,%r0") ; TODO: 1 Byte ?
  184. ((#:offset3 ,label) "je")))
  185. ;; signed
  186. (define (armv4:jump-g info label)
  187. `(((#:offset3 ,label) "jg")))
  188. (define (armv4:jump-ge info label)
  189. `(((#:offset3 ,label) "jge")))
  190. (define (armv4:jump-l info label)
  191. `(((#:offset3 ,label) "jl" )))
  192. (define (armv4:jump-le info label)
  193. `(((#:offset3 ,label) "jle")))
  194. ;; unsigned
  195. (define (armv4:jump-a info label)
  196. `(((#:offset3 ,label) "ja")))
  197. (define (armv4:jump-ae info label)
  198. `(((#:offset3 ,label) "jae")))
  199. (define (armv4:jump-b info label)
  200. `(((#:offset3 ,label) "jb")))
  201. (define (armv4:jump-be info label)
  202. `(((#:offset3 ,label) "jbe")))
  203. (define (armv4:byte-r0->r1-mem info)
  204. (let* ((r0 (get-r0 info))
  205. (r1 (get-r1 info)))
  206. `((,(string-append "strb___%" r0 ",(%" r1 ")")))))
  207. (define (armv4:label-mem->r info label)
  208. (let ((r (get-r info)))
  209. `((,(string-append "mov____0x32,%" r) (#:address ,label)))))
  210. (define (armv4:word-mem->r info)
  211. (let ((r (get-r info)))
  212. `((,(string-append "ldrsh__%" r ",(%" r ")")))))
  213. (define (armv4:mem->r info)
  214. (let ((r (get-r info)))
  215. `((,(string-append "mov____(%" r "),%" r)))))
  216. (define (armv4:local-add info n v)
  217. (let ((n (- 0 (* 4 n))))
  218. (append (immediate->r0 v)
  219. `(("mov____0x32(%ebp),%r1" (#:immediate ,n))
  220. ("add____%r0,%r1")
  221. ("mov____%r1,0x32(%ebp)" (#:immediate ,n))))))
  222. (define (armv4:label-mem-add info label v)
  223. (append (immediate->r0 v)
  224. `(("add____%r0,0x32" (#:address ,label)))))
  225. (define (armv4:nop info)
  226. '(("nop")))
  227. (define (armv4:swap-r0-r1 info)
  228. (let ((r0 (get-r0 info))
  229. (r1 (get-r1 info)))
  230. `((,(string-append "xchg___%" r0 ",%" r1)))))
  231. (define (armv4:flag->r branchspec info)
  232. "Find out whether a flag or set of flag has a given set of values and set the value of the register R to 1 if it is so, and to 0 otherwise.
  233. Possible values for branchspec are one of (\"cs\", \"cc\", \"ge\", \"gt\", \"hi\", \"lt\", \"le\")"
  234. (let* ((r (get-r info)))
  235. `(((#:immediate1 #x00) ,(string-append "mov____$i8,%" r))
  236. ((#:immediate1 #x01) ,(string-append "mov" branchspec "__%" r ",$i8")))))
  237. ;; signed
  238. (define (armv4:g?->r info)
  239. (armv4:flag->r "gt" info))
  240. (define (armv4:ge?->r info)
  241. (armv4:flag->r "ge" info))
  242. (define (armv4:l?->r info)
  243. (armv4:flag->r "lt" info))
  244. (define (armv4:le?->r info)
  245. (armv4:flag->r "le" info))
  246. ;; unsigned
  247. (define (armv4:a?->r info)
  248. (armv4:flag->r "hi" info))
  249. (define (armv4:ae?->r info)
  250. (armv4:flag->r "cs" info))
  251. (define (armv4:b?->r info)
  252. (armv4:flag->r "cc" info))
  253. (define (armv4:be?->r info)
  254. (let* ((r (get-r info)))
  255. `(((#:immediate1 #x01) ,(string-append "mov____$i8,%" r))
  256. ((#:immediate1 #x00) ,(string-append "movhi__%" r ",$i8")))))
  257. (define (armv4:test-r info)
  258. (let ((r (get-r info)))
  259. `((,(string-append "test___%" r ",%" r)))))
  260. (define (armv4:r->label info label)
  261. (let ((r (get-r info)))
  262. `((,(string-append "mov____%" r ",0x32") (#:address ,label)))))
  263. (define (armv4:r->byte-label info label)
  264. (let* ((r (get-r info))) ; r: byte
  265. `((,(string-append "movb___%" r ",0x32") (#:address ,label)))))
  266. (define (armv4:r->word-label info label)
  267. (let* ((r (get-r info))) ; r: halfword
  268. `((,(string-append "movw___%" r ",0x32") (#:address ,label)))))
  269. (define (armv4:call-r info n)
  270. (let ((r (get-r info)))
  271. `((,(string-append "call___*%" r))
  272. ;; Note: Assumes n > 0.
  273. ((#:immediate1 ,(* n 4)) "add____$i8,%esp"))))
  274. (define (armv4:r0*r1 info)
  275. ;; FIXME: Signedness.
  276. (let ((r0 (get-r0 info))
  277. (r1 (get-r1 info)))
  278. `((,(string-append "mul____%" r0 ",%" r1)))))
  279. (define (armv4:r0<<r1 info)
  280. (let ((r0 (get-r0 info))
  281. (r1 (get-r1 info)))
  282. `((,(string-append "lsl____%" r0 ",%" r0 ",%" r1)))))
  283. ;; FIXME: lsr??! Signed or unsigned r0?
  284. (define (armv4:r0>>r1 info)
  285. (let ((r0 (get-r0 info))
  286. (r1 (get-r1 info)))
  287. `((,(string-append "lsr____%" r0 ",%" r0 ",%" r1)))))
  288. (define (armv4:r0-and-r1 info)
  289. (let ((r0 (get-r0 info))
  290. (r1 (get-r1 info)))
  291. `((,(string-append "and____%" r1 ",%" r0)))))
  292. (define (armv4:r0/r1 info signed?)
  293. (let ((r0 (get-r0 info))
  294. (r1 (get-r1 info)))
  295. (if signed?
  296. ;; __mesabi_idiv(a, b)
  297. (cons* `(,(string-append "push___%" r1))
  298. `(,(string-append "push___%" r0))
  299. (armv4:call-label #f "__mesabi_idiv" 2))
  300. ;; __mesabi_uldiv(a, b, remainderp)
  301. (cons* `(,(string-append "push___0"))
  302. `(,(string-append "push___%" r1))
  303. `(,(string-append "push___%" r0))
  304. (armv4:call-label #f "__mesabi_uldiv" 3)))))
  305. (define (armv4:r0%r1 info signed?)
  306. (let ((r0 (get-r0 info))
  307. (r1 (get-r1 info)))
  308. (if signed?
  309. ;; __mesabi_imod(a,b)
  310. (cons* `(,(string-append "push___%" r1))
  311. `(,(string-append "push___%" r0))
  312. (armv4:call-label #f "__mesabi_imod" 2))
  313. ;; __mesabi_uldiv(a, b, remainderp)
  314. (append `(("push___%r0") ; slot for remainder
  315. ("mov____%esp,%r0")
  316. ("push___%r0") ; pointer to remainder
  317. (,(string-append "push___%" r1))
  318. (,(string-append "push___%" r0)))
  319. (armv4:call-label #f "__mesabi_uldiv" 3)
  320. `(("pop____%r0"))))))
  321. (define (armv4:r+value info v)
  322. (let ((r (get-r info)))
  323. (optimize-immediate v
  324. `(((#:immediate1 ,v) ,(string-append "add____$i8,%" r)))
  325. `(((#:immediate1 ,(- v)) ,(string-append "sub____$i8,%" r)))
  326. `((,(string-append "add____$i32,%" r) (#:immediate ,v))))))
  327. (define (armv4:r0->r1-mem info)
  328. (let ((r0 (get-r0 info))
  329. (r1 (get-r1 info)))
  330. `((,(string-append "mov____%" r0 ",(%" r1 ")")))))
  331. (define (armv4:byte-r0->r1-mem info)
  332. (let* ((r0 (get-r0 info))
  333. (r1 (get-r1 info)))
  334. `((,(string-append "strb___%" r0 ",(%" r1 ")")))))
  335. (define (armv4:word-r0->r1-mem info)
  336. (let* ((r0 (get-r0 info))
  337. (r1 (get-r1 info)))
  338. `((,(string-append "strh___%" r0 ",(%" r1 ")")))))
  339. (define (armv4:r-cmp-value info v)
  340. (let ((r (get-r info)))
  341. (optimize-immediate v
  342. `(((#:immediate1 ,v) ,(string-append "cmp____$i8,%" r)))
  343. `(((#:immediate1 ,(- v)) ,(string-append "cmn____$i8,%" r)))
  344. `((,(string-append "cmp____$i32,%" r) (#:immediate ,v))))))
  345. (define (armv4:push-register info r)
  346. `((,(string-append "push___%" r))))
  347. (define (armv4:pop-register info r)
  348. `((,(string-append "pop____%" r))))
  349. (define (armv4:return->r info)
  350. (let ((r (get-r info)))
  351. (if (equal? r "r0") '()
  352. `((,(string-append "mov____%r0,%" r))))))
  353. (define (armv4:r0-or-r1 info)
  354. (let ((r0 (get-r0 info))
  355. (r1 (get-r1 info)))
  356. `((,(string-append "or_____%" r1 ",%" r0)))))
  357. (define (armv4:shl-r info n)
  358. (let ((r (get-r info)))
  359. `(((#:immediate1 ,n) ,(string-append "lsl____%" r ",%" r ",$i8")))))
  360. (define (armv4:r+r info)
  361. (let ((r (get-r info)))
  362. `((,(string-append "add____%" r ",%" r)))))
  363. (define (armv4:not-r info)
  364. (let ((r (get-r info)))
  365. `((,(string-append "not____%" r)))))
  366. (define (armv4:r0-xor-r1 info)
  367. (let ((r0 (get-r0 info))
  368. (r1 (get-r1 info)))
  369. `((,(string-append "xor____%" r1 ",%" r0)))))
  370. (define (armv4:r0-mem->r1-mem info)
  371. (let* ((registers (.registers info))
  372. (r0 (get-r0 info))
  373. (r1 (get-r1 info))
  374. (r2 (car registers)))
  375. `((,(string-append "mov____(%" r0 "),%" r2))
  376. (,(string-append "mov____%" r2 ",(%" r1 ")")))))
  377. (define (armv4:byte-r0-mem->r1-mem info)
  378. (let* ((registers (.registers info))
  379. (r0 (get-r0 info))
  380. (r1 (get-r1 info))
  381. (r2 (car registers)))
  382. `((,(string-append "ldrsb__%" r2 ",(%" r0 ")"))
  383. (,(string-append "strb___%" r2 ",(%" r1 ")")))))
  384. (define (armv4:word-r0-mem->r1-mem info)
  385. (let* ((registers (.registers info))
  386. (r0 (get-r0 info))
  387. (r1 (get-r1 info))
  388. (r2 (car registers)))
  389. `((,(string-append "mov____(%" r0 "),%" r2))
  390. (,(string-append "strh___%" r2 ",(%" r1 ")")))))
  391. (define (armv4:r0+value info v)
  392. (let ((r0 (get-r0 info)))
  393. (optimize-immediate v
  394. `(((#:immediate1 ,v) ,(string-append "add____$i8,%" r0)))
  395. `(((#:immediate1 ,(- v)) ,(string-append "sub____$i8,%" r0)))
  396. `((,(string-append "add____$i32,%" r0) (#:immediate ,v))))))
  397. (define (armv4:value->r0 info v)
  398. (let ((r0 (get-r0 info)))
  399. `((,(string-append "mov____$i32,%" r0) (#:immediate ,v)))))
  400. (define (armv4:byte-r->local+n info id n)
  401. (let* ((n (+ (- 0 (* 4 id)) n))
  402. (r (get-r info)))
  403. `(,(optimize-immediate n
  404. `((#:immediate1 ,n)
  405. ,(string-append "strb___%" r ",(%fp,+#$i8)"))
  406. `((#:immediate1 ,(- n))
  407. ,(string-append "strb___%" r ",(%fp,-#$i8)"))
  408. `(,(string-append "strb___%" r ",0x32(%ebp)")
  409. (#:immediate ,n))))))
  410. (define (armv4:word-r->local+n info id n)
  411. (let* ((n (+ (- 0 (* 4 id)) n))
  412. (r (get-r info)))
  413. (optimize-immediate n
  414. `(((#:immediate1 ,n)
  415. ,(string-append "strh___%" r ",(%fp,+#$i8)")))
  416. `(((#:immediate1 ,(- n))
  417. ,(string-append "strh___%" r ",(%fp,-#$i8)")))
  418. `((,(string-append "strh___%" r ",0x32(%ebp)"))))))
  419. (define (armv4:r-and info v)
  420. (let ((r (get-r info)))
  421. `(((#:immediate1 ,v) ,(string-append "and____$i8,%" r)))))
  422. (define (armv4:push-r0 info)
  423. (let ((r0 (get-r0 info)))
  424. `((,(string-append "push___%" r0)))))
  425. (define (armv4:r1->r0 info)
  426. (let ((r0 (get-r0 info))
  427. (r1 (get-r1 info)))
  428. `((,(string-append "mov____%" r1 ",%" r0)))))
  429. (define (armv4:pop-r0 info)
  430. (let ((r0 (get-r0 info)))
  431. `((,(string-append "pop____%" r0)))))
  432. (define (armv4:swap-r-stack info)
  433. (let ((r (get-r info)))
  434. `((,(string-append "xchg___%" r ",(%esp)")))))
  435. (define (armv4:swap-r1-stack info)
  436. (let ((r0 (get-r0 info)))
  437. `((,(string-append "xchg___%" r0 ",(%esp)")))))
  438. (define (armv4:r2->r0 info)
  439. (let ((r0 (get-r0 info))
  440. (r1 (get-r1 info))
  441. (allocated (.allocated info)))
  442. (if (> (length allocated) 2)
  443. (let ((r2 (cadddr allocated)))
  444. `((,(string-append "mov____%" r2 ",%" r1))))
  445. `((,(string-append "pop____%" r0))
  446. (,(string-append "push___%" r0))))))
  447. (define armv4:instructions
  448. `(
  449. (a?->r . ,armv4:a?->r)
  450. (ae?->r . ,armv4:ae?->r)
  451. (b?->r . ,armv4:b?->r)
  452. (be?->r . ,armv4:be?->r)
  453. (byte-mem->r . ,armv4:byte-mem->r)
  454. (byte-r . ,armv4:byte-r)
  455. (byte-r->local+n . ,armv4:byte-r->local+n)
  456. (byte-r0->r1-mem . ,armv4:byte-r0->r1-mem)
  457. (byte-r0->r1-mem . ,armv4:byte-r0->r1-mem)
  458. (byte-r0-mem->r1-mem . ,armv4:byte-r0-mem->r1-mem)
  459. (byte-signed-r . ,armv4:byte-signed-r)
  460. (call-label . ,armv4:call-label)
  461. (call-r . ,armv4:call-r)
  462. (function-locals . ,armv4:function-locals)
  463. (function-preamble . ,armv4:function-preamble)
  464. (g?->r . ,armv4:g?->r)
  465. (ge?->r . ,armv4:ge?->r)
  466. (jump . ,armv4:jump)
  467. (jump-a . ,armv4:jump-a)
  468. (jump-ae . ,armv4:jump-ae)
  469. (jump-b . ,armv4:jump-b)
  470. (jump-be . ,armv4:jump-be)
  471. (jump-byte-z . ,armv4:jump-byte-z)
  472. (jump-g . , armv4:jump-g)
  473. (jump-ge . , armv4:jump-ge)
  474. (jump-l . ,armv4:jump-l)
  475. (jump-le . ,armv4:jump-le)
  476. (jump-nz . ,armv4:jump-nz)
  477. (jump-z . ,armv4:jump-z)
  478. (l?->r . ,armv4:l?->r)
  479. (label->arg . ,armv4:label->arg)
  480. (label->r . ,armv4:label->r)
  481. (label-mem->r . ,armv4:label-mem->r)
  482. (label-mem-add . ,armv4:label-mem-add)
  483. (le?->r . ,armv4:le?->r)
  484. (local->r . ,armv4:local->r)
  485. (local-add . ,armv4:local-add)
  486. (local-ptr->r . ,armv4:local-ptr->r)
  487. (long-r0->r1-mem . ,armv4:r0->r1-mem)
  488. (long-r0-mem->r1-mem . ,armv4:r0-mem->r1-mem)
  489. (mem->r . ,armv4:mem->r)
  490. (nop . ,armv4:nop)
  491. (not-r . ,armv4:not-r)
  492. (pop-r0 . ,armv4:pop-r0)
  493. (pop-register . ,armv4:pop-register)
  494. (push-r0 . ,armv4:push-r0)
  495. (push-register . ,armv4:push-register)
  496. (r+r . ,armv4:r+r)
  497. (r+value . ,armv4:r+value)
  498. (r->arg . ,armv4:r->arg)
  499. (r->byte-label . ,armv4:r->byte-label)
  500. (r->label . ,armv4:r->label)
  501. (r->local . ,armv4:r->local)
  502. (r->local+n . ,armv4:r->local+n)
  503. (r->word-label . ,armv4:r->word-label)
  504. (r-and . ,armv4:r-and)
  505. (r-byte-mem-add . ,armv4:r-byte-mem-add)
  506. (r-cmp-value . ,armv4:r-cmp-value)
  507. (r-mem-add . ,armv4:r-mem-add)
  508. (r-negate . ,armv4:r-negate)
  509. (r-word-mem-add . ,armv4:r-word-mem-add)
  510. (r-zero? . ,armv4:r-zero?)
  511. (r0%r1 . ,armv4:r0%r1)
  512. (r0*r1 . ,armv4:r0*r1)
  513. (r0+r1 . ,armv4:r0+r1)
  514. (r0+value . ,armv4:r0+value)
  515. (r0->r1 . ,armv4:r0->r1)
  516. (r0->r1-mem . ,armv4:r0->r1-mem)
  517. (r0-and-r1 . ,armv4:r0-and-r1)
  518. (r0-mem->r1-mem . ,armv4:r0-mem->r1-mem)
  519. (r0-or-r1 . ,armv4:r0-or-r1)
  520. (r0-r1 . ,armv4:r0-r1)
  521. (r0-xor-r1 . ,armv4:r0-xor-r1)
  522. (r0/r1 . ,armv4:r0/r1)
  523. (r0<<r1 . ,armv4:r0<<r1)
  524. (r0>>r1 . ,armv4:r0>>r1)
  525. (r1->r0 . ,armv4:r1->r0)
  526. (r2->r0 . ,armv4:r2->r0)
  527. (ret . ,armv4:ret)
  528. (return->r . ,armv4:return->r)
  529. (shl-r . ,armv4:shl-r)
  530. (swap-r-stack . ,armv4:swap-r-stack)
  531. (swap-r0-r1 . ,armv4:swap-r0-r1)
  532. (swap-r1-stack . ,armv4:swap-r1-stack)
  533. (test-r . ,armv4:test-r)
  534. (value->r . ,armv4:value->r)
  535. (value->r0 . ,armv4:value->r0)
  536. (word-mem->r . ,armv4:word-mem->r)
  537. (word-r . ,armv4:word-r)
  538. (word-r->local+n . ,armv4:word-r->local+n)
  539. (word-r0->r1-mem . ,armv4:word-r0->r1-mem)
  540. (word-r0-mem->r1-mem . ,armv4:word-r0-mem->r1-mem)
  541. (word-signed-r . ,armv4:word-signed-r)
  542. (xor-zf . ,armv4:xor-zf)
  543. (zf->r . ,armv4:zf->r)
  544. ))