aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-05-27 22:09:43 +0000
committers-ol <s-ol@users.noreply.github.com>2020-05-27 22:09:43 +0000
commit81de967626ef1d828389dead9545067409c83df9 (patch)
tree151a5b26ad2ab8616b5a92c8419d785980e2ad43
parentoutput emulatable .elf (diff)
downloadsubv-81de967626ef1d828389dead9545067409c83df9.tar.gz
subv-81de967626ef1d828389dead9545067409c83df9.zip
implement u-format for JAL
-rwxr-xr-xelf.py14
-rw-r--r--notes.md2
-rw-r--r--riscv.py13
-rwxr-xr-xtest.py10
4 files changed, 29 insertions, 10 deletions
diff --git a/elf.py b/elf.py
index 8990c88..919b690 100755
--- a/elf.py
+++ b/elf.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
import sys
-from subx import clean, classify, parse_segment, parse_instr, format_instr
+from subx import clean, classify, parse_segment, parse_instr
"""
Takes a packed & surveyed hex stream (with section headers) and packs it into a
@@ -28,16 +28,14 @@ for line in sys.stdin:
(name, addr) = parse_segment(line)
segment = { 'name': name, 'addr': addr, 'content': [] }
segments.append(segment)
- else:
+ elif type == 'instr':
if segment == None:
raise ValueError("label or code outside of segment!")
- if type == 'label':
- raise NotImplementedError()
- else:
- instr = parse_instr(line)
- segment['content'] += instr
-
+ instr = parse_instr(line)
+ segment['content'] += instr
+ else:
+ raise ValueError("elf input should contain only segments and instructions!")
entrypoint = 0x80000000
cursor = 0
diff --git a/notes.md b/notes.md
index f3e80bc..4351b27 100644
--- a/notes.md
+++ b/notes.md
@@ -117,7 +117,7 @@ opcode: 0b0010111 / 0x17
- imm20: top 20 bits of offset added to PC
- result stored in rd
-## UJ-Format: op(imm20/21) -> rd
+## U-Format: op(imm20/21) -> rd
`opcode[7] rd[5] imm31:12[20]`
immediates on a 32bit scale (jal)
diff --git a/riscv.py b/riscv.py
index b2af4cc..c0d5a15 100644
--- a/riscv.py
+++ b/riscv.py
@@ -29,3 +29,16 @@ def format_u(op, rd, imm20):
b2 = (imm20 >> 4) & 0xff
b3 = imm20 >> 12
return [(b0,), (b1,), (b2,), (b3,)]
+
+def format_j(op, rd, imm):
+ # opcode[7] rd[5] imm19:12[8] imm11[1] imm10:1[10] imm20[1]
+ imm12 = (imm >> 11) & 0xff
+ imm11 = (imm >> 12) & 0x1
+ imm1 = imm & 0x3ff
+ imm20 = imm >> 19
+
+ b0 = (rd & 0x1) << 7 | op # rd[1] op[7:0]
+ b1 = (imm12 & 0xf) << 4 | rd >> 1 # imm[15:12] rd[5:2]
+ b2 = (imm1 << 5) & 0xe0 | imm11 << 4 | (imm12 >> 4) # imm[3:1] imm[11] imm[19:16]
+ b3 = imm20 << 7 | imm1 >> 3
+ return [(b0,), (b1,), (b2,), (b3,)]
diff --git a/test.py b/test.py
index ba6ffd6..987535f 100755
--- a/test.py
+++ b/test.py
@@ -1,7 +1,13 @@
#!/usr/bin/env python3
-from riscv import format_u, format_i, format_s
+from riscv import format_u, format_i, format_s, format_j
from subx import format_instr
+def neg(val, bits):
+ """compute the 2's complement of int value val"""
+ # if (val & (1 << (bits - 1))) != 0: # if sign bit is set e.g., 8bit: 128-255
+ val = val - (1 << bits) # compute negative value
+ return -val
+
if __name__ == "__main__":
t0 = 0x5
t1 = 0x6
@@ -19,3 +25,5 @@ if __name__ == "__main__":
print(format_instr(format_s(0x23, t0, t1, 0, 0x2), "sw t1, 0(t0)"))
print(format_instr(format_i(0x13, t1, 0, 10, 0x0), "addi t1, x0, 10"))
print(format_instr(format_s(0x23, t0, t1, 0, 0x2), "sw t1, 0(t0)"))
+ print(format_instr(format_j(0x6f, 0, neg(26, 20)), "jal x0, -26"))
+