[simulator] Remove instruction instrumentation support.

This code hasn't been used in a long time so let's remove it. If one needs to
extract information from generated code, it's easy to add throw-away code to do
it in the simulator, so having first-class support for this isn't crucial. Also,
being tied to the decoder made the instrumentation support a little too
limiting.

Change-Id: Icf863a8b0bc19ac20bea3eb39e091c5e632982fc
This commit is contained in:
Pierre Langlois 2020-03-23 18:57:58 +01:00
parent 2fe55ec61d
commit 991ee198f6
12 changed files with 6 additions and 1203 deletions

1
.gitignore vendored
View File

@ -4,5 +4,4 @@
.sconsign.dblite
log/
obj/
vixl_stats.csv
tools/.cached_lint_results.pkl

View File

@ -1,975 +0,0 @@
// Copyright 2014, VIXL authors
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of ARM Limited nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "instrument-aarch64.h"
namespace vixl {
namespace aarch64 {
Counter::Counter(const char* name, CounterType type)
: count_(0), enabled_(false), type_(type) {
VIXL_ASSERT(name != NULL);
strncpy(name_, name, kCounterNameMaxLength - 1);
// Make sure `name_` is always NULL-terminated, even if the source's length is
// higher.
name_[kCounterNameMaxLength - 1] = '\0';
}
void Counter::Enable() { enabled_ = true; }
void Counter::Disable() { enabled_ = false; }
bool Counter::IsEnabled() { return enabled_; }
void Counter::Increment() {
if (enabled_) {
count_++;
}
}
uint64_t Counter::GetCount() {
uint64_t result = count_;
if (type_ == Gauge) {
// If the counter is a Gauge, reset the count after reading.
count_ = 0;
}
return result;
}
const char* Counter::GetName() { return name_; }
CounterType Counter::GetType() { return type_; }
struct CounterDescriptor {
const char* name;
CounterType type;
};
static const CounterDescriptor kCounterList[] = {{"Instruction", Cumulative},
{"Move Immediate", Gauge},
{"Add/Sub DP", Gauge},
{"Logical DP", Gauge},
{"Other Int DP", Gauge},
{"FP DP", Gauge},
{"Conditional Select", Gauge},
{"Conditional Compare", Gauge},
{"Unconditional Branch",
Gauge},
{"Compare and Branch", Gauge},
{"Test and Branch", Gauge},
{"Conditional Branch", Gauge},
{"Load Integer", Gauge},
{"Load FP", Gauge},
{"Load Pair", Gauge},
{"Load Literal", Gauge},
{"Store Integer", Gauge},
{"Store FP", Gauge},
{"Store Pair", Gauge},
{"PC Addressing", Gauge},
{"Other", Gauge},
{"NEON", Gauge},
{"Crypto", Gauge}};
Instrument::Instrument(const char* datafile, uint64_t sample_period)
: output_stream_(stdout), sample_period_(sample_period) {
// Set up the output stream. If datafile is non-NULL, use that file. If it
// can't be opened, or datafile is NULL, use stdout.
if (datafile != NULL) {
output_stream_ = fopen(datafile, "w");
if (output_stream_ == NULL) {
printf("Can't open output file %s. Using stdout.\n", datafile);
output_stream_ = stdout;
}
}
static const int num_counters =
sizeof(kCounterList) / sizeof(CounterDescriptor);
// Dump an instrumentation description comment at the top of the file.
fprintf(output_stream_, "# counters=%d\n", num_counters);
fprintf(output_stream_, "# sample_period=%" PRIu64 "\n", sample_period_);
// Construct Counter objects from counter description array.
for (int i = 0; i < num_counters; i++) {
Counter* counter = new Counter(kCounterList[i].name, kCounterList[i].type);
counters_.push_back(counter);
}
DumpCounterNames();
}
Instrument::~Instrument() {
// Dump any remaining instruction data to the output file.
DumpCounters();
// Free all the counter objects.
std::list<Counter*>::iterator it;
for (it = counters_.begin(); it != counters_.end(); it++) {
delete *it;
}
if (output_stream_ != stdout) {
fclose(output_stream_);
}
}
void Instrument::Update() {
// Increment the instruction counter, and dump all counters if a sample period
// has elapsed.
static Counter* counter = GetCounter("Instruction");
VIXL_ASSERT(counter->GetType() == Cumulative);
counter->Increment();
if ((sample_period_ != 0) && counter->IsEnabled() &&
(counter->GetCount() % sample_period_) == 0) {
DumpCounters();
}
}
void Instrument::DumpCounters() {
// Iterate through the counter objects, dumping their values to the output
// stream.
std::list<Counter*>::const_iterator it;
for (it = counters_.begin(); it != counters_.end(); it++) {
fprintf(output_stream_, "%" PRIu64 ",", (*it)->GetCount());
}
fprintf(output_stream_, "\n");
fflush(output_stream_);
}
void Instrument::DumpCounterNames() {
// Iterate through the counter objects, dumping the counter names to the
// output stream.
std::list<Counter*>::const_iterator it;
for (it = counters_.begin(); it != counters_.end(); it++) {
fprintf(output_stream_, "%s,", (*it)->GetName());
}
fprintf(output_stream_, "\n");
fflush(output_stream_);
}
void Instrument::HandleInstrumentationEvent(unsigned event) {
switch (event) {
case InstrumentStateEnable:
Enable();
break;
case InstrumentStateDisable:
Disable();
break;
default:
DumpEventMarker(event);
}
}
void Instrument::DumpEventMarker(unsigned marker) {
// Dumpan event marker to the output stream as a specially formatted comment
// line.
static Counter* counter = GetCounter("Instruction");
fprintf(output_stream_,
"# %c%c @ %" PRId64 "\n",
marker & 0xff,
(marker >> 8) & 0xff,
counter->GetCount());
}
Counter* Instrument::GetCounter(const char* name) {
// Get a Counter object by name from the counter list.
std::list<Counter*>::const_iterator it;
for (it = counters_.begin(); it != counters_.end(); it++) {
if (strcmp((*it)->GetName(), name) == 0) {
return *it;
}
}
// A Counter by that name does not exist: print an error message to stderr
// and the output file, and exit.
static const char* error_message =
"# Error: Unknown counter \"%s\". Exiting.\n";
fprintf(stderr, error_message, name);
fprintf(output_stream_, error_message, name);
exit(1);
}
void Instrument::Enable() {
std::list<Counter*>::iterator it;
for (it = counters_.begin(); it != counters_.end(); it++) {
(*it)->Enable();
}
}
void Instrument::Disable() {
std::list<Counter*>::iterator it;
for (it = counters_.begin(); it != counters_.end(); it++) {
(*it)->Disable();
}
}
void Instrument::VisitPCRelAddressing(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("PC Addressing");
counter->Increment();
}
void Instrument::VisitAddSubImmediate(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Add/Sub DP");
counter->Increment();
}
void Instrument::VisitLogicalImmediate(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Logical DP");
counter->Increment();
}
void Instrument::VisitMoveWideImmediate(const Instruction* instr) {
Update();
static Counter* counter = GetCounter("Move Immediate");
if (instr->IsMovn() && (instr->GetRd() == kZeroRegCode)) {
unsigned imm = instr->GetImmMoveWide();
HandleInstrumentationEvent(imm);
} else {
counter->Increment();
}
}
void Instrument::VisitBitfield(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Other Int DP");
counter->Increment();
}
void Instrument::VisitExtract(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Other Int DP");
counter->Increment();
}
void Instrument::VisitUnconditionalBranch(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Unconditional Branch");
counter->Increment();
}
void Instrument::VisitUnconditionalBranchToRegister(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Unconditional Branch");
counter->Increment();
}
void Instrument::VisitCompareBranch(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Compare and Branch");
counter->Increment();
}
void Instrument::VisitTestBranch(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Test and Branch");
counter->Increment();
}
void Instrument::VisitConditionalBranch(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Conditional Branch");
counter->Increment();
}
void Instrument::VisitSystem(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Other");
counter->Increment();
}
void Instrument::VisitException(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Other");
counter->Increment();
}
void Instrument::InstrumentLoadStorePair(const Instruction* instr) {
static Counter* load_pair_counter = GetCounter("Load Pair");
static Counter* store_pair_counter = GetCounter("Store Pair");
if (instr->Mask(LoadStorePairLBit) != 0) {
load_pair_counter->Increment();
} else {
store_pair_counter->Increment();
}
}
void Instrument::VisitLoadStorePairPostIndex(const Instruction* instr) {
Update();
InstrumentLoadStorePair(instr);
}
void Instrument::VisitLoadStorePairOffset(const Instruction* instr) {
Update();
InstrumentLoadStorePair(instr);
}
void Instrument::VisitLoadStorePairPreIndex(const Instruction* instr) {
Update();
InstrumentLoadStorePair(instr);
}
void Instrument::VisitLoadStorePairNonTemporal(const Instruction* instr) {
Update();
InstrumentLoadStorePair(instr);
}
void Instrument::VisitLoadStoreExclusive(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Other");
counter->Increment();
}
void Instrument::VisitAtomicMemory(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Other");
counter->Increment();
}
void Instrument::VisitLoadLiteral(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Load Literal");
counter->Increment();
}
void Instrument::VisitLoadStorePAC(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Load Integer");
counter->Increment();
}
void Instrument::InstrumentLoadStore(const Instruction* instr) {
static Counter* load_int_counter = GetCounter("Load Integer");
static Counter* store_int_counter = GetCounter("Store Integer");
static Counter* load_fp_counter = GetCounter("Load FP");
static Counter* store_fp_counter = GetCounter("Store FP");
switch (instr->Mask(LoadStoreMask)) {
case STRB_w:
case STRH_w:
case STR_w:
VIXL_FALLTHROUGH();
case STR_x:
store_int_counter->Increment();
break;
case STR_s:
VIXL_FALLTHROUGH();
case STR_d:
store_fp_counter->Increment();
break;
case LDRB_w:
case LDRH_w:
case LDR_w:
case LDR_x:
case LDRSB_x:
case LDRSH_x:
case LDRSW_x:
case LDRSB_w:
VIXL_FALLTHROUGH();
case LDRSH_w:
load_int_counter->Increment();
break;
case LDR_s:
VIXL_FALLTHROUGH();
case LDR_d:
load_fp_counter->Increment();
break;
}
}
void Instrument::VisitLoadStoreUnscaledOffset(const Instruction* instr) {
Update();
InstrumentLoadStore(instr);
}
void Instrument::VisitLoadStorePostIndex(const Instruction* instr) {
USE(instr);
Update();
InstrumentLoadStore(instr);
}
void Instrument::VisitLoadStorePreIndex(const Instruction* instr) {
Update();
InstrumentLoadStore(instr);
}
void Instrument::VisitLoadStoreRegisterOffset(const Instruction* instr) {
Update();
InstrumentLoadStore(instr);
}
void Instrument::VisitLoadStoreRCpcUnscaledOffset(const Instruction* instr) {
Update();
switch (instr->Mask(LoadStoreRCpcUnscaledOffsetMask)) {
case STLURB:
case STLURH:
case STLUR_w:
case STLUR_x: {
static Counter* counter = GetCounter("Store Integer");
counter->Increment();
break;
}
case LDAPURB:
case LDAPURSB_w:
case LDAPURSB_x:
case LDAPURH:
case LDAPURSH_w:
case LDAPURSH_x:
case LDAPUR_w:
case LDAPURSW:
case LDAPUR_x: {
static Counter* counter = GetCounter("Load Integer");
counter->Increment();
break;
}
}
}
void Instrument::VisitLoadStoreUnsignedOffset(const Instruction* instr) {
Update();
InstrumentLoadStore(instr);
}
void Instrument::VisitLogicalShifted(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Logical DP");
counter->Increment();
}
void Instrument::VisitAddSubShifted(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Add/Sub DP");
counter->Increment();
}
void Instrument::VisitAddSubExtended(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Add/Sub DP");
counter->Increment();
}
void Instrument::VisitAddSubWithCarry(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Add/Sub DP");
counter->Increment();
}
void Instrument::VisitRotateRightIntoFlags(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Other");
counter->Increment();
}
void Instrument::VisitEvaluateIntoFlags(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Other");
counter->Increment();
}
void Instrument::VisitConditionalCompareRegister(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Conditional Compare");
counter->Increment();
}
void Instrument::VisitConditionalCompareImmediate(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Conditional Compare");
counter->Increment();
}
void Instrument::VisitConditionalSelect(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Conditional Select");
counter->Increment();
}
void Instrument::VisitDataProcessing1Source(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Other Int DP");
counter->Increment();
}
void Instrument::VisitDataProcessing2Source(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Other Int DP");
counter->Increment();
}
void Instrument::VisitDataProcessing3Source(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Other Int DP");
counter->Increment();
}
void Instrument::VisitFPCompare(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("FP DP");
counter->Increment();
}
void Instrument::VisitFPConditionalCompare(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Conditional Compare");
counter->Increment();
}
void Instrument::VisitFPConditionalSelect(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Conditional Select");
counter->Increment();
}
void Instrument::VisitFPImmediate(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("FP DP");
counter->Increment();
}
void Instrument::VisitFPDataProcessing1Source(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("FP DP");
counter->Increment();
}
void Instrument::VisitFPDataProcessing2Source(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("FP DP");
counter->Increment();
}
void Instrument::VisitFPDataProcessing3Source(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("FP DP");
counter->Increment();
}
void Instrument::VisitFPIntegerConvert(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("FP DP");
counter->Increment();
}
void Instrument::VisitFPFixedPointConvert(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("FP DP");
counter->Increment();
}
void Instrument::VisitCrypto2RegSHA(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Crypto");
counter->Increment();
}
void Instrument::VisitCrypto3RegSHA(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Crypto");
counter->Increment();
}
void Instrument::VisitCryptoAES(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Crypto");
counter->Increment();
}
void Instrument::VisitNEON2RegMisc(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEON2RegMiscFP16(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEON3Same(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEON3SameFP16(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEON3SameExtra(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEON3Different(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONAcrossLanes(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONByIndexedElement(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONCopy(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONExtract(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONLoadStoreMultiStruct(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONLoadStoreMultiStructPostIndex(
const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONLoadStoreSingleStruct(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONLoadStoreSingleStructPostIndex(
const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONModifiedImmediate(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONScalar2RegMisc(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONScalar2RegMiscFP16(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONScalar3Diff(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONScalar3Same(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONScalar3SameFP16(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONScalar3SameExtra(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONScalarByIndexedElement(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONScalarCopy(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONScalarPairwise(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONScalarShiftImmediate(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONShiftImmediate(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONTable(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitNEONPerm(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("NEON");
counter->Increment();
}
void Instrument::VisitReserved(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Other");
counter->Increment();
}
void Instrument::VisitUnallocated(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Other");
counter->Increment();
}
void Instrument::VisitUnimplemented(const Instruction* instr) {
USE(instr);
Update();
static Counter* counter = GetCounter("Other");
counter->Increment();
}
} // namespace aarch64
} // namespace vixl

View File

@ -1,117 +0,0 @@
// Copyright 2014, VIXL authors
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of ARM Limited nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef VIXL_AARCH64_INSTRUMENT_AARCH64_H_
#define VIXL_AARCH64_INSTRUMENT_AARCH64_H_
#include "../globals-vixl.h"
#include "../utils-vixl.h"
#include "constants-aarch64.h"
#include "decoder-aarch64.h"
#include "instrument-aarch64.h"
namespace vixl {
namespace aarch64 {
const int kCounterNameMaxLength = 256;
const uint64_t kDefaultInstrumentationSamplingPeriod = 1 << 22;
enum InstrumentState { InstrumentStateDisable = 0, InstrumentStateEnable = 1 };
enum CounterType {
Gauge = 0, // Gauge counters reset themselves after reading.
Cumulative = 1 // Cumulative counters keep their value after reading.
};
class Counter {
public:
explicit Counter(const char* name, CounterType type = Gauge);
void Increment();
void Enable();
void Disable();
bool IsEnabled();
uint64_t GetCount();
VIXL_DEPRECATED("GetCount", uint64_t count()) { return GetCount(); }
const char* GetName();
VIXL_DEPRECATED("GetName", const char* name()) { return GetName(); }
CounterType GetType();
VIXL_DEPRECATED("GetType", CounterType type()) { return GetType(); }
private:
char name_[kCounterNameMaxLength];
uint64_t count_;
bool enabled_;
CounterType type_;
};
class Instrument : public DecoderVisitor {
public:
explicit Instrument(
const char* datafile = NULL,
uint64_t sample_period = kDefaultInstrumentationSamplingPeriod);
~Instrument();
void Enable();
void Disable();
// Declare all Visitor functions.
#define DECLARE(A) void Visit##A(const Instruction* instr) VIXL_OVERRIDE;
VISITOR_LIST(DECLARE)
#undef DECLARE
private:
void Update();
void DumpCounters();
void DumpCounterNames();
void DumpEventMarker(unsigned marker);
void HandleInstrumentationEvent(unsigned event);
Counter* GetCounter(const char* name);
void InstrumentLoadStore(const Instruction* instr);
void InstrumentLoadStorePair(const Instruction* instr);
std::list<Counter*> counters_;
FILE* output_stream_;
// Counter information is dumped every sample_period_ instructions decoded.
// For a sample_period_ = 0 a final counter value is only produced when the
// Instrumentation class is destroyed.
uint64_t sample_period_;
};
} // namespace aarch64
} // namespace vixl
#endif // VIXL_AARCH64_INSTRUMENT_AARCH64_H_

View File

@ -2764,32 +2764,6 @@ void MacroAssembler::Log(TraceParameters parameters) {
}
void MacroAssembler::EnableInstrumentation() {
VIXL_ASSERT(!isprint(InstrumentStateEnable));
ExactAssemblyScope scope(this, kInstructionSize);
movn(xzr, InstrumentStateEnable);
}
void MacroAssembler::DisableInstrumentation() {
VIXL_ASSERT(!isprint(InstrumentStateDisable));
ExactAssemblyScope scope(this, kInstructionSize);
movn(xzr, InstrumentStateDisable);
}
void MacroAssembler::AnnotateInstrumentation(const char* marker_name) {
VIXL_ASSERT(strlen(marker_name) == 2);
// We allow only printable characters in the marker names. Unprintable
// characters are reserved for controlling features of the instrumentation.
VIXL_ASSERT(isprint(marker_name[0]) && isprint(marker_name[1]));
ExactAssemblyScope scope(this, kInstructionSize);
movn(xzr, (marker_name[1] << 8) | marker_name[0]);
}
void MacroAssembler::SetSimulatorCPUFeatures(const CPUFeatures& features) {
ConfigureSimulatorCPUFeaturesHelper(features, kSetCPUFeaturesOpcode);
}

View File

@ -35,7 +35,6 @@
#include "../macro-assembler-interface.h"
#include "assembler-aarch64.h"
#include "instrument-aarch64.h"
// Required for runtime call support.
// TODO: Break this dependency. We should be able to separate out the necessary
// parts so that we don't need to include the whole simulator header.
@ -3548,16 +3547,6 @@ class MacroAssembler : public Assembler, public MacroAssemblerInterface {
// Will output the flags.
void Log(TraceParameters parameters);
// Enable or disable instrumentation when an Instrument visitor is attached to
// the simulator.
void EnableInstrumentation();
void DisableInstrumentation();
// Add a marker to the instrumentation data produced by an Instrument visitor.
// The name is a two character string that will be attached to the marker in
// the output data.
void AnnotateInstrumentation(const char* marker_name);
// Enable or disable CPU features dynamically. This mechanism allows users to
// strictly check the use of CPU features in different regions of code.
void SetSimulatorCPUFeatures(const CPUFeatures& features);

View File

@ -70,8 +70,6 @@ Simulator::Simulator(Decoder* decoder, FILE* stream)
VIXL_ASSERT((static_cast<int32_t>(-1) >> 1) == -1);
VIXL_ASSERT((static_cast<uint32_t>(-1) >> 1) == 0x7fffffff);
instruction_stats_ = false;
// Set up the decoder.
decoder_ = decoder;
decoder_->AppendVisitor(this);
@ -105,8 +103,6 @@ Simulator::Simulator(Decoder* decoder, FILE* stream)
tos = AlignDown(tos, 16);
WriteSp(tos);
instrumentation_ = NULL;
// Print a warning about exclusive-access instructions, but only the first
// time they are encountered. This warning can be silenced using
// SilenceExclusiveAccessWarning().
@ -159,9 +155,6 @@ Simulator::~Simulator() {
// The decoder may outlive the simulator.
decoder_->RemoveVisitor(print_disasm_);
delete print_disasm_;
decoder_->RemoveVisitor(instrumentation_);
delete instrumentation_;
}
@ -322,22 +315,6 @@ void Simulator::SetTraceParameters(int parameters) {
}
void Simulator::SetInstructionStats(bool value) {
if (value != instruction_stats_) {
if (value) {
if (instrumentation_ == NULL) {
// Set the sample period to 10, as the VIXL examples and tests are
// short.
instrumentation_ = new Instrument("vixl_stats.csv", 10);
}
decoder_->AppendVisitor(instrumentation_);
} else if (instrumentation_ != NULL) {
decoder_->RemoveVisitor(instrumentation_);
}
instruction_stats_ = value;
}
}
// Helpers ---------------------------------------------------------------------
uint64_t Simulator::AddWithCarry(unsigned reg_size,
bool set_flags,

View File

@ -37,7 +37,6 @@
#include "cpu-features-auditor-aarch64.h"
#include "disasm-aarch64.h"
#include "instructions-aarch64.h"
#include "instrument-aarch64.h"
#include "simulator-constants-aarch64.h"
#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
@ -1615,12 +1614,6 @@ class Simulator : public DecoderVisitor {
SetTraceParameters(parameters);
}
void SetInstructionStats(bool value);
VIXL_DEPRECATED("SetInstructionStats",
void set_instruction_stats(bool value)) {
SetInstructionStats(value);
}
// Clear the simulated local monitor to force the next store-exclusive
// instruction to fail.
void ClearLocalMonitor() { local_monitor_.Clear(); }
@ -3222,9 +3215,6 @@ class Simulator : public DecoderVisitor {
FILE* stream_;
PrintDisassembler* print_disasm_;
// Instruction statistics instrumentation.
Instrument* instrumentation_;
// General purpose registers. Register 31 is the stack pointer.
SimRegister registers_[kNumberOfRegisters];
@ -3358,9 +3348,6 @@ class Simulator : public DecoderVisitor {
// A set of TraceParameters flags.
int trace_parameters_;
// Indicates whether the instruction instrumentation is active.
bool instruction_stats_;
// Indicates whether the exclusive-access warning has been printed.
bool print_exclusive_access_warning_;
void PrintExclusiveAccessWarning();

View File

@ -177,13 +177,7 @@ uint32_t SumArrayC(uint8_t* array, uint32_t size) {
TRACE_ENABLE); \
} \
} \
if (Test::instruction_stats()) { \
masm.EnableInstrumentation(); \
} \
masm.Blr(test_function_reg); \
if (Test::instruction_stats()) { \
masm.DisableInstrumentation(); \
} \
masm.Trace(LOG_ALL, TRACE_DISABLE); \
regs.Dump(&masm); \
masm.Mov(lr, reinterpret_cast<uint64_t>(Simulator::kEndOfSimAddress)); \

View File

@ -110,7 +110,6 @@ static const CPUFeatures kInfrastructureCPUFeatures(CPUFeatures::kNEON);
Decoder simulator_decoder; \
Simulator simulator(&simulator_decoder); \
simulator.SetColouredTrace(Test::coloured_trace()); \
simulator.SetInstructionStats(Test::instruction_stats()); \
simulator.SetCPUFeatures(CPUFeatures::None()); \
RegisterDump core; \
ptrdiff_t offset_after_infrastructure_start; \
@ -133,9 +132,6 @@ static const CPUFeatures kInfrastructureCPUFeatures(CPUFeatures::kNEON);
__ Trace(static_cast<TraceParameters>(trace_parameters), TRACE_ENABLE); \
} \
} \
if (Test::instruction_stats()) { \
__ EnableInstrumentation(); \
} \
offset_after_infrastructure_start = masm.GetCursorOffset(); \
/* Avoid unused-variable warnings in case a test never calls RUN(). */ \
USE(offset_after_infrastructure_start)
@ -144,9 +140,6 @@ static const CPUFeatures kInfrastructureCPUFeatures(CPUFeatures::kNEON);
offset_before_infrastructure_end = masm.GetCursorOffset(); \
/* Avoid unused-variable warnings in case a test never calls RUN(). */ \
USE(offset_before_infrastructure_end); \
if (Test::instruction_stats()) { \
__ DisableInstrumentation(); \
} \
__ Trace(LOG_ALL, TRACE_DISABLE); \
{ \
SimulationCPUFeaturesScope cpu(&masm, kInfrastructureCPUFeatures); \

View File

@ -62,13 +62,12 @@ namespace aarch64 {
#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
#define SETUP_WITH_FEATURES(...) \
MacroAssembler masm; \
masm.SetCPUFeatures(CPUFeatures(__VA_ARGS__)); \
Decoder decoder; \
Simulator simulator(&decoder); \
simulator.SetColouredTrace(Test::coloured_trace()); \
simulator.SetInstructionStats(Test::instruction_stats());
#define SETUP_WITH_FEATURES(...) \
MacroAssembler masm; \
masm.SetCPUFeatures(CPUFeatures(__VA_ARGS__)); \
Decoder decoder; \
Simulator simulator(&decoder); \
simulator.SetColouredTrace(Test::coloured_trace());
#define START() \
masm.Reset(); \
@ -82,15 +81,9 @@ namespace aarch64 {
} \
if (Test::trace_sim()) { \
__ Trace(LOG_DISASM, TRACE_ENABLE); \
} \
if (Test::instruction_stats()) { \
__ EnableInstrumentation(); \
}
#define END() \
if (Test::instruction_stats()) { \
__ DisableInstrumentation(); \
} \
__ Trace(LOG_ALL, TRACE_DISABLE); \
__ PopCalleeSavedRegisters(); \
__ Ret(); \

View File

@ -49,9 +49,6 @@ bool vixl::Test::disassemble_infrastructure_ = false;
// No colour highlight by default.
bool vixl::Test::coloured_trace_ = false;
// No instruction statistics by default.
bool vixl::Test::instruction_stats_ = false;
// Don't generate traces by default.
bool vixl::Test::generate_test_trace_ = false;
@ -118,7 +115,6 @@ static void PrintHelpMessage() {
"--disassemble-test-code "
"As above, but don't disassemble infrastructure code.\n"
"--coloured_trace Generate coloured trace.\n"
"--instruction_stats Log instruction statistics to vixl_stats.csv.\n"
"--generate_test_trace "
"Print result traces for SIM_* and TRACE_* tests.\n");
}
@ -179,10 +175,6 @@ int main(int argc, char* argv[]) {
vixl::Test::set_disassemble_infrastructure(false);
}
if (IsInArgs("--instruction-stats", argc, argv)) {
vixl::Test::set_instruction_stats(true);
}
if (IsInArgs("--generate-test-trace", argc, argv)) {
vixl::Test::set_generate_test_trace(true);
}

View File

@ -64,8 +64,6 @@ class Test {
}
static bool coloured_trace() { return coloured_trace_; }
static void set_coloured_trace(bool value) { coloured_trace_ = value; }
static bool instruction_stats() { return instruction_stats_; }
static void set_instruction_stats(bool value) { instruction_stats_ = value; }
static bool generate_test_trace() { return generate_test_trace_; }
static void set_generate_test_trace(bool value) {
generate_test_trace_ = value;
@ -86,7 +84,6 @@ class Test {
static bool disassemble_;
static bool disassemble_infrastructure_;
static bool coloured_trace_;
static bool instruction_stats_;
static bool generate_test_trace_;
};