mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Improvements to overflow arithmetic
This commit is contained in:
parent
eb375362a1
commit
bf97431cdb
12 changed files with 91 additions and 45 deletions
|
@ -73,7 +73,7 @@ namespace System
|
|||
}
|
||||
while (valLeft < 0)
|
||||
{
|
||||
strChars[char8Idx] = (char8)('0' - (valLeft % 10));
|
||||
strChars[char8Idx] = (char8)('0' &- (valLeft % 10));
|
||||
valLeft /= 10;
|
||||
char8Idx--;
|
||||
}
|
||||
|
|
|
@ -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--;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,7 +14539,7 @@ 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
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -564,6 +564,7 @@ class BeMCInst
|
|||
{
|
||||
public:
|
||||
BeMCInstKind mKind;
|
||||
bool mDisableShortForm;
|
||||
|
||||
BeMCOperand mResult;
|
||||
BeMCOperand mArg0;
|
||||
|
|
|
@ -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:
|
||||
|
@ -1899,6 +1911,12 @@ BfAssignmentOp Beefy::BfTokenToAssignmentOp(BfToken token)
|
|||
return BfAssignmentOp_Subtract;
|
||||
case BfToken_MultiplyEquals:
|
||||
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:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1559,16 +1559,34 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
|
|||
}
|
||||
else if (mSrc[mSrcIdx] == '+')
|
||||
{
|
||||
if (mSrc[mSrcIdx + 1] == '=')
|
||||
{
|
||||
mToken = BfToken_AndPlusEquals;
|
||||
++mSrcIdx;
|
||||
}
|
||||
else
|
||||
mToken = BfToken_AndPlus;
|
||||
mTokenEnd = ++mSrcIdx;
|
||||
}
|
||||
else if (mSrc[mSrcIdx] == '-')
|
||||
{
|
||||
if (mSrc[mSrcIdx + 1] == '=')
|
||||
{
|
||||
mToken = BfToken_AndMinusEquals;
|
||||
++mSrcIdx;
|
||||
}
|
||||
else
|
||||
mToken = BfToken_AndMinus;
|
||||
mTokenEnd = ++mSrcIdx;
|
||||
}
|
||||
else if (mSrc[mSrcIdx] == '*')
|
||||
{
|
||||
if (mSrc[mSrcIdx + 1] == '=')
|
||||
{
|
||||
mToken = BfToken_AndStarEquals;
|
||||
++mSrcIdx;
|
||||
}
|
||||
else
|
||||
mToken = BfToken_AndStar;
|
||||
mTokenEnd = ++mSrcIdx;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue