~charles/awk-riscv

83354602bd03f7baeeb52290418320d6bd2bdb95 — Charles Daniels 10 months ago 42191b8
implement label resolution
2 files changed, 63 insertions(+), 2 deletions(-)

M riscv.awk
M tests/simulation/asm_jal.txt
M riscv.awk => riscv.awk +52 -1
@@ 67,6 67,12 @@
#	If TRACEMEM is nonzero, all memory reads and writes are pritned to
#	standard out.
#
# traceresolve TRACERESOLVE
#
#	If TRACERESOLVE is nonzero, then a detailed trace of assembler  label
#	resolution will be displayed. This will also display label information
#	as they are encountered by the assembler.
#
# poke ADDR VAL
#
#	Updates the memory address ADDR to the given 32-bit value VAL.


@@ 122,6 128,9 @@
#	assembly by rewriting the corresponding instructions in-memory to point
#	to the appropriate locations.
#
#	Note that errors in label resolution count as assembler errors for
#	exit-code calculation.
#
# debug FIELD INST
#
#	Displays the value of the specified field FIELD of the instruction


@@ 556,8 565,13 @@ function assemble() {

	# handle labels
	if (match($1, /[a-zA-Z][a-zA-Z0-9_]+[:]/)) {
		labels[sub(/[:]/, $1, $1)] = asmcursor
		sub(/[:]/, "", $1)
		labels[$1] = asmcursor
		if (traceresolve) {
			printf("# encountered label '%s' at mem[0x%08x]\n", $1, asmcursor)
		}
		fieldshift()

	}

	# skip comments and empty lines


@@ 967,6 981,9 @@ BEGIN {
	# display memory reads and writes
	tracemem=0

	# debug label resolve
	traceresolves = 0

	# "regs" and "mem" used for register and memory state, but not
	# initialized explicitly for efficiency, since undefined values have
	# a value of 0 in AWK.


@@ 1010,6 1027,8 @@ $1 == "traceinst" { traceinst=strtonum($2) ; next }

$1 == "tracemem" { tracemem=strtonum($2) ; next }

$1 == "traceresolve" { traceresolve=strtonum($2) ; next }

$1 == "poke" { memwrite(strtonum($2), strtonum($3)) ; next }

$1 == "peek" { printf("0x%08x\n", memread(strtonum($2))) ; next }


@@ 1046,6 1065,38 @@ $1 == "step" {
	next
}

$1 == "resolve" {
	for (resolve_label in unresolved) {
		if (traceresolve) {
			printf("# resolving label '%s'\n", resolve_label)
		}


		resolve_addr = unresolved[resolve_label]
		resolve_memval = memread(resolve_addr)

		if (! (resolve_label in labels)) {
			printf("# RESOLVE ERROR: unknown label '%s'\n", resolve_label)
			assemble_errors ++
			continue
		}

		if (traceresolve) {
			printf("# \tcurrent value: 0x%08x at mem[0x%08x]\n", resolve_memval, resolve_addr)
			printf("# \tresolves to: 0x%08x\n", labels[resolve_label])
		}

		resolve_memval = or(resolve_memval, packJimm(dec2two(labels[resolve_label] - resolve_addr)))
		if (traceresolve) {
			printf("# \tupdate memory value to: 0x%08x\n", resolve_memval)
		}

		memwrite(unresolved[resolve_label], resolve_memval)

		delete unresolved[resolve_label]
	}
}

$1 == "showregs" {
	printf("# register: ")
	for (i = 0 ; i < 8 ; i ++) {

M tests/simulation/asm_jal.txt => tests/simulation/asm_jal.txt +11 -1
@@ 1,4 1,5 @@
tracemem 1
traceresolve 1

mode assemble
jal x1 2


@@ 7,7 8,7 @@ jal x1 0x4
jal x1 0x8
jal x1 0x10
jal x1 0x20
jal x1 0x40
l1: jal x1 0x40
jal x1 0x80
jal x1 0x100
jal x1 0x200


@@ 23,8 24,15 @@ jal x1 0x40000
jal x1 0x80000
jal x1 -1
jal x1 -2
jal x0 l1
jal x3 l2
nop
nop
l2:
nop

mode normal
resolve

assert mem 0x00000000 0x002000ef
assert mem 0x00000004 0x002000ef


@@ 48,5 56,7 @@ assert mem 0x00000048 0x000400ef
assert mem 0x0000004c 0x000800ef
assert mem 0x00000050 0xfffff0ef
assert mem 0x00000054 0xfffff0ef
assert mem 0x00000058 0xfc1ff06f
assert mem 0x0000005c 0x00c001ef

dump