- ((A) ((core-get B-ptr) 'set-A-num!
- (f ((core-get B-ptr) 'A-num) ((core-get A-ptr) 'A-num)) name))
- ((B) ((core-get B-ptr) 'set-B-num!
- (f ((core-get B-ptr) 'B-num) ((core-get A-ptr) 'B-num)) name))
- ((AB) ((core-get B-ptr) 'set-B-num!
- (f ((core-get B-ptr) 'B-num) ((core-get A-ptr) 'A-num)) name))
- ((BA) ((core-get B-ptr) 'set-A-num!
- (f ((core-get B-ptr) 'A-num) ((core-get A-ptr) 'B-num)) name))
- ((F I) ((core-get B-ptr) 'set-A-num!
- (f ((core-get B-ptr) 'A-num) ((core-get A-ptr) 'A-num))) name
- ((core-get B-ptr) 'set-B-num!
- (f ((core-get B-ptr) 'B-num) ((core-get A-ptr) 'B-num)) name))
- ((X) ((core-get B-ptr) 'set-A-num!
- (f ((core-get B-ptr) 'A-num) ((core-get A-ptr) 'B-num)) name)
- ((core-get B-ptr) 'set-B-num!
- (f ((core-get B-ptr) 'B-num) ((core-get A-ptr) 'A-num)) name))))
-
-(define (eval-operand mode num ptr)
- (addr+ ptr
- (case mode
- ((immediate) 0)
- ((direct) num)
- ((indirect-A) (addr+ num ((core-get (addr+ ptr num)) 'A-num)))
- ((indirect-B) (addr+ num ((core-get (addr+ ptr num)) 'B-num)))
- ((pre-indirect-A)
- (let ((aux-instr (core-get (addr+ ptr num))))
- (instr-set-A-num! aux-instr (addr+ -1 (aux-instr 'A-num)))
- (addr+ num (aux-instr 'A-num))))
- ((pre-indirect-B)
- (let ((aux-instr (core-get (addr+ ptr num))))
- (instr-set-B-num! aux-instr (addr+ -1 (aux-instr 'B-num)))
- (addr+ num (aux-instr 'B-num))))
- ((post-indirect-A)
- (let* ((aux-instr (core-get (addr+ ptr num)))
- (old-A-num (aux-instr 'A-num)))
- (instr-set-A-num! aux-instr (addr+ 1 (aux-instr 'A-num)))
- (addr+ num old-A-num)))
- ((post-indirect-B)
- (let* ((aux-instr (core-get (addr+ ptr num)))
- (old-B-num (aux-instr 'B-num)))
- (instr-set-B-num! aux-instr (addr+ 1 (aux-instr 'B-num)))
- (addr+ num old-B-num)))
- (else
- (error "Unrecognized mode" mode)))))
+ ((A) (test (core A-ptr 'A-num) (core B-ptr 'A-num)))
+ ((B) (test (core A-ptr 'B-num) (core B-ptr 'B-num)))
+ ((AB) (test (core A-ptr 'A-num) (core B-ptr 'B-num)))
+ ((BA) (test (core A-ptr 'B-num) (core B-ptr 'A-num)))
+ ((F) (and
+ (test (core A-ptr 'A-num) (core B-ptr 'A-num))
+ (test (core A-ptr 'B-num) (core B-ptr 'B-num))))
+ ((X) (and
+ (test (core A-ptr 'A-num) (core B-ptr 'B-num))
+ (test (core A-ptr 'B-num) (core B-ptr 'A-num))))
+ ((I) (and
+ (if (eq? test =)
+ (and
+ (eq? (core A-ptr 'opcode) (core B-ptr 'opcode))
+ (eq? (core A-ptr 'modifier) (core B-ptr 'modifier))
+ (eq? (core A-ptr 'A-mode) (core B-ptr 'B-mode))
+ (eq? (core A-ptr 'B-mode) (core B-ptr 'A-mode)))
+ #t)
+ (test (core A-ptr 'A-num) (core B-ptr 'B-num))
+ (test (core A-ptr 'B-num) (core B-ptr 'A-num))))))
+
+(define (instr-zero? core ptr modifier decrement name)
+ (case modifier
+ ((A AB)
+ (if decrement (core ptr 'set! 'A-num (- (core ptr 'A-num) 1) name))
+ (= 0 (core ptr 'A-num)))
+ ((A AB)
+ (if decrement (core ptr 'set! 'B-num (- (core ptr 'B-num) 1) name))
+ (= 0 (core ptr 'B-num)))
+ ((X I F)
+ (if decrement
+ (begin
+ (core ptr 'set! 'A-num (- (core ptr 'A-num) 1) name)
+ (core ptr 'set! 'B-num (- (core ptr 'B-num) 1) name)))
+ (and (= 0 (core ptr 'A-num))
+ (= 0 (core ptr 'B-num))))))
+
+(define (combine-and-store core A-ptr B-ptr modifier name f)
+ (case modifier
+ ((A) (core B-ptr 'set! 'A-num
+ (f (core B-ptr 'A-num) (core A-ptr 'A-num)) name))
+ ((B) (core B-ptr 'set! 'B-num
+ (f (core B-ptr 'B-num) (core A-ptr 'B-num)) name))
+ ((AB) (core B-ptr 'set! 'B-num
+ (f (core B-ptr 'B-num) (core A-ptr 'A-num)) name))
+ ((BA) (core B-ptr 'set! 'A-num
+ (f (core B-ptr 'A-num) (core A-ptr 'B-num)) name))
+ ((F I) (core B-ptr 'set! 'A-num
+ (f (core B-ptr 'A-num) (core A-ptr 'A-num)) name)
+ (core B-ptr 'set! 'B-num
+ (f (core B-ptr 'B-num) (core A-ptr 'B-num)) name))
+ ((X) (core B-ptr 'set! 'A-num
+ (f (core B-ptr 'A-num) (core A-ptr 'B-num)) name)
+ (core B-ptr 'set! 'B-num
+ (f (core B-ptr 'B-num) (core A-ptr 'A-num)) name))))
+
+(define (eval-operand core mode num ptr name)
+ (core '->addr (+ ptr
+ (case mode
+ ((immediate) 0)
+ ((direct) num)
+ ((indirect-A) (+ num (core (+ ptr num) 'A-num)))
+ ((indirect-B) (+ num (core (+ ptr num) 'B-num)))
+ ((pre-indirect-A)
+ (let ((aux-ptr (+ ptr num)))
+ (core aux-ptr 'set! 'A-num (- (core aux-ptr 'A-num) 1) name)
+ (+ num (core aux-ptr 'A-num))))
+ ((pre-indirect-B)
+ (let ((aux-ptr (+ ptr num)))
+ (core aux-ptr 'set! 'B-num (- (core aux-ptr 'B-num) 1) name)
+ (+ num (core aux-ptr 'B-num))))
+ ((post-indirect-A)
+ (let* ((aux-ptr (+ ptr num))
+ (old-A-num (core aux-ptr 'A-num)))
+ (core aux-ptr 'set! 'A-num (+ (core aux-ptr 'A-num) 1) name)
+ (+ num old-A-num)))
+ ((post-indirect-B)
+ (let* ((aux-ptr (+ ptr num))
+ (old-B-num (core aux-ptr 'B-num)))
+ (core aux-ptr 'set! 'B-num (+ (core aux-ptr 'B-num) 1) name)
+ (+ num old-B-num)))
+ (else
+ (error "Unrecognized mode" mode))))))
+
+;;; Main procedure
+;;