Created
March 28, 2024 14:20
-
-
Save agatti/fb4e86a6d750926c8ddbeaa1408e9704 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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