#lang scheme/base
(require
"decoder.ss"
"pointers.ss"
"../tools.ss"
"../target.ss"
(lib "match.ss"))
(provide
asm-find
asm-register! asm-find
dasm-register! dasm-find
ir-ops
define-asm
asm?
make-asm
asm-prototype
asm-error
proto->asm-error-handler
asm-phase
)
(define asm-phase (make-parameter -1))
(define get hash-ref)
(define put! hash-set!)
(define table alist->hash)
(define table->alist hash->alist)
(define asm-error
(make-parameter
(lambda a (error 'asm-error-not-in-asm-context))))
(define (proto->asm-error-handler asm arguments)
(let ((asm-proto (asm-prototype asm)))
(match-lambda*
(('overflow type value bits)
(error 'asm-overflow
"~a overflow error in ~a at ~a (~a doesnt fit in ~a bits) : ~a"
type
(instruction->string (asm-current-instruction))
(pointer-get 'code)
value bits
asm-proto
)))))
(define-values
(struct:asm make-asm-internal asm? asm-ref asm-set!)
(make-struct-type 'word #f 2 0 #f null #f 0))
(define (make-asm fn [proto #f])
(make-asm-internal fn proto))
(define (asm-prototype asm)
(asm-ref asm 1))
(define (asm-debug opcode)
(lambda args `((,opcode ,@args))))
(define *asm* (table '()))
(define (asm-register! name fn)
(put! *asm* name fn))
(define (asm-find name)
(get *asm* name
(lambda () (asm-debug name))
))
(define-sr (define-asm (name . formals) . body)
(asm-register!
'name
(make-asm
(lambda formals . body)
'(name formals))))
(define-sr (asm! body ...) (begin body ... '()))
(define-asm (here) `(,(pointer-get 'code)))
(define-asm (allot-data n) (asm! (pointer-allot! 'data n)))
(define-asm (allot-code n) (asm! (pointer-allot! 'code n)))
(define (pseudo-op op)
(lambda _ (error 'asm-pseudo-op "~s" op)))
(define-sr (ir-ops (op . args) ...)
(begin (define-asm (op . args) (pseudo-op 'op)) ...))
(define disassemblers (decoder-leaf))
(define (dasm-register! address bits code)
(decoder-set! decoder-leaf disassemblers
address bits code))
(define (dasm-find address bits)
(decoder-get disassemblers address bits))
(define (run-dasm word)
((dasm-find word) word 16))