Initial commit
[disassembler.git] / Text / Disassembler / X86Disassembler.hs
1 --------------------------------------------------------------------------
2 -- |
3 -- Module      :  Text.Disassembler.X86Disassembler
4 -- Copyright   :  (c) Martin Grabmueller and Dirk Kleeblatt
5 -- License     :  BSD3
6 -- 
7 -- Maintainer  :  martin@grabmueller.de,klee@cs.tu-berlin.de
8 -- Stability   :  provisional
9 -- Portability :  portable
10 --
11 -- Disassembler for x86 machine code.
12 --
13 -- This is a disassembler for object code for the x86 architecture.
14 -- It provides functions for disassembling byte arrays, byte lists and
15 -- memory blocks containing raw binary code.
16 -- 
17 -- Features:
18 --
19 -- - Disassembles memory blocks, lists or arrays of bytes into lists of
20 --   instructions.
21 --
22 -- - Abstract instructions provide as much information as possible about
23 --   opcodes, addressing modes or operand sizes, allowing for detailed
24 --   output.
25 --
26 -- - Provides functions for displaying instructions in Intel or AT&T
27 --   style (like the GNU tools)
28 --
29 -- Differences to GNU tools, like gdb or objdump:
30 --
31 -- - Displacements are shown in decimal, with sign if negative.
32 --
33 -- Missing: 
34 --
35 -- - LOCK and repeat prefixes are recognized, but not contained in the
36 --   opcodes of instructions.
37 --
38 -- - Support for 16-bit addressing modes.  Could be added when needed.
39 --
40 -- - Complete disassembly of all 64-bit instructions.  I have tried to
41 --   disassemble them properly but have been limited to the information
42 --   in the docs, because I have no 64-bit machine to test on.  This will
43 --   probably change when I get GNU as to produce 64-bit object files.
44 --
45 -- - Not all MMX and SSE/SSE2/SSE3 instructions are decoded yet.  This is
46 --   just a matter of missing time.
47 --
48 -- - segment override prefixes are decoded, but not appended to memory
49 --   references
50 --
51 -- On the implementation:
52 --
53 -- This disassembler uses the Parsec parser combinators, working on byte
54 -- lists.  This proved to be very convenient, as the combinators keep
55 -- track of the current position, etc.
56 --------------------------------------------------------------------------
57
58 module Text.Disassembler.X86Disassembler(
59   -- * Types
60   Opcode,
61   Operand(..),
62   InstrOperandSize(..),
63   Instruction(..),
64   ShowStyle(..),
65   Config(..),
66   -- * Functions
67   disassembleBlock,
68   disassembleList,
69   disassembleArray,
70   disassembleFile,
71   disassembleBlockWithConfig,
72   disassembleListWithConfig,
73   disassembleArrayWithConfig,
74   disassembleFileWithConfig,
75   showIntel,
76   showAtt,
77   defaultConfig
78   ) where
79
80 import Text.ParserCombinators.Parsec
81 import Control.Monad.State
82 import System.IO
83 import Data.List
84 import Data.Char
85 import Data.Array.IArray
86 import Numeric
87 import Foreign
88
89 -- | All opcodes are represented by this enumeration type.
90
91 data Opcode = InvalidOpcode
92             | AAA
93             | AAD
94             | AAM
95             | AAS
96             | ADC
97             | ADD
98             | ADDPD
99             | ADDPS
100             | ADDSD
101             | ADDSS
102             | ADDSUBPD
103             | ADDUBPS
104             | AND
105             | ANDNPD
106             | ANDNPS
107             | ANDPD
108             | ANDPS
109             | ARPL
110             | BOUND
111             | BSF
112             | BSR
113             | BT
114             | BTC
115             | BTR
116             | BTS
117             | CALL
118             | CALLF
119             | CBW
120             | CDQ
121             | CDQE
122             | CLC
123             | CLD
124             | CLFLUSH
125             | CLI
126             | CLTS
127             | CMC
128             | CMOVA
129             | CMOVB
130             | CMOVBE
131             | CMOVE
132             | CMOVG
133             | CMOVGE
134             | CMOVL
135             | CMOVLE
136             | CMOVNB
137             | CMOVNE
138             | CMOVNO
139             | CMOVNP
140             | CMOVNS
141             | CMOVO
142             | CMOVP
143             | CMOVS
144             | CMP
145             | CMPS
146             | CMPXCHG
147             | CMPXCHG16B
148             | CMPXCHG8B
149             | COMISD
150             | COMISS
151             | CPUID
152             | CWD
153             | CWDE
154             | DAA
155             | DAS
156             | DEC
157             | DIV
158             | DIVPD
159             | DIVPS
160             | DIVSD
161             | DIVSS
162             | EMMS
163             | ENTER
164             | FABS
165             | FADD
166             | FADDP
167             | FBLD
168             | FBSTP
169             | FCHS
170             | FCLEX
171             | FCMOVB
172             | FCMOVBE
173             | FCMOVE
174             | FCMOVNB
175             | FCMOVNBE
176             | FCMOVNE
177             | FCMOVNU
178             | FCMOVU
179             | FCOM
180             | FCOMI
181             | FCOMIP
182             | FCOMP
183             | FCOMPP
184             | FDIV
185             | FDIVP
186             | FDIVR
187             | FDIVRP
188             | FFREE
189             | FIADD
190             | FICOM
191             | FICOMP
192             | FIDIV
193             | FIDIVR
194             | FILD
195             | FIMUL
196             | FINIT
197             | FIST
198             | FISTP
199             | FISTPP
200             | FISTTP
201             | FISUB
202             | FISUBR
203             | FLD
204             | FLD1
205             | FLDCW
206             | FLDENV
207             | FLDL2E
208             | FLDL2T
209             | FLDLG2
210             | FLDLN2
211             | FLDPI
212             | FLDZ
213             | FMUL
214             | FMULP
215             | FNOP
216             | FRSTOR
217             | FSAVE
218             | FST
219             | FSTCW
220             | FSTENV
221             | FSTP
222             | FSTSW
223             | FSUB
224             | FSUBP
225             | FSUBR
226             | FSUBRP
227             | FTST
228             | FUCOM
229             | FUCOMI
230             | FUCOMIP
231             | FUCOMP
232             | FUCOMPP
233             | FXAM
234             | FXCH
235             | FXRSTOR
236             | FXSAVE
237             | HADDPD
238             | HADDPS
239             | HLT
240             | HSUBPD
241             | HSUBPS
242             | IDIV
243             | IMUL
244             | BSWAP
245             | IN
246             | INC
247             | INS
248             | INT
249             | INT3
250             | INTO
251             | INVD
252             | INVLPG
253             | IRET
254             | JA
255             | JB
256             | JBE
257             | JCXZ
258             | JE
259             | JG
260             | JGE
261             | JL
262             | JLE
263             | JMP
264             | JMPF
265             | JMPN
266             | JNB
267             | JNE
268             | JNO
269             | JNP
270             | JNS
271             | JO
272             | JP
273             | JS
274             | LAHF
275             | LAR
276             | LDDQU
277             | LDMXCSR
278             | LDS
279             | LEA
280             | LEAVE
281             | LES
282             | LFENCE
283             | LFS
284             | LGDT
285             | LGS
286             | LIDT
287             | LLDT
288             | LMSW
289             | LODS
290             | LOOP
291             | LOOPE
292             | LOOPNE
293             | LSL
294             | LSS
295             | LTR
296             | MASKMOVQ
297             | MAXPD
298             | MAXPS
299             | MAXSD
300             | MAXSS
301             | MFENCE
302             | MINPD
303             | MINPS
304             | MINSD
305             | MINSS
306             | MONITOR
307             | MOV 
308             | MOVAPD
309             | MOVAPS
310             | MOVDDUP
311             | MOVHPD
312             | MOVHPS
313             | MOVLHPS
314             | MOVLPD
315             | MOVLPS
316             | MOVLSDUP
317             | MOVMSKPD
318             | MOVMSKPS
319             | MOVNTDQ
320             | MOVNTPD
321             | MOVNTPS
322             | MOVNTQ
323             | MOVQ
324             | MOVS
325             | MOVSD
326             | MOVSLDUP
327             | MOVSS
328             | MOVSXB
329             | MOVSXD
330             | MOVSXW
331             | MOVUPD
332             | MOVUPS
333             | MOVZXB
334             | MOVZXW
335             | MUL
336             | MULPD
337             | MULPS
338             | MULSD
339             | MULSS
340             | MWAIT
341             | NEG
342             | NOP
343             | NOT
344             | OR
345             | ORPD
346             | ORPS
347             | OUT
348             | OUTS
349             | PADDB
350             | PADDD
351             | PADDQ
352             | PADDSB
353             | PADDSW
354             | PADDUSB
355             | PADDUSW
356             | PADDW
357             | PAND
358             | PANDN
359             | PAUSE
360             | PAVGB
361             | PAVGW
362             | PMADDWD
363             | PMAXSW
364             | PMAXUB
365             | PMINSW
366             | PMINUB
367             | PMOVMSKB
368             | PMULHUW
369             | PMULHW
370             | PMULLW
371             | PMULUDQ
372             | POP
373             | POPA
374             | POPAD
375             | POPF
376             | POPFD
377             | POPFQ
378             | POR
379             | PREFETCHNTA
380             | PREFETCHT0
381             | PREFETCHT1
382             | PREFETCHT2
383             | PSADBW
384             | PSLLD
385             | PSLLDQ
386             | PSLLQ
387             | PSLLW
388             | PSRAD
389             | PSRAW
390             | PSRLD
391             | PSRLDQ
392             | PSRLQ
393             | PSRLW
394             | PSUBB
395             | PSUBD
396             | PSUBQ
397             | PSUBSB
398             | PSUBSQ
399             | PSUBUSB
400             | PSUBUSW
401             | PSUBW
402             | PUSH
403             | PUSHA
404             | PUSHAD
405             | PUSHF
406             | PUSHFD
407             | PUSHFQ
408             | PXOR
409             | RCL
410             | RCPPS
411             | RCPSS
412             | RCR
413             | RDMSR
414             | RDPMC
415             | RDTSC
416             | RET
417             | RETF
418             | ROL
419             | ROR
420             | RSM
421             | RSQRTPS
422             | RSQRTSS
423             | SAHF
424             | SAR
425             | SBB
426             | SCAS
427             | SETA
428             | SETB
429             | SETBE
430             | SETE
431             | SETG
432             | SETGE
433             | SETL
434             | SETLE
435             | SETNB
436             | SETNE
437             | SETNO
438             | SETNP
439             | SETNS
440             | SETO
441             | SETP
442             | SETS
443             | SFENCE
444             | SGDT
445             | SHL
446             | SHLD
447             | SHR
448             | SHRD
449             | SIDT
450             | SLDT
451             | SMSW
452             | SQRTPD
453             | SQRTPS
454             | SQRTSD
455             | SQRTSS
456             | STC
457             | STD
458             | STI
459             | STMXCSR
460             | STOS
461             | STR
462             | SUB
463             | SUBPD
464             | SUBPS
465             | SUBSD
466             | SUBSS
467             | SWAPGS
468             | SYSCALL
469             | SYSENTER
470             | SYSEXIT
471             | TEST
472             | UCOMISD
473             | UCOMISS
474             | UD2
475             | UNPCKHPD
476             | UNPCKHPS
477             | UNPCKLPD
478             | UNPCKLPS
479             | VERR
480             | VERW
481             | VMCALL
482             | VMCLEAR
483             | VMLAUNCH
484             | VMPTRLD
485             | VMPTRST
486             | VMREAD
487             | VMRESUME
488             | VMWRITE
489             | VMXOFF
490             | VMXON
491             | WAIT
492             | WBINVD
493             | WRMSR
494             | XADD
495             | XCHG
496             | XLAT
497             | XOR
498             | XORPD
499             | XORPS
500   deriving (Show, Eq)
501
502 -- Display an opcode in lower case.
503
504 showOp :: Opcode -> String
505 showOp = (map toLower) . show
506
507 -- | All operands are in one of the following locations:
508 --
509 -- - Constants in the instruction stream
510 --
511 -- - Memory locations
512 --
513 -- - Registers
514 --
515 -- Memory locations are referred to by on of several addressing modes:
516 --
517 -- - Absolute (address in instruction stream)
518 --
519 -- - Register-indirect (address in register)
520 --
521 -- - Register-indirect with displacement
522 --
523 -- - Base-Index with scale
524 --
525 -- - Base-Index with scale and displacement 
526 --
527 -- Displacements can be encoded as 8 or 32-bit immediates in the
528 -- instruction stream, but are encoded as Int in instructions for
529 -- simplicity.
530 --
531 data Operand = OpImm Word32             -- ^ Immediate value
532               | OpAddr Word32 InstrOperandSize -- ^ Absolute address
533               | OpReg String Int        -- ^ Register
534               | OpFPReg Int             -- ^ Floating-point register
535               | OpInd String InstrOperandSize -- ^Register-indirect
536               | OpIndDisp String Int InstrOperandSize
537                 -- ^ Register-indirect with displacement
538               | OpBaseIndex String String Int InstrOperandSize
539                                         -- ^ Base plus scaled index
540               | OpIndexDisp String Int Int InstrOperandSize
541                  -- ^ Scaled index with displacement
542               | OpBaseIndexDisp String String Int Int InstrOperandSize
543                  -- ^ Base plus scaled index with displacement
544   deriving (Eq)
545
546 -- Show an operand in AT&T style.
547
548 showAttOps (OpImm w) = showImm w
549 showAttOps (OpAddr w _) = showAddr w
550 showAttOps (OpReg s num) = "%" ++ s
551 showAttOps (OpFPReg 0) = "%st"
552 showAttOps (OpFPReg i) = "%st(" ++ show i ++ ")"
553 showAttOps (OpInd s _) = "(%" ++ s ++ ")"
554 showAttOps (OpIndDisp s disp _) = show disp ++ "(%" ++ s ++ ")"
555 showAttOps (OpBaseIndex b i s _) = "(%" ++ b ++ ",%" ++ i ++ "," ++ show s ++ ")"
556 showAttOps (OpIndexDisp i s disp _) = show disp ++ "(%" ++ i ++ "," ++ 
557   show s ++ ")"
558 showAttOps (OpBaseIndexDisp b i s disp _) = show disp ++ "(%" ++ b ++ ",%" ++ 
559   i ++ "," ++ show s ++ ")"
560
561 -- Show an operand in Intel style.
562
563 showIntelOps opsize (OpImm w) = showIntelImm w
564 showIntelOps opsize (OpAddr w sz) = opInd sz ++ "[" ++ showIntelAddr w ++ "]"
565 showIntelOps opsize (OpReg s num) = s
566 showIntelOps opsize (OpFPReg 0) = "st"
567 showIntelOps opsize (OpFPReg i) = "st(" ++ show i ++ ")"
568 showIntelOps opsize (OpInd s sz) = opInd sz ++ "[" ++ s ++ "]"
569 showIntelOps opsize (OpIndDisp s disp sz) = 
570     opInd sz ++ "[" ++ s ++ 
571        (if disp < 0 then "" else "+") ++ show disp ++ "]"
572 showIntelOps opsize (OpBaseIndex b i s sz) = 
573     opInd sz ++ "[" ++ b ++ "+" ++ i ++ "*" ++ show s ++ "]"
574 showIntelOps opsize (OpIndexDisp i s disp sz) = 
575     opInd sz ++ "[" ++ i ++ "*" ++ show s ++ 
576        (if disp < 0 then "" else "+") ++ show disp ++ "]"
577 showIntelOps opsize (OpBaseIndexDisp b i s disp sz) = 
578     opInd sz ++ "[" ++ b ++ "+" ++ i ++ "*" ++ show s ++ 
579        (if disp < 0 then "" else "+") ++ 
580       show disp ++ "]"
581 opInd OPNONE = ""
582 opInd OP8 = "byte ptr "
583 opInd OP16 = "word ptr "
584 opInd OP32 = "dword ptr "
585 opInd OPF32 = "dword ptr "
586 opInd OP64 = "qword ptr "
587 opInd OPF64 = "qword ptr "
588 opInd OPF80 = "tbyte ptr "
589 opInd OP128 = "dqword ptr "
590
591 -- | Encodes the default and currently active operand or address size.  Can
592 -- be changed with the operand- or address-size prefixes 0x66 and 0x67.
593
594 data OperandSize = BIT16 | BIT32
595
596 -- | Some opcodes can operate on data of several widths.  This information
597 -- is encoded in instructions using the following enumeration type..
598
599 data InstrOperandSize = OPNONE -- ^ No operand size specified
600                 | OP8          -- ^ 8-bit integer operand
601                 | OP16         -- ^ 16-bit integer operand
602                 | OP32         -- ^ 32-bit integer operand
603                 | OP64         -- ^ 64-bit integer operand
604                 | OP128        -- ^ 128-bit integer operand
605                 | OPF32        -- ^ 32-bit floating point operand
606                 | OPF64        -- ^ 64-bit floating point operand
607                 | OPF80        -- ^ 80-bit floating point operand
608   deriving (Show, Eq)
609
610
611 -- | The disassembly routines return lists of the following datatype.  It
612 -- encodes both invalid byte sequences (with a useful error message, if
613 -- possible), or a valid instruction.  Both variants contain the list of
614 -- opcode bytes from which the instruction was decoded and the address of
615 -- the instruction.
616
617 data Instruction = 
618     BadInstruction Word8 String Int [Word8]   -- ^ Invalid instruction
619   | PseudoInstruction Int String                  -- ^ Pseudo instruction, e.g. label
620   | Instruction { opcode :: Opcode,           -- ^ Opcode of the instruction
621                   opsize :: InstrOperandSize, -- ^ Operand size, if any
622                   operands :: [Operand],      -- ^ Instruction operands
623                   address :: Int,             -- ^ Start address of instruction
624                   bytes ::[Word8]             -- ^ Instruction bytes
625                  }                            -- ^ Valid instruction
626   deriving (Eq)
627
628 instance Show Instruction where
629     show = showIntel
630
631 data Instr = Bad Word8 String
632             | Instr Opcode InstrOperandSize [Operand]
633
634 -- Show an integer as an 8-digit hexadecimal number with leading zeroes.
635
636 hex32 :: Int -> String
637 hex32 i =
638     let w :: Word32
639         w = fromIntegral i
640         s = showHex w ""
641     in take (8 - length s) (repeat '0') ++ s
642
643 -- Show a byte as an 2-digit hexadecimal number with leading zeroes.
644
645 hex8 :: Word8 -> String
646 hex8 i =
647     let s = showHex i ""
648     in take (2 - length s) ['0','0'] ++ s
649
650
651 -- | Instructions can be displayed either in Intel or AT&T style (like in
652 -- GNU tools).
653 --
654 -- Intel style:
655 --
656 -- - Destination operand comes first, source second.
657 --
658 -- - No register or immediate prefixes.
659 --
660 -- - Memory operands are annotated with operand size.
661 --
662 -- - Hexadecimal numbers are suffixed with @H@ and prefixed with @0@ if
663 --   necessary.
664 --
665 -- AT&T style:
666 --
667 -- - Source operand comes first, destination second.
668 --
669 -- - Register names are prefixes with @%@.
670 --
671 -- - Immediates are prefixed with @$@.
672 --
673 -- - Hexadecimal numbers are prefixes with @0x@
674 --
675 -- - Opcodes are suffixed with operand size, when ambiguous otherwise.
676 data ShowStyle = IntelStyle             -- ^ Show in Intel style
677                 | AttStyle              -- ^ Show in AT&T style
678
679 -- | Show an instruction in Intel style.
680
681 showIntel :: Instruction -> [Char]
682 showIntel (BadInstruction b desc pos bytes) =
683     showPosBytes pos bytes ++
684     "(" ++ desc ++ ", byte=" ++ show b ++ ")"
685 showIntel (PseudoInstruction pos s) =
686     hex32 pos ++ "                          " ++ s
687 showIntel (Instruction op opsize [] pos bytes) = 
688     showPosBytes pos bytes ++
689        showOp op
690 showIntel (Instruction op opsize ops pos bytes) = 
691     showPosBytes pos bytes ++
692         enlarge (showOp op) 6 ++ " " ++
693        concat (intersperse "," (map (showIntelOps opsize) ops))
694
695 -- | Show an instruction in AT&T style.
696
697 showAtt :: Instruction -> [Char]
698 showAtt (BadInstruction b desc pos bytes) = 
699     showPosBytes pos bytes ++
700        "(" ++ desc ++ ", byte=" ++ show b ++ ")"
701 showAtt (PseudoInstruction pos s) =
702     hex32 pos ++ "                          " ++ s
703 showAtt (Instruction op opsize [] pos bytes) = 
704     showPosBytes pos bytes ++
705        showOp op ++ showInstrSuffix [] opsize
706 showAtt (Instruction op opsize ops pos bytes) = 
707     showPosBytes pos bytes ++
708        enlarge (showOp op ++ showInstrSuffix ops opsize) 6 ++ " " ++
709        concat (intersperse "," (map showAttOps (reverse ops)))
710
711 showPosBytes pos bytes =
712     hex32 pos ++ "  " ++ 
713       enlarge (concat (intersperse " " (map hex8 bytes))) 30
714
715 enlarge s i = s ++ take (i - length s) (repeat ' ')
716
717 opSizeSuffix OPNONE = ""
718 opSizeSuffix OP8 = "b"
719 opSizeSuffix OP16 = "w"
720 opSizeSuffix OP32 = "l"
721 opSizeSuffix OP64 = "q"
722 opSizeSuffix OP128 = "dq"
723 opSizeSuffix OPF32 = "s"
724 opSizeSuffix OPF64 = "l"
725 opSizeSuffix OPF80 = "t"
726
727 showInstrSuffix [] sz = opSizeSuffix sz
728 showInstrSuffix ((OpImm _) : os) s = showInstrSuffix os s
729 --showInstrSuffix ((OpReg _ _) : []) s = ""
730 showInstrSuffix ((OpReg _ _) : os) s = showInstrSuffix os OPNONE
731 showInstrSuffix ((OpFPReg _) : os) s = showInstrSuffix os s
732 showInstrSuffix ((OpAddr _ OPNONE) : os) s = showInstrSuffix os s
733 showInstrSuffix ((OpAddr _ sz) : os) s = opSizeSuffix sz
734 showInstrSuffix ((OpInd _ OPNONE) : os) s = showInstrSuffix os s
735 showInstrSuffix ((OpInd _ sz) : os) s = opSizeSuffix sz
736 showInstrSuffix ((OpIndDisp _ _ OPNONE) : os) s = showInstrSuffix os s
737 showInstrSuffix ((OpIndDisp _ _ sz) : os) s = opSizeSuffix sz
738 showInstrSuffix ((OpBaseIndex _ _ _ OPNONE) : os) s = showInstrSuffix os s
739 showInstrSuffix ((OpBaseIndex _ _ _ sz) : os) s = opSizeSuffix sz
740 showInstrSuffix ((OpIndexDisp _ _ _ OPNONE) : os) s = showInstrSuffix os s
741 showInstrSuffix ((OpIndexDisp _ _ _ sz) : os) s = opSizeSuffix sz
742 showInstrSuffix ((OpBaseIndexDisp _ _ _ _ OPNONE) : os) s = showInstrSuffix os s
743 showInstrSuffix ((OpBaseIndexDisp _ _ _ _ sz) : os) s = opSizeSuffix sz
744
745 -- showInstrOperandSize ops OPNONE | noRegop ops = ""
746 -- showInstrOperandSize ops OP8 | noRegop ops = "b"
747 -- showInstrOperandSize ops OP16 | noRegop ops = "w"
748 -- showInstrOperandSize ops OP32 | noRegop ops = "l"
749 -- showInstrOperandSize ops OPF32 | noRegop ops = "s"
750 -- showInstrOperandSize ops OP64 | noRegop ops = "q"
751 -- showInstrOperandSize ops OPF64 | noRegop ops = "l"
752 -- showInstrOperandSize ops OPF80 | noRegop ops = "e"
753 -- showInstrOperandSize ops OP128 | noRegop ops = ""
754 -- showInstrOperandSize _ _ = ""
755
756 -- noRegop ops = null (filter isRegop ops)
757 -- isRegop (OpReg _ _) = True
758 -- isRegop _ = False
759
760 -- Show an immediate value in hexadecimal.
761
762 showImm :: Word32 -> String
763 showImm i =
764   "$0x" ++ showHex i ""
765
766 showIntelImm :: Word32 -> String
767 showIntelImm i =
768   let h = showHex i "H"
769       (f:_) = h
770   in (if isDigit f then "" else "0") ++ h
771
772 -- Show an address in hexadecimal.
773
774 showAddr i =  
775   let w :: Word32
776       w = fromIntegral i
777   in "0x" ++ showHex w ""
778 showIntelAddr i = 
779   let w :: Word32
780       w = fromIntegral i
781       h = showHex w "H"
782       (f:_) = h
783   in (if isDigit f then "" else "0") ++ h
784
785 -- | Disassemble a block of memory.  Starting at the location
786 -- pointed to by the given pointer, the given number of bytes are
787 -- disassembled.
788
789 disassembleBlock :: Ptr Word8 -> Int -> IO (Either ParseError [Instruction])
790 disassembleBlock ptr len = 
791     disassembleBlockWithConfig defaultConfig{confStartAddr = fromIntegral (minusPtr ptr nullPtr)} 
792                                ptr len
793
794 disassembleBlockWithConfig :: Config -> Ptr Word8 -> Int -> IO (Either ParseError [Instruction])
795 disassembleBlockWithConfig config ptr len = do
796   l <- toList ptr len 0 []
797   parseInstructions (configToState config) (reverse l)
798   where 
799   toList :: (Ptr Word8) -> Int -> Int -> [Word8] -> IO [Word8]
800   toList ptr len idx acc | idx < len =
801            do p <- peekByteOff ptr idx
802               toList ptr len (idx + 1) (p : acc)
803 --                    return (p : r)
804   toList ptr len idx acc | idx >= len = return acc
805
806 -- | Disassemble the contents of the given array.
807
808 disassembleArray :: (Monad m, IArray a Word8, Ix i) =>
809                     a i Word8 -> m (Either ParseError [Instruction])
810 disassembleArray arr = disassembleArrayWithConfig defaultConfig arr
811
812 disassembleArrayWithConfig :: (Monad m, IArray a Word8, Ix i) => Config ->
813                              a i Word8 -> m (Either ParseError [Instruction])
814 disassembleArrayWithConfig config arr =
815   let l = elems arr
816   in parseInstructions (configToState config) l
817
818 -- | Disassemble the contents of the given list.
819
820 disassembleList :: (Monad m) =>
821                    [Word8] -> m (Either ParseError [Instruction])
822 disassembleList ls = disassembleListWithConfig defaultConfig ls
823
824 disassembleListWithConfig :: (Monad m) => Config ->
825                    [Word8] -> m (Either ParseError [Instruction])
826 disassembleListWithConfig config ls =
827     parseInstructions (configToState config) ls
828
829 disassembleFile filename = disassembleFileWithConfig defaultConfig filename
830
831 disassembleFileWithConfig config filename = do
832   l <- readFile filename
833   parseInstructions (configToState config) (map (fromIntegral . ord) l)
834
835 instrToString insts style =
836   map showInstr insts
837  where
838  showInstr = case style of
839           IntelStyle -> showIntel
840           AttStyle -> showAtt
841
842 -- | Test function for disassembling the contents of a binary file and
843 -- displaying it in the provided style ("IntelStyle" or "AttStyle").
844
845 testFile :: FilePath -> ShowStyle -> IO ()
846 testFile fname style = do
847   l <- readFile fname
848   i <- parseInstructions defaultState (map (fromIntegral . ord) l)
849   case i of
850     Left err -> putStrLn (show err)
851     Right i' -> mapM_ (putStrLn . showInstr) i'
852  where
853  showInstr = case style of
854           IntelStyle -> showIntel
855           AttStyle -> showAtt
856
857 -- This is the state maintained by the disassembler.
858
859 data PState = PState { defaultBitMode :: OperandSize,
860                        operandBitMode :: OperandSize,
861                        addressBitMode :: OperandSize,
862                        in64BitMode :: Bool,
863                        prefixes :: [Word8],
864                        startAddr :: Word32
865                       }
866
867 data Config = Config {confDefaultBitMode :: OperandSize,
868                       confOperandBitMode :: OperandSize,
869                       confAddressBitMode :: OperandSize,
870                       confIn64BitMode        :: Bool,
871                       confStartAddr          :: Word32}
872
873 defaultConfig = Config{ confDefaultBitMode = BIT32,
874                         confOperandBitMode = BIT32, 
875                         confAddressBitMode = BIT32, 
876                         confIn64BitMode = False,
877                         confStartAddr = 0}
878
879 configToState (Config defBitMode opMode addrMode in64 confStartAddr) =
880     defaultState{defaultBitMode = defBitMode,
881                  operandBitMode = opMode,
882                  addressBitMode = addrMode,
883                  in64BitMode = in64,
884                  startAddr = confStartAddr}
885            
886 -- Default state to be used if no other is given to the disassembly
887 -- routines.
888
889 defaultState = PState { defaultBitMode = BIT32,
890                   operandBitMode = BIT32, 
891                   addressBitMode = BIT32, 
892                   in64BitMode = False,
893                   prefixes = [],
894                   startAddr = 0}
895
896 type Word8Parser a = GenParser Word8 PState a
897
898 parseInstructions st l =
899     return (runParser instructionSequence st "memory block" l)
900
901 -- Parse a possibly empty sequence of instructions.
902
903 instructionSequence = many instruction
904
905 -- Parse a single instruction.  The result is either a valid instruction
906 -- or an indicator that there starts no valid instruction at the current
907 -- position.
908
909 instruction = do
910     startPos' <- getPosition
911     let startPos = sourceColumn startPos' - 1
912     input <- getInput
913     st <- getState
914     setState st{operandBitMode = defaultBitMode st,
915                  addressBitMode = defaultBitMode st,
916                prefixes = []}
917     many parsePrefix
918     b <- anyWord8
919     case lookup b oneByteOpCodeMap of
920       Just p -> do i <- p b
921                    endPos' <- getPosition
922                    let endPos = sourceColumn endPos' - 1
923                    case i of
924                      Instr oc opsize ops -> do
925                        return $ Instruction oc opsize ops
926                             (fromIntegral (startAddr st) + startPos)
927                             (take (endPos - startPos) input)
928                      Bad b desc ->
929                        return $ BadInstruction b desc 
930                             (fromIntegral (startAddr st) + startPos)
931                             (take (endPos - startPos) input)
932       Nothing -> do Bad b desc <- parseInvalidOpcode b
933                     endPos' <- getPosition
934                     let endPos = sourceColumn endPos' - 1
935                     return $ BadInstruction b desc 
936                         (fromIntegral (startAddr st) + startPos)
937                         (take (endPos - startPos) input)
938
939 toggleBitMode BIT16 = BIT32
940 toggleBitMode BIT32 = BIT16
941
942 rex_B = 0x1
943 rex_X = 0x2
944 rex_R = 0x4
945 rex_W = 0x8
946
947 -- Return True if the given REX prefix bit appears in the list of current
948 -- instruction prefixes, False otherwise.
949
950 hasREX rex st =
951     let rexs = filter (\ b -> b >= 0x40 && b <= 0x4f) (prefixes st) in
952        case rexs of
953          (r : _) -> if r .&. rex == rex then True else False
954          _ -> False
955
956 -- Return True if the given prefix appears in the list of current
957 -- instruction prefixes, False otherwise.
958
959 hasPrefix b st = b `elem` prefixes st
960
961 addPrefix b = do
962     st <- getState
963     setState st{prefixes = b : prefixes st}
964
965 -- Parse a single prefix byte and remember it in the parser state.  If in
966 -- 64-bit mode, accept REX prefixes.
967
968 parsePrefix = do
969     (word8 0xf0 >>= addPrefix) -- LOCK
970   <|>
971     (word8 0xf2 >>= addPrefix) -- REPNE/REPNZ
972   <|>
973     (word8 0xf3 >>= addPrefix) -- REP or REPE/REPZ
974   <|>
975     (word8 0x2e >>= addPrefix) -- CS segment override
976   <|>
977     (word8 0x36 >>= addPrefix) -- SS segment override
978   <|>
979     (word8 0x3e >>= addPrefix) -- DS segment override
980   <|>
981     (word8 0x26 >>= addPrefix) -- ES segment override
982   <|>
983     (word8 0x64 >>= addPrefix) -- FS segment override
984   <|>
985     (word8 0x65 >>= addPrefix) -- GS segment override
986   <|>
987     (word8 0x2e >>= addPrefix) -- branch not taken
988   <|>
989     (word8 0x3e >>= addPrefix) -- branch taken
990   <|>
991     do word8 0x66 -- operand-size override
992        st <- getState
993        setState st{operandBitMode = toggleBitMode (operandBitMode st)}
994        addPrefix 0x66
995   <|>
996     do word8 0x67 -- address-size override
997        st <- getState
998        setState st{addressBitMode = toggleBitMode (addressBitMode st)}
999        addPrefix 0x66
1000   <|>  do st <- getState
1001           if in64BitMode st 
1002             then    (word8 0x40 >>= addPrefix)
1003                      <|>
1004                      (word8 0x41 >>= addPrefix)
1005                      <|>
1006                      (word8 0x42 >>= addPrefix)
1007                      <|>
1008                      (word8 0x43 >>= addPrefix)
1009                      <|>
1010                      (word8 0x44 >>= addPrefix)
1011                      <|>
1012                      (word8 0x45 >>= addPrefix)
1013                      <|>
1014                      (word8 0x46 >>= addPrefix)
1015                      <|>
1016                      (word8 0x47 >>= addPrefix)
1017                      <|>
1018                      (word8 0x48 >>= addPrefix)
1019                      <|>
1020                      (word8 0x49 >>= addPrefix)
1021                      <|>
1022                      (word8 0x4a >>= addPrefix)
1023                      <|>
1024                      (word8 0x4b >>= addPrefix)
1025                      <|>
1026                      (word8 0x4c >>= addPrefix)
1027                      <|>
1028                      (word8 0x4d >>= addPrefix)
1029                      <|>
1030                      (word8 0x4e >>= addPrefix)
1031                      <|>
1032                      (word8 0x4f >>= addPrefix)
1033              else pzero
1034
1035 -- Accept the single unsigned byte B.
1036
1037 word8 b = do
1038     tokenPrim showByte nextPos testByte
1039   where
1040   showByte by = show by
1041   nextPos pos x xs = incSourceColumn pos 1
1042   testByte by = if b == by then Just by else Nothing
1043
1044 -- Accept and return a single unsigned byte.
1045
1046 anyWord8 :: Word8Parser Word8
1047 anyWord8 = do
1048     tokenPrim showByte nextPos testByte
1049   where
1050   showByte by = show by
1051   nextPos pos x xs = incSourceColumn pos 1
1052   testByte by =  Just by
1053
1054 -- Accept any 8-bit signed byte.
1055
1056 anyInt8 :: Word8Parser Int8
1057 anyInt8 = do
1058    b <- anyWord8
1059    let i :: Int8
1060        i = fromIntegral b
1061    return i
1062
1063 -- Accept any 16-bit unsigned word.
1064
1065 anyWord16 = do
1066      b0 <- anyWord8
1067      b1 <- anyWord8
1068      let w0, w1 :: Word16
1069          w0 = fromIntegral b0
1070          w1 = fromIntegral b1
1071      return $ w0 .|. (w1 `shiftL` 8)
1072
1073 -- Accept any 16-bit signed integer.
1074
1075 anyInt16 = do
1076      b0 <- anyWord16
1077      let w0 :: Int16
1078          w0 = fromIntegral b0
1079      return $ w0
1080
1081 -- Accept a 32-bit unsigned word.
1082
1083 anyWord32 = do
1084      b0 <- anyWord16
1085      b1 <- anyWord16
1086      let w0, w1 :: Word32
1087          w0 = fromIntegral b0
1088          w1 = fromIntegral b1
1089      return $ w0 .|. (w1 `shiftL` 16)
1090
1091 -- Accept a 32-bit signed integer.
1092
1093 anyInt32 :: Word8Parser Int32
1094 anyInt32 = do
1095      b0 <- anyWord32
1096      let w0 :: Int32
1097          w0 = fromIntegral b0
1098      return $ w0
1099
1100 -- Accept a 64-bit unsigned word.
1101
1102 anyWord64 :: Word8Parser Word64
1103 anyWord64 = do
1104      b0 <- anyWord32
1105      b1 <- anyWord32
1106      let w0, w1 :: Word64
1107          w0 = fromIntegral b0
1108          w1 = fromIntegral b1
1109      return $ w0 .|. (w1 `shiftL` 32)
1110
1111 -- Accept a 64-bit signed integer.
1112
1113 anyInt64 :: Word8Parser Int64
1114 anyInt64 = do
1115      b0 <- anyWord64
1116      let w0 :: Int64
1117          w0 = fromIntegral b0
1118      return $ w0
1119
1120 -- Accept a 16-bit word for 16-bit operand-size, a 32-bit word for
1121 -- 32-bit operand-size, or a 64-bit word in 64-bit mode.
1122
1123 anyWordV :: Word8Parser Word64
1124 anyWordV = do
1125     st <- getState
1126     if in64BitMode st
1127        then do w <- anyWord64
1128                return w
1129         else case operandBitMode st of
1130               BIT16 -> do w <- anyWord16
1131                           let w' :: Word64
1132                               w' = fromIntegral w
1133                           return w'
1134               BIT32 -> do w <- anyWord32
1135                           let w' :: Word64
1136                               w' = fromIntegral w
1137                           return w'
1138
1139 -- Accept a 16-bit word for 16-bit operand-size or a 32-bit word for
1140 -- 32-bit operand-size or 64-bit mode.
1141
1142 anyWordZ :: Word8Parser Word32
1143 anyWordZ = do
1144     st <- getState
1145     case operandBitMode st of
1146       BIT16 -> do 
1147         w <- anyWord16
1148         let w' :: Word32
1149             w' = fromIntegral w
1150         return w'
1151       BIT32 -> anyWord32
1152
1153 -- Accept a 16-bit integer for 16-bit operand-size or a 32-bit word for
1154 -- 32-bit operand-size or 64-bit mode.
1155
1156 anyIntZ :: Word8Parser Int32
1157 anyIntZ = do
1158     st <- getState
1159     case operandBitMode st of
1160       BIT16 -> do 
1161         w <- anyInt16
1162         let w' :: Int32
1163             w' = fromIntegral w
1164         return w'
1165       BIT32 -> anyInt32
1166
1167 -- Accept a 32-bit far address for 16-bit operand-size or a 48-bit far
1168 -- address for 32-bit operand-size.
1169
1170 anyWordP :: Word8Parser Word64
1171 anyWordP = do
1172     st <- getState
1173     case operandBitMode st of
1174       BIT16 -> do w <- anyWord32
1175                   let w' :: Word64
1176                       w' = fromIntegral w
1177                   return w'
1178       _ -> do w1 <- anyWord32
1179               w2 <- anyWord16
1180               let w1', w2' :: Word64
1181                   w1' = fromIntegral w1
1182                   w2' = fromIntegral w2
1183               return (w1' .|. (w2' `shiftL` 32))
1184
1185 oneByteOpCodeMap =
1186     [(0x00, parseALU ADD),
1187      (0x01, parseALU ADD),
1188      (0x02, parseALU ADD),
1189      (0x03, parseALU ADD),
1190      (0x04, parseALU ADD),
1191      (0x05, parseALU ADD),
1192      (0x06, invalidIn64BitMode (parsePUSHSeg "es")),
1193      (0x07, invalidIn64BitMode (parsePOPSeg "es")),
1194      (0x08, parseALU OR),
1195      (0x09, parseALU OR),
1196      (0x0a, parseALU OR),
1197      (0x0b, parseALU OR),
1198      (0x0c, parseALU OR),
1199      (0x0d, parseALU OR),
1200      (0x0e, invalidIn64BitMode (parsePUSHSeg "cs")),
1201      (0x0f, twoByteEscape),
1202
1203      (0x10, parseALU ADC),
1204      (0x11, parseALU ADC),
1205      (0x12, parseALU ADC),
1206      (0x13, parseALU ADC),
1207      (0x14, parseALU ADC),
1208      (0x15, parseALU ADC),
1209      (0x16, invalidIn64BitMode (parsePUSHSeg "ss")),
1210      (0x17, invalidIn64BitMode (parsePOPSeg "ss")),
1211      (0x18, parseALU SBB),
1212      (0x19, parseALU SBB),
1213      (0x1a, parseALU SBB),
1214      (0x1b, parseALU SBB),
1215      (0x1c, parseALU SBB),
1216      (0x1d, parseALU SBB),
1217      (0x1e, invalidIn64BitMode (parsePUSHSeg "ds")),
1218      (0x1f, invalidIn64BitMode (parsePOPSeg "ds")),
1219
1220      (0x20, parseALU AND),
1221      (0x21, parseALU AND),
1222      (0x22, parseALU AND),
1223      (0x23, parseALU AND),
1224      (0x24, parseALU AND),
1225      (0x25, parseALU AND),
1226      (0x26, parseInvalidPrefix), -- ES segment override prefix
1227      (0x27, invalidIn64BitMode (parseGeneric DAA OPNONE)),
1228      (0x28, parseALU SUB),
1229      (0x29, parseALU SUB),
1230      (0x2a, parseALU SUB),
1231      (0x2b, parseALU SUB),
1232      (0x2c, parseALU SUB),
1233      (0x2d, parseALU SUB),
1234      (0x2e, parseInvalidPrefix), -- CS segment override prefix
1235      (0x2f, invalidIn64BitMode (parseGeneric DAS OPNONE)),
1236
1237      (0x30, parseALU XOR),
1238      (0x31, parseALU XOR),
1239      (0x32, parseALU XOR),
1240      (0x33, parseALU XOR),
1241      (0x34, parseALU XOR),
1242      (0x35, parseALU XOR),
1243      (0x36, parseInvalidPrefix), -- SS segment override prefix
1244      (0x37, invalidIn64BitMode (parseGeneric AAA OPNONE)),
1245      (0x38, parseALU CMP),
1246      (0x39, parseALU CMP),
1247      (0x3a, parseALU CMP),
1248      (0x3b, parseALU CMP),
1249      (0x3c, parseALU CMP),
1250      (0x3d, parseALU CMP),
1251      (0x3e, parseInvalidPrefix), -- DS segment override prefix
1252      (0x3f, invalidIn64BitMode (parseGeneric AAS OPNONE)),
1253
1254      (0x40, invalidIn64BitMode parseINC), -- REX Prefix in 64-bit mode
1255      (0x41, invalidIn64BitMode parseINC), -- ...
1256      (0x42, invalidIn64BitMode parseINC),
1257      (0x43, invalidIn64BitMode parseINC),
1258      (0x44, invalidIn64BitMode parseINC),
1259      (0x45, invalidIn64BitMode parseINC),
1260      (0x46, invalidIn64BitMode parseINC),
1261      (0x47, invalidIn64BitMode parseINC),
1262      (0x48, invalidIn64BitMode parseDEC),
1263      (0x49, invalidIn64BitMode parseDEC),
1264      (0x4a, invalidIn64BitMode parseDEC),
1265      (0x4b, invalidIn64BitMode parseDEC),
1266      (0x4c, invalidIn64BitMode parseDEC),
1267      (0x4d, invalidIn64BitMode parseDEC),
1268      (0x4e, invalidIn64BitMode parseDEC),
1269      (0x4f, invalidIn64BitMode parseDEC),
1270
1271      (0x50, parsePUSH),
1272      (0x51, parsePUSH),
1273      (0x52, parsePUSH),
1274      (0x53, parsePUSH),
1275      (0x54, parsePUSH),
1276      (0x55, parsePUSH),
1277      (0x56, parsePUSH),
1278      (0x57, parsePUSH),
1279      (0x58, parsePOP),
1280      (0x59, parsePOP),
1281      (0x5a, parsePOP),
1282      (0x5b, parsePOP),
1283      (0x5c, parsePOP),
1284      (0x5d, parsePOP),
1285      (0x5e, parsePOP),
1286      (0x5f, parsePOP),
1287
1288      (0x60, invalidIn64BitMode parsePUSHA),
1289      (0x61, invalidIn64BitMode parsePOPA),
1290      (0x62, invalidIn64BitMode parseBOUND),
1291      (0x63, choose64BitMode parseARPL parseMOVSXD), -- MOVSXD in 64-bit mode
1292      (0x64, parseInvalidPrefix), -- FS segment override prefix
1293      (0x65, parseInvalidPrefix), -- GS segment override prefix
1294      (0x66, parseInvalidPrefix), -- operand-size prefix
1295      (0x67, parseInvalidPrefix), -- address-size prefix
1296      (0x68, parsePUSHImm),
1297      (0x69, parseIMUL),
1298      (0x6a, parsePUSHImm),
1299      (0x6b, parseIMUL),
1300      (0x6c, parseINS),
1301      (0x6d, parseINS),
1302      (0x6e, parseOUTS),
1303      (0x6f, parseOUTS),
1304
1305      (0x70, parseJccShort),
1306      (0x71, parseJccShort),
1307      (0x72, parseJccShort),
1308      (0x73, parseJccShort),
1309      (0x74, parseJccShort),
1310      (0x75, parseJccShort),
1311      (0x76, parseJccShort),
1312      (0x77, parseJccShort),
1313      (0x78, parseJccShort),
1314      (0x79, parseJccShort),
1315      (0x7a, parseJccShort),
1316      (0x7b, parseJccShort),
1317      (0x7c, parseJccShort),
1318      (0x7d, parseJccShort),
1319      (0x7e, parseJccShort),
1320      (0x7f, parseJccShort),
1321
1322      (0x80, parseGrp1),
1323      (0x81, parseGrp1),
1324      (0x82, invalidIn64BitMode parseGrp1),
1325      (0x83, parseGrp1),
1326      (0x84, parseTEST),
1327      (0x85, parseTEST),
1328      (0x86, parseXCHG),
1329      (0x87, parseXCHG),
1330      (0x88, parseMOV),
1331      (0x89, parseMOV),
1332      (0x8a, parseMOV),
1333      (0x8b, parseMOV),
1334      (0x8c, parseMOV),
1335      (0x8d, parseLEA),
1336      (0x8e, parseMOV),
1337      (0x8f, parseGrp1A),
1338
1339      (0x90, parse0x90), -- NOP, PAUSE(F3), XCHG r8,rAX
1340      (0x91, parseXCHGReg),
1341      (0x92, parseXCHGReg),
1342      (0x93, parseXCHGReg),
1343      (0x94, parseXCHGReg),
1344      (0x95, parseXCHGReg),
1345      (0x96, parseXCHGReg),
1346      (0x97, parseXCHGReg),
1347      (0x98, parseCBW_CWDE_CDQE),
1348      (0x99, parseCWD_CDQ_CQO),
1349      (0x9a, invalidIn64BitMode parseCALLF),
1350      (0x9b, parseGeneric WAIT OPNONE),
1351      (0x9c, parsePUSHF),
1352      (0x9d, parsePOPF),
1353      (0x9e, parseGeneric SAHF OPNONE),
1354      (0x9f, parseGeneric LAHF OPNONE),
1355
1356      (0xa0, parseMOVImm),
1357      (0xa1, parseMOVImm),
1358      (0xa2, parseMOVImm),
1359      (0xa3, parseMOVImm),
1360      (0xa4, parseMOVS),
1361      (0xa5, parseMOVS),
1362      (0xa6, parseCMPS),
1363      (0xa7, parseCMPS),
1364      (0xa8, parseTESTImm),
1365      (0xa9, parseTESTImm),
1366      (0xaa, parseSTOS),
1367      (0xab, parseSTOS),
1368      (0xac, parseLODS),
1369      (0xad, parseLODS),
1370      (0xae, parseSCAS),
1371      (0xaf, parseSCAS),
1372
1373      (0xb0, parseMOVImmByteToByteReg),
1374      (0xb1, parseMOVImmByteToByteReg),
1375      (0xb2, parseMOVImmByteToByteReg),
1376      (0xb3, parseMOVImmByteToByteReg),
1377      (0xb4, parseMOVImmByteToByteReg),
1378      (0xb5, parseMOVImmByteToByteReg),
1379      (0xb6, parseMOVImmByteToByteReg),
1380      (0xb7, parseMOVImmByteToByteReg),
1381      (0xb8, parseMOVImmToReg),
1382      (0xb9, parseMOVImmToReg),
1383      (0xba, parseMOVImmToReg),
1384      (0xbb, parseMOVImmToReg),
1385      (0xbc, parseMOVImmToReg),
1386      (0xbd, parseMOVImmToReg),
1387      (0xbe, parseMOVImmToReg),
1388      (0xbf, parseMOVImmToReg),
1389
1390      (0xc0, parseGrp2),
1391      (0xc1, parseGrp2),
1392      (0xc2, parseRETN),
1393      (0xc3, parseRETN),
1394      (0xc4, invalidIn64BitMode (parseLoadSegmentRegister LES)),
1395      (0xc5, invalidIn64BitMode (parseLoadSegmentRegister LDS)),
1396      (0xc6, parseGrp11),
1397      (0xc7, parseGrp11),
1398      (0xc8, parseENTER),
1399      (0xc9, parseGeneric LEAVE OPNONE),
1400      (0xca, parseGenericIw RETF),
1401      (0xcb, parseGeneric RETF OPNONE),
1402      (0xcc, parseGeneric INT3 OPNONE),
1403      (0xcd, parseGenericIb INT),
1404      (0xce, parseGeneric INTO OPNONE),
1405      (0xcf, parseGeneric IRET OPNONE),
1406
1407      (0xd0, parseGrp2),
1408      (0xd1, parseGrp2),
1409      (0xd2, parseGrp2),
1410      (0xd3, parseGrp2),
1411      (0xd4, parseGenericIb AAM),
1412      (0xd5, parseGenericIb AAD),
1413      (0xd6, parseReserved), -- reserved
1414      (0xd7, parseGeneric XLAT OPNONE),
1415      (0xd8, parseESC),
1416      (0xd9, parseESC),
1417      (0xda, parseESC),
1418      (0xdb, parseESC),
1419      (0xdc, parseESC),
1420      (0xdd, parseESC),
1421      (0xde, parseESC),
1422      (0xdf, parseESC),
1423
1424      (0xe0, parseGenericJb LOOPNE),
1425      (0xe1, parseGenericJb LOOPE),
1426      (0xe2, parseGenericJb LOOP),
1427      (0xe3, parseGenericJb JCXZ), -- depends on bit mode
1428      (0xe4, parseINImm),
1429      (0xe5, parseINImm),
1430      (0xe6, parseOUTImm),
1431      (0xe7, parseOUTImm),
1432      (0xe8, parseGenericJz CALL),
1433      (0xe9, parseGenericJz JMP),
1434      (0xea, parseJMPF),
1435      (0xeb, parseGenericJb JMP),
1436      (0xec, parseIN),
1437      (0xed, parseIN),
1438      (0xee, parseOUT),
1439      (0xef, parseOUT),
1440
1441      (0xf0, parseInvalidPrefix), -- LOCK prefix
1442      (0xf1, parseReserved), -- reserved
1443      (0xf2, parseInvalidPrefix), -- REPNE prefix
1444      (0xf3, parseInvalidPrefix), -- REP/REPQ prefix
1445      (0xf4, parseGeneric HLT OPNONE),
1446      (0xf5, parseGeneric CMC OPNONE),
1447      (0xf6, parseGrp3),
1448      (0xf7, parseGrp3),
1449      (0xf8, parseGeneric CLC OPNONE),
1450      (0xf9, parseGeneric STC OPNONE),
1451      (0xfa, parseGeneric CLI OPNONE),
1452      (0xfb, parseGeneric STI OPNONE),
1453      (0xfc, parseGeneric CLD OPNONE),
1454      (0xfd, parseGeneric STD OPNONE),
1455      (0xfe, parseGrp4),
1456      (0xff, parseGrp5)
1457
1458      ]
1459
1460 parseInvalidPrefix b = do
1461   return $ Bad b "invalid prefix"
1462
1463 parseInvalidOpcode b = do
1464   return $ Bad b "invalid opcode"
1465
1466 parseReserved b = do
1467   return $ Bad b "reserved opcode"
1468
1469 parseUndefined name b = do
1470   return $ Bad b ("undefined opcode: " ++ show name)
1471
1472 parseUnimplemented b = do
1473   return $ Bad b "not implemented yet"
1474
1475 invalidIn64BitMode p b = do
1476   st <- getState
1477   if in64BitMode st
1478      then return $ Bad b "invalid in 64-bit mode"
1479      else p b
1480
1481 onlyIn64BitMode p b = do
1482   st <- getState
1483   if in64BitMode st
1484      then p b
1485      else return $ Bad b "only in 64-bit mode"
1486
1487 choose64BitMode p32 p64 b = do
1488   st <- getState
1489   if in64BitMode st
1490      then p64 b
1491      else p32 b
1492
1493 chooseOperandSize p16 p32 b = do
1494   st <- getState
1495   case operandBitMode st of
1496     BIT16 -> p16 b
1497     BIT32 -> p32 b
1498
1499 chooseAddressSize p16 p32 b = do
1500   st <- getState
1501   case addressBitMode st of
1502     BIT16 -> p16 b
1503     BIT32 -> p32 b
1504
1505 parseModRM = do
1506   b <- anyWord8
1507   parseModRM' b
1508 parseModRM' b = do
1509   return (b `shiftR` 6, (b `shiftR` 3) .&. 7, (b .&. 7))
1510
1511 parseSIB = do
1512   b <- anyWord8
1513   parseSIB' b
1514 parseSIB' b = do
1515   return (b `shiftR` 6, (b `shiftR` 3) .&. 7, (b .&. 7))
1516
1517 scaleToFactor 0 = 1
1518 scaleToFactor 1 = 2
1519 scaleToFactor 2 = 4
1520 scaleToFactor 3 = 8
1521
1522
1523 parseAddress32 :: InstrOperandSize ->
1524                   Word8Parser (Operand, Operand, Word8, Word8, Word8)
1525 parseAddress32 s = do
1526   b <- anyWord8
1527   parseAddress32' s b
1528
1529 parseAddress32' :: InstrOperandSize -> 
1530     Word8 ->
1531     Word8Parser (Operand, Operand, Word8, Word8, Word8)
1532 parseAddress32' opsize modrm = do
1533   (mod, reg_opc, rm) <- parseModRM' modrm
1534   st <- getState
1535   let opregnames = if in64BitMode st && hasREX rex_W st
1536                      then regnames64
1537               else case operandBitMode st of 
1538                         BIT16 -> regnames16
1539                         BIT32 -> regnames32
1540   let addregnames = if in64BitMode st && hasREX rex_R st
1541                       then regnames64
1542                else case addressBitMode st of 
1543                         BIT16 -> regnames16
1544                         BIT32 -> regnames32
1545   case mod of
1546     0 -> case rm of
1547             4 -> do 
1548              (s, i, b) <- parseSIB
1549              case (i, b) of
1550                (4, 5) -> do
1551                            disp <- anyWord32
1552                            return (OpAddr (fromIntegral disp) opsize,
1553                                           OpReg (opregnames !! fromIntegral reg_opc)
1554                                                 (fromIntegral reg_opc),
1555                                           mod, reg_opc, rm)
1556                (_, 5) -> do
1557                            disp <- anyWord32
1558                            return (OpIndexDisp (addregnames !! fromIntegral i)
1559                                                (scaleToFactor s)
1560                                                (fromIntegral disp)
1561                                                opsize,
1562                                    OpReg (opregnames !! fromIntegral reg_opc)
1563                                          (fromIntegral reg_opc),
1564                                    mod, reg_opc, rm)
1565                (4, _) -> return (OpInd (addregnames !! fromIntegral b) opsize,
1566                            OpReg (opregnames !! fromIntegral reg_opc)
1567                              (fromIntegral reg_opc),
1568                            mod, reg_opc, rm)
1569                (_ ,_) -> return (OpBaseIndex 
1570                               (addregnames !! fromIntegral b)
1571                               (addregnames !! fromIntegral i)
1572                               (scaleToFactor (fromIntegral s))
1573                               opsize,
1574                             OpReg (opregnames !! fromIntegral reg_opc)
1575                               (fromIntegral reg_opc),
1576                             mod, reg_opc, rm)
1577             5 -> do 
1578              disp <- anyWord32
1579              return (OpAddr disp opsize, 
1580                      OpReg (opregnames !! fromIntegral reg_opc)
1581                        (fromIntegral reg_opc),
1582                      mod, reg_opc, rm)
1583             _ -> return (OpInd (addregnames !! fromIntegral rm) opsize, 
1584                   OpReg (opregnames !! fromIntegral reg_opc)
1585                         (fromIntegral reg_opc),
1586                   mod, reg_opc, rm)
1587     1 -> case rm of
1588             4 -> do 
1589              (s, i, b) <- parseSIB
1590              disp <- anyInt8
1591              case i of
1592                4 -> return (OpIndDisp
1593                             (addregnames !! fromIntegral b) 
1594                             (fromIntegral disp) opsize,
1595                             OpReg (opregnames !! fromIntegral reg_opc)
1596                               (fromIntegral reg_opc),
1597                             mod, reg_opc, rm)
1598                _ -> return (OpBaseIndexDisp
1599                             (addregnames !! fromIntegral b)
1600                             (addregnames !! fromIntegral i)
1601                             (scaleToFactor (fromIntegral s))
1602                             (fromIntegral disp)
1603                             opsize,
1604                             OpReg (opregnames !! fromIntegral reg_opc)
1605                               (fromIntegral reg_opc),
1606                             mod, reg_opc, rm)
1607             _ -> do disp <- anyInt8
1608                     return (OpIndDisp
1609                             (addregnames !! fromIntegral rm) 
1610                             (fromIntegral disp)
1611                             opsize,
1612                             OpReg (opregnames !! fromIntegral reg_opc)
1613                               (fromIntegral reg_opc),
1614                             mod, reg_opc, rm)
1615     2 -> case rm of
1616             4 -> do 
1617              (s, i, b) <- parseSIB
1618              disp <- anyInt32
1619              case i of
1620                4 -> return (OpIndDisp
1621                             (addregnames !! fromIntegral b)
1622                             (fromIntegral disp)
1623                             opsize,
1624                             OpReg (opregnames !! fromIntegral reg_opc)
1625                               (fromIntegral reg_opc),
1626                             mod, reg_opc, rm)
1627                _ -> return (OpBaseIndexDisp
1628                             (addregnames !! fromIntegral b)
1629                             (addregnames !! fromIntegral i)
1630                             (scaleToFactor (fromIntegral s))
1631                             (fromIntegral disp)
1632                             opsize,
1633                             OpReg (opregnames !! fromIntegral reg_opc)
1634                               (fromIntegral reg_opc),
1635                             mod, reg_opc, rm)
1636             _ -> do 
1637              disp <- anyInt32
1638              return (OpIndDisp
1639                      (addregnames !! fromIntegral rm)
1640                      (fromIntegral disp)
1641                      opsize,
1642                      OpReg (opregnames !! fromIntegral reg_opc)
1643                        (fromIntegral reg_opc),
1644                      mod, reg_opc, rm)
1645     3 -> return (OpReg (opregnames !! fromIntegral rm)
1646                    (fromIntegral rm),
1647                   OpReg (opregnames !! fromIntegral reg_opc)
1648                     (fromIntegral reg_opc),
1649                  mod, reg_opc, rm)
1650
1651 parseALU :: Opcode -> Word8 -> Word8Parser Instr
1652 parseALU op b = do
1653     opsize <- instrOperandSize
1654     case b .&. 0x07 of
1655       0 -> do (op1, op2, mod, reg, rm) <- parseAddress32 opsize
1656               return $ Instr op OP8 [op1,
1657                    (OpReg (regnames8 !! fromIntegral reg)) (fromIntegral reg)]
1658       1 -> do (op1, op2, mod, reg, rm) <- parseAddress32 opsize
1659               return $ Instr op opsize [op1, op2]
1660       2 -> do (op1, op2, mod, reg, rm) <- parseAddress32 opsize
1661               return $ Instr op OP8 
1662                    [(OpReg (regnames8 !! fromIntegral reg))
1663                        (fromIntegral reg), op1]
1664       3 -> do (op1, op2, mod, reg, rm) <- parseAddress32 opsize
1665               return $ Instr op opsize [op2, op1]
1666       4 -> do b <- anyWord8
1667               return $ Instr op OP8 [(OpReg "al" 0), (OpImm (fromIntegral b))]
1668       5 -> do b <- anyWordZ
1669               rn <- registerName 0
1670               return $ Instr op opsize [(OpReg rn 0), (OpImm b)]
1671       _ -> return $ Bad b "no ALU opcode (internal error)"
1672     
1673
1674 parsePUSHSeg :: String -> Word8 -> Word8Parser Instr
1675 parsePUSHSeg r _ = do
1676      return $ Instr PUSH OP16 [(OpReg r 0)] -- FIXME: register number
1677
1678 parsePOPSeg :: String -> Word8 -> Word8Parser Instr
1679 parsePOPSeg r _ = do
1680      return $ Instr POP OP16 [(OpReg r 0)] -- FIXME: register number
1681
1682 parseGenericGvEw name b = do
1683   (op1, op2, mod, reg, rm) <- parseAddress32 OP16
1684   case op1 of
1685     OpReg _ num -> return $ Instr name OP16 [op2, 
1686                                                OpReg (regnames16 !! num) num]
1687     _ -> return $ Instr name OP8 [op2, op1]
1688
1689 parseGenericGvEb name b = do
1690   (op1, op2, mod, reg, rm) <- parseAddress32 OP8
1691   case op1 of
1692     OpReg _ num -> return $ Instr name OP8 [op2, 
1693                                                OpReg (regnames8 !! num) num]
1694     _ -> return $ Instr name OP8 [op2, op1]
1695
1696 parseGenericGvEv name b = do
1697   opsize <- instrOperandSize
1698   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
1699   return $ Instr name opsize [op2, op1]
1700
1701 parseGenericEvGv name b = do
1702   opsize <- instrOperandSize
1703   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
1704   return $ Instr name opsize [op1, op2]
1705
1706 parseGenericEbGb name b = do
1707   (op1, op2, mod, reg, rm) <- parseAddress32 OP8
1708   return $ Instr name OP8 [op1, (OpReg (regnames8 !! fromIntegral reg)
1709                                 (fromIntegral reg))]
1710
1711 parseGenericEv name b = do
1712   opsize <- instrOperandSize
1713   (op1, op2, mod, _, rm) <- parseAddress32 opsize
1714   return $ Instr name opsize [op1]
1715
1716 twoByteOpCodeMap = 
1717     [(0x00, parseGrp6),
1718      (0x01, parseGrp7),
1719      (0x02, parseGenericGvEw LAR),
1720      (0x03, parseGenericGvEw LSL),
1721      (0x04, parseReserved),
1722      (0x05, onlyIn64BitMode (parseGeneric SYSCALL OPNONE)),
1723      (0x06, parseGeneric CLTS OPNONE),
1724      (0x07, onlyIn64BitMode (parseGeneric SYSCALL OPNONE)),
1725      (0x08, parseGeneric INVD OPNONE),
1726      (0x09, parseGeneric WBINVD OPNONE),
1727      (0x0a, parseReserved),
1728      (0x0b, parseUndefined UD2),
1729      (0x0c, parseReserved),
1730      (0x0d, parseGenericEv NOP),
1731      (0x0e, parseReserved),
1732      (0x0f, parseReserved),
1733
1734      (0x10, parseMOVUPS),
1735      (0x11, parseMOVUPS),
1736      (0x12, parseMOVLPS),
1737      (0x13, parseMOVLPS),
1738      (0x14, parseUNPCKLPS),
1739      (0x15, parseUNPCKHPS),
1740      (0x16, parseMOVHPS),
1741      (0x17, parseMOVHPS),
1742      (0x18, parseGrp16),
1743      (0x19, parseReserved),
1744      (0x1a, parseReserved),
1745      (0x1b, parseReserved),
1746      (0x1c, parseReserved),
1747      (0x1d, parseReserved),
1748      (0x1e, parseReserved),
1749      (0x1f, parseGenericEv NOP),
1750
1751      (0x20, parseMOVCtrlDebug),
1752      (0x21, parseMOVCtrlDebug),
1753      (0x22, parseMOVCtrlDebug),
1754      (0x23, parseMOVCtrlDebug),
1755      (0x24, parseReserved),
1756      (0x25, parseReserved),
1757      (0x26, parseReserved),
1758      (0x27, parseReserved),
1759      (0x28, parseMOVAPS),
1760      (0x29, parseMOVAPS),
1761      (0x2a, parseCVTI2PS),
1762      (0x2b, parseMOVNTPS),
1763      (0x2c, parseCVTTPS2PI),
1764      (0x2d, parseCVTPS2PI),
1765      (0x2e, parseUCOMISS),
1766      (0x2f, parseCOMISS),
1767
1768      (0x30, parseGeneric WRMSR OPNONE),
1769      (0x31, parseGeneric RDTSC OPNONE),
1770      (0x32, parseGeneric RDMSR OPNONE),
1771      (0x33, parseGeneric RDPMC OPNONE),
1772      (0x34, parseGeneric SYSENTER OPNONE),
1773      (0x35, parseGeneric SYSEXIT OPNONE),
1774      (0x36, parseReserved),
1775      (0x37, parseReserved),
1776      (0x38, parseReserved),
1777      (0x39, parseReserved),
1778      (0x3a, parseReserved),
1779      (0x3b, parseReserved),
1780      (0x3c, parseReserved),
1781      (0x3d, parseReserved),
1782      (0x3e, parseReserved),
1783      (0x3f, parseReserved),
1784
1785      (0x40, parseCMOVcc),
1786      (0x41, parseCMOVcc),
1787      (0x42, parseCMOVcc),
1788      (0x43, parseCMOVcc),
1789      (0x44, parseCMOVcc),
1790      (0x45, parseCMOVcc),
1791      (0x46, parseCMOVcc),
1792      (0x47, parseCMOVcc),
1793      (0x48, parseCMOVcc),
1794      (0x49, parseCMOVcc),
1795      (0x4a, parseCMOVcc),
1796      (0x4b, parseCMOVcc),
1797      (0x4c, parseCMOVcc),
1798      (0x4d, parseCMOVcc),
1799      (0x4e, parseCMOVcc),
1800      (0x4f, parseCMOVcc),
1801
1802      (0x50, parseMOVSKPS),
1803      (0x51, parseSQRTPS),
1804      (0x52, parseRSQRTPS),
1805      (0x53, parseRCPPS),
1806      (0x54, parseANDPS),
1807      (0x55, parseANDNPS),
1808      (0x56, parseORPS),
1809      (0x57, parseXORPS),
1810      (0x58, parseADDPS),
1811      (0x59, parseMULPS),
1812      (0x5a, parseCVTPS2PD),
1813      (0x5b, parseCVTDQ2PS),
1814      (0x5c, parseSUBPS),
1815      (0x5d, parseMINPS),
1816      (0x5e, parseDIVPS),
1817      (0x5f, parseMAXPS),
1818
1819      (0x60, parsePUNPCKLBW),
1820      (0x61, parsePUNPCKLWD),
1821      (0x62, parsePUNPCKLDQ),
1822      (0x63, parsePACKSSWB),
1823      (0x64, parsePCMPGTB),
1824      (0x65, parsePCMPGTW),
1825      (0x66, parsePCMPGTD),
1826      (0x67, parsePACKUSWB),
1827      (0x68, parsePUNPCKHBW),
1828      (0x69, parsePUNPCKHWD),
1829      (0x6a, parsePUNPCKHDQ),
1830      (0x6b, parsePACKSSDW),
1831      (0x6c, parsePUNPCKLQDQ),
1832      (0x6d, parsePUNPCKHQDQ),
1833      (0x6e, parseMOVD_Q),
1834      (0x6f, parseMOVQ),
1835
1836      (0x70, parsePSHUFW),
1837      (0x71, parseGrp12),
1838      (0x72, parseGrp13),
1839      (0x73, parseGrp14),
1840      (0x74, parsePCMPEQB),
1841      (0x75, parsePCMPEQW),
1842      (0x76, parsePCMPEQD),
1843      (0x77, parseGeneric EMMS OPNONE),
1844      (0x78, parseVMREAD),
1845      (0x79, parseVMWRITE),
1846      (0x7a, parseReserved),
1847      (0x7b, parseReserved),
1848      (0x7c, parseHADDPS),
1849      (0x7d, parseHSUBPS),
1850      (0x7e, parseMOVD_Q),
1851      (0x7f, parseMOVQ),
1852
1853      (0x80, parseJccLong),
1854      (0x81, parseJccLong),
1855      (0x82, parseJccLong),
1856      (0x83, parseJccLong),
1857      (0x84, parseJccLong),
1858      (0x85, parseJccLong),
1859      (0x86, parseJccLong),
1860      (0x87, parseJccLong),
1861      (0x88, parseJccLong),
1862      (0x89, parseJccLong),
1863      (0x8a, parseJccLong),
1864      (0x8b, parseJccLong),
1865      (0x8c, parseJccLong),
1866      (0x8d, parseJccLong),
1867      (0x8e, parseJccLong),
1868      (0x8f, parseJccLong),
1869
1870      (0x90, parseSETcc),
1871      (0x91, parseSETcc),
1872      (0x92, parseSETcc),
1873      (0x93, parseSETcc),
1874      (0x94, parseSETcc),
1875      (0x95, parseSETcc),
1876      (0x96, parseSETcc),
1877      (0x97, parseSETcc),
1878      (0x98, parseSETcc),
1879      (0x99, parseSETcc),
1880      (0x9a, parseSETcc),
1881      (0x9b, parseSETcc),
1882      (0x9c, parseSETcc),
1883      (0x9d, parseSETcc),
1884      (0x9e, parseSETcc),
1885      (0x9f, parseSETcc),
1886
1887      (0xa0, parsePUSHSeg "fs"),
1888      (0xa1, parsePOPSeg "fs"),
1889      (0xa2, parseGeneric CPUID OPNONE),
1890      (0xa3, parseGenericEvGv BT),
1891      (0xa4, parseSHLD),
1892      (0xa5, parseSHLD),
1893      (0xa6, parseReserved),
1894      (0xa7, parseReserved),
1895      (0xa8, parsePUSHSeg "gs"),
1896      (0xa9, parsePOPSeg "gs"),
1897      (0xaa, parseGeneric RSM OPNONE),
1898      (0xab, parseGenericEvGv BTS),
1899      (0xac, parseSHRD),
1900      (0xad, parseSHRD),
1901      (0xae, parseGrp15),
1902      (0xaf, parseGenericGvEv IMUL),
1903
1904      (0xb0, parseGenericEbGb CMPXCHG),
1905      (0xb1, parseGenericEvGv CMPXCHG),
1906      (0xb2, parseLoadSegmentRegister LSS),
1907      (0xb3, parseGenericEvGv BTR),
1908      (0xb4, parseLoadSegmentRegister LFS),
1909      (0xb5, parseLoadSegmentRegister LGS),
1910      (0xb6, parseGenericGvEb MOVZXB),
1911      (0xb7, parseGenericGvEw MOVZXW),
1912      (0xb8, parseReserved),
1913      (0xb9, parseGrp10),
1914      (0xba, parseGrp8),
1915      (0xbb, parseGenericEvGv BTC),
1916      (0xbc, parseGenericGvEv BSF),
1917      (0xbd, parseGenericGvEv BSR),
1918      (0xbe, parseGenericGvEb MOVSXB),
1919      (0xbf, parseGenericGvEw MOVSXW),
1920
1921      (0xc0, parseGenericEbGb XADD),
1922      (0xc1, parseGenericEvGv XADD),
1923      (0xc2, parseCMPPS),
1924      (0xc3, parseMOVNTI),
1925      (0xc4, parsePINSRW),
1926      (0xc5, parsePEXTRW),
1927      (0xc6, parseSHUFPS),
1928      (0xc7, parseGrp9),
1929      (0xc8, parseBSWAP),
1930      (0xc9, parseBSWAP),
1931      (0xca, parseBSWAP),
1932      (0xcb, parseBSWAP),
1933      (0xcc, parseBSWAP),
1934      (0xcd, parseBSWAP),
1935      (0xce, parseBSWAP),
1936      (0xcf, parseBSWAP),
1937
1938      (0xd0, parseADDSUBPS),
1939      (0xd1, parsePSRLW),
1940      (0xd2, parsePSRLD),
1941      (0xd3, parsePSRLQ),
1942      (0xd4, parsePADDQ),
1943      (0xd5, parsePMULLW),
1944      (0xd6, parseMOVQ),
1945      (0xd7, parsePMOVMSKB),
1946      (0xd8, parsePSUBUSB),
1947      (0xd9, parsePSUBUSW),
1948      (0xda, parsePMINUB),
1949      (0xdb, parsePAND),
1950      (0xdc, parsePADDUSB),
1951      (0xdd, parsePADDUSW),
1952      (0xde, parsePMAXUB),
1953      (0xdf, parsePANDN),
1954
1955      (0xe0, parsePAVGB),
1956      (0xe1, parsePSRAW),
1957      (0xe2, parsePSRAD),
1958      (0xe3, parsePAVGW),
1959      (0xe4, parsePMULHUW),
1960      (0xe5, parsePMULHW),
1961      (0xe6, parseCVTPD2DQ),
1962      (0xe7, parseMOVNTQ),
1963      (0xe8, parsePSUBSB),
1964      (0xe9, parsePSUBSQ),
1965      (0xea, parsePMINSW),
1966      (0xeb, parsePOR),
1967      (0xec, parsePADDSB),
1968      (0xed, parsePADDSW),
1969      (0xee, parsePMAXSW),
1970      (0xef, parsePXOR),
1971
1972      (0xf0, parseLDDQU),
1973      (0xf1, parsePSLLW),
1974      (0xf2, parsePSLLD),
1975      (0xf3, parsePSLLQ),
1976      (0xf4, parsePMULUDQ),
1977      (0xf5, parsePMADDWD),
1978      (0xf6, parsePSADBW),
1979      (0xf7, parseMASKMOVQ),
1980      (0xf8, parsePSUBB),
1981      (0xf9, parsePSUBW),
1982      (0xfa, parsePSUBD),
1983      (0xfb, parsePSUBQ),
1984      (0xfc, parsePADDB),
1985      (0xfd, parsePADDW),
1986      (0xfe, parsePADDD),
1987      (0xff, parseReserved)
1988      ]
1989
1990 twoByteEscape :: Word8 -> Word8Parser Instr
1991 twoByteEscape b1 = do
1992   b <- anyWord8
1993   case lookup b twoByteOpCodeMap of
1994     Just p -> p b
1995     Nothing -> return $ Bad b "invalid two-byte opcode"
1996
1997 parseGeneric name opsize _ = do
1998     return (Instr name opsize [])
1999 parseGenericIb name b = do
2000     b <-  anyWord8
2001     return $ Instr name OP8 [OpImm (fromIntegral b)]
2002 parseGenericIw name _ = do
2003     w <- anyWord16
2004     pos <- getPosition
2005     return $ Instr name OP16 [OpImm (fromIntegral w)]
2006 parseGenericJb name _ = do
2007     b <- anyInt8
2008     pos <- getPosition
2009     st <- getState
2010     return $ Instr name OPNONE 
2011         [OpAddr (fromIntegral ((fromIntegral b + sourceColumn pos - 1)) +
2012                 (startAddr st)) OPNONE]
2013 parseGenericJz name _ = do
2014     b <- anyIntZ
2015     pos <- getPosition
2016     st <- getState
2017     return $ Instr name OPNONE 
2018         [OpAddr (fromIntegral ((fromIntegral b + sourceColumn pos - 1)) +
2019                (startAddr st)) OPNONE]
2020
2021 parseINC b = do
2022   opsize <- instrOperandSize
2023   let reg = b .&. 0x0f
2024   rn <- registerName (fromIntegral reg)
2025   return $ Instr INC opsize [OpReg rn (fromIntegral reg)]
2026
2027 parseDEC b = do
2028   opsize <- instrOperandSize
2029   let reg = (b .&. 0x0f) - 8
2030   rn <- registerName (fromIntegral reg)
2031   return $ Instr DEC opsize [OpReg rn (fromIntegral reg)]
2032
2033 parsePUSH b = 
2034     let reg = b .&. 0x0f in do
2035       st <- getState
2036       rn <- registerName (fromIntegral reg)
2037       opsize <- instrOperandSize
2038       if hasREX rex_R st
2039          then return $ Instr PUSH opsize [OpReg ("r" ++ show (reg + 8))
2040                                            (fromIntegral reg)]
2041           else return $ Instr PUSH opsize [OpReg rn
2042                                             (fromIntegral reg)]
2043
2044 parsePOP b = 
2045     let reg = (b .&. 0x0f) - 8 in do
2046       st <- getState
2047       rn <- registerName (fromIntegral reg)
2048       opsize <- instrOperandSize
2049       if hasREX rex_R st
2050          then return $ Instr POP opsize [OpReg ("r" ++ show (reg + 8))
2051                                          (fromIntegral reg)]
2052           else return $ Instr POP opsize [OpReg rn (fromIntegral reg)]
2053
2054 parsePUSHA = do
2055   chooseOperandSize
2056     (\ _ -> return $ Instr PUSHA OPNONE [])
2057     (\ _ -> return $ Instr PUSHAD OPNONE [])
2058 parsePOPA = do
2059   chooseOperandSize
2060     (\ _ -> return $ Instr POPA OPNONE [])
2061     (\ _ -> return $ Instr POPAD OPNONE [])
2062
2063 parseBOUND b = do
2064   (op1, op2, mod, reg, rm) <- parseAddress32 OPNONE
2065   return $ Instr BOUND OPNONE [op2, op1]
2066   
2067 parseARPL b = do
2068   (op1, op2, mod, reg, rm) <- parseAddress32 OP16
2069   let rn = regnames16 !! fromIntegral reg
2070   return $ Instr ARPL OPNONE [op1, (OpReg rn (fromIntegral reg))]
2071      
2072 parseMOVSXD b = do
2073   (op1, op2, mod, reg, rm) <- parseAddress32 OPNONE
2074   return $ Instr MOVSXD OPNONE [op2, op1]
2075
2076 parsePUSHImm 0x68 = do
2077   w <- anyWordZ
2078   opsize <- instrOperandSize
2079   return $ Instr PUSH opsize [OpImm w]
2080 parsePUSHImm 0x6a = do
2081   w <- anyWord8
2082   opsize <- instrOperandSize
2083   return $ Instr PUSH opsize [OpImm (fromIntegral w)]
2084
2085 parseIMUL 0x69 = do
2086   opsize <- instrOperandSize
2087   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2088   imm <- anyWordZ
2089   return $ Instr IMUL opsize [op2, op1, OpImm imm]
2090 parseIMUL 0x6b = do
2091   opsize <- instrOperandSize
2092   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2093   imm <- anyWord8
2094   return $ Instr IMUL opsize [op2, op1, OpImm (fromIntegral imm)]
2095
2096 parseINS 0x6c = return $ Instr INS OP8 []
2097 parseINS b@0x6d = chooseOperandSize
2098                    (\ _ -> return $ Instr INS OP16 [])
2099                   (\ _ -> return $ Instr INS OP32 []) b
2100
2101 parseOUTS 0x6e = return $ Instr OUTS OP8 []
2102 parseOUTS b@0x6f = chooseOperandSize
2103                      (\ _ -> return $ Instr OUTS OP16 [])
2104                      (\ _ -> return $ Instr OUTS OP32 []) b
2105
2106 parseJccShort b = do
2107   disp <- anyInt8
2108   pos <- getPosition
2109   st <- getState
2110   return $ Instr (jccname (b .&. 0xf)) OPNONE
2111         [OpAddr (fromIntegral (fromIntegral disp + sourceColumn pos - 1) +
2112                 (startAddr st)) OPNONE]
2113
2114 parseTEST 0x84 = do
2115   (op1, op2, mod, reg, rm) <- parseAddress32 OP8
2116   return $ Instr TEST OP8 [op1, OpReg (regnames8 !! fromIntegral reg)
2117                           (fromIntegral reg)]
2118 parseTEST 0x85 = do
2119   opsize <- instrOperandSize
2120   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2121   return $ Instr TEST opsize [op1, op2]
2122
2123 parseXCHG 0x86 = do
2124   (op1, op2, mod, reg, rm) <- parseAddress32 OP8
2125   return $ Instr XCHG OP8 [op1, OpReg (regnames8 !! fromIntegral reg)
2126                            (fromIntegral reg)]
2127 parseXCHG 0x87 = do
2128   opsize <- instrOperandSize
2129   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2130   return $ Instr XCHG opsize[op1, op2]
2131
2132 parseMOV 0x88  = do
2133   (op1, op2, mod, reg, rm) <- parseAddress32 OP8
2134   return $ Instr MOV OP8 [op1, OpReg (regnames8 !! fromIntegral reg)
2135                           (fromIntegral reg)]
2136 parseMOV 0x89  = do
2137   opsize <- instrOperandSize
2138   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2139   return $ Instr MOV opsize [op1, op2]
2140 parseMOV 0x8a  = do
2141   (op1, op2, mod, reg, rm) <- parseAddress32 OP8
2142   return $ Instr MOV OP8 [OpReg (regnames8 !! fromIntegral reg) 
2143                           (fromIntegral reg), op1]
2144 parseMOV 0x8b  = do
2145   opsize <- instrOperandSize
2146   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2147   return $ Instr MOV opsize [op2, op1]
2148 parseMOV 0x8c  = do
2149   (op1, op2, mod, reg, rm) <- parseAddress32 OP16
2150   let rn = segregnames !! (fromIntegral reg)
2151   return $ Instr MOV OP16 [op1, OpReg rn (fromIntegral reg)]
2152 parseMOV 0x8e  = do
2153   (op1, op2, mod, reg, rm) <- parseAddress32 OP16
2154   let rn = segregnames !! (fromIntegral reg)
2155   return $ Instr MOV OP16 [OpReg rn (fromIntegral reg), op1]
2156
2157 parseLEA b = do
2158   (op1, op2, mod, reg, rm) <- parseAddress32 OPNONE
2159   return $ Instr LEA OPNONE [op2, op1]
2160
2161
2162 parse0x90 b = do
2163   st <- getState
2164   if hasPrefix 0xf3 st
2165      then return $ Instr PAUSE OPNONE []
2166      else do st <- getState
2167              if in64BitMode st
2168                 then parseXCHGReg b
2169                 else return $ Instr NOP OPNONE []
2170
2171 -- FIXME: Register name handling not quite right
2172
2173 parseXCHGReg :: Word8 -> Word8Parser Instr
2174 parseXCHGReg b = 
2175     let reg = b .&. 0x0f in do
2176       st <- getState
2177       if hasREX rex_R st
2178          then return $ Instr XCHG OP64 [OpReg "rax" 0, 
2179                                         OpReg ("r" ++ show (reg + 8))
2180                                         (fromIntegral reg)]
2181          else do rn <- registerName (fromIntegral reg)
2182                  return $ Instr XCHG OP64 [OpReg "rax" 0,
2183                                            OpReg rn (fromIntegral reg)]
2184
2185 parseCBW_CWDE_CDQE b = do
2186   st <- getState
2187   if in64BitMode st
2188      then if hasREX rex_W st
2189              then return $ Instr CDQE OPNONE []
2190               else return $ Instr CWDE OPNONE []
2191      else chooseOperandSize
2192             (\ _ -> return $ Instr CBW OPNONE [])
2193             (\ _ -> return $ Instr CWDE OPNONE []) b
2194
2195 parseCWD_CDQ_CQO b = do
2196   st <- getState
2197   if in64BitMode st
2198      then if hasREX rex_W st
2199              then return $ Instr CDQE OPNONE []
2200               else return $ Instr CDQ OPNONE []
2201      else chooseOperandSize
2202             (\ _ -> return $ Instr CWD OPNONE [])
2203             (\ _ -> return $ Instr CDQ OPNONE []) b
2204
2205 parseCALLF b = do
2206     w <- anyWord32
2207     s <- anyWord16
2208     return $ Instr CALLF OPNONE [OpImm (fromIntegral w),
2209                            OpImm (fromIntegral s)]
2210
2211 -- FIXME: Check default/operand sizes.
2212
2213 parsePUSHF b = do
2214   st <- getState
2215   if in64BitMode st
2216      then chooseOperandSize
2217              (\ _ -> return $ Instr PUSHF OPNONE [])
2218              (\ _ -> return $ Instr PUSHFQ OPNONE []) b
2219      else chooseOperandSize
2220              (\ _ -> return $ Instr PUSHF OPNONE [])
2221              (\ _ -> return $ Instr PUSHFD OPNONE []) b
2222
2223 parsePOPF b = do
2224   st <- getState
2225   if in64BitMode st
2226      then chooseOperandSize
2227              (\ _ -> return $ Instr POPF OPNONE [])
2228              (\ _ -> return $ Instr POPFQ OPNONE []) b
2229      else chooseOperandSize
2230              (\ _ -> return $ Instr POPF OPNONE [])
2231              (\ _ -> return $ Instr POPFD OPNONE []) b
2232
2233 parseJMPF b = do
2234     w <- anyWord32
2235     return $ Instr JMPF OPNONE [OpImm w]
2236
2237 parseMOVImm b@0xa0 = do
2238   chooseAddressSize
2239     (\ _ -> do w <- anyWord16
2240                return $ Instr MOV OP8 [OpReg "al" 0, OpImm (fromIntegral w)])
2241     (\ _ -> do w <- anyWord32
2242                return $ Instr MOV OP8 [OpReg "al" 0, OpImm w]) b
2243 parseMOVImm b@0xa1 = do
2244   opsize <- instrOperandSize
2245   reg <- registerName 0
2246   chooseAddressSize
2247     (\ _ -> do w <- anyWord16
2248                return $ Instr MOV opsize [OpReg reg 0, OpImm (fromIntegral w)])
2249     (\ _ -> do w <- anyWord32
2250                return $ Instr MOV opsize [OpReg reg 0, OpImm w]) b
2251 parseMOVImm b@0xa2 = do
2252   chooseAddressSize
2253     (\ _ -> do w <- anyWord16
2254                return $ Instr MOV OP8 [OpImm (fromIntegral w), OpReg "al" 0])
2255     (\ _ -> do w <- anyWord32
2256                return $ Instr MOV OP8 [OpImm w, OpReg "al" 0]) b
2257 parseMOVImm b@0xa3 = do
2258   opsize <- instrOperandSize
2259   reg <- registerName 0
2260   chooseAddressSize
2261     (\ _ -> do w <- anyWord16
2262                return $ Instr MOV opsize [OpImm (fromIntegral w), OpReg reg 0])
2263     (\ _ -> do w <- anyWord32
2264                return $ Instr MOV opsize [OpImm w, OpReg reg 0]) b
2265
2266 parseMOVS 0xa4 = return $ Instr MOVS OP8 []
2267 parseMOVS b@0xa5 = do
2268   st <- getState
2269   opsize <- instrOperandSize
2270   return $ Instr MOVS opsize []
2271
2272 parseCMPS 0xa6 = return $ Instr CMPS OP8 []
2273 parseCMPS 0xa7 = do
2274   st <- getState
2275   opsize <- instrOperandSize
2276   return $ Instr CMPS opsize []
2277
2278 parseTESTImm 0xa8 = do
2279   imm <- anyWord8
2280   return $ Instr TEST OP8 [OpReg "al" 0, OpImm (fromIntegral imm)]
2281 parseTESTImm 0xa9 = do
2282   imm <- anyWordZ
2283   rn <- registerName 0
2284   opsize <- instrOperandSize
2285   return $ Instr TEST opsize [OpReg rn 0, OpImm imm]
2286   
2287
2288 parseSTOS 0xaa = return $ Instr STOS OP8 []
2289 parseSTOS b@0xab = do
2290   st <- getState
2291   opsize <- instrOperandSize
2292   if in64BitMode st
2293      then if hasREX rex_W st
2294              then return $ Instr STOS opsize []
2295               else chooseOperandSize
2296                     (\ _ -> return $ Instr STOS opsize [])
2297                     (\ _ -> return $ Instr STOS opsize []) b
2298      else chooseOperandSize
2299             (\ _ -> return $ Instr STOS opsize [])
2300             (\ _ -> return $ Instr STOS opsize []) b
2301
2302 parseLODS 0xac = return $ Instr LODS OP8 []
2303 parseLODS b@0xad = do
2304   st <- getState
2305   opsize <- instrOperandSize
2306   if in64BitMode st
2307      then if hasREX rex_W st
2308              then return $ Instr LODS opsize []
2309               else chooseOperandSize
2310                     (\ _ -> return $ Instr LODS opsize [])
2311                     (\ _ -> return $ Instr LODS opsize []) b
2312      else chooseOperandSize
2313             (\ _ -> return $ Instr LODS opsize [])
2314             (\ _ -> return $ Instr LODS opsize []) b
2315
2316 parseSCAS 0xae = return $ Instr SCAS OP8 []
2317 parseSCAS b@0xaf = do
2318   st <- getState
2319   opsize <- instrOperandSize
2320   if in64BitMode st
2321      then if hasREX rex_W st
2322              then return $ Instr SCAS opsize []
2323               else chooseOperandSize
2324                     (\ _ -> return $ Instr SCAS opsize [])
2325                     (\ _ -> return $ Instr SCAS opsize []) b
2326      else chooseOperandSize
2327             (\ _ -> return $ Instr SCAS opsize [])
2328             (\ _ -> return $ Instr SCAS opsize []) b
2329
2330 parseMOVImmByteToByteReg :: Word8 -> Word8Parser Instr
2331 parseMOVImmByteToByteReg b = do
2332   let reg = b .&. 0x0f
2333   st <- getState
2334   imm <- anyWord8
2335   if hasREX rex_R st
2336      then return $ Instr MOV OP8 [OpReg ("r" ++ show reg ++ "l")
2337                                    (fromIntegral reg),
2338                                   OpImm (fromIntegral imm)]
2339      else return $ Instr MOV OP8 [OpReg (regnames8 !! (fromIntegral reg))
2340                                     (fromIntegral reg), 
2341                                   OpImm (fromIntegral imm)]
2342
2343 parseMOVImmToReg :: Word8 -> Word8Parser Instr
2344 parseMOVImmToReg b = do
2345   let reg = (b .&. 0x0f - 8)
2346   imm <- anyWordV
2347   opsize <- instrOperandSize
2348   rn <- registerName (fromIntegral reg)
2349   return $ Instr MOV opsize [OpReg rn (fromIntegral reg), 
2350                              OpImm (fromIntegral imm)]
2351
2352 parseRETN 0xc2 = do
2353     w <- anyWord16
2354     return $ Instr RET OPNONE [OpImm (fromIntegral w)]
2355 parseRETN 0xc3 = return $ Instr RET OPNONE []
2356
2357 parseLoadSegmentRegister opcode b = do
2358   (op1, op2, mod, reg, rm) <- parseAddress32 OPNONE
2359   return $ Instr opcode OPNONE [op2, op1]
2360
2361 parseENTER b = do
2362     w <- anyWord16
2363     b <- anyWord8
2364     return $ Instr ENTER OPNONE [OpImm (fromIntegral w), 
2365                            OpImm (fromIntegral b)]
2366
2367 -- Floating-point operations.  These can probably shortened by doing some
2368 -- arithmetic/logical tricks on the opcodes, but since the instruction
2369 -- set is still quite irregular (even though much better than the integer
2370 -- ops), I haven't bothered yet.
2371
2372 parseESC 0xd8 = do
2373   modrm <- anyWord8
2374   let modrm' :: Word8
2375       modrm' = modrm - 0xc0
2376   if modrm <= 0xbf
2377      then do (op1, op2, mod, reg, rm) <- parseAddress32' OPF32 modrm
2378              return $ Instr (ops !! fromIntegral reg) OPF32 [op1]
2379      else if (modrm .&. 0x0f) < 0x8
2380              then return $ Instr 
2381              (ops !! fromIntegral ((modrm' `shiftR` 3))) OPNONE
2382                     [OpFPReg 0, OpFPReg (fromIntegral (modrm .&. 0x0f))]
2383               else return $ Instr 
2384              (ops !! fromIntegral ((modrm' `shiftR` 3))) OPNONE
2385                     [OpFPReg 0, OpFPReg (fromIntegral ((modrm .&. 0x0f) - 8))]
2386  where ops = [FADD, FMUL, FCOM, FCOMP, 
2387                FSUB, FSUBR, FDIV, FDIVR]
2388              
2389 parseESC b@0xd9 = do
2390   modrm <- anyWord8
2391   let modrm' :: Word8
2392       modrm' = modrm - 0xc0
2393   if modrm <= 0xbf
2394      then do (op1', op2, mod, reg, rm) <- parseAddress32' OPNONE modrm
2395              let op1 = case op1' of 
2396                          OpAddr a _ -> OpAddr a  (opsizes !! fromIntegral reg)
2397                          op -> op
2398              return $ Instr (lowOps !! fromIntegral reg) 
2399                       (opsizes !! fromIntegral reg) [op1]
2400      else if (modrm < 0xd0)
2401              then if (modrm .&. 0x0f) < 8
2402                     then return $ Instr 
2403                   (ops !! fromIntegral ((modrm' `shiftR` 3))) OPNONE
2404                          [OpFPReg 0, OpFPReg (fromIntegral (modrm .&. 0x0f))]
2405                     else return $ Instr 
2406                   (ops !! fromIntegral ((modrm' `shiftR` 3))) OPNONE
2407                          [OpFPReg 0, OpFPReg (fromIntegral (modrm .&. 0x0f)
2408                               - 8)]
2409               else case modrm of
2410                      0xd0 -> return $ Instr FNOP OPNONE []
2411                      0xe0 -> return $ Instr FCHS OPNONE []
2412                      0xe1 -> return $ Instr FABS OPNONE []
2413                      0xe4 -> return $ Instr FTST OPNONE []
2414                      0xe5 -> return $ Instr FXAM OPNONE []
2415                      0xe8 -> return $ Instr FLD1 OPNONE []
2416                      0xe9 -> return $ Instr FLDL2T OPNONE []
2417                      0xea -> return $ Instr FLDL2E OPNONE []
2418                      0xeb -> return $ Instr FLDPI OPNONE []
2419                      0xec -> return $ Instr FLDLG2 OPNONE []
2420                      0xed -> return $ Instr FLDLN2 OPNONE []
2421                      0xee -> return $ Instr FLDZ OPNONE []
2422                      _ -> parseInvalidOpcode b
2423  where lowOps = [FLD, InvalidOpcode, FST, FSTP, 
2424                   FLDENV, FLDCW, FSTENV, FSTCW]
2425        opsizes = [OPF32, OPNONE, OPF32, OPF32,
2426                    OPNONE, OPNONE, OPNONE, OPNONE]
2427        ops = [FLD, FXCH]
2428
2429 parseESC 0xda = do
2430   modrm <- anyWord8
2431   let modrm' :: Word8
2432       modrm' = modrm - 0xc0
2433   if modrm <= 0xbf
2434      then do (op1, op2, mod, reg, rm) <- parseAddress32' OPNONE modrm
2435              return $ Instr (ops !! fromIntegral reg) OPNONE [op1]
2436      else if (modrm < 0xe0)
2437              then return $ Instr 
2438              (ops' !! fromIntegral ((modrm' `shiftR` 3))) OPNONE
2439                     [OpFPReg 0, OpFPReg (fromIntegral (modrm .&. 0x0f))]
2440               else case modrm of
2441                      0xe1 -> return $ Instr FUCOMPP OPNONE []
2442                      _ -> parseInvalidOpcode 0xda
2443  where ops = [FIADD, FIMUL, FICOM, FICOMP, 
2444                FISUB, FISUBR, FIDIV, FIDIVR]
2445        ops' = [FCMOVB, FCMOVE, FCMOVBE, FCMOVU]
2446
2447 parseESC 0xdb = do
2448   modrm <- anyWord8
2449   let modrm' :: Word8
2450       modrm' = modrm - 0xc0
2451   if modrm <= 0xbf
2452      then do (op1', op2, mod, reg, rm) <- parseAddress32' OPNONE modrm
2453              let op1 = case op1' of 
2454                          OpAddr a _ -> OpAddr a  (opsizes !! fromIntegral reg)
2455                          op -> op
2456              return $ Instr (ops !! fromIntegral reg) 
2457                       (opsizes !! fromIntegral reg) [op1]
2458      else 
2459       case modrm of
2460          0xe2 -> return $ Instr FCLEX OPNONE []
2461          0xe3 -> return $ Instr FINIT OPNONE []
2462          _ ->
2463            if (modrm .&. 0x0f) < 0x8
2464              then return $ Instr 
2465              (ops' !! fromIntegral ((modrm' `shiftR` 3))) OPNONE
2466                     [OpFPReg 0, OpFPReg (fromIntegral (modrm .&. 0x0f))]
2467               else return $ Instr 
2468              (ops' !! fromIntegral ((modrm' `shiftR` 3))) OPNONE
2469                     [OpFPReg 0, OpFPReg (fromIntegral ((modrm .&. 0x0f) - 8))]
2470  where ops = [FILD, FISTP, FIST, FISTP, 
2471                InvalidOpcode, FLD, InvalidOpcode, FSTP]
2472        opsizes = [OP32, OP32, OP32, OP32,
2473                    OPNONE, OPF80, OPNONE, OPF80]
2474        ops' = [FCMOVNB, FCMOVNE, FCMOVNBE, FCMOVNU,
2475                 InvalidOpcode, FUCOMI, FCOMI, InvalidOpcode]
2476
2477 parseESC 0xdc = do
2478   modrm <- anyWord8
2479   let modrm' :: Word8
2480       modrm' = modrm - 0xc0
2481   if modrm <= 0xbf
2482      then do (op1, op2, mod, reg, rm) <- parseAddress32' OPNONE modrm
2483              return $ Instr (ops !! fromIntegral reg) OPNONE [op1]
2484      else
2485        if modrm >= 0xd0 && modrm < 0xe0
2486         then parseInvalidOpcode 0xdc
2487         else if (modrm .&. 0x0f) < 0x8
2488              then return $ Instr 
2489              (ops !! fromIntegral ((modrm' `shiftR` 3))) OPNONE
2490                     [OpFPReg (fromIntegral (modrm .&. 0x0f)), OpFPReg 0]
2491               else return $ Instr 
2492              (ops !! fromIntegral ((modrm' `shiftR` 3))) OPNONE
2493                     [OpFPReg (fromIntegral ((modrm .&. 0x0f) - 8)), OpFPReg 0]
2494  where ops = [FADD, FMUL, FCOM, FCOMP, 
2495                FSUB, FSUBR, FDIV, FDIVR]
2496              
2497 parseESC 0xdd = do
2498   modrm <- anyWord8
2499   let modrm' :: Word8
2500       modrm' = modrm - 0xc0
2501   if modrm <= 0xbf
2502      then do (op1', op2, mod, reg, rm) <- parseAddress32' OPNONE modrm
2503              let op1 = case op1' of 
2504                          OpAddr a _ -> OpAddr a  (opsizes !! fromIntegral reg)
2505                          op -> op
2506              return $ Instr (ops !! fromIntegral reg) 
2507                       (opsizes !! fromIntegral reg) [op1]
2508      else
2509        if (modrm >= 0xc8) && modrm <= 0xd0 || (modrm >= 0xf0 && modrm < 0xff)
2510         then parseInvalidOpcode 0xdc
2511         else if (modrm .&. 0x0f) < 0x8
2512              then return $ Instr 
2513              (ops' !! fromIntegral ((modrm' `shiftR` 3))) OPNONE
2514                     [OpFPReg (fromIntegral (modrm .&. 0x0f)), OpFPReg 0]
2515               else return $ Instr 
2516              (ops' !! fromIntegral ((modrm' `shiftR` 3))) OPNONE
2517                     [OpFPReg (fromIntegral ((modrm .&. 0x0f) - 8)), OpFPReg 0]
2518  where ops = [FLD, FISTTP, FST, FSTP, 
2519                FRSTOR, InvalidOpcode, FSAVE, FSTSW]
2520        opsizes = [OPF64, OP64, OPF64, OPF64,
2521                    OPNONE, OPNONE, OPNONE, OP16]
2522        ops' = [FFREE, InvalidOpcode, FST, FSTP, 
2523                 FUCOM, FUCOMP]
2524              
2525 parseESC 0xde = do
2526   modrm <- anyWord8
2527   let modrm' :: Word8
2528       modrm' = modrm - 0xc0
2529   if modrm <= 0xbf
2530      then do (op1, op2, mod, reg, rm) <- parseAddress32' OPNONE modrm
2531              return $ Instr (ops !! fromIntegral reg) OPNONE [op1]
2532      else
2533        if modrm >= 0xd0 && modrm <= 0xe0
2534         then case modrm of
2535          0xd9 -> return $ Instr FCOMPP OPNONE []
2536          _ -> parseInvalidOpcode 0xde
2537         else if (modrm .&. 0x0f) < 0x8
2538              then return $ Instr 
2539              (ops' !! fromIntegral ((modrm' `shiftR` 3))) OPNONE
2540                     [OpFPReg (fromIntegral (modrm .&. 0x0f)), OpFPReg 0]
2541               else return $ Instr 
2542              (ops' !! fromIntegral ((modrm' `shiftR` 3))) OPNONE
2543                     [OpFPReg (fromIntegral ((modrm .&. 0x0f) - 8)), OpFPReg 0]
2544  where ops = [FIADD, FIMUL, FICOM, FICOMP, 
2545                FISUB, FISUBR, FIDIV, FIDIVR]
2546        ops' = [FADDP, FMULP, InvalidOpcode, InvalidOpcode,
2547                 FSUBRP, FSUBP, FDIVRP, FDIVP]
2548              
2549              
2550 parseESC 0xdf = do
2551   modrm <- anyWord8
2552   let modrm' :: Word8
2553       modrm' = modrm - 0xc0
2554   if modrm <= 0xbf
2555      then do (op1, op2, mod, reg, rm) <- parseAddress32' OPNONE modrm
2556              return $ Instr (ops !! fromIntegral reg) OPNONE [op1]
2557      else
2558        case modrm of
2559            0xe0 -> return $ Instr FSTSW OPNONE [OpReg "ax" 0]
2560            _ -> 
2561              if (modrm >= 0xe8 && modrm <= 0xef) ||
2562                 (modrm >= 0xf0 && modrm <= 0xf7)
2563              then
2564              if (modrm .&. 0x0f) < 0x8
2565              then return $ Instr 
2566              (ops' !! fromIntegral ((modrm' `shiftR` 3))) OPNONE
2567                     [OpFPReg (fromIntegral (modrm .&. 0x0f)), OpFPReg 0]
2568               else return $ Instr 
2569              (ops' !! fromIntegral ((modrm' `shiftR` 3))) OPNONE
2570                     [OpFPReg (fromIntegral ((modrm .&. 0x0f) - 8)), OpFPReg 0]
2571              else parseInvalidOpcode 0xdf
2572  where ops = [FILD, FISTPP, FIST, FISTP, 
2573                FBLD, FILD, FBSTP, FISTP]
2574        ops' = [InvalidOpcode, InvalidOpcode, InvalidOpcode, InvalidOpcode,
2575                 InvalidOpcode, FUCOMIP, FCOMIP, InvalidOpcode]
2576
2577 parseINImm 0xe4 = do
2578     b <- anyWord8
2579     return $ Instr IN OP8 [OpReg "al" 0, OpImm (fromIntegral b)]
2580 parseINImm 0xe5 = do
2581     b <- anyWord8
2582     rn <- registerName 0
2583     opsize <- instrOperandSize
2584     return $ Instr IN opsize [OpReg rn 0, OpImm (fromIntegral b)]
2585 parseOUTImm 0xe6 = do
2586     b <- anyWord8
2587     return $ Instr OUT OP8 [OpImm (fromIntegral b), OpReg "al" 0]
2588 parseOUTImm 0xe7 = do
2589     b <- anyWord8
2590     rn <- registerName 0
2591     opsize <- instrOperandSize
2592     return $ Instr OUT opsize [OpImm (fromIntegral b), OpReg rn 0]
2593
2594 parseIN 0xec = do
2595     return $ Instr IN OP8 [OpReg "al" 0, OpReg "dx" 2]
2596 parseIN 0xed = do
2597     rn <- registerName 0
2598     opsize <- instrOperandSize
2599     return $ Instr IN opsize [OpReg rn 0, OpReg "dx" 2]
2600 parseOUT 0xee = do
2601     return $ Instr OUT OP8 [OpReg "dx" 2, OpReg "al" 0]
2602 parseOUT 0xef = do
2603     rn <- registerName 0
2604     opsize <- instrOperandSize
2605     return $ Instr OUT opsize [OpReg "dx" 2, OpReg rn 0]
2606
2607 -- Return the name of the register encoded with R.  Take 64-bit mode and
2608 -- possible REX and operand-size prefixes into account.
2609
2610 registerName r = do
2611     st <- getState
2612     if in64BitMode st && hasREX rex_R st
2613        then return $ "r" ++ show (r + 8)
2614        else case operandBitMode st of
2615               BIT16 -> return $ regnames16 !! r
2616               BIT32 -> return $ regnames32 !! r
2617
2618 instrOperandSize = do
2619     st <- getState
2620     if in64BitMode st && hasREX rex_W st
2621        then return $ OP64
2622        else case operandBitMode st of
2623               BIT16 -> return OP16
2624               BIT32 -> return OP32
2625
2626 regnames8 = ["al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"]
2627 regnames16 = ["ax", "cx", "dx", "bx", "sp", "bp", "si", "di"]
2628 regnames32 = ["eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"]
2629 regnames64 = ["rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"]
2630 segregnames = ["es", "cs", "ss", "ds", "fs", "gs", "<invalid>", "<invalid>"]
2631 mmxregs = ["mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7"]
2632 xmmregs = ["xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"]
2633
2634 jccname 0 = JO
2635 jccname 1 = JNO
2636 jccname 2 = JB
2637 jccname 3 = JNB
2638 jccname 4 = JE
2639 jccname 5 = JNE
2640 jccname 6 = JBE
2641 jccname 7 = JA
2642 jccname 8 = JS
2643 jccname 9 = JNS
2644 jccname 10 = JP
2645 jccname 11 = JNP
2646 jccname 12 = JL
2647 jccname 13 = JGE
2648 jccname 14 = JLE
2649 jccname 15 = JG
2650
2651 setccname 0 = SETO
2652 setccname 1 = SETNO
2653 setccname 2 = SETB
2654 setccname 3 = SETNB
2655 setccname 4 = SETE
2656 setccname 5 = SETNE
2657 setccname 6 = SETBE
2658 setccname 7 = SETA
2659 setccname 8 = SETS
2660 setccname 9 = SETNS
2661 setccname 10 = SETP
2662 setccname 11 = SETNP
2663 setccname 12 = SETL
2664 setccname 13 = SETGE
2665 setccname 14 = SETLE
2666 setccname 15 = SETG
2667
2668 cmovccname 0 = CMOVO
2669 cmovccname 1 = CMOVNO
2670 cmovccname 2 = CMOVB
2671 cmovccname 3 = CMOVNB
2672 cmovccname 4 = CMOVE
2673 cmovccname 5 = CMOVNE
2674 cmovccname 6 = CMOVBE
2675 cmovccname 7 = CMOVA
2676 cmovccname 8 = CMOVS
2677 cmovccname 9 = CMOVNS
2678 cmovccname 10 = CMOVP
2679 cmovccname 11 = CMOVNP
2680 cmovccname 12 = CMOVL
2681 cmovccname 13 = CMOVGE
2682 cmovccname 14 = CMOVLE
2683 cmovccname 15 = CMOVG
2684
2685 parseGrp1 0x80 = do
2686   (op1, op2, mod, reg, rm) <- parseAddress32 OP8
2687   immb <- anyWord8
2688   return $ Instr (aluOps !! fromIntegral reg) OP8 
2689     [op1, OpImm (fromIntegral immb)]
2690 parseGrp1 0x81 = do
2691   opsize <- instrOperandSize
2692   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2693   immb <- anyWordZ
2694   return $ Instr (aluOps !! fromIntegral reg) opsize 
2695     [op1, OpImm (fromIntegral immb)]
2696 parseGrp1 0x82 = do
2697   (op1, op2, mod, reg, rm) <- parseAddress32 OP8
2698   immb <- anyWord8
2699   return $ Instr (aluOps !! fromIntegral reg) OP8 
2700     [op1, OpImm (fromIntegral immb)]
2701 parseGrp1 0x83 = do
2702   opsize <- instrOperandSize
2703   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2704   immb <- anyWord8
2705   return $ Instr (aluOps !! fromIntegral reg) opsize
2706     [op1, OpImm (fromIntegral immb)]
2707 aluOps = [ADD, OR, ADC, SBB, AND, SUB, XOR, CMP]
2708
2709
2710 parseGrp1A b = do
2711    opsize <- instrOperandSize
2712    (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2713    case reg of
2714      0 -> return $ Instr POP opsize [op1]
2715      _ -> parseInvalidOpcode b
2716
2717 parseGrp2 0xc0 = do
2718   (op1, op2, mod, reg, rm) <- parseAddress32 OP8
2719   immb <- anyWord8
2720   return $ Instr (shiftOps !! fromIntegral reg) OP8 
2721       [op1, OpImm (fromIntegral immb)]
2722 parseGrp2 0xc1 = do
2723   opsize <- instrOperandSize
2724   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2725   imm <- anyWord8
2726   return $ Instr (shiftOps !! fromIntegral reg) opsize
2727       [op1, OpImm (fromIntegral imm)]
2728 parseGrp2 0xd0 = do
2729   (op1, op2, mod, reg, rm) <- parseAddress32 OP8
2730   return $ Instr (shiftOps !! fromIntegral reg) OP8 [op1, OpImm 1]
2731 parseGrp2 0xd1 = do
2732   opsize <- instrOperandSize
2733   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2734   return $ Instr (shiftOps !! fromIntegral reg) opsize [op1, OpImm 1]
2735 parseGrp2 0xd2 = do
2736   (op1, op2, mod, reg, rm) <- parseAddress32 OP8
2737   return $ Instr (shiftOps !! fromIntegral reg) OP8 [op1, OpReg "cl" 1]
2738 parseGrp2 0xd3 = do
2739   opsize <- instrOperandSize
2740   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2741   return $ Instr (shiftOps !! fromIntegral reg) opsize [op1, OpReg "cl" 1]
2742 shiftOps = [ROL, ROR, RCL, RCR, SHL, SHR, InvalidOpcode, SAR]
2743
2744 parseGrp3 0xf6 = do
2745   (op1, op2, mod, reg, rm) <- parseAddress32 OP8
2746   case reg of
2747     0 -> do imm <- anyWord8
2748             return $ Instr TEST OP8 [op1, OpImm (fromIntegral imm)]
2749     1 -> parseInvalidOpcode 0xf6
2750     2 -> return $ Instr NOT OP8 [op1]
2751     3 -> return $ Instr NEG OP8 [op1]
2752     4 -> return $ Instr MUL OP8 [OpReg "al" 0, op1]
2753     5 -> return $ Instr IMUL OP8 [OpReg "al" 0, op1]
2754     6 -> return $ Instr DIV OP8 [OpReg "al" 0, op1]
2755     7 -> return $ Instr IDIV OP8 [OpReg "al" 0, op1]
2756 parseGrp3 0xf7 = do
2757   opsize <- instrOperandSize
2758   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2759   rn <- registerName 0
2760   case reg of
2761     0 -> do imm <- anyWordZ
2762             return $ Instr TEST opsize [op1, OpImm (fromIntegral imm)]
2763     1 -> parseInvalidOpcode 0xf6
2764     2 -> return $ Instr NOT opsize [op1]
2765     3 -> return $ Instr NEG opsize [op1]
2766     4 -> return $ Instr MUL opsize [OpReg rn 0, op1]
2767     5 -> return $ Instr IMUL opsize [OpReg rn 0, op1]
2768     6 -> return $ Instr DIV opsize [OpReg rn 0, op1]
2769     7 -> return $ Instr IDIV opsize [OpReg rn 0, op1]
2770
2771 parseGrp4 b = do
2772   (op1, op2, mod, reg, rm) <- parseAddress32 OP8
2773   case reg of
2774     0 -> return $ Instr INC OP8 [op1]
2775     1 -> return $ Instr DEC OP8 [op1]
2776     _ -> parseInvalidOpcode b
2777
2778 parseGrp5 b = do
2779   opsize <- instrOperandSize
2780   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2781   case reg of
2782     0 -> return $ Instr INC opsize [op1]
2783     1 -> return $ Instr DEC opsize [op1]
2784     2 -> return $ Instr CALL OPNONE [op1]
2785     3 -> do w <- anyWord16
2786             return $ Instr CALLF OPNONE [OpAddr (fromIntegral w) OPNONE, op1]
2787     4 -> return $ Instr JMPN OPNONE [op1]
2788     5 -> do w <- anyWord16
2789             return $ Instr JMPF OPNONE [OpAddr (fromIntegral w) OPNONE, op1]
2790     6 -> return $ Instr PUSH opsize [op1]
2791     _ -> parseInvalidOpcode b
2792
2793 parseGrp6 b = do
2794   (op1, op2, mod, reg, rm) <- parseAddress32 OPNONE
2795   case reg of
2796     0 -> return $ Instr SLDT OPNONE [op1]
2797     1 -> return $ Instr STR OPNONE [op1]
2798     2 -> return $ Instr LLDT OPNONE [op1]
2799     3 -> return $ Instr LTR OPNONE [op1]
2800     4 -> return $ Instr VERR OPNONE [op1]
2801     5 -> return $ Instr VERW OPNONE [op1]
2802     _ -> parseInvalidOpcode b
2803
2804 parseGrp7 b = do
2805   (op1, op2, mod, reg, rm) <- parseAddress32 OPNONE
2806   case mod of
2807     3 -> case reg of
2808            0 -> case rm of
2809                   1 -> return $ Instr VMCALL OPNONE []
2810                   2 -> return $ Instr VMLAUNCH OPNONE []
2811                   3 -> return $ Instr VMRESUME OPNONE []
2812                   4 -> return $ Instr VMXOFF OPNONE []
2813                   _ -> parseInvalidOpcode b
2814            1 -> case rm of
2815                   0 -> return $ Instr MONITOR OPNONE []
2816                   1 -> return $ Instr MWAIT OPNONE []
2817                   _ -> parseInvalidOpcode b
2818            4 -> return $ Instr SMSW OPNONE [op1]
2819            6 -> return $ Instr LMSW OPNONE [op1]
2820            7 -> case rm of
2821                   0 -> onlyIn64BitMode
2822                          (\b -> return $ Instr SWAPGS OPNONE []) b
2823                   _ -> parseInvalidOpcode b
2824            _ -> parseInvalidOpcode b
2825     _ -> case reg of
2826            0 -> return $ Instr SGDT OPNONE [op1]
2827            1 -> return $ Instr SIDT OPNONE [op1]
2828            2 -> return $ Instr LGDT OPNONE [op1]
2829            3 -> return $ Instr LIDT OPNONE [op1]
2830            4 -> return $ Instr SMSW OPNONE [op1]
2831            5 -> parseInvalidOpcode b
2832            6 -> return $ Instr LMSW OPNONE [op1]
2833            7 -> return $ Instr INVLPG OPNONE [op1]
2834
2835 parseGrp8 b = do
2836   opsize <- instrOperandSize
2837   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2838   imm <- anyWord8
2839   case reg of
2840     4 -> return $ Instr BT opsize [op1, OpImm (fromIntegral imm)]
2841     5 -> return $ Instr BTS opsize [op1, OpImm (fromIntegral imm)]
2842     6 -> return $ Instr BTR opsize [op1, OpImm (fromIntegral imm)]
2843     7 -> return $ Instr BTC opsize [op1, OpImm (fromIntegral imm)]
2844     _ -> parseInvalidOpcode b
2845
2846 parseGrp9 b = do
2847   (op1, op2, mod, reg, rm) <- parseAddress32 OPNONE
2848   st <- getState
2849   case mod of
2850     3 -> parseInvalidOpcode b
2851     _ -> case reg of
2852             1 -> if hasREX rex_W st
2853                     then return $ Instr CMPXCHG16B OPNONE [op1]
2854                     else return $ Instr CMPXCHG8B OPNONE [op1]
2855             6 -> if hasPrefix 0x66 st
2856                    then return $ Instr VMCLEAR OPNONE [op1]
2857              else if hasPrefix 0xf3 st
2858                   then return $ Instr VMXON OPNONE [op1]
2859                   else return $ Instr VMPTRLD OPNONE [op1]
2860             7 -> return $ Instr VMPTRST OPNONE [op1]
2861             _ -> parseInvalidOpcode b
2862
2863 parseGrp10 = parseInvalidOpcode
2864
2865 parseGrp11 0xc6 = do
2866   (op1, op2, mod, reg, rm) <- parseAddress32 OP8
2867   imm <- anyWord8
2868   return $ Instr MOV OP8 [op1, OpImm (fromIntegral imm)]
2869 parseGrp11 0xc7 = do
2870   opsize <- instrOperandSize
2871   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2872   imm <- anyWordZ
2873   return $ Instr MOV opsize [op1, OpImm (fromIntegral imm)]
2874
2875 mmxInstr op1 mod reg rm name = do
2876   st <- getState
2877   imm <- anyWord8
2878   if hasPrefix 0x66 st
2879      then return $ Instr name OP128
2880            [OpReg (xmmregs !! fromIntegral rm) (fromIntegral rm),
2881             OpImm (fromIntegral imm)]
2882      else return $ Instr name OP64
2883            [OpReg (mmxregs !! fromIntegral rm) (fromIntegral rm),
2884             OpImm (fromIntegral imm)]
2885         
2886 parseGrp12 b = do
2887   st <- getState
2888   let opsize = if hasPrefix 0x66 st then OP128 else OP64
2889   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2890   case mod of
2891     3 -> case reg of
2892            2 -> mmxInstr op1 mod reg rm PSRLW
2893            4 -> mmxInstr op1 mod reg rm PSRAW
2894            6 -> mmxInstr op1 mod reg rm PSLLW
2895            _ -> parseInvalidOpcode b
2896     _ -> parseInvalidOpcode b
2897 parseGrp13 b = do
2898   st <- getState
2899   let opsize = if hasPrefix 0x66 st then OP128 else OP64
2900   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2901   case mod of
2902     3 -> case reg of
2903            2 -> mmxInstr op1 mod reg rm PSRLD
2904            4 -> mmxInstr op1 mod reg rm PSRAD
2905            6 -> mmxInstr op1 mod reg rm PSLLD
2906            _ -> parseInvalidOpcode b
2907     _ -> parseInvalidOpcode b
2908 parseGrp14 b = do
2909   st <- getState
2910   let opsize = if hasPrefix 0x66 st then OP128 else OP64
2911   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
2912   st <- getState
2913   case mod of
2914     3 -> case reg of
2915            2 -> mmxInstr op1 mod reg rm PSRLQ
2916            3 -> if hasPrefix 0x66 st
2917                    then mmxInstr op1 mod reg rm PSRLDQ
2918                    else parseInvalidOpcode b
2919            6 -> mmxInstr op1 mod reg rm PSLLQ
2920            7 -> if hasPrefix 0x66 st
2921                    then mmxInstr op1 mod reg rm PSLLDQ
2922                    else parseInvalidOpcode b
2923            _ -> parseInvalidOpcode b
2924     _ -> parseInvalidOpcode b
2925
2926 parseGrp15 b = do
2927   (op1, op2, mod, reg, rm) <- parseAddress32 OPNONE
2928   case mod of
2929     3 -> case reg of
2930             5 -> return $ Instr LFENCE OPNONE []
2931             6 -> return $ Instr MFENCE OPNONE []
2932             7 -> return $ Instr SFENCE OPNONE []
2933             _ -> parseInvalidOpcode b
2934     _ -> case reg of
2935             0 -> return $ Instr FXSAVE OPNONE [op1]
2936             1 -> return $ Instr FXRSTOR OPNONE [op1]
2937             2 -> return $ Instr LDMXCSR OPNONE [op1]
2938             3 -> return $ Instr STMXCSR OPNONE [op1]
2939             7 -> return $ Instr CLFLUSH OPNONE [op1]
2940             _ -> parseInvalidOpcode b
2941 parseGrp16 b = do
2942   (op1, op2, mod, reg, rm) <- parseAddress32 OPNONE
2943   case mod of
2944     3 -> parseInvalidOpcode b
2945     _ -> case reg of
2946             0 -> return $ Instr PREFETCHNTA OPNONE [op1]
2947             1 -> return $ Instr PREFETCHT0 OPNONE [op1]
2948             2 -> return $ Instr PREFETCHT1 OPNONE [op1]
2949             3 -> return $ Instr PREFETCHT2 OPNONE [op1]
2950             _ -> parseInvalidOpcode b
2951
2952 parseXmmVW p p0xf3 p0x66 p0xf2 b =
2953     do (op1, op2, mod, reg, rm) <- parseAddress32 OP128
2954        st <- getState
2955        let v = OpReg (xmmregs !! (fromIntegral reg)) (fromIntegral reg)
2956        let w = case op1 of
2957                  OpReg _ num -> OpReg (xmmregs !! num) num
2958                  op -> op
2959        if hasPrefix 0xf3 st
2960           then return $ Instr p0xf3 OP128 [v, w]
2961           else if hasPrefix 0x66 st
2962                   then return $ Instr p0x66 OP128 [v, w]
2963                   else if hasPrefix 0xf2 st
2964                           then return $ Instr p0xf2 OP128 [v, w]
2965                           else return $ Instr p OP128 [v, w]
2966 parseXmmWV p p0xf3 p0x66 p0xf2 b =
2967     do (op1, op2, mod, reg, rm) <- parseAddress32 OP128
2968        st <- getState
2969        let w = OpReg (xmmregs !! (fromIntegral reg)) (fromIntegral reg)
2970        let v = case op1 of
2971                  OpReg _ num -> OpReg (xmmregs !! num) num
2972                  op -> op
2973        if hasPrefix 0xf3 st
2974           then return $ Instr p0xf3 OP128 [v, w]
2975           else if hasPrefix 0x66 st
2976                   then return $ Instr p0x66 OP128 [v, w]
2977                   else if hasPrefix 0xf2 st
2978                           then return $ Instr p0xf2 OP128 [v, w]
2979                           else return $ Instr p OP128 [v, w]
2980
2981 parseXmmGU p p0xf3 p0x66 p0xf2 b =
2982     do (mod, reg, rm) <- parseModRM
2983        st <- getState
2984        let g = OpReg (regnames32 !! (fromIntegral reg)) (fromIntegral reg)
2985        let u = OpReg (xmmregs !! (fromIntegral rm)) (fromIntegral rm)
2986        if hasPrefix 0xf3 st
2987           then return $ Instr p0xf3 OP32 [g, u]
2988           else if hasPrefix 0x66 st
2989                   then return $ Instr p0x66 OP32 [g, u]
2990                   else if hasPrefix 0xf2 st
2991                           then return $ Instr p0xf2 OP32 [g, u]
2992                           else return $ Instr p OP32 [g, u]
2993
2994 parseMOVUPS b@0x10 = parseXmmVW MOVUPS MOVSS MOVUPD MOVSD b
2995 parseMOVUPS b@0x11 = parseXmmWV MOVUPS MOVSS MOVUPD MOVSD b
2996 parseMOVLPS b@0x12 = parseXmmWV MOVLPS MOVSLDUP MOVLPD MOVDDUP b
2997 parseMOVLPS b@0x13 = parseXmmVW MOVLPS InvalidOpcode MOVLPD InvalidOpcode b
2998 parseUNPCKLPS b@0x14 =
2999     parseXmmVW UNPCKLPS InvalidOpcode UNPCKLPD InvalidOpcode b
3000 parseUNPCKHPS b@0x15 = 
3001     parseXmmVW UNPCKHPS InvalidOpcode UNPCKHPD InvalidOpcode b
3002 parseMOVHPS b@0x16 = parseXmmVW MOVHPS MOVLSDUP MOVHPD MOVLHPS b
3003 parseMOVHPS b@0x17 = parseXmmVW MOVHPS InvalidOpcode MOVHPD InvalidOpcode b
3004
3005 parseMOVCtrlDebug 0x20 = 
3006     do (mod, reg, rm) <- parseModRM
3007        return $ Instr MOV OPNONE [OpReg (regnames32 !! fromIntegral rm)
3008                                   (fromIntegral rm),
3009                                   OpReg ("cr" ++ show reg) (fromIntegral reg)]
3010 parseMOVCtrlDebug 0x21 = 
3011     do (mod, reg, rm) <- parseModRM
3012        return $ Instr MOV OPNONE [OpReg (regnames32 !! fromIntegral rm)
3013                                   (fromIntegral rm),
3014                                   OpReg ("db" ++ show reg) (fromIntegral reg)]
3015 parseMOVCtrlDebug 0x22 = 
3016     do (mod, reg, rm) <- parseModRM
3017        return $ Instr MOV OPNONE [OpReg ("cr" ++ show reg) (fromIntegral reg),
3018                                   OpReg (regnames32 !! fromIntegral rm)
3019                                   (fromIntegral rm)]
3020 parseMOVCtrlDebug 0x23 = 
3021     do (mod, reg, rm) <- parseModRM
3022        return $ Instr MOV OPNONE [OpReg ("db" ++ show reg) (fromIntegral reg),
3023                                   OpReg (regnames32 !! fromIntegral rm)
3024                                   (fromIntegral rm)]
3025   
3026
3027 parseMOVAPS b@0x28 = parseXmmVW MOVAPS InvalidOpcode MOVAPD InvalidOpcode b
3028 parseMOVAPS b@0x29 = parseXmmWV MOVAPS InvalidOpcode MOVAPD InvalidOpcode b
3029 parseCVTI2PS = parseUnimplemented
3030 parseMOVNTPS = parseXmmWV MOVNTPS InvalidOpcode MOVNTPD InvalidOpcode
3031 parseCVTPS2PI = parseUnimplemented
3032 parseCVTTPS2PI = parseUnimplemented
3033 parseUCOMISS = parseXmmVW UCOMISS InvalidOpcode UCOMISD InvalidOpcode
3034 parseCOMISS = parseXmmVW COMISS InvalidOpcode COMISD InvalidOpcode
3035
3036 parseCMOVcc b= do
3037   opsize <- instrOperandSize
3038   (op1, op2, mod, reg, rm) <- parseAddress32 opsize
3039   return $ Instr (cmovccname (b .&. 0xf)) OPNONE [op2, op1]
3040   
3041 parseMOVSKPS = parseXmmGU MOVMSKPS InvalidOpcode MOVMSKPD InvalidOpcode
3042
3043 parseSQRTPS = parseXmmVW SQRTPS SQRTSS SQRTPD SQRTSD
3044 parseRSQRTPS = parseXmmVW RSQRTPS RSQRTSS InvalidOpcode InvalidOpcode
3045 parseRCPPS = parseXmmVW RCPPS RCPSS InvalidOpcode InvalidOpcode
3046 parseCVTPS2PD = parseUnimplemented
3047 parseANDNPS = parseXmmVW ANDNPS InvalidOpcode ANDNPD InvalidOpcode
3048 parseANDPS =  parseXmmVW ANDPS InvalidOpcode ANDPD InvalidOpcode
3049 parseORPS = parseXmmVW ORPS InvalidOpcode ORPD InvalidOpcode
3050 parseXORPS = parseXmmVW XORPS InvalidOpcode XORPD InvalidOpcode
3051 parseADDPS = parseXmmVW ADDPS ADDSS ADDPD ADDSD
3052 parseMULPS = parseXmmVW MULPS MULSS MULPD MULSD
3053 parseCVTDQ2PS = parseUnimplemented
3054 parsePUNPCKLWD = parseUnimplemented
3055 parsePACKSSWB = parseUnimplemented
3056 parsePUNPCKHWD = parseUnimplemented
3057 parseSUBPS = parseXmmVW SUBPS SUBSS SUBPD SUBSD
3058 parseMINPS = parseXmmVW MINPS MINSS MINPD MINSD
3059 parseDIVPS = parseXmmVW DIVPS DIVSS DIVPD DIVSD
3060 parseMAXPS = parseXmmVW MAXPS MAXSS MAXPD MAXSD
3061 parsePUNPCKLBW = parseUnimplemented
3062 parsePUNPCKLDQ = parseUnimplemented
3063 parsePACKUSWB = parseUnimplemented
3064 parsePCMPGTB = parseUnimplemented
3065 parsePCMPGTW = parseUnimplemented
3066 parsePCMPGTD = parseUnimplemented
3067 parsePUNPCKHBW = parseUnimplemented
3068 parsePUNPCKHDQ = parseUnimplemented
3069 parsePACKSSDW = parseUnimplemented
3070 parsePUNPCKLQDQ = parseUnimplemented
3071 parsePUNPCKHQDQ = parseUnimplemented
3072 parsePSHUFW = parseUnimplemented
3073 parsePCMPEQB = parseUnimplemented
3074 parsePCMPEQW = parseUnimplemented
3075 parsePCMPEQD = parseUnimplemented
3076
3077 parseVMREAD b = 
3078     do st <- getState
3079        if in64BitMode st
3080           then do (op1, op2, mod, reg, rm) <- parseAddress32 OP64
3081                   return $ Instr VMREAD OP64 [op1, op2]
3082           else do (op1, op2, mod, reg, rm) <- parseAddress32 OP32
3083                   return $ Instr VMREAD OP32 [op1, op2]
3084 parseVMWRITE b = 
3085     do st <- getState
3086        if in64BitMode st
3087           then do (op1, op2, mod, reg, rm) <- parseAddress32 OP64
3088                   return $ Instr VMWRITE OP64 [op1, op2]
3089           else do (op1, op2, mod, reg, rm) <- parseAddress32 OP32
3090                   return $ Instr VMWRITE OP32 [op1, op2]
3091
3092 parseHADDPS = parseXmmVW InvalidOpcode InvalidOpcode HADDPD HADDPS
3093 parseHSUBPS = parseXmmVW InvalidOpcode InvalidOpcode HSUBPS HSUBPD
3094
3095 parseMOVD_Q = parseUnimplemented
3096
3097 parseJccLong b = do
3098   disp <- anyIntZ
3099   let disp' :: Int
3100       disp' = fromIntegral disp
3101   pos <- getPosition
3102   st <- getState
3103   return $ Instr (jccname (b .&. 0xf)) OPNONE
3104         [OpAddr (fromIntegral (disp' + sourceColumn pos - 1) +
3105                 (startAddr st)) OPNONE]
3106
3107 parseSETcc b = do
3108   (op1, op2, mod, reg, rm) <- parseAddress32 OP8
3109   case op1 of
3110     OpReg name num -> return $ Instr (setccname (b .&. 0xf)) OPNONE 
3111                       [OpReg (regnames8 !! fromIntegral num) num]
3112     _ -> return $ Instr (setccname (b .&. 0xf)) OPNONE [op1]
3113
3114 parseSHLD 0xa4 = 
3115     do opsize <- instrOperandSize
3116        (op1, op2, mod, reg, rm) <- parseAddress32 opsize
3117        b <- anyWord8
3118        opsize <- instrOperandSize
3119        return $ Instr SHLD opsize [op1, op2, OpImm (fromIntegral b)]
3120 parseSHLD 0xa5 = 
3121     do opsize <- instrOperandSize
3122        (op1, op2, mod, reg, rm) <- parseAddress32 opsize
3123        opsize <- instrOperandSize
3124        return $ Instr SHLD opsize [op1, op2, OpReg "cl" 1]
3125 parseSHRD 0xac = 
3126     do opsize <- instrOperandSize
3127        (op1, op2, mod, reg, rm) <- parseAddress32 opsize
3128        b <- anyWord8
3129        opsize <- instrOperandSize
3130        return $ Instr SHRD opsize [op1, op2, OpImm (fromIntegral b)]
3131 parseSHRD 0xad = 
3132     do opsize <- instrOperandSize
3133        (op1, op2, mod, reg, rm) <- parseAddress32 opsize
3134        opsize <- instrOperandSize
3135        return $ Instr SHRD opsize [op1, op2, OpReg "cl" 1]
3136
3137 parseCMPPS = parseUnimplemented
3138 parseMOVNTI = parseUnimplemented
3139 parsePINSRW = parseUnimplemented
3140 parsePEXTRW = parseUnimplemented
3141 parseSHUFPS = parseUnimplemented
3142
3143 parseBSWAP b = 
3144     do let reg = (b .&. 0xf) - 8
3145        r <- registerName (fromIntegral reg)
3146        opsize <- instrOperandSize
3147        return $ Instr BSWAP opsize [OpReg r (fromIntegral reg)]
3148
3149 parseADDSUBPS = parseXmmVW InvalidOpcode InvalidOpcode ADDSUBPD ADDUBPS
3150
3151 parseMmxXmmPQVW opcode b =
3152     do st <- getState
3153        if hasPrefix 0x66 st
3154           then do (op1, op2, mod, reg, rm) <- parseAddress32 OP128
3155                   let v = OpReg (xmmregs !! (fromIntegral reg)) 
3156                           (fromIntegral reg)
3157                   let w = case op1 of
3158                             OpReg _ num -> OpReg (xmmregs !! num) num
3159                             op -> op
3160                   return $ Instr opcode OP128 [v, w]
3161           else do (op1, op2, mod, reg, rm) <- parseAddress32 OP64
3162                   let p = OpReg (mmxregs !! (fromIntegral reg)) 
3163                           (fromIntegral reg)
3164                   let q = case op1 of
3165                             OpReg _ num -> OpReg (mmxregs !! num) num
3166                             op -> op
3167                   return $ Instr opcode OP128 [p, q]
3168
3169 parseMmxXmmMPMV opcode1 opcode2 b =
3170     do st <- getState
3171        if hasPrefix 0x66 st
3172           then do (op1, op2, mod, reg, rm) <- parseAddress32 OP128
3173                   let v = OpReg (xmmregs !! (fromIntegral reg)) 
3174                           (fromIntegral reg)
3175                   return $ Instr opcode2 OP128 [op1, v]
3176           else do (op1, op2, mod, reg, rm) <- parseAddress32 OP64
3177                   let p = OpReg (mmxregs !! (fromIntegral reg)) 
3178                           (fromIntegral reg)
3179                   return $ Instr opcode1 OP128 [op1, p]
3180
3181 parseMmxXmmPNVU opcode b =
3182     do st <- getState
3183        if hasPrefix 0x66 st
3184           then do (mod, reg, rm) <- parseModRM
3185                   let v = OpReg (xmmregs !! (fromIntegral reg)) 
3186                           (fromIntegral reg)
3187                   let u = OpReg (xmmregs !! (fromIntegral rm))
3188                           (fromIntegral reg)
3189                   return $ Instr opcode OP128 [v, u]
3190           else do (op1, op2, mod, reg, rm) <- parseAddress32 OP64
3191                   let p = OpReg (mmxregs !! (fromIntegral reg)) 
3192                           (fromIntegral reg)
3193                   let n = OpReg (mmxregs !! (fromIntegral rm))
3194                           (fromIntegral reg)
3195                   return $ Instr opcode OP128 [p, n]
3196
3197 parsePSRLW = parseMmxXmmPQVW PSRLW
3198 parsePSRLD = parseMmxXmmPQVW PSRLD
3199 parsePSRLQ = parseMmxXmmPQVW PSRLQ
3200 parsePADDQ = parseMmxXmmPQVW PADDQ
3201 parsePMULLW = parseMmxXmmPQVW PMULLW
3202 parseMOVQ b@0x6f = parseUnimplemented b
3203 parseMOVQ b@0x7f = parseUnimplemented b
3204 parseMOVQ b@0xd6 = 
3205     do st <- getState
3206        if hasPrefix 0x66 st
3207           then do (op1, op2, mod, reg, rm) <- parseAddress32 OP64
3208                   return $ Instr MOVQ OP64 [op1, op2]
3209           else if hasPrefix 0xf3 st
3210                   then do (mod, reg, rm) <- parseModRM
3211                           return $ Instr MOVQ OPNONE 
3212                                      [OpReg (xmmregs !! (fromIntegral reg))
3213                                       (fromIntegral reg),
3214                                       OpReg (mmxregs !! (fromIntegral rm))
3215                                       (fromIntegral rm)]
3216                   else
3217                     if hasPrefix 0xf2 st
3218                        then do (mod, reg, rm) <- parseModRM
3219                                return $ Instr MOVQ OPNONE
3220                                 [OpReg (mmxregs !! (fromIntegral reg))
3221                                  (fromIntegral reg),
3222                                  OpReg (xmmregs !! (fromIntegral rm))
3223                                  (fromIntegral rm)]
3224                        else parseInvalidOpcode b
3225                           
3226 parsePMOVMSKB b = 
3227     do st <- getState
3228        (mod, reg, rm) <- parseModRM
3229        if hasPrefix 0x66 st
3230           then do return $ Instr PMOVMSKB OPNONE 
3231                              [OpReg (regnames32 !! (fromIntegral reg))
3232                               (fromIntegral reg),
3233                               OpReg (xmmregs !! (fromIntegral rm))
3234                               (fromIntegral rm)]
3235           else do return $ Instr PMOVMSKB OPNONE 
3236                              [OpReg (regnames32 !! (fromIntegral reg))
3237                               (fromIntegral reg),
3238                               OpReg (mmxregs !! (fromIntegral rm))
3239                               (fromIntegral rm)]
3240 parsePSUBUSB = parseMmxXmmPQVW PSUBUSB
3241 parsePSUBUSW = parseMmxXmmPQVW PSUBUSW
3242 parsePMINUB = parseMmxXmmPQVW PMINUB
3243 parsePAND = parseMmxXmmPQVW PAND
3244 parsePADDUSB = parseMmxXmmPQVW PADDUSB
3245 parsePADDUSW = parseMmxXmmPQVW PADDUSW
3246 parsePMAXUB = parseMmxXmmPQVW PMAXUB
3247 parsePANDN = parseMmxXmmPQVW PANDN
3248 parsePAVGB = parseMmxXmmPQVW PAVGB
3249 parsePSRAW = parseMmxXmmPQVW PSRAW
3250 parsePSRAD = parseMmxXmmPQVW PSRAD
3251 parsePAVGW = parseMmxXmmPQVW PAVGW
3252 parseCVTPD2DQ = parseUnimplemented
3253 parsePMULHUW = parseMmxXmmPQVW PMULHUW
3254 parsePMULHW = parseMmxXmmPQVW PMULHW
3255 parseMOVNTQ = parseMmxXmmMPMV MOVNTQ MOVNTDQ
3256 parsePSUBSB = parseMmxXmmPQVW PSUBSB
3257 parsePSUBSQ = parseMmxXmmPQVW PSUBSQ
3258 parsePMINSW = parseMmxXmmPQVW PMINSW
3259 parsePOR = parseMmxXmmPQVW POR
3260 parsePADDSB = parseMmxXmmPQVW PADDSB
3261 parsePADDSW = parseMmxXmmPQVW PADDSW
3262 parsePMAXSW = parseMmxXmmPQVW PMAXSW
3263 parsePXOR = parseMmxXmmPQVW PXOR
3264 parseLDDQU b = 
3265     do st <- getState
3266        if hasPrefix 0xf2 st
3267           then do (op1, op2, mod, reg, rm) <- parseAddress32 OP128
3268                   let v = OpReg (xmmregs !! (fromIntegral reg))
3269                           (fromIntegral reg)
3270                   return $ Instr LDDQU OP128 [v, op1]
3271           else parseInvalidOpcode b
3272 parsePSLLW = parseMmxXmmPQVW PSLLW
3273 parsePSLLD = parseMmxXmmPQVW PSLLD
3274 parsePSLLQ = parseMmxXmmPQVW PSLLQ
3275 parsePMULUDQ = parseMmxXmmPQVW PMULUDQ
3276 parsePMADDWD = parseMmxXmmPQVW PMADDWD
3277 parsePSADBW = parseMmxXmmPQVW PSADBW
3278 parseMASKMOVQ = parseMmxXmmPNVU MASKMOVQ
3279 parsePSUBB = parseMmxXmmPQVW PSUBB
3280 parsePSUBW = parseMmxXmmPQVW PSUBW
3281 parsePSUBD = parseMmxXmmPQVW PSUBD
3282 parsePSUBQ = parseMmxXmmPQVW PSUBQ
3283 parsePADDB = parseMmxXmmPQVW PADDB
3284 parsePADDW = parseMmxXmmPQVW PADDW
3285 parsePADDD = parseMmxXmmPQVW PADDD