summaryrefslogtreecommitdiff
path: root/pysc-v/InstructionSets/RV32I.py
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)