diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2020-05-27 22:09:43 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2020-05-27 22:09:43 +0000 |
| commit | 81de967626ef1d828389dead9545067409c83df9 (patch) | |
| tree | 151a5b26ad2ab8616b5a92c8419d785980e2ad43 | |
| parent | output emulatable .elf (diff) | |
| download | subv-81de967626ef1d828389dead9545067409c83df9.tar.gz subv-81de967626ef1d828389dead9545067409c83df9.zip | |
implement u-format for JAL
| -rwxr-xr-x | elf.py | 14 | ||||
| -rw-r--r-- | notes.md | 2 | ||||
| -rw-r--r-- | riscv.py | 13 | ||||
| -rwxr-xr-x | test.py | 10 |
4 files changed, 29 insertions, 10 deletions
@@ -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 @@ -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) @@ -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,)] @@ -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")) + |
