mes/module/mescc/i386/as.scm
Jan Nieuwenhuizen a10c48735d
mescc: Posixify interface.
* module/mescc/compile.mes: Move from language/c99/compiler.mes.
* module/mescc: New module..
* module/mescc/M1.scm: Move from mes/M1.mes.
* module/mescc/as.scm: Likewise.
* module/mescc/bytevectors.scm: Likewise.
* module/mescc/mescc.scm: New file.
* scripts/mescc: Update to new layout and posixy interface.
* GNUmakefile: Likewise.
* build-aux/build-cc.sh: Likewise.
* build-aux/build-guile.sh: Likewise.
* build-aux/build-mes.sh: Likewise.
* build-aux/build-mlibc.sh: Likewise.
* build-aux/cc-mes.sh: Likewise.
* build-aux/cc-mlibc.sh: Likewise.
* build-aux/cc.sh: Likewise.
* build-aux/check-mescc.sh: Likewise.
* build-aux/test.sh: Likewise.
* build.sh: Likewise.
* .gitignore: Update for posixy extensions.
2018-05-25 08:05:02 +02:00

692 lines
22 KiB
Scheme
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;; Mes --- Maxwell Equations of Software
;;; Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of Mes.
;;;
;;; Mes is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; Mes is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with Mes. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; define i386 assembly
;;; Code:
(define-module (mescc i386 as)
#:use-module (mes guile)
#:use-module (mescc as)
#:export (
i386:accu%base
i386:accu*base
i386:accu*n->label
i386:accu*n->local
i386:accu+accu
i386:accu+base
i386:accu+value
i386:accu->base
i386:accu->base-mem
i386:byte-accu->base-mem
i386:word-accu->base-mem
i386:accu->base-mem+n
i386:byte-accu->base-mem+n
i386:word-accu->base-mem+n
i386:accu->label
i386:accu->local
i386:accu->local+n
i386:accu->local+n
i386:accu-and
i386:accu-and-base
i386:accu-and-base-mem
i386:accu-base
i386:accu-cmp-value
i386:accu-mem-add
i386:accu-mem->base-mem
i386:accu-negate
i386:accu-not
i386:accu-or-base
i386:accu-or-base-mem
i386:accu-shl
i386:accu-test
i386:accu-xor-base
i386:accu-zero?
i386:accu/base
i386:accu<->stack
i386:accu<<base
i386:accu>>base
i386:base+value
i386:base->accu
i386:base->accu-mem
i386:base->label
i386:base-mem->accu-mem
i386:base-mem+n->accu
i386:base-mem->accu
i386:base-sub
i386:byte-accu->base-mem
i386:word-accu->base-mem
i386:byte-base->accu-mem
i386:byte-base->accu-mem+n
i386:byte-base-mem->accu
i386:byte-base-sub
i386:byte-local->base
i386:byte-mem->accu
i386:word-mem->accu
i386:byte-mem->base
i386:byte-sub-base
i386:byte-test-base
i386:call-accu
i386:call-label
i386:formal
i386:function-locals
i386:function-preamble
i386:jump
i386:jump
i386:jump-a
i386:jump-ae
i386:jump-b
i386:jump-be
i386:jump-byte-z
i386:jump-g
i386:jump-ge
i386:jump-l
i386:jump-le
i386:jump-nz
i386:jump-z
i386:label->accu
i386:label->base
i386:label-mem->accu
i386:label-mem->base
i386:label-mem-add
i386:local->accu
i386:local->base
i386:local-add
i386:local-address->accu
i386:local-address->accu
i386:local-address->base
i386:local-ptr->accu
i386:local-ptr->base
i386:local-test
i386:mem+n->accu
i386:byte-mem+n->accu
i386:word-mem+n->accu
i386:mem->accu
i386:mem->base
i386:nop
i386:nz->accu
i386:pop-accu
i386:pop-base
i386:push-accu
i386:push-base
i386:push-byte-local-de-de-ref
i386:push-byte-local-de-ref
i386:push-word-local-de-ref
i386:push-label
i386:push-label-mem
i386:push-local
i386:push-local-address
i386:push-local-de-ref
i386:ret
i386:ret-local
i386:sub-base
i386:test-base
i386:value->accu
i386:value->accu-mem
i386:value->accu-mem+n
i386:value->base
i386:value->label
i386:value->local
i386:xor-accu
i386:xor-zf
i386:g?->accu
i386:ge?->accu
i386:l?->accu
i386:le?->accu
i386:a?->accu
i386:ae?->accu
i386:b?->accu
i386:be?->accu
i386:z->accu
i386:byte-accu
i386:signed-byte-accu
i386:word-accu
i386:signed-word-accu
))
(define (i386:nop)
'(("nop")))
(define (i386:function-preamble)
'(("push___%ebp")
("mov____%esp,%ebp")))
(define (i386:function-locals)
`(("sub____%esp,$i32" (#:immediate ,(+ (* 4 1025) (* 20 4)))))) ; sub %esp,xxx 4*1024 buf, 20 local vars
(define (i386:push-label label)
`(("push___$i32" (#:address ,label)))) ; push $0x<label>
(define (i386:push-label-mem label)
`(("mov____0x32,%eax" (#:address ,label)) ; mov 0x804a000,%eax
("push___%eax"))) ; push %eax
;;; locals
(define (i386:push-local n)
(or n (error "invalid value: push-local: " n))
(let ((n (- 0 (* 4 n))))
`(,(if (< (abs n) #x80) `("push___0x8(%ebp)" (#:immediate1 ,n))
`("push___0x32(%ebp)" (#:immediate ,n))))))
(define (i386:push-local-address n)
(or n (error "invalid value: push-local-address: " n))
(let ((n (- 0 (* 4 n))))
`(,(if (< (abs n) #x80) `("lea____0x8(%ebp),%eax" (#:immediate1 ,n))
`("lea____0x32(%ebp),%eax" (#:immediate ,n)))
("push___%eax"))))
(define (i386:push-byte-local-de-ref n)
(or n (error "invalid value: push-byte-local-de-ref: " n))
(let ((n (- 0 (* 4 n))))
`(,(if (< (abs n) #x80) `("mov____0x8(%ebp),%eax" (#:immediate1 ,n))
`("mov____0x32(%ebp),%eax" (#:immediate ,n)))
("movzbl_(%eax),%eax")
("push___%eax"))))
(define (i386:push-word-local-de-ref n)
(or n (error "invalid value: push-word-local-de-ref: " n))
(let ((n (- 0 (* 4 n))))
`(,(if (< (abs n) #x80) `("mov____0x8(%ebp),%eax" (#:immediate1 ,n))
`("mov____0x32(%ebp),%eax" (#:immediate ,n)))
("movzwl_(%eax),%eax")
("push___%eax"))))
(define (i386:push-byte-local-de-de-ref n)
(or n (error "invalid value: push-byte-local-de-de-ref: " n))
(let ((n (- 0 (* 4 n))))
`(,(if (< (abs n) #x80) `("mov____0x8(%ebp),%eax" (#:immediate1 ,n))
`("mov____0x32(%ebp),%eax" (#:immediate ,n)))
("mov____(%eax),%eax")
("movzbl_(%eax),%eax")
("push___%eax"))))
(define (i386:push-local-de-ref n)
(or n (error "invalid value: push-byte-local-de-ref: " n))
(let ((n (- 0 (* 4 n))))
`(,(if (< (abs n) #x80) `("mov____0x8(%ebp),%eax" (#:immediate1 ,n))
`("mov____0x32(%ebp),%eax" (#:immediate ,n)))
("mov____(%eax),%eax")
("push___%eax"))))
(define (i386:local-add n v)
(or n (error "invalid value: i386:local-add: " n))
(let ((n (- 0 (* 4 n))))
`(,(if (and (< (abs n) #x80)
(< (abs v) #x80)) `("add____$i8,0x8(%ebp)" (#:immediate1 ,n) (#:immediate1 ,v))
`("add____$i32,0x32(%ebp)" (#:immediate ,n) (#:immediate ,v))))))
(define (i386:accu->local n)
(or n (error "invalid value: accu->local: " n))
(let ((n (- 0 (* 4 n))))
`(,(if (< (abs n) #x80) `("mov____%eax,0x8(%ebp)" (#:immediate1 ,n))
`("mov____%eax,0x32(%ebp)" (#:immediate ,n))))))
(define (i386:accu->local+n id n)
(let ((n (+ (- 0 (* 4 id)) n)))
`(,(if (< (abs n) #x80) `("mov____%eax,0x8(%ebp)" (#:immediate1 ,n))
`("mov____%eax,0x32(%ebp)" (#:immediate ,n))))))
(define (i386:accu*n->local i n)
(or n (error "invalid value: accu->local: " n))
(let ((o (- 0 (* 4 i))))
(let loop ((i 0))
(if (>= i n) '() ;; FIXME: byte, word-sized
(let ((o (+ o i)))
(append
(if (< (abs o) #x80) `(("mov____0x8(%eax),%ebx" (#:immediate1 ,i))
("mov____%ebx,0x8(%ebp)" (#:immediate1 ,o)))
`(("mov____0x8(%eax),%ebx" (#:immediate1 ,i))
("mov____%ebx,0x32(%ebp)" (#:immediate ,o))))
(loop (+ i 4))))))))
(define (i386:local->accu n)
(or n (error "invalid value: local->accu: " n))
(let ((n (- 0 (* 4 n))))
`(,(if (< (abs n) #x80) `("mov____0x8(%ebp),%eax" (#:immediate1 ,n))
`("mov____0x32(%ebp),%eax" (#:immediate ,n))))))
(define (i386:local-address->accu n)
(or n (error "invalid value: ladd: " n))
(let ((n (- 0 (* 4 n))))
`(,(if (< (abs n) #x80) `("lea____0x8(%ebp),%eax" (#:immediate1 ,n))
`("lea____0x32(%ebp),%eax" (#:immediate ,n))))))
(define (i386:local-ptr->accu n)
(or n (error "invalid value: local-ptr->accu: " n))
(let ((n (- 0 (* 4 n))))
`(("mov____%ebp,%eax") ; mov %ebp,%eax
,(if (< (abs n) #x80) `("add____$i8,%eax" (#:immediate1 ,n))
`("add____$i32,%eax" (#:immediate ,n))))))
(define (i386:byte-local->base n)
(or n (error "invalid value: byte-local->base: " n))
(let ((n (- 0 (* 4 n))))
`(,(if (< (abs n) #x80) `("movzbl_0x8(%ebp),%edx" (#:immediate1 ,n))
`,@(("mov_0x32(%ebp),%edx" (#:immediate ,n))
("movzbl_%dl,%edx"))))))
(define (i386:local->base n)
(or n (error "invalid value: local->base: " n))
(let ((n (- 0 (* 4 n))))
`(,(if (< (abs n) #x80) `("mov____0x8(%ebp),%edx" (#:immediate1 ,n))
`("mov____0x32(%ebp),%edx" (#:immediate ,n))))))
(define (i386:local-address->base n) ;; DE-REF
(or n (error "invalid value: local-address->base: " n))
(let ((n (- 0 (* 4 n))))
`(,(if (< (abs n) #x80) `("lea____0x8(%ebp),%edx" (#:immediate1 ,n))
`("lea____0x32(%ebp),%edx" (#:immediate ,n))))))
(define (i386:local-ptr->base n)
(or n (error "invalid value: local-ptr->base: " n))
(let ((n (- 0 (* 4 n))))
`(("mov____%ebp,%edx") ; mov %ebp,%edx
,(if (< (abs n) #x80) `("add____$i8,%edx" (#:immediate1 ,n))
`("add____$i32,%edx" (#:immediate ,n))))))
(define (i386:value->local n v)
(or n (error "invalid value: value->local: " n))
(let ((n (- 0 (* 4 n))))
`(,(if (< (abs n) #x80) `("mov____$i32,0x8(%ebp)" (#:immediate1 ,n) (#:immediate ,v))
`("mov____$i32,0x32(%ebp)" (#:immediate ,n) (#:immediate ,v))))))
(define (i386:local-test n v)
(or n (error "invalid value: local-test: " n))
(let ((n (- 0 (* 4 n))))
`(,(cond ((and (< (abs n) #x80)
(< (abs v) #x80)) `("cmp____$i8,0x8(%ebp)" (#:immediate1 ,n) (#:immediate1 ,v)))
((< (abs n) #x80) `("cmp____$i32,0x8(%ebp)" (#:immediate1 ,n) (#:immediate ,v)))
((< (abs v) #x80) `("cmp____$i8,0x32(%ebp)" (#:immediate ,n) (#:immediate1 ,v)))
(else `("cmp____$i32,0x32(%ebp)" (#:immediate ,n) (#:immediate ,v)))))))
(define (i386:pop-accu)
'(("pop____%eax"))) ; pop %eax
(define (i386:push-accu)
'(("push___%eax"))) ; push %eax
(define (i386:pop-base)
'(("pop____%edx"))) ; pop %edx
(define (i386:push-base)
'(("push___%edx"))) ; push %edx
(define (i386:ret)
'(("leave") ; leave
("ret"))) ; ret
(define (i386:accu->base)
'(("mov____%eax,%edx"))) ; mov %eax,%edx
(define (i386:accu->base-mem)
'(("mov____%eax,(%edx)"))) ; mov %eax,(%edx)
(define (i386:byte-accu->base-mem)
'(("mov____%al,(%edx)"))) ; mov %al,(%edx)
(define (i386:word-accu->base-mem)
'(("mov____%ax,(%edx)"))) ; mov %ax,(%edx)
(define (i386:accu->base-mem+n n)
(or n (error "invalid value: accu->base-mem+n: " n))
`(,(if (< (abs n) #x80) `("mov____%eax,0x8(%edx)" (#:immediate1 ,n))
`("mov____%eax,0x32(%edx)" (#:immediate ,n)))))
(define (i386:byte-accu->base-mem+n n)
(or n (error "invalid value: accu->base-mem+n: " n))
`(,(if (< (abs n) #x80) `("mov____%al,0x8(%edx)" (#:immediate1 ,n))
`("mov____%al,0x32(%edx)" (#:immediate ,n)))))
(define (i386:word-accu->base-mem+n n)
(or n (error "invalid value: accu->base-mem+n: " n))
`(,(if (< (abs n) #x80) `("mov____%ax,0x8(%edx)" (#:immediate1 ,n))
`("mov____%ax,0x32(%edx)" (#:immediate ,n)))))
(define (i386:accu->label label)
`(("mov____%eax,0x32" (#:address ,label)))) ; mov %eax,0x<label>
(define (i386:accu*n->label label n)
(append
'(("push___%edx"))
(let loop ((i 0))
(if (>= i n) '() ;; FIXME: byte, word-sized
(append
`(("mov____$i32,%edx" (#:address ,label))
("mov____0x8(%eax),%ebx" (#:immediate1 ,i))
("mov____%ebx,0x8(%edx)" (#:immediate1 ,i)))
(loop (+ i 4)))))
'(("pop____%edx"))))
(define (i386:accu-shl n)
(or n (error "invalid value: accu:shl n: " n))
`(("shl____$i8,%eax" (#:immediate1 ,n)))) ; shl $0x8,%eax
(define (i386:accu<<base)
'(("xor____%ecx,%ecx") ; xor %ecx,%ecx
("mov____%edx,%ecx") ; mov %edx,%ecx
("shl____%cl,%eax"))) ; shl %cl,%eax
(define (i386:accu>>base)
'(("xor____%ecx,%ecx") ; xor %ecx,%ecx
("mov____%edx,%ecx") ; mov %edx,%ecx
("shr____%cl,%eax"))) ; shr %cl,%eax
(define (i386:accu-and-base)
'(("and____%edx,%eax")))
(define (i386:accu-and v)
`(("and____$i32,%eax" (#:immediate ,v))))
(define (i386:accu-and-base-mem)
'(("and____(%edx),%eax")))
(define (i386:accu-or-base-mem)
'(("or_____(%edx),%eax")))
(define (i386:accu-not)
'(("not____%eax"))) ; not %eax
(define (i386:accu-or-base)
'(("or_____%edx,%eax"))) ; or %edx,%eax
(define (i386:accu-xor-base)
'(("xor____%edx,%eax"))) ; xor %edx,%eax
(define (i386:accu+accu)
'(("add____%eax,%eax"))) ; add %eax,%eax
(define (i386:accu+base)
`(("add____%edx,%eax"))) ; add %edx,%eax
(define (i386:accu+value v)
`(,(if (< (abs v) #x80) `("add____$i8,%eax" (#:immediate1 ,v))
`("add____$i32,%eax" (#:immediate ,v)))))
(define (i386:base+value v)
`(,(if (< (abs v) #x80) `("add____$i8,%edx" (#:immediate1 ,v))
`("add____$i32,%edx" (#:immediate ,v)))))
(define (i386:accu-base)
`(("sub____%edx,%eax"))) ; sub %edx,%eax
(define (i386:accu*base)
`(("mul____%edx"))) ; mul %edx
(define (i386:accu/base)
'(("mov____%edx,%ebx") ; mov %edx,%ebx
("xor____%edx,%edx") ; xor %edx,%edx
("idiv___%ebx"))) ; div %ebx
(define (i386:accu%base)
'(("mov____%edx,%ebx") ; mov %edx,%ebx
("xor____%edx,%edx") ; xor %edx,%edx
("idiv___%ebx") ; div %ebx
("mov____%edx,%eax"))) ; mov %edx,%eax
(define (i386:base->accu)
'(("mov____%edx,%eax"))) ; mov %edx,%eax
(define (i386:label->accu label)
`(("mov____$i32,%eax" (#:address ,label)))) ; mov $<n>,%eax
(define (i386:label->base label)
`(("mov____$i32,%edx" (#:address ,label)))) ; mov $<n>,%edx
(define (i386:label-mem->accu label)
`(("mov____0x32,%eax" (#:address ,label)))) ; mov 0x<n>,%eax
(define (i386:label-mem->base label)
`(("mov____0x32,%edx" (#:address ,label)))) ; mov 0x<n>,%edx
(define (i386:label-mem-add label v)
`(,(if (< (abs v) #x80) `("add____$i8,0x32" (#:address ,label) (#:immediate1 ,v))
`("add____$i32,0x32" (#:address ,label) (#:immediate ,v)))))
(define (i386:byte-base-mem->accu)
'(("add____%edx,%eax") ; add %edx,%eax
("movzbl_(%eax),%eax"))) ; movzbl (%eax),%eax
(define (i386:byte-mem->accu)
'(("movzbl_(%eax),%eax"))) ; movzbl (%eax),%eax
(define (i386:word-mem->accu)
'(("movzwl_(%eax),%eax")))
(define (i386:byte-mem->base)
'(("movzbl_(%edx),%edx"))) ; movzbl (%edx),%edx
(define (i386:base-mem->accu)
'(("mov____(%edx),%eax")))
(define (i386:mem->accu)
'(("mov____(%eax),%eax")))
(define (i386:mem->base)
'(("mov____(%edx),%edx")))
(define (i386:mem+n->accu n)
`(,(if (< (abs n) #x80) `("mov____0x8(%eax),%eax" (#:immediate1 ,n))
`("mov____0x32(%eax),%eax" (#:immediate ,n)))))
(define (i386:byte-mem+n->accu n)
`(,(if (< (abs n) #x80) `("movzbl_0x8(%eax),%eax" (#:immediate1 ,n))
`("movzbl_0x32(%eax),%eax" (#:immediate ,n)))))
(define (i386:word-mem+n->accu n)
`(,(if (< (abs n) #x80) `("movzwl_0x8(%eax),%eax" (#:immediate1 ,n))
`("movzwl_xb0x32(%eax),%eax" (#:immediate ,n)))))
(define (i386:base-mem+n->accu v)
(or v (error "invalid value: base-mem+n->accu: " v))
`(("add___%edx,%eax")
,(if (< (abs v) #x80) `("mov____0x8(%eax),%eax" (#:immediate1 ,v))
`("mov____0x32(%eax),%eax" (#:immediate ,v)))))
(define (i386:value->accu v)
(or v (error "invalid value: i386:value->accu: " v))
`(("mov____$i32,%eax" (#:immediate ,v)))) ; mov $<v>,%eax
(define (i386:value->accu-mem v)
`(("mov____$i32,(%eax)" (#:immediate ,v)))) ; movl $0x<v>,(%eax)
(define (i386:value->accu-mem+n n v)
(or v (error "invalid value: i386:value->accu-mem+n: " v))
`(,(if (< (abs v) #x80) `("mov____$i32,0x8(%eax)" (#:immediate1 ,n) (#:immediate ,v))
`("mov____$i32,0x32(%eax)" (#:immediate ,n) (#:immediate ,v)))))
(define (i386:base->accu-mem)
'(("mov____%edx,(%eax)"))) ; mov %edx,(%eax)
(define (i386:accu-mem->base-mem)
'(("mov____(%eax),%ecx")
("mov____%ecx,(%edx)")))
(define (i386:base-mem->accu-mem)
'(("mov____(%edx),%ecx") ; mov (%edx),%ecx
("mov____%ecx,(%eax)"))) ; mov %ecx,(%eax)
(define (i386:byte-base->accu-mem)
'(("mov____%dl,(%eax)"))) ; mov %dl,(%eax)
(define (i386:byte-base->accu-mem+n n)
(or n (error "invalid value: byte-base->accu-mem+n: " n))
`(,(if (< (abs n) #x80) `("mov____%dl,0x8(%eax)" (#:immediate1 ,n))
`("mov____%dl,0x32(%eax)" (#:immediate ,n)))))
(define (i386:value->base v)
(or v (error "invalid value: i386:value->base: " v))
`(("mov____$i32,%edx" (#:immediate ,v)))) ; mov $<v>,%edx
(define (i386:accu-mem-add v)
`(,(if (< (abs v) #x80) `("add____$i8,(%eax)" (#:immediate1 ,v))
`("add____$i32,(%eax)" (#:immediate ,v)))))
(define (i386:value->label label v)
(or v (error "invalid value: value->label: " v))
`(("mov____$i32,0x32" (#:address ,label)
(#:immediate ,v))))
(define (i386:call-label label n)
`((call32 (#:offset ,label))
("add____$i8,%esp" (#:immediate1 ,(* n 4)))))
(define (i386:call-accu n)
`(,@(i386:push-accu)
,@(i386:pop-accu)
("call___*%eax") ; call *%eax
("add____$i8,%esp" (#:immediate1 ,(* n 4))))) ; add $00,%esp
(define (i386:accu-zero?)
'(("test___%eax,%eax")))
(define (i386:accu-negate)
'(("sete___%al") ; sete %al
("movzbl_%al,%eax"))) ; movzbl %al,%eax
(define (i386:xor-accu v)
(or v (error "invalid value: i386:xor-accu: n: " v))
`(("xor___$i32,%eax" (#:immediate ,v)))) ;xor $0xff,%eax
(define (i386:xor-zf)
'(("lahf") ; lahf
("xor____$i8,%ah" (#:immediate1 #x40)) ; xor $0x40,%ah
("sahf"))) ; sahf
(define (i386:accu-cmp-value v)
`(,(if (< (abs v) #x80) `("cmp____$i8,%eax" (#:immediate1 ,v))
`("cmp____$i32,%eax" (#:immediate ,v)))))
(define (i386:accu-test)
'(("test___%eax,%eax"))) ; test %eax,%eax
(define (i386:jump label)
`(("jmp32 " (#:offset ,label))))
(define (i386:jump-z label)
`(("je32 " (#:offset ,label)))) ; jz . + <n>
(define (i386:jump-byte-z label)
`(("test___%al,%al") ; test %al,%al
("je32 " (#:offset ,label)))) ; je <n>
;; signed
(define (i386:jump-g label)
`(("jg32 " (#:offset ,label))))
(define (i386:jump-ge label)
`(("jge32 " (#:offset ,label))))
(define (i386:jump-l label)
`(("jl32 " (#:offset ,label))))
(define (i386:jump-le label)
`(("jle32 " (#:offset ,label))))
(define (i386:g?->accu)
'(("setg___%al")
("movzbl_%al,%eax")))
(define (i386:ge?->accu)
'(("setge__%al")
("movzbl_%al,%eax")))
(define (i386:l?->accu)
'(("setl___%al")
("movzbl_%al,%eax")))
(define (i386:le?->accu)
'(("setle__%al")
("movzbl_%al,%eax")))
;; unsigned
(define (i386:jump-a label)
`(("ja32 " (#:offset ,label))))
(define (i386:jump-ae label)
`(("jae32 " (#:offset ,label))))
(define (i386:jump-b label)
`(("jb32 " (#:offset ,label))))
(define (i386:jump-be label)
`(("jbe32 " (#:offset ,label))))
(define (i386:a?->accu)
'(("seta___%al")
("movzbl_%al,%eax")))
(define (i386:ae?->accu)
'(("setae__%al")
("movzbl_%al,%eax")))
(define (i386:b?->accu)
'(("setb___%al")
("movzbl_%al,%eax")))
(define (i386:be?->accu)
'(("setbe__%al")
("movzbl_%al,%eax")))
(define (i386:jump-nz label)
`(("jne32 " (#:offset ,label)))) ; jnz . + <n>
(define (i386:byte-test-base)
'(("cmp____%al,%dl"))) ; cmp %al,%dl
(define (i386:test-base)
(("cmp____%edx,%eax"))) ; cmp %edx,%eax
(define (i386:byte-sub-base)
'(("sub____%dl,%al"))) ; sub %dl,%al
(define (i386:byte-base-sub)
`(("sub____%al,%dl"))) ; sub %al,%dl
(define (i386:sub-base)
`(("sub____%edx,%eax"))) ; sub %edx,%eax
(define (i386:base-sub)
`(("sub____%eax,%edx"))) ; sub %eax,%edx
(define (i386:nz->accu)
'(("setne__%al") ; setne %al
("movzbl_%al,%eax"))) ; movzbl %al,%eax
(define (i386:z->accu)
'(("sete___%al") ; sete %al
("movzbl_%al,%eax"))) ; movzbl %al,%eax
(define (i386:accu<->stack)
'(("xchg___%eax,(%esp)"))) ; xchg %eax,(%esp)
(define (i386:byte-accu)
'(("movzbl_%al,%eax")))
(define (i386:signed-byte-accu)
'(("movsbl_%al,%eax")))
(define (i386:word-accu)
'(("movzwl_%ax,%eax")))
(define (i386:signed-word-accu)
'(("movswl_%ax,%eax")))