2007-10-25 16:27:34 -04:00
|
|
|
;;; Ikarus Scheme -- A compiler for R6RS Scheme.
|
2008-01-29 00:34:34 -05:00
|
|
|
;;; Copyright (C) 2006,2007,2008 Abdulaziz Ghuloum
|
2007-10-25 16:27:34 -04:00
|
|
|
;;;
|
|
|
|
;;; This program is free software: you can redistribute it and/or modify
|
|
|
|
;;; it under the terms of the GNU General Public License version 3 as
|
|
|
|
;;; published by the Free Software Foundation.
|
|
|
|
;;;
|
|
|
|
;;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2006-11-23 19:44:29 -05:00
|
|
|
|
|
|
|
|
2008-02-14 17:45:15 -05:00
|
|
|
(library (ikarus.intel-assembler)
|
2008-01-02 07:01:45 -05:00
|
|
|
(export instruction-size assemble-sources code-entry-adjustment)
|
2007-05-06 18:24:25 -04:00
|
|
|
(import
|
|
|
|
(ikarus)
|
2007-10-12 00:33:19 -04:00
|
|
|
(rnrs bytevectors)
|
2008-02-14 17:45:15 -05:00
|
|
|
(except (ikarus.code-objects) procedure-annotation)
|
2007-05-06 18:24:25 -04:00
|
|
|
(ikarus system $pairs))
|
2006-11-23 19:44:29 -05:00
|
|
|
|
2008-01-03 02:07:17 -05:00
|
|
|
|
|
|
|
(module (wordsize)
|
|
|
|
(include "ikarus.config.ss"))
|
|
|
|
|
2006-11-23 19:44:29 -05:00
|
|
|
(define fold
|
|
|
|
(lambda (f init ls)
|
|
|
|
(cond
|
|
|
|
[(null? ls) init]
|
|
|
|
[else
|
|
|
|
(f (car ls) (fold f init (cdr ls)))])))
|
|
|
|
|
|
|
|
(define convert-instructions
|
|
|
|
(lambda (ls)
|
|
|
|
(fold convert-instruction '() ls)))
|
|
|
|
|
|
|
|
(define register-mapping
|
2008-01-01 04:24:36 -05:00
|
|
|
;;; reg cls idx REX.R
|
|
|
|
'([%eax 32 0 #f]
|
|
|
|
[%ecx 32 1 #f]
|
|
|
|
[%edx 32 2 #f]
|
|
|
|
[%ebx 32 3 #f]
|
|
|
|
[%esp 32 4 #f]
|
|
|
|
[%ebp 32 5 #f]
|
|
|
|
[%esi 32 6 #f]
|
|
|
|
[%edi 32 7 #f]
|
|
|
|
[%r8 32 0 #t]
|
|
|
|
[%r9 32 1 #t]
|
|
|
|
[%r10 32 2 #t]
|
|
|
|
[%r11 32 3 #t]
|
|
|
|
[%r12 32 4 #t]
|
|
|
|
[%r13 32 5 #t]
|
|
|
|
[%r14 32 6 #t]
|
|
|
|
[%r15 32 7 #t]
|
|
|
|
[%al 8 0 #f]
|
|
|
|
[%cl 8 1 #f]
|
|
|
|
[%dl 8 2 #f]
|
|
|
|
[%bl 8 3 #f]
|
|
|
|
[%ah 8 4 #f]
|
|
|
|
[%ch 8 5 #f]
|
|
|
|
[%dh 8 6 #f]
|
|
|
|
[%bh 8 7 #f]
|
|
|
|
[/0 0 0 #f]
|
|
|
|
[/1 0 1 #f]
|
|
|
|
[/2 0 2 #f]
|
|
|
|
[/3 0 3 #f]
|
|
|
|
[/4 0 4 #f]
|
|
|
|
[/5 0 5 #f]
|
|
|
|
[/6 0 6 #f]
|
|
|
|
[/7 0 7 #f]
|
|
|
|
[xmm0 xmm 0 #f]
|
|
|
|
[xmm1 xmm 1 #f]
|
|
|
|
[xmm2 xmm 2 #f]
|
|
|
|
[xmm3 xmm 3 #f]
|
|
|
|
[xmm4 xmm 4 #f]
|
|
|
|
[xmm5 xmm 5 #f]
|
|
|
|
[xmm6 xmm 6 #f]
|
|
|
|
[xmm7 xmm 7 #f]
|
2008-08-09 08:47:44 -04:00
|
|
|
[%r8l 8 0 #t]
|
|
|
|
[%r9l 8 1 #t]
|
|
|
|
[%r10l 8 2 #t]
|
|
|
|
[%r11l 8 3 #t]
|
|
|
|
[%r12l 8 4 #t]
|
|
|
|
[%r13l 8 5 #t]
|
|
|
|
[%r14l 8 6 #t]
|
|
|
|
[%r15l 8 7 #t]
|
|
|
|
|
2006-11-23 19:44:29 -05:00
|
|
|
))
|
|
|
|
|
|
|
|
(define register-index
|
|
|
|
(lambda (x)
|
|
|
|
(cond
|
|
|
|
[(assq x register-mapping) => caddr]
|
2007-12-15 08:22:49 -05:00
|
|
|
[else (die 'register-index "not a register" x)])))
|
2006-11-23 19:44:29 -05:00
|
|
|
|
|
|
|
(define reg32?
|
|
|
|
(lambda (x)
|
|
|
|
(cond
|
|
|
|
[(assq x register-mapping) =>
|
2007-06-15 01:53:34 -04:00
|
|
|
(lambda (x) (eqv? (cadr x) 32))]
|
2006-11-23 19:44:29 -05:00
|
|
|
[else #f])))
|
|
|
|
|
|
|
|
(define reg8?
|
|
|
|
(lambda (x)
|
|
|
|
(cond
|
|
|
|
[(assq x register-mapping) =>
|
2007-06-15 01:53:34 -04:00
|
|
|
(lambda (x) (eqv? (cadr x) 8))]
|
|
|
|
[else #f])))
|
|
|
|
|
|
|
|
(define xmmreg?
|
|
|
|
(lambda (x)
|
|
|
|
(cond
|
|
|
|
[(assq x register-mapping) =>
|
|
|
|
(lambda (x) (eqv? (cadr x) 'xmm))]
|
2006-11-23 19:44:29 -05:00
|
|
|
[else #f])))
|
|
|
|
|
|
|
|
(define reg?
|
|
|
|
(lambda (x)
|
|
|
|
(assq x register-mapping)))
|
|
|
|
|
2008-01-01 04:24:36 -05:00
|
|
|
(define reg-requires-REX?
|
|
|
|
(lambda (x)
|
|
|
|
(cond
|
|
|
|
[(assq x register-mapping) => cadddr]
|
|
|
|
[else (error 'reg-required-REX? "not a reg" x)])))
|
|
|
|
|
2006-11-23 19:44:29 -05:00
|
|
|
(define-syntax with-args
|
|
|
|
(syntax-rules (lambda)
|
|
|
|
[(_ x (lambda (a0 a1) b b* ...))
|
|
|
|
(let ([t x])
|
|
|
|
(if (pair? t)
|
|
|
|
(let ([t ($cdr t)])
|
|
|
|
(if (pair? t)
|
|
|
|
(let ([a0 ($car t)] [t ($cdr t)])
|
|
|
|
(if (pair? t)
|
|
|
|
(let ([a1 ($car t)])
|
|
|
|
(if (null? ($cdr t))
|
|
|
|
(let () b b* ...)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'with-args "too many args")))
|
|
|
|
(die 'with-args "too few args")))
|
|
|
|
(die 'with-args "too few args")))
|
|
|
|
(die 'with-args "too few args")))]))
|
2006-11-23 19:44:29 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(define-syntax byte
|
|
|
|
(syntax-rules ()
|
2008-01-04 03:49:27 -05:00
|
|
|
[(_ x)
|
|
|
|
(let ([t x])
|
|
|
|
(if (integer? t)
|
|
|
|
(bitwise-and t 255)
|
|
|
|
(error 'byte "invalid" t '(byte x))))]))
|
2006-11-23 19:44:29 -05:00
|
|
|
|
|
|
|
|
|
|
|
(define word
|
|
|
|
(lambda (x)
|
|
|
|
(cons 'word x)))
|
|
|
|
|
|
|
|
(define reloc-word
|
|
|
|
(lambda (x)
|
|
|
|
(cons 'reloc-word x)))
|
|
|
|
|
|
|
|
(define reloc-word+
|
|
|
|
(lambda (x d)
|
2007-09-09 23:41:12 -04:00
|
|
|
(cons* 'reloc-word+ x d)))
|
2006-11-23 19:44:29 -05:00
|
|
|
|
|
|
|
(define byte?
|
|
|
|
(lambda (x)
|
|
|
|
(and (fixnum? x)
|
|
|
|
(fx<= x 127)
|
|
|
|
(fx<= -128 x))))
|
|
|
|
|
|
|
|
(define mem?
|
|
|
|
(lambda (x)
|
2007-01-09 01:24:07 -05:00
|
|
|
(and (pair? x)
|
2007-02-25 21:29:28 -05:00
|
|
|
(eq? (car x) 'disp))))
|
2006-11-23 19:44:29 -05:00
|
|
|
|
|
|
|
(define small-disp?
|
|
|
|
(lambda (x)
|
|
|
|
(and (mem? x)
|
|
|
|
(byte? (cadr x)))))
|
|
|
|
|
|
|
|
|
|
|
|
(define CODE
|
|
|
|
(lambda (n ac)
|
|
|
|
(cons (byte n) ac)))
|
|
|
|
|
|
|
|
(define CODE+r
|
|
|
|
(lambda (n r ac)
|
|
|
|
(cons (byte (fxlogor n (register-index r))) ac)))
|
|
|
|
|
|
|
|
(define ModRM
|
|
|
|
(lambda (mod reg r/m ac)
|
|
|
|
(cons (byte (fxlogor
|
|
|
|
(register-index r/m)
|
|
|
|
(fxlogor
|
|
|
|
(fxsll (register-index reg) 3)
|
|
|
|
(fxsll mod 6))))
|
|
|
|
(if (and (not (fx= mod 3)) (eq? r/m '%esp))
|
|
|
|
(cons (byte #x24) ac)
|
|
|
|
ac))))
|
2008-01-04 03:49:27 -05:00
|
|
|
(define IMM32
|
|
|
|
(lambda (n ac)
|
|
|
|
(cond
|
|
|
|
[(= wordsize 4) (IMM n ac)]
|
|
|
|
[(imm32? n)
|
|
|
|
(cons*
|
|
|
|
(byte n)
|
|
|
|
(byte (sra n 8))
|
|
|
|
(byte (sra n 16))
|
|
|
|
(byte (sra n 24))
|
|
|
|
ac)]
|
2008-04-08 02:22:26 -04:00
|
|
|
[(label? n)
|
|
|
|
(cons (cons 'relative (label-name n)) ac)]
|
2008-01-04 03:49:27 -05:00
|
|
|
[else (die 'IMM32 "invalid" n)])))
|
2006-11-23 19:44:29 -05:00
|
|
|
|
2008-01-03 23:03:22 -05:00
|
|
|
(define IMM
|
2006-11-23 19:44:29 -05:00
|
|
|
(lambda (n ac)
|
|
|
|
(cond
|
|
|
|
[(int? n)
|
2008-01-03 23:03:22 -05:00
|
|
|
(case wordsize
|
|
|
|
[(4)
|
|
|
|
(cons*
|
|
|
|
(byte n)
|
|
|
|
(byte (sra n 8))
|
|
|
|
(byte (sra n 16))
|
|
|
|
(byte (sra n 24))
|
|
|
|
ac)]
|
|
|
|
[else
|
|
|
|
(cons*
|
|
|
|
(byte n)
|
|
|
|
(byte (sra n 8))
|
|
|
|
(byte (sra n 16))
|
|
|
|
(byte (sra n 24))
|
|
|
|
(byte (sra n 32))
|
|
|
|
(byte (sra n 40))
|
|
|
|
(byte (sra n 48))
|
|
|
|
(byte (sra n 56))
|
|
|
|
ac)])]
|
2006-11-23 19:44:29 -05:00
|
|
|
[(obj? n)
|
|
|
|
(let ([v (cadr n)])
|
|
|
|
(if (immediate? v)
|
|
|
|
(cons (word v) ac)
|
|
|
|
(cons (reloc-word v) ac)))]
|
|
|
|
[(obj+? n)
|
|
|
|
(let ([v (cadr n)] [d (caddr n)])
|
|
|
|
(cons (reloc-word+ v d) ac))]
|
|
|
|
[(label-address? n)
|
|
|
|
(cons (cons 'label-addr (label-name n)) ac)]
|
|
|
|
[(foreign? n)
|
|
|
|
(cons (cons 'foreign-label (label-name n)) ac)]
|
2008-01-02 23:22:55 -05:00
|
|
|
[(label? n)
|
2007-12-31 04:00:46 -05:00
|
|
|
(cons (cons 'relative (label-name n)) ac)]
|
2008-01-03 23:03:22 -05:00
|
|
|
[else (die 'IMM "invalid" n)])))
|
2006-11-23 19:44:29 -05:00
|
|
|
|
|
|
|
|
|
|
|
(define IMM8
|
|
|
|
(lambda (n ac)
|
|
|
|
(cond
|
|
|
|
[(int? n)
|
2007-09-09 23:41:12 -04:00
|
|
|
(cons* (byte n) ac)]
|
2007-12-15 08:22:49 -05:00
|
|
|
[else (die 'IMM8 "invalid" n)])))
|
2006-11-23 19:44:29 -05:00
|
|
|
|
|
|
|
|
|
|
|
(define imm?
|
|
|
|
(lambda (x)
|
|
|
|
(or (int? x)
|
|
|
|
(obj? x)
|
|
|
|
(obj+? x)
|
|
|
|
(label-address? x)
|
2007-12-31 04:00:46 -05:00
|
|
|
(foreign? x)
|
|
|
|
(label? x))))
|
2006-11-23 19:44:29 -05:00
|
|
|
|
|
|
|
(define foreign?
|
|
|
|
(lambda (x)
|
|
|
|
(and (pair? x) (eq? (car x) 'foreign-label))))
|
|
|
|
|
|
|
|
|
|
|
|
(define imm8?
|
|
|
|
(lambda (x)
|
2007-01-09 01:44:00 -05:00
|
|
|
(and (int? x) (byte? x))))
|
2006-11-23 19:44:29 -05:00
|
|
|
|
|
|
|
(define label?
|
|
|
|
(lambda (x)
|
2007-12-31 04:00:46 -05:00
|
|
|
(and (pair? x) (eq? (car x) 'label))))
|
2006-11-23 19:44:29 -05:00
|
|
|
|
|
|
|
(define label-address?
|
|
|
|
(lambda (x)
|
2007-12-31 04:00:46 -05:00
|
|
|
(and (pair? x) (eq? (car x) 'label-address))))
|
2006-11-23 19:44:29 -05:00
|
|
|
|
|
|
|
(define label-name
|
|
|
|
(lambda (x) (cadr x)))
|
|
|
|
|
2007-02-05 14:19:03 -05:00
|
|
|
(define int? integer?)
|
2006-11-23 19:44:29 -05:00
|
|
|
|
|
|
|
(define obj?
|
|
|
|
(lambda (x)
|
|
|
|
(and (pair? x) (eq? (car x) 'obj))))
|
|
|
|
|
|
|
|
(define obj+?
|
|
|
|
(lambda (x)
|
|
|
|
(and (pair? x) (eq? (car x) 'obj+))))
|
|
|
|
|
|
|
|
(define CODErri
|
|
|
|
(lambda (c d s i ac)
|
|
|
|
(cond
|
|
|
|
[(imm8? i)
|
|
|
|
(CODE c (ModRM 1 d s (IMM8 i ac)))]
|
|
|
|
[(imm? i)
|
2008-01-03 23:03:22 -05:00
|
|
|
(CODE c (ModRM 2 d s (IMM i ac)))]
|
2007-12-15 08:22:49 -05:00
|
|
|
[else (die 'CODErri "invalid i" i)])))
|
2006-11-23 19:44:29 -05:00
|
|
|
|
|
|
|
(define CODErr
|
2007-12-31 02:42:53 -05:00
|
|
|
(lambda (c r1 r2 ac)
|
|
|
|
(CODE c (ModRM 3 r1 r2 ac))))
|
2006-11-23 19:44:29 -05:00
|
|
|
|
|
|
|
(define RegReg
|
|
|
|
(lambda (r1 r2 r3 ac)
|
|
|
|
(cond
|
2007-12-15 08:22:49 -05:00
|
|
|
[(eq? r3 '%esp) (die 'assembler "BUG: invalid src %esp")]
|
|
|
|
[(eq? r1 '%ebp) (die 'assembler "BUG: invalid src %ebp")]
|
2006-11-23 19:44:29 -05:00
|
|
|
[else
|
2007-09-09 23:41:12 -04:00
|
|
|
(cons*
|
2006-11-23 19:44:29 -05:00
|
|
|
(byte (fxlogor 4 (fxsll (register-index r1) 3)))
|
2008-01-02 23:22:55 -05:00
|
|
|
(byte (fxlogor (register-index r2)
|
2006-11-23 19:44:29 -05:00
|
|
|
(fxsll (register-index r3) 3)))
|
|
|
|
ac)])))
|
|
|
|
|
2008-01-03 23:03:22 -05:00
|
|
|
(define IMM*2
|
2006-11-23 19:44:29 -05:00
|
|
|
(lambda (i1 i2 ac)
|
|
|
|
(cond
|
|
|
|
[(and (int? i1) (obj? i2))
|
2007-01-09 01:44:00 -05:00
|
|
|
(let ([d i1] [v (cadr i2)])
|
2006-11-23 19:44:29 -05:00
|
|
|
(cons (reloc-word+ v d) ac))]
|
2008-01-03 23:03:22 -05:00
|
|
|
[(and (int? i2) (obj? i1)) (IMM*2 i2 i1 ac)]
|
2008-01-19 09:47:15 -05:00
|
|
|
[(and (int? i1) (int? i2))
|
|
|
|
(IMM (bitwise-and (+ i1 i2)
|
|
|
|
(- (expt 2 (* wordsize 8)) 1))
|
|
|
|
ac)]
|
2008-01-03 23:03:22 -05:00
|
|
|
[else (die 'assemble "invalid IMM*2" i1 i2)])))
|
2006-11-23 19:44:29 -05:00
|
|
|
|
2007-12-31 02:42:53 -05:00
|
|
|
(define (SIB s i b ac)
|
|
|
|
(cons (byte
|
|
|
|
(fxlogor
|
|
|
|
(register-index b)
|
|
|
|
(fxlogor
|
|
|
|
(fxsll (register-index i) 3)
|
|
|
|
(fxsll s 6))))
|
|
|
|
ac))
|
|
|
|
|
2008-01-03 23:03:22 -05:00
|
|
|
(define (imm32? x)
|
|
|
|
(case wordsize
|
|
|
|
[(4) (imm? x)]
|
2008-01-04 03:49:27 -05:00
|
|
|
[(8)
|
|
|
|
(and (integer? x)
|
2008-01-03 23:03:22 -05:00
|
|
|
(<= (- (expt 2 31)) x (- (expt 2 31) 1)))]
|
|
|
|
[else (error 'imm32? "invalid wordsize" wordsize)]))
|
2007-02-13 17:24:00 -05:00
|
|
|
|
2006-11-23 19:44:29 -05:00
|
|
|
(define *cogen* (gensym "*cogen*"))
|
|
|
|
|
|
|
|
(define-syntax add-instruction
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ (name instr ac args ...) b b* ...)
|
|
|
|
(putprop 'name *cogen*
|
|
|
|
(cons (length '(args ...))
|
|
|
|
(lambda (instr ac args ...) b b* ...)))]))
|
|
|
|
|
|
|
|
(define-syntax add-instructions
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ instr ac [(name* arg** ...) b* b** ...] ...)
|
|
|
|
(begin
|
|
|
|
(add-instruction (name* instr ac arg** ...) b* b** ...) ...)]))
|
|
|
|
|
|
|
|
(define (convert-instruction a ac)
|
|
|
|
(cond
|
|
|
|
[(getprop (car a) *cogen*) =>
|
|
|
|
(lambda (p)
|
|
|
|
(let ([n (car p)] [proc (cdr p)] [args (cdr a)])
|
|
|
|
(cond
|
|
|
|
[(fx= n 2)
|
|
|
|
(if (fx= (length args) 2)
|
|
|
|
(proc a ac (car args) (cadr args))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'convert-instruction "incorrect args" a))]
|
2006-11-23 19:44:29 -05:00
|
|
|
[(fx= n 1)
|
|
|
|
(if (fx= (length args) 1)
|
|
|
|
(proc a ac (car args))
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'convert-instruction "incorrect args" a))]
|
2006-11-23 19:44:29 -05:00
|
|
|
[(fx= n 0)
|
|
|
|
(if (fx= (length args) 0)
|
|
|
|
(proc a ac)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'convert-instruction "incorrect args" a))]
|
2006-11-23 19:44:29 -05:00
|
|
|
[else
|
|
|
|
(if (fx= (length args) n)
|
|
|
|
(apply proc a ac args)
|
2007-12-15 08:22:49 -05:00
|
|
|
(die 'convert-instruction "incorrect args" a))])))]
|
2008-01-02 07:01:45 -05:00
|
|
|
[(eq? (car a) 'seq)
|
|
|
|
(fold convert-instruction ac (cdr a))]
|
2007-12-15 08:22:49 -05:00
|
|
|
[else (die 'convert-instruction "unknown instruction" a)]))
|
2006-11-23 19:44:29 -05:00
|
|
|
|
2007-12-31 05:34:20 -05:00
|
|
|
(define (RM /d dst ac)
|
|
|
|
(cond
|
|
|
|
[(mem? dst)
|
|
|
|
(with-args dst
|
|
|
|
(lambda (a0 a1)
|
|
|
|
(cond
|
|
|
|
[(and (imm8? a0) (reg32? a1))
|
|
|
|
(ModRM 1 /d a1 (IMM8 a0 ac))]
|
|
|
|
[(and (imm? a0) (reg32? a1))
|
2008-04-09 05:34:36 -04:00
|
|
|
(ModRM 2 /d a1 (IMM32 a0 ac))]
|
2007-12-31 05:34:20 -05:00
|
|
|
[(and (imm8? a1) (reg32? a0))
|
|
|
|
(ModRM 1 /d a0 (IMM8 a1 ac))]
|
|
|
|
[(and (imm? a1) (reg32? a0))
|
2008-04-09 05:34:36 -04:00
|
|
|
(ModRM 2 /d a0 (IMM32 a1 ac))]
|
2007-12-31 05:34:20 -05:00
|
|
|
[(and (reg32? a0) (reg32? a1))
|
|
|
|
(RegReg /d a0 a1 ac)]
|
|
|
|
[(and (imm? a0) (imm? a1))
|
2008-01-03 23:03:22 -05:00
|
|
|
(ModRM 0 /d '/5 (IMM*2 a0 a1 ac))]
|
2007-12-31 05:34:20 -05:00
|
|
|
[else (die 'RM "unhandled" a0 a1)])))]
|
|
|
|
[(reg? dst) (ModRM 3 /d dst ac)]
|
|
|
|
[else (die 'RM "unhandled" dst)]))
|
|
|
|
|
2006-11-23 19:44:29 -05:00
|
|
|
(module ()
|
|
|
|
(define who 'assembler)
|
|
|
|
|
2008-01-04 03:49:27 -05:00
|
|
|
|
|
|
|
(define (REX.R bits ac)
|
|
|
|
(when (eqv? wordsize 4)
|
|
|
|
(error 'ikarus "BUG: REX.R invalid in 32-bit mode"))
|
|
|
|
(cons (fxlogor #b01001000 bits) ac))
|
|
|
|
|
|
|
|
(define (REX+r r ac)
|
|
|
|
(cond
|
|
|
|
[(eqv? wordsize 4) ac]
|
|
|
|
[(reg-requires-REX? r) (REX.R #b001 ac)]
|
|
|
|
[else (REX.R #b000 ac)]))
|
|
|
|
|
2008-01-01 04:24:36 -05:00
|
|
|
(define (REX+RM r rm ac)
|
|
|
|
(define (C n ac)
|
|
|
|
ac)
|
2008-01-04 03:49:27 -05:00
|
|
|
;;;(printf "CASE ~s\n" n)
|
|
|
|
;;;(let f ([ac ac] [i 30])
|
|
|
|
;;; (unless (or (null? ac) (= i 0))
|
|
|
|
;;; (if (number? (car ac))
|
|
|
|
;;; (printf " #x~x" (car ac))
|
|
|
|
;;; (printf " ~s" (car ac)))
|
|
|
|
;;; (f (cdr ac) (- i 1))))
|
|
|
|
;;;(newline)
|
|
|
|
;;;ac)
|
2008-01-01 04:24:36 -05:00
|
|
|
(cond
|
2008-01-04 03:49:27 -05:00
|
|
|
[(eqv? wordsize 4) ac]
|
2008-01-01 04:24:36 -05:00
|
|
|
[(mem? rm)
|
|
|
|
(if (reg-requires-REX? r)
|
|
|
|
(with-args rm
|
|
|
|
(lambda (a0 a1)
|
|
|
|
(cond
|
|
|
|
[(and (imm? a0) (reg32? a1))
|
|
|
|
(if (reg-requires-REX? a1)
|
2008-04-09 03:05:19 -04:00
|
|
|
(REX.R #b101 ac)
|
|
|
|
(REX.R #b100 ac))]
|
2008-01-01 04:24:36 -05:00
|
|
|
[(and (imm? a1) (reg32? a0))
|
|
|
|
(if (reg-requires-REX? a0)
|
2008-04-09 03:05:19 -04:00
|
|
|
(REX.R #b101 ac)
|
|
|
|
(REX.R #b100 ac))]
|
2008-01-01 04:24:36 -05:00
|
|
|
[(and (reg32? a0) (reg32? a1))
|
2008-08-09 08:47:44 -04:00
|
|
|
(if (reg-requires-REX? a0)
|
|
|
|
(if (reg-requires-REX? a1)
|
|
|
|
(REX.R #b111 ac)
|
|
|
|
(REX.R #b110 ac))
|
|
|
|
(if (reg-requires-REX? a1)
|
|
|
|
(REX.R #b101 ac)
|
|
|
|
(REX.R #b100 ac)))]
|
2008-01-01 04:24:36 -05:00
|
|
|
[(and (imm? a0) (imm? a1))
|
2008-01-04 03:49:27 -05:00
|
|
|
(error 'REC+RM "not here 4")
|
2008-01-01 04:24:36 -05:00
|
|
|
(error 'REX+RM "unhandledb" a1)]
|
|
|
|
[else (die 'REX+RM "unhandled" a0 a1)])))
|
|
|
|
(with-args rm
|
|
|
|
(lambda (a0 a1)
|
|
|
|
(cond
|
|
|
|
[(and (imm? a0) (reg32? a1))
|
2008-04-07 10:20:05 -04:00
|
|
|
(if (reg-requires-REX? a1)
|
|
|
|
(REX.R #b001 ac)
|
|
|
|
(REX.R 0 ac))]
|
2008-01-01 04:24:36 -05:00
|
|
|
[(and (imm? a1) (reg32? a0))
|
|
|
|
(if (reg-requires-REX? a0)
|
2008-04-07 10:20:05 -04:00
|
|
|
(REX.R #b001 ac)
|
|
|
|
(REX.R 0 ac))]
|
2008-01-01 04:24:36 -05:00
|
|
|
[(and (reg32? a0) (reg32? a1))
|
|
|
|
(if (reg-requires-REX? a0)
|
|
|
|
(if (reg-requires-REX? a1)
|
|
|
|
(error 'REX+RM "unhandled x1" a0 a1)
|
2008-04-09 03:05:19 -04:00
|
|
|
(REX.R #b010 ac))
|
2008-01-01 04:24:36 -05:00
|
|
|
(if (reg-requires-REX? a1)
|
|
|
|
(error 'REX+RM "unhandled x3" a0 a1)
|
2008-04-07 10:20:05 -04:00
|
|
|
(REX.R 0 ac)))]
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (imm? a0) (imm? a1))
|
2008-04-07 10:20:05 -04:00
|
|
|
;(error 'REC+RM "not here 8")
|
|
|
|
(REX.R 0 ac)]
|
2008-01-01 04:24:36 -05:00
|
|
|
[else (die 'REX+RM "unhandled" a0 a1)]))))]
|
|
|
|
[(reg? rm)
|
2008-01-04 03:49:27 -05:00
|
|
|
(let* ([bits 0]
|
|
|
|
[bits
|
|
|
|
(if (reg-requires-REX? r)
|
|
|
|
(fxlogor bits #b100)
|
|
|
|
bits)]
|
|
|
|
[bits
|
|
|
|
(if (reg-requires-REX? rm)
|
|
|
|
(fxlogor bits #b001)
|
|
|
|
bits)])
|
|
|
|
(REX.R bits ac))]
|
2008-01-01 04:24:36 -05:00
|
|
|
[else (die 'REX+RM "unhandled" rm)]))
|
|
|
|
|
2008-01-04 03:49:27 -05:00
|
|
|
(define (C c ac)
|
|
|
|
(case wordsize
|
|
|
|
[(4) (CODE c ac)]
|
|
|
|
[else (REX.R 0 (CODE c ac))]))
|
2008-01-01 04:24:36 -05:00
|
|
|
|
2008-07-18 04:35:13 -04:00
|
|
|
(define trace-ac
|
|
|
|
(let ([cache '()])
|
|
|
|
(lambda (ac1 what ac2)
|
|
|
|
(when (assembler-output)
|
|
|
|
(let ([diff
|
|
|
|
(let f ([ls ac2])
|
|
|
|
(cond
|
|
|
|
[(eq? ls ac1) '()]
|
|
|
|
[else (cons (car ls) (f (cdr ls)))]))])
|
|
|
|
(unless (member diff cache)
|
|
|
|
(set! cache (cons diff cache))
|
|
|
|
(printf "~s => ~s\n" what diff))))
|
|
|
|
ac2)))
|
2008-04-07 10:20:05 -04:00
|
|
|
|
2007-12-31 04:00:46 -05:00
|
|
|
(define (CR c r ac)
|
2008-01-01 04:24:36 -05:00
|
|
|
(REX+r r (CODE+r c r ac)))
|
2007-12-31 05:34:20 -05:00
|
|
|
(define (CR* c r rm ac)
|
2008-01-04 03:49:27 -05:00
|
|
|
(REX+RM r rm (CODE c (RM r rm ac))))
|
2008-04-09 03:05:19 -04:00
|
|
|
(define (CR*-no-rex c r rm ac)
|
|
|
|
(CODE c (RM r rm ac)))
|
2007-12-31 05:34:20 -05:00
|
|
|
(define (CCR* c0 c1 r rm ac)
|
2008-04-09 03:05:19 -04:00
|
|
|
;(CODE c0 (CODE c1 (RM r rm ac))))
|
|
|
|
(REX+RM r rm (CODE c0 (CODE c1 (RM r rm ac)))))
|
2007-12-31 02:42:53 -05:00
|
|
|
(define (CCR c0 c1 r ac)
|
2008-07-19 17:41:06 -04:00
|
|
|
;(CODE c0 (CODE+r c1 r ac)))
|
|
|
|
(REX+r r (CODE c0 (CODE+r c1 r ac))))
|
2008-01-01 04:24:36 -05:00
|
|
|
(define (CCCR* c0 c1 c2 r rm ac)
|
2008-07-18 04:35:13 -04:00
|
|
|
;(CODE c0 (CODE c1 (CODE c2 (RM r rm ac)))))
|
|
|
|
(REX+RM r rm (CODE c0 (CODE c1 (CODE c2 (RM r rm ac))))))
|
2008-01-01 04:24:36 -05:00
|
|
|
|
|
|
|
|
2007-12-31 04:00:46 -05:00
|
|
|
(define (CCI32 c0 c1 i32 ac)
|
2008-04-08 02:22:26 -04:00
|
|
|
(CODE c0 (CODE c1 (IMM32 i32 ac))))
|
2007-12-31 03:02:12 -05:00
|
|
|
|
2008-04-09 05:34:36 -04:00
|
|
|
|
2008-01-04 03:49:27 -05:00
|
|
|
(define (dotrace orig ls)
|
|
|
|
(printf "TRACE: ~s\n"
|
2008-04-08 02:22:26 -04:00
|
|
|
(let f ([ls ls])
|
2008-01-04 03:49:27 -05:00
|
|
|
(if (eq? ls orig)
|
|
|
|
'()
|
|
|
|
(cons (car ls) (f (cdr ls))))))
|
|
|
|
ls)
|
|
|
|
|
2006-11-23 19:44:29 -05:00
|
|
|
(add-instructions instr ac
|
2007-12-31 02:42:53 -05:00
|
|
|
[(ret) (CODE #xC3 ac)]
|
2008-07-18 04:35:13 -04:00
|
|
|
[(cltd) (C #x99 ac)]
|
2007-12-31 02:42:53 -05:00
|
|
|
[(movl src dst)
|
|
|
|
(cond
|
2008-04-07 10:20:05 -04:00
|
|
|
[(and (imm? src) (reg? dst)) (CR #xB8 dst (IMM src ac))]
|
|
|
|
[(and (imm? src) (mem? dst)) (CR* #xC7 '/0 dst (IMM32 src ac))]
|
|
|
|
[(and (reg? src) (reg? dst)) (CR* #x89 src dst ac)]
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (reg? src) (mem? dst)) (CR* #x89 src dst ac)]
|
|
|
|
[(and (mem? src) (reg? dst)) (CR* #x8B dst src ac)]
|
2008-07-22 01:07:31 -04:00
|
|
|
[else (die who "invalid" instr)])]
|
2008-04-09 03:05:19 -04:00
|
|
|
[(mov32 src dst)
|
|
|
|
;;; FIXME
|
|
|
|
(cond
|
|
|
|
[(and (imm? src) (reg? dst))
|
|
|
|
(error 'mov32 "here1")
|
|
|
|
(CR #xB8 dst (IMM32 src ac))]
|
|
|
|
[(and (imm? src) (mem? dst)) (CR*-no-rex #xC7 '/0 dst (IMM32 src ac))]
|
|
|
|
[(and (reg? src) (reg? dst))
|
|
|
|
(error 'mov32 "here3")
|
|
|
|
(CR* #x89 src dst ac)]
|
|
|
|
[(and (reg? src) (mem? dst)) (CR*-no-rex #x89 src dst ac)]
|
|
|
|
[(and (mem? src) (reg? dst))
|
|
|
|
(if (= wordsize 4)
|
|
|
|
(CR* #x8B dst src ac)
|
2008-07-18 04:35:13 -04:00
|
|
|
(CR*-no-rex #x8B dst src ac))]
|
2008-04-09 03:05:19 -04:00
|
|
|
[else (die who "invalid" instr)])]
|
2006-11-23 19:44:29 -05:00
|
|
|
[(movb src dst)
|
|
|
|
(cond
|
2007-12-31 05:34:20 -05:00
|
|
|
[(and (imm8? src) (mem? dst)) (CR* #xC6 '/0 dst (IMM8 src ac))]
|
|
|
|
[(and (reg8? src) (mem? dst)) (CR* #x88 src dst ac)]
|
|
|
|
[(and (mem? src) (reg8? dst)) (CR* #x8A dst src ac)]
|
2007-12-31 02:42:53 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
|
|
|
[(addl src dst)
|
|
|
|
(cond
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (imm8? src) (reg? dst)) (CR* #x83 '/0 dst (IMM8 src ac))]
|
2008-04-09 05:34:36 -04:00
|
|
|
[(and (imm32? src) (eq? dst '%eax)) (C #x05 (IMM32 src ac))]
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (imm32? src) (reg? dst)) (CR* #x81 '/0 dst (IMM32 src ac))]
|
2008-07-22 01:07:31 -04:00
|
|
|
[(and (reg? src) (reg? dst)) (CR* #x01 src dst ac)]
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (mem? src) (reg? dst)) (CR* #x03 dst src ac)]
|
|
|
|
[(and (imm32? src) (mem? dst)) (CR* #x81 '/0 dst (IMM32 src ac))]
|
2008-07-22 01:07:31 -04:00
|
|
|
[(and (reg? src) (mem? dst)) (CR* #x01 src dst ac)]
|
2007-12-15 08:22:49 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
2007-12-31 02:42:53 -05:00
|
|
|
[(subl src dst)
|
|
|
|
(cond
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (imm8? src) (reg? dst)) (CR* #x83 '/5 dst (IMM8 src ac))]
|
2008-04-09 05:34:36 -04:00
|
|
|
[(and (imm32? src) (eq? dst '%eax)) (C #x2D (IMM32 src ac))]
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (imm32? src) (reg? dst)) (CR* #x81 '/5 dst (IMM32 src ac))]
|
|
|
|
[(and (reg? src) (reg? dst)) (CR* #x29 src dst ac)]
|
|
|
|
[(and (mem? src) (reg? dst)) (CR* #x2B dst src ac)]
|
|
|
|
[(and (imm32? src) (mem? dst)) (CR* #x81 '/5 dst (IMM32 src ac))]
|
|
|
|
[(and (reg? src) (mem? dst)) (CR* #x29 src dst ac)]
|
2007-12-31 02:42:53 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
|
|
|
[(sall src dst)
|
|
|
|
(cond
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (equal? 1 src) (reg? dst)) (CR* #xD1 '/4 dst ac)]
|
|
|
|
[(and (imm8? src) (reg? dst)) (CR* #xC1 '/4 dst (IMM8 src ac))]
|
2007-12-31 05:34:20 -05:00
|
|
|
[(and (imm8? src) (mem? dst)) (CR* #xC1 '/4 dst (IMM8 src ac))]
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (eq? src '%cl) (reg? dst)) (CR* #xD3 '/4 dst ac)]
|
2007-12-31 05:34:20 -05:00
|
|
|
[(and (eq? src '%cl) (mem? dst)) (CR* #xD3 '/4 dst ac)]
|
2007-12-31 02:42:53 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
|
|
|
[(shrl src dst)
|
|
|
|
(cond
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (equal? 1 src) (reg? dst)) (CR* #xD1 '/5 dst ac)]
|
|
|
|
[(and (imm8? src) (reg? dst)) (CR* #xC1 '/5 dst (IMM8 src ac))]
|
|
|
|
[(and (eq? src '%cl) (reg? dst)) (CR* #xD3 '/5 dst ac)]
|
2007-12-31 05:34:20 -05:00
|
|
|
[(and (imm8? src) (mem? dst)) (CR* #xC1 '/5 dst (IMM8 src ac))]
|
|
|
|
[(and (eq? src '%cl) (mem? dst)) (CR* #xD3 '/5 dst ac)]
|
2007-12-31 02:42:53 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
|
|
|
[(sarl src dst)
|
|
|
|
(cond
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (equal? 1 src) (reg? dst)) (CR* #xD1 '/7 dst ac)]
|
|
|
|
[(and (imm8? src) (reg? dst)) (CR* #xC1 '/7 dst (IMM8 src ac))]
|
2008-07-18 04:35:13 -04:00
|
|
|
[(and (imm8? src) (mem? dst)) (CR* #xC1 '/7 dst (IMM8 src ac))]
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (eq? src '%cl) (reg? dst)) (CR* #xD3 '/7 dst ac)]
|
2008-07-18 04:35:13 -04:00
|
|
|
[(and (eq? src '%cl) (mem? dst)) (CR* #xD3 '/7 dst ac)]
|
2008-07-22 01:07:31 -04:00
|
|
|
[else (die who "invalid" instr)])]
|
2007-12-31 02:42:53 -05:00
|
|
|
[(andl src dst)
|
|
|
|
(cond
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (imm32? src) (mem? dst)) (CR* #x81 '/4 dst (IMM32 src ac))]
|
|
|
|
[(and (imm8? src) (reg? dst)) (CR* #x83 '/4 dst (IMM8 src ac))]
|
|
|
|
[(and (imm32? src) (eq? dst '%eax)) (C #x25 (IMM32 src ac))]
|
|
|
|
[(and (imm32? src) (reg? dst)) (CR* #x81 '/4 dst (IMM32 src ac))]
|
|
|
|
[(and (reg? src) (reg? dst)) (CR* #x21 src dst ac)]
|
|
|
|
[(and (reg? src) (mem? dst)) (CR* #x21 src dst ac)]
|
|
|
|
[(and (mem? src) (reg? dst)) (CR* #x23 dst src ac)]
|
2008-07-22 01:07:31 -04:00
|
|
|
[else (die who "invalid" instr)])]
|
2007-12-31 02:42:53 -05:00
|
|
|
[(orl src dst)
|
|
|
|
(cond
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (imm32? src) (mem? dst)) (CR* #x81 '/1 dst (IMM32 src ac))]
|
|
|
|
[(and (reg? src) (mem? dst)) (CR* #x09 src dst ac)]
|
|
|
|
[(and (imm8? src) (reg? dst)) (CR* #x83 '/1 dst (IMM8 src ac))]
|
2008-07-22 01:07:31 -04:00
|
|
|
[(and (imm32? src) (eq? dst '%eax)) (C #x0D (IMM32 src ac))]
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (imm32? src) (reg? dst)) (CR* #x81 '/1 dst (IMM32 src ac))]
|
|
|
|
[(and (reg? src) (reg? dst)) (CR* #x09 src dst ac)]
|
|
|
|
[(and (mem? src) (reg? dst)) (CR* #x0B dst src ac)]
|
2007-12-31 02:42:53 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
|
|
|
[(xorl src dst)
|
|
|
|
(cond
|
2008-07-18 04:35:13 -04:00
|
|
|
[(and (imm8? src) (reg? dst)) (CR* #x83 '/6 dst (IMM8 src ac))]
|
2007-12-31 05:34:20 -05:00
|
|
|
[(and (imm8? src) (mem? dst)) (CR* #x83 '/6 dst (IMM8 src ac))]
|
2008-07-22 01:07:31 -04:00
|
|
|
[(and (imm32? src) (eq? dst '%eax)) (C #x35 (IMM32 src ac))]
|
2008-07-18 04:35:13 -04:00
|
|
|
[(and (reg? src) (reg? dst)) (CR* #x31 src dst ac)]
|
|
|
|
[(and (mem? src) (reg? dst)) (CR* #x33 dst src ac)]
|
|
|
|
[(and (reg? src) (mem? dst)) (CR* #x31 src dst ac)]
|
2007-12-31 02:42:53 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
|
|
|
[(leal src dst)
|
|
|
|
(cond
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (mem? src) (reg? dst)) (CR* #x8D dst src ac)]
|
2007-12-31 02:42:53 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
|
|
|
[(cmpl src dst)
|
|
|
|
(cond
|
2008-07-18 04:35:13 -04:00
|
|
|
[(and (imm8? src) (reg? dst)) (CR* #x83 '/7 dst (IMM8 src ac))]
|
2008-07-22 01:07:31 -04:00
|
|
|
[(and (imm32? src) (eq? dst '%eax)) (C #x3D (IMM32 src ac))]
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (imm32? src) (reg? dst)) (CR* #x81 '/7 dst (IMM32 src ac))]
|
2008-07-18 04:35:13 -04:00
|
|
|
[(and (reg? src) (reg? dst)) (CR* #x39 src dst ac)]
|
|
|
|
[(and (mem? src) (reg? dst)) (CR* #x3B dst src ac)]
|
2007-12-31 05:34:20 -05:00
|
|
|
[(and (imm8? src) (mem? dst)) (CR* #x83 '/7 dst (IMM8 src ac))]
|
2008-07-18 04:35:13 -04:00
|
|
|
[(and (imm32? src) (mem? dst)) (CR* #x81 '/7 dst (IMM32 src ac))]
|
2008-11-21 05:19:01 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
2007-12-31 02:42:53 -05:00
|
|
|
[(imull src dst)
|
|
|
|
(cond
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (imm8? src) (reg? dst)) (CR* #x6B dst dst (IMM8 src ac))]
|
2008-01-19 16:11:00 -05:00
|
|
|
[(and (imm32? src) (reg? dst)) (CR* #x69 dst dst (IMM32 src ac))]
|
|
|
|
[(and (reg? src) (reg? dst)) (CCR* #x0F #xAF dst src ac)]
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (mem? src) (reg? dst)) (CCR* #x0F #xAF dst src ac)]
|
2007-12-31 02:42:53 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
|
|
|
[(idivl dst)
|
|
|
|
(cond
|
2008-01-04 03:49:27 -05:00
|
|
|
[(reg? dst) (CR* #xF7 '/7 dst ac)]
|
2008-07-26 15:28:51 -04:00
|
|
|
[(mem? dst) (CR* #xF7 '/7 dst ac)]
|
2007-12-31 02:42:53 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
|
|
|
[(pushl dst)
|
|
|
|
(cond
|
2007-12-31 05:34:20 -05:00
|
|
|
[(imm8? dst) (CODE #x6A (IMM8 dst ac))]
|
2008-01-04 03:49:27 -05:00
|
|
|
[(imm32? dst) (CODE #x68 (IMM32 dst ac))]
|
|
|
|
[(reg? dst) (CR #x50 dst ac)]
|
2007-12-31 05:34:20 -05:00
|
|
|
[(mem? dst) (CR* #xFF '/6 dst ac)]
|
2007-12-31 02:42:53 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
|
|
|
[(popl dst)
|
|
|
|
(cond
|
2008-01-04 03:49:27 -05:00
|
|
|
[(reg? dst) (CR #x58 dst ac)]
|
2007-12-31 05:34:20 -05:00
|
|
|
[(mem? dst) (CR* #x8F '/0 dst ac)]
|
2007-12-31 02:42:53 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
|
|
|
[(notl dst)
|
|
|
|
(cond
|
2008-01-04 03:49:27 -05:00
|
|
|
[(reg? dst) (CR* #xF7 '/2 dst ac)]
|
2008-04-08 02:22:26 -04:00
|
|
|
[(mem? dst) (CR* #xF7 '/7 dst ac)]
|
2007-12-31 02:42:53 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
|
|
|
[(bswap dst)
|
|
|
|
(cond
|
2008-01-04 03:49:27 -05:00
|
|
|
[(reg? dst) (CCR #x0F #xC8 dst ac)]
|
2007-12-31 02:42:53 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
|
|
|
[(negl dst)
|
|
|
|
(cond
|
2008-04-08 02:22:26 -04:00
|
|
|
[(reg? dst) (CR* #xF7 '/3 dst ac)]
|
2007-12-31 02:42:53 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
|
|
|
[(jmp dst)
|
|
|
|
(cond
|
2008-04-08 02:22:26 -04:00
|
|
|
[(imm? dst) (CODE #xE9 (IMM32 dst ac))]
|
2007-12-31 05:34:20 -05:00
|
|
|
[(mem? dst) (CR* #xFF '/4 dst ac)]
|
2007-12-31 02:42:53 -05:00
|
|
|
[else (die who "invalid jmp target" dst)])]
|
|
|
|
[(call dst)
|
|
|
|
(cond
|
2008-04-08 02:22:26 -04:00
|
|
|
[(imm? dst) (CODE #xE8 (IMM32 dst ac))]
|
2007-12-31 05:34:20 -05:00
|
|
|
[(mem? dst) (CR* #xFF '/2 dst ac)]
|
2008-04-08 02:22:26 -04:00
|
|
|
[(reg? dst) (CR* #xFF '/2 dst ac)]
|
2007-12-31 02:42:53 -05:00
|
|
|
[else (die who "invalid jmp target" dst)])]
|
2007-06-15 01:53:34 -04:00
|
|
|
[(movsd src dst)
|
|
|
|
(cond
|
2007-12-31 05:34:20 -05:00
|
|
|
[(and (xmmreg? dst) (mem? src)) (CCCR* #xF2 #x0F #x10 dst src ac)]
|
|
|
|
[(and (xmmreg? src) (mem? dst)) (CCCR* #xF2 #x0F #x11 src dst ac)]
|
2007-12-15 08:22:49 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
2007-06-18 07:29:39 -04:00
|
|
|
[(cvtsi2sd src dst)
|
|
|
|
(cond
|
2008-01-04 03:49:27 -05:00
|
|
|
[(and (xmmreg? dst) (reg? src)) (CCCR* #xF2 #x0F #x2A src dst ac)]
|
2008-07-18 04:35:13 -04:00
|
|
|
[(and (xmmreg? dst) (mem? src)) (CCCR* #xF2 #x0F #x2A dst src ac)]
|
2007-12-15 08:22:49 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
2007-11-08 22:22:24 -05:00
|
|
|
[(cvtsd2ss src dst)
|
|
|
|
(cond
|
2007-12-31 05:34:20 -05:00
|
|
|
[(and (xmmreg? dst) (xmmreg? src)) (CCCR* #xF2 #x0F #x5A src dst ac)]
|
2007-12-15 08:22:49 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
2007-11-08 22:22:24 -05:00
|
|
|
[(cvtss2sd src dst)
|
|
|
|
(cond
|
2007-12-31 05:34:20 -05:00
|
|
|
[(and (xmmreg? dst) (xmmreg? src)) (CCCR* #xF3 #x0F #x5A src dst ac)]
|
2007-12-15 08:22:49 -05:00
|
|
|
[else (die who "invalid" instr)])]
|
2007-11-08 22:22:24 -05:00
|
|