scummvm/engines/scumm/smush/codec47ARM.s
2011-05-12 01:16:22 +02:00

370 lines
9.0 KiB
ArmAsm

@ ScummVM - Graphic Adventure Engine
@
@ ScummVM is the legal property of its developers, whose names
@ are too numerous to list here. Please refer to the COPYRIGHT
@ file distributed with this source distribution.
@
@ This program is free software@ you can redistribute it and/or
@ modify it under the terms of the GNU General Public License
@ as published by the Free Software Foundation@ either version 2
@ of the License, or (at your option) any later version.
@
@ This program is distributed in the hope that it will be useful,
@ but WITHOUT ANY WARRANTY@ without even the implied warranty of
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ GNU General Public License for more details.
@
@ You should have received a copy of the GNU General Public License
@ along with this program@ if not, write to the Free Software
@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@
@ @author Robin Watts (robin@wss.co.uk)
@
@ This file, provides an ARM optimised version of sections of codec47.cpp.
@ The algorithm is essentially the same as that within codec47.cpp
@ so to understand this file you should understand codec47.cpp first.
.text
.global _ARM_Smush_decode2
_ARM_Smush_decode2:
@ r0 = dst
@ r1 = src
@ r2 = width
@ r3 = height
@ r4 = param
@ <> = _table
@ <> = _tableBig
@ <> = _offset1
@ <> = _offset2
@ <> = _tableSmall
STMFD r13!,{r2,r4-r11,R14}
LDR r4,[r13,#40] @ r4 = param (40 = (9+1)*4)
@ stall
@ stall
SUB r4,r4,#0xF8
@ r0 = dst
@ r1 = _d_src
@ r2 = _d_pitch
@ r3 = height
@ r4 = param
ADD r7,r2,#7 @ r14 = bw
MOV r7,r7,LSR #3
y_loop:
x_loop:
@ LEVEL 1
LDRB r6,[r1],#1 @ r6 = *_d_src++
@ stall
@ stall
CMP r6,#0xF8
BLT level1codeSMALL
CMP r6,#0xFC
BLT level1codeMID
BEQ level1codeFC
CMP r6,#0xFE
BGT level1codeFF
BEQ level1codeFE
level1codeFD:
LDRB r6,[r1],#1 @ r6 = tmp = *_d_src++
LDR r8,[r13,#48] @ r8 = _tableBig (48 = (9+1+2)*4)
@ stall
ADD r12,r6,r6,LSL #1 @ r12= tmp*3
ADD r6,r6,r12,LSL #5 @ r6 = tmp*97
ADD r8,r8,r6,LSL #2 @ r8 = _tableBig + tmp*388
LDRB r9,[r8,#384] @ r9 = l = tmp_ptr[384]
LDRB r6,[r1],#1 @ r6 = val = *_d_src++
ADD r12,r8,#384 @ r12= &tmp_ptr[384]
@ I don''t really believe the next 2 lines are necessary, but...
CMP r9,#0
BEQ level1codeFD_over1
level1codeFD_loop1:
LDRB r10,[r8],#1
LDRB r11,[r8],#1
SUBS r9,r9,#1
ADD r10,r10,r0
STRB r6,[r10,r11,LSL #8] @ *(_d_dst + (*tmp_ptr2++)) = val
BGT level1codeFD_loop1
level1codeFD_over1:
LDRB r9,[r12,#1] @ r9 = l = tmp_ptr[385]
LDRB r6,[r1],#1 @ r6 = val = *_d_src++
SUB r12,r12,#256 @ r12= &tmp_ptr[128] (256 = 384-128)
@ I don''t really believe the next 2 lines are necessary, but...
CMP r9,#0
BEQ level1codeFD_over2
level1codeFD_loop2:
LDRB r10,[r12],#1
LDRB r11,[r12],#1
SUBS r9,r9,#1
ADD r10,r10,r0
STRB r6,[r10,r11,LSL #8] @ *(_d_dst + (*tmp_ptr2++)) = val
BGT level1codeFD_loop2
level1codeFD_over2:
level1_end:
ADD r0,r0,#8
SUBS r7,r7,#1
BGT x_loop
ADD r7,r2,#7
MOV r7,r7,LSR #3
ADD r0,r0,r2,LSL #3
SUB r0,r0,r7,LSL #3 @ r0 = dst += next_line
SUBS r3,r3,#8 @ if (--bh > 0)
BGT y_loop @ loop back
LDMFD r13!,{r2,r4-r11,PC}
level1codeSMALL:
LDR r8,[r13,#44] @ r8 = _table (44 = (9+1+1)*4)
LDR r9,[r13,#52] @ r9 = _offset1 (52 = (9+1+3)*4)
MOV r6,r6,LSL #1 @ r6 = code<<1
LDRSH r8,[r8,r6] @ tmp2 = _table[code]
level1codeFC:
@ EQ => FC
LDREQ r9,[r13,#56] @ r9 = _offset2 (56 = (9+1+4)*4)
MOVEQ r8,#0
SUB r11,r2,#7 @ r11 = _d_pitch-7
ADD r9,r9,r0 @ tmp2 = _d_dst+_offset
ADD r8,r8,r9 @ tmp2 = _d_dst+_table[code]+_offset
@ r8 = &_dst[tmp2]
MOV r12,#8
level1codeSMALL_loop:
LDRB r5, [r8],#1 @ r5 = d_dst[tmp2]
LDRB r6, [r8],#1 @ r10 = d_dst[tmp2]
LDRB r9, [r8],#1 @ r10 = d_dst[tmp2]
LDRB r10,[r8],#1 @ r10 = d_dst[tmp2]
STRB r5, [r0],#1 @ d_dst[0] = r5
STRB r6, [r0],#1 @ d_dst[1] = r6
STRB r9, [r0],#1 @ d_dst[2] = r9
STRB r10,[r0],#1 @ d_dst[3] = r10
LDRB r5, [r8],#1 @ r5 = d_dst[tmp2]
LDRB r6, [r8],#1 @ r10 = d_dst[tmp2]
LDRB r9, [r8],#1 @ r10 = d_dst[tmp2]
LDRB r10,[r8],r11 @ r10 = d_dst[tmp2]
STRB r5, [r0],#1 @ d_dst[4] = r5
STRB r6, [r0],#1 @ d_dst[5] = r6
STRB r9, [r0],#1 @ d_dst[6] = r9
STRB r10,[r0],r11 @ d_dst[7] = r10 d_dst += d_pitch
SUBS r12,r12,#1
BGT level1codeSMALL_loop
SUB r0,r0,r2,LSL #3 @ revert d_dst
B level1_end
level1codeMID:
@ LT => F8<=code<FC case
@ EQ => FE case
LDRB r6,[r4,r6] @ r6 = t = _paramPtr[code]
level1codeFE:
LDREQB r6,[r1],#1 @ r6 = t = *_d_src++
MOV r12,#8
SUB r11,r2,#7 @ r11 = _d_pitch-7
level1codeMID_loop:
STRB r6,[r0],#1
STRB r6,[r0],#1
STRB r6,[r0],#1
STRB r6,[r0],#1
STRB r6,[r0],#1
STRB r6,[r0],#1
STRB r6,[r0],#1
STRB r6,[r0],r11
SUBS r12,r12,#1
BGT level1codeMID_loop
SUB r0,r0,r2,LSL #3 @ revert d_dst
B level1_end
level1codeFF:
BL level2
ADD r0,r0,#4
BL level2
ADD r0,r0,r2,LSL #2
SUB r0,r0,#4
BL level2
ADD r0,r0,#4
BL level2
SUB r0,r0,#4
SUB r0,r0,r2,LSL #2
B level1_end
level2:
@ r0 = _d_dst
@ r1 = _d_src
@ r2 = _d_pitch
@ r3 = PRESERVE
@ r4 = param
@ r7 = PRESERVE
@ r14= return address
LDRB r6,[r1],#1 @ r6 = *_d_src++
@ stall
@ stall
CMP r6,#0xF8
BLT level2codeSMALL
CMP r6,#0xFC
BLT level2codeMID
BEQ level2codeFC
CMP r6,#0xFE
BGT level2codeFF
BEQ level2codeFE
level2codeFD:
LDRB r6,[r1],#1 @ r6 = tmp = *_d_src++
LDR r8,[r13,#60] @ r8 = _tableSmall (60 = (9+1+5)*4)
@ stall
@ stall
ADD r8,r8,r6,LSL #7 @ r8 = _tableSmall + tmp*128
LDRB r9,[r8,#96] @ r9 = l = tmp_ptr[96]
LDRB r6,[r1],#1 @ r6 = val = *_d_src++
ADD r12,r8,#32 @ r12 = tmp_ptr + 32
@ I don''t really believe the next 2 lines are necessary, but...
CMP r9,#0
BEQ level2codeFD_over1
level2codeFD_loop1:
LDRB r10,[r8],#1
LDRB r11,[r8],#1
SUBS r9,r9,#1
ADD r10,r10,r0
STRB r6,[r10,r11,LSL #8] @ *(_d_dst + (*tmp_ptr2++)) = val
BGT level2codeFD_loop1
level2codeFD_over1:
LDRB r9,[r12,#65] @ r9 = l = tmp_ptr[97] (65 = 97-32)
LDRB r6,[r1],#1 @ r6 = val = *_d_src++
@ I don''t really believe the next 2 lines are necessary, but...
CMP r9,#0
MOVEQ PC,R14
level2codeFD_loop2:
LDRB r10,[r12],#1
LDRB r11,[r12],#1
SUBS r9,r9,#1
ADD r10,r10,r0
STRB r6,[r10,r11,LSL #8] @ *(_d_dst + (*tmp_ptr2++)) = val
BGT level2codeFD_loop2
MOV PC,R14
level2codeSMALL:
LDR r8,[r13,#44] @ r8 = _table (44 = (9+1+1)*4)
LDR r9,[r13,#52] @ r9 = _offset1 (52 = (9+1+3)*4)
MOV r6,r6,LSL #1 @ r6 = code<<1
LDRSH r8,[r8,r6] @ tmp2 = _table[code]
level2codeFC:
@ EQ => FC
LDREQ r9,[r13,#56] @ r9 = _offset2 (56 = (9+1+4)*4)
MOVEQ r8,#0
SUB r11,r2,#3 @ r11 = _d_pitch-3
ADD r9,r9,r0 @ tmp2 = _d_dst + _table[code]
ADD r8,r8,r9 @ tmp2 = _d_dst+_table[code]+_offset1
@ r8 = &_dst[tmp2]
MOV r12,#4
level2codeSMALL_loop:
LDRB r5, [r8],#1 @ r5 = d_dst[tmp2]
LDRB r6, [r8],#1 @ r10 = d_dst[tmp2]
LDRB r9, [r8],#1 @ r10 = d_dst[tmp2]
LDRB r10,[r8],r11 @ r10 = d_dst[tmp2]
STRB r5, [r0],#1 @ d_dst[4] = r5
STRB r6, [r0],#1 @ d_dst[5] = r6
STRB r9, [r0],#1 @ d_dst[6] = r9
STRB r10,[r0],r11 @ d_dst[7] = r10 d_dst += d_pitch
SUBS r12,r12,#1
BGT level2codeSMALL_loop
SUB r0,r0,r2,LSL #2 @ revert d_dst
MOV PC,R14
level2codeMID:
@ LT => F8<=code<FC case
@ EQ => FE case
LDRB r6,[r4,r6] @ r6 = t = _paramPtr[code]
level2codeFE:
LDREQB r6,[r1],#1 @ r6 = t = *_d_src++
MOV r12,#4
SUB r11,r2,#3 @ r11 = _d_pitch-7
level2codeMID_loop:
STRB r6,[r0],#1
STRB r6,[r0],#1
STRB r6,[r0],#1
STRB r6,[r0],r11
SUBS r12,r12,#1
BGT level2codeMID_loop
SUB r0,r0,r2,LSL #2 @ revert d_dst
MOV PC,R14
level2codeFF:
MOV r5,r14
BL level3
ADD r0,r0,#2
BL level3
ADD r0,r0,r2,LSL #1
SUB r0,r0,#2
BL level3
ADD r0,r0,#2
BL level3
SUB r0,r0,#2
SUB r0,r0,r2,LSL #1
MOV PC,R5
level3:
@ r0 = _d_dst
@ r1 = _d_src
@ r2 = _d_pitch
@ r3 = PRESERVE
@ r4 = param
@ r5 = preserve
@ r7 = PRESERVE
@ r14= return address
LDRB r6,[r1],#1 @ r6 = code = *_d_src++
@ stall
@ stall
CMP r6,#0xF8
BLT level3codeSMALL
CMP r6,#0xFC
BLT level3codeMID
BEQ level3codeFC
CMP r6,#0xFE
BGT level3codeFF
level3codeFE:
LDRB r6,[r1],#1 @ r6 = t = *_d_src++
level3codeMID:
@ LT => F8<=code<FC case
@ EQ => FE case
LDRLTB r6,[r4,r6] @ r6 = t = _paramPtr[code]
@ stall
@ stall
STRB r6,[r0,#1]
STRB r6,[r0],r2
STRB r6,[r0,#1]
STRB r6,[r0],-r2
MOV PC,R14
level3codeFF:
LDRB r6,[r1],#1
LDRB r9,[r1],#1
LDRB r10,[r1],#1
LDRB r11,[r1],#1
STRB r9, [r0,#1]
STRB r6, [r0],r2
STRB r11,[r0,#1]
STRB r10,[r0],-r2
MOV PC,R14
level3codeSMALL:
LDR r8,[r13,#44] @ r8 = _table (44 = (9+1+1)*4)
LDR r9,[r13,#52] @ r9 = _offset1 (52 = (9+1+3)*4)
MOV r6,r6,LSL #1 @ r6 = code<<1
LDRSH r8,[r8,r6] @ tmp2 = _table[code]
level3codeFC:
@ EQ => FC
LDREQ r9,[r13,#56] @ r9 = _offset2 (56 = (9+1+4)*4)
MOVEQ r8,#0
ADD r9,r9,r0 @ tmp2 = _d_dst+offset
ADD r8,r8,r9 @ tmp2 = _d_dst+_table[code]+_offset
@ r8 = &_dst[tmp2]
LDRB r6, [r8,#1] @ r6 = d_dst[tmp2+1]
LDRB r9, [r8],r2 @ r9 = d_dst[tmp2+0]
LDRB r10,[r8,#1] @ r10= d_dst[tmp2+dst+1]
LDRB r11,[r8],-r2 @ r11= d_dst[tmp2+dst]
STRB r6, [r0,#1] @ d_dst[1 ] = r6
STRB r9, [r0],r2 @ d_dst[0 ] = r9
STRB r10,[r0,#1] @ d_dst[dst+1] = r10
STRB r11,[r0],-r2 @ d_dst[dst ] = r11
MOV PC,R14