Commit bbf17d89 authored by sewardj's avatar sewardj

[project @ 2000-06-29 13:51:38 by sewardj]

Add the x86 annotator part of cacheprof as a new nofib test.
parent ed373a79
{------------------------------------------------------------------------}
{--- Beginnings of X86 specific stuff Arch_X86.hs ---}
{------------------------------------------------------------------------}
{-
This file is part of Cacheprof, a profiling tool for finding
sources of cache misses in programs.
Copyright (C) 1999 Julian Seward (jseward@acm.org)
Home page: http://www.cacheprof.org
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA.
The GNU General Public License is contained in the file LICENSE.
-}
module Arch_x86 (
Opcode(..),
OperandInfo(..),
OperandEffect(..),
x86info,
nonJumpyOpcodes
)
where
data Opcode
= O_movl | O_movw | O_movb
| O_movzbw | O_movzbl | O_movzwl
| O_movsbw | O_movsbl | O_movswl
| O_pushl | O_popl
| O_pushfl | O_popfl
| O_notl | O_notw | O_notb
| O_sall | O_salw | O_salb
| O_sarl | O_sarw | O_sarb
| O_shrl | O_shrw | O_shrb
| O_roll | O_rolw | O_rolb
| O_rorl | O_rorw | O_rorb
| O_shldl | O_shrdl
| O_addl | O_addw | O_addb
| O_adcl
| O_subl | O_subw | O_subb
| O_sbbl
| O_imull | O_imulw | O_imulb
| O_mull
| O_divl | O_divw | O_divb
| O_idivl
| O_xorl | O_xorw | O_xorb
| O_andl | O_andw | O_andb
| O_orl | O_orw | O_orb
| O_incl | O_incw | O_incb
| O_decl | O_decw | O_decb
| O_negl | O_negw | O_negb
| O_testl | O_testw | O_testb
| O_leal
| O_cmpl | O_cmpw | O_cmpb
| O_cmpsb
| O_scasb
| O_movsl | O_movsw | O_movsb
| O_stosl | O_stosw | O_stosb
| O_leave | O_ret | O_call | O_jmp
| O_je | O_jne
| O_jl | O_jle
| O_jg | O_jge
| O_js | O_jns
| O_jz | O_jnz
| O_jc | O_jnc
| O_jo | O_jno
| O_ja | O_jae
| O_jb | O_jbe
| O_jp
| O_seta | O_setae
| O_setb | O_setbe
| O_sete | O_setne
| O_setl | O_setle
| O_setg | O_setge
| O_setc | O_setcb
| O_btl | O_btsl | O_btrl | O_btcl
| O_cld
| O_cltd
| O_cwtl
| O_cbtw
| O_rep | O_repz | O_repnz
| O_fild | O_fildl | O_fildll
| O_fsubp | O_fsubr | O_fsubrp | O_fsubrl | O_fsubrs
| O_fsubs | O_fsubl | O_fsub
| O_faddp | O_fadds | O_faddl | O_fadd | O_fiaddl
| O_fmul | O_fmuls | O_fmull | O_fmulp
| O_fimull
| O_fdiv | O_fdivp | O_fdivr | O_fdivrs | O_fdivrl | O_fdivrp
| O_fidivl | O_fidivrl | O_fdivl | O_fdivs
| O_fprem -- remainder (st(0) / st(1))
| O_fstp | O_fsts | O_fstps | O_fstl | O_fstpl | O_fstpt | O_fst
| O_fistl | O_fistpl | O_fistpll -- store (int)st(0)
| O_fld
| O_flds
| O_fldl
| O_fldt
| O_fldz | O_fld1 | O_fldl2e | O_fldln2
| O_fchs
| O_fsin | O_fcos | O_fptan | O_fsqrt | O_fpatan | O_fabs
| O_f2xm1 | O_fscale | O_fyl2x
| O_fucom | O_fucomp | O_fucompp
| O_fcomp | O_fcompp | O_fcoml | O_fcompl | O_ficompl
| O_fcoms | O_fcom | O_fcomps
| O_fnstsw -- store FP status word
| O_fnstcw -- store FP control word
| O_fldcw -- load FP control word
| O_frndint -- round ST(0) to nearest int
| O_fxch
| O_sahf -- store AH into flags
| O_nop
deriving (Show, Eq)
x86info :: [(Opcode, OperandInfo)]
x86info
= [
(O_movl, OI [OE_RW 4 4]),
(O_movw, OI [OE_RW 2 2]),
(O_movb, OI [OE_RW 1 1]),
(O_movzbw, OI [OE_RW 1 2]),
(O_movzbl, OI [OE_RW 1 4]),
(O_movzwl, OI [OE_RW 2 4]),
(O_movsbw, OI [OE_RW 1 2]),
(O_movsbl, OI [OE_RW 1 4]),
(O_movswl, OI [OE_RW 2 4]),
(O_pushl, OI_Special),
(O_popl, OI_Special),
(O_pushfl, OI_Error), -- only generated by simplify?
(O_popfl, OI_Error), -- only generated by simplify?
(O_sall, OI [OE_RM 1 4]),
(O_salw, OI [OE_RM 1 2]),
(O_salb, OI [OE_RM 1 1]),
(O_sarl, OI [OE_RM 1 4]),
(O_sarw, OI [OE_RM 1 2]),
(O_sarb, OI [OE_RM 1 1]),
(O_shrl, OI [OE_RM 1 4]),
(O_shrw, OI [OE_RM 1 2]),
(O_shrb, OI [OE_RM 1 1]),
(O_roll, OI [OE_RM 1 4]),
(O_rolw, OI [OE_RM 1 2]),
(O_rolb, OI [OE_RM 1 1]),
(O_rorl, OI [OE_RM 1 4]),
(O_rorw, OI [OE_RM 1 2]),
(O_rorb, OI [OE_RM 1 1]),
(O_shldl, OI [OE_RRM 4 4 4, OE_RM 4 4]), -- dubious
(O_shrdl, OI [OE_RRM 4 4 4, OE_RM 4 4]), -- equally dubious
(O_addl, OI [OE_RM 4 4]),
(O_addw, OI [OE_RM 2 2]),
(O_addb, OI [OE_RM 1 1]),
(O_adcl, OI [OE_RM 4 4]),
(O_subl, OI [OE_RM 4 4]),
(O_subw, OI [OE_RM 2 2]),
(O_subb, OI [OE_RM 1 1]),
(O_sbbl, OI [OE_RM 4 4]), -- check this!
(O_imull, OI [OE_M 4, OE_RM 4 4, OE_RRM 4 4 4]), -- dubious
(O_imulb, OI [OE_M 1]), -- dubious
(O_imulw, OI [OE_M 2, OE_RM 2 2]), -- dubious
(O_mull, OI [OE_M 4]), -- dubious
(O_idivl, OI [OE_M 4]),
(O_divl, OI [OE_M 4]),
(O_divw, OI [OE_M 2]),
(O_divb, OI [OE_M 1]),
(O_xorl, OI [OE_RM 4 4]),
(O_xorw, OI [OE_RM 2 2]),
(O_xorb, OI [OE_RM 1 1]),
(O_andl, OI [OE_RM 4 4]),
(O_andw, OI [OE_RM 2 2]),
(O_andb, OI [OE_RM 1 1]),
(O_orl, OI [OE_RM 4 4]),
(O_orw, OI [OE_RM 2 2]),
(O_orb, OI [OE_RM 1 1]),
(O_incl, OI [OE_M 4]),
(O_incw, OI [OE_M 2]),
(O_incb, OI [OE_M 1]),
(O_decl, OI [OE_M 4]),
(O_decw, OI [OE_M 2]),
(O_decb, OI [OE_M 1]),
(O_negl, OI [OE_M 4]),
(O_negw, OI [OE_M 2]),
(O_negb, OI [OE_M 1]),
(O_notl, OI [OE_M 4]),
(O_notw, OI [OE_M 2]),
(O_notb, OI [OE_M 1]),
(O_testl, OI [OE_RR 4 4]),
(O_testw, OI [OE_RR 2 2]),
(O_testb, OI [OE_RR 1 1]),
(O_leal, OI [OE_nW 4]),
(O_cmpl, OI [OE_RR 4 4]),
(O_cmpw, OI [OE_RR 2 2]),
(O_cmpb, OI [OE_RR 1 1]),
(O_cmpsb, OI_Special), -- really is
(O_scasb, OI_Special), -- really is
(O_movsl, OI_Special),
(O_movsw, OI_Special),
(O_movsb, OI_Special),
(O_stosl, OI_Special),
(O_stosw, OI_Special),
(O_stosb, OI_Special),
(O_leave, OI_Error),
(O_ret, OI_Special),
(O_call, OI_Special),
(O_jmp, OI_Jumpy),
(O_je, OI_Jumpy),
(O_jne, OI_Jumpy),
(O_jl, OI_Jumpy),
(O_jle, OI_Jumpy),
(O_jg, OI_Jumpy),
(O_jge, OI_Jumpy),
(O_js, OI_Jumpy),
(O_jns, OI_Jumpy),
(O_jz, OI_Jumpy),
(O_jnz, OI_Jumpy),
(O_jc, OI_Jumpy),
(O_jnc, OI_Jumpy),
(O_jo, OI_Jumpy),
(O_jno, OI_Jumpy),
(O_ja, OI_Jumpy),
(O_jae, OI_Jumpy),
(O_jb, OI_Jumpy),
(O_jbe, OI_Jumpy),
(O_jp, OI_Jumpy),
(O_seta, OI [OE_W 1]),
(O_setae, OI [OE_W 1]),
(O_setb, OI [OE_W 1]),
(O_setbe, OI [OE_W 1]),
(O_sete, OI [OE_W 1]), -- check
(O_setne, OI [OE_W 1]),
(O_setl, OI [OE_W 1]), -- check
(O_setle, OI [OE_W 1]), -- check
(O_setg, OI [OE_W 1]), -- check
(O_setge, OI [OE_W 1]), -- check
(O_setc, OI [OE_W 1]), -- check
(O_setcb, OI [OE_W 1]), -- check
(O_btl, OI [OE_RR 4 4]), -- check
(O_btsl, OI [OE_RM 4 4]), -- check
(O_btcl, OI [OE_RM 4 4]), -- check
(O_btrl, OI [OE_RM 4 4]), -- check
(O_cld, OI_NoEffect), -- dubious
(O_cltd, OI_NoEffect), -- dubious
(O_cwtl, OI_NoEffect), -- dubious
(O_cbtw, OI_NoEffect), -- dubious
(O_rep, OI_Error),
(O_repz, OI_Error),
(O_repnz, OI_Error),
(O_fld, OI [OE_R 8]), -- very dubious
(O_fldt, OI [OE_R 8]), -- very dubious
(O_fldl, OI [OE_R 8]), -- dubious
(O_flds, OI [OE_R 4]), -- dubious
(O_fild, OI [OE_R 4]), -- or is it OE_R 2
(O_fildl, OI [OE_R 4]), -- dubious
(O_fildll, OI [OE_R 8]),
(O_fstl, OI [OE_W 8]), -- dubious
(O_fstpl, OI [OE_W 8]), -- dubious
(O_fstp, OI [OE_W 8]), -- dubious
(O_fstps, OI [OE_W 4]), -- dubious
(O_fsts, OI [OE_W 4]), -- dubious
(O_fstpt, OI [OE_W 8]), -- dubious
(O_fistl, OI [OE_W 4]), -- dubious
(O_fistpl, OI [OE_W 4]), -- dubious
(O_fistpll, OI [OE_W 8]), -- dubious
(O_fst, OI [OE_W 8]), -- dubious
(O_fldz, OI_NoEffect), -- dubious
(O_fld1, OI_NoEffect), -- dubious
(O_fldl2e, OI_NoEffect),
(O_fldln2, OI_NoEffect),
(O_fchs, OI_NoEffect),
(O_fsin, OI_NoEffect),
(O_fcos, OI_NoEffect),
(O_fptan, OI_NoEffect),
(O_fsqrt, OI_NoEffect),
(O_fpatan, OI_NoEffect),
(O_fabs, OI_NoEffect),
(O_f2xm1, OI_NoEffect),
(O_fscale, OI_NoEffect),
(O_fyl2x, OI_NoEffect),
(O_faddp, OI [OE_R 8, OE_RM 8 8]),
(O_fadds, OI [OE_R 4]),
(O_faddl, OI [OE_R 8]),
(O_fiaddl, OI [OE_R 4]),
(O_fadd, OI [OE_R 8, OE_RM 8 8]),
(O_fsubp, OI [OE_RM 8 8]),
(O_fsubrp, OI [OE_RM 8 8]),
(O_fsubrl, OI [OE_R 8]),
(O_fsubrs, OI [OE_R 4]),
(O_fsubs, OI [OE_R 4]),
(O_fsubl, OI [OE_R 8]), -- dubious
(O_fsub, OI [OE_R 8, OE_RM 8 8]),
(O_fsubr, OI [OE_R 8, OE_RM 8 8]),
(O_fmul, OI [OE_R 8, OE_RM 8 8]),
(O_fmuls, OI [OE_R 4]),
(O_fmull, OI [OE_R 8]),
(O_fmulp, OI [OE_R 8, OE_RM 8 8]),
(O_fimull, OI [OE_R 8]), -- dubious
(O_fdiv, OI [OE_RM 8 8]), -- dubious
(O_fdivp, OI [OE_RM 8 8]), -- dubious
(O_fdivr, OI [OE_RM 8 8]), -- dubious
(O_fdivrl, OI [OE_R 8]), -- haven't got a clue
(O_fdivrs, OI [OE_R 4]), -- haven't got a clue
(O_fdivrp, OI [OE_RM 8 8]), -- dubious
(O_fidivrl, OI [OE_R 4]),
(O_fidivl, OI [OE_R 4]),
(O_fdivl, OI [OE_R 8]),
(O_fdivs, OI [OE_R 4]),
(O_fprem, OI_NoEffect),
(O_fucom, OI_NoEffect), -- dubious
(O_fucomp, OI_NoEffect), -- dubious
(O_fucompp, OI_NoEffect), -- dubious
(O_fcomp, OI_NoEffect), -- dubious
(O_fcompp, OI_NoEffect), -- dubious
(O_fcoms, OI [OE_R 4]), -- dubious
(O_fcoml, OI [OE_R 8]), -- dubious
(O_fcom, OI [OE_R 8]), -- dubious
(O_fcomps, OI [OE_R 4]), -- dubious
(O_fcompl, OI [OE_R 8]), -- dubious
(O_ficompl, OI [OE_R 4]), -- dubious
(O_fnstsw, OI [OE_W 2]),
(O_fnstcw, OI [OE_W 2]),
(O_fldcw, OI [OE_R 2]),
(O_fxch, OI_NoEffect),
(O_frndint, OI_NoEffect),
(O_sahf, OI_NoEffect),
(O_nop, OI_NoEffect)
]
data OperandInfo
= OI_Special
| OI_Jumpy
| OI_NoEffect
| OI_Error
| OI [OperandEffect]
deriving (Show, Eq)
data OperandEffect
= OE_RR Int Int
| OE_RM Int Int
| OE_RW Int Int
| OE_nW Int
| OE_RRM Int Int Int
| OE_R Int
| OE_M Int
| OE_W Int
deriving (Show, Eq)
-- Only put an opcode in here if it definitely doesn't
-- cause a control flow transfer. It's safe to not put
-- stuff in here.
-- Contents are quite arbitrary, and based on looking at
-- common sequences of annotated code. Arbitrary is safe
-- because it's always safe to leave opcodes out of this list.
nonJumpyOpcodes :: [Opcode]
nonJumpyOpcodes
= [
O_pushl, O_popl
,O_movl ,O_movw ,O_movb
,O_andl ,O_andw ,O_andb
,O_orl ,O_orw ,O_orb
,O_xorl ,O_xorw ,O_xorb
,O_addl ,O_addw ,O_addb
,O_subl ,O_subw ,O_subb
,O_incl ,O_incw ,O_incb
,O_decl ,O_decw ,O_decb
,O_cmpl ,O_cmpw ,O_cmpb
,O_sall ,O_salw ,O_salb
,O_shrl ,O_shrw ,O_shrb
,O_sarl
,O_leal
,O_movzbw ,O_movzbl ,O_movzwl
,O_movsbw ,O_movsbl ,O_movswl
, O_seta , O_setae
, O_setb , O_setbe
, O_sete , O_setne
, O_setl , O_setle
, O_setg , O_setge
, O_setc , O_setcb
, O_testl , O_testw , O_testb
, O_fld1 , O_fcoml , O_fnstsw , O_fstpl
, O_fstp , O_fsubrl , O_fldl , O_faddl , O_fsubl
]
{------------------------------------------------------------------------}
{--- end Arch_X86.hs ---}
{------------------------------------------------------------------------}
This diff is collapsed.
{------------------------------------------------------------------------}
{--- Generic stuff for all architectures. Generics.hs ---}
{------------------------------------------------------------------------}
{-
This file is part of Cacheprof, a profiling tool for finding
sources of cache misses in programs.
Copyright (C) 1999 Julian Seward (jseward@acm.org)
Home page: http://www.cacheprof.org
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA.
The GNU General Public License is contained in the file LICENSE.
-}
module Generics where
internal msg
= error ("\ncacheann: Internal error: " ++ msg ++ "\n")
incomplete msg
= error ("\ncacheann: Unhandled instruction set artefact:\n "
++ msg ++ "\n")
inputerr msg
= error ("\ncacheann: Bad input: " ++ msg ++ "\n")
{-----------------------------------------------------------}
{--- A data type for lexemes ---}
{-----------------------------------------------------------}
{- In here, LReg, LLiteral and LName are arch/syntax
specific, but I don't think this matters, so long
as the arch-specific lexer produces the Right Things.
Note that lexers themselves are arch/syntax
specific.
-}
data Lex
= LReg String -- a register name eg "%eax"
| LNum String -- a number "456"
| LLiteral String -- a literal value "$12"
| LName String -- a name "fprintf"
| LLabel String -- a label ".L3345"
| LComma
| LLParen
| LRParen
| LPlus
| LMinus
| LStar
| LDollar
deriving (Show, Eq)
unLReg (LReg s) = s
isLReg lx = case lx of { LReg _ -> True; _ -> False }
unLNum (LNum s) = s
isLNum lx = case lx of { LNum _ -> True; _ -> False }
unLLiteral (LLiteral s) = s
isLLiteral lx = case lx of { LLiteral _ -> True; _ -> False }
unLName (LName s) = s
isLName lx = case lx of { LName _ -> True; _ -> False }
unLLabel (LLabel s) = s
isLLabel lx = case lx of { LLabel _ -> True; _ -> False }
{-----------------------------------------------------------}
{--- Combinator parser generics -- building blocks for ---}
{--- parsers ---}
{-----------------------------------------------------------}
data PResult a
= PFail
| POk a [Lex]
deriving Show
type Parser a = [Lex] -> PResult a
pEmpty :: a -> Parser a
pEmpty x ts = POk x ts
pSat :: (Lex -> Bool) -> Parser Lex
pSat p [] = PFail
pSat p (t:ts) = if p t then POk t ts else PFail
pApply :: (a -> b) -> Parser a -> Parser b
pApply f p ts
= case p ts of
PFail -> PFail
POk x uu -> POk (f x) uu
pName :: String -> a -> Parser a
pName w x ((LName w2):lxs)
= if w == w2 then POk x lxs else PFail
pName w x _ = PFail
p2 :: (a -> b -> c)
-> Parser a -> Parser b -> Parser c
p2 f p1 p2 ts1
= case p1 ts1 of { PFail -> PFail ; POk x1 uu1 ->
case p2 uu1 of { PFail -> PFail ; POk x2 uu2 ->
POk (f x1 x2) uu2
}}
p3 :: (a -> b -> c -> d)
-> Parser a -> Parser b -> Parser c -> Parser d
p3 f p1 p2 p3 ts1
= case p1 ts1 of { PFail -> PFail ; POk x1 uu1 ->
case p2 uu1 of { PFail -> PFail ; POk x2 uu2 ->
case p3 uu2 of { PFail -> PFail ; POk x3 uu3 ->
POk (f x1 x2 x3) uu3
}}}
pStar :: Parser a -> Parser [a]
pStar p ts
= case p ts of
PFail -> POk [] ts
POk x uu1 -> case pStar p uu1 of
POk xs uu2 -> POk (x:xs) uu2
PFail -> internal "pStar failed"
pPlus :: Parser a -> Parser [a]
pPlus p = p2 (:) p (pStar p)
pAlt2 :: Parser a -> Parser a -> Parser a
pAlt2 p1 p2 ts
= case p1 ts of
POk x1 uu -> POk x1 uu
PFail -> p2 ts
pAlts :: [Parser a] -> Parser a
pAlts = foldl1 pAlt2
pOpt :: Parser a -> Parser (Maybe a)
pOpt p ts
= case p ts of
PFail -> POk Nothing ts
POk x uu -> POk (Just x) uu
pStarComma p
= pAlts [
p2 (\xs y -> xs++[y]) (pPlus (p2 (\x y -> x) p pLComma)) p,
pApply (\x -> [x]) p,
pEmpty []
]
pLComma = pSat (== LComma)
pLMinus = pSat (== LMinus)
pLPlus = pSat (== LPlus)
pLLParen = pSat (== LLParen)
pLRParen = pSat (== LRParen)
pLStar = pSat (== LStar)
pLDollar = pSat (== LDollar)
pInParens p = p3 (\_ r _ -> r) pLLParen p pLRParen
pPreComma p = p2 (\_ r -> r) pLComma p
pPreCommaOpt p = p2 (\_ r -> r) (pOpt pLComma) p