├── 6502 ├── base.lisp ├── ops.lisp ├── package.lisp ├── specops.6502.asd └── templates.lisp ├── .gitignore ├── LICENSE ├── README.md ├── m68k ├── base.lisp ├── ops.lisp ├── package.lisp ├── specops.m68k.asd └── templates.lisp ├── package.lisp ├── specops.asd ├── specops.lisp ├── superh ├── base.lisp ├── ops-nyi.lisp ├── ops.lisp ├── package.lisp └── specops.superh.asd ├── system-z ├── base.lisp ├── ops.lisp ├── package.lisp └── specops.system-z.asd ├── wasm ├── base.lisp ├── ops.lisp ├── package.lisp └── specops.wasm.asd ├── x86 ├── base.lisp ├── base.old.lisp ├── ops.main.lisp ├── ops.main2.lisp ├── package.lisp ├── specops.x86.asd └── templates.lisp └── z80 ├── base.lisp ├── comber.lisp ├── ops.lisp ├── package.lisp ├── specops.z80.asd └── templates.lisp /.gitignore: -------------------------------------------------------------------------------- 1 | # SpecOps files to ignore 2 | 3 | # Hidden files in subdirectories 4 | */.* 5 | 6 | # Emacs backup files 7 | *~ 8 | 9 | # Other Emacs files 10 | .emacs* 11 | 12 | # Common Lisp compiled files 13 | *.FASL 14 | *.fasl 15 | *.lisp-temp 16 | *.dfsl 17 | *.pfsl 18 | *.d64fsl 19 | *.p64fsl 20 | *.lx64fsl 21 | *.lx32fsl 22 | *.dx64fsl 23 | *.dx32fsl 24 | *.fx64fsl 25 | *.fx32fsl 26 | *.sx64fsl 27 | *.sx32fsl 28 | *.wx64fsl 29 | *.wx32fsl 30 | 31 | # OSX folder metadata 32 | .DS_Store 33 | -------------------------------------------------------------------------------- /6502/base.lisp: -------------------------------------------------------------------------------- 1 | ;;;; 6502.lisp 2 | 3 | (in-package #:specops.6502) 4 | 5 | (defclass 6502-mas (mas-displaced) 6 | () (:documentation "Memory access scheme for 6502 processors.")) 7 | 8 | (defclass assembler-6502 (assembler-encoding) 9 | ((%storage :accessor asm-storage 10 | :allocation :class 11 | :initform '(:gpr #(:a :x :y) :spr #(:sp :pc :f)) 12 | :initarg :storage) 13 | (%lexicon :accessor asm-lexicon 14 | :allocation :class 15 | :initform (make-hash-table :test #'eq) 16 | :initarg :lexicon) 17 | (%decoder :accessor asm-enc-decoder 18 | :allocation :class 19 | :initform (make-hash-table :test #'eq) 20 | :initarg :decoder)) 21 | (:documentation "Assembler for 6502 CPUs.")) 22 | 23 | (defun enc-displ (item) 24 | "Encode a memory address in $LLHH little-endian byte order. This also works in reverse." 25 | (let ((value (if (typep item 'memory-access-scheme) (mas-displ item) item))) 26 | (+ (ash value -8) 27 | (ash (logand #xFF value) 8)))) 28 | 29 | (defvar *assembler-prototype-6502*) 30 | 31 | (defun match-ops (a0 a1 &optional a2 a3) 32 | (let ((op0 a0) (op1 (if a2 a1 nil)) 33 | (val0 (or a2 a1)) (val1 a3)) 34 | (flet ((match (op val) 35 | (cond ((eq :iv val) 36 | (and (integerp op) (not (minusp op)) (> #x00100 op))) 37 | ((eq :rl val) 38 | (or (symbolp op) (typep op '(signed-byte 8)))) 39 | ((position val #(:a :x :y)) 40 | (eq op val)) 41 | ((position val #(:zp :in)) 42 | (and (typep op '6502-mas) (> #x00100 (mas-displ op)))) 43 | ((position val #(:ab :inw)) 44 | (and (typep op '6502-mas) (> #x10000 (mas-displ op))))))) 45 | (and (match op0 val0) 46 | (or (not (or op1 val1)) 47 | (match op1 val1)))))) 48 | 49 | ;; (defun match-ops (op0 op1 val0 &optional val1) 50 | ;; ;; (print (list op0 op1 val0 val1)) 51 | ;; (and (or (and (keywordp op0) (eq op0 val0))) 52 | ;; (or (not op1) 53 | ;; (and (keywordp op1) (eq op1 val1))))) 54 | 55 | (defun @ (displacement) 56 | (make-instance '6502-mas :displ displacement)) 57 | 58 | ;; (:CL (:SED ((IM) 248))) 59 | 60 | ;; (:CL 61 | ;; (:POP ((:AF) 241) ((:HL) 225) ((:IX) 56801) ((:IY) 64993) ((:DE) 209) 62 | ;; ((:BC) 193)) 63 | ;; (OP0 &OPTIONAL OP1)) 64 | ;; (:CL 65 | ;; (:RET ((:M) 248) ((:P) 240) ((:PE) 232) ((:PO) 224) ((:C) 216) ((:NC) 208) 66 | ;; (NIL 201) ((:Z) 200) ((:NZ) 192)) 67 | ;; (OP0 &OPTIONAL OP1)) 68 | 69 | ;; (defmethod clause-processor ((assembler assembler-6502) assembler-symbol) 70 | ;; (declare (ignore assembler)) 71 | ;; (labels ((operand-test (o1 o2) 72 | ;; (if (keywordp o1) 73 | ;; (eq o1 o2) 74 | ;; (if (listp o1) 75 | ;; (and (listp o2) (eq (second o2) (second o1))) 76 | ;; nil))) 77 | ;; (decode-symbol (symbol) 78 | ;; (if (position symbol #(a x y)) 79 | ;; (intern (string symbol) "KEYWORD") 80 | ;; (if (eq 'im symbol) `(funcall of-code 1) 81 | ;; (if (position symbol #(ab inw)) 82 | ;; `(list '@ (enc-displ (funcall of-code 2))) 83 | ;; (if (position symbol #(in zp rl)) 84 | ;; `(list '@ (funcall of-code 1))))))) 85 | ;; (encoding-entry (varops legal operands opcode) 86 | ;; (let ((operands (remove 'im operands))) 87 | ;; `(((match-ops ,@(if (second operands) 88 | ;; varops (list (first varops))) 89 | ;; ,@(loop :for op :in operands 90 | ;; :collect (case op 91 | ;; (x :x) (y :y) (a :a) (ab :ab) (im :im) 92 | ;; (zp :zp) (in :in) (inw :inw) 93 | ;; (rl :rl) (iv :iv) (t op)))) 94 | ;; ,@(if legal nil `((print "Illegal!"))) 95 | ;; ,(let* ((var-pos (or (position 'ab operands) 96 | ;; (position 'rl operands) 97 | ;; (position 'zp operands) 98 | ;; (position 'im operands) 99 | ;; (position 'in operands) 100 | ;; (position 'inw operands))) 101 | ;; (var-sym (and var-pos (nth var-pos operands)))) 102 | ;; (if (not var-pos) 103 | ;; opcode `(+ ,(ash opcode (if (member var-sym '(ab inw)) 16 8)) 104 | ;; ;; only the :im immediate operands are not 105 | ;; ;; derived from a memory address 106 | ;; ,(nth var-pos (cond ((eql var-sym 'rl) 107 | ;; '((of-program :label 8 8 op0) 108 | ;; (of-program :label 8 8 op1))) 109 | ;; ((member var-sym '(ab inw)) 110 | ;; '((enc-displ op0) (enc-displ op1))) 111 | ;; ((member var-sym '(in zp)) 112 | ;; '((mas-displ op0) (mas-displ op1))) 113 | ;; (t '(op0 op1)))))))))))) 114 | 115 | ;; (lambda (clauses op-symbols) 116 | ;; (let ((varops (remove '&optional op-symbols))) 117 | ;; (if (numberp (second clauses)) 118 | ;; ;; `(setf (gethash ,(first c) ,table) ,(second c)) 119 | ;; (let ((mnemonic (intern (string (first clauses)) "KEYWORD"))) 120 | ;; `((of-lexicon ,assembler-symbol ,mnemonic ,(second clauses)) 121 | ;; (of-decoder ,assembler-symbol ,(second clauses) (list ,mnemonic)))) 122 | ;; (cons `(of-lexicon 123 | ;; ,assembler-symbol ,(intern (string (first clauses)) "KEYWORD") 124 | ;; (lambda ,op-symbols 125 | ;; (declare (ignorable op1)) 126 | ;; (cond ,@(loop :for clause :in (rest clauses) 127 | ;; :append (apply #'encoding-entry varops 128 | ;; (keywordp (first clauses)) 129 | ;; clause))))) 130 | ;; (loop :for clause :in (rest clauses) 131 | ;; :append `((of-decoder ,assembler-symbol 132 | ;; ,(second clause) 133 | ;; (lambda (of-code) 134 | ;; (list ,(intern (string (first clauses)) "KEYWORD") 135 | ;; ,@(mapcar #'decode-symbol (first clause))))))) 136 | ;; )))))) 137 | 138 | (defmethod clause-processor ((assembler assembler-6502) action mnemonic operands params body) 139 | (declare (ignore assembler mnemonic params)) 140 | ;; (print (list :ff action mnemonic operands params body)) 141 | (labels ((operand-test (o1 o2) 142 | (if (keywordp o1) 143 | (eq o1 o2) 144 | (if (listp o1) 145 | (and (listp o2) (eq (second o2) (second o1))) 146 | nil))) 147 | (decode-symbol (symbol) 148 | (if (position symbol #(a x y)) 149 | (intern (string symbol) "KEYWORD") 150 | (if (eq 'im symbol) `(of-program :next-bytes 1) 151 | (if (position symbol #(ab inw)) 152 | `(list '@ (enc-displ (of-program :next-bytes 2))) 153 | (if (position symbol #(in zp rl)) 154 | `(list '@ (of-program :next-bytes 1))))))) 155 | (encoding-entry (varops legal operands opcode) 156 | (let ((operands (remove 'im operands))) 157 | `(((match-ops ,@(if (second operands) 158 | varops (list (first varops))) 159 | ,@(loop :for op :in operands 160 | :collect (case op 161 | (x :x) (y :y) (a :a) (ab :ab) (im :im) 162 | (zp :zp) (in :in) (inw :inw) 163 | (rl :rl) (iv :iv) (t op)))) 164 | ,@(if legal nil `((print "Illegal!"))) 165 | ,(let* ((var-pos (or (position 'ab operands) 166 | (position 'rl operands) 167 | (position 'zp operands) 168 | (position 'iv operands) 169 | (position 'in operands) 170 | (position 'inw operands))) 171 | (var-sym (and var-pos (nth var-pos operands)))) 172 | (if (not var-pos) 173 | opcode `(+ ,(ash opcode (if (member var-sym '(ab inw)) 16 8)) 174 | ;; only the :im immediate operands are not 175 | ;; derived from a memory address 176 | ,(nth var-pos (cond ((eql var-sym 'rl) 177 | '((of-program :label 8 8 op0) 178 | (of-program :label 8 8 op1))) 179 | ((member var-sym '(ab inw)) 180 | '((enc-displ op0) (enc-displ op1))) 181 | ((member var-sym '(in zp)) 182 | '((mas-displ op0) (mas-displ op1))) 183 | (t '(op0 op1)))))))))))) 184 | (let ((varops (remove '&optional operands)) 185 | (key-mnemonic (intern (string mnemonic) "KEYWORD"))) 186 | ;; (print (list :ee mnemonic params body)) 187 | ;; (if (eq :sed mnemonic) (print (list :bo body action))) 188 | ;; (print (list :bo body action)) 189 | (if (and (listp body) (symbolp (first body)) (numberp (second body)) (eql action 'of-lexicon)) 190 | (values (second body) key-mnemonic t) 191 | (if (and (numberp body) (eql action 'of-decoder)) 192 | (values (list 'list key-mnemonic) body t) 193 | (case action 194 | (of-lexicon (values `((cond ,@(loop :for clause :in (rest body) 195 | :append (apply #'encoding-entry 196 | varops (keywordp (first body)) 197 | clause)))) 198 | key-mnemonic)) 199 | (of-decoder (values `((list ,key-mnemonic ,@(if (integerp body) 200 | nil (mapcar #'decode-symbol 201 | (first body))))) 202 | (if (listp body) (second body) body))))))))) 203 | 204 | ;; (OF-ENCODED *ASSEMBLER-PROTOTYPE-Z80* 205 205 | ;; (LAMBDA (OF-CODE) (LIST :CALL (FUNCALL OF-CODE 2)))) 206 | 207 | #| 208 | 209 | (assemble *assembler-prototype-6502* 210 | (:with) 211 | (:adc :x :y) 212 | (:sre :x 50)) 213 | 214 | |# 215 | 216 | (setf *assembler-prototype-6502* (make-instance 'assembler-6502)) 217 | -------------------------------------------------------------------------------- /6502/ops.lisp: -------------------------------------------------------------------------------- 1 | ;;;; ops.lisp 2 | 3 | (in-package #:specops.6502) 4 | 5 | (specops 0 (op0 &optional op1) *assembler-prototype-6502* 6 | ;; the table of 6502 instructions, including illegal instructions 7 | ((:tabular :cross-adding :matcher match-ops) (:duplex . of-decoder)) 8 | (( ) (#x0 ) (#x1 ) (#x2 ) (#x3 ) (#x4 ) (#x5 ) (#x6 ) (#x7 ) (#x8 ) (#x9 ) (#xA ) (#xB ) (#xC ) (#xD ) (#xE ) (#xF )) 9 | ((#x00) (:brk ) (:ora x in) ( jam ) (:slo x in) ( nop zp ) (:ora zp ) (:asl zp ) ( slo zp ) (:php) (:ora iv ) (:asl a) ( anc iv ) ( nop ab ) (:ora ab ) (:asl ab ) ( slo ab )) 10 | ((#x10) (:bpl rl) (:ora in y) ( jam ) (:slo in y) ( nop zp x) (:ora zp x) (:asl zp x) ( slo zp x) (:clc) (:ora ab y) ( nop ) ( slo ab y) ( nop ab x) (:ora ab x) (:asl ab x) ( slo ab x)) 11 | ((#x20) (:jsr ab) (:and x in) ( jam ) (:rla x in) (:bit zp ) (:and zp ) (:rol zp ) ( rla zp ) (:plp) (:and iv ) (:rol a) ( anc iv ) (:bit ab ) (:and ab ) (:rol ab ) ( rla ab )) 12 | ((#x30) (:bmi rl) (:and in y) ( jam ) (:rla in y) ( nop zp x) (:and zp x) (:rol zp x) ( rla zp x) (:sec) (:and ab y) ( nop ) ( rla ab y) ( nop ab x) (:and ab x) (:rol ab x) ( rla ab x)) 13 | ((#x40) (:rti ) (:eor x in) ( jam ) (:sre x in) ( nop zp ) (:eor zp ) (:lsr zp ) ( sre zp ) (:pha) (:eor iv ) (:lsr a) ( alr iv ) (:jmp ab ) (:eor ab ) (:lsr ab ) ( sre ab )) 14 | ((#x50) (:bvc rl) (:eor in y) ( jam ) (:sre in y) ( nop zp x) (:eor zp x) (:lsr zp x) ( sre zp x) (:cli) (:eor ab y) ( nop ) ( sre ab y) ( nop ab x) (:eor ab x) (:lsr ab x) ( sre ab x)) 15 | ((#x60) (:rts ) (:adc x in) ( jam ) (:rra x in) ( nop zp ) (:adc zp ) (:ror zp ) ( rra zp ) (:pla) (:adc iv ) (:ror a) ( arr iv ) (:jmp inw ) (:adc ab ) (:ror ab ) ( rra ab )) 16 | ((#x70) (:bvs rl) (:adc in y) ( jam ) (:rra in y) ( nop zp x) (:adc zp x) (:ror zp x) ( rra zp x) (:sei) (:adc ab y) ( nop ) ( rra ab y) ( nop ab x) (:adc ab x) (:ror ab x) ( rra ab x)) 17 | ((#x80) ( nop iv) (:sta x in) ( nop iv) (:sax x in) (:sty zp ) (:sta zp ) (:stx zp ) ( sax zp ) (:dey) (:nop iv ) (:txa ) ( ane iv ) (:sty ab ) (:sta ab ) (:stx ab ) ( sax ab )) 18 | ((#x90) (:bcc rl) (:sta in y) ( jam ) (:sha in y) (:sty zp x) (:sta zp x) (:stx zp y) ( sax zp y) (:tya) (:sta ab y) (:txs ) ( tas ab y) ( shy ab x) (:sta ab x) ( shx ab y) ( sha ab y)) 19 | ((#xA0) (:ldy iv) (:lda x in) (:ldx iv) (:lax x in) (:ldy zp ) (:lda zp ) (:ldx zp ) ( lax zp ) (:tay) (:lda iv ) (:tax ) ( lxa iv ) (:ldy ab ) (:lda ab ) (:ldx ab ) ( lax ab )) 20 | ((#xB0) (:bcs rl) (:lda in y) ( jam ) (:lax in y) (:ldy zp x) (:lda zp x) (:ldx zp y) ( lax zp y) (:clv) (:lda ab y) (:tsx ) ( las ab y) (:ldy ab x) (:lda ab x) (:ldx ab y) ( lax ab y)) 21 | ((#xC0) (:cpy iv) (:cmp x in) ( nop iv) (:dcp x in) (:cpy zp ) (:cmp zp ) (:dec zp ) ( dcp zp ) (:iny) (:cmp iv ) (:dex ) ( sbx iv ) (:cpy ab ) (:cmp ab ) (:dec ab ) ( dcp ab )) 22 | ((#xD0) (:bne rl) (:cmp in y) ( jam ) (:dcp in y) ( nop zp x) (:cmp zp x) (:dec zp x) ( dcp zp x) (:cld) (:cmp ab y) ( nop ) ( dcp ab y) ( nop ab x) (:cmp ab x) (:dec ab x) ( dcp ab x)) 23 | ((#xE0) (:cpx iv) (:sbc x in) ( nop iv) (:isc x in) (:cpx zp ) (:sbc zp ) (:inc zp ) ( isc zp ) (:inx) (:sbc iv ) (:nop ) ( usbc iv) (:cpx ab ) (:sbc ab ) (:inc ab ) ( isc ab )) 24 | ((#xF0) (:beq rl) (:sbc in y) ( jam ) (:isc in y) ( nop zp x) (:sbc zp x) (:inc zp x) ( isc zp x) (:sed) (:sbc ab y) ( nop ) ( isc ab y) ( nop ab x) (:sbc ab x) (:inc ab x) ( isc ab x))) 25 | -------------------------------------------------------------------------------- /6502/package.lisp: -------------------------------------------------------------------------------- 1 | ;;;; package.lisp 2 | 3 | (defpackage #:specops.6502 4 | (:use #:cl #:specops)) 5 | -------------------------------------------------------------------------------- /6502/specops.6502.asd: -------------------------------------------------------------------------------- 1 | ;;;; specops.6502.asd 2 | 3 | (asdf:defsystem #:specops.6502 4 | :description "Describe 6502 here" 5 | :author "Andrew Sengul" 6 | :license "BSD" 7 | :version "0.0.1" 8 | :serial t 9 | :depends-on ("specops") 10 | :components ((:file "package") 11 | (:file "base") 12 | (:file "ops"))) 13 | -------------------------------------------------------------------------------- /6502/templates.lisp: -------------------------------------------------------------------------------- 1 | ;;; templates.lisp 2 | 3 | (in-package #:specops.6502) 4 | 5 | (setf *assembler-prototype-6502* (make-instance 'assembler-6502)) 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2024 Andrew Sengul 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /m68k/base.lisp: -------------------------------------------------------------------------------- 1 | ;;;; base.lisp 2 | 3 | (in-package #:specops.m68k) 4 | 5 | (defvar *m68k-layout*) 6 | 7 | (setf *m68k-layout* 8 | (list :gp '(:d0 :d1 :d2 :d3 :d4 :d5 :d6 :d7) 9 | :ad '(:a0 :a1 :a2 :a3 :a4 :a5 :a6 :a7) 10 | :sp '(:usp :sr :ccr))) 11 | 12 | (defun rix (register &optional type) 13 | (typecase register 14 | (register (of-register-type-index register type)) 15 | (keyword (if type (values (position register (getf *m68k-layout* type)) 16 | type) 17 | (let ((position) (type-found)) 18 | (loop :for (type-key names) :on *m68k-layout* :by #'cddr :until position 19 | :do (setf position (position register names) 20 | type-found type-key)) 21 | (values position type-found)))))) 22 | 23 | (defun gpr-p (item) 24 | (and (keywordp item) (rix item :gp))) 25 | 26 | (defun adr-p (item) 27 | (and (keywordp item) (rix item :ad))) 28 | 29 | (deftype gpr () `(satisfies gpr-p)) 30 | 31 | (deftype adr () `(satisfies adr-p)) 32 | 33 | (defclass mas-m68k (mas-based mas-indexed mas-displaced) 34 | ()) 35 | 36 | (defclass mas-m68k-postinc (mas-m68k) 37 | ()) 38 | 39 | (defclass mas-m68k-predecr (mas-m68k) 40 | ()) 41 | 42 | (defclass mas-m68k-absolute (mas-absolute) 43 | ()) 44 | 45 | (defun mas-simple-p (item) 46 | (and (typep item 'mas-m68k) 47 | (not (or (typep item 'mas-m68k-predecr) 48 | (typep item 'mas-m68k-postinc))))) 49 | 50 | (defun mas-postinc-p (item) 51 | (typep item 'mas-m68k-postinc)) 52 | 53 | (defun mas-predecr-p (item) 54 | (typep item 'mas-m68k-predecr)) 55 | 56 | (defun mas-disp-p (item) 57 | (and (typep item 'mas-m68k) 58 | (mas-displ item) (adr-p (mas-base item)))) 59 | 60 | (defun mas-bi+disp-p (item) 61 | (and (typep item 'mas-m68k) 62 | (mas-displ item) (adr-p (mas-base item)) (adr-p (mas-index item)))) 63 | 64 | (defun mas-pc+disp-p (item) 65 | (and (typep item 'mas-m68k) 66 | (mas-displ item) (eq :pc (mas-base item)))) 67 | 68 | (defun mas-pci+disp-p (item) 69 | (and (typep item 'mas-m68k) 70 | (mas-displ item) (eq :pc (mas-base item)) (adr-p (mas-index item)))) 71 | 72 | (defun mas-abs-w-p (item) 73 | (and (typep item 'mas-m68k-absolute) 74 | (< (mas-addr item) (expt 2 16))) 75 | 76 | (defun mas-abs-l-p (item) 77 | (and (typep item 'mas-m68k-absolute) 78 | (< (mas-addr item) (expt 2 32))))) 79 | 80 | (defun location-p (item) 81 | (or (gpr-p item) (adr-p item) (typep item 'mas-m68k))) 82 | 83 | (deftype mas-simple () `(satisfies mas-simple-p)) 84 | 85 | (deftype mas-postinc () `(satisfies mas-postinc-p)) 86 | 87 | (deftype mas-predecr () `(satisfies mas-predecr-p)) 88 | 89 | (deftype mas-disp () `(satisfies mas-disp-p)) 90 | 91 | (deftype mas-bi+disp () `(satisfies mas-bi+disp-p)) 92 | 93 | (deftype mas-pc+disp () `(satisfies mas-pc+disp-p)) 94 | 95 | (deftype mas-pci+disp () `(satisfies mas-pci+disp-p)) 96 | 97 | (deftype mas-abs-w () `(satisfies mas-abs-w-p)) 98 | 99 | (deftype mas-abs-l () `(satisfies mas-abs-l-p)) 100 | 101 | (deftype location () `(satisfies location-p)) 102 | 103 | (defun @ (base &optional index displacement) 104 | (if (not (position base (getf *m68k-layout* :ad))) 105 | (error "Memory can only be addressed using an address register.") 106 | (make-instance 'mas-m68k :base base :index (if displacement index nil) 107 | :displ (or displacement index)))) 108 | 109 | (defun @+ (base) 110 | (if (not (position base (getf *m68k-layout* :ad))) 111 | (error "Memory can only be addressed using an address register.") 112 | (make-instance 'mas-m68k-postinc :base base))) 113 | 114 | (defun -@ (base) 115 | (if (not (position base (getf *m68k-layout* :ad))) 116 | (error "Memory can only be addressed using an address register.") 117 | (make-instance 'mas-m68k-predecr :base base))) 118 | 119 | (defun @= (addr) 120 | (make-instance 'mas-m68k-addr :addr addr)) 121 | 122 | (defun encode-location (location) 123 | (typecase location 124 | (gpr (values (rix location :gp) #b000)) 125 | (adr (values (rix location :ad) #b001)) 126 | (mas-simple (values (rix (mas-base location) :ad) #b010)) 127 | (mas-postinc (values (rix (mas-base location) :ad) #b011)) 128 | (mas-predecr (values (rix (mas-base location) :ad) #b100)) 129 | (mas-disp (values (rix (mas-base location) :ad) #b101 (mas-displ location))) 130 | (mas-bi+disp (values (rix (mas-base location) :ad) #b110)) 131 | (mas-abs-w (values #b000 #b111 (mas-addr location))) 132 | (mas-abs-l (values #b001 #b111 (mas-addr location))) 133 | (mas-pc+disp (values #b010 #b111 (mas-displ location))) 134 | (mas-pci+disp (values #b011 #b111)) 135 | (immediate (values #b100 #b111 (imm-value location))))) 136 | 137 | (defun encode-extension-word (width access) 138 | (if (or (typep access 'mas-bi+disp) (typep access 'mas-pci+disp)) 139 | (masque "MXXXS000.DDDDDDDD" 140 | (m 0) (x (rix (mas-index access) :ad)) 141 | (s (case width (:w 0) (:l 1) (t 0))) (d (mas-displ access))))) 142 | 143 | (defun derive-location (mode index &key base displacement (pa (lambda (a b) (declare (ignore a b)) 0))) 144 | (case mode 145 | (#b000 (nth index (getf *m68k-layout* :gp))) ;; Dn 146 | (#b001 (nth index (getf *m68k-layout* :ad))) ;; An 147 | (#b010 (list '@ (nth index (getf *m68k-layout* :ad)))) ;; (An) 148 | (#b011 (list '@+ (nth index (getf *m68k-layout* :ad)))) ;; (An)+ 149 | (#b100 (list '-@ (nth index (getf *m68k-layout* :ad)))) ;; -(An) 150 | (#b101 (list '@~ (nth index (getf *m68k-layout* :ad)) nil (funcall pa :read 1))) ;; (d16,An) 151 | (#b110 (unmasque "MXXXS000.DDDDDDDD" (funcall pa :read 1) (m x s d) ;; (d8,An,Xn) 152 | (list '@~ (nth index (getf *m68k-layout* :ad)) 153 | (nth x (getf *m68k-layout* :ad)) d))) 154 | (#b111 (case index 155 | (#b000 (list '@= (funcall pa :read 1))) ;; (xxx).W 156 | (#b001 (list '@= (funcall pa :read 2))) ;; (xxx).L 157 | (#b010 (list '@~ :pc nil (funcall pa :read 1))) ;; (d16,PC) 158 | (#b011 (unmasque "MXXXS000.DDDDDDDD" (funcall pa :read 1) (m x s d) ;; (d8,PC,Xn) 159 | (list '@~ :pc (nth x (getf *m68k-layout* :ad))))) 160 | (#b100 (funcall pa :read 1)))))) ;; #imm 161 | 162 | (defvar *assembler-prototype-m68k*) 163 | 164 | (defclass assembler-m68k (assembler-encoding assembler-masking) 165 | ((%storage :accessor asm-storage 166 | :allocation :class 167 | :initform *m68k-layout* 168 | :initarg :storage) 169 | (%lexicon :accessor asm-lexicon 170 | :allocation :class 171 | :initform (make-hash-table :test #'eq) 172 | :initarg :lexicon) 173 | (%segment :accessor asm-msk-segment 174 | :allocation :class 175 | :initform '(1) 176 | :initarg :segment) 177 | (%decoder :accessor asm-enc-decoder 178 | :allocation :class 179 | :initform (make-hash-table :test #'eq) 180 | :initarg :decoder) 181 | (%battery :accessor asm-msk-battery 182 | :allocation :class 183 | :initform (make-hash-table :test #'eq) 184 | :initarg :battery) 185 | (%domains :accessor asm-domains 186 | :initform *m68k-layout* 187 | :initarg :domains) 188 | (%breadth :accessor asm-breadth 189 | :allocation :class 190 | :initform 16 191 | :initarg :breadth) 192 | (%joiner :accessor asm-joiner 193 | :allocation :class 194 | :initform #'joinw 195 | :initarg :joiner))) 196 | 197 | (defun determine-width (width &optional prefix) 198 | (if prefix 199 | (case width (:b #b01) (:w #b11) (:l #b10)) 200 | (case width (:b #b00) (:w #b01) (:l #b10)))) 201 | 202 | (defun derive-width (width &optional prefix) 203 | (if prefix 204 | (case width (#b01 :b) (#b11 :w) (#b10 :l)) 205 | (case width (#b00 :b) (#b01 :w) (#b10 :l)))) 206 | 207 | (defun determine-width-bit (width) 208 | (case width (:w 0) (:l 1))) 209 | 210 | (defun derive-width-bit (width) 211 | (if (zerop width) :w :l)) 212 | 213 | (defun match-imm-width (addressing-mode width immediate) 214 | (if (not (and addressing-mode (= #b111 addressing-mode))) 215 | t (zerop (ash (imm-value immediate) (case width (:b -8) (:w -16) (:l -32)))))) 216 | 217 | (defun qualify-operand (operand type) 218 | (typecase type 219 | (symbol (case type 220 | (nil `(null ,operand)) 221 | (width `(and (wspec-name ,operand) 222 | (member (wspec-name ,operand) '(:b :w :l)))) 223 | (width-prefix `(and (wspec-name ,operand) 224 | (member (wspec-name ,operand) '(:b :w :l)))) 225 | (width-bit `(and (wspec-name ,operand) 226 | (member (wspec-name ,operand) '(:w :l)))) 227 | (gpr `(gpr-p ,operand)) 228 | (adr `(adr-p ,operand)) 229 | (label `(or (gpr-p ,operand) (symbolp ,operand))) 230 | (mas-all `(typep ,operand 'mas-m68k)) 231 | (mas-all-but-pc `(and (typep ,operand 'mas-m68k) 232 | (not (or (typep ,operand 'mas-bi+disp) 233 | (typep ,operand 'mas-pci+disp))))) 234 | (vector `(and (integerp (imm-value ,operand)) 235 | (<= 0 (imm-value ,operand) 15))) 236 | (reg-list `(listp ,operand)))) ;; this should be more detailed 237 | (list (destructuring-bind (type &rest qualities) type 238 | (case type 239 | (width `(member ,operand ',qualities)) 240 | (imm (case (first qualities) 241 | (:width `(and (imm-value ,operand) 242 | (< (imm-value ,operand) ,(expt 2 (second qualities))))) 243 | (:range `(and (imm-value ,operand) 244 | (<= ,(second qualities) (imm-value ,operand) ,(third qualities)))))) 245 | (idata `(and (imm-value ,operand) 246 | (< (imm-value ,operand) ,(expt 2 (first qualities))))) 247 | (mas `(and (typep ,operand 'mas-m68k) 248 | (or ,@(loop :for q :in qualities :collect `(typep ,operand ',q))))) 249 | (reg-fixed `(eq (reg-name ,operand) ,(first qualities)))))))) 250 | 251 | (defun verbalize-operand (spec) 252 | (flet ((mas-express (mas-type) 253 | (case mas-type 254 | (mas-simple "(An)") (mas-postinc "(An)+") (mas-predecr "-(An)") (mas-disp "(d16,An)") 255 | (mas-bi+disp "(d8,An,Xn)") (mas-abs-w "ABS.W") (mas-abs-l "ABS.L") 256 | (mas-pc+disp "(d16,PC)") (mas-pci+disp "(d8,PC,Xn)")))) 257 | (let ((mas-all-list '(mas-simple mas-postinc mas-predecr mas-disp mas-bi+disp 258 | mas-abs-w mas-abs-l mas-pc+disp mas-pci+disp)) 259 | (mas-no-pc-list '(mas-simple mas-postinc mas-predecr mas-disp mas-bi+disp mas-abs-w mas-abs-l))) 260 | (format nil "~a~%" (typecase spec 261 | (symbol (case spec 262 | (nil "null") 263 | (width "width : any") 264 | (width-bit "width : B / W") 265 | (width-prefix "width : any") 266 | (gpr "general purpose register : any") 267 | (adr "address register : any") 268 | (label "label") 269 | (mas-all (format nil "memory access : ~{~a ~}" 270 | (mapcar #'mas-express mas-all-list))) 271 | (mas-all-but-pc (format nil "memory access : ~{~a ~}" 272 | (mapcar #'mas-express mas-no-pc-list))) 273 | (vector "immediate vector index: 0-15") 274 | (reg-list "register list"))) 275 | (list (destructuring-bind (type &rest qualities) spec 276 | (case type 277 | (width (format nil "width : ~{~a~^ ~^/ ~}" qualities)) 278 | (imm (case (first qualities) 279 | (:width (format nil "immediate value : ~d bits" 280 | (second qualities))) 281 | (:range (format nil "immediate value: ~d to ~d" 282 | (second qualities) (third qualities))))) 283 | (idata (format nil "immediate data : ~a bits" (first qualities))) 284 | (mas (format nil "memory access : ~{~a ~}" 285 | (mapcar #'mas-express qualities))) 286 | (reg-fixed (format nil "~a (fixed register)" 287 | (first qualities))))))))))) 288 | 289 | (defun derive-operand (spec) 290 | (destructuring-bind (operand &rest types) spec 291 | (cons 'cond (loop :for type :in types 292 | :collect 293 | (list (qualify-operand operand type) 294 | (typecase type 295 | (symbol (case type 296 | (nil nil) 297 | (width `(determine-width (wspec-name ,operand))) 298 | (width-prefix `(determine-width (wspec-name ,operand) t)) 299 | (width-bit `(determine-width-bit (wspec-name ,operand))) 300 | ((gpr adr mas-all mas-all-but-pc mas-simple mas-postinc mas-predecr 301 | mas-disp mas-bi+disp mas-pc+disp mas-pci+disp mas-abs) 302 | `(encode-location ,operand)) 303 | (label operand) 304 | (vector `(imm-value ,operand)) 305 | (reg-list operand))) 306 | (list (destructuring-bind (type &rest qualities) type 307 | (declare (ignore qualities)) 308 | (case type 309 | (width `(determine-width ,operand)) 310 | (imm (list 'imm-value operand)) 311 | (idata (list 'encode-location operand)) 312 | (mas `(encode-location ,operand)) 313 | (reg-fixed `(reg-name ,operand))))))))))) 314 | 315 | (defmacro determine (specs &optional bindings &body body) 316 | "This placeholder macro is not meant to be evaluated but to inform indentation algorithms; (determine) forms will be converted to determine-in-context forms as (specops) forms are expanded." 317 | (list specs bindings body)) 318 | 319 | ;; (defmethod of-storage ((assembler assembler-m68k) key) 320 | ;; (if (typep key 'mas-m68k) 321 | ;; (values (rix (mas-base key) :ad) 322 | ;; (typecase key (mas-m68k-postinc #b011) (mas-m68k-predecr #b100) 323 | ;; (t (if (not (mas-displ key)) 324 | ;; #b010 (if (mas-index key) #b110 #b101))))) 325 | ;; ;; (multiple-value-bind (index type) (call-next-method) 326 | ;; ;; (values index (case type (:gp #b000) (:ad #b001)))) 327 | ;; (multiple-value-bind (index type) (rix key) 328 | ;; (values index (case type (:gp #b000) (:ad #b001)))) 329 | ;; )) 330 | 331 | ;; (defmethod locate ((assembler assembler-m68k) asm-sym items) 332 | ;; (let ((domains (copy-tree (asm-domains assembler))) 333 | ;; (bound (loop :for item :in items :when (member :bind item :test #'eq) :collect item)) 334 | ;; (unbound (loop :for item :in items :unless (member :bind item :test #'eq) :collect item))) 335 | ;; ;; (print (list :bu bound unbound domains)) 336 | 337 | ;; (append (loop :for item :in bound 338 | ;; :collect (destructuring-bind (symbol type &rest params) item 339 | ;; ;; (print (list :dom domains)) 340 | ;; ;; (print (list :par params type (getf *m68k-storage* type))) 341 | ;; (let ((bind-position (getf params :bind))) 342 | ;; (setf (rest (assoc type domains)) 343 | ;; (remove bind-position (rest (assoc type domains)))) 344 | ;; (list symbol `(reserve ,asm-sym ,type ,bind-position))))) 345 | ;; (loop :for item :in unbound 346 | ;; :collect (destructuring-bind (symbol type &rest params) item 347 | ;; (declare (ignore params)) 348 | ;; (list symbol (let ((random-index 349 | ;; (nth (random (length (rest (assoc type domains)))) 350 | ;; (rest (assoc type domains))))) 351 | ;; (setf (rest (assoc type domains)) 352 | ;; (remove random-index (rest (assoc type domains)))) 353 | ;; `(reserve ,asm-sym ,type ,random-index)))))))) 354 | 355 | ;; (defmethod reserve ((assembler assembler-m68k) &rest params) 356 | ;; (destructuring-bind (type index &rest _) params 357 | ;; (declare (ignore _)) 358 | ;; (aref (getf (asm-storage assembler) type) index))) 359 | 360 | #| 361 | 362 | (assemble *assembler-prototype-m68k* 363 | ((:store (abc :gpr) (def :gpr))) 364 | (:addi :b 10 abc) 365 | (:addi :b 330 def)) 366 | 367 | (assemble *assembler-prototype-m68k* 368 | ((:store (abc :gpr) (def :gpr))) 369 | (:addi :b 10 abc) 370 | :hello 371 | (:nop) 372 | (:ori :b 330 def) 373 | (:bra :hello) 374 | (:ori :b 330 def) 375 | :gg (:addi :b 10 abc)) 376 | 377 | (@+ abc) 378 | 379 | (-@ abc) 380 | 381 | (@ abc 50) 382 | 383 | 384 | |# 385 | -------------------------------------------------------------------------------- /m68k/package.lisp: -------------------------------------------------------------------------------- 1 | ;;;; package.lisp 2 | 3 | (defpackage #:specops.m68k 4 | (:use #:cl #:specops)) 5 | -------------------------------------------------------------------------------- /m68k/specops.m68k.asd: -------------------------------------------------------------------------------- 1 | ;;;; m68k.asd 2 | 3 | (asdf:defsystem #:specops.m68k 4 | :description "Assembler framework for Motorola 68000 architectures based on SpecOps." 5 | :author "Andrew Sengul" 6 | :license "BSD" 7 | :version "0.0.1" 8 | :serial t 9 | :depends-on ("specops") 10 | :components ((:file "package") 11 | (:file "base") 12 | (:file "templates") 13 | (:file "ops"))) 14 | -------------------------------------------------------------------------------- /m68k/templates.lisp: -------------------------------------------------------------------------------- 1 | ;;;; templates.lisp 2 | 3 | (in-package #:specops.m68k) 4 | 5 | (setf *assembler-prototype-m68k* (make-instance 'assembler-m68k)) 6 | 7 | (defun form-process (symbol options form) 8 | (declare (ignore options)) 9 | (if (eql 'determine (first form)) 10 | (append (list 'determine-in-context 11 | (list :qualify #'qualify-operand :verbalize #'verbalize-operand 12 | :derive #'derive-operand) 13 | symbol) 14 | (rest form)))) 15 | 16 | (defmacro specop-68k (symbol operands &body params) 17 | (let* ((options (and (listp (first params)) 18 | (listp (caar params)) 19 | (keywordp (caaar params)) 20 | (first params))) 21 | (operations (if options (rest params) params))) 22 | (cons 'specops (append (list symbol operands '*assembler-prototype-m68k*) 23 | (cons (cons (cons :process-forms 'form-process) 24 | options) 25 | operations))))) 26 | 27 | ;; (defmacro specop (symbol operands &body params) 28 | ;; (specify-ops *assembler-prototype-m68k* '*assembler-prototype-m68k* symbol operands params)) 29 | 30 | (defmacro readop-68k (symbol args &body body) 31 | (let ((symbol (macroexpand symbol)) 32 | (function `#'(lambda ,args (declare (ignorable ,@args)) ,@body))) 33 | (if (numberp symbol) 34 | `(of-decoder *assembler-prototype-m68k* ,symbol ,function) 35 | `(of-battery *assembler-prototype-m68k* ,(intern (string symbol) "KEYWORD") ,function)))) 36 | 37 | ;; (defmacro address (operands bindings &body body) 38 | ;; (labels ((process-level (ops bns) 39 | ;; (if (not ops) 40 | ;; body `((multiple-value-bind ,(first bns) 41 | ;; (if (numberp ,(first ops)) 42 | ;; (list ,(first ops)) 43 | ;; (of-storage *assembler-prototype-m68k* ,(first ops))) 44 | ;; ,@(process-level (rest ops) (rest bns))))))) 45 | ;; (first (process-level operands bindings)))) 46 | -------------------------------------------------------------------------------- /package.lisp: -------------------------------------------------------------------------------- 1 | ;;;; package.lisp 2 | 3 | (defpackage #:specops 4 | (:use #:cl) 5 | (:export #:make-array-writer #:width-spec #:wspec-name #:wspec-bits 6 | #:register #:reg-name #:reg-index #:reg-type #:of-register-type-index 7 | #:immediate #:imm-value #:make-immediate ;; #:imm 8 | #:memory-access-scheme 9 | #:mas-based #:mas-base #:mas-indexed #:mas-index #:mas-displaced #:mas-displ 10 | #:mas-scaling-displaced #:mas-sdisp-scale #:mas-absolute #:mas-addr 11 | #:assembler #:assembler-encoding #:assembler-masking 12 | #:asm-name #:asm-type #:asm-storage #:asm-lexicon 13 | #:asm-domains #:asm-reserve #:asm-breadth #:asm-joiner #:asm-exmodes 14 | #:asm-enc-breadth #:asm-enc-decoder #:asm-msk-segment #:asm-msk-battery 15 | #:join #:joinw #:program-api #:of-program 16 | #:flipbits #:masque #:unmasque #:mqbase 17 | #:types-of #:derive-domains #:of-lexicon #:of-decoder #:of-battery #:of-storage 18 | #:storage-type-p #:specify-ops #:qualify-ops 19 | #:locate #:compose #:process-operands #:extend-clauses #:clause-processor #:label-delta 20 | #:assemble #:specops #:readops #:interpret 21 | #:match-types #:to-tag #:determine-in-context #:complete-dforms 22 | )) 23 | 24 | -------------------------------------------------------------------------------- /specops.asd: -------------------------------------------------------------------------------- 1 | ;;;; specops.asd 2 | 3 | (asdf:defsystem #:specops 4 | :description "A framework for creating assemblers." 5 | :author "Andrew Sengul" 6 | :license "BSD" 7 | :version "0.0.1" 8 | :serial t 9 | :components ((:file "package") 10 | (:file "specops"))) 11 | -------------------------------------------------------------------------------- /superh/base.lisp: -------------------------------------------------------------------------------- 1 | ;;;; superh.lisp 2 | 3 | (in-package #:specops.superh) 4 | 5 | (defvar *super-h-layout*) 6 | (defvar *assembler-prototype-super-h*) 7 | 8 | (setf *super-h-layout* 9 | (list :gp '(:r0 :r1 :r2 :r3 :r4 :r5 :r6 :r7 :r8 :r9 :r10 :r11 :r12 :r13 :r14 :r15) 10 | :fp '(:f0 :f1 :f2 :f3 :f4 :f5 :f6 :f7 :f8 :f9 :f10 :f11 :f12 :f13 :f14 :f15) 11 | :dp '(:dr0 :dr2 :dr4 :dr6 :dr8 :dr10 :dr12 :dr14) 12 | :fv '(:fv0 :fv4 :fv8 :fv12) 13 | :xf '(:xf0 :xf1 :xf2 :xf3 :xf4 :xf5 :xf6 :xf7 14 | :xf8 :xf9 :xf10 :xf11 :xf12 :xf13 :xf14 :xf15) 15 | :xd '(:xd0 :xd2 :xd4 :xd6 :xd8 :xd10 :xd12 :xd14) 16 | :gb '(:rb0 :rb1 :rb2 :rb3 :rb4 :rb5 :rb6 :rb7) 17 | :spr '(:sr :gbr :vbr :mach :macl :pr :pc 18 | :fpul :xmtrx) 19 | :dspr '(:dsr :a0 :x0 :x1 :y0 :y1))) 20 | 21 | (defun rix (register &optional type) 22 | (typecase register 23 | (register (of-register-type-index register type)) 24 | (keyword (if type (values (position register (getf *super-h-layout* type)) 25 | type) 26 | (let ((position) (type-found)) 27 | (loop :for (type-key names) :on *super-h-layout* :by #'cddr :until position 28 | :do (setf position (position register names) 29 | type-found type-key)) 30 | (values position type-found)))))) 31 | 32 | (defun gpr-p (item) 33 | (and (keywordp item) (rix item :gp))) 34 | 35 | (defun gprb-p (item) 36 | (and (keywordp item) (rix item :gb))) 37 | 38 | (defun fpr-p (item) 39 | (and (keywordp item) (rix item :fp))) 40 | 41 | (defun fvr-p (item) 42 | (and (keywordp item) (rix item :fv))) 43 | 44 | (defun dpr-p (item) 45 | (and (keywordp item) (rix item :dp))) 46 | 47 | (defun xdr-p (item) 48 | (and (keywordp item) (rix item :xd))) 49 | 50 | (deftype gpr () `(satisfies gpr-p)) 51 | 52 | (deftype gprb () `(satisfies gprb-p)) 53 | 54 | (deftype fpr () `(satisfies fpr-p)) 55 | 56 | (deftype fvr () `(satisfies fvr-p)) 57 | 58 | (deftype dpr () `(satisfies dpr-p)) 59 | 60 | (deftype xdr () `(satisfies xdr-p)) 61 | 62 | (defclass mas-super-h (mas-based mas-indexed mas-displaced) 63 | ((%qualifier :accessor mas-super-h-qualifier 64 | :initform nil 65 | :initarg :qualifier))) 66 | 67 | (defclass mas-super-h-postinc (mas-super-h) 68 | ()) 69 | 70 | (defclass mas-super-h-predecr (mas-super-h) 71 | ()) 72 | 73 | (defclass mas-super-h-bd (mas-super-h mas-displaced) 74 | ()) 75 | 76 | (defclass mas-super-h-pc (mas-displaced) 77 | ()) 78 | 79 | (defun @ (base) 80 | (make-instance 'mas-super-h :base base)) 81 | 82 | (defun @+ (base) 83 | (make-instance 'mas-super-h-postinc :base base)) 84 | 85 | (defun -@ (base) 86 | (make-instance 'mas-super-h-predecr :base base)) 87 | 88 | (defun @0 (index) 89 | (make-instance 'mas-super-h :base :r0 :index index)) 90 | 91 | (defun @> (base displacement) 92 | (make-instance 'mas-super-h :base base :displ displacement)) 93 | 94 | (defun @pc (displacement) 95 | (make-instance 'mas-super-h :base :pc :displ displacement)) 96 | 97 | (defun @gb (displacement) 98 | (make-instance 'mas-super-h :base :gbr :displ displacement)) 99 | 100 | (defun @gbr0 () 101 | (make-instance 'mas-super-h :base :gbr :index :r0)) 102 | 103 | (defun @@tbr (displacement) 104 | (make-instance 'mas-super-h :base :tbr :displ displacement)) 105 | 106 | (defun mas-simple-p (item) 107 | (and (typep item 'mas-super-h) 108 | (not (mas-displ item)) 109 | (not (typep item 'mas-super-h-predecr)) 110 | (not (typep item 'mas-super-h-postinc)))) 111 | 112 | (defun mas-predecr-p (item) 113 | (typep item 'mas-super-h-predecr)) 114 | 115 | (defun mas-postinc-p (item) 116 | (typep item 'mas-super-h-postinc)) 117 | 118 | (defun mas-b+rzero-p (item) 119 | (and (typep item 'mas-super-h) 120 | (eq :r0 (mas-base item)) 121 | (typep (mas-index item) 'gpr))) 122 | 123 | (defun mas-disp-p (item) 124 | (and (typep item 'mas-super-h) 125 | (mas-displ item) 126 | (typep (mas-base item) 'gpr))) 127 | 128 | (defun mas-disp4-p (item) 129 | (and (typep item 'mas-super-h) 130 | (mas-displ item) 131 | (zerop (ash (mas-displ item) -4)) 132 | (gpr-p (mas-base item)))) 133 | 134 | (defun mas-disp8-p (item) 135 | (and (typep item 'mas-super-h) 136 | (mas-displ item) 137 | (zerop (ash (mas-displ item) -8)) 138 | (gpr-p (mas-base item)))) 139 | 140 | (defun mas-disp12-p (item) 141 | (and (typep item 'mas-super-h) 142 | (mas-displ item) 143 | (zerop (ash (mas-displ item) -12)) 144 | (gpr-p (mas-base item)))) 145 | 146 | (defun mas-disp20-p (item) 147 | (and (typep item 'mas-super-h) 148 | (mas-displ item) 149 | (zerop (ash (mas-displ item) -20)) 150 | (gpr-p (mas-base item)))) 151 | 152 | (defun mas-pc+disp-p (item) 153 | (and (typep item 'mas-super-h) 154 | (mas-displ item) 155 | (eq :pc (mas-base item)))) 156 | 157 | (defun mas-gb+disp-p (item) 158 | (and (typep item 'mas-super-h) 159 | (mas-displ item) 160 | (zerop (ash (mas-displ item) -8)) 161 | (eq :gbr (mas-base item)))) 162 | 163 | (defun mas-gb+rzro-p (item) 164 | (and (typep item 'mas-super-h) 165 | (eq :gbr (mas-base item)) 166 | (eq :r0 (mas-index item)))) 167 | 168 | (defun mas-tb+disp-p (item) 169 | (and (typep item 'mas-super-h) 170 | (eq :tbr (mas-base item)) 171 | (mas-displ item))) 172 | 173 | (deftype mas-simple () `(satisfies mas-simple-p)) 174 | 175 | (deftype mas-predecr () `(satisfies mas-predecr-p)) 176 | 177 | (deftype mas-postinc () `(satisfies mas-postinc-p)) 178 | 179 | (deftype mas-b+rzero () `(satisfies mas-b+rzero-p)) 180 | 181 | (deftype mas-disp () `(satisfies mas-disp-p)) 182 | 183 | (deftype mas-disp4 () `(satisfies mas-disp4-p)) 184 | 185 | (deftype mas-disp8 () `(satisfies mas-disp8-p)) 186 | 187 | (deftype mas-disp12 () `(satisfies mas-disp12-p)) 188 | 189 | (deftype mas-disp20 () `(satisfies mas-disp20-p)) 190 | 191 | (deftype mas-pc+disp () `(satisfies mas-pc+disp-p)) 192 | 193 | (deftype mas-gb+disp () `(satisfies mas-gb+disp-p)) 194 | 195 | (deftype mas-gb+rzro () `(satisfies mas-gb+rzro-p)) 196 | 197 | (deftype mas-tb+disp () `(satisfies mas-tb+disp-p)) 198 | 199 | (defun drv-gpr (index) 200 | (nth index (getf *super-h-layout* :gp))) 201 | 202 | (defun drv-gprb (index) 203 | (nth index (getf *super-h-layout* :gpb))) 204 | 205 | (defun drv-fpr (index) 206 | (nth index (getf *super-h-layout* :fp))) 207 | 208 | (defun drv-fvr (index) 209 | (nth index (getf *super-h-layout* :fv))) 210 | 211 | (defun drv-dpr (index) 212 | (nth index (getf *super-h-layout* :dp))) 213 | 214 | (defun drv-xdr (index) 215 | (nth index (getf *super-h-layout* :xd))) 216 | 217 | (defun rs16 (number) 218 | (ash number -16)) 219 | 220 | (defun lo16 (number) 221 | (logand number #xFFFF)) 222 | 223 | (defclass assembler-super-h (assembler-encoding assembler-masking) 224 | ((%storage :accessor asm-storage 225 | :allocation :class 226 | :initform *super-h-layout* 227 | :initarg :storage) 228 | (%lexicon :accessor asm-lexicon 229 | :allocation :class 230 | :initform (make-hash-table :test #'eq) 231 | :initarg :lexicon) 232 | (%breadth :accessor asm-msk-segment 233 | :allocation :class 234 | :initform '(2) 235 | :initarg :breadth) 236 | (%decoder :accessor asm-enc-decoder 237 | :allocation :class 238 | :initform (make-hash-table :test #'eq) 239 | :initarg :decoder) 240 | (%battery :accessor asm-msk-battery 241 | :allocation :class 242 | :initform (make-hash-table :test #'eq) 243 | :initarg :battery) 244 | (%domains :accessor asm-domains 245 | :initform nil 246 | :initarg :domains) 247 | (%joiner :accessor asm-joiner 248 | :allocation :class 249 | :initform #'joinw 250 | :initarg :joiner))) 251 | 252 | (setf *assembler-prototype-super-h* (make-instance 'assembler-super-h :type '(:sh1))) 253 | 254 | (defun encode-location (location) 255 | (typecase location 256 | (mas-pc+disp (mas-displ location)) 257 | (mas-gb+disp (mas-displ location)) 258 | (mas-tb+disp (mas-displ location)) 259 | (mas-superh (values (mas-base location) (mas-displ location))))) 260 | 261 | (defun qualify-operand (operand type) 262 | (typecase type 263 | (symbol (case type 264 | (width `(member (wspec-name ,operand) '(:b :w :l))) 265 | ((gpr gprb fpr fvr dpr xfr xdr) `(typep ,operand ',type)))) 266 | (list (destructuring-bind (type &rest qualities) type 267 | (case type 268 | (width `(member ,operand ',qualities)) 269 | (imm `(and (imm-value ,operand) 270 | (< (imm-value ,operand) ,(expt 2 (first qualities))))) 271 | (mas `(and (typep ,operand 'mas-superh) 272 | (or ,@(loop :for q :in qualities :collect `(typep ,operand ',q))))) 273 | (reg-by-name `(member (reg-name ,operand) ',qualities)) 274 | (label-offset `(or (gpr-p ,operand) (symbolp ,operand)))))))) 275 | 276 | (defun verbalize-operand (spec) 277 | (flet ((mas-express (mas-type) 278 | (case mas-type 279 | (mas-simple "@(Rx)") (mas-postinc "@(Rx)+") (mas-predecr "-@(Rx)") 280 | (mas-postinc-r15 "@R15+") (mas-predecr-r15 "-@R15") (mas-disp4 "@(disp4,Rx)") 281 | (mas-disp8 "@(disp8,Rx)") (mas-disp12 "@(disp12,Rx)") (mas-b+rzero "@(R0,Rx)") 282 | (mas-gb+rzro "@(R0,GBR)") (mas-pc+disp "@(disp,PC)") (mas-gb+disp "@(disp8,GBR)") 283 | (mas-tb+disp "@@(disp8,TBR)")))) 284 | (format nil "~a~%" (typecase spec 285 | (symbol (case spec 286 | (width "width : any") 287 | (gpr "general purpose register : any") 288 | (gprb "general purpose register bank : any") 289 | (fpr "floating point register : any") 290 | (fvr "floating point register vector : any") 291 | (dpr "double-precision floating point register : any") 292 | (xfr "single extended floating point register : any") 293 | (xdr "single extended floating point register pair : any"))) 294 | (list (destructuring-bind (type &rest qualities) spec 295 | (case type 296 | (width (format nil "width : ~{~a~^ ~^/ ~}" qualities)) 297 | (imm (format nil "immediate value : ~d bits" (first qualities))) 298 | (mas (format nil "memory access : ~{~a ~}" 299 | (mapcar #'mas-express qualities))) 300 | (reg-by-name (format nil "specific register~a: ~{~a ~}" 301 | (if (second qualities) #\s "") qualities)) 302 | (label-offset "label / offset")))))))) 303 | 304 | (defun derive-operand (spec) 305 | (destructuring-bind (operand &rest types) spec 306 | (cons 'cond (loop :for type :in types 307 | :collect 308 | (list (qualify-operand operand type) 309 | (typecase type 310 | (symbol (case type 311 | (width `(determine-width (wspec-name ,operand))) 312 | ((gpr gprb fpr fvr dpr xfr xdr) 313 | (let ((file-sym (case type (gpr :gp) (gprb :gb) (fpr :fp) 314 | (dpr :dp) (fvr :fv) (xfr :xf) (xdr :xd)))) 315 | `(position (reg-name ,operand) 316 | (getf *super-h-layout* ,file-sym)))))) 317 | (list (destructuring-bind (type &rest qualities) type 318 | (case type 319 | (width `(determine-width ,operand)) 320 | (imm (list 'imm-value operand)) 321 | (mas `(encode-location ,operand)) 322 | (reg-by-name `(reg-name ,operand)) 323 | (label-offset (destructuring-bind (api-fnsym length offset) qualities 324 | (list api-fnsym :label length offset operand)))))))))))) 325 | 326 | (defmacro determine (specs &optional bindings &body body) 327 | "This placeholder macro is not meant to be evaluated but to inform indentation algorithms; (determine) forms will be converted to determine-in-context forms as (specops) forms are expanded." 328 | (list specs bindings body)) 329 | 330 | (defun form-process (symbol options form) 331 | (declare (ignore options)) 332 | (if (eql 'determine (first form)) 333 | (append (list 'determine-in-context 334 | (list :qualify #'qualify-operand :verbalize #'verbalize-operand 335 | :derive #'derive-operand) 336 | symbol) 337 | (rest form)))) 338 | 339 | (defmacro specops-sh (symbol operands &body params) 340 | (let* ((options (and (listp (first params)) 341 | (listp (caar params)) 342 | (keywordp (caaar params)) 343 | (first params))) 344 | (operations (if options (rest params) params))) 345 | (cons 'specops (append (list symbol operands '*assembler-prototype-super-h*) 346 | (cons (cons (cons :process-forms 'form-process) 347 | options) 348 | operations))))) 349 | 350 | ;; (defmacro specops-sh (symbol operands &body params) 351 | ;; (cons 'specops (append (list symbol operands '*assembler-prototype-super-h*) params))) 352 | 353 | (defmacro readops-sh (symbol operands &body params) 354 | (cons 'readops (append (list symbol operands '*assembler-prototype-super-h*) params))) 355 | -------------------------------------------------------------------------------- /superh/package.lisp: -------------------------------------------------------------------------------- 1 | ;;;; package.lisp 2 | 3 | (defpackage #:specops.superh 4 | (:use #:cl #:specops)) 5 | -------------------------------------------------------------------------------- /superh/specops.superh.asd: -------------------------------------------------------------------------------- 1 | ;;;; super-h.asd 2 | 3 | (asdf:defsystem #:specops.superh 4 | :description "Describe super-h here" 5 | :author "Andrew Sengul" 6 | :license "BSD" 7 | :version "0.0.1" 8 | :serial t 9 | :depends-on ("specops") 10 | :components ((:file "package") 11 | (:file "base") 12 | (:file "ops"))) 13 | -------------------------------------------------------------------------------- /system-z/package.lisp: -------------------------------------------------------------------------------- 1 | ;;;; package.lisp 2 | 3 | (defpackage #:specops.system-z 4 | (:use #:cl #:specops)) 5 | -------------------------------------------------------------------------------- /system-z/specops.system-z.asd: -------------------------------------------------------------------------------- 1 | ;;;; specops.system-z.asd 2 | 3 | (asdf:defsystem #:specops.system-z 4 | :description "Describe system-z here" 5 | :author "Your Name " 6 | :license "BSD" 7 | :version "0.0.1" 8 | :serial t 9 | :depends-on ("specops") 10 | :components ((:file "package") 11 | (:file "base") 12 | (:file "ops"))) 13 | -------------------------------------------------------------------------------- /wasm/base.lisp: -------------------------------------------------------------------------------- 1 | ;;;; wasm.lisp 2 | 3 | (in-package #:specops.wasm) 4 | 5 | (defclass assembler-wasm (assembler-encoding) 6 | ((%lexicon :accessor asm-lexicon 7 | :allocation :class 8 | :initform (make-hash-table :test #'eq) 9 | :initarg :lexicon) 10 | (%decoder :accessor asm-enc-decoder 11 | :allocation :class 12 | :initform (make-hash-table :test #'eq) 13 | :initarg :decoder))) 14 | -------------------------------------------------------------------------------- /wasm/ops.lisp: -------------------------------------------------------------------------------- 1 | ;;;; ops.lisp 2 | 3 | (in-package #:specops.wasm) 4 | 5 | ;; TRUNCATE > TRN, CONVERT > CNV, DEMOTE > DEMO, PROMOTE > PROM, REINTERPRET > REI, *RETURN_CALL_INDIRECT > *RCL_IND, *RETURN_CALL_REF > *RCL_REF, 6 | 7 | (specops 0 (op0 &optional op1) *assembler-prototype-wasm* 8 | ;; the main table of WASM instructions 9 | ((:tabular :cross-adding :matcher match-ops)) 10 | (( ) (#x0 ) (#x1 ) (#x2 ) (#x3 ) (#x4 ) (#x5 ) (#x6 ) (#x7 ) (#x8 ) (#x9 ) (#xA ) (#xB ) (#xC ) (#xD ) (#xE ) (#xF )) 11 | ((#x00) () (:nop ) (:block ) (:loop ) (:if ) (:else ) (:*try ) (:*catch ) (:*throw ) (:*rethrow ) (:*throw-ref ) (:end ) (:br ) (:br-if ) (:br-table ) (:return )) 12 | ((#x10) (:call ) (:call-indirect ) (:*return-call ) (:*rcl-ind ) (:*call-ref ) (:*rcl-ref ) () () (:*delegate ) (:*catch-all ) (:drop ) (:select ) (:*select t) () () (:*try-table )) 13 | ((#x20) (:get local) (:set local) (:tee local) (:get global) (:set global) (:get *table) (:set *table) () (:load i32) (:load i64) (:load f32) (:load f64) (:load-s i32 8) (:load-u i32 8) (:load-s i32 16) (:load-u *i32 16)) 14 | ((#x30) (:load-s i64 8) (:load-u i64 8) (:load-s i64 16) (:load-u i64 16) (:load-s i64 32) (:load-u i64 32) (:store i32) (:store i64) (:store f32) (:store f64) (:store i32 8) (:store i32 16) (:store i64 8) (:store i64 16) (:store i64 32) (:memory size)) 15 | ((#x40) (:memory grow) (:const i32) (:const i64) (:const f32) (:const f64) (:eqz i32) (:eq i32) (:ne i32) (:lt-s i32) (:lt-u i32) (:gt-s i32) (:gt-u i32) (:le-s i32) (:le-u i32) (:ge-s i32) (:ge-u i32)) 16 | ((#x50) (:eqz i64) (:eq i64) (:ne i64) (:lt-s i64) (:lt-u i64) (:gt-s i64) (:gt-u i64) (:le-s i64) (:le-u i64) (:ge-s i64) (:ge-u i64) (:eq f32) (:ne f32) (:lt f32) (:gt f32) (:le f32)) 17 | ((#x60) (:ge f32) (:eq f64) (:ne f64) (:lt f64) (:gt f64) (:le f64) (:ge f64) (:clz i32) (:ctz i32) (:popcnt i32) (:add i32) (:sub i32) (:mul i32) (:div-s i32) (:div-u i32) (:rem-s i32)) 18 | ((#x70) (:rem-u i32) (:and i32) (:or i32) (:xor i32) (:shl i32) (:shr-s i32) (:shr-u i32) (:rotl i32) (:rotr i32) (:clz i64) (:ctz i64) (:popcnt i64) (:add i64) (:sub i64) (:mul i64) (:div-s i64)) 19 | ((#x80) (:div-u i64) (:rem-s i64) (:rem-u i64) (:and i64) (:or i64) (:xor i64) (:shl i64) (:shr-s i64) (:shr-u i64) (:rotl i64) (:rotr i64) (:abs f32) (:neg f32) (:ceil f32) (:floor f32) (:trn f32)) 20 | ((#x90) (:nearest f32) (:sqrt f32) (:add f32) (:sub f32) (:mul f32) (:div f32) (:min f32) (:max f32) (:copysign f32) (:abs f64) (:neg f64) (:ceil f64) (:floor f64) (:trn f64) (:nearest f64) (:sqrt f64)) 21 | ((#xA0) (:add f64) (:sub f64) (:mul f64) (:div f64) (:min f64) (:max f64) (:copysign f64) (:wrap i32 i64) (:trn-s i32 f32) (:trn-u i32 f32) (:trn-s i32 f64) (:trn-u i32 f64) (:ext-s i64 i32) (:ext-u i64 i32) (:trn-s i64 f32) (:trn-u i64 f32)) 22 | ((#xB0) (:trn-s i64 f64) (:trn-u i64 f64) (:cnv-s f32 i32) (:cnv-u f32 i32) (:cnv-s f32 i64) (:cnv-u f32 i64) (:dem f32 f64) (:cnv-s f64 i32) (:cnv-u f64 i32) (:cnv-s f64 i64) (:cnv-u f64 i64) (:prm f64 f32) (:rei i32 f32) (:rei i64 f64) (:rei f32 i32) (:rei f64 i64)) 23 | ((#xC0) (:extend-s *i32 8) (:extend-s *i32 16) (:extend-s *i64 8) (:extend-s *i64 16) (:extend-s *i64 32)) 24 | ((#xD0) (:null *ref) (:is-null *ref) (:func *ref) (:as-non-null *ref) (:*br-on-null ) (:eq *ref) (:*br-on-non-null))) 25 | 26 | (specops #xFC (op0 &optional op1) *assembler-prototype-wasm* 27 | ((:tabular :cross-adding :matcher match-ops)) 28 | (( ) (#x0 ) (#x1 ) (#x2 ) (#x3 ) (#x4 ) (#x5 ) (#x6 ) (#x7 ) (#x8 ) (#x9 ) (#xA ) (#xB ) (#xC ) (#xD ) (#xE ) (#xF )) 29 | ((#xFC00) (:trunc-sat-s i32 f32) (:trunc-sat-u i32 f32) (:trunc-sat-s i32 f64) (:trunc-sat-u i32 f64) (:trunc-sat-s i64 f32) (:trunc-sat-u i64 f32) (:trunc-sat-s i64 f64) (:trunc-sat-u i64 f64) (:init memory) (:drop data) (:copy memory) (:fill memory) (:init table) (:drop elem) (:copy table) (:grow table)) 30 | ((#xFC10) (:size table) (:fill table))) 31 | 32 | 33 | ;; REPLACE_LANE > RPLANE, EXTRACT_LANE > EXLANE, RELAXED_NMADD > RXNMADD, RELAXED_SWIZZLE > RXSWIZ, RELAXED_LANESELECT > RXLSEL, RELAXED_MAX > RXMAX, RELAXED_MIN > RXMIN 34 | ;; RELAXED_MADD > RXMADD, RELAXED_TRUNC > RXTRUNC, NARROW > NRW, EXTEND_LOW > XTLO, EXTEND_HIGH > XTHI 35 | 36 | (specops #xFD (op0 &optional op1) *assembler-prototype-wasm* 37 | ;; the table of SIMD WASM instructions 38 | ((:tabular :cross-adding :matcher match-ops)) 39 | (( ) (#x0 ) (#x1 ) (#x2 ) (#x3 ) (#x4 ) (#x5 ) (#x6 ) (#x7 ) (#x8 ) (#x9 ) (#xA ) (#xB ) (#xC ) (#xD ) (#xE ) (#xF )) 40 | ((#xFD00) (:load v128) (:load-s v128 8x8) (:load-u v128 8x8) (:load-s v128 16x4) (:load-u v128 16x4) (:load-s v128 32x2) (:load-u v128 32x2) (:load-splat v128 8) (:load-splat v128 16) (:load-splat v128 32) (:load-splat v128 64) (:store v128) (:const v128) (:shuffle i8x16) (:swizzle i8x16) (:splat i8x16)) 41 | ((#xFD10) (:splat i16x8) (:splat i32x4) (:splat i64x2) (:splat f32x4) (:splat f64x2) (:exlane-s i8x16) (:exlane-u i8x16) (:rplane i8x16) (:exlane-s i16x8) (:exlane-u i16x8) (:rplane i16x8) (:exlane i32x4) (:rplane i32x4) (:exlane i64x2) (:rplane i64x2) (:exlane f32x4)) 42 | ((#xFD20) (:rplane f32x4) (:exlane f64x2) (:rplane f64x2) (:eq i8x16) (:ne i8x16) (:lt-s i8x16) (:lt-u i8x16) (:gt-s i8x16) (:gt-u i8x16) (:le-s i8x16) (:le-u i8x16) (:ge-s i8x16) (:ge-u i8x16) (:eq i16x8) (:ne i16x8) (:lt-s i16x8)) 43 | ((#xFD30) (:lt-u i16x8) (:gt-s i16x8) (:gt-u i16x8) (:le-s i16x8) (:le-u i16x8) (:ge-s i16x8) (:ge-u i16x8) (:eq i32x4) (:ne i32x4) (:lt-s i32x4) (:lt-u i32x4) (:gt-s i32x4) (:gt-u i32x4) (:le-s i32x4) (:le-u i32x4) (:ge-s i32x4)) 44 | ((#xFD40) (:ge-u i32x4) (:eq f32x4) (:ne f32x4) (:lt f32x4) (:gt f32x4) (:le f32x4) (:ge f32x4) (:eq f64x2) (:ne f64x2) (:lt f64x2) (:gt f64x2) (:le f64x2) (:ge f64x2) (:not v128) (:and v128) (:andnot v128)) 45 | ((#xFD50) (:or v128) (:xor v128) (:bitselect v128) (:any-true v128) (:load-lane v128 8) (:load-lane v128 16) (:load-lane v128 32) (:load-lane v128 64) (:store-lane v128 8) (:store-lane v128 16) (:store-lane v128 32) (:store-lane v128 64) (:load-zero v128 32) (:load-zero v128 64) (:demote-zero f32x4 f64x2) (:promote-low f64x2 f32x4)) 46 | ((#xFD60) (:abs i8x16) (:neg i8x16) (:popcnt i8x16) (:all-true i8x16) (:bitmask i8x16) (:nrw-s i8x16 i16x8) (:nrw-u i8x16 i16x8) (:ceil f32x4) (:floor f32x4) (:trunc f32x4) (:nearest f32x4) (:shl i8x16) (:shr-s i8x16) (:shr-u i8x16) (:add i8x16) (:add-sat-s i8x16)) 47 | ((#xFD70) (:add-sat-u i8x16) (:sub i8x16) (:sub-sat-s i8x16) (:sub-sat-u i8x16) (:ceil f64x2) (:floor f64x2) (:min-s i8x16) (:min-u i8x16) (:max-s i8x16) (:max-u i8x16) (:trunc f64x2) (:avgr-u i8x16) (:extadd-pairwise-s i16x8 i8x16) (:extadd-pairwise-u i16x8 i8x16) (:extadd-pairwise-s i32x4 i16x8) (:extadd-pairwise-u i32x4 i16x8)) 48 | ((#xFD80) (:abs i16x8) (:neg i16x8) (:q15mulr-sat-s i16x8) (:all-true i16x8) (:bitmask i16x8) (:nrw-s i16x8 i32x4) (:nrw-u i16x8 i32x4) (:xtlo-s i16x8 i8x16) (:xthi-s i16x8 i8x16) (:xtlo-u i16x8 i8x16) (:xthi-u i16x8 i8x16) (:shl i16x8) (:shr-s i16x8) (:shr-u i16x8) (:add i16x8) (:add-sat-s i16x8)) 49 | ((#xFD90) (:add-sat-u i16x8) (:sub i16x8) (:sub-sat-s i16x8) (:sub-sat-u i16x8) (:nearest f64x2) (:mul i16x8) (:min-s i16x8) (:min-u i16x8) (:max-s i16x8) (:max-u i16x8) () (:avgr-u i16x8) (:extmul-low-s i16x8 i8x16) (:extmul-high-s i16x8 i8x16) (:extmul-low-u i16x8 i8x16) (:extmul-high-u i16x8 i8x16)) 50 | ((#xFDA0) (:abs i32x4) (:neg i32x4) (:rxswiz *i8x16) (:all-true i32x4) (:bitmask i32x4) (:rxtrunc-s *i32x4 f32x4) (:rxtrunc-u *i32x4 f32x4) (:xtlo-s i32x4 i16x8) (:xthi-s i32x4 i16x8) (:xtlo-u i32x4 i16x8) (:xthi-u i32x4 i16x8) (:shl i32x4) (:shr-s i32x4) (:shr-u i32x4) (:add i32x4) (:rxmadd *f32x4)) 51 | ((#xFDB0) (:rxnmadd *f32x4) (:sub i32x4) (:rxlsel *i8x16) (:rxlsel *i16x8) (:rxmin *f32x4) (:mul i32x4) (:min-s i32x4) (:min-u i32x4) (:max-s i32x4) (:max-u i32x4) (:dot-s i32x4 i16x8) () (:extmul-low-s i32x4 i16x8) (:extmul-high-s i32x4 i16x8) (:extmul-low-u i32x4 i16x8) (:extmul-high-u i32x4 i16x8)) 52 | ((#xFDC0) (:abs i64x2) (:neg i64x2) () (:all-true i64x2) (:bitmask i64x2) (:rxtrunc-s0 *i32x4 f64x2) (:rxtrunc-u0 *i32x4 f64x2) (:xtlo-s i64x2 i32x4) (:xthi-s i64x2 i32x4) (:xtlo-u i64x2 i32x4) (:xthi-u i64x2 i32x4) (:shl i64x2) (:shr-s i64x2) (:shr-u i64x2) (:add i64x2) (:rxmadd *f64x2)) 53 | ((#xFDD0) (:rxnmadd *f64x2) (:sub i64x2) (:rxlsel *i32x4) (:rxlsel *i64x2) (:rxmin *f64x2) (:mul i64x2) (:eq i64x2) (:ne i64x2) (:lt-s i64x2) (:gt-s i64x2) (:le-s i64x2) (:ge-s i64x2) (:extmul-low-s i64x2 i32x4) (:extmul-high-s i64x2 i32x4) (:extmul-low-u i64x2 i32x4) (:extmul-high-u i64x2 i32x4)) 54 | ((#xFDE0) (:abs f32x4) (:neg f32x4) (:relaxed-max *f32x4) (:sqrt f32x4) (:add f32x4) (:sub f32x4) (:mul f32x4) (:div f32x4) (:min f32x4) (:max f32x4) (:pmin f32x4) (:pmax f32x4) (:abs f64x2) (:neg f64x2) (:relaxed-max *f64x2) (:sqrt f64x2)) 55 | ((#xFDF0) (:add f64x2) (:sub f64x2) (:mul f64x2) (:div f64x2) (:min f64x2) (:max f64x2) (:pmin f64x2) (:pmax f64x2) (:trunc-sat-s i32x4 f32x4) (:trunc-sat-u i32x4 f32x4) (:convert-s f32x4 i32x4) (:convert-u f32x4 i32x4) (:trunc-sat-s0 i32x4 f64x2) (:trunc-sat-u0 i32x4 f64x2) (:convert-low-s f64x i32x4) (:convert-low-u f64x2 i32x4))) 56 | -------------------------------------------------------------------------------- /wasm/package.lisp: -------------------------------------------------------------------------------- 1 | ;;;; package.lisp 2 | 3 | (defpackage #:specops.wasm 4 | (:use #:cl #:specops)) 5 | -------------------------------------------------------------------------------- /wasm/specops.wasm.asd: -------------------------------------------------------------------------------- 1 | ;;;; wasm.asd 2 | 3 | (asdf:defsystem #:specops.wasm 4 | :description "Describe wasm here" 5 | :author "Your Name " 6 | :license "BSD" 7 | :version "0.0.1" 8 | :serial t 9 | :components ((:file "package") 10 | (:file "base"))) 11 | -------------------------------------------------------------------------------- /x86/base.lisp: -------------------------------------------------------------------------------- 1 | ;;;; base.lisp 2 | 3 | (in-package #:specops.x86) 4 | 5 | ;; (defclass x86-register (register) 6 | ;; ((%series :accessor reg-series 7 | ;; :initform nil 8 | ;; :initarg :series 9 | ;; :documentation "The register's series."))) 10 | 11 | ;; (defclass x86-gpregister (x86-register) 12 | ;; ()) 13 | 14 | ;; (defclass x86-vcregister (x86-register) 15 | ;; ()) 16 | 17 | (defclass mas-x86 (mas-based mas-indexed mas-scaling-displaced) 18 | ((%half-width :accessor mas-x86-half-width 19 | :initform nil 20 | :initarg :half-width 21 | :documentation "The register's name.")) 22 | (:documentation "Memory access scheme for x86 ISA featuring base, index and scaled displacement.")) 23 | 24 | (defvar *assembler-prototype-x86*) 25 | 26 | (defvar *x86-layout* 27 | (list :gpr '(:a :c :d :b :sp :bp :di :si :r8 :r9 :r10 :r11 :r12 :r13 :r14 :r15) 28 | :vcr '(:m0 :m1 :m2 :m3 :m4 :m5 :m6 :m7 :m8 :m9 :m10 :m11 :m12 :m13 :m14 :m15 29 | :m16 :m17 :m18 :m19 :m20 :m21 :m22 :m23 :m24 :m25 :m26 :m27 :m28 :m29 :m30 :m31) 30 | :gpr-hb '(:ah :ch :dh :bh))) 31 | 32 | (defvar *storage-domains-x86* 33 | (list :gpr '(:a :c :d :b :sp :bp :di :si))) 34 | 35 | (defvar *storage-domains-x86-64* 36 | (list :gpr '(:a :c :d :b :sp :bp :di :si :r8 :r9 :r10 :r11 :r12 :r13 :r14 :r15) 37 | :gpr-hb '(:ah :ch :dh :bh))) 38 | 39 | (defvar *storage-domains-x86-64-avx* 40 | (list :gpr '(:a :c :d :b :sp :bp :di :si :r8 :r9 :r10 :r11 :r12 :r13 :r14 :r15) 41 | :vcr '(:m0 :m1 :m2 :m3 :m4 :m5 :m6 :m7 :m8 :m9 :m10 :m11 :m12 :m13 :m14 :m15) 42 | :gpr-hb '(:ah :ch :dh :bh))) 43 | 44 | (defvar *storage-domains-x86-64-avx-512* 45 | (list :gpr '(:a :c :d :b :sp :bp :di :si :r8 :r9 :r10 :r11 :r12 :r13 :r14 :r15) 46 | :vcr '(:m0 :m1 :m2 :m3 :m4 :m5 :m6 :m7 :m8 :m9 :m10 :m11 :m12 :m13 :m14 :m15 47 | :m16 :m17 :m18 :m19 :m20 :m21 :m22 :m23 :m24 :m25 :m26 :m27 :m28 :m29 :m30 :m31) 48 | :gpr-hb '(:ah :ch :dh :bh))) 49 | 50 | (defun gprix (item) 51 | (or (position item (getf *x86-layout* :gpr)) 52 | (position item (getf *x86-layout* :gpr-hb)))) 53 | 54 | (defun vcrix (item) 55 | (position item (getf *x86-layout* :vcr))) 56 | 57 | ;; (defun fprix (index) 58 | ;; (position index (getf *x86-layout* :fpr))) 59 | 60 | (defun regix (item) 61 | (or (gprix item) (vcrix item))) 62 | 63 | (defun gpr-p (item) 64 | (and (keywordp item) (gprix item))) 65 | 66 | (defun vcr-p (item) 67 | (and (keywordp item) (vcrix item))) 68 | 69 | (defun gpr-hb-p (item) 70 | (and (keywordp item) 71 | (position item (getf *x86-layout* :gpr-hb)))) 72 | 73 | (deftype gpr () `(satisfies gpr-p)) 74 | 75 | (deftype vcr () `(satisfies vcr-p)) 76 | 77 | (deftype gpr-hb () `(satisfies gpr-hb-p)) 78 | 79 | ;; (defun mas-simple-p (item) 80 | ;; (and (typep item 'mas-x86) (not (mas-displ item)))) 81 | 82 | ;; (deftype mas-simple () `(satisfies mas-simple-p)) 83 | 84 | (defun b+ (gpr-sym) 85 | "Express an _H upper-byte register - an 8-bit register coincident with the top half of a 16-bit register. The argument is a register spec that otherwise, given as an argument to an 8-bit operation, would express a _L lower-byte register." 86 | (if (keywordp item) 87 | (let ((gprix (position item (getf *x86-layout* :gpr)))) 88 | (if (and gprix (> 4 gprix)) 89 | (nth gprix (getf *x86-layout* :gpr-hb)))))) 90 | 91 | (defun @ (base &rest options) 92 | "Specify a memory access scheme with base and, optionally, index, displacement and scale." 93 | (let* ((index (if (gpr-p (first options)) (first options) nil)) 94 | (options (if index (rest options) options)) 95 | (displ (if (integerp (first options)) (first options) nil))) 96 | (make-instance 'mas-x86 :base base :index index :displ displ :scale (if displ (or (second options) 1))))) 97 | 98 | (defun @/ (&rest args) 99 | "Specify a 32-bit memory address - only applicable in 64-bit mode and even then seldom used." 100 | (let ((mas (apply #'@ args))) 101 | (setf (mas-x86-half-width mas) t) 102 | mas)) 103 | 104 | ;; (defun prefix-rex (&optional wide rex iex rbex) 105 | ;; (masque "0100.WRXB" 106 | ;; (w (if wide 1 0)) ;; bit 4 indicates use of 64-bit register(s) 107 | ;; (r (if rex 1 0)) ;; bit 5 indicates extension of the MODRM.reg field 108 | ;; (x (if iex 1 0)) ;; bit 6 indicates extension of the SIB.index field 109 | ;; (b (if rbex 1 0)))) ;; bit 7 indicates extension of MODRM.rm or SIB.base field 110 | 111 | ;; (defun prefix-vex (long-prefix &key r x b map wide (length 128) third-op prefix) 112 | ;; (if long-prefix 113 | ;; (masque "11000100.RXBmmmmm.WvvvvLpp" 114 | ;; (r (if (zerop r) 1 0)) ;; bit 1.0 indicates inverse extension of the MODRM.reg field 115 | ;; (x (if (zerop x) 1 0)) ;; bit 1.1 indicates inverse extension of the SIB.index field 116 | ;; (b (if (zerop b) 1 0)) ;; bit 1.2 indicates inverse extension of MODRM.rm or SIB.base field 117 | ;; (m (if (> 4 map) ;; map field contains operator extension index 1, 2 or 3 118 | ;; map (case map (#x0F #b01) (#x0F35 #b10) (#x0F38 #b11) (t 0)))) 119 | ;; (w (if wide 1 0)) ;; bit 2.0 indicates 64-bit width of integer operand 120 | ;; (v (if third-op (flipbits third-op) 0)) ;; v field addresses third operand (reversed) 121 | ;; (l (if (= length 256) 1 0)) ;; bit 2.5 denotes use of 256-bit registers 122 | ;; ;; prefix field expresses opcode prefix if needed 123 | ;; (p (case prefix (#x66 #b01) (#xF3 #b10) (#xF2 #b11) (t 0)))) 124 | ;; (masque "11000101.WvvvvLpp" 125 | ;; (w (if wide 1 0)) ;; bit 2.0 indicates 64-bit width of integer operand 126 | ;; (v (if third-op (flipbits third-op) 0)) ;; v field addresses third operand (reversed) 127 | ;; (l (if (= length 256) 1 0)) ;; bit 2.5 denotes use of 256-bit registers 128 | ;; ;; prefix field expresses opcode prefix if needed 129 | ;; (p (case prefix (#x66 #b01) (#xF3 #b10) (#xF2 #b11) (t 0)))))) 130 | 131 | ;; (defun prefix-evex (&key rex iex rbex map wide (length 128) 132 | ;; third-op prefix merge br-control op3-extend) 133 | ;; (masque "01100010.RXBŔ00mm.Wvvvv1pp.ZLLḂṼaaa" 134 | ;; (r (if rex 0 1)) ;; bit 1.0 indicates inverse extension of the MODRM.reg field 135 | ;; (x (if iex 0 1)) ;; bit 1.1 indicates inverse extension of the SIB.index field 136 | ;; (b (if rbex 0 1)) ;; bit 1.2 indicates inverse extension of MODRM.rm or SIB.base field 137 | ;; (ŕ (if rbex 0 1)) ;; bit 1.3 indicates further inverse extension of MODRM.reg field 138 | ;; (m (if (> 4 map) ;; map field contains operator extension index 1, 2 or 3 139 | ;; map (case map (#x0F #b01) (#x0F35 #b10) (#x0F38 #b11) (t 0)))) 140 | ;; (w (if wide 1 0)) ;; bit 2.0 indicates 64-bit width of integer operand 141 | ;; (v (if third-op (flipbits third-op) 0)) ;; v field addresses third operand (reversed) 142 | ;; ;; prefix field expresses opcode prefix if needed 143 | ;; (p (case prefix (#x66 #b01) (#xF3 #b10) (#xF2 #b11) (t 0))) 144 | ;; (z (if merge 1 0)) ;; bit 3.0 toggles merge function 145 | ;; (l (+ (if (= length 512) #b10 0) (if (= length 256) #b01 0))) 146 | ;; (ḃ (if br-control 1 0)) 147 | ;; ;; bits 3.1-2 determine use of 256-bit or 512-bit registers 148 | ;; (ṽ (if op3-extend 1 0)) 149 | ;; (a 0))) 150 | 151 | 152 | (defun determine-modrm (op0 op1) 153 | ;; (print (list :oo op0 op1)) 154 | (masque "MMRRROOO" 155 | (m (if (gpr-p op1) 156 | #b11 (if (or (not (mas-displ op1)) (zerop (mas-displ op1))) 157 | ;; no displacement and a BP register base forces use of a zero 8-bit disp. 158 | (if (eq :bp (reg-series (mas-base op1))) 159 | #b01 #b00) 160 | (if (> 256 (mas-displ op1)) ;; choose 8 or 32-bit displacement 161 | #b01 #b10)))) 162 | (r (if (numberp op0) 163 | op0 (if (not (gpr-p op0)) 164 | 0 (logand #b111 (regix op0))))) 165 | (o (if (numberp op1) 166 | op1 (if (gpr-p op1) 167 | (logand #b111 (regix op1)) 168 | (if (not (typep op1 'mas-x86)) 169 | 0 (if (not (mas-base op1)) 170 | #b101 ;; determines 32-bit displacement-only mode 171 | (if (mas-index op1) ;; #b100 determines SIB addressing 172 | #b100 (logand #b111 (regix (mas-base op1))))))))))) 173 | 174 | (defun determine-sib (mac) 175 | (if (or (not (typep mac 'mas-x86)) 176 | (not (mas-index mac))) 177 | nil (masque "SSIIIBBB" 178 | (s (mas-sdisp-scale mac)) 179 | (i (logand #b111 (regix (mas-index mac)))) 180 | (b (logand #b111 (regix (mas-base mac))))))) 181 | 182 | (defun determine-pfsize (width op0 op1 mode) 183 | (let ((reg-size (case mode 184 | (:r16 (eq width :d)) 185 | (:p16 (eq width :d)) 186 | (:p32 (eq width :w)) 187 | (:l64 (eq width :w)))) 188 | (adr-size (case mode 189 | (:l64 (or (and (typep op0 'mas-x86) 190 | (mas-x86-half-width op0)) 191 | (and (typep op1 'mas-x86) 192 | (mas-x86-half-width op1))))))) 193 | (if reg-size (if adr-size #x6766 #x66) 194 | (if adr-size #x67 nil)))) 195 | 196 | ;; (defun determine-pfasize (width op0 op1 mode) 197 | ;; (case mode 198 | ;; (:r16 (if (eq width :d) #x67 nil)) 199 | ;; (:p32 (if (eq width :w) #x67 nil)) 200 | ;; (:l64 (if (eq width :w) #x67 nil)))) 201 | 202 | (defun determine-pfrex (width op0 op1) 203 | (let ((flags (+ (if (eq :q width) 8 0) ;; 8-bit indicates 64-bit width 204 | (if (not (gpr-p op0)) ;; 4-bit is upper bit of extended GPR 0 index 205 | 0 (ash (ash (regix op0) -3) 2)) 206 | (if (not (and (typep op1 'mas-x86) ;; 2-bit is upper bit of extended GPR 1 index 207 | (mas-base op1) (mas-index op1))) 208 | 0 (ash (ash (regix (mas-index op1)) -3) 1)) 209 | (if (gpr-p op0) ;; 1-bit is upper bit of extended GPR 1/MAS 1 indec 210 | (ash (regix op0) -3) 211 | (if (not (and (typep op0 'mas-x86) (mas-base op1))) 212 | 0 (ash (regix (mas-base op1)) -3)))))) 213 | (if (not (zerop flags)) 214 | (masque "0100.FFFF" (f flags)) 215 | (if (not (eq :b width)) 216 | nil (let ((gprix0 (gprix op0)) 217 | (gprix1 (gprix op1))) 218 | (if (or (and gprix0 (> 4 gprix0)) 219 | (and gprix1 (> 4 gprix1))) 220 | (if (not (or (gpr-hb-p op0) (gpr-hb-p op1))) 221 | #b01000000 222 | (error "The 8-bit registers SPL, BPL, DIL and SIL may not be addressed in the same instruction as the upper-byte registers AL, CL, DL and BL.")))))))) 223 | 224 | (defun determine-pfvex (op0 op1 op2 &key long map prefix) 225 | (let ((sib-index (and (typep op1 'mas-x86) 226 | (ash (mas-index op1) -3)))) 227 | (if long 228 | (masque "11000100.RXBmmmmm.WvvvvLpp" 229 | (r (if (zerop (logand #b1000 (regix op0))) 1 0)) 230 | ;; bit 1.0 indicates inverse extension of the MODRM.reg field: op0 index upper bit 231 | (x (if (or (not sib-index) (zerop sib-index)) 1 0)) 232 | ;; bit 1.1 indicates inverse extension of the SIB.index field: index register upper bit 233 | (b (if (or (not sib-index) (zerop (ash (mas-base op1) -3))) 1 0)) 234 | ;; bit 1.2 indicates inverse extension of MODRM.rm or SIB.base field: base register upper bit 235 | (m (case map (#x0F #b01) (#x0F35 #b10) (#x0F38 #b11) (t map))) 236 | ;; map field contains operator extension index 1-3, may be mapped to codes or direct 237 | (w (if (= 64 (reg-width op0)) 1 0)) ;; bit 2.0 indicates 64-bit width of integer operand 238 | (v (if op2 (flipbits (regix op2)) 0)) ;; v field addresses third operand (reversed) 239 | (l (if (= 256 (reg-width op0)) 1 0)) ;; bit 2.5 denotes use of 256-bit registers 240 | ;; prefix field expresses opcode prefix if needed 241 | (p (case prefix (#x66 #b01) (#xF3 #b10) (#xF2 #b11) (t 0)))) 242 | (masque "11000101.WvvvvLpp" 243 | (w (if (= 64 (reg-width op0)) 1 0)) ;; bit 2.0 indicates 64-bit width of integer operand 244 | (v (if op2 (flipbits (regix op2)) 0)) 245 | ;; v field addresses third operand (reversed) 246 | (l (if (= 256 (reg-width op0)) 1 0)) ;; bit 2.5 denotes use of 256-bit registers 247 | ;; prefix field expresses opcode prefix if needed 248 | (p (case prefix (#x66 #b01) (#xF3 #b10) (#xF2 #b11) (t 0))))))) 249 | 250 | (defun determine-pfevex (op0 op1 op2 &key map br-control prefix merge) 251 | (let ((sib-index (or (and (typep op1 'mas-x86) 252 | (ash (mas-index op1) -3))))) 253 | (masque "01100010.RXBŔ00mm.Wvvvv1pp.ZllḂṼaaa" 254 | (r (if (zerop (logand #b1000 (regix op0))) 1 0)) 255 | ;; bit 1.0 indicates inverse extension of the MODRM.reg field: op0 index upper bit 256 | (x (if (or (not sib-index) (zerop sib-index)) 1 0)) 257 | ;; bit 1.1 indicates inverse extension of the SIB.index field: index register upper bit 258 | (b (if (or (not sib-index) (zerop (ash (mas-base op1) -3))) 1 0)) 259 | ;; bit 1.2 indicates inverse extension of MODRM.rm or SIB.base field: base register upper bit 260 | (ŕ (if (zerop (logand #b10000 (regix op0))) 1 0)) 261 | ;; bit 1.3 indicates further inverse extension of MODRM.reg field 262 | (m (case map (#x0F #b01) (#x0F35 #b10) (#x0F38 #b11) (t map))) 263 | ;; map field contains operator extension index 1-3, may be mapped to codes or direct 264 | (w (if (= 64 (reg-width op0)) 1 0)) ;; bit 2.0 indicates 64-bit width of integer operand 265 | (v (if op2 (flipbits (logand #b1111 (regix op2))) 0)) 266 | ;; v field addresses third operand (reversed) 267 | ;; prefix field expresses opcode prefix if needed 268 | (p (case prefix (#x66 #b01) (#xF3 #b10) (#xF2 #b11) (t 0))) 269 | (z (if merge 1 0)) ;; bit 3.0 toggles merge function 270 | (l (if (= 512 (reg-width op0)) #b10 (if (= 256 (reg-width op0)) #b01 0))) 271 | ;; bit 3.1-2 determine use of 256 or 512-bit registers 272 | (ḃ (if br-control 1 0)) 273 | ;; prefix field expresses opcode prefix if needed 274 | (ṽ (if (zerop (logand #b10000 (regix op2))) 1 0)) 275 | (a 0)))) 276 | 277 | ;; (defvar *x86-lexicon* (make-hash-table :test #'eq)) 278 | 279 | (defclass assembler-x86 (assembler) 280 | ((%storage :accessor asm-storage 281 | :allocation :class 282 | :initform (make-hash-table :test #'eq) 283 | :initarg :storage) 284 | (%lexicon :accessor asm-lexicon 285 | :allocation :class 286 | :initform (make-hash-table :test #'eq) 287 | :initarg :lexicon) 288 | (%domains :accessor asm-domains 289 | :initform *storage-domains-x86* 290 | :allocation :class 291 | :initarg :domains) 292 | (%exmodes :accessor asm-exmodes 293 | :allocation :class 294 | :initform '(:l64 :p32 :p16 :r16) 295 | :initarg :exmodes))) 296 | 297 | (defmethod qualify-ops ((assembler assembler-x86) operands form order) 298 | (declare (ignore assembler)) 299 | ;; (print (list :or order)) 300 | (let ((wix (gensym))) 301 | (flet ((operand-determine (o spec) 302 | (destructuring-bind (type &optional qualifier) spec 303 | (symbol-macrolet 304 | (( w-case `(eq ,o ,qualifier)) 305 | (gpr-case `(and (gpr-p ,o) 306 | ,@(typecase qualifier 307 | (keyword `((eq ,qualifier ,o))) 308 | (integer `((= ,qualifier (reg-width ,o))))))) 309 | (vcr-case `(and (vcr-p ,o) 310 | ,@(typecase qualifier 311 | (keyword `((eq ,qualifier ,o))) 312 | (integer `((= ,qualifier (reg-width ,o))))))) 313 | (mem-case `(and (typep ,o 'mas-x86) 314 | ,@(typecase qualifier 315 | (keyword `((eq ,qualifier ,o))) 316 | (integer `((= ,qualifier (reg-width ,o)))))))) 317 | (case type 318 | (:w (list w-case)) 319 | (:gpr (list gpr-case)) 320 | (:vcr (list vcr-case)) 321 | (:mem (list mem-case)) 322 | (:gxm `((or ,gpr-case ,mem-case))) 323 | (:vxm `((or ,vcr-case ,mem-case))) 324 | (:imm `((and (typep ,o 'integer) 325 | ,@(if qualifier `((< ,o ,(expt 2 qualifier)))))))))))) 326 | (loop :for index :in order 327 | :append (let ((f (nth index form)) (o (nth index operands))) 328 | (typecase f 329 | (integer `((and (integerp ,o) (= ,f ,o)))) 330 | ;; (keyword (case f 331 | ;; (:w (list w-case)) 332 | ;; (:gpr `((gpr-p ,o))) 333 | ;; (:vcr `((vcr-p ,o))) 334 | ;; (:mem `((typep ,o 'mas-x86))) 335 | ;; (:gxm `((or (gpr-p ,o) (typep ,o 'mas-x86)))) 336 | ;; (:vxm `((or (vcr-p ,o) (typep ,o 'mas-x86)))) 337 | ;; (:imm `((typep ,o 'integer))))) 338 | (list (operand-determine o f)))))))) 339 | 340 | (defmethod specify-ops ((assembler assembler-x86) op-symbol operands params operations) 341 | "A simple scheme for implementing operations - the (specop) content is directly placed within functions in the lexicon hash table." 342 | ;; (print (list :par op-symbol operands params)) 343 | (let ((provisions (rest (assoc :provisions params)))) 344 | (clause-processor 345 | assembler 'of-lexicon op-symbol operands params 346 | `((symbol-macrolet ,provisions 347 | (cond ,@(loop :for op :in operations 348 | :collect (destructuring-bind (manifest conditions) op 349 | (list (cons 'and (qualify-ops assembler operands conditions 350 | (rest (assoc :priority params)))) 351 | (cons 'list manifest)))) 352 | (t "Invalid operation."))))))) 353 | 354 | (defun w (width value) 355 | (if (and (not (zerop (ash value (ash (1- width) 3))))) 356 | (cons width value) 357 | (if (zerop (ash value (ash width 3))) 358 | value (logand value (1- (ash 1 width)))))) 359 | 360 | ;; (defmethod initialize-instance :after ((assembler assembler-x86) &key) 361 | ;; (derive-domains assembler (t (:gpr 8)) 362 | ;; (:x86-64 (:gpr 16)) 363 | ;; (:avx (:vcr 8)) 364 | ;; (:avx2 (:vcr 16)) 365 | ;; (:avx512 (:vcr 32)))) 366 | 367 | ;; (defmacro defop (symbol operands lexicon &rest specs) 368 | ;; (let* ((provisions (rest (assoc :provisions specs))) 369 | ;; (ins-part (rest (assoc :instructions specs))) 370 | ;; (ins-meta (rest (assoc :with ins-part))) 371 | ;; (opcon-process (symbol-function (rest (assoc :opcons ins-meta)))) 372 | ;; (ins-main)) 373 | 374 | ;; (let ((ins-list ins-part)) 375 | ;; (loop :while (and ins-list (not ins-main)) 376 | ;; :do (if (keywordp (caar ins-list)) 377 | ;; (setf ins-list (rest ins-list)) 378 | ;; (setf ins-main ins-list)))) 379 | 380 | ;; `(setf (gethash ,(intern (string symbol) "KEYWORD") ,lexicon) 381 | ;; (lambda ,operands 382 | ;; (symbol-macrolet ,provisions 383 | ;; (cond ,@(loop :for in :in ins-main 384 | ;; :collect (destructuring-bind (manifest conditions) in 385 | ;; (list (cons 'and (funcall opcon-process operands conditions 386 | ;; (rest (assoc :priority ins-meta)))) 387 | ;; (cons 'join manifest)))) 388 | ;; (t "Invalid operation."))))))) 389 | 390 | ;; (defun genopcons-x86 (operands form order) 391 | ;; "Generate operand conditions for x86 architecture." 392 | ;; (loop :for index :in order 393 | ;; :append (let ((f (nth index form)) (o (nth index operands))) 394 | ;; (if (integerp f) 395 | ;; `((and (integerp ,o) (= ,f ,o))) 396 | ;; (if (not f) 397 | ;; nil (destructuring-bind (type qualifier) f 398 | ;; (symbol-macrolet 399 | ;; ((gpr-case `(and (typep ,o 'x86-gpregister) 400 | ;; ,(typecase qualifier 401 | ;; (keyword `(eq ,qualifier (reg-name ,o))) 402 | ;; (integer `(= ,qualifier (reg-width ,o)))))) 403 | ;; (vcr-case `(and (typep ,o 'x86-vcregister) 404 | ;; ,(typecase qualifier 405 | ;; (keyword `(eq ,qualifier (reg-name ,o))) 406 | ;; (integer `(= ,qualifier (reg-width ,o)))))) 407 | ;; (mem-case `(and (typep ,o 'mas-x86) 408 | ;; ,(typecase qualifier 409 | ;; (keyword `(eq ,qualifier (reg-name ,o))) 410 | ;; (integer `(= ,qualifier (reg-width ,o))))))) 411 | ;; (case type 412 | ;; (:gpr (list gpr-case)) 413 | ;; (:vcr (list vcr-case)) 414 | ;; (:mem (list mem-case)) 415 | ;; (:gxm `((or ,gpr-case ,mem-case))) 416 | ;; (:vxm `((or ,vcr-case ,mem-case))) 417 | ;; (:imm `((and (typep ,o 'integer) 418 | ;; (< ,o ,(expt 2 qualifier))))))))))))) 419 | 420 | ;; (defmethod specify-ops ((assembler assembler-x86) asm-sym op-symbol operands items) 421 | ;; "A simple scheme for implementing operations - the (specop) content is directly placed within functions in the lexicon hash table." 422 | ;; (print (list :par asm-sym op-symbol op-symbol operands items)) 423 | ;; (let* ((params (if (not (and (listp (first items)) (listp (caar items)) 424 | ;; (keywordp (caaar items)))) 425 | ;; nil (first items))) 426 | ;; (operations (if (not params) items (rest items))) 427 | ;; (provisions (rest (assoc :provisions params)))) 428 | ;; ;; (print (list :op operations params)) 429 | 430 | ;; `(setf (gethash ,(intern (string op-symbol) "KEYWORD") 431 | ;; (asm-lexicon ,asm-sym)) 432 | ;; (lambda ,operands 433 | ;; (symbol-macrolet ,provisions 434 | ;; (cond ,@(loop :for op :in operations 435 | ;; :collect (destructuring-bind (manifest mconditions) op 436 | ;; (list (cons 'and (qualify-ops assembler operands conditions 437 | ;; (rest (assoc :priority params)))) 438 | ;; (cons 'join manifest)))) 439 | ;; (t "Invalid operation."))))))) 440 | 441 | ;; (defun determine-pfrex (width op0 op1 &optional null-if-zero) 442 | ;; (let ((flags (+ (if (eq :q width) 8 0) ;; 8-bit indicates 64-bit width 443 | ;; (if (not (gpr-p op0)) ;; 4-bit is upper bit of extended GPR 0 index 444 | ;; 0 (ash (ash (regix op0) -3) 2)) 445 | ;; (if (not (and (typep op1 'mas-x86) ;; 2-bit is upper bit of extended GPR 1 index 446 | ;; (mas-base op1) (mas-index op1))) 447 | ;; 0 (ash (ash (regix (mas-index op1)) -3) 1)) 448 | ;; (if (gpr-p op0) ;; 1-bit is upper bit of extended GPR 1/MAS 1 indec 449 | ;; (ash (regix op0) -3) 450 | ;; (if (not (and (typep op0 'mas-x86) (mas-base op1))) 451 | ;; 0 (ash (regix (mas-base op1)) -3)))))) 452 | ;; (if (and null-if-zero (zerop flags)) 453 | ;; nil (masque "0100.FFFF" (f flags))))) 454 | 455 | ;; (defun determine-pfrex (wide op0 op1 &key szpx-reg szpx-addr) 456 | ;; (masque "0100.WRXB" 457 | ;; (w (if wide 1 (if (or (and (gpr-p op0) 458 | ;; (= 64 (reg-width op0))) 459 | ;; (and (gpr-p op1) 460 | ;; (= 64 (reg-width op1)))) 461 | ;; 1 0))) 462 | ;; (r (if (not (gpr-p op0)) 463 | ;; 0 (ash (regix op0) -3))) 464 | ;; (x (if (not (and (typep op1 'mas-x86) 465 | ;; (mas-base op1) (mas-index op1))) 466 | ;; 0 (ash (regix (mas-index op1)) -3))) 467 | ;; (b (if (gpr-p op0) 468 | ;; (ash (regix op0) -3) 469 | ;; (if (not (and (typep op0 'mas-x86) 470 | ;; (mas-base op1))) 471 | ;; 0 (ash (regix (mas-base op1)) -3)))))) 472 | 473 | 474 | 475 | ;; (defmethod specify-ops ((assembler assembler) op-symbol operands params operations) 476 | ;; "A simple scheme for implementing operations - the (specop) content is directly placed within functions in the lexicon hash table." 477 | ;; (cond ((assoc :combine params) 478 | ;; ;; combinatoric parameters are used to specify mnemonics and opcodes that can be derived 479 | ;; ;; by combining lists of base components, such as the Xcc conditional instructions seen 480 | ;; ;; in many ISAs, where many different conditions share a common numeric and mnemonic base 481 | ;; (destructuring-bind (co-symbol join-by indexer &rest combinators) 482 | ;; (rest (assoc :combine params)) 483 | ;; (cons 'progn (loop :for co :in combinators :for i :from 0 484 | ;; :collect (let ((comp-sym (case join-by 485 | ;; (:appending (intern (format nil "~a~a" op-symbol co) 486 | ;; "KEYWORD")))) 487 | ;; (index (funcall (case indexer (:by-index #'identity)) 488 | ;; i))) 489 | ;; (clause-processor 490 | ;; assembler 'of-lexicon comp-sym operands 491 | ;; (append (list (cons :wrap-body 492 | ;; (lambda (body) 493 | ;; `((let ((,co-symbol ,index)) ,@body))))) 494 | ;; params) 495 | ;; operations)))))) 496 | ;; ((assoc :tabular params) 497 | ;; ;; tabular parameters are used to specify many opcodes for ISAs like Z80 and 6502 along 498 | ;; ;; with more recent one-byte instruction sets like WebAssembly 499 | ;; (destructuring-bind (mode &rest properties) (rest (assoc :tabular params)) 500 | ;; (declare (ignore properties)) 501 | ;; (case mode (:cross-adding 502 | ;; (cons 'progn (process-clause-matrix assembler op-symbol 503 | ;; operands params operations)))))) 504 | ;; ;; ((and (not operands) (= 1 (length operations))) 505 | ;; ;; ;; `(setf (gethash ,(intern (string op-symbol) "KEYWORD") 506 | ;; ;; ;; (asm-lexicon ,asm-sym)) 507 | ;; ;; ;; ,(first operations)) 508 | ;; ;; `(of-lexicon ,asm-sym ,(intern (string op-symbol) "KEYWORD") 509 | ;; ;; ,(first operations))) 510 | ;; (t (clause-processor assembler 'of-lexicon op-symbol operands params operations)))) 511 | 512 | ;; (let ((gpr-series-names) (vcr-series-names)) 513 | ;; (dotimes (n (/ (length (getf *x86-storage* :gpr)) 8)) 514 | ;; (push (reg-series (nth (1+ (* 8 n)) (getf *x86-storage* :gpr))) gpr-series-names)) 515 | 516 | ;; (dotimes (n (/ (length (getf *x86-storage* :vcr)) 6)) 517 | ;; (push (reg-series (nth (1+ (* 6 n)) (getf *x86-storage* :vcr))) vcr-series-names)) 518 | 519 | ;; (setf gpr-series-names (reverse gpr-series-names) 520 | ;; vcr-series-names (reverse vcr-series-names)) 521 | 522 | ;; (defun series-index (type series-id) 523 | ;; (case type (:gpr (position series-id gpr-series-names)) 524 | ;; (:vcr (position series-id vcr-series-names))))) 525 | 526 | ;; (defmethod of-storage ((assembler assembler-x86) &rest params) 527 | ;; (destructuring-bind (type &key series width series-index) params 528 | ;; ;; (print (list :in width type series-index)) 529 | ;; (let* ((series-index (or series-index (if (not series) 0 (series-index type series)))) 530 | ;; (type-list (getf *x86-storage* type)) 531 | ;; (storage-index (+ 1 (* 4 series-index) (* 2 width)))) 532 | ;; ;; (print (list :ss storage-index width type)) 533 | ;; (if (not (member series-index (assoc type (asm-domains assembler)))) 534 | ;; nil (values (nth storage-index type-list) 535 | ;; (+ series-index width)))))) 536 | 537 | ;; (defmethod locate ((assembler assembler-x86) items) 538 | ;; (let ((domains (copy-tree (asm-domains assembler))) 539 | ;; (bound (loop :for item :in items :when (member :bind item :test #'eq) :collect item)) 540 | ;; (unbound (loop :for item :in items :unless (member :bind item :test #'eq) :collect item))) 541 | ;; (print (list :bu bound unbound)) 542 | ;; (append (loop :for item :in bound 543 | ;; :collect (destructuring-bind (symbol type &rest params) item 544 | ;; ;; (print (list :dom domains)) 545 | ;; (list symbol (let ((out-index (series-index type (getf params :bind)))) 546 | ;; (setf (rest (assoc type domains)) 547 | ;; (remove out-index (rest (assoc type domains)))) 548 | ;; out-index)))) 549 | ;; (loop :for item :in unbound 550 | ;; :collect (destructuring-bind (symbol type &rest params) item 551 | ;; (list symbol (let ((random-index (nth (random (length (rest (assoc type domains)))) 552 | ;; (rest (assoc type domains))))) 553 | ;; (setf (rest (assoc type domains)) 554 | ;; (remove random-index (rest (assoc type domains)))) 555 | ;; random-index))))))) 556 | 557 | ;; (loop :for item :in items 558 | ;; :collect (destructuring-bind (symbol type &rest params) item 559 | ;; ;; (print (list :dom domains)) 560 | ;; (list symbol (if (getf params :bind) 561 | ;; (let ((out-index (series-index type (getf params :bind)))) 562 | ;; (setf (rest (assoc type domains)) 563 | ;; (remove out-index (rest (assoc type domains)))) 564 | ;; out-index) 565 | ;; (let ((random-index (nth (random (length (rest (assoc type domains)))) 566 | ;; (rest (assoc type domains))))) 567 | ;; (setf (rest (assoc type domains)) 568 | ;; (remove random-index (rest (assoc type domains)))) 569 | ;; random-index))))))) 570 | 571 | ;; (defmethod compose ((assembler assembler-x86) params expression) 572 | ;; (print (list :ar params)) 573 | ;; (destructuring-bind (op &rest props) expression 574 | ;; (if (listp op) 575 | ;; (loop :for item :in expression :collect (compose assembler params item)) 576 | ;; (if (not (keywordp op)) 577 | ;; (compose assembler params (macroexpand op)) 578 | ;; (let (;; (width (if (not (keywordp (first props))) 579 | ;; ;; nil (position (first props) #(:b :w :d :q) :test #'eq))) 580 | ;; ;; (props (if (not width) props (rest props))) 581 | ;; (bindings (rest (assoc :store params)))) 582 | ;; (print (list :bi bindings params props expression 583 | ;; (gethash op (asm-lexicon assembler)))) 584 | ;; (apply (gethash op (asm-lexicon assembler)) props 585 | ;; ;; (loop :for p :in props 586 | ;; ;; :collect (typecase p 587 | ;; ;; ;; (symbol (of-storage assembler :gpr :width width 588 | ;; ;; ;; :series-index (second (assoc p bindings)))) 589 | ;; ;; (t p))) 590 | ;; )))))) 591 | 592 | #| 593 | (assemble *assembler-prototype-x86* 594 | ((:exmode . :l64) (:store (abc :gpr) (def :gpr :bind :a))) 595 | (:add :w abc 10) 596 | (:add :w def 33)) 597 | |# 598 | 599 | ;; (specify-assembler asm-x86 assemble 600 | ;; (:options :x86-64) 601 | ;; (:lexicon *x86-lexicon*)) 602 | 603 | ;; (assemble-x86 604 | ;; (:with (:options :x86-64 :avx2) 605 | ;; (:input ) 606 | ;; (:store(abc :gpr) (def :gpr :binding-series :a) (vec :vcr))) 607 | ;; (:mov abc 10) 608 | ;; (:mov def 33)) 609 | -------------------------------------------------------------------------------- /x86/ops.main.lisp: -------------------------------------------------------------------------------- 1 | ;;;; ops.main.lisp 2 | 3 | (in-package #:specops.x86) 4 | 5 | ;; Intel PDF pg. 588 has guide to opcode table abbreviations 6 | 7 | (specops mov (op0 op1) *assembler-prototype-x86* 8 | ((:provisions 9 | (rix (logand #b111 (reg-index op0))) (rex (determine-pfrex w op0 op1)) 10 | (sz? (determine-pfsize w op0 op1 (of-program :exmode))) 11 | (modz0 (determine-modrm 0 op0)) (mod10 (determine-modrm op1 op0)) 12 | (mod01 (determine-modrm op0 op1)) (sib0 (determine-sib op0))) 13 | (:priority 0 1)) 14 | ;; ((rex #x88 mod10 sib0) ((:gxm 8) (:gpr 8))) 15 | ((sz? rex #x88 mod10 sib0) ((:w :b) (:gxm ) (:gpr ))) 16 | ((sz? rex #x89 mod10 sib0) ((:w :w) (:gxm ) (:gpr ))) 17 | ((sz? rex #x89 mod10 sib0) ((:w :d) (:gxm ) (:gpr ))) 18 | ((sz? rex #x89 mod10 sib0) ((:w :q) (:gxm ) (:gpr ))) 19 | ;; ((rex #x8A mod10 sib0) ((:gpr 8) (:gxm 8))) 20 | ((sz? rex #x8A mod10 sib0) ((:w :b) (:gpr ) (:gxm ))) 21 | ((sz? rex #x8B mod10 sib0) ((:w :w) (:gpr ) (:gxm ))) 22 | ((sz? rex #x8B mod10 sib0) ((:w :d) (:gpr ) (:gxm ))) 23 | ((sz? rex #x8B mod10 sib0) ((:w :q) (:gpr ) (:gxm ))) 24 | ;; segment register instructions ommitted 25 | ;; ((rex #xA0 ) ((:gpr :al) (:off 8))) 26 | (( rex #xA0 ) ((:w :b) (:gpr :a) (:off ))) 27 | ((sz? rex #xA1 ) ((:w :w) (:gpr :a) (:off ))) 28 | ((sz? rex #xA1 ) ((:w :d) (:gpr :a) (:off ))) 29 | (( rex #xA1 ) ((:w :q) (:gpr :a) (:off ))) 30 | ;; ((rex #xA2 ) ((:off 8) (:gpr :al))) 31 | (( rex #xA2 ) ((:w :b) (:off ) (:gpr :a))) 32 | ((sz? rex #xA3 ) ((:w :w) (:off ) (:gpr :a))) 33 | ((sz? rex #xA3 ) ((:w :d) (:off ) (:gpr :a))) 34 | (( rex #xA3 ) ((:w :q) (:off ) (:gpr :a))) 35 | ;; ((rex (+ #xB0 rix) ) ((:gpr 8) (:imm 8))) 36 | ((sz? rex (+ #xB0 rix) ) ((:w :b) (:gpr ) (:imm ))) 37 | ((sz? rex (+ #xB8 rix) ) ((:w :w) (:gpr ) (:imm ))) 38 | ((sz? rex (+ #xB8 rix) ) ((:w :d) (:gpr ) (:imm ))) 39 | ((sz? rex (+ #xB8 rix) ) ((:w :q) (:gpr ) (:imm ))) 40 | ;; ((sz? rex #xC6 modz0 sib0) ((:gxm 8) (:imm 8))) 41 | ((sz? rex #xC6 modz0 sib0) ((:w :b) (:gxm ) (:imm ))) 42 | ((sz? rex #xC7 modz0 sib0) ((:w :w) (:gxm ) (:imm ))) 43 | ((sz? rex #xC7 modz0 sib0) ((:w :d) (:gxm ) (:imm ))) 44 | ((sz? rex #xC7 modz0 sib0) ((:w :q) (:gxm ) (:imm )))) 45 | 46 | (specops add (w op0 op1) *assembler-prototype-x86* 47 | ((:provisions 48 | (rex (determine-pfrex w op0 op1)) (modz0 (determine-modrm 0 op0)) 49 | (sz? (determine-pfsize w op0 op1 (of-program :exmode))) 50 | (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 51 | (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 52 | (:priority 0 2 1)) 53 | (( rex #x04 op1 ) ((:w :b) (:gpr :a) (:imm ))) 54 | ((sz? rex #x05 (w 2 op1)) ((:w :w) (:gpr :a) (:imm ))) 55 | ((sz? rex #x05 (w 4 op1)) ((:w :d) (:gpr :a) (:imm ))) 56 | (( rex #x05 (w 4 op1)) ((:w :q) (:gpr :a) (:imm ))) 57 | ;; (( #x80 modz0 sib0 op1 ) ((:w :b) (:gxm ) (:imm ))) 58 | ((sz? rex #x80 modz0 sib0 op1 ) ((:w :b) (:gxm ) (:imm 8))) 59 | ((sz? rex #x83 modz0 sib0 op1 ) ((:w :w) (:gxm ) (:imm 8))) 60 | ((sz? rex #x83 modz0 sib0 op1 ) ((:w :d) (:gxm ) (:imm 8))) 61 | ((sz? rex #x83 modz0 sib0 op1 ) ((:w :q) (:gxm ) (:imm 8))) 62 | ((sz? rex #x81 modz0 sib0 (w 2 op1)) ((:w :w) (:gxm ) (:imm 16))) 63 | ((sz? rex #x81 modz0 sib0 (w 4 op1)) ((:w :d) (:gxm ) (:imm 32))) 64 | ((sz? rex #x81 modz0 sib0 (w 4 op1)) ((:w :q) (:gxm ) (:imm 64))) 65 | ;; (( #x00 mod10 sib0 ) ((:w :b) (:gxm ) (:gpr ))) 66 | ((sz? rex #x00 mod10 sib0 ) ((:w :b) (:gxm ) (:gpr ))) 67 | ((sz? rex #x01 mod10 sib0 ) ((:w :w) (:gxm ) (:gpr ))) 68 | ((sz? rex #x01 mod10 sib0 ) ((:w :d) (:gxm ) (:gpr ))) 69 | ((sz? rex #x01 mod10 sib0 ) ((:w :q) (:gxm ) (:gpr ))) 70 | ;; (( #x02 mod01 sib1 ) ((:w :b) (:gpr ) (:gxm ))) 71 | ((sz? rex #x02 mod01 sib1 ) ((:w :b) (:gpr ) (:gxm ))) 72 | ((sz? rex #x03 mod01 sib1 ) ((:w :w) (:gpr ) (:gxm ))) 73 | ((sz? rex #x03 mod01 sib1 ) ((:w :d) (:gpr ) (:gxm ))) 74 | ((sz? rex #x03 mod01 sib1 ) ((:w :q) (:gpr ) (:gxm )))) 75 | 76 | (specops adc (w op0 op1) *assembler-prototype-x86* 77 | ((:provisions 78 | (rex (determine-pfrex w op0 op1)) (mod20 (determine-modrm 2 op0)) 79 | (sz? (determine-pfrsize w op0 op1 (of-program :exmode))) 80 | (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 81 | (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 82 | (:priority 0 2 1)) 83 | (( rex #x14 op1 ) ((:w :b) (:gpr :a) (:imm ))) 84 | ((sz? rex #x15 (w 2 op1)) ((:w :w) (:gpr :a) (:imm ))) 85 | ((sz? rex #x15 (w 4 op1)) ((:w :d) (:gpr :a) (:imm ))) 86 | (( rex #x15 (w 4 op1)) ((:w :q) (:gpr :a) (:imm ))) 87 | ;; (( #x80 mod20 sib0 op1 ) ((:gxm 8) (:imm))) 88 | ((sz? rex #x80 mod20 sib0 op1 ) ((:w :b) (:gxm ) (:imm 8))) 89 | ((sz? rex #x81 mod20 sib0 (w 2 op1)) ((:w :w) (:gxm ) (:imm 16))) 90 | ((sz? rex #x81 mod20 sib0 (w 4 op1)) ((:w :d) (:gxm ) (:imm 32))) 91 | ((sz? rex #x81 mod20 sib0 (w 4 op1)) ((:w :q) (:gxm ) (:imm 64))) 92 | ((sz? rex #x83 mod20 sib0 op1 ) ((:w :w) (:gxm ) (:imm 8))) 93 | ((sz? rex #x83 mod20 sib0 op1 ) ((:w :d) (:gxm ) (:imm 8))) 94 | ((sz? rex #x83 mod20 sib0 op1 ) ((:w :q) (:gxm ) (:imm 8))) 95 | ;; (( #x10 mod10 sib0 ) ((:gxm 8) (:gpr))) 96 | ((sz? rex #x10 mod10 sib0 ) ((:w :b) (:gxm ) (:gpr ))) 97 | ((sz? rex #x11 mod10 sib0 ) ((:w :w) (:gxm ) (:gpr ))) 98 | ((sz? rex #x11 mod10 sib0 ) ((:w :d) (:gxm ) (:gpr ))) 99 | ((sz? rex #x11 mod10 sib0 ) ((:w :q) (:gxm ) (:gpr ))) 100 | ;; (( #x12 mod01 sib1 ) ((:gpr 8) (:gxm))) 101 | ((sz? rex #x12 mod01 sib1 ) ((:w :b) (:gpr ) (:gxm ))) 102 | ((sz? rex #x13 mod01 sib1 ) ((:w :w) (:gpr ) (:gxm ))) 103 | ((sz? rex #x13 mod01 sib1 ) ((:w :d) (:gpr ) (:gxm ))) 104 | ((sz? rex #x13 mod01 sib1 ) ((:w :q) (:gpr ) (:gxm )))) 105 | 106 | (specops sub (w op0 op1) *assembler-prototype-x86* 107 | ((:provisions 108 | (rex (determine-pfrex nil op0 op1)) (mod50 (determine-modrm 5 op0)) 109 | (sz? (determine-pfrsize w op0 op1 (of-program :exmode))) 110 | (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 111 | (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 112 | (:priority 0 2 1)) 113 | (( rex #x2C op1 ) ((:w :b) (:gpr :a) (:imm ))) 114 | ((sz? rex #x2D (w 2 op1)) ((:w :w) (:gpr :a) (:imm ))) 115 | ((sz? rex #x2D (w 4 op1)) ((:w :d) (:gpr :a) (:imm ))) 116 | (( rex #x2D (w 8 op1)) ((:w :q) (:gpr :a) (:imm ))) 117 | ;; (( #x80 mod50 sib0 op1 ) ((:gxm 8) (:imm 8))) 118 | ((sz? rex #x80 mod50 sib0 op1 ) ((:w :b) (:gxm ) (:imm 8))) 119 | ((sz? rex #x81 mod50 sib0 (w 2 op1)) ((:w :w) (:gxm ) (:imm 16))) 120 | ((sz? rex #x81 mod50 sib0 (w 4 op1)) ((:w :d) (:gxm ) (:imm 32))) 121 | ((sz? rex #x81 mod50 sib0 (w 4 op1)) ((:w :q) (:gxm ) (:imm 64))) 122 | ((sz? rex #x83 mod50 sib0 op1 ) ((:w :w) (:gxm ) (:imm 8))) 123 | ((sz? rex #x83 mod50 sib0 op1 ) ((:w :d) (:gxm ) (:imm 8))) 124 | ((sz? rex #x83 mod50 sib0 op1 ) ((:w :q) (:gxm ) (:imm 8))) 125 | ;; (( #x28 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 126 | ((sz? rex #x28 mod10 sib0 ) ((:w :b) (:gxm ) (:gpr ))) 127 | ((sz? rex #x29 mod10 sib0 ) ((:w :w) (:gxm ) (:gpr ))) 128 | ((sz? rex #x29 mod10 sib0 ) ((:w :d) (:gxm ) (:gpr ))) 129 | ((sz? rex #x29 mod10 sib0 ) ((:w :q) (:gxm ) (:gpr ))) 130 | ;; (( #x2A mod01 sib1 ) ((:gpr 8) (:gxm 8))) 131 | ((sz? rex #x2A mod01 sib1 ) ((:w :b) (:gpr ) (:gxm ))) 132 | ((sz? rex #x2B mod01 sib1 ) ((:w :w) (:gpr ) (:gxm ))) 133 | ((sz? rex #x2B mod01 sib1 ) ((:w :d) (:gpr ) (:gxm ))) 134 | ((sz? rex #x2B mod01 sib1 ) ((:w :q) (:gpr ) (:gxm )))) 135 | 136 | (specops sbb (w op0 op1) *assembler-prototype-x86* 137 | ((:provisions 138 | (rex (determine-pfrex w op0 op1)) (mod30 (determine-modrm 3 op0)) 139 | (sz? (determine-pfrsize w op0 op1 (of-program :exmode))) 140 | (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 141 | (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 142 | (:priority 0 2 1)) 143 | (( rex #x1C op1 ) ((:w :b) (:gpr :a) (:imm ))) 144 | ((sz? rex #x1D (w 2 op1)) ((:w :w) (:gpr :a) (:imm ))) 145 | ((sz? rex #x1D (w 4 op1)) ((:w :d) (:gpr :a) (:imm ))) 146 | (( rex #x1D (w 4 op1)) ((:w :q) (:gpr :a) (:imm ))) 147 | ;; (( #x80 mod30 sib0 op1 ) ((:gxm 8) (:imm 8))) 148 | ((sz? rex #x80 mod30 sib0 op1 ) ((:w :b) (:gxm ) (:imm 8))) 149 | ((sz? rex #x81 mod30 sib0 (w 2 op1)) ((:w :w) (:gxm ) (:imm 16))) 150 | ((sz? rex #x81 mod30 sib0 (w 4 op1)) ((:w :d) (:gxm ) (:imm 32))) 151 | ((sz? rex #x81 mod30 sib0 (w 4 op1)) ((:w :q) (:gxm ) (:imm 64))) 152 | ((sz? rex #x83 mod30 sib0 op1 ) ((:w :w) (:gxm ) (:imm 8))) 153 | ((sz? rex #x83 mod30 sib0 op1 ) ((:w :d) (:gxm ) (:imm 8))) 154 | ((sz? rex #x83 mod30 sib0 op1 ) ((:w :q) (:gxm ) (:imm 8))) 155 | ;; (( #x18 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 156 | ((sz? rex #x18 mod10 sib0 ) ((:w :b) (:gxm ) (:gpr ))) 157 | ((sz? rex #x19 mod10 sib0 ) ((:w :w) (:gxm ) (:gpr ))) 158 | ((sz? rex #x19 mod10 sib0 ) ((:w :d) (:gxm ) (:gpr ))) 159 | ((sz? rex #x19 mod10 sib0 ) ((:w :q) (:gxm ) (:gpr ))) 160 | ;; (( #x1A mod01 sib1 ) ((:gpr 8) (:gxm 8))) 161 | ((sz? rex #x1A mod01 sib1 ) ((:w :b) (:gpr ) (:gxm ))) 162 | ((sz? rex #x1B mod01 sib1 ) ((:w :w) (:gpr ) (:gxm ))) 163 | ((sz? rex #x1B mod01 sib1 ) ((:w :d) (:gpr ) (:gxm ))) 164 | ((sz? rex #x1B mod01 sib1 ) ((:w :q) (:gpr ) (:gxm )))) 165 | 166 | (specops aas () *assembler-prototype-x86* 167 | ((#x3F) ())) 168 | 169 | (specops mul (w op0) *assembler-prototype-x86* 170 | ((:provisions 171 | (rex (determine-pfrex w op0 op1)) 172 | (sz? (determine-pfrsize w op0 op1 (of-program :exmode))) 173 | (mod40 (determine-modrm 4 op0)) (sib0 (determine-sib op0))) 174 | (:priority 0 1)) 175 | ;; (( #xF6 mod40 sib0) ((:gxm 8))) 176 | ((sz? rex #xF6 mod40 sib0) ((:w :b) (:gxm 8))) 177 | ((sz? rex #xF7 mod40 sib0) ((:w :w) (:gxm 16))) 178 | ((sz? rex #xF7 mod40 sib0) ((:w :d) (:gxm 32))) 179 | ((sz? rex #xF7 mod40 sib0) ((:w :q) (:gxm 64)))) 180 | 181 | ;; (specops aam (&optional op0) *assembler-prototype-x86* 182 | ;; ((:priority 0)) 183 | ;; ((#xD4 op0) ((:imm 8))) 184 | ;; ((#xD40A ) ())) 185 | 186 | (specops div (w op0) *assembler-prototype-x86* 187 | ((:provisions 188 | (rex (determine-pfrex w op0 op1)) 189 | (sz? (determine-pfrsize w op0 op1 (of-program :exmode))) 190 | (mod60 (determine-modrm 6 op0)) (sib0 (determine-sib op0))) 191 | (:priority 0 1)) 192 | ;; (( #xF6 mod60 sib0) ((:gxm 8))) 193 | ((sz? rex #xF6 mod60 sib0) ((:w :b) (:gxm 8))) 194 | ((sz? rex #xF7 mod60 sib0) ((:w :w) (:gxm 16))) 195 | ((sz? rex #xF7 mod60 sib0) ((:w :d) (:gxm 32))) 196 | ((sz? rex #xF7 mod60 sib0) ((:w :q) (:gxm 64)))) 197 | 198 | (specops neg (w op0) *assembler-prototype-x86* 199 | ((:provisions 200 | (rex (determine-pfrex w op0 nil)) 201 | (sz? (determine-pfrsize w op0 op1 (of-program :exmode))) 202 | (mod30 (determine-modrm 3 op0)) (sib0 (determine-sib op0))) 203 | (:priority 0)) 204 | ;; ((rex #xF6 mod30 sib0) ((:gxm 8))) 205 | ((sz? rex #xF6 mod30 sib0) ((:w :b) (:gxm 8))) 206 | ((sz? rex #xF7 mod30 sib0) ((:w :w) (:gxm 16))) 207 | ((sz? rex #xF7 mod30 sib0) ((:w :d) (:gxm 32))) 208 | ((sz? rex #xF7 mod30 sib0) ((:w :q) (:gxm 64)))) 209 | 210 | (specops and (w op0 op1) *assembler-prototype-x86* 211 | ((:provisions 212 | (rex (determine-pfrex w op0 op1)) 213 | ;; (rex.w (determine-pfrex t op0 op1)) 214 | (sz? (determine-pfrsize w op0 op1 (of-program :exmode))) 215 | (mod40 (determine-modrm 4 op0)) 216 | (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 217 | (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 218 | (:priority 0 2 1)) 219 | (( rex #x24 op1 ) ((:w :b) (:gpr :a) (:imm ))) 220 | ((sz? rex #x25 (w 2 op1)) ((:w :w) (:gpr :a) (:imm ))) 221 | ((sz? rex #x25 (w 4 op1)) ((:w :d) (:gpr :a) (:imm ))) 222 | (( rex #x25 (w 4 op1)) ((:w :q) (:gpr :a) (:imm ))) 223 | ;; ((sz? rex #x80 mod40 sib0 op1 ) ((:gxm 8) (:imm 8))) 224 | ((sz? rex #x80 mod40 sib0 op1 ) ((:w :b) (:gxm ) (:imm 8))) 225 | ((sz? rex #x81 mod40 sib0 (w 2 op1)) ((:w :w) (:gxm ) (:imm 16))) 226 | ((sz? rex #x81 mod40 sib0 (w 4 op1)) ((:w :d) (:gxm ) (:imm 32))) 227 | ((sz? rex #x81 mod40 sib0 (w 4 op1)) ((:w :q) (:gxm ) (:imm 32))) 228 | ((sz? rex #x83 mod40 sib0 op1 ) ((:w :w) (:gxm ) (:imm 8))) 229 | ((sz? rex #x83 mod40 sib0 op1 ) ((:w :d) (:gxm ) (:imm 8))) 230 | ((sz? rex #x83 mod40 sib0 op1 ) ((:w :q) (:gxm ) (:imm 8))) 231 | ;; ((sz? rex #x20 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 232 | ((sz? rex #x20 mod10 sib0 ) ((:w :b) (:gxm ) (:gpr ))) 233 | ((sz? rex #x21 mod10 sib0 ) ((:w :w) (:gxm ) (:gpr ))) 234 | ((sz? rex #x21 mod10 sib0 ) ((:w :d) (:gxm ) (:gpr ))) 235 | ((sz? rex #x21 mod10 sib0 ) ((:w :q) (:gxm ) (:gpr ))) 236 | ;; ((sz? rex #x22 mod01 sib1 ) ((:gpr 8) (:gxm 8))) 237 | ((sz? rex #x22 mod01 sib1 ) ((:w :b) (:gpr ) (:gxm ))) 238 | ((sz? rex #x23 mod01 sib1 ) ((:w :w) (:gpr ) (:gxm ))) 239 | ((sz? rex #x23 mod01 sib1 ) ((:w :d) (:gpr ) (:gxm ))) 240 | ((sz? rex #x23 mod01 sib1 ) ((:w :q) (:gpr ) (:gxm )))) 241 | 242 | (specops or (w op0 op1) *assembler-prototype-x86* 243 | ((:provisions 244 | (rex (determine-pfrex w op0 op1)) (modo0 (determine-modrm 1 op0)) 245 | (sz? (determine-pfrsize w op0 op1 (of-program :exmode))) 246 | (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 247 | (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 248 | (:priority 0 2 1)) 249 | (( rex #x0C op1 ) ((:w :b) (:gpr :a) (:imm ))) 250 | ((sz? rex #x0D (w 2 op1)) ((:w :w) (:gpr :a) (:imm ))) 251 | ((sz? rex #x0D (w 4 op1)) ((:w :d) (:gpr :a) (:imm ))) 252 | (( rex #x0D (w 4 op1)) ((:w :q) (:gpr :a) (:imm ))) 253 | ;; (( #x80 modo0 sib0 op1 ) ((:gxm 8) (:imm 8))) 254 | ((sz? rex #x80 modo0 sib0 op1 ) ((:w :b) (:gxm ) (:imm 8))) 255 | ((sz? rex #x81 modo0 sib0 (w 2 op1)) ((:w :w) (:gxm ) (:imm 16))) 256 | ((sz? rex #x81 modo0 sib0 (w 4 op1)) ((:w :d) (:gxm ) (:imm 32))) 257 | ((sz? rex #x81 modo0 sib0 (w 4 op1)) ((:w :q) (:gxm ) (:imm 32))) 258 | ((sz? rex #x83 modo0 sib0 op1 ) ((:w :w) (:gxm ) (:imm 8))) 259 | ((sz? rex #x83 modo0 sib0 op1 ) ((:w :d) (:gxm ) (:imm 8))) 260 | ((sz? rex #x83 modo0 sib0 op1 ) ((:w :q) (:gxm ) (:imm 8))) 261 | ;; (( #x08 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 262 | ((sz? rex #x08 mod10 sib0 ) ((:w :b) (:gxm ) (:gpr ))) 263 | ((sz? rex #x09 mod10 sib0 ) ((:w :w) (:gxm ) (:gpr ))) 264 | ((sz? rex #x09 mod10 sib0 ) ((:w :d) (:gxm ) (:gpr ))) 265 | ((sz? rex #x09 mod10 sib0 ) ((:w :q) (:gxm ) (:gpr ))) 266 | ;; (( #x0A mod01 sib1 ) ((:gpr 8) (:gxm 8))) 267 | ((sz? rex #x0A mod01 sib1 ) ((:w :b) (:gpr ) (:gxm ))) 268 | ((sz? rex #x0B mod01 sib1 ) ((:w :w) (:gpr ) (:gxm ))) 269 | ((sz? rex #x0B mod01 sib1 ) ((:w :d) (:gpr ) (:gxm ))) 270 | ((sz? rex #x0B mod01 sib1 ) ((:w :q) (:gpr ) (:gxm )))) 271 | 272 | (specops xor (w op0 op1) *assembler-prototype-x86* 273 | ((:provisions 274 | (rex (determine-pfrex w op0 op1)) (mod60 (determine-modrm 6 op0)) 275 | (sz? (determine-pfrsize w op0 op1 (of-program :exmode))) 276 | (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 277 | (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 278 | (:priority 1 0)) 279 | (( rex #x34 op1 ) ((:w :b) (:gpr :a) (:imm ))) 280 | ((sz? rex #x35 (w 2 op1)) ((:w :w) (:gpr :a) (:imm ))) 281 | ((sz? rex #x35 (w 4 op1)) ((:w :d) (:gpr :a) (:imm ))) 282 | (( rex #x35 (w 4 op1)) ((:w :q) (:gpr :a) (:imm ))) 283 | ;; ((rex #x80 mod60 sib0 op1 ) ((:gxm 8) (:imm 8))) 284 | ((sz? rex #x80 mod60 sib0 op1 ) ((:w :b) (:gxm ) (:imm 8))) 285 | ((sz? rex #x81 mod60 sib0 (w 2 op1)) ((:w :w) (:gxm ) (:imm 16))) 286 | ((sz? rex #x81 mod60 sib0 (w 4 op1)) ((:w :d) (:gxm ) (:imm 32))) 287 | ((sz? rex #x81 mod60 sib0 (w 4 op1)) ((:w :q) (:gxm ) (:imm 32))) 288 | ((sz? rex #x83 mod60 sib0 op1 ) ((:w :w) (:gxm ) (:imm 8))) 289 | ((sz? rex #x83 mod60 sib0 op1 ) ((:w :d) (:gxm ) (:imm 8))) 290 | ((sz? rex #x83 mod60 sib0 op1 ) ((:w :q) (:gxm ) (:imm 8))) 291 | ;; ((rex #x30 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 292 | ((sz? rex #x30 mod10 sib0 ) ((:w :b) (:gxm ) (:gpr ))) 293 | ((sz? rex #x31 mod10 sib0 ) ((:w :w) (:gxm ) (:gpr ))) 294 | ((sz? rex #x31 mod10 sib0 ) ((:w :d) (:gxm ) (:gpr ))) 295 | ((sz? rex #x31 mod10 sib0 ) ((:w :q) (:gxm ) (:gpr ))) 296 | ;; (( #x32 mod01 sib1 ) ((:gpr 8) (:gxm 8))) 297 | ((sz? rex #x32 mod01 sib1 ) ((:w :b) (:gpr ) (:gxm ))) 298 | ((sz? rex #x33 mod01 sib1 ) ((:w :w) (:gpr ) (:gxm ))) 299 | ((sz? rex #x33 mod01 sib1 ) ((:w :d) (:gpr ) (:gxm ))) 300 | ((sz? rex #x33 mod01 sib1 ) ((:w :q) (:gpr ) (:gxm )))) 301 | 302 | (specops sal (w op0 op1) *assembler-prototype-x86* 303 | ((:provisions 304 | (rex (determine-pfrex w op0 op1)) 305 | (sz? (determine-pfrsize w op0 op1 (of-program :exmode))) 306 | (mod40 (determine-modrm 4 op0)) (sib0 (determine-sib op0))) 307 | (:priority 0 1)) 308 | ;; (( #xD0 mod40 sib0 ) ((:gxm 8) 1 )) 309 | ((sz? rex #xD0 mod40 sib0 ) ((:w :b) (:gxm) 1 )) 310 | ;; (( #xD2 mod40 sib0 ) ((:gxm 8) (:gpr :cl))) 311 | ((sz? rex #xD2 mod40 sib0 ) ((:w :b) (:gxm) (:gpr :cl))) 312 | ;; ((rex #xC0 mod40 sib0 op1) ((:gxm 8) (:imm 8))) 313 | ((sz? rex #xC0 mod40 sib0 op1) ((:w :b) (:gxm) (:imm 8))) 314 | ((sz? rex #xD1 mod40 sib0 ) ((:w :w) (:gxm) 1 )) 315 | ((sz? rex #xD3 mod40 sib0 ) ((:w :w) (:gxm) (:gpr :cl))) 316 | ((sz? rex #xC1 mod40 sib0 op1) ((:w :w) (:gxm) (:imm 8))) 317 | ((sz? rex #xD1 mod40 sib0 ) ((:w :d) (:gxm) 1 )) 318 | ((sz? rex #xD1 mod40 sib0 ) ((:w :q) (:gxm) 1 )) 319 | ((sz? rex #xD3 mod40 sib0 ) ((:w :d) (:gxm) (:gpr :cl))) 320 | ((sz? rex #xD3 mod40 sib0 ) ((:w :q) (:gxm) (:gpr :cl))) 321 | ((sz? rex #xC1 mod40 sib0 op1) ((:w :d) (:gxm) (:imm 8))) 322 | ((sz? rex #xC1 mod40 sib0 op1) ((:w :q) (:gxm) (:imm 8)))) 323 | 324 | (specops sar (w op0 op1) *assembler-prototype-x86* 325 | ((:provisions 326 | (rex (determine-pfrex w op0 op1)) 327 | (sz? (determine-pfrsize w op0 op1 (of-program :exmode))) 328 | (mod70 (determine-modrm 4 op0)) (sib0 (determine-sib op0))) 329 | (:priority 0 1)) 330 | ;; ((rex #xD0 mod70 sib0 ) ((:gxm 8) 1 )) 331 | ((sz? rex #xD0 mod70 sib0 ) ((:w :b) (:gxm) 1 )) 332 | ;; ((rex #xD2 mod70 sib0 ) ((:gxm 8) (:gpr :cl))) 333 | ((sz? rex #xD2 mod70 sib0 ) ((:w :b) (:gxm) (:gpr :cl))) 334 | ;; ((rex #xC0 mod70 sib0 op1) ((:gxm 8) (:imm 8))) 335 | ((sz? rex #xC0 mod70 sib0 op1) ((:w :b) (:gxm) (:imm 8))) 336 | ((sz? rex #xD1 mod70 sib0 ) ((:w :w) (:gxm) 1 )) 337 | ((sz? rex #xD3 mod70 sib0 ) ((:w :w) (:gxm) (:gpr :cl))) 338 | ((sz? rex #xC1 mod70 sib0 op1) ((:w :w) (:gxm) (:imm 8))) 339 | ((sz? rex #xD1 mod70 sib0 ) ((:w :d) (:gxm) 1 )) 340 | ((sz? rex #xD1 mod70 sib0 ) ((:w :q) (:gxm) 1 )) 341 | ((sz? rex #xD3 mod70 sib0 ) ((:w :d) (:gxm) (:gpr :cl))) 342 | ((sz? rex #xD3 mod70 sib0 ) ((:w :q) (:gxm) (:gpr :cl))) 343 | ((sz? rex #xC1 mod70 sib0 op1) ((:w :d) (:gxm) (:imm 8))) 344 | ((sz? rex #xC1 mod70 sib0 op1) ((:w :q) (:gxm) (:imm 8)))) 345 | 346 | (specops shr (w op0 op1) *assembler-prototype-x86* 347 | ((:provisions 348 | (rex (determine-pfrex w op0 op1)) 349 | (sz? (determine-pfrsize w op0 op1 (of-program :exmode))) 350 | (mod50 (determine-modrm 4 op0)) (sib0 (determine-sib op0))) 351 | (:priority 0 2 1)) 352 | ;; (( #xD0 mod50 sib0 ) ((:gxm 8) 1 )) 353 | ((sz? rex #xD0 mod50 sib0 ) ((:w :b) (:gxm) 1 )) 354 | ;; (( #xD2 mod50 sib0 ) ((:gxm 8) (:gpr :cl))) 355 | ((sz? rex #xD2 mod50 sib0 ) ((:w :b) (:gxm) (:gpr :cl))) 356 | ;; (( #xC0 mod50 sib0 op1) ((:gxm 8) (:imm 8))) 357 | ((sz? rex #xC0 mod50 sib0 op1) ((:w :b) (:gxm) (:imm 8))) 358 | ((sz? rex #xD1 mod50 sib0 ) ((:w :w) (:gxm) 1 )) 359 | ((sz? rex #xD3 mod50 sib0 ) ((:w :w) (:gxm) (:gpr :cl))) 360 | ((sz? rex #xC1 mod50 sib0 op1) ((:w :w) (:gxm) (:imm 8))) 361 | ((sz? rex #xD1 mod50 sib0 ) ((:w :d) (:gxm) 1 )) 362 | ((sz? rex #xD1 mod50 sib0 ) ((:w :q) (:gxm) 1 )) 363 | ((sz? rex #xD3 mod50 sib0 ) ((:w :d) (:gxm) (:gpr :cl))) 364 | ((sz? rex #xD3 mod50 sib0 ) ((:w :q) (:gxm) (:gpr :cl))) 365 | ((sz? rex #xC1 mod50 sib0 op1) ((:w :d) (:gxm) (:imm 8))) 366 | ((sz? rex #xC1 mod50 sib0 op1) ((:w :q) (:gxm) (:imm 8)))) 367 | 368 | (specops cmp (w op0 op1) *assembler-prototype-x86* 369 | ((:provisions 370 | (rex (determine-pfrex w op0 op1)) (mod70 (determine-modrm 7 op0)) 371 | (sz? (determine-pfrsize w op0 op1 (of-program :exmode))) 372 | (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 373 | (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 374 | (:priority 0 2 1)) 375 | (( rex #x3C op1 ) ((:w :b) (:gpr :a) (:imm ))) 376 | ((sz? rex #x3D (w 2 op1)) ((:w :w) (:gpr :a) (:imm ))) 377 | ((sz? rex #x3D (w 4 op1)) ((:w :d) (:gpr :a) (:imm ))) 378 | (( rex #x3D (w 4 op1)) ((:w :q) (:gpr :a) (:imm ))) 379 | ;; ((sz? rex #x80 mod70 sib0 op1 ) ((:gxm 8) (:imm 8))) 380 | ((sz? rex #x80 mod70 sib0 op1 ) ((:w :b) (:gxm ) (:imm 8))) 381 | ((sz? rex #x81 mod70 sib0 (w 2 op1)) ((:w :w) (:gxm ) (:imm 16))) 382 | ((sz? rex #x81 mod70 sib0 (w 4 op1)) ((:w :d) (:gxm ) (:imm 32))) 383 | ((sz? rex #x81 mod70 sib0 (w 4 op1)) ((:w :q) (:gxm ) (:imm 32))) 384 | ((sz? rex #x83 mod70 sib0 op1 ) ((:w :w) (:gxm ) (:imm 8))) 385 | ((sz? rex #x83 mod70 sib0 op1 ) ((:w :d) (:gxm ) (:imm 8))) 386 | ((sz? rex #x83 mod70 sib0 op1 ) ((:w :q) (:gxm ) (:imm 8))) 387 | ;; ((sz? rex #x38 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 388 | ((sz? rex #x38 mod10 sib0 ) ((:w :b) (:gxm ) (:gpr ))) 389 | ((sz? rex #x39 mod10 sib0 ) ((:w :w) (:gxm ) (:gpr ))) 390 | ((sz? rex #x39 mod10 sib0 ) ((:w :d) (:gxm ) (:gpr ))) 391 | ((sz? rex #x39 mod10 sib0 ) ((:w :q) (:gxm ) (:gpr ))) 392 | ;; ((sz? rex #x3A mod01 sib1 ) ((:gpr 8) (:gxm 8))) 393 | ((sz? rex #x3A mod01 sib1 ) ((:w :b) (:gpr ) (:gxm ))) 394 | ((sz? rex #x3B mod01 sib1 ) ((:w :w) (:gpr ) (:gxm ))) 395 | ((sz? rex #x3B mod01 sib1 ) ((:w :d) (:gpr ) (:gxm ))) 396 | ((sz? rex #x3B mod01 sib1 ) ((:w :q) (:gpr ) (:gxm )))) 397 | 398 | (specops ja (w op0) *assembler-prototype-x86* 399 | ((:priority 0 1)) 400 | ((#x77 op0) ((:w :b) (:imm 8))) 401 | ((#x0F87 op0) ((:w :w) (:imm 16))) 402 | ((#x0F87 op0) ((:w :d) (:imm 32)))) 403 | 404 | (specops jae (w op0) *assembler-prototype-x86* 405 | ((:priority 0 1)) 406 | ((#x73 op0) ((:w :b) (:imm 8))) 407 | ((#x0F83 op0) ((:w :w) (:imm 16))) 408 | ((#x0F83 op0) ((:w :d) (:imm 32)))) 409 | 410 | (specops jb (w op0) *assembler-prototype-x86* 411 | ((:priority 0 1)) 412 | ((#x72 op0) ((:w :b) (:imm 8))) 413 | ((#x0F82 op0) ((:w :w) (:imm 16))) 414 | ((#x0F82 op0) ((:w :d) (:imm 32)))) 415 | 416 | (specops jbe (w op0) *assembler-prototype-x86* 417 | ((:priority 0 1)) 418 | ((#x76 op0) ((:w :b) (:imm 8))) 419 | ((#x0F86 op0) ((:w :w) (:imm 16))) 420 | ((#x0F86 op0) ((:w :d) (:imm 32)))) 421 | 422 | (specops jc (w op0) *assembler-prototype-x86* 423 | ((:priority 0 1)) 424 | ((#x72 op0) ((:w :b) (:imm 8))) 425 | ((#x0F82 op0) ((:w :w) (:imm 16))) 426 | ((#x0F82 op0) ((:w :d) (:imm 32)))) 427 | 428 | (specops jcxz (w op0) *assembler-prototype-x86* 429 | ((:priority 0 1)) 430 | ((#xE3 op0) ((:w :b) (:imm 8)))) 431 | 432 | (specops jecxz (w op0) *assembler-prototype-x86* 433 | ((:priority 0 1)) 434 | ((#xE3 op0) ((:w :b) (:imm 8)))) 435 | 436 | (specops jrcxz (w op0) *assembler-prototype-x86* 437 | ((:priority 0 1)) 438 | ((#xE3 op0) ((:w :b) (:imm 8)))) 439 | 440 | (specops je (w op0) *assembler-prototype-x86* 441 | ((:priority 0 1)) 442 | ((#x74 op0) ((:w :b) (:imm 8))) 443 | ((#x0F84 op0) ((:w :w) (:imm 16))) 444 | ((#x0F84 op0) ((:w :d) (:imm 32)))) 445 | 446 | (specops jg (w op0) *assembler-prototype-x86* 447 | ((:priority 0 1)) 448 | ((#x7F op0) ((:w :b) (:imm 8))) 449 | ((#x0F8F op0) ((:w :w) (:imm 16))) 450 | ((#x0F8F op0) ((:w :d) (:imm 32)))) 451 | 452 | (specops jge (w op0) *assembler-prototype-x86* 453 | ((:priority 0 1)) 454 | ((#x7D op0) ((:w :b) (:imm 8))) 455 | ((#x0F8D op0) ((:w :w) (:imm 16))) 456 | ((#x0F8D op0) ((:w :d) (:imm 32)))) 457 | 458 | (specops jl (w op0) *assembler-prototype-x86* 459 | ((:priority 0 1)) 460 | ((#x7C op0) ((:w :b) (:imm 8))) 461 | ((#x0F8C op0) ((:w :w) (:imm 16))) 462 | ((#x0F8C op0) ((:w :d) (:imm 32)))) 463 | 464 | (specops jna (w op0) *assembler-prototype-x86* 465 | ((:priority 0 1)) 466 | ((#x76 op0) ((:w :b) (:imm 8))) 467 | ((#x0F86 op0) ((:w :w) (:imm 16))) 468 | ((#x0F86 op0) ((:w :d) (:imm 32)))) 469 | 470 | (specops jle (w op0) *assembler-prototype-x86* 471 | ((:priority 0 1)) 472 | ((#x7E op0) ((:w :b) (:imm 8))) 473 | ((#x0F8E op0) ((:w :w) (:imm 16))) 474 | ((#x0F8E op0) ((:w :d) (:imm 32)))) 475 | 476 | ;; ...more to come 477 | 478 | ;; (specops ret (op0) *assembler-prototype-x86* 479 | ;; ((:priority 0)) 480 | ;; ((#xC2 op0) ((:imm 16))) ;; needs work 481 | ;; ((#xCA op0) ((:imm 16))) 482 | ;; ((#xC3 op0)) 483 | ;; ((#xCB op0))) 484 | 485 | (specops lea (w op0 op1) *assembler-prototype-x86* 486 | ((:provisions 487 | (rex.w (determine-pfrex w op0 op1)) 488 | (mod01 (determine-modrm op0 op1)) (sib1 (determine-sib op1))) 489 | (:priority 0 1 2)) 490 | ((sz? rex #x8D mod01 sib1) ((:w :w) (:gpr) (:mem))) 491 | ((sz? rex #x8D mod01 sib1) ((:w :w) (:gpr) (:mem))) 492 | ((sz? rex #x8D mod01 sib1) ((:w :q) (:gpr) (:mem)))) 493 | 494 | (specops popcnt (w op0 op1) *assembler-prototype-x86* 495 | ((:provisions 496 | (rex (determine-pfrex w op0 op1)) 497 | (mod01 (determine-modrm op0 op1)) (sib1 (determine-sib op1))) 498 | (:priority 0 1 2)) 499 | ((#xF3 rex #x0FB8 mod01 sib1) ((:w :w) (:gpr) (:gxm))) 500 | ((#xF3 rex #x0FB8 mod01 sib1) ((:w :w) (:gpr) (:gxm))) 501 | ((#xF3 rex #x0FB8 mod01 sib1) ((:w :q) (:gpr) (:gxm)))) 502 | 503 | (specops pshufb (w op0 op1 &optional op2) *assembler-prototype-x86* 504 | ((:provisions 505 | ( vex (determine-pfvex op0 op2 op1 :prefix #x66 :map #x0F38 :long t)) 506 | (evex (determine-pfevex op0 op2 op1 :prefix #x66 :map #x0F38)) 507 | (mod01 (determine-modrm op0 op1)) (mod02 (determine-modrm op0 op2)) 508 | (sib1 (determine-sib op1)) (sib2 (determine-sib op2))) 509 | (:priority 0 1 2)) 510 | ;; (( #x0F3800 mod01 sib1) ((:vcr 64) (:vxm 64) )) 511 | (( #x660F3800 mod01 sib1) ((:w :x) (:vcr) (:vxm) )) 512 | (( vex #x00 mod02 sib2) ((:w :x) (:vcr) (:vcr) (:vxm))) 513 | (( vex #x00 mod02 sib2) ((:w :y) (:vcr) (:vcr) (:vxm))) 514 | ((evex #x00 mod02 sib2) ((:w :x) (:vcr) (:vcr) (:vxm))) 515 | ((evex #x00 mod02 sib2) ((:w :y) (:vcr) (:vcr) (:vxm))) 516 | ((evex #x00 mod02 sib2) ((:w :z) (:vcr) (:vcr) (:vxm)))) 517 | 518 | (specops pshufd (w op0 op1 op2) *assembler-prototype-x86* 519 | ((:provisions 520 | ( vex (determine-pfvex op0 op1 op2 :prefix #x66 :map #x0F :long t)) 521 | (evex (determine-pfevex op0 op1 op2 :prefix #x66 :map #x0F)) 522 | (mod01 (determine-modrm op0 op1)) 523 | (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 524 | (:priority 0 1 2 3)) 525 | (( #x660F70 mod01 sib1 op2) ((:w :x) (:vcr) (:vxm) (:imm 8))) 526 | (( vex #x70 mod01 sib1 op2) ((:w :x) (:vcr) (:vcr) (:imm 8))) 527 | (( vex #x70 mod01 sib1 op2) ((:w :y) (:vcr) (:vcr) (:imm 8))) 528 | ((evex #x70 mod01 sib1 op2) ((:w :x) (:vcr) (:vcr) (:imm 8))) 529 | ((evex #x70 mod01 sib1 op2) ((:w :y) (:vcr) (:vcr) (:imm 8))) 530 | ((evex #x70 mod01 sib1 op2) ((:w :z) (:vcr) (:vcr) (:imm 8)))) 531 | 532 | (specops vpblendd (w op0 op1 op2 op3) *assembler-prototype-x86* 533 | ((:provisions 534 | (vex (determine-pfvex op0 op1 op2 :prefix #x66 :map #x0F3A :long t)) 535 | (mod01 (determine-modrm op0 op1)) (sib1 (determine-sib op1))) 536 | (:priority 0 1 2 3 4)) 537 | ((vex #x02 mod01 sib1 op3) ((:w :x) (:vcr 128) (:vcr 128) (:vxm 128) (:imm 8))) 538 | ((vex #x02 mod01 sib1 op3) ((:w :y) (:vcr 256) (:vcr 256) (:vxm 256) (:imm 8)))) 539 | -------------------------------------------------------------------------------- /x86/ops.main2.lisp: -------------------------------------------------------------------------------- 1 | ;;;; ops.main.lisp 2 | 3 | (in-package #:specops.x86) 4 | 5 | ;; Intel PDF pg. 588 has guide to opcode table abbreviations 6 | 7 | ;; (specops mov (op0 op1) *assembler-prototype-x86* 8 | ;; ((:provisions 9 | ;; (rix (logand #b111 (reg-index op0))) (rex (determine-pfrex nil op0 op1)) 10 | ;; (rex.w (determine-pfrex t op0 op1)) (modz0 (determine-modrm 0 op0)) 11 | ;; (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 12 | ;; (sib0 (determine-sib op0))) 13 | ;; (:priority 0 1)) 14 | ;; (( #x88 mod10 sib0) ((:gxm 8) (:gpr 8))) 15 | ;; ((rex #x88 mod10 sib0) ((:gxm 8) (:gpr 8))) 16 | ;; (( #x89 mod10 sib0) ((:gxm 16) (:gpr 16))) 17 | ;; (( #x89 mod10 sib0) ((:gxm 32) (:gpr 32))) 18 | ;; ((rex.w #x89 mod10 sib0) ((:gxm 64) (:gpr 64))) 19 | ;; (( #x8A mod10 sib0) ((:gpr 8) (:gxm 8))) 20 | ;; ((rex #x8A mod10 sib0) ((:gpr 8) (:gxm 8))) 21 | ;; (( #x8B mod10 sib0) ((:gpr 16) (:gxm 16))) 22 | ;; (( #x8B mod10 sib0) ((:gpr 32) (:gxm 32))) 23 | ;; ((rex.w #x8B mod10 sib0) ((:gpr 64) (:gxm 64))) 24 | ;; ;; segment register instructions ommitted 25 | ;; (( #xA0 ) ((:gpr :al) (:off 8))) 26 | ;; ((rex.w #xA0 ) ((:gpr :al) (:off 8))) 27 | ;; (( #xA1 ) ((:gpr :ax) (:off 16))) 28 | ;; (( #xA1 ) ((:gpr :eax) (:off 32))) 29 | ;; ((rex.w #xA1 ) ((:gpr :rax) (:off 64))) 30 | ;; (( #xA2 ) ((:off 8) (:gpr :al))) 31 | ;; ((rex.w #xA2 ) ((:off 8) (:gpr :al))) 32 | ;; (( #xA3 ) ((:off 16) (:gpr :ax))) 33 | ;; (( #xA3 ) ((:off 32) (:gpr :eax))) 34 | ;; ((rex.w #xA3 ) ((:off 64) (:gpr :rax))) 35 | ;; (( (+ #xB0 rix) ) ((:gpr 8) (:imm 8))) 36 | ;; ((rex (+ #xB0 rix) ) ((:gpr 8) (:imm 8))) 37 | ;; (( (+ #xB8 rix) ) ((:gpr 16) (:imm 16))) 38 | ;; (( (+ #xB8 rix) ) ((:gpr 32) (:imm 32))) 39 | ;; ((rex.w (+ #xB8 rix) ) ((:gpr 64) (:imm 64))) 40 | ;; (( #xC6 modz0 sib0) ((:gxm 8) (:imm 8))) 41 | ;; ((rex #xC6 modz0 sib0) ((:gxm 8) (:imm 8))) 42 | ;; (( #xC7 modz0 sib0) ((:gxm 16) (:imm 16))) 43 | ;; (( #xC7 modz0 sib0) ((:gxm 32) (:imm 32))) 44 | ;; ((rex.w #xC7 modz0 sib0) ((:gxm 64) (:imm 64)))) 45 | 46 | (specops movsx (op0 op1) *assembler-prototype-x86* 47 | ((:provisions 48 | (rex.w (determine-pfrex t op0 op1)) 49 | (mod01 (determine-modrm op0 op1)) (sib1 (determine-sib op1))) 50 | (:priority 0 1)) 51 | (( #x0FBE mod01 sib1) ((:gpr 16) (:gxm 8))) 52 | (( #x0FBE mod01 sib1) ((:gpr 32) (:gxm 8))) 53 | ((rex.w #x0FBE mod01 sib1) ((:gpr 64) (:gxm 8))) 54 | (( #x0FBF mod01 sib1) ((:gpr 32) (:gxm 16))) 55 | ((rex.w #x0FBF mod01 sib1) ((:gpr 64) (:gxm 16)))) 56 | 57 | (specops movsxd (op0 op1) *assembler-prototype-x86* 58 | ((:provisions 59 | (rex.w (determine-pfrex t op0 op1)) 60 | (mod01 (determine-modrm op0 op1)) (sib1 (determine-sib op1))) 61 | (:priority 0 1)) 62 | (( #x63 mod01 sib1) ((:gpr 16) (:gxm 16))) 63 | (( #x63 mod01 sib1) ((:gpr 32) (:gxm 32))) 64 | ((rex.w #x63 mod01 sib1) ((:gpr 64) (:gxm 32)))) 65 | 66 | ;; (specops add (op0 op1) *assembler-prototype-x86* 67 | ;; ((:provisions 68 | ;; (rex (determine-pfrex nil op0 op1)) 69 | ;; (rex.w (determine-pfrex t op0 op1)) (modz0 (determine-modrm 0 op0)) 70 | ;; (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 71 | ;; (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 72 | ;; (:priority 1 0)) 73 | ;; (( #x04 op1 ) ((:gpr :al) (:imm 8))) 74 | ;; (( #x05 (w 2 op1)) ((:gpr :ax) (:imm 16))) 75 | ;; (( #x05 (w 4 op1)) ((:gpr :eax) (:imm 32))) 76 | ;; ((rex.w #x05 (w 4 op1)) ((:gpr :rax) (:imm 32))) 77 | ;; (( #x80 modz0 sib0 op1 ) ((:gxm 8) (:imm 8))) 78 | ;; ((rex #x80 modz0 sib0 op1 ) ((:gxm 8) (:imm 8))) 79 | ;; (( #x81 modz0 sib0 (w 2 op1)) ((:gxm 16) (:imm 16))) 80 | ;; (( #x81 modz0 sib0 (w 4 op1)) ((:gxm 32) (:imm 32))) 81 | ;; ((rex.w #x81 modz0 sib0 (w 4 op1)) ((:gxm 64) (:imm 32))) 82 | ;; (( #x83 modz0 sib0 op1 ) ((:gxm 16) (:imm 8))) 83 | ;; (( #x83 modz0 sib0 op1 ) ((:gxm 32) (:imm 8))) 84 | ;; ((rex.w #x83 modz0 sib0 op1 ) ((:gxm 64) (:imm 8))) 85 | ;; (( #x00 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 86 | ;; ((rex #x00 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 87 | ;; (( #x01 mod10 sib0 ) ((:gxm 16) (:gpr 16))) 88 | ;; (( #x01 mod10 sib0 ) ((:gxm 32) (:gpr 32))) 89 | ;; ((rex.w #x01 mod10 sib0 ) ((:gxm 64) (:gpr 64))) 90 | ;; (( #x02 mod01 sib1 ) ((:gpr 8) (:gxm 8))) 91 | ;; ((rex #x02 mod01 sib1 ) ((:gpr 8) (:gxm 8))) 92 | ;; (( #x03 mod01 sib1 ) ((:gpr 16) (:gxm 16))) 93 | ;; (( #x03 mod01 sib1 ) ((:gpr 32) (:gxm 32))) 94 | ;; ((rex.w #x03 mod01 sib1 ) ((:gpr 64) (:gxm 64)))) 95 | 96 | ;; (specops add (w op0 op1) *assembler-prototype-x86* 97 | ;; ((:provisions 98 | ;; (rex (determine-pfrex nil op0 op1)) 99 | ;; (rex.w (determine-pfrex t op0 op1)) (modz0 (determine-modrm 0 op0)) 100 | ;; (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 101 | ;; (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 102 | ;; (:priority 0 2 1)) 103 | ;; (( #x04 op1 ) ((:w 1) (:gpr :a) (:imm ))) 104 | ;; (( #x05 (w 2 op1)) ((:w 2) (:gpr :a) (:imm ))) 105 | ;; (( #x05 (w 4 op1)) ((:w 4) (:gpr :a) (:imm ))) 106 | ;; ((rex.w #x05 (w 4 op1)) ((:w 8) (:gpr :a) (:imm ))) 107 | ;; (( #x80 modz0 sib0 op1 ) ((:w 1) (:gxm ) (:imm ))) 108 | ;; ((rex #x80 modz0 sib0 op1 ) ((:w 1) (:gxm ) (:imm ))) 109 | ;; (( #x81 modz0 sib0 (w 2 op1)) ((:w 2) (:gxm :lo) (:imm ))) 110 | ;; (( #x81 modz0 sib0 (w 4 op1)) ((:w 4) (:gxm :lo) (:imm ))) 111 | ;; ((rex.w #x81 modz0 sib0 (w 4 op1)) ((:w 8) (:gxm ) (:imm ))) 112 | ;; (( #x83 modz0 sib0 op1 ) ((:w 2) (:gxm :lo) (:imm ))) 113 | ;; (( #x83 modz0 sib0 op1 ) ((:w 4) (:gxm :lo) (:imm ))) 114 | ;; ((rex.w #x83 modz0 sib0 op1 ) ((:w 8) (:gxm ) (:imm ))) 115 | ;; (( #x00 mod10 sib0 ) ((:w 1) (:gxm :lo) (:gpr :lo))) 116 | ;; ((rex #x00 mod10 sib0 ) ((:w 1) (:gxm ) (:gpr ))) 117 | ;; (( #x01 mod10 sib0 ) ((:w 2) (:gxm :lo) (:gpr :lo))) 118 | ;; (( #x01 mod10 sib0 ) ((:w 4) (:gxm :lo) (:gpr :lo))) 119 | ;; ((rex.w #x01 mod10 sib0 ) ((:w 8) (:gxm ) (:gpr ))) 120 | ;; (( #x02 mod01 sib1 ) ((:w 1) (:gpr ) (:gxm ))) 121 | ;; ((rex #x02 mod01 sib1 ) ((:w 1) (:gpr ) (:gxm ))) 122 | ;; (( #x03 mod01 sib1 ) ((:w 2) (:gpr :lo) (:gxm :lo))) 123 | ;; (( #x03 mod01 sib1 ) ((:w 4) (:gpr :lo) (:gxm :lo))) 124 | ;; ((rex.w #x03 mod01 sib1 ) ((:w 8) (:gpr ) (:gxm )))) 125 | 126 | ;; (specops add (w op0 op1) *assembler-prototype-x86* 127 | ;; ((:provisions 128 | ;; (rex (determine-pfrex w op0 op1)) 129 | ;; (sz? (determine-pfrsize w op0 op1 (of-program :exmode))) 130 | ;; (modz0 (determine-modrm 0 op0)) 131 | ;; (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 132 | ;; (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 133 | ;; (:priority 0 2 1)) 134 | ;; (( rex #x04 op1 ) ((:w 1) (:gpr :a) (:imm))) 135 | ;; ((sz? rex #x05 (w 2 op1)) ((:w 2) (:gpr :a) (:imm))) 136 | ;; ((sz? rex #x05 (w 4 op1)) ((:w 4) (:gpr :a) (:imm))) 137 | ;; (( rex #x05 (w 4 op1)) ((:w 8) (:gpr :a) (:imm))) 138 | ;; ;; (( #x80 modz0 sib0 op1 ) ((:w 1) (:gxm ) (:imm ))) 139 | ;; (( rex #x80 modz0 sib0 op1 ) ((:w 1) (:gxm ) (:imm))) 140 | ;; ((sz? rex #x81 modz0 sib0 (w 2 op1)) ((:w 2) (:gxm ) (:imm))) 141 | ;; ((sz? rex #x81 modz0 sib0 (w 4 op1)) ((:w 4) (:gxm ) (:imm))) 142 | ;; (( rex #x81 modz0 sib0 (w 4 op1)) ((:w 8) (:gxm ) (:imm))) 143 | ;; ((sz? rex #x83 modz0 sib0 op1 ) ((:w 2) (:gxm ) (:imm))) 144 | ;; ((sz? rex #x83 modz0 sib0 op1 ) ((:w 4) (:gxm ) (:imm))) 145 | ;; (( rex #x83 modz0 sib0 op1 ) ((:w 8) (:gxm ) (:imm))) 146 | ;; ;; (( #x00 mod10 sib0 ) ((:w 1) (:gxm ) (:gpr ))) 147 | ;; (( rex #x00 mod10 sib0 ) ((:w 1) (:gxm ) (:gpr))) 148 | ;; ((sz? rex #x01 mod10 sib0 ) ((:w 2) (:gxm ) (:gpr))) 149 | ;; ((sz? rex #x01 mod10 sib0 ) ((:w 4) (:gxm ) (:gpr))) 150 | ;; (( rex #x01 mod10 sib0 ) ((:w 8) (:gxm ) (:gpr))) 151 | ;; ;; (( #x02 mod01 sib1 ) ((:w 1) (:gpr ) (:gxm ))) 152 | ;; (( rex #x02 mod01 sib1 ) ((:w 1) (:gpr ) (:gxm))) 153 | ;; ((sz? rex #x03 mod01 sib1 ) ((:w 2) (:gpr ) (:gxm))) 154 | ;; ((sz? rex #x03 mod01 sib1 ) ((:w 4) (:gpr ) (:gxm))) 155 | ;; (( rex #x03 mod01 sib1 ) ((:w 8) (:gpr ) (:gxm)))) 156 | 157 | ;; (specops adc (op0 op1) *assembler-prototype-x86* 158 | ;; ((:provisions 159 | ;; (rex (determine-pfrex nil op0 op1)) 160 | ;; (rex.w (determine-pfrex t op0 op1)) (mod20 (determine-modrm 2 op0)) 161 | ;; (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 162 | ;; (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 163 | ;; (:priority 0 2 1)) 164 | ;; ((rex #x14 op1 ) ((:w 1) (:gpr :a) (:imm))) 165 | ;; ((rex #x15 (w 2 op1)) ((:w 2) (:gpr :a) (:imm))) 166 | ;; ((rex #x15 (w 4 op1)) ((:w 4) (:gpr :a) (:imm))) 167 | ;; ((rex #x15 (w 4 op1)) ((:w 8) (:gpr :a) (:imm))) 168 | ;; ;; (( #x80 mod20 sib0 op1 ) ((:gxm 8) (:imm))) 169 | ;; ((rex #x80 mod20 sib0 op1 ) ((:w 1) (:gxm ) (:imm))) 170 | ;; ((rex #x81 mod20 sib0 (w 2 op1)) ((:w 2) (:gxm ) (:imm))) 171 | ;; ((rex #x81 mod20 sib0 (w 4 op1)) ((:w 4) (:gxm ) (:imm))) 172 | ;; ((rex #x81 mod20 sib0 (w 4 op1)) ((:w 8) (:gxm ) (:imm))) 173 | ;; ((rex #x83 mod20 sib0 op1 ) ((:w 2) (:gxm ) (:imm))) 174 | ;; ((rex #x83 mod20 sib0 op1 ) ((:w 4) (:gxm ) (:imm))) 175 | ;; ((rex #x83 mod20 sib0 op1 ) ((:w 8) (:gxm ) (:imm))) 176 | ;; ;; (( #x10 mod10 sib0 ) ((:gxm 8) (:gpr))) 177 | ;; ((rex #x10 mod10 sib0 ) ((:w 1) (:gxm ) (:gpr))) 178 | ;; ((rex #x11 mod10 sib0 ) ((:w 2) (:gxm ) (:gpr))) 179 | ;; ((rex #x11 mod10 sib0 ) ((:w 4) (:gxm ) (:gpr))) 180 | ;; ((rex #x11 mod10 sib0 ) ((:w 8) (:gxm ) (:gpr))) 181 | ;; ;; (( #x12 mod01 sib1 ) ((:gpr 8) (:gxm))) 182 | ;; ((rex #x12 mod01 sib1 ) ((:w 1) (:gpr ) (:gxm))) 183 | ;; ((rex #x13 mod01 sib1 ) ((:w 2) (:gpr ) (:gxm))) 184 | ;; ((rex #x13 mod01 sib1 ) ((:w 4) (:gpr ) (:gxm))) 185 | ;; ((rex #x13 mod01 sib1 ) ((:w 8) (:gpr ) (:gxm)))) 186 | 187 | ;; (specops sub (op0 op1) *assembler-prototype-x86* 188 | ;; ((:provisions 189 | ;; (rex (determine-pfrex nil op0 op1)) 190 | ;; (rex.w (determine-pfrex t op0 op1)) (mod50 (determine-modrm 5 op0)) 191 | ;; (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 192 | ;; (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 193 | ;; (:priority 1 0)) 194 | ;; (( #x2C op1 ) ((:gpr :al) (:imm 8))) 195 | ;; (( #x2D (w 2 op1)) ((:gpr :ax) (:imm 16))) 196 | ;; (( #x2D (w 4 op1)) ((:gpr :eax) (:imm 32))) 197 | ;; ((rex.w #x2D (w 8 op1)) ((:gpr :rax) (:imm 32))) 198 | ;; (( #x80 mod50 sib0 op1 ) ((:gxm 8) (:imm 8))) 199 | ;; ((rex #x80 mod50 sib0 op1 ) ((:gxm 8) (:imm 8))) 200 | ;; (( #x81 mod50 sib0 (w 2 op1)) ((:gxm 16) (:imm 16))) 201 | ;; (( #x81 mod50 sib0 (w 4 op1)) ((:gxm 32) (:imm 32))) 202 | ;; ((rex.w #x81 mod50 sib0 (w 4 op1)) ((:gxm 64) (:imm 64))) 203 | ;; (( #x83 mod50 sib0 op1 ) ((:gxm 16) (:imm 8))) 204 | ;; (( #x83 mod50 sib0 op1 ) ((:gxm 32) (:imm 8))) 205 | ;; ((rex.w #x83 mod50 sib0 op1 ) ((:gxm 64) (:imm 8))) 206 | ;; (( #x28 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 207 | ;; ((rex #x28 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 208 | ;; (( #x29 mod10 sib0 ) ((:gxm 16) (:gpr 16))) 209 | ;; (( #x29 mod10 sib0 ) ((:gxm 32) (:gpr 32))) 210 | ;; ((rex.w #x29 mod10 sib0 ) ((:gxm 64) (:gpr 64))) 211 | ;; (( #x2A mod01 sib1 ) ((:gpr 8) (:gxm 8))) 212 | ;; ((rex #x2A mod01 sib1 ) ((:gpr 8) (:gxm 8))) 213 | ;; (( #x2B mod01 sib1 ) ((:gpr 16) (:gxm 16))) 214 | ;; (( #x2B mod01 sib1 ) ((:gpr 32) (:gxm 32))) 215 | ;; ((rex.w #x2B mod01 sib1 ) ((:gpr 64) (:gxm 64)))) 216 | 217 | ;; (specops sbb (op0 op1) *assembler-prototype-x86* 218 | ;; ((:provisions 219 | ;; (rex (determine-pfrex nil op0 op1)) 220 | ;; (rex.w (determine-pfrex t op0 op1)) (mod30 (determine-modrm 3 op0)) 221 | ;; (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 222 | ;; (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 223 | ;; (:priority 1 0)) 224 | ;; (( #x1C op1 ) ((:gpr :al) (:imm 8))) 225 | ;; (( #x1D (w 2 op1)) ((:gpr :ax) (:imm 16))) 226 | ;; (( #x1D (w 4 op1)) ((:gpr :eax) (:imm 32))) 227 | ;; ((rex.w #x1D (w 4 op1)) ((:gpr :rax) (:imm 32))) 228 | ;; (( #x80 mod30 sib0 op1 ) ((:gxm 8) (:imm 8))) 229 | ;; ((rex #x80 mod30 sib0 op1 ) ((:gxm 8) (:imm 8))) 230 | ;; (( #x81 mod30 sib0 (w 2 op1)) ((:gxm 16) (:imm 16))) 231 | ;; (( #x81 mod30 sib0 (w 4 op1)) ((:gxm 32) (:imm 32))) 232 | ;; ((rex.w #x81 mod30 sib0 (w 4 op1)) ((:gxm 64) (:imm 64))) 233 | ;; (( #x83 mod30 sib0 op1 ) ((:gxm 16) (:imm 8))) 234 | ;; (( #x83 mod30 sib0 op1 ) ((:gxm 32) (:imm 8))) 235 | ;; ((rex.w #x83 mod30 sib0 op1 ) ((:gxm 64) (:imm 8))) 236 | ;; (( #x18 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 237 | ;; ((rex #x18 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 238 | ;; (( #x19 mod10 sib0 ) ((:gxm 16) (:gpr 16))) 239 | ;; (( #x19 mod10 sib0 ) ((:gxm 32) (:gpr 32))) 240 | ;; ((rex.w #x19 mod10 sib0 ) ((:gxm 64) (:gpr 64))) 241 | ;; (( #x1A mod01 sib1 ) ((:gpr 8) (:gxm 8))) 242 | ;; ((rex #x1A mod01 sib1 ) ((:gpr 8) (:gxm 8))) 243 | ;; (( #x1B mod01 sib1 ) ((:gpr 16) (:gxm 16))) 244 | ;; (( #x1B mod01 sib1 ) ((:gpr 32) (:gxm 32))) 245 | ;; ((rex.w #x1B mod01 sib1 ) ((:gpr 64) (:gxm 64)))) 246 | 247 | ;; (specops aas () *assembler-prototype-x86* 248 | ;; ((#x3F) ())) 249 | 250 | ;; (specops mul (op0 op1) *assembler-prototype-x86* 251 | ;; ((:provisions 252 | ;; (rex (determine-pfrex nil op0 op1)) (rex.w (determine-pfrex t op0 op1)) 253 | ;; (mod40 (determine-modrm 4 op0)) (sib0 (determine-sib op0))) 254 | ;; (:priority 0)) 255 | ;; (( #xF6 mod40 sib0) ((:gxm 8))) 256 | ;; ((rex #xF6 mod40 sib0) ((:gxm 8))) 257 | ;; (( #xF7 mod40 sib0) ((:gxm 16))) 258 | ;; (( #xF7 mod40 sib0) ((:gxm 32))) 259 | ;; ((rex.w #xF7 mod40 sib0) ((:gxm 64)))) 260 | 261 | ;; (specops aam (&optional op0) *assembler-prototype-x86* 262 | ;; ((:priority 0)) 263 | ;; ((#xD4 op0) ((:imm 8))) 264 | ;; ((#xD40A ) ())) 265 | 266 | ;; (specops div (op0 op1) *assembler-prototype-x86* 267 | ;; ((:provisions 268 | ;; (rex (determine-pfrex nil op0 op1)) (rex.w (determine-pfrex t op0 op1)) 269 | ;; (mod60 (determine-modrm 6 op0)) (sib0 (determine-sib op0))) 270 | ;; (:priority 0)) 271 | ;; (( #xF6 mod60 sib0) ((:gxm 8))) 272 | ;; ((rex #xF6 mod60 sib0) ((:gxm 8))) 273 | ;; (( #xF7 mod60 sib0) ((:gxm 16))) 274 | ;; (( #xF7 mod60 sib0) ((:gxm 32))) 275 | ;; ((rex.w #xF7 mod60 sib0) ((:gxm 64)))) 276 | 277 | ;; (specops neg (op0) *assembler-prototype-x86* 278 | ;; ((:provisions 279 | ;; (rex (determine-pfrex nil op0 nil)) (rex.w (determine-pfrex t op0 nil)) 280 | ;; (mod30 (determine-modrm 3 op0)) (sib0 (determine-sib op0))) 281 | ;; (:priority 0)) 282 | ;; (( #xF6 mod30 sib0) ((:gxm 8))) 283 | ;; ((rex #xF6 mod30 sib0) ((:gxm 8))) 284 | ;; (( #xF7 mod30 sib0) ((:gxm 16))) 285 | ;; (( #xF7 mod30 sib0) ((:gxm 32))) 286 | ;; ((rex.w #xF7 mod30 sib0) ((:gxm 64)))) 287 | 288 | ;; (specops and (op0 op1) *assembler-prototype-x86* 289 | ;; ((:provisions 290 | ;; (rex (determine-pfrex nil op0 op1)) 291 | ;; (rex.w (determine-pfrex t op0 op1)) (mod40 (determine-modrm 4 op0)) 292 | ;; (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 293 | ;; (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 294 | ;; (:priority 1 0)) 295 | ;; (( #x24 op1 ) ((:gpr :al) (:imm 8))) 296 | ;; (( #x25 (w 2 op1)) ((:gpr :ax) (:imm 16))) 297 | ;; (( #x25 (w 4 op1)) ((:gpr :eax) (:imm 32))) 298 | ;; ((rex.w #x25 (w 4 op1)) ((:gpr :rax) (:imm 32))) 299 | ;; (( #x80 mod40 sib0 op1 ) ((:gxm 8) (:imm 8))) 300 | ;; ((rex #x80 mod40 sib0 op1 ) ((:gxm 8) (:imm 8))) 301 | ;; (( #x81 mod40 sib0 (w 2 op1)) ((:gxm 16) (:imm 16))) 302 | ;; (( #x81 mod40 sib0 (w 4 op1)) ((:gxm 32) (:imm 32))) 303 | ;; ((rex.w #x81 mod40 sib0 (w 4 op1)) ((:gxm 64) (:imm 32))) 304 | ;; (( #x83 mod40 sib0 (w 2 op1)) ((:gxm 16) (:imm 8))) 305 | ;; (( #x83 mod40 sib0 (w 4 op1)) ((:gxm 32) (:imm 8))) 306 | ;; ((rex.w #x83 mod40 sib0 (w 4 op1)) ((:gxm 64) (:imm 8))) 307 | ;; (( #x20 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 308 | ;; ((rex #x20 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 309 | ;; (( #x21 mod10 sib0 ) ((:gxm 16) (:gpr 16))) 310 | ;; (( #x21 mod10 sib0 ) ((:gxm 32) (:gpr 32))) 311 | ;; ((rex.w #x21 mod10 sib0 ) ((:gxm 64) (:gpr 64))) 312 | ;; (( #x22 mod01 sib1 ) ((:gpr 8) (:gxm 8))) 313 | ;; ((rex #x22 mod01 sib1 ) ((:gpr 8) (:gxm 8))) 314 | ;; (( #x23 mod01 sib1 ) ((:gpr 16) (:gxm 16))) 315 | ;; (( #x23 mod01 sib1 ) ((:gpr 32) (:gxm 32))) 316 | ;; ((rex.w #x23 mod01 sib1 ) ((:gpr 64) (:gxm 64)))) 317 | 318 | ;; (specops or (op0 op1) *assembler-prototype-x86* 319 | ;; ((:provisions 320 | ;; (rex (determine-pfrex nil op0 op1)) 321 | ;; (rex.w (determine-pfrex t op0 op1)) (modo0 (determine-modrm 1 op0)) 322 | ;; (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 323 | ;; (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 324 | ;; (:priority 0 1)) 325 | ;; (( #x0C op1 ) ((:gpr :al) (:imm 8))) 326 | ;; (( #x0D (w 2 op1)) ((:gpr :ax) (:imm 16))) 327 | ;; (( #x0D (w 4 op1)) ((:gpr :eax) (:imm 32))) 328 | ;; ((rex.w #x0D (w 4 op1)) ((:gpr :rax) (:imm 32))) 329 | ;; (( #x80 modo0 sib0 op1 ) ((:gxm 8) (:imm 8))) 330 | ;; ((rex #x80 modo0 sib0 op1 ) ((:gxm 8) (:imm 8))) 331 | ;; (( #x81 modo0 sib0 (w 2 op1)) ((:gxm 16) (:imm 16))) 332 | ;; (( #x81 modo0 sib0 (w 4 op1)) ((:gxm 32) (:imm 32))) 333 | ;; ((rex.w #x81 modo0 sib0 (w 4 op1)) ((:gxm 64) (:imm 32))) 334 | ;; (( #x83 modo0 sib0 (w 2 op1)) ((:gxm 16) (:imm 8))) 335 | ;; (( #x83 modo0 sib0 (w 4 op1)) ((:gxm 32) (:imm 8))) 336 | ;; ((rex.w #x83 modo0 sib0 (w 4 op1)) ((:gxm 32) (:imm 8))) 337 | ;; (( #x08 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 338 | ;; ((rex #x08 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 339 | ;; (( #x09 mod10 sib0 ) ((:gxm 16) (:gpr 16))) 340 | ;; (( #x09 mod10 sib0 ) ((:gxm 32) (:gpr 32))) 341 | ;; ((rex.w #x09 mod10 sib0 ) ((:gxm 64) (:gpr 64))) 342 | ;; (( #x0A mod01 sib1 ) ((:gpr 8) (:gxm 8))) 343 | ;; ((rex #x0A mod01 sib1 ) ((:gpr 8) (:gxm 8))) 344 | ;; (( #x0B mod01 sib1 ) ((:gpr 16) (:gxm 16))) 345 | ;; (( #x0B mod01 sib1 ) ((:gpr 32) (:gxm 32))) 346 | ;; ((rex.w #x0B mod01 sib1 ) ((:gpr 64) (:gxm 64)))) 347 | 348 | ;; (specops xor (op0 op1) *assembler-prototype-x86* 349 | ;; ((:provisions 350 | ;; (rex (determine-pfrex nil op0 op1)) 351 | ;; (rex.w (determine-pfrex t op0 op1)) (mod60 (determine-modrm 6 op0)) 352 | ;; (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 353 | ;; (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 354 | ;; (:priority 1 0)) 355 | ;; (( #x34 op1 ) ((:gpr :al) (:imm 8))) 356 | ;; (( #x35 (w 2 op1)) ((:gpr :ax) (:imm 16))) 357 | ;; (( #x35 (w 4 op1)) ((:gpr :eax) (:imm 32))) 358 | ;; ((rex.w #x35 (w 4 op1)) ((:gpr :rax) (:imm 32))) 359 | ;; (( #x80 mod60 sib0 op1 ) ((:gxm 8) (:imm 8))) 360 | ;; ((rex #x80 mod60 sib0 op1 ) ((:gxm 8) (:imm 8))) 361 | ;; (( #x81 mod60 sib0 (w 2 op1)) ((:gxm 16) (:imm 16))) 362 | ;; (( #x81 mod60 sib0 (w 4 op1)) ((:gxm 32) (:imm 32))) 363 | ;; ((rex.w #x81 mod60 sib0 (w 4 op1)) ((:gxm 64) (:imm 32))) 364 | ;; (( #x83 mod60 sib0 (w 2 op1)) ((:gxm 16) (:imm 16))) 365 | ;; (( #x83 mod60 sib0 (w 4 op1)) ((:gxm 32) (:imm 32))) 366 | ;; ((rex.w #x83 mod60 sib0 (w 4 op1)) ((:gxm 32) (:imm 32))) 367 | ;; (( #x30 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 368 | ;; ((rex #x30 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 369 | ;; (( #x31 mod10 sib0 ) ((:gxm 16) (:gpr 16))) 370 | ;; (( #x31 mod10 sib0 ) ((:gxm 32) (:gpr 32))) 371 | ;; ((rex.w #x31 mod10 sib0 ) ((:gxm 64) (:gpr 64))) 372 | ;; (( #x32 mod01 sib1 ) ((:gpr 8) (:gxm 8))) 373 | ;; ((rex #x32 mod01 sib1 ) ((:gpr 8) (:gxm 8))) 374 | ;; (( #x33 mod01 sib1 ) ((:gpr 16) (:gxm 16))) 375 | ;; (( #x33 mod01 sib1 ) ((:gpr 32) (:gxm 32))) 376 | ;; ((rex.w #x33 mod01 sib1 ) ((:gpr 64) (:gxm 64)))) 377 | 378 | ;; (specops sal (op0 op1) *assembler-prototype-x86* 379 | ;; ((:provisions 380 | ;; (rex (determine-pfrex nil op0 op1)) (rex.w (determine-pfrex t op0 op1)) 381 | ;; (mod40 (determine-modrm 4 op0)) (sib0 (determine-sib op0))) 382 | ;; (:priority 0 1)) 383 | ;; (( #xD0 mod40 sib0 ) ((:gxm 8) 1 )) 384 | ;; ((rex #xD0 mod40 sib0 ) ((:gxm 8) 1 )) 385 | ;; (( #xD2 mod40 sib0 ) ((:gxm 8) (:gpr :cl))) 386 | ;; ((rex #xD2 mod40 sib0 ) ((:gxm 8) (:gpr :cl))) 387 | ;; (( #xC0 mod40 sib0 op1) ((:gxm 8) (:imm 8))) 388 | ;; ((rex #xC0 mod40 sib0 op1) ((:gxm 8) (:imm 8))) 389 | ;; (( #xD1 mod40 sib0 ) ((:gxm 16) 1 )) 390 | ;; (( #xD3 mod40 sib0 ) ((:gxm 16) (:gpr :cl))) 391 | ;; (( #xC1 mod40 sib0 op1) ((:gxm 16) (:imm 8))) 392 | ;; (( #xD1 mod40 sib0 ) ((:gxm 32) 1 )) 393 | ;; ((rex.w #xD1 mod40 sib0 ) ((:gxm 64) 1 )) 394 | ;; (( #xD3 mod40 sib0 ) ((:gxm 32) (:gpr :cl))) 395 | ;; ((rex.w #xD3 mod40 sib0 ) ((:gxm 64) (:gpr :cl))) 396 | ;; (( #xC1 mod40 sib0 op1) ((:gxm 32) (:imm 8))) 397 | ;; ((rex.w #xC1 mod40 sib0 op1) ((:gxm 64) (:imm 8)))) 398 | 399 | ;; (specops sar (op0 op1) *assembler-prototype-x86* 400 | ;; ((:provisions 401 | ;; (rex (determine-pfrex nil op0 op1)) (rex.w (determine-pfrex t op0 op1)) 402 | ;; (mod70 (determine-modrm 4 op0)) (sib0 (determine-sib op0))) 403 | ;; (:priority 0 1)) 404 | ;; (( #xD0 mod70 sib0 ) ((:gxm 8) 1 )) 405 | ;; ((rex #xD0 mod70 sib0 ) ((:gxm 8) 1 )) 406 | ;; (( #xD2 mod70 sib0 ) ((:gxm 8) (:gpr :cl))) 407 | ;; ((rex #xD2 mod70 sib0 ) ((:gxm 8) (:gpr :cl))) 408 | ;; (( #xC0 mod70 sib0 op1) ((:gxm 8) (:imm 8))) 409 | ;; ((rex #xC0 mod70 sib0 op1) ((:gxm 8) (:imm 8))) 410 | ;; (( #xD1 mod70 sib0 ) ((:gxm 16) 1 )) 411 | ;; (( #xD3 mod70 sib0 ) ((:gxm 16) (:gpr :cl))) 412 | ;; (( #xC1 mod70 sib0 op1) ((:gxm 16) (:imm 8))) 413 | ;; (( #xD1 mod70 sib0 ) ((:gxm 32) 1 )) 414 | ;; ((rex.w #xD1 mod70 sib0 ) ((:gxm 64) 1 )) 415 | ;; (( #xD3 mod70 sib0 ) ((:gxm 32) (:gpr :cl))) 416 | ;; ((rex.w #xD3 mod70 sib0 ) ((:gxm 64) (:gpr :cl))) 417 | ;; (( #xC1 mod70 sib0 op1) ((:gxm 32) (:imm 8))) 418 | ;; ((rex.w #xC1 mod70 sib0 op1) ((:gxm 64) (:imm 8)))) 419 | 420 | ;; (specops shr (op0 op1) *assembler-prototype-x86* 421 | ;; ((:provisions 422 | ;; (rex (determine-pfrex nil op0 op1)) (rex.w (determine-pfrex t op0 op1)) 423 | ;; (mod50 (determine-modrm 4 op0)) (sib0 (determine-sib op0))) 424 | ;; (:priority 0 1)) 425 | ;; (( #xD0 mod50 sib0 ) ((:gxm 8) 1 )) 426 | ;; ((rex #xD0 mod50 sib0 ) ((:gxm 8) 1 )) 427 | ;; (( #xD2 mod50 sib0 ) ((:gxm 8) (:gpr :cl))) 428 | ;; ((rex #xD2 mod50 sib0 ) ((:gxm 8) (:gpr :cl))) 429 | ;; (( #xC0 mod50 sib0 op1) ((:gxm 8) (:imm 8))) 430 | ;; ((rex #xC0 mod50 sib0 op1) ((:gxm 8) (:imm 8))) 431 | ;; (( #xD1 mod50 sib0 ) ((:gxm 16) 1 )) 432 | ;; (( #xD3 mod50 sib0 ) ((:gxm 16) (:gpr :cl))) 433 | ;; (( #xC1 mod50 sib0 op1) ((:gxm 16) (:imm 8))) 434 | ;; (( #xD1 mod50 sib0 ) ((:gxm 32) 1 )) 435 | ;; ((rex.w #xD1 mod50 sib0 ) ((:gxm 64) 1 )) 436 | ;; (( #xD3 mod50 sib0 ) ((:gxm 32) (:gpr :cl))) 437 | ;; ((rex.w #xD3 mod50 sib0 ) ((:gxm 64) (:gpr :cl))) 438 | ;; (( #xC1 mod50 sib0 op1) ((:gxm 32) (:imm 8))) 439 | ;; ((rex.w #xC1 mod50 sib0 op1) ((:gxm 64) (:imm 8)))) 440 | 441 | ;; (specops cmp (op0 op1) *assembler-prototype-x86* 442 | ;; ((:provisions 443 | ;; (rex (determine-pfrex nil op0 op1)) 444 | ;; (rex.w (determine-pfrex t op0 op1)) (mod70 (determine-modrm 7 op0)) 445 | ;; (mod10 (determine-modrm op1 op0)) (mod01 (determine-modrm op0 op1)) 446 | ;; (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 447 | ;; (:priority 1 0)) 448 | ;; (( #x3C op1 ) ((:gpr :al) (:imm 8))) 449 | ;; (( #x3D (w 2 op1)) ((:gpr :ax) (:imm 16))) 450 | ;; (( #x3D (w 4 op1)) ((:gpr :eax) (:imm 32))) 451 | ;; ((rex.w #x3D (w 4 op1)) ((:gpr :rax) (:imm 32))) 452 | ;; (( #x80 mod70 sib0 op1 ) ((:gxm 8) (:imm 8))) 453 | ;; ((rex #x80 mod70 sib0 op1 ) ((:gxm 8) (:imm 8))) 454 | ;; (( #x81 mod70 sib0 (w 2 op1)) ((:gxm 16) (:imm 16))) 455 | ;; (( #x81 mod70 sib0 (w 4 op1)) ((:gxm 32) (:imm 32))) 456 | ;; ((rex.w #x81 mod70 sib0 (w 4 op1)) ((:gxm 64) (:imm 32))) 457 | ;; (( #x83 mod70 sib0 (w 2 op1)) ((:gxm 16) (:imm 16))) 458 | ;; (( #x83 mod70 sib0 (w 4 op1)) ((:gxm 32) (:imm 32))) 459 | ;; ((rex.w #x83 mod70 sib0 (w 4 op1)) ((:gxm 32) (:imm 32))) 460 | ;; (( #x38 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 461 | ;; ((rex #x38 mod10 sib0 ) ((:gxm 8) (:gpr 8))) 462 | ;; (( #x39 mod10 sib0 ) ((:gxm 16) (:gpr 16))) 463 | ;; (( #x39 mod10 sib0 ) ((:gxm 32) (:gpr 32))) 464 | ;; ((rex.w #x39 mod10 sib0 ) ((:gxm 64) (:gpr 64))) 465 | ;; (( #x3A mod01 sib1 ) ((:gpr 8) (:gxm 8))) 466 | ;; ((rex #x3A mod01 sib1 ) ((:gpr 8) (:gxm 8))) 467 | ;; (( #x3B mod01 sib1 ) ((:gpr 16) (:gxm 16))) 468 | ;; (( #x3B mod01 sib1 ) ((:gpr 32) (:gxm 32))) 469 | ;; ((rex.w #x3B mod01 sib1 ) ((:gpr 64) (:gxm 64)))) 470 | 471 | ;; (specops ja (op0) *assembler-prototype-x86* 472 | ;; ((:priority 0)) 473 | ;; ((#x77 op0) ((:imm 8))) 474 | ;; ((#x0F87 op0) ((:imm 16))) 475 | ;; ((#x0F87 op0) ((:imm 32)))) 476 | 477 | ;; (specops jae (op0) *assembler-prototype-x86* 478 | ;; ((:priority 0)) 479 | ;; ((#x73 op0) ((:imm 8))) 480 | ;; ((#x0F83 op0) ((:imm 16))) 481 | ;; ((#x0F83 op0) ((:imm 32)))) 482 | 483 | ;; (specops jb (op0) *assembler-prototype-x86* 484 | ;; ((:priority 0)) 485 | ;; ((#x72 op0) ((:imm 8))) 486 | ;; ((#x0F82 op0) ((:imm 16))) 487 | ;; ((#x0F82 op0) ((:imm 32)))) 488 | 489 | ;; (specops jbe (op0) *assembler-prototype-x86* 490 | ;; ((:priority 0)) 491 | ;; ((#x76 op0) ((:imm 8))) 492 | ;; ((#x0F86 op0) ((:imm 16))) 493 | ;; ((#x0F86 op0) ((:imm 32)))) 494 | 495 | ;; (specops jc (op0) *assembler-prototype-x86* 496 | ;; ((:priority 0)) 497 | ;; ((#x72 op0) ((:imm 8))) 498 | ;; ((#x0F82 op0) ((:imm 16))) 499 | ;; ((#x0F82 op0) ((:imm 32)))) 500 | 501 | ;; (specops jcxz (op0) *assembler-prototype-x86* 502 | ;; ((:priority 0)) 503 | ;; ((#xE3op0) ((:imm 8)))) 504 | 505 | ;; (specops jecxz (op0) *assembler-prototype-x86* 506 | ;; ((:priority 0)) 507 | ;; ((#xE3 op0) ((:imm 8)))) 508 | 509 | ;; (specops jrcxz (op0) *assembler-prototype-x86* 510 | ;; ((:priority 0)) 511 | ;; ((#xE3 op0) ((:imm 8)))) 512 | 513 | ;; (specops je (op0) *assembler-prototype-x86* 514 | ;; ((:priority 0)) 515 | ;; ((#x74 op0) ((:imm 8))) 516 | ;; ((#x0F84 op0) ((:imm 16))) 517 | ;; ((#x0F84 op0) ((:imm 32)))) 518 | 519 | ;; (specops jg (op0) *assembler-prototype-x86* 520 | ;; ((:priority 0)) 521 | ;; ((#x7F op0) ((:imm 8))) 522 | ;; ((#x0F8F op0) ((:imm 16))) 523 | ;; ((#x0F8F op0) ((:imm 32)))) 524 | 525 | ;; (specops jge (op0) *assembler-prototype-x86* 526 | ;; ((:priority 0)) 527 | ;; ((#x7D op0) ((:imm 8))) 528 | ;; ((#x0F8D op0) ((:imm 16))) 529 | ;; ((#x0F8D op0) ((:imm 32)))) 530 | 531 | ;; (specops jl (op0) *assembler-prototype-x86* 532 | ;; ((:priority 0)) 533 | ;; ((#x7C op0) ((:imm 8))) 534 | ;; ((#x0F8C op0) ((:imm 16))) 535 | ;; ((#x0F8C op0) ((:imm 32)))) 536 | 537 | ;; (specops jna (op0) *assembler-prototype-x86* 538 | ;; ((:priority 0)) 539 | ;; ((#x76 op0) ((:imm 8))) 540 | ;; ((#x0F86 op0) ((:imm 16))) 541 | ;; ((#x0F86 op0) ((:imm 32)))) 542 | 543 | ;; (specops jle (op0) *assembler-prototype-x86* 544 | ;; ((:priority 0)) 545 | ;; ((#x7E op0) ((:imm 8))) 546 | ;; ((#x0F8E op0) ((:imm 16))) 547 | ;; ((#x0F8E op0) ((:imm 32)))) 548 | 549 | ;; ...more to come 550 | 551 | ;; (specops ret (op0) *assembler-prototype-x86* 552 | ;; ((:priority 0)) 553 | ;; ((#xC2 op0) ((:imm 16))) ;; needs work 554 | ;; ((#xCA op0) ((:imm 16))) 555 | ;; ((#xC3 op0)) 556 | ;; ((#xCB op0))) 557 | 558 | ;; (specops lea (op0 op1) *assembler-prototype-x86* 559 | ;; ((:provisions 560 | ;; (rex.w (determine-pfrex t op0 op1)) 561 | ;; (mod01 (determine-modrm op0 op1)) (sib1 (determine-sib op1))) 562 | ;; (:priority 0 1)) 563 | ;; (( #x8D mod01 sib1) ((:gpr 16) (:mem 16))) 564 | ;; (( #x8D mod01 sib1) ((:gpr 32) (:mem 32))) 565 | ;; ((rex.w #x8D mod01 sib1) ((:gpr 64) (:mem 64)))) 566 | 567 | ;; (specops popcnt (op0 op1) *assembler-prototype-x86* 568 | ;; ((:provisions 569 | ;; (rex.w (determine-pfrex t op0 op1)) 570 | ;; (mod01 (determine-modrm op0 op1)) (sib1 (determine-sib op1))) 571 | ;; (:priority 0 1)) 572 | ;; ((#xF3 #x0FB8 mod01 sib1) ((:gpr 16) (:gxm 16))) 573 | ;; ((#xF3 #x0FB8 mod01 sib1) ((:gpr 32) (:gxm 32))) 574 | ;; ((#xF3 rex.w #x0FB8 mod01 sib1) ((:gpr 64) (:gxm 64)))) 575 | 576 | ;; (specops pshufb (op0 op1 &optional op2) *assembler-prototype-x86* 577 | ;; ((:provisions 578 | ;; (vex (determine-pfvex op0 op2 op1 :prefix #x66 :map #x0F38 :long t)) 579 | ;; (evex (determine-pfevex op0 op2 op1 :prefix #x66 :map #x0F38)) 580 | ;; (mod01 (determine-modrm op0 op1)) (mod02 (determine-modrm op0 op2)) 581 | ;; (sib1 (determine-sib op1)) (sib2 (determine-sib op2))) 582 | ;; (:priority 0 1 2)) 583 | ;; ;; (( #x0F3800 mod01 sib1) ((:vcr 64) (:vxm 64) )) 584 | ;; (( #x660F3800 mod01 sib1) ((:vcr 128) (:vxm 128) )) 585 | ;; (( vex #x00 mod02 sib2) ((:vcr 128) (:vcr 128) (:vxm 128))) 586 | ;; (( vex #x00 mod02 sib2) ((:vcr 256) (:vcr 256) (:vxm 256))) 587 | ;; ((evex #x00 mod02 sib2) ((:vcr 128) (:vcr 128) (:vxm 128))) 588 | ;; ((evex #x00 mod02 sib2) ((:vcr 256) (:vcr 256) (:vxm 256))) 589 | ;; ((evex #x00 mod02 sib2) ((:vcr 512) (:vcr 512) (:vxm 512)))) 590 | 591 | ;; (specops pshufd (op0 op1 op2) *assembler-prototype-x86* 592 | ;; ((:provisions 593 | ;; ( vex (determine-pfvex op0 op1 op2 :prefix #x66 :map #x0F :long t)) 594 | ;; (evex (determine-pfevex op0 op1 op2 :prefix #x66 :map #x0F)) 595 | ;; (mod01 (determine-modrm op0 op1)) 596 | ;; (sib0 (determine-sib op0)) (sib1 (determine-sib op1))) 597 | ;; (:priority 0 1 2)) 598 | ;; (( #x660F70 mod01 sib1 op2) ((:vcr 128) (:vxm 128) (:imm 8))) 599 | ;; (( vex #x70 mod01 sib1 op2) ((:vcr 128) (:vcr 128) (:imm 8))) 600 | ;; (( vex #x70 mod01 sib1 op2) ((:vcr 256) (:vcr 256) (:imm 8))) 601 | ;; ((evex #x70 mod01 sib1 op2) ((:vcr 128) (:vcr 128) (:imm 8))) 602 | ;; ((evex #x70 mod01 sib1 op2) ((:vcr 256) (:vcr 256) (:imm 8))) 603 | ;; ((evex #x70 mod01 sib1 op2) ((:vcr 512) (:vcr 512) (:imm 8)))) 604 | 605 | ;; (specops vpblendd (op0 op1 op2 op3) *assembler-prototype-x86* 606 | ;; ((:provisions 607 | ;; (vex (determine-pfvex op0 op1 op2 :prefix #x66 :map #x0F3A :long t)) 608 | ;; (mod01 (determine-modrm op0 op1)) (sib1 (determine-sib op1))) 609 | ;; (:priority 0 1 2 3)) 610 | ;; ((vex #x02 mod01 sib1 op3) ((:vcr 128) (:vcr 128) (:vxm 128) (:imm 8))) 611 | ;; ((vex #x02 mod01 sib1 op3) ((:vcr 256) (:vcr 256) (:vxm 256) (:imm 8)))) 612 | 613 | 614 | ;; https://wiki.raptorcs.com/w/images/f/f5/PowerISA_public.v3.1.pdf pg. 12 615 | 616 | (defun powerformat-a 617 | (masque "PPPPPPAA.AAABBBBB.CCCCCDDD.DDXXXXXR")) 618 | -------------------------------------------------------------------------------- /x86/package.lisp: -------------------------------------------------------------------------------- 1 | ;;;; package.lisp 2 | 3 | (defpackage #:specops.x86 4 | (:use #:cl #:specops)) 5 | -------------------------------------------------------------------------------- /x86/specops.x86.asd: -------------------------------------------------------------------------------- 1 | ;;;; specops.x86.asd 2 | 3 | (asdf:defsystem #:specops.x86 4 | :description "Assembler framework for x86 architectures based on SpecOps." 5 | :author "Andrew Sengul" 6 | :license "BSD" 7 | :version "0.0.1" 8 | :serial t 9 | :depends-on ("specops") 10 | :components ((:file "package") 11 | (:file "base") 12 | (:file "templates") 13 | (:file "ops.main") 14 | )) 15 | -------------------------------------------------------------------------------- /x86/templates.lisp: -------------------------------------------------------------------------------- 1 | ;;;; templates.lisp 2 | 3 | (in-package #:specops.x86) 4 | 5 | (setf *assembler-prototype-x86* (make-instance 'assembler-x86)) 6 | -------------------------------------------------------------------------------- /z80/base.lisp: -------------------------------------------------------------------------------- 1 | ;;;; z80.lisp 2 | 3 | (in-package #:specops.z80) 4 | 5 | (defclass mas-z80 (mas-based mas-displaced) 6 | () (:documentation "Memory access scheme for z80 processors.")) 7 | 8 | (defclass assembler-z80 (assembler-encoding) 9 | ((%storage :accessor asm-storage 10 | :allocation :class 11 | :initform '(:gpr #(:a :f :af :b :c :bc :d :e :de :h :l :hl) 12 | :ixr #(:ixl :iyl :ix :iy) 13 | :spr #(:sp :r :i)) 14 | :initarg :storage) 15 | (%lexicon :accessor asm-lexicon 16 | :allocation :class 17 | :initform (make-hash-table :test #'eq) 18 | :initarg :lexicon) 19 | (%decoder :accessor asm-enc-decoder 20 | :allocation :class 21 | :initform (make-hash-table :test #'eq) 22 | :initarg :decoder))) 23 | 24 | ;; (defvar *z80-storage*) 25 | ;; (defvar *z80-layout*) 26 | (defvar *assembler-prototype-z80*) 27 | 28 | ;; (setf *z80-layout* 29 | ;; (list :gpr #(:a :f :af :b :c :bc :d :e :de :h :l :hl) 30 | ;; :ixr #(:ixl :iyl :ix :iy) 31 | ;; :spr #(:sp :r :i))) 32 | 33 | ;; as an op-matrix, the symbol is swapped out for a prefix 34 | 35 | (defun match-ops (a0 a1 &optional a2 a3) 36 | (let ((op0 a0) (op1 (if a2 a1 nil)) 37 | (val0 (or a2 a1)) (val1 a3)) 38 | (flet ((match (op val) 39 | (cond ((position val #(:a :b :c :d :e :f :af :bc :de 40 | :h :l :hl :ixh :ixl :ix :iyh :iyl :iy :sp)) 41 | (eq op val)) 42 | ((eq :x val) 43 | (and (integerp op) (not (minusp op)) (> #x00100 op))) 44 | ((eq :xx val) 45 | (and (integerp op) (not (minusp op)) (> #x10000 op))) 46 | (t (let ((masix (position val #(:@x :@xx :@ix+ :@iy+ :@bc :@de :@hl :@sp)))) 47 | (and (typep val 'mas-z80) 48 | (or (and (position masix #(0 1)) 49 | (mas-disp val) (not (mas-base val))) 50 | (and (position masix #(2 3)) 51 | (mas-disp val) (eq (mas-base val) 52 | (aref #(:ix :iy) (- masix 2)))) 53 | (eq (mas-base val) 54 | (aref #(:bc :de :hl :sp) (- masix 4)))))))))) 55 | (and (match op0 val0) 56 | (or (not (or op1 val1)) (match op1 val1)))))) 57 | 58 | (defun @ (base &optional displacement) 59 | (let ((base (if (numberp base) nil base)) 60 | (displacement (if (numberp base) base displacement))) 61 | (make-instance 'mas-z80 :base base :displ displacement))) 62 | 63 | (defmethod extend-clauses ((assembler assembler-z80) mnemonic operands params sub-clauses) 64 | (declare (ignore assembler)) 65 | (loop :for clause :in sub-clauses 66 | :append (destructuring-bind (operands opcode) clause 67 | (let* ((variant-found) (opcode-out) 68 | (variant-operands '(:hl :h :l :@hl)) 69 | (vmaps '((:ix :ixh :ixl :@ix+) 70 | (:iy :iyh :iyl :@iy+))) 71 | (ops-out (loop :for i :in operands 72 | :collect 73 | (funcall (lambda (item) 74 | (when (and (> 256 opcode) 75 | ;; the HL→IX etc. extensions are only done 76 | ;; for opcodes in the main table, i.e. 77 | ;; of values 255 and below 78 | (member item variant-operands :test #'eq)) 79 | (setf variant-found t)) 80 | item) 81 | (typecase i (number i) 82 | (symbol (intern (string i) "KEYWORD"))))))) 83 | (cons (list ops-out opcode) 84 | (if (not variant-found) 85 | nil (let ((ops-out-dd) (ops-out-fd)) 86 | (loop :for op :in ops-out :for ix :from 0 87 | :do (let ((pos (position op variant-operands :test #'eq))) 88 | (push (if (not pos) op (nth pos (first vmaps))) 89 | ops-out-dd) 90 | (push (if (not pos) op (nth pos (second vmaps))) 91 | ops-out-fd))) 92 | (list (list (reverse ops-out-dd) (+ #xDD00 opcode)) 93 | (list (reverse ops-out-fd) (+ #xFD00 opcode)))))))))) 94 | 95 | (defmethod clause-processor ((assembler assembler-z80) action mnemonic operands params body) 96 | (declare (ignore assembler)) 97 | (labels ((decode-symbol (symbol) 98 | (cond ((eq symbol :x) 99 | `(of-program :next-bytes 1)) 100 | ((eq symbol :xx) 101 | `(of-program :next-bytes 2)) 102 | ((eq symbol :@x) 103 | '(list '@ (of-program :next-bytes 1))) 104 | ((eq symbol :@xx) 105 | '(list '@ (of-program :next-bytes 2))) 106 | ((position symbol #(:a :f :af :b :c :bc :d :e :de :h :l :hl 107 | :ixl :ixh :ix :iyl :iyh :iy :sp) 108 | :test #'eq) 109 | (intern (string symbol) "KEYWORD")) 110 | (t (let ((symx (position symbol #(:@ix+ :@iy+ :@c :@bc :@de :@hl :@sp) :test #'eq))) 111 | (if (not symx) nil ;; '(:error) 112 | (append `(list '@ ,(aref #(:ix :iy :c :bc :de :hl :sp) symx)) 113 | (if (> symx 1) nil '((of-program :next-bytes 1))))))))) 114 | 115 | (clause-extend (clauses clause) 116 | (destructuring-bind (operands opcode) clause 117 | (let* ((variant-found) (opcode-out) (ops-out operands)) 118 | (mapcar (lambda (op-spec) 119 | (destructuring-bind (operands opcode) op-spec 120 | (let ((opcode-out)) 121 | (loop :for ix :from 0 :for op :in operands 122 | :do (cond ((position op #(:x :@x) :test #'eq) 123 | (setf opcode-out `(+ ,(ash opcode 8) 124 | ,(nth ix '(op0 op1))))) 125 | ((position op #(:xx :@xx) :test #'eq) 126 | (setf opcode-out `(+ ,(ash opcode 16) 127 | ,(nth ix '(op0 op1))))) 128 | ((position op #(:@ix+ :@iy+) :test #'eq) 129 | (setf opcode-out `(+ ,(ash opcode 8) 130 | (mas-displ ,(nth ix '(op0 op1)))))) 131 | (t (setf opcode-out opcode)))) 132 | (list operands opcode-out)))) 133 | (list (list ops-out opcode)))))) 134 | (swap-numeric (operands) 135 | (let ((exchanged)) ;; exchanged is an index reflecting :x or :xx as an immediate value 136 | (values (loop :for op :in operands :collect (if (keywordp op) 137 | (let ((pos (position op #(:x :xx)))) 138 | (if (not pos) 139 | op (progn (setf exchanged (1+ pos)) 140 | `(funcall of-code 141 | ,(1+ pos))))) 142 | (if (not (listp op)) 143 | op (multiple-value-bind (new-op ex) 144 | (swap-numeric op) 145 | (setf exchanged (or exchanged ex)) 146 | new-op)))) 147 | exchanged))) 148 | (encoding-entry (varops operands opcode) 149 | `(((match-ops ,@(if (second operands) varops (list (first varops))) 150 | ,@operands) 151 | ,opcode)))) 152 | (if (and (listp body) (numberp (first body)) (eql action 'of-lexicon)) 153 | ;; (and (listp body) (symbolp (first body)) (numberp (second body)) (eql action 'of-lexicon)) 154 | (values (first body) mnemonic t) 155 | (if (and (numberp body) (eql action 'of-decoder)) 156 | (values (list 'list mnemonic) body t) 157 | (let ((varops (remove '&optional operands))) 158 | (case action 159 | (of-lexicon 160 | (values `((cond ,@(loop :for clause :in (loop :for c :in body :append (clause-extend body c)) 161 | :append (apply #'encoding-entry varops clause)))) 162 | mnemonic)) 163 | (of-decoder 164 | (values `((list ,mnemonic ,@(if (integerp body) 165 | nil (remove nil (mapcar #'decode-symbol (first body)))))) 166 | (second body))))))))) 167 | -------------------------------------------------------------------------------- /z80/comber.lisp: -------------------------------------------------------------------------------- 1 | ;;;; comber.lisp 2 | 3 | (ql:quickload 'lquery) 4 | 5 | (defun comb-z80-specs (table) 6 | ;; this is a function to comb through the z80 instruction tables at 7 | ;; http://z80-heaven.wikidot.com/opcode-reference-chart and glean the opcode specs 8 | ;; for use with the (specops) macro; it depends on the lquery macro 9 | (let ((data (lquery:$ (initialize table))) 10 | (holders (list nil)) (index 0)) 11 | (loop :for item :across (lquery:$ data "tbody tr td a" (text)) 12 | :do (let ((output (cl-ppcre:split "[ ,]" item))) 13 | (when (eq 16 index) (push nil holders) 14 | (setf index 0)) 15 | (push (cons (intern (string-upcase (first output)) "KEYWORD") 16 | (loop :for i :in (rest output) :collect (intern (string-upcase i)))) 17 | (first holders)) 18 | (incf index))) 19 | (reverse (loop :for h :in holders :collect (reverse h))))) 20 | 21 | (defun comb-wasm-specs (table) 22 | ;; this is a function to comb through the z80 instruction tables at 23 | ;; http://z80-heaven.wikidot.com/opcode-reference-chart and glean the opcode specs 24 | ;; for use with the (specops) macro; it depends on the lquery macro 25 | (let ((data (lquery:$ (initialize table))) 26 | (holders (list nil)) (index 0)) 27 | (loop :for item :across (lquery:$ data "tbody tr td" (text)) 28 | :do (let ((output (cl-ppcre:split "[. ]" item))) 29 | (when (eq 16 index) (push nil holders) 30 | (setf index 0)) 31 | (push (funcall (lambda (output) 32 | (cons (intern (string-upcase (first output)) "KEYWORD") 33 | (loop :for i :in (rest output) 34 | :collect (intern (string-upcase i))))) 35 | (append (if (member (first output) '("i32" "i64" "f32" "f64" "v128" "i8x16" "i16x8" "i32x4" "i64x2" "f32x4" "f64x2") 36 | :test #'string=) 37 | (list (second output) (first output)) 38 | (list (first output) (second output))) 39 | (cddr output))) 40 | (first holders)) 41 | (incf index))) 42 | (reverse (loop :for h :in holders :collect (reverse h))))) 43 | 44 | (defvar bla) 45 | 46 | (setf bla " 47 | 48 | FD 0_ 49 | v128.load 50 | v128.load8x8_s 51 | v128.load8x8_u 52 | v128.load16x4_s 53 | v128.load16x4_u 54 | v128.load32x2_s 55 | v128.load32x2_u 56 | v128.load8_splat 57 | v128.load16_splat 58 | v128.load32_splat 59 | v128.load64_splat 60 | v128.store 61 | v128.const 62 | i8x16.shuffle 63 | i8x16.swizzle 64 | i8x16.splat 65 | 66 | 67 | FD 1_ 68 | i16x8.splat 69 | i32x4.splat 70 | i64x2.splat 71 | f32x4.splat 72 | f64x2.splat 73 | i8x16.extract_lane_s 74 | i8x16.extract_lane_u 75 | i8x16.replace_lane 76 | i16x8.extract_lane_s 77 | i16x8.extract_lane_u 78 | i16x8.replace_lane 79 | i32x4.extract_lane 80 | i32x4.replace_lane 81 | i64x2.extract_lane 82 | i64x2.replace_lane 83 | f32x4.extract_lane 84 | 85 | 86 | FD 2_ 87 | f32x4.replace_lane 88 | f64x2.extract_lane 89 | f64x2.replace_lane 90 | i8x16.eq 91 | i8x16.ne 92 | i8x16.lt_s 93 | i8x16.lt_u 94 | i8x16.gt_s 95 | i8x16.gt_u 96 | i8x16.le_s 97 | i8x16.le_u 98 | i8x16.ge_s 99 | i8x16.ge_u 100 | i16x8.eq 101 | i16x8.ne 102 | i16x8.lt_s 103 | 104 | 105 | FD 3_ 106 | i16x8.lt_u 107 | i16x8.gt_s 108 | i16x8.gt_u 109 | i16x8.le_s 110 | i16x8.le_u 111 | i16x8.ge_s 112 | i16x8.ge_u 113 | i32x4.eq 114 | i32x4.ne 115 | i32x4.lt_s 116 | i32x4.lt_u 117 | i32x4.gt_s 118 | i32x4.gt_u 119 | i32x4.le_s 120 | i32x4.le_u 121 | i32x4.ge_s 122 | 123 | 124 | FD 4_ 125 | i32x4.ge_u 126 | f32x4.eq 127 | f32x4.ne 128 | f32x4.lt 129 | f32x4.gt 130 | f32x4.le 131 | f32x4.ge 132 | f64x2.eq 133 | f64x2.ne 134 | f64x2.lt 135 | f64x2.gt 136 | f64x2.le 137 | f64x2.ge 138 | v128.not 139 | v128.and 140 | v128.andnot 141 | 142 | 143 | FD 5_ 144 | v128.or 145 | v128.xor 146 | v128.bitselect 147 | v128.any_true 148 | v128.load8_lane 149 | v128.load16_lane 150 | v128.load32_lane 151 | v128.load64_lane 152 | v128.store8_lane 153 | v128.store16_lane 154 | v128.store32_lane 155 | v128.store64_lane 156 | v128.load32_zero 157 | v128.load64_zero 158 | f32x4.demote_f64x2_zero 159 | f64x2.promote_low_f32x4 160 | 161 | 162 | FD 6_ 163 | i8x16.abs 164 | i8x16.neg 165 | i8x16.popcnt 166 | i8x16.all_true 167 | i8x16.bitmask 168 | i8x16.narrow_i16x8_s 169 | i8x16.narrow_i16x8_u 170 | f32x4.ceil 171 | f32x4.floor 172 | f32x4.trunc 173 | f32x4.nearest 174 | i8x16.shl 175 | i8x16.shr_s 176 | i8x16.shr_u 177 | i8x16.add 178 | i8x16.add_sat_s 179 | 180 | 181 | FD 7_ 182 | i8x16.add_sat_u 183 | i8x16.sub 184 | i8x16.sub_sat_s 185 | i8x16.sub_sat_u 186 | f64x2.ceil 187 | f64x2.floor 188 | i8x16.min_s 189 | i8x16.min_u 190 | i8x16.max_s 191 | i8x16.max_u 192 | f64x2.trunc 193 | i8x16.avgr_u 194 | i16x8.extadd_pairwise_i8x16_s 195 | i16x8.extadd_pairwise_i8x16_u 196 | i32x4.extadd_pairwise_i16x8_s 197 | i32x4.extadd_pairwise_i16x8_u 198 | 199 | 200 | FD 8_ 201 | i16x8.abs 202 | i16x8.neg 203 | i16x8.q15mulr_sat_s 204 | i16x8.all_true 205 | i16x8.bitmask 206 | i16x8.narrow_i32x4_s 207 | i16x8.narrow_i32x4_u 208 | i16x8.extend_low_i8x16_s 209 | i16x8.extend_high_i8x16_s 210 | i16x8.extend_low_i8x16_u 211 | i16x8.extend_high_i8x16_u 212 | i16x8.shl 213 | i16x8.shr_s 214 | i16x8.shr_u 215 | i16x8.add 216 | i16x8.add_sat_s 217 | 218 | 219 | FD 9_ 220 | i16x8.add_sat_u 221 | i16x8.sub 222 | i16x8.sub_sat_s 223 | i16x8.sub_sat_u 224 | f64x2.nearest 225 | i16x8.mul 226 | i16x8.min_s 227 | i16x8.min_u 228 | i16x8.max_s 229 | i16x8.max_u 230 |   231 | i16x8.avgr_u 232 | i16x8.extmul_low_i8x16_s 233 | i16x8.extmul_high_i8x16_s 234 | i16x8.extmul_low_i8x16_u 235 | i16x8.extmul_high_i8x16_u 236 | 237 | 238 | FD A_ 239 | i32x4.abs 240 | i32x4.neg 241 | *i8x16.relaxed_swizzle 242 | i32x4.all_true 243 | i32x4.bitmask 244 | *i32x4.relaxed_trunc_f32x4_s 245 | *i32x4.relaxed_trunc_f32x4_u 246 | i32x4.extend_low_i16x8_s 247 | i32x4.extend_high_i16x8_s 248 | i32x4.extend_low_i16x8_u 249 | i32x4.extend_high_i16x8_u 250 | i32x4.shl 251 | i32x4.shr_s 252 | i32x4.shr_u 253 | i32x4.add 254 | *f32x4.relaxed_madd 255 | 256 | 257 | FD B_ 258 | *f32x4.relaxed_nmadd 259 | i32x4.sub 260 | *i8x16.relaxed_laneselect 261 | *i16x8.relaxed_laneselect 262 | *f32x4.relaxed_min 263 | i32x4.mul 264 | i32x4.min_s 265 | i32x4.min_u 266 | i32x4.max_s 267 | i32x4.max_u 268 | i32x4.dot_i16x8_s 269 |   270 | i32x4.extmul_low_i16x8_s 271 | i32x4.extmul_high_i16x8_s 272 | i32x4.extmul_low_i16x8_u 273 | i32x4.extmul_high_i16x8_u 274 | 275 | 276 | FD C_ 277 | i64x2.abs 278 | i64x2.neg 279 |   280 | i64x2.all_true 281 | i64x2.bitmask 282 | *i32x4.relaxed_trunc_f64x2_s_zero 283 | *i32x4.relaxed_trunc_f64x2_u_zero 284 | i64x2.extend_low_i32x4_s 285 | i64x2.extend_high_i32x4_s 286 | i64x2.extend_low_i32x4_u 287 | i64x2.extend_high_i32x4_u 288 | i64x2.shl 289 | i64x2.shr_s 290 | i64x2.shr_u 291 | i64x2.add 292 | *f64x2.relaxed_madd 293 | 294 | 295 | FD D_ 296 | *f64x2.relaxed_nmadd 297 | i64x2.sub 298 | *i32x4.relaxed_laneselect 299 | *i64x2.relaxed_laneselect 300 | *f64x2.relaxed_min 301 | i64x2.mul 302 | i64x2.eq 303 | i64x2.ne 304 | i64x2.lt_s 305 | i64x2.gt_s 306 | i64x2.le_s 307 | i64x2.ge_s 308 | i64x2.extmul_low_i32x4_s 309 | i64x2.extmul_high_i32x4_s 310 | i64x2.extmul_low_i32x4_u 311 | i64x2.extmul_high_i32x4_u 312 | 313 | 314 | FD E_ 315 | f32x4.abs 316 | f32x4.neg 317 | *f32x4.relaxed_max 318 | f32x4.sqrt 319 | f32x4.add 320 | f32x4.sub 321 | f32x4.mul 322 | f32x4.div 323 | f32x4.min 324 | f32x4.max 325 | f32x4.pmin 326 | f32x4.pmax 327 | f64x2.abs 328 | f64x2.neg 329 | *f64x2.relaxed_max 330 | f64x2.sqrt 331 | 332 | 333 | FD F_ 334 | f64x2.add 335 | f64x2.sub 336 | f64x2.mul 337 | f64x2.div 338 | f64x2.min 339 | f64x2.max 340 | f64x2.pmin 341 | f64x2.pmax 342 | i32x4.trunc_sat_f32x4_s 343 | i32x4.trunc_sat_f32x4_u 344 | f32x4.convert_i32x4_s 345 | f32x4.convert_i32x4_u 346 | i32x4.trunc_sat_f64x2_s_zero 347 | i32x4.trunc_sat_f64x2_u_zero 348 | f64x2.convert_low_i32x4_s 349 | f64x2.convert_low_i32x4_u 350 | 351 | ") 352 | -------------------------------------------------------------------------------- /z80/ops.lisp: -------------------------------------------------------------------------------- 1 | ;;;; ops.lisp 2 | 3 | (in-package #:specops.z80) 4 | 5 | (specops 0 (op0 &optional op1) *assembler-prototype-z80* 6 | ;; the main table of z80 instructions; this is permuted by replacing H, L, HL and @HL operands to 7 | ;; manifest the DD__ and FD__ instruction tables expressing IX and IY operations` 8 | ((:tabular :cross-adding :matcher match-ops) (:duplex . of-decoder)) 9 | (( ) (#x0 ) (#x1 ) (#x2 ) (#x3 ) (#x4 ) (#x5 ) (#x6 ) (#x7 ) (#x8 ) (#x9 ) (#xA ) (#xB ) (#xC ) (#xD ) (#xE ) (#xF )) 10 | ((#x00) (:nop ) (:ld bc xx) (:ld @bc a) (:inc bc) (:inc b) (:dec b) (:ld b x) (:rlca ) (:ex af -af) (:add hl bc) (:ld a @bc) (:dec bc) (:inc c) (:dec c) (:ld c x) (:rrca )) 11 | ((#x10) (:djnz x) (:ld de xx) (:ld @de a) (:inc de) (:inc d) (:dec d) (:ld d x) (:rla ) (:jr x) (:add hl de) (:ld a @de) (:dec de) (:inc e) (:dec e) (:ld e x) (:rra )) 12 | ((#x20) (:jr nz x) (:ld hl xx) (:ld @xx hl) (:inc hl) (:inc h) (:dec h) (:ld h x) (:daa ) (:jr z x) (:add hl hl) (:ld hl @xx) (:dec hl) (:inc l) (:dec l) (:ld l x) (:cpl )) 13 | ((#x30) (:jr nc x) (:ld sp xx) (:ld @xx a) (:inc sp) (:inc @hl) (:dec @hl) (:ld @hl x) (:scf ) (:jr c x) (:add hl sp) (:ld a @xx) (:dec sp) (:inc a) (:dec a) (:ld a x) (:ccf )) 14 | ((#x40) (:ld b b) (:ld b c) (:ld b d) (:ld b e) (:ld b h) (:ld b l) (:ld b @hl) (:ld b a) (:ld c b) (:ld c c) (:ld c d) (:ld c e) (:ld c h) (:ld c l) (:ld c @hl) (:ld c a)) 15 | ((#x50) (:ld d b) (:ld d c) (:ld d d) (:ld d e) (:ld d h) (:ld d l) (:ld d @hl) (:ld d a) (:ld e b) (:ld e c) (:ld e d) (:ld e e) (:ld e h) (:ld e l) (:ld e @hl) (:ld e a)) 16 | ((#x60) (:ld h b) (:ld h c) (:ld h d) (:ld h e) (:ld h h) (:ld h l) (:ld h @hl) (:ld h a) (:ld l b) (:ld l c) (:ld l d) (:ld l e) (:ld l h) (:ld l l) (:ld l @hl) (:ld l a)) 17 | ((#x70) (:ld @hl b) (:ld @h c) (:ld @hl d) (:ld @hl e) (:ld @hl h) (:ld @hl l) (:halt ) (:ld @hl a) (:ld a b) (:ld a c) (:ld a d) (:ld a e) (:ld a h) (:ld a l) (:ld a @hl) (:ld a a)) 18 | ((#x80) (:add a b) (:add a c) (:add a d) (:add a e) (:add a h) (:add a l) (:add a @hl) (:add a a) (:adc a b) (:adc a c) (:adc a d) (:adc a e) (:adc a h) (:adc a l) (:adc a @hl) (:adc a a)) 19 | ((#x90) (:sub b) (:sub c) (:sub d) (:sub e) (:sub h) (:sub l) (:sub @hl) (:sub a) (:sbc a b) (:sbc a c) (:sbc a d) (:sbc a e) (:sbc a h) (:sbc a l) (:sbc a @hl) (:sbc a a)) 20 | ((#xA0) (:and b) (:and c) (:and d) (:and e) (:and h) (:and l) (:and @hl) (:and a) (:xor b) (:xor c) (:xor d) (:xor e) (:xor h) (:xor l) (:xor @hl) (:xor a)) 21 | ((#xB0) (:or b) (:or c) (:or d) (:or e) (:or h) (:or l) (:or @hl) (:or a) (:cp b) (:cp c) (:cp d) (:cp e) (:cp h) (:cp l) (:cp @hl) (:cp a)) 22 | ((#xC0) (:ret nz) (:pop bc) (:jp nz xx) (:jp xx) (:call nz xx) (:push bc) (:add a x) (:rst 00h) (:ret z) (:ret ) (:jp z xx) :prefix (:call z xx) (:call xx) (:adc a x) (:rst 08h)) 23 | ((#xD0) (:ret nc) (:pop de) (:jp nc xx) (:out @x a) (:call nc xx) (:push de) (:sub x) (:rst 10h) (:ret c) (:exx ) (:jp c xx) (:in a @x) (:call c xx) () (:sbc a x) (:rst 18h)) 24 | ((#xE0) (:ret po) (:pop hl) (:jp po xx) (:ex @sp hl) (:call po xx) (:push hl) (:and x) (:rst 20h) (:ret pe) (:jp @hl) (:jp pe xx) (:ex de hl) (:call pe xx) :prefix (:xor x) (:rst 28h)) 25 | ((#xF0) (:ret p) (:pop af) (:jp p xx) (:di ) (:call p xx) (:push af) (:or x) (:rst 30h) (:ret m) (:ld sp hl) (:jp m xx) (:ei ) (:call m xx) () (:cp x) (:rst 38h))) 26 | 27 | (specops #xCB00 (op0 &optional op1) *assembler-prototype-z80* 28 | ;; the CB__ table of z80 instructions 29 | ((:tabular :cross-adding :matcher match-ops) (:duplex . of-decoder)) 30 | (( ) (#x0 ) (#x1 ) (#x2 ) (#x3 ) (#x4 ) (#x5 ) (#x6 ) (#x7 ) (#x8 ) (#x9 ) (#xA ) (#xB ) (#xC ) (#xD ) (#xE ) (#xF )) 31 | ((#x00) (:rlc b) (:rlc c) (:rlc d) (:rlc e) (:rlc h) (:rlc l) (:rlc @hl) (:rlc a) (:rrc b) (:rrc c) (:rrc d) (:rrc e) (:rrc h) (:rrc l) (:rrc @hl) (:rrc a)) 32 | ((#x10) (:rl b) (:rl c) (:rl d) (:rl e) (:rl h) (:rl l) (:rl @hl) (:rl a) (:rr b) (:rr c) (:rr d) (:rr e) (:rr h) (:rr l) (:rr @hl) (:rr a)) 33 | ((#x20) (:sla b) (:sla c) (:sla d) (:sla e) (:sla h) (:sla l) (:sla @hl) (:sla a) (:sra b) (:sra c) (:sra d) (:sra e) (:sra h) (:sra l) (:sra @hl) (:sra a)) 34 | ((#x30) (:sll b) (:sll c) (:sll d) (:sll e) (:sll h) (:sll l) (:sll @hl) (:sll a) (:srl b) (:srl c) (:srl d) (:srl e) (:srl h) (:srl l) (:srl @hl) (:srl a)) 35 | ((#x40) (:bit 0 b) (:bit 0 c) (:bit 0 d) (:bit 0 e) (:bit 0 h) (:bit 0 l) (:bit 0 @hl) (:bit 0 a) (:bit 1 b) (:bit 1 c) (:bit 1 d) (:bit 1 e) (:bit 1 h) (:bit 1 l) (:bit 1 @hl) (:bit 1 a)) 36 | ((#x50) (:bit 2 b) (:bit 2 c) (:bit 2 d) (:bit 2 e) (:bit 2 h) (:bit 2 l) (:bit 2 @hl) (:bit 2 a) (:bit 3 b) (:bit 3 c) (:bit 3 d) (:bit 3 e) (:bit 3 h) (:bit 3 l) (:bit 3 @hl) (:bit 3 a)) 37 | ((#x60) (:bit 4 b) (:bit 4 c) (:bit 4 d) (:bit 4 e) (:bit 4 h) (:bit 4 l) (:bit 4 @hl) (:bit 4 a) (:bit 5 b) (:bit 5 c) (:bit 5 d) (:bit 5 e) (:bit 5 h) (:bit 5 l) (:bit 5 @hl) (:bit 5 a)) 38 | ((#x70) (:bit 6 b) (:bit 6 c) (:bit 6 d) (:bit 6 e) (:bit 6 h) (:bit 6 l) (:bit 6 @hl) (:bit 6 a) (:bit 7 b) (:bit 7 c) (:bit 7 d) (:bit 7 e) (:bit 7 h) (:bit 7 l) (:bit 7 @hl) (:bit 7 a)) 39 | ((#x80) (:res 0 b) (:res 0 c) (:res 0 d) (:res 0 e) (:res 0 h) (:res 0 l) (:res 0 @hl) (:res 0 a) (:res 1 b) (:res 1 c) (:res 1 d) (:res 1 e) (:res 1 h) (:res 1 l) (:res 1 @hl) (:res 1 a)) 40 | ((#x90) (:res 2 b) (:res 2 c) (:res 2 d) (:res 2 e) (:res 2 h) (:res 2 l) (:res 2 @hl) (:res 2 a) (:res 3 b) (:res 3 c) (:res 3 d) (:res 3 e) (:res 3 h) (:res 3 l) (:res 3 @hl) (:res 3 a)) 41 | ((#xA0) (:res 4 b) (:res 4 c) (:res 4 d) (:res 4 e) (:res 4 h) (:res 4 l) (:res 4 @hl) (:res 4 a) (:res 5 b) (:res 5 c) (:res 5 d) (:res 5 e) (:res 5 h) (:res 5 l) (:res 5 @hl) (:res 5 a)) 42 | ((#xB0) (:res 6 b) (:res 6 c) (:res 6 d) (:res 6 e) (:res 6 h) (:res 6 l) (:res 6 @hl) (:res 6 a) (:res 7 b) (:res 7 c) (:res 7 d) (:res 7 e) (:res 7 h) (:res 7 l) (:res 7 @hl) (:res 7 a)) 43 | ((#xC0) (:set 0 b) (:set 0 c) (:set 0 d) (:set 0 e) (:set 0 h) (:set 0 l) (:set 0 @hl) (:set 0 a) (:set 1 b) (:set 1 c) (:set 1 d) (:set 1 e) (:set 1 h) (:set 1 l) (:set 1 @hl) (:set 1 a)) 44 | ((#xD0) (:set 2 b) (:set 2 c) (:set 2 d) (:set 2 e) (:set 2 h) (:set 2 l) (:set 2 @hl) (:set 2 a) (:set 3 b) (:set 3 c) (:set 3 d) (:set 3 e) (:set 3 h) (:set 3 l) (:set 3 @hl) (:set 3 a)) 45 | ((#xE0) (:set 4 b) (:set 4 c) (:set 4 d) (:set 4 e) (:set 4 h) (:set 4 l) (:set 4 @hl) (:set 4 a) (:set 5 b) (:set 5 c) (:set 5 d) (:set 5 e) (:set 5 h) (:set 5 l) (:set 5 @hl) (:set 5 a)) 46 | ((#xF0) (:set 6 b) (:set 6 c) (:set 6 d) (:set 6 e) (:set 6 h) (:set 6 l) (:set 6 @hl) (:set 6 a) (:set 7 b) (:set 7 c) (:set 7 d) (:set 7 e) (:set 7 h) (:set 7 l) (:set 7 @hl) (:set 7 a))) 47 | 48 | (specops #xED00 (op0 &optional op1) *assembler-prototype-z80* 49 | ;; the ED__ table of z80 instructions 50 | ((:tabular :cross-adding :matcher match-ops) (:duplex . of-decoder)) 51 | (( ) (#x0 ) (#x1 ) (#x2 ) (#x3 ) (#x4 ) (#x5 ) (#x6 ) (#x7 ) (#x8 ) (#x9 ) (#xA ) (#xB ) (#xC ) (#xD ) (#xE ) (#xF )) 52 | ((#x40) (:in b @c) (:out @c b) (:sbc hl bc) (:ld @xx bc) (:neg) (:retn) (:im 0) (:ld i a) (:in c @c) (:out @c c) (:adc hl bc) (:ld bc @xx) (:neg) (:reti) () (:ld r a)) 53 | ((#x50) (:in d @c) (:out @c d) (:sbc hl de) (:ld @xx de) (:neg) (:retn) (:im 1) (:ld a i) (:in e @c) (:out @c e) (:adc hl de) (:ld de @xx) (:neg) (:retn) (:im 2) (:ld a r)) 54 | ((#x60) (:in h @c) (:out @c h) (:sbc hl hl) (:ld @xx hl) (:neg) (:retn) () (:rrd ) (:in l @c) (:out @c l) (:adc hl hl) (:ld hl @xx) (:neg) (:retn) () (:rld )) 55 | ((#x70) (:in f @c) (:out @c 0) (:sbc hl sp) (:ld @xx sp) (:neg) (:retn) () () (:in a @c) (:out @c a) (:adc hl sp) (:ld sp @xx) (:neg) (:reti)) 56 | ((#xA0) (:ldi ) (:cpi ) (:ini ) (:outi ) () () () () (:ldd ) (:cpd ) (:ind ) (:outd )) 57 | ((#xB0) (:ldir ) (:cpir ) (:inir ) (:otir ) () () () () (:lddr ) (:cpdr ) (:indr ) (:otdr ))) 58 | 59 | ;; (cb-logicop-specs (:rlc :rrc :rl :rr :sla :sra :sll :srl) (:b :c :d :e :h :l (:hl) :a)) 60 | ;; (cb-bitop-specs (:bit :res :set) (:b :c :d :e :h :l (:hl) :a)) 61 | 62 | 63 | 64 | ;; (((:LOAD V128) (:LOAD8X8_S V128) (:LOAD8X8_U V128) (:LOAD16X4_S V128) (:LOAD16X4_U V128) (:LOAD32X2_S V128) (:LOAD32X2_U V128) (:LOAD8_SPLAT V128) (:LOAD16_SPLAT V128) (:LOAD32_SPLAT V128) (:LOAD64_SPLAT V128) (:STORE V128) (:CONST V128) (:SHUFFLE I8X16) (:SWIZZLE I8X16) (:SPLAT I8X16)) 65 | ;; ((:SPLAT I16X8) (:SPLAT I32X4) (:SPLAT I64X2) (:SPLAT F32X4) (:SPLAT F64X2) (:EXTRACT_LANE_S I8X16) (:EXTRACT_LANE_U I8X16) (:REPLACE_LANE I8X16) (:EXTRACT_LANE_S I16X8) (:EXTRACT_LANE_U I16X8) (:REPLACE_LANE I16X8) (:EXTRACT_LANE I32X4) (:REPLACE_LANE I32X4) (:EXTRACT_LANE I64X2) (:REPLACE_LANE I64X2) (:EXTRACT_LANE F32X4)) 66 | ;; ((:REPLACE_LANE F32X4) (:EXTRACT_LANE F64X2) (:REPLACE_LANE F64X2) (:EQ I8X16) (:NE I8X16) (:LT_S I8X16) (:LT_U I8X16) (:GT_S I8X16) (:GT_U I8X16) (:LE_S I8X16) (:LE_U I8X16) (:GE_S I8X16) (:GE_U I8X16) (:EQ I16X8) (:NE I16X8) (:LT_S I16X8)) 67 | ;; ((:LT_U I16X8) (:GT_S I16X8) (:GT_U I16X8) (:LE_S I16X8) (:LE_U I16X8) (:GE_S I16X8) (:GE_U I16X8) (:EQ I32X4) (:NE I32X4) (:LT_S I32X4) (:LT_U I32X4) (:GT_S I32X4) (:GT_U I32X4) (:LE_S I32X4) (:LE_U I32X4) (:GE_S I32X4)) 68 | ;; ((:GE_U I32X4) (:EQ F32X4) (:NE F32X4) (:LT F32X4) (:GT F32X4) (:LE F32X4) (:GE F32X4) (:EQ F64X2) (:NE F64X2) (:LT F64X2) (:GT F64X2) (:LE F64X2) (:GE F64X2) (:NOT V128) (:AND V128) (:ANDNOT V128)) 69 | ;; ((:OR V128) (:XOR V128) (:BITSELECT V128) (:ANY_TRUE V128) (:LOAD8_LANE V128) (:LOAD16_LANE V128) (:LOAD32_LANE V128) (:LOAD64_LANE V128) (:STORE8_LANE V128) (:STORE16_LANE V128) (:STORE32_LANE V128) (:STORE64_LANE V128) (:LOAD32_ZERO V128) (:LOAD64_ZERO V128) (:DEMOTE_F64X2_ZERO F32X4) (:PROMOTE_LOW_F32X4 F64X2)) 70 | ;; ((:ABS I8X16) (:NEG I8X16) (:POPCNT I8X16) (:ALL_TRUE I8X16) (:BITMASK I8X16) (:NARROW_I16X8_S I8X16) (:NARROW_I16X8_U I8X16) (:CEIL F32X4) (:FLOOR F32X4) (:TRUNC F32X4) (:NEAREST F32X4) (:SHL I8X16) (:SHR_S I8X16) (:SHR_U I8X16) (:ADD I8X16) (:ADD_SAT_S I8X16)) 71 | ;; ((:ADD_SAT_U I8X16) (:SUB I8X16) (:SUB_SAT_S I8X16) (:SUB_SAT_U I8X16) (:CEIL F64X2) (:FLOOR F64X2) (:MIN_S I8X16) (:MIN_U I8X16) (:MAX_S I8X16) (:MAX_U I8X16) (:TRUNC F64X2) (:AVGR_U I8X16) (:EXTADD_PAIRWISE_I8X16_S I16X8) (:EXTADD_PAIRWISE_I8X16_U I16X8) (:EXTADD_PAIRWISE_I16X8_S I32X4) (:EXTADD_PAIRWISE_I16X8_U I32X4)) 72 | ;; ((:ABS I16X8) (:NEG I16X8) (:Q15MULR_SAT_S I16X8) (:ALL_TRUE I16X8) (:BITMASK I16X8) (:NARROW_I32X4_S I16X8) (:NARROW_I32X4_U I16X8) (:EXTEND_LOW_I8X16_S I16X8) (:EXTEND_HIGH_I8X16_S I16X8) (:EXTEND_LOW_I8X16_U I16X8) (:EXTEND_HIGH_I8X16_U I16X8) (:SHL I16X8) (:SHR_S I16X8) (:SHR_U I16X8) (:ADD I16X8) (:ADD_SAT_S I16X8)) 73 | ;; ((:ADD_SAT_U I16X8) (:SUB I16X8) (:SUB_SAT_S I16X8) (:SUB_SAT_U I16X8) (:NEAREST F64X2) (:MUL I16X8) (:MIN_S I16X8) (:MIN_U I16X8) (:MAX_S I16X8) (:MAX_U I16X8) (:NIL NIL) (:AVGR_U I16X8) (:EXTMUL_LOW_I8X16_S I16X8) (:EXTMUL_HIGH_I8X16_S I16X8) (:EXTMUL_LOW_I8X16_U I16X8) (:EXTMUL_HIGH_I8X16_U I16X8)) 74 | ;; ((:ABS I32X4) (:NEG I32X4) (:*I8X16 RELAXED_SWIZZLE) (:ALL_TRUE I32X4) (:BITMASK I32X4) (:*I32X4 RELAXED_TRUNC_F32X4_S) (:*I32X4 RELAXED_TRUNC_F32X4_U) (:EXTEND_LOW_I16X8_S I32X4) (:EXTEND_HIGH_I16X8_S I32X4) (:EXTEND_LOW_I16X8_U I32X4) (:EXTEND_HIGH_I16X8_U I32X4) (:SHL I32X4) (:SHR_S I32X4) (:SHR_U I32X4) (:ADD I32X4) (:*F32X4 RELAXED_MADD)) 75 | ;; ((:RELAXED_NMADD *F32X4) (:SUB I32X4) (:*I8X16 RELAXED_LANESELECT) (:*I16X8 RELAXED_LANESELECT) (:*F32X4 RELAXED_MIN) (:MUL I32X4) (:MIN_S I32X4) (:MIN_U I32X4) (:MAX_S I32X4) (:MAX_U I32X4) (:DOT_I16X8_S I32X4) (:NIL NIL) (:EXTMUL_LOW_I16X8_S I32X4) (:EXTMUL_HIGH_I16X8_S I32X4) (:EXTMUL_LOW_I16X8_U I32X4) (:EXTMUL_HIGH_I16X8_U I32X4)) 76 | ;; ((:ABS I64X2) (:NEG I64X2) (:NIL NIL) (:ALL_TRUE I64X2) (:BITMASK I64X2) (:*I32X4 RELAXED_TRUNC_F64X2_S_ZERO) (:*I32X4 RELAXED_TRUNC_F64X2_U_ZERO) (:EXTEND_LOW_I32X4_S I64X2) (:EXTEND_HIGH_I32X4_S I64X2) (:EXTEND_LOW_I32X4_U I64X2) (:EXTEND_HIGH_I32X4_U I64X2) (:SHL I64X2) (:SHR_S I64X2) (:SHR_U I64X2) (:ADD I64X2) (:*F64X2 RELAXED_MADD)) 77 | ;; ((:RELAXED_NMADD *F64X2) (:SUB I64X2) (:*I32X4 RELAXED_LANESELECT) (:*I64X2 RELAXED_LANESELECT) (:*F64X2 RELAXED_MIN) (:MUL I64X2) (:EQ I64X2) (:NE I64X2) (:LT_S I64X2) (:GT_S I64X2) (:LE_S I64X2) (:GE_S I64X2) (:EXTMUL_LOW_I32X4_S I64X2) (:EXTMUL_HIGH_I32X4_S I64X2) (:EXTMUL_LOW_I32X4_U I64X2) (:EXTMUL_HIGH_I32X4_U I64X2)) 78 | ;; ((:ABS F32X4) (:NEG F32X4) (:*F32X4 RELAXED_MAX) (:SQRT F32X4) (:ADD F32X4) (:SUB F32X4) (:MUL F32X4) (:DIV F32X4) (:MIN F32X4) (:MAX F32X4) (:PMIN F32X4) (:PMAX F32X4) (:ABS F64X2) (:NEG F64X2) (:*F64X2 RELAXED_MAX) (:SQRT F64X2)) 79 | ;; ((:ADD F64X2) (:SUB F64X2) (:MUL F64X2) (:DIV F64X2) (:MIN F64X2) (:MAX F64X2) (:PMIN F64X2) (:PMAX F64X2) (:TRUNC_SAT_F32X4_S I32X4) (:TRUNC_SAT_F32X4_U I32X4) (:CONVERT_I32X4_S F32X4) (:CONVERT_I32X4_U F32X4) (:TRUNC_SAT_F64X2_S_ZERO I32X4) (:TRUNC_SAT_F64X2_U_ZERO I32X4) (:CONVERT_LOW_I32X4_S F64X2) (:CONVERT_LOW_I32X4_U F64X2))) 80 | 81 | ;; ((( ) (#x0 ) (#x1 ) (#x2 ) (#x3 ) (#x4 ) (#x5 ) (#x6 ) (#x7 ) (#x8 ) (#x9 ) (#xA ) (#xB ) (#xC ) (#xD ) (#xE ) (#xF )) 82 | ;; ((#x00) () (:NOP ) (:BLOCK) (:LOOP) (:IF) (:ELSE) (:*TRY) (:*CATCH)) 83 | ;; ((#x08) (:*THROW) (:*RETHROW) (:*THROW_REF) (:END) (:BR) (:BR_IF) (:BR_TABLE) (:RETURN)) 84 | ;; ((#x10) (:CALL ) (:CALL_INDIRECT ) (:*RETURN_CALL) (:*RETURN_CALL_INDIRECT) (:*CALL_REF) (:*RETURN_CALL_REF) (:NIL) (:NIL)) 85 | ;; ((#x18) (:*DELEGATE) (:*CATCH_ALL) (:DROP) (:SELECT) (:*SELECT T) (:NIL) (:NIL) (:*TRY_TABLE)) 86 | ;; ((#x20) (:LOCAL GET) (:LOCAL SET) (:LOCAL TEE) (:GLOBAL GET) (:GLOBAL SET) (:*TABLE GET) (:*TABLE SET) (:NIL)) 87 | ;; ((#x28) (:LOAD :I32) (:LOAD :I64) (:LOAD :F32) (:LOAD :F64) (:LOAD8_S :I32) (:LOAD8_U :I32) (:LOAD16_S :I32) (:LOAD16_U :I32)) 88 | ;; ((#x30) (:LOAD8_S :I64) (:LOAD8_U :I64) (:LOAD16_S :I64) (:LOAD16_U :I64) (:LOAD32_S :I64) (:LOAD32_U :I64) (:STORE :I32) (:STORE :I64)) 89 | ;; ((#x38) (:STORE :F32) (:STORE :F64) (:STORE8 :I32) (:STORE16 :I32) (:STORE8 :I64) (:STORE16 :I64) (:STORE32 :I64) (:MEMORY SIZE)) 90 | ;; ((#x40) (:MEMORY GROW) (:CONST :I32) (:CONST :I64) (:CONST :F32) (:CONST :F64) (:EQZ :I32) (:EQ :I32) (:NE :I32)) 91 | ;; ((#x48) (:LT_S :I32) (:LT_U :I32) (:GT_S :I32) (:GT_U :I32) (:LE_S :I32) (:LE_U :I32) (:GE_S :I32) (:GE_U :I32)) 92 | ;; ((#x50) (:EQZ :I64) (:EQ :I64) (:NE :I64) (:LT_S :I64) (:LT_U :I64) (:GT_S :I64) (:GT_U :I64) (:LE_S :I64)) 93 | ;; ((#x58) (:LE_U :I64) (:GE_S :I64) (:GE_U :I64) (:EQ :F32) (:NE :F32) (:LT :F32) (:GT :F32) (:LE :F32)) 94 | ;; ((#x60) (:GE :F32) (:EQ :F64) (:NE :F64) (:LT :F64) (:GT :F64) (:LE :F64) (:GE :F64) (:CLZ :I32)) 95 | ;; ((#x68) (:CTZ :I32) (:POPCNT :I32) (:ADD :I32) (:SUB :I32) (:MUL :I32) (:DIV_S :I32) (:DIV_U :I32) (:REM_S :I32)) 96 | ;; ((#x70) (:REM_U :I32) (:AND :I32) (:OR :I32) (:XOR :I32) (:SHL :I32) (:SHR_S :I32) (:SHR_U :I32) (:ROTL :I32)) 97 | ;; ((#x78) (:ROTR :I32) (:CLZ :I64) (:CTZ :I64) (:POPCNT :I64) (:ADD :I64) (:SUB :I64) (:MUL :I64) (:DIV_S :I64)) 98 | ;; ((#x80) (:DIV_U :I64) (:REM_S :I64) (:REM_U :I64) (:AND :I64) (:OR :I64) (:XOR :I64) (:SHL :I64) (:SHR_S :I64)) 99 | ;; ((#x88) (:SHR_U :I64) (:ROTL :I64) (:ROTR :I64) (:ABS :F32) (:NEG :F32) (:CEIL :F32) (:FLOOR :F32) (:TRUNC :F32)) 100 | ;; ((#x90) (:NEAREST :F32) (:SQRT :F32) (:ADD :F32) (:SUB :F32) (:MUL :F32) (:DIV :F32) (:MIN :F32) (:MAX :F32) (:COPYSIGN :F32) (:ABS :F64) (:NEG :F64) (:CEIL :F64) (:FLOOR :F64) (:TRUNC :F64) (:NEAREST :F64) (:SQRT :F64)) 101 | ;; ((#xA0) (:ADD :F64) (:SUB :F64) (:MUL :F64) (:DIV :F64) (:MIN :F64) (:MAX :F64) (:COPYSIGN :F64) (:WRAP_:I64 :I32) (:TRUNC_F32_S :I32) (:TRUNC_F32_U :I32) (:TRUNC_F64_S :I32) (:TRUNC_F64_U :I32) (:EXTEND_I32_S :I64) (:EXTEND_I32_U :I64) (:TRUNC_F32_S :I64) (:TRUNC_F32_U :I64)) 102 | ;; ((#xB0) (:TRUNC_F64_S :I64) (:TRUNC_F64_U :I64) (:CONVERT_I32_S :F32) (:CONVERT_I32_U :F32) (:CONVERT_:I64_S :F32) (:CONVERT_I64_U :F32) (:DEMOTE_F64 :F32) (:CONVERT_I32_S :F64) (:CONVERT_I32_U :F64) (:CONVERT_I64_S :F64) (:CONVERT_I64_U :F64) (:PROMOTE_F32 :F64) (:REINTERPRET_F32 I32) (:REINTERPRET_F64 :I64) (:REINTERPRET_I32 :F32) (:REINTERPRET_I64 :F64)) 103 | ;; ((#xC0) (:*I32 EXTEND8_S) (:*I32 EXTEND16_S) (:*:I64 EXTEND8_S) (:*I64 EXTEND16_S) (:*I64 EXTEND32_S) (:NIL) (:NIL) (:NIL) (:NIL) (:NIL) (:NIL) (:NIL) (:NIL) (:NIL) (:NIL) (:NIL)) 104 | ;; ((#xD0) (:*REF NULL) (:*REF IS_NULL) (:*REF FUNC) (:*REF AS_NON_NULL) (:*BR_ON_NULL) (:*REF EQ) (:*BR_ON_NON_NULL) (:NIL) (:NIL) (:NIL) (:NIL) (:NIL) (:NIL) (:NIL) (:NIL) (:NIL))) 105 | -------------------------------------------------------------------------------- /z80/package.lisp: -------------------------------------------------------------------------------- 1 | ;;;; package.lisp 2 | 3 | (defpackage #:specops.z80 4 | (:use #:cl #:specops)) 5 | -------------------------------------------------------------------------------- /z80/specops.z80.asd: -------------------------------------------------------------------------------- 1 | ;;;; z80.asd 2 | 3 | (asdf:defsystem #:specops.z80 4 | :description "Common Lisp assembler framework for z80 processor based on SpecOps." 5 | :author "Andrew Sengul" 6 | :license "BSD" 7 | :version "0.0.1" 8 | :serial t 9 | :depends-on ("specops") 10 | :components ((:file "package") 11 | (:file "base") 12 | (:file "templates") 13 | (:file "ops"))) 14 | -------------------------------------------------------------------------------- /z80/templates.lisp: -------------------------------------------------------------------------------- 1 | ;;;; templates.lisp 2 | 3 | (in-package #:specops.z80) 4 | 5 | (setf *assembler-prototype-z80* (make-instance 'assembler-z80)) 6 | --------------------------------------------------------------------------------