summaryrefslogtreecommitdiff
path: root/SHARC/ComputeField.hs
diff options
context:
space:
mode:
Diffstat (limited to 'SHARC/ComputeField.hs')
-rw-r--r--SHARC/ComputeField.hs210
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
+ ]