Newer
Older
case NN_psignd: // Packed SIGN Doubleword
case NN_pshufb: // Packed Shuffle Bytes
return this->BuildBinaryRTL(SMP_SHUFFLE);
break;
case NN_pmulhrsw: // Packed Multiply High with Round and Scale
case NN_pmaddubsw: // Multiply and Add Packed Signed and Unsigned Bytes
case NN_phsubsw: // Packed Horizontal Subtract and Saturate
case NN_phaddsw: // Packed Horizontal Add and Saturate
case NN_phaddw: // Packed Horizontal Add Word
case NN_phaddd: // Packed Horizontal Add Doubleword
case NN_phsubw: // Packed Horizontal Subtract Word
case NN_phsubd: // Packed Horizontal Subtract Doubleword
return false;
break;
case NN_palignr: // Packed Align Right
return this->BuildPackShiftRTL(SMP_CONCATENATE, SMP_REVERSE_SHIFT_U);
break;
case NN_pabsb: // Packed Absolute Value Byte
case NN_pabsw: // Packed Absolute Value Word
case NN_pabsd: // Packed Absolute Value Doubleword
return false;
break;
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
// VMX instructions
case NN_vmcall: // Call to VM Monitor
case NN_vmclear: // Clear Virtual Machine Control Structure
case NN_vmlaunch: // Launch Virtual Machine
case NN_vmresume: // Resume Virtual Machine
case NN_vmptrld: // Load Pointer to Virtual Machine Control Structure
case NN_vmptrst: // Store Pointer to Virtual Machine Control Structure
case NN_vmread: // Read Field from Virtual Machine Control Structure
case NN_vmwrite: // Write Field from Virtual Machine Control Structure
case NN_vmxoff: // Leave VMX Operation
case NN_vmxon: // Enter VMX Operation
return false;
break;
default:
msg("ERROR: Unknown instruction opcode at %x : %s\n", this->GetAddr(),
this->GetDisasm());
break;
} // end switch on opcode
return true;
} // end SMPInstr::BuildRTL()
// Iterate through all reg transfers and call SyncRTLDefUse for each.
void SMPInstr::SyncAllRTs(void) {
for (size_t index = 0; index < this->RTL.GetCount(); ++index) {
this->SyncRTLDefUse(this->RTL.GetRT(index));
}
return;
} // end of SMPInstr:SyncAllRTs()
// Ensure that each operand of the RTL is found in the appropriate DEF or USE list.
void SMPInstr::SyncRTLDefUse(SMPRegTransfer *CurrRT) {
// The Guard expression and ExtraKills are almost never represented in the DEF and USE
// lists. When they are, they are added in MDFixupDefUseLists(), so we ignore them here.
// The only DEFs should come from left operands of SMP_ASSIGN operators, i.e. the effects
// of register transfers.
op_t LeftOp, RightOp;
set<DefOrUse, LessDefUse>::iterator CurrDef, CurrUse;
bool DebugFlag = false;
#if SMP_VERBOSE_DEBUG_BUILD_RTL
DebugFlag |= (0 == strcmp("__libc_csu_fini", this->BasicBlock->GetFunc()->GetFuncName()));
#endif
if (DebugFlag) {
msg("SyncRTLDefUse entered. Dump of USE list:\n");
this->Uses.Dump();
}
LeftOp = CurrRT->GetLeftOperand();
if (SMP_ASSIGN == CurrRT->GetOperator()) {
assert(o_void != LeftOp.type);
assert(o_imm != LeftOp.type);
CurrDef = this->Defs.FindRef(LeftOp);
if (CurrDef == this->GetLastDef() && !LeftOp.is_reg(R_ip)) {
#if SMP_VERBOSE_DEBUG_BUILD_RTL
msg("WARNING: DEF not found for SMP_ASSIGN in %s ; added op:", this->GetDisasm());
PrintOperand(LeftOp);
msg("\n");
#endif
this->Defs.SetRef(LeftOp, CurrRT->GetOperatorType());
}
}
else { // not SMP_ASSIGN; left operand should be a USE
if (o_void != LeftOp.type) {
CurrUse = this->Uses.FindRef(LeftOp);
if (CurrUse == this->GetLastUse()) {
#if SMP_VERBOSE_DEBUG_BUILD_RTL_DEF_USE
msg("WARNING: USE not found for ");
PrintOperand(LeftOp);
msg(" in %s ; added\n", this->GetDisasm());
#endif
this->Uses.SetRef(LeftOp);
}
}
}
if (!CurrRT->HasRightSubTree()) {
RightOp = CurrRT->GetRightOperand(); // right operand should be a USE
if (o_void != RightOp.type) {
CurrUse = this->Uses.FindRef(RightOp);
if (CurrUse == this->GetLastUse()) {
#if SMP_VERBOSE_DEBUG_BUILD_RTL_DEF_USE
msg("WARNING: USE not found for ");
PrintOperand(RightOp);
msg(" in %s ; added\n", this->GetDisasm());
#endif
this->Uses.SetRef(RightOp);
}
}
}
else { // recurse into right subtree
this->SyncRTLDefUse(CurrRT->GetRightTree());
}
return;
} // end of SMPInstr::SyncRTLDefUse()
// SetOperatorType - set the type of the operator, take into account the speculative (profiler) status
void SMPRegTransfer::SetOperatorType(SMPOperandType OpType, const SMPInstr* Instr) {
SMPOperandType OldType = RTop.type;
SMPOperandType NewType = OpType;
if (Instr->GetBlock()->GetFunc()->GetIsSpeculative()) {
NewType = (SMPOperandType) (((int)NewType) | PROF_BASE);
if (!IsProfDerived(OldType))
RTop.NonSpeculativeType = OldType;
}
RTop.type = NewType;
} // end of SMPRegTransfer::SetOperatorType
// Update the memory source operands to have the new type
void SMPInstr::UpdateMemLoadTypes(SMPOperandType newType) {
bool MemSrc = false;
op_t Opnd;
for (int i = 0; i < UA_MAXOP; ++i) {
Opnd = this->SMPcmd.Operands[i];
optype_t CurrType = Opnd.type;
if (this->features & UseMacros[i]) { // USE
MemSrc = ((CurrType == o_mem) || (CurrType == o_phrase) || (CurrType == o_displ));
if (MemSrc) {
set<DefOrUse, LessDefUse>::iterator use = this->FindUse(Opnd);
SMPOperandType type = use->GetType();
assert(newType == (NUMERIC|PROF_BASE));
switch (type) {
case UNINIT:
case CODEPTR:
this->SetUseType(Opnd,newType);
break;
case POINTER:
this->SetUseType(Opnd, (SMPOperandType)(UNKNOWN|PROF_BASE));
break;
default:
break;
}
}