blob: 53b6859e5692623b30191acd54197d62b2dd1a97 (
plain)
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
|
from .instructions import Instruction, InstructionSet
from ctypes import c_uint32
RV32I = InstructionSet()
class R(Instruction):
funct3 = None
funct7 = None
opcode = None
def __init__(self, rd, rs1, rs2):
self.rd = rd
self.rs1 = rs1
self.rs2 = rs2
def compile(self):
# TODO: ensure sizes and convert register names to number...
return c_uint32(
(self.funct7 << 25) +\
(self.rs2 << 20) +\
(self.rs1 << 15) +\
(self.funct3 << 12) +\
(self.rd << 7) +\
self.opcode
)
class I(Instruction):
funct3 = None
opcode = None
def __init__(self, rd, rs, imm):
self.rd = rd
self.rs = rs
self.imm = imm
def compile(self):
return c_uint32(
(self.imm << 20) +\
(self.rs << 15) +\
(self.funct3 << 12) +\
(self.rd << 7) +\
self.opcode
)
class S(Instruction):
pass
class B(Instruction):
pass
class U(Instruction):
pass
class J(Instruction):
# TODO check if it's correct
opcode = None
def __init__(self, rd, imm):
self.rd = rd
self.imm = imm
def compile(self):
return c_uint32(
(self.imm << 12) +\
(self.rd << 7) +\
self.opcode
)
@RV32I.instruction
class add(R):
name = "add"
opcode = 0b0110011
funct3 = 0b000
funct7 = 0b0000000
def execute(self):
return pc + self.size
@RV32I.instruction
class addi(I):
name = "addi"
opcode = 0b0010011
funct3 = 0b000
@RV32I.instruction
class jal(J):
name = "jal"
opcode = 0b1101111
def execute(self):
# TODO
# - Save current pc in rd
# - Make pc from `imm`
# - Return new pc
return pc
@RV32I.pseudoinstruction
class j(J):
name = "j"
def __new__(cls, imm):
return jal("x0", imm)
if __name__ == "__main__":
print(RV32I)
print(RV32I.instructions)
|