Optimize: u3a_malt takes care of trailing zeros.

This commit is contained in:
Benjamin Summers 2019-12-10 19:32:43 -08:00 committed by Logan Allen
parent f391a26334
commit 290bf55c45

View File

@ -15,41 +15,11 @@
(x==0) ? 0 : \ (x==0) ? 0 : \
1 + ((x - 1) / y); 1 + ((x - 1) / y);
/*
TODO Don't do the double flop.
*/
u3_noun u3qc_repn(u3_atom bits, u3_noun blox) { u3_noun u3qc_repn(u3_atom bits, u3_noun blox) {
if ( !_(u3a_is_cat(bits) || bits==0 || bits>31) ) { if ( !_(u3a_is_cat(bits) || bits==0 || bits>31) ) {
return u3m_bail(c3__fail); return u3m_bail(c3__fail);
} }
blox = u3kb_flop(blox);
//
// We need to enforce the invariant that the result does not contain
// leading (? TODO). Since each input block must be smaller than
// a word, simply stripping off leading zero blocks is enough to
// ensure this.
//
// We also verify that each input block is a direct atom.
//
while (1) {
if (blox == 0) {
return 0;
}
u3_noun blok_n = u3h(blox);
if (!_(u3a_is_cat(blok_n)))
return u3m_bail(c3__fail);
if (blok_n != 0) break;
blox = u3t(blox);
}
blox = u3kb_flop(blox);
// //
// Calculate input and output size. // Calculate input and output size.
// //
@ -77,16 +47,15 @@ u3_noun u3qc_repn(u3_atom bits, u3_noun blox) {
// once full. // once full.
// //
// acc register // acc register
// idx where the register will be flushed to
// use number of register bits filled (used) // use number of register bits filled (used)
// cur next buffer word to flush into.
// //
c3_w acc=0, idx=0, use=0; c3_w acc=0, use=0, *cur=buf;
void flush() { void flush() {
buf[idx++] = acc; *cur++ = acc;
acc = 0; acc = use = 0;
use = 0;
} }
c3_w slice(c3_w sz, c3_w off, c3_w val) { c3_w slice(c3_w sz, c3_w off, c3_w val) {
@ -94,9 +63,14 @@ u3_noun u3qc_repn(u3_atom bits, u3_noun blox) {
} }
for (c3_w i=0; i<num_blox; i++) { for (c3_w i=0; i<num_blox; i++) {
c3_w blok = u3a_h(blox); u3_noun blok_n = u3h(blox);
blox = u3t(blox); blox = u3t(blox);
if (!_(u3a_is_cat(blok_n)))
return u3m_bail(c3__fail);
c3_w blok = blok_n;
for (c3_w rem_in_blok=bits; rem_in_blok;) { for (c3_w rem_in_blok=bits; rem_in_blok;) {
c3_w rem_in_acc = 32 - use; c3_w rem_in_acc = 32 - use;
if (rem_in_blok == rem_in_acc) { // EQ if (rem_in_blok == rem_in_acc) { // EQ
@ -114,7 +88,6 @@ u3_noun u3qc_repn(u3_atom bits, u3_noun blox) {
flush(); flush();
} }
} }
} }
// //