Morphed undocumented behavior asserts into things that can be silenced.
Some instruction encoding combinations are not documented in the Cray manuals. These were asserted upon previously. This causes crashes if those instructions are encountered. Obviously not ideal for "production" code. The new behavior replaces these by the exceptions that can be supressed.
This commit is contained in:
parent
21b5680ba8
commit
2ac3afbaad
@ -453,7 +453,7 @@ template <bool aDoExecute> size_t SoftCpu_c::Decode0002(uint64_t aParcels, size_
|
||||
aExplanation << "Enable floating point exceptions";
|
||||
}
|
||||
if (aDoExecute) {
|
||||
CRAY_ASSERT(jk == 000);
|
||||
CRAY_UNDOCUMENTED_FLOW_THROUGH(jk == 000);
|
||||
mState.Mode.SetFloatingPointErrorMode(true);
|
||||
CalcInterruptMask();
|
||||
mState.Flags.ClearFloatingPointError();
|
||||
@ -495,7 +495,7 @@ template <bool aDoExecute> size_t SoftCpu_c::Decode0002(uint64_t aParcels, size_
|
||||
aExplanation << "Enable range exceptions";
|
||||
}
|
||||
if (aDoExecute) {
|
||||
CRAY_ASSERT(jk == 000);
|
||||
CRAY_UNDOCUMENTED_FLOW_THROUGH(jk == 000);
|
||||
mState.Mode.SetOperandRangeErrorMode(true);
|
||||
CalcInterruptMask();
|
||||
}
|
||||
@ -506,7 +506,7 @@ template <bool aDoExecute> size_t SoftCpu_c::Decode0002(uint64_t aParcels, size_
|
||||
aExplanation << "Disable range exceptions";
|
||||
}
|
||||
if (aDoExecute) {
|
||||
CRAY_ASSERT(jk == 000);
|
||||
CRAY_UNDOCUMENTED_FLOW_THROUGH(jk == 000);
|
||||
mState.Mode.SetOperandRangeErrorMode(false);
|
||||
CalcInterruptMask();
|
||||
}
|
||||
@ -517,7 +517,7 @@ template <bool aDoExecute> size_t SoftCpu_c::Decode0002(uint64_t aParcels, size_
|
||||
aExplanation << "Disable bidirectional memory transfers";
|
||||
}
|
||||
if (aDoExecute) {
|
||||
CRAY_ASSERT(jk == 000);
|
||||
CRAY_UNDOCUMENTED_FLOW_THROUGH(jk == 000);
|
||||
mState.Mode.SetBidirectionalMemoryMode(true);
|
||||
CalcInterruptMask();
|
||||
}
|
||||
@ -528,7 +528,7 @@ template <bool aDoExecute> size_t SoftCpu_c::Decode0002(uint64_t aParcels, size_
|
||||
aExplanation << "Enable bidirectional memory transfers";
|
||||
}
|
||||
if (aDoExecute) {
|
||||
CRAY_ASSERT(jk == 000);
|
||||
CRAY_UNDOCUMENTED_FLOW_THROUGH(jk == 000);
|
||||
mState.Mode.SetBidirectionalMemoryMode(false);
|
||||
CalcInterruptMask();
|
||||
}
|
||||
@ -627,8 +627,7 @@ template <bool aDoExecute> size_t SoftCpu_c::Decode0003(uint64_t aParcels, size_
|
||||
aDisassembly << "SM" << DecPrinter(int(jk), 0) << " 1,TS";
|
||||
aExplanation << "Test and set semaphore SM" << DecPrinter(int(jk), 0);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (mState.Cluster == 0) return 1;
|
||||
// std::unique_lock<std::mutex> Lock(mMainframe.GetCluster(mState.Cluster - 1).ClusterMutex);
|
||||
Lock_c Lock(mMainframe.GetCluster(mState.Cluster - 1).ClusterMutex);
|
||||
@ -1082,7 +1081,7 @@ template <bool aDoExecute> size_t SoftCpu_c::Decode0020(uint64_t aParcels, size_
|
||||
aDisassembly << RefAiTarget << " " << Addr(Value);
|
||||
}
|
||||
if (aDoExecute) {
|
||||
CRAY_ASSERT(jk == 000);
|
||||
CRAY_UNDOCUMENTED_FLOW_THROUGH(jk == 000);
|
||||
RefAiTarget = Value;
|
||||
}
|
||||
return 3;
|
||||
@ -1108,7 +1107,7 @@ template <bool aDoExecute> size_t SoftCpu_c::Decode0021(uint64_t aParcels, size_
|
||||
aDisassembly << RefAiTarget << " " << Addr(Value);
|
||||
}
|
||||
if (aDoExecute) {
|
||||
CRAY_ASSERT(jk == 000);
|
||||
CRAY_UNDOCUMENTED_FLOW_THROUGH(jk == 000);
|
||||
RefAiTarget = Value;
|
||||
}
|
||||
return 3;
|
||||
|
||||
@ -29,7 +29,7 @@ template <bool aDoExecute> size_t SoftCpu_c::Decode0040(uint64_t aParcels, size_
|
||||
aDisassembly << RefSiTarget << " " << HexPrinter(Value);
|
||||
}
|
||||
if (aDoExecute) {
|
||||
CRAY_ASSERT(jk == 000);
|
||||
CRAY_UNDOCUMENTED_FLOW_THROUGH(jk == 000);
|
||||
RefSiTarget = Value;
|
||||
}
|
||||
return 3;
|
||||
@ -55,7 +55,7 @@ template <bool aDoExecute> size_t SoftCpu_c::Decode0041(uint64_t aParcels, size_
|
||||
aDisassembly << RefSiTarget << " " << HexPrinter(Value);
|
||||
}
|
||||
if (aDoExecute) {
|
||||
CRAY_ASSERT(jk == 000);
|
||||
CRAY_UNDOCUMENTED_FLOW_THROUGH(jk == 000);
|
||||
RefSiTarget = Value;
|
||||
}
|
||||
return 3;
|
||||
@ -513,7 +513,7 @@ template <bool aDoExecute> size_t SoftCpu_c::Decode0070(uint64_t aParcels, size_
|
||||
aExplanation << "Transmit the bit-matrix product of (Sj ) and transpose of (BMM) to Si. *********** UNIMPLEMENTED FOR NOW ***********";
|
||||
}
|
||||
if (aDoExecute) {
|
||||
CRAY_ASSERT(mState.Mode.IsSv1BitMatrixLoaded());
|
||||
CRAY_UNDOCUMENTED_FLOW_THROUGH(mState.Mode.IsSv1BitMatrixLoaded());
|
||||
CInt_t Result = 0;
|
||||
for (int i = 0; i < mState.VL; ++i) {
|
||||
Result ^= RefSj & RefBM[i];
|
||||
|
||||
@ -26,7 +26,7 @@ template <bool aDoExecute> size_t SoftCpu_c::Decode010x(uint64_t aParcels, size_
|
||||
}
|
||||
}
|
||||
if (aDoExecute) {
|
||||
CRAY_ASSERT(IsXMode() || jk == 000);
|
||||
CRAY_UNDOCUMENTED_FLOW_THROUGH(IsXMode() || jk == 000);
|
||||
CAddr_t Addr = CAddr_t(RefAh) + Offset;
|
||||
if (IsXmp()) {
|
||||
if (!mState.XmpEnhancedAddressingMode) Addr = ApplyShortMask(CXmpAddr_t(Addr));
|
||||
@ -52,7 +52,7 @@ template <bool aDoExecute> size_t SoftCpu_c::Decode011x(uint64_t aParcels, size_
|
||||
}
|
||||
}
|
||||
if (aDoExecute) {
|
||||
CRAY_ASSERT(IsXMode() || jk == 000);
|
||||
CRAY_UNDOCUMENTED_FLOW_THROUGH(IsXMode() || jk == 000);
|
||||
CAddr_t Addr = CAddr_t(RefAh) + Offset;
|
||||
if (IsXmp()) {
|
||||
if (!mState.XmpEnhancedAddressingMode) Addr = ApplyShortMask(CXmpAddr_t(Addr));
|
||||
@ -78,7 +78,7 @@ template <bool aDoExecute> size_t SoftCpu_c::Decode012x(uint64_t aParcels, size_
|
||||
}
|
||||
}
|
||||
if (aDoExecute) {
|
||||
CRAY_ASSERT(IsXMode() || jk == 000);
|
||||
CRAY_UNDOCUMENTED_FLOW_THROUGH(IsXMode() || jk == 000);
|
||||
CAddr_t Addr = CAddr_t(RefAh) + Offset;
|
||||
if (IsXmp()) {
|
||||
if (!mState.XmpEnhancedAddressingMode) Addr = ApplyShortMask(CXmpAddr_t(Addr));
|
||||
@ -104,7 +104,7 @@ template <bool aDoExecute> size_t SoftCpu_c::Decode013x(uint64_t aParcels, size_
|
||||
}
|
||||
}
|
||||
if (aDoExecute) {
|
||||
CRAY_ASSERT(IsXMode() || jk == 000);
|
||||
CRAY_UNDOCUMENTED_FLOW_THROUGH(IsXMode() || jk == 000);
|
||||
CAddr_t Addr = CAddr_t(RefAh) + Offset;
|
||||
if (IsXmp()) {
|
||||
if (!mState.XmpEnhancedAddressingMode) Addr = ApplyShortMask(CXmpAddr_t(Addr));
|
||||
|
||||
@ -273,12 +273,15 @@ template <bool aDoExecute> size_t SoftCpu_c::Decode0152(uint64_t aParcels, size_
|
||||
}
|
||||
if (aDoExecute) {
|
||||
RefVj.LogState("input");
|
||||
CRAY_ASSERT(mState.VL != 0);
|
||||
CRAY_UNDOCUMENTED_FLOW_THROUGH(mState.VL != 0);
|
||||
CRAY_ASSERT(RefVL <= cVecSize);
|
||||
for (size_t Idx = 0; Idx < size_t(mState.VL - 1); ++Idx) {
|
||||
mState.V[i][Idx] = DoubleShiftLeft(mState.V[j][Idx], mState.V[j][Idx + 1], RefAk);
|
||||
// It is not documented what happens in VL=0. For now, we're doing a no-op
|
||||
if (mState.VL != 0) {
|
||||
for (size_t Idx = 0; Idx < size_t(mState.VL - 1); ++Idx) {
|
||||
mState.V[i][Idx] = DoubleShiftLeft(mState.V[j][Idx], mState.V[j][Idx + 1], RefAk);
|
||||
}
|
||||
mState.V[i][mState.VL - 1] = DoubleShiftLeft(mState.V[j][mState.VL - 1], CInt_t(0), RefAk);
|
||||
}
|
||||
mState.V[i][mState.VL - 1] = DoubleShiftLeft(mState.V[j][mState.VL - 1], CInt_t(0), RefAk);
|
||||
RefVi.LogState();
|
||||
mState.VectorNotUsed = false;
|
||||
}
|
||||
@ -740,7 +743,7 @@ template <bool aDoExecute> size_t SoftCpu_c::Decode0174(uint64_t aParcels, size_
|
||||
aExplanation << "Bit-matrix product";
|
||||
}
|
||||
if (aDoExecute) {
|
||||
CRAY_ASSERT(mState.Mode.IsSv1BitMatrixLoaded());
|
||||
CRAY_UNDOCUMENTED_FLOW_THROUGH(mState.Mode.IsSv1BitMatrixLoaded());
|
||||
CRAY_ASSERT(RefVL <= cVecSize);
|
||||
for (int j = 0; j < mState.VL; ++j) {
|
||||
CInt_t Result = 0;
|
||||
|
||||
@ -57,6 +57,23 @@
|
||||
} while (false);
|
||||
|
||||
|
||||
#define CRAY_UNDOCUMENTED(aCond, aRetVal) \
|
||||
do { \
|
||||
if (!(aCond)) { \
|
||||
UndocumentedInstError_x Error(__FILE__,__LINE__,#aCond); \
|
||||
if (mThrowOnUnknown) { \
|
||||
throw Error; \
|
||||
} else { \
|
||||
mLogger << setloglevel(LogLevel_Error) << Error.what() << std::endl; \
|
||||
if (aRetVal > 0) return aRetVal; \
|
||||
} \
|
||||
} \
|
||||
} while (false);
|
||||
|
||||
#define CRAY_UNDOCUMENTED_FLOW_THROUGH(aCond) CRAY_UNDOCUMENTED(aCond, 0)
|
||||
|
||||
|
||||
|
||||
inline size_t FirstParcel(uint64_t aInst) { return size_t((aInst >> 32) & 0xffff); }
|
||||
inline size_t SecondParcel(uint64_t aInst) { return size_t((aInst >> 16) & 0xffff); }
|
||||
inline size_t ThirdParcel(uint64_t aInst) { return size_t((aInst >> 0) & 0xffff); }
|
||||
@ -852,6 +869,7 @@ protected:
|
||||
struct DataWriteOutOfBoundsError_x: public Generic_x { DataWriteOutOfBoundsError_x() : Generic_x("Data write out of bounds") {} };
|
||||
struct InstDecodeError_x : public Generic_x { InstDecodeError_x() : Generic_x("Instruction decode error") {} };
|
||||
struct UnknownInstError_x : public Generic_x { UnknownInstError_x(const char *aFile, size_t aLine) : Generic_x("Unknown instruction error at") { *this << aFile << ":" << DecPrinter(aLine, 0); } };
|
||||
struct UndocumentedInstError_x : public Generic_x { UndocumentedInstError_x(const char *aFile, size_t aLine, const char *aCond) : Generic_x("Undocumented instruction behavior error at") { *this << aFile << ":" << DecPrinter(aLine, 0) << " faild condition: " << aCond; } };
|
||||
struct TerminateInstError_x : public Generic_x { TerminateInstError_x() : Generic_x("Terminate instruction executed") {} };
|
||||
struct InstExecError_x : public Generic_x { InstExecError_x() : Generic_x("Instruction execution error") {} };
|
||||
struct InstUnimplementedError_x : public Generic_x { InstUnimplementedError_x(const char *aFile, size_t aLine) { *this << "Unimplemented instruction at " << aFile << ":" << DecPrinter(aLine, 0); ResetSpacePrinted(); } };
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user