diff --git a/.gitignore b/.gitignore index 910b4cf..ff4fab1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ main-c main-hs *.hi *.o +ladirvirelyl-hs +xarzniar-hs diff --git a/assembler/CommonIO.hs b/assembler/CommonIO.hs new file mode 100644 index 0000000..92a5faa --- /dev/null +++ b/assembler/CommonIO.hs @@ -0,0 +1,30 @@ +{-# OPTIONS -Wall -fno-warn-unused-do-bind #-} +module CommonIO +(semicolonExtension +,parse' +,(>>>=) +) where +import System.IO +--import System.Environment(getArgs) +--import Control.Monad +--import Data.List + +import Parse +--import Execute +--import Linker +import Messages +import Types + + +semicolonExtension :: String -> String +semicolonExtension = unlines . map (takeWhile (/=';')) . lines + +parse' :: FilePath -> IO () +parse' filepath = do + str <- semicolonExtension <$> readFile filepath + putStrLn' English $ NormalMessage $ "\nparsing " ++ filepath ++ ":\n" + fullParse' str >>>= print + +(>>>=) :: (Message a) => Either a b -> (b -> IO ()) -> IO () +Right b >>>= action = action b +Left a >>>= _ = hPutStrLn stderr (show' English a) diff --git a/assembler/Makefile b/assembler/Makefile index bc3301d..8b14aeb 100644 --- a/assembler/Makefile +++ b/assembler/Makefile @@ -1,7 +1,8 @@ .PHONY: c haskell haskell: - ghc main.hs -o main-hs -Wall + ghc xarzniar.hs -o xarzniar-hs -Wall + ghc ladirvirelyl.hs -o ladirvirelyl-hs -Wall c: gcc main.c parse.c -o main-c diff --git a/assembler/ladirvirelyl.hs b/assembler/ladirvirelyl.hs new file mode 100644 index 0000000..417fb20 --- /dev/null +++ b/assembler/ladirvirelyl.hs @@ -0,0 +1,28 @@ +{-# OPTIONS -Wall -fno-warn-unused-do-bind #-} +-- import System.IO +import System.Environment(getArgs) +import Control.Monad +import Data.List + +-- import Parse +-- import Execute +-- import Linker +import Messages +import Types +import CommonIO + + +main :: IO () +main = do + args <- getArgs + main'' args + +main'' :: [FilePath] -> IO () +main'' paths = do + mapM_ parse' paths + strs <- forM paths (fmap semicolonExtension . readFile) + putStrLn' English $ NormalMessage $ "\ncompiling " ++ intercalate ", " paths ++ ":\n" + fullCompile' strs + +fullCompile' :: [String] -> IO () +fullCompile' strs = undefined diff --git a/assembler/main.hs b/assembler/xarzniar.hs similarity index 82% rename from assembler/main.hs rename to assembler/xarzniar.hs index 2052a81..48d7fad 100644 --- a/assembler/main.hs +++ b/assembler/xarzniar.hs @@ -9,13 +9,12 @@ import Execute import Linker import Messages import Types +import CommonIO -semicolonExtension :: String -> String -semicolonExtension = unlines . map (takeWhile (/=';')) . lines - +{- fullExecute :: String -> IO () fullExecute = fullExecute' . return - +-} fullExecute' :: [String] -> IO () fullExecute' strs = strs `getProgramAndApply` \program -> let (boolerh, logs) = execute program in do @@ -26,9 +25,7 @@ fullExecute' strs = strs `getProgramAndApply` \program -> getProgramAndApply :: [String] -> (Program -> IO ()) -> IO () strs `getProgramAndApply` f = mapM fullParse' strs >>>= \ps -> linker ps >>>= f -(>>>=) :: (Message a) => Either a b -> (b -> IO ()) -> IO () -Right b >>>= action = action b -Left a >>>= _ = hPutStrLn stderr (show' English a) + main :: IO () main = do @@ -66,15 +63,10 @@ main'' paths = do strs <- forM paths (fmap semicolonExtension . readFile) putStrLn' English $ NormalMessage $ "\nrunning " ++ intercalate ", " paths ++ ":\n" fullExecute' strs - +{- main' :: FilePath -> IO () main' filepath = main'' [filepath] - -parse' :: FilePath -> IO () -parse' filepath = do - str <- semicolonExtension <$> readFile filepath - putStrLn' English $ NormalMessage $ "\nparsing " ++ filepath ++ ":\n" - fullParse' str >>>= print +-} demo :: IO () diff --git a/opcode.html b/opcode.html index b92cd05..fc5af5a 100644 --- a/opcode.html +++ b/opcode.html @@ -1832,6 +1832,117 @@
よさそう。
+そろそろオペコードやっていきましょうか。
+「データへのアクセスは32bit固定長なのになんで命令は8bit単位なのか」などという突っ込みどころが存在するが、まあ気にせずやっていきましょう。
+とりあえず、前に炭酸ソーダさんが作ってくださった案を見てみよう。
++8ビットを基本とした可変長セット +回路設計が簡単になるように考慮 +'i'c順を基にする + +命令の構成 +00oooooo 命令 o:OPCODE +rrrmmmmm 1つめのオペランド。MODEがimmの場合REGは無視される。r:REG m:MODE +(imm/disp) +rrrmmmmm 2つめのオペランド +(imm/disp) +(rrrmmmmm 3つめのオペランド) +(imm/disp) + +OPCODE +0xxxxx: オペランド2つの命令 +000000: ata + +000001: nta - +000010: ada & +000011: ekc | +000100: dto >>> +000101: dro << +000110: dtosna >> +000111: dal ~^ +001000: krz = +001001: malkrz +01cccc: fi +10xxxx: オペランド3つの命令 +100000: inj +101000: lat +101001: latsna + +COND +0000 llonys > +0001 xtlonys <= +0010 xolonys >= +0011 xylonys < +0110 clo == +0111 niv != +1000 llo > +1001 xtlo <= +1010 xolo >= +1011 xylo < +比較は 右の値 + (-左の値) で行う。順番が逆なのはntaに合わせるため +上記ビットをscznに割り当てる +Z: 加算の結果が0かどうか +C: 加算で最上位ビットで繰り上がりが起きて捨てられたか +判定は、((z AND Z) OR NOT(c OR C)) XOR n で決定する +sが1の場合は比較処理の前に両方の値の最上位ビットを反転さそる + +REG +000: f0 +001: f1 +010: f2 +011: f3 +101: f5 +111: xx + +MODE +00000: reg +00100: imm8 +00101: imm16 +00110: imm32 +10000: reg@ +10100: reg+disp8@ +10101: reg+disp16@ +10110: reg+disp32@ +11rrr: reg+reg@ r:2つめのreg +immかdispを含むとき、その値を表す8/16/32ビットの値が後続する。 +imm8/16は符号無し、disp8/16符号あり(C0ならFFFFFFC0として扱う) + + +例 +'c'i +nll fib1 +krz f0 f5+ 4@ +krz f1 0 +krz f2 1 +fi f0 0 clo l' is malkrz xx ka +nta f0 1 +krz f3 f1 +ata f3 f2 +inj f1 f2 f3 +krz xx is +krz f0 f1 l' ka +krz xx f5@ + +1482E8D4: 08 B4 04 00 +1482E8D8: 08 04 00 20 +1482E8DC: 08 04 01 40 +1482E8E0: 16 00 04 00 +1482E8E4: 09 06 14 82 E8 FC E0 +1482E8EB: 01 04 01 00 +1482E8EF: 08 20 60 +1482E8F2: 00 40 60 +1482E8F5: 20 60 40 20 +1482E8F5: 08 06 14 82 E8 E0 E0 +1482E8FC: 08 20 00 +1482E8FF: 08 B0 E0 ++
とのこと。
+よさそう(よさそう)
+とりあえずアセンブラでも考えてみるか?Haskellに触れるのは大分久しぶりだな。
+インタプリタの方をxarzniarと改名し、ladirvirelyl.hsというファイルを新たに作成。
+共通化できそうな処理はCommonIO.hsとして分離し、とりあえず形式だけ合わせたダミーを作成。
+さて、まともなコンパイラとリンカを作らねばなぁ。nヶ月前に書いたコードだからどういう構成になってるのかも読み返さねばだし。
+