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

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

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

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

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

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

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

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


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

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

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

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


;(0x8C /r   MOV r/m16   Sreg    "Move segment register to r/m16")
;(0x8E /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 0x0F 0x22 (/s Sv Gv)     "Move to control register")

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

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

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