xref: /third_party/lzma/Asm/arm64/LzmaDecOpt.S (revision 370b324c)
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