10c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
278e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar;// Copyright (C) 2007-2008 ARM Limited
378e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar;//
478e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar;// Licensed under the Apache License, Version 2.0 (the "License");
578e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar;// you may not use this file except in compliance with the License.
678e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar;// You may obtain a copy of the License at
778e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar;//
878e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar;//      http://www.apache.org/licenses/LICENSE-2.0
978e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar;//
1078e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar;// Unless required by applicable law or agreed to in writing, software
1178e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar;// distributed under the License is distributed on an "AS IS" BASIS,
1278e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1378e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar;// See the License for the specific language governing permissions and
1478e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar;// limitations under the License.
1578e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar;//
1678e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar;//
170c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
180c1bc742181ded4930842b46e9507372f0b1b963James Dong;// File Name:  armCOMM_BitDec_s.h
190c1bc742181ded4930842b46e9507372f0b1b963James Dong;// OpenMAX DL: v1.0.2
200c1bc742181ded4930842b46e9507372f0b1b963James Dong;// Revision:   9641
210c1bc742181ded4930842b46e9507372f0b1b963James Dong;// Date:       Thursday, February 7, 2008
220c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
230c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
240c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
250c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
260c1bc742181ded4930842b46e9507372f0b1b963James Dong;// OpenMAX optimized bitstream decode module
270c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
280c1bc742181ded4930842b46e9507372f0b1b963James Dong;// You must include armCOMM_s.h before including this file
290c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
300c1bc742181ded4930842b46e9507372f0b1b963James Dong;// This module provides macros to perform assembly optimized fixed and
310c1bc742181ded4930842b46e9507372f0b1b963James Dong;// variable length decoding from a read-only bitstream. The variable
320c1bc742181ded4930842b46e9507372f0b1b963James Dong;// length decode modules take as input a pointer to a table of 16-bit
330c1bc742181ded4930842b46e9507372f0b1b963James Dong;// entries of the following format.
340c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
350c1bc742181ded4930842b46e9507372f0b1b963James Dong;// VLD Table Entry format
360c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
370c1bc742181ded4930842b46e9507372f0b1b963James Dong;//        15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
380c1bc742181ded4930842b46e9507372f0b1b963James Dong;//       +------------------------------------------------+
390c1bc742181ded4930842b46e9507372f0b1b963James Dong;//       |  Len   |               Symbol              | 1 |
400c1bc742181ded4930842b46e9507372f0b1b963James Dong;//       +------------------------------------------------+
410c1bc742181ded4930842b46e9507372f0b1b963James Dong;//       |                Offset                      | 0 |
420c1bc742181ded4930842b46e9507372f0b1b963James Dong;//       +------------------------------------------------+
430c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
440c1bc742181ded4930842b46e9507372f0b1b963James Dong;// If the table entry is a leaf entry then bit 0 set:
450c1bc742181ded4930842b46e9507372f0b1b963James Dong;//    Len    = Number of bits overread (0 to 7)
460c1bc742181ded4930842b46e9507372f0b1b963James Dong;//    Symbol = Symbol payload (unsigned 12 bits)
470c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
480c1bc742181ded4930842b46e9507372f0b1b963James Dong;// If the table entry is an internal node then bit 0 is clear:
490c1bc742181ded4930842b46e9507372f0b1b963James Dong;//    Offset = Number of (16-bit) half words from the table
500c1bc742181ded4930842b46e9507372f0b1b963James Dong;//             start to the next table node
510c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
520c1bc742181ded4930842b46e9507372f0b1b963James Dong;// The table is accessed by successive lookup up on the
530c1bc742181ded4930842b46e9507372f0b1b963James Dong;// next Step bits of the input bitstream until a leaf node
540c1bc742181ded4930842b46e9507372f0b1b963James Dong;// is obtained. The Step sizes are supplied to the VLD macro.
550c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
560c1bc742181ded4930842b46e9507372f0b1b963James Dong;// USAGE:
570c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
580c1bc742181ded4930842b46e9507372f0b1b963James Dong;// To use any of the macros in this package, first call:
590c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
600c1bc742181ded4930842b46e9507372f0b1b963James Dong;//    M_BD_INIT ppBitStream, pBitOffset, pBitStream, RBitBuffer, RBitCount, Tmp
610c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
620c1bc742181ded4930842b46e9507372f0b1b963James Dong;// This caches the current bitstream position and next available
630c1bc742181ded4930842b46e9507372f0b1b963James Dong;// bits in registers pBitStream, RBitBuffer, RBitCount. These registers
640c1bc742181ded4930842b46e9507372f0b1b963James Dong;// are reserved for use by the bitstream decode package until you
650c1bc742181ded4930842b46e9507372f0b1b963James Dong;// call M_BD_FINI.
660c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
670c1bc742181ded4930842b46e9507372f0b1b963James Dong;// Next call the following macro(s) as many times as you need:
680c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
690c1bc742181ded4930842b46e9507372f0b1b963James Dong;//    M_BD_LOOK8       - Look ahead constant 1<=N<=8  bits into the bitstream
700c1bc742181ded4930842b46e9507372f0b1b963James Dong;//    M_BD_LOOK16      - Look ahead constant 1<=N<=16 bits into the bitstream
710c1bc742181ded4930842b46e9507372f0b1b963James Dong;//    M_BD_READ8       - Read constant 1<=N<=8  bits from the bitstream
720c1bc742181ded4930842b46e9507372f0b1b963James Dong;//    M_BD_READ16      - Read constant 1<=N<=16 bits from the bitstream
730c1bc742181ded4930842b46e9507372f0b1b963James Dong;//    M_BD_VREAD8      - Read variable 1<=N<=8  bits from the bitstream
740c1bc742181ded4930842b46e9507372f0b1b963James Dong;//    M_BD_VREAD16     - Read variable 1<=N<=16 bits from the bitstream
750c1bc742181ded4930842b46e9507372f0b1b963James Dong;//    M_BD_VLD         - Perform variable length decode using lookup table
760c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
770c1bc742181ded4930842b46e9507372f0b1b963James Dong;// Finally call the macro:
780c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
790c1bc742181ded4930842b46e9507372f0b1b963James Dong;//    M_BD_FINI ppBitStream, pBitOffset
800c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
810c1bc742181ded4930842b46e9507372f0b1b963James Dong;// This writes the bitstream state back to memory.
820c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
830c1bc742181ded4930842b46e9507372f0b1b963James Dong;// The three bitstream cache register names are assigned to the following global
840c1bc742181ded4930842b46e9507372f0b1b963James Dong;// variables:
850c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
860c1bc742181ded4930842b46e9507372f0b1b963James Dong
870c1bc742181ded4930842b46e9507372f0b1b963James Dong        GBLS    pBitStream  ;// Register name for pBitStream
880c1bc742181ded4930842b46e9507372f0b1b963James Dong        GBLS    BitBuffer   ;// Register name for BitBuffer
890c1bc742181ded4930842b46e9507372f0b1b963James Dong        GBLS    BitCount    ;// Register name for BitCount
900c1bc742181ded4930842b46e9507372f0b1b963James Dong
910c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
920c1bc742181ded4930842b46e9507372f0b1b963James Dong;// These register variables must have a certain defined state on entry to every bitstream
930c1bc742181ded4930842b46e9507372f0b1b963James Dong;// macro (except M_BD_INIT) and on exit from every bitstream macro (except M_BD_FINI).
940c1bc742181ded4930842b46e9507372f0b1b963James Dong;// The state may depend on implementation.
950c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
960c1bc742181ded4930842b46e9507372f0b1b963James Dong;// For the default (ARM11) implementation the following hold:
970c1bc742181ded4930842b46e9507372f0b1b963James Dong;//    pBitStream - points to the first byte not held in the BitBuffer
980c1bc742181ded4930842b46e9507372f0b1b963James Dong;//    BitBuffer  - is a cache of (4 bytes) 32 bits, bit 31 the first bit
990c1bc742181ded4930842b46e9507372f0b1b963James Dong;//    BitCount   - is offset (from the top bit) to the next unused bitstream bit
1000c1bc742181ded4930842b46e9507372f0b1b963James Dong;//    0<=BitCount<=15 (so BitBuffer holds at least 17 unused bits)
1010c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
1020c1bc742181ded4930842b46e9507372f0b1b963James Dong;//
1030c1bc742181ded4930842b46e9507372f0b1b963James Dong
1040c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Bitstream Decode initialise
1050c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
1060c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Initialises the bitstream decode global registers from
1070c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// bitstream pointers. This macro is split into 3 parts to enable
1080c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// scheduling.
1090c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
1100c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Input Registers:
1110c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
1120c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $ppBitStream    - pointer to pointer to the next bitstream byte
1130c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitOffset     - pointer to the number of bits used in the current byte (0..7)
1140c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $RBitStream     - register to use for pBitStream (can be $ppBitStream)
1150c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $RBitBuffer     - register to use for BitBuffer
1160c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $RBitCount      - register to use for BitCount   (can be $pBitOffset)
1170c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
1180c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Output Registers:
1190c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
1200c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T1,$T2,$T3     - registers that must be preserved between calls to
1210c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//                   M_BD_INIT1 and M_BD_INIT2
1220c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
1230c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
1240c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
1250c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
1260c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
1270c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_INIT0  $ppBitStream, $pBitOffset, $RBitStream, $RBitBuffer, $RBitCount
1280c1bc742181ded4930842b46e9507372f0b1b963James Dong
1290c1bc742181ded4930842b46e9507372f0b1b963James DongpBitStream  SETS "$RBitStream"
1300c1bc742181ded4930842b46e9507372f0b1b963James DongBitBuffer   SETS "$RBitBuffer"
1310c1bc742181ded4930842b46e9507372f0b1b963James DongBitCount    SETS "$RBitCount"
1320c1bc742181ded4930842b46e9507372f0b1b963James Dong
1330c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// load inputs
1340c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDR     $pBitStream, [$ppBitStream]
1350c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDR     $BitCount, [$pBitOffset]
1360c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
1370c1bc742181ded4930842b46e9507372f0b1b963James Dong
1380c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
1390c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_INIT1  $T1, $T2, $T3
1400c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDRB    $T2, [$pBitStream, #2]
1410c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDRB    $T1, [$pBitStream, #1]
1420c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDRB    $BitBuffer,  [$pBitStream], #3
1430c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADD     $BitCount, $BitCount, #8
1440c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
1450c1bc742181ded4930842b46e9507372f0b1b963James Dong
1460c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
1470c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_INIT2  $T1, $T2, $T3
1480c1bc742181ded4930842b46e9507372f0b1b963James Dong        ORR     $T2, $T2, $T1, LSL #8
1490c1bc742181ded4930842b46e9507372f0b1b963James Dong        ORR     $BitBuffer, $T2, $BitBuffer, LSL #16
1500c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
1510c1bc742181ded4930842b46e9507372f0b1b963James Dong
1520c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
1530c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Look ahead fixed 1<=N<=8 bits without consuming any bits
1540c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// The next bits will be placed at bit 31..24 of destination register
1550c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
1560c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Input Registers:
1570c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
1580c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $N              - number of bits to look
1590c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
1600c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
1610c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
1620c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
1630c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Output Registers:
1640c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
1650c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $Symbol         - the next N bits of the bitstream
1660c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T1             - corrupted temp/scratch register
1670c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
1680c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
1690c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
1700c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
1710c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
1720c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_LOOK8  $Symbol, $N
1730c1bc742181ded4930842b46e9507372f0b1b963James Dong        ASSERT  ($N>=1):LAND:($N<=8)
1740c1bc742181ded4930842b46e9507372f0b1b963James Dong        MOV     $Symbol, $BitBuffer, LSL $BitCount
1750c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
1760c1bc742181ded4930842b46e9507372f0b1b963James Dong
1770c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
1780c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Look ahead fixed 1<=N<=16 bits without consuming any bits
1790c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// The next bits will be placed at bit 31..16 of destination register
1800c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
1810c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Input Registers:
1820c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
1830c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $N              - number of bits to look
1840c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
1850c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
1860c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
1870c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
1880c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Output Registers:
1890c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
1900c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $Symbol         - the next N bits of the bitstream
1910c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T1             - corrupted temp/scratch register
1920c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
1930c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
1940c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
1950c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
1960c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
1970c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_LOOK16  $Symbol, $N, $T1
1980c1bc742181ded4930842b46e9507372f0b1b963James Dong        ASSERT  ($N >= 1):LAND:($N <= 16)
1990c1bc742181ded4930842b46e9507372f0b1b963James Dong        MOV     $Symbol, $BitBuffer, LSL $BitCount
2000c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
2010c1bc742181ded4930842b46e9507372f0b1b963James Dong
2020c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2030c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Skips fixed 1<=N<=8 bits from the bitstream, advancing the bitstream pointer
2040c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2050c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Input Registers:
2060c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2070c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $N              - number of bits
2080c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
2090c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
2100c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
2110c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2120c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Output Registers:
2130c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2140c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T1             - corrupted temp/scratch register
2150c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
2160c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
2170c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
2180c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2190c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
2200c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_SKIP8 $N, $T1
2210c1bc742181ded4930842b46e9507372f0b1b963James Dong        ASSERT  ($N>=1):LAND:($N<=8)
2220c1bc742181ded4930842b46e9507372f0b1b963James Dong        SUBS    $BitCount, $BitCount, #(8-$N)
2230c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDRCSB  $T1, [$pBitStream], #1
2240c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADDCC   $BitCount, $BitCount, #8
2250c1bc742181ded4930842b46e9507372f0b1b963James Dong        ORRCS   $BitBuffer, $T1, $BitBuffer, LSL #8
2260c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
2270c1bc742181ded4930842b46e9507372f0b1b963James Dong
2280c1bc742181ded4930842b46e9507372f0b1b963James Dong
2290c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2300c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Read fixed 1<=N<=8 bits from the bitstream, advancing the bitstream pointer
2310c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2320c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Input Registers:
2330c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2340c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $N              - number of bits to read
2350c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
2360c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
2370c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
2380c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2390c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Output Registers:
2400c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2410c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $Symbol         - the next N bits of the bitstream
2420c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T1             - corrupted temp/scratch register
2430c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
2440c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
2450c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
2460c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2470c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
2480c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_READ8 $Symbol, $N, $T1
2490c1bc742181ded4930842b46e9507372f0b1b963James Dong        ASSERT  ($N>=1):LAND:($N<=8)
2500c1bc742181ded4930842b46e9507372f0b1b963James Dong        MOVS    $Symbol, $BitBuffer, LSL $BitCount
2510c1bc742181ded4930842b46e9507372f0b1b963James Dong        SUBS    $BitCount, $BitCount, #(8-$N)
2520c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDRCSB  $T1, [$pBitStream], #1
2530c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADDCC   $BitCount, $BitCount, #8
2540c1bc742181ded4930842b46e9507372f0b1b963James Dong        MOV     $Symbol, $Symbol, LSR #(32-$N)
2550c1bc742181ded4930842b46e9507372f0b1b963James Dong        ORRCS   $BitBuffer, $T1, $BitBuffer, LSL #8
2560c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
2570c1bc742181ded4930842b46e9507372f0b1b963James Dong
2580c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2590c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Read fixed 1<=N<=16 bits from the bitstream, advancing the bitstream pointer
2600c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2610c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Input Registers:
2620c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2630c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $N              - number of bits to read
2640c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
2650c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
2660c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
2670c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2680c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Output Registers:
2690c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2700c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $Symbol         - the next N bits of the bitstream
2710c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T1             - corrupted temp/scratch register
2720c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T2             - corrupted temp/scratch register
2730c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
2740c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
2750c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
2760c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2770c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
2780c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_READ16 $Symbol, $N, $T1, $T2
2790c1bc742181ded4930842b46e9507372f0b1b963James Dong        ASSERT  ($N>=1):LAND:($N<=16)
2800c1bc742181ded4930842b46e9507372f0b1b963James Dong        ASSERT  $Symbol<>$T1
2810c1bc742181ded4930842b46e9507372f0b1b963James Dong        IF ($N<=8)
2820c1bc742181ded4930842b46e9507372f0b1b963James Dong            M_BD_READ8  $Symbol, $N, $T1
2830c1bc742181ded4930842b46e9507372f0b1b963James Dong        ELSE
2840c1bc742181ded4930842b46e9507372f0b1b963James Dong            ;// N>8 so we will be able to refill at least one byte
2850c1bc742181ded4930842b46e9507372f0b1b963James Dong            LDRB    $T1, [$pBitStream], #1
2860c1bc742181ded4930842b46e9507372f0b1b963James Dong            MOVS    $Symbol, $BitBuffer, LSL $BitCount
2870c1bc742181ded4930842b46e9507372f0b1b963James Dong            ORR     $BitBuffer, $T1, $BitBuffer, LSL #8
2880c1bc742181ded4930842b46e9507372f0b1b963James Dong            SUBS    $BitCount, $BitCount, #(16-$N)
2890c1bc742181ded4930842b46e9507372f0b1b963James Dong            LDRCSB  $T1, [$pBitStream], #1
2900c1bc742181ded4930842b46e9507372f0b1b963James Dong            MOV     $Symbol, $Symbol, LSR #(32-$N)
2910c1bc742181ded4930842b46e9507372f0b1b963James Dong            ADDCC   $BitCount, $BitCount, #8
2920c1bc742181ded4930842b46e9507372f0b1b963James Dong            ORRCS   $BitBuffer, $T1, $BitBuffer, LSL #8
2930c1bc742181ded4930842b46e9507372f0b1b963James Dong        ENDIF
2940c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
2950c1bc742181ded4930842b46e9507372f0b1b963James Dong
2960c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2970c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Skip variable 1<=N<=8 bits from the bitstream, advancing the bitstream pointer.
2980c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
2990c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Input Registers:
3000c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3010c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $N              - number of bits. 1<=N<=8
3020c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
3030c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
3040c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
3050c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3060c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Output Registers:
3070c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3080c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T1             - corrupted temp/scratch register
3090c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T2             - corrupted temp/scratch register
3100c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
3110c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
3120c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
3130c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3140c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
3150c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_VSKIP8 $N, $T1
3160c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADD     $BitCount, $BitCount, $N
3170c1bc742181ded4930842b46e9507372f0b1b963James Dong        SUBS    $BitCount, $BitCount, #8
3180c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDRCSB  $T1, [$pBitStream], #1
3190c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADDCC   $BitCount, $BitCount, #8
3200c1bc742181ded4930842b46e9507372f0b1b963James Dong        ORRCS   $BitBuffer, $T1, $BitBuffer, LSL #8
3210c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
3220c1bc742181ded4930842b46e9507372f0b1b963James Dong
3230c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3240c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Skip variable 1<=N<=16 bits from the bitstream, advancing the bitstream pointer.
3250c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3260c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Input Registers:
3270c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3280c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $N              - number of bits. 1<=N<=16
3290c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
3300c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
3310c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
3320c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3330c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Output Registers:
3340c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3350c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T1             - corrupted temp/scratch register
3360c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T2             - corrupted temp/scratch register
3370c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
3380c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
3390c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
3400c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3410c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
3420c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_VSKIP16 $N, $T1, $T2
3430c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADD     $BitCount, $BitCount, $N
3440c1bc742181ded4930842b46e9507372f0b1b963James Dong        SUBS    $BitCount, $BitCount, #8
3450c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDRCSB  $T1, [$pBitStream], #1
3460c1bc742181ded4930842b46e9507372f0b1b963James Dong        ORRCS   $BitBuffer, $T1, $BitBuffer, LSL #8
3470c1bc742181ded4930842b46e9507372f0b1b963James Dong        SUBCSS  $BitCount, $BitCount, #8
3480c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDRCSB  $T1, [$pBitStream], #1
3490c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADDCC   $BitCount, $BitCount, #8
3500c1bc742181ded4930842b46e9507372f0b1b963James Dong        ORRCS   $BitBuffer, $T1, $BitBuffer, LSL #8
3510c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
3520c1bc742181ded4930842b46e9507372f0b1b963James Dong
3530c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3540c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Read variable 1<=N<=8 bits from the bitstream, advancing the bitstream pointer.
3550c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3560c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Input Registers:
3570c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3580c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $N              - number of bits to read. 1<=N<=8
3590c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
3600c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
3610c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
3620c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3630c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Output Registers:
3640c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3650c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $Symbol         - the next N bits of the bitstream
3660c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T1             - corrupted temp/scratch register
3670c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T2             - corrupted temp/scratch register
3680c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
3690c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
3700c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
3710c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3720c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
3730c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_VREAD8 $Symbol, $N, $T1, $T2
3740c1bc742181ded4930842b46e9507372f0b1b963James Dong        MOV     $Symbol, $BitBuffer, LSL $BitCount
3750c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADD     $BitCount, $BitCount, $N
3760c1bc742181ded4930842b46e9507372f0b1b963James Dong        SUBS    $BitCount, $BitCount, #8
3770c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDRCSB  $T1, [$pBitStream], #1
3780c1bc742181ded4930842b46e9507372f0b1b963James Dong        RSB     $T2, $N, #32
3790c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADDCC   $BitCount, $BitCount, #8
3800c1bc742181ded4930842b46e9507372f0b1b963James Dong        MOV     $Symbol, $Symbol, LSR $T2
3810c1bc742181ded4930842b46e9507372f0b1b963James Dong        ORRCS   $BitBuffer, $T1, $BitBuffer, LSL #8
3820c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
3830c1bc742181ded4930842b46e9507372f0b1b963James Dong
3840c1bc742181ded4930842b46e9507372f0b1b963James Dong
3850c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3860c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Read variable 1<=N<=16 bits from the bitstream, advancing the bitstream pointer.
3870c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3880c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Input Registers:
3890c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3900c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $N              - number of bits to read. 1<=N<=16
3910c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
3920c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
3930c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
3940c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3950c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Output Registers:
3960c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
3970c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $Symbol         - the next N bits of the bitstream
3980c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T1             - corrupted temp/scratch register
3990c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T2             - corrupted temp/scratch register
4000c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
4010c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
4020c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
4030c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
4040c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
4050c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_VREAD16 $Symbol, $N, $T1, $T2
4060c1bc742181ded4930842b46e9507372f0b1b963James Dong        MOV     $Symbol, $BitBuffer, LSL $BitCount
4070c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADD     $BitCount, $BitCount, $N
4080c1bc742181ded4930842b46e9507372f0b1b963James Dong        SUBS    $BitCount, $BitCount, #8
4090c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDRCSB  $T1, [$pBitStream], #1
4100c1bc742181ded4930842b46e9507372f0b1b963James Dong        RSB     $T2, $N, #32
4110c1bc742181ded4930842b46e9507372f0b1b963James Dong        ORRCS   $BitBuffer, $T1, $BitBuffer, LSL #8
4120c1bc742181ded4930842b46e9507372f0b1b963James Dong        SUBCSS  $BitCount, $BitCount, #8
4130c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDRCSB  $T1, [$pBitStream], #1
4140c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADDCC   $BitCount, $BitCount, #8
4150c1bc742181ded4930842b46e9507372f0b1b963James Dong        MOV     $Symbol, $Symbol, LSR $T2
4160c1bc742181ded4930842b46e9507372f0b1b963James Dong        ORRCS   $BitBuffer, $T1, $BitBuffer, LSL #8
4170c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
4180c1bc742181ded4930842b46e9507372f0b1b963James Dong
4190c1bc742181ded4930842b46e9507372f0b1b963James Dong
4200c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
4210c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Decode a code of the form 0000...001 where there
4220c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// are N zeros before the 1 and N<=15 (code length<=16)
4230c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
4240c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Input Registers:
4250c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
4260c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
4270c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
4280c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
4290c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
4300c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Output Registers:
4310c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
4320c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $Symbol         - the number of zeros before the next 1
4330c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//                   >=16 is an illegal code
4340c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T1             - corrupted temp/scratch register
4350c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T2             - corrupted temp/scratch register
4360c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
4370c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
4380c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
4390c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
4400c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
4410c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_CLZ16 $Symbol, $T1, $T2
4420c1bc742181ded4930842b46e9507372f0b1b963James Dong        MOVS    $Symbol, $BitBuffer, LSL $BitCount
4430c1bc742181ded4930842b46e9507372f0b1b963James Dong        CLZ     $Symbol, $Symbol
4440c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADD     $BitCount, $BitCount, $Symbol
4450c1bc742181ded4930842b46e9507372f0b1b963James Dong        SUBS    $BitCount, $BitCount, #7        ;// length is Symbol+1
4460c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDRCSB  $T1, [$pBitStream], #1
4470c1bc742181ded4930842b46e9507372f0b1b963James Dong        ORRCS   $BitBuffer, $T1, $BitBuffer, LSL #8
4480c1bc742181ded4930842b46e9507372f0b1b963James Dong        SUBCSS  $BitCount, $BitCount, #8
4490c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDRCSB  $T1, [$pBitStream], #1
4500c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADDCC   $BitCount, $BitCount, #8
4510c1bc742181ded4930842b46e9507372f0b1b963James Dong        ORRCS   $BitBuffer, $T1, $BitBuffer, LSL #8
4520c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
4530c1bc742181ded4930842b46e9507372f0b1b963James Dong
4540c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
4550c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Decode a code of the form 1111...110 where there
4560c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// are N ones before the 0 and N<=15 (code length<=16)
4570c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
4580c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Input Registers:
4590c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
4600c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
4610c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
4620c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
4630c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
4640c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Output Registers:
4650c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
4660c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $Symbol         - the number of zeros before the next 1
4670c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//                   >=16 is an illegal code
4680c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T1             - corrupted temp/scratch register
4690c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T2             - corrupted temp/scratch register
4700c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
4710c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
4720c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
4730c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
4740c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
4750c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_CLO16 $Symbol, $T1, $T2
4760c1bc742181ded4930842b46e9507372f0b1b963James Dong        MOV     $Symbol, $BitBuffer, LSL $BitCount
4770c1bc742181ded4930842b46e9507372f0b1b963James Dong        MVN     $Symbol, $Symbol
4780c1bc742181ded4930842b46e9507372f0b1b963James Dong        CLZ     $Symbol, $Symbol
4790c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADD     $BitCount, $BitCount, $Symbol
4800c1bc742181ded4930842b46e9507372f0b1b963James Dong        SUBS    $BitCount, $BitCount, #7        ;// length is Symbol+1
4810c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDRCSB  $T1, [$pBitStream], #1
4820c1bc742181ded4930842b46e9507372f0b1b963James Dong        ORRCS   $BitBuffer, $T1, $BitBuffer, LSL #8
4830c1bc742181ded4930842b46e9507372f0b1b963James Dong        SUBCSS  $BitCount, $BitCount, #8
4840c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDRCSB  $T1, [$pBitStream], #1
4850c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADDCC   $BitCount, $BitCount, #8
4860c1bc742181ded4930842b46e9507372f0b1b963James Dong        ORRCS   $BitBuffer, $T1, $BitBuffer, LSL #8
4870c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
4880c1bc742181ded4930842b46e9507372f0b1b963James Dong
4890c1bc742181ded4930842b46e9507372f0b1b963James Dong
4900c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
4910c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Variable Length Decode module
4920c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
4930c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Decodes one VLD Symbol from a bitstream and refill the bitstream
4940c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// buffer.
4950c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
4960c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Input Registers:
4970c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
4980c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pVLDTable      - pointer to VLD decode table of 16-bit entries.
4990c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//                   The format is described above at the start of
5000c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//                   this file.
5010c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $S0             - The number of bits to look up for the first step
5020c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//                   1<=$S0<=8
5030c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $S1             - The number of bits to look up for each subsequent
5040c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//                   step 1<=$S1<=$S0.
5050c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
5060c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
5070c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
5080c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
5090c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
5100c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Output Registers:
5110c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
5120c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $Symbol         - decoded VLD symbol value
5130c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T1             - corrupted temp/scratch register
5140c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T2             - corrupted temp/scratch register
5150c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
5160c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
5170c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
5180c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
5190c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
5200c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_VLD $Symbol, $T1, $T2, $pVLDTable, $S0, $S1
5210c1bc742181ded4930842b46e9507372f0b1b963James Dong        ASSERT (1<=$S0):LAND:($S0<=8)
5220c1bc742181ded4930842b46e9507372f0b1b963James Dong        ASSERT (1<=$S1):LAND:($S1<=$S0)
5230c1bc742181ded4930842b46e9507372f0b1b963James Dong
5240c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Note 0<=BitCount<=15 on entry and exit
5250c1bc742181ded4930842b46e9507372f0b1b963James Dong
5260c1bc742181ded4930842b46e9507372f0b1b963James Dong        MOVS    $T1, $BitBuffer, LSL $BitCount       ;// left align next bits
5270c1bc742181ded4930842b46e9507372f0b1b963James Dong        MOVS    $Symbol, #(2<<$S0)-2                 ;// create mask
5280c1bc742181ded4930842b46e9507372f0b1b963James Dong        AND     $Symbol, $Symbol, $T1, LSR #(31-$S0) ;// 2*(next $S0 bits)
5290c1bc742181ded4930842b46e9507372f0b1b963James Dong        SUBS    $BitCount, $BitCount, #8             ;// CS if buffer can be filled
5300c1bc742181ded4930842b46e9507372f0b1b963James Dong01
5310c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDRCSB  $T1, [$pBitStream], #1               ;// load refill byte
5320c1bc742181ded4930842b46e9507372f0b1b963James Dong        LDRH    $Symbol, [$pVLDTable, $Symbol]       ;// load table entry
5330c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADDCC   $BitCount, $BitCount, #8             ;// refill not possible
5340c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADD     $BitCount, $BitCount, #$S0           ;// assume $S0 bits used
5350c1bc742181ded4930842b46e9507372f0b1b963James Dong        ORRCS   $BitBuffer, $T1, $BitBuffer, LSL #8  ;// merge in refill byte
5360c1bc742181ded4930842b46e9507372f0b1b963James Dong        MOVS    $T1, $Symbol, LSR #1                 ;// CS=leaf entry
5370c1bc742181ded4930842b46e9507372f0b1b963James Dong        BCS     %FT02
5380c1bc742181ded4930842b46e9507372f0b1b963James Dong
5390c1bc742181ded4930842b46e9507372f0b1b963James Dong        MOVS    $T1, $BitBuffer, LSL $BitCount       ;// left align next bit
5400c1bc742181ded4930842b46e9507372f0b1b963James Dong        IF (2*$S0-$S1<=8)
5410c1bc742181ded4930842b46e9507372f0b1b963James Dong            ;// Can combine refill check and -S0+S1 and keep $BitCount<=15
5420c1bc742181ded4930842b46e9507372f0b1b963James Dong            SUBS    $BitCount, $BitCount, #8+($S0-$S1)
5430c1bc742181ded4930842b46e9507372f0b1b963James Dong        ELSE
5440c1bc742181ded4930842b46e9507372f0b1b963James Dong            ;// Separate refill check and -S0+S1 offset
5450c1bc742181ded4930842b46e9507372f0b1b963James Dong            SUBS  $BitCount, $BitCount, #8
5460c1bc742181ded4930842b46e9507372f0b1b963James Dong            SUB   $BitCount, $BitCount, #($S0-$S1)
5470c1bc742181ded4930842b46e9507372f0b1b963James Dong        ENDIF
5480c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADD     $Symbol, $Symbol, $T1, LSR #(31-$S1) ;// add 2*(next $S1 bits) to
5490c1bc742181ded4930842b46e9507372f0b1b963James Dong        BIC     $Symbol, $Symbol, #1                 ;//   table offset
5500c1bc742181ded4930842b46e9507372f0b1b963James Dong        B       %BT01                                ;// load next table entry
5510c1bc742181ded4930842b46e9507372f0b1b963James Dong02
5520c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// BitCount range now depend on the route here
5530c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// if (first step)       S0 <= BitCount <= 7+S0        <=15
5540c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// else if (2*S0-S1<=8)  S0 <= BitCount <= 7+(2*S0-S1) <=15
5550c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// else                  S1 <= BitCount <= 7+S1        <=15
5560c1bc742181ded4930842b46e9507372f0b1b963James Dong
5570c1bc742181ded4930842b46e9507372f0b1b963James Dong        SUB     $BitCount, $BitCount, $Symbol, LSR#13
5580c1bc742181ded4930842b46e9507372f0b1b963James Dong        BIC     $Symbol, $T1, #0xF000
5590c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
5600c1bc742181ded4930842b46e9507372f0b1b963James Dong
5610c1bc742181ded4930842b46e9507372f0b1b963James Dong
5620c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Add an offset number of bits
5630c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
5640c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Outputs destination byte and bit index values which corresponds to an offset number of bits
5650c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// from the current location. This is used to compare bitstream positions using. M_BD_CMP.
5660c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
5670c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Input Registers:
5680c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
5690c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $Offset         - Offset to be added in bits.
5700c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
5710c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
5720c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
5730c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
5740c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Output Registers:
5750c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
5760c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $ByteIndex      - Destination pBitStream pointer after adding the Offset.
5770c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//                   This value will be 4 byte ahead and needs to subtract by 4 to get exact
5780c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//                   pointer (as in M_BD_FINI). But for using with M_BD_CMP subtract is not needed.
5790c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitIndex       - Destination BitCount after the addition of Offset number of bits
5800c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
5810c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
5820c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_ADD  $ByteIndex, $BitIndex, $Offset
5830c1bc742181ded4930842b46e9507372f0b1b963James Dong
5840c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// ($ByteIndex,$BitIndex) = Current position + $Offset bits
5850c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADD     $Offset, $Offset, $BitCount
5860c1bc742181ded4930842b46e9507372f0b1b963James Dong        AND     $BitIndex, $Offset, #7
5870c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADD     $ByteIndex, $pBitStream, $Offset, ASR #3
5880c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
5890c1bc742181ded4930842b46e9507372f0b1b963James Dong
5900c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Move bitstream pointers to the location given
5910c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
5920c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Outputs destination byte and bit index values which corresponds to
5930c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// the current location given (calculated using M_BD_ADD).
5940c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
5950c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Input Registers:
5960c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
5970c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
5980c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
5990c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
6000c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $ByteIndex      - Destination pBitStream pointer after move.
6010c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//                   This value will be 4 byte ahead and needs to subtract by 4 to get exact
6020c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//                   pointer (as in M_BD_FINI).
6030c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitIndex       - Destination BitCount after the move
6040c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
6050c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Output Registers:
6060c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
6070c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
6080c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//                  } See description above.
6090c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
6100c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
6110c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
6120c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_MOV  $ByteIndex, $BitIndex
6130c1bc742181ded4930842b46e9507372f0b1b963James Dong
6140c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// ($pBitStream, $Offset) = ($ByteIndex,$BitIndex)
6150c1bc742181ded4930842b46e9507372f0b1b963James Dong        MOV     $BitCount, $BitIndex
6160c1bc742181ded4930842b46e9507372f0b1b963James Dong        MOV     $pBitStream, $ByteIndex
6170c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
6180c1bc742181ded4930842b46e9507372f0b1b963James Dong
6190c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Bitstream Compare
6200c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
6210c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Compares bitstream position with that of a destination position. Destination position
6220c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// is held in two input registers which are calculated using M_BD_ADD macro
6230c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
6240c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Input Registers:
6250c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
6260c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $ByteIndex      - Destination pBitStream pointer, (4 byte ahead as described in M_BD_ADD)
6270c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitIndex       - Destination BitCount
6280c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
6290c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
6300c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
6310c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
6320c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Output Registers:
6330c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
6340c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// FLAGS           - GE if destination is reached, LT = is destination is ahead
6350c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $T1             - corrupted temp/scratch register
6360c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
6370c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
6380c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_CMP  $ByteIndex, $BitIndex, $T1
6390c1bc742181ded4930842b46e9507372f0b1b963James Dong
6400c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Return flags set by (current positon)-($ByteIndex,$BitIndex)
6410c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// so GE means that we have reached the indicated position
6420c1bc742181ded4930842b46e9507372f0b1b963James Dong
6430c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADD         $T1, $pBitStream, $BitCount, LSR #3
6440c1bc742181ded4930842b46e9507372f0b1b963James Dong        CMP         $T1, $ByteIndex
6450c1bc742181ded4930842b46e9507372f0b1b963James Dong        AND         $T1, $BitCount, #7
6460c1bc742181ded4930842b46e9507372f0b1b963James Dong        CMPEQ       $T1, $BitIndex
6470c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
6480c1bc742181ded4930842b46e9507372f0b1b963James Dong
6490c1bc742181ded4930842b46e9507372f0b1b963James Dong
6500c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Bitstream Decode finalise
6510c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
6520c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Writes back the bitstream state to the bitstream pointers
6530c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
6540c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Input Registers:
6550c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
6560c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
6570c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } See description above.
6580c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
6590c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
6600c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Output Registers:
6610c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
6620c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $ppBitStream    - pointer to pointer to the next bitstream byte
6630c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitOffset     - pointer to the number of bits used in the current byte (0..7)
6640c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $pBitStream     \
6650c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitBuffer       } these register are corrupted
6660c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// $BitCount       /
6670c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;//
6680c1bc742181ded4930842b46e9507372f0b1b963James Dong        MACRO
6690c1bc742181ded4930842b46e9507372f0b1b963James Dong        M_BD_FINI  $ppBitStream, $pBitOffset
6700c1bc742181ded4930842b46e9507372f0b1b963James Dong
6710c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Advance pointer by the number of free bits in the buffer
6720c1bc742181ded4930842b46e9507372f0b1b963James Dong        ADD     $pBitStream, $pBitStream, $BitCount, LSR#3
6730c1bc742181ded4930842b46e9507372f0b1b963James Dong        AND     $BitCount, $BitCount, #7
6740c1bc742181ded4930842b46e9507372f0b1b963James Dong
6750c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Now move back 32 bits to reach the first usued bit
6760c1bc742181ded4930842b46e9507372f0b1b963James Dong        SUB     $pBitStream, $pBitStream, #4
6770c1bc742181ded4930842b46e9507372f0b1b963James Dong
6780c1bc742181ded4930842b46e9507372f0b1b963James Dong        ;// Store out bitstream state
6790c1bc742181ded4930842b46e9507372f0b1b963James Dong        STR     $BitCount, [$pBitOffset]
6800c1bc742181ded4930842b46e9507372f0b1b963James Dong        STR     $pBitStream, [$ppBitStream]
6810c1bc742181ded4930842b46e9507372f0b1b963James Dong        MEND
6820c1bc742181ded4930842b46e9507372f0b1b963James Dong
6830c1bc742181ded4930842b46e9507372f0b1b963James Dong        END
68478e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar
685