Skip to content

Instantly share code, notes, and snippets.

@agatti
Created March 28, 2024 14:20
Show Gist options
  • Save agatti/fb4e86a6d750926c8ddbeaa1408e9704 to your computer and use it in GitHub Desktop.
Save agatti/fb4e86a6d750926c8ddbeaa1408e9704 to your computer and use it in GitHub Desktop.
/*
A0: Source buffer (word-aligned)
A1: Target buffer (byte-aligned)
A2: Samples count (in bytes)
*/
a_law_encode_buffer:
li t0, 0b0100000000000000 /* Prepare source match mask */
add t5, a0, a2 /* Prepare buffer end */
encode_a_law_sample:
lhu t2, 0(a0) /* Read sample */
li t1, 0b0000000000000111 /* Prepare target base mask */
srli t3, t2, 10 /* Relocate sign bit */
/* s1ab_cdxx_xxxx_xxxx */
and t4, t2, t0 /* Find bit */
slli t2, t2, 1 /* Prepare for next bit */
bne t4, zero, a_law_encode_sample /* Encode */
addi t1, t1, -1 /* Prepare mask for next bit */
/* s01a_bcdx_xxxx_xxxx */
and t4, t2, t0 /* Find bit */
slli t2, t2, 1 /* Prepare for next bit */
bne t4, zero, a_law_encode_sample /* Encode */
addi t1, t1, -1 /* Prepare mask for next bit */
/* s001_abcd_xxxx_xxxx */
and t4, t2, t0 /* Find bit */
slli t2, t2, 1 /* Prepare for next bit */
bne t4, zero, a_law_encode_sample /* Encode */
addi t1, t1, -1 /* Prepare mask for next bit */
/* s000_1abc_dxxx_xxxx */
and t4, t2, t0 /* Find bit */
slli t2, t2, 1 /* Prepare for next bit */
bne t4, zero, a_law_encode_sample /* Encode */
addi t1, t1, -1 /* Prepare mask for next bit */
/* s000_01ab_cdxx_xxxx */
and t4, t2, t0 /* Find bit */
slli t2, t2, 1 /* Prepare for next bit */
bne t4, zero, a_law_encode_sample /* Encode */
addi t1, t1, -1 /* Prepare mask for next bit */
/* s000_001a_bcdx_xxxx */
and t4, t2, t0 /* Find bit */
slli t2, t2, 1 /* Prepare for next bit */
bne t4, zero, a_law_encode_sample /* Encode */
addi t1, t1, -1 /* Prepare mask for next bit */
/* s000_0001_abcd_xxxx */
and t4, t2, t0 /* Find bit */
slli t2, t2, 1 /* Prepare for next bit */
bne t4, zero, a_law_encode_sample /* Encode */
addi t1, t1, -1 /* Prepare mask for next bit */
/* s000_0000_abcd_xxxx */
/*
T1: xxxx_xxxx_xxxx_xmmm (mask)
T2: xxab_cdxx_xxxx_xxxx (sample)
T3: xxxx_xxxx_xxxx_sxxx (sign)
*/
a_law_encode_sample:
slli t2, t2, 10 /* Relocate sample bits */
or t4, t3, t1 /* xxxx_smmm */
andi t2, t2, 0b00001111 /* Clean up sample bits */
slli t3, t4, 4 /* smmm_xxxx */
addi a0, a0, 2 /* Next source sample */
or t3, t2, t3 /* smmm_abcd */
addi a1, a1, 1 /* Next target sample */
xori t3, t3, 0b01010101 /* A-Law XOR mask */
/* STALL (T3) */
sb t3, -1(a1) /* Store encoded sample */
bne a0, t5, encode_a_law_sample /* Next sample */
jalr zero, ra, 0 /* Done */
/*
A0: Source buffer (byte-aligned)
A1: Target buffer (word-aligned)
A2: Samples count (in bytes)
*/
a_law_decode_buffer:
auipc t5, %pcrel_hi(a_law_decode_table) /* Load table address */
add t6, a0, a2 /* Prepare buffer end */
addi t5, t5, %pcrel_lo(a_law_decode_table) /* Fix up table address */
decode_a_law_sample:
lbu t0, 0(a0) /* Read sample */
/* STALL (T0) */
xori t1, t0, 0b01010101 /* Apply A-Law XOR mask */
/* STALL (T1) */
srli t2, t1, 4 /* Relocate table offset */
slli t3, t1, 8 /* Relocate sign bit */
add t2, t2, t5 /* Compute table offset */
/* STALL (T2) */
lw t4, (t2) /* Load decode table entry */
/* STALL (T4) */
or t3, t4, t3 /* Set mask bits */
srli t4, t4, 16 /* Load shift offset */
andi t1, t1, 0b00001111 /* Mask out offset */
/* STALL (T1) */
sll t2, t1, t4 /* Relocate sample bits */
addi a1, a1, 2 /* Prepare for next sample */
or t1, t2, t3 /* Build 16-bits sample */
addi a0, a0, 1 /* Prepare for next sample */
sh t1, -2(a1) /* Write decoded sample */
bne a0, t5, decode_a_law_sample /* Next sample */
jalr zero, ra, 0 /* Done */
a_law_decode_table:
.word 0b01000000000000001000 /* 4, s000_0000_abcd_1000 */
.word 0b01000000000100001000 /* 4, s000_0001_abcd_1000 */
.word 0b01010000001000010000 /* 5, s000_001a_bcd1_0000 */
.word 0b01100000010000100000 /* 6, s000_01ab_cd10_0000 */
.word 0b01110000100001000000 /* 7, s000_1abc_d100_0000 */
.word 0b10000001000010000000 /* 8, s001_abcd_1000_0000 */
.word 0b10010010000100000000 /* 9, s01a_bcd1_0000_0000 */
.word 0b10100100001000000000 /* 10, s1ab_cd10_0000_0000 */
/* Table is replicated to ignore sign bit when decoding. */
.word 0b01000000000000001000 /* 4, s000_0000_abcd_1000 */
.word 0b01000000000100001000 /* 4, s000_0001_abcd_1000 */
.word 0b01010000001000010000 /* 5, s000_001a_bcd1_0000 */
.word 0b01100000010000100000 /* 6, s000_01ab_cd10_0000 */
.word 0b01110000100001000000 /* 7, s000_1abc_d100_0000 */
.word 0b10000001000010000000 /* 8, s001_abcd_1000_0000 */
.word 0b10010010000100000000 /* 9, s01a_bcd1_0000_0000 */
.word 0b10100100001000000000 /* 10, s1ab_cd10_0000_0000 */
/*****************************************************************************/
/*
A0: Source buffer (word-aligned)
A1: Target buffer (byte-aligned)
A2: Samples count (in bytes)
*/
u_law_encode_buffer:
li t0, 0b0100000000000000 /* Prepare source match mask */
add t5, a0, a2 /* Prepare buffer end */
encode_u_law_sample:
lhu t2, 0(a0) /* Read sample */
li t1, 0b0000000000000111 /* Prepare target base mask */
srli t3, t2, 10 /* Relocate sign bit */
blt t2, zero, 1f /* Skip inversion if positive */
xori t2, t2, -1 /* Invert bits */
1:
/* STALL (T2) */
addi t2, t2, 33 /* Add #33 according to specs */
/* STALL (T2) */
/* s1ab_cdxx_xxxx_xxxx */
and t4, t2, t0 /* Find bit */
slli t2, t2, 1 /* Prepare for next bit */
bne t4, zero, u_law_encode_sample /* Encode */
addi t1, t1, -1 /* Prepare mask for next bit */
/* s01a_bcdx_xxxx_xxxx */
and t4, t2, t0 /* Find bit */
slli t2, t2, 1 /* Prepare for next bit */
bne t4, zero, u_law_encode_sample /* Encode */
addi t1, t1, -1 /* Prepare mask for next bit */
/* s001_abcd_xxxx_xxxx */
and t4, t2, t0 /* Find bit */
slli t2, t2, 1 /* Prepare for next bit */
bne t4, zero, u_law_encode_sample /* Encode */
addi t1, t1, -1 /* Prepare mask for next bit */
/* s000_1abc_dxxx_xxxx */
and t4, t2, t0 /* Find bit */
slli t2, t2, 1 /* Prepare for next bit */
bne t4, zero, u_law_encode_sample /* Encode */
addi t1, t1, -1 /* Prepare mask for next bit */
/* s000_01ab_cdxx_xxxx */
and t4, t2, t0 /* Find bit */
slli t2, t2, 1 /* Prepare for next bit */
bne t4, zero, u_law_encode_sample /* Encode */
addi t1, t1, -1 /* Prepare mask for next bit */
/* s000_001a_bcdx_xxxx */
and t4, t2, t0 /* Find bit */
slli t2, t2, 1 /* Prepare for next bit */
bne t4, zero, u_law_encode_sample /* Encode */
addi t1, t1, -1 /* Prepare mask for next bit */
/* s000_0001_abcd_xxxx */
and t4, t2, t0 /* Find bit */
slli t2, t2, 1 /* Prepare for next bit */
bne t4, zero, u_law_encode_sample /* Encode */
addi t1, t1, -1 /* Prepare mask for next bit */
/* s000_0000_1abcd_xxx */
/*
T1: xxxx_xxxx_xxxx_xmmm (mask)
T2: xxab_cdxx_xxxx_xxxx (sample)
T3: xxxx_xxxx_xxxx_sxxx (sign)
*/
u_law_encode_sample:
slli t2, t2, 10 /* Relocate sample bits */
or t4, t3, t1 /* xxxx_smmm */
andi t2, t2, 0b00001111 /* Clean up sample bits */
slli t3, t4, 4 /* smmm_xxxx */
addi a0, a0, 2 /* Next source sample */
or t3, t2, t3 /* smmm_abcd */
addi a1, a1, 1 /* Next target sample */
xori t3, t3, 0b11111111 /* U-Law XOR mask */
/* STALL (T3) */
sb t3, -1(a1) /* Store encoded sample */
bne a0, t5, encode_u_law_sample /* Next sample */
jalr zero, ra, 0 /* Done */
/*
A0: Source buffer (byte-aligned)
A1: Target buffer (word-aligned)
A2: Samples count (in bytes)
*/
u_law_decode_buffer:
auipc t5, %pcrel_hi(u_law_decode_table) /* Load table address */
add t6, a0, a2 /* Prepare buffer end */
addi t5, t5, %pcrel_lo(u_law_decode_table) /* Fix up table address */
decode_u_law_sample:
lbu t0, 0(a0) /* Read sample */
/* STALL (T0) */
xori t1, t0, 0b11111111 /* Apply U-Law XOR mask */
/* STALL (T1) */
addi t1, t1, -33 /* Subtract 33 with sign */
/* STALL (T1) */
blt t1, zero, 1f /* Skip inversion */
xori t2, t1, -1 /* Invert bits */
/* STALL (T2) */
1:
srli t1, t2, 4 /* Relocate table offset */
slli t3, t2, 8 /* Relocate sign bit */
add t1, t1, t5 /* Compute table offset */
/* STALL (T1) */
lw t4, (t1) /* Load decode table entry */
/* STALL (T4) */
or t3, t4, t3 /* Set mask bits */
srli t4, t4, 16 /* Load shift offset */
andi t2, t2, 0b00001111 /* Mask out offset */
/* STALL (T2) */
sll t1, t2, t4 /* Relocate sample bits */
addi a1, a1, 2 /* Prepare for next sample */
or t2, t1, t3 /* Build 16-bits sample */
addi a0, a0, 1 /* Prepare for next sample */
sh t2, -2(a1) /* Write decoded sample */
bne a0, t5, decode_u_law_sample /* Next sample */
jalr zero, ra, 0 /* Done */
u_law_decode_table:
.word 0b00110000000010000100 /* 3, s000_0000_1abc_d100 */
.word 0b01000000000100001000 /* 4, s000_0001_abcd_1000 */
.word 0b01010000001000100000 /* 5, s000_001a_bcd1_0000 */
.word 0b01100000010001000000 /* 6, s000_01ab_cd10_0000 */
.word 0b01110000100010000000 /* 7, s000_1abc_d100_0000 */
.word 0b10000001000100000000 /* 8, s001_abcd_1000_0000 */
.word 0b10010010001000000000 /* 9, s01a_bcd1_0000_0000 */
.word 0b10100100010000000000 /* 10, s1ab_cd10_0000_0000 */
/* Table is replicated to ignore sign bit when decoding. */
.word 0b00110000000010000100 /* 3, s000_0000_1abc_d100 */
.word 0b01000000000100001000 /* 4, s000_0001_abcd_1000 */
.word 0b01010000001000100000 /* 5, s000_001a_bcd1_0000 */
.word 0b01100000010001000000 /* 6, s000_01ab_cd10_0000 */
.word 0b01110000100010000000 /* 7, s000_1abc_d100_0000 */
.word 0b10000001000100000000 /* 8, s001_abcd_1000_0000 */
.word 0b10010010001000000000 /* 9, s01a_bcd1_0000_0000 */
.word 0b10100100010000000000 /* 10, s1ab_cd10_0000_0000 */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment