From 6d1413c754291d19a042e6085a4328931b9c757f Mon Sep 17 00:00:00 2001 From: Andrew Ekstedt Date: Fri, 23 Aug 2024 23:14:11 -0700 Subject: [PATCH] crc32 --- .gitignore | 1 + Makefile | 1 + crc32.s | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 181 insertions(+) create mode 100644 crc32.s diff --git a/.gitignore b/.gitignore index 498cced..86608c7 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ /hexdump /prtest /flagtest +/crc32 *.o diff --git a/Makefile b/Makefile index 20aba3d..8fc8739 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,7 @@ all: true false cat env hexdump echo prtest: prtest.o lib/printregs.o lib/hex.o sorttest: lib/sort.o flagtest: lib/flags.o +crc32: lib/hex.o .PHONY: test test: diff --git a/crc32.s b/crc32.s new file mode 100644 index 0000000..8192223 --- /dev/null +++ b/crc32.s @@ -0,0 +1,179 @@ +.globl _start +.option rvc # enable compressed instructions +.option norelax + +.data +sigaction_ignore: + .dword 1 # sa_handler = SIG_IGN + .dword 0 # sa_flags + .dword 0 # sa_mask + +.bss +.equ bufsize, 4<<10 +buf: .zero bufsize + +.bss +crc_table: .zero 256*4 + +.text +_start: + # ignore SIGPIPE + li a7, 134 # sys_rt_sigaction + li a0, 13 # SIGPIPE + la a1, sigaction_ignore # action + li a2, 0 # oldact = NULL + # if this is a non-null pointer the kernel will + # return a copy of the old action to us, but we don't care + li a3, 8 # signal set size (bytes) + ecall + +# TODO: error messages + + call init_table + + li s1, 0 # CRC + +loop: + li a7, 63 # sys_read + li a0, 0 # fd = stdin + la a1, buf # pointer to buffer + li a2, bufsize # size of buffer + ecall + #li a0, 0 + + # return in a0 + # negative => error code + # positive => number of byte read + # zero => end of input + bltz a0, error + beqz a0, done + + mv s0, a0 + + # loop over buffer and update crc + mv a0, s1 + la a1, buf + mv a2, s0 # buf size + call crc_update + mv s1, a0 + + bnez s0, loop # loop if not end of input + +error: + li a7, 93 # sys_exit + li a0, 1 # status code = failure + ecall + +done: + #la a0, crc_table + #addi a0, a0, 4*0x80 + #lwu a0, (a0) + #mv s1, a0 + + # encode crc + la a0, buf + mv a1, s1 + call u32hex + + # add newline + la a1, buf + li t0, 10 # '\n' + sb t0, 8(a1) + + # write crc + li a7, 64 # sys_write + li a0, 1 # fd = stdout + li a2, 9 # size of data + ecall + #mv s0, a0 + + # check for EPIPE + li t0, -32 + beq a0, t0, ok # EPIPE + bltz a0, error + +ok: + li a7, 93 # sys_exit + li a0, 0 # status code = success + ecall + +#............................................ + +.equ poly, 0xEDB88320 + +.text +init_table: + la s0, crc_table + li t6, 256 + li a0, poly +iloop: + addi t6, t6, -1 + mv t0, t6 + li t2, 8 +iloop2: + andi t1, t0, 1 + srli t0, t0, 1 + beqz t1, 0f + xor t0, t0, a0 +0: + addi t2, t2, -1 + bnez t2, iloop2 + + slli t1, t6, 2 + add t1, t1, s0 + sw t0, (t1) + bnez t6, iloop + ret + +#............................................ + +# inputs: +# a0: crc +# a1: buf +# a2: buf size +# +# returns: +# a0 - new crc +# +# clobbers: t0, t1, t2, t3 +.text +crc_update: + mv t1, s0 + mv t2, s1 + mv t3, s2 + # invert crc + li t0, -1 + srli t0, t0, 32 + xor a0, a0, t0 + + mv s0, a0 # crc + mv s1, a1 # buffer + la s2, crc_table + + beqz a2, udone + +uloop: + lbu a1, (s1) # load byte + andi t0, a0, 0xff # a1 = crc&0xff ^ byte + xor a1, a1, t0 + srli a0, a0, 8 # crc >>= 8 + slli a1, a1, 2 # convert a1 to table address + add a1, a1, s2 + lwu a1, (a1) # load crc table entry + xor a0, a0, a1 # crc ^= table entry + + addi s1, s1, 1 + addi a2, a2, -1 + bnez a2, uloop + +udone: + # restore saved registers + mv s0, t1 + mv s1, t2 + mv s2, t3 + # invert crc + #li t0, -1 + #srli t0, t0, 32 + li t0, 0xFFFFFFFF + xor a0, a0, t0 + ret