1370b324cSopenharmony_ci// LzmaDecOpt.S -- ARM64-ASM version of LzmaDec_DecodeReal_3() function 2370b324cSopenharmony_ci// 2021-04-25 : Igor Pavlov : Public domain 3370b324cSopenharmony_ci 4370b324cSopenharmony_ci/* 5370b324cSopenharmony_ci; 3 - is the code compatibility version of LzmaDec_DecodeReal_*() 6370b324cSopenharmony_ci; function for check at link time. 7370b324cSopenharmony_ci; That code is tightly coupled with LzmaDec_TryDummy() 8370b324cSopenharmony_ci; and with another functions in LzmaDec.c file. 9370b324cSopenharmony_ci; CLzmaDec structure, (probs) array layout, input and output of 10370b324cSopenharmony_ci; LzmaDec_DecodeReal_*() must be equal in both versions (C / ASM). 11370b324cSopenharmony_ci*/ 12370b324cSopenharmony_ci 13370b324cSopenharmony_ci 14370b324cSopenharmony_ci#include "7zAsm.S" 15370b324cSopenharmony_ci 16370b324cSopenharmony_ci // .arch armv8-a 17370b324cSopenharmony_ci // .file "LzmaDecOpt.c" 18370b324cSopenharmony_ci .text 19370b324cSopenharmony_ci .align 2 20370b324cSopenharmony_ci .p2align 4,,15 21370b324cSopenharmony_ci#ifdef __APPLE__ 22370b324cSopenharmony_ci .globl _LzmaDec_DecodeReal_3 23370b324cSopenharmony_ci#else 24370b324cSopenharmony_ci .global LzmaDec_DecodeReal_3 25370b324cSopenharmony_ci#endif 26370b324cSopenharmony_ci // .type LzmaDec_DecodeReal_3, %function 27370b324cSopenharmony_ci 28370b324cSopenharmony_ci// #define _LZMA_SIZE_OPT 1 29370b324cSopenharmony_ci 30370b324cSopenharmony_ci#define LZMA_USE_4BYTES_FILL 1 31370b324cSopenharmony_ci// #define LZMA_USE_2BYTES_COPY 1 32370b324cSopenharmony_ci// #define LZMA_USE_CMOV_LZ_WRAP 1 33370b324cSopenharmony_ci// #define _LZMA_PROB32 1 34370b324cSopenharmony_ci 35370b324cSopenharmony_ci#define MY_ALIGN_FOR_ENTRY MY_ALIGN_32 36370b324cSopenharmony_ci#define MY_ALIGN_FOR_LOOP MY_ALIGN_32 37370b324cSopenharmony_ci#define MY_ALIGN_FOR_LOOP_16 MY_ALIGN_16 38370b324cSopenharmony_ci 39370b324cSopenharmony_ci#ifdef _LZMA_PROB32 40370b324cSopenharmony_ci .equ PSHIFT , 2 41370b324cSopenharmony_ci .macro PLOAD dest:req, mem:req 42370b324cSopenharmony_ci ldr \dest, [\mem] 43370b324cSopenharmony_ci .endm 44370b324cSopenharmony_ci .macro PLOAD_PREINDEXED dest:req, mem:req, offset:req 45370b324cSopenharmony_ci ldr \dest, [\mem, \offset]! 46370b324cSopenharmony_ci .endm 47370b324cSopenharmony_ci .macro PLOAD_2 dest:req, mem1:req, mem2:req 48370b324cSopenharmony_ci ldr \dest, [\mem1, \mem2] 49370b324cSopenharmony_ci .endm 50370b324cSopenharmony_ci .macro PLOAD_LSL dest:req, mem1:req, mem2:req 51370b324cSopenharmony_ci ldr \dest, [\mem1, \mem2, lsl #PSHIFT] 52370b324cSopenharmony_ci .endm 53370b324cSopenharmony_ci .macro PSTORE src:req, mem:req 54370b324cSopenharmony_ci str \src, [\mem] 55370b324cSopenharmony_ci .endm 56370b324cSopenharmony_ci .macro PSTORE_2 src:req, mem1:req, mem2:req 57370b324cSopenharmony_ci str \src, [\mem1, \mem2] 58370b324cSopenharmony_ci .endm 59370b324cSopenharmony_ci .macro PSTORE_LSL src:req, mem1:req, mem2:req 60370b324cSopenharmony_ci str \src, [\mem1, \mem2, lsl #PSHIFT] 61370b324cSopenharmony_ci .endm 62370b324cSopenharmony_ci .macro PSTORE_LSL_M1 src:req, mem1:req, mem2:req, temp_reg:req 63370b324cSopenharmony_ci // you must check that temp_reg is free register when macro is used 64370b324cSopenharmony_ci add \temp_reg, \mem1, \mem2 65370b324cSopenharmony_ci str \src, [\temp_reg, \mem2] 66370b324cSopenharmony_ci .endm 67370b324cSopenharmony_ci#else 68370b324cSopenharmony_ci // .equ PSHIFT , 1 69370b324cSopenharmony_ci #define PSHIFT 1 70370b324cSopenharmony_ci .macro PLOAD dest:req, mem:req 71370b324cSopenharmony_ci ldrh \dest, [\mem] 72370b324cSopenharmony_ci .endm 73370b324cSopenharmony_ci .macro PLOAD_PREINDEXED dest:req, mem:req, offset:req 74370b324cSopenharmony_ci ldrh \dest, [\mem, \offset]! 75370b324cSopenharmony_ci .endm 76370b324cSopenharmony_ci .macro PLOAD_2 dest:req, mem1:req, mem2:req 77370b324cSopenharmony_ci ldrh \dest, [\mem1, \mem2] 78370b324cSopenharmony_ci .endm 79370b324cSopenharmony_ci .macro PLOAD_LSL dest:req, mem1:req, mem2:req 80370b324cSopenharmony_ci ldrh \dest, [\mem1, \mem2, lsl #PSHIFT] 81370b324cSopenharmony_ci .endm 82370b324cSopenharmony_ci .macro PSTORE src:req, mem:req 83370b324cSopenharmony_ci strh \src, [\mem] 84370b324cSopenharmony_ci .endm 85370b324cSopenharmony_ci .macro PSTORE_2 src:req, mem1:req, mem2:req 86370b324cSopenharmony_ci strh \src, [\mem1, \mem2] 87370b324cSopenharmony_ci .endm 88370b324cSopenharmony_ci .macro PSTORE_LSL src:req, mem1:req, mem2:req 89370b324cSopenharmony_ci strh \src, [\mem1, \mem2, lsl #PSHIFT] 90370b324cSopenharmony_ci .endm 91370b324cSopenharmony_ci .macro PSTORE_LSL_M1 src:req, mem1:req, mem2:req, temp_reg:req 92370b324cSopenharmony_ci strh \src, [\mem1, \mem2] 93370b324cSopenharmony_ci .endm 94370b324cSopenharmony_ci#endif 95370b324cSopenharmony_ci 96370b324cSopenharmony_ci.equ PMULT , (1 << PSHIFT) 97370b324cSopenharmony_ci.equ PMULT_2 , (2 << PSHIFT) 98370b324cSopenharmony_ci 99370b324cSopenharmony_ci.equ kMatchSpecLen_Error_Data , (1 << 9) 100370b324cSopenharmony_ci 101370b324cSopenharmony_ci# x7 t0 : NORM_CALC : prob2 (IF_BIT_1) 102370b324cSopenharmony_ci# x6 t1 : NORM_CALC : probs_state 103370b324cSopenharmony_ci# x8 t2 : (LITM) temp : (TREE) temp 104370b324cSopenharmony_ci# x4 t3 : (LITM) bit : (TREE) temp : UPDATE_0/UPDATE_0 temp 105370b324cSopenharmony_ci# x10 t4 : (LITM) offs : (TREE) probs_PMULT : numBits 106370b324cSopenharmony_ci# x9 t5 : (LITM) match : sym2 (ShortDist) 107370b324cSopenharmony_ci# x1 t6 : (LITM) litm_prob : (TREE) prob_reg : pbPos 108370b324cSopenharmony_ci# x2 t7 : (LITM) prm : probBranch : cnt 109370b324cSopenharmony_ci# x3 sym : dist 110370b324cSopenharmony_ci# x12 len 111370b324cSopenharmony_ci# x0 range 112370b324cSopenharmony_ci# x5 cod 113370b324cSopenharmony_ci 114370b324cSopenharmony_ci 115370b324cSopenharmony_ci#define range w0 116370b324cSopenharmony_ci 117370b324cSopenharmony_ci// t6 118370b324cSopenharmony_ci#define pbPos w1 119370b324cSopenharmony_ci#define pbPos_R r1 120370b324cSopenharmony_ci#define prob_reg w1 121370b324cSopenharmony_ci#define litm_prob prob_reg 122370b324cSopenharmony_ci 123370b324cSopenharmony_ci// t7 124370b324cSopenharmony_ci#define probBranch w2 125370b324cSopenharmony_ci#define cnt w2 126370b324cSopenharmony_ci#define cnt_R r2 127370b324cSopenharmony_ci#define prm r2 128370b324cSopenharmony_ci 129370b324cSopenharmony_ci#define sym w3 130370b324cSopenharmony_ci#define sym_R r3 131370b324cSopenharmony_ci#define dist sym 132370b324cSopenharmony_ci 133370b324cSopenharmony_ci#define t3 w4 134370b324cSopenharmony_ci#define bit w4 135370b324cSopenharmony_ci#define bit_R r4 136370b324cSopenharmony_ci#define update_temp_reg r4 137370b324cSopenharmony_ci 138370b324cSopenharmony_ci#define cod w5 139370b324cSopenharmony_ci 140370b324cSopenharmony_ci#define t1 w6 141370b324cSopenharmony_ci#define t1_R r6 142370b324cSopenharmony_ci#define probs_state t1_R 143370b324cSopenharmony_ci 144370b324cSopenharmony_ci#define t0 w7 145370b324cSopenharmony_ci#define t0_R r7 146370b324cSopenharmony_ci#define prob2 t0 147370b324cSopenharmony_ci 148370b324cSopenharmony_ci#define t2 w8 149370b324cSopenharmony_ci#define t2_R r8 150370b324cSopenharmony_ci 151370b324cSopenharmony_ci// t5 152370b324cSopenharmony_ci#define match w9 153370b324cSopenharmony_ci#define sym2 w9 154370b324cSopenharmony_ci#define sym2_R r9 155370b324cSopenharmony_ci 156370b324cSopenharmony_ci#define t4 w10 157370b324cSopenharmony_ci#define t4_R r10 158370b324cSopenharmony_ci 159370b324cSopenharmony_ci#define offs w10 160370b324cSopenharmony_ci#define offs_R r10 161370b324cSopenharmony_ci 162370b324cSopenharmony_ci#define probs r11 163370b324cSopenharmony_ci 164370b324cSopenharmony_ci#define len w12 165370b324cSopenharmony_ci#define len_R x12 166370b324cSopenharmony_ci 167370b324cSopenharmony_ci#define state w13 168370b324cSopenharmony_ci#define state_R r13 169370b324cSopenharmony_ci 170370b324cSopenharmony_ci#define dicPos r14 171370b324cSopenharmony_ci#define buf r15 172370b324cSopenharmony_ci#define bufLimit r16 173370b324cSopenharmony_ci#define dicBufSize r17 174370b324cSopenharmony_ci 175370b324cSopenharmony_ci#define limit r19 176370b324cSopenharmony_ci#define rep0 w20 177370b324cSopenharmony_ci#define rep0_R r20 178370b324cSopenharmony_ci#define rep1 w21 179370b324cSopenharmony_ci#define rep2 w22 180370b324cSopenharmony_ci#define rep3 w23 181370b324cSopenharmony_ci#define dic r24 182370b324cSopenharmony_ci#define probs_IsMatch r25 183370b324cSopenharmony_ci#define probs_Spec r26 184370b324cSopenharmony_ci#define checkDicSize w27 185370b324cSopenharmony_ci#define processedPos w28 186370b324cSopenharmony_ci#define pbMask w29 187370b324cSopenharmony_ci#define lc2_lpMask w30 188370b324cSopenharmony_ci 189370b324cSopenharmony_ci 190370b324cSopenharmony_ci.equ kNumBitModelTotalBits , 11 191370b324cSopenharmony_ci.equ kBitModelTotal , (1 << kNumBitModelTotalBits) 192370b324cSopenharmony_ci.equ kNumMoveBits , 5 193370b324cSopenharmony_ci.equ kBitModelOffset , (kBitModelTotal - (1 << kNumMoveBits) + 1) 194370b324cSopenharmony_ci 195370b324cSopenharmony_ci.macro NORM_2 macro 196370b324cSopenharmony_ci ldrb t0, [buf], 1 197370b324cSopenharmony_ci shl range, 8 198370b324cSopenharmony_ci orr cod, t0, cod, lsl 8 199370b324cSopenharmony_ci /* 200370b324cSopenharmony_ci mov t0, cod 201370b324cSopenharmony_ci ldrb cod, [buf], 1 202370b324cSopenharmony_ci shl range, 8 203370b324cSopenharmony_ci bfi cod, t0, #8, #24 204370b324cSopenharmony_ci */ 205370b324cSopenharmony_ci.endm 206370b324cSopenharmony_ci 207370b324cSopenharmony_ci.macro TEST_HIGH_BYTE_range macro 208370b324cSopenharmony_ci tst range, 0xFF000000 209370b324cSopenharmony_ci.endm 210370b324cSopenharmony_ci 211370b324cSopenharmony_ci.macro NORM macro 212370b324cSopenharmony_ci TEST_HIGH_BYTE_range 213370b324cSopenharmony_ci jnz 1f 214370b324cSopenharmony_ci NORM_2 215370b324cSopenharmony_ci1: 216370b324cSopenharmony_ci.endm 217370b324cSopenharmony_ci 218370b324cSopenharmony_ci 219370b324cSopenharmony_ci# ---------- Branch MACROS ---------- 220370b324cSopenharmony_ci 221370b324cSopenharmony_ci.macro UPDATE_0__0 222370b324cSopenharmony_ci sub prob2, probBranch, kBitModelOffset 223370b324cSopenharmony_ci.endm 224370b324cSopenharmony_ci 225370b324cSopenharmony_ci.macro UPDATE_0__1 226370b324cSopenharmony_ci sub probBranch, probBranch, prob2, asr #(kNumMoveBits) 227370b324cSopenharmony_ci.endm 228370b324cSopenharmony_ci 229370b324cSopenharmony_ci.macro UPDATE_0__2 probsArray:req, probOffset:req, probDisp:req 230370b324cSopenharmony_ci .if \probDisp == 0 231370b324cSopenharmony_ci PSTORE_2 probBranch, \probsArray, \probOffset 232370b324cSopenharmony_ci .elseif \probOffset == 0 233370b324cSopenharmony_ci PSTORE_2 probBranch, \probsArray, \probDisp * PMULT 234370b324cSopenharmony_ci .else 235370b324cSopenharmony_ci .error "unsupported" 236370b324cSopenharmony_ci // add update_temp_reg, \probsArray, \probOffset 237370b324cSopenharmony_ci PSTORE_2 probBranch, update_temp_reg, \probDisp * PMULT 238370b324cSopenharmony_ci .endif 239370b324cSopenharmony_ci.endm 240370b324cSopenharmony_ci 241370b324cSopenharmony_ci.macro UPDATE_0 probsArray:req, probOffset:req, probDisp:req 242370b324cSopenharmony_ci UPDATE_0__0 243370b324cSopenharmony_ci UPDATE_0__1 244370b324cSopenharmony_ci UPDATE_0__2 \probsArray, \probOffset, \probDisp 245370b324cSopenharmony_ci.endm 246370b324cSopenharmony_ci 247370b324cSopenharmony_ci 248370b324cSopenharmony_ci.macro UPDATE_1 probsArray:req, probOffset:req, probDisp:req 249370b324cSopenharmony_ci // sub cod, cod, prob2 250370b324cSopenharmony_ci // sub range, range, prob2 251370b324cSopenharmony_ci p2_sub cod, range 252370b324cSopenharmony_ci sub range, prob2, range 253370b324cSopenharmony_ci sub prob2, probBranch, probBranch, lsr #(kNumMoveBits) 254370b324cSopenharmony_ci .if \probDisp == 0 255370b324cSopenharmony_ci PSTORE_2 prob2, \probsArray, \probOffset 256370b324cSopenharmony_ci .elseif \probOffset == 0 257370b324cSopenharmony_ci PSTORE_2 prob2, \probsArray, \probDisp * PMULT 258370b324cSopenharmony_ci .else 259370b324cSopenharmony_ci .error "unsupported" 260370b324cSopenharmony_ci // add update_temp_reg, \probsArray, \probOffset 261370b324cSopenharmony_ci PSTORE_2 prob2, update_temp_reg, \probDisp * PMULT 262370b324cSopenharmony_ci .endif 263370b324cSopenharmony_ci.endm 264370b324cSopenharmony_ci 265370b324cSopenharmony_ci 266370b324cSopenharmony_ci.macro CMP_COD_BASE 267370b324cSopenharmony_ci NORM 268370b324cSopenharmony_ci // lsr prob2, range, kNumBitModelTotalBits 269370b324cSopenharmony_ci // imul prob2, probBranch 270370b324cSopenharmony_ci // cmp cod, prob2 271370b324cSopenharmony_ci mov prob2, range 272370b324cSopenharmony_ci shr range, kNumBitModelTotalBits 273370b324cSopenharmony_ci imul range, probBranch 274370b324cSopenharmony_ci cmp cod, range 275370b324cSopenharmony_ci.endm 276370b324cSopenharmony_ci 277370b324cSopenharmony_ci.macro CMP_COD_1 probsArray:req 278370b324cSopenharmony_ci PLOAD probBranch, \probsArray 279370b324cSopenharmony_ci CMP_COD_BASE 280370b324cSopenharmony_ci.endm 281370b324cSopenharmony_ci 282370b324cSopenharmony_ci.macro CMP_COD_3 probsArray:req, probOffset:req, probDisp:req 283370b324cSopenharmony_ci .if \probDisp == 0 284370b324cSopenharmony_ci PLOAD_2 probBranch, \probsArray, \probOffset 285370b324cSopenharmony_ci .elseif \probOffset == 0 286370b324cSopenharmony_ci PLOAD_2 probBranch, \probsArray, \probDisp * PMULT 287370b324cSopenharmony_ci .else 288370b324cSopenharmony_ci .error "unsupported" 289370b324cSopenharmony_ci add update_temp_reg, \probsArray, \probOffset 290370b324cSopenharmony_ci PLOAD_2 probBranch, update_temp_reg, \probDisp * PMULT 291370b324cSopenharmony_ci .endif 292370b324cSopenharmony_ci CMP_COD_BASE 293370b324cSopenharmony_ci.endm 294370b324cSopenharmony_ci 295370b324cSopenharmony_ci 296370b324cSopenharmony_ci.macro IF_BIT_1_NOUP probsArray:req, probOffset:req, probDisp:req, toLabel:req 297370b324cSopenharmony_ci CMP_COD_3 \probsArray, \probOffset, \probDisp 298370b324cSopenharmony_ci jae \toLabel 299370b324cSopenharmony_ci.endm 300370b324cSopenharmony_ci 301370b324cSopenharmony_ci 302370b324cSopenharmony_ci.macro IF_BIT_1 probsArray:req, probOffset:req, probDisp:req, toLabel:req 303370b324cSopenharmony_ci IF_BIT_1_NOUP \probsArray, \probOffset, \probDisp, \toLabel 304370b324cSopenharmony_ci UPDATE_0 \probsArray, \probOffset, \probDisp 305370b324cSopenharmony_ci.endm 306370b324cSopenharmony_ci 307370b324cSopenharmony_ci 308370b324cSopenharmony_ci.macro IF_BIT_0_NOUP probsArray:req, probOffset:req, probDisp:req, toLabel:req 309370b324cSopenharmony_ci CMP_COD_3 \probsArray, \probOffset, \probDisp 310370b324cSopenharmony_ci jb \toLabel 311370b324cSopenharmony_ci.endm 312370b324cSopenharmony_ci 313370b324cSopenharmony_ci.macro IF_BIT_0_NOUP_1 probsArray:req, toLabel:req 314370b324cSopenharmony_ci CMP_COD_1 \probsArray 315370b324cSopenharmony_ci jb \toLabel 316370b324cSopenharmony_ci.endm 317370b324cSopenharmony_ci 318370b324cSopenharmony_ci 319370b324cSopenharmony_ci# ---------- CMOV MACROS ---------- 320370b324cSopenharmony_ci 321370b324cSopenharmony_ci.macro NORM_LSR 322370b324cSopenharmony_ci NORM 323370b324cSopenharmony_ci lsr t0, range, #kNumBitModelTotalBits 324370b324cSopenharmony_ci.endm 325370b324cSopenharmony_ci 326370b324cSopenharmony_ci.macro COD_RANGE_SUB 327370b324cSopenharmony_ci subs t1, cod, t0 328370b324cSopenharmony_ci p2_sub range, t0 329370b324cSopenharmony_ci.endm 330370b324cSopenharmony_ci 331370b324cSopenharmony_ci.macro RANGE_IMUL prob:req 332370b324cSopenharmony_ci imul t0, \prob 333370b324cSopenharmony_ci.endm 334370b324cSopenharmony_ci 335370b324cSopenharmony_ci.macro NORM_CALC prob:req 336370b324cSopenharmony_ci NORM_LSR 337370b324cSopenharmony_ci RANGE_IMUL \prob 338370b324cSopenharmony_ci COD_RANGE_SUB 339370b324cSopenharmony_ci.endm 340370b324cSopenharmony_ci 341370b324cSopenharmony_ci.macro CMOV_range 342370b324cSopenharmony_ci cmovb range, t0 343370b324cSopenharmony_ci.endm 344370b324cSopenharmony_ci 345370b324cSopenharmony_ci.macro CMOV_code 346370b324cSopenharmony_ci cmovae cod, t1 347370b324cSopenharmony_ci.endm 348370b324cSopenharmony_ci 349370b324cSopenharmony_ci.macro CMOV_code_Model_Pre prob:req 350370b324cSopenharmony_ci sub t0, \prob, kBitModelOffset 351370b324cSopenharmony_ci CMOV_code 352370b324cSopenharmony_ci cmovae t0, \prob 353370b324cSopenharmony_ci.endm 354370b324cSopenharmony_ci 355370b324cSopenharmony_ci 356370b324cSopenharmony_ci.macro PUP_BASE_2 prob:req, dest_reg:req 357370b324cSopenharmony_ci # only sar works for both 16/32 bit prob modes 358370b324cSopenharmony_ci sub \dest_reg, \prob, \dest_reg, asr #(kNumMoveBits) 359370b324cSopenharmony_ci.endm 360370b324cSopenharmony_ci 361370b324cSopenharmony_ci.macro PUP prob:req, probPtr:req, mem2:req 362370b324cSopenharmony_ci PUP_BASE_2 \prob, t0 363370b324cSopenharmony_ci PSTORE_2 t0, \probPtr, \mem2 364370b324cSopenharmony_ci.endm 365370b324cSopenharmony_ci 366370b324cSopenharmony_ci 367370b324cSopenharmony_ci 368370b324cSopenharmony_ci#define probs_PMULT t4_R 369370b324cSopenharmony_ci 370370b324cSopenharmony_ci.macro BIT_01 371370b324cSopenharmony_ci add probs_PMULT, probs, PMULT 372370b324cSopenharmony_ci.endm 373370b324cSopenharmony_ci 374370b324cSopenharmony_ci 375370b324cSopenharmony_ci.macro BIT_0_R prob:req 376370b324cSopenharmony_ci PLOAD_2 \prob, probs, 1 * PMULT 377370b324cSopenharmony_ci NORM_LSR 378370b324cSopenharmony_ci sub t3, \prob, kBitModelOffset 379370b324cSopenharmony_ci RANGE_IMUL \prob 380370b324cSopenharmony_ci PLOAD_2 t2, probs, 1 * PMULT_2 381370b324cSopenharmony_ci COD_RANGE_SUB 382370b324cSopenharmony_ci CMOV_range 383370b324cSopenharmony_ci cmovae t3, \prob 384370b324cSopenharmony_ci PLOAD_2 t0, probs, 1 * PMULT_2 + PMULT 385370b324cSopenharmony_ci PUP_BASE_2 \prob, t3 386370b324cSopenharmony_ci csel \prob, t2, t0, lo 387370b324cSopenharmony_ci CMOV_code 388370b324cSopenharmony_ci mov sym, 2 389370b324cSopenharmony_ci PSTORE_2 t3, probs, 1 * PMULT 390370b324cSopenharmony_ci adc sym, sym, wzr 391370b324cSopenharmony_ci BIT_01 392370b324cSopenharmony_ci.endm 393370b324cSopenharmony_ci 394370b324cSopenharmony_ci.macro BIT_1_R prob:req 395370b324cSopenharmony_ci NORM_LSR 396370b324cSopenharmony_ci p2_add sym, sym 397370b324cSopenharmony_ci sub t3, \prob, kBitModelOffset 398370b324cSopenharmony_ci RANGE_IMUL \prob 399370b324cSopenharmony_ci PLOAD_LSL t2, probs, sym_R 400370b324cSopenharmony_ci COD_RANGE_SUB 401370b324cSopenharmony_ci CMOV_range 402370b324cSopenharmony_ci cmovae t3, \prob 403370b324cSopenharmony_ci PLOAD_LSL t0, probs_PMULT, sym_R 404370b324cSopenharmony_ci PUP_BASE_2 \prob, t3 405370b324cSopenharmony_ci csel \prob, t2, t0, lo 406370b324cSopenharmony_ci CMOV_code 407370b324cSopenharmony_ci PSTORE_LSL_M1 t3, probs, sym_R, t2_R 408370b324cSopenharmony_ci adc sym, sym, wzr 409370b324cSopenharmony_ci.endm 410370b324cSopenharmony_ci 411370b324cSopenharmony_ci 412370b324cSopenharmony_ci.macro BIT_2_R prob:req 413370b324cSopenharmony_ci NORM_LSR 414370b324cSopenharmony_ci p2_add sym, sym 415370b324cSopenharmony_ci sub t3, \prob, kBitModelOffset 416370b324cSopenharmony_ci RANGE_IMUL \prob 417370b324cSopenharmony_ci COD_RANGE_SUB 418370b324cSopenharmony_ci CMOV_range 419370b324cSopenharmony_ci cmovae t3, \prob 420370b324cSopenharmony_ci CMOV_code 421370b324cSopenharmony_ci PUP_BASE_2 \prob, t3 422370b324cSopenharmony_ci PSTORE_LSL_M1 t3, probs, sym_R, t2_R 423370b324cSopenharmony_ci adc sym, sym, wzr 424370b324cSopenharmony_ci.endm 425370b324cSopenharmony_ci 426370b324cSopenharmony_ci 427370b324cSopenharmony_ci# ---------- MATCHED LITERAL ---------- 428370b324cSopenharmony_ci 429370b324cSopenharmony_ci.macro LITM_0 macro 430370b324cSopenharmony_ci shl match, (PSHIFT + 1) 431370b324cSopenharmony_ci and bit, match, 256 * PMULT 432370b324cSopenharmony_ci add prm, probs, 256 * PMULT + 1 * PMULT 433370b324cSopenharmony_ci p2_add match, match 434370b324cSopenharmony_ci p2_add prm, bit_R 435370b324cSopenharmony_ci eor offs, bit, 256 * PMULT 436370b324cSopenharmony_ci PLOAD litm_prob, prm 437370b324cSopenharmony_ci 438370b324cSopenharmony_ci NORM_LSR 439370b324cSopenharmony_ci sub t2, litm_prob, kBitModelOffset 440370b324cSopenharmony_ci RANGE_IMUL litm_prob 441370b324cSopenharmony_ci COD_RANGE_SUB 442370b324cSopenharmony_ci cmovae offs, bit 443370b324cSopenharmony_ci CMOV_range 444370b324cSopenharmony_ci and bit, match, offs 445370b324cSopenharmony_ci cmovae t2, litm_prob 446370b324cSopenharmony_ci CMOV_code 447370b324cSopenharmony_ci mov sym, 2 448370b324cSopenharmony_ci PUP_BASE_2 litm_prob, t2 449370b324cSopenharmony_ci PSTORE t2, prm 450370b324cSopenharmony_ci add prm, probs, offs_R 451370b324cSopenharmony_ci adc sym, sym, wzr 452370b324cSopenharmony_ci.endm 453370b324cSopenharmony_ci 454370b324cSopenharmony_ci.macro LITM macro 455370b324cSopenharmony_ci p2_add prm, bit_R 456370b324cSopenharmony_ci xor offs, bit 457370b324cSopenharmony_ci PLOAD_LSL litm_prob, prm, sym_R 458370b324cSopenharmony_ci 459370b324cSopenharmony_ci NORM_LSR 460370b324cSopenharmony_ci p2_add match, match 461370b324cSopenharmony_ci sub t2, litm_prob, kBitModelOffset 462370b324cSopenharmony_ci RANGE_IMUL litm_prob 463370b324cSopenharmony_ci COD_RANGE_SUB 464370b324cSopenharmony_ci cmovae offs, bit 465370b324cSopenharmony_ci CMOV_range 466370b324cSopenharmony_ci and bit, match, offs 467370b324cSopenharmony_ci cmovae t2, litm_prob 468370b324cSopenharmony_ci CMOV_code 469370b324cSopenharmony_ci PUP_BASE_2 litm_prob, t2 470370b324cSopenharmony_ci PSTORE_LSL t2, prm, sym_R 471370b324cSopenharmony_ci add prm, probs, offs_R 472370b324cSopenharmony_ci adc sym, sym, sym 473370b324cSopenharmony_ci.endm 474370b324cSopenharmony_ci 475370b324cSopenharmony_ci 476370b324cSopenharmony_ci.macro LITM_2 macro 477370b324cSopenharmony_ci p2_add prm, bit_R 478370b324cSopenharmony_ci PLOAD_LSL litm_prob, prm, sym_R 479370b324cSopenharmony_ci 480370b324cSopenharmony_ci NORM_LSR 481370b324cSopenharmony_ci sub t2, litm_prob, kBitModelOffset 482370b324cSopenharmony_ci RANGE_IMUL litm_prob 483370b324cSopenharmony_ci COD_RANGE_SUB 484370b324cSopenharmony_ci CMOV_range 485370b324cSopenharmony_ci cmovae t2, litm_prob 486370b324cSopenharmony_ci CMOV_code 487370b324cSopenharmony_ci PUP_BASE_2 litm_prob, t2 488370b324cSopenharmony_ci PSTORE_LSL t2, prm, sym_R 489370b324cSopenharmony_ci adc sym, sym, sym 490370b324cSopenharmony_ci.endm 491370b324cSopenharmony_ci 492370b324cSopenharmony_ci 493370b324cSopenharmony_ci# ---------- REVERSE BITS ---------- 494370b324cSopenharmony_ci 495370b324cSopenharmony_ci.macro REV_0 prob:req 496370b324cSopenharmony_ci NORM_CALC \prob 497370b324cSopenharmony_ci CMOV_range 498370b324cSopenharmony_ci PLOAD t2, sym2_R 499370b324cSopenharmony_ci PLOAD_2 t3, probs, 3 * PMULT 500370b324cSopenharmony_ci CMOV_code_Model_Pre \prob 501370b324cSopenharmony_ci add t1_R, probs, 3 * PMULT 502370b324cSopenharmony_ci cmovae sym2_R, t1_R 503370b324cSopenharmony_ci PUP \prob, probs, 1 * PMULT 504370b324cSopenharmony_ci csel \prob, t2, t3, lo 505370b324cSopenharmony_ci.endm 506370b324cSopenharmony_ci 507370b324cSopenharmony_ci 508370b324cSopenharmony_ci.macro REV_1 prob:req, step:req 509370b324cSopenharmony_ci NORM_LSR 510370b324cSopenharmony_ci PLOAD_PREINDEXED t2, sym2_R, (\step * PMULT) 511370b324cSopenharmony_ci RANGE_IMUL \prob 512370b324cSopenharmony_ci COD_RANGE_SUB 513370b324cSopenharmony_ci CMOV_range 514370b324cSopenharmony_ci PLOAD_2 t3, sym2_R, (\step * PMULT) 515370b324cSopenharmony_ci sub t0, \prob, kBitModelOffset 516370b324cSopenharmony_ci CMOV_code 517370b324cSopenharmony_ci add t1_R, sym2_R, \step * PMULT 518370b324cSopenharmony_ci cmovae t0, \prob 519370b324cSopenharmony_ci cmovae sym2_R, t1_R 520370b324cSopenharmony_ci PUP_BASE_2 \prob, t0 521370b324cSopenharmony_ci csel \prob, t2, t3, lo 522370b324cSopenharmony_ci PSTORE_2 t0, t1_R, 0 - \step * PMULT_2 523370b324cSopenharmony_ci.endm 524370b324cSopenharmony_ci 525370b324cSopenharmony_ci 526370b324cSopenharmony_ci.macro REV_2 prob:req, step:req 527370b324cSopenharmony_ci sub t1_R, sym2_R, probs 528370b324cSopenharmony_ci NORM_LSR 529370b324cSopenharmony_ci orr sym, sym, t1, lsr #PSHIFT 530370b324cSopenharmony_ci RANGE_IMUL \prob 531370b324cSopenharmony_ci COD_RANGE_SUB 532370b324cSopenharmony_ci sub t2, sym, \step 533370b324cSopenharmony_ci CMOV_range 534370b324cSopenharmony_ci cmovb sym, t2 535370b324cSopenharmony_ci CMOV_code_Model_Pre \prob 536370b324cSopenharmony_ci PUP \prob, sym2_R, 0 537370b324cSopenharmony_ci.endm 538370b324cSopenharmony_ci 539370b324cSopenharmony_ci 540370b324cSopenharmony_ci.macro REV_1_VAR prob:req 541370b324cSopenharmony_ci PLOAD \prob, sym_R 542370b324cSopenharmony_ci mov probs, sym_R 543370b324cSopenharmony_ci p2_add sym_R, sym2_R 544370b324cSopenharmony_ci NORM_LSR 545370b324cSopenharmony_ci add t2_R, sym_R, sym2_R 546370b324cSopenharmony_ci RANGE_IMUL \prob 547370b324cSopenharmony_ci COD_RANGE_SUB 548370b324cSopenharmony_ci cmovae sym_R, t2_R 549370b324cSopenharmony_ci CMOV_range 550370b324cSopenharmony_ci CMOV_code_Model_Pre \prob 551370b324cSopenharmony_ci p2_add sym2, sym2 552370b324cSopenharmony_ci PUP \prob, probs, 0 553370b324cSopenharmony_ci.endm 554370b324cSopenharmony_ci 555370b324cSopenharmony_ci 556370b324cSopenharmony_ci.macro add_big dest:req, src:req, param:req 557370b324cSopenharmony_ci .if (\param) < (1 << 12) 558370b324cSopenharmony_ci add \dest, \src, \param 559370b324cSopenharmony_ci .else 560370b324cSopenharmony_ci #ifndef _LZMA_PROB32 561370b324cSopenharmony_ci .error "unexpcted add_big expansion" 562370b324cSopenharmony_ci #endif 563370b324cSopenharmony_ci add \dest, \src, (\param) / 2 564370b324cSopenharmony_ci add \dest, \dest, (\param) - (\param) / 2 565370b324cSopenharmony_ci .endif 566370b324cSopenharmony_ci.endm 567370b324cSopenharmony_ci 568370b324cSopenharmony_ci.macro sub_big dest:req, src:req, param:req 569370b324cSopenharmony_ci .if (\param) < (1 << 12) 570370b324cSopenharmony_ci sub \dest, \src, \param 571370b324cSopenharmony_ci .else 572370b324cSopenharmony_ci #ifndef _LZMA_PROB32 573370b324cSopenharmony_ci .error "unexpcted sub_big expansion" 574370b324cSopenharmony_ci #endif 575370b324cSopenharmony_ci sub \dest, \src, (\param) / 2 576370b324cSopenharmony_ci sub \dest, \dest, (\param) - (\param) / 2 577370b324cSopenharmony_ci .endif 578370b324cSopenharmony_ci.endm 579370b324cSopenharmony_ci 580370b324cSopenharmony_ci 581370b324cSopenharmony_ci.macro SET_probs offset:req 582370b324cSopenharmony_ci // add_big probs, probs_Spec, (\offset) * PMULT 583370b324cSopenharmony_ci add probs, probs_IsMatch, ((\offset) - IsMatch) * PMULT 584370b324cSopenharmony_ci.endm 585370b324cSopenharmony_ci 586370b324cSopenharmony_ci 587370b324cSopenharmony_ci.macro LIT_PROBS 588370b324cSopenharmony_ci add sym, sym, processedPos, lsl 8 589370b324cSopenharmony_ci inc processedPos 590370b324cSopenharmony_ci UPDATE_0__0 591370b324cSopenharmony_ci shl sym, lc2_lpMask 592370b324cSopenharmony_ci SET_probs Literal 593370b324cSopenharmony_ci p2_and sym, lc2_lpMask 594370b324cSopenharmony_ci // p2_add probs_state, pbPos_R 595370b324cSopenharmony_ci p2_add probs, sym_R 596370b324cSopenharmony_ci UPDATE_0__1 597370b324cSopenharmony_ci add probs, probs, sym_R, lsl 1 598370b324cSopenharmony_ci UPDATE_0__2 probs_state, pbPos_R, 0 599370b324cSopenharmony_ci.endm 600370b324cSopenharmony_ci 601370b324cSopenharmony_ci 602370b324cSopenharmony_ci 603370b324cSopenharmony_ci.equ kNumPosBitsMax , 4 604370b324cSopenharmony_ci.equ kNumPosStatesMax , (1 << kNumPosBitsMax) 605370b324cSopenharmony_ci 606370b324cSopenharmony_ci.equ kLenNumLowBits , 3 607370b324cSopenharmony_ci.equ kLenNumLowSymbols , (1 << kLenNumLowBits) 608370b324cSopenharmony_ci.equ kLenNumHighBits , 8 609370b324cSopenharmony_ci.equ kLenNumHighSymbols , (1 << kLenNumHighBits) 610370b324cSopenharmony_ci.equ kNumLenProbs , (2 * kLenNumLowSymbols * kNumPosStatesMax + kLenNumHighSymbols) 611370b324cSopenharmony_ci 612370b324cSopenharmony_ci.equ LenLow , 0 613370b324cSopenharmony_ci.equ LenChoice , LenLow 614370b324cSopenharmony_ci.equ LenChoice2 , (LenLow + kLenNumLowSymbols) 615370b324cSopenharmony_ci.equ LenHigh , (LenLow + 2 * kLenNumLowSymbols * kNumPosStatesMax) 616370b324cSopenharmony_ci 617370b324cSopenharmony_ci.equ kNumStates , 12 618370b324cSopenharmony_ci.equ kNumStates2 , 16 619370b324cSopenharmony_ci.equ kNumLitStates , 7 620370b324cSopenharmony_ci 621370b324cSopenharmony_ci.equ kStartPosModelIndex , 4 622370b324cSopenharmony_ci.equ kEndPosModelIndex , 14 623370b324cSopenharmony_ci.equ kNumFullDistances , (1 << (kEndPosModelIndex >> 1)) 624370b324cSopenharmony_ci 625370b324cSopenharmony_ci.equ kNumPosSlotBits , 6 626370b324cSopenharmony_ci.equ kNumLenToPosStates , 4 627370b324cSopenharmony_ci 628370b324cSopenharmony_ci.equ kNumAlignBits , 4 629370b324cSopenharmony_ci.equ kAlignTableSize , (1 << kNumAlignBits) 630370b324cSopenharmony_ci 631370b324cSopenharmony_ci.equ kMatchMinLen , 2 632370b324cSopenharmony_ci.equ kMatchSpecLenStart , (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols) 633370b324cSopenharmony_ci 634370b324cSopenharmony_ci// .equ kStartOffset , 1408 635370b324cSopenharmony_ci.equ kStartOffset , 0 636370b324cSopenharmony_ci.equ SpecPos , (-kStartOffset) 637370b324cSopenharmony_ci.equ IsRep0Long , (SpecPos + kNumFullDistances) 638370b324cSopenharmony_ci.equ RepLenCoder , (IsRep0Long + (kNumStates2 << kNumPosBitsMax)) 639370b324cSopenharmony_ci.equ LenCoder , (RepLenCoder + kNumLenProbs) 640370b324cSopenharmony_ci.equ IsMatch , (LenCoder + kNumLenProbs) 641370b324cSopenharmony_ci.equ kAlign , (IsMatch + (kNumStates2 << kNumPosBitsMax)) 642370b324cSopenharmony_ci.equ IsRep , (kAlign + kAlignTableSize) 643370b324cSopenharmony_ci.equ IsRepG0 , (IsRep + kNumStates) 644370b324cSopenharmony_ci.equ IsRepG1 , (IsRepG0 + kNumStates) 645370b324cSopenharmony_ci.equ IsRepG2 , (IsRepG1 + kNumStates) 646370b324cSopenharmony_ci.equ PosSlot , (IsRepG2 + kNumStates) 647370b324cSopenharmony_ci.equ Literal , (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) 648370b324cSopenharmony_ci.equ NUM_BASE_PROBS , (Literal + kStartOffset) 649370b324cSopenharmony_ci 650370b324cSopenharmony_ci.if kStartOffset != 0 // && IsMatch != 0 651370b324cSopenharmony_ci .error "Stop_Compiling_Bad_StartOffset" 652370b324cSopenharmony_ci.endif 653370b324cSopenharmony_ci 654370b324cSopenharmony_ci.if NUM_BASE_PROBS != 1984 655370b324cSopenharmony_ci .error "Stop_Compiling_Bad_LZMA_PROBS" 656370b324cSopenharmony_ci.endif 657370b324cSopenharmony_ci 658370b324cSopenharmony_ci.equ offset_lc , 0 659370b324cSopenharmony_ci.equ offset_lp , 1 660370b324cSopenharmony_ci.equ offset_pb , 2 661370b324cSopenharmony_ci.equ offset_dicSize , 4 662370b324cSopenharmony_ci.equ offset_probs , 4 + offset_dicSize 663370b324cSopenharmony_ci.equ offset_probs_1664 , 8 + offset_probs 664370b324cSopenharmony_ci.equ offset_dic , 8 + offset_probs_1664 665370b324cSopenharmony_ci.equ offset_dicBufSize , 8 + offset_dic 666370b324cSopenharmony_ci.equ offset_dicPos , 8 + offset_dicBufSize 667370b324cSopenharmony_ci.equ offset_buf , 8 + offset_dicPos 668370b324cSopenharmony_ci.equ offset_range , 8 + offset_buf 669370b324cSopenharmony_ci.equ offset_code , 4 + offset_range 670370b324cSopenharmony_ci.equ offset_processedPos , 4 + offset_code 671370b324cSopenharmony_ci.equ offset_checkDicSize , 4 + offset_processedPos 672370b324cSopenharmony_ci.equ offset_rep0 , 4 + offset_checkDicSize 673370b324cSopenharmony_ci.equ offset_rep1 , 4 + offset_rep0 674370b324cSopenharmony_ci.equ offset_rep2 , 4 + offset_rep1 675370b324cSopenharmony_ci.equ offset_rep3 , 4 + offset_rep2 676370b324cSopenharmony_ci.equ offset_state , 4 + offset_rep3 677370b324cSopenharmony_ci.equ offset_remainLen , 4 + offset_state 678370b324cSopenharmony_ci.equ offset_TOTAL_SIZE , 4 + offset_remainLen 679370b324cSopenharmony_ci 680370b324cSopenharmony_ci.if offset_TOTAL_SIZE != 96 681370b324cSopenharmony_ci .error "Incorrect offset_TOTAL_SIZE" 682370b324cSopenharmony_ci.endif 683370b324cSopenharmony_ci 684370b324cSopenharmony_ci 685370b324cSopenharmony_ci.macro IsMatchBranch_Pre 686370b324cSopenharmony_ci # prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; 687370b324cSopenharmony_ci and pbPos, pbMask, processedPos, lsl #(kLenNumLowBits + 1 + PSHIFT) 688370b324cSopenharmony_ci add probs_state, probs_IsMatch, state_R 689370b324cSopenharmony_ci.endm 690370b324cSopenharmony_ci 691370b324cSopenharmony_ci 692370b324cSopenharmony_ci/* 693370b324cSopenharmony_ci.macro IsMatchBranch 694370b324cSopenharmony_ci IsMatchBranch_Pre 695370b324cSopenharmony_ci IF_BIT_1 probs_state, pbPos_R, (IsMatch - IsMatch), IsMatch_label 696370b324cSopenharmony_ci.endm 697370b324cSopenharmony_ci*/ 698370b324cSopenharmony_ci 699370b324cSopenharmony_ci.macro CheckLimits 700370b324cSopenharmony_ci cmp buf, bufLimit 701370b324cSopenharmony_ci jae fin_OK 702370b324cSopenharmony_ci cmp dicPos, limit 703370b324cSopenharmony_ci jae fin_OK 704370b324cSopenharmony_ci.endm 705370b324cSopenharmony_ci 706370b324cSopenharmony_ci#define CheckLimits_lit CheckLimits 707370b324cSopenharmony_ci/* 708370b324cSopenharmony_ci.macro CheckLimits_lit 709370b324cSopenharmony_ci cmp buf, bufLimit 710370b324cSopenharmony_ci jae fin_OK_lit 711370b324cSopenharmony_ci cmp dicPos, limit 712370b324cSopenharmony_ci jae fin_OK_lit 713370b324cSopenharmony_ci.endm 714370b324cSopenharmony_ci*/ 715370b324cSopenharmony_ci 716370b324cSopenharmony_ci 717370b324cSopenharmony_ci#define PARAM_lzma REG_ABI_PARAM_0 718370b324cSopenharmony_ci#define PARAM_limit REG_ABI_PARAM_1 719370b324cSopenharmony_ci#define PARAM_bufLimit REG_ABI_PARAM_2 720370b324cSopenharmony_ci 721370b324cSopenharmony_ci 722370b324cSopenharmony_ci.macro LOAD_LZMA_VAR reg:req, struct_offs:req 723370b324cSopenharmony_ci ldr \reg, [PARAM_lzma, \struct_offs] 724370b324cSopenharmony_ci.endm 725370b324cSopenharmony_ci 726370b324cSopenharmony_ci.macro LOAD_LZMA_BYTE reg:req, struct_offs:req 727370b324cSopenharmony_ci ldrb \reg, [PARAM_lzma, \struct_offs] 728370b324cSopenharmony_ci.endm 729370b324cSopenharmony_ci 730370b324cSopenharmony_ci.macro LOAD_LZMA_PAIR reg0:req, reg1:req, struct_offs:req 731370b324cSopenharmony_ci ldp \reg0, \reg1, [PARAM_lzma, \struct_offs] 732370b324cSopenharmony_ci.endm 733370b324cSopenharmony_ci 734370b324cSopenharmony_ci 735370b324cSopenharmony_ciLzmaDec_DecodeReal_3: 736370b324cSopenharmony_ci_LzmaDec_DecodeReal_3: 737370b324cSopenharmony_ci/* 738370b324cSopenharmony_ci.LFB0: 739370b324cSopenharmony_ci .cfi_startproc 740370b324cSopenharmony_ci*/ 741370b324cSopenharmony_ci 742370b324cSopenharmony_ci stp x19, x20, [sp, -128]! 743370b324cSopenharmony_ci stp x21, x22, [sp, 16] 744370b324cSopenharmony_ci stp x23, x24, [sp, 32] 745370b324cSopenharmony_ci stp x25, x26, [sp, 48] 746370b324cSopenharmony_ci stp x27, x28, [sp, 64] 747370b324cSopenharmony_ci stp x29, x30, [sp, 80] 748370b324cSopenharmony_ci 749370b324cSopenharmony_ci str PARAM_lzma, [sp, 120] 750370b324cSopenharmony_ci 751370b324cSopenharmony_ci mov bufLimit, PARAM_bufLimit 752370b324cSopenharmony_ci mov limit, PARAM_limit 753370b324cSopenharmony_ci 754370b324cSopenharmony_ci LOAD_LZMA_PAIR dic, dicBufSize, offset_dic 755370b324cSopenharmony_ci LOAD_LZMA_PAIR dicPos, buf, offset_dicPos 756370b324cSopenharmony_ci LOAD_LZMA_PAIR rep0, rep1, offset_rep0 757370b324cSopenharmony_ci LOAD_LZMA_PAIR rep2, rep3, offset_rep2 758370b324cSopenharmony_ci 759370b324cSopenharmony_ci mov t0, 1 << (kLenNumLowBits + 1 + PSHIFT) 760370b324cSopenharmony_ci LOAD_LZMA_BYTE pbMask, offset_pb 761370b324cSopenharmony_ci p2_add limit, dic 762370b324cSopenharmony_ci mov len, wzr // we can set it in all requiread branches instead 763370b324cSopenharmony_ci lsl pbMask, t0, pbMask 764370b324cSopenharmony_ci p2_add dicPos, dic 765370b324cSopenharmony_ci p2_sub pbMask, t0 766370b324cSopenharmony_ci 767370b324cSopenharmony_ci LOAD_LZMA_BYTE lc2_lpMask, offset_lc 768370b324cSopenharmony_ci mov t0, 256 << PSHIFT 769370b324cSopenharmony_ci LOAD_LZMA_BYTE t1, offset_lp 770370b324cSopenharmony_ci p2_add t1, lc2_lpMask 771370b324cSopenharmony_ci p2_sub lc2_lpMask, (256 << PSHIFT) - PSHIFT 772370b324cSopenharmony_ci shl t0, t1 773370b324cSopenharmony_ci p2_add lc2_lpMask, t0 774370b324cSopenharmony_ci 775370b324cSopenharmony_ci LOAD_LZMA_VAR probs_Spec, offset_probs 776370b324cSopenharmony_ci LOAD_LZMA_VAR checkDicSize, offset_checkDicSize 777370b324cSopenharmony_ci LOAD_LZMA_VAR processedPos, offset_processedPos 778370b324cSopenharmony_ci LOAD_LZMA_VAR state, offset_state 779370b324cSopenharmony_ci // range is r0 : this load must be last don't move 780370b324cSopenharmony_ci LOAD_LZMA_PAIR range, cod, offset_range 781370b324cSopenharmony_ci mov sym, wzr 782370b324cSopenharmony_ci shl state, PSHIFT 783370b324cSopenharmony_ci 784370b324cSopenharmony_ci add_big probs_IsMatch, probs_Spec, ((IsMatch - SpecPos) << PSHIFT) 785370b324cSopenharmony_ci 786370b324cSopenharmony_ci // if (processedPos != 0 || checkDicSize != 0) 787370b324cSopenharmony_ci orr t0, checkDicSize, processedPos 788370b324cSopenharmony_ci cbz t0, 1f 789370b324cSopenharmony_ci add t0_R, dicBufSize, dic 790370b324cSopenharmony_ci cmp dicPos, dic 791370b324cSopenharmony_ci cmovne t0_R, dicPos 792370b324cSopenharmony_ci ldrb sym, [t0_R, -1] 793370b324cSopenharmony_ci1: 794370b324cSopenharmony_ci IsMatchBranch_Pre 795370b324cSopenharmony_ci cmp state, 4 * PMULT 796370b324cSopenharmony_ci jb lit_end 797370b324cSopenharmony_ci cmp state, kNumLitStates * PMULT 798370b324cSopenharmony_ci jb lit_matched_end 799370b324cSopenharmony_ci jmp lz_end 800370b324cSopenharmony_ci 801370b324cSopenharmony_ci 802370b324cSopenharmony_ci 803370b324cSopenharmony_ci#define BIT_0 BIT_0_R prob_reg 804370b324cSopenharmony_ci#define BIT_1 BIT_1_R prob_reg 805370b324cSopenharmony_ci#define BIT_2 BIT_2_R prob_reg 806370b324cSopenharmony_ci 807370b324cSopenharmony_ci# ---------- LITERAL ---------- 808370b324cSopenharmony_ciMY_ALIGN_64 809370b324cSopenharmony_cilit_start: 810370b324cSopenharmony_ci mov state, wzr 811370b324cSopenharmony_cilit_start_2: 812370b324cSopenharmony_ci LIT_PROBS 813370b324cSopenharmony_ci 814370b324cSopenharmony_ci #ifdef _LZMA_SIZE_OPT 815370b324cSopenharmony_ci 816370b324cSopenharmony_ci PLOAD_2 prob_reg, probs, 1 * PMULT 817370b324cSopenharmony_ci mov sym, 1 818370b324cSopenharmony_ci BIT_01 819370b324cSopenharmony_ciMY_ALIGN_FOR_LOOP 820370b324cSopenharmony_cilit_loop: 821370b324cSopenharmony_ci BIT_1 822370b324cSopenharmony_ci tbz sym, 7, lit_loop 823370b324cSopenharmony_ci 824370b324cSopenharmony_ci #else 825370b324cSopenharmony_ci 826370b324cSopenharmony_ci BIT_0 827370b324cSopenharmony_ci BIT_1 828370b324cSopenharmony_ci BIT_1 829370b324cSopenharmony_ci BIT_1 830370b324cSopenharmony_ci BIT_1 831370b324cSopenharmony_ci BIT_1 832370b324cSopenharmony_ci BIT_1 833370b324cSopenharmony_ci 834370b324cSopenharmony_ci #endif 835370b324cSopenharmony_ci 836370b324cSopenharmony_ci BIT_2 837370b324cSopenharmony_ci IsMatchBranch_Pre 838370b324cSopenharmony_ci strb sym, [dicPos], 1 839370b324cSopenharmony_ci p2_and sym, 255 840370b324cSopenharmony_ci 841370b324cSopenharmony_ci CheckLimits_lit 842370b324cSopenharmony_cilit_end: 843370b324cSopenharmony_ci IF_BIT_0_NOUP probs_state, pbPos_R, (IsMatch - IsMatch), lit_start 844370b324cSopenharmony_ci 845370b324cSopenharmony_ci # jmp IsMatch_label 846370b324cSopenharmony_ci 847370b324cSopenharmony_ci 848370b324cSopenharmony_ci#define FLAG_STATE_BITS (4 + PSHIFT) 849370b324cSopenharmony_ci 850370b324cSopenharmony_ci# ---------- MATCHES ---------- 851370b324cSopenharmony_ci# MY_ALIGN_FOR_ENTRY 852370b324cSopenharmony_ciIsMatch_label: 853370b324cSopenharmony_ci UPDATE_1 probs_state, pbPos_R, (IsMatch - IsMatch) 854370b324cSopenharmony_ci IF_BIT_1 probs_state, 0, (IsRep - IsMatch), IsRep_label 855370b324cSopenharmony_ci 856370b324cSopenharmony_ci SET_probs LenCoder 857370b324cSopenharmony_ci or state, (1 << FLAG_STATE_BITS) 858370b324cSopenharmony_ci 859370b324cSopenharmony_ci# ---------- LEN DECODE ---------- 860370b324cSopenharmony_cilen_decode: 861370b324cSopenharmony_ci mov len, 8 - kMatchMinLen 862370b324cSopenharmony_ci IF_BIT_0_NOUP_1 probs, len_mid_0 863370b324cSopenharmony_ci UPDATE_1 probs, 0, 0 864370b324cSopenharmony_ci p2_add probs, (1 << (kLenNumLowBits + PSHIFT)) 865370b324cSopenharmony_ci mov len, 0 - kMatchMinLen 866370b324cSopenharmony_ci IF_BIT_0_NOUP_1 probs, len_mid_0 867370b324cSopenharmony_ci UPDATE_1 probs, 0, 0 868370b324cSopenharmony_ci p2_add probs, LenHigh * PMULT - (1 << (kLenNumLowBits + PSHIFT)) 869370b324cSopenharmony_ci 870370b324cSopenharmony_ci #if 0 == 1 871370b324cSopenharmony_ci BIT_0 872370b324cSopenharmony_ci BIT_1 873370b324cSopenharmony_ci BIT_1 874370b324cSopenharmony_ci BIT_1 875370b324cSopenharmony_ci BIT_1 876370b324cSopenharmony_ci BIT_1 877370b324cSopenharmony_ci #else 878370b324cSopenharmony_ci PLOAD_2 prob_reg, probs, 1 * PMULT 879370b324cSopenharmony_ci mov sym, 1 880370b324cSopenharmony_ci BIT_01 881370b324cSopenharmony_ciMY_ALIGN_FOR_LOOP 882370b324cSopenharmony_cilen8_loop: 883370b324cSopenharmony_ci BIT_1 884370b324cSopenharmony_ci tbz sym, 6, len8_loop 885370b324cSopenharmony_ci #endif 886370b324cSopenharmony_ci 887370b324cSopenharmony_ci mov len, (kLenNumHighSymbols - kLenNumLowSymbols * 2) - kMatchMinLen 888370b324cSopenharmony_ci jmp len_mid_2 889370b324cSopenharmony_ci 890370b324cSopenharmony_ciMY_ALIGN_FOR_ENTRY 891370b324cSopenharmony_cilen_mid_0: 892370b324cSopenharmony_ci UPDATE_0 probs, 0, 0 893370b324cSopenharmony_ci p2_add probs, pbPos_R 894370b324cSopenharmony_ci BIT_0 895370b324cSopenharmony_cilen_mid_2: 896370b324cSopenharmony_ci BIT_1 897370b324cSopenharmony_ci BIT_2 898370b324cSopenharmony_ci sub len, sym, len 899370b324cSopenharmony_ci tbz state, FLAG_STATE_BITS, copy_match 900370b324cSopenharmony_ci 901370b324cSopenharmony_ci# ---------- DECODE DISTANCE ---------- 902370b324cSopenharmony_ci // probs + PosSlot + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); 903370b324cSopenharmony_ci 904370b324cSopenharmony_ci mov t0, 3 + kMatchMinLen 905370b324cSopenharmony_ci cmp len, 3 + kMatchMinLen 906370b324cSopenharmony_ci cmovb t0, len 907370b324cSopenharmony_ci SET_probs PosSlot - (kMatchMinLen << (kNumPosSlotBits)) 908370b324cSopenharmony_ci add probs, probs, t0_R, lsl #(kNumPosSlotBits + PSHIFT) 909370b324cSopenharmony_ci 910370b324cSopenharmony_ci #ifdef _LZMA_SIZE_OPT 911370b324cSopenharmony_ci 912370b324cSopenharmony_ci PLOAD_2 prob_reg, probs, 1 * PMULT 913370b324cSopenharmony_ci mov sym, 1 914370b324cSopenharmony_ci BIT_01 915370b324cSopenharmony_ciMY_ALIGN_FOR_LOOP 916370b324cSopenharmony_cislot_loop: 917370b324cSopenharmony_ci BIT_1 918370b324cSopenharmony_ci tbz sym, 5, slot_loop 919370b324cSopenharmony_ci 920370b324cSopenharmony_ci #else 921370b324cSopenharmony_ci 922370b324cSopenharmony_ci BIT_0 923370b324cSopenharmony_ci BIT_1 924370b324cSopenharmony_ci BIT_1 925370b324cSopenharmony_ci BIT_1 926370b324cSopenharmony_ci BIT_1 927370b324cSopenharmony_ci 928370b324cSopenharmony_ci #endif 929370b324cSopenharmony_ci 930370b324cSopenharmony_ci #define numBits t4 931370b324cSopenharmony_ci mov numBits, sym 932370b324cSopenharmony_ci BIT_2 933370b324cSopenharmony_ci // we need only low bits 934370b324cSopenharmony_ci p2_and sym, 3 935370b324cSopenharmony_ci cmp numBits, 32 + kEndPosModelIndex / 2 936370b324cSopenharmony_ci jb short_dist 937370b324cSopenharmony_ci 938370b324cSopenharmony_ci SET_probs kAlign 939370b324cSopenharmony_ci 940370b324cSopenharmony_ci # unsigned numDirectBits = (unsigned)(((distance >> 1) - 1)); 941370b324cSopenharmony_ci p2_sub numBits, (32 + 1 + kNumAlignBits) 942370b324cSopenharmony_ci # distance = (2 | (distance & 1)); 943370b324cSopenharmony_ci or sym, 2 944370b324cSopenharmony_ci PLOAD_2 prob_reg, probs, 1 * PMULT 945370b324cSopenharmony_ci add sym2_R, probs, 2 * PMULT 946370b324cSopenharmony_ci 947370b324cSopenharmony_ci# ---------- DIRECT DISTANCE ---------- 948370b324cSopenharmony_ci 949370b324cSopenharmony_ci.macro DIRECT_1 950370b324cSopenharmony_ci shr range, 1 951370b324cSopenharmony_ci subs t0, cod, range 952370b324cSopenharmony_ci p2_add sym, sym 953370b324cSopenharmony_ci // add t1, sym, 1 954370b324cSopenharmony_ci csel cod, cod, t0, mi 955370b324cSopenharmony_ci csinc sym, sym, sym, mi 956370b324cSopenharmony_ci // csel sym, t1, sym, pl 957370b324cSopenharmony_ci // adc sym, sym, sym // not 100% compatible for "corruptued-allowed" LZMA streams 958370b324cSopenharmony_ci dec_s numBits 959370b324cSopenharmony_ci je direct_end 960370b324cSopenharmony_ci.endm 961370b324cSopenharmony_ci 962370b324cSopenharmony_ci #ifdef _LZMA_SIZE_OPT 963370b324cSopenharmony_ci 964370b324cSopenharmony_ci jmp direct_norm 965370b324cSopenharmony_ciMY_ALIGN_FOR_ENTRY 966370b324cSopenharmony_cidirect_loop: 967370b324cSopenharmony_ci DIRECT_1 968370b324cSopenharmony_cidirect_norm: 969370b324cSopenharmony_ci TEST_HIGH_BYTE_range 970370b324cSopenharmony_ci jnz direct_loop 971370b324cSopenharmony_ci NORM_2 972370b324cSopenharmony_ci jmp direct_loop 973370b324cSopenharmony_ci 974370b324cSopenharmony_ci #else 975370b324cSopenharmony_ci 976370b324cSopenharmony_ci.macro DIRECT_2 977370b324cSopenharmony_ci TEST_HIGH_BYTE_range 978370b324cSopenharmony_ci jz direct_unroll 979370b324cSopenharmony_ci DIRECT_1 980370b324cSopenharmony_ci.endm 981370b324cSopenharmony_ci 982370b324cSopenharmony_ci DIRECT_2 983370b324cSopenharmony_ci DIRECT_2 984370b324cSopenharmony_ci DIRECT_2 985370b324cSopenharmony_ci DIRECT_2 986370b324cSopenharmony_ci DIRECT_2 987370b324cSopenharmony_ci DIRECT_2 988370b324cSopenharmony_ci DIRECT_2 989370b324cSopenharmony_ci DIRECT_2 990370b324cSopenharmony_ci 991370b324cSopenharmony_cidirect_unroll: 992370b324cSopenharmony_ci NORM_2 993370b324cSopenharmony_ci DIRECT_1 994370b324cSopenharmony_ci DIRECT_1 995370b324cSopenharmony_ci DIRECT_1 996370b324cSopenharmony_ci DIRECT_1 997370b324cSopenharmony_ci DIRECT_1 998370b324cSopenharmony_ci DIRECT_1 999370b324cSopenharmony_ci DIRECT_1 1000370b324cSopenharmony_ci DIRECT_1 1001370b324cSopenharmony_ci jmp direct_unroll 1002370b324cSopenharmony_ci 1003370b324cSopenharmony_ci #endif 1004370b324cSopenharmony_ci 1005370b324cSopenharmony_ciMY_ALIGN_FOR_ENTRY 1006370b324cSopenharmony_cidirect_end: 1007370b324cSopenharmony_ci shl sym, kNumAlignBits 1008370b324cSopenharmony_ci REV_0 prob_reg 1009370b324cSopenharmony_ci REV_1 prob_reg, 2 1010370b324cSopenharmony_ci REV_1 prob_reg, 4 1011370b324cSopenharmony_ci REV_2 prob_reg, 8 1012370b324cSopenharmony_ci 1013370b324cSopenharmony_cidecode_dist_end: 1014370b324cSopenharmony_ci 1015370b324cSopenharmony_ci // if (distance >= (checkDicSize == 0 ? processedPos: checkDicSize)) 1016370b324cSopenharmony_ci 1017370b324cSopenharmony_ci tst checkDicSize, checkDicSize 1018370b324cSopenharmony_ci csel t0, processedPos, checkDicSize, eq 1019370b324cSopenharmony_ci cmp sym, t0 1020370b324cSopenharmony_ci jae end_of_payload 1021370b324cSopenharmony_ci // jmp end_of_payload # for debug 1022370b324cSopenharmony_ci 1023370b324cSopenharmony_ci mov rep3, rep2 1024370b324cSopenharmony_ci mov rep2, rep1 1025370b324cSopenharmony_ci mov rep1, rep0 1026370b324cSopenharmony_ci add rep0, sym, 1 1027370b324cSopenharmony_ci 1028370b324cSopenharmony_ci.macro STATE_UPDATE_FOR_MATCH 1029370b324cSopenharmony_ci // state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; 1030370b324cSopenharmony_ci // cmp state, (kNumStates + kNumLitStates) * PMULT 1031370b324cSopenharmony_ci cmp state, kNumLitStates * PMULT + (1 << FLAG_STATE_BITS) 1032370b324cSopenharmony_ci mov state, kNumLitStates * PMULT 1033370b324cSopenharmony_ci mov t0, (kNumLitStates + 3) * PMULT 1034370b324cSopenharmony_ci cmovae state, t0 1035370b324cSopenharmony_ci.endm 1036370b324cSopenharmony_ci STATE_UPDATE_FOR_MATCH 1037370b324cSopenharmony_ci 1038370b324cSopenharmony_ci# ---------- COPY MATCH ---------- 1039370b324cSopenharmony_cicopy_match: 1040370b324cSopenharmony_ci 1041370b324cSopenharmony_ci // if ((rem = limit - dicPos) == 0) break // return SZ_ERROR_DATA; 1042370b324cSopenharmony_ci subs cnt_R, limit, dicPos 1043370b324cSopenharmony_ci // jz fin_dicPos_LIMIT 1044370b324cSopenharmony_ci jz fin_OK 1045370b324cSopenharmony_ci 1046370b324cSopenharmony_ci // curLen = ((rem < len) ? (unsigned)rem : len); 1047370b324cSopenharmony_ci cmp cnt_R, len_R 1048370b324cSopenharmony_ci cmovae cnt, len 1049370b324cSopenharmony_ci 1050370b324cSopenharmony_ci sub t0_R, dicPos, dic 1051370b324cSopenharmony_ci p2_add dicPos, cnt_R 1052370b324cSopenharmony_ci p2_add processedPos, cnt 1053370b324cSopenharmony_ci p2_sub len, cnt 1054370b324cSopenharmony_ci 1055370b324cSopenharmony_ci // pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0); 1056370b324cSopenharmony_ci p2_sub_s t0_R, rep0_R 1057370b324cSopenharmony_ci jae 1f 1058370b324cSopenharmony_ci 1059370b324cSopenharmony_ci cmn t0_R, cnt_R 1060370b324cSopenharmony_ci p2_add t0_R, dicBufSize 1061370b324cSopenharmony_ci ja copy_match_cross 1062370b324cSopenharmony_ci1: 1063370b324cSopenharmony_ci# ---------- COPY MATCH FAST ---------- 1064370b324cSopenharmony_ci # t0_R : src_pos 1065370b324cSopenharmony_ci p2_add t0_R, dic 1066370b324cSopenharmony_ci ldrb sym, [t0_R] 1067370b324cSopenharmony_ci p2_add t0_R, cnt_R 1068370b324cSopenharmony_ci p1_neg cnt_R 1069370b324cSopenharmony_ci 1070370b324cSopenharmony_cicopy_common: 1071370b324cSopenharmony_ci dec dicPos 1072370b324cSopenharmony_ci 1073370b324cSopenharmony_ci # dicPos : (ptr_to_last_dest_BYTE) 1074370b324cSopenharmony_ci # t0_R : (src_lim) 1075370b324cSopenharmony_ci # cnt_R : (-curLen) 1076370b324cSopenharmony_ci 1077370b324cSopenharmony_ci IsMatchBranch_Pre 1078370b324cSopenharmony_ci 1079370b324cSopenharmony_ci inc_s cnt_R 1080370b324cSopenharmony_ci jz copy_end 1081370b324cSopenharmony_ci 1082370b324cSopenharmony_ci cmp rep0, 1 1083370b324cSopenharmony_ci je copy_match_0 1084370b324cSopenharmony_ci 1085370b324cSopenharmony_ci #ifdef LZMA_USE_2BYTES_COPY 1086370b324cSopenharmony_ci strb sym, [dicPos, cnt_R] 1087370b324cSopenharmony_ci dec dicPos 1088370b324cSopenharmony_ci # dicPos : (ptr_to_last_dest_16bitWORD) 1089370b324cSopenharmony_ci p2_and cnt_R, -2 1090370b324cSopenharmony_ci ldrh sym, [t0_R, cnt_R] 1091370b324cSopenharmony_ci adds cnt_R, cnt_R, 2 1092370b324cSopenharmony_ci jz 2f 1093370b324cSopenharmony_ciMY_ALIGN_FOR_LOOP 1094370b324cSopenharmony_ci1: 1095370b324cSopenharmony_ci /* 1096370b324cSopenharmony_ci strh sym, [dicPos, cnt_R] 1097370b324cSopenharmony_ci ldrh sym, [t0_R, cnt_R] 1098370b324cSopenharmony_ci adds cnt_R, cnt_R, 2 1099370b324cSopenharmony_ci jz 2f 1100370b324cSopenharmony_ci */ 1101370b324cSopenharmony_ci 1102370b324cSopenharmony_ci strh sym, [dicPos, cnt_R] 1103370b324cSopenharmony_ci ldrh sym, [t0_R, cnt_R] 1104370b324cSopenharmony_ci adds cnt_R, cnt_R, 2 1105370b324cSopenharmony_ci jnz 1b 1106370b324cSopenharmony_ci2: 1107370b324cSopenharmony_ci 1108370b324cSopenharmony_ci /* 1109370b324cSopenharmony_ci // for universal little/big endian code, but slow 1110370b324cSopenharmony_ci strh sym, [dicPos] 1111370b324cSopenharmony_ci inc dicPos 1112370b324cSopenharmony_ci ldrb sym, [t0_R, -1] 1113370b324cSopenharmony_ci */ 1114370b324cSopenharmony_ci 1115370b324cSopenharmony_ci #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 1116370b324cSopenharmony_ci // we must improve big-endian detection for another compilers 1117370b324cSopenharmony_ci // for big-endian we need to revert bytes 1118370b324cSopenharmony_ci rev16 sym, sym 1119370b324cSopenharmony_ci #endif 1120370b324cSopenharmony_ci 1121370b324cSopenharmony_ci // (sym) must represent as little-endian here: 1122370b324cSopenharmony_ci strb sym, [dicPos], 1 1123370b324cSopenharmony_ci shr sym, 8 1124370b324cSopenharmony_ci 1125370b324cSopenharmony_ci #else 1126370b324cSopenharmony_ci 1127370b324cSopenharmony_ciMY_ALIGN_FOR_LOOP 1128370b324cSopenharmony_ci1: 1129370b324cSopenharmony_ci strb sym, [dicPos, cnt_R] 1130370b324cSopenharmony_ci ldrb sym, [t0_R, cnt_R] 1131370b324cSopenharmony_ci inc_s cnt_R 1132370b324cSopenharmony_ci jz copy_end 1133370b324cSopenharmony_ci 1134370b324cSopenharmony_ci strb sym, [dicPos, cnt_R] 1135370b324cSopenharmony_ci ldrb sym, [t0_R, cnt_R] 1136370b324cSopenharmony_ci inc_s cnt_R 1137370b324cSopenharmony_ci jnz 1b 1138370b324cSopenharmony_ci #endif 1139370b324cSopenharmony_ci 1140370b324cSopenharmony_cicopy_end: 1141370b324cSopenharmony_cilz_end_match: 1142370b324cSopenharmony_ci strb sym, [dicPos], 1 1143370b324cSopenharmony_ci 1144370b324cSopenharmony_ci # IsMatchBranch_Pre 1145370b324cSopenharmony_ci CheckLimits 1146370b324cSopenharmony_cilz_end: 1147370b324cSopenharmony_ci IF_BIT_1_NOUP probs_state, pbPos_R, (IsMatch - IsMatch), IsMatch_label 1148370b324cSopenharmony_ci 1149370b324cSopenharmony_ci 1150370b324cSopenharmony_ci 1151370b324cSopenharmony_ci# ---------- LITERAL MATCHED ---------- 1152370b324cSopenharmony_ci 1153370b324cSopenharmony_ci LIT_PROBS 1154370b324cSopenharmony_ci 1155370b324cSopenharmony_ci // matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; 1156370b324cSopenharmony_ci 1157370b324cSopenharmony_ci sub t0_R, dicPos, dic 1158370b324cSopenharmony_ci p2_sub_s t0_R, rep0_R 1159370b324cSopenharmony_ci 1160370b324cSopenharmony_ci #ifdef LZMA_USE_CMOV_LZ_WRAP 1161370b324cSopenharmony_ci add t1_R, t0_R, dicBufSize 1162370b324cSopenharmony_ci cmovb t0_R, t1_R 1163370b324cSopenharmony_ci #else 1164370b324cSopenharmony_ci jae 1f 1165370b324cSopenharmony_ci p2_add t0_R, dicBufSize 1166370b324cSopenharmony_ci1: 1167370b324cSopenharmony_ci #endif 1168370b324cSopenharmony_ci 1169370b324cSopenharmony_ci ldrb match, [dic, t0_R] 1170370b324cSopenharmony_ci 1171370b324cSopenharmony_ci // state -= (state < 10) ? 3 : 6; 1172370b324cSopenharmony_ci sub sym, state, 6 * PMULT 1173370b324cSopenharmony_ci cmp state, 10 * PMULT 1174370b324cSopenharmony_ci p2_sub state, 3 * PMULT 1175370b324cSopenharmony_ci cmovae state, sym 1176370b324cSopenharmony_ci 1177370b324cSopenharmony_ci #ifdef _LZMA_SIZE_OPT 1178370b324cSopenharmony_ci 1179370b324cSopenharmony_ci mov offs, 256 * PMULT 1180370b324cSopenharmony_ci shl match, (PSHIFT + 1) 1181370b324cSopenharmony_ci mov sym, 1 1182370b324cSopenharmony_ci and bit, match, offs 1183370b324cSopenharmony_ci add prm, probs, offs_R 1184370b324cSopenharmony_ci 1185370b324cSopenharmony_ciMY_ALIGN_FOR_LOOP 1186370b324cSopenharmony_cilitm_loop: 1187370b324cSopenharmony_ci LITM 1188370b324cSopenharmony_ci tbz sym, 8, litm_loop 1189370b324cSopenharmony_ci 1190370b324cSopenharmony_ci #else 1191370b324cSopenharmony_ci 1192370b324cSopenharmony_ci LITM_0 1193370b324cSopenharmony_ci LITM 1194370b324cSopenharmony_ci LITM 1195370b324cSopenharmony_ci LITM 1196370b324cSopenharmony_ci LITM 1197370b324cSopenharmony_ci LITM 1198370b324cSopenharmony_ci LITM 1199370b324cSopenharmony_ci LITM_2 1200370b324cSopenharmony_ci 1201370b324cSopenharmony_ci #endif 1202370b324cSopenharmony_ci 1203370b324cSopenharmony_ci IsMatchBranch_Pre 1204370b324cSopenharmony_ci strb sym, [dicPos], 1 1205370b324cSopenharmony_ci p2_and sym, 255 1206370b324cSopenharmony_ci 1207370b324cSopenharmony_ci // mov len, wzr // LITM uses same regisetr (len / offs). So we clear it 1208370b324cSopenharmony_ci CheckLimits_lit 1209370b324cSopenharmony_cilit_matched_end: 1210370b324cSopenharmony_ci IF_BIT_1_NOUP probs_state, pbPos_R, (IsMatch - IsMatch), IsMatch_label 1211370b324cSopenharmony_ci # IsMatchBranch 1212370b324cSopenharmony_ci p2_sub state, 3 * PMULT 1213370b324cSopenharmony_ci jmp lit_start_2 1214370b324cSopenharmony_ci 1215370b324cSopenharmony_ci 1216370b324cSopenharmony_ci 1217370b324cSopenharmony_ci# ---------- REP 0 LITERAL ---------- 1218370b324cSopenharmony_ciMY_ALIGN_FOR_ENTRY 1219370b324cSopenharmony_ciIsRep0Short_label: 1220370b324cSopenharmony_ci UPDATE_0 probs_state, pbPos_R, 0 1221370b324cSopenharmony_ci 1222370b324cSopenharmony_ci // dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; 1223370b324cSopenharmony_ci sub t0_R, dicPos, dic 1224370b324cSopenharmony_ci 1225370b324cSopenharmony_ci // state = state < kNumLitStates ? 9 : 11; 1226370b324cSopenharmony_ci or state, 1 * PMULT 1227370b324cSopenharmony_ci 1228370b324cSopenharmony_ci # the caller doesn't allow (dicPos >= limit) case for REP_SHORT 1229370b324cSopenharmony_ci # so we don't need the following (dicPos == limit) check here: 1230370b324cSopenharmony_ci # cmp dicPos, limit 1231370b324cSopenharmony_ci # jae fin_dicPos_LIMIT_REP_SHORT 1232370b324cSopenharmony_ci # // jmp fin_dicPos_LIMIT_REP_SHORT // for testing/debug puposes 1233370b324cSopenharmony_ci 1234370b324cSopenharmony_ci inc processedPos 1235370b324cSopenharmony_ci 1236370b324cSopenharmony_ci IsMatchBranch_Pre 1237370b324cSopenharmony_ci 1238370b324cSopenharmony_ci p2_sub_s t0_R, rep0_R 1239370b324cSopenharmony_ci #ifdef LZMA_USE_CMOV_LZ_WRAP 1240370b324cSopenharmony_ci add sym_R, t0_R, dicBufSize 1241370b324cSopenharmony_ci cmovb t0_R, sym_R 1242370b324cSopenharmony_ci #else 1243370b324cSopenharmony_ci jae 1f 1244370b324cSopenharmony_ci p2_add t0_R, dicBufSize 1245370b324cSopenharmony_ci1: 1246370b324cSopenharmony_ci #endif 1247370b324cSopenharmony_ci 1248370b324cSopenharmony_ci ldrb sym, [dic, t0_R] 1249370b324cSopenharmony_ci // mov len, wzr 1250370b324cSopenharmony_ci jmp lz_end_match 1251370b324cSopenharmony_ci 1252370b324cSopenharmony_ciMY_ALIGN_FOR_ENTRY 1253370b324cSopenharmony_ciIsRep_label: 1254370b324cSopenharmony_ci UPDATE_1 probs_state, 0, (IsRep - IsMatch) 1255370b324cSopenharmony_ci 1256370b324cSopenharmony_ci # The (checkDicSize == 0 && processedPos == 0) case was checked before in LzmaDec.c with kBadRepCode. 1257370b324cSopenharmony_ci # So we don't check it here. 1258370b324cSopenharmony_ci 1259370b324cSopenharmony_ci # mov t0, processedPos 1260370b324cSopenharmony_ci # or t0, checkDicSize 1261370b324cSopenharmony_ci # jz fin_ERROR_2 1262370b324cSopenharmony_ci 1263370b324cSopenharmony_ci // state = state < kNumLitStates ? 8 : 11; 1264370b324cSopenharmony_ci cmp state, kNumLitStates * PMULT 1265370b324cSopenharmony_ci mov state, 8 * PMULT 1266370b324cSopenharmony_ci mov probBranch, 11 * PMULT 1267370b324cSopenharmony_ci cmovae state, probBranch 1268370b324cSopenharmony_ci 1269370b324cSopenharmony_ci SET_probs RepLenCoder 1270370b324cSopenharmony_ci 1271370b324cSopenharmony_ci IF_BIT_1 probs_state, 0, (IsRepG0 - IsMatch), IsRepG0_label 1272370b324cSopenharmony_ci sub_big probs_state, probs_state, (IsMatch - IsRep0Long) << PSHIFT 1273370b324cSopenharmony_ci IF_BIT_0_NOUP probs_state, pbPos_R, 0, IsRep0Short_label 1274370b324cSopenharmony_ci UPDATE_1 probs_state, pbPos_R, 0 1275370b324cSopenharmony_ci jmp len_decode 1276370b324cSopenharmony_ci 1277370b324cSopenharmony_ciMY_ALIGN_FOR_ENTRY 1278370b324cSopenharmony_ciIsRepG0_label: 1279370b324cSopenharmony_ci UPDATE_1 probs_state, 0, (IsRepG0 - IsMatch) 1280370b324cSopenharmony_ci IF_BIT_1 probs_state, 0, (IsRepG1 - IsMatch), IsRepG1_label 1281370b324cSopenharmony_ci mov dist, rep1 1282370b324cSopenharmony_ci mov rep1, rep0 1283370b324cSopenharmony_ci mov rep0, dist 1284370b324cSopenharmony_ci jmp len_decode 1285370b324cSopenharmony_ci 1286370b324cSopenharmony_ci# MY_ALIGN_FOR_ENTRY 1287370b324cSopenharmony_ciIsRepG1_label: 1288370b324cSopenharmony_ci UPDATE_1 probs_state, 0, (IsRepG1 - IsMatch) 1289370b324cSopenharmony_ci IF_BIT_1 probs_state, 0, (IsRepG2 - IsMatch), IsRepG2_label 1290370b324cSopenharmony_ci mov dist, rep2 1291370b324cSopenharmony_ci mov rep2, rep1 1292370b324cSopenharmony_ci mov rep1, rep0 1293370b324cSopenharmony_ci mov rep0, dist 1294370b324cSopenharmony_ci jmp len_decode 1295370b324cSopenharmony_ci 1296370b324cSopenharmony_ci# MY_ALIGN_FOR_ENTRY 1297370b324cSopenharmony_ciIsRepG2_label: 1298370b324cSopenharmony_ci UPDATE_1 probs_state, 0, (IsRepG2 - IsMatch) 1299370b324cSopenharmony_ci mov dist, rep3 1300370b324cSopenharmony_ci mov rep3, rep2 1301370b324cSopenharmony_ci mov rep2, rep1 1302370b324cSopenharmony_ci mov rep1, rep0 1303370b324cSopenharmony_ci mov rep0, dist 1304370b324cSopenharmony_ci jmp len_decode 1305370b324cSopenharmony_ci 1306370b324cSopenharmony_ci 1307370b324cSopenharmony_ci 1308370b324cSopenharmony_ci# ---------- SPEC SHORT DISTANCE ---------- 1309370b324cSopenharmony_ci 1310370b324cSopenharmony_ciMY_ALIGN_FOR_ENTRY 1311370b324cSopenharmony_cishort_dist: 1312370b324cSopenharmony_ci p2_sub_s numBits, 32 + 1 1313370b324cSopenharmony_ci jbe decode_dist_end 1314370b324cSopenharmony_ci or sym, 2 1315370b324cSopenharmony_ci shl sym, numBits 1316370b324cSopenharmony_ci add sym_R, probs_Spec, sym_R, lsl #PSHIFT 1317370b324cSopenharmony_ci p2_add sym_R, SpecPos * PMULT + 1 * PMULT 1318370b324cSopenharmony_ci mov sym2, PMULT // # step 1319370b324cSopenharmony_ciMY_ALIGN_FOR_LOOP 1320370b324cSopenharmony_cispec_loop: 1321370b324cSopenharmony_ci REV_1_VAR prob_reg 1322370b324cSopenharmony_ci dec_s numBits 1323370b324cSopenharmony_ci jnz spec_loop 1324370b324cSopenharmony_ci 1325370b324cSopenharmony_ci p2_add sym2_R, probs_Spec 1326370b324cSopenharmony_ci .if SpecPos != 0 1327370b324cSopenharmony_ci p2_add sym2_R, SpecPos * PMULT 1328370b324cSopenharmony_ci .endif 1329370b324cSopenharmony_ci p2_sub sym_R, sym2_R 1330370b324cSopenharmony_ci shr sym, PSHIFT 1331370b324cSopenharmony_ci 1332370b324cSopenharmony_ci jmp decode_dist_end 1333370b324cSopenharmony_ci 1334370b324cSopenharmony_ci 1335370b324cSopenharmony_ci 1336370b324cSopenharmony_ci# ---------- COPY MATCH 0 ---------- 1337370b324cSopenharmony_ciMY_ALIGN_FOR_ENTRY 1338370b324cSopenharmony_cicopy_match_0: 1339370b324cSopenharmony_ci #ifdef LZMA_USE_4BYTES_FILL 1340370b324cSopenharmony_ci strb sym, [dicPos, cnt_R] 1341370b324cSopenharmony_ci inc_s cnt_R 1342370b324cSopenharmony_ci jz copy_end 1343370b324cSopenharmony_ci 1344370b324cSopenharmony_ci strb sym, [dicPos, cnt_R] 1345370b324cSopenharmony_ci inc_s cnt_R 1346370b324cSopenharmony_ci jz copy_end 1347370b324cSopenharmony_ci 1348370b324cSopenharmony_ci strb sym, [dicPos, cnt_R] 1349370b324cSopenharmony_ci inc_s cnt_R 1350370b324cSopenharmony_ci jz copy_end 1351370b324cSopenharmony_ci 1352370b324cSopenharmony_ci orr t3, sym, sym, lsl 8 1353370b324cSopenharmony_ci p2_and cnt_R, -4 1354370b324cSopenharmony_ci orr t3, t3, t3, lsl 16 1355370b324cSopenharmony_ciMY_ALIGN_FOR_LOOP_16 1356370b324cSopenharmony_ci1: 1357370b324cSopenharmony_ci /* 1358370b324cSopenharmony_ci str t3, [dicPos, cnt_R] 1359370b324cSopenharmony_ci adds cnt_R, cnt_R, 4 1360370b324cSopenharmony_ci jz 2f 1361370b324cSopenharmony_ci */ 1362370b324cSopenharmony_ci 1363370b324cSopenharmony_ci str t3, [dicPos, cnt_R] 1364370b324cSopenharmony_ci adds cnt_R, cnt_R, 4 1365370b324cSopenharmony_ci jnz 1b 1366370b324cSopenharmony_ci2: 1367370b324cSopenharmony_ci // p2_and sym, 255 1368370b324cSopenharmony_ci #else 1369370b324cSopenharmony_ci 1370370b324cSopenharmony_ciMY_ALIGN_FOR_LOOP 1371370b324cSopenharmony_ci1: 1372370b324cSopenharmony_ci strb sym, [dicPos, cnt_R] 1373370b324cSopenharmony_ci inc_s cnt_R 1374370b324cSopenharmony_ci jz copy_end 1375370b324cSopenharmony_ci 1376370b324cSopenharmony_ci strb sym, [dicPos, cnt_R] 1377370b324cSopenharmony_ci inc_s cnt_R 1378370b324cSopenharmony_ci jnz 1b 1379370b324cSopenharmony_ci #endif 1380370b324cSopenharmony_ci 1381370b324cSopenharmony_ci jmp copy_end 1382370b324cSopenharmony_ci 1383370b324cSopenharmony_ci 1384370b324cSopenharmony_ci# ---------- COPY MATCH CROSS ---------- 1385370b324cSopenharmony_cicopy_match_cross: 1386370b324cSopenharmony_ci # t0_R - src pos 1387370b324cSopenharmony_ci # cnt_R - total copy len 1388370b324cSopenharmony_ci 1389370b324cSopenharmony_ci p1_neg cnt_R 1390370b324cSopenharmony_ci1: 1391370b324cSopenharmony_ci ldrb sym, [dic, t0_R] 1392370b324cSopenharmony_ci inc t0_R 1393370b324cSopenharmony_ci strb sym, [dicPos, cnt_R] 1394370b324cSopenharmony_ci inc cnt_R 1395370b324cSopenharmony_ci cmp t0_R, dicBufSize 1396370b324cSopenharmony_ci jne 1b 1397370b324cSopenharmony_ci 1398370b324cSopenharmony_ci ldrb sym, [dic] 1399370b324cSopenharmony_ci sub t0_R, dic, cnt_R 1400370b324cSopenharmony_ci jmp copy_common 1401370b324cSopenharmony_ci 1402370b324cSopenharmony_ci 1403370b324cSopenharmony_ci 1404370b324cSopenharmony_ci 1405370b324cSopenharmony_ci/* 1406370b324cSopenharmony_cifin_dicPos_LIMIT_REP_SHORT: 1407370b324cSopenharmony_ci mov len, 1 1408370b324cSopenharmony_ci jmp fin_OK 1409370b324cSopenharmony_ci*/ 1410370b324cSopenharmony_ci 1411370b324cSopenharmony_ci/* 1412370b324cSopenharmony_cifin_dicPos_LIMIT: 1413370b324cSopenharmony_ci jmp fin_OK 1414370b324cSopenharmony_ci # For more strict mode we can stop decoding with error 1415370b324cSopenharmony_ci # mov sym, 1 1416370b324cSopenharmony_ci # jmp fin 1417370b324cSopenharmony_ci*/ 1418370b324cSopenharmony_ci 1419370b324cSopenharmony_cifin_ERROR_MATCH_DIST: 1420370b324cSopenharmony_ci # rep0 = distance + 1; 1421370b324cSopenharmony_ci p2_add len, kMatchSpecLen_Error_Data 1422370b324cSopenharmony_ci mov rep3, rep2 1423370b324cSopenharmony_ci mov rep2, rep1 1424370b324cSopenharmony_ci mov rep1, rep0 1425370b324cSopenharmony_ci mov rep0, sym 1426370b324cSopenharmony_ci STATE_UPDATE_FOR_MATCH 1427370b324cSopenharmony_ci # jmp fin_OK 1428370b324cSopenharmony_ci mov sym, 1 1429370b324cSopenharmony_ci jmp fin 1430370b324cSopenharmony_ci 1431370b324cSopenharmony_ciend_of_payload: 1432370b324cSopenharmony_ci inc_s sym 1433370b324cSopenharmony_ci jnz fin_ERROR_MATCH_DIST 1434370b324cSopenharmony_ci 1435370b324cSopenharmony_ci mov len, kMatchSpecLenStart 1436370b324cSopenharmony_ci xor state, (1 << FLAG_STATE_BITS) 1437370b324cSopenharmony_ci jmp fin_OK 1438370b324cSopenharmony_ci 1439370b324cSopenharmony_ci/* 1440370b324cSopenharmony_cifin_OK_lit: 1441370b324cSopenharmony_ci mov len, wzr 1442370b324cSopenharmony_ci*/ 1443370b324cSopenharmony_ci 1444370b324cSopenharmony_cifin_OK: 1445370b324cSopenharmony_ci mov sym, wzr 1446370b324cSopenharmony_ci 1447370b324cSopenharmony_cifin: 1448370b324cSopenharmony_ci NORM 1449370b324cSopenharmony_ci 1450370b324cSopenharmony_ci #define fin_lzma_reg t0_R 1451370b324cSopenharmony_ci 1452370b324cSopenharmony_ci .macro STORE_LZMA_VAR reg:req, struct_offs:req 1453370b324cSopenharmony_ci str \reg, [fin_lzma_reg, \struct_offs] 1454370b324cSopenharmony_ci .endm 1455370b324cSopenharmony_ci 1456370b324cSopenharmony_ci .macro STORE_LZMA_PAIR reg0:req, reg1:req, struct_offs:req 1457370b324cSopenharmony_ci stp \reg0, \reg1, [fin_lzma_reg, \struct_offs] 1458370b324cSopenharmony_ci .endm 1459370b324cSopenharmony_ci 1460370b324cSopenharmony_ci ldr fin_lzma_reg, [sp, 120] 1461370b324cSopenharmony_ci p2_sub dicPos, dic 1462370b324cSopenharmony_ci shr state, PSHIFT 1463370b324cSopenharmony_ci 1464370b324cSopenharmony_ci STORE_LZMA_PAIR dicPos, buf, offset_dicPos 1465370b324cSopenharmony_ci STORE_LZMA_PAIR range, cod, offset_range 1466370b324cSopenharmony_ci STORE_LZMA_VAR processedPos, offset_processedPos 1467370b324cSopenharmony_ci STORE_LZMA_PAIR rep0, rep1, offset_rep0 1468370b324cSopenharmony_ci STORE_LZMA_PAIR rep2, rep3, offset_rep2 1469370b324cSopenharmony_ci STORE_LZMA_PAIR state, len, offset_state 1470370b324cSopenharmony_ci 1471370b324cSopenharmony_ci mov w0, sym 1472370b324cSopenharmony_ci 1473370b324cSopenharmony_ci ldp x29, x30, [sp, 80] 1474370b324cSopenharmony_ci ldp x27, x28, [sp, 64] 1475370b324cSopenharmony_ci ldp x25, x26, [sp, 48] 1476370b324cSopenharmony_ci ldp x23, x24, [sp, 32] 1477370b324cSopenharmony_ci ldp x21, x22, [sp, 16] 1478370b324cSopenharmony_ci ldp x19, x20, [sp], 128 1479370b324cSopenharmony_ci 1480370b324cSopenharmony_ci ret 1481370b324cSopenharmony_ci/* 1482370b324cSopenharmony_ci .cfi_endproc 1483370b324cSopenharmony_ci.LFE0: 1484370b324cSopenharmony_ci .size LzmaDec_DecodeReal_3, .-LzmaDec_DecodeReal_3 1485370b324cSopenharmony_ci .ident "TAG_LZMA" 1486370b324cSopenharmony_ci .section .note.GNU-stack,"",@progbits 1487370b324cSopenharmony_ci*/ 1488