1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 12:32:20 +02:00

Improvements to overflow arithmetic

This commit is contained in:
Brian Fiete 2022-01-11 10:36:22 -05:00
parent eb375362a1
commit bf97431cdb
12 changed files with 91 additions and 45 deletions

View file

@ -73,7 +73,7 @@ namespace System
}
while (valLeft < 0)
{
strChars[char8Idx] = (char8)('0' - (valLeft % 10));
strChars[char8Idx] = (char8)('0' &- (valLeft % 10));
valLeft /= 10;
char8Idx--;
}

View file

@ -91,7 +91,7 @@ namespace System
}
while ((valLeft < 0) || (minNumeralsLeft > 0))
{
strChars[char8Idx] = (char8)('0' - (valLeft % 10));
strChars[char8Idx] = (char8)('0' &- (valLeft % 10));
valLeft /= 10;
char8Idx--;
minNumeralsLeft--;

View file

@ -80,7 +80,7 @@ namespace System
{
for (int32 i = 1; i < 56; i++)
{
SeedArray[i] -= SeedArray[1 + (i + 30) % 55];
SeedArray[i] &-= SeedArray[1 + (i + 30) % 55];
if (SeedArray[i] < 0) SeedArray[i] += MBIG;
}
}

View file

@ -129,27 +129,27 @@ namespace System.Security.Cryptography
// The MD5 transformation for all four rounds.
mixin STEP_F(var a, var b, var c, var d, var x, var t, var s)
{
a += F!(b, c, d) + x + t;
a &+= F!(b, c, d) &+ x &+ t;
a = ((a << s) | ((a & 0xffffffff) >> (32 - s)));
a += b;
a &+= b;
}
mixin STEP_G(var a, var b, var c, var d, var x, var t, var s)
{
a += G!(b, c, d) + x + t;
a &+= G!(b, c, d) &+ x &+ t;
a = ((a << s) | ((a & 0xffffffff) >> (32 - s)));
a += b;
a &+= b;
}
mixin STEP_H(var a, var b, var c, var d, var x, var t, var s)
{
a += H!(b, c, d) + x + t;
a &+= H!(b, c, d) &+ x &+ t;
a = ((a << s) | ((a & 0xffffffff) >> (32 - s)));
a += b;
a &+= b;
}
mixin STEP_I(var a, var b, var c, var d, var x, var t, var s)
{
a += I!(b, c, d) + x + t;
a &+= I!(b, c, d) &+ x &+ t;
a = ((a << s) | ((a & 0xffffffff) >> (32 - s)));
a += b;
a &+= b;
}
// SET reads 4 input bytes in little-endian byte order and stores them
@ -249,10 +249,10 @@ namespace System.Security.Cryptography
STEP_I!(c, d, a, b, GET!(2), 0x2ad7d2bb, 15);
STEP_I!(b, c, d, a, GET!(9), 0xeb86d391, 21);
a += saved_a;
b += saved_b;
c += saved_c;
d += saved_d;
a &+= saved_a;
b &+= saved_b;
c &+= saved_c;
d &+= saved_d;
ptr += 64;
}

View file

@ -142,7 +142,7 @@ namespace System.Security.Cryptography
for (i = 0, j = 0; i < 16; ++i, j += 4)
m[i] = ((uint32)mData[j] << 24) | ((uint32)mData[j + 1] << 16) | ((uint32)mData[j + 2] << 8) | ((uint32)mData[j + 3]);
for ( ; i < 64; ++i)
m[i] = SIG1!(m[i - 2]) + m[i - 7] + SIG0!(m[i - 15]) + m[i - 16];
m[i] = SIG1!(m[i - 2]) &+ m[i - 7] &+ SIG0!(m[i - 15]) &+ m[i - 16];
a = mState[0];
b = mState[1];
@ -155,26 +155,26 @@ namespace System.Security.Cryptography
for (i = 0; i < 64; ++i)
{
t1 = h + EP1!(e) + CH!(e,f,g) + k[i] + m[i];
t2 = EP0!(a) + MAJ!(a,b,c);
t1 = h &+ EP1!(e) &+ CH!(e,f,g) &+ k[i] &+ m[i];
t2 = EP0!(a) &+ MAJ!(a,b,c);
h = g;
g = f;
f = e;
e = d + t1;
e = d &+ t1;
d = c;
c = b;
b = a;
a = t1 + t2;
a = t1 &+ t2;
}
mState[0] += a;
mState[1] += b;
mState[2] += c;
mState[3] += d;
mState[4] += e;
mState[5] += f;
mState[6] += g;
mState[7] += h;
mState[0] &+= a;
mState[1] &+= b;
mState[2] &+= c;
mState[3] &+= d;
mState[4] &+= e;
mState[5] &+= f;
mState[6] &+= g;
mState[7] &+= h;
}
public void Update(Span<uint8> data)

View file

@ -397,14 +397,14 @@ namespace System
let intSize = sizeof(int);
while (charsLeft >= intSize)
{
hash = (hash ^ *((int*)curPtr)) + (hash * 16777619);
hash = (hash ^ *((int*)curPtr)) &+ (hash &* 16777619);
charsLeft -= intSize;
curPtr += intSize;
}
while (charsLeft > 1)
{
hash = ((hash ^ (int)*curPtr) << 5) - hash;
hash = ((hash ^ (int)*curPtr) << 5) &- hash;
charsLeft--;
curPtr++;
}
@ -1774,8 +1774,8 @@ namespace System
//Contract.Assert((char8A | char8B) <= 0x7F, "strings have to be ASCII");
// uppercase both chars - notice that we need just one compare per char
if ((uint32)(charA - 'a') <= (uint32)('z' - 'a')) charA -= 0x20;
if ((uint32)(charB - 'a') <= (uint32)('z' - 'a')) charB -= 0x20;
if ((uint32)(charA &- 'a') <= (uint32)('z' - 'a')) charA -= 0x20;
if ((uint32)(charB &- 'a') <= (uint32)('z' - 'a')) charB -= 0x20;
//Return the (case-insensitive) difference between them.
if (charA != charB)
@ -1807,8 +1807,8 @@ namespace System
//Contract.Assert((char8A | char8B) <= 0x7F, "strings have to be ASCII");
// uppercase both chars - notice that we need just one compare per char
if ((uint32)(charA - 'a') <= (uint32)('z' - 'a')) charA -= 0x20;
if ((uint32)(charB - 'a') <= (uint32)('z' - 'a')) charB -= 0x20;
if ((uint32)(charA &- 'a') <= (uint32)('z' - 'a')) charA -= 0x20;
if ((uint32)(charB &- 'a') <= (uint32)('z' - 'a')) charB -= 0x20;
//Return the (case-insensitive) difference between them.
if (charA != charB)
@ -1835,8 +1835,8 @@ namespace System
//Contract.Assert((char8A | char8B) <= 0x7F, "strings have to be ASCII");
// uppercase both chars - notice that we need just one compare per char
if ((uint32)(charA - 'a') <= (uint32)('z' - 'a')) charA -= 0x20;
if ((uint32)(charB - 'a') <= (uint32)('z' - 'a')) charB -= 0x20;
if ((uint32)(charA &- 'a') <= (uint32)('z' - 'a')) charA -= 0x20;
if ((uint32)(charB &- 'a') <= (uint32)('z' - 'a')) charB -= 0x20;
//Return the (case-insensitive) difference between them.
if (charA != charB)

View file

@ -9226,7 +9226,7 @@ bool BeMCContext::DoLegalization()
else
{
bool addCanBeLEA =
((inst->mKind == BeMCInstKind_Sub) || (inst->mKind == BeMCInstKind_Add)) &&
((inst->mKind == BeMCInstKind_Sub) || (inst->mKind == BeMCInstKind_Add)) && (!inst->mDisableShortForm) &&
(arg0Type->mSize >= 2) && // Int8s don't have an LEA
(GetFixedOperand(inst->mResult).IsNativeReg()) && (arg0.IsNativeReg()) && (arg1.IsImmediateInt());
@ -10209,7 +10209,7 @@ bool BeMCContext::DoLegalization()
handled = true;
}
if (handled)
if (!handled)
{
if (inst->mResult)
{
@ -14338,6 +14338,7 @@ void BeMCContext::DoCodeEmission()
{
if ((inst->mResult) && (inst->mResult != inst->mArg0))
{
BF_ASSERT(!inst->mDisableShortForm);
BF_ASSERT(inst->mResult.IsNativeReg());
BF_ASSERT(inst->mArg0.IsNativeReg());
BF_ASSERT(inst->mArg1.IsImmediate());
@ -14538,9 +14539,9 @@ void BeMCContext::DoCodeEmission()
if (result)
{
BF_ASSERT(inst->mArg1.IsImmediate());
if ((inst->mArg0.IsNativeReg()) &&
if ((inst->mArg0.IsNativeReg()) && (!inst->mDisableShortForm) &&
((inst->mArg1.mImmediate == 2) || (inst->mArg1.mImmediate == 4) || (inst->mArg1.mImmediate == 8)))
{
{
// LEA form
auto resultType = GetType(inst->mArg0);
if (resultType->mTypeCode != BeTypeCode_Int8)
@ -16030,6 +16031,7 @@ BeMCOperand BeMCContext::AllocBinaryOp(BeMCInstKind instKind, const BeMCOperand&
if (overflowCheckKind != BeMCOverflowCheckKind_None)
{
mcInst->mDisableShortForm = true;
AllocInst(BeMCInstKind_CondBr, BeMCOperand::FromImmediate(1), BeMCOperand::FromCmpKind((overflowCheckKind == BeMCOverflowCheckKind_B) ? BeCmpKind_NB : BeCmpKind_NO));
AllocInst(BeMCInstKind_DbgBreak);
}

View file

@ -564,6 +564,7 @@ class BeMCInst
{
public:
BeMCInstKind mKind;
bool mDisableShortForm;
BeMCOperand mResult;
BeMCOperand mArg0;

View file

@ -1513,6 +1513,12 @@ const char* Beefy::BfTokenToString(BfToken token)
return "&+";
case BfToken_AndStar:
return "&*";
case BfToken_AndMinusEquals:
return "&-=";
case BfToken_AndPlusEquals:
return "&+=";
case BfToken_AndStarEquals:
return "&*=";
case BfToken_OrEquals:
return "|=";
case BfToken_XorEquals:
@ -1620,6 +1626,12 @@ BfBinaryOp Beefy::BfAssignOpToBinaryOp(BfAssignmentOp assignmentOp)
return BfBinaryOp_Multiply;
case BfAssignmentOp_Divide:
return BfBinaryOp_Divide;
case BfAssignmentOp_OverflowAdd:
return BfBinaryOp_OverflowAdd;
case BfAssignmentOp_OverflowSubtract:
return BfBinaryOp_OverflowSubtract;
case BfAssignmentOp_OverflowMultiply:
return BfBinaryOp_OverflowMultiply;
case BfAssignmentOp_Modulus:
return BfBinaryOp_Modulus;
case BfAssignmentOp_ShiftLeft:
@ -1898,7 +1910,13 @@ BfAssignmentOp Beefy::BfTokenToAssignmentOp(BfToken token)
case BfToken_MinusEquals:
return BfAssignmentOp_Subtract;
case BfToken_MultiplyEquals:
return BfAssignmentOp_Multiply;
return BfAssignmentOp_Multiply;
case BfToken_AndPlusEquals:
return BfAssignmentOp_OverflowAdd;
case BfToken_AndMinusEquals:
return BfAssignmentOp_OverflowSubtract;
case BfToken_AndStarEquals:
return BfAssignmentOp_OverflowMultiply;
case BfToken_DivideEquals:
return BfAssignmentOp_Divide;
case BfToken_ModulusEquals:

View file

@ -205,7 +205,6 @@ enum BfToken : uint8
BfToken_PlusEquals,
BfToken_MinusEquals,
BfToken_MultiplyEquals,
BfToken_DivideEquals,
BfToken_ModulusEquals,
BfToken_ShiftLeftEquals,
@ -214,6 +213,9 @@ enum BfToken : uint8
BfToken_AndMinus,
BfToken_AndPlus,
BfToken_AndStar,
BfToken_AndMinusEquals,
BfToken_AndPlusEquals,
BfToken_AndStarEquals,
BfToken_OrEquals,
BfToken_XorEquals,
BfToken_NullCoalsceEquals,
@ -1843,6 +1845,9 @@ enum BfAssignmentOp
BfAssignmentOp_Add,
BfAssignmentOp_Subtract,
BfAssignmentOp_Multiply,
BfAssignmentOp_OverflowAdd,
BfAssignmentOp_OverflowSubtract,
BfAssignmentOp_OverflowMultiply,
BfAssignmentOp_Divide,
BfAssignmentOp_Modulus,
BfAssignmentOp_ShiftLeft,

View file

@ -22667,6 +22667,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
auto _GetOverflowKind = [&](bool wantOverflow)
{
if (resultType->IsFloat())
return BfOverflowCheckKind_None;
if (!wantOverflow)
return BfOverflowCheckKind_None;
if (mModule->GetDefaultCheckedKind() != BfCheckedKind_Checked)

View file

@ -1559,17 +1559,35 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
}
else if (mSrc[mSrcIdx] == '+')
{
mToken = BfToken_AndPlus;
if (mSrc[mSrcIdx + 1] == '=')
{
mToken = BfToken_AndPlusEquals;
++mSrcIdx;
}
else
mToken = BfToken_AndPlus;
mTokenEnd = ++mSrcIdx;
}
else if (mSrc[mSrcIdx] == '-')
{
mToken = BfToken_AndMinus;
if (mSrc[mSrcIdx + 1] == '=')
{
mToken = BfToken_AndMinusEquals;
++mSrcIdx;
}
else
mToken = BfToken_AndMinus;
mTokenEnd = ++mSrcIdx;
}
else if (mSrc[mSrcIdx] == '*')
{
mToken = BfToken_AndStar;
if (mSrc[mSrcIdx + 1] == '=')
{
mToken = BfToken_AndStarEquals;
++mSrcIdx;
}
else
mToken = BfToken_AndStar;
mTokenEnd = ++mSrcIdx;
}
else