anchor.diff:      (:wzr :wzr)
       (:xzr :xzr)
       (:pc :pc)))
  +
  +(defun check-register-class (register &rest classes)
  +  (assert (member (register-class register) classes)))
   
   (defun register-number (register &optional restrict-to)
     (when restrict-to
  
positive.code: (defmacro define-logical-instruction (name inverted-name opcode)
    `(progn
       (define-instruction ,name (dst lhs rhs &optional shift amount)
         (when (emit-logical-instruction ',name ',opcode nil dst lhs rhs shift amount)
           (return-from instruction t)))
       (define-instruction ,inverted-name (dst lhs rhs &optional shift amount)
         (when (emit-logical-instruction ',inverted-name ',opcode t dst lhs rhs shift amount)
           (return-from instruction t)))))
  
  (define-logical-instruction and bic #b00)
  
negative.code:                               (ldb (byte 19 2) imm-value)))
      (return-from instruction t)))
  
  (define-instruction br (target)
    (check-register-class reg :gpr-64)
    (emit-instruction (logior #xd61f0000
                              (ash (register-number target) +rn-shift+)))
    (return-from instruction t))
  
  (define-instruction blr (target)
    (check-register-class reg :gpr-64)
    (emit-instruction (logior #xd63f0000
                              (ash (register-number target) +rn-shift+)))
    (return-from instruction t))
  
  (define-instruction ret (&optional (reg :x30))
    (check-register-class reg :gpr-64)
    (emit-instruction (logior #xd65f0000
                              (ash (register-number reg) +rn-shift+)))
    (return-from instruction t))
  
  (define-instruction cbz (reg target)
    (check-register-class reg :gpr-64 :gpr-32)
    (let ((imm-value (- (or (resolve-immediate target) (current-address))
                        (current-address))))
      (assert (not (logtest imm-value #b11)))
      (assert (<= -134217728 imm-value 134217727))
      (emit-instruction (logior #x34000000
                                (if (eql (register-class reg) :gpr-64)
                                    #x80000000
                                    #x00000000)
                                (ash (ldb (byte 19 2) imm-value) 5)
                                (ash (register-number reg) +rt-shift+)))
      (return-from instruction t)))
  
  (define-instruction cbnz (reg target)
    (check-register-class reg :gpr-64 :gpr-32)
    (let ((imm-value (- (or (resolve-immediate target) (current-address))
                        (current-address))))
      (assert (not (logtest imm-value #b11)))
      (assert (<= -134217728 imm-value 134217727))
      (emit-instruction (logior #x35000000
                                (if (eql (register-class reg) :gpr-64)
                                    #x80000000
                                    #x00000000)
                                (ash (ldb (byte 19 2) imm-value) 5)
                                (ash (register-number reg) +rt-shift+)))
      (return-from instruction t)))
  
  (define-instruction tbnz (reg bit target)
    (check-register-class reg :gpr-64 :gpr-32)
    (let ((is-64-bit (eql (register-class reg) :gpr-64))
          (imm-value (- (or (resolve-immediate target) (current-address))
                        (current-address))))
      (assert (not (logtest imm-value #b11)))
      (assert (<= -32767 imm-value 32767))
      (if is-64-bit
          (assert (<= 0 bit 63))
          (assert (<= 0 bit 31)))
      (emit-instruction (logior #x37000000
                                (ash (ldb (byte 1 5) bit) 31)
                                (ash (ldb (byte 5 0) bit) 19)
                                (ash (ldb (byte 14 2) imm-value) 5)
                                (ash (register-number reg) +rt-shift+)))
      (return-from instruction t)))
  
  (defun emit-conditional-select (condition dst true false)
    (check-register-class dst :gpr-64 :gpr-32)
    (let ((is-64-bit (eql (register-class dst) :gpr-64)))
      (cond (is-64-bit
             (check-register-class true :gpr-64 :xzr)
             (check-register-class false :gpr-64 :xzr))
            (t
             (check-register-class true :gpr-32 :wzr)
             (check-register-class false :gpr-32 :wzr)))
      (emit-instruction (logior #x1A800000
                                (if is-64-bit
                                    #x80000000
                                    #x00000000)
                                (ash condition 12)
                                (ash false +rm-shift+)
                                (ash true +rn-shift+)
                                (ash dst +rd-shift+))))
    t)
  
  (defmacro define-conditional-select (name condition)
    `(define-instruction ,name (dst true false)
       (when (emit-conditional-select ',condition dst true false)
         (return-from instruction t))))
  
  (define-conditional-select csel.eq #b0000)
  (define-conditional-select csel.ne #b0001)
  (define-conditional-select csel.cs #b0010)
  (define-conditional-select csel.hs #b0010)
  (define-conditional-select csel.cc #b0011)
  (define-conditional-select csel.lo #b0011)
  (define-conditional-select csel.mi #b0100)
  (define-conditional-select csel.pl #b0101)
  (define-conditional-select csel.vs #b0110)
  (define-conditional-select csel.vc #b0111)
  (define-conditional-select csel.hi #b1000)
  (define-conditional-select csel.ls #b1001)
  (define-conditional-select csel.ge #b1010)
  (define-conditional-select csel.lt #b1011)
  (define-conditional-select csel.gt #b1100)
  (define-conditional-select csel.le #b1101)
  (define-conditional-select csel.al #b1110)
  
  (define-instruction brk (imm)
    (let ((imm-value (or (resolve-immediate imm) 0)))
      (assert (<= 0 imm-value 65535))
      (emit-instruction (logior #xd4200000
                                (ash imm-value 5)))
      (return-from instruction t)))
  
  (define-instruction hlt (imm)
    (let ((imm-value (or (resolve-immediate imm) 0)))
      (assert (<= 0 imm-value 65535))
      (emit-instruction (logior #xd4400000
                                (ash imm-value 5)))
      (return-from instruction t)))
  
  (define-instruction movz (dst value &optional (shift 0))
    (check-register-class dst :gpr-64 :gpr-32)
    (let ((is-64-bit (eql (register-class dst) :gpr-64))
          (imm-value (or (resolve-immediate value) 0)))
      (assert (<= 0 imm-value 65535))
      (if is-64-bit
          (assert (member shift '(0 16 32 48)))
          (assert (member shift '(0 16))))
      (emit-instruction (logior (if is-64-bit
                                    #x80000000
                                    #x00000000)
                                #x52800000
                                (ash (truncate shift 16) 21)
                                (ash (ldb (byte 16 0) imm-value) 5)
                                (ash (register-number dst) +rd-shift+)))
      (return-from instruction t)))
  