-
Notifications
You must be signed in to change notification settings - Fork 16
/
ExecuteI.hs
205 lines (204 loc) · 5.92 KB
/
ExecuteI.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
{-# LANGUAGE ScopedTypeVariables #-}
module Spec.ExecuteI where
import Spec.Decode
import Spec.Machine
import Utility.Utility
import Spec.VirtualMemory
import Data.Bits hiding (Xor, And, Or)
import Data.Int
import Data.Word
import Control.Monad
import Prelude
execute :: forall p t. (RiscvMachine p t) => InstructionI -> p ()
-- begin ast
execute (Lui rd imm20) = do
setRegister rd (fromImm imm20)
execute (Auipc rd oimm20) = do
pc <- getPC
setRegister rd (fromImm oimm20 + pc)
execute (Jal rd jimm20) = do
pc <- getPC
let newPC = pc + (fromImm jimm20)
if (remu newPC 4 /= 0)
then raiseExceptionWithInfo 0 0 (fromIntegral newPC)
else (do
setRegister rd (pc + 4)
setPC newPC)
execute (Jalr rd rs1 oimm12) = do
x <- getRegister rs1
pc <- getPC
let newPC = (x + fromImm oimm12) .&. (complement 1)
if (remu newPC 4 /= 0)
then raiseExceptionWithInfo 0 0 (fromIntegral newPC)
else (do
setRegister rd (pc + 4)
setPC newPC)
execute (Beq rs1 rs2 sbimm12) = do
x <- getRegister rs1
y <- getRegister rs2
pc <- getPC
when (x == y) (do
let newPC = (pc + fromImm sbimm12)
if (remu newPC 4 /= 0)
then raiseExceptionWithInfo 0 0 (fromIntegral newPC)
else setPC newPC)
execute (Bne rs1 rs2 sbimm12) = do
x <- getRegister rs1
y <- getRegister rs2
pc <- getPC
when (x /= y) (do
let addr = (pc + fromImm sbimm12)
if (remu addr 4 /= 0)
then raiseExceptionWithInfo 0 0 (fromIntegral addr)
else setPC addr)
execute (Blt rs1 rs2 sbimm12) = do
x <- getRegister rs1
y <- getRegister rs2
pc <- getPC
when (x < y) (do
let addr = (pc + fromImm sbimm12)
if (remu addr 4 /= 0)
then raiseExceptionWithInfo 0 0 (fromIntegral addr)
else setPC addr)
execute (Bge rs1 rs2 sbimm12) = do
x <- getRegister rs1
y <- getRegister rs2
pc <- getPC
when (x >= y) (do
let addr = (pc + fromImm sbimm12)
if (remu addr 4 /= 0)
then raiseExceptionWithInfo 0 0 (fromIntegral addr)
else setPC addr)
execute (Bltu rs1 rs2 sbimm12) = do
x <- getRegister rs1
y <- getRegister rs2
pc <- getPC
when ((ltu x y)) (do
let addr = (pc + fromImm sbimm12)
if (remu addr 4 /= 0)
then raiseExceptionWithInfo 0 0 (fromIntegral addr)
else setPC addr)
execute (Bgeu rs1 rs2 sbimm12) = do
x <- getRegister rs1
y <- getRegister rs2
pc <- getPC
when (not (ltu x y)) (do
let addr = (pc + fromImm sbimm12)
if (remu addr 4 /= 0)
then raiseExceptionWithInfo 0 0 (fromIntegral addr)
else setPC addr)
execute (Lb rd rs1 oimm12) = do
a <- getRegister rs1
addr <- translate Load 1 (a + fromImm oimm12)
x <- loadByte Execute addr
setRegister rd (int8ToReg x)
execute (Lh rd rs1 oimm12) = do
a <- getRegister rs1
addr <- translate Load 2 (a + fromImm oimm12)
x <- loadHalf Execute addr
setRegister rd (int16ToReg x)
execute (Lw rd rs1 oimm12) = do
a <- getRegister rs1
addr <- translate Load 4 (a + fromImm oimm12)
x <- loadWord Execute addr
setRegister rd (int32ToReg x)
execute (Lbu rd rs1 oimm12) = do
a <- getRegister rs1
addr <- translate Load 1 (a + fromImm oimm12)
x <- loadByte Execute addr
setRegister rd (uInt8ToReg x)
execute (Lhu rd rs1 oimm12) = do
a <- getRegister rs1
addr <- translate Load 2 (a + fromImm oimm12)
x <- loadHalf Execute addr
setRegister rd (uInt16ToReg x)
execute (Sb rs1 rs2 simm12) = do
a <- getRegister rs1
addr <- translate Store 1 (a + fromImm simm12)
x <- getRegister rs2
storeByte Execute addr (regToInt8 x)
execute (Sh rs1 rs2 simm12) = do
a <- getRegister rs1
addr <- translate Store 2 (a + fromImm simm12)
x <- getRegister rs2
storeHalf Execute addr (regToInt16 x)
execute (Sw rs1 rs2 simm12) = do
a <- getRegister rs1
addr <- translate Store 4 (a + fromImm simm12)
x <- getRegister rs2
storeWord Execute addr (regToInt32 x)
execute (Addi rd rs1 imm12) = do
x <- getRegister rs1
setRegister rd (x + fromImm imm12)
execute (Slti rd rs1 imm12) = do
x <- getRegister rs1
let val = (if x < (fromImm imm12) then 1 else 0)
setRegister rd val
execute (Sltiu rd rs1 imm12) = do
x <- getRegister rs1
let val = (if (ltu x (fromImm imm12)) then 1 else 0)
setRegister rd val
execute (Xori rd rs1 imm12) = do
x <- getRegister rs1
setRegister rd (xor x (fromImm imm12))
execute (Ori rd rs1 imm12) = do
x <- getRegister rs1
setRegister rd (x .|. (fromImm imm12))
execute (Andi rd rs1 imm12) = do
x <- getRegister rs1
setRegister rd (x .&. (fromImm imm12))
execute (Slli rd rs1 shamt6) = do
x <- getRegister rs1
setRegister rd (sll x shamt6)
execute (Srli rd rs1 shamt6) = do
x <- getRegister rs1
setRegister rd (srl x shamt6)
execute (Srai rd rs1 shamt6) = do
x <- getRegister rs1
setRegister rd (sra x shamt6)
execute (Add rd rs1 rs2) = do
x <- getRegister rs1
y <- getRegister rs2
setRegister rd (x + y)
execute (Sub rd rs1 rs2) = do
x <- getRegister rs1
y <- getRegister rs2
setRegister rd (x - y)
execute (Sll rd rs1 rs2) = do
x <- getRegister rs1
y <- getRegister rs2
setRegister rd (sll x (regToShamt y))
execute (Slt rd rs1 rs2) = do
x <- getRegister rs1
y <- getRegister rs2
let val = if x < y then 1 else 0
setRegister rd val
execute (Sltu rd rs1 rs2) = do
x <- getRegister rs1
y <- getRegister rs2
let val = if ltu x y then 1 else 0
setRegister rd val
execute (Xor rd rs1 rs2) = do
x <- getRegister rs1
y <- getRegister rs2
setRegister rd (xor x y)
execute (Or rd rs1 rs2) = do
x <- getRegister rs1
y <- getRegister rs2
setRegister rd (x .|. y)
execute (Srl rd rs1 rs2) = do
x <- getRegister rs1
y <- getRegister rs2
setRegister rd (srl x (regToShamt y))
execute (Sra rd rs1 rs2) = do
x <- getRegister rs1
y <- getRegister rs2
setRegister rd (sra x (regToShamt y))
execute (And rd rs1 rs2) = do
x <- getRegister rs1
y <- getRegister rs2
setRegister rd (x .&. y)
execute (Fence pred succ) = fence pred succ -- TODO
execute Fence_i = return () -- TODO
-- end ast
execute inst = error $ "dispatch bug: " ++ show inst