Add the procedural signed power function.

This patch adds the procedural power function %pow/s for signed
values. This has bit based inputs and outputs, but uses the double
pow() function to calculate the value.
This commit is contained in:
Cary R 2008-11-26 18:20:53 -08:00 committed by Stephen Williams
parent 38abe7185d
commit 6b76f76a3a
4 changed files with 39 additions and 3 deletions

View File

@ -135,6 +135,7 @@ extern bool of_NORR(vthread_t thr, vvp_code_t code);
extern bool of_OR(vthread_t thr, vvp_code_t code);
extern bool of_ORR(vthread_t thr, vvp_code_t code);
extern bool of_POW(vthread_t thr, vvp_code_t code);
extern bool of_POW_S(vthread_t thr, vvp_code_t code);
extern bool of_POW_WR(vthread_t thr, vvp_code_t code);
extern bool of_RELEASE_NET(vthread_t thr, vvp_code_t code);
extern bool of_RELEASE_REG(vthread_t thr, vvp_code_t code);

View File

@ -178,6 +178,7 @@ const static struct opcode_table_s opcode_table[] = {
{ "%or", of_OR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%or/r", of_ORR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%pow", of_POW, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%pow/s", of_POW_S, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%pow/wr", of_POW_WR, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
{ "%release/net",of_RELEASE_NET,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} },
{ "%release/reg",of_RELEASE_REG,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} },

View File

@ -653,10 +653,14 @@ and the <dst> is a writable scalar. The <dst> gets the value of the
or of all the bits of the src vector.
* %pow <bit-l>, <bit-r>
* %pow <bit-l>, <bit-r>, <wid>
* %pow/s <bit-l>, <bit-r>, <wid>
This opcode raises <bit-l> (unsigned) to the power of <bit-r> (unsigned).
The result replaces the left operand.
The %pow opcode raises <bit-l> (unsigned) to the power of <bit-r>
(unsigned) giving an exact integer result. The %pow/s opcode does
the same for signed values, except it uses the double pow() function
to calculate the result so may not produce exact results. The result
replaces the left operand.
* %pow/wr <bit-l>, <bit-r>

View File

@ -3838,6 +3838,36 @@ bool of_POW(vthread_t thr, vvp_code_t cp)
return true;
}
bool of_POW_S(vthread_t thr, vvp_code_t cp)
{
assert(cp->bit_idx[0] >= 4);
unsigned idx = cp->bit_idx[0];
unsigned idy = cp->bit_idx[1];
unsigned wid = cp->number;
vvp_vector4_t xv = vthread_bits_to_vector(thr, idx, wid);
vvp_vector4_t yv = vthread_bits_to_vector(thr, idy, wid);
/* If we have an X or Z in the arguments return X. */
if (xv.has_xz() || yv.has_xz()) {
for (unsigned jdx = 0 ; jdx < wid ; jdx += 1)
thr_put_bit(thr, cp->bit_idx[0]+jdx, BIT4_X);
return true;
}
/* Calculate the result using the double pow() function. */
double xd, yd;
vector4_to_value(xv, xd, true);
vector4_to_value(yv, yd, true);
vvp_vector4_t res = vvp_vector4_t(wid, pow(xd, yd));
/* Copy the result. */
for (unsigned jdx = 0; jdx < wid; jdx += 1)
thr_put_bit(thr, cp->bit_idx[0]+jdx, res.value(jdx));
return true;
}
bool of_POW_WR(vthread_t thr, vvp_code_t cp)
{
double l = thr->words[cp->bit_idx[0]].w_real;