aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-05-28 18:31:54 +0000
committers-ol <s-ol@users.noreply.github.com>2020-05-28 19:04:28 +0000
commit11c5c7d29a1b96367ac94c78a898fd1fcd4d7202 (patch)
treea272f59949f9be336304db1e9fb85bd7388ad446
parentAdd Status to README (diff)
downloadsubv-11c5c7d29a1b96367ac94c78a898fd1fcd4d7202.tar.gz
subv-11c5c7d29a1b96367ac94c78a898fd1fcd4d7202.zip
Hello World!
-rwxr-xr-xelf.py15
-rw-r--r--format.py7
-rw-r--r--pack.py19
-rw-r--r--survey.py2
-rw-r--r--test.subv45
5 files changed, 53 insertions, 35 deletions
diff --git a/elf.py b/elf.py
index ae81253..a3379c5 100755
--- a/elf.py
+++ b/elf.py
@@ -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)
diff --git a/format.py b/format.py
index 6a6a3b2..053e04e 100644
--- a/format.py
+++ b/format.py
@@ -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__':
diff --git a/pack.py b/pack.py
index f772de3..98d7d86 100644
--- a/pack.py
+++ b/pack.py
@@ -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__':
diff --git a/survey.py b/survey.py
index 23fac27..442ef11 100644
--- a/survey.py
+++ b/survey.py
@@ -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)
diff --git a/test.subv b/test.subv
index f1c73fd..05cb8c1 100644
--- a/test.subv
+++ b/test.subv
@@ -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