harpy 0.2 → 0.4
raw patch · 16 files changed
+5299/−3496 lines, 16 filesdep +arraydep +containersdep +prettydep ~base
Dependencies added: array, containers, pretty
Dependency ranges changed: base
Files
- Harpy.hs +22/−0
- Harpy/Call.hs +1/−1
- Harpy/CodeGenMonad.hs +203/−115
- Harpy/X86Assembler.hs +3746/−0
- Harpy/X86Assembler.lhs +0/−2906
- Harpy/X86CGCombinators.hs +80/−90
- Harpy/X86CodeGen.hs +581/−349
- Harpy/X86Disassembler.hs +49/−28
- Makefile +0/−0
- NEWS +46/−0
- doc/Makefile +18/−0
- doc/larger-tutorial.lhs +312/−0
- examples/evaluator/ArithParser.hs +73/−0
- examples/evaluator/ArithTypes.hs +22/−0
- examples/evaluator/Evaluator.hs +118/−0
- harpy.cabal +28/−7
+ Harpy.hs view
@@ -0,0 +1,22 @@+--------------------------------------------------------------------------+-- |+-- Module: Harpy+-- Copyright: (c) 2006-2007 Martin Grabmueller and Dirk Kleeblatt+-- License: GPL+-- +-- Maintainer: {magr,klee}@cs.tu-berlin.de+-- Stability: provisional+-- Portability: portable+--+-- Harpy is a library for run-time code generation of x86 machine code.+--+-- This is a convenience module which re-exports the modules which are+-- essential for using Harpy.+----------------------------------------------------------------------------+module Harpy(module Harpy.CodeGenMonad,+ module Harpy.Call,+ module Harpy.X86Assembler) where++import Harpy.CodeGenMonad+import Harpy.Call+import Harpy.X86Assembler
Harpy/Call.hs view
@@ -2,7 +2,7 @@ -------------------------------------------------------------------------- -- |--- Module : Call+-- Module : Harpy.Call -- Copyright : (c) 2006-2007 Martin Grabmueller and Dirk Kleeblatt -- License : GPL --
Harpy/CodeGenMonad.hs view
@@ -2,13 +2,13 @@ -------------------------------------------------------------------------- -- |--- Module : CodeGenMonad--- Copyright : (c) 2006-2007 Martin Grabmueller and Dirk Kleeblatt--- License : GPL+-- Module: Harpy.CodeGenMonad+-- Copyright: (c) 2006-2007 Martin Grabmueller and Dirk Kleeblatt+-- License: GPL -- --- Maintainer : {magr,klee}@cs.tu-berlin.de--- Stability : provisional--- Portability : portable (but generated code non-portable)+-- Maintainer: {magr,klee}@cs.tu-berlin.de+-- Stability: provisional+-- Portability: portable (but generated code non-portable) -- -- Monad for generating x86 machine code at runtime. --@@ -16,20 +16,21 @@ -- the details of handling code buffers, emitting binary data, -- relocation etc. ----- All the code generation functions in module "Harpy.X86CodeGen"--- live in this monad and use its error reporting facilities as well--- as the internal state maintained by the monad. The user state is--- independent from the internal state and may be used by--- higher-level code generation libraries to maintain their own--- state across code generation operations.+-- All the code generation functions in module "Harpy.X86CodeGen" live+-- in this monad and use its error reporting facilities as well as the+-- internal state maintained by the monad. -----------------------------------------------------------------------------+-- The library user can pass a user environment and user state through+-- the monad. This state is independent from the internal state and+-- may be used by higher-level code generation libraries to maintain+-- their own state across code generation operations.+-- -------------------------------------------------------------------------- module Harpy.CodeGenMonad( -- * Types CodeGen,- RelocKind(..), ErrMsg,+ RelocKind(..), Reloc, Label, FixupKind(..),@@ -50,6 +51,7 @@ withEnv, -- ** Label management newLabel,+ newNamedLabel, setLabel, defineLabel, (@@),@@ -78,12 +80,12 @@ import Control.Monad import Text.PrettyPrint.HughesPJ-import Text.Printf -import Data.Word+import Numeric++import Data.List import qualified Data.Map as Map import Foreign-import System.Cmd import System.IO import Control.Monad.Trans@@ -98,37 +100,53 @@ -- monad. newtype CodeGen e s a = CodeGen ((e, CodeGenEnv) -> (s, CodeGenState) -> IO ((s, CodeGenState), Either ErrMsg a)) --- | Configuration of the code generator.-data CodeGenConfig = CodeGenConfig { codeBufferSize :: Int -- ^ Size of individual code buffer blocks. - }+-- | Configuration of the code generator. There are currently two+-- configuration options. The first is the number fo bytes to use for+-- allocating code buffers (the first as well as additional buffers+-- created in calls to 'ensureBufferSize'. The second allows to pass+-- in a pre-allocated code buffer and its size. When this option is+-- used, Harpy does not perform any code buffer resizing (calls to+-- 'ensureBufferSize' will be equivalent to calls to+-- 'checkBufferSize').+data CodeGenConfig = CodeGenConfig { + codeBufferSize :: Int, -- ^ Size of individual code buffer blocks. + customCodeBuffer :: Maybe (Ptr Word8, Int) -- ^ Code buffer passed in.+ } -- | Internal state of the code generator-data CodeGenState = CodeGenState { buffer :: Ptr Word8,- bufferList :: [(Ptr Word8, Int)],- firstBuffer :: Ptr Word8,- bufferOfs :: Int,- bufferSize :: Int,- relocEntries :: [Reloc],- nextLabel :: Int,- definedLabels :: Map.Map Int (Ptr Word8, Int),- pendingFixups :: Map.Map Int [FixupEntry],- config :: CodeGenConfig}+data CodeGenState = CodeGenState { + buffer :: Ptr Word8, -- ^ Pointer to current code buffer.+ bufferList :: [(Ptr Word8, Int)], -- ^ List of all other code buffers.+ firstBuffer :: Ptr Word8, -- ^ Pointer to first buffer.+ bufferOfs :: Int, -- ^ Current offset into buffer where next instruction will be stored.+ bufferSize :: Int, -- ^ Size of current buffer.+ relocEntries :: [Reloc], -- ^ List of all emitted relocation entries.+ nextLabel :: Int, -- ^ Counter for generating labels.+ definedLabels :: Map.Map Int (Ptr Word8, Int, String), -- ^ Map of already defined labels.+ pendingFixups :: Map.Map Int [FixupEntry], -- ^ Map of labels which have been referenced, but not defined.+ config :: CodeGenConfig -- ^ Configuration record.+ } -data FixupKind = Fixup8- | Fixup16- | Fixup32- | Fixup32Absolute- deriving (Show)+data FixupEntry = FixupEntry { + fueBuffer :: Ptr Word8,+ fueOfs :: Int,+ fueKind :: FixupKind + } -data FixupEntry = FixupEntry { fueBuffer :: Ptr Word8,- fueOfs :: Int,- fueKind :: FixupKind }+-- | Kind of a fixup entry. When a label is emitted with+-- 'defineLabel', all prior references to this label must be fixed+-- up. This data type tells how to perform the fixup operation.+data FixupKind = Fixup8 -- ^ 8-bit relative reference+ | Fixup16 -- ^ 16-bit relative reference+ | Fixup32 -- ^ 32-bit relative reference+ | Fixup32Absolute -- ^ 32-bit absolute reference+ deriving (Show) data CodeGenEnv = CodeGenEnv { tailContext :: Bool } deriving (Show) -- | Kind of relocation, for example PC-relative-data RelocKind = RelocPCRel -- ^ PC-relative relocation+data RelocKind = RelocPCRel -- ^ PC-relative relocation | RelocAbsolute -- ^ Absolute address deriving (Show) @@ -143,7 +161,7 @@ deriving (Show) -- | Label-data Label = Label Int+data Label = Label Int String unCg :: CodeGen e s a -> ((e, CodeGenEnv) -> (s, CodeGenState) -> IO ((s, CodeGenState), Either ErrMsg a)) unCg (CodeGen a) = a@@ -153,11 +171,13 @@ fail err = cgFail err m >>= k = cgBind m k --- {-# INLINE cgReturn #-}+cgReturn :: a -> CodeGen e s a cgReturn x = CodeGen (\_env state -> return (state, Right x))--- {-# INLINE cgFail #-}++cgFail :: String -> CodeGen e s a cgFail err = CodeGen (\_env state -> return (state, Left (text err)))--- {-# INLINE cgBind #-}++cgBind :: CodeGen e s a -> (a -> CodeGen e s a1) -> CodeGen e s a1 cgBind m k = CodeGen (\env state -> do r1 <- unCg m env state case r1 of@@ -183,29 +203,44 @@ pendingFixups = Map.empty, config = defaultCodeGenConfig} +-- | Default code generation configuration. The code buffer size is+-- set to 4KB, and code buffer management is automatic. This value is+-- intended to be used with record update syntax, for example:+--+-- > runCodeGenWithConfig ... defaultCodeGenConfig{codeBufferSize = 128} ... defaultCodeGenConfig :: CodeGenConfig-defaultCodeGenConfig = CodeGenConfig { codeBufferSize = defaultCodeBufferSize }+defaultCodeGenConfig = CodeGenConfig { codeBufferSize = defaultCodeBufferSize,+ customCodeBuffer = Nothing } defaultCodeBufferSize :: Int-defaultCodeBufferSize = 128+defaultCodeBufferSize = 4096 --- | Execute code generation, given a user environment and state.--- The result is a tuple of the resulting user state and either an--- error message (when code generation failed) or the result of the--- code generation.+-- | Execute code generation, given a user environment and state. The+-- result is a tuple of the resulting user state and either an error+-- message (when code generation failed) or the result of the code+-- generation. This function runs 'runCodeGenWithConfig' with a+-- sensible default configuration. runCodeGen :: CodeGen e s a -> e -> s -> IO (s, Either ErrMsg a) runCodeGen cg uenv ustate = runCodeGenWithConfig cg uenv ustate defaultCodeGenConfig +-- | Like 'runCodeGen', but allows more control over the code+-- generation process. In addition to a code generator and a user+-- environment and state, a code generation configuration must be+-- provided. A code generation configuration allows control over the+-- allocation of code buffers, for example. runCodeGenWithConfig :: CodeGen e s a -> e -> s -> CodeGenConfig -> IO (s, Either ErrMsg a) runCodeGenWithConfig (CodeGen cg) uenv ustate conf =- do let initSize = codeBufferSize conf- arr <- mallocBytes initSize+ do (buf, sze) <- case customCodeBuffer conf of+ Nothing -> do let initSize = codeBufferSize conf+ arr <- mallocBytes initSize+ return (arr, initSize)+ Just (buf, sze) -> return (buf, sze) let env = CodeGenEnv {tailContext = True}- let state = emptyCodeGenState{buffer = arr,+ let state = emptyCodeGenState{buffer = buf, bufferList = [],- firstBuffer = arr,- bufferSize = initSize,+ firstBuffer = buf,+ bufferSize = sze, config = conf} ((ustate', _), res) <- cg (uenv, env) (ustate, state) return (ustate', res)@@ -215,6 +250,9 @@ -- whenever it cannot be guaranteed that the code buffer is large -- enough to hold all the generated code. Lets the code generation -- monad fail when the buffer overflows.+--+-- /Note:/ Starting with version 0.4, Harpy automatically checks for+-- buffer overflow, so you do not need to call this function anymore. checkBufferSize :: Int -> CodeGen e s () checkBufferSize needed = do state <- getInternalState@@ -226,57 +264,63 @@ int (bufferSize state) <> text ")")) -- | Make sure that the code buffer has room for at least the given--- number of bytes. This should be called by code generators--- whenever it cannot be guaranteed that the code buffer is large--- enough to hold all the generated code. Creates a new buffer and--- places a jump to the new buffer when there is not sufficient space--- available+-- number of bytes. This should be called by code generators whenever+-- it cannot be guaranteed that the code buffer is large enough to+-- hold all the generated code. Creates a new buffer and places a+-- jump to the new buffer when there is not sufficient space+-- available. When code generation was invoked with a pre-defined+-- code buffer, code generation is aborted on overflow.+--+-- /Note:/ Starting with version 0.4, Harpy automatically checks for+-- buffer overflow, so you do not need to call this function anymore. ensureBufferSize :: Int -> CodeGen e s () ensureBufferSize needed = do state <- getInternalState- unless (bufferOfs state + needed + 5 <= bufferSize state)- (do let incrSize = max (needed + 16) - (codeBufferSize (config state))- arr <- liftIO $ mallocBytes incrSize- ofs <- getCodeOffset- let buf = buffer state- disp :: Int- disp = arr `minusPtr` (buf `plusPtr` ofs) - 5- emit8 0xe9- emit32 (fromIntegral disp)- st <- getInternalState- setInternalState st{buffer = arr, bufferList = bufferList st ++ [(buffer st, bufferOfs st)], bufferOfs = 0})+ case (customCodeBuffer (config state)) of+ Nothing ->+ unless (bufferOfs state + needed + 5 <= bufferSize state)+ (do let incrSize = max (needed + 16) (codeBufferSize (config state))+ arr <- liftIO $ mallocBytes incrSize+ ofs <- getCodeOffset+ let buf = buffer state+ disp :: Int+ disp = arr `minusPtr` (buf `plusPtr` ofs) - 5+ emit8 0xe9 -- FIXME: Machine dependent!+ emit32 (fromIntegral disp)+ st <- getInternalState+ setInternalState st{buffer = arr, bufferList = bufferList st ++ [(buffer st, bufferOfs st)], bufferOfs = 0})+ Just (_, _) -> checkBufferSize needed -- | Return a pointer to the beginning of the first code buffer, which -- is normally the entry point to the generated code. getEntryPoint :: CodeGen e s (Ptr Word8) getEntryPoint =- CodeGen (\ env (ustate, state) -> + CodeGen (\ _ (ustate, state) -> return $ ((ustate, state), Right (firstBuffer state))) -- | Return the current offset in the code buffer, e.g. the offset -- at which the next instruction will be emitted. getCodeOffset :: CodeGen e s Int getCodeOffset =- CodeGen (\ env (ustate, state) -> + CodeGen (\ _ (ustate, state) -> return $ ((ustate, state), Right (bufferOfs state))) -- | Set the user state to the given value. setState :: s -> CodeGen e s () setState st =- CodeGen (\ env (_, state) -> + CodeGen (\ _ (_, state) -> return $ ((st, state), Right ())) -- | Return the current user state. getState :: CodeGen e s s getState =- CodeGen (\ env (ustate, state) -> + CodeGen (\ _ (ustate, state) -> return $ ((ustate, state), Right (ustate))) -- | Return the current user environment. getEnv :: CodeGen e s e getEnv =- CodeGen (\ (uenv, env) state -> + CodeGen (\ (uenv, _) state -> return $ (state, Right uenv)) -- | Set the environment to the given value and execute the given@@ -289,20 +333,19 @@ -- | Set the user state to the given value. setInternalState :: CodeGenState -> CodeGen e s () setInternalState st =- CodeGen (\ env (ustate, _) -> + CodeGen (\ _ (ustate, _) -> return $ ((ustate, st), Right ())) -- | Return the current user state. getInternalState :: CodeGen e s CodeGenState getInternalState =- CodeGen (\ env (ustate, state) -> + CodeGen (\ _ (ustate, state) -> return $ ((ustate, state), Right (state))) -- | Return the pointer to the start of the code buffer.--- {-# INLINE getBasePtr #-} getBasePtr :: CodeGen e s (Ptr Word8) getBasePtr =- CodeGen (\ env (ustate, state) -> + CodeGen (\ _ (ustate, state) -> return $ ((ustate, state), Right (buffer state))) -- | Return a list of all code buffers and their respective size @@ -312,14 +355,24 @@ return $ bufferList st ++ [(buffer st, bufferOfs st)] -- | Generate a new label to be used with the label operations--- 'emitRelocInfo', 'emitFixup' and 'defineLabel'.+-- 'emitFixup' and 'defineLabel'. newLabel :: CodeGen e s Label newLabel = do state <- getInternalState let lab = nextLabel state setInternalState state{nextLabel = lab + 1}- return (Label lab)+ return (Label lab "") +-- | Generate a new label to be used with the label operations+-- 'emitFixup' and 'defineLabel'. The given name is used for+-- diagnostic purposes, and will appear in the disassembly.+newNamedLabel :: String -> CodeGen e s Label+newNamedLabel name =+ do state <- getInternalState+ let lab = nextLabel state+ setInternalState state{nextLabel = lab + 1}+ return (Label lab name)+ -- | Generate a new label and define it at once setLabel :: CodeGen e s Label setLabel =@@ -330,58 +383,52 @@ -- | Emit a relocation entry for the given offset, relocation kind -- and target address. emitRelocInfo :: Int -> RelocKind -> FunPtr a -> CodeGen e s ()-emitRelocInfo ofs kind addr = - CodeGen (\ env (ustate, state) -> - do let newState = state{relocEntries =+emitRelocInfo ofs knd addr = + do state <- getInternalState+ setInternalState state{relocEntries = Reloc{offset = ofs, - kind = kind,+ kind = knd, address = castFunPtr addr} : (relocEntries state)}- return $ ((ustate, newState), Right ())) -- | Emit a byte value to the code buffer. --- {-# INLINE emit8 #-} emit8 :: Word8 -> CodeGen e s () emit8 op = - CodeGen (\ env (ustate, state) -> + CodeGen (\ _ (ustate, state) -> do let buf = buffer state ptr = bufferOfs state pokeByteOff buf ptr op return $ ((ustate, state{bufferOfs = ptr + 1}), Right ())) -- | Store a byte value at the given offset into the code buffer.--- {-# INLINE emit8At #-} emit8At :: Int -> Word8 -> CodeGen e s () emit8At pos op = - CodeGen (\ env (ustate, state) -> + CodeGen (\ _ (ustate, state) -> do let buf = buffer state pokeByteOff buf pos op return $ ((ustate, state), Right ())) -- | Return the byte value at the given offset in the code buffer.--- {-# INLINE peek8At #-} peek8At :: Int -> CodeGen e s Word8 peek8At pos =- CodeGen (\ env (ustate, state) -> + CodeGen (\ _ (ustate, state) -> do let buf = buffer state b <- peekByteOff buf pos return $ ((ustate, state), Right b)) -- | Like 'emit8', but for a 32-bit value.--- {-# INLINE emit32 #-} emit32 :: Word32 -> CodeGen e s () emit32 op = - CodeGen (\ env (ustate, state) -> + CodeGen (\ _ (ustate, state) -> do let buf = buffer state ptr = bufferOfs state pokeByteOff buf ptr op return $ ((ustate, state{bufferOfs = ptr + 4}), Right ())) -- | Like 'emit8At', but for a 32-bit value.--- {-# INLINE emit32At #-} emit32At :: Int -> Word32 -> CodeGen e s () emit32At pos op = - CodeGen (\ env (ustate, state) -> + CodeGen (\ _ (ustate, state) -> do let buf = buffer state pokeByteOff buf pos op return $ ((ustate, state), Right ()))@@ -389,19 +436,23 @@ -- | Emit a label at the current offset in the code buffer. All -- references to the label will be relocated to this offset. defineLabel :: Label -> CodeGen e s ()-defineLabel (Label lab) = +defineLabel (Label lab name) = do state <- getInternalState+ case Map.lookup lab (definedLabels state) of+ Just _ -> failCodeGen $ text "duplicate definition of label" <+> + int lab+ _ -> return () case Map.lookup lab (pendingFixups state) of Just fixups -> do mapM_ (performFixup (buffer state) (bufferOfs state)) fixups setInternalState state{pendingFixups = Map.delete lab (pendingFixups state)} Nothing -> return ()- state <- getInternalState- setInternalState state{definedLabels = Map.insert lab (buffer state, bufferOfs state) (definedLabels state)}+ state1 <- getInternalState+ setInternalState state1{definedLabels = Map.insert lab (buffer state1, bufferOfs state1, name) (definedLabels state1)} performFixup :: Ptr Word8 -> Int -> FixupEntry -> CodeGen e s ()-performFixup labBuf labOfs (FixupEntry{fueBuffer = buf, fueOfs = ofs, fueKind = kind}) =+performFixup labBuf labOfs (FixupEntry{fueBuffer = buf, fueOfs = ofs, fueKind = knd}) = do let diff = (labBuf `plusPtr` labOfs) `minusPtr` (buf `plusPtr` (ofs + 4))- liftIO $ case kind of+ liftIO $ case knd of Fixup8 -> pokeByteOff buf ofs (fromIntegral diff :: Word8) Fixup16 -> pokeByteOff buf ofs (fromIntegral diff :: Word16) Fixup32 -> pokeByteOff buf ofs (fromIntegral diff :: Word32)@@ -409,6 +460,11 @@ return () +-- | This operator gives neat syntax for defining labels. When @l@ is a label, the code+--+-- > l @@ mov eax ebx+--+-- associates the label l with the following @mov@ instruction. (@@) :: Label -> CodeGen e s a -> CodeGen e s a (@@) lab gen = do defineLabel lab gen@@ -419,40 +475,72 @@ -- be patched to target the address associated with this label when -- it is defined later. emitFixup :: Label -> Int -> FixupKind -> CodeGen e s ()-emitFixup (Label lab) ofs kind = +emitFixup (Label lab _) ofs knd = do state <- getInternalState let base = buffer state ptr = bufferOfs state case Map.lookup lab (definedLabels state) of- Just (labBuf, labOfs) -> performFixup labBuf labOfs (FixupEntry{fueBuffer = base,- fueOfs = ptr + ofs,- fueKind = kind})+ Just (labBuf, labOfs, _) -> performFixup labBuf labOfs (FixupEntry{fueBuffer = base,+ fueOfs = ptr + ofs,+ fueKind = knd}) Nothing -> setInternalState state{pendingFixups = Map.insertWith (++) lab [FixupEntry{fueBuffer = base, fueOfs = ptr + ofs,- fueKind = kind}]+ fueKind = knd}] (pendingFixups state)} -- | Return the address of a label, fail if the label is not yet defined. labelAddress :: Label -> CodeGen e s (Ptr a)-labelAddress (Label lab) = do+labelAddress (Label lab name) = do state <- getInternalState case Map.lookup lab (definedLabels state) of- Just (labBuf, labOfs) -> return $ plusPtr labBuf labOfs- Nothing -> fail $ "Label " ++ show lab ++ " not yet defined"+ Just (labBuf, labOfs, _) -> return $ plusPtr labBuf labOfs+ Nothing -> fail $ "Label " ++ show lab ++ "(" ++ name ++ ") not yet defined" --- | Disassemble all code buffers.+-- | Disassemble all code buffers. The result is a list of+-- disassembled instructions which can be converted to strings using+-- the 'Dis.showIntel' or 'Dis.showAtt' functions from module+-- "Harpy.X86Disassembler". disassemble :: CodeGen e s [Dis.Instruction] disassemble = do s <- getInternalState let buffers = bufferList s- r <- mapM (\ (buffer, length) -> do- r <- liftIO $ Dis.disassembleBlock buffer length+ r <- mapM (\ (buff, len) -> do+ r <- liftIO $ Dis.disassembleBlock buff len case r of Left err -> cgFail $ show err Right instr -> return instr ) $ buffers ++ [(buffer s, bufferOfs s)]- return $ concat r+ r' <- insertLabels (concat r)+ return r'+ where insertLabels :: [Dis.Instruction] -> CodeGen e s [Dis.Instruction]+ insertLabels = liftM concat . mapM ins+ ins :: Dis.Instruction -> CodeGen e s [Dis.Instruction]+ ins i@(Dis.BadInstruction{}) = return [i]+ ins i@(Dis.PseudoInstruction{}) = return [i]+ ins i@(Dis.Instruction{Dis.address = addr}) =+ do state <- getInternalState+ let labs = Map.toList (definedLabels state)+ lab = find (\ (_, (buf, ofs, _)) -> fromIntegral (ptrToWordPtr (buf `plusPtr` ofs)) == addr) labs+ case lab of+ Nothing -> return [i]+ Just (l, (buf, ofs, name)) -> return [Dis.PseudoInstruction addr+ (case name of+ "" ->+ "label " ++ show l ++ + " [" ++ + hex32 (fromIntegral (ptrToWordPtr (buf `plusPtr` ofs))) ++ + "]"+ _ -> name ++ ": [" ++ + hex32 (fromIntegral (ptrToWordPtr (buf `plusPtr` ofs))) ++ + "]"), + i]+ hex32 :: Int -> String+ hex32 i =+ let w :: Word32+ w = fromIntegral i+ s = showHex w ""+ in take (8 - length s) (repeat '0') ++ s #ifndef __HADDOCK__ @@ -460,7 +548,7 @@ callDecl ns qt = do t0 <- qt let (tvars, cxt, t) = case t0 of- ForallT vs c t -> (vs, c, t)+ ForallT vs c t' -> (vs, c, t') _ -> ([], [], t0) let name = mkName ns let funptr = AppT (ConT $ mkName "FunPtr") t
+ Harpy/X86Assembler.hs view
@@ -0,0 +1,3746 @@+--------------------------------------------------------------------------+-- |+-- 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 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+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++-- 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 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 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) 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 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 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 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) 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 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) 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) 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) 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 couter++loop :: Word8 -> CodeGen e s ()+loop w = ensureBufferSize x86_max_instruction_bytes >> x86_loop w++loope :: Word8 -> CodeGen e s ()+loope w = ensureBufferSize x86_max_instruction_bytes >> x86_loope w++loopne :: Word8 -> CodeGen e s ()+loopne w = ensureBufferSize x86_max_instruction_bytes >> x86_loopne w+++-- 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+ +-- 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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++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+++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+++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+++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+++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 False++instance Fild (Disp, Reg32) where + fild (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fild_membase r d False++instance Fild Ind where + fild (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fild_membase r 0 False+++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 False++instance Fist Ind where + fist (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fist_membase r 0 False+++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 False++instance Fistp (Disp, Reg32) where + fistp (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fist_pop_membase r d False++instance Fistp Ind where + fistp (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fist_pop_membase r 0 False+++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 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 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++
− Harpy/X86Assembler.lhs
@@ -1,2906 +0,0 @@--> ---------------------------------------------------------------------------> -- |-> -- Module : 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.-> -----------------------------------------------------------------------------This module provides simple assembler facilities.--> module Harpy.X86Assembler 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-> 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---- 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---int 3--> breakpoint = x86_breakpoint---clear direction flag--> cld = x86_cld---store string--> stosb = x86_stosb-> stosl = x86_stosl-> stosd = x86_stosd---move string--> movsb = x86_movsb-> movsl = x86_movsl-> movsd = x86_movsd---read time stamp counter--> rdtsc = 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) = x86_cmpxchg_reg_reg dest source->-> instance Cmpxchg Addr Reg32 where-> cmpxchg (Addr dest) (Reg32 source) = x86_cmpxchg_mem_reg dest source->-> instance Cmpxchg (Disp, Reg32) Reg32 where-> cmpxchg (Disp disp, Reg32 dest) (Reg32 source) = x86_cmpxchg_membase_reg dest disp source->-> instance Cmpxchg Ind Reg32 where-> cmpxchg (Ind (Reg32 dest)) (Reg32 source) = 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) = x86_xchg_reg_reg dest source 1->-> instance Xchg Reg32 Reg32 where-> xchg (Reg32 dest) (Reg32 source) = x86_xchg_reg_reg dest source 4->-> instance Xchg Addr Reg8 where-> xchg (Addr dest) (Reg8 source) = x86_xchg_mem_reg dest source 1->-> instance Xchg Addr Reg32 where-> xchg (Addr dest) (Reg32 source) = x86_xchg_mem_reg dest source 4->-> instance Xchg (Disp, Reg32) Reg8 where-> xchg (Disp disp, Reg32 dest) (Reg8 source) = x86_xchg_membase_reg dest disp source 1->-> instance Xchg Ind Reg8 where-> xchg (Ind (Reg32 dest)) (Reg8 source) = x86_xchg_membase_reg dest 0 source 1->-> instance Xchg (Disp, Reg32) Reg32 where-> xchg (Disp disp, Reg32 dest) (Reg32 source) = x86_xchg_membase_reg dest disp source 4->-> instance Xchg Ind Reg32 where-> xchg (Ind (Reg32 dest)) (Reg32 source) = 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) = x86_xadd_reg_reg dest source 1->-> instance Xadd Reg32 Reg32 where-> xadd (Reg32 dest) (Reg32 source) = x86_xadd_reg_reg dest source 4->-> instance Xadd Addr Reg8 where-> xadd (Addr dest) (Reg8 source) = x86_xadd_mem_reg dest source 1->-> instance Xadd Addr Reg32 where-> xadd (Addr dest) (Reg32 source) = x86_xadd_mem_reg dest source 4->-> instance Xadd (Disp, Reg32) Reg8 where-> xadd (Disp disp, Reg32 dest) (Reg8 source) = x86_xadd_membase_reg dest disp source 1->-> instance Xadd Ind Reg8 where-> xadd (Ind (Reg32 dest)) (Reg8 source) = x86_xadd_membase_reg dest 0 source 1->-> instance Xadd (Disp, Reg32) Reg32 where-> xadd (Disp disp, Reg32 dest) (Reg32 source) = x86_xadd_membase_reg dest disp source 4->-> instance Xadd Ind Reg32 where-> xadd (Ind (Reg32 dest)) (Reg32 source) = 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) = x86_inc_mem dest->-> instance Inc (Disp, Reg32) where-> inc (Disp disp, Reg32 dest) = x86_inc_membase dest disp->-> instance Inc Ind where-> inc (Ind (Reg32 dest)) = x86_inc_membase dest 0->-> instance Inc Reg32 where-> inc (Reg32 dest) = x86_inc_reg dest---Decrement by 1--> class Dec a where-> dec :: a -> CodeGen e s ()--> instance Dec Addr where-> dec (Addr dest) = x86_dec_mem dest->-> instance Dec (Disp, Reg32) where-> dec (Disp disp, Reg32 dest) = x86_dec_membase dest disp->-> instance Dec Ind where-> dec (Ind (Reg32 dest)) = x86_dec_membase dest 0->-> instance Dec Reg32 where-> dec (Reg32 dest) = x86_dec_reg dest---One's complement negation--> class Not a where-> not :: a -> CodeGen e s ()--> instance Not Addr where-> not (Addr dest) = x86_not_mem dest->-> instance Not (Disp, Reg32) where-> not (Disp disp, Reg32 dest) = x86_not_membase dest disp->-> instance Not Ind where-> not (Ind (Reg32 dest)) = x86_not_membase dest 0->-> instance Not Reg32 where-> not (Reg32 dest) = x86_not_reg dest---Two's complement negation--> class Neg a where-> neg :: a -> CodeGen e s ()--> instance Neg Addr where-> neg (Addr dest) = x86_neg_mem dest->-> instance Neg (Disp, Reg32) where-> neg (Disp disp, Reg32 dest) = x86_neg_membase dest disp->-> instance Neg Ind where-> neg (Ind (Reg32 dest)) = x86_neg_membase dest 0->-> instance Neg Reg32 where-> neg (Reg32 dest) = x86_neg_reg dest---No operation--> nop = 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 = x86_alu_reg_imm x86_add dest (fromIntegral imm)->-> instance Add Addr Word32 where-> add (Addr dest) imm = x86_alu_mem_imm x86_add dest (fromIntegral imm)->-> instance Add (Disp, Reg32) Word32 where-> add (Disp disp, Reg32 dest) imm = x86_alu_membase_imm x86_add dest disp (fromIntegral imm)->-> instance Add Ind Word32 where-> add (Ind (Reg32 dest)) imm = x86_alu_membase_imm x86_add dest 0 (fromIntegral imm)->-> instance Add (Disp, Reg32) Word8 where-> add (Disp disp, Reg32 dest) imm = x86_alu_membase8_imm x86_add dest disp (fromIntegral imm)->-> instance Add Ind Word8 where-> add (Ind (Reg32 dest)) imm = x86_alu_membase8_imm x86_add dest 0 (fromIntegral imm)->-> instance Add Addr Reg32 where-> add (Addr dest) (Reg32 source) = x86_alu_mem_reg x86_add dest source->-> instance Add (Disp, Reg32) Reg32 where-> add (Disp disp, Reg32 dest) (Reg32 source) = x86_alu_membase_reg x86_add dest disp source->-> instance Add Ind Reg32 where-> add (Ind (Reg32 dest)) (Reg32 source) = x86_alu_membase_reg x86_add dest 0 source->-> instance Add Reg32 Reg32 where-> add (Reg32 dest) (Reg32 source) = x86_alu_reg_reg x86_add dest source->-> instance Add Reg8 Reg8 where-> add (Reg8 dest) (Reg8 source) = x86_alu_reg8_reg8 x86_add dest source False False->-> instance Add Reg32 Addr where-> add (Reg32 dest) (Addr source) = x86_alu_reg_mem x86_add dest source->-> instance Add Reg32 (Disp, Reg32) where-> add (Reg32 dest) (Disp disp, Reg32 source) = x86_alu_reg_membase x86_add dest source disp->-> instance Add Reg32 Ind where-> add (Reg32 dest) (Ind (Reg32 source)) = 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 = x86_alu_reg_imm x86_or dest (fromIntegral imm)->-> instance Or Addr Word32 where-> or (Addr dest) imm = x86_alu_mem_imm x86_or dest (fromIntegral imm)->-> instance Or (Disp, Reg32) Word32 where-> or (Disp disp, Reg32 dest) imm = x86_alu_membase_imm x86_or dest disp (fromIntegral imm)->-> instance Or Ind Word32 where-> or (Ind (Reg32 dest)) imm = x86_alu_membase_imm x86_or dest 0 (fromIntegral imm)->-> instance Or (Disp, Reg32) Word8 where-> or (Disp disp, Reg32 dest) imm = x86_alu_membase8_imm x86_or dest disp (fromIntegral imm)->-> instance Or Ind Word8 where-> or (Ind (Reg32 dest)) imm = x86_alu_membase8_imm x86_or dest 0 (fromIntegral imm)->-> instance Or Addr Reg32 where-> or (Addr dest) (Reg32 source) = x86_alu_mem_reg x86_or dest source->-> instance Or (Disp, Reg32) Reg32 where-> or (Disp disp, Reg32 dest) (Reg32 source) = x86_alu_membase_reg x86_or dest disp source->-> instance Or Ind Reg32 where-> or (Ind (Reg32 dest)) (Reg32 source) = x86_alu_membase_reg x86_or dest 0 source->-> instance Or Reg32 Reg32 where-> or (Reg32 dest) (Reg32 source) = x86_alu_reg_reg x86_or dest source->-> instance Or Reg8 Reg8 where-> or (Reg8 dest) (Reg8 source) = x86_alu_reg8_reg8 x86_or dest source False False->-> instance Or Reg32 Addr where-> or (Reg32 dest) (Addr source) = x86_alu_reg_mem x86_or dest source->-> instance Or Reg32 (Disp, Reg32) where-> or (Reg32 dest) (Disp disp, Reg32 source) = x86_alu_reg_membase x86_or dest source disp->-> instance Or Reg32 Ind where-> or (Reg32 dest) (Ind (Reg32 source)) = 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 = x86_alu_reg_imm x86_adc dest (fromIntegral imm)->-> instance Adc Addr Word32 where-> adc (Addr dest) imm = x86_alu_mem_imm x86_adc dest (fromIntegral imm)->-> instance Adc (Disp, Reg32) Word32 where-> adc (Disp disp, Reg32 dest) imm = x86_alu_membase_imm x86_adc dest disp (fromIntegral imm)->-> instance Adc Ind Word32 where-> adc (Ind (Reg32 dest)) imm = x86_alu_membase_imm x86_adc dest 0 (fromIntegral imm)->-> instance Adc (Disp, Reg32) Word8 where-> adc (Disp disp, Reg32 dest) imm = x86_alu_membase8_imm x86_adc dest disp (fromIntegral imm)->-> instance Adc Ind Word8 where-> adc (Ind (Reg32 dest)) imm = x86_alu_membase8_imm x86_adc dest 0 (fromIntegral imm)->-> instance Adc Addr Reg32 where-> adc (Addr dest) (Reg32 source) = x86_alu_mem_reg x86_adc dest source->-> instance Adc (Disp, Reg32) Reg32 where-> adc (Disp disp, Reg32 dest) (Reg32 source) = x86_alu_membase_reg x86_adc dest disp source->-> instance Adc Ind Reg32 where-> adc (Ind (Reg32 dest)) (Reg32 source) = x86_alu_membase_reg x86_adc dest 0 source->-> instance Adc Reg32 Reg32 where-> adc (Reg32 dest) (Reg32 source) = x86_alu_reg_reg x86_adc dest source->-> instance Adc Reg8 Reg8 where-> adc (Reg8 dest) (Reg8 source) = x86_alu_reg8_reg8 x86_adc dest source False False->-> instance Adc Reg32 Addr where-> adc (Reg32 dest) (Addr source) = x86_alu_reg_mem x86_adc dest source->-> instance Adc Reg32 (Disp, Reg32) where-> adc (Reg32 dest) (Disp disp, Reg32 source) = x86_alu_reg_membase x86_adc dest source disp->-> instance Adc Reg32 Ind where-> adc (Reg32 dest) (Ind (Reg32 source)) = 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 = x86_alu_reg_imm x86_sbb dest (fromIntegral imm)->-> instance Sbb Addr Word32 where-> sbb (Addr dest) imm = x86_alu_mem_imm x86_sbb dest (fromIntegral imm)->-> instance Sbb (Disp, Reg32) Word32 where-> sbb (Disp disp, Reg32 dest) imm = x86_alu_membase_imm x86_sbb dest disp (fromIntegral imm)->-> instance Sbb Ind Word32 where-> sbb (Ind (Reg32 dest)) imm = x86_alu_membase_imm x86_sbb dest 0 (fromIntegral imm)->-> instance Sbb (Disp, Reg32) Word8 where-> sbb (Disp disp, Reg32 dest) imm = x86_alu_membase8_imm x86_sbb dest disp (fromIntegral imm)->-> instance Sbb Ind Word8 where-> sbb (Ind (Reg32 dest)) imm = x86_alu_membase8_imm x86_sbb dest 0 (fromIntegral imm)->-> instance Sbb Addr Reg32 where-> sbb (Addr dest) (Reg32 source) = x86_alu_mem_reg x86_sbb dest source->-> instance Sbb (Disp, Reg32) Reg32 where-> sbb (Disp disp, Reg32 dest) (Reg32 source) = x86_alu_membase_reg x86_sbb dest disp source->-> instance Sbb Ind Reg32 where-> sbb (Ind (Reg32 dest)) (Reg32 source) = x86_alu_membase_reg x86_sbb dest 0 source->-> instance Sbb Reg32 Reg32 where-> sbb (Reg32 dest) (Reg32 source) = x86_alu_reg_reg x86_sbb dest source->-> instance Sbb Reg8 Reg8 where-> sbb (Reg8 dest) (Reg8 source) = x86_alu_reg8_reg8 x86_sbb dest source False False->-> instance Sbb Reg32 Addr where-> sbb (Reg32 dest) (Addr source) = x86_alu_reg_mem x86_sbb dest source->-> instance Sbb Reg32 (Disp, Reg32) where-> sbb (Reg32 dest) (Disp disp, Reg32 source) = x86_alu_reg_membase x86_sbb dest source disp->-> instance Sbb Reg32 Ind where-> sbb (Reg32 dest) (Ind (Reg32 source)) = 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 = x86_alu_reg_imm x86_and dest (fromIntegral imm)->-> instance And Addr Word32 where-> and (Addr dest) imm = x86_alu_mem_imm x86_and dest (fromIntegral imm)->-> instance And (Disp, Reg32) Word32 where-> and (Disp disp, Reg32 dest) imm = x86_alu_membase_imm x86_and dest disp (fromIntegral imm)->-> instance And Ind Word32 where-> and (Ind (Reg32 dest)) imm = x86_alu_membase_imm x86_and dest 0 (fromIntegral imm)->-> instance And (Disp, Reg32) Word8 where-> and (Disp disp, Reg32 dest) imm = x86_alu_membase8_imm x86_and dest disp (fromIntegral imm)->-> instance And Ind Word8 where-> and (Ind (Reg32 dest)) imm = x86_alu_membase8_imm x86_and dest 0 (fromIntegral imm)->-> instance And Addr Reg32 where-> and (Addr dest) (Reg32 source) = x86_alu_mem_reg x86_and dest source->-> instance And (Disp, Reg32) Reg32 where-> and (Disp disp, Reg32 dest) (Reg32 source) = x86_alu_membase_reg x86_and dest disp source->-> instance And Ind Reg32 where-> and (Ind (Reg32 dest)) (Reg32 source) = x86_alu_membase_reg x86_and dest 0 source->-> instance And Reg32 Reg32 where-> and (Reg32 dest) (Reg32 source) = x86_alu_reg_reg x86_and dest source->-> instance And Reg8 Reg8 where-> and (Reg8 dest) (Reg8 source) = x86_alu_reg8_reg8 x86_and dest source False False->-> instance And Reg32 Addr where-> and (Reg32 dest) (Addr source) = x86_alu_reg_mem x86_and dest source->-> instance And Reg32 (Disp, Reg32) where-> and (Reg32 dest) (Disp disp, Reg32 source) = x86_alu_reg_membase x86_and dest source disp->-> instance And Reg32 Ind where-> and (Reg32 dest) (Ind (Reg32 source)) = 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 = x86_alu_reg_imm x86_sub dest (fromIntegral imm)->-> instance Sub Addr Word32 where-> sub (Addr dest) imm = x86_alu_mem_reg x86_sub dest (fromIntegral imm)->-> instance Sub (Disp, Reg32) Word32 where-> sub (Disp disp, Reg32 dest) imm = x86_alu_membase_imm x86_sub dest disp (fromIntegral imm)->-> instance Sub Ind Word32 where-> sub (Ind (Reg32 dest)) imm = x86_alu_membase_imm x86_sub dest 0 (fromIntegral imm)->-> instance Sub (Disp, Reg32) Word8 where-> sub (Disp disp, Reg32 dest) imm = x86_alu_membase8_imm x86_sub dest disp (fromIntegral imm)->-> instance Sub Ind Word8 where-> sub (Ind (Reg32 dest)) imm = x86_alu_membase8_imm x86_sub dest 0 (fromIntegral imm)->-> instance Sub Addr Reg32 where-> sub (Addr dest) (Reg32 source) = x86_alu_mem_reg x86_sub dest source->-> instance Sub (Disp, Reg32) Reg32 where-> sub (Disp disp, Reg32 dest) (Reg32 source) = x86_alu_membase_reg x86_sub dest disp source->-> instance Sub Ind Reg32 where-> sub (Ind (Reg32 dest)) (Reg32 source) = x86_alu_membase_reg x86_sub dest 0 source->-> instance Sub Reg32 Reg32 where-> sub (Reg32 dest) (Reg32 source) = x86_alu_reg_reg x86_sub dest source->-> instance Sub Reg8 Reg8 where-> sub (Reg8 dest) (Reg8 source) = x86_alu_reg8_reg8 x86_sub dest source False False->-> instance Sub Reg32 Addr where-> sub (Reg32 dest) (Addr source) = x86_alu_reg_mem x86_sub dest source->-> instance Sub Reg32 (Disp, Reg32) where-> sub (Reg32 dest) (Disp disp, Reg32 source) = x86_alu_reg_membase x86_sub dest source disp->-> instance Sub Reg32 Ind where-> sub (Reg32 dest) (Ind (Reg32 source)) = 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 = x86_alu_reg_imm x86_xor dest (fromIntegral imm)->-> instance Xor Addr Word32 where-> xor (Addr dest) imm = x86_alu_mem_imm x86_xor dest (fromIntegral imm)->-> instance Xor (Disp, Reg32) Word32 where-> xor (Disp disp, Reg32 dest) imm = x86_alu_membase_imm x86_xor dest disp (fromIntegral imm)->-> instance Xor Ind Word32 where-> xor (Ind (Reg32 dest)) imm = x86_alu_membase_imm x86_xor dest 0 (fromIntegral imm)->-> instance Xor (Disp, Reg32) Word8 where-> xor (Disp disp, Reg32 dest) imm = x86_alu_membase8_imm x86_xor dest disp (fromIntegral imm)->-> instance Xor Ind Word8 where-> xor (Ind (Reg32 dest)) imm = x86_alu_membase8_imm x86_xor dest 0 (fromIntegral imm)->-> instance Xor Addr Reg32 where-> xor (Addr dest) (Reg32 source) = x86_alu_mem_reg x86_xor dest source->-> instance Xor (Disp, Reg32) Reg32 where-> xor (Disp disp, Reg32 dest) (Reg32 source) = x86_alu_membase_reg x86_xor dest disp source->-> instance Xor Ind Reg32 where-> xor (Ind (Reg32 dest)) (Reg32 source) = x86_alu_membase_reg x86_xor dest 0 source->-> instance Xor Reg32 Reg32 where-> xor (Reg32 dest) (Reg32 source) = x86_alu_reg_reg x86_xor dest source->-> instance Xor Reg8 Reg8 where-> xor (Reg8 dest) (Reg8 source) = x86_alu_reg8_reg8 x86_xor dest source False False->-> instance Xor Reg32 Addr where-> xor (Reg32 dest) (Addr source) = x86_alu_reg_mem x86_xor dest source->-> instance Xor Reg32 (Disp, Reg32) where-> xor (Reg32 dest) (Disp disp, Reg32 source) = x86_alu_reg_membase x86_xor dest source disp->-> instance Xor Reg32 Ind where-> xor (Reg32 dest) (Ind (Reg32 source)) = 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 = x86_alu_reg_imm x86_cmp dest (fromIntegral imm)->-> instance Cmp Reg32 Label where-> cmp (Reg32 dest) lab = do-> x86_alu_reg_imm x86_cmp dest 0xf0f0f0f0-> emitFixup lab (-4) Fixup32Absolute->-> instance Cmp Addr Word32 where-> cmp (Addr dest) imm = x86_alu_mem_imm x86_cmp dest (fromIntegral imm)->-> instance Cmp Addr Label where-> cmp (Addr dest) lab = do-> x86_alu_mem_imm x86_cmp dest 0xf0f0f0f0-> emitFixup lab (-4) Fixup32Absolute->-> instance Cmp (Disp, Reg32) Word32 where-> cmp (Disp disp, Reg32 dest) imm = x86_alu_membase_imm x86_cmp dest disp (fromIntegral imm)->-> instance Cmp (Disp, Reg32) Label where-> cmp (Disp disp, Reg32 dest) lab = do-> x86_alu_membase_imm x86_cmp dest disp 0xf0f0f0f0-> emitFixup lab (-4) Fixup32Absolute->-> instance Cmp Ind Word32 where-> cmp (Ind (Reg32 dest)) imm = x86_alu_membase_imm x86_cmp dest 0 (fromIntegral imm)->-> instance Cmp Ind Label where-> cmp (Ind (Reg32 dest)) lab = do-> 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 = x86_alu_membase8_imm x86_cmp dest disp imm->-> instance Cmp Ind Word8 where-> cmp (Ind (Reg32 dest)) imm = x86_alu_membase8_imm x86_cmp dest 0 imm->-> instance Cmp Addr Reg32 where-> cmp (Addr dest) (Reg32 source) = x86_alu_mem_reg x86_cmp dest source->-> instance Cmp (Disp, Reg32) Reg32 where-> cmp (Disp disp, Reg32 dest) (Reg32 source) = x86_alu_membase_reg x86_cmp dest disp source->-> instance Cmp Ind Reg32 where-> cmp (Ind (Reg32 dest)) (Reg32 source) = x86_alu_membase_reg x86_cmp dest 0 source->-> instance Cmp Reg32 Reg32 where-> cmp (Reg32 dest) (Reg32 source) = x86_alu_reg_reg x86_cmp dest source->-> instance Cmp Reg8 Reg8 where-> cmp (Reg8 dest) (Reg8 source) = x86_alu_reg8_reg8 x86_cmp dest source False False->-> instance Cmp Reg32 Addr where-> cmp (Reg32 dest) (Addr source) = x86_alu_reg_mem x86_cmp dest source->-> instance Cmp Reg32 (Disp, Reg32) where-> cmp (Reg32 dest) (Disp disp, Reg32 source) = x86_alu_reg_membase x86_cmp dest source disp->-> instance Cmp Reg32 Ind where-> cmp (Reg32 dest) (Ind (Reg32 source)) = 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 = x86_test_reg_imm dest imm ->-> instance Test Addr Word32 where-> test (Addr dest) imm = x86_test_mem_imm dest imm ->-> instance Test (Disp, Reg32) Word32 where-> test (Disp disp, Reg32 dest) imm = x86_test_membase_imm dest disp imm ->-> instance Test Ind Word32 where-> test (Ind (Reg32 dest)) imm = x86_test_membase_imm dest 0 imm ->-> instance Test Reg32 Reg32 where-> test (Reg32 dest) (Reg32 source) = x86_test_reg_reg dest source ->-> instance Test Addr Reg32 where-> test (Addr dest) (Reg32 source) = x86_test_mem_reg dest source ->-> instance Test (Disp, Reg32) Reg32 where-> test (Disp disp, Reg32 dest) (Reg32 source) = x86_test_membase_reg dest disp source ->-> instance Test Ind Reg32 where-> test (Ind (Reg32 dest)) (Reg32 source) = 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 = x86_shift_reg_imm x86_rol dest imm ->-> instance Rol Addr Word8 where-> rol (Addr dest) imm = x86_shift_mem_imm x86_rol dest imm ->-> instance Rol (Disp, Reg32) Word8 where-> rol (Disp disp, Reg32 dest) imm = x86_shift_membase_imm x86_rol dest disp imm ->-> instance Rol Ind Word8 where-> rol (Ind (Reg32 dest)) imm = x86_shift_membase_imm x86_rol dest 0 imm ->-> instance Rol Reg32 Reg8 where-> rol (Reg32 dest) (Reg8 1) = x86_shift_reg x86_rol dest-> rol _ _ = onlyCl->-> instance Rol Addr Reg8 where-> rol (Addr dest) (Reg8 1) = x86_shift_mem x86_rol dest-> rol _ _ = onlyCl->-> instance Rol (Disp, Reg32) Reg8 where-> rol (Disp disp, Reg32 dest) (Reg8 1) = x86_shift_membase x86_rol dest disp->-> instance Rol Ind Reg8 where-> rol (Ind (Reg32 dest)) (Reg8 1) = 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 = x86_shift_reg_imm x86_ror dest imm ->-> instance Ror Addr Word8 where-> ror (Addr dest) imm = x86_shift_mem_imm x86_ror dest imm ->-> instance Ror (Disp, Reg32) Word8 where-> ror (Disp disp, Reg32 dest) imm = x86_shift_membase_imm x86_ror dest disp imm ->-> instance Ror Ind Word8 where-> ror (Ind (Reg32 dest)) imm = x86_shift_membase_imm x86_ror dest 0 imm ->-> instance Ror Reg32 Reg8 where-> ror (Reg32 dest) (Reg8 1) = x86_shift_reg x86_ror dest-> ror _ _ = onlyCl->-> instance Ror Addr Reg8 where-> ror (Addr dest) (Reg8 1) = x86_shift_mem x86_ror dest-> ror _ _ = onlyCl->-> instance Ror (Disp, Reg32) Reg8 where-> ror (Disp disp, Reg32 dest) (Reg8 1) = x86_shift_membase x86_ror dest disp->-> instance Ror Ind Reg8 where-> ror (Ind (Reg32 dest)) (Reg8 1) = 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 = x86_shift_reg_imm x86_rcl dest imm ->-> instance Rcl Addr Word8 where-> rcl (Addr dest) imm = x86_shift_mem_imm x86_rcl dest imm ->-> instance Rcl (Disp, Reg32) Word8 where-> rcl (Disp disp, Reg32 dest) imm = x86_shift_membase_imm x86_rcl dest disp imm ->-> instance Rcl Ind Word8 where-> rcl (Ind (Reg32 dest)) imm = x86_shift_membase_imm x86_rcl dest 0 imm ->-> instance Rcl Reg32 Reg8 where-> rcl (Reg32 dest) (Reg8 1) = x86_shift_reg x86_rcl dest-> rcl _ _ = onlyCl->-> instance Rcl Addr Reg8 where-> rcl (Addr dest) (Reg8 1) = x86_shift_mem x86_rcl dest-> rcl _ _ = onlyCl->-> instance Rcl (Disp, Reg32) Reg8 where-> rcl (Disp disp, Reg32 dest) (Reg8 1) = x86_shift_membase x86_rcl dest disp->-> instance Rcl Ind Reg8 where-> rcl (Ind (Reg32 dest)) (Reg8 1) = 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 = x86_shift_reg_imm x86_rcr dest imm ->-> instance Rcr Addr Word8 where-> rcr (Addr dest) imm = x86_shift_mem_imm x86_rcr dest imm ->-> instance Rcr (Disp, Reg32) Word8 where-> rcr (Disp disp, Reg32 dest) imm = x86_shift_membase_imm x86_rcr dest disp imm ->-> instance Rcr Ind Word8 where-> rcr (Ind (Reg32 dest)) imm = x86_shift_membase_imm x86_rcr dest 0 imm ->-> instance Rcr Reg32 Reg8 where-> rcr (Reg32 dest) (Reg8 1) = x86_shift_reg x86_rcr dest-> rcr _ _ = onlyCl->-> instance Rcr Addr Reg8 where-> rcr (Addr dest) (Reg8 1) = x86_shift_mem x86_rcr dest-> rcr _ _ = onlyCl->-> instance Rcr (Disp, Reg32) Reg8 where-> rcr (Disp disp, Reg32 dest) (Reg8 1) = x86_shift_membase x86_rcr dest disp->-> instance Rcr Ind Reg8 where-> rcr (Ind (Reg32 dest)) (Reg8 1) = 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 = x86_shift_reg_imm x86_shl dest imm ->-> instance Shl Addr Word8 where-> shl (Addr dest) imm = x86_shift_mem_imm x86_shl dest imm ->-> instance Shl (Disp, Reg32) Word8 where-> shl (Disp disp, Reg32 dest) imm = x86_shift_membase_imm x86_shl dest disp imm ->-> instance Shl Ind Word8 where-> shl (Ind (Reg32 dest)) imm = x86_shift_membase_imm x86_shl dest 0 imm ->-> instance Shl Reg32 Reg8 where-> shl (Reg32 dest) (Reg8 1) = x86_shift_reg x86_shl dest-> shl _ _ = onlyCl->-> instance Shl Addr Reg8 where-> shl (Addr dest) (Reg8 1) = x86_shift_mem x86_shl dest-> shl _ _ = onlyCl->-> instance Shl (Disp, Reg32) Reg8 where-> shl (Disp disp, Reg32 dest) (Reg8 1) = x86_shift_membase x86_shl dest disp->-> instance Shl Ind Reg8 where-> shl (Ind (Reg32 dest)) (Reg8 1) = 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 = x86_shift_reg_imm x86_shr dest imm ->-> instance Shr Addr Word8 where-> shr (Addr dest) imm = x86_shift_mem_imm x86_shr dest imm ->-> instance Shr (Disp, Reg32) Word8 where-> shr (Disp disp, Reg32 dest) imm = x86_shift_membase_imm x86_shr dest disp imm ->-> instance Shr Ind Word8 where-> shr (Ind (Reg32 dest)) imm = x86_shift_membase_imm x86_shr dest 0 imm ->-> instance Shr Reg32 Reg8 where-> shr (Reg32 dest) (Reg8 1) = x86_shift_reg x86_shr dest-> shr _ _ = onlyCl->-> instance Shr Addr Reg8 where-> shr (Addr dest) (Reg8 1) = x86_shift_mem x86_shr dest-> shr _ _ = onlyCl->-> instance Shr (Disp, Reg32) Reg8 where-> shr (Disp disp, Reg32 dest) (Reg8 1) = x86_shift_membase x86_shr dest disp->-> instance Shr Ind Reg8 where-> shr (Ind (Reg32 dest)) (Reg8 1) = 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 = x86_shift_reg_imm x86_sar dest imm ->-> instance Sar Addr Word8 where-> sar (Addr dest) imm = x86_shift_mem_imm x86_sar dest imm ->-> instance Sar (Disp, Reg32) Word8 where-> sar (Disp disp, Reg32 dest) imm = x86_shift_membase_imm x86_sar dest disp imm ->-> instance Sar Ind Word8 where-> sar (Ind (Reg32 dest)) imm = x86_shift_membase_imm x86_sar dest 0 imm ->-> instance Sar Reg32 Reg8 where-> sar (Reg32 dest) (Reg8 1) = x86_shift_reg x86_sar dest-> sar _ _ = onlyCl->-> instance Sar Addr Reg8 where-> sar (Addr dest) (Reg8 1) = x86_shift_mem x86_sar dest-> sar _ _ = onlyCl->-> instance Sar (Disp, Reg32) Reg8 where-> sar (Disp disp, Reg32 dest) (Reg8 1) = x86_shift_membase x86_sar dest disp->-> instance Sar Ind Reg8 where-> sar (Ind (Reg32 dest)) (Reg8 1) = 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 = x86_shift_reg_imm x86_shl dest imm ->-> instance Sal Addr Word8 where-> sal (Addr dest) imm = x86_shift_mem_imm x86_shl dest imm ->-> instance Sal (Disp, Reg32) Word8 where-> sal (Disp disp, Reg32 dest) imm = x86_shift_membase_imm x86_shl dest disp imm ->-> instance Sal Ind Word8 where-> sal (Ind (Reg32 dest)) imm = x86_shift_membase_imm x86_shl dest 0 imm ->-> instance Sal Reg32 Reg8 where-> sal (Reg32 dest) (Reg8 1) = x86_shift_reg x86_shl dest-> sal _ _ = onlyCl->-> instance Sal Addr Reg8 where-> sal (Addr dest) (Reg8 1) = x86_shift_mem x86_shl dest-> sal _ _ = onlyCl->-> instance Sal (Disp, Reg32) Reg8 where-> sal (Disp disp, Reg32 dest) (Reg8 1) = x86_shift_membase x86_shl dest disp->-> instance Sal Ind Reg8 where-> sal (Ind (Reg32 dest)) (Reg8 1) = 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) = x86_shrd_reg dest source-> shrd _ _ _ = onlyCl->-> instance Shrd Reg32 Reg32 Word8 where-> shrd (Reg32 dest) (Reg32 source) imm = 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) = x86_shld_reg dest source-> shld _ _ _ = onlyCl->-> instance Shld Reg32 Reg32 Word8 where-> shld (Reg32 dest) (Reg32 source) imm = 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) = x86_mul_reg arg False->-> instance Mul Addr where-> mul (Addr arg) = x86_mul_mem arg False->-> instance Mul (Disp, Reg32) where-> mul (Disp disp, Reg32 arg) = x86_mul_membase arg disp False->-> instance Mul Ind where-> mul (Ind (Reg32 arg)) = 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) = x86_imul_reg_reg dest source->-> instance Imul InPlace Reg32 Addr where-> imul _ (Reg32 dest) (Addr source) = x86_imul_reg_mem dest source->-> instance Imul InPlace Reg32 (Disp, Reg32) where-> imul _ (Reg32 dest) (Disp disp, Reg32 source) = x86_imul_reg_membase dest source disp->-> instance Imul InPlace Reg32 Ind where-> imul _ (Reg32 dest) (Ind (Reg32 source)) = x86_imul_reg_membase dest source 0->-> instance Imul Reg32 Reg32 Word32 where-> imul (Reg32 dest) (Reg32 source) imm = x86_imul_reg_reg_imm dest source imm ->-> instance Imul Reg32 Addr Word32 where-> imul (Reg32 dest) (Addr source) imm = x86_imul_reg_mem_imm dest source imm ->-> instance Imul Reg32 (Disp, Reg32) Word32 where-> imul (Reg32 dest) (Disp disp, Reg32 source) imm = x86_imul_reg_membase_imm dest source disp imm ->-> instance Imul Reg32 Ind Word32 where-> imul (Reg32 dest) (Ind (Reg32 source)) imm = 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) = x86_div_reg arg False->-> instance Div Addr where-> div (Addr arg) = x86_div_mem arg False->-> instance Div (Disp, Reg32) where-> div (Disp disp, Reg32 arg) = x86_div_membase arg disp False->-> instance Div Ind where-> div (Ind (Reg32 arg)) = x86_div_membase arg 0 False---signed divide--> class Idiv a where-> idiv :: a -> CodeGen e s ()--> instance Idiv Reg32 where-> idiv (Reg32 arg) = x86_div_reg arg True->-> instance Idiv Addr where-> idiv (Addr arg) = x86_div_mem arg True->-> instance Idiv (Disp, Reg32) where-> idiv (Disp disp, Reg32 arg) = x86_div_membase arg disp True->-> instance Idiv Ind where-> idiv (Ind (Reg32 arg)) = 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) = x86_mov_reg_reg dest source 1->-> instance Mov Reg16 Reg16 where-> mov (Reg16 dest) (Reg16 source) = x86_mov_reg_reg dest source 2->-> instance Mov Reg32 Reg32 where-> mov (Reg32 dest) (Reg32 source) = x86_mov_reg_reg dest source 4---> instance Mov Reg32 Word32 where-> mov (Reg32 dest) imm = x86_mov_reg_imm dest (fromIntegral imm)--> instance Mov Reg32 Label where-> mov (Reg32 dest) lab = do x86_mov_reg_imm dest 0-> emitFixup lab (-4) Fixup32Absolute--> instance Mov Addr Word8 where-> mov (Addr dest) imm = x86_mov_mem_imm dest (fromIntegral imm) 1->-> instance Mov Addr Word16 where-> mov (Addr dest) imm = x86_mov_mem_imm dest (fromIntegral imm) 2->-> instance Mov Addr Word32 where-> mov (Addr dest) imm = x86_mov_mem_imm dest imm 4--> instance Mov Addr Label where-> mov (Addr dest) lab = do x86_mov_mem_imm dest 0 4-> emitFixup lab (-4) Fixup32Absolute--> instance Mov (Disp, Reg32) Word8 where-> mov (Disp disp, Reg32 dest) imm = x86_mov_membase_imm dest disp (fromIntegral imm) 1->-> instance Mov Ind Word8 where-> mov (Ind (Reg32 dest)) imm = x86_mov_membase_imm dest 0 (fromIntegral imm) 1->-> instance Mov (Disp, Reg32) Word16 where-> mov (Disp disp, Reg32 dest) imm = x86_mov_membase_imm dest disp (fromIntegral imm) 2->-> instance Mov Ind Word16 where-> mov (Ind (Reg32 dest)) imm = x86_mov_membase_imm dest 0 (fromIntegral imm) 2->-> instance Mov (Disp, Reg32) Word32 where-> mov (Disp disp, Reg32 dest) imm = x86_mov_membase_imm dest disp imm 4->-> instance Mov (Disp, Reg32) Label where-> mov (Disp disp, Reg32 dest) lab = do x86_mov_membase_imm dest disp 0 4-> emitFixup lab (-4) Fixup32Absolute--> instance Mov Ind Word32 where-> mov (Ind (Reg32 dest)) imm = x86_mov_membase_imm dest 0 imm 4--> instance Mov Ind Label where-> mov (Ind (Reg32 dest)) lab = do 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 = 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 = 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 = x86_mov_memindex_imm base 0 index (scaleToShift scale) imm 4--> instance Mov (Reg32, Reg32, Scale) Label where-> mov (Reg32 base, Reg32 index, scale) lab = do 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 = 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 = 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 = x86_mov_memindex_imm x86_nobasereg disp index (scaleToShift scale) imm 4--> instance Mov (Disp, Reg32, Scale) Label where-> mov (Disp disp, Reg32 index, scale) lab = do 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 = 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 = 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 = x86_mov_memindex_imm 5 disp index (scaleToShift scale) imm 4-> mov _ _ = onlyEbp--> instance Mov (Disp, Reg32, Reg32, Scale) Label where-> mov (Disp disp, Reg32 5, Reg32 index, scale) lab = do 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) = x86_mov_mem_reg a source 1->-> instance Mov Addr Reg16 where-> mov (Addr a) (Reg16 source) = x86_mov_mem_reg a source 2->-> instance Mov Addr Reg32 where-> mov (Addr a) (Reg32 source) = x86_mov_mem_reg a source 4->-> instance Mov Reg8 Addr where-> mov (Reg8 dest) (Addr a) = x86_mov_reg_mem dest a 1->-> instance Mov Reg16 Addr where-> mov (Reg16 dest) (Addr a) = x86_mov_reg_mem dest a 2->-> instance Mov Reg32 Addr where-> mov (Reg32 dest) (Addr a) = x86_mov_reg_mem dest a 4---> instance Mov Ind Reg8 where-> mov (Ind (Reg32 dest)) (Reg8 source) = x86_mov_regp_reg dest source 1->-> instance Mov Ind Reg16 where-> mov (Ind (Reg32 dest)) (Reg16 source) = x86_mov_regp_reg dest source 2->-> instance Mov Ind Reg32 where-> mov (Ind (Reg32 dest)) (Reg32 source) = x86_mov_regp_reg dest source 4--> instance Mov Reg8 Ind where-> mov (Reg8 dest) (Ind (Reg32 source)) = x86_mov_reg_regp dest source 1->-> instance Mov Reg16 Ind where-> mov (Reg16 dest) (Ind (Reg32 source)) = x86_mov_reg_regp dest source 2->-> instance Mov Reg32 Ind where-> mov (Reg32 dest) (Ind (Reg32 source)) = x86_mov_reg_regp dest source 4---> instance Mov (Disp, Reg32) Reg8 where-> mov (Disp disp, Reg32 dest) (Reg8 source) = x86_mov_membase_reg dest disp source 1->-> instance Mov (Disp, Reg32) Reg16 where-> mov (Disp disp, Reg32 dest) (Reg16 source) = x86_mov_membase_reg dest disp source 2->-> instance Mov (Disp, Reg32) Reg32 where-> mov (Disp disp, Reg32 dest) (Reg32 source) = x86_mov_membase_reg dest disp source 4->-> instance Mov Reg8 (Disp, Reg32) where-> mov (Reg8 dest) (Disp disp, Reg32 source) = x86_mov_reg_membase dest source disp 1->-> instance Mov Reg16 (Disp, Reg32) where-> mov (Reg16 dest) (Disp disp, Reg32 source) = x86_mov_reg_membase dest source disp 2->-> instance Mov Reg32 (Disp, Reg32) where-> mov (Reg32 dest) (Disp disp, Reg32 source) = x86_mov_reg_membase dest source disp 4---> instance Mov (Reg32, Reg32, Scale) Reg8 where-> mov (Reg32 base, Reg32 index, s) (Reg8 source) = 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) = 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) = 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) = 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) = 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) = 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) = 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) = 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) = 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) = 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) = 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) = 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) = 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) = 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) = 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) = 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) = 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) = 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) = x86_widen_reg dest source True False->-> instance Movsxb Reg32 Addr where-> movsxb (Reg32 dest) (Addr source) = x86_widen_mem dest source True False->-> instance Movsxb Reg32 (Disp, Reg32) where-> movsxb (Reg32 dest) (Disp disp, Reg32 source) = x86_widen_membase dest source disp True False->-> instance Movsxb Reg32 Ind where-> movsxb (Reg32 dest) (Ind (Reg32 source)) = 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) = 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) = 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) = 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) = x86_widen_reg dest source True True->-> instance Movsxw Reg32 Addr where-> movsxw (Reg32 dest) (Addr source) = x86_widen_mem dest source True True->-> instance Movsxw Reg32 (Disp, Reg32) where-> movsxw (Reg32 dest) (Disp disp, Reg32 source) = x86_widen_membase dest source disp True True->-> instance Movsxw Reg32 Ind where-> movsxw (Reg32 dest) (Ind (Reg32 source)) = 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) = 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) = 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) = 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) = x86_widen_reg dest source False False->-> instance Movzxb Reg32 Addr where-> movzxb (Reg32 dest) (Addr source) = x86_widen_mem dest source False False->-> instance Movzxb Reg32 (Disp, Reg32) where-> movzxb (Reg32 dest) (Disp disp, Reg32 source) = x86_widen_membase dest source disp False False->-> instance Movzxb Reg32 Ind where-> movzxb (Reg32 dest) (Ind (Reg32 source)) = 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) = 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) = 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) = 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) = x86_widen_reg dest source False True->-> instance Movzxw Reg32 Addr where-> movzxw (Reg32 dest) (Addr source) = x86_widen_mem dest source False True->-> instance Movzxw Reg32 (Disp, Reg32) where-> movzxw (Reg32 dest) (Disp disp, Reg32 source) = x86_widen_membase dest source disp False True->-> instance Movzxw Reg32 Ind where-> movzxw (Reg32 dest) (Ind (Reg32 source)) = 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) = 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) = 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) = 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) = x86_lea_mem dest source ->-> instance Lea Reg32 (Disp, Reg32) where-> lea (Reg32 dest) (Disp disp, Reg32 source) = x86_lea_membase dest source disp ->-> instance Lea Reg32 Ind where-> lea (Reg32 dest) (Ind (Reg32 source)) = x86_lea_membase dest source 0 ->-> instance Lea Reg32 (Disp, Reg32, Reg32, Scale) where-> lea (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = 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) = 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) = x86_lea_memindex dest base 0 index (scaleToShift s)---convert word to doubleword--> cdq = x86_cdq---wait for FPU--> wait = x86_wait---push to stack--> class Push a where-> push :: a -> CodeGen e s ()--> instance Push Reg32 where-> push (Reg32 source) = x86_push_reg source ->-> instance Push Ind where-> push (Ind (Reg32 source)) = x86_push_regp source->-> instance Push Addr where-> push (Addr source) = x86_push_mem source ->-> instance Push (Disp, Reg32) where-> push (Disp disp, Reg32 source) = x86_push_membase source disp ->-> instance Push Word32 where-> push imm = x86_push_imm imm ->-> instance Push Label where-> push l = do x86_push_imm_template-> emitFixup l (-4) Fixup32Absolute->-> instance Push (Disp, Reg32, Reg32, Scale) where-> push (Disp disp, Reg32 5, Reg32 index, s) = x86_push_memindex 5 disp index (scaleToShift s)-> push _ = onlyEbp->-> instance Push (Disp, Reg32, Scale) where-> push (Disp disp, Reg32 index, s) = x86_push_memindex x86_nobasereg disp index (scaleToShift s)->-> instance Push (Reg32, Reg32, Scale) where-> push (Reg32 base, Reg32 index, s) = 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) = x86_pop_reg dest ->-> instance Pop Addr where-> pop (Addr dest) = x86_pop_mem dest ->-> instance Pop (Disp, Reg32) where-> pop (Disp disp, Reg32 dest) = x86_pop_membase dest disp ->-> instance Pop Ind where-> pop (Ind (Reg32 dest)) = x86_pop_membase dest 0 ---push/pop general purpose registers--> pushad = x86_pushad-> popad = x86_popad---push/pop EFLAGS--> pushfd = x86_pushfd-> popfd = x86_popfd---loop according to ECX couter--> loop :: Word8 -> CodeGen e s ()-> loop = x86_loop--> loope :: Word8 -> CodeGen e s ()-> loope = x86_loope--> loopne :: Word8 -> CodeGen e s ()-> loopne = x86_loopne---jump--> class Jmp a where-> jmp :: a -> CodeGen e s ()--> instance Jmp Word8 where-> jmp imm = x86_jump8 imm ->-> instance Jmp Word32 where-> jmp imm = x86_jump32 imm ->-> instance Jmp Reg32 where-> jmp (Reg32 dest) = x86_jump_reg dest ->-> instance Jmp Addr where-> jmp (Addr dest) = x86_jump_mem dest ->-> instance Jmp (Disp, Reg32) where-> jmp (Disp disp, Reg32 dest) = x86_jump_membase dest disp ->-> instance Jmp Ind where-> jmp (Ind (Reg32 dest)) = x86_jump_membase dest 0 ->-> instance Jmp Label where-> jmp l = do x86_jump32 0-> emitFixup l (-4) Fixup32- -jump on condition code (branch)--> class Ja a where-> ja :: a -> CodeGen e s ()--> instance Ja Word8 where-> ja imm = x86_branch8 x86_cc_a imm False->-> instance Ja Word32 where-> ja imm = x86_branch32 x86_cc_a imm False--> class Jae a where-> jae :: a -> CodeGen e s ()--> instance Jae Word8 where-> jae imm = x86_branch8 x86_cc_ae imm False->-> instance Jae Word32 where-> jae imm = x86_branch32 x86_cc_ae imm False-> -> instance Jae Label where-> jae l = do 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 = x86_branch8 x86_cc_b imm False->-> instance Jb Word32 where-> jb imm = x86_branch32 x86_cc_b imm False-> -> instance Jb Label where-> jb l = do 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 = x86_branch8 x86_cc_be imm False->-> instance Jbe Word32 where-> jbe imm = x86_branch32 x86_cc_be imm False-> -> instance Jbe Label where-> jbe l = do 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 = x86_branch8 x86_cc_c imm False->-> instance Jc Word32 where-> jc imm = x86_branch32 x86_cc_c imm False-> -> instance Jc Label where-> jc l = do 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 = x86_branch8 x86_cc_e imm False->-> instance Je Word32 where-> je imm = x86_branch32 x86_cc_e imm False-> -> instance Je Label where-> je l = do 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 = x86_branch8 x86_cc_na imm False->-> instance Jna Word32 where-> jna imm = x86_branch32 x86_cc_na imm False-> -> instance Jna Label where-> jna l = do 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 = x86_branch8 x86_cc_nae imm False->-> instance Jnae Word32 where-> jnae imm = x86_branch32 x86_cc_nae imm False-> -> instance Jnae Label where-> jnae l = do 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 = x86_branch8 x86_cc_nb imm False->-> instance Jnb Word32 where-> jnb imm = x86_branch32 x86_cc_nb imm False-> -> instance Jnb Label where-> jnb l = do 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 = x86_branch8 x86_cc_nbe imm False->-> instance Jnbe Word32 where-> jnbe imm = x86_branch32 x86_cc_nbe imm False-> -> instance Jnbe Label where-> jnbe l = do 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 = x86_branch8 x86_cc_nc imm False->-> instance Jnc Word32 where-> jnc imm = x86_branch32 x86_cc_nc imm False-> -> instance Jnc Label where-> jnc l = do 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 = x86_branch8 x86_cc_ne imm False->-> instance Jne Word32 where-> jne imm = x86_branch32 x86_cc_ne imm False-> -> instance Jne Label where-> jne l = do 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 = x86_branch8 x86_cc_np imm False->-> instance Jnp Word32 where-> jnp imm = x86_branch32 x86_cc_np imm False-> -> instance Jnp Label where-> jnp l = do 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 = x86_branch8 x86_cc_nz imm False->-> instance Jnz Word32 where-> jnz imm = x86_branch32 x86_cc_nz imm False-> -> instance Jnz Label where-> jnz l = do 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 = x86_branch8 x86_cc_p imm False->-> instance Jp Word32 where-> jp imm = x86_branch32 x86_cc_p imm False-> -> instance Jp Label where-> jp l = do 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 = x86_branch8 x86_cc_pe imm False->-> instance Jpe Word32 where-> jpe imm = x86_branch32 x86_cc_pe imm False-> -> instance Jpe Label where-> jpe l = do 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 = x86_branch8 x86_cc_po imm False->-> instance Jpo Word32 where-> jpo imm = x86_branch32 x86_cc_po imm False-> -> instance Jpo Label where-> jpo l = do 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 = x86_branch8 x86_cc_z imm False->-> instance Jz Word32 where-> jz imm = x86_branch32 x86_cc_z imm False-> -> instance Jz Label where-> jz l = do 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 = x86_branch8 x86_cc_gt imm True->-> instance Jg Word32 where-> jg imm = x86_branch32 x86_cc_gt imm True-> -> instance Jg Label where-> jg l = do 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 = x86_branch8 x86_cc_ge imm True->-> instance Jge Word32 where-> jge imm = x86_branch32 x86_cc_ge imm True-> -> instance Jge Label where-> jge l = do 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 = x86_branch8 x86_cc_lt imm True->-> instance Jl Word32 where-> jl imm = x86_branch32 x86_cc_lt imm True-> -> instance Jl Label where-> jl l = do 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 = x86_branch8 x86_cc_le imm True->-> instance Jle Word32 where-> jle imm = x86_branch32 x86_cc_le imm True-> -> instance Jle Label where-> jle l = do 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 = x86_branch8 x86_cc_le imm True->-> instance Jng Word32 where-> jng imm = x86_branch32 x86_cc_le imm True-> -> instance Jng Label where-> jng l = do 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 = x86_branch8 x86_cc_lt imm True->-> instance Jnge Word32 where-> jnge imm = x86_branch32 x86_cc_lt imm True-> -> instance Jnge Label where-> jnge l = do 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 = x86_branch8 x86_cc_ge imm True->-> instance Jnl Word32 where-> jnl imm = x86_branch32 x86_cc_ge imm True-> -> instance Jnl Label where-> jnl l = do 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 = x86_branch8 x86_cc_gt imm True->-> instance Jnle Word32 where-> jnle imm = x86_branch32 x86_cc_gt imm True-> -> instance Jnle Label where-> jnle l = do 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 = x86_branch8 x86_cc_no imm True->-> instance Jno Word32 where-> jno imm = x86_branch32 x86_cc_no imm True-> -> instance Jno Label where-> jno l = do 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 = x86_branch8 x86_cc_ns imm True->-> instance Jns Word32 where-> jns imm = x86_branch32 x86_cc_ns imm True-> -> instance Jns Label where-> jns l = do 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 = x86_branch8 x86_cc_o imm True->-> instance Jo Word32 where-> jo imm = x86_branch32 x86_cc_o imm True-> -> instance Jo Label where-> jo l = do 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 = x86_branch8 x86_cc_s imm True->-> instance Js Word32 where-> js imm = x86_branch32 x86_cc_s imm True-> -> instance Js Label where-> js l = do x86_branch32 x86_cc_s 0 True-> emitFixup l (-4) Fixup32--jump if ecx register is 0--> jecxz :: Word8 -> CodeGen e s ()-> jecxz = x86_jecxz---set byte on condition code--> class Seta a where-> seta :: a -> CodeGen e s ()--> instance Seta Reg8 where-> seta (Reg8 dest) = x86_set_reg x86_cc_a dest False->-> instance Seta Addr where-> seta (Addr dest) = x86_set_mem x86_cc_a dest False->-> instance Seta (Disp, Reg32) where-> seta (Disp disp, Reg32 dest) = x86_set_membase x86_cc_a dest disp False->-> instance Seta Ind where-> seta (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_ae dest False->-> instance Setae Addr where-> setae (Addr dest) = x86_set_mem x86_cc_ae dest False->-> instance Setae (Disp, Reg32) where-> setae (Disp disp, Reg32 dest) = x86_set_membase x86_cc_ae dest disp False->-> instance Setae Ind where-> setae (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_b dest False->-> instance Setb Addr where-> setb (Addr dest) = x86_set_mem x86_cc_b dest False->-> instance Setb (Disp, Reg32) where-> setb (Disp disp, Reg32 dest) = x86_set_membase x86_cc_b dest disp False->-> instance Setb Ind where-> setb (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_be dest False->-> instance Setbe Addr where-> setbe (Addr dest) = x86_set_mem x86_cc_be dest False->-> instance Setbe (Disp, Reg32) where-> setbe (Disp disp, Reg32 dest) = x86_set_membase x86_cc_be dest disp False->-> instance Setbe Ind where-> setbe (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_c dest False->-> instance Setc Addr where-> setc (Addr dest) = x86_set_mem x86_cc_c dest False->-> instance Setc (Disp, Reg32) where-> setc (Disp disp, Reg32 dest) = x86_set_membase x86_cc_c dest disp False->-> instance Setc Ind where-> setc (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_e dest False->-> instance Sete Addr where-> sete (Addr dest) = x86_set_mem x86_cc_e dest False->-> instance Sete (Disp, Reg32) where-> sete (Disp disp, Reg32 dest) = x86_set_membase x86_cc_e dest disp False->-> instance Sete Ind where-> sete (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_na dest False->-> instance Setna Addr where-> setna (Addr dest) = x86_set_mem x86_cc_na dest False->-> instance Setna (Disp, Reg32) where-> setna (Disp disp, Reg32 dest) = x86_set_membase x86_cc_na dest disp False->-> instance Setna Ind where-> setna (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_nae dest False->-> instance Setnae Addr where-> setnae (Addr dest) = x86_set_mem x86_cc_nae dest False->-> instance Setnae (Disp, Reg32) where-> setnae (Disp disp, Reg32 dest) = x86_set_membase x86_cc_nae dest disp False->-> instance Setnae Ind where-> setnae (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_nb dest False->-> instance Setnb Addr where-> setnb (Addr dest) = x86_set_mem x86_cc_nb dest False->-> instance Setnb (Disp, Reg32) where-> setnb (Disp disp, Reg32 dest) = x86_set_membase x86_cc_nb dest disp False->-> instance Setnb Ind where-> setnb (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_nbe dest False->-> instance Setnbe Addr where-> setnbe (Addr dest) = x86_set_mem x86_cc_nbe dest False->-> instance Setnbe (Disp, Reg32) where-> setnbe (Disp disp, Reg32 dest) = x86_set_membase x86_cc_nbe dest disp False->-> instance Setnbe Ind where-> setnbe (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_nc dest False->-> instance Setnc Addr where-> setnc (Addr dest) = x86_set_mem x86_cc_nc dest False->-> instance Setnc (Disp, Reg32) where-> setnc (Disp disp, Reg32 dest) = x86_set_membase x86_cc_nc dest disp False->-> instance Setnc Ind where-> setnc (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_ne dest False->-> instance Setne Addr where-> setne (Addr dest) = x86_set_mem x86_cc_ne dest False->-> instance Setne (Disp, Reg32) where-> setne (Disp disp, Reg32 dest) = x86_set_membase x86_cc_ne dest disp False->-> instance Setne Ind where-> setne (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_np dest False->-> instance Setnp Addr where-> setnp (Addr dest) = x86_set_mem x86_cc_np dest False->-> instance Setnp (Disp, Reg32) where-> setnp (Disp disp, Reg32 dest) = x86_set_membase x86_cc_np dest disp False->-> instance Setnp Ind where-> setnp (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_nz dest False->-> instance Setnz Addr where-> setnz (Addr dest) = x86_set_mem x86_cc_nz dest False->-> instance Setnz (Disp, Reg32) where-> setnz (Disp disp, Reg32 dest) = x86_set_membase x86_cc_nz dest disp False->-> instance Setnz Ind where-> setnz (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_p dest False->-> instance Setp Addr where-> setp (Addr dest) = x86_set_mem x86_cc_p dest False->-> instance Setp (Disp, Reg32) where-> setp (Disp disp, Reg32 dest) = x86_set_membase x86_cc_p dest disp False->-> instance Setp Ind where-> setp (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_pe dest False->-> instance Setpe Addr where-> setpe (Addr dest) = x86_set_mem x86_cc_pe dest False->-> instance Setpe (Disp, Reg32) where-> setpe (Disp disp, Reg32 dest) = x86_set_membase x86_cc_pe dest disp False->-> instance Setpe Ind where-> setpe (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_po dest False->-> instance Setpo Addr where-> setpo (Addr dest) = x86_set_mem x86_cc_po dest False->-> instance Setpo (Disp, Reg32) where-> setpo (Disp disp, Reg32 dest) = x86_set_membase x86_cc_po dest disp False->-> instance Setpo Ind where-> setpo (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_gt dest True->-> instance Setg Addr where-> setg (Addr dest) = x86_set_mem x86_cc_gt dest True->-> instance Setg (Disp, Reg32) where-> setg (Disp disp, Reg32 dest) = x86_set_membase x86_cc_gt dest disp True->-> instance Setg Ind where-> setg (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_ge dest True->-> instance Setge Addr where-> setge (Addr dest) = x86_set_mem x86_cc_ge dest True->-> instance Setge (Disp, Reg32) where-> setge (Disp disp, Reg32 dest) = x86_set_membase x86_cc_ge dest disp True->-> instance Setge Ind where-> setge (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_lt dest True->-> instance Setl Addr where-> setl (Addr dest) = x86_set_mem x86_cc_lt dest True->-> instance Setl (Disp, Reg32) where-> setl (Disp disp, Reg32 dest) = x86_set_membase x86_cc_lt dest disp True->-> instance Setl Ind where-> setl (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_le dest True->-> instance Setle Addr where-> setle (Addr dest) = x86_set_mem x86_cc_le dest True->-> instance Setle (Disp, Reg32) where-> setle (Disp disp, Reg32 dest) = x86_set_membase x86_cc_le dest disp True->-> instance Setle Ind where-> setle (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_le dest True->-> instance Setng Addr where-> setng (Addr dest) = x86_set_mem x86_cc_le dest True->-> instance Setng (Disp, Reg32) where-> setng (Disp disp, Reg32 dest) = x86_set_membase x86_cc_le dest disp True->-> instance Setng Ind where-> setng (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_lt dest True->-> instance Setnge Addr where-> setnge (Addr dest) = x86_set_mem x86_cc_lt dest True->-> instance Setnge (Disp, Reg32) where-> setnge (Disp disp, Reg32 dest) = x86_set_membase x86_cc_lt dest disp True->-> instance Setnge Ind where-> setnge (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_ge dest True->-> instance Setnl Addr where-> setnl (Addr dest) = x86_set_mem x86_cc_ge dest True->-> instance Setnl (Disp, Reg32) where-> setnl (Disp disp, Reg32 dest) = x86_set_membase x86_cc_ge dest disp True->-> instance Setnl Ind where-> setnl (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_gt dest True->-> instance Setnle Addr where-> setnle (Addr dest) = x86_set_mem x86_cc_gt dest True->-> instance Setnle (Disp, Reg32) where-> setnle (Disp disp, Reg32 dest) = x86_set_membase x86_cc_gt dest disp True->-> instance Setnle Ind where-> setnle (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_no dest True->-> instance Setno Addr where-> setno (Addr dest) = x86_set_mem x86_cc_no dest True->-> instance Setno (Disp, Reg32) where-> setno (Disp disp, Reg32 dest) = x86_set_membase x86_cc_no dest disp True->-> instance Setno Ind where-> setno (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_ns dest True->-> instance Setns Addr where-> setns (Addr dest) = x86_set_mem x86_cc_ns dest True->-> instance Setns (Disp, Reg32) where-> setns (Disp disp, Reg32 dest) = x86_set_membase x86_cc_ns dest disp True->-> instance Setns Ind where-> setns (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_o dest True->-> instance Seto Addr where-> seto (Addr dest) = x86_set_mem x86_cc_o dest True->-> instance Seto (Disp, Reg32) where-> seto (Disp disp, Reg32 dest) = x86_set_membase x86_cc_o dest disp True->-> instance Seto Ind where-> seto (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_s dest True->-> instance Sets Addr where-> sets (Addr dest) = x86_set_mem x86_cc_s dest True->-> instance Sets (Disp, Reg32) where-> sets (Disp disp, Reg32 dest) = x86_set_membase x86_cc_s dest disp True->-> instance Sets Ind where-> sets (Ind (Reg32 dest)) = 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) = x86_set_reg x86_cc_z dest False->-> instance Setz Addr where-> setz (Addr dest) = x86_set_mem x86_cc_z dest False->-> instance Setz (Disp, Reg32) where-> setz (Disp disp, Reg32 dest) = x86_set_membase x86_cc_z dest disp False->-> instance Setz Ind where-> setz (Ind (Reg32 dest)) = 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 = x86_call_imm imm ->-> instance Call Label where-> call l = do x86_call_imm 0-> emitFixup l (-4) Fixup32->-> instance Call Reg32 where-> call (Reg32 dest) = x86_call_reg dest ->-> instance Call Addr where-> call (Addr dest) = x86_call_mem dest ->-> instance Call (Disp, Reg32) where-> call (Disp disp, Reg32 dest) = x86_call_membase dest disp ->-> instance Call Ind where-> call (Ind (Reg32 dest)) = x86_call_membase dest 0 ->-> instance Call (FunPtr a) where-> call = x86_call_hs---return from procedure--> ret :: CodeGen e s ()-> ret = x86_ret->-> retN :: Word16 -> CodeGen e s ()-> retN n = x86_ret_imm n---make stack frame--> enter :: Word16 -> CodeGen e s ()-> enter = x86_enter---conditional move--> class Cmova a b where-> cmova :: a -> b -> CodeGen e s ()--> instance Cmova Reg32 Reg32 where-> cmova (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_a False dest source->-> instance Cmova Reg32 Addr where-> cmova (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_a False dest source->-> instance Cmova Reg32 (Disp, Reg32) where-> cmova (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_a False dest source disp->-> instance Cmova Reg32 Ind where-> cmova (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_ae False dest source->-> instance Cmovae Reg32 Addr where-> cmovae (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_ae False dest source->-> instance Cmovae Reg32 (Disp, Reg32) where-> cmovae (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_ae False dest source disp->-> instance Cmovae Reg32 Ind where-> cmovae (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_b False dest source->-> instance Cmovb Reg32 Addr where-> cmovb (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_b False dest source->-> instance Cmovb Reg32 (Disp, Reg32) where-> cmovb (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_b False dest source disp->-> instance Cmovb Reg32 Ind where-> cmovb (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_be False dest source->-> instance Cmovbe Reg32 Addr where-> cmovbe (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_be False dest source->-> instance Cmovbe Reg32 (Disp, Reg32) where-> cmovbe (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_be False dest source disp->-> instance Cmovbe Reg32 Ind where-> cmovbe (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_c False dest source->-> instance Cmovc Reg32 Addr where-> cmovc (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_c False dest source->-> instance Cmovc Reg32 (Disp, Reg32) where-> cmovc (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_c False dest source disp->-> instance Cmovc Reg32 Ind where-> cmovc (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_e False dest source->-> instance Cmove Reg32 Addr where-> cmove (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_e False dest source->-> instance Cmove Reg32 (Disp, Reg32) where-> cmove (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_e False dest source disp->-> instance Cmove Reg32 Ind where-> cmove (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_na False dest source->-> instance Cmovna Reg32 Addr where-> cmovna (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_na False dest source->-> instance Cmovna Reg32 (Disp, Reg32) where-> cmovna (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_na False dest source disp->-> instance Cmovna Reg32 Ind where-> cmovna (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_nae False dest source->-> instance Cmovnae Reg32 Addr where-> cmovnae (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_nae False dest source->-> instance Cmovnae Reg32 (Disp, Reg32) where-> cmovnae (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_nae False dest source disp->-> instance Cmovnae Reg32 Ind where-> cmovnae (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_nb False dest source->-> instance Cmovnb Reg32 Addr where-> cmovnb (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_nb False dest source->-> instance Cmovnb Reg32 (Disp, Reg32) where-> cmovnb (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_nb False dest source disp->-> instance Cmovnb Reg32 Ind where-> cmovnb (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_nbe False dest source->-> instance Cmovnbe Reg32 Addr where-> cmovnbe (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_nbe False dest source->-> instance Cmovnbe Reg32 (Disp, Reg32) where-> cmovnbe (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_nbe False dest source disp->-> instance Cmovnbe Reg32 Ind where-> cmovnbe (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_nc False dest source->-> instance Cmovnc Reg32 Addr where-> cmovnc (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_nc False dest source->-> instance Cmovnc Reg32 (Disp, Reg32) where-> cmovnc (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_nc False dest source disp->-> instance Cmovnc Reg32 Ind where-> cmovnc (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_ne False dest source->-> instance Cmovne Reg32 Addr where-> cmovne (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_ne False dest source->-> instance Cmovne Reg32 (Disp, Reg32) where-> cmovne (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_ne False dest source disp->-> instance Cmovne Reg32 Ind where-> cmovne (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_np False dest source->-> instance Cmovnp Reg32 Addr where-> cmovnp (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_np False dest source->-> instance Cmovnp Reg32 (Disp, Reg32) where-> cmovnp (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_np False dest source disp->-> instance Cmovnp Reg32 Ind where-> cmovnp (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_nz False dest source->-> instance Cmovnz Reg32 Addr where-> cmovnz (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_nz False dest source->-> instance Cmovnz Reg32 (Disp, Reg32) where-> cmovnz (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_nz False dest source disp->-> instance Cmovnz Reg32 Ind where-> cmovnz (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_p False dest source->-> instance Cmovp Reg32 Addr where-> cmovp (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_p False dest source->-> instance Cmovp Reg32 (Disp, Reg32) where-> cmovp (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_p False dest source disp->-> instance Cmovp Reg32 Ind where-> cmovp (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_pe False dest source->-> instance Cmovpe Reg32 Addr where-> cmovpe (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_pe False dest source->-> instance Cmovpe Reg32 (Disp, Reg32) where-> cmovpe (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_pe False dest source disp->-> instance Cmovpe Reg32 Ind where-> cmovpe (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_po False dest source->-> instance Cmovpo Reg32 Addr where-> cmovpo (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_po False dest source->-> instance Cmovpo Reg32 (Disp, Reg32) where-> cmovpo (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_po False dest source disp->-> instance Cmovpo Reg32 Ind where-> cmovpo (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_z False dest source->-> instance Cmovz Reg32 Addr where-> cmovz (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_z False dest source->-> instance Cmovz Reg32 (Disp, Reg32) where-> cmovz (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_z False dest source disp->-> instance Cmovz Reg32 Ind where-> cmovz (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_gt True dest source->-> instance Cmovg Reg32 Addr where-> cmovg (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_gt True dest source->-> instance Cmovg Reg32 (Disp, Reg32) where-> cmovg (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_gt True dest source disp->-> instance Cmovg Reg32 Ind where-> cmovg (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_ge True dest source->-> instance Cmovge Reg32 Addr where-> cmovge (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_ge True dest source->-> instance Cmovge Reg32 (Disp, Reg32) where-> cmovge (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_ge True dest source disp->-> instance Cmovge Reg32 Ind where-> cmovge (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_lt True dest source->-> instance Cmovl Reg32 Addr where-> cmovl (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_lt True dest source->-> instance Cmovl Reg32 (Disp, Reg32) where-> cmovl (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_lt True dest source disp->-> instance Cmovl Reg32 Ind where-> cmovl (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_le True dest source->-> instance Cmovle Reg32 Addr where-> cmovle (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_le True dest source->-> instance Cmovle Reg32 (Disp, Reg32) where-> cmovle (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_le True dest source disp->-> instance Cmovle Reg32 Ind where-> cmovle (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_le True dest source->-> instance Cmovng Reg32 Addr where-> cmovng (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_le True dest source->-> instance Cmovng Reg32 (Disp, Reg32) where-> cmovng (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_le True dest source disp->-> instance Cmovng Reg32 Ind where-> cmovng (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_lt True dest source->-> instance Cmovnge Reg32 Addr where-> cmovnge (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_lt True dest source->-> instance Cmovnge Reg32 (Disp, Reg32) where-> cmovnge (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_lt True dest source disp->-> instance Cmovnge Reg32 Ind where-> cmovnge (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_ge True dest source->-> instance Cmovnl Reg32 Addr where-> cmovnl (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_ge True dest source->-> instance Cmovnl Reg32 (Disp, Reg32) where-> cmovnl (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_ge True dest source disp->-> instance Cmovnl Reg32 Ind where-> cmovnl (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_gt True dest source->-> instance Cmovnle Reg32 Addr where-> cmovnle (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_gt True dest source->-> instance Cmovnle Reg32 (Disp, Reg32) where-> cmovnle (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_gt True dest source disp->-> instance Cmovnle Reg32 Ind where-> cmovnle (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_no True dest source->-> instance Cmovno Reg32 Addr where-> cmovno (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_no True dest source->-> instance Cmovno Reg32 (Disp, Reg32) where-> cmovno (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_no True dest source disp->-> instance Cmovno Reg32 Ind where-> cmovno (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_ns True dest source->-> instance Cmovns Reg32 Addr where-> cmovns (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_ns True dest source->-> instance Cmovns Reg32 (Disp, Reg32) where-> cmovns (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_ns True dest source disp->-> instance Cmovns Reg32 Ind where-> cmovns (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_o True dest source->-> instance Cmovo Reg32 Addr where-> cmovo (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_o True dest source->-> instance Cmovo Reg32 (Disp, Reg32) where-> cmovo (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_o True dest source disp->-> instance Cmovo Reg32 Ind where-> cmovo (Reg32 dest) (Ind (Reg32 source)) = 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) = x86_cmov_reg x86_cc_s True dest source->-> instance Cmovs Reg32 Addr where-> cmovs (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_s True dest source->-> instance Cmovs Reg32 (Disp, Reg32) where-> cmovs (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_s True dest source disp->-> instance Cmovs Reg32 Ind where-> cmovs (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_s True dest source 0---release stack frame--> leave :: CodeGen e s ()-> leave = x86_leave---store ah into flags--> sahf :: CodeGen e s ()-> sahf = x86_sahf
Harpy/X86CGCombinators.hs view
@@ -19,6 +19,8 @@ -- * Types UserState(..), UserEnv(..),+ emptyUserEnv,+ emptyUserState, CtrlDest(..), DataDest(..), -- * Combinators@@ -26,24 +28,26 @@ doWhile, continue, continueBranch,+ saveRegs,+ function, withDataDest, withCtrlDest, withDest,- function,- withRegister- ) where+ ) where import Text.PrettyPrint.HughesPJ import Foreign+import Data.Word import Harpy.CodeGenMonad import Harpy.X86CodeGen+import Harpy.X86Assembler -- | Destination for a calculated value.-data DataDest = RegDest Word8 -- ^ Store into specific register+data DataDest = RegDest Reg32 -- ^ Store into specific register | StackDest -- ^ Push onto stack- | MemBaseDest Word8 Word32 -- ^ Store at memory address+ | MemBaseDest Reg32 Word32 -- ^ Store at memory address | Ignore -- ^ Throw result away. -- | Destination for control transfers@@ -54,18 +58,19 @@ -- depending on outcome of test -- | User state is used to maintain bitmask of registers currently in use.-data UserState = UserState { usedRegs :: Int}+data UserState = UserState {} -- | User environment stores code generators for accessing specific -- variables as well as the current data and control destinations-data UserEnv = UserEnv { bindings :: [(String, - CodeGen UserEnv UserState ())],+data UserEnv = UserEnv { bindings :: [(String, CodeGen UserEnv UserState ())], dataDest :: DataDest, ctrlDest :: CtrlDest } -emptyUserState = UserState{usedRegs = 0}+emptyUserState :: UserState+emptyUserState = UserState{} +emptyUserEnv :: UserEnv emptyUserEnv = UserEnv{bindings = [], dataDest = Ignore, ctrlDest = Return} @@ -77,35 +82,48 @@ do env <- getEnv elseLabel <- newLabel endLabel <- newLabel- withDest Ignore (Branch FallThrough (Goto elseLabel)) - (condCg)+ withDest Ignore (Branch FallThrough (Goto elseLabel)) condCg withCtrlDest (case ctrlDest env of FallThrough -> Goto endLabel _ -> ctrlDest env) (thenCg >> continue)- defineLabel elseLabel- elseCg >> continue- defineLabel endLabel+ elseLabel @@ (elseCg >> continue)+ endLabel @@ return () doWhile :: CodeGen UserEnv s r -> CodeGen UserEnv s a -> CodeGen UserEnv s () doWhile condCg bodyCg = do topLabel <- newLabel testLabel <- newLabel- emitFixup testLabel 1 Fixup8- x86_jump8 0- defineLabel topLabel- withCtrlDest FallThrough (bodyCg >> continue)- defineLabel testLabel- withDest Ignore (Branch (Goto topLabel) FallThrough) condCg + jmp testLabel+ topLabel @@ withCtrlDest FallThrough (bodyCg >> continue)+ testLabel @@ withDest Ignore (Branch (Goto topLabel) FallThrough) + condCg continue +doFor :: (Mov a Word32, Add a Word32, Cmp a Word32) => a -> Word32 -> Word32 -> Int32 ->+ CodeGen UserEnv s r ->+ CodeGen UserEnv s ()+doFor loc from to step body =+ do topLabel <- newLabel+ testLabel <- newLabel+ mov loc from+ jmp testLabel+ topLabel @@ withCtrlDest FallThrough (body >> continue)+ testLabel @@ cmp loc to+ add loc (fromIntegral step :: Word32)+ if step < 0+ then jge topLabel+ else jle topLabel+ continue+ + continue :: CodeGen UserEnv s () continue = do env <- getEnv cont (ctrlDest env) where cont FallThrough = return ()- cont (Goto l) = emitFixup l 1 Fixup32 >> x86_jump32 0+ cont (Goto l) = jmp l cont (Branch _ _) = error "Branch in continue" cont Return = x86_epilog 0 @@ -117,23 +135,23 @@ cont cc isSigned c1 c2 where cont cc isSigned (Goto l1) (Goto l2) =- do emitFixup l1 1 Fixup32- x86_branch32 cc 0 isSigned- emitFixup l2 1 Fixup32+ do x86_branch32 cc 0 isSigned+ emitFixup l1 (-4) Fixup32 x86_branch32 (negateCC cc) 0 isSigned+ emitFixup l2 (-4) Fixup32 cont cc isSigned (Goto l1) FallThrough =- do emitFixup l1 1 Fixup32- x86_branch32 cc 0 isSigned+ do x86_branch32 cc 0 isSigned+ emitFixup l1 (-4) Fixup32 cont cc isSigned FallThrough (Goto l2) =- do emitFixup l2 1 Fixup32- x86_branch32 (negateCC cc) 0 isSigned+ do x86_branch32 (negateCC cc) 0 isSigned+ emitFixup l2 (-4) Fixup32 cont cc isSigned (Goto l1) Return =- do emitFixup l1 1 Fixup32- x86_branch32 cc 0 isSigned+ do x86_branch32 cc 0 isSigned+ emitFixup l1 (-4) Fixup32 withCtrlDest Return continue cont cc isSigned Return (Goto l2) =- do emitFixup l2 1 Fixup32- x86_branch32 (negateCC cc) 0 isSigned+ do x86_branch32 (negateCC cc) 0 isSigned+ emitFixup l2 (-4) Fixup32 withCtrlDest Return continue cont _ _ _ _ = error "unhandled case in continueBranch" @@ -143,12 +161,12 @@ where reg' sreg (RegDest r) = do if sreg /= r - then x86_mov_reg_reg r sreg x86_dword_size + then mov r sreg else return () reg' sreg (StackDest) = - do x86_push_reg sreg+ do push sreg reg' sreg (MemBaseDest r offset) = - do x86_mov_membase_reg r offset sreg x86_dword_size+ do mov (Disp offset, r) sreg reg' sreg Ignore = return () membase reg ofs =@@ -156,12 +174,14 @@ membase' reg ofs (dataDest env) where membase' reg ofs (RegDest r) = - do x86_mov_reg_membase r reg ofs x86_dword_size+ do mov r (Disp ofs, reg) membase' reg ofs (StackDest) = - do x86_push_membase reg ofs+ do push (Disp ofs, reg) membase' reg ofs (MemBaseDest r offset) = - do x86_mov_reg_membase x86_edi reg ofs x86_dword_size- x86_mov_membase_reg r offset x86_edi x86_dword_size+ do push edi+ mov edi (Disp ofs, reg)+ mov (Disp offset, r) edi+ pop edi membase' reg ofs Ignore = return () global ofs =@@ -169,12 +189,14 @@ global' ofs (dataDest env) where global' ofs (RegDest r) = - do x86_mov_reg_mem r ofs x86_dword_size+ do mov r (Addr ofs) global' ofs (StackDest) = - do x86_push_mem ofs+ do push (Addr ofs) global' ofs (MemBaseDest r offset) = - do x86_mov_reg_mem x86_edi ofs x86_dword_size- x86_mov_membase_reg r offset x86_edi x86_dword_size+ do push edi+ mov edi (Addr ofs)+ mov (Disp offset, r) edi+ pop edi global' ofs Ignore = return () immediate value =@@ -182,38 +204,30 @@ immediate' value (dataDest env) where immediate' value (RegDest r) = - do x86_mov_reg_imm r value+ do mov r value immediate' value (StackDest) = do x86_push_imm value immediate' value (MemBaseDest r offset) = - do x86_mov_reg_imm x86_edi value - x86_mov_membase_reg r offset x86_edi x86_dword_size+ do push edi+ mov edi value + mov (Disp offset, r) edi+ pop edi immediate' ofs Ignore = return () -- | Save a number of registers on the stack, perform the given code -- generation, and restore the registers.-saveRegs :: (Bits a) =>- a -> CodeGen UserEnv s r -> CodeGen UserEnv s ()-saveRegs reg_mask cg =- do gen_push 0 1+saveRegs :: [Reg32] -> CodeGen UserEnv s r -> CodeGen UserEnv s ()+saveRegs [] cg = cg >> return ()+saveRegs regs cg =+ do gen_push regs withCtrlDest FallThrough cg- gen_pop x86_edi (1 `shiftL` (fromIntegral x86_edi))+ gen_pop regs continue 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 ()- 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 ()+ gen_push [] = return ()+ gen_push (r:regs) = push r >> gen_push regs+ gen_pop [] = return ()+ gen_pop (r:regs) = gen_pop regs >> pop r -- | Perform the code generation associated with the variable given. loadVar :: String -> CodeGen UserEnv UserState ()@@ -223,18 +237,6 @@ Just cg -> cg Nothing -> failCodeGen (text ("undefined variable: " ++ name)) --- | Find a register not recorded in the given bit mask.-findReg :: (Bits a) => a -> Word8-findReg reg_mask = findR 0 1- where- findR i m =- if i <= x86_edi- then if (reg_mask .&. m) == 0- then i- else findR (i + 1) (m `shiftL` 1)- else error "no register left for allocation"- - -- | Set the data destinations to the given values while -- running the code generator. withDataDest :: DataDest -> CodeGen UserEnv s r -> CodeGen UserEnv s r@@ -261,16 +263,4 @@ function :: CodeGen UserEnv s r -> CodeGen UserEnv s r function cg = do x86_prolog 0 0- withDataDest (RegDest x86_eax) $ withCtrlDest Return $ cg---- | Apply the given cg to a register, which is reserved while the--- generator is running.-withRegister :: (Word8 -> CodeGen e UserState t) -> CodeGen e UserState ()-withRegister cg =- do state <- getState- let used = usedRegs state- let reg = findReg used- setState (state{usedRegs = used .|. (1 `shiftL` fromIntegral reg)})- cg reg- state <- getState- setState (state{usedRegs = used})+ withDest (RegDest eax) Return $ cg
Harpy/X86CodeGen.hs view
@@ -45,38 +45,68 @@ -------------------------------------------------------------------------- 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_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_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- x86_imm_emit32, x86_imm_emit16, x86_imm_emit8, + -- | 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_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,@@ -130,16 +160,42 @@ -- ** 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,+ 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,+ -- ** 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, -- ** 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 Debug.Trace- import Data.Word import Data.Bits @@ -147,8 +203,10 @@ 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. --- | Sizes of various machine data types in bytes. x86_dword_size, x86_qword_size :: Int x86_dword_size = 4 -- Number of bytes in doubleword@@ -165,7 +223,6 @@ x86_esi = 6 x86_edi = 7 --- | Opcodes for ALU instructions x86_cmp, x86_or, x86_adc, x86_sbb, x86_and, x86_sub, x86_xor, x86_add :: Word8 x86_add = 0@@ -177,7 +234,6 @@ x86_xor = 6 x86_cmp = 7 --- | Opcodes for shift instructions x86_sar, x86_shld, x86_shlr, x86_rol, x86_ror, x86_rcl, x86_rcr, x86_shl, x86_shr :: Word8 @@ -191,8 +247,6 @@ x86_shr = 5 x86_sar = 7 --- | Opcodes for floating-point instructions- x86_fadd, x86_fmul, x86_fcom, x86_fcomp, x86_fsub, x86_fsubr :: Word8 x86_fdiv, x86_fdivr :: Word8 @@ -205,7 +259,6 @@ x86_fdiv = 6 x86_fdivr = 7 --- | Integer conditions codes 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@@ -300,6 +353,7 @@ x86_address_prefix = 0x67 -- | Mapping from condition code to opcode (unsigned)+x86_cc_unsigned_map :: [Word8] x86_cc_unsigned_map = [ 0x74, -- eq 0x75, -- ne @@ -316,6 +370,7 @@ ] -- | Mapping from condition code to opcode (signed)+x86_cc_signed_map :: [Word8] x86_cc_signed_map = [ 0x74, -- eq 0x75, -- ne @@ -332,6 +387,7 @@ ] -- | 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 @@ -359,7 +415,6 @@ x86_nobasereg :: Word8 x86_nobasereg = (-1) --- | Bitvector masks for general-purpose registers 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))@@ -408,10 +463,12 @@ -- useful building blocks -x86_modrm_mod modrm = ((modrm) `shiftR` 6)-x86_modrm_reg modrm = (((modrm) `shiftR` 3) .&. 0x7)-x86_modrm_rm modrm = ((modrm) .&. 0x7)+--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)))@@ -420,8 +477,9 @@ 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 pos imm = emit32At pos 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 ()@@ -436,16 +494,21 @@ x86_imm_emit8 imm = emit8 (imm .&. 0xff) --- | Emit a 8-bit constant to the instruction stream at the given offset.-x86_imm_emit8_at pos imm = - emit8At pos (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 imm = (((fromIntegral imm :: Integer) >= -(1 `shiftL` 16)) && - ((fromIntegral imm :: Integer) <= ((1 `shiftL` 16)-1)))+-- 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)@@ -475,32 +538,34 @@ 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)+ 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 r basereg disp indexreg shift =+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 shift indexreg 5+ 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 shift indexreg (fromIntegral basereg)+ x86_address_byte shft indexreg (fromIntegral basereg) else if x86_is_imm8 disp then do x86_address_byte 1 r 4- x86_address_byte shift indexreg + x86_address_byte shft indexreg (fromIntegral basereg) x86_imm_emit8 (fromIntegral disp) else do x86_address_byte 2 r 4- x86_address_byte shift indexreg 5+ x86_address_byte shft indexreg 5 x86_imm_emit32 disp +{- x86_jmp_ofs_size ins = do instr <- peek8At ins- case trace (show instr) instr of+ case instr of 0xe8 -> return 1 0xe9 -> return 1 0x0f ->@@ -509,6 +574,7 @@ then failCodeGen (PP.text "Wrong Opcode") else return 1 _ -> return 0+-} -- target is the position in the code where to jump to: @@ -527,6 +593,7 @@ -- 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@@ -537,6 +604,7 @@ 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 ()@@ -555,13 +623,20 @@ 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 =@@ -569,8 +644,8 @@ x86_xchg_membase_reg basereg disp reg size = do x86_xchg size ; x86_membase_emit reg basereg disp -x86_xadd size = - do emit8 0x0f ; if size == 1 then emit8 0xc0 else emit8 0xc1+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 =@@ -760,6 +835,7 @@ 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@@ -767,6 +843,7 @@ 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@@ -782,8 +859,8 @@ do x86_mov2 size ; x86_regp_emit reg regp x86_mov_membase_reg basereg disp reg size = do x86_mov1 size ; x86_membase_emit reg basereg disp -x86_mov_memindex_reg basereg disp indexreg shift reg size = - do x86_mov1 size ; x86_memindex_emit reg basereg disp indexreg shift+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 dreg reg size = do x86_mov2 size x86_reg_emit dreg reg @@ -793,15 +870,11 @@ x86_mov_reg_membase reg basereg disp size = do x86_mov2 size x86_membase_emit reg basereg disp -x86_mov_reg_memindex reg basereg disp 4 shift size =+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 shift size = +x86_mov_reg_memindex reg basereg disp indexreg shft size = do x86_mov2 size- x86_memindex_emit reg basereg disp indexreg shift ---- Note: x86_clear_reg () changes the condition code!--x86_clear_reg reg = x86_alu_reg_reg x86_xor reg reg+ x86_memindex_emit reg basereg disp indexreg shft x86_mov_reg_imm reg imm = emit8 (0xb8 + reg) >> x86_imm_emit32 imm @@ -832,28 +905,34 @@ x86_membase_emit 0 basereg disp x86_imm_emit32 imm -x86_mov_memindex_imm basereg disp indexreg shift imm size = +x86_mov_memindex_imm basereg disp indexreg shft imm size = if size == 1 then do emit8 0xc6 - x86_memindex_emit 0 basereg disp indexreg shift + 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 shift + x86_memindex_emit 0 basereg disp indexreg shft x86_imm_emit16 (fromIntegral imm) else do emit8 0xc7 - x86_memindex_emit 0 basereg disp indexreg shift + 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 reg basereg disp indexreg shift =- emit8 0x8d >> x86_memindex_emit reg basereg disp indexreg shift +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) +@@ -862,42 +941,52 @@ 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 dreg basereg disp indexreg shift is_signed is_half =++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 shift + 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 :: Int -> Word8 -> Bool -> CodeGen e s () x86_fp_op_reg opc index pop_stack = - do let map = [ 0, 1, 2, 3, 5, 4, 7, 6, 8] + do let opcMap = [ 0, 1, 2, 3, 5, 4, 7, 6, 8] emit8 (if pop_stack then 0xde else 0xdc) - emit8 (0xc0 + ((map !! opc) `shiftL` 3) + (index .&. 0x07))+ emit8 (0xc0 + ((opcMap !! opc) `shiftL` 3) + (index .&. 0x07)) -- @x86_fp_int_op_membase@@ -906,67 +995,100 @@ -- 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))+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 -> Bool -> CodeGen e s () x86_fild mem is_long = if is_long then emit8 0xdf >> x86_mem_emit 5 mem else emit8 0xdb >> x86_mem_emit 0 mem +x86_fild_membase :: Word8 -> Word32 -> Bool -> CodeGen e s () x86_fild_membase basereg disp is_long = if is_long then emit8 0xdf >> x86_membase_emit 5 basereg disp else emit8 0xdb >> x86_membase_emit 0 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 -> Bool -> CodeGen e s () x86_fist_pop mem is_long = if is_long then emit8 0xdf >> x86_mem_emit 7 mem else emit8 0xdb >> x86_mem_emit 3 mem +x86_fist_pop_membase :: Word8 -> Word32 -> Bool -> CodeGen e s () x86_fist_pop_membase basereg disp is_long = if is_long then emit8 0xdf >> x86_membase_emit 7 basereg disp else emit8 0xdb >> x86_membase_emit 3 basereg disp +x86_fstsw :: CodeGen e s () x86_fstsw = emit8 0x9b >> emit8 0xdf >> emit8 0xe0 -- @x86_fist_membase@@ -974,6 +1096,7 @@ -- addressed by [basereg + disp]. -- is_int specifies whether destination is int32 (TRUE) or int16 (FALSE). +x86_fist_membase :: Word8 -> Word32 -> Bool -> CodeGen e s () x86_fist_membase basereg disp is_int = if is_int then emit8 0xdb >> x86_membase_emit 2 basereg disp @@ -981,14 +1104,27 @@ -- 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 basereg disp indexreg shift =- emit8 0xff >> x86_memindex_emit 6 basereg disp indexreg shift ++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)@@ -996,46 +1132,79 @@ -- 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 -- 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 @@ -1043,21 +1212,25 @@ 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_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@@ -1065,12 +1238,14 @@ 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@@ -1117,18 +1292,21 @@ 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 @@ -1163,6 +1341,7 @@ -- 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@@ -1221,341 +1400,273 @@ else return () -- TODO: Move signatures to definition, delete duplicates.-x86_cmpxchg_reg_reg ::- forall e s.- Word8- -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()-x86_cmpxchg_mem_reg ::- forall e s.- Word32- -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()-x86_cmpxchg_membase_reg ::- forall e s.- Word8- -> Word32- -> Word8- -> Harpy.CodeGenMonad.CodeGen e s () x86_xchg_reg_reg ::- forall a e s. (Num a) => Word8 -> Word8 -> a- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_xchg_mem_reg ::- forall a e s. (Num a) => Word32 -> Word8 -> a- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_xchg_membase_reg ::- forall a e s. (Num a) => Word8 -> Word32 -> Word8 -> a- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_xadd_reg_reg ::- forall a e s. (Num a) => Word8 -> Word8 -> a- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_xadd_mem_reg ::- forall a e s. (Num a) => Word32 -> Word8 -> a- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_xadd_membase_reg ::- forall a e s. (Num a) => Word8 -> Word32 -> Word8 -> a- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_inc_mem ::- forall e s. Word32 -> Harpy.CodeGenMonad.CodeGen e s ()+ Word32 -> CodeGen e s () x86_inc_membase ::- forall e s. Word8 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_inc_reg ::- forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()+ Word8 -> CodeGen e s () x86_dec_mem ::- forall e s. Word32 -> Harpy.CodeGenMonad.CodeGen e s ()+ Word32 -> CodeGen e s () x86_dec_membase ::- forall e s. Word8 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_dec_reg ::- forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()+ Word8 -> CodeGen e s () x86_not_mem ::- forall e s. Word32 -> Harpy.CodeGenMonad.CodeGen e s ()+ Word32 -> CodeGen e s () x86_not_membase ::- forall e s. Word8 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_not_reg ::- forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()+ Word8 -> CodeGen e s () x86_neg_mem ::- forall e s. Word32 -> Harpy.CodeGenMonad.CodeGen e s ()+ Word32 -> CodeGen e s () x86_neg_membase ::- forall e s. Word8 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_neg_reg ::- forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()+ Word8 -> CodeGen e s () x86_alu_mem_imm ::- forall e s. Word8 -> Word32 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_alu_membase_imm ::- forall e s. Word8 -> Word8 -> Word32 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_alu_membase8_imm ::- forall e s. Word8 -> Word8 -> Word32 -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_alu_mem_reg ::- forall e s. Word8 -> Word32 -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_alu_membase_reg ::- forall e s. Word8 -> Word8 -> Word32 -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_alu_reg_reg ::- forall e s. Word8 -> Word8 -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_alu_reg8_reg8 ::- forall e s. Word8 -> Word8 -> Word8 -> Bool -> Bool- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_alu_reg_mem ::- forall e s. Word8 -> Word8 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_alu_reg_membase ::- forall e s. Word8 -> Word8 -> Word8 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_test_reg_imm ::- forall e s. Word8 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_test_mem_imm ::- forall e s. Word32 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_test_membase_imm ::- forall e s. Word8 -> Word32 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_test_reg_reg ::- forall e s. Word8 -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_test_mem_reg ::- forall e s. Word32 -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_test_membase_reg ::- forall e s. Word8 -> Word32 -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_shift_reg_imm ::- forall e s. Word8 -> Word8 -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_shift_mem_imm ::- forall e s. Word8 -> Word32 -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_shift_membase_imm ::- forall e s. Word8 -> Word8 -> Word32 -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_shift_reg ::- forall e s. Word8 -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_shift_mem ::- forall e s. Word8 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_shift_membase ::- forall e s. Word8 -> Word8 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_shrd_reg ::- forall e s. Word8 -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_shrd_reg_imm ::- forall e s. Word8 -> Word8 -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_shld_reg ::- forall e s. Word8 -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_shld_reg_imm ::- forall e s. Word8 -> Word8 -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_mul_reg ::- forall e s.- Word8 -> Bool -> Harpy.CodeGenMonad.CodeGen e s ()+ Word8 -> Bool -> CodeGen e s () x86_mul_mem ::- forall e s.- Word32 -> Bool -> Harpy.CodeGenMonad.CodeGen e s ()+ Word32 -> Bool -> CodeGen e s () x86_mul_membase ::- forall e s. Word8 -> Word32 -> Bool- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_imul_reg_reg ::- forall e s. Word8 -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_imul_reg_mem ::- forall e s. Word8 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_imul_reg_membase ::- forall e s. Word8 -> Word8 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_imul_reg_reg_imm ::- forall e s. Word8 -> Word8 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_imul_reg_mem_imm ::- forall e s. Word8 -> Word32 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_imul_reg_membase_imm ::- forall e s. Word8 -> Word8 -> Word32 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_div_reg ::- forall e s.- Word8 -> Bool -> Harpy.CodeGenMonad.CodeGen e s ()+ Word8 -> Bool -> CodeGen e s () x86_div_mem ::- forall e s.- Word32 -> Bool -> Harpy.CodeGenMonad.CodeGen e s ()+ Word32 -> Bool -> CodeGen e s () x86_div_membase ::- forall e s. Word8 -> Word32 -> Bool- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_mov_mem_reg ::- forall t e s. (Num t) => Word32 -> Word8 -> t- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_mov_regp_reg ::- forall t e s. (Num t) => Word8 -> Word8 -> t- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_mov_reg_regp ::- forall t e s. (Num t) => Word8 -> Word8 -> t- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_mov_membase_reg ::- forall t e s. (Num t) => Word8 -> Word32 -> Word8 -> t- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_mov_memindex_reg ::- forall t e s. (Num t) => Word8 -> Word32@@ -1563,31 +1674,27 @@ -> Word8 -> Word8 -> t- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_mov_reg_reg ::- forall t e s. (Num t) => Word8 -> Word8 -> t- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_mov_reg_mem ::- forall t e s. (Num t) => Word8 -> Word32 -> t- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_mov_reg_membase ::- forall t e s. (Num t) => Word8 -> Word8 -> Word32 -> t- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_mov_reg_memindex ::- forall e s t. (Num t) => Word8 -> Word8@@ -1595,29 +1702,25 @@ -> Word8 -> Word8 -> t- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_mov_reg_imm ::- forall e s. Word8 -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_mov_mem_imm ::- forall a e s. (Num a) => Word32 -> Word32 -> a- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_mov_membase_imm ::- forall a e s. (Num a) => Word8 -> Word32 -> Word32 -> a- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> CodeGen e s () x86_mov_memindex_imm ::- forall a e s. (Num a) => Word8 -> Word32@@ -1625,156 +1728,285 @@ -> Word8 -> Word32 -> a- -> Harpy.CodeGenMonad.CodeGen e s ()-x86_lea_mem ::- forall e s.- Word8- -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()-x86_lea_membase ::- forall e s.- Word8- -> Word8- -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()-x86_lea_memindex ::- forall e s.- Word8- -> Word8- -> Word32- -> Word8- -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()-x86_widen_reg ::- forall e s.- Word8- -> Word8- -> Bool- -> Bool- -> Harpy.CodeGenMonad.CodeGen e s ()-x86_widen_mem ::- forall e s.- Word8- -> Word32- -> Bool- -> Bool- -> Harpy.CodeGenMonad.CodeGen e s ()-x86_widen_membase ::- forall e s.- Word8- -> Word8- -> Word32- -> Bool- -> Bool- -> Harpy.CodeGenMonad.CodeGen e s ()-x86_widen_memindex ::- forall e s.- Word8- -> Word8- -> Word32- -> Word8- -> Word8- -> Bool- -> Bool- -> Harpy.CodeGenMonad.CodeGen e s ()-x86_push_reg ::- forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_push_regp ::- forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_push_mem ::- forall e s. Word32 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_push_membase ::- forall e s.- Word8- -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()-x86_push_memindex ::- forall e s.- Word8- -> Word32- -> Word8- -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()-x86_push_imm_template ::- forall e s. Harpy.CodeGenMonad.CodeGen e s ()-x86_push_imm ::- forall e s. Word32 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_pop_reg ::- forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_pop_mem ::- forall e s. Word32 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_pop_membase ::- forall e s.- Word8- -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()-x86_pushad :: forall e s. Harpy.CodeGenMonad.CodeGen e s ()-x86_pushfd :: forall e s. Harpy.CodeGenMonad.CodeGen e s ()-x86_popad :: forall e s. Harpy.CodeGenMonad.CodeGen e s ()-x86_popfd :: forall e s. Harpy.CodeGenMonad.CodeGen e s ()-x86_loop ::- forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_loope ::- forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_loopne ::- forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_jump32 ::- forall e s. Word32 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_jump8 ::- forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_jump_reg ::- forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_jump_mem ::- forall e s. Word32 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_jump_membase ::- forall e s.- Word8- -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()-x86_branch8 ::- forall e s.- Int -> Word8 -> Bool -> Harpy.CodeGenMonad.CodeGen e s ()-x86_branch32 ::- forall e s.- Int -> Word32 -> Bool -> Harpy.CodeGenMonad.CodeGen e s ()-x86_branch ::- forall e s. Int -> Int -> Bool -> Harpy.CodeGenMonad.CodeGen e s ()-x86_jecxz ::- forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_set_reg ::- forall e s.- Int -> Word8 -> Bool -> Harpy.CodeGenMonad.CodeGen e s ()-x86_set_mem ::- forall e s.- Int -> Word32 -> Bool -> Harpy.CodeGenMonad.CodeGen e s ()-x86_set_membase ::- forall e s.- Int- -> Word8- -> Word32- -> Bool- -> Harpy.CodeGenMonad.CodeGen e s ()-x86_cmov_reg ::- forall e s.- Int- -> Bool- -> Word8- -> Word8- -> Harpy.CodeGenMonad.CodeGen e s ()-x86_cmov_mem ::- forall e s.- Int- -> Bool- -> Word8- -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()-x86_cmov_membase ::- forall e s.- Int- -> Bool- -> Word8- -> Word8- -> Word32- -> Harpy.CodeGenMonad.CodeGen e s ()+ -> 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
Harpy/X86Disassembler.hs view
@@ -1,6 +1,6 @@ -------------------------------------------------------------------------- -- |--- Module : X86Disassembler+-- Module : Harpy.X86Disassembler -- Copyright : (c) Martin Grabmueller and Dirk Kleeblatt -- License : GPL -- @@ -10,9 +10,9 @@ -- -- Disassembler for x86 machine code. ----- This is a disassembler for object code for the x86 architecture. It--- provides functions for disassembling byte arrays, byte lists and files--- containing raw binary code.+-- This is a disassembler for object code for the x86 architecture.+-- It provides functions for disassembling byte arrays, byte lists and+-- memory blocks containing raw binary code. -- -- Features: --@@ -67,8 +67,7 @@ disassembleList, disassembleArray, showIntel,- showAtt,- testFile+ showAtt ) where import Text.ParserCombinators.Parsec@@ -501,15 +500,21 @@ -- | All operands are in one of the following locations: -- -- - Constants in the instruction stream+-- -- - Memory locations+-- -- - Registers -- -- Memory locations are referred to by on of several addressing modes: -- -- - Absolute (address in instruction stream)+-- -- - Register-indirect (address in register)+-- -- - Register-indirect with displacement+-- -- - Base-Index with scale+-- -- - Base-Index with scale and displacement -- -- Displacements can be encoded as 8 or 32-bit immediates in the@@ -583,15 +588,15 @@ -- | Some opcodes can operate on data of several widths. This information -- is encoded in instructions using the following enumeration type.. -data InstrOperandSize = OPNONE -- ^ No operand size specified- | OP8 -- ^ 8-bit integer operand- | OP16 -- ^ 16-bit integer operand- | OP32 -- ^ 32-bit integer operand- | OP64 -- ^ 64-bit integer operand- | OP128 -- ^ 128-bit integer operand- | OPF32 -- ^ 32-bit floating point operand- | OPF64 -- ^ 64-bit floating point operand- | OPF80 -- ^ 80-bit floating point operand+data InstrOperandSize = OPNONE -- ^ No operand size specified+ | OP8 -- ^ 8-bit integer operand+ | OP16 -- ^ 16-bit integer operand+ | OP32 -- ^ 32-bit integer operand+ | OP64 -- ^ 64-bit integer operand+ | OP128 -- ^ 128-bit integer operand+ | OPF32 -- ^ 32-bit floating point operand+ | OPF64 -- ^ 64-bit floating point operand+ | OPF80 -- ^ 80-bit floating point operand deriving (Show) @@ -602,13 +607,14 @@ -- the instruction. data Instruction = - BadInstruction Word8 String Int [Word8] -- ^ Invalid instruction- | Instruction { opcode :: Opcode, -- ^ Opcode of the instruction+ BadInstruction Word8 String Int [Word8] -- ^ Invalid instruction+ | PseudoInstruction Int String -- ^ Pseudo instruction, e.g. label+ | Instruction { opcode :: Opcode, -- ^ Opcode of the instruction opsize :: InstrOperandSize, -- ^ Operand size, if any- operands :: [Operand], -- ^ Instruction operands- address :: Int, -- ^ Start address of instruction- bytes ::[Word8] -- ^ Instruction bytes- } -- ^ Valid instruction+ operands :: [Operand], -- ^ Instruction operands+ address :: Int, -- ^ Start address of instruction+ bytes ::[Word8] -- ^ Instruction bytes+ } -- ^ Valid instruction instance Show Instruction where show = showIntel@@ -620,7 +626,9 @@ hex32 :: Int -> String hex32 i =- let s = showHex i ""+ let w :: Word32+ w = fromIntegral i+ s = showHex w "" in take (8 - length s) (repeat '0') ++ s -- Show a byte as an 2-digit hexadecimal number with leading zeroes.@@ -637,17 +645,24 @@ -- Intel style: -- -- - Destination operand comes first, source second.+-- -- - No register or immediate prefixes.+-- -- - Memory operands are annotated with operand size.--- - Hexadecimal numbers are suffixed with H and prefixed with 0 if+--+-- - Hexadecimal numbers are suffixed with @H@ and prefixed with @0@ if -- necessary. -- -- AT&T style: -- -- - Source operand comes first, destination second.--- - Register names are prefixes with %.--- - Immediates are prefixed with $.--- - Hexadecimal numbers are prefixes with 0x+--+-- - Register names are prefixes with @%@.+--+-- - Immediates are prefixed with @$@.+--+-- - Hexadecimal numbers are prefixes with @0x@+-- -- - Opcodes are suffixed with operand size, when ambiguous otherwise. data ShowStyle = IntelStyle -- ^ Show in Intel style | AttStyle -- ^ Show in AT&T style@@ -658,6 +673,8 @@ showIntel (BadInstruction b desc pos bytes) = showPosBytes pos bytes ++ "(" ++ desc ++ ", byte=" ++ show b ++ ")"+showIntel (PseudoInstruction pos s) =+ hex32 pos ++ " " ++ s showIntel (Instruction op opsize [] pos bytes) = showPosBytes pos bytes ++ showOp op@@ -672,6 +689,8 @@ showAtt (BadInstruction b desc pos bytes) = showPosBytes pos bytes ++ "(" ++ desc ++ ", byte=" ++ show b ++ ")"+showAtt (PseudoInstruction pos s) =+ hex32 pos ++ " " ++ s showAtt (Instruction op opsize [] pos bytes) = showPosBytes pos bytes ++ showOp op ++ showInstrSuffix [] opsize@@ -731,13 +750,15 @@ -- Show an immediate value in hexadecimal. +showImm :: Word32 -> String showImm i = "$0x" ++ showHex i "" +showIntelImm :: Word32 -> String showIntelImm i = let h = showHex i "H" (f:_) = h- in (if isDigit f then "" else "0") ++ showHex i "H"+ in (if isDigit f then "" else "0") ++ h -- Show an address in hexadecimal. @@ -750,7 +771,7 @@ w = fromIntegral i h = showHex w "H" (f:_) = h- in (if isDigit f then "" else "0") ++ showHex w "H"+ in (if isDigit f then "" else "0") ++ h -- | Disassemble a block of memory. Starting at the location -- pointed to by the given pointer, the given number of bytes are
Makefile view
+ NEWS view
@@ -0,0 +1,46 @@+ -*-outline-*-+* Harpy NEWS++** New in version 0.4++- New convenience top-level module "Harpy", which re-exports+ Harpy.CodeGenMonad, Harpy.Call and Harpy.X86Assembler++- It is now possible to override Harpy's automatic code buffer+ management. The new field 'customCodeBuffer' in the type+ 'CodeGenConfig' can be set to 'Just (buf, size)', where 'buf' is a+ pointer to a memory region of 'size' bytes. Harpy will then use the+ supplied code buffer and will not perform any automatic code buffer+ allocation on overflow. Overflow checking is still performed and+ will result in an exception in the CodeGen monad.++- When using the high-level assembler in X86Assembler, the code buffer+ is automatically protected from overflow.++- Floating point operations added to X86Assembler (only for double+ operands yet).++- Preliminary support for SSE instructions. Currently, only the+ packed and scalar floating-point arithmetic operations are supported+ (both in the low-level module Harpy.X86CodeGen and as methods in+ Harpy.X86Assembler)++- Code buffer default size has been increased from 128 to 4096 bytes.++- The CodeGenMonad fails when a label is defined twice.++- It is now possible to associate names with labels, using the new+ operation newNamedLabel. The given names will show up in the+ disassembly, which makes debugging of generated code much easier.++- The doc directory contains a second, slightly larger tutorial now.++- The examples/evaluator directory contains a small example+ interpreter for arithmetic expressions, which translates expressions+ entered at the keayboard to machine code on the fly. This is the+ demo program we presented at the Haskell Workshop 2007.++** New in version 0.2++- Everything is new! This is the first released version.+
+ doc/Makefile view
@@ -0,0 +1,18 @@+all: larger-tutorial.pdf++larger-tutorial.pdf: larger-tutorial.tex ++larger-tutorial.tex: larger-tutorial.lhs+ lhs2TeX $< > $@++%.pdf: %.tex+ pdflatex $<+ pdflatex $<++clean:+ rm -f larger-tutorial.aux larger-tutorial.toc\+ larger-tutorial.tex larger-tutorial.log larger-tutorial.out\+ larger-tutorial.ptb++really-clean: clean+ rm -f larger-tutorial.pdf
+ doc/larger-tutorial.lhs view
@@ -0,0 +1,312 @@+\documentclass[a4paper,11pt]{article}++\usepackage[margin=2.5cm]{geometry}+\usepackage{hyperref}++%include polycode.fmt+%format alpha = "\alpha"+++\title{\textbf{Slightly Larger Harpy Tutorial}}+\author{Martin Grabmüller \and Dirk Kleeblatt}++\begin{document}+\maketitle+\begin{abstract}\noindent+This tutorial is an introduction to some of the more advanced features+of Harpy. In the course of the tutorial, we will build a small+run-time compiler for a call-by-value lambda-calculus.+This document is written as a litarate Haskell program, so you can+compile and run it without any modifications. +\end{abstract}++\section{Introduction}++In this tutorial, we develop a small run-time compiler for a simple+call-by-value lambda calculus extended with natural number constants.++Before reading, you should have read the Harpy tutorial, which+introduces the most basic concepts. We also recommend to have a+running \verb|ghci| session running for loading the literate Haskell+script of this tutorial and to try it out. Maybe you want to have the+Harpy API documentation available, too.++\section{The Code}++To make use of Harpy and (a subset of) the x86 assembler instructions, we need+to import some modules.++\begin{code}+import Harpy.CodeGenMonad+import Harpy.X86Assembler+import Harpy.X86Disassembler+import Foreign+import Control.Monad+import Control.Monad.Trans+import Data.List +\end{code}++The following module system hackery is necessary, because the+|Harpy.X86Assembler| module exports a method called+|div|, which clashes with the |div| function+exported by the Haskell Prelude. The prelude |div| will be+hidden, but is still available as a qualified name.++\begin{code}+import Prelude hiding (div)+import qualified Prelude+\end{code}++\subsection{Data Types}++In the following, we define several data types for representing lambda+calculus terms++A |Name| represents a variable name. In a real+implementation, it would probably be more complicated data type for+handling qualified or compiler-generated names. For now, a string+will suffice.++\begin{code}+type Name = String+\end{code}++In our implementation, a variable may refer to (a) a global variable,+which is represented by its address, (b) a parameter, which is+represented by the number of enclosing lambda expression, or (c) a+free variable, which is represented by its index into the current code+closure.++\begin{code}+data VarLoc = Global Word32+ | Param Int+ | Free Int+ deriving (Show)+\end{code}++A compile-time environment represents a mapping from variable names to+variable locations.++\begin{code}+data Env = Env [(Name, VarLoc)]+\end{code}++An expression is represented by the following data type and may be a+variable, an immediate value (integer constant), a lambda abstraction+or an application expression.++\begin{code}+data Exp = Var Name+ | Imm Int+ | Abs Name Exp+ | App Exp Exp+\end{code}++The |State| type represents the state of a running program.+It consists of a pointer to the next available word of heap memory,+and a pointer to the end of the heap. These two values are necessary+for dynamically allocating memory and for performing heap-overflow+checks.++\begin{code}+data State = State { heap :: Ptr Word32,+ heapEnd :: Ptr Word32}+\end{code}++The following test expressions are constructed using the constructors of+type |Exp| and are to be evaluated by the main program.++\begin{code}+testExp0 = App (Abs "x" (Var "x")) (Imm 12)+testExp1 = App (App (Abs "x" (Abs "y" (Var "x"))) (Imm 12)) (Imm 23)+\end{code}++\subsection{Main Program}++Before presenting the compiler, we will have a look at how it is used.+The entry point to the dynamic compiler is the function+|interpret|, which takes an expression and returns the value+calculated by the expression. The main program simply prints the+result.++\begin{code}+$(callDecl "callFunc" [t|Word32|])+\end{code}++\begin{code}+main :: IO ()+main = do res <- interpret testExp1+ putStrLn $ "Result: " ++ show res+\end{code}++The |interpret| function allocates 16 kbytes of heap and+compiles the expression. The |State| of the compiler is+passed to the |runCodeGen| function as a user state.++\begin{code}+interpret :: Exp -> IO Word32+interpret exp =+ do let heapSize = 1024 * 16+ heap <- mallocBytes heapSize+ (_, Right res) <- runCodeGen (compileTop exp) (Env []) + (State heap (heap `plusPtr` + (heapSize `Prelude.div` 4)))+ return res+\end{code}++\subsection{Compilation}++The compilation starts in the function |compileTop|, which emits code+for creating a stack frame, saving all general-purpose registers+(except \verb|eax|, which will contain the result of the execution),+and finally compiles the expression. Afterwards, all registers are+restored and the function is called. In addition we call the+disassembler on the generated code and print it out. This is a useful+debuggin aid when generating assembler code.++\begin{code}+compileTop :: Exp -> CodeGen Env State Word32+compileTop exp =+ do st <- getState+ push ebp+ mov ebp esp+ push ebx+ push ecx+ push edi+ push esi+ mov ecx ((fromIntegral (ptrToWordPtr (heap st))) :: Word32)+ compile exp+ pop esi+ pop edi+ pop ecx+ pop ebx+ mov esp ebp+ pop ebp+ ret+ y <- callFunc+ dis <- disassemble+ liftIO $ mapM_ (putStrLn . showIntel) dis+ return y++\end{code}++\subsubsection{Handling Variables}++The |findVar| function looks up a variable in the+environment and returns its binding.++\begin{code}+findVar s = + do Env e <- getEnv+ case lookup s e of+ Just vl -> return vl+ Nothing -> error ("unbound variable: " ++ s)+\end{code}++For the implementation of closures, we need to calculate free+variables of expressions, so that we know what to store into closures+and how to access free variables from the body of a lambda expression.++\begin{code}+freeVariables (Var s) = return [s]+freeVariables (Imm _) = return []+freeVariables (Abs x b) = liftM (delete x) (freeVariables b)+freeVariables (App e1 e2) = liftM2 union (freeVariables e1) (freeVariables e2)+\end{code}++\subsubsection{Heap Allocation}++Closures are the only dynamically allocated structures in our little+compiler. They are allocated from a contiguous block of malloc'ed+memory, which is passed in the code generator monad's state. The+following function generates code for allocating $w$ words of memory+in the heap, and returning a pointer to the memory in register+\verb|eax|. On heap overflow, a breakpoint instruction is executed.++\begin{code}+emitAlloc w =+ do mov eax ecx+ st <- getState+ cmp ecx (fromIntegral (ptrToWordPtr (heapEnd st)) :: Word32)+ next <- newLabel+ jl next+ breakpoint+ defineLabel next+ add ecx ((4 * w) :: Word32)+\end{code}++\subsubsection{The Compilation Proper}++Finally, the |compile| function compiles an expression.+Constants are simply loaded into the result register, values of+variables are retrieved from their respective addresses (global+variables from absolute addresses, parameters relative to the stack+base pointer, and free variables relative to the closure pointer.++\begin{code}+compile :: Exp -> CodeGen Env State ()+compile (Imm i) = + do mov eax (fromIntegral i :: Word32)+compile (Var s) =+ do c <- findVar s+ case c of+ Global addr -> mov eax (Addr addr)+ Param ofs -> mov eax (Disp (fromIntegral ofs), ebp)+ Free ofs -> mov eax (Disp (fromIntegral ofs), esi)+\end{code}++Lambda expressions are more complicated. We first need to calculate+the set of free variables of the body expression. Then the body of+the expression is compiled (with a jump around its code, so that it is+not actually executed at this point). Then a closure record is+allocated on the heap, a code pointer to the body is stored in the+first word, and the values of all free variables of the body are+calculated and moved into the remaining fields of the closure.++The result is a pointer to the new closure, returned in \verb|eax|, as+usual.++\begin{code}+compile exp@(Abs x body) =+ do fv <- freeVariables exp+ let frees = zip fv (map Free [4,8..])+ next <- newLabel+ jmp next+ f <- setLabel+ push ebp+ mov ebp esp+ mov esi (Disp 8, ebp)+ withEnv (Env ((x, Param 12) : frees)) (compile body)+ mov esp ebp+ pop ebp+ ret+ defineLabel next+ emitAlloc (fromIntegral (length frees + 1))+ mov edi eax+ mov (Disp 0, edi) f+ if length frees > 0+ then do push eax+ mapM_ (\ (x, Free ofs) -> + do compile (Var x)+ mov (Disp (fromIntegral ofs), edi) eax)+ frees+ pop eax+ else return ()+compile (App e1 e2) = + do compile e2+ push eax+ compile e1+ push eax+ call (Disp 0, eax)+ add esp (8 :: Word32)+\end{code}++\section{Conclusion}++This completes our little just-in-time compiled lambda calculus+evaluator. We hope that this tutorial makes clear many of the fine+points in using the libray.++Happy Harpy Hacking in Haskell!++\end{document}
+ examples/evaluator/ArithParser.hs view
@@ -0,0 +1,73 @@+module ArithParser where++import Control.Monad++import ArithTypes++import Foreign++import Text.ParserCombinators.Parsec+import qualified Text.ParserCombinators.Parsec.Token as P+import Text.ParserCombinators.Parsec.Language+import Text.ParserCombinators.Parsec.Expr++lexer :: P.TokenParser ()+lexer = P.makeTokenParser + (haskellStyle+ { reservedOpNames = ["*","/","+","-"]+ })++statement :: Parser Stmt+statement = do s <- statement'+ eof+ return s++statement' :: Parser Stmt+statement' = try((do [i] <- identifier+ if i < 'a' || i > 'z'+ then fail "character a-z expected"+ else return ()+ symbol ":="+ e <- expr+ return $ Assign i e) <?> "assignment")+ <|> liftM Cmd cmd+ <|> liftM Print expr++cmd :: Parser Cmd+cmd = try (do symbol ":help"+ return Help)+ <|> try (do symbol ":verbose"+ return Verbose)+ <|> (do symbol ":quit"+ return Quit)++expr :: Parser Exp+expr = buildExpressionParser table factor+ <?> "expression"++table = [[op "*" Mul AssocLeft, op "/" Div AssocLeft]+ ,[op "+" Add AssocLeft, op "-" Sub AssocLeft]+ ]+ where+ op s f assoc+ = Infix (do{ reservedOp s; return f} <?> "operator") assoc++factor = parens expr+ <|> liftM (Lit . fromInteger) natural+ <|> (do [i] <- identifier+ if i < 'a' || i > 'z'+ then fail "character a-z expected"+ else return ()+ return $ Var i)+ <?> "simple expression"++whiteSpace= P.whiteSpace lexer+lexeme = P.lexeme lexer+symbol = P.symbol lexer+natural = P.natural lexer+parens = P.parens lexer+semi = P.semi lexer+identifier= P.identifier lexer+reserved = P.reserved lexer+reservedOp= P.reservedOp lexer+
+ examples/evaluator/ArithTypes.hs view
@@ -0,0 +1,22 @@+module ArithTypes where++import Foreign++data Stmt = Assign Char Exp+ | Print Exp+ | Cmd Cmd+ deriving (Show)++data Cmd = Help+ | Quit+ | Verbose+ deriving (Show)++data Exp = Add Exp Exp+ | Sub Exp Exp+ | Mul Exp Exp+ | Div Exp Exp+ | Lit Int32+ | Var Char+ deriving (Show)+
+ examples/evaluator/Evaluator.hs view
@@ -0,0 +1,118 @@+module Main(main) where++import ArithTypes+import ArithParser++import Harpy+import Harpy.X86Disassembler++import Foreign++import Control.Monad++import System.Console.Readline++import Text.ParserCombinators.Parsec++$(callDecl "callAsWord32" [t|Word32|])++main :: IO ()+main = do putStrLn "\n\n\n\nHarpy Interpreter"+ putStrLn "(type :help to see a help message)"+ allocaArray 26 (\ p -> mapM_ (\ i -> poke (advancePtr p i) 0) [0..25] >> repl p False)++repl :: Ptr Int32 -> Bool -> IO ()+repl env verbose =+ do s <- readline "@ "+ case s of+ Nothing -> return ()+ Just s' -> do addHistory s'+ interpret env verbose s'++interpret :: Ptr Int32 -> Bool -> String -> IO ()+interpret env verbose s = + do let e = parse statement "<standard input>" s+ case e of+ Left err -> do putStrLn (show err)+ repl env verbose+ Right stmt -> run env verbose stmt++run :: Ptr Int32 -> Bool -> Stmt -> IO ()+run env verbose (Cmd Help) = + do putStrLn "Enter an arithmetic expression to evaluate it"+ putStrLn " e.g. 5 / 2"+ putStrLn "Enter an assignment to set a variable"+ putStrLn " e.g. a := 4 * 2 - (6 + 1)"+ putStrLn "Enter :help to see this message again"+ putStrLn "Enter :quit to exit"+ putStrLn "Enter :verbose to toggle disassembly output"+ repl env verbose++run env _ (Cmd Quit) = return ()++run env verbose (Cmd Verbose) = repl env (Prelude.not verbose)++run env verbose stmt@(Assign var exp) =+ do (i, ins) <- eval' env stmt+ when verbose (mapM_ (putStrLn . showIntel) ins)+ repl env verbose++run env verbose stmt@(Print exp) =+ do (i, ins) <- eval' env stmt+ putStrLn (show i)+ when verbose (mapM_ (putStrLn . showIntel) ins)+ repl env verbose++-- Function for compiling and executing statements.+eval' :: Ptr Int32 -> Stmt -> IO (Int32, [Instruction])+eval' env e = do (_, Right v) <- runCodeGen (compileAndRun e) env ()+ return v++compileAndRun :: Stmt -> CodeGen (Ptr Int32) s (Int32, [Instruction])+compileAndRun (Assign c exp) = + do entryCode+ compileExp exp+ env <- getEnv+ mov (variableAddress env c) eax+ exitCode+ d <- disassemble+ callAsVoid+ return (0, d)+compileAndRun (Print exp) =+ do entryCode+ compileExp exp+ exitCode+ d <- disassemble+ r <- callAsWord32+ return (fromIntegral r, d)++compileExp :: Exp -> CodeGen (Ptr Int32) s ()+compileExp (Add e1 e2) = compileBinOp e1 e2 (add eax (Ind esp))+compileExp (Sub e1 e2) = compileBinOp e1 e2 (sub eax (Ind esp))+compileExp (Mul e1 e2) = compileBinOp e1 e2 (imul InPlace eax (Ind esp))+compileExp (Div e1 e2) = compileBinOp e1 e2 (cdq >> idiv (Ind esp))+compileExp (Lit i) = mov eax ((fromIntegral i) :: Word32)+compileExp (Var c) = do env <- getEnv+ mov eax (variableAddress env c)++compileBinOp :: Exp -> Exp -> CodeGen (Ptr Int32) s a -> CodeGen (Ptr Int32) s ()+compileBinOp e1 e2 op = do compileExp e2+ push eax+ compileExp e1+ op+ add esp (4 :: Word32) ++entryCode :: CodeGen e s ()+entryCode = do push ebp+ mov ebp esp++exitCode :: CodeGen e s ()+exitCode = do mov esp ebp+ pop ebp+ ret++variableAddress :: Ptr Int32 -> Char -> Addr+variableAddress env c =+ let ofs = fromEnum c - fromEnum 'a'+ env' = advancePtr env ofs+ in Addr (fromIntegral (ptrToWordPtr env'))
harpy.cabal view
@@ -1,12 +1,13 @@+Cabal-version: >=1.2 Name: harpy-Version: 0.2+Version: 0.4 License: GPL License-file: COPYING Author: Dirk Kleeblatt <klee@cs.tu-berlin.de> Martin Grabmueller <magr@cs.tu-berlin.de> Maintainer: klee@cs.tu-berlin.de, magr@cs.tu-berlin.de Homepage: http://uebb.cs.tu-berlin.de/harpy/-Category: Code generation+Category: Code Generation Synopsis: Runtime code generation for x86 machine code Description: The package contains the following components: .@@ -27,15 +28,35 @@ . * All the above modules use the code generation monad defined in module "Harpy.CodeGenMonad".+ .+ * The Darcs repo and two tutorials on using Harpy can be found at+ Harpy's homepage: <http://uebb.cs.tu-berlin.de/harpy/> Stability: Experimental-Build-depends: base, parsec, mtl, template-haskell-Exposed-Modules:++Extra-source-files: + NEWS README Makefile+ doc/Makefile doc/tutorial.lhs doc/larger-tutorial.lhs+ examples/evaluator/ArithTypes.hs examples/evaluator/ArithParser.hs+ examples/evaluator/Evaluator.hs++Flag small_base+ Description: Choose the new smaller, split-up base package.++Library+ if flag(small_base)+ Build-depends: base >= 3,parsec,mtl,template-haskell,pretty,containers,array+ else+ Build-Depends: base < 3,parsec,mtl,template-haskell+ Exposed-Modules:+ Harpy, Harpy.X86CodeGen, Harpy.X86Assembler, Harpy.CodeGenMonad, Harpy.Call, Harpy.X86Disassembler, Harpy.X86CGCombinators-Extensions: ForeignFunctionInterface, MultiParamTypeClasses, - TemplateHaskell, CPP-ghc-options: -O+ Extensions: + ForeignFunctionInterface, MultiParamTypeClasses, + TemplateHaskell, CPP, FlexibleContexts, FlexibleInstances,+ RankNTypes+ Ghc-options: -O2