packages feed

harpy 0.4 → 0.4.1

raw patch · 10 files changed

+327/−154 lines, 10 filesnew-uploaderPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Harpy.Call: conv[a10Ee] :: FunPtr () -> IO ()
- Harpy.Call: conv[a10FL] :: FunPtr (Word32 -> Word32) -> Word32 -> IO Word32
- Harpy.Call: conv[a10Lb] :: FunPtr (Ptr a[a10L4] -> Ptr b[a10L5] -> Ptr c[a10L6] -> Ptr d[a10L7] -> Ptr e[a10L8] -> Ptr f[a10L9] -> Ptr g[a10La] -> ()) -> Ptr a[a10L4] -> Ptr b[a10L5] -> Ptr c[a10L6] -> Ptr d[a10L7] -> Ptr e[a10L8] -> Ptr f[a10L9] -> Ptr g[a10La] -> IO ()
+ Harpy.Call: conv[a126I] :: FunPtr () -> IO ()
+ Harpy.Call: conv[a128f] :: FunPtr (Word32 -> Word32) -> Word32 -> IO Word32
+ Harpy.Call: conv[a12dF] :: FunPtr (Ptr a[a12dy] -> Ptr b[a12dz] -> Ptr c[a12dA] -> Ptr d[a12dB] -> Ptr e[a12dC] -> Ptr f[a12dD] -> Ptr g[a12dE] -> ()) -> Ptr a[a12dy] -> Ptr b[a12dz] -> Ptr c[a12dA] -> Ptr d[a12dB] -> Ptr e[a12dC] -> Ptr f[a12dD] -> Ptr g[a12dE] -> IO ()
+ Harpy.CodeGenMonad: instance Eq Label
+ Harpy.CodeGenMonad: instance Ord Label
+ Harpy.X86Assembler: class Prefetch0 a
+ Harpy.X86Assembler: class Prefetch1 a
+ Harpy.X86Assembler: class Prefetch2 a
+ Harpy.X86Assembler: class Prefetchnta a
+ Harpy.X86Assembler: instance Eq XMMReg
+ Harpy.X86Assembler: instance Jmp (Ptr a)
+ Harpy.X86Assembler: instance Ord Reg32
+ Harpy.X86Assembler: instance Ord XMMReg
+ Harpy.X86Assembler: instance Prefetch0 (Disp, Reg32)
+ Harpy.X86Assembler: instance Prefetch0 Addr
+ Harpy.X86Assembler: instance Prefetch0 Ind
+ Harpy.X86Assembler: instance Prefetch1 (Disp, Reg32)
+ Harpy.X86Assembler: instance Prefetch1 Addr
+ Harpy.X86Assembler: instance Prefetch1 Ind
+ Harpy.X86Assembler: instance Prefetch2 (Disp, Reg32)
+ Harpy.X86Assembler: instance Prefetch2 Addr
+ Harpy.X86Assembler: instance Prefetch2 Ind
+ Harpy.X86Assembler: instance Prefetchnta (Disp, Reg32)
+ Harpy.X86Assembler: instance Prefetchnta Addr
+ Harpy.X86Assembler: instance Prefetchnta Ind
+ Harpy.X86Assembler: instance Show XMMReg
+ Harpy.X86Assembler: prefetch0 :: (Prefetch0 a) => a -> CodeGen e s ()
+ Harpy.X86Assembler: prefetch1 :: (Prefetch1 a) => a -> CodeGen e s ()
+ Harpy.X86Assembler: prefetch2 :: (Prefetch2 a) => a -> CodeGen e s ()
+ Harpy.X86Assembler: prefetchnta :: (Prefetchnta a) => a -> CodeGen e s ()
+ Harpy.X86Assembler: xmm0 :: XMMReg
+ Harpy.X86Assembler: xmm1 :: XMMReg
+ Harpy.X86Assembler: xmm2 :: XMMReg
+ Harpy.X86Assembler: xmm3 :: XMMReg
+ Harpy.X86Assembler: xmm4 :: XMMReg
+ Harpy.X86Assembler: xmm5 :: XMMReg
+ Harpy.X86Assembler: xmm6 :: XMMReg
+ Harpy.X86Assembler: xmm7 :: XMMReg
+ Harpy.X86CodeGen: x86_jump_pointer :: Ptr a -> CodeGen e s ()
+ Harpy.X86CodeGen: x86_prefetch0_mem :: Word32 -> CodeGen e s ()
+ Harpy.X86CodeGen: x86_prefetch0_membase :: Word8 -> Word32 -> CodeGen e s ()
+ Harpy.X86CodeGen: x86_prefetch0_regp :: Word8 -> CodeGen e s ()
+ Harpy.X86CodeGen: x86_prefetch1_mem :: Word32 -> CodeGen e s ()
+ Harpy.X86CodeGen: x86_prefetch1_membase :: Word8 -> Word32 -> CodeGen e s ()
+ Harpy.X86CodeGen: x86_prefetch1_regp :: Word8 -> CodeGen e s ()
+ Harpy.X86CodeGen: x86_prefetch2_mem :: Word32 -> CodeGen e s ()
+ Harpy.X86CodeGen: x86_prefetch2_membase :: Word8 -> Word32 -> CodeGen e s ()
+ Harpy.X86CodeGen: x86_prefetch2_regp :: Word8 -> CodeGen e s ()
+ Harpy.X86CodeGen: x86_prefetchnta_mem :: Word32 -> CodeGen e s ()
+ Harpy.X86CodeGen: x86_prefetchnta_membase :: Word8 -> Word32 -> CodeGen e s ()
+ Harpy.X86CodeGen: x86_prefetchnta_regp :: Word8 -> CodeGen e s ()
+ Harpy.X86Disassembler: instance Eq InstrOperandSize
+ Harpy.X86Disassembler: instance Eq Instruction
+ Harpy.X86Disassembler: instance Eq Opcode
+ Harpy.X86Disassembler: instance Eq Operand

Files

+ ANNOUNCE view
@@ -0,0 +1,60 @@+ANNOUNCE: Harpy 0.4 - Runtime code generation for x86 machine code++We are pleased to announce the release of Harpy 0.4, a library for+runtime code generation for x86 machine code.++Harpy is available from Hackage:++  http://hackage.haskell.org/cgi-bin/hackage-scripts/package/harpy-0.4++Also see Harpy's homepage, which features two tutorials and access to+the darcs repo (and to the Haddock documentation, until it is available+from Hackage, too):++  http://uebb.cs.tu-berlin.de/harpy/++Harpy is supposed to be built with GHC 6.8 and GHC 6.6 (with Cabal 1.2+or greater).  Please report any build problems you encounter.++This release features the following additions and fixes:++- 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.++Happy Haskell Hacking with Harpy,++  Martin and Dirk
Harpy/CodeGenMonad.hs view
@@ -162,6 +162,7 @@  -- | Label data Label = Label Int String+           deriving (Eq, Ord)  unCg :: CodeGen e s a -> ((e, CodeGenEnv) -> (s, CodeGenState) -> IO ((s, CodeGenState), Either ErrMsg a)) unCg (CodeGen a) = a
Harpy/X86Assembler.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE MultiParamTypeClasses,FlexibleInstances #-} -------------------------------------------------------------------------- -- | -- Module      :  Harpy.X86Assembler@@ -64,7 +65,7 @@ si = Reg16 6 di = Reg16 7 -newtype Reg32 = Reg32 Word8 deriving Eq+newtype Reg32 = Reg32 Word8 deriving (Eq, Ord) eax, ecx, edx, ebx, esp, ebp, esi, edi :: Reg32  eax = Reg32 0@@ -77,7 +78,9 @@ edi = Reg32 7  newtype XMMReg = XMMReg Word8+    deriving (Eq, Ord) +xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 :: XMMReg xmm0 = XMMReg 0 xmm1 = XMMReg 1 xmm2 = XMMReg 2@@ -87,6 +90,9 @@ xmm6 = XMMReg 6 xmm7 = XMMReg 7 +instance Show XMMReg where+    show (XMMReg i) = "xmm" ++ show i+ -- TODO: instances for other registers  instance Show Reg32 where@@ -1572,6 +1578,9 @@   jmp l = do ensureBufferSize x86_max_instruction_bytes >> x86_jump32 0              emitFixup l (-4) Fixup32             +instance Jmp (Ptr a) where+  jmp ptr = ensureBufferSize x86_max_instruction_bytes >> x86_jump_pointer ptr + -- jump on condition code (branch)  class Ja a where@@ -2952,6 +2961,18 @@ fucomi (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fucomi idx fucomip (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fucomip idx +fsin = ensureBufferSize x86_max_instruction_bytes >> x86_fsin+fcos = ensureBufferSize x86_max_instruction_bytes >> x86_fcos+fptan = ensureBufferSize x86_max_instruction_bytes >> x86_fptan+fpatan = ensureBufferSize x86_max_instruction_bytes >> x86_fpatan+fabs = ensureBufferSize x86_max_instruction_bytes >> x86_fabs+ftst = ensureBufferSize x86_max_instruction_bytes >> x86_ftst+fxam = ensureBufferSize x86_max_instruction_bytes >> x86_fxam+fprem = ensureBufferSize x86_max_instruction_bytes >> x86_fprem+fprem1 = ensureBufferSize x86_max_instruction_bytes >> x86_fprem1+frndint = ensureBufferSize x86_max_instruction_bytes >> x86_frndint+fsqrt = ensureBufferSize x86_max_instruction_bytes >> x86_fsqrt+ class Fadd a b where     fadd :: a -> b -> CodeGen e s () @@ -3743,4 +3764,52 @@ instance Ucomiss XMMReg (Disp, Reg32) where     ucomiss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_ucomiss_reg_membase xd r d ++class Prefetchnta a where+    prefetchnta :: a -> CodeGen e s ()++instance Prefetchnta Addr where+    prefetchnta (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetchnta_mem a++instance Prefetchnta (Disp, Reg32) where+    prefetchnta (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetchnta_membase r d++instance Prefetchnta Ind where+    prefetchnta (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetchnta_regp r++class Prefetch0 a where+    prefetch0 :: a -> CodeGen e s ()++instance Prefetch0 Addr where+    prefetch0 (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetch0_mem a++instance Prefetch0 (Disp, Reg32) where+    prefetch0 (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetch0_membase r d++instance Prefetch0 Ind where+    prefetch0 (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetch0_regp r++class Prefetch1 a where+    prefetch1 :: a -> CodeGen e s ()++instance Prefetch1 Addr where+    prefetch1 (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetch1_mem a++instance Prefetch1 (Disp, Reg32) where+    prefetch1 (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetch1_membase r d++instance Prefetch1 Ind where+    prefetch1 (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetch1_regp r++class Prefetch2 a where+    prefetch2 :: a -> CodeGen e s ()++instance Prefetch2 Addr where+    prefetch2 (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetch2_mem a++instance Prefetch2 (Disp, Reg32) where+    prefetch2 (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetch2_membase r d++instance Prefetch2 Ind where+    prefetch2 (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_prefetch2_regp r 
Harpy/X86CodeGen.hs view
@@ -113,7 +113,7 @@     x86_ret, x86_ret_imm,     -- ** Jump and branch     x86_jecxz, x86_branch, x86_branch32, x86_branch8,-    x86_jump_membase, x86_jump_mem, x86_jump_reg, +    x86_jump_membase, x86_jump_pointer, x86_jump_mem, x86_jump_reg,      x86_jump32, x86_jump8,      x86_loopne, x86_loope, x86_loop,      -- ** Stack operations@@ -187,6 +187,10 @@     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,+    -- ** Prefetch instructions+    x86_prefetch0_mem, x86_prefetch1_mem, x86_prefetch2_mem, x86_prefetchnta_mem,+    x86_prefetch0_membase, x86_prefetch1_membase, x86_prefetch2_membase, x86_prefetchnta_membase,+    x86_prefetch0_regp, x86_prefetch1_regp, x86_prefetch2_regp, x86_prefetchnta_regp,     -- ** Miscellaneous     x86_sahf, x86_wait, x86_nop, x86_breakpoint, x86_rdtsc, x86_cld,     x86_prefix, x86_padding,@@ -786,36 +790,51 @@  -- EDX:EAX = EAX * rm +x86_mul_reg :: Word8 -> Bool -> CodeGen e s () x86_mul_reg reg is_signed =        emit8 0xf7 >> x86_reg_emit (4 + (if is_signed then 1 else 0)) reg ++x86_mul_mem :: Word32 -> Bool -> CodeGen e s () x86_mul_mem mem is_signed =        emit8 0xf7 >> x86_mem_emit (4 + (if is_signed then 1 else 0)) mem ++x86_mul_membase :: Word8 -> Word32 -> Bool -> CodeGen e s () x86_mul_membase basereg disp is_signed =           do emit8 0xf7        x86_membase_emit (4 + (if is_signed then 1 else 0)) basereg disp  -- r *= rm +x86_imul_reg_reg :: Word8 -> Word8 -> CodeGen e s () x86_imul_reg_reg dreg reg =        emit8 0x0f >> emit8 0xaf >> x86_reg_emit dreg reg ++x86_imul_reg_mem :: Word8 -> Word32 -> CodeGen e s () x86_imul_reg_mem reg mem =         emit8 0x0f >> emit8 0xaf >> x86_mem_emit reg mem  ++x86_imul_reg_membase :: Word8 -> Word8 -> Word32 -> CodeGen e s () x86_imul_reg_membase reg basereg disp =            emit8 0x0f >> emit8 0xaf >> x86_membase_emit reg basereg disp       -- dreg = rm * imm +x86_imul_reg_reg_imm :: Word8 -> Word8 -> Word32 -> CodeGen e s () x86_imul_reg_reg_imm dreg reg imm =        if x86_is_imm8 imm        then emit8 0x6b >> x86_reg_emit dreg reg >>                x86_imm_emit8 (fromIntegral imm)                else emit8 0x69 >> x86_reg_emit dreg reg >> x86_imm_emit32 imm ++x86_imul_reg_mem_imm :: Word8 -> Word32 -> Word32 -> CodeGen e s () x86_imul_reg_mem_imm reg mem imm =         if x86_is_imm8 imm        then emit8 0x6b >> x86_mem_emit reg mem >>                x86_imm_emit8 (fromIntegral imm)                else emit8 0x69 >> x86_reg_emit reg (fromIntegral mem) >>                x86_imm_emit32 imm      ++x86_imul_reg_membase_imm :: Word8 -> Word8 -> Word32 -> Word32 -> CodeGen e s () x86_imul_reg_membase_imm reg basereg disp imm =            if x86_is_imm8 imm        then emit8 0x6b >> x86_membase_emit reg basereg disp >> @@ -827,10 +846,14 @@ -- divide EDX:EAX by rm; -- eax = quotient, edx = remainder +x86_div_reg :: Word8 -> Bool -> CodeGen e s () x86_div_reg reg is_signed =        emit8 0xf7 >> x86_reg_emit (6 + (if is_signed then 1 else 0)) reg +x86_div_mem :: Word32 -> Bool -> CodeGen e s () x86_div_mem mem is_signed =        emit8 0xf7 >> x86_mem_emit (6 + (if is_signed then 1 else 0)) mem ++x86_div_membase :: Word8 -> Word32 -> Bool -> CodeGen e s () x86_div_membase basereg disp is_signed =           do emit8 0xf7        x86_membase_emit (6 + (if is_signed then 1 else 0)) basereg disp@@ -851,33 +874,53 @@          4 -> emit8 0x8b          _ -> failCodeGen (PP.text "invalid operand size")        +x86_mov_mem_reg :: (Num t) => Word32 -> Word8 -> t -> CodeGen e s () x86_mov_mem_reg mem reg size =             do x86_mov1 size ; x86_mem_emit reg mem   ++x86_mov_regp_reg :: (Num t) => Word8 -> Word8 -> t -> CodeGen e s () x86_mov_regp_reg regp reg size =           do x86_mov1 size ; x86_regp_emit reg regp++x86_mov_reg_regp :: (Num t) => Word8 -> Word8 -> t -> CodeGen e s () x86_mov_reg_regp reg regp size =           do x86_mov2 size ; x86_regp_emit reg regp++x86_mov_membase_reg :: (Num t) => Word8 -> Word32 -> Word8 -> t -> CodeGen e s () x86_mov_membase_reg basereg disp reg size =        do x86_mov1 size ; x86_membase_emit reg basereg disp      ++x86_mov_memindex_reg :: (Num t) => Word8 -> Word32 -> Word8 -> Word8 -> Word8 -> t -> CodeGen e s () x86_mov_memindex_reg basereg disp indexreg shft reg size =        do x86_mov1 size ; x86_memindex_emit reg basereg disp indexreg shft++x86_mov_reg_reg :: (Num t) => Word8 -> Word8 -> t -> CodeGen e s () x86_mov_reg_reg dreg reg size =            do x86_mov2 size        x86_reg_emit dreg reg  ++x86_mov_reg_mem :: (Num t) => Word8 -> Word32 -> t -> CodeGen e s () x86_mov_reg_mem reg mem size =             do x86_mov2 size        x86_mem_emit reg mem   ++x86_mov_reg_membase :: (Num t) => Word8 -> Word8 -> Word32 -> t -> CodeGen e s () x86_mov_reg_membase reg basereg disp size =     do x86_mov2 size        x86_membase_emit reg basereg disp      ++x86_mov_reg_memindex :: (Num t) => Word8 -> Word8 -> Word32 -> Word8 -> Word8 -> t -> CodeGen e s () x86_mov_reg_memindex _ _ _ 4 _ _ =     failCodeGen $ PP.text "x86_mov_reg_memindex: cannot use (E)SP as index register" x86_mov_reg_memindex reg basereg disp indexreg shft size =        do x86_mov2 size        x86_memindex_emit reg basereg disp indexreg  shft +x86_mov_reg_imm :: Word8 -> Word32 -> CodeGen e s () x86_mov_reg_imm reg imm =          emit8 (0xb8 + reg) >> x86_imm_emit32 imm  ++x86_mov_mem_imm :: (Num a) => Word32 -> Word32 -> a -> CodeGen e s () x86_mov_mem_imm mem imm size =             if size == 1        then do emit8 0xc6;    @@ -891,6 +934,8 @@                else do emit8 0xc7                        x86_mem_emit 0 mem                             x86_imm_emit32 imm     ++x86_mov_membase_imm :: (Num a) => Word8 -> Word32 -> Word32 -> a -> CodeGen e s () x86_mov_membase_imm basereg disp imm size =        if size == 1        then do emit8 0xc6     @@ -905,6 +950,7 @@                        x86_membase_emit 0 basereg disp                                x86_imm_emit32 imm      +x86_mov_memindex_imm :: (Num a) => Word8 -> Word32 -> Word8 -> Word8 -> Word32 -> a -> CodeGen e s () x86_mov_memindex_imm basereg disp indexreg shft imm size =        if size == 1     then do emit8 0xc6        @@ -1179,6 +1225,13 @@ x86_jump_membase basereg disp =            emit8 0xff >> x86_membase_emit 4 basereg disp      +x86_jump_pointer :: Ptr a -> CodeGen e s ()+x86_jump_pointer target =+    do inst <- getCodeOffset+       base <- getBasePtr+       let ptr = base `plusPtr` inst+       x86_jump32 (fromIntegral (target `minusPtr` ptr - 5))+ -- target is a pointer in our buffer.  {-@@ -1594,143 +1647,10 @@   -> Word8   -> Word8   -> CodeGen e s ()-x86_mul_reg ::-  Word8 -> Bool -> CodeGen e s ()-x86_mul_mem ::-  Word32 -> Bool -> CodeGen e s ()-x86_mul_membase ::-  Word8-  -> Word32-  -> Bool-  -> CodeGen e s ()-x86_imul_reg_reg ::-  Word8-  -> Word8-  -> CodeGen e s ()-x86_imul_reg_mem ::-  Word8-  -> Word32-  -> CodeGen e s ()-x86_imul_reg_membase ::-  Word8-  -> Word8-  -> Word32-  -> CodeGen e s ()-x86_imul_reg_reg_imm ::-  Word8-  -> Word8-  -> Word32-  -> CodeGen e s ()-x86_imul_reg_mem_imm ::-  Word8-  -> Word32-  -> Word32-  -> CodeGen e s ()-x86_imul_reg_membase_imm ::-  Word8-  -> Word8-  -> Word32-  -> Word32-  -> CodeGen e s ()-x86_div_reg ::-  Word8 -> Bool -> CodeGen e s ()-x86_div_mem ::-  Word32 -> Bool -> CodeGen e s ()-x86_div_membase ::-  Word8-  -> Word32-  -> Bool-  -> CodeGen e s ()-x86_mov_mem_reg ::-  (Num t) =>-  Word32-  -> Word8-  -> t-  -> CodeGen e s ()-x86_mov_regp_reg ::-  (Num t) =>-  Word8-  -> Word8-  -> t-  -> CodeGen e s ()-x86_mov_reg_regp ::-  (Num t) =>-  Word8-  -> Word8-  -> t-  -> CodeGen e s ()-x86_mov_membase_reg ::-  (Num t) =>-  Word8-  -> Word32-  -> Word8-  -> t-  -> CodeGen e s ()-x86_mov_memindex_reg ::-  (Num t) =>-  Word8-  -> Word32-  -> Word8-  -> Word8-  -> Word8-  -> t-  -> CodeGen e s ()-x86_mov_reg_reg ::-  (Num t) =>-  Word8-  -> Word8-  -> t-  -> CodeGen e s ()-x86_mov_reg_mem ::-  (Num t) =>-  Word8-  -> Word32-  -> t-  -> CodeGen e s ()-x86_mov_reg_membase ::-  (Num t) =>-  Word8-  -> Word8-  -> Word32-  -> t-  -> CodeGen e s ()-x86_mov_reg_memindex ::-  (Num t) =>-  Word8-  -> Word8-  -> Word32-  -> Word8-  -> Word8-  -> t-  -> CodeGen e s ()-x86_mov_reg_imm ::-  Word8-  -> Word32-  -> CodeGen e s ()-x86_mov_mem_imm ::-  (Num a) =>-  Word32-  -> Word32-  -> a-  -> CodeGen e s ()-x86_mov_membase_imm ::-  (Num a) =>-  Word8-  -> Word32-  -> Word32-  -> a-  -> CodeGen e s ()-x86_mov_memindex_imm ::-  (Num a) =>-  Word8-  -> Word32-  -> Word8-  -> Word8-  -> Word32-  -> a-  -> CodeGen e s () +-- ============================================================================= -- SSE instructions.+-- =============================================================================  data X86_SSE_PFX = X86_SSE_SD                  | X86_SSE_SS@@ -2009,4 +1929,63 @@     do emit8 0x0f        emit8 0x2e        x86_membase_emit dreg basereg disp++-- =============================================================================+-- Prefetching instructions.+-- =============================================================================++x86_prefetch0_mem :: Word32 -> CodeGen e s ()+x86_prefetch0_mem m = x86_prefetch_mem 1 m++x86_prefetch1_mem :: Word32 -> CodeGen e s ()+x86_prefetch1_mem m = x86_prefetch_mem 2 m++x86_prefetch2_mem :: Word32 -> CodeGen e s ()+x86_prefetch2_mem m = x86_prefetch_mem 3 m++x86_prefetchnta_mem :: Word32 -> CodeGen e s ()+x86_prefetchnta_mem m = x86_prefetch_mem 0 m++x86_prefetch_mem :: Word8 -> Word32 -> CodeGen e s ()+x86_prefetch_mem hint disp =+    do emit8 0x0f+       emit8 0x18+       x86_address_byte 0 hint 0 +       x86_imm_emit32 disp++x86_prefetch0_membase :: Word8 -> Word32 -> CodeGen e s ()+x86_prefetch0_membase r m = x86_prefetch_membase 1 r m++x86_prefetch1_membase :: Word8 -> Word32 -> CodeGen e s ()+x86_prefetch1_membase r m = x86_prefetch_membase 2 r m++x86_prefetch2_membase :: Word8 -> Word32 -> CodeGen e s ()+x86_prefetch2_membase r m = x86_prefetch_membase 3 r m++x86_prefetchnta_membase :: Word8 -> Word32 -> CodeGen e s ()+x86_prefetchnta_membase r m = x86_prefetch_membase 0 r m++x86_prefetch_membase :: Word8 -> Word8 -> Word32 -> CodeGen e s ()+x86_prefetch_membase hint reg disp =+    do emit8 0x0f+       emit8 0x18+       x86_membase_emit hint reg disp++x86_prefetch0_regp :: Word8 -> CodeGen e s ()+x86_prefetch0_regp r = x86_prefetch_regp 1 r++x86_prefetch1_regp :: Word8 -> CodeGen e s ()+x86_prefetch1_regp r = x86_prefetch_regp 2 r++x86_prefetch2_regp :: Word8 -> CodeGen e s ()+x86_prefetch2_regp r = x86_prefetch_regp 3 r++x86_prefetchnta_regp :: Word8 -> CodeGen e s ()+x86_prefetchnta_regp r = x86_prefetch_regp 0 r++x86_prefetch_regp :: Word8 -> Word8 -> CodeGen e s ()+x86_prefetch_regp hint reg =+    do emit8 0x0f+       emit8 0x18+       x86_regp_emit hint reg 
Harpy/X86Disassembler.hs view
@@ -490,7 +490,7 @@ 	    | XOR 	    | XORPD 	    | XORPS-  deriving (Show)+  deriving (Show, Eq)  -- Display an opcode in lower case. @@ -534,6 +534,7 @@        		 -- ^ Scaled index with displacement               | OpBaseIndexDisp String String Int Int InstrOperandSize        		 -- ^ Base plus scaled index with displacement+  deriving (Eq)  -- Show an operand in AT&T style. @@ -597,7 +598,7 @@        	        | OPF32	       -- ^ 32-bit floating point operand        	        | OPF64	       -- ^ 64-bit floating point operand        	        | OPF80	       -- ^ 80-bit floating point operand-  deriving (Show)+  deriving (Show, Eq)   -- | The disassembly routines return lists of the following datatype.  It@@ -615,6 +616,7 @@                   address :: Int,             -- ^ Start address of instruction        		  bytes ::[Word8]	      -- ^ Instruction bytes                  }			      -- ^ Valid instruction+  deriving (Eq)  instance Show Instruction where     show = showIntel@@ -779,16 +781,16 @@  disassembleBlock :: Ptr Word8 -> Int -> IO (Either ParseError [Instruction]) disassembleBlock ptr len = do-  l <- toList ptr len 0+  l <- toList ptr len 0 []   parseInstructions -    defaultState{startAddr = fromIntegral (minusPtr ptr nullPtr)} l+    defaultState{startAddr = fromIntegral (minusPtr ptr nullPtr)} (reverse l)   where -  toList :: (Ptr Word8) -> Int -> Int -> IO [Word8]-  toList ptr len idx | idx < len =+  toList :: (Ptr Word8) -> Int -> Int -> [Word8] -> IO [Word8]+  toList ptr len idx acc | idx < len =        	   do p <- peekByteOff ptr idx-       	      r <- toList ptr len (idx + 1)-       	      return (p : r)-  toList ptr len idx | idx >= len = return []+       	      toList ptr len (idx + 1) (p : acc)+--       	      return (p : r)+  toList ptr len idx acc | idx >= len = return acc  -- | Disassemble the contents of the given array. @@ -870,7 +872,8 @@     input <- getInput     st <- getState     setState st{operandBitMode = defaultBitMode st,-                 addressBitMode = defaultBitMode st}+                 addressBitMode = defaultBitMode st,+               prefixes = []}     many parsePrefix     b <- anyWord8     case lookup b oneByteOpCodeMap of@@ -1503,12 +1506,27 @@     0 -> case rm of             4 -> do  	     (s, i, b) <- parseSIB-       	     case i of-       	       4 -> return (OpInd (addregnames !! fromIntegral b) opsize,+       	     case (i, b) of+               (4, 5) -> do+                           disp <- anyWord32+                           return (OpAddr (fromIntegral disp) opsize,+                                          OpReg (opregnames !! fromIntegral reg_opc)+                                                (fromIntegral reg_opc),+                                          mod, reg_opc, rm)+               (_, 5) -> do+                           disp <- anyWord32+                           return (OpIndexDisp (addregnames !! fromIntegral i)+                                               (scaleToFactor s)+                                               (fromIntegral disp)+                                               opsize,+                                   OpReg (opregnames !! fromIntegral reg_opc)+                                         (fromIntegral reg_opc),+                                   mod, reg_opc, rm)+       	       (4, _) -> return (OpInd (addregnames !! fromIntegral b) opsize,        	                   OpReg (opregnames !! fromIntegral reg_opc) 			     (fromIntegral reg_opc),        		           mod, reg_opc, rm)-       	       _ -> return (OpBaseIndex +       	       (_ ,_) -> return (OpBaseIndex         		              (addregnames !! fromIntegral b)        	                      (addregnames !! fromIntegral i)        		              (scaleToFactor (fromIntegral s))
NEWS view
@@ -1,6 +1,30 @@ 							-*-outline-*- * Harpy NEWS +** New in version 0.4.1++*** New Instances++- Many of Harpy's types are now instances of Eq.++*** New instructions++- Added support for the prefetching instructions PREFETCH0, PREFETCH1,+  PREFETCH2 and PREFETCHNTA.++*** Bug fixes++- Harpy.X86Disassembler.disassembleBloc was too strict and caused+  stack overflows for large inputs.  This was fixed.++- Disassembler: The instruction prefix list was not cleared when+  beginning to parse a new instruction.  This caused incorrect+  disassembly of SSE instructions.++- Disassembler: A bug has been fixed in the parsing routine for the+  addressing mode "scaled index + 32 bit offset" without base+  register.+ ** New in version 0.4  - New convenience top-level module "Harpy", which re-exports
doc/larger-tutorial.lhs view
@@ -16,7 +16,7 @@ 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+This document is written as a literate Haskell program, so you can compile and run it without any modifications.   \end{abstract} @@ -305,7 +305,7 @@  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.+points in using the library.  Happy Harpy Hacking in Haskell! 
doc/tutorial.lhs view
@@ -38,7 +38,7 @@ step by step an assembler implementation of the factorial function, and show how assembler code can be called from ordinary Haskell code. -This document is written as a litarate Haskell program, so you can compile and run it+This document is written as a literate Haskell program, so you can compile and run it without any modifications. } 
+ examples/evaluator/README view
@@ -0,0 +1,21 @@+The three modules contained in this directory contain an evaluator+for arithmetic expressions.++Load it into ghci using the command++  ghci -XTemplateHaskell Evaluator.hs++or compile it with++  ghc --make -XTemplateHaskell Evaluator.hs++and start it with++  ./Evaluator++Then type the command++  :help++and start playing with it.+
harpy.cabal view
@@ -1,6 +1,7 @@ Cabal-version:  >=1.2+Build-type: Simple Name:           harpy-Version:        0.4+Version:        0.4.1 License:        GPL License-file:   COPYING Author:         Dirk Kleeblatt <klee@cs.tu-berlin.de>