--- /dev/null
+{-# LANGUAGE MultiParamTypeClasses,FlexibleInstances,FunctionalDependencies #-}
+--------------------------------------------------------------------------
+-- |
+-- Module : Harpy.X86Assembler
+-- Copyright : (c) 2006-2007 Martin Grabmueller and Dirk Kleeblatt
+-- License : GPL
+--
+-- Maintainer : {magr,klee}@cs.tu-berlin.de
+-- Stability : provisional
+-- Portability : non-portable
+--
+-- A type class based layer on top of X86CodeGen
+-- which determines the addressing modes from the types of the
+-- operands.
+--------------------------------------------------------------------------
+module Harpy.X86Assembler (
+ module Harpy.X86Assembler,
+ XMMReg(..),
+ ) where
+
+import Harpy.X86CodeGen
+import Harpy.CodeGenMonad
+import Data.Word
+import Foreign.Ptr
+
+import qualified Text.PrettyPrint.HughesPJ as PP
+
+
+-- address modes used in this module:
+
+-- Word8/16/32 immediate values
+-- Reg8/16/32 register
+-- Addr Word32 absolut
+-- Ind Reg32 register indirect
+-- (Disp, Reg32) register indirect with displacement
+-- (Reg32, Reg32, Scale) (base, index, scale), effective address is (base + index * scale)
+-- (Disp, Reg32, Scale) (disp, index, scale), effective address is (disp + index * scale)
+-- (Disp, Reg32, Reg32, Scale) (base, index, scale) + displacement (only ebp is allowed as base register)
+-- Label not-yet-specified label
+
+onlyEbp = failCodeGen (PP.text "only epb is allowed as base register for disp/base/index/scale addressing")
+onlyCl = failCodeGen (PP.text "only cl is allowed as shift count")
+
+
+-- x86 Registers
+
+newtype Reg8 = Reg8 Word8
+al, cl, dl, bl, ah, ch, dh, bh :: Reg8
+
+al = Reg8 0
+cl = Reg8 1
+dl = Reg8 2
+bl = Reg8 3
+ah = Reg8 4
+ch = Reg8 5
+dh = Reg8 6
+bh = Reg8 7
+
+newtype Reg16 = Reg16 Word8
+ax, cx, dx, bx, sp, bp, si, di :: Reg16
+
+ax = Reg16 0
+cx = Reg16 1
+dx = Reg16 2
+bx = Reg16 3
+sp = Reg16 4
+bp = Reg16 5
+si = Reg16 6
+di = Reg16 7
+
+newtype Reg32 = Reg32 Word8 deriving (Eq, Ord)
+eax, ecx, edx, ebx, esp, ebp, esi, edi :: Reg32
+
+eax = Reg32 0
+ecx = Reg32 1
+edx = Reg32 2
+ebx = Reg32 3
+esp = Reg32 4
+ebp = Reg32 5
+esi = Reg32 6
+edi = Reg32 7
+
+{-
+newtype XMMReg = XMMReg Word8
+ deriving (Eq, Ord)
+-}
+
+xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 :: XMMReg
+xmm0 = XMMReg 0
+xmm1 = XMMReg 1
+xmm2 = XMMReg 2
+xmm3 = XMMReg 3
+xmm4 = XMMReg 4
+xmm5 = XMMReg 5
+xmm6 = XMMReg 6
+xmm7 = XMMReg 7
+
+instance Show XMMReg where
+ show (XMMReg i) = "xmm" ++ show i
+
+-- TODO: instances for other registers
+
+instance Show Reg32 where
+ show (Reg32 0) = "eax"
+ show (Reg32 1) = "ecx"
+ show (Reg32 2) = "edx"
+ show (Reg32 3) = "ebx"
+ show (Reg32 4) = "esp"
+ show (Reg32 5) = "ebp"
+ show (Reg32 6) = "esi"
+ show (Reg32 7) = "edi"
+
+-- memory addresses
+
+newtype Addr = Addr Word32
+newtype Ind = Ind Reg32
+newtype Disp = Disp Word32
+
+data Scale = S1 | S2 | S4 | S8
+
+scaleToShift :: Scale -> Word8
+scaleToShift S1 = 0
+scaleToShift S2 = 1
+scaleToShift S4 = 2
+scaleToShift S8 = 3
+
+newtype FPReg = FPReg Word8
+
+data FPTopReg = FPTopReg
+
+fpTop = FPTopReg
+
+fp0 = FPReg 0
+fp1 = FPReg 1
+fp2 = FPReg 2
+fp3 = FPReg 3
+fp4 = FPReg 4
+fp5 = FPReg 5
+fp6 = FPReg 6
+fp7 = FPReg 7
+
+-- int 3
+
+breakpoint = ensureBufferSize x86_max_instruction_bytes >> x86_breakpoint
+
+
+-- clear direction flag
+
+cld = ensureBufferSize x86_max_instruction_bytes >> x86_cld
+
+
+-- store string
+
+stosb = ensureBufferSize x86_max_instruction_bytes >> x86_stosb
+stosl = ensureBufferSize x86_max_instruction_bytes >> x86_stosl
+stosd = ensureBufferSize x86_max_instruction_bytes >> x86_stosd
+
+
+-- move string
+
+movsb = ensureBufferSize x86_max_instruction_bytes >> x86_movsb
+movsl = ensureBufferSize x86_max_instruction_bytes >> x86_movsl
+--movsd = ensureBufferSize x86_max_instruction_bytes >> x86_movsd
+
+
+-- read time stamp counter
+
+rdtsc = ensureBufferSize x86_max_instruction_bytes >> x86_rdtsc
+
+
+-- compare and exchange
+
+class Cmpxchg a b where
+ cmpxchg :: a -> b -> CodeGen e s ()
+
+instance Cmpxchg Reg32 Reg32 where
+ cmpxchg (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmpxchg_reg_reg dest source
+
+instance Cmpxchg Addr Reg32 where
+ cmpxchg (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmpxchg_mem_reg dest source
+
+instance Cmpxchg (Disp, Reg32) Reg32 where
+ cmpxchg (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmpxchg_membase_reg dest disp source
+
+instance Cmpxchg Ind Reg32 where
+ cmpxchg (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmpxchg_membase_reg dest 0 source
+
+
+
+-- exchange memory/register with register
+
+class Xchg a b where
+ xchg :: a -> b -> CodeGen e s ()
+
+instance Xchg Reg8 Reg8 where
+ xchg (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xchg_reg_reg dest source 1
+
+instance Xchg Reg32 Reg32 where
+ xchg (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xchg_reg_reg dest source 4
+
+instance Xchg Addr Reg8 where
+ xchg (Addr dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xchg_mem_reg dest source 1
+
+instance Xchg Addr Reg32 where
+ xchg (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xchg_mem_reg dest source 4
+
+instance Xchg (Disp, Reg32) Reg8 where
+ xchg (Disp disp, Reg32 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xchg_membase_reg dest disp source 1
+
+instance Xchg Ind Reg8 where
+ xchg (Ind (Reg32 dest)) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xchg_membase_reg dest 0 source 1
+
+instance Xchg (Disp, Reg32) Reg32 where
+ xchg (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xchg_membase_reg dest disp source 4
+
+instance Xchg Ind Reg32 where
+ xchg (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xchg_membase_reg dest 0 source 4
+
+
+-- exchange and add
+
+class Xadd a b where
+ xadd :: a -> b -> CodeGen e s ()
+
+instance Xadd Reg8 Reg8 where
+ xadd (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xadd_reg_reg dest source 1
+
+instance Xadd Reg32 Reg32 where
+ xadd (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xadd_reg_reg dest source 4
+
+instance Xadd Addr Reg8 where
+ xadd (Addr dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xadd_mem_reg dest source 1
+
+instance Xadd Addr Reg32 where
+ xadd (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xadd_mem_reg dest source 4
+
+instance Xadd (Disp, Reg32) Reg8 where
+ xadd (Disp disp, Reg32 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xadd_membase_reg dest disp source 1
+
+instance Xadd Ind Reg8 where
+ xadd (Ind (Reg32 dest)) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xadd_membase_reg dest 0 source 1
+
+instance Xadd (Disp, Reg32) Reg32 where
+ xadd (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xadd_membase_reg dest disp source 4
+
+instance Xadd Ind Reg32 where
+ xadd (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xadd_membase_reg dest 0 source 4
+
+
+-- Increment by 1
+
+class Inc a where
+ inc :: a -> CodeGen e s ()
+
+instance Inc Addr where
+ inc (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_inc_mem dest
+
+instance Inc (Disp, Reg32) where
+ inc (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_inc_membase dest disp
+
+instance Inc Ind where
+ inc (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_inc_membase dest 0
+
+instance Inc Reg32 where
+ inc (Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_inc_reg dest
+
+
+-- Decrement by 1
+
+class Dec a where
+ dec :: a -> CodeGen e s ()
+
+instance Dec Addr where
+ dec (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_dec_mem dest
+
+instance Dec (Disp, Reg32) where
+ dec (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_dec_membase dest disp
+
+instance Dec Ind where
+ dec (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_dec_membase dest 0
+
+instance Dec Reg32 where
+ dec (Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_dec_reg dest
+
+
+-- One's complement negation
+
+class Not a where
+ not :: a -> CodeGen e s ()
+
+instance Not Addr where
+ not (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_not_mem dest
+
+instance Not (Disp, Reg32) where
+ not (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_not_membase dest disp
+
+instance Not Ind where
+ not (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_not_membase dest 0
+
+instance Not Reg32 where
+ not (Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_not_reg dest
+
+
+-- Two's complement negation
+
+class Neg a where
+ neg :: a -> CodeGen e s ()
+
+instance Neg Addr where
+ neg (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_neg_mem dest
+
+instance Neg (Disp, Reg32) where
+ neg (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_neg_membase dest disp
+
+instance Neg Ind where
+ neg (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_neg_membase dest 0
+
+instance Neg Reg32 where
+ neg (Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_neg_reg dest
+
+
+-- No operation
+
+nop = ensureBufferSize x86_max_instruction_bytes >> x86_nop
+
+
+-- ALU operations
+
+-- Calling "x86_alu_reg8_reg8 _ _ _ *False* *False*" is a little bit hackish: the last two
+-- arguments are set to True for the "high byte registers" ah, bh, ch and dh.
+-- x86_reg8_emit then sets the 3rd bit in the register number. This bit is set in our
+-- encoding anyway to the right value, so we simply skip this part.
+
+class Add a b where
+ add :: a -> b -> CodeGen e s ()
+
+instance Add Reg32 Word32 where
+ add (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_imm x86_add dest (fromIntegral imm)
+
+instance Add Addr Word32 where
+ add (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_imm x86_add dest (fromIntegral imm)
+
+instance Add (Disp, Reg32) Word32 where
+ add (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_add dest disp (fromIntegral imm)
+
+instance Add Ind Word32 where
+ add (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_add dest 0 (fromIntegral imm)
+
+instance Add (Disp, Reg32) Word8 where
+ add (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_add dest disp (fromIntegral imm)
+
+instance Add Ind Word8 where
+ add (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_add dest 0 (fromIntegral imm)
+
+instance Add Addr Reg32 where
+ add (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_reg x86_add dest source
+
+instance Add (Disp, Reg32) Reg32 where
+ add (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_add dest disp source
+
+instance Add Ind Reg32 where
+ add (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_add dest 0 source
+
+instance Add Reg32 Reg32 where
+ add (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_reg x86_add dest source
+
+instance Add Reg8 Reg8 where
+ add (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg8_reg8 x86_add dest source False False
+
+instance Add Reg32 Addr where
+ add (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_mem x86_add dest source
+
+instance Add Reg32 (Disp, Reg32) where
+ add (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_add dest source disp
+
+instance Add Reg32 Ind where
+ add (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_add dest source 0
+
+
+class Or a b where
+ or :: a -> b -> CodeGen e s ()
+
+instance Or Reg32 Word32 where
+ or (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_imm x86_or dest (fromIntegral imm)
+
+instance Or Addr Word32 where
+ or (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_imm x86_or dest (fromIntegral imm)
+
+instance Or (Disp, Reg32) Word32 where
+ or (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_or dest disp (fromIntegral imm)
+
+instance Or Ind Word32 where
+ or (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_or dest 0 (fromIntegral imm)
+
+instance Or (Disp, Reg32) Word8 where
+ or (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_or dest disp (fromIntegral imm)
+
+instance Or Ind Word8 where
+ or (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_or dest 0 (fromIntegral imm)
+
+instance Or Addr Reg32 where
+ or (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_reg x86_or dest source
+
+instance Or (Disp, Reg32) Reg32 where
+ or (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_or dest disp source
+
+instance Or Ind Reg32 where
+ or (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_or dest 0 source
+
+instance Or Reg32 Reg32 where
+ or (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_reg x86_or dest source
+
+instance Or Reg8 Reg8 where
+ or (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg8_reg8 x86_or dest source False False
+
+instance Or Reg32 Addr where
+ or (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_mem x86_or dest source
+
+instance Or Reg32 (Disp, Reg32) where
+ or (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_or dest source disp
+
+instance Or Reg32 Ind where
+ or (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_or dest source 0
+
+
+class Adc a b where
+ adc :: a -> b -> CodeGen e s ()
+
+instance Adc Reg32 Word32 where
+ adc (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_imm x86_adc dest (fromIntegral imm)
+
+instance Adc Addr Word32 where
+ adc (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_imm x86_adc dest (fromIntegral imm)
+
+instance Adc (Disp, Reg32) Word32 where
+ adc (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_adc dest disp (fromIntegral imm)
+
+instance Adc Ind Word32 where
+ adc (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_adc dest 0 (fromIntegral imm)
+
+instance Adc (Disp, Reg32) Word8 where
+ adc (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_adc dest disp (fromIntegral imm)
+
+instance Adc Ind Word8 where
+ adc (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_adc dest 0 (fromIntegral imm)
+
+instance Adc Addr Reg32 where
+ adc (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_reg x86_adc dest source
+
+instance Adc (Disp, Reg32) Reg32 where
+ adc (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_adc dest disp source
+
+instance Adc Ind Reg32 where
+ adc (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_adc dest 0 source
+
+instance Adc Reg32 Reg32 where
+ adc (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_reg x86_adc dest source
+
+instance Adc Reg8 Reg8 where
+ adc (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg8_reg8 x86_adc dest source False False
+
+instance Adc Reg32 Addr where
+ adc (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_mem x86_adc dest source
+
+instance Adc Reg32 (Disp, Reg32) where
+ adc (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_adc dest source disp
+
+instance Adc Reg32 Ind where
+ adc (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_adc dest source 0
+
+
+class Sbb a b where
+ sbb :: a -> b -> CodeGen e s ()
+
+instance Sbb Reg32 Word32 where
+ sbb (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_imm x86_sbb dest (fromIntegral imm)
+
+instance Sbb Addr Word32 where
+ sbb (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_imm x86_sbb dest (fromIntegral imm)
+
+instance Sbb (Disp, Reg32) Word32 where
+ sbb (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_sbb dest disp (fromIntegral imm)
+
+instance Sbb Ind Word32 where
+ sbb (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_sbb dest 0 (fromIntegral imm)
+
+instance Sbb (Disp, Reg32) Word8 where
+ sbb (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_sbb dest disp (fromIntegral imm)
+
+instance Sbb Ind Word8 where
+ sbb (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_sbb dest 0 (fromIntegral imm)
+
+instance Sbb Addr Reg32 where
+ sbb (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_reg x86_sbb dest source
+
+instance Sbb (Disp, Reg32) Reg32 where
+ sbb (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_sbb dest disp source
+
+instance Sbb Ind Reg32 where
+ sbb (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_sbb dest 0 source
+
+instance Sbb Reg32 Reg32 where
+ sbb (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_reg x86_sbb dest source
+
+instance Sbb Reg8 Reg8 where
+ sbb (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg8_reg8 x86_sbb dest source False False
+
+instance Sbb Reg32 Addr where
+ sbb (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_mem x86_sbb dest source
+
+instance Sbb Reg32 (Disp, Reg32) where
+ sbb (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_sbb dest source disp
+
+instance Sbb Reg32 Ind where
+ sbb (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_sbb dest source 0
+
+
+class And a b where
+ and :: a -> b -> CodeGen e s ()
+
+instance And Reg32 Word32 where
+ and (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_imm x86_and dest (fromIntegral imm)
+
+instance And Addr Word32 where
+ and (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_imm x86_and dest (fromIntegral imm)
+
+instance And (Disp, Reg32) Word32 where
+ and (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_and dest disp (fromIntegral imm)
+
+instance And Ind Word32 where
+ and (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_and dest 0 (fromIntegral imm)
+
+instance And (Disp, Reg32) Word8 where
+ and (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_and dest disp (fromIntegral imm)
+
+instance And Ind Word8 where
+ and (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_and dest 0 (fromIntegral imm)
+
+instance And Addr Reg32 where
+ and (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_reg x86_and dest source
+
+instance And (Disp, Reg32) Reg32 where
+ and (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_and dest disp source
+
+instance And Ind Reg32 where
+ and (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_and dest 0 source
+
+instance And Reg32 Reg32 where
+ and (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_reg x86_and dest source
+
+instance And Reg8 Reg8 where
+ and (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg8_reg8 x86_and dest source False False
+
+instance And Reg32 Addr where
+ and (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_mem x86_and dest source
+
+instance And Reg32 (Disp, Reg32) where
+ and (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_and dest source disp
+
+instance And Reg32 Ind where
+ and (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_and dest source 0
+
+
+class Sub a b where
+ sub :: a -> b -> CodeGen e s ()
+
+instance Sub Reg32 Word32 where
+ sub (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_imm x86_sub dest (fromIntegral imm)
+
+instance Sub Addr Word32 where
+ sub (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_reg x86_sub dest (fromIntegral imm)
+
+instance Sub (Disp, Reg32) Word32 where
+ sub (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_sub dest disp (fromIntegral imm)
+
+instance Sub Ind Word32 where
+ sub (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_sub dest 0 (fromIntegral imm)
+
+instance Sub (Disp, Reg32) Word8 where
+ sub (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_sub dest disp (fromIntegral imm)
+
+instance Sub Ind Word8 where
+ sub (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_sub dest 0 (fromIntegral imm)
+
+instance Sub Addr Reg32 where
+ sub (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_reg x86_sub dest source
+
+instance Sub (Disp, Reg32) Reg32 where
+ sub (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_sub dest disp source
+
+instance Sub Ind Reg32 where
+ sub (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_sub dest 0 source
+
+instance Sub Reg32 Reg32 where
+ sub (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_reg x86_sub dest source
+
+instance Sub Reg8 Reg8 where
+ sub (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg8_reg8 x86_sub dest source False False
+
+instance Sub Reg32 Addr where
+ sub (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_mem x86_sub dest source
+
+instance Sub Reg32 (Disp, Reg32) where
+ sub (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_sub dest source disp
+
+instance Sub Reg32 Ind where
+ sub (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_sub dest source 0
+
+
+class Xor a b where
+ xor :: a -> b -> CodeGen e s ()
+
+instance Xor Reg32 Word32 where
+ xor (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_imm x86_xor dest (fromIntegral imm)
+
+instance Xor Addr Word32 where
+ xor (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_imm x86_xor dest (fromIntegral imm)
+
+instance Xor (Disp, Reg32) Word32 where
+ xor (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_xor dest disp (fromIntegral imm)
+
+instance Xor Ind Word32 where
+ xor (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_xor dest 0 (fromIntegral imm)
+
+instance Xor (Disp, Reg32) Word8 where
+ xor (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_xor dest disp (fromIntegral imm)
+
+instance Xor Ind Word8 where
+ xor (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_xor dest 0 (fromIntegral imm)
+
+instance Xor Addr Reg32 where
+ xor (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_reg x86_xor dest source
+
+instance Xor (Disp, Reg32) Reg32 where
+ xor (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_xor dest disp source
+
+instance Xor Ind Reg32 where
+ xor (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_xor dest 0 source
+
+instance Xor Reg32 Reg32 where
+ xor (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_reg x86_xor dest source
+
+instance Xor Reg8 Reg8 where
+ xor (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg8_reg8 x86_xor dest source False False
+
+instance Xor Reg32 Addr where
+ xor (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_mem x86_xor dest source
+
+instance Xor Reg32 (Disp, Reg32) where
+ xor (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_xor dest source disp
+
+instance Xor Reg32 Ind where
+ xor (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_xor dest source 0
+
+
+class Cmp a b where
+ cmp :: a -> b -> CodeGen e s ()
+
+instance Cmp Reg32 Word32 where
+ cmp (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_imm x86_cmp dest (fromIntegral imm)
+
+instance Cmp Reg32 (Ptr a) where
+ cmp (Reg32 dest) ptr = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_imm x86_cmp dest (ptrToInt ptr)
+
+instance Cmp Reg32 Label where
+ cmp (Reg32 dest) lab = do
+ ensureBufferSize x86_max_instruction_bytes
+ x86_alu_reg_imm x86_cmp dest 0xf0f0f0f0
+ emitFixup lab (-4) Fixup32Absolute
+
+instance Cmp Addr Word32 where
+ cmp (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_imm x86_cmp dest (fromIntegral imm)
+
+instance Cmp Addr (Ptr a) where
+ cmp (Addr dest) ptr = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_imm x86_cmp dest (ptrToWord32 ptr)
+
+instance Cmp Addr Label where
+ cmp (Addr dest) lab = do
+ ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_imm x86_cmp dest 0xf0f0f0f0
+ emitFixup lab (-4) Fixup32Absolute
+
+instance Cmp (Disp, Reg32) Word32 where
+ cmp (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_cmp dest disp (fromIntegral imm)
+
+instance Cmp (Disp, Reg32) (Ptr a) where
+ cmp (Disp disp, Reg32 dest) ptr = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_cmp dest disp (ptrToWord32 ptr)
+
+instance Cmp (Disp, Reg32) Label where
+ cmp (Disp disp, Reg32 dest) lab = do
+ ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_cmp dest disp 0xf0f0f0f0
+ emitFixup lab (-4) Fixup32Absolute
+
+instance Cmp Ind Word32 where
+ cmp (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_cmp dest 0 (fromIntegral imm)
+
+instance Cmp Ind (Ptr a) where
+ cmp (Ind (Reg32 dest)) ptr = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_cmp dest 0 (ptrToWord32 ptr)
+
+instance Cmp Ind Label where
+ cmp (Ind (Reg32 dest)) lab = do
+ ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_cmp dest 0 0xf0f0f0f0
+ emitFixup lab (-4) Fixup32Absolute
+
+instance Cmp (Disp, Reg32) Word8 where
+ cmp (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_cmp dest disp imm
+
+instance Cmp Ind Word8 where
+ cmp (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_cmp dest 0 imm
+
+instance Cmp Addr Reg32 where
+ cmp (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_reg x86_cmp dest source
+
+instance Cmp (Disp, Reg32) Reg32 where
+ cmp (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_cmp dest disp source
+
+instance Cmp Ind Reg32 where
+ cmp (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_cmp dest 0 source
+
+instance Cmp Reg32 Reg32 where
+ cmp (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_reg x86_cmp dest source
+
+instance Cmp Reg8 Reg8 where
+ cmp (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg8_reg8 x86_cmp dest source False False
+
+instance Cmp Reg32 Addr where
+ cmp (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_mem x86_cmp dest source
+
+instance Cmp Reg32 (Disp, Reg32) where
+ cmp (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_cmp dest source disp
+
+instance Cmp Reg32 Ind where
+ cmp (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_cmp dest source 0
+
+
+-- logical compare
+
+class Test a b where
+ test :: a -> b -> CodeGen e s ()
+
+instance Test Reg32 Word32 where
+ test (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_test_reg_imm dest imm
+
+instance Test Addr Word32 where
+ test (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_test_mem_imm dest imm
+
+instance Test (Disp, Reg32) Word32 where
+ test (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_test_membase_imm dest disp imm
+
+instance Test Ind Word32 where
+ test (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_test_membase_imm dest 0 imm
+
+instance Test Reg32 Reg32 where
+ test (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_test_reg_reg dest source
+
+instance Test Addr Reg32 where
+ test (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_test_mem_reg dest source
+
+instance Test (Disp, Reg32) Reg32 where
+ test (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_test_membase_reg dest disp source
+
+instance Test Ind Reg32 where
+ test (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_test_membase_reg dest 0 source
+
+
+-- shift and rotate
+
+class Rol a b where
+ rol :: a -> b -> CodeGen e s ()
+
+instance Rol Reg32 Word8 where
+ rol (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg_imm x86_rol dest imm
+
+instance Rol Addr Word8 where
+ rol (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem_imm x86_rol dest imm
+
+instance Rol (Disp, Reg32) Word8 where
+ rol (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_rol dest disp imm
+
+instance Rol Ind Word8 where
+ rol (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_rol dest 0 imm
+
+instance Rol Reg32 Reg8 where
+ rol (Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg x86_rol dest
+ rol _ _ = onlyCl
+
+instance Rol Addr Reg8 where
+ rol (Addr dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem x86_rol dest
+ rol _ _ = onlyCl
+
+instance Rol (Disp, Reg32) Reg8 where
+ rol (Disp disp, Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_rol dest disp
+
+instance Rol Ind Reg8 where
+ rol (Ind (Reg32 dest)) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_rol dest 0
+ rol _ _ = onlyCl
+
+class Ror a b where
+ ror :: a -> b -> CodeGen e s ()
+
+instance Ror Reg32 Word8 where
+ ror (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg_imm x86_ror dest imm
+
+instance Ror Addr Word8 where
+ ror (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem_imm x86_ror dest imm
+
+instance Ror (Disp, Reg32) Word8 where
+ ror (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_ror dest disp imm
+
+instance Ror Ind Word8 where
+ ror (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_ror dest 0 imm
+
+instance Ror Reg32 Reg8 where
+ ror (Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg x86_ror dest
+ ror _ _ = onlyCl
+
+instance Ror Addr Reg8 where
+ ror (Addr dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem x86_ror dest
+ ror _ _ = onlyCl
+
+instance Ror (Disp, Reg32) Reg8 where
+ ror (Disp disp, Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_ror dest disp
+
+instance Ror Ind Reg8 where
+ ror (Ind (Reg32 dest)) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_ror dest 0
+ ror _ _ = onlyCl
+
+class Rcl a b where
+ rcl :: a -> b -> CodeGen e s ()
+
+instance Rcl Reg32 Word8 where
+ rcl (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg_imm x86_rcl dest imm
+
+instance Rcl Addr Word8 where
+ rcl (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem_imm x86_rcl dest imm
+
+instance Rcl (Disp, Reg32) Word8 where
+ rcl (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_rcl dest disp imm
+
+instance Rcl Ind Word8 where
+ rcl (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_rcl dest 0 imm
+
+instance Rcl Reg32 Reg8 where
+ rcl (Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg x86_rcl dest
+ rcl _ _ = onlyCl
+
+instance Rcl Addr Reg8 where
+ rcl (Addr dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem x86_rcl dest
+ rcl _ _ = onlyCl
+
+instance Rcl (Disp, Reg32) Reg8 where
+ rcl (Disp disp, Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_rcl dest disp
+
+instance Rcl Ind Reg8 where
+ rcl (Ind (Reg32 dest)) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_rcl dest 0
+ rcl _ _ = onlyCl
+
+class Rcr a b where
+ rcr :: a -> b -> CodeGen e s ()
+
+instance Rcr Reg32 Word8 where
+ rcr (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg_imm x86_rcr dest imm
+
+instance Rcr Addr Word8 where
+ rcr (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem_imm x86_rcr dest imm
+
+instance Rcr (Disp, Reg32) Word8 where
+ rcr (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_rcr dest disp imm
+
+instance Rcr Ind Word8 where
+ rcr (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_rcr dest 0 imm
+
+instance Rcr Reg32 Reg8 where
+ rcr (Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg x86_rcr dest
+ rcr _ _ = onlyCl
+
+instance Rcr Addr Reg8 where
+ rcr (Addr dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem x86_rcr dest
+ rcr _ _ = onlyCl
+
+instance Rcr (Disp, Reg32) Reg8 where
+ rcr (Disp disp, Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_rcr dest disp
+
+instance Rcr Ind Reg8 where
+ rcr (Ind (Reg32 dest)) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_rcr dest 0
+ rcr _ _ = onlyCl
+
+class Shl a b where
+ shl :: a -> b -> CodeGen e s ()
+
+instance Shl Reg32 Word8 where
+ shl (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg_imm x86_shl dest imm
+
+instance Shl Addr Word8 where
+ shl (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem_imm x86_shl dest imm
+
+instance Shl (Disp, Reg32) Word8 where
+ shl (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_shl dest disp imm
+
+instance Shl Ind Word8 where
+ shl (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_shl dest 0 imm
+
+instance Shl Reg32 Reg8 where
+ shl (Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg x86_shl dest
+ shl _ _ = onlyCl
+
+instance Shl Addr Reg8 where
+ shl (Addr dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem x86_shl dest
+ shl _ _ = onlyCl
+
+instance Shl (Disp, Reg32) Reg8 where
+ shl (Disp disp, Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_shl dest disp
+
+instance Shl Ind Reg8 where
+ shl (Ind (Reg32 dest)) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_shl dest 0
+ shl _ _ = onlyCl
+
+class Shr a b where
+ shr :: a -> b -> CodeGen e s ()
+
+instance Shr Reg32 Word8 where
+ shr (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg_imm x86_shr dest imm
+
+instance Shr Addr Word8 where
+ shr (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem_imm x86_shr dest imm
+
+instance Shr (Disp, Reg32) Word8 where
+ shr (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_shr dest disp imm
+
+instance Shr Ind Word8 where
+ shr (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_shr dest 0 imm
+
+instance Shr Reg32 Reg8 where
+ shr (Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg x86_shr dest
+ shr _ _ = onlyCl
+
+instance Shr Addr Reg8 where
+ shr (Addr dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem x86_shr dest
+ shr _ _ = onlyCl
+
+instance Shr (Disp, Reg32) Reg8 where
+ shr (Disp disp, Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_shr dest disp
+
+instance Shr Ind Reg8 where
+ shr (Ind (Reg32 dest)) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_shr dest 0
+ shr _ _ = onlyCl
+
+class Sar a b where
+ sar :: a -> b -> CodeGen e s ()
+
+instance Sar Reg32 Word8 where
+ sar (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg_imm x86_sar dest imm
+
+instance Sar Addr Word8 where
+ sar (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem_imm x86_sar dest imm
+
+instance Sar (Disp, Reg32) Word8 where
+ sar (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_sar dest disp imm
+
+instance Sar Ind Word8 where
+ sar (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_sar dest 0 imm
+
+instance Sar Reg32 Reg8 where
+ sar (Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg x86_sar dest
+ sar _ _ = onlyCl
+
+instance Sar Addr Reg8 where
+ sar (Addr dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem x86_sar dest
+ sar _ _ = onlyCl
+
+instance Sar (Disp, Reg32) Reg8 where
+ sar (Disp disp, Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_sar dest disp
+
+instance Sar Ind Reg8 where
+ sar (Ind (Reg32 dest)) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_sar dest 0
+ sar _ _ = onlyCl
+
+class Sal a b where
+ sal :: a -> b -> CodeGen e s ()
+
+instance Sal Reg32 Word8 where
+ sal (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg_imm x86_shl dest imm
+
+instance Sal Addr Word8 where
+ sal (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem_imm x86_shl dest imm
+
+instance Sal (Disp, Reg32) Word8 where
+ sal (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_shl dest disp imm
+
+instance Sal Ind Word8 where
+ sal (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_shl dest 0 imm
+
+instance Sal Reg32 Reg8 where
+ sal (Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg x86_shl dest
+ sal _ _ = onlyCl
+
+instance Sal Addr Reg8 where
+ sal (Addr dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem x86_shl dest
+ sal _ _ = onlyCl
+
+instance Sal (Disp, Reg32) Reg8 where
+ sal (Disp disp, Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_shl dest disp
+
+instance Sal Ind Reg8 where
+ sal (Ind (Reg32 dest)) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_shl dest 0
+ sal _ _ = onlyCl
+
+
+-- double precision shift right
+
+class Shrd a b c where
+ shrd :: a -> b -> c -> CodeGen e s ()
+
+instance Shrd Reg32 Reg32 Reg8 where
+ shrd (Reg32 dest) (Reg32 source) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shrd_reg dest source
+ shrd _ _ _ = onlyCl
+
+instance Shrd Reg32 Reg32 Word8 where
+ shrd (Reg32 dest) (Reg32 source) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shrd_reg_imm dest source imm
+
+
+-- double precision shift left
+
+class Shld a b c where
+ shld :: a -> b -> c -> CodeGen e s ()
+
+instance Shld Reg32 Reg32 Reg8 where
+ shld (Reg32 dest) (Reg32 source) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shld_reg dest source
+ shld _ _ _ = onlyCl
+
+instance Shld Reg32 Reg32 Word8 where
+ shld (Reg32 dest) (Reg32 source) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shld_reg_imm dest source imm
+
+
+-- unsigned multiply
+
+class Mul a where
+ mul :: a -> CodeGen e s ()
+
+instance Mul Reg32 where
+ mul (Reg32 arg) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_reg arg False
+
+instance Mul Addr where
+ mul (Addr arg) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_mem arg False
+
+instance Mul (Disp, Reg32) where
+ mul (Disp disp, Reg32 arg) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_membase arg disp False
+
+instance Mul Ind where
+ mul (Ind (Reg32 arg)) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_membase arg 0 False
+
+
+-- signed multiply
+
+data InPlace = InPlace
+
+-- if a == InPlace then
+-- b = b * c
+-- else
+-- a = b * c
+
+class Imul a b c where
+ imul :: a -> b -> c -> CodeGen e s ()
+
+instance Imul InPlace Reg32 Reg32 where
+ imul _ (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_imul_reg_reg dest source
+
+instance Imul InPlace Reg32 Addr where
+ imul _ (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_imul_reg_mem dest source
+
+instance Imul InPlace Reg32 (Disp, Reg32) where
+ imul _ (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_imul_reg_membase dest source disp
+
+instance Imul InPlace Reg32 Ind where
+ imul _ (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_imul_reg_membase dest source 0
+
+instance Imul Reg32 Reg32 Word32 where
+ imul (Reg32 dest) (Reg32 source) imm = ensureBufferSize x86_max_instruction_bytes >> x86_imul_reg_reg_imm dest source imm
+
+instance Imul Reg32 Addr Word32 where
+ imul (Reg32 dest) (Addr source) imm = ensureBufferSize x86_max_instruction_bytes >> x86_imul_reg_mem_imm dest source imm
+
+instance Imul Reg32 (Disp, Reg32) Word32 where
+ imul (Reg32 dest) (Disp disp, Reg32 source) imm = ensureBufferSize x86_max_instruction_bytes >> x86_imul_reg_membase_imm dest source disp imm
+
+instance Imul Reg32 Ind Word32 where
+ imul (Reg32 dest) (Ind (Reg32 source)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_imul_reg_membase_imm dest source 0 imm
+
+
+-- divide EDX:EAX by rm;
+-- eax = quotient, edx = remainder
+
+-- unsigned divide
+
+class Div a where
+ div :: a -> CodeGen e s ()
+
+instance Div Reg32 where
+ div (Reg32 arg) = ensureBufferSize x86_max_instruction_bytes >> x86_div_reg arg False
+
+instance Div Addr where
+ div (Addr arg) = ensureBufferSize x86_max_instruction_bytes >> x86_div_mem arg False
+
+instance Div (Disp, Reg32) where
+ div (Disp disp, Reg32 arg) = ensureBufferSize x86_max_instruction_bytes >> x86_div_membase arg disp False
+
+instance Div Ind where
+ div (Ind (Reg32 arg)) = ensureBufferSize x86_max_instruction_bytes >> x86_div_membase arg 0 False
+
+
+-- signed divide
+
+class Idiv a where
+ idiv :: a -> CodeGen e s ()
+
+instance Idiv Reg32 where
+ idiv (Reg32 arg) = ensureBufferSize x86_max_instruction_bytes >> x86_div_reg arg True
+
+instance Idiv Addr where
+ idiv (Addr arg) = ensureBufferSize x86_max_instruction_bytes >> x86_div_mem arg True
+
+instance Idiv (Disp, Reg32) where
+ idiv (Disp disp, Reg32 arg) = ensureBufferSize x86_max_instruction_bytes >> x86_div_membase arg disp True
+
+instance Idiv Ind where
+ idiv (Ind (Reg32 arg)) = ensureBufferSize x86_max_instruction_bytes >> x86_div_membase arg 0 True
+
+
+-- "mov" instruction for different sources and destinations
+
+class Mov a b where
+ mov :: a -> b -> CodeGen e s ()
+
+
+instance Mov Reg8 Reg8 where
+ mov (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_reg dest source 1
+
+instance Mov Reg16 Reg16 where
+ mov (Reg16 dest) (Reg16 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_reg dest source 2
+
+instance Mov Reg32 Reg32 where
+ mov (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_reg dest source 4
+
+
+instance Mov Reg32 Word32 where
+ mov (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_imm dest (fromIntegral imm)
+
+instance Mov Reg32 (Ptr a) where
+ mov (Reg32 dest) ptr = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_imm dest (ptrToWord32 ptr)
+
+instance Mov Reg32 Label where
+ mov (Reg32 dest) lab = do ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_imm dest 0
+ emitFixup lab (-4) Fixup32Absolute
+
+instance Mov Addr Word8 where
+ mov (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_mem_imm dest (fromIntegral imm) 1
+
+instance Mov Addr Word16 where
+ mov (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_mem_imm dest (fromIntegral imm) 2
+
+instance Mov Addr Word32 where
+ mov (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_mem_imm dest imm 4
+
+instance Mov Addr (Ptr a) where
+ mov (Addr dest) ptr = ensureBufferSize x86_max_instruction_bytes >> x86_mov_mem_imm dest (ptrToWord32 ptr) 4
+
+instance Mov Addr Label where
+ mov (Addr dest) lab = do ensureBufferSize x86_max_instruction_bytes >> x86_mov_mem_imm dest 0 4
+ emitFixup lab (-4) Fixup32Absolute
+
+instance Mov (Disp, Reg32) Word8 where
+ mov (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_imm dest disp (fromIntegral imm) 1
+
+instance Mov Ind Word8 where
+ mov (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_imm dest 0 (fromIntegral imm) 1
+
+instance Mov (Disp, Reg32) Word16 where
+ mov (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_imm dest disp (fromIntegral imm) 2
+
+instance Mov Ind Word16 where
+ mov (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_imm dest 0 (fromIntegral imm) 2
+
+instance Mov (Disp, Reg32) Word32 where
+ mov (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_imm dest disp imm 4
+
+instance Mov (Disp, Reg32) (Ptr a) where
+ mov (Disp disp, Reg32 dest) ptr = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_imm dest disp (ptrToWord32 ptr) 4
+
+instance Mov (Disp, Reg32) Label where
+ mov (Disp disp, Reg32 dest) lab = do ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_imm dest disp 0 4
+ emitFixup lab (-4) Fixup32Absolute
+
+instance Mov Ind Word32 where
+ mov (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_imm dest 0 imm 4
+
+instance Mov Ind (Ptr a) where
+ mov (Ind (Reg32 dest)) ptr = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_imm dest 0 (ptrToWord32 ptr) 4
+
+instance Mov Ind Label where
+ mov (Ind (Reg32 dest)) lab = do ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_imm dest 0 0 4
+ emitFixup lab (-4) Fixup32Absolute
+
+instance Mov (Reg32, Reg32, Scale) Word8 where
+ mov (Reg32 base, Reg32 index, scale) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm base 0 index (scaleToShift scale) (fromIntegral imm) 1
+
+instance Mov (Reg32, Reg32, Scale) Word16 where
+ mov (Reg32 base, Reg32 index, scale) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm base 0 index (scaleToShift scale) (fromIntegral imm) 2
+
+instance Mov (Reg32, Reg32, Scale) Word32 where
+ mov (Reg32 base, Reg32 index, scale) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm base 0 index (scaleToShift scale) imm 4
+
+instance Mov (Reg32, Reg32, Scale) (Ptr a) where
+ mov (Reg32 base, Reg32 index, scale) ptr = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm base 0 index (scaleToShift scale) (ptrToWord32 ptr) 4
+
+instance Mov (Reg32, Reg32, Scale) Label where
+ mov (Reg32 base, Reg32 index, scale) lab = do ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm base 0 index (scaleToShift scale) 0 4
+ emitFixup lab (-4) Fixup32Absolute
+
+instance Mov (Disp, Reg32, Scale) Word8 where
+ mov (Disp disp, Reg32 index, scale) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm x86_nobasereg disp index (scaleToShift scale) (fromIntegral imm) 1
+
+instance Mov (Disp, Reg32, Scale) Word16 where
+ mov (Disp disp, Reg32 index, scale) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm x86_nobasereg disp index (scaleToShift scale) (fromIntegral imm) 2
+
+instance Mov (Disp, Reg32, Scale) Word32 where
+ mov (Disp disp, Reg32 index, scale) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm x86_nobasereg disp index (scaleToShift scale) imm 4
+
+instance Mov (Disp, Reg32, Scale) (Ptr a) where
+ mov (Disp disp, Reg32 index, scale) ptr = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm x86_nobasereg disp index (scaleToShift scale) (ptrToWord32 ptr) 4
+
+instance Mov (Disp, Reg32, Scale) Label where
+ mov (Disp disp, Reg32 index, scale) lab = do ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm x86_nobasereg disp index (scaleToShift scale) 0 4
+ emitFixup lab (-4) Fixup32Absolute
+
+instance Mov (Disp, Reg32, Reg32, Scale) Word8 where
+ mov (Disp disp, Reg32 5, Reg32 index, scale) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm 5 disp index (scaleToShift scale) (fromIntegral imm) 1
+ mov _ _ = onlyEbp
+
+instance Mov (Disp, Reg32, Reg32, Scale) Word16 where
+ mov (Disp disp, Reg32 5, Reg32 index, scale) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm 5 disp index (scaleToShift scale) (fromIntegral imm) 2
+ mov _ _ = onlyEbp
+
+instance Mov (Disp, Reg32, Reg32, Scale) Word32 where
+ mov (Disp disp, Reg32 5, Reg32 index, scale) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm 5 disp index (scaleToShift scale) imm 4
+ mov _ _ = onlyEbp
+
+instance Mov (Disp, Reg32, Reg32, Scale) (Ptr a) where
+ mov (Disp disp, Reg32 5, Reg32 index, scale) ptr = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm 5 disp index (scaleToShift scale) (ptrToWord32 ptr) 4
+ mov _ _ = onlyEbp
+
+instance Mov (Disp, Reg32, Reg32, Scale) Label where
+ mov (Disp disp, Reg32 5, Reg32 index, scale) lab = do ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm 5 disp index (scaleToShift scale) 0 4
+ emitFixup lab (-4) Fixup32Absolute
+ mov _ _ = onlyEbp
+
+instance Mov Addr Reg8 where
+ mov (Addr a) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_mem_reg a source 1
+
+instance Mov Addr Reg16 where
+ mov (Addr a) (Reg16 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_mem_reg a source 2
+
+instance Mov Addr Reg32 where
+ mov (Addr a) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_mem_reg a source 4
+
+instance Mov Reg8 Addr where
+ mov (Reg8 dest) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_mem dest a 1
+
+instance Mov Reg16 Addr where
+ mov (Reg16 dest) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_mem dest a 2
+
+instance Mov Reg32 Addr where
+ mov (Reg32 dest) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_mem dest a 4
+
+
+instance Mov Ind Reg8 where
+ mov (Ind (Reg32 dest)) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_regp_reg dest source 1
+
+instance Mov Ind Reg16 where
+ mov (Ind (Reg32 dest)) (Reg16 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_regp_reg dest source 2
+
+instance Mov Ind Reg32 where
+ mov (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_regp_reg dest source 4
+
+instance Mov Reg8 Ind where
+ mov (Reg8 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_regp dest source 1
+
+instance Mov Reg16 Ind where
+ mov (Reg16 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_regp dest source 2
+
+instance Mov Reg32 Ind where
+ mov (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_regp dest source 4
+
+
+instance Mov (Disp, Reg32) Reg8 where
+ mov (Disp disp, Reg32 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_reg dest disp source 1
+
+instance Mov (Disp, Reg32) Reg16 where
+ mov (Disp disp, Reg32 dest) (Reg16 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_reg dest disp source 2
+
+instance Mov (Disp, Reg32) Reg32 where
+ mov (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_reg dest disp source 4
+
+instance Mov Reg8 (Disp, Reg32) where
+ mov (Reg8 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_membase dest source disp 1
+
+instance Mov Reg16 (Disp, Reg32) where
+ mov (Reg16 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_membase dest source disp 2
+
+instance Mov Reg32 (Disp, Reg32) where
+ mov (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_membase dest source disp 4
+
+
+instance Mov (Reg32, Reg32, Scale) Reg8 where
+ mov (Reg32 base, Reg32 index, s) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_reg base 0 index (scaleToShift s) source 1
+
+instance Mov (Reg32, Reg32, Scale) Reg16 where
+ mov (Reg32 base, Reg32 index, s) (Reg16 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_reg base 0 index (scaleToShift s) source 2
+
+instance Mov (Reg32, Reg32, Scale) Reg32 where
+ mov (Reg32 base, Reg32 index, s) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_reg base 0 index (scaleToShift s) source 4
+
+instance Mov Reg8 (Reg32, Reg32, Scale) where
+ mov (Reg8 dest) (Reg32 base, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_memindex dest base 0 index (scaleToShift s) 1
+
+instance Mov Reg16 (Reg32, Reg32, Scale) where
+ mov (Reg16 dest) (Reg32 base, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_memindex dest base 0 index (scaleToShift s) 2
+
+instance Mov Reg32 (Reg32, Reg32, Scale) where
+ mov (Reg32 dest) (Reg32 base, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_memindex dest base 0 index (scaleToShift s) 4
+
+
+instance Mov (Disp, Reg32, Scale) Reg8 where
+ mov (Disp disp, Reg32 index, s) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_reg x86_nobasereg disp index (scaleToShift s) source 1
+
+instance Mov (Disp, Reg32, Scale) Reg16 where
+ mov (Disp disp, Reg32 index, s) (Reg16 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_reg x86_nobasereg disp index (scaleToShift s) source 2
+
+instance Mov (Disp, Reg32, Scale) Reg32 where
+ mov (Disp disp, Reg32 index, s) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_reg x86_nobasereg disp index (scaleToShift s) source 4
+
+instance Mov Reg8 (Disp, Reg32, Scale) where
+ mov (Reg8 dest) (Disp disp, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_memindex dest x86_nobasereg disp index (scaleToShift s) 1
+
+instance Mov Reg16 (Disp, Reg32, Scale) where
+ mov (Reg16 dest) (Disp disp, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_memindex dest x86_nobasereg disp index (scaleToShift s) 2
+
+instance Mov Reg32 (Disp, Reg32, Scale) where
+ mov (Reg32 dest) (Disp disp, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_memindex dest x86_nobasereg disp index (scaleToShift s) 4
+
+
+instance Mov (Disp, Reg32, Reg32, Scale) Reg8 where
+ mov (Disp disp, Reg32 5, Reg32 index, s) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_reg 5 disp index (scaleToShift s) source 1
+ mov _ _ = onlyEbp
+
+instance Mov (Disp, Reg32, Reg32, Scale) Reg16 where
+ mov (Disp disp, Reg32 5, Reg32 index, s) (Reg16 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_reg 5 disp index (scaleToShift s) source 2
+ mov _ _ = onlyEbp
+
+instance Mov (Disp, Reg32, Reg32, Scale) Reg32 where
+ mov (Disp disp, Reg32 5, Reg32 index, s) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_reg 5 disp index (scaleToShift s) source 4
+ mov _ _ = onlyEbp
+
+instance Mov Reg8 (Disp, Reg32, Reg32, Scale) where
+ mov (Reg8 dest) (Disp disp, Reg32 5, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_memindex dest 5 disp index (scaleToShift s) 1
+ mov _ _ = onlyEbp
+
+instance Mov Reg16 (Disp, Reg32, Reg32, Scale) where
+ mov (Reg16 dest) (Disp disp, Reg32 5, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_memindex dest 5 disp index (scaleToShift s) 2
+ mov _ _ = onlyEbp
+
+instance Mov Reg32 (Disp, Reg32, Reg32, Scale) where
+ mov (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_memindex dest 5 disp index (scaleToShift s) 4
+ mov _ _ = onlyEbp
+
+
+-- move with sign-extension
+
+class Movsxb a b where
+ movsxb :: a -> b -> CodeGen e s ()
+
+instance Movsxb Reg32 Reg8 where
+ movsxb (Reg32 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_reg dest source True False
+
+instance Movsxb Reg32 Addr where
+ movsxb (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_mem dest source True False
+
+instance Movsxb Reg32 (Disp, Reg32) where
+ movsxb (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_membase dest source disp True False
+
+instance Movsxb Reg32 Ind where
+ movsxb (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_membase dest source 0 True False
+
+instance Movsxb Reg32 (Disp, Reg32, Reg32, Scale) where
+ movsxb (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest 5 disp index (scaleToShift s) True False
+ movsxb _ _ = onlyEbp
+
+instance Movsxb Reg32 (Disp, Reg32, Scale) where
+ movsxb (Reg32 dest) (Disp disp, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest x86_nobasereg disp index (scaleToShift s) True False
+
+instance Movsxb Reg32 (Reg32, Reg32, Scale) where
+ movsxb (Reg32 dest) (Reg32 base, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest base 0 index (scaleToShift s) True False
+
+class Movsxw a b where
+ movsxw :: a -> b -> CodeGen e s ()
+
+instance Movsxw Reg32 Reg16 where
+ movsxw (Reg32 dest) (Reg16 source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_reg dest source True True
+
+instance Movsxw Reg32 Addr where
+ movsxw (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_mem dest source True True
+
+instance Movsxw Reg32 (Disp, Reg32) where
+ movsxw (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_membase dest source disp True True
+
+instance Movsxw Reg32 Ind where
+ movsxw (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_membase dest source 0 True True
+
+instance Movsxw Reg32 (Disp, Reg32, Reg32, Scale) where
+ movsxw (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest 5 disp index (scaleToShift s) True True
+ movsxw _ _ = onlyEbp
+
+instance Movsxw Reg32 (Disp, Reg32, Scale) where
+ movsxw (Reg32 dest) (Disp disp, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest x86_nobasereg disp index (scaleToShift s) True True
+
+instance Movsxw Reg32 (Reg32, Reg32, Scale) where
+ movsxw (Reg32 dest) (Reg32 base, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest base 0 index (scaleToShift s) True True
+
+
+-- move with zero-extension
+
+class Movzxb a b where
+ movzxb :: a -> b -> CodeGen e s ()
+
+instance Movzxb Reg32 Reg8 where
+ movzxb (Reg32 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_reg dest source False False
+
+instance Movzxb Reg32 Addr where
+ movzxb (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_mem dest source False False
+
+instance Movzxb Reg32 (Disp, Reg32) where
+ movzxb (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_membase dest source disp False False
+
+instance Movzxb Reg32 Ind where
+ movzxb (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_membase dest source 0 False False
+
+instance Movzxb Reg32 (Disp, Reg32, Reg32, Scale) where
+ movzxb (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest 5 disp index (scaleToShift s) False False
+ movzxb _ _ = onlyEbp
+
+instance Movzxb Reg32 (Disp, Reg32, Scale) where
+ movzxb (Reg32 dest) (Disp disp, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest x86_nobasereg disp index (scaleToShift s) False False
+
+instance Movzxb Reg32 (Reg32, Reg32, Scale) where
+ movzxb (Reg32 dest) (Reg32 base, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest base 0 index (scaleToShift s) False False
+
+class Movzxw a b where
+ movzxw :: a -> b -> CodeGen e s ()
+
+instance Movzxw Reg32 Reg16 where
+ movzxw (Reg32 dest) (Reg16 source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_reg dest source False True
+
+instance Movzxw Reg32 Addr where
+ movzxw (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_mem dest source False True
+
+instance Movzxw Reg32 (Disp, Reg32) where
+ movzxw (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_membase dest source disp False True
+
+instance Movzxw Reg32 Ind where
+ movzxw (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_membase dest source 0 False True
+
+instance Movzxw Reg32 (Disp, Reg32, Reg32, Scale) where
+ movzxw (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest 5 disp index (scaleToShift s) False True
+ movzxw _ _ = onlyEbp
+
+instance Movzxw Reg32 (Disp, Reg32, Scale) where
+ movzxw (Reg32 dest) (Disp disp, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest x86_nobasereg disp index (scaleToShift s) False True
+
+instance Movzxw Reg32 (Reg32, Reg32, Scale) where
+ movzxw (Reg32 dest) (Reg32 base, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest base 0 index (scaleToShift s) False True
+
+
+-- load effective address
+
+class Lea a b where
+ lea :: a -> b -> CodeGen e s ()
+
+instance Lea Reg32 Addr where
+ lea (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_lea_mem dest source
+
+instance Lea Reg32 (Disp, Reg32) where
+ lea (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_lea_membase dest source disp
+
+instance Lea Reg32 Ind where
+ lea (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_lea_membase dest source 0
+
+instance Lea Reg32 (Disp, Reg32, Reg32, Scale) where
+ lea (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_lea_memindex dest 5 disp index (scaleToShift s)
+ lea _ _ = onlyEbp
+
+instance Lea Reg32 (Disp, Reg32, Scale) where
+ lea (Reg32 dest) (Disp disp, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_lea_memindex dest x86_nobasereg disp index (scaleToShift s)
+
+instance Lea Reg32 (Reg32, Reg32, Scale) where
+ lea (Reg32 dest) (Reg32 base, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_lea_memindex dest base 0 index (scaleToShift s)
+
+
+-- convert word to doubleword
+
+cdq = ensureBufferSize x86_max_instruction_bytes >> x86_cdq
+
+
+-- wait for FPU
+
+wait = ensureBufferSize x86_max_instruction_bytes >> x86_wait
+
+
+-- push to stack
+
+class Push a where
+ push :: a -> CodeGen e s ()
+
+instance Push Reg32 where
+ push (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_push_reg source
+
+instance Push Ind where
+ push (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_push_regp source
+
+instance Push Addr where
+ push (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_push_mem source
+
+instance Push (Disp, Reg32) where
+ push (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_push_membase source disp
+
+instance Push Word32 where
+ push imm = ensureBufferSize x86_max_instruction_bytes >> x86_push_imm imm
+
+instance Push Label where
+ push l = do ensureBufferSize x86_max_instruction_bytes >> x86_push_imm_template
+ emitFixup l (-4) Fixup32Absolute
+
+instance Push (Disp, Reg32, Reg32, Scale) where
+ push (Disp disp, Reg32 5, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_push_memindex 5 disp index (scaleToShift s)
+ push _ = onlyEbp
+
+instance Push (Disp, Reg32, Scale) where
+ push (Disp disp, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_push_memindex x86_nobasereg disp index (scaleToShift s)
+
+instance Push (Reg32, Reg32, Scale) where
+ push (Reg32 base, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_push_memindex base 0 index (scaleToShift s)
+
+
+-- pop from stack
+
+class Pop a where
+ pop :: a -> CodeGen e s ()
+
+instance Pop Reg32 where
+ pop (Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_pop_reg dest
+
+instance Pop Addr where
+ pop (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_pop_mem dest
+
+instance Pop (Disp, Reg32) where
+ pop (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_pop_membase dest disp
+
+instance Pop Ind where
+ pop (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_pop_membase dest 0
+
+
+-- push/pop general purpose registers
+
+pushad = ensureBufferSize x86_max_instruction_bytes >> x86_pushad
+popad = ensureBufferSize x86_max_instruction_bytes >> x86_popad
+
+
+-- push/pop EFLAGS
+
+pushfd = ensureBufferSize x86_max_instruction_bytes >> x86_pushfd
+popfd = ensureBufferSize x86_max_instruction_bytes >> x86_popfd
+
+
+-- loop according to ECX counter
+
+class Loop a where
+ loop :: a -> CodeGen e s ()
+ loope :: a -> CodeGen e s ()
+ loopne :: a -> CodeGen e s ()
+
+instance Loop Word8 where
+ loop w = ensureBufferSize x86_max_instruction_bytes >> x86_loop w
+ loope w = ensureBufferSize x86_max_instruction_bytes >> x86_loope w
+ loopne w = ensureBufferSize x86_max_instruction_bytes >> x86_loopne w
+
+instance Loop Label where
+ loop l = do ensureBufferSize x86_max_instruction_bytes >> x86_loop 0
+ emitFixup l (-1) Fixup8
+ loope l = do ensureBufferSize x86_max_instruction_bytes >> x86_loope 0
+ emitFixup l (-1) Fixup8
+ loopne l = do ensureBufferSize x86_max_instruction_bytes >> x86_loopne 0
+ emitFixup l (-1) Fixup8
+
+-- jump
+
+class Jmp a where
+ jmp :: a -> CodeGen e s ()
+
+instance Jmp Word8 where
+ jmp imm = ensureBufferSize x86_max_instruction_bytes >> x86_jump8 imm
+
+instance Jmp Word32 where
+ jmp imm = ensureBufferSize x86_max_instruction_bytes >> x86_jump32 imm
+
+instance Jmp Reg32 where
+ jmp (Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_jump_reg dest
+
+instance Jmp Addr where
+ jmp (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_jump_mem dest
+
+instance Jmp (Disp, Reg32) where
+ jmp (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_jump_membase dest disp
+
+instance Jmp Ind where
+ jmp (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_jump_membase dest 0
+
+instance Jmp Label where
+ jmp l = do ensureBufferSize x86_max_instruction_bytes >> x86_jump32 0
+ emitFixup l (-4) Fixup32
+
+instance Jmp (Ptr a) where
+ jmp ptr = ensureBufferSize x86_max_instruction_bytes >> x86_jump_pointer ptr
+
+-- jump on condition code (branch)
+
+class Ja a where
+ ja :: a -> CodeGen e s ()
+
+instance Ja Word8 where
+ ja imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_a imm False
+
+instance Ja Word32 where
+ ja imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_a imm False
+
+instance Ja (Ptr a) where
+ ja ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_a ptr False
+
+instance Ja Label where
+ ja l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_a 0 False
+ emitFixup l (-4) Fixup32
+
+class Jae a where
+ jae :: a -> CodeGen e s ()
+
+instance Jae Word8 where
+ jae imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_ae imm False
+
+instance Jae Word32 where
+ jae imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ae imm False
+
+instance Jae (Ptr a) where
+ jae ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_ae ptr False
+
+instance Jae Label where
+ jae l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ae 0 False
+ emitFixup l (-4) Fixup32
+
+class Jb a where
+ jb :: a -> CodeGen e s ()
+
+instance Jb Word8 where
+ jb imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_b imm False
+
+instance Jb Word32 where
+ jb imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_b imm False
+
+instance Jb (Ptr a) where
+ jb ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_b ptr False
+
+instance Jb Label where
+ jb l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_b 0 False
+ emitFixup l (-4) Fixup32
+
+class Jbe a where
+ jbe :: a -> CodeGen e s ()
+
+instance Jbe Word8 where
+ jbe imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_be imm False
+
+instance Jbe Word32 where
+ jbe imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_be imm False
+
+instance Jbe (Ptr a) where
+ jbe ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_be ptr False
+
+instance Jbe Label where
+ jbe l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_be 0 False
+ emitFixup l (-4) Fixup32
+
+class Jc a where
+ jc :: a -> CodeGen e s ()
+
+instance Jc Word8 where
+ jc imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_c imm False
+
+instance Jc Word32 where
+ jc imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_c imm False
+
+instance Jc (Ptr a) where
+ jc ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_c ptr False
+
+instance Jc Label where
+ jc l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_c 0 False
+ emitFixup l (-4) Fixup32
+
+class Je a where
+ je :: a -> CodeGen e s ()
+
+instance Je Word8 where
+ je imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_e imm False
+
+instance Je Word32 where
+ je imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_e imm False
+
+instance Je (Ptr a) where
+ je ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_e ptr False
+
+instance Je Label where
+ je l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_e 0 False
+ emitFixup l (-4) Fixup32
+
+class Jna a where
+ jna :: a -> CodeGen e s ()
+
+instance Jna Word8 where
+ jna imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_na imm False
+
+instance Jna Word32 where
+ jna imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_na imm False
+
+instance Jna (Ptr a) where
+ jna ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_na ptr False
+
+instance Jna Label where
+ jna l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_na 0 False
+ emitFixup l (-4) Fixup32
+
+class Jnae a where
+ jnae :: a -> CodeGen e s ()
+
+instance Jnae Word8 where
+ jnae imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_nae imm False
+
+instance Jnae Word32 where
+ jnae imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nae imm False
+
+instance Jnae (Ptr a) where
+ jnae ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_nae ptr False
+
+instance Jnae Label where
+ jnae l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nae 0 False
+ emitFixup l (-4) Fixup32
+
+class Jnb a where
+ jnb :: a -> CodeGen e s ()
+
+instance Jnb Word8 where
+ jnb imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_nb imm False
+
+instance Jnb Word32 where
+ jnb imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nb imm False
+
+instance Jnb (Ptr a) where
+ jnb ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_nb ptr False
+
+instance Jnb Label where
+ jnb l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nb 0 False
+ emitFixup l (-4) Fixup32
+
+class Jnbe a where
+ jnbe :: a -> CodeGen e s ()
+
+instance Jnbe Word8 where
+ jnbe imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_nbe imm False
+
+instance Jnbe Word32 where
+ jnbe imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nbe imm False
+
+instance Jnbe (Ptr a) where
+ jnbe ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_nbe ptr False
+
+instance Jnbe Label where
+ jnbe l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nbe 0 False
+ emitFixup l (-4) Fixup32
+
+class Jnc a where
+ jnc :: a -> CodeGen e s ()
+
+instance Jnc Word8 where
+ jnc imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_nc imm False
+
+instance Jnc Word32 where
+ jnc imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nc imm False
+
+instance Jnc (Ptr a) where
+ jnc ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_nc ptr False
+
+instance Jnc Label where
+ jnc l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nc 0 False
+ emitFixup l (-4) Fixup32
+
+class Jne a where
+ jne :: a -> CodeGen e s ()
+
+instance Jne Word8 where
+ jne imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_ne imm False
+
+instance Jne Word32 where
+ jne imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ne imm False
+
+instance Jne (Ptr a) where
+ jne ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_ne ptr False
+
+instance Jne Label where
+ jne l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ne 0 False
+ emitFixup l (-4) Fixup32
+
+class Jnp a where
+ jnp :: a -> CodeGen e s ()
+
+instance Jnp Word8 where
+ jnp imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_np imm False
+
+instance Jnp Word32 where
+ jnp imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_np imm False
+
+instance Jnp (Ptr a) where
+ jnp ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_np ptr False
+
+instance Jnp Label where
+ jnp l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_np 0 False
+ emitFixup l (-4) Fixup32
+
+class Jnz a where
+ jnz :: a -> CodeGen e s ()
+
+instance Jnz Word8 where
+ jnz imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_nz imm False
+
+instance Jnz Word32 where
+ jnz imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nz imm False
+
+instance Jnz (Ptr a) where
+ jnz ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_nz ptr False
+
+instance Jnz Label where
+ jnz l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nz 0 False
+ emitFixup l (-4) Fixup32
+
+class Jp a where
+ jp :: a -> CodeGen e s ()
+
+instance Jp Word8 where
+ jp imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_p imm False
+
+instance Jp Word32 where
+ jp imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_p imm False
+
+instance Jp (Ptr a) where
+ jp ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_p ptr False
+
+instance Jp Label where
+ jp l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_p 0 False
+ emitFixup l (-4) Fixup32
+
+class Jpe a where
+ jpe :: a -> CodeGen e s ()
+
+instance Jpe Word8 where
+ jpe imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_pe imm False
+
+instance Jpe Word32 where
+ jpe imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_pe imm False
+
+instance Jpe (Ptr a) where
+ jpe ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_pe ptr False
+
+instance Jpe Label where
+ jpe l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_pe 0 False
+ emitFixup l (-4) Fixup32
+
+class Jpo a where
+ jpo :: a -> CodeGen e s ()
+
+instance Jpo Word8 where
+ jpo imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_po imm False
+
+instance Jpo Word32 where
+ jpo imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_po imm False
+
+instance Jpo (Ptr a) where
+ jpo ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_po ptr False
+
+instance Jpo Label where
+ jpo l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_po 0 False
+ emitFixup l (-4) Fixup32
+
+class Jz a where
+ jz :: a -> CodeGen e s ()
+
+instance Jz Word8 where
+ jz imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_z imm False
+
+instance Jz Word32 where
+ jz imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_z imm False
+
+instance Jz (Ptr a) where
+ jz ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_z ptr False
+
+instance Jz Label where
+ jz l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_z 0 False
+ emitFixup l (-4) Fixup32
+
+class Jg a where
+ jg :: a -> CodeGen e s ()
+
+instance Jg Word8 where
+ jg imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_gt imm True
+
+instance Jg Word32 where
+ jg imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_gt imm True
+
+instance Jg (Ptr a) where
+ jg ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_gt ptr True
+
+instance Jg Label where
+ jg l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_gt 0 True
+ emitFixup l (-4) Fixup32
+
+class Jge a where
+ jge :: a -> CodeGen e s ()
+
+instance Jge Word8 where
+ jge imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_ge imm True
+
+instance Jge Word32 where
+ jge imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ge imm True
+
+instance Jge (Ptr a) where
+ jge ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_ge ptr True
+
+instance Jge Label where
+ jge l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ge 0 True
+ emitFixup l (-4) Fixup32
+
+class Jl a where
+ jl :: a -> CodeGen e s ()
+
+instance Jl Word8 where
+ jl imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_lt imm True
+
+instance Jl Word32 where
+ jl imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_lt imm True
+
+instance Jl (Ptr a) where
+ jl ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_lt ptr True
+
+instance Jl Label where
+ jl l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_lt 0 True
+ emitFixup l (-4) Fixup32
+
+class Jle a where
+ jle :: a -> CodeGen e s ()
+
+instance Jle Word8 where
+ jle imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_le imm True
+
+instance Jle Word32 where
+ jle imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_le imm True
+
+instance Jle (Ptr a) where
+ jle ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_le ptr True
+
+instance Jle Label where
+ jle l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_le 0 True
+ emitFixup l (-4) Fixup32
+
+class Jng a where
+ jng :: a -> CodeGen e s ()
+
+instance Jng Word8 where
+ jng imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_le imm True
+
+instance Jng Word32 where
+ jng imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_le imm True
+
+instance Jng (Ptr a) where
+ jng ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_le ptr True
+
+instance Jng Label where
+ jng l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_le 0 True
+ emitFixup l (-4) Fixup32
+
+class Jnge a where
+ jnge :: a -> CodeGen e s ()
+
+instance Jnge Word8 where
+ jnge imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_lt imm True
+
+instance Jnge Word32 where
+ jnge imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_lt imm True
+
+instance Jnge (Ptr a) where
+ jnge ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_lt ptr True
+
+instance Jnge Label where
+ jnge l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_lt 0 True
+ emitFixup l (-4) Fixup32
+
+class Jnl a where
+ jnl :: a -> CodeGen e s ()
+
+instance Jnl Word8 where
+ jnl imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_ge imm True
+
+instance Jnl Word32 where
+ jnl imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ge imm True
+
+instance Jnl (Ptr a) where
+ jnl ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_ge ptr True
+
+instance Jnl Label where
+ jnl l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ge 0 True
+ emitFixup l (-4) Fixup32
+
+class Jnle a where
+ jnle :: a -> CodeGen e s ()
+
+instance Jnle Word8 where
+ jnle imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_gt imm True
+
+instance Jnle Word32 where
+ jnle imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_gt imm True
+
+instance Jnle (Ptr a) where
+ jnle ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_gt ptr True
+
+instance Jnle Label where
+ jnle l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_gt 0 True
+ emitFixup l (-4) Fixup32
+
+class Jno a where
+ jno :: a -> CodeGen e s ()
+
+instance Jno Word8 where
+ jno imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_no imm True
+
+instance Jno Word32 where
+ jno imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_no imm True
+
+instance Jno (Ptr a) where
+ jno ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_no ptr True
+
+instance Jno Label where
+ jno l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_no 0 True
+ emitFixup l (-4) Fixup32
+
+class Jns a where
+ jns :: a -> CodeGen e s ()
+
+instance Jns Word8 where
+ jns imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_ns imm True
+
+instance Jns Word32 where
+ jns imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ns imm True
+
+instance Jns (Ptr a) where
+ jns ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_ns ptr True
+
+instance Jns Label where
+ jns l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ns 0 True
+ emitFixup l (-4) Fixup32
+
+class Jo a where
+ jo :: a -> CodeGen e s ()
+
+instance Jo Word8 where
+ jo imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_o imm True
+
+instance Jo Word32 where
+ jo imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_o imm True
+
+instance Jo (Ptr a) where
+ jo ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_o ptr True
+
+instance Jo Label where
+ jo l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_o 0 True
+ emitFixup l (-4) Fixup32
+
+class Js a where
+ js :: a -> CodeGen e s ()
+
+instance Js Word8 where
+ js imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_s imm True
+
+instance Js Word32 where
+ js imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_s imm True
+
+instance Js (Ptr a) where
+ js ptr = ensureBufferSize x86_max_instruction_bytes >> x86_branch_pointer x86_cc_s ptr True
+
+instance Js Label where
+ js l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_s 0 True
+ emitFixup l (-4) Fixup32
+
+-- jump if ecx register is 0
+
+jecxz :: Word8 -> CodeGen e s ()
+jecxz w = ensureBufferSize x86_max_instruction_bytes >> x86_jecxz w
+
+
+-- set byte on condition code
+
+class Seta a where
+ seta :: a -> CodeGen e s ()
+
+instance Seta Reg8 where
+ seta (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_a dest False
+
+instance Seta Addr where
+ seta (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_a dest False
+
+instance Seta (Disp, Reg32) where
+ seta (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_a dest disp False
+
+instance Seta Ind where
+ seta (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_a dest 0 False
+
+class Setae a where
+ setae :: a -> CodeGen e s ()
+
+instance Setae Reg8 where
+ setae (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_ae dest False
+
+instance Setae Addr where
+ setae (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_ae dest False
+
+instance Setae (Disp, Reg32) where
+ setae (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ae dest disp False
+
+instance Setae Ind where
+ setae (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ae dest 0 False
+
+class Setb a where
+ setb :: a -> CodeGen e s ()
+
+instance Setb Reg8 where
+ setb (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_b dest False
+
+instance Setb Addr where
+ setb (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_b dest False
+
+instance Setb (Disp, Reg32) where
+ setb (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_b dest disp False
+
+instance Setb Ind where
+ setb (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_b dest 0 False
+
+class Setbe a where
+ setbe :: a -> CodeGen e s ()
+
+instance Setbe Reg8 where
+ setbe (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_be dest False
+
+instance Setbe Addr where
+ setbe (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_be dest False
+
+instance Setbe (Disp, Reg32) where
+ setbe (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_be dest disp False
+
+instance Setbe Ind where
+ setbe (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_be dest 0 False
+
+class Setc a where
+ setc :: a -> CodeGen e s ()
+
+instance Setc Reg8 where
+ setc (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_c dest False
+
+instance Setc Addr where
+ setc (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_c dest False
+
+instance Setc (Disp, Reg32) where
+ setc (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_c dest disp False
+
+instance Setc Ind where
+ setc (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_c dest 0 False
+
+class Sete a where
+ sete :: a -> CodeGen e s ()
+
+instance Sete Reg8 where
+ sete (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_e dest False
+
+instance Sete Addr where
+ sete (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_e dest False
+
+instance Sete (Disp, Reg32) where
+ sete (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_e dest disp False
+
+instance Sete Ind where
+ sete (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_e dest 0 False
+
+class Setna a where
+ setna :: a -> CodeGen e s ()
+
+instance Setna Reg8 where
+ setna (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_na dest False
+
+instance Setna Addr where
+ setna (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_na dest False
+
+instance Setna (Disp, Reg32) where
+ setna (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_na dest disp False
+
+instance Setna Ind where
+ setna (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_na dest 0 False
+
+class Setnae a where
+ setnae :: a -> CodeGen e s ()
+
+instance Setnae Reg8 where
+ setnae (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_nae dest False
+
+instance Setnae Addr where
+ setnae (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_nae dest False
+
+instance Setnae (Disp, Reg32) where
+ setnae (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nae dest disp False
+
+instance Setnae Ind where
+ setnae (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nae dest 0 False
+
+class Setnb a where
+ setnb :: a -> CodeGen e s ()
+
+instance Setnb Reg8 where
+ setnb (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_nb dest False
+
+instance Setnb Addr where
+ setnb (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_nb dest False
+
+instance Setnb (Disp, Reg32) where
+ setnb (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nb dest disp False
+
+instance Setnb Ind where
+ setnb (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nb dest 0 False
+
+class Setnbe a where
+ setnbe :: a -> CodeGen e s ()
+
+instance Setnbe Reg8 where
+ setnbe (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_nbe dest False
+
+instance Setnbe Addr where
+ setnbe (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_nbe dest False
+
+instance Setnbe (Disp, Reg32) where
+ setnbe (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nbe dest disp False
+
+instance Setnbe Ind where
+ setnbe (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nbe dest 0 False
+
+class Setnc a where
+ setnc :: a -> CodeGen e s ()
+
+instance Setnc Reg8 where
+ setnc (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_nc dest False
+
+instance Setnc Addr where
+ setnc (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_nc dest False
+
+instance Setnc (Disp, Reg32) where
+ setnc (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nc dest disp False
+
+instance Setnc Ind where
+ setnc (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nc dest 0 False
+
+class Setne a where
+ setne :: a -> CodeGen e s ()
+
+instance Setne Reg8 where
+ setne (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_ne dest False
+
+instance Setne Addr where
+ setne (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_ne dest False
+
+instance Setne (Disp, Reg32) where
+ setne (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ne dest disp False
+
+instance Setne Ind where
+ setne (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ne dest 0 False
+
+class Setnp a where
+ setnp :: a -> CodeGen e s ()
+
+instance Setnp Reg8 where
+ setnp (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_np dest False
+
+instance Setnp Addr where
+ setnp (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_np dest False
+
+instance Setnp (Disp, Reg32) where
+ setnp (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_np dest disp False
+
+instance Setnp Ind where
+ setnp (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_np dest 0 False
+
+class Setnz a where
+ setnz :: a -> CodeGen e s ()
+
+instance Setnz Reg8 where
+ setnz (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_nz dest False
+
+instance Setnz Addr where
+ setnz (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_nz dest False
+
+instance Setnz (Disp, Reg32) where
+ setnz (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nz dest disp False
+
+instance Setnz Ind where
+ setnz (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nz dest 0 False
+
+class Setp a where
+ setp :: a -> CodeGen e s ()
+
+instance Setp Reg8 where
+ setp (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_p dest False
+
+instance Setp Addr where
+ setp (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_p dest False
+
+instance Setp (Disp, Reg32) where
+ setp (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_p dest disp False
+
+instance Setp Ind where
+ setp (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_p dest 0 False
+
+class Setpe a where
+ setpe :: a -> CodeGen e s ()
+
+instance Setpe Reg8 where
+ setpe (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_pe dest False
+
+instance Setpe Addr where
+ setpe (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_pe dest False
+
+instance Setpe (Disp, Reg32) where
+ setpe (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_pe dest disp False
+
+instance Setpe Ind where
+ setpe (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_pe dest 0 False
+
+class Setpo a where
+ setpo :: a -> CodeGen e s ()
+
+instance Setpo Reg8 where
+ setpo (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_po dest False
+
+instance Setpo Addr where
+ setpo (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_po dest False
+
+instance Setpo (Disp, Reg32) where
+ setpo (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_po dest disp False
+
+instance Setpo Ind where
+ setpo (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_po dest 0 False
+
+class Setg a where
+ setg :: a -> CodeGen e s ()
+
+instance Setg Reg8 where
+ setg (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_gt dest True
+
+instance Setg Addr where
+ setg (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_gt dest True
+
+instance Setg (Disp, Reg32) where
+ setg (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_gt dest disp True
+
+instance Setg Ind where
+ setg (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_gt dest 0 True
+
+class Setge a where
+ setge :: a -> CodeGen e s ()
+
+instance Setge Reg8 where
+ setge (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_ge dest True
+
+instance Setge Addr where
+ setge (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_ge dest True
+
+instance Setge (Disp, Reg32) where
+ setge (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ge dest disp True
+
+instance Setge Ind where
+ setge (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ge dest 0 True
+
+class Setl a where
+ setl :: a -> CodeGen e s ()
+
+instance Setl Reg8 where
+ setl (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_lt dest True
+
+instance Setl Addr where
+ setl (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_lt dest True
+
+instance Setl (Disp, Reg32) where
+ setl (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_lt dest disp True
+
+instance Setl Ind where
+ setl (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_lt dest 0 True
+
+class Setle a where
+ setle :: a -> CodeGen e s ()
+
+instance Setle Reg8 where
+ setle (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_le dest True
+
+instance Setle Addr where
+ setle (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_le dest True
+
+instance Setle (Disp, Reg32) where
+ setle (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_le dest disp True
+
+instance Setle Ind where
+ setle (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_le dest 0 True
+
+class Setng a where
+ setng :: a -> CodeGen e s ()
+
+instance Setng Reg8 where
+ setng (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_le dest True
+
+instance Setng Addr where
+ setng (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_le dest True
+
+instance Setng (Disp, Reg32) where
+ setng (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_le dest disp True
+
+instance Setng Ind where
+ setng (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_le dest 0 True
+
+class Setnge a where
+ setnge :: a -> CodeGen e s ()
+
+instance Setnge Reg8 where
+ setnge (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_lt dest True
+
+instance Setnge Addr where
+ setnge (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_lt dest True
+
+instance Setnge (Disp, Reg32) where
+ setnge (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_lt dest disp True
+
+instance Setnge Ind where
+ setnge (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_lt dest 0 True
+
+class Setnl a where
+ setnl :: a -> CodeGen e s ()
+
+instance Setnl Reg8 where
+ setnl (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_ge dest True
+
+instance Setnl Addr where
+ setnl (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_ge dest True
+
+instance Setnl (Disp, Reg32) where
+ setnl (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ge dest disp True
+
+instance Setnl Ind where
+ setnl (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ge dest 0 True
+
+class Setnle a where
+ setnle :: a -> CodeGen e s ()
+
+instance Setnle Reg8 where
+ setnle (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_gt dest True
+
+instance Setnle Addr where
+ setnle (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_gt dest True
+
+instance Setnle (Disp, Reg32) where
+ setnle (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_gt dest disp True
+
+instance Setnle Ind where
+ setnle (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_gt dest 0 True
+
+class Setno a where
+ setno :: a -> CodeGen e s ()
+
+instance Setno Reg8 where
+ setno (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_no dest True
+
+instance Setno Addr where
+ setno (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_no dest True
+
+instance Setno (Disp, Reg32) where
+ setno (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_no dest disp True
+
+instance Setno Ind where
+ setno (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_no dest 0 True
+
+class Setns a where
+ setns :: a -> CodeGen e s ()
+
+instance Setns Reg8 where
+ setns (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_ns dest True
+
+instance Setns Addr where
+ setns (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_ns dest True
+
+instance Setns (Disp, Reg32) where
+ setns (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ns dest disp True
+
+instance Setns Ind where
+ setns (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ns dest 0 True
+
+class Seto a where
+ seto :: a -> CodeGen e s ()
+
+instance Seto Reg8 where
+ seto (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_o dest True
+
+instance Seto Addr where
+ seto (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_o dest True
+
+instance Seto (Disp, Reg32) where
+ seto (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_o dest disp True
+
+instance Seto Ind where
+ seto (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_o dest 0 True
+
+class Sets a where
+ sets :: a -> CodeGen e s ()
+
+instance Sets Reg8 where
+ sets (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_s dest True
+
+instance Sets Addr where
+ sets (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_s dest True
+
+instance Sets (Disp, Reg32) where
+ sets (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_s dest disp True
+
+instance Sets Ind where
+ sets (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_s dest 0 True
+
+class Setz a where
+ setz :: a -> CodeGen e s ()
+
+instance Setz Reg8 where
+ setz (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_z dest False
+
+instance Setz Addr where
+ setz (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_z dest False
+
+instance Setz (Disp, Reg32) where
+ setz (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_z dest disp False
+
+instance Setz Ind where
+ setz (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_z dest 0 False
+
+
+-- call procedure
+
+class Call a where
+ call :: a -> CodeGen e s ()
+
+instance Call Word32 where
+ call imm = ensureBufferSize x86_max_instruction_bytes >> x86_call_imm imm
+
+instance Call Label where
+ call l = do ensureBufferSize x86_max_instruction_bytes >> x86_call_imm 0
+ emitFixup l (-4) Fixup32
+
+instance Call Reg32 where
+ call (Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_call_reg dest
+
+instance Call Addr where
+ call (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_call_mem dest
+
+instance Call (Disp, Reg32) where
+ call (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_call_membase dest disp
+
+instance Call Ind where
+ call (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_call_membase dest 0
+
+instance Call (FunPtr a) where
+ call f = ensureBufferSize x86_max_instruction_bytes >> x86_call_hs f
+
+
+-- return from procedure
+
+ret :: CodeGen e s ()
+ret = ensureBufferSize x86_max_instruction_bytes >> x86_ret
+
+retN :: Word16 -> CodeGen e s ()
+retN n = ensureBufferSize x86_max_instruction_bytes >> x86_ret_imm n
+
+
+-- make stack frame
+
+enter :: Word16 -> CodeGen e s ()
+enter w = ensureBufferSize x86_max_instruction_bytes >> x86_enter w
+
+
+-- conditional move
+
+class Cmova a b where
+ cmova :: a -> b -> CodeGen e s ()
+
+instance Cmova Reg32 Reg32 where
+ cmova (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_a False dest source
+
+instance Cmova Reg32 Addr where
+ cmova (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_a False dest source
+
+instance Cmova Reg32 (Disp, Reg32) where
+ cmova (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_a False dest source disp
+
+instance Cmova Reg32 Ind where
+ cmova (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_a False dest source 0
+
+class Cmovae a b where
+ cmovae :: a -> b -> CodeGen e s ()
+
+instance Cmovae Reg32 Reg32 where
+ cmovae (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_ae False dest source
+
+instance Cmovae Reg32 Addr where
+ cmovae (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_ae False dest source
+
+instance Cmovae Reg32 (Disp, Reg32) where
+ cmovae (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ae False dest source disp
+
+instance Cmovae Reg32 Ind where
+ cmovae (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ae False dest source 0
+
+class Cmovb a b where
+ cmovb :: a -> b -> CodeGen e s ()
+
+instance Cmovb Reg32 Reg32 where
+ cmovb (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_b False dest source
+
+instance Cmovb Reg32 Addr where
+ cmovb (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_b False dest source
+
+instance Cmovb Reg32 (Disp, Reg32) where
+ cmovb (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_b False dest source disp
+
+instance Cmovb Reg32 Ind where
+ cmovb (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_b False dest source 0
+
+class Cmovbe a b where
+ cmovbe :: a -> b -> CodeGen e s ()
+
+instance Cmovbe Reg32 Reg32 where
+ cmovbe (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_be False dest source
+
+instance Cmovbe Reg32 Addr where
+ cmovbe (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_be False dest source
+
+instance Cmovbe Reg32 (Disp, Reg32) where
+ cmovbe (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_be False dest source disp
+
+instance Cmovbe Reg32 Ind where
+ cmovbe (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_be False dest source 0
+
+class Cmovc a b where
+ cmovc :: a -> b -> CodeGen e s ()
+
+instance Cmovc Reg32 Reg32 where
+ cmovc (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_c False dest source
+
+instance Cmovc Reg32 Addr where
+ cmovc (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_c False dest source
+
+instance Cmovc Reg32 (Disp, Reg32) where
+ cmovc (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_c False dest source disp
+
+instance Cmovc Reg32 Ind where
+ cmovc (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_c False dest source 0
+
+class Cmove a b where
+ cmove :: a -> b -> CodeGen e s ()
+
+instance Cmove Reg32 Reg32 where
+ cmove (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_e False dest source
+
+instance Cmove Reg32 Addr where
+ cmove (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_e False dest source
+
+instance Cmove Reg32 (Disp, Reg32) where
+ cmove (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_e False dest source disp
+
+instance Cmove Reg32 Ind where
+ cmove (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_e False dest source 0
+
+class Cmovna a b where
+ cmovna :: a -> b -> CodeGen e s ()
+
+instance Cmovna Reg32 Reg32 where
+ cmovna (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_na False dest source
+
+instance Cmovna Reg32 Addr where
+ cmovna (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_na False dest source
+
+instance Cmovna Reg32 (Disp, Reg32) where
+ cmovna (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_na False dest source disp
+
+instance Cmovna Reg32 Ind where
+ cmovna (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_na False dest source 0
+
+class Cmovnae a b where
+ cmovnae :: a -> b -> CodeGen e s ()
+
+instance Cmovnae Reg32 Reg32 where
+ cmovnae (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_nae False dest source
+
+instance Cmovnae Reg32 Addr where
+ cmovnae (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_nae False dest source
+
+instance Cmovnae Reg32 (Disp, Reg32) where
+ cmovnae (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nae False dest source disp
+
+instance Cmovnae Reg32 Ind where
+ cmovnae (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nae False dest source 0
+
+class Cmovnb a b where
+ cmovnb :: a -> b -> CodeGen e s ()
+
+instance Cmovnb Reg32 Reg32 where
+ cmovnb (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_nb False dest source
+
+instance Cmovnb Reg32 Addr where
+ cmovnb (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_nb False dest source
+
+instance Cmovnb Reg32 (Disp, Reg32) where
+ cmovnb (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nb False dest source disp
+
+instance Cmovnb Reg32 Ind where
+ cmovnb (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nb False dest source 0
+
+class Cmovnbe a b where
+ cmovnbe :: a -> b -> CodeGen e s ()
+
+instance Cmovnbe Reg32 Reg32 where
+ cmovnbe (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_nbe False dest source
+
+instance Cmovnbe Reg32 Addr where
+ cmovnbe (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_nbe False dest source
+
+instance Cmovnbe Reg32 (Disp, Reg32) where
+ cmovnbe (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nbe False dest source disp
+
+instance Cmovnbe Reg32 Ind where
+ cmovnbe (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nbe False dest source 0
+
+class Cmovnc a b where
+ cmovnc :: a -> b -> CodeGen e s ()
+
+instance Cmovnc Reg32 Reg32 where
+ cmovnc (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_nc False dest source
+
+instance Cmovnc Reg32 Addr where
+ cmovnc (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_nc False dest source
+
+instance Cmovnc Reg32 (Disp, Reg32) where
+ cmovnc (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nc False dest source disp
+
+instance Cmovnc Reg32 Ind where
+ cmovnc (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nc False dest source 0
+
+class Cmovne a b where
+ cmovne :: a -> b -> CodeGen e s ()
+
+instance Cmovne Reg32 Reg32 where
+ cmovne (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_ne False dest source
+
+instance Cmovne Reg32 Addr where
+ cmovne (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_ne False dest source
+
+instance Cmovne Reg32 (Disp, Reg32) where
+ cmovne (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ne False dest source disp
+
+instance Cmovne Reg32 Ind where
+ cmovne (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ne False dest source 0
+
+class Cmovnp a b where
+ cmovnp :: a -> b -> CodeGen e s ()
+
+instance Cmovnp Reg32 Reg32 where
+ cmovnp (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_np False dest source
+
+instance Cmovnp Reg32 Addr where
+ cmovnp (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_np False dest source
+
+instance Cmovnp Reg32 (Disp, Reg32) where
+ cmovnp (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_np False dest source disp
+
+instance Cmovnp Reg32 Ind where
+ cmovnp (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_np False dest source 0
+
+class Cmovnz a b where
+ cmovnz :: a -> b -> CodeGen e s ()
+
+instance Cmovnz Reg32 Reg32 where
+ cmovnz (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_nz False dest source
+
+instance Cmovnz Reg32 Addr where
+ cmovnz (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_nz False dest source
+
+instance Cmovnz Reg32 (Disp, Reg32) where
+ cmovnz (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nz False dest source disp
+
+instance Cmovnz Reg32 Ind where
+ cmovnz (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nz False dest source 0
+
+class Cmovp a b where
+ cmovp :: a -> b -> CodeGen e s ()
+
+instance Cmovp Reg32 Reg32 where
+ cmovp (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_p False dest source
+
+instance Cmovp Reg32 Addr where
+ cmovp (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_p False dest source
+
+instance Cmovp Reg32 (Disp, Reg32) where
+ cmovp (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_p False dest source disp
+
+instance Cmovp Reg32 Ind where
+ cmovp (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_p False dest source 0
+
+class Cmovpe a b where
+ cmovpe :: a -> b -> CodeGen e s ()
+
+instance Cmovpe Reg32 Reg32 where
+ cmovpe (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_pe False dest source
+
+instance Cmovpe Reg32 Addr where
+ cmovpe (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_pe False dest source
+
+instance Cmovpe Reg32 (Disp, Reg32) where
+ cmovpe (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_pe False dest source disp
+
+instance Cmovpe Reg32 Ind where
+ cmovpe (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_pe False dest source 0
+
+class Cmovpo a b where
+ cmovpo :: a -> b -> CodeGen e s ()
+
+instance Cmovpo Reg32 Reg32 where
+ cmovpo (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_po False dest source
+
+instance Cmovpo Reg32 Addr where
+ cmovpo (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_po False dest source
+
+instance Cmovpo Reg32 (Disp, Reg32) where
+ cmovpo (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_po False dest source disp
+
+instance Cmovpo Reg32 Ind where
+ cmovpo (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_po False dest source 0
+
+class Cmovz a b where
+ cmovz :: a -> b -> CodeGen e s ()
+
+instance Cmovz Reg32 Reg32 where
+ cmovz (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_z False dest source
+
+instance Cmovz Reg32 Addr where
+ cmovz (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_z False dest source
+
+instance Cmovz Reg32 (Disp, Reg32) where
+ cmovz (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_z False dest source disp
+
+instance Cmovz Reg32 Ind where
+ cmovz (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_z False dest source 0
+
+class Cmovg a b where
+ cmovg :: a -> b -> CodeGen e s ()
+
+instance Cmovg Reg32 Reg32 where
+ cmovg (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_gt True dest source
+
+instance Cmovg Reg32 Addr where
+ cmovg (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_gt True dest source
+
+instance Cmovg Reg32 (Disp, Reg32) where
+ cmovg (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_gt True dest source disp
+
+instance Cmovg Reg32 Ind where
+ cmovg (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_gt True dest source 0
+
+class Cmovge a b where
+ cmovge :: a -> b -> CodeGen e s ()
+
+instance Cmovge Reg32 Reg32 where
+ cmovge (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_ge True dest source
+
+instance Cmovge Reg32 Addr where
+ cmovge (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_ge True dest source
+
+instance Cmovge Reg32 (Disp, Reg32) where
+ cmovge (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ge True dest source disp
+
+instance Cmovge Reg32 Ind where
+ cmovge (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ge True dest source 0
+
+class Cmovl a b where
+ cmovl :: a -> b -> CodeGen e s ()
+
+instance Cmovl Reg32 Reg32 where
+ cmovl (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_lt True dest source
+
+instance Cmovl Reg32 Addr where
+ cmovl (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_lt True dest source
+
+instance Cmovl Reg32 (Disp, Reg32) where
+ cmovl (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_lt True dest source disp
+
+instance Cmovl Reg32 Ind where
+ cmovl (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_lt True dest source 0
+
+class Cmovle a b where
+ cmovle :: a -> b -> CodeGen e s ()
+
+instance Cmovle Reg32 Reg32 where
+ cmovle (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_le True dest source
+
+instance Cmovle Reg32 Addr where
+ cmovle (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_le True dest source
+
+instance Cmovle Reg32 (Disp, Reg32) where
+ cmovle (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_le True dest source disp
+
+instance Cmovle Reg32 Ind where
+ cmovle (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_le True dest source 0
+
+class Cmovng a b where
+ cmovng :: a -> b -> CodeGen e s ()
+
+instance Cmovng Reg32 Reg32 where
+ cmovng (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_le True dest source
+
+instance Cmovng Reg32 Addr where
+ cmovng (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_le True dest source
+
+instance Cmovng Reg32 (Disp, Reg32) where
+ cmovng (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_le True dest source disp
+
+instance Cmovng Reg32 Ind where
+ cmovng (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_le True dest source 0
+
+class Cmovnge a b where
+ cmovnge :: a -> b -> CodeGen e s ()
+
+instance Cmovnge Reg32 Reg32 where
+ cmovnge (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_lt True dest source
+
+instance Cmovnge Reg32 Addr where
+ cmovnge (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_lt True dest source
+
+instance Cmovnge Reg32 (Disp, Reg32) where
+ cmovnge (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_lt True dest source disp
+
+instance Cmovnge Reg32 Ind where
+ cmovnge (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_lt True dest source 0
+
+class Cmovnl a b where
+ cmovnl :: a -> b -> CodeGen e s ()
+
+instance Cmovnl Reg32 Reg32 where
+ cmovnl (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_ge True dest source
+
+instance Cmovnl Reg32 Addr where
+ cmovnl (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_ge True dest source
+
+instance Cmovnl Reg32 (Disp, Reg32) where
+ cmovnl (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ge True dest source disp
+
+instance Cmovnl Reg32 Ind where
+ cmovnl (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ge True dest source 0
+
+class Cmovnle a b where
+ cmovnle :: a -> b -> CodeGen e s ()
+
+instance Cmovnle Reg32 Reg32 where
+ cmovnle (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_gt True dest source
+
+instance Cmovnle Reg32 Addr where
+ cmovnle (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_gt True dest source
+
+instance Cmovnle Reg32 (Disp, Reg32) where
+ cmovnle (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_gt True dest source disp
+
+instance Cmovnle Reg32 Ind where
+ cmovnle (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_gt True dest source 0
+
+class Cmovno a b where
+ cmovno :: a -> b -> CodeGen e s ()
+
+instance Cmovno Reg32 Reg32 where
+ cmovno (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_no True dest source
+
+instance Cmovno Reg32 Addr where
+ cmovno (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_no True dest source
+
+instance Cmovno Reg32 (Disp, Reg32) where
+ cmovno (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_no True dest source disp
+
+instance Cmovno Reg32 Ind where
+ cmovno (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_no True dest source 0
+
+class Cmovns a b where
+ cmovns :: a -> b -> CodeGen e s ()
+
+instance Cmovns Reg32 Reg32 where
+ cmovns (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_ns True dest source
+
+instance Cmovns Reg32 Addr where
+ cmovns (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_ns True dest source
+
+instance Cmovns Reg32 (Disp, Reg32) where
+ cmovns (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ns True dest source disp
+
+instance Cmovns Reg32 Ind where
+ cmovns (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ns True dest source 0
+
+class Cmovo a b where
+ cmovo :: a -> b -> CodeGen e s ()
+
+instance Cmovo Reg32 Reg32 where
+ cmovo (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_o True dest source
+
+instance Cmovo Reg32 Addr where
+ cmovo (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_o True dest source
+
+instance Cmovo Reg32 (Disp, Reg32) where
+ cmovo (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_o True dest source disp
+
+instance Cmovo Reg32 Ind where
+ cmovo (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_o True dest source 0
+
+class Cmovs a b where
+ cmovs :: a -> b -> CodeGen e s ()
+
+instance Cmovs Reg32 Reg32 where
+ cmovs (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_s True dest source
+
+instance Cmovs Reg32 Addr where
+ cmovs (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_s True dest source
+
+instance Cmovs Reg32 (Disp, Reg32) where
+ cmovs (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_s True dest source disp
+
+instance Cmovs Reg32 Ind where
+ cmovs (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_s True dest source 0
+
+
+-- release stack frame
+
+leave :: CodeGen e s ()
+leave = ensureBufferSize x86_max_instruction_bytes >> x86_leave
+
+
+-- store ah into flags
+
+sahf :: CodeGen e s ()
+sahf = ensureBufferSize x86_max_instruction_bytes >> x86_sahf
+
+-- Floating point instructions
+
+fldz = ensureBufferSize x86_max_instruction_bytes >> x86_fldz
+fld1 = ensureBufferSize x86_max_instruction_bytes >> x86_fld1
+fldpi = ensureBufferSize x86_max_instruction_bytes >> x86_fldpi
+
+fstsw = ensureBufferSize x86_max_instruction_bytes >> x86_fstsw
+fnstsw = ensureBufferSize x86_max_instruction_bytes >> x86_fstsw
+
+fcompp = ensureBufferSize x86_max_instruction_bytes >> x86_fcompp
+fucompp = ensureBufferSize x86_max_instruction_bytes >> x86_fucompp
+
+fchs = ensureBufferSize x86_max_instruction_bytes >> x86_fchs
+frem = ensureBufferSize x86_max_instruction_bytes >> x86_frem
+
+fxch (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fxch idx
+
+fcomi (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fcomi idx
+fcomip (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fcomip idx
+fucomi (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fucomi idx
+fucomip (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fucomip idx
+
+fsin = ensureBufferSize x86_max_instruction_bytes >> x86_fsin
+fcos = ensureBufferSize x86_max_instruction_bytes >> x86_fcos
+fptan = ensureBufferSize x86_max_instruction_bytes >> x86_fptan
+fpatan = ensureBufferSize x86_max_instruction_bytes >> x86_fpatan
+fabs = ensureBufferSize x86_max_instruction_bytes >> x86_fabs
+ftst = ensureBufferSize x86_max_instruction_bytes >> x86_ftst
+fxam = ensureBufferSize x86_max_instruction_bytes >> x86_fxam
+fprem = ensureBufferSize x86_max_instruction_bytes >> x86_fprem
+fprem1 = ensureBufferSize x86_max_instruction_bytes >> x86_fprem1
+frndint = ensureBufferSize x86_max_instruction_bytes >> x86_frndint
+fsqrt = ensureBufferSize x86_max_instruction_bytes >> x86_fsqrt
+
+class Fadd a b where
+ fadd :: a -> b -> CodeGen e s ()
+
+instance Fadd FPTopReg FPReg where
+ fadd FPTopReg (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op x86_fadd idx
+
+instance Fadd FPTopReg Addr where
+ fadd FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_mem x86_fadd a True
+
+instance Fadd FPTopReg (Disp, Reg32) where
+ fadd FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fadd r d True
+
+instance Fadd FPTopReg Ind where
+ fadd FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fadd r 0 True
+
+instance Fadd FPReg FPTopReg where
+ fadd (FPReg idx) FPTopReg = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_reg x86_fadd idx False
+
+
+class Faddp a b where
+ faddp :: a -> b -> CodeGen e s ()
+
+instance Faddp FPReg FPTopReg where
+ faddp (FPReg idx) FPTopReg = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_reg x86_fadd idx True
+
+
+class Fiadd a b where
+ fiadd32 :: a -> b -> CodeGen e s ()
+ fiadd16 :: a -> b -> CodeGen e s ()
+
+instance Fiadd FPTopReg (Disp, Reg32) where
+ fiadd32 FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_int_op_membase x86_fadd r d True
+ fiadd16 FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_int_op_membase x86_fadd r d False
+
+instance Fiadd FPTopReg Ind where
+ fiadd32 FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_int_op_membase x86_fadd r 0 True
+ fiadd16 FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_int_op_membase x86_fadd r 0 False
+
+
+class Fsub a b where
+ fsub :: a -> b -> CodeGen e s ()
+
+instance Fsub FPTopReg FPReg where
+ fsub FPTopReg (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op x86_fsub idx
+
+instance Fsub FPTopReg Addr where
+ fsub FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_mem x86_fsub a True
+
+instance Fsub FPTopReg (Disp, Reg32) where
+ fsub FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fsub r d True
+
+instance Fsub FPTopReg Ind where
+ fsub FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fsub r 0 True
+
+instance Fsub FPReg FPTopReg where
+ fsub (FPReg idx) FPTopReg = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_reg x86_fsub idx False
+
+
+class Fsubp a b where
+ fsubp :: a -> b -> CodeGen e s ()
+
+instance Fsubp FPReg FPTopReg where
+ fsubp (FPReg idx) FPTopReg = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_reg x86_fsub idx True
+
+
+class Fisub a b where
+ fisub32 :: a -> b -> CodeGen e s ()
+ fisub16 :: a -> b -> CodeGen e s ()
+
+instance Fisub FPTopReg (Disp, Reg32) where
+ fisub32 FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_int_op_membase x86_fsub r d True
+ fisub16 FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_int_op_membase x86_fsub r d False
+
+instance Fisub FPTopReg Ind where
+ fisub32 FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_int_op_membase x86_fsub r 0 True
+ fisub16 FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_int_op_membase x86_fsub r 0 False
+
+
+class Fsubr a b where
+ fsubr :: a -> b -> CodeGen e s ()
+
+instance Fsubr FPTopReg FPReg where
+ fsubr FPTopReg (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op x86_fsubr idx
+
+instance Fsubr FPTopReg Addr where
+ fsubr FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_mem x86_fsubr a True
+
+instance Fsubr FPTopReg (Disp, Reg32) where
+ fsubr FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fsubr r d True
+
+instance Fsubr FPTopReg Ind where
+ fsubr FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fsubr r 0 True
+
+
+class Fmul a b where
+ fmul :: a -> b -> CodeGen e s ()
+
+instance Fmul FPTopReg FPReg where
+ fmul FPTopReg (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op x86_fmul idx
+
+instance Fmul FPTopReg Addr where
+ fmul FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_mem x86_fmul a True
+
+instance Fmul FPTopReg (Disp, Reg32) where
+ fmul FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fmul r d True
+
+instance Fmul FPTopReg Ind where
+ fmul FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fmul r 0 True
+
+instance Fmul FPReg FPTopReg where
+ fmul (FPReg idx) FPTopReg = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_reg x86_fmul idx False
+
+
+class Fmulp a b where
+ fmulp :: a -> b -> CodeGen e s ()
+
+instance Fmulp FPReg FPTopReg where
+ fmulp (FPReg idx) FPTopReg = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_reg x86_fmul idx True
+
+
+class Fimul a b where
+ fimul32 :: a -> b -> CodeGen e s ()
+ fimul16 :: a -> b -> CodeGen e s ()
+
+instance Fimul FPTopReg (Disp, Reg32) where
+ fimul32 FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_int_op_membase x86_fmul r d True
+ fimul16 FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_int_op_membase x86_fmul r d False
+
+instance Fimul FPTopReg Ind where
+ fimul32 FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_int_op_membase x86_fmul r 0 True
+ fimul16 FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_int_op_membase x86_fmul r 0 False
+
+
+class Fdiv a b where
+ fdiv :: a -> b -> CodeGen e s ()
+
+instance Fdiv FPTopReg FPReg where
+ fdiv FPTopReg (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op x86_fdiv idx
+
+instance Fdiv FPTopReg Addr where
+ fdiv FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_mem x86_fdiv a True
+
+instance Fdiv FPTopReg (Disp, Reg32) where
+ fdiv FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fdiv r d True
+
+instance Fdiv FPTopReg Ind where
+ fdiv FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fdiv r 0 True
+
+instance Fdiv FPReg FPTopReg where
+ fdiv (FPReg idx) FPTopReg = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_reg x86_fdiv idx False
+
+
+class Fdivp a b where
+ fdivp :: a -> b -> CodeGen e s ()
+
+instance Fdivp FPReg FPTopReg where
+ fdivp (FPReg idx) FPTopReg = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_reg x86_fdiv idx True
+
+
+class Fidiv a b where
+ fidiv32 :: a -> b -> CodeGen e s ()
+ fidiv16 :: a -> b -> CodeGen e s ()
+
+instance Fidiv FPTopReg (Disp, Reg32) where
+ fidiv32 FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_int_op_membase x86_fdiv r d True
+ fidiv16 FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_int_op_membase x86_fdiv r d False
+
+instance Fidiv FPTopReg Ind where
+ fidiv32 FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_int_op_membase x86_fdiv r 0 True
+ fidiv16 FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_int_op_membase x86_fdiv r 0 False
+
+
+class Fdivr a b where
+ fdivr :: a -> b -> CodeGen e s ()
+
+instance Fdivr FPTopReg FPReg where
+ fdivr FPTopReg (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op x86_fdivr idx
+
+instance Fdivr FPTopReg Addr where
+ fdivr FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_mem x86_fdivr a True
+
+instance Fdivr FPTopReg (Disp, Reg32) where
+ fdivr FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fdivr r d True
+
+instance Fdivr FPTopReg Ind where
+ fdivr FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fdivr r 0 True
+
+
+class Fcom a b where
+ fcom :: a -> b -> CodeGen e s ()
+
+instance Fcom FPTopReg FPReg where
+ fcom FPTopReg (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op x86_fcom idx
+
+instance Fcom FPTopReg Addr where
+ fcom FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_mem x86_fcom a True
+
+instance Fcom FPTopReg (Disp, Reg32) where
+ fcom FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fcom r d True
+
+instance Fcom FPTopReg Ind where
+ fcom FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fcom r 0 True
+
+
+class Fcomp a b where
+ fcomp :: a -> b -> CodeGen e s ()
+
+instance Fcomp FPTopReg FPReg where
+ fcomp FPTopReg (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op x86_fcomp idx
+
+instance Fcomp FPTopReg Addr where
+ fcomp FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_mem x86_fcomp a True
+
+instance Fcomp FPTopReg (Disp, Reg32) where
+ fcomp FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fcomp r d True
+
+instance Fcomp FPTopReg Ind where
+ fcomp FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fcomp r 0 True
+
+
+class Fld a b where
+ fld :: a -> b -> CodeGen e s ()
+
+instance Fld FPTopReg FPReg where
+ fld FPTopReg (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fld_reg idx
+
+instance Fld FPTopReg Addr where
+ fld FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fld a True
+
+instance Fld FPTopReg (Disp, Reg32) where
+ fld FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fld_membase r d True
+
+instance Fld FPTopReg Ind where
+ fld FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fld_membase r 0 True
+
+class Fld80 a b where
+ fld80 :: a -> b -> CodeGen e s ()
+
+instance Fld80 FPTopReg Addr where
+ fld80 FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fld80_mem a
+
+instance Fld80 FPTopReg (Disp, Reg32) where
+ fld80 FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fld80_membase r d
+
+instance Fld80 FPTopReg Ind where
+ fld80 FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fld80_membase r 0
+
+class Fst a where
+ fst :: a -> CodeGen e s ()
+
+instance Fst Addr where
+ fst (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fst a True False
+
+instance Fst (Disp, Reg32) where
+ fst (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fst_membase r d True False
+
+instance Fst Ind where
+ fst (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fst_membase r 0 True False
+
+class Fstp a where
+ fstp :: a -> CodeGen e s ()
+
+instance Fstp FPReg where
+ fstp (FPReg r) = ensureBufferSize x86_max_instruction_bytes >> x86_fstp r
+
+instance Fstp Addr where
+ fstp (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fst a True True
+
+instance Fstp (Disp, Reg32) where
+ fstp (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fst_membase r d True True
+
+instance Fstp Ind where
+ fstp (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fst_membase r 0 True True
+
+
+class Fst80 a where
+ fst80 :: a -> CodeGen e s ()
+
+instance Fst80 Addr where
+ fst80 (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fst80_mem a
+
+instance Fst80 (Disp, Reg32) where
+ fst80 (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fst80_membase r d
+
+instance Fst80 Ind where
+ fst80 (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fst80_membase r 0
+
+
+class Fnstcw a where
+ fnstcw :: a -> CodeGen e s ()
+
+instance Fnstcw Addr where
+ fnstcw (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fnstcw a
+
+instance Fnstcw (Disp, Reg32) where
+ fnstcw (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fnstcw_membase r d
+
+instance Fnstcw Ind where
+ fnstcw (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fnstcw_membase r 0
+
+
+class Fldcw a where
+ fldcw :: a -> CodeGen e s ()
+
+instance Fldcw Addr where
+ fldcw (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fldcw a
+
+instance Fldcw (Disp, Reg32) where
+ fldcw (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fldcw_membase r d
+
+instance Fldcw Ind where
+ fldcw (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fldcw_membase r 0
+
+
+class Fild a where
+ fild :: a -> CodeGen e s ()
+
+instance Fild Addr where
+ fild (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fild a FInt32
+
+instance Fild (Disp, Reg32) where
+ fild (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fild_membase r d FInt32
+
+instance Fild Ind where
+ fild (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fild_membase r 0 FInt32
+
+
+class Fist a where
+ fist :: a -> CodeGen e s ()
+
+instance Fist (Disp, Reg32) where
+ fist (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fist_membase r d FInt32
+
+instance Fist Ind where
+ fist (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fist_membase r 0 FInt32
+
+
+class Fistp a where
+ fistp :: a -> CodeGen e s ()
+
+instance Fistp Addr where
+ fistp (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fist_pop a FInt32
+
+instance Fistp (Disp, Reg32) where
+ fistp (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fist_pop_membase r d FInt32
+
+instance Fistp Ind where
+ fistp (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fist_pop_membase r 0 FInt32
+
+
+class Sqrtsd a b where
+ sqrtsd :: a -> b -> CodeGen e s ()
+
+instance Sqrtsd XMMReg XMMReg where
+ sqrtsd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_reg x86_sse_sd xd xs
+
+instance Sqrtsd XMMReg Addr where
+ sqrtsd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_mem x86_sse_sd xd a
+
+instance Sqrtsd XMMReg Ind where
+ sqrtsd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_membase x86_sse_sd xd r 0
+
+instance Sqrtsd XMMReg (Disp, Reg32) where
+ sqrtsd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_membase x86_sse_sd xd r d
+
+
+class Sqrtss a b where
+ sqrtss :: a -> b -> CodeGen e s ()
+
+instance Sqrtss XMMReg XMMReg where
+ sqrtss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_reg x86_sse_ss xd xs
+
+instance Sqrtss XMMReg Addr where
+ sqrtss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_mem x86_sse_ss xd a
+
+instance Sqrtss XMMReg Ind where
+ sqrtss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_membase x86_sse_ss xd r 0
+
+instance Sqrtss XMMReg (Disp, Reg32) where
+ sqrtss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_membase x86_sse_ss xd r d
+
+
+class Sqrtpd a b where
+ sqrtpd :: a -> b -> CodeGen e s ()
+
+instance Sqrtpd XMMReg XMMReg where
+ sqrtpd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_reg x86_sse_pd xd xs
+
+instance Sqrtpd XMMReg Addr where
+ sqrtpd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_mem x86_sse_pd xd a
+
+instance Sqrtpd XMMReg Ind where
+ sqrtpd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_membase x86_sse_pd xd r 0
+
+instance Sqrtpd XMMReg (Disp, Reg32) where
+ sqrtpd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_membase x86_sse_pd xd r d
+
+
+class Sqrtps a b where
+ sqrtps :: a -> b -> CodeGen e s ()
+
+instance Sqrtps XMMReg XMMReg where
+ sqrtps (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_reg x86_sse_ps xd xs
+
+instance Sqrtps XMMReg Addr where
+ sqrtps (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_mem x86_sse_ps xd a
+
+instance Sqrtps XMMReg Ind where
+ sqrtps (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_membase x86_sse_ps xd r 0
+
+instance Sqrtps XMMReg (Disp, Reg32) where
+ sqrtps (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_membase x86_sse_ps xd r d
+
+
+class Addsd a b where
+ addsd :: a -> b -> CodeGen e s ()
+
+instance Addsd XMMReg XMMReg where
+ addsd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_reg x86_sse_sd xd xs
+
+instance Addsd XMMReg Addr where
+ addsd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_mem x86_sse_sd xd a
+
+instance Addsd XMMReg Ind where
+ addsd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_membase x86_sse_sd xd r 0
+
+instance Addsd XMMReg (Disp, Reg32) where
+ addsd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_membase x86_sse_sd xd r d
+
+
+class Addss a b where
+ addss :: a -> b -> CodeGen e s ()
+
+instance Addss XMMReg XMMReg where
+ addss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_reg x86_sse_ss xd xs
+
+instance Addss XMMReg Addr where
+ addss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_mem x86_sse_ss xd a
+
+instance Addss XMMReg Ind where
+ addss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_membase x86_sse_ss xd r 0
+
+instance Addss XMMReg (Disp, Reg32) where
+ addss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_membase x86_sse_ss xd r d
+
+
+class Addpd a b where
+ addpd :: a -> b -> CodeGen e s ()
+
+instance Addpd XMMReg XMMReg where
+ addpd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_reg x86_sse_pd xd xs
+
+instance Addpd XMMReg Addr where
+ addpd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_mem x86_sse_pd xd a
+
+instance Addpd XMMReg Ind where
+ addpd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_membase x86_sse_pd xd r 0
+
+instance Addpd XMMReg (Disp, Reg32) where
+ addpd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_membase x86_sse_pd xd r d
+
+
+class Addps a b where
+ addps :: a -> b -> CodeGen e s ()
+
+instance Addps XMMReg XMMReg where
+ addps (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_reg x86_sse_ps xd xs
+
+instance Addps XMMReg Addr where
+ addps (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_mem x86_sse_ps xd a
+
+instance Addps XMMReg Ind where
+ addps (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_membase x86_sse_ps xd r 0
+
+instance Addps XMMReg (Disp, Reg32) where
+ addps (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_membase x86_sse_ps xd r d
+
+class Subsd a b where
+ subsd :: a -> b -> CodeGen e s ()
+
+instance Subsd XMMReg XMMReg where
+ subsd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_reg x86_sse_sd xd xs
+
+instance Subsd XMMReg Addr where
+ subsd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_mem x86_sse_sd xd a
+
+instance Subsd XMMReg Ind where
+ subsd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_membase x86_sse_sd xd r 0
+
+instance Subsd XMMReg (Disp, Reg32) where
+ subsd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_membase x86_sse_sd xd r d
+
+
+class Subss a b where
+ subss :: a -> b -> CodeGen e s ()
+
+instance Subss XMMReg XMMReg where
+ subss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_reg x86_sse_ss xd xs
+
+instance Subss XMMReg Addr where
+ subss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_mem x86_sse_ss xd a
+
+instance Subss XMMReg Ind where
+ subss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_membase x86_sse_ss xd r 0
+
+instance Subss XMMReg (Disp, Reg32) where
+ subss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_membase x86_sse_ss xd r d
+
+
+class Subpd a b where
+ subpd :: a -> b -> CodeGen e s ()
+
+instance Subpd XMMReg XMMReg where
+ subpd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_reg x86_sse_pd xd xs
+
+instance Subpd XMMReg Addr where
+ subpd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_mem x86_sse_pd xd a
+
+instance Subpd XMMReg Ind where
+ subpd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_membase x86_sse_pd xd r 0
+
+instance Subpd XMMReg (Disp, Reg32) where
+ subpd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_membase x86_sse_pd xd r d
+
+
+class Subps a b where
+ subps :: a -> b -> CodeGen e s ()
+
+instance Subps XMMReg XMMReg where
+ subps (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_reg x86_sse_ps xd xs
+
+instance Subps XMMReg Addr where
+ subps (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_mem x86_sse_ps xd a
+
+instance Subps XMMReg Ind where
+ subps (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_membase x86_sse_ps xd r 0
+
+instance Subps XMMReg (Disp, Reg32) where
+ subps (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_membase x86_sse_ps xd r d
+
+class Mulsd a b where
+ mulsd :: a -> b -> CodeGen e s ()
+
+instance Mulsd XMMReg XMMReg where
+ mulsd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_reg x86_sse_sd xd xs
+
+instance Mulsd XMMReg Addr where
+ mulsd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_mem x86_sse_sd xd a
+
+instance Mulsd XMMReg Ind where
+ mulsd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_membase x86_sse_sd xd r 0
+
+instance Mulsd XMMReg (Disp, Reg32) where
+ mulsd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_membase x86_sse_sd xd r d
+
+
+class Mulss a b where
+ mulss :: a -> b -> CodeGen e s ()
+
+instance Mulss XMMReg XMMReg where
+ mulss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_reg x86_sse_ss xd xs
+
+instance Mulss XMMReg Addr where
+ mulss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_mem x86_sse_ss xd a
+
+instance Mulss XMMReg Ind where
+ mulss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_membase x86_sse_ss xd r 0
+
+instance Mulss XMMReg (Disp, Reg32) where
+ mulss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_membase x86_sse_ss xd r d
+
+
+class Mulpd a b where
+ mulpd :: a -> b -> CodeGen e s ()
+
+instance Mulpd XMMReg XMMReg where
+ mulpd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_reg x86_sse_pd xd xs
+
+instance Mulpd XMMReg Addr where
+ mulpd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_mem x86_sse_pd xd a
+
+instance Mulpd XMMReg Ind where
+ mulpd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_membase x86_sse_pd xd r 0
+
+instance Mulpd XMMReg (Disp, Reg32) where
+ mulpd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_membase x86_sse_pd xd r d
+
+
+class Mulps a b where
+ mulps :: a -> b -> CodeGen e s ()
+
+instance Mulps XMMReg XMMReg where
+ mulps (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_reg x86_sse_ps xd xs
+
+instance Mulps XMMReg Addr where
+ mulps (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_mem x86_sse_ps xd a
+
+instance Mulps XMMReg Ind where
+ mulps (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_membase x86_sse_ps xd r 0
+
+instance Mulps XMMReg (Disp, Reg32) where
+ mulps (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_membase x86_sse_ps xd r d
+
+
+class Divsd a b where
+ divsd :: a -> b -> CodeGen e s ()
+
+instance Divsd XMMReg XMMReg where
+ divsd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_reg x86_sse_sd xd xs
+
+instance Divsd XMMReg Addr where
+ divsd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_mem x86_sse_sd xd a
+
+instance Divsd XMMReg Ind where
+ divsd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_membase x86_sse_sd xd r 0
+
+instance Divsd XMMReg (Disp, Reg32) where
+ divsd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_membase x86_sse_sd xd r d
+
+
+class Divss a b where
+ divss :: a -> b -> CodeGen e s ()
+
+instance Divss XMMReg XMMReg where
+ divss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_reg x86_sse_ss xd xs
+
+instance Divss XMMReg Addr where
+ divss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_mem x86_sse_ss xd a
+
+instance Divss XMMReg Ind where
+ divss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_membase x86_sse_ss xd r 0
+
+instance Divss XMMReg (Disp, Reg32) where
+ divss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_membase x86_sse_ss xd r d
+
+
+class Divpd a b where
+ divpd :: a -> b -> CodeGen e s ()
+
+instance Divpd XMMReg XMMReg where
+ divpd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_reg x86_sse_pd xd xs
+
+instance Divpd XMMReg Addr where
+ divpd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_mem x86_sse_pd xd a
+
+instance Divpd XMMReg Ind where
+ divpd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_membase x86_sse_pd xd r 0
+
+instance Divpd XMMReg (Disp, Reg32) where
+ divpd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_membase x86_sse_pd xd r d
+
+
+class Divps a b where
+ divps :: a -> b -> CodeGen e s ()
+
+instance Divps XMMReg XMMReg where
+ divps (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_reg x86_sse_ps xd xs
+
+instance Divps XMMReg Addr where
+ divps (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_mem x86_sse_ps xd a
+
+instance Divps XMMReg Ind where
+ divps (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_membase x86_sse_ps xd r 0
+
+instance Divps XMMReg (Disp, Reg32) where
+ divps (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_membase x86_sse_ps xd r d
+
+class Minsd a b where
+ minsd :: a -> b -> CodeGen e s ()
+
+instance Minsd XMMReg XMMReg where
+ minsd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_reg x86_sse_sd xd xs
+
+instance Minsd XMMReg Addr where
+ minsd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_mem x86_sse_sd xd a
+
+instance Minsd XMMReg Ind where
+ minsd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_membase x86_sse_sd xd r 0
+
+instance Minsd XMMReg (Disp, Reg32) where
+ minsd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_membase x86_sse_sd xd r d
+
+
+class Minss a b where
+ minss :: a -> b -> CodeGen e s ()
+
+instance Minss XMMReg XMMReg where
+ minss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_reg x86_sse_ss xd xs
+
+instance Minss XMMReg Addr where
+ minss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_mem x86_sse_ss xd a
+
+instance Minss XMMReg Ind where
+ minss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_membase x86_sse_ss xd r 0
+
+instance Minss XMMReg (Disp, Reg32) where
+ minss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_membase x86_sse_ss xd r d
+
+
+class Minpd a b where
+ minpd :: a -> b -> CodeGen e s ()
+
+instance Minpd XMMReg XMMReg where
+ minpd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_reg x86_sse_pd xd xs
+
+instance Minpd XMMReg Addr where
+ minpd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_mem x86_sse_pd xd a
+
+instance Minpd XMMReg Ind where
+ minpd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_membase x86_sse_pd xd r 0
+
+instance Minpd XMMReg (Disp, Reg32) where
+ minpd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_membase x86_sse_pd xd r d
+
+
+class Minps a b where
+ minps :: a -> b -> CodeGen e s ()
+
+instance Minps XMMReg XMMReg where
+ minps (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_reg x86_sse_ps xd xs
+
+instance Minps XMMReg Addr where
+ minps (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_mem x86_sse_ps xd a
+
+instance Minps XMMReg Ind where
+ minps (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_membase x86_sse_ps xd r 0
+
+instance Minps XMMReg (Disp, Reg32) where
+ minps (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_membase x86_sse_ps xd r d
+
+
+class Maxsd a b where
+ maxsd :: a -> b -> CodeGen e s ()
+
+instance Maxsd XMMReg XMMReg where
+ maxsd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_reg x86_sse_sd xd xs
+
+instance Maxsd XMMReg Addr where
+ maxsd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_mem x86_sse_sd xd a
+
+instance Maxsd XMMReg Ind where
+ maxsd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_membase x86_sse_sd xd r 0
+
+instance Maxsd XMMReg (Disp, Reg32) where
+ maxsd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_membase x86_sse_sd xd r d
+
+
+class Maxss a b where
+ maxss :: a -> b -> CodeGen e s ()
+
+instance Maxss XMMReg XMMReg where
+ maxss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_reg x86_sse_ss xd xs
+
+instance Maxss XMMReg Addr where
+ maxss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_mem x86_sse_ss xd a
+
+instance Maxss XMMReg Ind where
+ maxss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_membase x86_sse_ss xd r 0
+
+instance Maxss XMMReg (Disp, Reg32) where
+ maxss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_membase x86_sse_ss xd r d
+
+
+class Maxpd a b where
+ maxpd :: a -> b -> CodeGen e s ()
+
+instance Maxpd XMMReg XMMReg where
+ maxpd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_reg x86_sse_pd xd xs
+
+instance Maxpd XMMReg Addr where
+ maxpd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_mem x86_sse_pd xd a
+
+instance Maxpd XMMReg Ind where
+ maxpd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_membase x86_sse_pd xd r 0
+
+instance Maxpd XMMReg (Disp, Reg32) where
+ maxpd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_membase x86_sse_pd xd r d
+
+
+class Maxps a b where
+ maxps :: a -> b -> CodeGen e s ()
+
+instance Maxps XMMReg XMMReg where
+ maxps (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_reg x86_sse_ps xd xs
+
+instance Maxps XMMReg Addr where
+ maxps (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_mem x86_sse_ps xd a
+
+instance Maxps XMMReg Ind where
+ maxps (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_membase x86_sse_ps xd r 0
+
+instance Maxps XMMReg (Disp, Reg32) where
+ maxps (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_membase x86_sse_ps xd r d
+
+
+class Movss a b where
+ movss :: a -> b -> CodeGen e s ()
+
+instance Movss XMMReg XMMReg where
+ movss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_reg_reg x86_sse_ss xd xs
+
+instance Movss XMMReg Addr where
+ movss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_reg_mem x86_sse_ss xd a
+
+instance Movss Addr XMMReg where
+ movss (Addr a) (XMMReg xd) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_mem_reg x86_sse_ss a xd
+
+instance Movss XMMReg Ind where
+ movss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_reg_membase x86_sse_ss xd r 0
+
+instance Movss Ind XMMReg where
+ movss (Ind (Reg32 r)) (XMMReg xd) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_membase_reg x86_sse_ss r 0 xd
+
+instance Movss XMMReg (Disp, Reg32) where
+ movss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_reg_membase x86_sse_ss xd r d
+
+instance Movss (Disp, Reg32) XMMReg where
+ movss (Disp d, Reg32 r) (XMMReg xd) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_membase_reg x86_sse_ss r d xd
+
+
+class Movsd a b where
+ movsd :: a -> b -> CodeGen e s ()
+
+instance Movsd XMMReg XMMReg where
+ movsd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_reg_reg x86_sse_sd xd xs
+
+instance Movsd XMMReg Addr where
+ movsd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_reg_mem x86_sse_sd xd a
+
+instance Movsd Addr XMMReg where
+ movsd (Addr a) (XMMReg xd) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_mem_reg x86_sse_sd a xd
+
+instance Movsd XMMReg Ind where
+ movsd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_reg_membase x86_sse_sd xd r 0
+
+instance Movsd Ind XMMReg where
+ movsd (Ind (Reg32 r)) (XMMReg xd) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_membase_reg x86_sse_sd r 0 xd
+
+instance Movsd XMMReg (Disp, Reg32) where
+ movsd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_reg_membase x86_sse_sd xd r d
+
+instance Movsd (Disp, Reg32) XMMReg where
+ movsd (Disp d, Reg32 r) (XMMReg xd) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_membase_reg x86_sse_sd r d xd
+
+
+class Movups a b where
+ movups :: a -> b -> CodeGen e s ()
+
+instance Movups XMMReg XMMReg where
+ movups (XMMReg xd) xs = ensureBufferSize x86_max_instruction_bytes >> x86_movups_to_reg xd (xmmLocLowLevel xs)
+
+instance Movups XMMReg Addr where
+ movups (XMMReg xd) xs = ensureBufferSize x86_max_instruction_bytes >> x86_movups_to_reg xd (xmmLocLowLevel xs)
+
+instance Movups Addr XMMReg where
+ movups xd (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_movups_from_reg xs (xmmLocLowLevel xd)
+
+instance Movups XMMReg Ind where
+ movups (XMMReg xd) xs = ensureBufferSize x86_max_instruction_bytes >> x86_movups_to_reg xd (xmmLocLowLevel xs)
+
+instance Movups Ind XMMReg where
+ movups xd (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_movups_from_reg xs (xmmLocLowLevel xd)
+
+instance Movups XMMReg (Disp, Reg32) where
+ movups (XMMReg xd) xs = ensureBufferSize x86_max_instruction_bytes >> x86_movups_to_reg xd (xmmLocLowLevel xs)
+
+instance Movups (Disp, Reg32) XMMReg where
+ movups xd (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_movups_from_reg xs (xmmLocLowLevel xd)
+
+
+class Movlps a b where
+ movlps :: a -> b -> CodeGen e s ()
+
+instance Movlps XMMReg XMMReg where
+ movlps (XMMReg xd) xs = ensureBufferSize x86_max_instruction_bytes >> x86_movlps_to_reg xd (xmmLocLowLevel xs)
+
+instance Movlps XMMReg Addr where
+ movlps (XMMReg xd) xs = ensureBufferSize x86_max_instruction_bytes >> x86_movlps_to_reg xd (xmmLocLowLevel xs)
+
+instance Movlps Addr XMMReg where
+ movlps xd (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_movlps_from_reg xs (xmmLocLowLevel xd)
+
+instance Movlps XMMReg Ind where
+ movlps (XMMReg xd) xs = ensureBufferSize x86_max_instruction_bytes >> x86_movlps_to_reg xd (xmmLocLowLevel xs)
+
+instance Movlps Ind XMMReg where
+ movlps xd (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_movlps_from_reg xs (xmmLocLowLevel xd)
+
+instance Movlps XMMReg (Disp, Reg32) where
+ movlps (XMMReg xd) xs = ensureBufferSize x86_max_instruction_bytes >> x86_movlps_to_reg xd (xmmLocLowLevel xs)
+
+instance Movlps (Disp, Reg32) XMMReg where
+ movlps xd (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_movlps_from_reg xs (xmmLocLowLevel xd)
+
+
+class Comisd a b where
+ comisd :: a -> b -> CodeGen e s ()
+
+instance Comisd XMMReg XMMReg where
+ comisd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_comisd_reg_reg xd xs
+
+instance Comisd XMMReg Addr where
+ comisd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_comisd_reg_mem xd a
+
+instance Comisd XMMReg Ind where
+ comisd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_comisd_reg_membase xd r 0
+
+instance Comisd XMMReg (Disp, Reg32) where
+ comisd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_comisd_reg_membase xd r d
+
+
+class Comiss a b where
+ comiss :: a -> b -> CodeGen e s ()
+
+instance Comiss XMMReg XMMReg where
+ comiss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_comiss_reg_reg xd xs
+
+instance Comiss XMMReg Addr where
+ comiss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_comiss_reg_mem xd a
+
+instance Comiss XMMReg Ind where
+ comiss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_comiss_reg_membase xd r 0
+
+instance Comiss XMMReg (Disp, Reg32) where
+ comiss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_comiss_reg_membase xd r d
+
+
+class Ucomisd a b where
+ ucomisd :: a -> b -> CodeGen e s ()
+
+instance Ucomisd XMMReg XMMReg where
+ ucomisd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_ucomisd_reg_reg xd xs
+
+instance Ucomisd XMMReg Addr where
+ ucomisd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_ucomisd_reg_mem xd a
+
+instance Ucomisd XMMReg Ind where
+ ucomisd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_ucomisd_reg_membase xd r 0
+
+instance Ucomisd XMMReg (Disp, Reg32) where
+ ucomisd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_ucomisd_reg_membase xd r d
+
+
+class Ucomiss a b where
+ ucomiss :: a -> b -> CodeGen e s ()
+
+instance Ucomiss XMMReg XMMReg where
+ ucomiss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_ucomiss_reg_reg xd xs
+
+instance Ucomiss XMMReg Addr where
+ ucomiss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_ucomiss_reg_mem xd a
+
+instance Ucomiss XMMReg Ind where
+ ucomiss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_ucomiss_reg_membase xd r 0
+
+instance Ucomiss XMMReg (Disp, Reg32) where
+ ucomiss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_ucomiss_reg_membase xd r d
+
+
+class XMMLocation b => XMMLoc a b | a -> b where
+ xmmLocLowLevel :: a -> b
+
+instance XMMLoc XMMReg XMMReg where
+ xmmLocLowLevel = id
+
+instance XMMLoc Addr Mem where
+ xmmLocLowLevel (Addr a) = Mem a
+
+instance XMMLoc Ind MemBase where
+ xmmLocLowLevel (Ind (Reg32 r)) = MemBase r 0
+
+instance XMMLoc (Disp, Reg32) MemBase where
+ xmmLocLowLevel (Disp d, Reg32 r) = MemBase r d
+
+
+haddps :: XMMLoc xmm a => XMMReg -> xmm -> CodeGen e s ()
+haddps (XMMReg dreg) reg =
+ x86_haddps dreg (xmmLocLowLevel reg)
+
+haddpd :: XMMLoc xmm a => XMMReg -> xmm -> CodeGen e s ()
+haddpd (XMMReg dreg) reg =
+ x86_haddpd dreg (xmmLocLowLevel reg)
+
+
+shufps :: XMMLoc xmm a => XMMReg -> xmm -> Word8 -> CodeGen e s ()
+shufps (XMMReg dreg) reg src =
+ x86_shufps dreg (xmmLocLowLevel reg) src
+
+shufpd :: XMMLoc xmm a => XMMReg -> xmm -> Word8 -> CodeGen e s ()
+shufpd (XMMReg dreg) reg src =
+ x86_shufpd dreg (xmmLocLowLevel reg) src
+
+
+cvtdq2ps :: XMMLoc xmm a => XMMReg -> xmm -> CodeGen e s ()
+cvtdq2ps (XMMReg dreg) reg =
+ x86_cvtdq2ps dreg (xmmLocLowLevel reg)
+
+cvttps2dq :: XMMLoc xmm a => XMMReg -> xmm -> CodeGen e s ()
+cvttps2dq (XMMReg dreg) reg =
+ x86_cvttps2dq dreg (xmmLocLowLevel reg)
+
+
+class Prefetchnta a where
+ prefetchnta :: a -> CodeGen e s ()
+
+instance Prefetchnta Addr where
+ prefetchnta (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetchnta_mem a
+
+instance Prefetchnta (Disp, Reg32) where
+ prefetchnta (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetchnta_membase r d
+
+instance Prefetchnta Ind where
+ prefetchnta (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetchnta_regp r
+
+class Prefetch0 a where
+ prefetch0 :: a -> CodeGen e s ()
+
+instance Prefetch0 Addr where
+ prefetch0 (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetch0_mem a
+
+instance Prefetch0 (Disp, Reg32) where
+ prefetch0 (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetch0_membase r d
+
+instance Prefetch0 Ind where
+ prefetch0 (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetch0_regp r
+
+class Prefetch1 a where
+ prefetch1 :: a -> CodeGen e s ()
+
+instance Prefetch1 Addr where
+ prefetch1 (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetch1_mem a
+
+instance Prefetch1 (Disp, Reg32) where
+ prefetch1 (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetch1_membase r d
+
+instance Prefetch1 Ind where
+ prefetch1 (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetch1_regp r
+
+class Prefetch2 a where
+ prefetch2 :: a -> CodeGen e s ()
+
+instance Prefetch2 Addr where
+ prefetch2 (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetch2_mem a
+
+instance Prefetch2 (Disp, Reg32) where
+ prefetch2 (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetch2_membase r d
+
+instance Prefetch2 Ind where
+ prefetch2 (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetch2_regp r
+
+
+ptrToWord32 :: Ptr a -> Word32
+ptrToWord32 = fromIntegral . ptrToIntPtr
+
+ptrToInt :: Ptr a -> Int
+ptrToInt = fromIntegral . ptrToIntPtr
--- /dev/null
+--------------------------------------------------------------------------
+-- |
+-- Module : X86CodeGen
+-- Copyright : (c) 2006 Martin Grabmueller and Dirk Kleeblatt
+-- License : GPL
+--
+-- Maintainer : {magr,klee}@cs.tu-berlin.de
+-- Stability : provisional
+-- Portability : portable (but generated code non-portable)
+--
+-- Functions for generating x86 machine code instructions. The
+-- functions make use of the code generation monad in module
+-- "Harpy.CodeGenMonad" for emitting binary code into a code buffer.
+--
+-- This module is very low-level, since there are different
+-- functions for different addressing modes. A more convenient
+-- interface is provided in module "Harpy.X86Assembler", which uses
+-- the operand types to determine the correct addressing modes for
+-- all supported instructions.
+--
+-- Note: this file does not (yet) provide the complete x86
+-- instruction set, not even all user-mode instructions. For some
+-- operations, some addressing modes are missing as well.
+--
+-- Copyright notice:
+--
+-- The information in this file is based on the header file
+-- x86-codegen.h from the mono distribution, which has the following
+-- copyright information:
+--
+-- @
+-- * x86-codegen.h: Macros for generating x86 code
+-- *
+-- * Authors:
+-- * Paolo Molaro (lupus\@ximian.com)
+-- * Intel Corporation (ORP Project)
+-- * Sergey Chaban (serge\@wildwestsoftware.com)
+-- * Dietmar Maurer (dietmar\@ximian.com)
+-- * Patrik Torstensson
+-- *
+-- * Copyright (C) 2000 Intel Corporation. All rights reserved.
+-- * Copyright (C) 2001, 2002 Ximian, Inc.
+-- *
+-- @
+--------------------------------------------------------------------------
+
+module Harpy.X86CodeGen(
+ -- * Types
+ X86_SSE_PFX,
+ -- * Constants
+ -- ** Machine characteristics
+ -- | Sizes of various machine data types in bytes.
+ x86_dword_size,
+ x86_qword_size,
+ x86_max_instruction_bytes,
+ -- ** Register numbers
+ -- | x86 general-purpose register numbers
+ x86_eax, x86_ecx, x86_edx, x86_ebx, x86_esp, x86_ebp, x86_esi, x86_edi,
+ x86_nobasereg,
+ -- ** Register masks and predicates
+ -- | Bitvector masks for general-purpose registers
+ x86_eax_mask, x86_ecx_mask, x86_edx_mask, x86_ebx_mask,
+ x86_esi_mask, x86_edi_mask, x86_ebp_mask,
+ x86_callee_regs, x86_caller_regs, x86_byte_regs,
+ -- ** ALU operations
+ -- | Opcodes for ALU instructions
+ x86_add, x86_or, x86_adc, x86_sbb, x86_and, x86_sub, x86_xor, x86_cmp,
+ -- ** Shift operations
+ -- | Opcodes for shift instructions
+ x86_rol, x86_ror, x86_rcl, x86_rcr, x86_shl,
+ x86_shr, x86_sar, x86_shld, x86_shlr,
+ -- ** FP operations
+ -- | Opcodes for floating-point instructions
+ x86_fadd, x86_fmul, x86_fcom, x86_fcomp, x86_fsub, x86_fsubr,
+ x86_fdiv, x86_fdivr,
+ -- ** FP conditions and control codes
+ -- | FP status word codes
+ x86_fp_c0, x86_fp_c1, x86_fp_c2, x86_fp_c3, x86_fp_cc_mask,
+ -- | FP control word codes
+ x86_fpcw_invopex_mask, x86_fpcw_denopex_mask, x86_fpcw_zerodiv_mask,
+ x86_fpcw_ovfex_mask, x86_fpcw_undfex_mask, x86_fpcw_precex_mask,
+ x86_fpcw_precc_mask, x86_fpcw_roundc_mask,
+ x86_fpcw_prec_single, x86_fpcw_prec_double,
+ x86_fpcw_prec_extended,
+ x86_fpcw_round_nearest, x86_fpcw_round_down, x86_fpcw_round_up,
+ x86_fpcw_round_tozero,
+ -- ** Condition codes
+ -- | Integer conditions codes
+ x86_cc_eq, x86_cc_e, x86_cc_z,
+ x86_cc_ne, x86_cc_nz,
+ x86_cc_lt, x86_cc_b, x86_cc_c, x86_cc_nae, x86_cc_le, x86_cc_be,
+ x86_cc_na, x86_cc_gt, x86_cc_a, x86_cc_nbe, x86_cc_ge, x86_cc_ae,
+ x86_cc_nb, x86_cc_nc, x86_cc_lz, x86_cc_s, x86_cc_gez, x86_cc_ns,
+ x86_cc_p, x86_cc_np, x86_cc_pe, x86_cc_po, x86_cc_o, x86_cc_no,
+ -- ** Instruction prefix codes
+ x86_lock_prefix, x86_repnz_prefix, x86_repz_prefix, x86_rep_prefix,
+ x86_cs_prefix, x86_ss_prefix, x86_ds_prefix, x86_es_prefix,
+ x86_fs_prefix, x86_gs_prefix, x86_unlikely_prefix,
+ x86_likely_prefix, x86_operand_prefix, x86_address_prefix,
+ -- * Functions
+ -- ** Utility functions
+ x86_is_scratch, x86_is_callee,
+ -- ** Code emission
+ -- | These functions are used to emit parts of instructions, such
+ -- as constants or operand descriptions.
+ x86_imm_emit16, x86_imm_emit8, x86_imm_emit32,
+ x86_membase_emit, x86_alu_reg_imm,
+ -- ** Call instructions
+ x86_call_hs, x86_call_membase, x86_call_mem, x86_call_reg, x86_call_code,
+ x86_call_imm,
+ -- ** Function prologue and epilogue
+ x86_prolog, x86_epilog, x86_enter, x86_leave,
+ x86_ret, x86_ret_imm,
+ -- ** Jump and branch
+ x86_jecxz, x86_branch, x86_branch_pointer, x86_branch32, x86_branch8,
+ x86_jump_membase, x86_jump_pointer, x86_jump_mem, x86_jump_reg,
+ x86_jump32, x86_jump8,
+ x86_loopne, x86_loope, x86_loop,
+ -- ** Stack operations
+ x86_push_reg, x86_push_regp, x86_push_mem, x86_push_membase,
+ x86_push_imm, x86_push_imm_template, x86_push_memindex,
+ x86_pop_membase, x86_pop_mem, x86_pop_reg,
+ x86_popfd, x86_pushfd, x86_popad, x86_pushad,
+ -- ** Data movement
+ x86_mov_reg_reg, x86_mov_reg_imm, x86_mov_mem_imm, x86_mov_membase_imm,
+ x86_mov_memindex_imm, x86_mov_mem_reg, x86_mov_reg_mem,
+ x86_mov_regp_reg, x86_mov_reg_regp, x86_mov_membase_reg,
+ x86_mov_reg_membase, x86_mov_memindex_reg, x86_mov_reg_memindex,
+ -- ** Arithmetic
+ x86_xadd_reg_reg, x86_xadd_mem_reg, x86_xadd_membase_reg,
+ x86_inc_mem, x86_inc_membase, x86_inc_reg,
+ x86_dec_mem, x86_dec_membase, x86_dec_reg,
+ x86_not_mem, x86_not_membase, x86_not_reg,
+ x86_neg_mem, x86_neg_membase, x86_neg_reg,
+ x86_alu_mem_imm, x86_alu_membase_imm, x86_alu_membase8_imm,
+ x86_alu_mem_reg, x86_alu_membase_reg, x86_alu_reg_reg,
+ x86_alu_reg8_reg8, x86_alu_reg_mem, x86_alu_reg_membase,
+ x86_mul_reg, x86_mul_mem, x86_mul_membase,
+ x86_imul_reg_reg, x86_imul_reg_membase, x86_imul_reg_reg_imm,
+ x86_imul_reg_mem,
+ x86_imul_reg_mem_imm, x86_imul_reg_membase_imm,
+ x86_div_reg, x86_div_mem, x86_div_membase,
+ x86_test_reg_imm, x86_test_mem_imm, x86_test_membase_imm,
+ x86_test_reg_reg, x86_test_mem_reg, x86_test_membase_reg,
+ -- ** Exchange
+ x86_cmpxchg_reg_reg, x86_cmpxchg_mem_reg, x86_cmpxchg_membase_reg,
+ x86_xchg_reg_reg, x86_xchg_mem_reg, x86_xchg_membase_reg,
+ -- ** String operations
+ x86_stosb, x86_stosl, x86_stosd, x86_movsb, x86_movsl, x86_movsd,
+ -- ** Bitwise shift
+ x86_shift_reg_imm, x86_shift_mem_imm, x86_shift_membase_imm,
+ x86_shift_reg, x86_shift_mem, x86_shift_membase,
+ x86_shrd_reg, x86_shrd_reg_imm, x86_shld_reg, x86_shld_reg_imm,
+ -- ** Conditional move
+ x86_cmov_membase, x86_cmov_mem, x86_cmov_reg,
+ -- ** Conditional set
+ x86_set_membase, x86_set_mem, x86_set_reg,
+ -- ** Address calculation
+ x86_lea_mem, x86_lea_membase, x86_lea_memindex,
+ -- ** Conversion
+ x86_cdq,x86_widen_memindex, x86_widen_membase, x86_widen_mem,
+ x86_widen_reg,
+ -- ** Floating point
+ x86_fp_op_mem, x86_fp_op_membase, x86_fp_op, x86_fp_op_reg,
+ x86_fp_int_op_membase, x86_fstp, x86_fcompp, x86_fucompp,
+ x86_fnstsw, x86_fnstcw, x86_fnstcw_membase,
+ x86_fldcw, x86_fldcw_membase, x86_fchs,
+ x86_frem, x86_fxch, x86_fcomi, x86_fcomip, x86_fucomi, x86_fucomip,
+ x86_fld, x86_fld_membase, x86_fld80_mem, x86_fld80_membase,
+ x86_fld_reg, x86_fldz, x86_fld1, x86_fldpi,
+ x86_fst, x86_fst_membase, x86_fst80_mem, x86_fst80_membase,
+ FIntSize(..),
+ x86_fist_pop, x86_fist_pop_membase, x86_fstsw,
+ x86_fist_membase, x86_fild, x86_fild_membase,
+ x86_fsin, x86_fcos, x86_fabs, x86_ftst, x86_fxam, x86_fpatan,
+ x86_fprem, x86_fprem1, x86_frndint, x86_fsqrt, x86_fptan,
+ x86_fincstp, x86_fdecstp,
+ -- ** SSE instructions
+ x86_sse_ps, x86_sse_pd, x86_sse_ss, x86_sse_sd,
+ x86_add_sse_reg_reg, x86_add_sse_reg_mem, x86_add_sse_reg_membase,
+ x86_sub_sse_reg_reg, x86_sub_sse_reg_mem, x86_sub_sse_reg_membase,
+ x86_mul_sse_reg_reg, x86_mul_sse_reg_mem, x86_mul_sse_reg_membase,
+ x86_div_sse_reg_reg, x86_div_sse_reg_mem, x86_div_sse_reg_membase,
+ x86_max_sse_reg_reg, x86_max_sse_reg_mem, x86_max_sse_reg_membase,
+ x86_min_sse_reg_reg, x86_min_sse_reg_mem, x86_min_sse_reg_membase,
+ x86_sqrt_sse_reg_reg, x86_sqrt_sse_reg_mem, x86_sqrt_sse_reg_membase,
+ x86_mov_sse_reg_reg, x86_mov_sse_reg_mem, x86_mov_sse_reg_membase, x86_mov_sse_mem_reg ,x86_mov_sse_membase_reg,
+ x86_ucomisd_reg_reg, x86_ucomisd_reg_mem, x86_ucomisd_reg_membase,
+ x86_ucomiss_reg_reg, x86_ucomiss_reg_mem, x86_ucomiss_reg_membase,
+ x86_comisd_reg_reg, x86_comisd_reg_mem, x86_comisd_reg_membase,
+ x86_comiss_reg_reg, x86_comiss_reg_mem, x86_comiss_reg_membase,
+ XMMReg(XMMReg), Mem(Mem), MemBase(MemBase),
+ XMMLocation(xmm_location_emit),
+ x86_movss_to_reg, x86_movss_from_reg,
+ x86_movsd_to_reg, x86_movsd_from_reg,
+ x86_movlps_to_reg, x86_movlps_from_reg,
+ x86_movlpd_to_reg, x86_movlpd_from_reg,
+ x86_movups_to_reg, x86_movups_from_reg,
+ x86_movupd_to_reg, x86_movupd_from_reg,
+ x86_haddps, x86_haddpd,
+ x86_shufps, x86_shufpd,
+ x86_cvtdq2ps, x86_cvttps2dq,
+ -- ** Prefetch instructions
+ x86_prefetch0_mem, x86_prefetch1_mem, x86_prefetch2_mem, x86_prefetchnta_mem,
+ x86_prefetch0_membase, x86_prefetch1_membase, x86_prefetch2_membase, x86_prefetchnta_membase,
+ x86_prefetch0_regp, x86_prefetch1_regp, x86_prefetch2_regp, x86_prefetchnta_regp,
+ -- ** Miscellaneous
+ x86_sahf, x86_wait, x86_nop, x86_breakpoint, x86_rdtsc, x86_cld,
+ x86_prefix, x86_padding,
+ -- ** Other utilities
+ negateCC
+ ) where
+
+import qualified Text.PrettyPrint.HughesPJ as PP
+
+import Data.Word
+import Data.Bits
+
+import Foreign.Ptr
+
+import Harpy.CodeGenMonad
+
+-- | Maximal length of an x86 instruction in bytes.
+x86_max_instruction_bytes :: Int
+x86_max_instruction_bytes = 16 -- According to Intel manual.
+
+x86_dword_size, x86_qword_size :: Int
+
+x86_dword_size = 4 -- Number of bytes in doubleword
+x86_qword_size = 8 -- Number of bytes in quadword
+
+x86_eax, x86_ecx, x86_edx, x86_ebx, x86_esp, x86_ebp, x86_esi,
+ x86_edi :: Word8
+x86_eax = 0
+x86_ecx = 1
+x86_edx = 2
+x86_ebx = 3
+x86_esp = 4
+x86_ebp = 5
+x86_esi = 6
+x86_edi = 7
+
+x86_cmp, x86_or, x86_adc, x86_sbb, x86_and, x86_sub, x86_xor,
+ x86_add :: Word8
+x86_add = 0
+x86_or = 1
+x86_adc = 2
+x86_sbb = 3
+x86_and = 4
+x86_sub = 5
+x86_xor = 6
+x86_cmp = 7
+
+x86_sar, x86_shld, x86_shlr, x86_rol, x86_ror, x86_rcl, x86_rcr,
+ x86_shl, x86_shr :: Word8
+
+x86_shld = 0
+x86_shlr = 1
+x86_rol = 0
+x86_ror = 1
+x86_rcl = 2
+x86_rcr = 3
+x86_shl = 4
+x86_shr = 5
+x86_sar = 7
+
+x86_fadd, x86_fmul, x86_fcom, x86_fcomp, x86_fsub, x86_fsubr :: Word8
+x86_fdiv, x86_fdivr :: Word8
+
+x86_fadd = 0
+x86_fmul = 1
+x86_fcom = 2
+x86_fcomp = 3
+x86_fsub = 4
+x86_fsubr = 5
+x86_fdiv = 6
+x86_fdivr = 7
+
+x86_cc_no, x86_cc_eq, x86_cc_e, x86_cc_z, x86_cc_ne, x86_cc_nz, x86_cc_lt :: Int
+x86_cc_b, x86_cc_c, x86_cc_nae, x86_cc_le, x86_cc_be, x86_cc_na :: Int
+x86_cc_gt :: Int
+x86_cc_a, x86_cc_nbe, x86_cc_ge, x86_cc_ae, x86_cc_nb, x86_cc_nc :: Int
+x86_cc_lz, x86_cc_s, x86_cc_gez, x86_cc_ns, x86_cc_p, x86_cc_pe :: Int
+x86_cc_np, x86_cc_po, x86_cc_o :: Int
+x86_cc_eq = 0
+x86_cc_e = 0
+x86_cc_z = 0
+x86_cc_ne = 1
+x86_cc_nz = 1
+x86_cc_lt = 2
+x86_cc_b = 2
+x86_cc_c = 2
+x86_cc_nae = 2
+x86_cc_le = 3
+x86_cc_be = 3
+x86_cc_na = 3
+x86_cc_gt = 4
+x86_cc_a = 4
+x86_cc_nbe = 4
+x86_cc_ge = 5
+x86_cc_ae = 5
+x86_cc_nb = 5
+x86_cc_nc = 5
+x86_cc_lz = 6
+x86_cc_s = 6
+x86_cc_gez = 7
+x86_cc_ns = 7
+x86_cc_p = 8
+x86_cc_pe = 8
+x86_cc_np = 9
+x86_cc_po = 9
+x86_cc_o = 10
+x86_cc_no = 11
+
+-- | FP status
+x86_fp_c0, x86_fp_c1, x86_fp_c2, x86_fp_c3, x86_fp_cc_mask :: Word32
+x86_fp_c0 = 0x100
+x86_fp_c1 = 0x200
+x86_fp_c2 = 0x400
+x86_fp_c3 = 0x4000
+x86_fp_cc_mask = 0x4500
+
+-- | FP control word
+x86_fpcw_invopex_mask, x86_fpcw_denopex_mask, x86_fpcw_zerodiv_mask,
+ x86_fpcw_ovfex_mask, x86_fpcw_undfex_mask, x86_fpcw_precex_mask,
+ x86_fpcw_precc_mask, x86_fpcw_roundc_mask :: Word32
+
+x86_fpcw_invopex_mask = 0x1
+x86_fpcw_denopex_mask = 0x2
+x86_fpcw_zerodiv_mask = 0x4
+x86_fpcw_ovfex_mask = 0x8
+x86_fpcw_undfex_mask = 0x10
+x86_fpcw_precex_mask = 0x20
+x86_fpcw_precc_mask = 0x300
+x86_fpcw_roundc_mask = 0xc00
+
+-- | Values for precision control
+x86_fpcw_prec_single, x86_fpcw_prec_double,
+ x86_fpcw_prec_extended :: Word32
+x86_fpcw_prec_single = 0
+x86_fpcw_prec_double = 0x200
+x86_fpcw_prec_extended = 0x300
+
+-- | Values for rounding control
+x86_fpcw_round_nearest, x86_fpcw_round_down, x86_fpcw_round_up,
+ x86_fpcw_round_tozero :: Word32
+x86_fpcw_round_nearest = 0
+x86_fpcw_round_down = 0x400
+x86_fpcw_round_up = 0x800
+x86_fpcw_round_tozero = 0xc00
+
+-- | Prefix codes
+x86_lock_prefix, x86_repnz_prefix, x86_repz_prefix, x86_rep_prefix,
+ x86_cs_prefix, x86_ss_prefix, x86_ds_prefix, x86_es_prefix,
+ x86_fs_prefix, x86_gs_prefix, x86_unlikely_prefix,
+ x86_likely_prefix, x86_operand_prefix, x86_address_prefix :: Word8
+x86_lock_prefix = 0xf0
+x86_repnz_prefix = 0xf2
+x86_repz_prefix = 0xf3
+x86_rep_prefix = 0xf3
+x86_cs_prefix = 0x2e
+x86_ss_prefix = 0x36
+x86_ds_prefix = 0x3e
+x86_es_prefix = 0x26
+x86_fs_prefix = 0x64
+x86_gs_prefix = 0x65
+x86_unlikely_prefix = 0x2e
+x86_likely_prefix = 0x3e
+x86_operand_prefix = 0x66
+x86_address_prefix = 0x67
+
+-- | Mapping from condition code to opcode (unsigned)
+x86_cc_unsigned_map :: [Word8]
+x86_cc_unsigned_map = [
+ 0x74, -- eq
+ 0x75, -- ne
+ 0x72, -- lt
+ 0x76, -- le
+ 0x77, -- gt
+ 0x73, -- ge
+ 0x78, -- lz
+ 0x79, -- gez
+ 0x7a, -- p
+ 0x7b, -- np
+ 0x70, -- o
+ 0x71 -- no
+ ]
+
+-- | Mapping from condition code to opcode (signed)
+x86_cc_signed_map :: [Word8]
+x86_cc_signed_map = [
+ 0x74, -- eq
+ 0x75, -- ne
+ 0x7c, -- lt
+ 0x7e, -- le
+ 0x7f, -- gt
+ 0x7d, -- ge
+ 0x78, -- lz
+ 0x79, -- gez
+ 0x7a, -- p
+ 0x7b, -- np
+ 0x70, -- o
+ 0x71 -- no
+ ]
+
+-- | Mapping from condition code to negated condition code.
+x86_cc_negate :: [(Int, Int)]
+x86_cc_negate = [
+ (x86_cc_eq, x86_cc_ne), -- eq
+ (x86_cc_ne, x86_cc_eq), -- ne
+ (x86_cc_lt, x86_cc_ge), -- lt
+ (x86_cc_le, x86_cc_gt), -- le
+ (x86_cc_gt, x86_cc_le), -- gt
+ (x86_cc_ge, x86_cc_lt), -- ge
+ (x86_cc_lz, x86_cc_gez), -- lz
+ (x86_cc_gez, x86_cc_lz), -- gez
+ (x86_cc_p, x86_cc_np), -- p
+ (x86_cc_np, x86_cc_p), -- np
+ (x86_cc_o, x86_cc_no), -- o
+ (x86_cc_no, x86_cc_o) -- no
+ ]
+
+-- | Invert a condition code.
+negateCC :: Int -> Int
+negateCC cc =
+ case lookup cc x86_cc_negate of
+ Just cc' -> cc'
+ Nothing -> error ("unhandled case in negateCC" ++ show cc)
+
+-- | Used to encode the fact that no base register is used in an
+-- instruction.
+x86_nobasereg :: Word8
+x86_nobasereg = (-1)
+
+x86_edi_mask, x86_esi_mask, x86_ebx_mask, x86_ebp_mask,
+ x86_eax_mask, x86_ecx_mask, x86_edx_mask:: Int
+x86_esi_mask = (1 `shiftL` (fromIntegral x86_esi))
+x86_edi_mask = (1 `shiftL` (fromIntegral x86_edi))
+x86_ebx_mask = (1 `shiftL` (fromIntegral x86_ebx))
+x86_ebp_mask = (1 `shiftL` (fromIntegral x86_ebp))
+x86_eax_mask = (1 `shiftL` (fromIntegral x86_eax))
+x86_ecx_mask = (1 `shiftL` (fromIntegral x86_ecx))
+x86_edx_mask = (1 `shiftL` (fromIntegral x86_edx))
+
+-- | Bitvector mask for callee-saved registers
+x86_callee_regs :: Int
+x86_callee_regs = ((1 `shiftL` (fromIntegral x86_eax)) .|.
+ (1 `shiftL` (fromIntegral x86_ecx)) .|.
+ (1 `shiftL` (fromIntegral x86_edx)))
+
+-- | Bitvector mask for caller-saved registers
+x86_caller_regs :: Int
+x86_caller_regs = ((1 `shiftL` (fromIntegral x86_ebx)) .|.
+ (1 `shiftL` (fromIntegral x86_ebp)) .|.
+ (1 `shiftL` (fromIntegral x86_esi)) .|.
+ (1 `shiftL` (fromIntegral x86_edi)))
+
+-- | Bitvector mask for byte-adressable registers
+x86_byte_regs :: Int
+x86_byte_regs = ((1 `shiftL` (fromIntegral x86_eax)) .|.
+ (1 `shiftL` (fromIntegral x86_ecx)) .|.
+ (1 `shiftL` (fromIntegral x86_edx)) .|.
+ (1 `shiftL` (fromIntegral x86_ebx)))
+
+-- | Returns true when the given register is caller-saved.
+x86_is_scratch :: Int -> Bool
+x86_is_scratch reg = (x86_caller_regs .&. (1 `shiftL` (reg))) /= 0
+
+-- | Returns true when the given register is caller-saved.
+x86_is_callee :: Int -> Bool
+
+x86_is_callee reg = (x86_callee_regs .&. (1 `shiftL` (reg))) /= 0
+
+-- | Returns true when the given register is byte-addressable.
+x86_is_byte_reg :: (Num a, Ord a) => a -> Bool
+x86_is_byte_reg reg = ((reg) < 4)
+
+
+
+-- useful building blocks
+
+
+--x86_modrm_mod modrm = ((modrm) `shiftR` 6)
+--x86_modrm_reg :: Bits a => a -> a
+--x86_modrm_reg modrm = (((modrm) `shiftR` 3) .&. 0x7)
+--x86_modrm_rm modrm = ((modrm) .&. 0x7)
+
+x86_address_byte :: Word8 -> Word8 -> Word8 -> CodeGen e s ()
+x86_address_byte m o r = emit8 ((((m) .&. 0x03) `shiftL` 6) .|.
+ (((o) .&. 0x07) `shiftL` 3) .|.
+ (((r) .&. 0x07)))
+
+-- | Emit a 32-bit constant to the instruction stream.
+x86_imm_emit32 :: Word32 -> CodeGen e s ()
+x86_imm_emit32 imm = emit32 imm
+
+-- -- | Emit a 32-bit constant to the instruction stream at the given offset.
+-- x86_imm_emit32_at :: Int -> Word32 -> CodeGen e s ()
+-- x86_imm_emit32_at pos imm = emit32At pos imm
+
+-- | Emit a 16-bit constant to the instruction stream.
+x86_imm_emit16 :: Word16 -> CodeGen e s ()
+x86_imm_emit16 imm =
+ let b0 = (imm .&. 0xff)
+ b1 = ((imm `shiftR` 8) .&. 0xff)
+ in do emit8 (fromIntegral b0)
+ emit8 (fromIntegral b1)
+
+-- | Emit a 8-bit constant to the instruction stream.
+x86_imm_emit8 :: Word8 -> CodeGen e s ()
+x86_imm_emit8 imm =
+ emit8 (imm .&. 0xff)
+
+-- -- | Emit a 8-bit constant to the instruction stream at the given offset.
+-- x86_imm_emit8_at :: Int -> Word8 -> CodeGen e s ()
+-- x86_imm_emit8_at pos imm = emit8At pos (imm .&. 0xff)
+
+-- | Return true if the given value is a signed 8-bit constant.
+x86_is_imm8 :: Integral a => a -> Bool
+x86_is_imm8 imm = (((fromIntegral imm :: Integer) >= -128) && ((fromIntegral imm :: Integer) <= 127))
+-- x86_is_imm16 :: Integral a => a -> Bool
+-- x86_is_imm16 imm = (((fromIntegral imm :: Integer) >= -(1 `shiftL` 16)) &&
+-- ((fromIntegral imm :: Integer) <= ((1 `shiftL` 16)-1)))
+
+x86_reg_emit :: Word8 -> Word8 -> CodeGen e s ()
+x86_reg_emit r regno = x86_address_byte 3 r regno
+
+x86_reg8_emit :: Word8 -> Word8 -> Bool -> Bool -> CodeGen e s ()
+x86_reg8_emit r regno is_rh is_rnoh =
+ x86_address_byte 3 (if is_rh then (r .|. 4) else r)
+ (if is_rnoh then regno .|. 4 else regno)
+
+-- | Emit a register-indirect address encoding.
+x86_regp_emit :: Word8 -> Word8 -> CodeGen e s ()
+x86_regp_emit r regno = x86_address_byte 0 r regno
+
+-- | Emit a memory+displacement address encoding.
+x86_mem_emit :: Word8 -> Word32 -> CodeGen e s ()
+x86_mem_emit r disp = do x86_address_byte 0 r 5
+ x86_imm_emit32 disp
+
+-- | Emit a mem+base address encoding
+x86_membase_emit :: Word8 -> Word8 -> Word32 -> CodeGen e s ()
+x86_membase_emit r basereg disp =
+ if basereg == x86_esp
+ then if disp == 0
+ then do x86_address_byte 0 r x86_esp
+ x86_address_byte 0 x86_esp x86_esp
+ else if x86_is_imm8 disp
+ then do x86_address_byte 1 r x86_esp
+ x86_address_byte 0 x86_esp x86_esp
+ x86_imm_emit8 (fromIntegral disp)
+ else do x86_address_byte 2 r x86_esp
+ x86_address_byte 0 x86_esp x86_esp
+ x86_imm_emit32 (fromIntegral disp)
+ else do if (disp == 0 && (toInteger basereg) /= (toInteger x86_ebp))
+ then x86_address_byte 0 r basereg
+ else if x86_is_imm8 (fromIntegral disp :: Word32)
+ then do x86_address_byte 1 r basereg
+ x86_imm_emit8 (fromIntegral disp)
+ else do x86_address_byte 2 r basereg
+ x86_imm_emit32 (fromIntegral disp)
+
+x86_memindex_emit :: Word8 -> Word8 -> Word32 -> Word8 -> Word8 -> CodeGen e s ()
+x86_memindex_emit r basereg disp indexreg shft =
+ if (basereg == x86_nobasereg)
+ then do x86_address_byte 0 r 4
+ x86_address_byte shft indexreg 5
+ x86_imm_emit32 disp
+ else if ((disp) == 0 && (basereg) /= x86_ebp)
+ then do x86_address_byte 0 r 4
+ x86_address_byte shft indexreg (fromIntegral basereg)
+ else if x86_is_imm8 disp
+ then do x86_address_byte 1 r 4
+ x86_address_byte shft indexreg
+ (fromIntegral basereg)
+ x86_imm_emit8 (fromIntegral disp)
+ else do x86_address_byte 2 r 4
+ x86_address_byte shft indexreg 5
+ x86_imm_emit32 disp
+
+{-
+x86_jmp_ofs_size ins =
+ do instr <- peek8At ins
+ case instr of
+ 0xe8 -> return 1
+ 0xe9 -> return 1
+ 0x0f ->
+ do atPos <- peek8At (ins + 1)
+ if (atPos < 0x70 || atPos > 0x8f)
+ then failCodeGen (PP.text "Wrong Opcode")
+ else return 1
+ _ -> return 0
+-}
+
+-- target is the position in the code where to jump to:
+
+-- target = code;
+-- .. output loop code...
+-- x86_mov_reg_imm (code, X86_EAX, 0);
+-- loop = code;
+-- x86_loop (code, -1);
+-- ... finish method
+
+-- patch displacement
+
+-- x86_patch (loop, target);
+
+-- ins should point at the start of the instruction that encodes a target.
+-- the instruction is inspected for validity and the correct displacement
+-- is inserted.
+
+{-
+x86_patch ins target =
+ let pos = ins + 1
+ in do size <- x86_jmp_ofs_size ins
+ instr <- peek8At ins
+ let disp = target - (if instr == 0x0f then pos + 1 else pos)
+ if size == 1
+ then x86_imm_emit32_at pos (fromIntegral (disp - 4))
+ else if (x86_is_imm8 (disp - 1))
+ then x86_imm_emit8_at pos (fromIntegral (disp - 1))
+ else failCodeGen (PP.text "Wrong offset")
+-}
+
+x86_breakpoint, x86_cld, x86_stosb, x86_stosl, x86_stosd, x86_movsb,
+ x86_movsl, x86_movsd :: CodeGen s e ()
+x86_breakpoint = emit8 0xcc
+x86_cld = emit8 0xfc
+x86_stosb = emit8 0xaa
+x86_stosl = emit8 0xab
+x86_stosd = x86_stosl
+x86_movsb = emit8 0xa4
+x86_movsl = emit8 0xa5
+x86_movsd = x86_movsl
+
+x86_prefix :: Word8 -> CodeGen s e ()
+x86_prefix p = emit8 p
+
+x86_rdtsc :: CodeGen s e ()
+x86_rdtsc = emit8 0x0f >> emit8 0x31
+
+x86_cmpxchg_reg_reg :: Word8 -> Word8 -> CodeGen e s ()
+x86_cmpxchg_reg_reg dreg reg =
+ emit8 0x0f >> emit8 0xb1 >> x86_reg_emit reg dreg
+
+x86_cmpxchg_mem_reg :: Word32 -> Word8 -> CodeGen e s ()
+x86_cmpxchg_mem_reg mem reg = emit8 0x0f >> emit8 0xb1 >> x86_mem_emit reg mem
+
+x86_cmpxchg_membase_reg :: Word8 -> Word32 -> Word8 -> CodeGen e s ()
+x86_cmpxchg_membase_reg basereg disp reg =
+ emit8 0x0f >> emit8 0xb1 >> x86_membase_emit reg basereg disp
+
+x86_xchg :: Num a => a -> CodeGen e s ()
+x86_xchg size = if size == 1 then emit8 0x86 else emit8 0x87
+
+x86_xchg_reg_reg dreg reg size =
+ do x86_xchg size ; x86_reg_emit reg dreg
+x86_xchg_mem_reg mem reg size =
+ do x86_xchg size ; x86_mem_emit reg mem
+x86_xchg_membase_reg basereg disp reg size =
+ do x86_xchg size ; x86_membase_emit reg basereg disp
+
+x86_xadd :: Num a => a -> CodeGen e s ()
+x86_xadd size = do emit8 0x0f ; if size == 1 then emit8 0xc0 else emit8 0xc1
+x86_xadd_reg_reg dreg reg size = x86_xadd size >> x86_reg_emit reg dreg
+x86_xadd_mem_reg mem reg size = x86_xadd size >> x86_mem_emit reg mem
+x86_xadd_membase_reg basereg disp reg size =
+ x86_xadd size >> x86_membase_emit reg basereg disp
+
+x86_inc_mem mem = emit8 0xff >> x86_mem_emit 0 mem
+x86_inc_membase basereg disp = emit8 0xff >> x86_membase_emit 0 basereg disp
+x86_inc_reg reg = emit8 (0x40 + reg)
+
+x86_dec_mem mem = emit8 0xff >> x86_mem_emit 1 mem
+x86_dec_membase basereg disp = emit8 0xff >> x86_membase_emit 1 basereg disp
+x86_dec_reg reg = emit8 (0x48 + reg)
+
+x86_not_mem mem = emit8 0xf7 >> x86_mem_emit 2 mem
+x86_not_membase basereg disp = emit8 0xf7 >> x86_membase_emit 2 basereg disp
+x86_not_reg reg = emit8 0xf7 >> x86_reg_emit 2 reg
+
+x86_neg_mem mem = emit8 0xf7 >> x86_mem_emit 3 mem
+x86_neg_membase basereg disp = emit8 0xf7 >> x86_membase_emit 3 basereg disp
+x86_neg_reg reg = emit8 0xf7 >> x86_reg_emit 3 reg
+
+x86_nop :: CodeGen s e ()
+x86_nop = emit8 0x90
+
+x86_alu_reg_imm :: Word8 -> Word8 -> Int -> CodeGen e s ()
+x86_alu_reg_imm opc reg imm =
+ do if reg == x86_eax
+ then emit8 (fromIntegral (((opc) `shiftL` 3) + 5)) >> x86_imm_emit32 (fromIntegral imm)
+ else if x86_is_imm8 imm
+ then do emit8 0x83
+ x86_reg_emit (fromIntegral opc) (fromIntegral reg)
+ x86_imm_emit8 (fromIntegral imm)
+ else do emit8 0x81
+ x86_reg_emit (fromIntegral opc) (fromIntegral reg)
+ x86_imm_emit32 (fromIntegral imm)
+
+
+x86_alu_mem_imm opc mem imm =
+ if x86_is_imm8 imm
+ then do emit8 0x83
+ x86_mem_emit opc mem
+ x86_imm_emit8 (fromIntegral imm)
+ else do emit8 0x81
+ x86_mem_emit opc mem
+ x86_imm_emit32 imm
+
+
+x86_alu_membase_imm opc basereg disp imm =
+ if x86_is_imm8 imm
+ then do emit8 0x83
+ x86_membase_emit opc basereg disp
+ x86_imm_emit8 (fromIntegral imm)
+ else do emit8 0x81
+ x86_membase_emit opc basereg disp
+ x86_imm_emit32 imm
+x86_alu_membase8_imm opc basereg disp imm =
+ do emit8 0x80
+ x86_membase_emit opc basereg disp
+ x86_imm_emit8 imm
+x86_alu_mem_reg opc mem reg =
+ do emit8 ((opc `shiftL` 3) + 1)
+ x86_mem_emit reg mem
+x86_alu_membase_reg opc basereg disp reg =
+ do emit8 ((opc `shiftL` 3) + 1)
+ x86_membase_emit reg basereg disp
+x86_alu_reg_reg opc dreg reg =
+ do emit8 ((opc `shiftL` 3) + 3)
+ x86_reg_emit dreg reg
+
+-- @x86_alu_reg8_reg8:
+-- Supports ALU operations between two 8-bit registers.
+-- dreg := dreg opc reg
+-- X86_Reg_No enum is used to specify the registers.
+-- Additionally is_*_h flags are used to specify what part
+-- of a given 32-bit register is used - high (TRUE) or low (FALSE).
+-- For example: dreg = X86_EAX, is_dreg_h = TRUE -> use AH
+
+x86_alu_reg8_reg8 opc dreg reg is_dreg_h is_reg_h =
+ do emit8 ((opc `shiftL` 3) + 2)
+ x86_reg8_emit dreg reg is_dreg_h is_reg_h
+x86_alu_reg_mem opc reg mem =
+ do emit8 ((opc `shiftL` 3) + 3)
+ x86_mem_emit reg mem
+x86_alu_reg_membase opc reg basereg disp =
+ do emit8 ((opc `shiftL` 3) + 3)
+ x86_membase_emit reg basereg disp
+
+x86_test_reg_imm reg imm =
+ do if reg == x86_eax
+ then emit8 0xa9
+ else do emit8 0xf7 ; x86_reg_emit 0 (fromIntegral reg)
+ x86_imm_emit32 imm
+x86_test_mem_imm mem imm =
+ do emit8 0xf7 ; x86_mem_emit 0 mem ; x86_imm_emit32 imm
+x86_test_membase_imm basereg disp imm =
+ do emit8 0xf7 ; x86_membase_emit 0 basereg disp ; x86_imm_emit32 imm
+x86_test_reg_reg dreg reg = do emit8 0x85 ; x86_reg_emit reg dreg
+x86_test_mem_reg mem reg =
+ do emit8 0x85 ; x86_mem_emit reg mem
+x86_test_membase_reg basereg disp reg =
+ do emit8 0x85 ; x86_membase_emit reg basereg disp
+
+x86_shift_reg_imm opc reg imm =
+ if imm == 1
+ then do emit8 0xd1 ; x86_reg_emit opc reg
+ else do emit8 0xc1
+ x86_reg_emit opc reg
+ x86_imm_emit8 imm
+x86_shift_mem_imm opc mem imm =
+ if imm == 1
+ then do emit8 0xd1 ; x86_mem_emit opc mem
+ else do emit8 0xc1
+ x86_mem_emit opc mem
+ x86_imm_emit8 imm
+x86_shift_membase_imm opc basereg disp imm =
+ if imm == 1
+ then do emit8 0xd1 ; x86_membase_emit opc basereg disp
+ else do emit8 0xc1
+ x86_membase_emit opc basereg disp
+ x86_imm_emit8 imm
+x86_shift_reg opc reg =
+ emit8 0xd3 >> x86_reg_emit opc reg
+x86_shift_mem opc mem =
+ emit8 0xd3 >> x86_mem_emit opc mem
+x86_shift_membase opc basereg disp =
+ emit8 0xd3 >> x86_membase_emit opc basereg disp
+
+-- Multi op shift missing.
+
+x86_shrd_reg dreg reg =
+ emit8 0x0f >> emit8 0xad >> x86_reg_emit reg dreg
+x86_shrd_reg_imm dreg reg shamt =
+ emit8 0x0f >> emit8 0xac >> x86_reg_emit reg dreg >> x86_imm_emit8 shamt
+x86_shld_reg dreg reg =
+ emit8 0x0f >> emit8 0xa5 >> x86_reg_emit reg dreg
+x86_shld_reg_imm dreg reg shamt =
+ emit8 0x0f >> emit8 0xa4 >> x86_reg_emit reg dreg >>x86_imm_emit8 shamt
+
+-- EDX:EAX = EAX * rm
+
+x86_mul_reg :: Word8 -> Bool -> CodeGen e s ()
+x86_mul_reg reg is_signed =
+ emit8 0xf7 >> x86_reg_emit (4 + (if is_signed then 1 else 0)) reg
+
+x86_mul_mem :: Word32 -> Bool -> CodeGen e s ()
+x86_mul_mem mem is_signed =
+ emit8 0xf7 >> x86_mem_emit (4 + (if is_signed then 1 else 0)) mem
+
+x86_mul_membase :: Word8 -> Word32 -> Bool -> CodeGen e s ()
+x86_mul_membase basereg disp is_signed =
+ do emit8 0xf7
+ x86_membase_emit (4 + (if is_signed then 1 else 0)) basereg disp
+
+-- r *= rm
+
+x86_imul_reg_reg :: Word8 -> Word8 -> CodeGen e s ()
+x86_imul_reg_reg dreg reg =
+ emit8 0x0f >> emit8 0xaf >> x86_reg_emit dreg reg
+
+x86_imul_reg_mem :: Word8 -> Word32 -> CodeGen e s ()
+x86_imul_reg_mem reg mem =
+ emit8 0x0f >> emit8 0xaf >> x86_mem_emit reg mem
+
+x86_imul_reg_membase :: Word8 -> Word8 -> Word32 -> CodeGen e s ()
+x86_imul_reg_membase reg basereg disp =
+ emit8 0x0f >> emit8 0xaf >> x86_membase_emit reg basereg disp
+
+-- dreg = rm * imm
+
+x86_imul_reg_reg_imm :: Word8 -> Word8 -> Word32 -> CodeGen e s ()
+x86_imul_reg_reg_imm dreg reg imm =
+ if x86_is_imm8 imm
+ then emit8 0x6b >> x86_reg_emit dreg reg >>
+ x86_imm_emit8 (fromIntegral imm)
+ else emit8 0x69 >> x86_reg_emit dreg reg >> x86_imm_emit32 imm
+
+x86_imul_reg_mem_imm :: Word8 -> Word32 -> Word32 -> CodeGen e s ()
+x86_imul_reg_mem_imm reg mem imm =
+ if x86_is_imm8 imm
+ then emit8 0x6b >> x86_mem_emit reg mem >>
+ x86_imm_emit8 (fromIntegral imm)
+ else emit8 0x69 >> x86_reg_emit reg (fromIntegral mem) >>
+ x86_imm_emit32 imm
+
+x86_imul_reg_membase_imm :: Word8 -> Word8 -> Word32 -> Word32 -> CodeGen e s ()
+x86_imul_reg_membase_imm reg basereg disp imm =
+ if x86_is_imm8 imm
+ then emit8 0x6b >> x86_membase_emit reg basereg disp >>
+ x86_imm_emit8 (fromIntegral imm)
+ else do emit8 0x69
+ x86_membase_emit reg basereg disp
+ x86_imm_emit32 imm
+
+-- divide EDX:EAX by rm;
+-- eax = quotient, edx = remainder
+
+x86_div_reg :: Word8 -> Bool -> CodeGen e s ()
+x86_div_reg reg is_signed =
+ emit8 0xf7 >> x86_reg_emit (6 + (if is_signed then 1 else 0)) reg
+x86_div_mem :: Word32 -> Bool -> CodeGen e s ()
+x86_div_mem mem is_signed =
+ emit8 0xf7 >> x86_mem_emit (6 + (if is_signed then 1 else 0)) mem
+
+x86_div_membase :: Word8 -> Word32 -> Bool -> CodeGen e s ()
+x86_div_membase basereg disp is_signed =
+ do emit8 0xf7
+ x86_membase_emit (6 + (if is_signed then 1 else 0)) basereg disp
+
+x86_mov1 :: Num t => t -> CodeGen e s ()
+x86_mov1 size =
+ case size of
+ 1 -> emit8 0x88
+ 2 -> emit8 0x66 >> emit8 0x89
+ 4 -> emit8 0x89
+ _ -> failCodeGen (PP.text "invalid operand size")
+
+x86_mov2 :: Num t => t -> CodeGen e s ()
+x86_mov2 size =
+ case size of
+ 1 -> emit8 0x8a
+ 2 -> emit8 0x66 >> emit8 0x8b
+ 4 -> emit8 0x8b
+ _ -> failCodeGen (PP.text "invalid operand size")
+
+x86_mov_mem_reg :: (Num t) => Word32 -> Word8 -> t -> CodeGen e s ()
+x86_mov_mem_reg mem reg size =
+ do x86_mov1 size ; x86_mem_emit reg mem
+
+x86_mov_regp_reg :: (Num t) => Word8 -> Word8 -> t -> CodeGen e s ()
+x86_mov_regp_reg regp reg size =
+ do x86_mov1 size ; x86_regp_emit reg regp
+
+x86_mov_reg_regp :: (Num t) => Word8 -> Word8 -> t -> CodeGen e s ()
+x86_mov_reg_regp reg regp size =
+ do x86_mov2 size ; x86_regp_emit reg regp
+
+x86_mov_membase_reg :: (Num t) => Word8 -> Word32 -> Word8 -> t -> CodeGen e s ()
+x86_mov_membase_reg basereg disp reg size =
+ do x86_mov1 size ; x86_membase_emit reg basereg disp
+
+x86_mov_memindex_reg :: (Num t) => Word8 -> Word32 -> Word8 -> Word8 -> Word8 -> t -> CodeGen e s ()
+x86_mov_memindex_reg basereg disp indexreg shft reg size =
+ do x86_mov1 size ; x86_memindex_emit reg basereg disp indexreg shft
+
+x86_mov_reg_reg :: (Num t) => Word8 -> Word8 -> t -> CodeGen e s ()
+x86_mov_reg_reg dreg reg size =
+ do x86_mov2 size
+ x86_reg_emit dreg reg
+
+x86_mov_reg_mem :: (Num t) => Word8 -> Word32 -> t -> CodeGen e s ()
+x86_mov_reg_mem reg mem size =
+ do x86_mov2 size
+ x86_mem_emit reg mem
+
+x86_mov_reg_membase :: (Num t) => Word8 -> Word8 -> Word32 -> t -> CodeGen e s ()
+x86_mov_reg_membase reg basereg disp size =
+ do x86_mov2 size
+ x86_membase_emit reg basereg disp
+
+x86_mov_reg_memindex :: (Num t) => Word8 -> Word8 -> Word32 -> Word8 -> Word8 -> t -> CodeGen e s ()
+x86_mov_reg_memindex _ _ _ 4 _ _ =
+ failCodeGen $ PP.text "x86_mov_reg_memindex: cannot use (E)SP as index register"
+x86_mov_reg_memindex reg basereg disp indexreg shft size =
+ do x86_mov2 size
+ x86_memindex_emit reg basereg disp indexreg shft
+
+x86_mov_reg_imm :: Word8 -> Word32 -> CodeGen e s ()
+x86_mov_reg_imm reg imm =
+ emit8 (0xb8 + reg) >> x86_imm_emit32 imm
+
+x86_mov_mem_imm :: (Num a) => Word32 -> Word32 -> a -> CodeGen e s ()
+x86_mov_mem_imm mem imm size =
+ if size == 1
+ then do emit8 0xc6;
+ x86_mem_emit 0 mem
+ x86_imm_emit8 (fromIntegral imm)
+ else if size == 2
+ then do emit8 0x66
+ emit8 0xc7
+ x86_mem_emit 0 mem
+ x86_imm_emit16 (fromIntegral imm)
+ else do emit8 0xc7
+ x86_mem_emit 0 mem
+ x86_imm_emit32 imm
+
+x86_mov_membase_imm :: (Num a) => Word8 -> Word32 -> Word32 -> a -> CodeGen e s ()
+x86_mov_membase_imm basereg disp imm size =
+ if size == 1
+ then do emit8 0xc6
+ x86_membase_emit 0 basereg disp
+ x86_imm_emit8 (fromIntegral imm)
+ else if size == 2
+ then do emit8 0x66
+ emit8 0xc7
+ x86_membase_emit 0 basereg disp
+ x86_imm_emit16 (fromIntegral imm)
+ else do emit8 0xc7
+ x86_membase_emit 0 basereg disp
+ x86_imm_emit32 imm
+
+x86_mov_memindex_imm :: (Num a) => Word8 -> Word32 -> Word8 -> Word8 -> Word32 -> a -> CodeGen e s ()
+x86_mov_memindex_imm basereg disp indexreg shft imm size =
+ if size == 1
+ then do emit8 0xc6
+ x86_memindex_emit 0 basereg disp indexreg shft
+ x86_imm_emit8 (fromIntegral imm)
+ else if size == 2
+ then do emit8 0x66
+ emit8 0xc7
+ x86_memindex_emit 0 basereg disp indexreg shft
+ x86_imm_emit16 (fromIntegral imm)
+ else do emit8 0xc7
+ x86_memindex_emit 0 basereg disp indexreg shft
+ x86_imm_emit32 imm
+
+-- LEA: Load Effective Address
+
+x86_lea_mem :: Word8 -> Word32 -> CodeGen e s ()
+x86_lea_mem reg mem = emit8 0x8d >> x86_mem_emit reg mem
+
+x86_lea_membase :: Word8 -> Word8 -> Word32 -> CodeGen e s ()
+x86_lea_membase reg basereg disp =
+ emit8 0x8d >> x86_membase_emit reg basereg disp
+
+x86_lea_memindex :: Word8 -> Word8 -> Word32 -> Word8 -> Word8 -> CodeGen e s ()
+x86_lea_memindex reg basereg disp indexreg shft =
+ emit8 0x8d >> x86_memindex_emit reg basereg disp indexreg shft
+
+x86_widen_reg :: Word8 -> Word8 -> Bool -> Bool -> CodeGen e s ()
+x86_widen_reg dreg reg is_signed is_half =
+ if is_half || x86_is_byte_reg reg
+ then do let op = 0xb6 + (if is_signed then 0x08 else 0) +
+ (if is_half then 0x1 else 0)
+ emit8 0x0f
+ emit8 op
+ x86_reg_emit dreg reg
+ else failCodeGen (PP.text "widen: need byte register or is_half=True")
+
+x86_widen_mem :: Word8 -> Word32 -> Bool -> Bool -> CodeGen e s ()
+x86_widen_mem dreg mem is_signed is_half =
+ do let op = 0xb6 + (if is_signed then 0x08 else 0) +
+ (if is_half then 0x1 else 0)
+ emit8 0x0f
+ emit8 op
+ x86_mem_emit dreg mem
+
+x86_widen_membase :: Word8 -> Word8 -> Word32 -> Bool -> Bool -> CodeGen e s ()
+x86_widen_membase dreg basereg disp is_signed is_half =
+ do let op = 0xb6 + (if is_signed then 0x08 else 0) +
+ (if is_half then 0x1 else 0)
+ emit8 0x0f
+ emit8 op
+ x86_membase_emit dreg basereg disp
+
+x86_widen_memindex :: Word8 -> Word8 -> Word32 -> Word8 -> Word8 -> Bool -> Bool -> CodeGen e s ()
+x86_widen_memindex dreg basereg disp indexreg shft is_signed is_half =
+ do let op = 0xb6 + (if is_signed then 0x08 else 0) +
+ (if is_half then 0x1 else 0)
+ emit8 0x0f
+ emit8 op
+ x86_memindex_emit dreg basereg disp indexreg shft
+
+x86_cdq, x86_wait :: CodeGen s e ()
+x86_cdq = emit8 0x99
+x86_wait = emit8 0x9b
+
+x86_fp_op_mem :: Word8 -> Word32 -> Bool -> CodeGen e s ()
+x86_fp_op_mem opc mem is_double =
+ do emit8 (if is_double then 0xdc else 0xd8)
+ x86_mem_emit opc mem
+x86_fp_op_membase :: Word8 -> Word8 -> Word32 -> Bool -> CodeGen e s ()
+x86_fp_op_membase opc basereg disp is_double =
+ do emit8 (if is_double then 0xdc else 0xd8)
+ x86_membase_emit opc basereg disp
+x86_fp_op ::Word8 -> Word8 -> CodeGen e s ()
+x86_fp_op opc index =
+ do emit8 0xd8
+ emit8 (0xc0 + (opc `shiftL` 3) + (index .&. 0x07))
+x86_fp_op_reg :: Word8 -> Word8 -> Bool -> CodeGen e s ()
+x86_fp_op_reg opc index pop_stack =
+ do let opcMap = [ 0, 1, 2, 3, 5, 4, 7, 6, 8]
+ emit8 (if pop_stack then 0xde else 0xdc)
+ emit8 (0xc0 + ((opcMap !! fromIntegral opc) `shiftL` 3) + (index .&. 0x07))
+
+
+-- @x86_fp_int_op_membase
+-- Supports FPU operations between ST(0) and integer operand in memory.
+-- Operation encoded using X86_FP_Opcode enum.
+-- Operand is addressed by [basereg + disp].
+-- is_int specifies whether operand is int32 (TRUE) or int16 (FALSE).
+
+x86_fp_int_op_membase :: Word8 -> Word8 -> Word32 -> Bool -> CodeGen e s ()
+x86_fp_int_op_membase opc basereg disp is_int =
+ do emit8 (if is_int then 0xda else 0xde)
+ x86_membase_emit opc basereg disp
+x86_fstp :: Word8 -> CodeGen e s ()
+x86_fstp index =
+ emit8 0xdd >> emit8 (0xd8 + index)
+x86_fcompp :: CodeGen e s ()
+x86_fcompp = emit8 0xde >> emit8 0xd9
+x86_fucompp :: CodeGen e s ()
+x86_fucompp = emit8 0xda >> emit8 0xe9
+x86_fnstsw :: CodeGen e s ()
+x86_fnstsw = emit8 0xdf >> emit8 0xe0
+x86_fnstcw :: Word32 -> CodeGen e s ()
+x86_fnstcw mem = emit8 0xd9 >> x86_mem_emit 7 mem
+x86_fnstcw_membase :: Word8 -> Word32 -> CodeGen e s ()
+x86_fnstcw_membase basereg disp =
+ emit8 0xd9 >> x86_membase_emit 7 basereg disp
+x86_fldcw :: Word32 -> CodeGen e s ()
+x86_fldcw mem = emit8 0xd9 >> x86_mem_emit 5 mem
+x86_fldcw_membase :: Word8 -> Word32 -> CodeGen e s ()
+x86_fldcw_membase basereg disp =
+ emit8 0xd9 >> x86_membase_emit 5 basereg disp
+x86_fchs :: CodeGen e s ()
+x86_fchs = emit8 0xd9 >> emit8 0xe0
+x86_frem :: CodeGen e s ()
+x86_frem = emit8 0xd9 >> emit8 0xf8
+x86_fxch :: Word8 -> CodeGen e s ()
+x86_fxch index = emit8 0xd9 >> emit8 (0xc8 + (index .&. 0x07))
+x86_fcomi :: Word8 -> CodeGen e s ()
+x86_fcomi index = emit8 0xdb >> emit8 (0xf0 + (index .&. 0x07))
+x86_fcomip :: Word8 -> CodeGen e s ()
+x86_fcomip index = emit8 0xdf >> emit8 (0xf0 + (index .&. 0x07))
+x86_fucomi :: Word8 -> CodeGen e s ()
+x86_fucomi index = emit8 0xdb >> emit8 (0xe8 + (index .&. 0x07))
+x86_fucomip :: Word8 -> CodeGen e s ()
+x86_fucomip index = emit8 0xdf >> emit8 (0xe8 + (index .&. 0x07))
+
+data FIntSize = FInt16 | FInt32 | FInt64
+
+x86_fld :: Word32 -> Bool -> CodeGen e s ()
+x86_fld mem is_double =
+ do emit8 (if is_double then 0xdd else 0xd9)
+ x86_mem_emit 0 mem
+x86_fld_membase :: Word8 -> Word32 -> Bool -> CodeGen e s ()
+x86_fld_membase basereg disp is_double =
+ do emit8 (if is_double then 0xdd else 0xd9)
+ x86_membase_emit 0 basereg disp
+x86_fld80_mem :: Word32 -> CodeGen e s ()
+x86_fld80_mem mem = emit8 0xdb >> x86_mem_emit 5 mem
+x86_fld80_membase :: Word8 -> Word32 -> CodeGen e s ()
+x86_fld80_membase basereg disp =
+ emit8 0xdb >> x86_membase_emit 5 basereg disp
+x86_fild :: Word32 -> FIntSize -> CodeGen e s ()
+x86_fild mem size =
+ case size of
+ FInt16 -> emit8 0xdf >> x86_mem_emit 0 mem
+ FInt32 -> emit8 0xdb >> x86_mem_emit 0 mem
+ FInt64 -> emit8 0xdf >> x86_mem_emit 5 mem
+x86_fild_membase :: Word8 -> Word32 -> FIntSize -> CodeGen e s ()
+x86_fild_membase basereg disp size =
+ case size of
+ FInt16 -> emit8 0xdb >> x86_membase_emit 0 basereg disp
+ FInt32 -> emit8 0xdb >> x86_membase_emit 0 basereg disp
+ FInt64 -> emit8 0xdf >> x86_membase_emit 5 basereg disp
+x86_fld_reg :: Word8 -> CodeGen e s ()
+x86_fld_reg index =
+ emit8 0xd9 >> emit8 (0xc0 + (index .&. 0x07))
+x86_fldz :: CodeGen e s ()
+x86_fldz = emit8 0xd9 >> emit8 0xee
+x86_fld1 :: CodeGen e s ()
+x86_fld1 = emit8 0xd9 >> emit8 0xe8
+x86_fldpi :: CodeGen e s ()
+x86_fldpi = emit8 0xd9 >> emit8 0xeb
+
+x86_fst :: Word32 -> Bool -> Bool -> CodeGen e s ()
+x86_fst mem is_double pop_stack =
+ do emit8 (if is_double then 0xdd else 0xd9)
+ x86_mem_emit (2 + (if pop_stack then 1 else 0)) mem
+x86_fst_membase :: Word8 -> Word32 -> Bool -> Bool -> CodeGen e s ()
+x86_fst_membase basereg disp is_double pop_stack =
+ do emit8 (if is_double then 0xdd else 0xd9)
+ x86_membase_emit (2 + (if pop_stack then 1 else 0)) basereg disp
+x86_fst80_mem :: Word32 -> CodeGen e s ()
+x86_fst80_mem mem = emit8 0xdb >> x86_mem_emit 7 mem
+x86_fst80_membase :: Word8 -> Word32 -> CodeGen e s ()
+x86_fst80_membase basereg disp =
+ emit8 0xdb >> x86_membase_emit 7 basereg disp
+x86_fist_pop :: Word32 -> FIntSize -> CodeGen e s ()
+x86_fist_pop mem size =
+ case size of
+ FInt16 -> emit8 0xdf >> x86_mem_emit 3 mem
+ FInt32 -> emit8 0xdb >> x86_mem_emit 3 mem
+ FInt64 -> emit8 0xdf >> x86_mem_emit 7 mem
+x86_fist_pop_membase :: Word8 -> Word32 -> FIntSize -> CodeGen e s ()
+x86_fist_pop_membase basereg disp size =
+ case size of
+ FInt16 -> emit8 0xdf >> x86_membase_emit 3 basereg disp
+ FInt32 -> emit8 0xdb >> x86_membase_emit 3 basereg disp
+ FInt64 -> emit8 0xdf >> x86_membase_emit 7 basereg disp
+x86_fstsw :: CodeGen e s ()
+x86_fstsw = emit8 0x9b >> emit8 0xdf >> emit8 0xe0
+
+-- @x86_fist_membase
+-- Converts content of ST(0) to integer and stores it at memory location
+-- addressed by [basereg + disp].
+-- size specifies whether destination is int32 or int16.
+
+x86_fist_membase :: Word8 -> Word32 -> FIntSize -> CodeGen e s ()
+x86_fist_membase basereg disp size =
+ case size of
+ FInt16 -> emit8 0xdf >> x86_membase_emit 2 basereg disp
+ FInt32 -> emit8 0xdb >> x86_membase_emit 2 basereg disp
+ FInt64 -> error "fist does not support 64 bit access"
+
+x86_fincstp :: CodeGen e s ()
+x86_fincstp = emit8 0xd9 >> emit8 0xf7
+
+x86_fdecstp :: CodeGen e s ()
+x86_fdecstp = emit8 0xd9 >> emit8 0xf6
+
+-- PUSH instruction.
+
+x86_push_reg :: Word8 -> CodeGen e s ()
+x86_push_reg reg = emit8 (0x50 + reg)
+
+x86_push_regp :: Word8 -> CodeGen e s ()
+x86_push_regp reg = emit8 0xff >> x86_regp_emit 6 reg
+
+x86_push_mem :: Word32 -> CodeGen e s ()
+x86_push_mem mem = emit8 0xff >> x86_mem_emit 6 mem
+
+x86_push_membase :: Word8 -> Word32 -> CodeGen e s ()
+x86_push_membase basereg disp =
+ emit8 0xff >> x86_membase_emit 6 basereg disp
+
+x86_push_memindex :: Word8 -> Word32 -> Word8 -> Word8 -> CodeGen e s ()
+x86_push_memindex basereg disp indexreg shft =
+ emit8 0xff >> x86_memindex_emit 6 basereg disp indexreg shft
+
+x86_push_imm_template :: CodeGen e s ()
+x86_push_imm_template = x86_push_imm 0xf0f0f0f0
+
+x86_push_imm :: Word32 -> CodeGen e s ()
+x86_push_imm imm =
+ if x86_is_imm8 imm
+ then emit8 0x6A >> x86_imm_emit8 (fromIntegral imm)
+ else emit8 0x68 >> x86_imm_emit32 imm
+
+-- POP instruction.
+
+x86_pop_reg :: Word8 -> CodeGen e s ()
+x86_pop_reg reg = emit8 (0x58 + reg)
+
+x86_pop_mem :: Word32 -> CodeGen e s ()
+x86_pop_mem mem = emit8 0x87 >> x86_mem_emit 0 mem
+
+x86_pop_membase :: Word8 -> Word32 -> CodeGen e s ()
+x86_pop_membase basereg disp =
+ emit8 0x87 >> x86_membase_emit 0 basereg disp
+
+x86_pushad :: CodeGen e s ()
+x86_pushad = emit8 0x60
+
+x86_pushfd :: CodeGen e s ()
+x86_pushfd = emit8 0x9c
+
+x86_popad :: CodeGen e s ()
+x86_popad = emit8 0x61
+
+x86_popfd :: CodeGen e s ()
+x86_popfd = emit8 0x9d
+
+x86_loop :: Word8 -> CodeGen e s ()
+x86_loop imm = emit8 0xe2 >> x86_imm_emit8 imm
+
+x86_loope :: Word8 -> CodeGen e s ()
+x86_loope imm = emit8 0xe1 >> x86_imm_emit8 imm
+
+x86_loopne :: Word8 -> CodeGen e s ()
+x86_loopne imm = emit8 0xe0 >> x86_imm_emit8 imm
+
+x86_jump32 :: Word32 -> CodeGen e s ()
+x86_jump32 imm = emit8 0xe9 >> x86_imm_emit32 imm
+
+x86_jump8 :: Word8 -> CodeGen e s ()
+x86_jump8 imm = emit8 0xeb >> x86_imm_emit8 imm
+
+x86_jump_reg :: Word8 -> CodeGen e s ()
+x86_jump_reg reg = emit8 0xff >> x86_reg_emit 4 reg
+
+x86_jump_mem :: Word32 -> CodeGen e s ()
+x86_jump_mem mem = emit8 0xff >> x86_mem_emit 4 mem
+
+x86_jump_membase :: Word8 -> Word32 -> CodeGen e s ()
+x86_jump_membase basereg disp =
+ emit8 0xff >> x86_membase_emit 4 basereg disp
+
+x86_jump_pointer :: Ptr a -> CodeGen e s ()
+x86_jump_pointer target =
+ do inst <- getCodeOffset
+ base <- getBasePtr
+ let ptr = base `plusPtr` inst
+ x86_jump32 (fromIntegral (target `minusPtr` ptr - 5))
+
+-- target is a pointer in our buffer.
+
+{-
+x86_jump_code target =
+ do inst <- getCodeOffset
+ let t = target - inst - 2
+ if x86_is_imm8 t
+ then x86_jump8 (fromIntegral t)
+ else x86_jump32 (fromIntegral (t - 3))
+-}
+{-
+x86_jump_disp disp =
+ do let t = disp - 2
+ if x86_is_imm8 t
+ then x86_jump8 (fromIntegral t)
+ else x86_jump32 (t - 3)
+-}
+
+x86_branch8 :: Int -> Word8 -> Bool -> CodeGen e s ()
+x86_branch8 cond imm is_signed =
+ do if is_signed
+ then emit8 (x86_cc_signed_map !! cond)
+ else emit8 (x86_cc_unsigned_map !! cond)
+ x86_imm_emit8 imm
+
+x86_branch32 :: Int -> Word32 -> Bool -> CodeGen e s ()
+x86_branch32 cond imm is_signed =
+ do emit8 0x0f
+ if is_signed
+ then emit8 ((x86_cc_signed_map !! cond) + 0x10)
+ else emit8 ((x86_cc_unsigned_map !! cond) + 0x10)
+ x86_imm_emit32 imm
+
+x86_branch :: Int -> Int -> Bool -> CodeGen e s ()
+x86_branch cond target is_signed =
+ do inst <- getCodeOffset
+ let offset = target - inst - 2;
+ if x86_is_imm8 offset
+ then x86_branch8 cond (fromIntegral offset) is_signed
+ else x86_branch32 cond (fromIntegral (offset - 4)) is_signed
+
+x86_branch_pointer :: Int -> Ptr a -> Bool -> CodeGen e s ()
+x86_branch_pointer cond target is_signed =
+ do inst <- getCodeOffset
+ base <- getBasePtr
+ let ptr = base `plusPtr` inst
+ x86_branch32 cond (fromIntegral (target `minusPtr` ptr - 5)) is_signed
+
+{-
+x86_branch_disp cond disp is_signed =
+ do let offset = disp - 2
+ if x86_is_imm8 offset
+ then x86_branch8 cond (fromIntegral offset) is_signed
+ else x86_branch32 cond (offset - 4) is_signed
+-}
+
+x86_jecxz :: Word8 -> CodeGen e s ()
+x86_jecxz imm = emit8 0xe3 >> emit8 imm
+
+x86_set_reg :: Int -> Word8 -> Bool -> CodeGen e s ()
+x86_set_reg cond reg is_signed =
+ do emit8 0x0f
+ if is_signed
+ then emit8 ((x86_cc_signed_map !! cond) + 0x20)
+ else emit8 ((x86_cc_unsigned_map !! cond) + 0x20)
+ x86_reg_emit 0 reg
+
+x86_set_mem :: Int -> Word32 -> Bool -> CodeGen e s ()
+x86_set_mem cond mem is_signed =
+ do emit8 0x0f
+ if is_signed
+ then emit8 ((x86_cc_signed_map !! cond) + 0x20)
+ else emit8 ((x86_cc_unsigned_map !! cond) + 0x20)
+ x86_mem_emit 0 mem
+x86_set_membase :: Int -> Word8 -> Word32 -> Bool -> CodeGen e s ()
+x86_set_membase cond basereg disp is_signed =
+ do emit8 0x0f
+ if is_signed
+ then emit8 ((x86_cc_signed_map !! cond) + 0x20)
+ else emit8 ((x86_cc_unsigned_map !! cond) + 0x20)
+ x86_membase_emit 0 basereg disp
+
+-- Call instructions.
+
+x86_call_imm :: Word32 -> CodeGen s e ()
+x86_call_imm disp = emit8 0xe8 >> x86_imm_emit32 disp
+
+x86_call_reg :: Word8 -> CodeGen s e ()
+x86_call_reg reg = emit8 0xff >> x86_reg_emit 2 reg
+
+x86_call_mem :: Word32 -> CodeGen s e ()
+x86_call_mem mem = emit8 0xff >> x86_mem_emit 2 mem
+
+x86_call_membase :: Word8 -> Word32 -> CodeGen s e ()
+x86_call_membase basereg disp =
+ emit8 0xff >> x86_membase_emit 2 basereg disp
+
+x86_call_code :: Int -> CodeGen s e ()
+x86_call_code target =
+ do inst <- getCodeOffset
+ let _x86_offset = (target - inst - 5)
+ x86_call_imm (fromIntegral _x86_offset)
+
+x86_call_hs :: FunPtr a -> CodeGen e s ()
+x86_call_hs fptr = do { offset <- getCodeOffset
+ ; base <- getBasePtr
+ ; emitRelocInfo (offset + 1)
+ RelocPCRel fptr
+ ; x86_call_imm $ (fromIntegral (minusPtr (castFunPtrToPtr fptr) (plusPtr base offset) - 5))
+ }
+
+-- RET instruction.
+
+x86_ret :: CodeGen s e ()
+x86_ret = emit8 0xc3
+
+x86_ret_imm :: Word16 -> CodeGen s e ()
+x86_ret_imm imm =
+ if imm == 0 then x86_ret else emit8 0xc2 >> x86_imm_emit16 imm
+
+-- Conditional move instructions.
+x86_cmov ::Int -> Bool -> CodeGen e s ()
+x86_cmov cond is_signed =
+ do emit8 0x0f
+ if is_signed
+ then emit8 ((x86_cc_signed_map !! cond) - 0x30)
+ else emit8 ((x86_cc_unsigned_map !! cond) - 0x30)
+x86_cmov_reg :: Int -> Bool -> Word8 -> Word8 -> CodeGen e s ()
+x86_cmov_reg cond is_signed dreg reg =
+ do x86_cmov cond is_signed
+ x86_reg_emit dreg reg
+x86_cmov_mem :: Int -> Bool -> Word8 -> Word32 -> CodeGen e s ()
+x86_cmov_mem cond is_signed reg mem =
+ do x86_cmov cond is_signed
+ x86_mem_emit reg mem
+x86_cmov_membase :: Int -> Bool -> Word8 -> Word8 -> Word32 -> CodeGen e s ()
+x86_cmov_membase cond is_signed reg basereg disp =
+ do x86_cmov cond is_signed
+ x86_membase_emit reg basereg disp
+
+-- Note: definition for ENTER instruction is not complete. The counter
+-- for the display setup is set to 0.
+
+x86_enter :: Word16 -> CodeGen s e ()
+x86_enter framesize = emit8 0xc8 >> x86_imm_emit16 framesize >> emit8 0
+
+x86_leave :: CodeGen s e ()
+x86_leave = emit8 0xc9
+
+x86_sahf :: CodeGen s e ()
+x86_sahf = emit8 0x9e
+
+-- Trigonometric floating point functions
+
+x86_fsin, x86_fcos, x86_fabs, x86_ftst, x86_fxam, x86_fpatan,
+ x86_fprem, x86_fprem1, x86_frndint, x86_fsqrt, x86_fptan :: CodeGen s e ()
+x86_fsin = emit8 0xd9 >> emit8 0xfe
+x86_fcos = emit8 0xd9 >> emit8 0xff
+x86_fabs = emit8 0xd9 >> emit8 0xe1
+x86_ftst = emit8 0xd9 >> emit8 0xe4
+x86_fxam = emit8 0xd9 >> emit8 0xe5
+x86_fpatan = emit8 0xd9 >> emit8 0xf3
+x86_fprem = emit8 0xd9 >> emit8 0xf8
+x86_fprem1 = emit8 0xd9 >> emit8 0xf5
+x86_frndint = emit8 0xd9 >> emit8 0xfc
+x86_fsqrt = emit8 0xd9 >> emit8 0xfa
+x86_fptan = emit8 0xd9 >> emit8 0xf2
+
+-- Fast instruction sequences for 1 to 7-byte noops.
+
+x86_padding ::(Num t) => t -> CodeGen e s ()
+x86_padding size =
+ case size of
+ 1 -> x86_nop
+ 2 -> emit8 0x8b >> emit8 0xc0
+ 3 -> emit8 0x8d >> emit8 0x6d >> emit8 0x00
+ 4 -> emit8 0x8d >> emit8 0x64 >> emit8 0x24 >> emit8 0x00
+ 5 -> emit8 0x8d >> emit8 0x64 >> emit8 0x24 >> emit8 0x00 >>
+ x86_nop
+ 6 -> emit8 0x8d >> emit8 0xad >>
+ emit8 0x00 >> emit8 0x00 >>
+ emit8 0x00 >> emit8 0x00
+ 7 -> emit8 0x8d >> emit8 0xa4 >>
+ emit8 0x24 >> emit8 0x00 >>
+ emit8 0x00 >> emit8 0x00 >>
+ emit8 0x00
+ _ -> failCodeGen (PP.text "invalid padding size")
+
+-- Generate the code for a function prologue. The frame_size is the
+-- number of bytes to be allocated as the frame size, and the reg_mask
+-- specifies which registers to save on function entry.
+
+x86_prolog :: Int -> Int -> CodeGen e s ()
+x86_prolog frame_size reg_mask =
+ do x86_push_reg x86_ebp
+ x86_mov_reg_reg x86_ebp x86_esp x86_dword_size
+ gen_push 0 1
+ if frame_size /= 0
+ then x86_alu_reg_imm x86_sub x86_esp frame_size
+ else return ()
+ where
+ gen_push i m =
+ if i <= x86_edi
+ then do if (reg_mask .&. m) /= 0
+ then x86_push_reg i
+ else return ()
+ gen_push (i + 1) (m `shiftL` 1)
+ else return ()
+
+-- Opposite to x86_prolog: destroys the stack frame and restores the
+-- registers in reg_mask, which should be the same as the register mask
+-- used on function entry.
+
+x86_epilog :: Int -> CodeGen e s ()
+x86_epilog reg_mask =
+ do gen_pop x86_edi (1 `shiftL` (fromIntegral x86_edi))
+ x86_mov_reg_reg x86_esp x86_ebp x86_dword_size
+ x86_pop_reg x86_ebp
+ x86_ret
+ where
+ gen_pop i m =
+ if m /= 0
+ then do if (reg_mask .&. m) /= 0
+ then x86_pop_reg i
+ else return ()
+ gen_pop (i - 1) (m `shiftR` 1)
+ else return ()
+
+-- TODO: Move signatures to definition, delete duplicates.
+x86_xchg_reg_reg ::
+ (Num a) =>
+ Word8
+ -> Word8
+ -> a
+ -> CodeGen e s ()
+x86_xchg_mem_reg ::
+ (Num a) =>
+ Word32
+ -> Word8
+ -> a
+ -> CodeGen e s ()
+x86_xchg_membase_reg ::
+ (Num a) =>
+ Word8
+ -> Word32
+ -> Word8
+ -> a
+ -> CodeGen e s ()
+x86_xadd_reg_reg ::
+ (Num a) =>
+ Word8
+ -> Word8
+ -> a
+ -> CodeGen e s ()
+x86_xadd_mem_reg ::
+ (Num a) =>
+ Word32
+ -> Word8
+ -> a
+ -> CodeGen e s ()
+x86_xadd_membase_reg ::
+ (Num a) =>
+ Word8
+ -> Word32
+ -> Word8
+ -> a
+ -> CodeGen e s ()
+x86_inc_mem ::
+ Word32 -> CodeGen e s ()
+x86_inc_membase ::
+ Word8
+ -> Word32
+ -> CodeGen e s ()
+x86_inc_reg ::
+ Word8 -> CodeGen e s ()
+x86_dec_mem ::
+ Word32 -> CodeGen e s ()
+x86_dec_membase ::
+ Word8
+ -> Word32
+ -> CodeGen e s ()
+x86_dec_reg ::
+ Word8 -> CodeGen e s ()
+x86_not_mem ::
+ Word32 -> CodeGen e s ()
+x86_not_membase ::
+ Word8
+ -> Word32
+ -> CodeGen e s ()
+x86_not_reg ::
+ Word8 -> CodeGen e s ()
+x86_neg_mem ::
+ Word32 -> CodeGen e s ()
+x86_neg_membase ::
+ Word8
+ -> Word32
+ -> CodeGen e s ()
+x86_neg_reg ::
+ Word8 -> CodeGen e s ()
+x86_alu_mem_imm ::
+ Word8
+ -> Word32
+ -> Word32
+ -> CodeGen e s ()
+x86_alu_membase_imm ::
+ Word8
+ -> Word8
+ -> Word32
+ -> Word32
+ -> CodeGen e s ()
+x86_alu_membase8_imm ::
+ Word8
+ -> Word8
+ -> Word32
+ -> Word8
+ -> CodeGen e s ()
+x86_alu_mem_reg ::
+ Word8
+ -> Word32
+ -> Word8
+ -> CodeGen e s ()
+x86_alu_membase_reg ::
+ Word8
+ -> Word8
+ -> Word32
+ -> Word8
+ -> CodeGen e s ()
+x86_alu_reg_reg ::
+ Word8
+ -> Word8
+ -> Word8
+ -> CodeGen e s ()
+x86_alu_reg8_reg8 ::
+ Word8
+ -> Word8
+ -> Word8
+ -> Bool
+ -> Bool
+ -> CodeGen e s ()
+x86_alu_reg_mem ::
+ Word8
+ -> Word8
+ -> Word32
+ -> CodeGen e s ()
+x86_alu_reg_membase ::
+ Word8
+ -> Word8
+ -> Word8
+ -> Word32
+ -> CodeGen e s ()
+x86_test_reg_imm ::
+ Word8
+ -> Word32
+ -> CodeGen e s ()
+x86_test_mem_imm ::
+ Word32
+ -> Word32
+ -> CodeGen e s ()
+x86_test_membase_imm ::
+ Word8
+ -> Word32
+ -> Word32
+ -> CodeGen e s ()
+x86_test_reg_reg ::
+ Word8
+ -> Word8
+ -> CodeGen e s ()
+x86_test_mem_reg ::
+ Word32
+ -> Word8
+ -> CodeGen e s ()
+x86_test_membase_reg ::
+ Word8
+ -> Word32
+ -> Word8
+ -> CodeGen e s ()
+x86_shift_reg_imm ::
+ Word8
+ -> Word8
+ -> Word8
+ -> CodeGen e s ()
+x86_shift_mem_imm ::
+ Word8
+ -> Word32
+ -> Word8
+ -> CodeGen e s ()
+x86_shift_membase_imm ::
+ Word8
+ -> Word8
+ -> Word32
+ -> Word8
+ -> CodeGen e s ()
+x86_shift_reg ::
+ Word8
+ -> Word8
+ -> CodeGen e s ()
+x86_shift_mem ::
+ Word8
+ -> Word32
+ -> CodeGen e s ()
+x86_shift_membase ::
+ Word8
+ -> Word8
+ -> Word32
+ -> CodeGen e s ()
+x86_shrd_reg ::
+ Word8
+ -> Word8
+ -> CodeGen e s ()
+x86_shrd_reg_imm ::
+ Word8
+ -> Word8
+ -> Word8
+ -> CodeGen e s ()
+x86_shld_reg ::
+ Word8
+ -> Word8
+ -> CodeGen e s ()
+x86_shld_reg_imm ::
+ Word8
+ -> Word8
+ -> Word8
+ -> CodeGen e s ()
+
+-- =============================================================================
+-- SSE instructions.
+-- =============================================================================
+
+data X86_SSE_PFX = X86_SSE_SD
+ | X86_SSE_SS
+ | X86_SSE_PD
+ | X86_SSE_PS
+--newtype X86_SSE_PFX = X86_SSE_PFX (forall e s. CodeGen e s ())
+
+x86_sse_sd, x86_sse_ss, x86_sse_pd, x86_sse_ps :: X86_SSE_PFX
+x86_sse_sd = X86_SSE_SD
+x86_sse_ss = X86_SSE_SS
+x86_sse_pd = X86_SSE_PD
+x86_sse_ps = X86_SSE_PS
+
+emit_sse :: X86_SSE_PFX -> CodeGen e s ()
+emit_sse X86_SSE_SD = emit8 0xf2
+emit_sse X86_SSE_SS = emit8 0xf3
+emit_sse X86_SSE_PD = emit8 0x66
+emit_sse X86_SSE_PS = return ()
+
+x86_sqrt_sse_reg_reg :: X86_SSE_PFX -> Word8 -> Word8 -> CodeGen e s ()
+x86_sqrt_sse_reg_reg pfx dreg reg =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x51
+ x86_reg_emit dreg reg
+
+x86_sqrt_sse_reg_mem :: X86_SSE_PFX -> Word8 -> Word32 -> CodeGen e s ()
+x86_sqrt_sse_reg_mem pfx dreg mem =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x51
+ x86_mem_emit dreg mem
+
+x86_sqrt_sse_reg_membase :: X86_SSE_PFX -> Word8 -> Word8 -> Word32 -> CodeGen e s ()
+x86_sqrt_sse_reg_membase pfx dreg basereg disp =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x51
+ x86_membase_emit dreg basereg disp
+
+x86_add_sse_reg_reg :: X86_SSE_PFX -> Word8 -> Word8 -> CodeGen e s ()
+x86_add_sse_reg_reg pfx dreg reg =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x58
+ x86_reg_emit dreg reg
+
+x86_add_sse_reg_mem :: X86_SSE_PFX -> Word8 -> Word32 -> CodeGen e s ()
+x86_add_sse_reg_mem pfx dreg mem =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x58
+ x86_mem_emit dreg mem
+
+x86_add_sse_reg_membase :: X86_SSE_PFX -> Word8 -> Word8 -> Word32 -> CodeGen e s ()
+x86_add_sse_reg_membase pfx dreg basereg disp =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x58
+ x86_membase_emit dreg basereg disp
+
+x86_mul_sse_reg_reg :: X86_SSE_PFX -> Word8 -> Word8 -> CodeGen e s ()
+x86_mul_sse_reg_reg pfx dreg reg =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x59
+ x86_reg_emit dreg reg
+
+x86_mul_sse_reg_mem :: X86_SSE_PFX -> Word8 -> Word32 -> CodeGen e s ()
+x86_mul_sse_reg_mem pfx dreg mem =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x59
+ x86_mem_emit dreg mem
+
+x86_mul_sse_reg_membase :: X86_SSE_PFX -> Word8 -> Word8 -> Word32 -> CodeGen e s ()
+x86_mul_sse_reg_membase pfx dreg basereg disp =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x59
+ x86_membase_emit dreg basereg disp
+
+x86_sub_sse_reg_reg :: X86_SSE_PFX -> Word8 -> Word8 -> CodeGen e s ()
+x86_sub_sse_reg_reg pfx dreg reg =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x5c
+ x86_reg_emit dreg reg
+
+x86_sub_sse_reg_mem :: X86_SSE_PFX -> Word8 -> Word32 -> CodeGen e s ()
+x86_sub_sse_reg_mem pfx dreg mem =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x5c
+ x86_mem_emit dreg mem
+
+x86_sub_sse_reg_membase :: X86_SSE_PFX -> Word8 -> Word8 -> Word32 -> CodeGen e s ()
+x86_sub_sse_reg_membase pfx dreg basereg disp =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x5c
+ x86_membase_emit dreg basereg disp
+
+x86_min_sse_reg_reg :: X86_SSE_PFX -> Word8 -> Word8 -> CodeGen e s ()
+x86_min_sse_reg_reg pfx dreg reg =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x5d
+ x86_reg_emit dreg reg
+
+x86_min_sse_reg_mem :: X86_SSE_PFX -> Word8 -> Word32 -> CodeGen e s ()
+x86_min_sse_reg_mem pfx dreg mem =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x5d
+ x86_mem_emit dreg mem
+
+x86_min_sse_reg_membase :: X86_SSE_PFX -> Word8 -> Word8 -> Word32 -> CodeGen e s ()
+x86_min_sse_reg_membase pfx dreg basereg disp =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x5d
+ x86_membase_emit dreg basereg disp
+
+x86_div_sse_reg_reg :: X86_SSE_PFX -> Word8 -> Word8 -> CodeGen e s ()
+x86_div_sse_reg_reg pfx dreg reg =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x5e
+ x86_reg_emit dreg reg
+
+x86_div_sse_reg_mem :: X86_SSE_PFX -> Word8 -> Word32 -> CodeGen e s ()
+x86_div_sse_reg_mem pfx dreg mem =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x5e
+ x86_mem_emit dreg mem
+
+x86_div_sse_reg_membase :: X86_SSE_PFX -> Word8 -> Word8 -> Word32 -> CodeGen e s ()
+x86_div_sse_reg_membase pfx dreg basereg disp =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x5e
+ x86_membase_emit dreg basereg disp
+
+x86_max_sse_reg_reg :: X86_SSE_PFX -> Word8 -> Word8 -> CodeGen e s ()
+x86_max_sse_reg_reg pfx dreg reg =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x5f
+ x86_reg_emit dreg reg
+
+x86_max_sse_reg_mem :: X86_SSE_PFX -> Word8 -> Word32 -> CodeGen e s ()
+x86_max_sse_reg_mem pfx dreg mem =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x5f
+ x86_mem_emit dreg mem
+
+x86_max_sse_reg_membase :: X86_SSE_PFX -> Word8 -> Word8 -> Word32 -> CodeGen e s ()
+x86_max_sse_reg_membase pfx dreg basereg disp =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x5f
+ x86_membase_emit dreg basereg disp
+
+x86_mov_sse_reg_reg :: X86_SSE_PFX -> Word8 -> Word8 -> CodeGen e s ()
+x86_mov_sse_reg_reg pfx dreg reg =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x10
+ x86_reg_emit dreg reg
+
+x86_mov_sse_reg_mem :: X86_SSE_PFX -> Word8 -> Word32 -> CodeGen e s ()
+x86_mov_sse_reg_mem pfx dreg mem =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x10
+ x86_mem_emit dreg mem
+
+x86_mov_sse_reg_membase :: X86_SSE_PFX -> Word8 -> Word8 -> Word32 -> CodeGen e s ()
+x86_mov_sse_reg_membase pfx dreg basereg disp =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x10
+ x86_membase_emit dreg basereg disp
+
+x86_mov_sse_mem_reg :: X86_SSE_PFX -> Word32 -> Word8 -> CodeGen e s ()
+x86_mov_sse_mem_reg pfx mem reg =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x11
+ x86_mem_emit reg mem
+
+x86_mov_sse_membase_reg :: X86_SSE_PFX -> Word8 -> Word32 -> Word8 -> CodeGen e s ()
+x86_mov_sse_membase_reg pfx basereg disp reg =
+ do emit_sse pfx
+ emit8 0x0f
+ emit8 0x11
+ x86_membase_emit reg basereg disp
+
+x86_ucomisd_reg_reg :: Word8 -> Word8 -> CodeGen e s ()
+x86_ucomisd_reg_reg dreg reg =
+ do emit8 0x66
+ emit8 0x0f
+ emit8 0x2e
+ x86_reg_emit dreg reg
+
+x86_ucomisd_reg_mem :: Word8 -> Word32 -> CodeGen e s ()
+x86_ucomisd_reg_mem dreg mem =
+ do emit8 0x66
+ emit8 0x0f
+ emit8 0x2e
+ x86_mem_emit dreg mem
+
+x86_ucomisd_reg_membase :: Word8 -> Word8 -> Word32 -> CodeGen e s ()
+x86_ucomisd_reg_membase dreg basereg disp =
+ do emit8 0x66
+ emit8 0x0f
+ emit8 0x2e
+ x86_membase_emit dreg basereg disp
+
+x86_ucomiss_reg_reg :: Word8 -> Word8 -> CodeGen e s ()
+x86_ucomiss_reg_reg dreg reg =
+ do emit8 0x0f
+ emit8 0x2e
+ x86_reg_emit dreg reg
+
+x86_ucomiss_reg_mem :: Word8 -> Word32 -> CodeGen e s ()
+x86_ucomiss_reg_mem dreg mem =
+ do emit8 0x0f
+ emit8 0x2e
+ x86_mem_emit dreg mem
+
+x86_ucomiss_reg_membase :: Word8 -> Word8 -> Word32 -> CodeGen e s ()
+x86_ucomiss_reg_membase dreg basereg disp =
+ do emit8 0x0f
+ emit8 0x2e
+ x86_membase_emit dreg basereg disp
+
+x86_comisd_reg_reg :: Word8 -> Word8 -> CodeGen e s ()
+x86_comisd_reg_reg dreg reg =
+ do emit8 0x66
+ emit8 0x0f
+ emit8 0x2f
+ x86_reg_emit dreg reg
+
+x86_comisd_reg_mem :: Word8 -> Word32 -> CodeGen e s ()
+x86_comisd_reg_mem dreg mem =
+ do emit8 0x66
+ emit8 0x0f
+ emit8 0x2f
+ x86_mem_emit dreg mem
+
+x86_comisd_reg_membase :: Word8 -> Word8 -> Word32 -> CodeGen e s ()
+x86_comisd_reg_membase dreg basereg disp =
+ do emit8 0x66
+ emit8 0x0f
+ emit8 0x2e
+ x86_membase_emit dreg basereg disp
+
+x86_comiss_reg_reg :: Word8 -> Word8 -> CodeGen e s ()
+x86_comiss_reg_reg dreg reg =
+ do emit8 0x0f
+ emit8 0x2f
+ x86_reg_emit dreg reg
+
+x86_comiss_reg_mem :: Word8 -> Word32 -> CodeGen e s ()
+x86_comiss_reg_mem dreg mem =
+ do emit8 0x0f
+ emit8 0x2f
+ x86_mem_emit dreg mem
+
+x86_comiss_reg_membase :: Word8 -> Word8 -> Word32 -> CodeGen e s ()
+x86_comiss_reg_membase dreg basereg disp =
+ do emit8 0x0f
+ emit8 0x2e
+ x86_membase_emit dreg basereg disp
+
+
+newtype XMMReg = XMMReg Word8
+ deriving (Eq, Ord)
+
+newtype Mem = Mem Word32
+
+data MemBase = MemBase Word8 Word32
+
+
+class XMMLocation xmm where
+ xmm_location_emit :: Word8 -> xmm -> CodeGen e s ()
+
+instance XMMLocation XMMReg where
+ xmm_location_emit dreg (XMMReg reg) =
+ x86_reg_emit dreg reg
+
+instance XMMLocation Mem where
+ xmm_location_emit dreg (Mem mem) =
+ x86_mem_emit dreg mem
+
+instance XMMLocation MemBase where
+ xmm_location_emit dreg (MemBase basereg disp) =
+ x86_membase_emit dreg basereg disp
+
+
+x86_movss_to_reg :: XMMLocation xmm => Word8 -> xmm -> CodeGen e s ()
+x86_movss_to_reg dreg reg =
+ do emit8 0xf3
+ emit8 0x0f
+ emit8 0x10
+ xmm_location_emit dreg reg
+
+x86_movss_from_reg :: XMMLocation xmm => Word8 -> xmm -> CodeGen e s ()
+x86_movss_from_reg dreg reg =
+ do emit8 0xf3
+ emit8 0x0f
+ emit8 0x11
+ xmm_location_emit dreg reg
+
+x86_movsd_to_reg :: XMMLocation xmm => Word8 -> xmm -> CodeGen e s ()
+x86_movsd_to_reg dreg reg =
+ do emit8 0xf2
+ emit8 0x0f
+ emit8 0x10
+ xmm_location_emit dreg reg
+
+x86_movsd_from_reg :: XMMLocation xmm => Word8 -> xmm -> CodeGen e s ()
+x86_movsd_from_reg dreg reg =
+ do emit8 0xf2
+ emit8 0x0f
+ emit8 0x11
+ xmm_location_emit dreg reg
+
+
+-- | xmm must not be a register
+x86_movlps_to_reg :: XMMLocation xmm => Word8 -> xmm -> CodeGen e s ()
+x86_movlps_to_reg dreg reg =
+ do emit8 0x0f
+ emit8 0x12
+ xmm_location_emit dreg reg
+
+-- | xmm must not be a register
+x86_movlps_from_reg :: XMMLocation xmm => Word8 -> xmm -> CodeGen e s ()
+x86_movlps_from_reg dreg reg =
+ do emit8 0x0f
+ emit8 0x13
+ xmm_location_emit dreg reg
+
+-- | xmm must not be a register
+x86_movlpd_to_reg :: XMMLocation xmm => Word8 -> xmm -> CodeGen e s ()
+x86_movlpd_to_reg dreg reg =
+ do emit8 0x66
+ emit8 0x0f
+ emit8 0x12
+ xmm_location_emit dreg reg
+
+-- | xmm must not be a register
+x86_movlpd_from_reg :: XMMLocation xmm => Word8 -> xmm -> CodeGen e s ()
+x86_movlpd_from_reg dreg reg =
+ do emit8 0x66
+ emit8 0x0f
+ emit8 0x13
+ xmm_location_emit dreg reg
+
+
+x86_movups_to_reg :: XMMLocation xmm => Word8 -> xmm -> CodeGen e s ()
+x86_movups_to_reg dreg reg =
+ do emit8 0x0f
+ emit8 0x10
+ xmm_location_emit dreg reg
+
+x86_movups_from_reg :: XMMLocation xmm => Word8 -> xmm -> CodeGen e s ()
+x86_movups_from_reg dreg reg =
+ do emit8 0x0f
+ emit8 0x11
+ xmm_location_emit dreg reg
+
+x86_movupd_to_reg :: XMMLocation xmm => Word8 -> xmm -> CodeGen e s ()
+x86_movupd_to_reg dreg reg =
+ do emit8 0x66
+ emit8 0x0f
+ emit8 0x10
+ xmm_location_emit dreg reg
+
+x86_movupd_from_reg :: XMMLocation xmm => Word8 -> xmm -> CodeGen e s ()
+x86_movupd_from_reg dreg reg =
+ do emit8 0x66
+ emit8 0x0f
+ emit8 0x11
+ xmm_location_emit dreg reg
+
+
+x86_haddps :: XMMLocation xmm => Word8 -> xmm -> CodeGen e s ()
+x86_haddps dreg reg =
+ do emit8 0xf2
+ emit8 0x0f
+ emit8 0x7c
+ xmm_location_emit dreg reg
+
+x86_haddpd :: XMMLocation xmm => Word8 -> xmm -> CodeGen e s ()
+x86_haddpd dreg reg =
+ do emit8 0x66
+ emit8 0x0f
+ emit8 0x7c
+ xmm_location_emit dreg reg
+
+
+x86_shufps :: XMMLocation xmm => Word8 -> xmm -> Word8 -> CodeGen e s ()
+x86_shufps dreg reg src =
+ do emit8 0x0f
+ emit8 0xc6
+ xmm_location_emit dreg reg
+ emit8 src
+
+x86_shufpd :: XMMLocation xmm => Word8 -> xmm -> Word8 -> CodeGen e s ()
+x86_shufpd dreg reg src =
+ do emit8 0x66
+ emit8 0x0f
+ emit8 0xc6
+ xmm_location_emit dreg reg
+ emit8 src
+
+
+x86_cvtdq2ps :: XMMLocation xmm => Word8 -> xmm -> CodeGen e s ()
+x86_cvtdq2ps dreg reg =
+ do emit8 0x0f
+ emit8 0x5b
+ xmm_location_emit dreg reg
+
+x86_cvttps2dq :: XMMLocation xmm => Word8 -> xmm -> CodeGen e s ()
+x86_cvttps2dq dreg reg =
+ do emit8 0xf3
+ emit8 0x0f
+ emit8 0x5b
+ xmm_location_emit dreg reg
+
+
+
+-- =============================================================================
+-- Prefetching instructions.
+-- =============================================================================
+
+x86_prefetch0_mem :: Word32 -> CodeGen e s ()
+x86_prefetch0_mem m = x86_prefetch_mem 1 m
+
+x86_prefetch1_mem :: Word32 -> CodeGen e s ()
+x86_prefetch1_mem m = x86_prefetch_mem 2 m
+
+x86_prefetch2_mem :: Word32 -> CodeGen e s ()
+x86_prefetch2_mem m = x86_prefetch_mem 3 m
+
+x86_prefetchnta_mem :: Word32 -> CodeGen e s ()
+x86_prefetchnta_mem m = x86_prefetch_mem 0 m
+
+x86_prefetch_mem :: Word8 -> Word32 -> CodeGen e s ()
+x86_prefetch_mem hint disp =
+ do emit8 0x0f
+ emit8 0x18
+ x86_address_byte 0 hint 0
+ x86_imm_emit32 disp
+
+x86_prefetch0_membase :: Word8 -> Word32 -> CodeGen e s ()
+x86_prefetch0_membase r m = x86_prefetch_membase 1 r m
+
+x86_prefetch1_membase :: Word8 -> Word32 -> CodeGen e s ()
+x86_prefetch1_membase r m = x86_prefetch_membase 2 r m
+
+x86_prefetch2_membase :: Word8 -> Word32 -> CodeGen e s ()
+x86_prefetch2_membase r m = x86_prefetch_membase 3 r m
+
+x86_prefetchnta_membase :: Word8 -> Word32 -> CodeGen e s ()
+x86_prefetchnta_membase r m = x86_prefetch_membase 0 r m
+
+x86_prefetch_membase :: Word8 -> Word8 -> Word32 -> CodeGen e s ()
+x86_prefetch_membase hint reg disp =
+ do emit8 0x0f
+ emit8 0x18
+ x86_membase_emit hint reg disp
+
+x86_prefetch0_regp :: Word8 -> CodeGen e s ()
+x86_prefetch0_regp r = x86_prefetch_regp 1 r
+
+x86_prefetch1_regp :: Word8 -> CodeGen e s ()
+x86_prefetch1_regp r = x86_prefetch_regp 2 r
+
+x86_prefetch2_regp :: Word8 -> CodeGen e s ()
+x86_prefetch2_regp r = x86_prefetch_regp 3 r
+
+x86_prefetchnta_regp :: Word8 -> CodeGen e s ()
+x86_prefetchnta_regp r = x86_prefetch_regp 0 r
+
+x86_prefetch_regp :: Word8 -> Word8 -> CodeGen e s ()
+x86_prefetch_regp hint reg =
+ do emit8 0x0f
+ emit8 0x18
+ x86_regp_emit hint reg
+