summaryrefslogtreecommitdiff
path: root/pysc-v/InstructionSets/RV32I.py
diff options
context:
space:
mode:
authorEkaitz Zarraga <ekaitz@elenq.tech>2021-07-23 20:49:14 +0200
committerEkaitz Zarraga <ekaitz@elenq.tech>2021-07-23 20:49:14 +0200
commit681036ddc3891904f13c84197cd90e2472cb3e1c (patch)
tree080b9580c14274698d1848e7640cba0cc47a53a6 /pysc-v/InstructionSets/RV32I.py
parent309d36182ef32a1bc5bff84f39e9e81db0ddb9a6 (diff)
Change folder nameHEADmaster
Diffstat (limited to 'pysc-v/InstructionSets/RV32I.py')
-rw-r--r--pysc-v/InstructionSets/RV32I.py461
1 files changed, 0 insertions, 461 deletions
diff --git a/pysc-v/InstructionSets/RV32I.py b/pysc-v/InstructionSets/RV32I.py
deleted file mode 100644
index f2929f3..0000000
--- a/pysc-v/InstructionSets/RV32I.py
+++ /dev/null
@@ -1,461 +0,0 @@
-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):
- funct3 = None
- opcode = None
-
- def __init__(self, rs1, rs2, imm):
- self.rs1 = rs1
- self.rs2 = rs2
- self.imm = imm
-
- def compile(self):
- imm_0_4 = self.imm & 0x1F
- imm_5_11 = (self.imm & 0xFE0)>>5
- return c_uint32(
- (imm_5_11 << 25) +\
- (self.rs1 << 20) +\
- (self.rs2 << 15) +\
- (self.funct3 << 12) +\
- (imm_0_4 << 7) +\
- self.opcode
- )
-
-class B(Instruction):
- funct3 = None
- opcode = None
-
- def __init__(self, rs1, rs2, imm):
- self.rs1 = rs1
- self.rs2 = rs2
- self.imm = imm
-
- def compile(self):
- # NOTE: The lowest bit of the imm is always 0 because instructions
- # are at least 16 bits wide, so it's not used, that's why this
- # instruction looks that weird
- imm_12 = (self.imm & 0b1000000000000)>>12
- imm_11 = (self.imm & 0b0100000000000)>>11
- imm_5_10 = (self.imm & 0b0011111100000)>>5
- imm_1_4 = (self.imm & 0b0000000011110)>>1
- return c_uint32(
- (imm_12 << 31) +\
- (imm_5_10 << 25) +\
- (self.rs2 << 20) +\
- (self.rs1 << 15) +\
- (self.funct3 << 12) +\
- (imm_1_4 << 8) +\
- (imm_11 << 7) +\
- self.opcode
- )
-
-
-class U(Instruction):
- opcode = None
- def __init__(self, rd, imm):
- self.rd = rd
- self.imm = imm
-
- def compile(self):
- # NOTE: U Type is for AUIPC and LUI that only use the high part of the
- # immediate
- imm_12_32 = (self.imm & 0xFFFFF000)>>12
- return c_uint32(
- (imm_12_32 << 12) +\
- (self.rd << 7) +\
- self.opcode
- )
-
-class J(Instruction):
- opcode = None
-
- def __init__(self, rd, imm):
- self.rd = rd
- self.imm = imm
-
- def compile(self):
- # NOTE: Jumps are also weird
- imm_20 = (self.imm & 0x100000)>>20
- imm_12_19 = (self.imm & 0x0FF000)>>12
- imm_11 = (self.imm & 0x000800)>>11
- imm_1_10 = (self.imm & 0x0007FE)>>1
- return c_uint32(
- (imm_20 << 31) +\
- (imm_1_10 << 21) +\
- (imm_11 << 20) +\
- (imm_12_19 << 12) +\
- (self.rd << 7) +\
- self.opcode
- )
-
-
-
-
-@RV32I.instruction
-class lui(U):
- name = "lui"
- opcode = 0b0110111
-
-@RV32I.instruction
-class auipc(U):
- name = "auipc"
- opcode = 0b0010111
-
-@RV32I.instruction
-class jal(J):
- name = "jal"
- opcode = 0b1101111
-
- def execute(self, pc):
- # TODO
- # - Save current pc in rd
- # - Make pc from `imm`
- # - Return new pc
- return pc
-
-@RV32I.instruction
-class jalr(I):
- name = "jalr"
- opcode = 0b1100111
- funct3 = 0b000
-
-@RV32I.instruction
-class beq(B):
- name = "beq"
- opcode = 0b1100011
- funct3 = 0b000
-
-@RV32I.instruction
-class bne(B):
- name = "bne"
- opcode = 0b1100011
- funct3 = 0b001
-
-@RV32I.instruction
-class blt(B):
- name = "blt"
- opcode = 0b1100011
- funct3 = 0b100
-
-@RV32I.instruction
-class bge(B):
- name = "bge"
- opcode = 0b1100011
- funct3 = 0b101
-
-@RV32I.instruction
-class bltu(B):
- name = "bltu"
- opcode = 0b1100011
- funct3 = 0b110
-
-@RV32I.instruction
-class bgeu(B):
- name = "bgeu"
- opcode = 0b1100011
- funct3 = 0b111
-
-@RV32I.instruction
-class lb(I):
- name = "lb"
- opcode = 0b0000011
- funct3 = 0b000
-
-@RV32I.instruction
-class lh(I):
- name = "lh"
- opcode = 0b0000011
- funct3 = 0b001
-
-@RV32I.instruction
-class lw(I):
- name = "lw"
- opcode = 0b0000011
- funct3 = 0b010
-
-@RV32I.instruction
-class lbu(I):
- name = "lbu"
- opcode = 0b0000011
- funct3 = 0b100
-
-@RV32I.instruction
-class lhu(I):
- name = "lhu"
- opcode = 0b0000011
- funct3 = 0b101
-
-
-@RV32I.instruction
-class sb(S):
- name = "sb"
- opcode = 0b0100011
- funct3 = 0b000
-
-@RV32I.instruction
-class sh(S):
- name = "sh"
- opcode = 0b0100011
- funct3 = 0b001
-
-@RV32I.instruction
-class sw(S):
- name = "sw"
- opcode = 0b0100011
- funct3 = 0b010
-
-@RV32I.instruction
-class addi(I):
- name = "addi"
- opcode = 0b0010011
- funct3 = 0b000
-
- def execute(self, pc):
- # TODO
- return pc + self.size
-
-@RV32I.instruction
-class slti(I):
- name = "slti"
- opcode = 0b0010011
- funct3 = 0b010
-
-@RV32I.instruction
-class sltiu(I):
- name = "sltiu"
- opcode = 0b0010011
- funct3 = 0b011
-
-@RV32I.instruction
-class xori(I):
- name = "xori"
- opcode = 0b0010011
- funct3 = 0b100
-
-@RV32I.instruction
-class ori(I):
- name = "ori"
- opcode = 0b0010011
- funct3 = 0b110
-
-@RV32I.instruction
-class andi(I):
- name = "andi"
- opcode = 0b0010011
- funct3 = 0b111
-
-
-class ShiftImm(I):
- # NOTE: This is an special type used for shifting operations because they
- # have 7 bits left after the maximum shift (5bits -> 32 rotations)
- # they can apply.
- # In RV64I they can indicate rotation with 1 bit more (64 rotations) so
- # they use a funct6 instead.
- funct7 = None
- 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.funct7 << 25) +\
- (self.imm << 20) +\
- (self.rs << 15) +\
- (self.funct3 << 12) +\
- (self.rd << 7) +\
- self.opcode
- )
-
-@RV32I.instruction
-class slli(ShiftImm):
- name = "slli"
- opcode = 0b0010011
- funct3 = 0b001
- funct7 = 0b0000000
-
-@RV32I.instruction
-class srli(ShiftImm):
- name = "srli"
- opcode = 0b0010011
- funct3 = 0b101
- funct7 = 0b0000000
-
-@RV32I.instruction
-class srai(ShiftImm):
- name = "srai"
- opcode = 0b0010011
- funct3 = 0b101
- funct7 = 0b0100000
-
-
-@RV32I.instruction
-class add(R):
- name = "add"
- opcode = 0b0110011
- funct3 = 0b000
- funct7 = 0b0000000
-
- def execute(self, pc):
- # TODO
- return pc + self.size
-
-@RV32I.instruction
-class sub(R):
- name = "sub"
- opcode = 0b0110011
- funct3 = 0b000
- funct7 = 0b0100000
-
-@RV32I.instruction
-class sll(R):
- name = "sll"
- opcode = 0b0110011
- funct3 = 0b001
- funct7 = 0b0000000
-
-@RV32I.instruction
-class slt(R):
- name = "slt"
- opcode = 0b0110011
- funct3 = 0b010
- funct7 = 0b0000000
-
-@RV32I.instruction
-class sltu(R):
- name = "sltu"
- opcode = 0b0110011
- funct3 = 0b011
- funct7 = 0b0000000
-
-@RV32I.instruction
-class xor(R):
- name = "xor"
- opcode = 0b0110011
- funct3 = 0b100
- funct7 = 0b0000000
-
-@RV32I.instruction
-class srl(R):
- name = "srl"
- opcode = 0b0110011
- funct3 = 0b101
- funct7 = 0b0000000
-
-@RV32I.instruction
-class sra(R):
- name = "sra"
- opcode = 0b0110011
- funct3 = 0b101
- funct7 = 0b0100000
-
-@RV32I.instruction
-class _or(R):
- name = "or"
- opcode = 0b0110011
- funct3 = 0b110
- funct7 = 0b0000000
-
-@RV32I.instruction
-class _and(R):
- name = "and"
- opcode = 0b0110011
- funct3 = 0b111
- funct7 = 0b0000000
-
-@RV32I.instruction
-class ecall(I):
- name = "ecall"
- opcode = 0b1110011
- funct3 = 0b000
-
- def __init__(self):
- # NOTE: ecall is a I-type instruction but doesn't get any arg and sets
- # every field to 0
- self.rd = 0b00000
- self.rs = 0b00000
- self.imm = 0b000000000000
-
-
-@RV32I.instruction
-class ebreak(I):
- name = "ebreak"
- opcode = 0b1110011
- funct3 = 0b000
-
- def __init__(self):
- # NOTE: ebreak is a I-type instruction but doesn't get any arg and pre-
- # -sets every field to a fixed value
- self.rd = 0b00000
- self.rs = 0b00000
- self.imm = 0b000000000001
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-@RV32I.pseudoinstruction
-class j(J):
- name = "j"
- def __new__(cls, imm):
- return jal("x0", imm)
-
-
-if __name__ == "__main__":
- print(RV32I)
- print(RV32I.instructions)