~charles/awk-riscv

fa3c47fde6c5a46743f34bc972ece337a8974615 — Charles Daniels 10 months ago 1239206
assemble lw and sw
2 files changed, 73 insertions(+), 1 deletions(-)

M riscv.awk
A tests/simulation/asm_lwsw.txt
M riscv.awk => riscv.awk +61 -1
@@ 228,6 228,23 @@
#   related instructions are not implemented.
#
#
#                         DIFFERENCES FROM RARS
#
# This program implements J-type immediate encoding slightly differently. I
# believe this is an error in the implementation RARs uses. I have opened an
# issue upstream: https://github.com/TheThirdOne/rars/issues/89. One it is
# established which approach is correct, this program will be updated to use
# it.
#
# The syntax for lw and sw is changed in order to make them easier to parse.
# The assembled instructions are identical in memory.  The equivalence table is
# shown below:
#
#		RARS instruction	riscv.awk instruction
#		lw x1 100(x2)		lw x1 x2 100
#		sw x2 100(x1)		sw x1 x2 100
#
#
#                               LIMITATIONS
#
# Support for error handling, detecting and recovering from bad inputs, and so


@@ 381,6 398,12 @@ function packBimm(v) {
		rshift(and(v, 0x800), 4))
}

function packSimm(v) {
	return or( \
	       lshift(and(v, 0x1f), 7), \
	       lshift(and(v, 0xfe0), 20))
}

#### INSTRUCTION DECODING #####################################################

# masks to pull relevant values out of an instruction


@@ 616,6 639,8 @@ function assemble() {
	# nop -- generate a no-op
	#
	# B -- branches
	#
	# S -- store instruction
	asm_style = "error"

	if (tolower($1) == "addi") {


@@ 779,6 804,16 @@ function assemble() {
		asm_opcode = 0x63
		asm_funct3 = 0x7

	} else if  (tolower($1) == "lw") {
		asm_style = "I"
		asm_opcode = 0x3
		asm_funct3 = 0x2

	} else if  (tolower($1) == "sw") {
		asm_style = "S"
		asm_opcode = 0x23
		asm_funct3 = 0x2

	} else {
		printf("# ASSEMBLER ERROR: expected opcode, got '%s' (line %d: '%s')\n", $1, NR, asm_line)
		assemble_errors++


@@ 889,6 924,30 @@ function assemble() {
			unresolved[$4] = asmcursor
		}

	} else if (asm_style == "S") {
		asm_rs1 = parsereg($2)
		if (asm_rs1 < 0) {
			printf("# ASSEMBLER ERROR: expected rs1 register, got '%s' (line %d: '%s')\n", $2, NR, asm_line)
			assemble_errors++
			return
		}

		asm_rs2 = parsereg($3)
		if (asm_rs1 < 0) {
			printf("# ASSEMBLER ERROR: expected rs2 register, got '%s' (line %d: '%s')\n", $3, NR, asm_line)
			assemble_errors++
			return
		}

		if (strtonum($4) > 2047 || strtonum($4) < -2048) {
			printf("# ASSEMBLER ERROR: expected immediate in range -2048...2047, got '%s' (line %d: '%s')\n", $4, NR, asm_line)
			assemble_errors++
			return
		}

		asm_immS = packSimm(dec2two(strtonum($4)))


	} else if (asm_style == "nop") {
		# do nothing
	}


@@ 904,7 963,8 @@ function assemble() {
		 lshift(asm_rs2, 20), \
		 lshift(asm_funct7, 25), \
		 asm_immJ, \
		 asm_immB)
		 asm_immB, \
		 asm_immS)

	memwrite(asmcursor, asm_inst)


A tests/simulation/asm_lwsw.txt => tests/simulation/asm_lwsw.txt +12 -0
@@ 0,0 1,12 @@
mode assemble
lw x1 x2 100
sw x1 x2 100

mode normal

assert mem 0x000 0x06412083
assert mem 0x004 0x0620a223

dump