diff options
Diffstat (limited to 'SHARC/ComputeField.hs')
-rw-r--r-- | SHARC/ComputeField.hs | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/SHARC/ComputeField.hs b/SHARC/ComputeField.hs new file mode 100644 index 0000000..d82d75f --- /dev/null +++ b/SHARC/ComputeField.hs @@ -0,0 +1,210 @@ +{- + This file is part of shark-disassembler. + + Copyright (C) 2014 Ricardo Wurmus + + 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 3 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, see <http://www.gnu.org/licenses/>. +-} + +{-# LANGUAGE QuasiQuotes #-} + +module SHARC.ComputeField where + +import SHARC.Types +import SHARC.Word48 + +import Language.Literals.Binary +import Data.Map (fromList, findWithDefault) +import Data.Word (Word8, Word16, Word64) +import Data.Bits ((.&.), (.|.), shift, shiftL, shiftR) +import Text.Printf (printf) + +{- +The Compute Field + +See page 6-1 for full description. + +The compute field of an instruction is 23 bit wide and structured like this: + +1 unused bit +2 CU bits (00=ALU, 01=Multiplier, 10=Shifter) +8 bit opcode +3 register addresses (result, x operand, y operand), each 4 bit wide +-} + +-- 23 bit compute field +data ComputeField = ComputeField + { compFieldCU :: ComputationUnit + , compFieldOpCode :: OpCode + , compFieldRn :: Dreg + , compFieldRx :: Dreg + , compFieldRy :: Dreg + } + +data ComputationUnit = ALU | Multiplier | Shifter deriving Show +type OpCode = Word8 + +mkComputeField :: Word48 -> ComputeField +mkComputeField w = ComputeField cu op rn rx ry + where + word64 = word48ToWord64 w + w' = word64 `cutMask` 0x000000FFFFFF + cu = case w' `cutMask` [b| 011 0000 0000 0000 0000 0000 |] of + 0 -> ALU + 1 -> Multiplier + 2 -> Shifter + op = w' `cutMask` [b| 000 1111 1111 0000 0000 0000 |] + rn = mkDreg $ w' `cutMask` [b| 000 0000 0000 1111 0000 0000 |] + rx = mkDreg $ w' `cutMask` [b| 000 0000 0000 0000 1111 0000 |] + ry = mkDreg $ w' `cutMask` [b| 000 0000 0000 0000 0000 1111 |] + +instance Show ComputeField where + show cf = printer rn rx ry + where + dict = case compFieldCU cf of + ALU -> opCodesALU + Multiplier -> opCodesMultiplier + Shifter -> opCodesShifter + rn = show (compFieldRn cf) + rx = show (compFieldRx cf) + ry = show (compFieldRy cf) + def = rawPrintCF (show (compFieldCU cf)) (compFieldOpCode cf) + rawPrintCF cu op rn rx ry = printf "[%s] %s = %s [0x%02X] %s" cu rn rx op ry + printer = findWithDefault def (compFieldOpCode cf) dict + +-- special type for Type 6 instruction +type ShiftOp = Word8 +data ImmediateShift = ImmediateShift + ShiftOp {-6 bits-} + Word16 {-dependent on shiftop: either 6 bit shift value + 6 bit length; or 8 bit value-} + Dreg {-4 bit Rn register-} + Dreg {-4 bit Rx register-} + +-- TODO +instance Show ImmediateShift where + show (ImmediateShift op dat rn rx) = + "[" ++ show rn ++ " = " ++ printf "0x%02X" op ++ " " ++ show rx ++ " data:" ++ printf "0x%02X" dat ++ "]" + + + +opCodesALU = fromList + -- fixed point ALU operations (table 6-1) + [ (0, \n x y -> "") -- print nothing if the opcode is empty + , ([b| 0000 0001 |], \n x y -> n ++ " = " ++ x ++ " + " ++ y) -- Rn = Rx + Ry + , ([b| 0000 0010 |], \n x y -> n ++ " = " ++ x ++ " - " ++ y) -- Rn = Rx – Ry + , ([b| 0000 0101 |], \n x y -> n ++ " = " ++ x ++ " + " ++ y ++ " + CI") -- Rn = Rx + Ry + CI + , ([b| 0000 0110 |], \n x y -> n ++ " = " ++ x ++ " - " ++ y ++ " + CI - 1") -- Rn = Rx – Ry + CI – 1 + , ([b| 0000 1001 |], \n x y -> n ++ " = (" ++ x ++ " + " ++ y ++ ")/2") -- Rn = (Rx + Ry)/2 + , ([b| 0000 1010 |], \n x y -> "COMP(" ++ x ++ ", " ++ y ++ ")") -- COMP(Rx, Ry) + , ([b| 0000 1011 |], \n x y -> "COMPU(" ++ x ++ ", " ++ y ++ ")") -- COMPU(Rx, Ry) + , ([b| 0010 0101 |], \n x y -> n ++ " = " ++ x ++ " + CI") -- Rn = Rx + CI + , ([b| 0010 0110 |], \n x y -> n ++ " = " ++ x ++ " + CI - 1") -- Rn = Rx + CI – 1 + , ([b| 0010 1001 |], \n x y -> n ++ " = " ++ x ++ " + 1") -- Rn = Rx + 1 + , ([b| 0010 1010 |], \n x y -> n ++ " = " ++ x ++ " - 1") -- Rn = Rx – 1 + , ([b| 0010 0010 |], \n x y -> n ++ " = - " ++ x) -- Rn = – Rx + , ([b| 0011 0000 |], \n x y -> n ++ " = ABS " ++ x) -- Rn = ABS Rx + , ([b| 0010 0001 |], \n x y -> n ++ " = PASS " ++ x) -- Rn = PASS Rx + , ([b| 0100 0000 |], \n x y -> n ++ " = " ++ x ++ " AND " ++ y) -- Rn = Rx AND Ry + , ([b| 0100 0001 |], \n x y -> n ++ " = " ++ x ++ " OR " ++ y) -- Rn = Rx OR Ry + , ([b| 0100 0010 |], \n x y -> n ++ " = " ++ x ++ " XOR " ++ y) -- Rn = Rx XOR Ry + , ([b| 0100 0011 |], \n x y -> n ++ " = NOT " ++ x) -- Rn = NOT Rx + , ([b| 0110 0001 |], \n x y -> n ++ " = MIN(" ++ x ++ ", " ++ y ++ ")") -- Rn = MIN(Rx, Ry) + , ([b| 0110 0010 |], \n x y -> n ++ " = MAX(" ++ x ++ ", " ++ y ++ ")") -- Rn = MAX(Rx, Ry) + , ([b| 0110 0011 |], \n x y -> n ++ " = CLIP " ++ x ++ " BY " ++ y) -- Rn = CLIP Rx BY Ry + -- floating-point ALU operations (table 6-2) + , ([b| 1000 0001 |], \n x y -> n ++ " = " ++ x ++ " + " ++ y) -- Fn = Fx + Fy + , ([b| 1000 0010 |], \n x y -> n ++ " = " ++ x ++ " - " ++ y) -- Fn = Fx – Fy + , ([b| 1001 0001 |], \n x y -> n ++ " = ABS (" ++ x ++ " + " ++ y ++ ")") -- Fn = ABS (Fx + Fy) + , ([b| 1001 0010 |], \n x y -> n ++ " = ABS (" ++ x ++ " - " ++ y ++ ")") -- Fn = ABS (Fx – Fy) + , ([b| 1000 1001 |], \n x y -> n ++ " = (" ++ x ++ " + " ++ y ++ ")/2") -- Fn = (Fx + Fy)/2 + , ([b| 1000 1010 |], \n x y -> n ++ " = COMP(" ++ x ++ ", " ++ y ++ ")") -- Fn = COMP(Fx, Fy) + , ([b| 1010 0010 |], \n x y -> n ++ " = -" ++ x) -- Fn = –Fx + , ([b| 1011 0000 |], \n x y -> n ++ " = ABS " ++ x) -- Fn = ABS Fx + , ([b| 1010 0001 |], \n x y -> n ++ " = PASS " ++ x) -- Fn = PASS Fx + , ([b| 1010 0101 |], \n x y -> n ++ " = RND " ++ x) -- Fn = RND Fx + , ([b| 1011 1101 |], \n x y -> n ++ " = SCALB " ++ x ++ " BY " ++ y) -- Fn = SCALB Fx BY Ry + , ([b| 1010 1101 |], \n x y -> n ++ " = MANT " ++ x) -- Rn = MANT Fx + , ([b| 1100 0001 |], \n x y -> n ++ " = LOGB " ++ x) -- Rn = LOGB Fx + , ([b| 1101 1001 |], \n x y -> n ++ " = FIX " ++ x ++ " BY " ++ y) -- Rn = FIX Fx BY Ry + , ([b| 1100 1001 |], \n x y -> n ++ " = FIX " ++ x) -- Rn = FIX Fx + , ([b| 1101 1101 |], \n x y -> n ++ " = TRUNC " ++ x ++ " BY " ++ y) -- Rn = TRUNC Fx BY Ry + , ([b| 1100 1101 |], \n x y -> n ++ " = TRUNC " ++ x) -- Rn = TRUNC Fx + , ([b| 1101 1010 |], \n x y -> n ++ " = FLOAT " ++ x ++ " BY " ++ y) -- Fn = FLOAT Rx BY Ry + , ([b| 1100 1010 |], \n x y -> n ++ " = FLOAT " ++ x) -- Fn = FLOAT Rx + , ([b| 1100 0100 |], \n x y -> n ++ " = RECIPS " ++ x) -- Fn = RECIPS Fx + , ([b| 1100 0101 |], \n x y -> n ++ " = RSQRTS " ++ x) -- Fn = RSQRTS Fx + , ([b| 1110 0000 |], \n x y -> n ++ " = " ++ x ++ " COPYSIGN " ++ y) -- Fn = Fx COPYSIGN Fy + , ([b| 1110 0001 |], \n x y -> n ++ " = MIN(" ++ x ++ ", " ++ y ++ ")") -- Fn = MIN(Fx, Fy) + , ([b| 1110 0010 |], \n x y -> n ++ " = MAX(" ++ x ++ ", " ++ y ++ ")") -- Fn = MAX(Fx, Fy) + , ([b| 1110 0011 |], \n x y -> n ++ " = CLIY " ++ x ++ " BY " ++ y) -- Fn = CLIP Fx BY Fy + ] + + +opCodesMultiplier = fromList [] -- TODO +{- +-- fixed-point multiplier operations (table 6-3) +-- TODO: check table 6-5 and table 6-6 for y/x/f/r flags +[b| 01yx f00r ] -- on page 6-56 -- Rn = Rx*Ry mod2 +[b| 01yx f10r ] -- on page 6-56 -- MRF = Rx*Ry mod2 +[b| 01yx f11r ] -- on page 6-56 -- MRB = Rx*Ry mod2 +[b| 10yx f00r ] -- on page 6-57 -- Rn = MRF +Rx*Ry mod2 +[b| 10yx f01r ] -- on page 6-57 -- Rn = MRB +Rx*Ry mod2 +[b| 10yx f10r ] -- on page 6-57 -- MRF = MRF +Rx*Ry mod2 +[b| 10yx f11r ] -- on page 6-57 -- MRB = MRB +Rx*Ry mod2 +[b| 11yx f00r ] -- on page 6-58 -- Rn = MRF –Rx*Ry mod2 +[b| 11yx f01r ] -- on page 6-58 -- Rn = MRB –Rx*Ry mod2 +[b| 11yx f10r ] -- on page 6-58 -- MRF = MRF –Rx*Ry mod2 +[b| 11yx f11r ] -- on page 6-58 -- MRB = MRB –Rx*Ry mod2 +[b| 0000 f00x ] -- on page 6-59 -- Rn = SAT MRF mod1 +[b| 0000 f01x ] -- on page 6-59 -- Rn = SAT MRB mod1 +[b| 0000 f10x ] -- on page 6-59 -- MRF = SAT MRF mod1 +[b| 0000 f11x ] -- on page 6-59 -- MRB = SAT MRB mod1 +[b| 0001 100x ] -- on page 6-60 -- Rn =RND MRF mod1 +[b| 0001 101x ] -- on page 6-60 -- Rn = RND MRB mod1 +[b| 0001 110x ] -- on page 6-60 -- MRF = RND MRF mod1 +[b| 0001 111x ] -- on page 6-60 -- MRB = RND MRB mod1 +[b| 0001 0100 ] -- on page 6-61 -- MRF = 0 +[b| 0001 0110r ] -- on page 6-61 -- MRB = 0 +-- MR = Rn on page 6-62 +-- Rn = MR on page 6-62 + +-- floating-point multiplier operations (table 6-4) +[b| 0011 0000 ] -- on page 6-64 -- Fn = Fx*Fy +-} + + +opCodesShifter = fromList + -- shifter operations (table 6-8) + [ ([b| 0000 0000 |], \n x y -> n ++ " = LSHIFT " ++ x ++ " BY " ++ y) -- Rn = LSHIFT Rx BY Ry|<data8> + , ([b| 0010 0000 |], \n x y -> n ++ " = OR LSHIFT " ++ x ++ " BY " ++ y) -- Rn = Rn OR LSHIFT Rx BY Ry|<data8> + , ([b| 0000 0100 |], \n x y -> n ++ " = ASHIFT " ++ x ++ " BY " ++ y) -- Rn = ASHIFT Rx BY Ry|<data8> + , ([b| 0010 0100 |], \n x y -> n ++ " = " ++ n ++ " OR ASHIFT " ++ x ++ " BY "++ y) -- Rn = Rn OR ASHIFT Rx BY Ry|<data8> + , ([b| 0000 1000 |], \n x y -> n ++ " = ROT " ++ x ++ " BY " ++ y) -- Rn = ROT Rx BY Ry|<data8> + , ([b| 1100 0100 |], \n x y -> n ++ " = BCLR " ++ x ++ " BY " ++ y) -- Rn = BCLR Rx BY Ry|<data8> + , ([b| 1100 0000 |], \n x y -> n ++ " = BSET " ++ x ++ " BY " ++ y) -- Rn = BSET Rx BY Ry|<data8> + , ([b| 1100 1000 |], \n x y -> n ++ " = BTGL " ++ x ++ " BY " ++ y) -- Rn = BTGL Rx BY Ry|<data8> + , ([b| 1100 1100 |], \n x y -> "BTST " ++ x ++ " BY " ++ y) -- BTST Rx BY Ry|<data8> + , ([b| 0100 0100 |], \n x y -> n ++ " = FDEP " ++ x ++ " BY " ++ y) -- Rn = FDEP Rx BY Ry|<bit6>:<len6> + , ([b| 0110 0100 |], \n x y -> n ++ " = " ++ n ++ " OR FDEP " ++ x ++ " BY " ++ y) -- Rn = Rn OR FDEP Rx BY Ry|<bit6>:<len6> + , ([b| 0100 1100 |], \n x y -> n ++ " = FDEP " ++ x ++ " BY " ++ y) -- Rn = FDEP Rx BY Ry|<bit6>:<len6> (SE) + , ([b| 0110 1100 |], \n x y -> n ++ " = " ++ n ++ " OR FDEP " ++ x ++ " BY " ++ y) -- Rn = Rn OR FDEP Rx BY Ry|<bit6>:<len6>(SE) + , ([b| 0100 0000 |], \n x y -> n ++ " = FEXT " ++ x ++ " BY " ++ y) -- Rn = FEXT RX BY Ry|<bit6>:<len6> + , ([b| 0100 1000 |], \n x y -> n ++ " = FEXT " ++ x ++ " BY " ++ y ++ " (SE)") -- Rn = FEXT Rx BY Ry|<bit6>:<len6> (SE) + , ([b| 1000 0000 |], \n x y -> n ++ " = EXP " ++ x) -- Rn = EXP Rx + , ([b| 1000 0100 |], \n x y -> n ++ " = EXP " ++ x ++ " (EX)") -- Rn = EXP Rx (EX) + , ([b| 1000 1000 |], \n x y -> n ++ " = LEFTZ " ++ x) -- Rn = LEFTZ Rx + , ([b| 1000 1100 |], \n x y -> n ++ " = LEFTO " ++ x) -- Rn = LEFTO Rx + , ([b| 1001 0000 |], \n x y -> n ++ " = FPACK " ++ x) -- Rn = FPACK Fx + , ([b| 1001 0100 |], \n x y -> n ++ " = FUNPACK " ++ x) -- Fn = FUNPACK Rx + ] |