summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--instructions.py145
-rw-r--r--pysc-v/Frontend/__init__.py0
-rw-r--r--pysc-v/Frontend/lexer.py4
-rw-r--r--pysc-v/Frontend/reader.py (renamed from reader.py)0
-rw-r--r--pysc-v/InstructionSets/RV32C.py29
-rw-r--r--pysc-v/InstructionSets/RV32D.py0
-rw-r--r--pysc-v/InstructionSets/RV32F.py0
-rw-r--r--pysc-v/InstructionSets/RV32I.py71
-rw-r--r--pysc-v/InstructionSets/__init__.py0
-rw-r--r--pysc-v/InstructionSets/instructions.py30
-rw-r--r--pysc-v/main.py5
-rw-r--r--pysc-v/memory.py (renamed from memory.py)0
-rw-r--r--pysc-v/registers/RV32I.py (renamed from registersRV32I.py)0
-rw-r--r--pysc-v/registers/__init__.py0
15 files changed, 140 insertions, 145 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bee8a64
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+__pycache__
diff --git a/instructions.py b/instructions.py
deleted file mode 100644
index 0bfda4c..0000000
--- a/instructions.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# 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")
diff --git a/pysc-v/Frontend/__init__.py b/pysc-v/Frontend/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pysc-v/Frontend/__init__.py
diff --git a/pysc-v/Frontend/lexer.py b/pysc-v/Frontend/lexer.py
new file mode 100644
index 0000000..5175097
--- /dev/null
+++ b/pysc-v/Frontend/lexer.py
@@ -0,0 +1,4 @@
+# Returns:
+# - label
+# - instruction (with args)
+# - directive (with args)
diff --git a/reader.py b/pysc-v/Frontend/reader.py
index 45d155c..45d155c 100644
--- a/reader.py
+++ b/pysc-v/Frontend/reader.py
diff --git a/pysc-v/InstructionSets/RV32C.py b/pysc-v/InstructionSets/RV32C.py
new file mode 100644
index 0000000..e740ac4
--- /dev/null
+++ b/pysc-v/InstructionSets/RV32C.py
@@ -0,0 +1,29 @@
+from instructions import Instruction, InstructionSet
+
+class Compressed(Instruction):
+ size = 2
+
+
+class CR(Compressed):
+ pass
+
+class CI(Compressed):
+ pass
+
+class CSS(Compressed):
+ pass
+
+class CIW(Compressed):
+ pass
+
+class CJ(Compressed):
+ pass
+
+class CB(Compressed):
+ pass
+
+class CL(Compressed):
+ pass
+
+class CS(Compressed):
+ pass
diff --git a/pysc-v/InstructionSets/RV32D.py b/pysc-v/InstructionSets/RV32D.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pysc-v/InstructionSets/RV32D.py
diff --git a/pysc-v/InstructionSets/RV32F.py b/pysc-v/InstructionSets/RV32F.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pysc-v/InstructionSets/RV32F.py
diff --git a/pysc-v/InstructionSets/RV32I.py b/pysc-v/InstructionSets/RV32I.py
new file mode 100644
index 0000000..967b24d
--- /dev/null
+++ b/pysc-v/InstructionSets/RV32I.py
@@ -0,0 +1,71 @@
+from instructions import Instruction, InstructionSet
+
+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):
+ pass
+
+
+class add(R):
+ name = "add"
+ opcode = 0b0110011
+ funct3 = 0b000
+ funct7 = 0b0000000
+
+ def execute(self):
+ return pc + self.size
+
+class addi(I):
+ name = "addi"
+ opcode = 0b0010011
+ funct3 = 0b000
+
+ def execute(self):
+ pass
diff --git a/pysc-v/InstructionSets/__init__.py b/pysc-v/InstructionSets/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pysc-v/InstructionSets/__init__.py
diff --git a/pysc-v/InstructionSets/instructions.py b/pysc-v/InstructionSets/instructions.py
new file mode 100644
index 0000000..5587f2e
--- /dev/null
+++ b/pysc-v/InstructionSets/instructions.py
@@ -0,0 +1,30 @@
+from ctypes import c_uint32
+
+
+class Instruction:
+ size = 4 # Instruction size in bytes
+
+ 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 InstructionSet:
+ def __init__(self, init=None):
+ self.data = dict()
+
+ def add_instruction(self, ins):
+ if ins.name not in self.data:
+ self.data[ins.name] = ins
+
+
+if __name__ == "__main__":
+ # TODO This is the interface i'd love to have
+ addins = add("x5","x2","zero")
+ j("labelName")
diff --git a/pysc-v/main.py b/pysc-v/main.py
new file mode 100644
index 0000000..2d6f6a5
--- /dev/null
+++ b/pysc-v/main.py
@@ -0,0 +1,5 @@
+# Use a generator for the execution flow
+# -> PC has to be a global variable, updated by each instruction to the next val
+# So user can set the PC by hand and call next(run) and make the code jump!
+
+
diff --git a/memory.py b/pysc-v/memory.py
index 84bf0bd..84bf0bd 100644
--- a/memory.py
+++ b/pysc-v/memory.py
diff --git a/registersRV32I.py b/pysc-v/registers/RV32I.py
index 4652bca..4652bca 100644
--- a/registersRV32I.py
+++ b/pysc-v/registers/RV32I.py
diff --git a/pysc-v/registers/__init__.py b/pysc-v/registers/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pysc-v/registers/__init__.py