module Harpy.X86Assembler where
import Harpy.X86CodeGen
import Harpy.CodeGenMonad
import Data.Word
import Foreign.Ptr
import qualified Text.PrettyPrint.HughesPJ as PP
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")
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
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
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 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"
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
breakpoint = ensureBufferSize x86_max_instruction_bytes >> x86_breakpoint
cld = ensureBufferSize x86_max_instruction_bytes >> x86_cld
stosb = ensureBufferSize x86_max_instruction_bytes >> x86_stosb
stosl = ensureBufferSize x86_max_instruction_bytes >> x86_stosl
stosd = ensureBufferSize x86_max_instruction_bytes >> x86_stosd
movsb = ensureBufferSize x86_max_instruction_bytes >> x86_movsb
movsl = ensureBufferSize x86_max_instruction_bytes >> x86_movsl
rdtsc = ensureBufferSize x86_max_instruction_bytes >> x86_rdtsc
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
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
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
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
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
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
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
nop = ensureBufferSize x86_max_instruction_bytes >> x86_nop
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