-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathRISCVReg.hs
458 lines (375 loc) · 11.3 KB
/
RISCVReg.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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Data.Macaw.RISCV.RISCVReg
( -- * RISC-V macaw register state
RISCVReg(..)
, GPR(..)
-- ** Patterns for GPRs
, pattern GPR
, pattern GPR_RA
, pattern GPR_SP
, pattern GPR_GP
, pattern GPR_TP
, pattern GPR_T0
, pattern GPR_T1
, pattern GPR_T2
, pattern GPR_S0
, pattern GPR_S1
, pattern GPR_A0
, pattern GPR_A1
, pattern GPR_A2
, pattern GPR_A3
, pattern GPR_A4
, pattern GPR_A5
, pattern GPR_A6
, pattern GPR_A7
, pattern GPR_S2
, pattern GPR_S3
, pattern GPR_S4
, pattern GPR_S5
, pattern GPR_S6
, pattern GPR_S7
, pattern GPR_S8
, pattern GPR_S9
, pattern GPR_S10
, pattern GPR_S11
, pattern GPR_T3
, pattern GPR_T4
, pattern GPR_T5
, pattern GPR_T6
) where
import qualified Data.Macaw.Types as MT
import qualified Data.Macaw.CFG as MC
import Data.Macaw.RISCV.Arch
import Data.Parameterized.Classes
import Data.Parameterized.Some (Some(..))
import Data.Parameterized.NatRepr (knownNat)
import Data.Parameterized.TH.GADT ( structuralTypeEquality
, structuralTypeOrd
)
import qualified Prettyprinter as PP
import qualified GRIFT.Types as G
import qualified GRIFT.Semantics.Utils as G
newtype GPR = BuildGPR (G.SizedBV 5)
deriving (Enum, Eq, Ord)
-- | Return address
pattern RA :: GPR
pattern RA = BuildGPR 1
-- | Stack pointer
pattern SP :: GPR
pattern SP = BuildGPR 2
-- | Global pointer
pattern GP :: GPR
pattern GP = BuildGPR 3
-- | Thread pointer
pattern TP :: GPR
pattern TP = BuildGPR 4
-- | Temporary/Alternate link register
pattern T0 :: GPR
pattern T0 = BuildGPR 5
-- | Temporary
pattern T1 :: GPR
pattern T1 = BuildGPR 6
-- | Temporary
pattern T2 :: GPR
pattern T2 = BuildGPR 7
-- | Saved register/frame pointer
pattern S0 :: GPR
pattern S0 = BuildGPR 8
-- | Saved register
pattern S1 :: GPR
pattern S1 = BuildGPR 9
-- | Function argument/return value
pattern A0 :: GPR
pattern A0 = BuildGPR 10
-- | Function argument/return value
pattern A1 :: GPR
pattern A1 = BuildGPR 11
-- | Function argument
pattern A2 :: GPR
pattern A2 = BuildGPR 12
-- | Function argument
pattern A3 :: GPR
pattern A3 = BuildGPR 13
-- | Function argument
pattern A4 :: GPR
pattern A4 = BuildGPR 14
-- | Function argument
pattern A5 :: GPR
pattern A5 = BuildGPR 15
-- | Function argument
pattern A6 :: GPR
pattern A6 = BuildGPR 16
-- | Function argument
pattern A7 :: GPR
pattern A7 = BuildGPR 17
-- | Saved register
pattern S2 :: GPR
pattern S2 = BuildGPR 18
-- | Saved register
pattern S3 :: GPR
pattern S3 = BuildGPR 19
-- | Saved register
pattern S4 :: GPR
pattern S4 = BuildGPR 20
-- | Saved register
pattern S5 :: GPR
pattern S5 = BuildGPR 21
-- | Saved register
pattern S6 :: GPR
pattern S6 = BuildGPR 22
-- | Saved register
pattern S7 :: GPR
pattern S7 = BuildGPR 23
-- | Saved register
pattern S8 :: GPR
pattern S8 = BuildGPR 24
-- | Saved register
pattern S9 :: GPR
pattern S9 = BuildGPR 25
-- | Saved register
pattern S10 :: GPR
pattern S10 = BuildGPR 26
-- | Saved register
pattern S11 :: GPR
pattern S11 = BuildGPR 27
-- | Temporary
pattern T3 :: GPR
pattern T3 = BuildGPR 28
-- | Temporary
pattern T4 :: GPR
pattern T4 = BuildGPR 29
-- | Temporary
pattern T5 :: GPR
pattern T5 = BuildGPR 30
-- | Temporary
pattern T6 :: GPR
pattern T6 = BuildGPR 31
{-# COMPLETE
RA, SP, GP, TP,
A0, A1, A2, A3, A4, A5, A6, A7,
S0, S1, S2, S3, S4, S5, S6, S7,
S8, S9, S10, S11,
T0, T1, T2, T3, T4, T5, T6 #-}
instance Show GPR where
show RA = "ra"
show SP = "sp"
show GP = "gp"
show TP = "tp"
show T0 = "t0"
show T1 = "t1"
show T2 = "t2"
show S0 = "s0"
show S1 = "s1"
show A0 = "a0"
show A1 = "a1"
show A2 = "a2"
show A3 = "a3"
show A4 = "a4"
show A5 = "a5"
show A6 = "a6"
show A7 = "a7"
show S2 = "s2"
show S3 = "s3"
show S4 = "s4"
show S5 = "s5"
show S6 = "s6"
show S7 = "s7"
show S8 = "s8"
show S9 = "s9"
show S10 = "s10"
show S11 = "s11"
show T3 = "t3"
show T4 = "t4"
show T5 = "t5"
show T6 = "t6"
-- | RISC-V register.
data RISCVReg rv tp where
-- | Program counter.
PC :: RISCVReg rv (MT.BVType (G.RVWidth rv))
-- | General-purpose registers. GPR[0] is not really a register, so
-- it should never be directly read from or written to.
RISCV_GPR :: GPR -> RISCVReg rv (MT.BVType (G.RVWidth rv))
-- | Floating-point registers.
FPR :: G.SizedBV 5 -> RISCVReg rv (MT.BVType (G.RVFloatWidth rv))
-- | Control/status registers.
CSR :: G.CSR -> RISCVReg rv (MT.BVType (G.RVWidth rv))
-- | Current privilege level.
PrivLevel :: RISCVReg rv (MT.BVType 2)
-- | Trip this if something bad happens.
EXC :: RISCVReg rv MT.BoolType
pattern GPR ::
forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
G.SizedBV 5 -> RISCVReg rv tp
pattern GPR bv = RISCV_GPR (BuildGPR bv)
-- | Return address
pattern GPR_RA :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_RA = GPR 1
-- | Stack pointer
pattern GPR_SP :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_SP = GPR 2
-- | Global pointer
pattern GPR_GP :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_GP = GPR 3
-- | Thread pointer
pattern GPR_TP :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_TP = GPR 4
-- | Temporary/Alternate link register
pattern GPR_T0 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_T0 = GPR 5
-- | Temporary
pattern GPR_T1 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_T1 = GPR 6
-- | Temporary
pattern GPR_T2 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_T2 = GPR 7
-- | Saved register/frame pointer
pattern GPR_S0 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_S0 = GPR 8
-- | Saved register
pattern GPR_S1 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_S1 = GPR 9
-- | Function argument/return value
pattern GPR_A0 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_A0 = GPR 10
-- | Function argument/return value
pattern GPR_A1 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_A1 = GPR 11
-- | Function argument
pattern GPR_A2 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_A2 = GPR 12
-- | Function argument
pattern GPR_A3 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_A3 = GPR 13
-- | Function argument
pattern GPR_A4 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_A4 = GPR 14
-- | Function argument
pattern GPR_A5 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_A5 = GPR 15
-- | Function argument
pattern GPR_A6 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_A6 = GPR 16
-- | Function argument
pattern GPR_A7 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_A7 = GPR 17
-- | Saved register
pattern GPR_S2 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_S2 = GPR 18
-- | Saved register
pattern GPR_S3 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_S3 = GPR 19
-- | Saved register
pattern GPR_S4 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_S4 = GPR 20
-- | Saved register
pattern GPR_S5 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_S5 = GPR 21
-- | Saved register
pattern GPR_S6 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_S6 = GPR 22
-- | Saved register
pattern GPR_S7 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_S7 = GPR 23
-- | Saved register
pattern GPR_S8 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_S8 = GPR 24
-- | Saved register
pattern GPR_S9 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_S9 = GPR 25
-- | Saved register
pattern GPR_S10 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_S10 = GPR 26
-- | Saved register
pattern GPR_S11 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_S11 = GPR 27
-- | Temporary
pattern GPR_T3 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_T3 = GPR 28
-- | Temporary
pattern GPR_T4 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_T4 = GPR 29
-- | Temporary
pattern GPR_T5 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_T5 = GPR 30
-- | Temporary
pattern GPR_T6 :: forall rv tp . () => (tp ~ 'MT.BVType (G.RVWidth rv)) =>
RISCVReg rv tp
pattern GPR_T6 = GPR 31
instance Show (RISCVReg rv tp) where
show PC = "pc"
show (RISCV_GPR gpr) = show gpr
show (FPR rid) = "f" <> show (G.asUnsignedSized rid)
show (CSR csr) = show csr
show PrivLevel = "priv"
show EXC = "exc"
$(return [])
instance TestEquality (RISCVReg rv) where
testEquality = $(structuralTypeEquality [t|RISCVReg|] [])
instance OrdF (RISCVReg rv) where
compareF = $(structuralTypeOrd [t|RISCVReg|] [])
instance ShowF (RISCVReg rv)
instance MC.PrettyF (RISCVReg rv) where
prettyF = PP.pretty . showF
instance G.KnownRV rv => MT.HasRepr (RISCVReg rv) MT.TypeRepr where
typeRepr PC = MT.BVTypeRepr knownNat
typeRepr (RISCV_GPR _) = MT.BVTypeRepr knownNat
typeRepr (FPR _) = MT.BVTypeRepr knownNat
typeRepr (CSR _) = MT.BVTypeRepr knownNat
typeRepr PrivLevel = MT.BVTypeRepr knownNat
typeRepr EXC = MT.BoolTypeRepr
type instance MC.ArchReg (RISCV rv) = RISCVReg rv
type instance MC.RegAddrWidth (RISCVReg rv) = G.RVWidth rv
riscvRegs :: [Some (RISCVReg rv)]
riscvRegs = [Some PC] ++
((Some . GPR) <$> [1..31]) ++
((Some . FPR) <$> [0..31]) ++
[Some PrivLevel, Some EXC]
instance (G.KnownRV rv, RISCVConstraints rv) => MC.RegisterInfo (RISCVReg rv) where
archRegs = riscvRegs
sp_reg = GPR_SP
ip_reg = PC
syscall_num_reg = error "syscall_num_reg undefined"
syscallArgumentRegs = error "syscallArgumentRegs undefined"