📄 cachegen.hs
字号:
{------------------------------------------------------------------------}{--- Generates C code to simulate various kinds of caches. ---}{--- CacheGen.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 Main whereimport IOimport Systemvalid_sizes, valid_linesizes, valid_ways :: [Int]valid_sizes = [1024,2048,4096,8192,16384,32768,65536,131072, 262144,524288,1048576,2097152,4194304,8388608,16777216]valid_ways = [1,2,4,8]valid_linesizes = [8,16,32,64,128]powers_of_two_table :: [(Int,Int)]powers_of_two_table = [(0,1),(1,2),(2,4),(3,8),(4,16),(5,32),(6,64),(7,128),(8,256), (9,512),(10,1024),(11,2048),(12,4096),(13,8192), (14,16384),(15,32768),(16,65536),(17,131072),(18,262144), (19,524288),(20,1048576),(21,2097152),(22,4194304), (23,8388608),(24,16777216),(25,33554432),(26,67108864), (27,134217728),(28,268435456),(29,536870912),(30,1073741824)]log2 :: Int -> Intlog2 x = case [n | (n, two_to_the_n) <- powers_of_two_table, two_to_the_n == x] of [log2_x] -> log2_x other -> error "cachegen: log2"validConfig [sz, linesz, ways] = sz `elem` (map show valid_sizes) && linesz `elem` (map show valid_linesizes) && ways `elem` (map show valid_ways)main = getArgs >>= \as -> if length as /= 3 || not (validConfig as) then usage as >> exitWith (ExitFailure 1) else mkCache (map read as) >> exitWith ExitSuccessusage as = hPutStr stderr (unlines [ "usage: cachegen size line_size number_of_ways", " where", " size is one of " ++ unwords (map show (take 9 valid_sizes)), " " ++ unwords (map show (drop 9 valid_sizes)), " line_size is one of " ++ unwords (map show valid_linesizes), " number_of_ways is one of " ++ unwords (map show valid_ways), "" ]) mkCache :: [Int] -> IO ()mkCache [sz, linesz, ways] = let num_lines = sz `div` linesz num_sets = num_lines `div` ways line_bits = log2 linesz set_bits = log2 num_sets text = unlines (the_text num_sets ways line_bits set_bits sz linesz) in putStr textthe_text num_sets ways line_bits set_bits sz linesz = [ "", "/* A cache simulator, generated by cachegen.", " * total size = " ++ show sz ++ " bytes", " * line size = " ++ show linesz ++ " bytes", " * associativity = " ++ show ways ++ (if ways == 1 then " (direct-mapped)" else ""), " * This file should be #include-d into cachesim.c.", " */", "", "static UInt32 tags[" ++ show num_sets ++ "][" ++ show ways ++ "];", "", "static void cachesim_initcache ( void ) ", "{", " Int32 set, way;", " for (set = 0; set < " ++ show num_sets ++ "; set++)", " for (way = 0; way < " ++ show ways ++ "; way++)", " tags[set][way] = 0;", "}", "", "__inline__ static UInt32 cachesim_doref ( void* ap )", "{", " register UInt32 a = (UInt32)ap;", " register UInt32 set = (a >> " ++ show line_bits ++ ") & " ++ show (num_sets-1) ++ ";", " register UInt32 tag = (a >> " ++ show (line_bits + set_bits) ++ ");", " register UInt32 tmp;", "" ] ++ concatMap trySet [0 .. ways-1] ++ [ " {" ] ++ shiftSequence (ways-1) ++ [ " tags[set][0] = tag;", " return 1;", " }", "}", "" ]trySet :: Int -> [String]trySet k = [ " if (tag == tags[set][" ++ show k ++ "]) {" ] ++ (if k == 0 then [] else [ " tmp = tags[set][" ++ show k ++ "];"]) ++ shiftSequence k ++ (if k == 0 then [] else [ " tags[set][0] = tmp;"]) ++ [ " return 0;", " }" ]shiftSequence :: Int -> [String]shiftSequence k = map f [k, k-1 .. 1] where f i = " tags[set][" ++ show i ++ "] = tags[set][" ++ show (i-1) ++ "];"{------------------------------------------------------------------------}{--- end CacheGen.hs ---}{------------------------------------------------------------------------}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -