@ Code by mtheall
#include "asmfunc.h"
.arm
.cpu mpcore
.fpu vfpv2
ASM_FUNC lz11Decompress
push {r4-r6}
ldr r3, =(0x01010101)
.Lloop:
cmp r2, #0 @ if(size <= 0)
pople {r4-r6} @ pop stack
bxle lr @ return
rors r3, r3, #1 @ r3 = (r3<<31) | (r3>>1)
ldrcsb r12, [r0], #1 @ if(r3 & (1<<31)) flags = *in++
tst r12, r3 @ if(flags & r3 == 0)
beq .Lcopy_uncompressed @ goto copy_uncompressed
ldrb r4, [r0], #1 @ r4 = *in++
and r5, r4, #0xF0 @ r5 = r4 & 0xF0
cmp r5, #0x00 @ if(r5 == 0x00)
beq .Lextended @ goto extended
cmp r5, #0x10 @ if(r5 == 0x10)
beq .LXextended @ goto Xextended
lsr r6, r4, #4 @ len = r4>>4
add r6, r6, #1 @ len++
b .L1
.Lextended:
lsl r6, r4, #4 @ len = r4<<4
ldrb r4, [r0], #1 @ r4 = *in++
orr r6, r6, r4, lsr #4 @ len = len | (r4>>4)
add r6, r6, #0x11 @ len += 0x11
b .L1
.LXextended:
and r4, r4, #0x0F @ r4 &= 0x0F
lsl r6, r4, #12 @ len = r4<<12
ldrb r4, [r0], #1 @ r4 = *in++
orr r6, r6, r4, lsl #4 @ len |= r4<<4
ldrb r4, [r0], #1 @ r4 = *in++
orr r6, r6, r4, lsr #4 @ len |= r4>>4
add r6, r6, #0x011 @ len += 0x011
add r6, r6, #0x100 @ len += 0x100
.L1:
and r5, r4, #0x0F @ disp = r4 & 0x0F note: disp is in r5
ldrb r4, [r0], #1 @ r4 = *in++
orr r4, r4, r5, lsl #8 @ disp = r4 | (disp<<8) note: disp changes to r4
add r4, r4, #1 @ disp++
sub r2, r2, r6 @ size -= len
tst r4, #1 @ if(r4 & 1 == 0) // aligned displacement
beq .Lcopy_aligned @ goto copy_aligned
.Lcopy_compressed:
ldrb r5, [r1, -r4] @ r5 = *(out - disp)
subs r6, r6, #1 @ if(len-- == 1)
strb r5, [r1], #1 @ *out++ = r5
bne .Lcopy_compressed @ goto copy_compressed
b .Lloop @ goto loop
.Lcopy_aligned:
tst r1, #0x1 @ if(r1 & 0x1 == 0) // src/dst is aligned
beq .Lcopy_hwords @ goto copy_hwords
ldrb r5, [r1, -r4] @ r5 = *(out - disp) // read a byte to align
strb r5, [r1], #1 @ *out++ = r5
sub r6, r6, #1 @ len--
.Lcopy_hwords:
subs r6, r6, #2 @ len -= 2
ldrgeh r5, [r1, -r4] @ if(len >= 0) r5 = *(short*)(out - disp)
strgeh r5, [r1], #2 @ if(len >= 0) *(short*)out++ = r5
beq .Lloop @ if(len == 0) goto loop
bgt .Lcopy_hwords @ if(len > 0) goto copy_hwords
@ extra byte
ldrb r5, [r1, -r4] @ r5 = *(out - disp)
strb r5, [r1], #1 @ *out++ = r5
b .Lloop @ goto loop
.Lcopy_uncompressed:
ldrb r4, [r0], #1 @ r4 = *in++
sub r2, r2, #1 @ size--
strb r4, [r1], #1 @ *out++ = r4
b .Lloop @ goto loop
.pool