📄 bitdcods.s
字号:
BIC $dstword, $dstword, #255 << 24 ; clear top 8 bits of $dstword since required to hold data
; after operation which will be added by ADDing into bits
; 1 <= $t <= 3
ELSE
BIC $dstword, $dstword, #255 ; as for little but clear bottom 8 bits
ENDIF
BGT %FT4 ; get_decoded_byte_3 ; $t = 3 bytes already decoded into, jump to start of decoding with 1 byte remaining
IF {ENDIAN} = "little"
BIC $dstword, $dstword, #255 << 16 ; clear bits 16-23 of $dstword since required to hold data
; after operation which will be added by ADDing into bits
; top 8-bits are also clear by previous operation
; where passed over branch instruction
; 2 <= $t <= 3
ELSE
BIC $dstword, $dstword, #255 << 8 ; as for little but clear bits 8-15
ENDIF
BEQ %FT3 ; get_decoded_byte_2 ; $t = 2 bytes already decoded into, jump to start of decoding with 2 bytes remaining
IF {ENDIAN} = "little"
BIC $dstword, $dstword, #255 << 8 ; clear bits 8-15 of $dstword since required to hold data
; after operation which will be added by ADDing into bits
; bits 16-31 are also clear by previous two operations
; where passed over two branch instructions to here
; $t = 3
ELSE
BIC $dstword, $dstword, #255 << 16 ; as for little but clear bits 16-23
ENDIF
BLT %FT2 ; get_decoded_byte_1 ; $t = 1 byte already decoded to, jump to start of decoding with 3 bytes remaining
; all values of $t covered
; could use just B (branch) here without a test as always true at this point
; for each codeword decode it to a byte symbol
0 ; get_4_decoded_bytes
1 ; get_decoded_byte_0
DECODECODEWORD $lentable, $symtable, $srcword, $word, $bits, $codebits, $symbol, 8
IF {ENDIAN} = "little"
ADD $dstword, $symbol, #0 ; add decoded byte as bits 0-7 (bottom byte)
ELSE
MOV $dstword, #0 ; clear the destination word
ADD $dstword, $dstword, $symbol, LSL #24 ; add decoded byte as bits 24-31 (top byte)
ENDIF
2 ; get_decoded_byte_1
DECODECODEWORD $lentable, $symtable, $srcword, $word, $bits, $codebits, $symbol, 8
IF {ENDIAN} = "little"
ADD $dstword, $dstword, $symbol, LSL #8 ; add the decoded byte as bits 8-15
ELSE
ADD $dstword, $dstword, $symbol, LSL #16 ; add the decoded byte as bits 16-23
ENDIF
3 ; get_decoded_byte_2
DECODECODEWORD $lentable, $symtable, $srcword, $word, $bits, $codebits, $symbol, 8
IF {ENDIAN} = "little"
ADD $dstword, $dstword, $symbol, LSL #16 ; add the decoded byte as bits 16-23
ELSE
ADD $dstword, $dstword, $symbol, LSL #8 ; add the decoded byte as bits 8-15
ENDIF
4 ; get_decoded_byte_3
DECODECODEWORD $lentable, $symtable, $srcword, $word, $bits, $codebits, $symbol, 8
IF {ENDIAN} = "little"
ADD $dstword, $dstword, $symbol, LSL #24 ; add the decoded byte as bits 24-31 (top byte)
ELSE
ADD $dstword, $dstword, $symbol ; add the decoded byte as bits 0-7 (bottom byte)
ENDIF
5 ; save_4_decoded_bytes
STR $dstword, [$bytedest], #4 ; $dstword is now full so store into decoded byte array
6 ; check_4_byte_decode_process
SUBS $nbytes, $nbytes, #4 ; decrement the number of words (4 bytes) decoded
BGE %BT0 ; get_4_decoded_bytes ; loop while more words to decode else drop through to decode over bytes
7 ; decode_bytes
ADDS $nbytes, $nbytes, #4 ; add four onto number of bytes to decode
; 4 bytes will always have been subtracted from $nbytes when this point reached
; by word operations thus add back 4 to determine actual number of bytes
; remaining for processing which should be 0 <= $nbytes <= 3 unless function
; called with $nbytes < 0
BLE %FT10 ; end_byte_decoder ; if there are <= 0 bytes to decode, finished so clean up and return
8 ; byte_decode
DECODECODEWORD $lentable, $symtable, $srcword, $word, $bits, $codebits, $symbol, 8
STRB $symbol, [$bytedest], #1 ; store the decoded byte into decoded byte array and move to next position
9 ; check_byte_decode
SUBS $nbytes, $nbytes, #1 ; decrement number of bytes decoded
BGT %BT8 ; byte_decode ; loop while more bytes to decode
10 ; end_byte_decoder
MEND
;---------------------------------------------------------------
; decode to an array of halfwords
;
; decode variable length codewords to halfword symbols
;
; $nhwords register: number of halfwords to decode
; $hworddest register: an array to store halfwords decoded
; $dstword register: to hold decoded halfwords before saving
; $lentable register: decoding length table
; $symtable register: decoding symbol table
; $srcword register: current word being decoded
; $word register: top-up for $srcword
; $bits register: number of bits before $word is exhausted
; $codebits register: to hold each length of codeword being decoded
; $symbol register: to hold each decoded symbol
; $t register: temporary
;
; $nhwords, $hworddest, $dstword, $lentable, $symtable, $srcword, $word,
; $bits, $codebits and $symbol must all be distinct
;
; $t must be distinct from all registers except $codebits and $symbol
;
;---------------------------------------------------------------
MACRO
DECODETOHWORDS $nhwords, $hworddest, $dstword, $lentable, $symtable, $srcword, $word, $bits, $codebits, $symbol, $t
; check registers are distinct
DISTINCT $nhwords, $hworddest, $dstword, $lentable, $symtable, $srcword, $word, $bits, $codebits, $symbol
DISTINCT $t, $nhwords, $hworddest, $dstword, $lentable, $symtable, $srcword, $word, $bits
SUBS $nhwords, $nhwords, #2 ; check that there are at least 2 half words (1 word)...
BLT %FT5 ; check_hword_decode_process ; ...if < 2 half words, cannot operate on words so process half word
ANDS $t, $hworddest, #3 ; check that pointer is word-aligned (low 2-bits clear)...
BEQ %FT0 ; get_2_decoded_hwords ; ...if word aligned begin processing over words
LDR $dstword, [$hworddest, #-2]! ; ...else get initial (incomplete) destination word
; adjusting the pointer to make it word-aligned and leave the
; pointer in its adjusted state
IF {ENDIAN} = "little"
BIC $dstword, $dstword, #255 << 16 ; clear bits 16-31 since data added here by ADDing into bits
BIC $dstword, $dstword, #255 << 24
ELSE
BIC $dstword, $dstword, #255 ; clear bits 0-15 since data added here by ADDing into bits
BIC $dstword, $dstword, #255 << 8
ENDIF
ADD $nhwords, $nhwords, #1 ; $nhwords = $nhwords + 1
; word operations decrement number of half words processed by 2 thus add 1
; to ensure $nhwords is divisible by 2 so that decrement will remove 1 for
; odd half word and this extra 1 added here to leave correct number remaining
B %FT2 ; get_high_decoded_hword ; branch to have odd half word decoded which is in high 2-bytes of word
; for each codeword decode it to a halfword symbol
0 ; get_2_decoded_hwords
1 ; get_low_decoded_hword
DECODECODEWORD $lentable, $symtable, $srcword, $word, $bits, $codebits, $symbol, 16
IF {ENDIAN} = "little"
ADD $dstword, $symbol, #0 ; add decoded halfword as bits 0-15 (low half word)
ELSE
MOV $dstword, #0 ; clear the destination word
ADD $dstword, $dstword, $symbol, LSL #16 ; add decoded halfword as bits 16-31 (high half word)
ENDIF
2 ; get_high_decoded_hword
DECODECODEWORD $lentable, $symtable, $srcword, $word, $bits, $codebits, $symbol, 16
IF {ENDIAN} = "little"
ADD $dstword, $dstword, $symbol, LSL #16 ; add the decoded halfword as bits 16-31
ELSE
ADD $dstword, $dstword, $symbol ; add the decoded halfword as bits 0-15
ENDIF
3 ; save_2_decoded_hwords
STR $dstword, [$hworddest], #4 ; $dstword is now full so store into decoded array
4 ; check_2_hword_decode_process
SUBS $nhwords, $nhwords, #2 ; decrement the number of half words decoded
BGE %BT0 ; get_2_decoded_hwords ; loop while more words to decode else drop through to decode last half word
5 ; check_hword_decode_process
ADDS $nhwords, $nhwords, #2 ; add 2 back to $nhwords since will always have been decremented by 2 when reach here
BLE %FT7 ; end_hword_decoder ; if there are <= 0 half words to decode, finished so clean up and return
6 ; decode_hword
DECODECODEWORD $lentable, $symtable, $srcword, $word, $bits, $codebits, $symbol, 16
IF ARCHITECTURE_4
STRH $symbol, [$hworddest], #2 ; store the decoded halfword into array and move to next position
ELSE
IF {ENDIAN} = "big" ; store the byte of the halfword in the correct order for endianness
STRB $symbol, [$hworddest, #1] ; increment the pointer and store but do not permanently update pointer
ELSE
STRB $symbol, [$hworddest], #1 ; store and increment the pointer permanently
ENDIF
MOV $symbol, $symbol, ROR #8 ; clear the bottom 8 bits and move the top 8 bits of the halfword into the bottom
STRB $symbol, [$hworddest], #1 ; store the next byte
ENDIF
7 ; end_hword_decoder
MEND
;---------------------------------------------------------------
; decode to an array of word
;
; decode variable length codewords to word symbols
;
; $nwords register: number of words to decode
; $worddest register: an array to store words decoded
; $dstword register: to hold decoded word before saving
; $lentable register: decoding length table
; $symtable register: decoding symbol table
; $srcword register: current word being decoded
; $word register: top-up for $srcword
; $bits register: number of bits before $word is exhausted
; $codebits register: to hold each length of codeword being decoded
; $symbol register: to hold each decoded symbol
; $t register: temporary
;
; $nwords, $worddest, $dstword, $lentable, $symtable, $srcword, $word,
; $bits, $codebits and $symbol must all be distinct
;
; $t must be distinct from all registers except $codebits and $symbol
;
;---------------------------------------------------------------
MACRO
DECODETOWORDS $nwords, $worddest, $dstword, $lentable, $symtable, $srcword, $word, $bits, $codebits, $symbol, $t
; check registers are distinct
DISTINCT $nwords, $worddest, $dstword, $lentable, $symtable, $srcword, $word, $bits, $codebits, $symbol
DISTINCT $t, $nwords, $worddest, $dstword, $lentable, $symtable, $srcword, $word, $bits
B %FT2 ; check_word_decode_process ; branch to check number of words to decode
; for each codeword decode it to a word symbol
0 ; get_decoded_word
DECODECODEWORD $lentable, $symtable, $srcword, $word, $bits, $codebits, $symbol, 32
1 ; save_decoded_word
STR $symbol, [$worddest], #4 ; store into decoded array
2 ; check_word_decode_process
SUBS $nwords, $nwords, #1 ; decrement the number of words decoded
BGE %BT0 ; get_decoded_word ; loop while more words to decode
7 ; end_word_decoder
MEND
;---------------------------------------------------------------
; tree or refill
;
; determine if a tree traversal is required or a decoding word
; refill
;
; $bits register: amount by which top-up word is exhausted
; or < -32 for a tree traversal
; $datasize the size of the data items in the array - 8, 16 or 32 bits
;
;---------------------------------------------------------------
MACRO
TREEORREFILL $bits, $datasize
ASSERT ( $datasize = 8 :LOR: $datasize = 16 :LOR: $datasize = 32 ) ; check data size
CMP $bits, #-32 ; if the codeword could not be looked up in the table, 255 is returned as its
; length which is subracted from $bits thus test for this which indicates the
; case of walking through the tree
; $bits has normal range 0 <= $bits <= 32, thus the test for -32 is sufficient
; test for tree walk case and allows for the value for tree walking to be changed
; to anything from 33 or more
; $bits is always negative here
IF $datasize = 8
BLT tree_walk_byte ; if $bits < -32, then perform a tree traversal else drop through to refill
; which MUST follow an instance of this macro
; it is assumed that the tree walk is only used for codewords that do not occur
; very frequently and thus the branch to this point is more likely to be for
; refilling rather than tree walking hence no extra overhead is added to branch
; again to refill but another branch is required to walk to the tree
ELSE
IF $datasize = 16
BLT tree_walk_hword
ELSE
BLT tree_walk_word
ENDIF
ENDIF
MEND
;---------------------------------------------------------------
; refill top-up word
;
; use the final bits from the top-up word then refill the top-up word
;
; $source register: pointer to bit stream to read next word for decoding
; $srcword register: the current 32 bits being decoded
; $word register: the top-up word that needs refilling
; $codebits register: the number of bits in $srcword to replace
; $bits register: the amount by which the top-up word is short
; for refilling $srcword
; $t register: temporary
;
; $source, $srcword, $word and $bits must be distinct
;
;---------------------------------------------------------------
MACRO
REFILLBUFFER $source, $srcword, $word, $codebits, $bits, $t
; check registers are distinct
DISTINCT $srcword, $word, $source, $bits
MOV $srcword, $srcword, LSL $codebits ; remove the codeword that has been decoded from top of the decoding word shifting
; all remaining bits to decode into the top bits
; $codebits may be equal to (255-codeword length) where codeword length <= 27 thus the
; shift clears
RSB $bits, $bits, #0 ; $bits < 0 thus get $bits = 0 - $bits = -$bits
; this gives $bits as a positive number of the number of bits that are required
; from the top-up word that currently don't exist in the word since it has been
; exhausted
ORR $srcword, $srcword, $word, LSL $bits ; add remaining bits from the top-up word to the decoding word from the
; first free bit down
LDR $word, [ $source ], #4 ; load the next 32 bits from the coded stream into the top-up word
IF {ENDIAN} = "little" ; the bit operations are big endian but if the decoding is performed in little endian mode
BYTEREV $word, $word, $t ; then the bytes of a word need reversing to make them little endian before they can be used
ENDIF
RSB $bits, $bits, #32 ; $bits = 32 - $bits
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -