Inst_SOPK__S_SETREG_B32::Inst_SOPK__S_SETREG_B32(InFmt_SOPK *iFmt)
: Inst_SOPK(iFmt, "s_setreg_b32")
{
+ setFlag(ALU);
} // Inst_SOPK__S_SETREG_B32
Inst_SOPK__S_SETREG_B32::~Inst_SOPK__S_SETREG_B32()
void
Inst_SOPK__S_SETREG_B32::execute(GPUDynInstPtr gpuDynInst)
{
+ ScalarRegI16 simm16 = instData.SIMM16;
+ ScalarRegU32 hwregId = simm16 & 0x3f;
+ ScalarRegU32 offset = (simm16 >> 6) & 31;
+ ScalarRegU32 size = ((simm16 >> 11) & 31) + 1;
+
+ ScalarOperandU32 hwreg(gpuDynInst, hwregId);
+ ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
+ hwreg.read();
+ sdst.read();
+
+ // Store value from SDST to part of the hardware register.
+ ScalarRegU32 mask = (((1U << size) - 1U) << offset);
+ hwreg = ((hwreg.rawData() & ~mask)
+ | ((sdst.rawData() << offset) & mask));
+ hwreg.write();
+
+ // set MODE register to control the behavior of single precision
+ // floating-point numbers: denormal mode or round mode
+ if (hwregId==1 && size==2
+ && (offset==4 || offset==0)) {
+ warn_once("Be cautious that s_setreg_b32 has no real effect "
+ "on FP modes: %s\n", gpuDynInst->disassemble());
+ return;
+ }
+
+ // panic if not changing MODE of floating-point numbers
panicUnimplemented();
}