diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2020-05-28 18:31:54 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2020-05-28 19:04:28 +0000 |
| commit | 11c5c7d29a1b96367ac94c78a898fd1fcd4d7202 (patch) | |
| tree | a272f59949f9be336304db1e9fb85bd7388ad446 | |
| parent | Add Status to README (diff) | |
| download | subv-11c5c7d29a1b96367ac94c78a898fd1fcd4d7202.tar.gz subv-11c5c7d29a1b96367ac94c78a898fd1fcd4d7202.zip | |
Hello World!
| -rwxr-xr-x | elf.py | 15 | ||||
| -rw-r--r-- | format.py | 7 | ||||
| -rw-r--r-- | pack.py | 19 | ||||
| -rw-r--r-- | survey.py | 2 | ||||
| -rw-r--r-- | test.subv | 45 |
5 files changed, 53 insertions, 35 deletions
@@ -29,7 +29,7 @@ def wi(num, size=2): def padto(offset, cursor): missing = offset - cursor if missing < 0: - raise ValueError("already past offset!") + raise ValueError("cursor {} already past offset {}!".format(cursor, offset)) w(b'\x00' * missing) return offset @@ -57,12 +57,13 @@ def write_elf_header(segments): c += wi(0x0) # e_shstrndx return c -def write_program_header(segment, c): +def write_program_header(segment, c, start): align = 0x1000 - offset = (1 + c // align) * align + offset = (1 + start // align) * align + segment['offset'] = offset start = segment['addr'] size = len(segment['content']) - segment['offset'] = offset + flags = 5 if segment['name'] == "code" else 6 if offset % align != start % align: print("{:02x} {:02x}".format(offset, offset % align)) @@ -75,7 +76,7 @@ def write_program_header(segment, c): c += wi(start, 4) # p_paddr c += wi(size, 4) # p_filesz c += wi(size, 4) # p_memsz - c += wi(0x5, 4) # p_flags, 0x5=rx, 0x6=rw + c += wi(flags, 4) # p_flags, 0x5=rx, 0x6=rw c += wi(align, 4) # p_align return c @@ -100,8 +101,10 @@ if __name__ == "__main__": cursor = 0 c = write_elf_header(segments) + segment_start = 0x1000 for seg in segments: - c = write_program_header(seg, c) + c = write_program_header(seg, c, segment_start) + segment_start = seg['offset'] + len(seg['content']) for seg in segments: c = padto(seg['offset'], c) @@ -96,10 +96,11 @@ def pack_b(instr): return [op, imm_11, imm_lo, sub, rs1, rs2, imm_md, imm_12] def format(iter): + segment = None for line in iter: line = subv.parse(line) - if line['type'] == 'instr': + if segment == 'code' and line['type'] == 'instr': instr = line['instr'] op = instr[0] if len(op) != 2: @@ -121,11 +122,15 @@ def format(iter): out = pack_s(instr) elif format == 'j': out = pack_j(instr) + elif format == 'b': + out = pack_b(instr) else: raise NotImplementedError() yield subv.format_instr(out) else: + if line['type'] == 'segment': + segment = line['segment'][0] yield line['raw'] if __name__ == '__main__': @@ -4,27 +4,30 @@ import bits def byteify(word): (val, size) = word - if size != 32: - raise ValueError("Expected 32-bit word") + if size % 8 != 0: + raise ValueError("Not byte aligned: {} bits".format(size)) - b0 = bits.slice(word, 7, 0) - b1 = bits.slice(word, 15, 8) - b2 = bits.slice(word, 23, 16) - b3 = bits.slice(word, 31, 24) - return [b0[:1], b1[:1], b2[:1], b3[:1]] + out = [] + for i in range(0, size, 8): + byte = bits.slice(word, i+7, i) + out.append(byte[:1]) + return out def pack(iter): + segment = None for line in iter: line = subv.parse(line) if line['type'] == 'instr': fields = [bits.from_part(p) for p in line['instr']] total = bits.concat(*fields) - if total[1] != 32: + if segment == 'code' and total[1] != 32: raise ValueError("instruction parts do not add up to 32 bit!") yield subv.format_instr(byteify(total)) else: + if line['type'] == 'segment': + segment = line['segment'][0] yield line['raw'] if __name__ == '__main__': @@ -24,7 +24,7 @@ def observe(part, rel_addr, map): mode, size, shift = tag_re.match(tag).groups() size = int(size) - shift = int(shift) + shift = int(shift) if shift else 0 if mode == 'imm': addr = bits.u(addr, size) @@ -2,23 +2,30 @@ main: # load 0x10010000 (UART0) into t0 37/lui 5/rd/t0 0x10010/imm20 - # store 0x48 (H) in UART0+0 - 13/opi 0/subop/add 6/rd/t1 0/rs/x0 48/imm12 + + # x4 = &message + # . load high bits + 37/lui 4/rd/x4 Message/20/imm32>>12 + # . add low bits + 13/opi 0/subop/add 4/rd/x4 4/rs/x4 Message/12/imm32 +print:loop: + # load unsigned byte at x4 + 03/load 4/subop/lbu 6/rd/t1 4/rs/x4 0/imm12 + # break loop if zero + 63/branch 0/subop/== 6/rs/t1 0/rs/x0 print:break/off13 + # print char 23/store 2/subop/word 5/rs/t0 6/rs/t1 0/off12 - # store 0x65 (e) in UART0+0 - 13/opi 0/subop/add 6/rd/t1 0/rs/x0 65/imm12 - 23/store 2/subop/word 5/rs/t0 6/rs/t1 0/off12 - # store 0x6c (l) in UART0+0 - 13/opi 0/subop/add 6/rd/t1 0/rs/x0 6c/imm12 - 23/store 2/subop/word 5/rs/t0 6/rs/t1 0/off12 - # store 0x6c (l) in UART0+0 - 13/opi 0/subop/add 6/rd/t1 0/rs/x0 6c/imm12 - 23/store 2/subop/word 5/rs/t0 6/rs/t1 0/off12 - # store 0x6f (o) in UART0+0 - 13/opi 0/subop/add 6/rd/t1 0/rs/x0 6f/imm12 - 23/store 2/subop/word 5/rs/t0 6/rs/t1 0/off12 - # store 0x0a (\n) in UART0+0 - 13/opi 0/subop/add 6/rd/t1 0/rs/x0 0a/imm12 - 23/store 2/subop/word 5/rs/t0 6/rs/t1 0/off12 - # jump back up to the top - 6f/jal 0/rd/x0 main/off21 + # increment x4 + 13/opi 0/subop/add 4/rd/x4 4/rs/x4 1/imm12 + # jump back up + 6f/jal 0/rd/x0 print:loop/off21 +print:break: + +loop: + # infinite loop + 6f/jal 0/rd/x0 loop/off21 + +== data 0x80001000 +Message: + # "Hello World\n\0" + 48/8 65/8 6c/8 6c/8 6f/8 20/8 77/8 6f/8 72/8 6c/8 64/8 21/8 0a/8 00/8 |
