home *** CD-ROM | disk | FTP | other *** search
- (herald mipsis)
-
- (define *offset-from-template* 10)
-
- (define-constant op/bcond 1)
- (define-constant op/special 0)
- (define-constant op/beq 4)
- (define-constant op/bne 5)
- (define-constant code/bgez 1)
- (define-constant code/bgezal #b010001)
- (define-constant code/bltz 0)
- (define-constant op/blez 6)
- (define-constant op/bgtz 7)
-
-
- (define mips/bcc
- (object (lambda (bv i cc disp)
- (let ((displ (branch-target-offset i disp)))
- (xselect (car cc)
- ((jump-op/jabs)
- (i-type bv i op/bcond (rnum zero) code/bgez displ))
- ((jump-op/jl)
- (i-type bv i op/bcond (rnum zero) code/bgezal displ))
- ((jump-op/j=)
- (i-type bv i op/beq (rnum (cadr cc)) (rnum (caddr cc)) displ))
- ((jump-op/jn=)
- (i-type bv i op/bne (rnum (cadr cc)) (rnum (caddr cc)) displ))
- ((jump-op/j<)
- (i-type bv i op/bcond (rnum (cadr cc)) code/bltz displ))
- ((jump-op/j<=)
- (i-type bv i op/blez (rnum (cadr cc)) 0 displ))
- ((jump-op/j>)
- (i-type bv i op/bgtz (rnum (cadr cc)) 0 displ))
- ((jump-op/j>=)
- (i-type bv i op/bcond (rnum (cadr cc)) code/bgez displ)))))
- ((instruction-as-string self i cc disp)
- (select (car cc)
- ((jump-op/jabs)
- (format nil "br ~a"
- (fx+ i (fx+ (fixnum-ashl (branch-target-offset i disp) 2) 4))))
- ((jump-op/jl)
- (format nil "brl ~a"
- (fx+ i (fx+ (fixnum-ashl (branch-target-offset i disp) 2) 4))))
- ((jump-op/j=)
- (format nil "beq ~a,~a,~a" (rname (cadr cc)) (rname (caddr cc))
- (fx+ i (fx+ (fixnum-ashl (branch-target-offset i disp) 2) 4))))
- ((jump-op/jn=)
- (format nil "bne ~a,~a,~a" (rname (cadr cc)) (rname (caddr cc))
- (fx+ i (fx+ (fixnum-ashl (branch-target-offset i disp) 2) 4))))
- (else
- (format nil "b~a ~a,~a" (j->name (car cc)) (rname (cadr cc))
- (fx+ i (fx+ (fixnum-ashl (branch-target-offset i disp) 2) 4))))))
- ((identification self) "bcc")))
-
- (define (j->name jump-op)
- (cond ((fx>= jump-op 0)
- (vref '#("a" "ne" "gtz" "gez" "gu" "cc" "pos" "vc") jump-op))
- (else
- (vref '#("a" "e" "lez" "ltz" "leu" "cs" "neg" "vs") (fx- 0 jump-op)))))
-
- (define (branch-target-offset pc thing)
- (cond ((fixnum? thing) (fixnum-ashr (fx- thing 4) 2))
- (else
- (let ((addr (address-of (cdr thing))))
- (fixnum-ashr (fx- (fx- (xcase (car thing)
- ((label) addr)
- ((template) (fx+ addr 12))
- ((label+1) (fx+ addr 4)))
- pc) 4) 2)))))
-
-
- (define (normal-3op name r-code i-op)
- (object (lambda (bv i s1 s2 d)
- (cond ((fixnum? s1)
- (r-type bv i op/special (rnum s2) (rnum s1) (rnum d) 0 r-code))
- (else
- (i-type bv i i-op (rnum s2) (rnum d) (get-literal i s1)))))
- ((instruction-as-string self i s1 s2 d)
- (cond ((fixnum? s1)
- (format nil "~a ~a,~a,~a" name (rname s1) (rname s2)
- (rname d)))
- (else
- (format nil "~a $~d,~a,~a" name (get-literal i s1)
- (rname s2) (rname d)))))
- ((read-registers self s1 s2 #f)
- (return (if (fixnum? s1) s1 zero) s2))
- ((write-register self #f #f d) d)
- ((identification self) name)))
-
- (define mips/add (normal-3op "add" #b100000 #b001000))
- (define mips/sub (normal-3op "sub" #b100010 0))
- (define mips/slt (normal-3op "slt" #b101010 #b001010))
- (define mips/sltu (normal-3op "sltu" #b101011 #b001011))
- (define risc/or (normal-3op "or" #b100101 #b001101))
- (define risc/and (normal-3op "and" #b100100 #b001100))
- (define risc/xor (normal-3op "xor" #b100110 #b001110))
- (define mips/addu (normal-3op "addu" #b100001 #b001001))
- (define mips/subu (normal-3op "subu" #b100011 0))
- (define risc/add mips/addu)
-
- (define (shifter name f-code v-code)
- (object (lambda (bv i s1 s2 d)
- (cond ((fixnum? s1)
- (r-type bv i op/special (rnum s1) (rnum s2) (rnum d) 0 v-code))
- (else
- (r-type bv i op/special 0 (rnum s2) (rnum d)
- (get-literal i s1) f-code))))
- ((instruction-as-string self i s1 s2 d)
- (cond ((fixnum? s1)
- (format nil "~a ~a,~a,~a" name (rname s1) (rname s2)
- (rname d)))
- (else
- (format nil "~a $~d,~a,~a" name (get-literal i s1)
- (rname s2) (rname d)))))
- ((read-registers self s1 s2 #f)
- (return (if (fixnum? s1) s1 zero) s2))
- ((write-register self #f #f d) d)
- ((identification self) name)))
-
- (define risc/sra (shifter "sra" #b000011 #b000111))
- (define risc/srl (shifter "srl" #b000010 #b000110))
- (define risc/sll (shifter "sll" #b000000 #b000100))
-
- (define mips/load
- (object (lambda (bv i size ro d)
- (receive (base offset) (get-reg-and-offset ro)
- (i-type bv i (load-op size) (rnum base) (rnum d) offset)))
- ((instruction-as-string self i size ro d)
- (receive (base offset) (get-reg-and-offset ro)
- (format nil "~a ~d(~a),~a" (load-op-name size) offset
- (rname base) (rname d))))
- ((read-registers self #f ro #f)
- (return zero (cadr ro)))
- ((write-register self #f #f d) d)
- ((identification self) "load")))
-
- (define (load-op size)
- (xcase size
- ((l) #b100011)
- ((uw) #b100101)
- ((sw) #b100001)
- ((ub) #b100100)
- ((sb) #b100000)))
- (define (load-op-name size)
- (xcase size
- ((l) "lw")
- ((uw) "lhu")
- ((sw) "lh")
- ((ub) "lbu")
- ((sb) "lb")))
-
- (define risc/store
- (object (lambda (bv i size d ro)
- (receive (base offset) (get-reg-and-offset ro)
- (i-type bv i (store-op size) (rnum base) (rnum d) offset)))
- ((instruction-as-string self i size d ro)
- (receive (base offset) (get-reg-and-offset ro)
- (format nil "~a ~a,~d(~a)" (store-op-name size) (rname d)
- offset (rname base))))
- ((read-registers self #f d ro)
- (return d (cadr ro)))
- ((identification self) "store")))
-
- (define (store-op size)
- (xcase size
- ((l) #b101011)
- ((w) #b101001)
- ((b) #b101000)))
- (define (store-op-name size)
- (xcase size
- ((L) "sw")
- ((w) "sh")
- ((b) "sb")))
-
-
- (define mips/fload
- (object (lambda (bv i ro d)
- (receive (base offset) (get-reg-and-offset ro)
- (i-type bv i #b110001 (rnum base) d offset)))
- ((instruction-as-string self i ro d)
- (receive (base offset) (get-reg-and-offset ro)
- (format nil "fload ~d(~a),$f~a" offset
- (rname base) d)))
- ((identification self) "fload")))
-
- (define mips/fstore
- (object (lambda (bv i d ro)
- (receive (base offset) (get-reg-and-offset ro)
- (i-type bv i #b111001 (rnum base) d offset)))
- ((instruction-as-string self i d ro)
- (receive (base offset) (get-reg-and-offset ro)
- (format nil "fstore $f~a,~d(~a)" d
- offset (rname base))))
- ((identification self) "fstore")))
-
- (define-constant (16bit? x)
- (and (fx<= #x-8000 x) (fx< x #x8000)))
-
- (define-constant (u16bit? x)
- (and (fx>= x 0) (fx<= x #xffff)))
-
- (define (get-reg-and-offset ro)
- (xcase (car ro)
- ((reg-offset) (return (cadr ro) (enforce 16bit? (caddr ro))))))
-
- (define (get-literal i lit)
- (if (eq? (car lit) 'unsigned)
- (enforce u16bit? (cdr lit))
- (enforce 16bit?
- (xcase (car lit)
- ((lit) (cdr lit))
- ((tp-offset)
- (fx- (fx+ (ib-address (cdr lit)) 10) (fx+ i 4)))
- ((label-offset)
- (fx- (ib-address (cdr lit)) (fx+ i 4)))
- ((handler-diff)
- (fx- (fx+ (ib-address (cadr lit)) 12)
- (ib-address (cddr lit))))))))
-
- (define mips/lui
- (object (lambda (bv i lit reg)
- (i-type bv i #b001111 0 (rnum reg) (cdr lit)))
- ((instruction-as-string self i lit reg)
- (format nil "lui $~x,~a" (cdr lit) (rname reg)))
- ((write-register self #f d) d)
- ((identification self) "lui")))
-
- (define mips/noop
- (object (lambda (bv i)
- (i-type bv i #b001111 0 0 0))
- ((instruction-as-string self i)
- "noop")))
-
- (define mips/mult
- (object (lambda (bv i sr1 sr2)
- (r-type bv i op/special (rnum sr2) (rnum sr1) 0 0 #b011000))
- ((read-registers self sr1 sr2)
- (return sr1 sr2))
- ((instruction-as-string self i sr1 sr2)
- (format nil "mul ~a,~a" (rname sr1) (rname sr2)))))
-
- (define mips/div
- (object (lambda (bv i sr1 sr2)
- (r-type bv i op/special (rnum sr2) (rnum sr1) 0 0 #b011010))
- ((read-registers self sr1 sr2)
- (return sr1 sr2))
- ((instruction-as-string self i sr1 sr2)
- (format nil "div ~a,~a" (rname sr1) (rname sr2)))))
-
- (define mips/mfhi
- (object (lambda (bv i sr1)
- (r-type bv i op/special 0 0 (rnum sr1) 0 #b010000))
- ((write-register self #f d) d)
- ((instruction-as-string self i sr1)
- (format nil "mfhi ~a" (rname sr1)))))
-
- (define mips/mflo
- (object (lambda (bv i sr1)
- (r-type bv i op/special 0 0 (rnum sr1) 0 #b010010))
- ((write-register self #f d) d)
- ((instruction-as-string self i sr1)
- (format nil "mflo ~a" (rname sr1)))))
-
- (define mips/jalr
- (object (lambda (bv i reg d)
- (r-type bv i op/special (rnum reg) 0 (rnum d) 0 #b001001))
- ((read-registers self reg #f)
- (return zero reg))
- ((write-register self #f d) d)
- ((instruction-as-string self i reg d)
- (format nil "jalr ~a,~a" (rname reg) (rname d)))))
-
- (define mips/jr
- (object (lambda (bv i reg)
- (r-type bv i op/special (rnum reg) 0 0 0 #b001000))
- ((read-registers self reg)
- (return zero reg))
- ((instruction-as-string self i reg)
- (format nil "jr ~a" (rname reg)))))
-
-
- (define (rnum r)
- (cond ((fx>= r 0)
- (fx+ r 2))
- (else
- (vref '#(nil 0 24 25 16 17 18 19 20 30 31 1 21 29) (- r)))))
-
- (define *reg-names* (make-vector *real-registers*))
- (set (vref *reg-names* 0) "p")
- (do ((i 1 (fx+ i 1)))
- ((fx= i AN)
- (set (vref *reg-names* AN) "an")
- (set (vref *reg-names* AN+1) "an+1"))
- (set (vref *reg-names* i)
- (format nil "a~d" i)))
-
- (define (rname r)
- (cond ((fx>= r 0)
- (vref *reg-names* r))
- (else
- (vref '#("nil" "zero" "eargs" "extra" "scratch" "nil" "pex" "vector"
- "t" "sp" "link" "ass" "crit" "ssp")
- (- r)))))
-
-
- (define lap-table (make-table 'lap-table))
- (define (define-lap x y)
- (set (table-entry lap-table x) y))
-
-
-
- (define jbr-inst mips/bcc)
- (define noop-inst `(,mips/noop))
-
-
-
-
-