diff --git a/asm_unpackers/Makefile b/asm_unpackers/Makefile index 43b7473..ef49ae9 100644 --- a/asm_unpackers/Makefile +++ b/asm_unpackers/Makefile @@ -1,4 +1,4 @@ -build/unpack_riscv64: ../c_unpacker/main.c ../c_unpacker/unpack.c +build/unpack_riscv64: ../c_unpacker/main.c unpack_riscv.S mkdir -p build riscv64-linux-gnu-gcc -g -static -o $@ $^ @@ -6,6 +6,11 @@ test_riscv64: build/unpack_riscv64 qemu-riscv64 $< test_data.upk /tmp/out.bin cmp test_data.bin /tmp/out.bin +build/unpack_riscv64.bin: unpack_riscv.S + mkdir -p build + riscv64-linux-gnu-gcc -c -o build/unpack_riscv64.o $? + riscv64-linux-gnu-objcopy -O binary --only-section=.text build/unpack_riscv64.o $@ + build/unpack_armv6m: ../c_unpacker/main.c unpack_armv6m.S mkdir -p build arm-linux-gnueabihf-gcc -g -static -o $@ $^ @@ -15,6 +20,7 @@ test_armv6m: build/unpack_armv6m cmp test_data.bin /tmp/out.bin build/unpack_armv6m.bin: unpack_armv6m.S + mkdir -p build arm-none-eabi-gcc -march=armv6-m -c -o build/unpack_armv6m.o $? arm-none-eabi-objcopy -O binary --only-section=.text build/unpack_armv6m.o $@ @@ -26,5 +32,5 @@ test_c: build/unpack_c $< test_data.upk /tmp/out.bin cmp test_data.bin /tmp/out.bin -sizes: build/unpack_armv6m.bin +sizes: build/unpack_armv6m.bin build/unpack_riscv64.bin ls -l build/*.bin \ No newline at end of file diff --git a/asm_unpackers/unpack_riscv.S b/asm_unpackers/unpack_riscv.S new file mode 100644 index 0000000..b0266a2 --- /dev/null +++ b/asm_unpackers/unpack_riscv.S @@ -0,0 +1,144 @@ +.section .text + +#define FRAME_SIZE (256+64*4+4) + +// x8 prob array ptr +// x9 prev was literal +// x10 out ptr +// x11 in ptr +// x12 offset +// x13 state + +.global upkr_unpack +.type upkr_unpack, %function +upkr_unpack: + mv t4, ra + mv x17, x8 + mv t6, x9 + li x13, FRAME_SIZE + li x9, 128 +1: + addi sp, sp, -1 + sb x9, 0(sp) + addi x13, x13, -1 + bnez x13, 1b + +.Lmainloop: + li x14, 0 + jal upkr_decode_bit + beqz x15, .Lliteral + + li x14, 256 + beqz x9, .Lread_offset + jal upkr_decode_bit + beqz x15, .Lskip_offset +.Lread_offset: + jal t3, upkr_decode_number + addi x12, x9, -1 + beqz x12, .Ldone + +.Lskip_offset: + li x14, 256+64 + jal t3, upkr_decode_number +1: + sub x15, x10, x12 + lbu x15, (x15) + sb x15, (x10) + addi x10, x10, 1 + addi x9, x9, -1 + bnez x9, 1b + j .Lmainloop + +.Lliteral: + li x14, 1 +1: + jal upkr_decode_bit + slli x14, x14, 1 + add x14, x14, x15 + srli x9, x14, 8 + beqz x9, 1b + sb x14, 0(x10) + addi x10, x10, 1 + j .Lmainloop + +.Ldone: + addi sp, sp, FRAME_SIZE + mv x8, x17 + mv x9, t6 + jr t4 + +// x14 context index +// return: x9 decoded number +upkr_decode_number: + mv t5, x14 + li x9, 0 + li x8, 1 +1: + addi x14, x14, 1 + jal upkr_decode_bit + beqz x15, 1f + addi x14, x14, 1 + jal upkr_decode_bit + beqz x15, 2f + add x9, x9, x8 +2: + slli x8, x8, 1 + j 1b +1: + add x9, x9, x8 + + mv x14, t5 + jr t3 + +upkr_load_byte: + lbu x15, 0(x11) + addi x11, x11, 1 + slli x13, x13, 8 + add x13, x13, x15 +// x8 prob array ptr +// x11 in ptr +// x13 state +// x14 context index +// return: x15 decoded bit +upkr_decode_bit: + srli x15, x13, 12 + beqz x15, upkr_load_byte + + mv t0, x9 + mv t1, x14 + mv t2, x10 + + add x14, x14, sp + lbu x9, 0(x14) + + andi x10, x13, 255 + sltu x15, x10, x9 + srli x13, x13, 8 + beqz x15, .Lelse + + mul x13, x13, x9 + add x13, x13, x10 + li x10, 256 + 8 + sub x10, x10, x9 + srli x10, x10, 4 + add x9, x9, x10 + j .Lendif + +.Lelse: + li x16, 256 + sub x16, x16, x9 + mul x13, x13, x16 + add x13, x13, x10 + sub x13, x13, x9 + addi x10, x9, 8 + srli x10, x10, 4 + sub x9, x9, x10 + +.Lendif: + + sb x9, 0(x14) + + mv x9, t0 + mv x14, t1 + mv x10, t2 + ret