1
0
mirror of synced 2026-03-06 10:53:21 +00:00
Files
andrastantos.cray-sim/simulator/sim_lib/cray_cpu_inst_0040_0077.h
Andras Tantos 2ac3afbaad 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.
2025-02-17 22:30:44 +00:00

862 lines
28 KiB
C++

// Cray-1S CPU simulator class
// !!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!
// !!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!
//
// To be true to the documentation, octal numbers are extensively used in this file.
// Watch out for the leading 0-s!
//
// !!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!
// !!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!
template <bool aDoExecute> size_t SoftCpu_c::Decode0040(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0040);
// Si exp
if (IsXMode()) {
CInt_t Value = CInt_t(jkm);
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << HexPrinter(Value);
}
if (aDoExecute) {
RefSiTarget = Value;
}
return 2;
}
else {
CInt_t Value = CInt_t(mn);
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << HexPrinter(Value);
}
if (aDoExecute) {
CRAY_UNDOCUMENTED_FLOW_THROUGH(jk == 000);
RefSiTarget = Value;
}
return 3;
}
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0041(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0041);
// Si -exp
if (IsXMode()) {
CInt_t Value = ~CInt_t(jkm);
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << HexPrinter(Value);
}
if (aDoExecute) {
RefSiTarget = Value;
}
return 2;
}
else {
CInt_t Value = ~CInt_t(mn);
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << HexPrinter(Value);
}
if (aDoExecute) {
CRAY_UNDOCUMENTED_FLOW_THROUGH(jk == 000);
RefSiTarget = Value;
}
return 3;
}
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0042(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0042);
// Si <exp
if (!aDoExecute) {
switch (jk) {
case 077:
aDisassembly << RefSiTarget << " 1";
break;
case 000:
aDisassembly << RefSiTarget << " -1";
break;
default:
aDisassembly << RefSiTarget << " <" << 64 - jk;
aExplanation << "form " << 64 - jk << " ones from right";
break;
}
}
if (aDoExecute) {
RefSi = (0xffffffffffffffffULL) >> (jk);
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0043(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0043);
// Si >exp
if (!aDoExecute) {
switch (jk) {
case 000:
aDisassembly << RefSiTarget << " 0";
break;
default:
aDisassembly << RefSiTarget << " >" << jk;
aExplanation << "form " << jk << " ones from left";
break;
}
}
if (aDoExecute) {
if (jk == 0) {
RefSi = 0;
}
else {
RefSi = (0xffffffffffffffffULL) << (64 - jk);
}
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0044(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0044);
// Si Sj&Sk
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << RefSj << "&" << RefSk;
}
if (aDoExecute) {
RefSi = RefSj & RefSk;
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0045(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0045);
// Si #Sk&Sj
if (!aDoExecute) {
aDisassembly << RefSiTarget << " #" << RefSk << "&" << RefSj;
aExplanation << RefSiTarget << " not(" << RefSk << ") and (" << RefSj << ")";
}
if (aDoExecute) {
RefSi = RefSj & ~RefSk;
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0046(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0046);
// Si Sj\Sk (xor)
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << RefSj << "\\" << RefSk;
aExplanation << RefSiTarget << " " << RefSj << " xor " << RefSk;
}
if (aDoExecute) {
RefSi = RefSj ^ RefSk;
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0047(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0047);
// Si #Sj\Sk (xnor)
if (!aDoExecute) {
aDisassembly << RefSiTarget << " #" << RefSj << "\\" << RefSk;
aExplanation << RefSiTarget << " not(" << RefSj << ") xor " << RefSk;
}
if (aDoExecute) {
RefSi = ~RefSj ^ RefSk;
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0050(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0050);
// Si Sj!Si&Sk (scalar merge)
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << RefSj << "!" << RefSi << "&" << RefSk;
aExplanation << RefSiTarget << " bit-wise " << RefSk << "==1 ? " << RefSj << ":" << RefSi;
}
if (aDoExecute) {
RefSi = (RefSj & RefSk) | (RefSi & ~RefSk);
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0051(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0051);
// Si Sj!Sk (or)
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << RefSj << "!" << RefSk;
aExplanation << RefSiTarget << " " << RefSj << " or " << RefSk;
}
if (aDoExecute) {
RefSi = RefSj | RefSk;
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0052(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0052);
// S0 Si < exp
if (!aDoExecute) {
aDisassembly << "S0 " << RefSi << " < " << jk;
}
if (aDoExecute) {
RefS0 = ShiftLeft(RefSi, CAddr_t(jk));
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0053(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0053);
// S0 Si > exp
if (!aDoExecute) {
aDisassembly << "S0 " << RefSi << " > " << 64 - jk;
}
if (aDoExecute) {
RefS0 = ShiftRight(RefSi, CAddr_t(64 - jk)); // It should be unsigned already, but just to be extra sure in case someone changes CInt_t to signed
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0054(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0054);
// Si Si < exp
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << RefSi << " < " << jk;
}
if (aDoExecute) {
RefSi = ShiftLeft(RefSi, CAddr_t(jk));
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0055(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0055);
// Si Si > exp
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << RefSi << " > " << 64 - jk;
}
if (aDoExecute) {
RefSi = ShiftRight(RefSi, CAddr_t(64 - jk)); // It should be unsigned already, but just to be extra sure in case someone changes CInt_t to signed
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0056(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0056);
// Si Si,Sj < Ak
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << RefSi << "," << RefSj << " < " << RefAk;
}
if (aDoExecute) {
RefSi = DoubleShiftLeft(RefSi, RefSj, RefAk);
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0057(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0057);
// Si Sj,Si > Ak
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << RefSj << "," << RefSi << " > " << RefAk;
}
if (aDoExecute) {
RefSi = DoubleShiftRight(RefSj, RefSi, RefAk);
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0060(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0060);
// Si Sj+Sk
if (!aDoExecute) {
if (j == 0) {
aDisassembly << RefSiTarget << " " << RefSk;
}
else {
aDisassembly << RefSiTarget << " " << RefSj << "+" << RefSk;
}
}
if (aDoExecute) {
RefSi = CInt_t(RefSj) + CInt_t(RefSk);
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0061(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0061); // Si Sj-Sk
if (!aDoExecute) {
if (j == 0) {
aDisassembly << RefSiTarget << " -" << RefSk;
}
else {
aDisassembly << RefSiTarget << " " << RefSj << "-" << RefSk;
}
}
if (aDoExecute) {
RefSi = CInt_t(RefSj) - CInt_t(RefSk);
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0062(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0062); // Si Sj+FSk
if (!aDoExecute) {
if (j == 0) {
aDisassembly << RefSiTarget << " F" << RefSk;
aExplanation << "Normalize " << RefSk;
}
else {
aDisassembly << RefSiTarget << " " << RefSj << "+F" << RefSk;
aExplanation << "floating point addition";
}
}
if (aDoExecute) {
CFloat_t J = CFloat_t(RefSj);
CFloat_t K = CFloat_t(RefSk);
CFloat_t I = J + K;
// double dI = J.ToDouble() + K.ToDouble();
// if (!TestResult(dI, I, mLogger)) {
// mLogger << setloglevel(LogLevel_Always) << "Binary input values: " << HexPrinter(J.Value) << " " << HexPrinter(K.Value) << std::endl;
// mLogger << setloglevel(LogLevel_Always) << "Floating point values: " << DoublePrinter(I) << " = " << DoublePrinter(J) << " + " << DoublePrinter(K) << std::endl;
// std::cout << "Binary input values: " << HexPrinter(J.Value) << " " << HexPrinter(K.Value) << std::endl;
// std::cout << "Floating point values: " << DoublePrinter(I) << " = " << DoublePrinter(J) << " + " << DoublePrinter(K) << std::endl;
// //CRAY_ASSERT(false);
// }
mLogger << setloglevel(LogLevel_SideEffects) << SideEffectIndent << "Floating point values: " << DoublePrinter(I) << " = " << DoublePrinter(J) << " + " << DoublePrinter(K) << std::endl;
RefSi = CInt_t(I);
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0063(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0063); // Si Sj-FSk
if (!aDoExecute) {
if (j == 0) {
aDisassembly << RefSiTarget << " -F" << RefSk;
aExplanation << "floating point subtraction";
}
else {
aDisassembly << RefSiTarget << " " << RefSj << "-F" << RefSk;
aExplanation << "floating point subtraction";
}
}
if (aDoExecute) {
CFloat_t J = CFloat_t(RefSj);
CFloat_t K = CFloat_t(RefSk);
CFloat_t I = J - K;
// double dI = J.ToDouble() - K.ToDouble();
// if (!TestResult(dI, I, mLogger)) {
// mLogger << setloglevel(LogLevel_Always) << "Binary input values: " << HexPrinter(J.Value) << " " << HexPrinter(K.Value) << std::endl;
// mLogger << setloglevel(LogLevel_Always) << "Floating point values: " << DoublePrinter(I) << " = " << DoublePrinter(J) << " - " << DoublePrinter(K) << std::endl;
// std::cout << "Binary input values: " << HexPrinter(J.Value) << " " << HexPrinter(K.Value) << std::endl;
// std::cout << "Floating point values: " << DoublePrinter(I) << " = " << DoublePrinter(J) << " - " << DoublePrinter(K) << std::endl;
// //CRAY_ASSERT(false);
// }
mLogger << setloglevel(LogLevel_SideEffects) << SideEffectIndent << "Floating point values: " << DoublePrinter(I) << " = " << DoublePrinter(J) << " - " << DoublePrinter(K) << std::endl;
RefSi = CInt_t(I);
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0064(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0064); // Si Sj*FSk
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << RefSj << "*F" << RefSk;
aExplanation << "floating point multiplication";
}
if (aDoExecute) {
CFloat_t J = CFloat_t(RefSj);
CFloat_t K = CFloat_t(RefSk);
CFloat_t I = J * K;
// {
// bool IntegerMult = (J.RawExp() == 0 && K.RawExp() == 0);
// if (IntegerMult) {
// uint64_t FractA = J.UFract();
// uint64_t FractB = K.UFract();
// if ((FractA & 0xffffffull) != 0 || (FractB & 0xffffffull) != 0) {
// DumpHistory();
// }
// }
// }
// double dI = J.ToDouble() * K.ToDouble();
// if ((J.Exp() != -CFloat_t::ExpOfs || K.Exp() != -CFloat_t::ExpOfs) && !TestResult(dI, I, mLogger)) {
// mLogger << setloglevel(LogLevel_Always) << "Binary input values: " << HexPrinter(J.Value) << " " << HexPrinter(K.Value) << std::endl;
// mLogger << setloglevel(LogLevel_Always) << "Floating point values: " << DoublePrinter(I) << " = " << DoublePrinter(J) << " H* " << DoublePrinter(K) << std::endl;
// std::cout << "Binary input values: " << HexPrinter(J.Value) << " " << HexPrinter(K.Value) << std::endl;
// std::cout << "Floating point values: " << DoublePrinter(I) << " = " << DoublePrinter(J) << " H* " << DoublePrinter(K) << std::endl;
// //CRAY_ASSERT(false);
// }
mLogger << setloglevel(LogLevel_SideEffects) << SideEffectIndent << "Floating point values: " << DoublePrinter(I) << " = " << DoublePrinter(J) << " F* " << DoublePrinter(K) << std::endl;
RefSi = CInt_t(I);
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0065(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0065); // Si Sj*HSk
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << RefSj << "*H" << RefSk;
aExplanation << "Half-precision floating point multiplication";
}
if (aDoExecute) {
CHalfFloat_t J = CHalfFloat_t(RefSj);
CHalfFloat_t K = CHalfFloat_t(RefSk);
CHalfFloat_t I = HalfPrecisionMult(J, K);
// double dI = J.ToDouble() * K.ToDouble();
// if ((J.Exp() != -CFloat_t::ExpOfs || K.Exp() != -CFloat_t::ExpOfs) && !TestResult(dI, I, mLogger)) {
// mLogger << setloglevel(LogLevel_Always) << "Binary input values: " << HexPrinter(J.Value) << " " << HexPrinter(K.Value) << std::endl;
// mLogger << setloglevel(LogLevel_Always) << "Floating point values: " << DoublePrinter(I) << " = " << DoublePrinter(J) << " H* " << DoublePrinter(K) << std::endl;
// std::cout << "Binary input values: " << HexPrinter(J.Value) << " " << HexPrinter(K.Value) << std::endl;
// std::cout << "Floating point values: " << DoublePrinter(I) << " = " << DoublePrinter(J) << " H* " << DoublePrinter(K) << std::endl;
// //CRAY_ASSERT(false);
// }
mLogger << setloglevel(LogLevel_SideEffects) << SideEffectIndent << "Floating point values: " << DoublePrinter(I) << " = " << DoublePrinter(J) << " H* " << DoublePrinter(K) << std::endl;
RefSi = CInt_t(I);
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0066(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0066); // Si Sj*RSk
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << RefSj << "*R" << RefSk;
aExplanation << "Rounded floating point multiplication";
}
if (aDoExecute) {
CFloat_t J = CFloat_t(RefSj);
CFloat_t K = CFloat_t(RefSk);
CFloat_t I = RoundedMult(J, K);
// double dI = J.ToDouble() * K.ToDouble();
// if ((J.Exp() != -CFloat_t::ExpOfs || K.Exp() != -CFloat_t::ExpOfs) && !TestResult(dI, I, mLogger)) {
// mLogger << setloglevel(LogLevel_Always) << "Binary input values: " << HexPrinter(J.Value) << " " << HexPrinter(K.Value) << std::endl;
// mLogger << setloglevel(LogLevel_Always) << "Floating point values: " << DoublePrinter(I) << " = " << DoublePrinter(J) << " R* " << DoublePrinter(K) << std::endl;
// std::cout << "Binary input values: " << HexPrinter(J.Value) << " " << HexPrinter(K.Value) << std::endl;
// std::cout << "Floating point values: " << DoublePrinter(I) << " = " << DoublePrinter(J) << " R* " << DoublePrinter(K) << std::endl;
// //CRAY_ASSERT(false);
// }
mLogger << setloglevel(LogLevel_SideEffects) << SideEffectIndent << "Floating point values: " << DoublePrinter(I) << " = " << DoublePrinter(J) << " R* " << DoublePrinter(K) << std::endl;
RefSi = CInt_t(I);
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0067(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0067); // Si Sj*ISk
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << RefSj << "*I" << RefSk;
aExplanation << "Reciprocial iteration: " << RefSiTarget << " = 2-" << RefSj << "*" << RefSk;
}
if (aDoExecute) {
CFloat_t J = CFloat_t(RefSj);
CFloat_t K = CFloat_t(RefSk);
CFloat_t I = ReciprocIterate(J, K);
// double dI = 2.0 - J.ToDouble() * K.ToDouble();
// if (!TestResult(dI, I, mLogger)) {
// mLogger << setloglevel(LogLevel_Always) << "Binary input values: " << HexPrinter(J.Value) << " " << HexPrinter(K.Value) << std::endl;
// mLogger << setloglevel(LogLevel_Always) << "Floating point values: " << DoublePrinter(I) << " = " << DoublePrinter(J) << " (RI) " << DoublePrinter(K) << std::endl;
// std::cout << "Binary input values: " << HexPrinter(J.Value) << " " << HexPrinter(K.Value) << std::endl;
// std::cout << "Floating point values: " << DoublePrinter(I) << " = " << DoublePrinter(J) << " (RI) " << DoublePrinter(K) << std::endl;
// //CRAY_ASSERT(false);
// }
mLogger << setloglevel(LogLevel_SideEffects) << SideEffectIndent << "Floating point values: " << DoublePrinter(I) << " = " << DoublePrinter(J) << " (RI) " << DoublePrinter(K) << std::endl;
RefSi = CInt_t(I);
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0070(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0070); // Si /HSj
switch (k) {
case 0:
if (!aDoExecute) {
aDisassembly << RefSiTarget << " /H" << RefSj;
aExplanation << "Reciproc";
}
if (aDoExecute) {
CFloat_t J = CFloat_t(RefSj);
CFloat_t I = ReciprocApprox(J);
// double dI = 1.0 / J.ToDouble();
// if (!TestResult(dI, I, mLogger)) {
// mLogger << setloglevel(LogLevel_Always) << "Binary input values: " << HexPrinter(J.Value) << std::endl;
// mLogger << setloglevel(LogLevel_Always) << "Floating point values: " << DoublePrinter(I) << " = 1/" << DoublePrinter(J) << std::endl;
// std::cout << "Binary input values: " << HexPrinter(J.Value) << std::endl;
// std::cout << "Floating point values: " << DoublePrinter(I) << " = 1/" << DoublePrinter(J) << std::endl;
// //CRAY_ASSERT(false);
// }
mLogger << setloglevel(LogLevel_SideEffects) << SideEffectIndent << "Floating point values: " << I.ToDouble() << " = 1/" << J.ToDouble() << std::endl;
RefSi = CInt_t(I);
}
return 1;
case 6: // Si Sj * BT
if (IsSV1()) {
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << RefSj << " * BT";
aExplanation << "Transmit the bit-matrix product of (Sj ) and transpose of (BMM) to Si. *********** UNIMPLEMENTED FOR NOW ***********";
}
if (aDoExecute) {
CRAY_UNDOCUMENTED_FLOW_THROUGH(mState.Mode.IsSv1BitMatrixLoaded());
CInt_t Result = 0;
for (int i = 0; i < mState.VL; ++i) {
Result ^= RefSj & RefBM[i];
}
RefSiTarget = Result;
}
}
else {
CRAY_UNKNOWN
}
return 1;
default:
CRAY_UNKNOWN
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0071(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0071);
switch (j) {
case 0: // Si Ak
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << RefAk;
aExplanation << "Assign with no sign-extension";
}
if (aDoExecute) {
RefSi = CInt_t(CAddr_t(RefAk));
}
return 1;
case 1: // Si +Ak
if (!aDoExecute) {
aDisassembly << RefSiTarget << " +" << RefAk;
aExplanation << "Assign with sign-extension";
}
if (aDoExecute) {
if (IsXMode()) {
RefSi = uint64_t(SignExtendLongLong(CXmpAddr_t(RefAk)));
}
else {
RefSi = uint64_t(SignExtendLongLong(CAddr_t(RefAk)));
}
}
return 1;
case 2: // Si +FAk
if (!aDoExecute) {
aDisassembly << RefSiTarget << " +F" << RefAk;
aExplanation << "Assign as unnormalized float";
}
if (aDoExecute) {
int32_t Ak = SignExtend(RefAk);
CInt_t Result = 040060ULL << 48;
if (Ak < 0) Result |= CFloat_t::FractSignMask;
Result |= abs(Ak);
RefSiTarget = Result;
}
return 1;
case 3: // Si 0.6
if (!aDoExecute) {
aDisassembly << RefSiTarget << " 0.6";
}
if (aDoExecute) {
RefSi = 0400606000000000000000ULL;
}
return 1;
case 4: // Si 0.4
if (!aDoExecute) {
aDisassembly << RefSiTarget << " 0.4";
}
if (aDoExecute) {
RefSi = 0400004000000000000000ULL;
}
return 1;
case 5: // Si 1.0
if (!aDoExecute) {
aDisassembly << RefSiTarget << " 1.";
}
if (aDoExecute) {
RefSi = 0400014000000000000000ULL;
}
return 1;
case 6: // Si 2.0
if (!aDoExecute) {
aDisassembly << RefSiTarget << " 2.";
}
if (aDoExecute) {
RefSi = 0400024000000000000000ULL;
}
return 1;
case 7: // Si 4.0
if (!aDoExecute) {
aDisassembly << RefSiTarget << " 4.";
}
if (aDoExecute) {
RefSi = 0400034000000000000000ULL;
}
return 1;
default: CRAY_UNKNOWN
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0072(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0072);
switch (k) {
case 0: // Si RT
if (!aDoExecute) {
aDisassembly << RefSiTarget << " RT";
aExplanation << "Read the real-time-clock";
}
if (aDoExecute) {
RefSi = mMainframe.GetRealTimeClock();
aBreakBurst = true;
}
return 1;
case 2: // Si SM
if (!aDoExecute) {
aDisassembly << RefSiTarget << " SM";
aExplanation << "Read the semaphores";
}
if (aDoExecute) {
if (mState.Cluster > 0) {
uint64_t RetVal = 0;
auto &Cluster = mMainframe.GetCluster(mState.Cluster - 1);
for (int i = 0; i < 32; ++i) {
if (Cluster.SM[i].load()) RetVal |= (1ULL << 31);
RetVal <<= 1;
}
RefSi = RetVal;
aBreakBurst = true;
}
}
return 1;
case 3: // Si STj
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << RefSTj;
}
if (aDoExecute) {
if (mState.Cluster > 0) {
RefSi = RefSTj;
aBreakBurst = true;
}
}
return 1;
default: CRAY_UNKNOWN
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0073(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0073);
switch (k) {
case 0: // Si VM
if (!aDoExecute) {
aDisassembly << RefSiTarget << " VM";
aExplanation << "Read the vector-mask register";
}
if (aDoExecute) {
RefSi = RefVM;
}
return 1;
case 1: // multiple
switch (j) {
case 0: // Si SR0
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << RefSRj;
aExplanation << "See HR-0097 5-60 for bit-definitions of SR0 registers";
}
if (aDoExecute) {
if (j != 0) {
// We don't know what SRj registers are...
CRAY_UNIMPLEMENTED;
}
else {
RefSi = GetSR(0);
aBreakBurst = true;
}
}
return 1;
case 1: // Read perf counter to Si
if (!aDoExecute) {
aDisassembly << RefSiTarget << " PFPTR++";
aExplanation << "Read (high or low order bits of) performance counter into " << RefSiTarget << " than increment performance counter pointer";
}
if (aDoExecute) {
if (mState.Mode.IsMonitorMode()) {
//CRAY_UNIMPLEMENTED;
RefSi = CInt_t(0);
}
}
return 1;
case 2: // Increment perf counter
if (!aDoExecute) {
if (IsXmp()) {
aDisassembly << "PFC++";
aExplanation << "Increment the current performance counter (low or high-part) pointed by PFPTR";
}
else {
aDisassembly << "PFC++ - low";
aExplanation << "Increment the current performance counter (low-part) pointed by PFPTR";
}
}
if (aDoExecute) {
if (mState.Mode.IsMonitorMode()) {
//CRAY_UNIMPLEMENTED;
}
}
return 1;
case 3: // Clear all maintanace modes
if (!aDoExecute) {
aDisassembly << "CLM " << RefSiTarget << " -1";
aExplanation << "Clear all maintenance modes. Loads " << RefSiTarget << " with -1 as a side-effect";
}
if (aDoExecute) {
if (mState.Mode.IsMonitorMode()) {
//CRAY_UNIMPLEMENTED;
}
}
return 1;
case 4: // SIM-TO-HOST COMMUNICATION CHANNEL.
if (!aDoExecute) {
aDisassembly << "HOST_WR " << RefSi << " -1";
aExplanation << "Sends " << RefSi << " to host";
}
if (aDoExecute) {
RefSiTarget = mMainframe.SimToHost(RefSi);
}
case 5: // Gets defined in C90
CRAY_UNKNOWN;
case 6: // Increment perf counter (higher)
if (!IsXmp()) {
if (!aDoExecute) {
aDisassembly << "PFC++ - high";
aExplanation << "Increment the current performance counter (high-part) pointed by PFPTR";
}
if (aDoExecute) {
if (mState.Mode.IsMonitorMode()) {
//CRAY_UNIMPLEMENTED;
}
}
}
else CRAY_UNKNOWN
return 1;
case 7: // HOST-TO-SIM COMMUNICATION CHANNEL.
if (!aDoExecute) {
aDisassembly << "HOST_WR " << RefSiTarget << " -1";
aExplanation << "Sends " << RefSiTarget << " to host";
}
if (aDoExecute) {
RefSiTarget = mMainframe.HostToSim();
}
default: CRAY_UNKNOWN
}
return 1;
case 2: // SM Si
if (!aDoExecute) {
aDisassembly << "SM " << RefSi;
}
if (aDoExecute) {
if (mState.Cluster > 0) {
uint64_t NewVal = RefSi;
auto &Cluster = mMainframe.GetCluster(mState.Cluster - 1);
for (int i = 0; i < 32; ++i) {
Cluster.SM[i].store(GetBit(NewVal, 63 - i) != 0);
}
aBreakBurst = true;
}
}
return 1;
case 3: // STj Si
if (!aDoExecute) {
aDisassembly << RefSTjTarget << " " << RefSi;
}
if (aDoExecute) {
if (mState.Cluster > 0) {
RefSTj = RefSi;
aBreakBurst = true;
}
}
return 1;
case 5: // Multiple
if (i == 0 && j == 1) { // SPECIAL SIM OPERATION TO TERMINATE SIMULATOR
throw TerminateInstError_x();
}
else {
CRAY_UNKNOWN
}
default: CRAY_UNKNOWN
}
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0074(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0074);
// Si Tjk
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << RefTjk;
}
if (aDoExecute) {
RefSi = RefTjk;
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0075(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0075);
// Tjk Si
if (!aDoExecute) {
aDisassembly << RefTjkTarget << " " << RefSi;
}
if (aDoExecute) {
RefTjk = RefSi;
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0076(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0076);
// Si Vj,Ak
if (!aDoExecute) {
aDisassembly << RefSiTarget << " " << RefVj << "," << RefAk;
}
if (aDoExecute) {
RefSi = mState.V[j][CAddr_t(RefAk) % cVecSize];
}
return 1;
}
template <bool aDoExecute> size_t SoftCpu_c::Decode0077(uint64_t aParcels, size_t aMaxParcelCnt, std::ostream &aDisassembly, std::ostream &aExplanation, bool &aBreakBurst) {
EXTRACT_FIELDS(aParcels);
CRAY_ASSERT(gh == 0077);
// Vi,Ak Sj
if (!aDoExecute) {
aDisassembly << RefViTarget << "," << RefAk << " " << RefSj;
}
if (aDoExecute) {
mState.V[i][CAddr_t(RefAk) % cVecSize] = RefSj;
RefVi.LogState();
mState.VectorNotUsed = false;
}
return 1;
}