1
0
mirror of synced 2026-01-11 23:42:44 +00:00

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:
Andras Tantos 2025-02-17 22:30:44 +00:00
parent 21b5680ba8
commit 2ac3afbaad
5 changed files with 41 additions and 21 deletions

View File

@ -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;

View File

@ -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];

View File

@ -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));

View File

@ -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;

View File

@ -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(); } };