isa-l/igzip/aarch64/igzip_deflate_body_aarch64.S

262 lines
8.2 KiB
ArmAsm
Raw Normal View History

/**********************************************************************
Copyright(c) 2019 Arm Corporation All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Arm Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**********************************************************************/
.arch armv8-a+crc
.text
.align 2
#include "lz0a_const_aarch64.h"
#include "data_struct_aarch64.h"
#include "huffman_aarch64.h"
#include "bitbuf2_aarch64.h"
#include "stdmac_aarch64.h"
/*
declare Macros
*/
.macro declare_generic_reg name:req,reg:req,default:req
\name .req \default\reg
w_\name .req w\reg
x_\name .req x\reg
.endm
.macro update_state stream:req,start_in:req,next_in:req,end_in:req, \
m_out_buf:req,m_out_start:req,tmp0:req,tmp1:req
//m_out_buf=bytes_written
sub x_\m_out_buf,x_\m_out_buf,x_\m_out_start
cmp next_in,start_in
bls skip_has_hist
mov w_\tmp0,1
strb w_\tmp0,[x_\stream,_internal_state_has_hist]
skip_has_hist:
ldr w_\tmp0,[\stream,_total_in]
ldr x_\m_out_start,[\stream,_next_out] //m_out_start = next_out
str x_\next_in,[\stream,_next_in]
sub x_\start_in,x_\next_in,x_\start_in
sub x_\end_in,x_\end_in,x_\next_in
add w_\tmp0,w_\tmp0,w_\start_in
stp w_\end_in,w_\tmp0,[\stream,_avail_in]
//next_in=avail_out,start_in=total_out
ldp w_\next_in,w_\start_in,[\stream,_avail_out]
add x_\m_out_start,x_\m_out_start,x_\m_out_buf
str x_\m_out_start,[\stream,_next_out]
add w_\start_in,w_\start_in,w_\m_out_buf
sub w_\next_in,w_\next_in,w_\m_out_buf
stp w_\next_in,w_\start_in,[\stream,_avail_out]
.endm
.global isal_deflate_body_aarch64
.type isal_deflate_body_aarch64, %function
/*
void isal_deflate_body_aarch64(struct isal_zstream *stream)
*/
declare_generic_reg stream, 0,x //struct isal_zstream *stream
declare_generic_reg state, 8,x //&stream->state
declare_generic_reg avail_in, 9,w
declare_generic_reg end_of_stream, 10,w //can be used in loop
declare_generic_reg hash_mask, 11,w
declare_generic_reg match_length, 12,w
declare_generic_reg hufftables, 13,x
declare_generic_reg m_out_buf, 14,x
declare_generic_reg m_out_start, 15,x
declare_generic_reg m_out_end, 16,x
declare_generic_reg m_bits, 17,x
declare_generic_reg m_bit_count, 18,w
declare_generic_reg start_in, 19,x
declare_generic_reg end_in, 20,x
declare_generic_reg next_in, 21,x
declare_generic_reg loop_end_cnt, 22,x
declare_generic_reg literal, 23,w
declare_generic_reg hash, 24,w
declare_generic_reg dist, 25,w
declare_generic_reg last_seen, 26,x
declare_generic_reg file_start, 27,x
declare_generic_reg hist_size, 28,w
declare_generic_reg tmp0, 5 ,w
declare_generic_reg tmp1, 6 ,w
declare_generic_reg tmp2, 7 ,w
declare_generic_reg code, 3,x
declare_generic_reg code_len, 24,x
declare_generic_reg code2, 10,x
declare_generic_reg code_len2, 4,x
isal_deflate_body_aarch64:
//save registers
push_stack
ldr avail_in, [stream, _avail_in]
cbz avail_in, exit_save_state
// set_buf(&state->bitbuf, stream->next_out, stream->avail_out);
ldr w_m_out_end,[stream,_avail_out]
ldr m_out_buf,[stream,_next_out]
add m_out_end,m_out_buf,w_m_out_end,uxtw
sub m_out_end,m_out_end , 8
mov m_out_start,m_out_buf
stp m_out_buf,m_out_end,[stream, _bitbuf + _internal_state + _m_out_buf]
str m_out_start,[stream, _bitbuf + _internal_state + _m_out_start]
ldr m_bit_count ,[stream,_internal_state_bitbuf_m_bit_count]
ldr m_bits ,[stream,_internal_state_bitbuf_m_bits]
//init variables
//last_seen=&stream.internal_state.head = _internal_state+_head
add last_seen,stream,65536
add last_seen,last_seen,_internal_state+_head -65536
//start_in=stream->next_in;next_in=start_in
ldr start_in,[stream,_next_in]
mov next_in,start_in
add end_in,start_in,avail_in,uxtw //avail_in reg is free now
sub loop_end_cnt,end_in,289 //loop end
cmp next_in,loop_end_cnt
//file_start = (uint8_t *) ((uintptr_t) stream->next_in - stream->total_in);
ldr w_file_start,[stream,_total_in]
sub file_start,next_in,file_start,uxtw
//uint32_t hist_size = state->dist_mask;
ldr hist_size,[stream,_internal_state + _dist_mask]
//uint32_t hash_mask = state->hash_mask;
ldr hash_mask,[stream,_internal_state + _hash_mask]
ldr hufftables,[stream,_hufftables]
bhi main_loop_end
main_loop_start:
//is_full(&state->bitbuf)
cmp m_out_buf,m_out_end
bhi update_state_exit
ldr literal,[next_in]
crc32cw hash,wzr,literal
and hash,hash,hash_mask
///dist = (next_in - file_start - last_seen[hash]) & 0xFFFF;
ldrh w_tmp0,[last_seen,x_hash,lsl 1] //tmp_w last_seen[hash]
sub x_dist,next_in,file_start
//last_seen[hash] = (uint64_t) (next_in - file_start);
strh dist,[last_seen,x_hash,lsl 1]
sub dist,dist,w_tmp0
and dist,dist,0xffff
sub w_tmp0,dist,1
cmp hist_size,w_tmp0
bls get_lit_code
///match_length = compare258(next_in - dist, next_in, 258);
sub x_tmp2,next_in,x_dist
compare_258_bytes tmp2,next_in,match_length,tmp0,tmp1
cmp match_length,3
bls get_lit_code
sub x_tmp0,next_in,file_start
ldr literal,[next_in,1]
crc32cw hash,wzr,literal
and hash,hash,hash_mask
add tmp0,tmp0,1
strh tmp0,[last_seen,x_hash,lsl 1]
//call_print_b hash,dist,last_seen
ldr literal,[next_in,2]
crc32cw hash,wzr,literal
and hash,hash,hash_mask
add tmp0,tmp0,1
strh tmp0,[last_seen,x_hash,lsl 1]
//get_len_code(stream->hufftables, match_length, &code,
// &code_len);
get_len_code hufftables,match_length,code,code_len,tmp0
//get_dist_code(stream->hufftables, dist, &code2, &code_len2);
get_dist_code hufftables,dist,code2,code_len2,tmp0,tmp1,tmp2
//code |= code2 << code_len;
//code_len += code_len2;
lsl code2,code2,code_len
orr code,code,code2
add code_len,code_len,code_len2
//next_in += match_length;
add next_in,next_in,match_length,uxtw
//write_bits(&state->bitbuf, code, code_len);
update_bits stream,code,code_len,m_bits,m_bit_count,m_out_buf
cmp next_in,loop_end_cnt
bls main_loop_start
b main_loop_end
get_lit_code:
//get_lit_code(stream->hufftables, literal & 0xFF, &code, &code_len);
and literal,literal,0xff
get_lit_code hufftables,literal,code,code_len
//next_in++;
add next_in,next_in,1
//write_bits(&state->bitbuf, code, code_len);
update_bits stream,code,code_len,m_bits,m_bit_count,m_out_buf
cmp next_in,loop_end_cnt
bls main_loop_start
main_loop_end:
//update state here
//load end_of_stream and flush together
ldr w_end_of_stream, [stream, _end_of_stream]
//(stream->end_of_stream || stream->flush != 0)
cbz w_end_of_stream, update_state_exit
mov w_tmp0 , ZSTATE_FLUSH_READ_BUFFER
str w_tmp0, [stream, _internal_state+_state]
update_state_exit:
update_state stream,start_in,next_in,end_in,m_out_buf,m_out_start,tmp0,tmp1
exit_ret:
pop_stack
ret
exit_save_state:
ldr w_end_of_stream, [stream, _end_of_stream]
cbz w_end_of_stream, exit_ret //(stream->end_of_stream || stream->flush != 0)
mov w_tmp0 , ZSTATE_FLUSH_READ_BUFFER
str w_tmp0, [stream, _internal_state+_state]
b exit_ret
.size isal_deflate_body_aarch64, .-isal_deflate_body_aarch64