# Full list of instructions """ U lui U auipc J jal I jalr B beq B bne B blt B bge B bltu B bgeu I lb I lh I lw I lbu I lhu S sb S sh S sw I addi I slti I sltiu I xori I ori I andi I slli I srli I srai R add R sub R sll R slt R sltu R xor R srl R sra R or R and I fence I fence.i I ecall I ebreak I csrrw I csrrs I csrrc I csrrwi I csrrsi I csrrci """ from ctypes import c_uint32 class Instruction: self.memory = None self.regs = None def __init__(self): pass def compile(self): # return the binstream of the instruction in a c_uint32 pass def execute(self): # executes the instruction and returns the next program counter return 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): pass class add(R): name = "add" opcode = 0b0110011 funct3 = 0b000 funct7 = 0b0000000 def execute(self): pass class addi(I): name = "addi" opcode = 0b0010011 funct3 = 0b000 def execute(self): pass if __name__ == "__main__": r = Regs() # This is the interface i'd love to have addins = add("x5","x2","zero") j("labelName")