Skip to content

Commit

Permalink
C: fixed-point analysis now tracks exponent of LSB rather than MSB
Browse files Browse the repository at this point in the history
This is in preparation for working with different word sizes in same
model. Would also allow the whole runtime to be compiled for a different
word size.
  • Loading branch information
frothga committed May 13, 2024
1 parent 634f8dd commit 191f348
Show file tree
Hide file tree
Showing 63 changed files with 715 additions and 573 deletions.
92 changes: 49 additions & 43 deletions N2A/src/gov/sandia/n2a/backend/c/JobC.java

Large diffs are not rendered by default.

7 changes: 3 additions & 4 deletions N2A/src/gov/sandia/n2a/backend/c/RendererC.java
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,7 @@ public boolean render (Operator op)
}
else if (useExponent)
{
int shiftX = Operator.MSB - y.exponent;
int x = shiftX >= 0 ? 0x1 << shiftX : 0;
int x = y.exponent >= 0 ? 0x1 << y.exponent : 0;
result.append (", " + x);
}
}
Expand Down Expand Up @@ -249,14 +248,14 @@ else if (useExponent)
if (op instanceof Draw3D)
{
boolean needModel = ((Draw3D) d).needModelMatrix ();
int exponentP = Operator.MSB;
int exponentP = 0;
if (useExponent)
{
// position and model matrix share same exponent
Operator model = d.getKeyword ("model");
if (model != null) exponentP = model.exponentNext;
else if (d.operands.length > 1) exponentP = d.operands[1].exponentNext;
// else model has been initialized to identity, presumably integer 1. Operator.MSB set above is suitable default.
// else model has been initialized to identity, presumably integer 1. Zero set above is suitable default.
}

result.append (d.name + "->" + op + " (" + job.SIMULATOR + "currentEvent->t, material");
Expand Down
38 changes: 17 additions & 21 deletions N2A/src/gov/sandia/n2a/backend/c/RendererCfp.java
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,8 @@ public boolean render (Operator op)
OperatorBinary b = (OperatorBinary) op;

// Explanation of shift -- The exponent of the result will be the sum of the exponents
// of the two operands. That new exponent will be associated with bit position 2*MSB.
// We want the exponent at bit position MSB.
int exponentRaw = b.operand0.exponentNext + b.operand1.exponentNext - Operator.MSB; // Exponent at MSB position after a direct integer multiply.
// of the two operands.
int exponentRaw = b.operand0.exponentNext + b.operand1.exponentNext; // Exponent at LSB position after a direct integer multiply.
int shift = exponentRaw - b.exponentNext;

if (shift == 0)
Expand Down Expand Up @@ -266,8 +265,8 @@ public boolean render (Operator op)
// Explanation of shift -- In a division, the quotient is effectively down-shifted by
// the number of bits in the denominator, and its exponent is the difference between
// the exponents of the numerator and denominator. In A/B, exponentA-exponentB will
// be the exponent at bit position 0. We want the exponent at bit position MSB.
int exponentRaw = d.operand0.exponentNext - d.operand1.exponentNext + Operator.MSB; // Exponent in MSB from a direct integer division.
// be the exponent at bit position 0.
int exponentRaw = d.operand0.exponentNext - d.operand1.exponentNext; // Exponent in LSB from a direct integer division.
int shift = exponentRaw - d.exponentNext;

if (shift == 0)
Expand Down Expand Up @@ -395,22 +394,21 @@ public boolean render (Operator op)
{
Ceil c = (Ceil) op;
Operator a = c.operands[0];
if (a.exponent >= Operator.MSB) // LSB is above decimal, so ceil() operation is impossible. This test must be on a.exponent rather than a.exponentNext because ...
if (a.exponent >= 0) // LSB is above decimal, so ceil() operation is impossible. This test must be on a.exponent rather than a.exponentNext because ...
{
// a.exponentNext has been set to f.exponentNext by Round.determineExponentNextStatic(),
// so no shift is necessary.
a.render (this);
}
else // a.exponentNext is in [0, MSB), as enforced by Round.determineExponentNextStatic()
else // a.exponentNext is in [-MSB, -1], as enforced by Round.determineExponentNextStatic()
{
// Create a mask for bits below the decimal point.
// When this mask is added to the number, it will add 1 to the first bit position
// above the decimal if any bit is set under the mask. Afterward, used AND to remove
// any residual bits below the decimal.
// This works for both positive and negative numbers.
int shift = a.exponentNext - c.exponentNext;
int decimalPlaces = Operator.MSB - a.exponentNext;
int wholeMask = 0xFFFFFFFF << decimalPlaces;
int wholeMask = 0xFFFFFFFF << -a.exponentNext;
int decimalMask = ~wholeMask;

if (shift != 0) result.append ("(");
Expand Down Expand Up @@ -456,8 +454,7 @@ public boolean render (Operator op)
if (op.parent == null || op.parent instanceof OperatorLogicalInput) return super.render (op);

Event e = (Event) op;
int exponentRaw = Operator.MSB - e.eventType.valueIndex;
int shift = exponentRaw - e.exponentNext;
int shift = -e.eventType.valueIndex - e.exponentNext;

if (shift != 0) result.append ("(");
result.append ("(flags & (" + bed.localFlagType + ") 0x1 << " + e.eventType.valueIndex + ")");
Expand All @@ -473,16 +470,15 @@ public boolean render (Operator op)
// See Ceil above for similar code.
Floor f = (Floor) op;
Operator a = f.operands[0];
if (a.exponent >= Operator.MSB)
if (a.exponent >= 0)
{
a.render (this);
}
else
{
// Mask off bits below the decimal point. This works for both positive and negative numbers.
int shift = a.exponentNext - f.exponentNext;
int decimalPlaces = Operator.MSB - a.exponentNext;
int wholeMask = 0xFFFFFFFF << decimalPlaces;
int wholeMask = 0xFFFFFFFF << -a.exponentNext;

if (shift != 0) result.append ("(");
result.append ("(");
Expand Down Expand Up @@ -528,14 +524,14 @@ public boolean render (Operator op)
// See Ceil above for similar code.
Round r = (Round) op;
Operator a = r.operands[0];
if (a.exponent >= Operator.MSB)
if (a.exponent >= 0)
{
a.render (this);
}
else // a.exponentNext in [0, MSB)
else // a.exponentNext in [-MSB, -1]
{
int shift = a.exponentNext - r.exponentNext;
int decimalPlaces = Operator.MSB - a.exponentNext;
int decimalPlaces = -a.exponentNext;
int mask = 0xFFFFFFFF << decimalPlaces;
int half = 0x1 << decimalPlaces - 1;

Expand All @@ -555,7 +551,7 @@ public boolean render (Operator op)
{
Signum s = (Signum) op;
Operator a = s.operands[0];
int one = 0x1 << Operator.MSB - s.exponentNext;
int one = 0x1 << -s.exponentNext;
boolean needParens = a.precedence () >= new LT ().precedence ();
if (needParens) result.append ("(");
a.render (this);
Expand Down Expand Up @@ -609,14 +605,14 @@ public boolean provides64bit (Operator op)
if (op instanceof Multiply)
{
OperatorBinary b = (OperatorBinary) op;
int exponentRaw = b.operand0.exponentNext + b.operand1.exponentNext - Operator.MSB;
int exponentRaw = b.operand0.exponentNext + b.operand1.exponentNext;
int shift = exponentRaw - b.exponentNext;
return shift < 0; // only use 64-bit when we downshift the raw result
}
if (op instanceof Divide)
{
OperatorBinary b = (OperatorBinary) op;
int exponentRaw = b.operand0.exponentNext - b.operand1.exponentNext + Operator.MSB;
int exponentRaw = b.operand0.exponentNext - b.operand1.exponentNext;
int shift = exponentRaw - b.exponentNext;
return shift > 0; // only use 64-bit when we upshift the raw result
}
Expand Down Expand Up @@ -665,7 +661,7 @@ public String print (double d, int exponent)
bits |= 0x10000000000000l; // set implied msb of mantissa (bit 52) to 1
bits &= 0x1FFFFFFFFFFFFFl; // clear sign and exponent bits
if (negate) bits = -bits;
bits >>= 52 - Operator.MSB + exponent - e;
bits >>= 52 + exponent - e;
return Integer.toString ((int) bits);
}
}
Loading

0 comments on commit 191f348

Please sign in to comment.