-- parsing --
-instruction :: [DictLabel] -> Parser Word32
+instruction :: Dict -> Parser Word32
instruction dict = foldl1 (<|>) (fmap (\x -> try (x dict)) instructions) <* char '\n'
testins :: String -> IO ()
Left err -> do { putStr "fail :/\n"; print err}
Right x -> do { printf "0x%08X\n" x }
where
- dict = [("lolz", 0x1337), ("rofl", 0xaaaa)]
+ dict = (0x8000,[("lolz", 0x1337), ("rofl", 0xaaaa)])
comma = char ','
mnem m = string m
-iLabel :: [DictLabel] -> Parser Word32
-iLabel dict = do
+iLabel :: Dict -> Parser Word32
+iLabel (addr,dict) = do
s <- foldl1 (<|>) (fmap (try . string . fst) dict)
- let (Just ret) = get_label s dict
- return ret
+ let lab = get_elem s dict
+ return $ ((lab - addr) .&. 0xefff)
iLit :: Parser Word32
iLit = do { parseMySpaces; ret <- liftM read (many1 digit); parseMySpaces; return ret}
infixl 1 <@>
ins m form e = do {mnem m; form e}
-csv0i_sp dict f = f<$>sign<*>condition<*>branchpred<*>(iLabel dict)
-csv0i_sp' f = f<$>sign<*>condition<*>branchpred
+csv0i_p dict f = f<$>condition<*>branchpred<*>(iLabel dict)
+csv0i_p' f = f<$>condition<*>branchpred
csv2_scd f = f<$>sign<*>carry<*>updateDisable<*>condition<%>reg<.>reg
csv2m f = f<$>condition<%>reg<.>iLit15<@>reg
csv2i_scd f = f<$>sign<*>carry<*>updateDisable<*>condition<%>reg<.>reg<.>iLit12
-- ldx, stx
-- call, reti
br, ret
- -- brreg
+ -- brr, callr
-- cmp, cmpi
]
ldw _ = ins "ldw" csv2m $ mformi 0x0e
ldi _ = ins "ldi" csv2i_sl $ lformi' 0x1a
-- misc
-br dict = ins "br" (csv0i_sp dict) $ bform 0x16 0x0
-ret _ = ins "ret" csv0i_sp' $ bform' 0x16 0x2
+-- set signed by default! in very rare cases this can be an issue.
+br dict = ins "br" (csv0i_p dict) $ bform 0x16 0x0 1
+ret _ = ins "ret" csv0i_p' $ bform' 0x16 0x2
+reti _ = ins "reti" csv0i_p' $ bform' 0x16 0x3
-- instruction formats
aform opcd c d cond rd ra rb = pack [(cond,28),(opcd,23),(rd,19),(ra,15),(rb,11),(free,2),(c,1),(d,0)]
bform opcd typ s cond bp imm = pack [(cond,28),(opcd,23),(imm,7),(free,4),(typ,2),(bp,1),(s,0)]
where free = 0
-bform' opcd typ s cond bp = bform opcd typ s cond bp 0
+bform' opcd typ cond bp = bform opcd typ 0 cond bp 0
-- ppc64 stuff (TODO: remove)
iform opcd aa lk li = pack [(opcd,6),(li,30),(aa,31),(lk,0)]
datins = printf "%s;%08x;%08x;%s;%s;%s\n"
-type DictLabel = (String,Word32)
+-- datastructure for managing labels and defines
+type Dict = (Address,[DictElem])
+type DictElem = (String,Word32)
-get_label :: String -> [DictLabel] -> Maybe Word32
-get_label = lookup
+get_elem :: String -> [DictElem] -> Word32
+get_elem s dict = case (lookup s dict) of
+ Nothing -> error ("unknown label or define: \"" ++ s ++ "\"")
+ Just z -> z
-add_label :: [DictLabel] -> (String,Word32) -> [DictLabel]
-add_label dic (s,w)
+add_elem :: [DictElem] -> (String,Word32) -> [DictElem]
+add_elem dic (s,w)
| s == "" = dic -- ignore empty string
- | already_in = error ("Label " ++ s ++ " already exists")
+ | already_in = error ("Label or define \"" ++ s ++ "\" already exists")
| otherwise = (s,w):dic
where
- already_in = case (get_label s dic) of
+ already_in = case (lookup s dic) of
Just _ -> True
Nothing -> False
sequence_ [printf "%s" (show x) | x <- parsed]
-parseInstr :: [DictLabel] -> [DTF] -> [DTF]
+parseInstr :: [DictElem] -> [DTF] -> [DTF]
parseInstr _ [] = []
parseInstr dict ((DTF_InstrToParse a instr c l s):xs) =
(DTF_Instr a bytecode c l s):(parseInstr dict xs)
where
- bytecode = case (parse (instruction dict) "" (instr++"\n")) of
+ bytecode = case (parse (instruction (a,dict)) "" (instr++"\n")) of
Left err -> error ("couldn't parse Instruction: " ++ instr ++ "\n" ++ show err)
Right x -> x
parseInstr dict (x:xs) = x:(parseInstr dict xs)
inc = ((+) 4)
-convertDTF :: [(Int,String)] -> DT_State -> Counter -> Counter -> [DictLabel] -> ([DictLabel], [DTF])
+convertDTF :: [(Int,String)] -> DT_State -> Counter -> Counter -> [DictElem] -> ([DictElem], [DTF])
convertDTF [] _ _ _ d = (d,[])
convertDTF ((lno,str):xs) state datacnt instrcnt dict = (newdict, (actlist newdtf))
where
nstate (DTF_State s) = s
nstate _ = state
- ndict (DTF_Label l _ a) = dict `add_label` (l,a)
- ndict (DTF_SectionToDet a _ _ l _) = dict `add_label` (l,a)
- ndict (DTF_InstrToParse a _ _ l _) = dict `add_label` (l,a)
- ndict (DTF_Data a _ _ l _) = dict `add_label` (l,a)
- ndict (DTF_Instr a _ _ l _) = dict `add_label` (l,a)
+ ndict (DTF_Label l _ a) = dict `add_elem` (l,a)
+ ndict (DTF_SectionToDet a _ _ l _) = dict `add_elem` (l,a)
+ ndict (DTF_InstrToParse a _ _ l _) = dict `add_elem` (l,a)
+ ndict (DTF_Data a _ _ l _) = dict `add_elem` (l,a)
+ ndict (DTF_Instr a _ _ l _) = dict `add_elem` (l,a)
ndict _ = dict
newdtf = case (parse parseDTFLine "" (str++"\n")) of