1 %include "reg_sizes.asm"
2 %include "lz0a_const.asm"
3 %include "data_struct2.asm"
6 ; tree entry is 4 bytes:
7 ; lit/len tree (513 entries)
13 ; |eblen:codlen| code |
16 ; DIST_OFFSET:0 : lit/len
17 ; 31:(DIST_OFFSET + 5) : dist Extra Bits
18 ; (DIST_OFFSET + 5):DIST_OFFSET : dist code
19 ; lit/len: 0-256 (literal)
20 ; 257-512 (dist + 254)
22 ; returns final token pointer
23 ; equal to token_end if successful
24 ; uint32_t* encode_df(uint32_t *token_start, uint32_t *token_end,
25 ; BitBuf *out_buf, uint32_t *trees);
27 %ifidn __OUTPUT_FORMAT__, win64
44 %define hufftables r11
48 %define in_buf_end arg2
50 %define out_buf bitbuf
59 %define LIT_MASK ((0x1 << LIT_LEN_BIT_COUNT) - 1)
60 %define DIST_MASK ((0x1 << DIST_LIT_BIT_COUNT) - 1)
63 %define code_lens1 ymm2
65 %define code_lens2 ymm4
67 %define code_lens3 ymm6
71 %define code_lens4 ymm8
75 %define codes_lookup1 ymm10
76 %define codes_lookup2 ymm11
79 %define ybits_count ymm14
80 %define yoffset_mask ymm15
82 %define VECTOR_SIZE 0x20
83 %define VECTOR_LOOP_PROCESSED (2 * VECTOR_SIZE)
84 %define VECTOR_SLOP 0x20 - 8
86 gpr_save_mem_offset equ 0
87 gpr_save_mem_size equ 8 * 6
88 xmm_save_mem_offset equ gpr_save_mem_offset + gpr_save_mem_size
89 xmm_save_mem_size equ 10 * 16
90 bitbuf_mem_offset equ xmm_save_mem_offset + xmm_save_mem_size
92 stack_size equ gpr_save_mem_size + xmm_save_mem_size + bitbuf_mem_size
97 mov [rsp + gpr_save_mem_offset + 0*8], rbx
98 mov [rsp + gpr_save_mem_offset + 1*8], rbp
99 mov [rsp + gpr_save_mem_offset + 2*8], r12
101 %ifidn __OUTPUT_FORMAT__, win64
102 mov [rsp + gpr_save_mem_offset + 3*8], rsi
103 mov [rsp + gpr_save_mem_offset + 4*8], rdi
105 MOVDQU [rsp + xmm_save_mem_offset + 0*8], xmm6
106 MOVDQU [rsp + xmm_save_mem_offset + 1*8], xmm7
107 MOVDQU [rsp + xmm_save_mem_offset + 2*8], xmm8
108 MOVDQU [rsp + xmm_save_mem_offset + 3*8], xmm9
109 MOVDQU [rsp + xmm_save_mem_offset + 4*8], xmm10
110 MOVDQU [rsp + xmm_save_mem_offset + 5*8], xmm11
111 MOVDQU [rsp + xmm_save_mem_offset + 6*8], xmm12
112 MOVDQU [rsp + xmm_save_mem_offset + 7*8], xmm13
113 MOVDQU [rsp + xmm_save_mem_offset + 8*8], xmm14
114 MOVDQU [rsp + xmm_save_mem_offset + 9*8], xmm15
119 %macro FUNC_RESTORE 0
120 mov rbx, [rsp + gpr_save_mem_offset + 0*8]
121 mov rbp, [rsp + gpr_save_mem_offset + 1*8]
122 mov r12, [rsp + gpr_save_mem_offset + 2*8]
124 %ifidn __OUTPUT_FORMAT__, win64
125 mov rsi, [rsp + gpr_save_mem_offset + 3*8]
126 mov rdi, [rsp + gpr_save_mem_offset + 4*8]
128 MOVDQU xmm6, [rsp + xmm_save_mem_offset + 0*8]
129 MOVDQU xmm7, [rsp + xmm_save_mem_offset + 1*8]
130 MOVDQU xmm8, [rsp + xmm_save_mem_offset + 2*8]
131 MOVDQU xmm9, [rsp + xmm_save_mem_offset + 3*8]
132 MOVDQU xmm10, [rsp + xmm_save_mem_offset + 4*8]
133 MOVDQU xmm11, [rsp + xmm_save_mem_offset + 5*8]
134 MOVDQU xmm12, [rsp + xmm_save_mem_offset + 6*8]
135 MOVDQU xmm13, [rsp + xmm_save_mem_offset + 7*8]
136 MOVDQU xmm14, [rsp + xmm_save_mem_offset + 8*8]
137 MOVDQU xmm15, [rsp + xmm_save_mem_offset + 9*8]
143 global encode_deflate_icf_ %+ ARCH
144 encode_deflate_icf_ %+ ARCH:
150 %ifnidn hufftables, arg4
154 mov [rsp + bitbuf_mem_offset], bitbuf
155 mov bits, [bitbuf + _m_bits]
156 mov ecx, [bitbuf + _m_bit_count]
157 mov end_ptr, [bitbuf + _m_out_end]
158 mov out_buf, [bitbuf + _m_out_buf] ; clobbers bitbuf
160 sub end_ptr, VECTOR_SLOP
161 sub in_buf_end, VECTOR_LOOP_PROCESSED
165 vpcmpeqq ytmp, ytmp, ytmp
167 vpand syms, datas, [lit_mask]
168 vpgatherdd codes_lookup1, [hufftables + _lit_len_table + 4 * syms], ytmp
170 vpcmpeqq ytmp, ytmp, ytmp
171 vpsrld dsyms, datas, DIST_OFFSET
172 vpand dsyms, dsyms, [dist_mask]
173 vpgatherdd codes_lookup2, [hufftables + _dist_table + 4 * dsyms], ytmp
175 vmovq ybits %+ x, bits
176 vmovq ybits_count %+ x, rcx
177 vmovdqa yoffset_mask, [offset_mask]
180 ;; Sets codes1 to contain lit/len codes andcode_lens1 the corresponding lengths
181 vpsrld code_lens1, codes_lookup1, 24
182 vpand codes1, codes_lookup1, [lit_icr_mask]
184 ;; Sets codes2 to contain dist codes, code_lens2 the corresponding lengths,
185 ;; and code_lens3 the extra bit counts
186 vpblendw codes2, ybits, codes_lookup2, 0x55 ;Bits 8 and above of ybits are 0
187 vpsrld code_lens2, codes_lookup2, 24
188 vpsrld code_lens3, codes_lookup2, 16
189 vpand code_lens3, [eb_icr_mask]
191 ;; Set codes3 to contain the extra bits
192 vpsrld codes3, datas, EXTRA_BITS_OFFSET
197 ;; Start code lookups for next iteration
199 vpcmpeqq ytmp, ytmp, ytmp
201 vpand syms, datas, [lit_mask]
202 vpgatherdd codes_lookup1, [hufftables + _lit_len_table + 4 * syms], ytmp
204 vpcmpeqq ytmp, ytmp, ytmp
205 vpsrld dsyms, datas, DIST_OFFSET
206 vpand dsyms, dsyms, [dist_mask]
207 vpgatherdd codes_lookup2, [hufftables + _dist_table + 4 * dsyms], ytmp
209 ;; Merge dist code with extra bits
210 vpsllvd codes3, codes3, code_lens2
211 vpxor codes2, codes2, codes3
212 vpaddd code_lens2, code_lens2, code_lens3
214 ;; Check for long codes
215 vpaddd code_lens3, code_lens1, code_lens2
216 vpcmpgtd ytmp, code_lens3, [max_write_d]
220 ;; Merge dist and len codes
221 vpsllvd codes2, codes2, code_lens1
222 vpxor codes1, codes1, codes2
224 ;; Split buffer data into qwords, ytmp is 0 after last branch
225 vpblendd codes3, ytmp, codes1, 0x55
226 vpsrlq codes1, codes1, 32
227 vpsrlq code_lens1, code_lens3, 32
228 vpblendd code_lens3, ytmp, code_lens3, 0x55
231 vpsllvq codes3, codes3, ybits_count
232 vpxor codes3, codes3, ybits
233 vpaddq code_lens3, code_lens3, ybits_count
235 ;; Merge two symbols into qwords
236 vpsllvq codes1, codes1, code_lens3
237 vpxor codes1, codes1, codes3
238 vpaddq code_lens1, code_lens1, code_lens3
240 ;; Split buffer data into dqwords, ytmp is 0 after last branch
241 vpblendd codes2, ytmp, codes1, 0x33
242 vpblendd code_lens2, ytmp, code_lens1, 0x33
244 vpsrldq code_lens1, 8
246 ;; Merge two qwords into dqwords
248 vpsubq code_lens3, ytmp, code_lens2
249 vpsrlvq codes3, codes1, code_lens3
250 vpslldq codes3, codes3, 8
252 vpsllvq codes1, codes1, code_lens2
254 vpxor codes1, codes1, codes3
255 vpxor codes1, codes1, codes2
256 vpaddq code_lens1, code_lens1, code_lens2
258 vmovq tmp, code_lens1 %+ x ;Number of bytes
260 vpand ybits_count, code_lens1, yoffset_mask ;Extra bits
262 ;; bit shift upper dqword combined bits to line up with lower dqword
263 vextracti128 codes2 %+ x, codes1, 1
264 vextracti128 code_lens2 %+ x, code_lens1, 1
266 vpbroadcastq ybits_count, ybits_count %+ x
267 vpsrldq codes3, codes2, 1
268 vpsllvq codes2, codes2, ybits_count
269 vpsllvq codes3, codes3, ybits_count
270 vpslldq codes3, codes3, 1
271 vpor codes2, codes2, codes3
273 ; Write out lower dqword of combined bits
274 vmovdqu [out_buf], codes1
275 movzx bits, byte [out_buf + tmp]
276 vmovq codes1 %+ x, bits
277 vpaddq code_lens1, code_lens1, code_lens2
279 vmovq tmp2, code_lens1 %+ x ;Number of bytes
281 vpand ybits_count, code_lens1, yoffset_mask ;Extra bits
283 ; Write out upper dqword of combined bits
284 vpor codes1 %+ x, codes1 %+ x, codes2 %+ x
285 vmovdqu [out_buf + tmp], codes1 %+ x
287 movzx bits, byte [out_buf]
288 vmovq ybits %+ x, bits
294 vmovq rcx, ybits_count %+ x
295 vmovq bits, ybits %+ x
299 add end_ptr, VECTOR_SLOP
302 vpxor ytmp, ytmp, ytmp
303 vpblendd codes3, ytmp, codes1, 0x55
304 vpblendd code_lens3, ytmp, code_lens1, 0x55
305 vpblendd codes4, ytmp, codes2, 0x55
307 vpsllvq codes4, codes4, code_lens3
308 vpxor codes3, codes3, codes4
309 vpaddd code_lens3, code_lens1, code_lens2
311 vpsrlq codes1, codes1, 32
312 vpsrlq code_lens1, code_lens1, 32
313 vpsrlq codes2, codes2, 32
315 vpsllvq codes2, codes2, code_lens1
316 vpxor codes1, codes1, codes2
318 vpsrlq code_lens1, code_lens3, 32
319 vpblendd code_lens3, ytmp, code_lens3, 0x55
322 vpsllvq codes3, codes3, ybits_count
323 vpxor codes3, codes3, ybits
324 vpaddq code_lens3, code_lens3, ybits_count
325 vpaddq code_lens1, code_lens1, code_lens3
329 vpsubq code_lens1, code_lens1, code_lens3
331 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
335 vmovq sym, codes3 %+ x
336 vmovq tmp2, code_lens3 %+ x
344 shr tmp, 3 ; byte count
353 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
357 vmovq sym, codes1 %+ x
358 vmovq tmp2, code_lens1 %+ x
366 shr tmp, 3 ; byte count
375 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
379 vpextrq sym, codes3 %+ x, 1
380 vpextrq tmp2, code_lens3 %+ x, 1
388 shr tmp, 3 ; byte count
397 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
401 vpextrq sym, codes1 %+ x, 1
402 vpextrq tmp2, code_lens1 %+ x, 1
410 shr tmp, 3 ; byte count
419 vextracti128 codes3 %+ x, codes3, 1
420 vextracti128 code_lens3 %+ x, code_lens3, 1
421 vextracti128 codes1 %+ x, codes1, 1
422 vextracti128 code_lens1 %+ x, code_lens1, 1
424 sub end_ptr, VECTOR_SLOP
426 vmovq ybits %+ x, bits
427 vmovq ybits_count %+ x, rcx
432 add in_buf_end, VECTOR_LOOP_PROCESSED
433 add end_ptr, VECTOR_SLOP
439 mov DWORD(data), [ptr]
445 and sym, LIT_MASK ; sym has ll_code
446 mov DWORD(sym), [hufftables + _lit_len_table + sym * 4]
450 shr dsym, DIST_OFFSET
452 mov DWORD(dsym), [hufftables + _dist_table + dsym * 4]
455 ; sym: 31:24 length; 23:0 code
464 movzx tmp, WORD(dsym)
471 ; insert dist extra bits
472 shr data, EXTRA_BITS_OFFSET
483 shr tmp, 3 ; byte count
495 mov tmp, [rsp + bitbuf_mem_offset]
496 mov [tmp + _m_bits], bits
497 mov [tmp + _m_bit_count], ecx
498 mov [tmp + _m_out_buf], out_buf
509 dd 0x1c, 0x1d, 0x20, 0x20, 0x1e, 0x1e, 0x1e, 0x1e
511 dq 0x0000000000000007, 0x0000000000000000
512 dq 0x0000000000000000, 0x0000000000000000
514 dq 0x0000000000000040, 0x0000000000000000
515 dq 0x0000000000000040, 0x0000000000000000
517 dd LIT_MASK, LIT_MASK, LIT_MASK, LIT_MASK
518 dd LIT_MASK, LIT_MASK, LIT_MASK, LIT_MASK
520 dd DIST_MASK, DIST_MASK, DIST_MASK, DIST_MASK
521 dd DIST_MASK, DIST_MASK, DIST_MASK, DIST_MASK
523 dd 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF
524 dd 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF
526 dd 0x000000FF, 0x000000FF, 0x000000FF, 0x000000FF
527 dd 0x000000FF, 0x000000FF, 0x000000FF, 0x000000FF