/* * Copyright 2002-2019 Intel Corporation. * * This software is provided to you as Sample Source Code as defined in the accompanying * End User License Agreement for the Intel(R) Software Development Products ("Agreement") * section 1.L. * * This software and the related documents are provided as is, with no express or implied * warranties, other than those that are expressly stated in the License. */ // // Check that IARG_EXECUTING works on IA32, by counting the number of // cmovs and the number executed in the test code. // #include "pin.H" #include #include #include using std::ofstream; using std::cerr; using std::string; using std::endl; LOCALVAR ofstream out; KNOB KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", "o", "checkexecuting.out", "Output file"); KNOB KnobVerbose(KNOB_MODE_WRITEONCE, "pintool", "v", "0", "Verbose"); UINT64 executed = 0; UINT64 total = 0; int enabled = 0; static struct { const char * name; UINT32 opcode; } opInfo [] = { {"cmovb", XED_ICLASS_CMOVB}, {"cmovbe", XED_ICLASS_CMOVBE}, {"cmovl", XED_ICLASS_CMOVL}, {"cmovle", XED_ICLASS_CMOVLE}, {"cmovnb", XED_ICLASS_CMOVNB}, {"cmovnbe", XED_ICLASS_CMOVNBE}, {"cmovnl", XED_ICLASS_CMOVNL}, {"cmovnle", XED_ICLASS_CMOVNLE}, {"cmovno", XED_ICLASS_CMOVNO}, {"cmovnp", XED_ICLASS_CMOVNP}, {"cmovns", XED_ICLASS_CMOVNS}, {"cmovnz", XED_ICLASS_CMOVNZ}, {"cmovo", XED_ICLASS_CMOVO}, {"cmovp", XED_ICLASS_CMOVP}, {"cmovs", XED_ICLASS_CMOVS}, {"cmovz", XED_ICLASS_CMOVZ}, // String ops, which are predicated if REPped {"lodsb", XED_ICLASS_LODSB}, {"lodsw", XED_ICLASS_LODSW}, {"lodsd", XED_ICLASS_LODSD}, {"lodsq", XED_ICLASS_LODSQ}, {"movsb", XED_ICLASS_MOVSB}, {"movsw", XED_ICLASS_MOVSW}, {"movsd", XED_ICLASS_MOVSD}, {"movsq", XED_ICLASS_MOVSQ}, {"scasb", XED_ICLASS_SCASB}, {"scasw", XED_ICLASS_SCASW}, {"scasd", XED_ICLASS_SCASD}, {"scasq", XED_ICLASS_SCASQ}, {"cmpsb", XED_ICLASS_CMPSB}, {"cmpsw", XED_ICLASS_CMPSW}, {"cmpsd", XED_ICLASS_CMPSD}, {"cmpsq", XED_ICLASS_CMPSQ}, {"stosb", XED_ICLASS_STOSB}, {"stosw", XED_ICLASS_STOSW}, {"stosd", XED_ICLASS_STOSD}, {"stosq", XED_ICLASS_STOSQ}, }; #define NumOps (sizeof(opInfo)/sizeof(opInfo[0])) static struct opCS { int total; int executed; int viaPredicated; int viaIfPredicated; int viaThenPredicated; int viaIfThenPredicated; } opCounts [NumOps]; INT32 Usage() { cerr << "This pin tool counts predicated instructions selected by the\n" "following filter options\n" "\n"; cerr << KNOB_BASE::StringKnobSummary() << endl; return -1; } static int opcodeToIndex(UINT32 opcode) { for (UINT32 i=0; itotal == 0) continue; out << opInfo[i].name << " : " << counts->total << " " << counts->executed << endl; // Check that the predicated calls all gave the same results as the executed call. // We check externally that the executed call agrees with that the code actually did. if (KnobVerbose) { out << " via predicated " << counts->viaPredicated << endl; out << " via ifPredicated " << counts->viaIfPredicated << endl; out << " via thenPredicated " << counts->viaThenPredicated << endl; out << " via ifThenPredicated " << counts->viaIfThenPredicated << endl; } if (counts->executed != counts->viaPredicated) { out << "***Error : executed gave " << counts->executed << " predicated gave " << counts->viaPredicated << endl; exit(1); } if (counts->executed != counts->viaIfPredicated) { out << "***Error : executed gave " << counts->executed << " if predicated gave " << counts->viaIfPredicated << endl; exit(1); } if (counts->executed != counts->viaThenPredicated) { out << "***Error : executed gave " << counts->executed << " then predicated gave " << counts->viaThenPredicated << endl; exit(1); } if (counts->executed != counts->viaIfThenPredicated) { out << "***Error : executed gave " << counts->executed << " ifthen predicated gave " << counts->viaIfThenPredicated << endl; exit(1); } } } // argc, argv are the entire command line, including pin -t -- ... int main(int argc, char * argv[]) { if( PIN_Init(argc,argv) ) { return Usage(); } string filename = KnobOutputFile.Value(); // Do this before we activate controllers out.open(filename.c_str()); TRACE_AddInstrumentFunction(Trace, 0); PIN_AddFiniFunction(Fini, 0); // Start the program, never returns PIN_StartProgram(); return 0; }