peepopt: Support shift amounts zero-padded from below

The `opt_expr` pass running before `peepopt` can interfere with the
detection of a shiftmul pattern due to some of the bottom bits of the
shift amount being replaced with constant zero. Extend the detection to
cover those situations as well.
This commit is contained in:
Martin Povišer 2023-08-02 16:10:27 +02:00
parent dd1a8ae49a
commit 038a5e1ed4
1 changed files with 14 additions and 3 deletions

View File

@ -8,9 +8,13 @@ match shift
filter !port(shift, \B).empty() filter !port(shift, \B).empty()
endmatch endmatch
// the right shift amount
state <SigSpec> shift_amount state <SigSpec> shift_amount
// log2 scale factor in interpreting of shift_amount
// due to zero padding on the shift cell's B port
state <int> log2scale
code shift_amount code shift_amount log2scale
shift_amount = port(shift, \B); shift_amount = port(shift, \B);
if (shift->type.in($shr) || !param(shift, \B_SIGNED).as_bool()) if (shift->type.in($shr) || !param(shift, \B_SIGNED).as_bool())
shift_amount.append(State::S0); shift_amount.append(State::S0);
@ -25,6 +29,13 @@ code shift_amount
if (shift_amount.empty()) reject; if (shift_amount.empty()) reject;
} }
log2scale = 0;
while (shift_amount[0] == State::S0) {
shift_amount.remove(0);
if (shift_amount.empty()) reject;
log2scale++;
}
if (GetSize(shift_amount) > 20) if (GetSize(shift_amount) > 20)
reject; reject;
endcode endcode
@ -41,7 +52,7 @@ match mul
filter port(mul, constport).is_fully_const() filter port(mul, constport).is_fully_const()
define <IdString> varport (constport == \A ? \B : \A) define <IdString> varport (constport == \A ? \B : \A)
set mul_const port(mul, constport).as_const() set mul_const SigSpec({port(mul, constport), SigSpec(State::S0, log2scale)}).as_const()
// get mul_din unmapped (so no `port()` shorthand) // get mul_din unmapped (so no `port()` shorthand)
// because we will be using it to set the \A port // because we will be using it to set the \A port
// on the shift cell, and we want to stay close // on the shift cell, and we want to stay close
@ -61,7 +72,7 @@ code
int factor_bits = ceil_log2(mul_const.as_int()); int factor_bits = ceil_log2(mul_const.as_int());
// make sure the multiplication never wraps around // make sure the multiplication never wraps around
if (GetSize(shift_amount) < factor_bits + GetSize(mul_din)) if (GetSize(shift_amount) + log2scale < factor_bits + GetSize(mul_din))
reject; reject;
did_something = true; did_something = true;