1
0
mirror of synced 2026-04-18 00:46:29 +00:00
Files
andrastantos.cray-sim/simulator/sim_lib/cray_cpu_inst_0040_0077.h
Andras Tantos e8751fb2b6 Removed assert for monitor mode-only instructions.
These instructions should simply do nothing if attempted
in user mode. Now they should.
2024-11-30 20:04:14 -08: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_ASSERT(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_ASSERT(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_ASSERT(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;
}