; Miasma: x86 Scheme Assembler.
; Copyright (C) 2000, Darius Bacon, Brian Spilsbury, Alycat
; Refer to legal/License.txt

; FIXME: Brian updated this without updating the doc.  At least Sx
; should be added to the feature list below.  There's an extra field
; after the doc-string, which I think is the registers the instruction
; affects.  Anything else?

; mnemonic feature* doc-string
; where:
; feature ::= byte
;          |  literal-register
;          |  =y
;          |  Sreg | cr | dr    (not yet implemented)
;          |  Ix | Ux | Ox | Jx
;          |  (? byte)
;          |  (+ byte Gx)
;          |  (/r Ex Gx)   [FIXME: but look out for restrictions on Ex, like Mx]
;          |  (/r Gx Ex)   [FIXME: also Gx might be cr or dr]
;          |  (/n Ex)
;
; where x = b | w | d | v
; and   y = 16 | 32

; FIXME: I think Sreg, cr, and dr should be unified with Gx -- so we 
; have a Gx operand category with a register-family attribute.  Of
; course, then the x part of Gx is unused for those cases.


; compare and contrast!
;
; (aad    (#xD5 #x0A)         "ASCII adjust AX before division")
; (aad    (#xD5) Ub           "ASCII adjust AX before division")
;
; vs:
;
; (rcl    (#xD0) (/2 Eb) 1    "Rotate left through carry")
; (rcl    (#xC0) (/2 Eb) Ub   "Rotate left through carry")
;
; Since we decided on the former (taking out the 1 in rcl), we need
; to be able to put it back in the gas listing (I think -- check it).


; other issues:
; 16/32 bit mode-sensitivity
; oops, left out the temporarily commented-out instructions from the original
; some instructions like MOV should allow either Ix or Ux operands


(aaa    #x37                    "ASCII adjust AL after addition" (%al %af %cf %of %sf %zf %pf))
(aas    #x3F                    "ASCII adjust AL after subtraction" (%al %ah %af %cf %of %sf %zf %pf))
(daa    #x27                    "Decimal adjust AL after addition" (%al %cf %af))
(das    #x2F                    "Decimal adjust AL after subtraction" (%al %cf %af))
(aad    #xD5 #x0A               "ASCII adjust AX before division" (%al %ah %sf %zf %pf))
(aad    #xD5 Ub                 "ASCII adjust AX before division" (%al %ah %sf %zf %pf))
(aam    #xD4 #x0A               "ASCII adjust AX after multiply" (%al %ah %sf %zf %pf %of %af %cf))
(aam    #xD4 Ub                 "ASCII adjust AX after multiply" (%al %ah %sf %zf %pf %of %af %cf))
(adc    #x14 %al Ib             "Add with carry" (%of %sf %zf %af %cf %pf))
(adc    #x15 %eax Iv            "Add with carry" (%of %sf %zf %af %cf %pf))
(adc    #x80 (/2 Eb) Ib         "Add with carry" (%of %sf %zf %af %cf %pf))
(adc    #x81 (/2 Ev) Iv         "Add with carry" (%of %sf %zf %af %cf %pf))
(adc    #x83 (/2 Ev) Ib         "Add with carry" (%of %sf %zf %af %cf %pf))
(adc    #x10 (/r Eb Gb)         "Add with carry" (%of %sf %zf %af %cf %pf))
(adc    #x11 (/r Ev Gv)         "Add with carry" (%of %sf %zf %af %cf %pf))
(adc    #x12 (/r Gb Eb)         "Add with carry" (%of %sf %zf %af %cf %pf))
(adc    #x13 (/r Gv Ev)         "Add with carry" (%of %sf %zf %af %cf %pf))
(add    #x04 %al Ib             "Add" (%of %sf %zf %af %cf %pf))
(add    #x05 %eax Iv            "Add" (%of %sf %zf %af %cf %pf))
(add    #x80 (/0 Eb) Ib         "Add" (%of %sf %zf %af %cf %pf))
(add    #x81 (/0 Ev) Iv         "Add" (%of %sf %zf %af %cf %pf))
(add    #x83 (/0 Ev) Ib         "Add" (%of %sf %zf %af %cf %pf))
(add    #x00 (/r Eb Gb)         "Add" (%of %sf %zf %af %cf %pf))
(add    #x01 (/r Ev Gv)         "Add" (%of %sf %zf %af %cf %pf))
(add    #x02 (/r Gb Eb)         "Add" (%of %sf %zf %af %cf %pf))
(add    #x03 (/r Gv Ev)         "Add" (%of %sf %zf %af %cf %pf))
(sbb    #x1C %al Ib             "Subtract with borrow" (%of %sf %zf %af %pf %cf))
(sbb    #x1D %eax Iv            "Subtract with borrow" (%of %sf %zf %af %pf %cf))
(sbb    #x80 (/3 Eb) Ib         "Subtract with borrow" (%of %sf %zf %af %pf %cf))
(sbb    #x81 (/3 Ev) Iv         "Subtract with borrow" (%of %sf %zf %af %pf %cf))
(sbb    #x83 (/3 Ev) Ib         "Subtract with borrow" (%of %sf %zf %af %pf %cf))
(sbb    #x18 (/r Eb Gb)         "Subtract with borrow" (%of %sf %zf %af %pf %cf))
(sbb    #x19 (/r Ev Gv)         "Subtract with borrow" (%of %sf %zf %af %pf %cf))
(sbb    #x1A (/r Gb Eb)         "Subtract with borrow" (%of %sf %zf %af %pf %cf))
(sbb    #x1B (/r Gv Ev)         "Subtract with borrow" (%of %sf %zf %af %pf %cf))
(sub    #x2C %al Ib             "Subtract" (%of %sf %zf %pf %cf))
(sub    #x2D %eax Iv            "Subtract" (%of %sf %zf %pf %cf))
(sub    #x80 (/5 Eb) Ib         "Subtract" (%of %sf %zf %pf %cf))
(sub    #x81 (/5 Ev) Iv         "Subtract" (%of %sf %zf %pf %cf))
(sub    #x83 (/5 Ev) Ib         "Subtract" (%of %sf %zf %pf %cf))
(sub    #x28 (/r Eb Gb)         "Subtract" (%of %sf %zf %pf %cf))
(sub    #x29 (/r Ev Gv)         "Subtract" (%of %sf %zf %pf %cf))
(sub    #x2A (/r Gb Eb)         "Subtract" (%of %sf %zf %pf %cf))
(sub    #x2B (/r Gv Ev)         "Subtract" (%of %sf %zf %pf %cf))
(and    #x24 %al Ib             "And" (%of %cf %sf %zf %pf %af))
(and    #x25 %eax Iv            "And" (%of %cf %sf %zf %pf %af))
(and    #x80 (/4 Eb) Ib         "And" (%of %cf %sf %zf %pf %af))
(and    #x81 (/4 Ev) Iv         "And" (%of %cf %sf %zf %pf %af))
(and    #x83 (/4 Ev) Ib         "And" (%of %cf %sf %zf %pf %af))
(and    #x24 %al Ub             "And" (%of %cf %sf %zf %pf %af))
(and    #x25 %eax Uv            "And" (%of %cf %sf %zf %pf %af))
(and    #x80 (/4 Eb) Ub         "And" (%of %cf %sf %zf %pf %af))
(and    #x81 (/4 Ev) Uv         "And" (%of %cf %sf %zf %pf %af))
(and    #x83 (/4 Ev) Ub         "And" (%of %cf %sf %zf %pf %af))
(and    #x20 (/r Eb Gb)         "And" (%of %cf %sf %zf %pf %af))
(and    #x21 (/r Ev Gv)         "And" (%of %cf %sf %zf %pf %af))
(and    #x22 (/r Gb Eb)         "And" (%of %cf %sf %zf %pf %af))
(and    #x23 (/r Gv Ev)         "And" (%of %cf %sf %zf %pf %af))
(or     #x0C %al Ib             "Or" (%of %cf %sf %zf %pf %af))
(or     #x0D %eax Iv            "Or" (%of %cf %sf %zf %pf %af))
(or     #x80 (/1 Eb) Ib         "Or" (%of %cf %sf %zf %pf %af))
(or     #x81 (/1 Ev) Iv         "Or" (%of %cf %sf %zf %pf %af))
(or     #x83 (/1 Ev) Ib         "Or" (%of %cf %sf %zf %pf %af))
(or     #x0C %al Ub             "Or" (%of %cf %sf %zf %pf %af))
(or     #x0D %eax Uv            "Or" (%of %cf %sf %zf %pf %af))
(or     #x80 (/1 Eb) Ub         "Or" (%of %cf %sf %zf %pf %af))
(or     #x81 (/1 Ev) Uv         "Or" (%of %cf %sf %zf %pf %af))
(or     #x83 (/1 Ev) Ub         "Or" (%of %cf %sf %zf %pf %af))
(or     #x08 (/r Eb Gb)         "Or" (%of %cf %sf %zf %pf %af))
(or     #x09 (/r Ev Gv)         "Or" (%of %cf %sf %zf %pf %af))
(or     #x0A (/r Gb Eb)         "Or" (%of %cf %sf %zf %pf %af))
(or     #x0B (/r Gv Ev)         "Or" (%of %cf %sf %zf %pf %af))
(xor    #x34 %al Ib             "Exclusive or" (%of %cf %sf %zf %pf))
(xor    #x35 %eax Iv            "Exclusive or" (%of %cf %sf %zf %pf))
(xor    #x80 (/6 Eb) Ib         "Exclusive or" (%of %cf %sf %zf %pf))
(xor    #x81 (/6 Ev) Iv         "Exclusive or" (%of %cf %sf %zf %pf))
(xor    #x83 (/6 Ev) Ib         "Exclusive or" (%of %cf %sf %zf %pf))
(xor    #x30 (/r Eb Gb)         "Exclusive or" (%of %cf %sf %zf %pf))
(xor    #x31 (/r Ev Gv)         "Exclusive or" (%of %cf %sf %zf %pf))
(xor    #x32 (/r Gb Eb)         "Exclusive or" (%of %cf %sf %zf %pf))
(xor    #x33 (/r Gv Ev)         "Exclusive or" (%of %cf %sf %zf %pf))
(test   #xA8 %al Ib             "Logical compare" ((%of 0) (%cf 0) %sf %zf %pf))
(test   #xA9 %eax Iv            "Logical compare" ((%of 0) (%cf 0) %sf %zf %pf))
(test   #xF6 (/0 Eb) Ib         "Logical compare" ((%of 0) (%cf 0) %sf %zf %pf))
(test   #xF7 (/0 Ev) Iv         "Logical compare" ((%of 0) (%cf 0) %sf %zf %pf))
(test   #x84 (/r Eb Gb)         "Logical compare" ((%of 0) (%cf 0) %sf %zf %pf))
(test   #x85 (/r Ev Gv)         "Logical compare" ((%of 0) (%cf 0) %sf %zf %pf))
(arpl   #x63 (/r Ew Gw)         "Adjust RPL of 1st to not less than RPL of 2nd" (%zf))
(bound  #x62 (/r Gv Mv)         "Bounds-checking")
(bsf    #x0F #xBC (/r Gv Ev)    "Bit Scan Forward" (%zf %cf %of %sf %af %pf))
(bsr    #x0F #xBD (/r Gv Ev)    "Bit Scan Reverse" (%zf %cf %of %sf %af %pf))
(bt     #x0F #xA3 (/r Ev Gv)    "Store selected bit in CF flag" (%cf %of %sf %zf %af %pf))
(bt     #x0F #xBA (/4 Ev) Ub    "Store selected bit in CF flag" (%cf %of %sf %zf %af %pf))
(btc    #x0F #xBB (/r Ev Gv)    "Store selected bit in CF flag and complement" (%cf %of %sf %zf %af %pf))
(btc    #x0F #xBA (/7 Ev) Ub    "Store selected bit in CF flag and complement" (%cf %of %sf %zf %af %pf))
(btr    #x0F #xB3 (/r Ev Gv)    "Store selected bit in CF flag and reset" (%cf %of %sf %zf %af %pf))
(btr    #x0F #xBA (/6 Ev) Ub    "Store selected bit in CF flag and reset" (%cf %of %sf %zf %af %pf))
(bts    #x0F #xAB (/r Ev Gv)    "Store selected bit in CF flag and set" (%cf %of %sf %zf %af %pf))
(bts    #x0F #xBA (/5 Ev) Ub    "Store selected bit in CF flag and set" (%cf %of %sf %zf %af %pf))
(call   #xE8 Jv                 "Call near, relative" #t)
(call   #xFF (/2 Ev)            "Call near, absolute indirect" #t)
(callf  #xFF (/3 Mv)            "Call far, absolute indirect" #t)

;(callf  #x9A Ov                 "Call near, absolute" #t)

(cbw    =16 #x98                "AX <- sign extend of AL" (%ax))
(cwde   =32 #x98                "EAX <- sign extend of AX" (%eax))
(cwd    =16 #x99                "Convert word to double" (%dx))
(cdq    =32 #x99                "Convert double to quad" (%edx))
(clc    #xF8                    "Clear CF flag" ((%cf 0)))
(cld    #xFC                    "Clear DF flag" ((%df 0)))
(cli    #xFA                    "Clear interrupt flag" (%if))
(stc    #xF9                    "Set CF flag" ((%cf 1)))
(std    #xFD                    "Set DF flag" ((%df 1)))
(sti    #xFB                    "Set interrupt flag" ((%if 1)))
(cmc    #xF5                    "Complement CF flag" ((%cf 1)))
(clts   #x0F #x06               "Clear task-switched flag in CR0" ((%cro.TS 0)))
(cmp    #x3D %eax Iv            "Compare Iv with EAX" (%cf %of %sf %zf %af %pf))
(cmp    #x3C %al Ib             "Compare Ib with AL" (%cf %of %sf %zf %af %pf))
(cmp    #x3D %eax Uv            "Compare Iv with EAX" (%cf %of %sf %zf %af %pf))
(cmp    #x3C %al Ub             "Compare Ib with AL" (%cf %of %sf %zf %af %pf))
(cmp    #x80 (/7 Eb) Ib         "Compare Ib with Eb" (%cf %of %sf %zf %af %pf))
(cmp    #x81 (/7 Ev) Iv         "Compare Iv with Ev" (%cf %of %sf %zf %af %pf))
(cmp    #x83 (/7 Ev) Ib         "Compare Ib with Ev" (%cf %of %sf %zf %af %pf))
(cmp    #x80 (/7 Eb) Ub         "Compare Ib with Eb" (%cf %of %sf %zf %af %pf))
(cmp    #x81 (/7 Ev) Uv         "Compare Iv with Ev" (%cf %of %sf %zf %af %pf))
(cmp    #x83 (/7 Ev) Ub         "Compare Ib with Ev" (%cf %of %sf %zf %af %pf))
(cmp    #x38 (/r Eb Gb)         "Compare Gb with Eb" (%cf %of %sf %zf %af %pf))
(cmp    #x39 (/r Ev Gv)         "Compare Gv with Ev" (%cf %of %sf %zf %af %pf))
(cmp    #x3A (/r Gb Eb)         "Compare Eb with Gb" (%cf %of %sf %zf %af %pf))
(cmp    #x3B (/r Gv Ev)         "Compare Ev with Gv" (%cf %of %sf %zf %af %pf))
(cmpsb  #xA6                    "Compare strings" (%esi %edi %si %di %cf %of %sf %zf %af %pf))
(cmpsw  =16 #xA7                "Compare strings" (%cf %of %sf %zf %af %pf))
(cmpsd  =32 #xA7                "Compare strings" (%cf %of %sf %zf %af %pf))
(cmpxchg #x0F #xB0 (/r Eb Gb)   "Compare and exchange" (%zf %cf %pf %af %sf %of))
(cmpxchg #x0F #xB1 (/r Ev Gv)   "Compare and exchange" (%zf %cf %pf %af %sf %of))
(cmpxchg8b #x0F #xC7 (/1 Md)    "Compare and exchange" (%zf %cf %pf %af %sf %of))
(cpuid  #x0F #xA2               "CPU identification in EAX" (%eax %ebx %ecx %edx))
(dec    (+ #x48 Gv)             "Decrement Gv by 1" (%of %sf %zf %af %pf))
(dec    #xFE (/1 Eb)            "Decrement Eb by 1" (%of %sf %zf %af %pf))
(dec    #xFF (/1 Ev)            "Decrement Ev by 1" (%of %sf %zf %af %pf))
(div    #xF6 (/6 Eb)            "Unsigned divide AX by Eb" (%al %ah %cf %of %sf %zf %af %pf))
(div    #xF7 (/6 Ev)            "Unsigned divide EDX:EAX by Ev" (%eax %edx %cf %of %sf %zf %af %pf))
(enter  #xC8 Uw Ub              "Create a stack frame for a procedure" (%esp %ebp))
(hlt    #xF4                    "Halt")
(idiv   #xF6 (/7 Eb)            "Signed integer divide" (%al %ah))
(idiv   #xF7 (/7 Ev)            "Signed integer divide" (%eax %edx))
(imul   #xF6 (/5 Eb)            "Signed integer multiply" (%ax %cf %of %sf %zf %af %pf))
(imul   #xF7 (/5 Ev)            "Signed integer multiply" (%cf %of %sf %zf %af %pf))
(imul   #x0F #xAF (/r Gv Ev)    "Signed integer multiply" (%cf %of %sf %zf %af %pf))
(imul   #x69 (/r Gv Ev) Iv      "Signed integer multiply" (%cf %of %sf %zf %af %pf))
(imul   #x6B (/r Gv Ev) Ib      "Signed integer multiply" (%cf %of %sf %zf %af %pf))
(in     #xE4 %al Ub             "Input from port")
(in     =16 #xE5 %ax Ub         "Input from port")
(in     #xE5 %eax Ub            "Input from port")
(in     #xEC %al %dx            "Input from port")
(in     #xED %eax %dx           "Input from port")
(in     =16 #xED %ax %dx        "Input from port")
(out    #xE6 Ub %al             "Output to port")
(out    #xE7 Ub %eax            "Output to port")
(out    =16 #xE7 Ub %ax         "Output to port")
(out    #xEE %dx %al            "Output to port")
(out    #xEF %dx %eax           "Output to port")
(out    =16 #xEF %dx %ax        "Output to port")
(inc    (+ #x40 Gv)             "Increment Gv by 1" (%of %sf %zf %af %pf))
(inc    #xFE (/0 Eb)            "Increment Eb by 1" (%of %sf %zf %af %pf))
(inc    #xFF (/0 Ev)            "Increment Ev by 1" (%of %sf %zf %af %pf))
(insb   #x6C                    "Input from port to string" (%di))
(insw   =16 #x6D                "Input from port to string" (%di))
(insd   =32 #x6D                "Input from port to string" (%edi))
(outsb  #x6E                    "Output to port from string" (%si))
(outsw  =16 #x6F                "Output to port from string" (%si))
(outsd  =32 #x6F                "Output to port from string" (%esi))
(int    #xCD Ub                 "Interrupt vector number specified by immediate byte" #t) ; confused about dirtiness... [bts]
(int-3  #xCC                    "Interrupt 3 -- Trap to debugger" #t) ; ditto
(into   #xCE                    "Interrupt 4 -- if overflow flag is 1" #t) ; ditto
(iret   =16 #xCF                "Interrupt return" #t)
(iretd  =32 #xCF                "Interrupt return" #t)
(j      (? #x70) Jb             "Jump short if condition")
(j      #x0F (? #x80) Jv        "Jump near if condition")
(jcxz   =16 #xE3 Jb             "Jump short if CX register is 0")
(jecxz  =32 #xE3 Jb             "Jump short if ECX register is 0")
(jmp    #xEB Jb                 "Jump short, relative")
(jmp    #xE9 Jv                 "Jump near, relative")
(jmp    #xFF (/4 Ev)            "Jump near, absolute indirect, address given in Ev")
(jmpf   #xFF (/5 Mv)            "Jump far, absolute indirect, address given in Mv")

;(jmpf   #xEA Ov                 "Jump far, absolute, address given in operand")

(lahf   #x9F                    "Load status flags into AH" (%ah))
(lar    #x0F #x02 (/r Gv Ev)    "Load access rights byte" (%zf))
(lds    #xC5 (/r Gv Mv)         "Load DS and Gv with far pointer from memory")
(les    #xC4 (/r Gv Mv)         "Load ES and Gv with far pointer from memory")
(lss    #x0F #xB2 (/r Gv Mv)    "Load SS and Gv with far pointer from memory")
(lfs    #x0F #xB4 (/r Gv Mv)    "Load FS and Gv with far pointer from memory")
(lgs    #x0F #xB5 (/r Gv Mv)    "Load GS and Gv with far pointer from memory")
(lea    #x8D (/r Gv Mv)         "Load effective address")
(leave  #xC9                    "Leave procedure" (%esp %sp %ebp %ep))
(lgdt   #x0F #x01 (/2 Mv)       "Load global descriptor table")
(lidt   #x0F #x01 (/3 Mv)       "Load interrupt descriptor table")
(sgdt   #x0F #x01 (/0 Mv)       "Store global descriptor table")
(sidt   #x0F #x01 (/1 Mv)       "Store interrupt descriptor table")
(lldt   #x0F #x00 (/2 Ew)       "Load local descriptor table")
(sldt   #x0F #x00 (/0 Ev)       "Store local descriptor table")
(lmsw   #x0F #x01 (/6 Ew)       "Load machine status word")
(smsw   #x0F #x01 (/4 Ev)       "Store machine status word")
(lodsb  #xAC                    "Load string byte" (%al %si))
(lodsw  =16 #xAD                "Load string word" (%ax %si))
(lodsd  =32 #xAD                "Load string word" (%eax %esi))
(loop   #xE2 Jb                 "Loop according to ECX" (%ecx))
(loope  #xE1 Jb                 "Loop according to ECX" (%ecx))
(loopz  #xE1 Jb                 "Loop according to ECX" (%ecx))
(loopne #xE0 Jb                 "Loop according to ECX" (%ecx))
(loopnz #xE0 Jb                 "Loop according to ECX" (%ecx))
(lsl    #x0F #x3 (/r Gv Ev)     "Load segment limit" (%zf))
(ltr    #x0F #x00 (/3 Ew)       "Load task register")
(str    #x0F #x00 (/1 Ew)       "Store task register")

(mov    #x88 (/r Eb Gb)         "Move Gb to Eb")
(mov    #x89 (/r Ev Gv)         "Move Gv to Ev")
(mov    #x8A (/r Gb Eb)         "Move Eb to Gb")
(mov    #x8B (/r Gv Ev)         "Move Ev to Gv")
(mov    #xA0 %al Ob             "Move byte at (seg:offset) to AL")
(mov    #xA1 %eax Ov            "Move doubleword at (seg:offset) to EAX")
(mov    #xA2 Ob %al             "Move AL to (seg:offset)")
(mov    #xA3 Ov %eax            "Move EAX to (seg:offset)")
(mov    (+ #xB0 Gb) Ib          "Move Ib to Gb")
(mov    (+ #xB8 Gv) Iv          "Move Iv to Gv")
(mov    #xC6 (/0 Eb) Ib         "Move Ib to Eb")
(mov    #xC7 (/0 Ev) Iv         "Move Iv to Ev")
(mov    (+ #xB0 Gb) Ub          "Move Ub to Gb")
(mov    (+ #xB8 Gv) Uv          "Move Uv to Gv")
(mov    #xC6 (/0 Eb) Ub         "Move Ub to Eb")
(mov    #xC7 (/0 Ev) Uv         "Move Uv to Ev")

(mov   =16 #x89 (/r Ew Gw)      "Move Gw to Ew")
(mov   =16 #x8B (/r Gw Ew)      "Move Ew to Gw")
(mov   =16 #xA1 %ax Ow          "Move word at (seg:offset) to AX")
(mov   =16 #xA3 Ow %ax          "Move AX to (seg:offset)")
(mov   =16 (+ #xB8 Gw) Iv       "Move Iv to Gw")
(mov   =16 #xC7 (/0 Ew) Iv      "Move Iv to Ew")
(mov   =16 (+ #xB8 Gw) Uv       "Move Uv to Gw")
(mov   =16 #xC7 (/0 Ew) Uv      "Move Uv to Ew")

(movsb  #xA4                    "String move" (%esi %edi))
(movsw  =16 #xA5                "String move" (%esi %edi))
(movsd  =32 #xA5                "String move" (%esi %edi))
(movsx  #x0F #xBE (/r Gv Eb)    "Move with sign-extension")
(movsx  #x0F #xBF (/r Gv Ew)    "Move with sign-extension")
(movzx  #x0F #xB6 (/r Gv Eb)    "Move with zero-extension")
(movzx  #x0F #xB7 (/r Gv Ew)    "Move with zero-extension")
(mul    #xF6 (/4 Eb)            "Unsigned multiply" (%eax %of %cf %sf %zf %af %pf))
(mul    #xF7 (/4 Ev)            "Unsigned multiply" (%of %cf %sf %zf %af %pf))
(neg    #xF6 (/3 Eb)            "Arithmetic negative" (%cf %of %sf %zf %af %pf))
(neg    #xF7 (/3 Ev)            "Arithmetic negative" (%cf %of %sf %zf %af %pf))
(nop    #x90                    "No op")
(not    #xF6 (/2 Eb)            "Bitwise not")
(not    #xF7 (/2 Ev)            "Bitwise not")
(pop    (+ #x58 Gv)             "Pop from stack" (%esp))
(pop    #x8F (/0 Ev)            "Pop from stack" (%esp))
(pop    #x1F %ds                "Pop from stack" (%esp))
(pop    #x07 %es                "Pop from stack" (%esp))
(pop    #x17 %ss                "Pop from stack" (%esp))
(pop    #x0F #xA1 %fs           "Pop from stack" (%esp))
(pop    #x0F #xA9 %gs           "Pop from stack" (%esp))
(popa   =16 #x61                "Pop all general regs from stack" #t)
(popad  =32 #x61                "Pop all general regs from stack" #t)
(popf   =16 #x9D                "Pop into eflags register" #t) ; not quite, most flags
(popfd  =32 #x9D                "Pop into eflags register" #t) ;        ""
(push   (+ #x50 Gv)             "Push to stack" (%esp))
(push   #x6A Ib                 "Push byte to stack" (%esp))
(push   #x68 Iv                 "Push dword to stack" (%esp))
(push   #x0E %cs                "Push to stack" (%esp))
(push   #x1E %ds                "Push to stack" (%esp))
(push   #x06 %es                "Push to stack" (%esp))
(push   #x16 %ss                "Push to stack" (%esp))
(push   #x0F #xA0 %fs           "Push to stack" (%esp))
(push   #x0F #xA8 %gs           "Push to stack" (%esp))
(push   #xFF (/6 Ev)            "Push to stack" (%esp))
(pusha  =16 #x60                "Push all general regs to stack" (%esp))
(pushad =32 #x60                "Push all general regs to stack" (%esp))
(pushf  =16 #x9C                "Push eflags register" (%esp))
(pushfd =32 #x9C                "Push eflags register" (%esp))
(rcl    #xD0 (/2 Eb)            "Rotate left through carry" (%cf %of))
(rcl    #xD1 (/2 Ev)            "Rotate left through carry" (%cf %of))
(rcl    #xD2 (/2 Eb) %cl        "Rotate left through carry" (%cf %of))
(rcl    #xD3 (/2 Ev) %cl        "Rotate left through carry" (%cf %of))
(rcl    #xC0 (/2 Eb) Ub         "Rotate left through carry" (%cf %of))
(rcl    #xC1 (/2 Ev) Ub         "Rotate left through carry" (%cf %of))
(rcr    #xD0 (/3 Eb)            "Rotate right through carry" (%cf %of))
(rcr    #xD1 (/3 Ev)            "Rotate right through carry" (%cf %of))
(rcr    #xD2 (/3 Eb) %cl        "Rotate right through carry" (%cf %of))
(rcr    #xD3 (/3 Ev) %cl        "Rotate right through carry" (%cf %of))
(rcr    #xC0 (/3 Eb) Ub         "Rotate right through carry" (%cf %of))
(rcr    #xC1 (/3 Ev) Ub         "Rotate right through carry" (%cf %of))
(rol    #xD0 (/0 Eb)            "Rotate left" (%cf %of))
(rol    #xD1 (/0 Ev)            "Rotate left" (%cf %of))
(rol    #xD2 (/0 Eb) %cl        "Rotate left" (%cf %of))
(rol    #xD3 (/0 Ev) %cl        "Rotate left" (%cf %of))
(rol    #xC0 (/0 Eb) Ub         "Rotate left" (%cf %of))
(rol    #xC1 (/0 Ev) Ub         "Rotate left" (%cf %of))
(ror    #xD0 (/1 Eb)            "Rotate right" (%cf %of))
(ror    #xD1 (/1 Ev)            "Rotate right" (%cf %of))
(ror    #xD2 (/1 Eb) %cl        "Rotate right" (%cf %of))
(ror    #xD3 (/1 Ev) %cl        "Rotate right" (%cf %of))
(ror    #xC0 (/1 Eb) Ub         "Rotate right" (%cf %of))
(ror    #xC1 (/1 Ev) Ub         "Rotate right" (%cf %of))
(sal    #xD0 (/4 Eb)            "Shift arithmetic left" (%cf %of %sf %zf %pf))
(sal    #xD1 (/4 Ev)            "Shift arithmetic left" (%cf %of %sf %zf %pf))
(sal    #xD2 (/4 Eb) %cl        "Shift arithmetic left" (%cf %of %sf %zf %pf))
(sal    #xD3 (/4 Ev) %cl        "Shift arithmetic left" (%cf %of %sf %zf %pf))
(sal    #xC0 (/4 Eb) Ub         "Shift arithmetic left" (%cf %of %sf %zf %pf))
(sal    #xC1 (/4 Ev) Ub         "Shift arithmetic left" (%cf %of %sf %zf %pf))
(shl    #xD0 (/4 Eb)            "Shift left" (%cf %of %sf %zf %pf))
(shl    #xD1 (/4 Ev)            "Shift left" (%cf %of %sf %zf %pf))
(shl    #xD2 (/4 Eb) %cl        "Shift left" (%cf %of %sf %zf %pf))
(shl    #xD3 (/4 Ev) %cl        "Shift left" (%cf %of %sf %zf %pf))
(shl    #xC0 (/4 Eb) Ub         "Shift left" (%cf %of %sf %zf %pf))
(shl    #xC1 (/4 Ev) Ub         "Shift left" (%cf %of %sf %zf %pf))
(sar    #xD0 (/7 Eb)            "Shift arithmetic right" (%cf %of %sf %zf %pf))
(sar    #xD1 (/7 Ev)            "Shift arithmetic right" (%cf %of %sf %zf %pf))
(sar    #xD2 (/7 Eb) %cl        "Shift arithmetic right" (%cf %of %sf %zf %pf))
(sar    #xD3 (/7 Ev) %cl        "Shift arithmetic right" (%cf %of %sf %zf %pf))
(sar    #xC0 (/7 Eb) Ub         "Shift arithmetic right" (%cf %of %sf %zf %pf))
(sar    #xC1 (/7 Ev) Ub         "Shift arithmetic right" (%cf %of %sf %zf %pf))
(shr    #xD0 (/5 Eb)            "Shift unsigned right" (%cf %of %sf %zf %pf))
(shr    #xD1 (/5 Ev)            "Shift unsigned right" (%cf %of %sf %zf %pf))
(shr    #xD2 (/5 Eb) %cl        "Shift unsigned right" (%cf %of %sf %zf %pf))
(shr    #xD3 (/5 Ev) %cl        "Shift unsigned right" (%cf %of %sf %zf %pf))
(shr    #xC0 (/5 Eb) Ub         "Shift unsigned right" (%cf %of %sf %zf %pf))
(shr    #xC1 (/5 Ev) Ub         "Shift unsigned right" (%cf %of %sf %zf %pf))
(ret    #xC2 Iw                 "Near return and pop Iw bytes from stack" (%esp)) ; ??? is this true [bts]
(ret    #xC3                    "Near return" (%esp)) ; ??? is this true [bts]
(retf   #xCA Iw                 "Far return and pop Iw bytes from stack" (%esp)) ; ??
(retf   #xCB                    "Far return" (%esp)) ; ??
(rsm    #x0F #xAA               "Resume from system management mode" #t)
(sahf   #x9E                    "Store AH into flags" (%sf %zf %af %pf %cf))
(scasb  #xAE                    "String scan" (%edi %of %sf %zf %af %pf %cf))
(scasw  =16 #xAF                "String scan" (%edi %of %sf %zf %af %pf %cf))
(scasd  =32 #xAF                "String scan" (%edi %of %sf %zf %af %pf %cf))
(set    #x0F (? #x90) (/0 Eb)   "Set byte if condition")
(shld   #x0F #xA4 (/r Ev Gv) Ub  "Double precision shift left" (%cf %sf %zf %pf %of %af))
(shld   #x0F #xA5 (/r Ev Gv) %cl "Double precision shift left" (%cf %sf %zf %pf %of %af))
(shrd   #x0F #xAC (/r Ev Gv) Ub  "Double precision shift right" (%cf %sf %zf %pf %of %af))
(shrd   #x0F #xAD (/r Ev Gv) %cl "Double precision shift right" (%cf %sf %zf %pf %of %af))
(stosb  #xAA                    "String store" (%edi))
(stosw  =16 #xAB                "String store" (%edi))
(stosd  =32 #xAB                "String store" (%edi))
(verr   #x0F #x00 (/4 Ew)       "Verify segment for reading" (%zf))
(verw   #x0F #x00 (/5 Ew)       "Verify segment for writing" (%zf))
(xchg   (+ #x90 Gv) %eax        "Exchange")
(xchg   %eax (+ #x90 Gv)        "Exchange")
(xchg   #x86 (/r Gb Eb)         "Exchange")
(xchg   #x86 (/r Eb Gb)         "Exchange")
(xchg   #x87 (/r Gv Ev)         "Exchange")
(xchg   #x87 (/r Ev Gv)         "Exchange")
(xlatb  #xD7                    "Byte table lookup" (%eax))


;;this one is only legal before certain instructions:
(lock:  #xF0                    "The lock prefix") 

(repne: #xF2                    "Repeat prefix (only for string instructions)")
(repnz: #xF2                    "Synonym for REPNE")
(rep:   #xF3                    "Repeat prefix (only for string instructions)")
(repe:  #xF3                    "Synonym for REP")
(repz:  #xF3                    "Synonym for REP")

(cs:    #x2E                    "Segment override prefix")
(ss:    #x36                    "Segment override prefix")
(ds:    #x3E                    "Segment override prefix")
(es:    #x26                    "Segment override prefix")
(fs:    #x64                    "Segment override prefix")
(gs:    #x65                    "Segment override prefix")

(operand-size-prefix: #x66      "Intel brain damage")
(address-size-prefix: #x67      "Intel brain damage")


;(#x8C /r   MOV r/m16   Sreg    "Move segment register to r/m16")
;(#x8E /r   MOV Sreg    r/m16   "Move r/m16 to segment register")

;; FIXME: r/m32 in the 4 below are all actually required to be r32
;; (though encoded like r/m32)

;;(movcr #x0F #x22 (/s Sv Gv)     "Move to control register")

;;(movcr #x0F #x20 (/s Gv Sv)     "Move from control register")

;(#x0F #x20 /r MOV cr r/m32       "Move to control register")
;(#x0F #x22 /r MOV r/m32 cr       "Move from control register")

;(#x0F #x21 /r MOV r/m32 dr       "Move from debug register")
;(#x0F #x23 /r MOV dr r/m32       "Move to debug register")
