tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Instrument-vixl.cpp (20042B)


      1 // Copyright 2014, VIXL authors
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are met:
      6 //
      7 //   * Redistributions of source code must retain the above copyright notice,
      8 //     this list of conditions and the following disclaimer.
      9 //   * Redistributions in binary form must reproduce the above copyright notice,
     10 //     this list of conditions and the following disclaimer in the documentation
     11 //     and/or other materials provided with the distribution.
     12 //   * Neither the name of ARM Limited nor the names of its contributors may be
     13 //     used to endorse or promote products derived from this software without
     14 //     specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
     17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
     20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 
     27 #include "jit/arm64/vixl/Instrument-vixl.h"
     28 
     29 namespace vixl {
     30 
     31 Counter::Counter(const char* name, CounterType type)
     32    : count_(0), enabled_(false), type_(type) {
     33  VIXL_ASSERT(name != NULL);
     34  strncpy(name_, name, kCounterNameMaxLength);
     35 }
     36 
     37 
     38 void Counter::Enable() {
     39  enabled_ = true;
     40 }
     41 
     42 
     43 void Counter::Disable() {
     44  enabled_ = false;
     45 }
     46 
     47 
     48 bool Counter::IsEnabled() {
     49  return enabled_;
     50 }
     51 
     52 
     53 void Counter::Increment() {
     54  if (enabled_) {
     55    count_++;
     56  }
     57 }
     58 
     59 
     60 uint64_t Counter::count() {
     61  uint64_t result = count_;
     62  if (type_ == Gauge) {
     63    // If the counter is a Gauge, reset the count after reading.
     64    count_ = 0;
     65  }
     66  return result;
     67 }
     68 
     69 
     70 const char* Counter::name() {
     71  return name_;
     72 }
     73 
     74 
     75 CounterType Counter::type() {
     76  return type_;
     77 }
     78 
     79 
     80 struct CounterDescriptor {
     81  const char* name;
     82  CounterType type;
     83 };
     84 
     85 
     86 static const CounterDescriptor kCounterList[] = {
     87  {"Instruction", Cumulative},
     88 
     89  {"Move Immediate", Gauge},
     90  {"Add/Sub DP", Gauge},
     91  {"Logical DP", Gauge},
     92  {"Other Int DP", Gauge},
     93  {"FP DP", Gauge},
     94 
     95  {"Conditional Select", Gauge},
     96  {"Conditional Compare", Gauge},
     97 
     98  {"Unconditional Branch", Gauge},
     99  {"Compare and Branch", Gauge},
    100  {"Test and Branch", Gauge},
    101  {"Conditional Branch", Gauge},
    102 
    103  {"Load Integer", Gauge},
    104  {"Load FP", Gauge},
    105  {"Load Pair", Gauge},
    106  {"Load Literal", Gauge},
    107 
    108  {"Store Integer", Gauge},
    109  {"Store FP", Gauge},
    110  {"Store Pair", Gauge},
    111 
    112  {"PC Addressing", Gauge},
    113  {"Other", Gauge},
    114  {"NEON", Gauge},
    115  {"Crypto", Gauge}
    116 };
    117 
    118 
    119 Instrument::Instrument(const char* datafile, uint64_t sample_period)
    120    : output_stream_(stdout), sample_period_(sample_period) {
    121 
    122  // Set up the output stream. If datafile is non-NULL, use that file. If it
    123  // can't be opened, or datafile is NULL, use stdout.
    124  if (datafile != NULL) {
    125    output_stream_ = fopen(datafile, "w");
    126    if (output_stream_ == NULL) {
    127      printf("Can't open output file %s. Using stdout.\n", datafile);
    128      output_stream_ = stdout;
    129    }
    130  }
    131 
    132  static const int num_counters =
    133    sizeof(kCounterList) / sizeof(CounterDescriptor);
    134 
    135  // Dump an instrumentation description comment at the top of the file.
    136  fprintf(output_stream_, "# counters=%d\n", num_counters);
    137  fprintf(output_stream_, "# sample_period=%" PRIu64 "\n", sample_period_);
    138 
    139  // Construct Counter objects from counter description array.
    140  for (int i = 0; i < num_counters; i++) {
    141    if (Counter* counter = js_new<Counter>(kCounterList[i].name, kCounterList[i].type))
    142      (void)counters_.append(counter);
    143  }
    144 
    145  DumpCounterNames();
    146 }
    147 
    148 
    149 Instrument::~Instrument() {
    150  // Dump any remaining instruction data to the output file.
    151  DumpCounters();
    152 
    153  // Free all the counter objects.
    154  for (auto counter : counters_) {
    155    js_delete(counter);
    156  }
    157 
    158  if (output_stream_ != stdout) {
    159    fclose(output_stream_);
    160  }
    161 }
    162 
    163 
    164 void Instrument::Update() {
    165  // Increment the instruction counter, and dump all counters if a sample period
    166  // has elapsed.
    167  static Counter* counter = GetCounter("Instruction");
    168  VIXL_ASSERT(counter->type() == Cumulative);
    169  counter->Increment();
    170 
    171  if (counter->IsEnabled() && (counter->count() % sample_period_) == 0) {
    172    DumpCounters();
    173  }
    174 }
    175 
    176 
    177 void Instrument::DumpCounters() {
    178  // Iterate through the counter objects, dumping their values to the output
    179  // stream.
    180  for (auto counter : counters_) {
    181    fprintf(output_stream_, "%" PRIu64 ",", counter->count());
    182  }
    183  fprintf(output_stream_, "\n");
    184  fflush(output_stream_);
    185 }
    186 
    187 
    188 void Instrument::DumpCounterNames() {
    189  // Iterate through the counter objects, dumping the counter names to the
    190  // output stream.
    191  for (auto counter : counters_) {
    192    fprintf(output_stream_, "%s,", counter->name());
    193  }
    194  fprintf(output_stream_, "\n");
    195  fflush(output_stream_);
    196 }
    197 
    198 
    199 void Instrument::HandleInstrumentationEvent(unsigned event) {
    200  switch (event) {
    201    case InstrumentStateEnable: Enable(); break;
    202    case InstrumentStateDisable: Disable(); break;
    203    default: DumpEventMarker(event);
    204  }
    205 }
    206 
    207 
    208 void Instrument::DumpEventMarker(unsigned marker) {
    209  // Dumpan event marker to the output stream as a specially formatted comment
    210  // line.
    211  static Counter* counter = GetCounter("Instruction");
    212 
    213  fprintf(output_stream_, "# %c%c @ %" PRId64 "\n", marker & 0xff,
    214          (marker >> 8) & 0xff, counter->count());
    215 }
    216 
    217 
    218 Counter* Instrument::GetCounter(const char* name) {
    219  // Get a Counter object by name from the counter list.
    220  for (auto counter : counters_) {
    221    if (strcmp(counter->name(), name) == 0) {
    222      return counter;
    223    }
    224  }
    225 
    226  // A Counter by that name does not exist: print an error message to stderr
    227  // and the output file, and exit.
    228  static const char* error_message =
    229    "# Error: Unknown counter \"%s\". Exiting.\n";
    230  fprintf(stderr, error_message, name);
    231  fprintf(output_stream_, error_message, name);
    232  exit(1);
    233 }
    234 
    235 
    236 void Instrument::Enable() {
    237  for (auto counter : counters_) {
    238    counter->Enable();
    239  }
    240 }
    241 
    242 
    243 void Instrument::Disable() {
    244  for (auto counter : counters_) {
    245    counter->Disable();
    246  }
    247 }
    248 
    249 
    250 void Instrument::VisitPCRelAddressing(const Instruction* instr) {
    251  USE(instr);
    252  Update();
    253  static Counter* counter = GetCounter("PC Addressing");
    254  counter->Increment();
    255 }
    256 
    257 
    258 void Instrument::VisitAddSubImmediate(const Instruction* instr) {
    259  USE(instr);
    260  Update();
    261  static Counter* counter = GetCounter("Add/Sub DP");
    262  counter->Increment();
    263 }
    264 
    265 
    266 void Instrument::VisitLogicalImmediate(const Instruction* instr) {
    267  USE(instr);
    268  Update();
    269  static Counter* counter = GetCounter("Logical DP");
    270  counter->Increment();
    271 }
    272 
    273 
    274 void Instrument::VisitMoveWideImmediate(const Instruction* instr) {
    275  Update();
    276  static Counter* counter = GetCounter("Move Immediate");
    277 
    278  if (instr->IsMovn() && (instr->Rd() == kZeroRegCode)) {
    279    unsigned imm = instr->ImmMoveWide();
    280    HandleInstrumentationEvent(imm);
    281  } else {
    282    counter->Increment();
    283  }
    284 }
    285 
    286 
    287 void Instrument::VisitBitfield(const Instruction* instr) {
    288  USE(instr);
    289  Update();
    290  static Counter* counter = GetCounter("Other Int DP");
    291  counter->Increment();
    292 }
    293 
    294 
    295 void Instrument::VisitExtract(const Instruction* instr) {
    296  USE(instr);
    297  Update();
    298  static Counter* counter = GetCounter("Other Int DP");
    299  counter->Increment();
    300 }
    301 
    302 
    303 void Instrument::VisitUnconditionalBranch(const Instruction* instr) {
    304  USE(instr);
    305  Update();
    306  static Counter* counter = GetCounter("Unconditional Branch");
    307  counter->Increment();
    308 }
    309 
    310 
    311 void Instrument::VisitUnconditionalBranchToRegister(const Instruction* instr) {
    312  USE(instr);
    313  Update();
    314  static Counter* counter = GetCounter("Unconditional Branch");
    315  counter->Increment();
    316 }
    317 
    318 
    319 void Instrument::VisitCompareBranch(const Instruction* instr) {
    320  USE(instr);
    321  Update();
    322  static Counter* counter = GetCounter("Compare and Branch");
    323  counter->Increment();
    324 }
    325 
    326 
    327 void Instrument::VisitTestBranch(const Instruction* instr) {
    328  USE(instr);
    329  Update();
    330  static Counter* counter = GetCounter("Test and Branch");
    331  counter->Increment();
    332 }
    333 
    334 
    335 void Instrument::VisitConditionalBranch(const Instruction* instr) {
    336  USE(instr);
    337  Update();
    338  static Counter* counter = GetCounter("Conditional Branch");
    339  counter->Increment();
    340 }
    341 
    342 
    343 void Instrument::VisitSystem(const Instruction* instr) {
    344  USE(instr);
    345  Update();
    346  static Counter* counter = GetCounter("Other");
    347  counter->Increment();
    348 }
    349 
    350 
    351 void Instrument::VisitException(const Instruction* instr) {
    352  USE(instr);
    353  Update();
    354  static Counter* counter = GetCounter("Other");
    355  counter->Increment();
    356 }
    357 
    358 
    359 void Instrument::InstrumentLoadStorePair(const Instruction* instr) {
    360  static Counter* load_pair_counter = GetCounter("Load Pair");
    361  static Counter* store_pair_counter = GetCounter("Store Pair");
    362 
    363  if (instr->Mask(LoadStorePairLBit) != 0) {
    364    load_pair_counter->Increment();
    365  } else {
    366    store_pair_counter->Increment();
    367  }
    368 }
    369 
    370 
    371 void Instrument::VisitLoadStorePairPostIndex(const Instruction* instr) {
    372  Update();
    373  InstrumentLoadStorePair(instr);
    374 }
    375 
    376 
    377 void Instrument::VisitLoadStorePairOffset(const Instruction* instr) {
    378  Update();
    379  InstrumentLoadStorePair(instr);
    380 }
    381 
    382 
    383 void Instrument::VisitLoadStorePairPreIndex(const Instruction* instr) {
    384  Update();
    385  InstrumentLoadStorePair(instr);
    386 }
    387 
    388 
    389 void Instrument::VisitLoadStorePairNonTemporal(const Instruction* instr) {
    390  Update();
    391  InstrumentLoadStorePair(instr);
    392 }
    393 
    394 
    395 void Instrument::VisitLoadStoreExclusive(const Instruction* instr) {
    396  USE(instr);
    397  Update();
    398  static Counter* counter = GetCounter("Other");
    399  counter->Increment();
    400 }
    401 
    402 void Instrument::VisitAtomicMemory(const Instruction* instr) {
    403  USE(instr);
    404  Update();
    405  static Counter* counter = GetCounter("Other");
    406  counter->Increment();
    407 }
    408 
    409 void Instrument::VisitLoadLiteral(const Instruction* instr) {
    410  USE(instr);
    411  Update();
    412  static Counter* counter = GetCounter("Load Literal");
    413  counter->Increment();
    414 }
    415 
    416 
    417 void Instrument::InstrumentLoadStore(const Instruction* instr) {
    418  static Counter* load_int_counter = GetCounter("Load Integer");
    419  static Counter* store_int_counter = GetCounter("Store Integer");
    420  static Counter* load_fp_counter = GetCounter("Load FP");
    421  static Counter* store_fp_counter = GetCounter("Store FP");
    422 
    423  switch (instr->Mask(LoadStoreMask)) {
    424    case STRB_w:
    425    case STRH_w:
    426    case STR_w:
    427      VIXL_FALLTHROUGH();
    428    case STR_x:     store_int_counter->Increment(); break;
    429    case STR_s:
    430      VIXL_FALLTHROUGH();
    431    case STR_d:     store_fp_counter->Increment(); break;
    432    case LDRB_w:
    433    case LDRH_w:
    434    case LDR_w:
    435    case LDR_x:
    436    case LDRSB_x:
    437    case LDRSH_x:
    438    case LDRSW_x:
    439    case LDRSB_w:
    440      VIXL_FALLTHROUGH();
    441    case LDRSH_w:   load_int_counter->Increment(); break;
    442    case LDR_s:
    443      VIXL_FALLTHROUGH();
    444    case LDR_d:     load_fp_counter->Increment(); break;
    445  }
    446 }
    447 
    448 
    449 void Instrument::VisitLoadStoreUnscaledOffset(const Instruction* instr) {
    450  Update();
    451  InstrumentLoadStore(instr);
    452 }
    453 
    454 
    455 void Instrument::VisitLoadStorePostIndex(const Instruction* instr) {
    456  USE(instr);
    457  Update();
    458  InstrumentLoadStore(instr);
    459 }
    460 
    461 
    462 void Instrument::VisitLoadStorePreIndex(const Instruction* instr) {
    463  Update();
    464  InstrumentLoadStore(instr);
    465 }
    466 
    467 
    468 void Instrument::VisitLoadStoreRegisterOffset(const Instruction* instr) {
    469  Update();
    470  InstrumentLoadStore(instr);
    471 }
    472 
    473 
    474 void Instrument::VisitLoadStoreUnsignedOffset(const Instruction* instr) {
    475  Update();
    476  InstrumentLoadStore(instr);
    477 }
    478 
    479 
    480 void Instrument::VisitLogicalShifted(const Instruction* instr) {
    481  USE(instr);
    482  Update();
    483  static Counter* counter = GetCounter("Logical DP");
    484  counter->Increment();
    485 }
    486 
    487 
    488 void Instrument::VisitAddSubShifted(const Instruction* instr) {
    489  USE(instr);
    490  Update();
    491  static Counter* counter = GetCounter("Add/Sub DP");
    492  counter->Increment();
    493 }
    494 
    495 
    496 void Instrument::VisitAddSubExtended(const Instruction* instr) {
    497  USE(instr);
    498  Update();
    499  static Counter* counter = GetCounter("Add/Sub DP");
    500  counter->Increment();
    501 }
    502 
    503 
    504 void Instrument::VisitAddSubWithCarry(const Instruction* instr) {
    505  USE(instr);
    506  Update();
    507  static Counter* counter = GetCounter("Add/Sub DP");
    508  counter->Increment();
    509 }
    510 
    511 
    512 void Instrument::VisitConditionalCompareRegister(const Instruction* instr) {
    513  USE(instr);
    514  Update();
    515  static Counter* counter = GetCounter("Conditional Compare");
    516  counter->Increment();
    517 }
    518 
    519 
    520 void Instrument::VisitConditionalCompareImmediate(const Instruction* instr) {
    521  USE(instr);
    522  Update();
    523  static Counter* counter = GetCounter("Conditional Compare");
    524  counter->Increment();
    525 }
    526 
    527 
    528 void Instrument::VisitConditionalSelect(const Instruction* instr) {
    529  USE(instr);
    530  Update();
    531  static Counter* counter = GetCounter("Conditional Select");
    532  counter->Increment();
    533 }
    534 
    535 
    536 void Instrument::VisitDataProcessing1Source(const Instruction* instr) {
    537  USE(instr);
    538  Update();
    539  static Counter* counter = GetCounter("Other Int DP");
    540  counter->Increment();
    541 }
    542 
    543 
    544 void Instrument::VisitDataProcessing2Source(const Instruction* instr) {
    545  USE(instr);
    546  Update();
    547  static Counter* counter = GetCounter("Other Int DP");
    548  counter->Increment();
    549 }
    550 
    551 
    552 void Instrument::VisitMaxMinImmediate(const Instruction *instr) {
    553  USE(instr);
    554  Update();
    555  static Counter* counter = GetCounter("Other Int DP");
    556  counter->Increment();
    557 }
    558 
    559 
    560 void Instrument::VisitDataProcessing3Source(const Instruction* instr) {
    561  USE(instr);
    562  Update();
    563  static Counter* counter = GetCounter("Other Int DP");
    564  counter->Increment();
    565 }
    566 
    567 
    568 void Instrument::VisitFPCompare(const Instruction* instr) {
    569  USE(instr);
    570  Update();
    571  static Counter* counter = GetCounter("FP DP");
    572  counter->Increment();
    573 }
    574 
    575 
    576 void Instrument::VisitFPConditionalCompare(const Instruction* instr) {
    577  USE(instr);
    578  Update();
    579  static Counter* counter = GetCounter("Conditional Compare");
    580  counter->Increment();
    581 }
    582 
    583 
    584 void Instrument::VisitFPConditionalSelect(const Instruction* instr) {
    585  USE(instr);
    586  Update();
    587  static Counter* counter = GetCounter("Conditional Select");
    588  counter->Increment();
    589 }
    590 
    591 
    592 void Instrument::VisitFPImmediate(const Instruction* instr) {
    593  USE(instr);
    594  Update();
    595  static Counter* counter = GetCounter("FP DP");
    596  counter->Increment();
    597 }
    598 
    599 
    600 void Instrument::VisitFPDataProcessing1Source(const Instruction* instr) {
    601  USE(instr);
    602  Update();
    603  static Counter* counter = GetCounter("FP DP");
    604  counter->Increment();
    605 }
    606 
    607 
    608 void Instrument::VisitFPDataProcessing2Source(const Instruction* instr) {
    609  USE(instr);
    610  Update();
    611  static Counter* counter = GetCounter("FP DP");
    612  counter->Increment();
    613 }
    614 
    615 
    616 void Instrument::VisitFPDataProcessing3Source(const Instruction* instr) {
    617  USE(instr);
    618  Update();
    619  static Counter* counter = GetCounter("FP DP");
    620  counter->Increment();
    621 }
    622 
    623 
    624 void Instrument::VisitFPIntegerConvert(const Instruction* instr) {
    625  USE(instr);
    626  Update();
    627  static Counter* counter = GetCounter("FP DP");
    628  counter->Increment();
    629 }
    630 
    631 
    632 void Instrument::VisitFPFixedPointConvert(const Instruction* instr) {
    633  USE(instr);
    634  Update();
    635  static Counter* counter = GetCounter("FP DP");
    636  counter->Increment();
    637 }
    638 
    639 
    640 void Instrument::VisitCrypto2RegSHA(const Instruction* instr) {
    641  USE(instr);
    642  Update();
    643  static Counter* counter = GetCounter("Crypto");
    644  counter->Increment();
    645 }
    646 
    647 
    648 void Instrument::VisitCrypto3RegSHA(const Instruction* instr) {
    649  USE(instr);
    650  Update();
    651  static Counter* counter = GetCounter("Crypto");
    652  counter->Increment();
    653 }
    654 
    655 
    656 void Instrument::VisitCryptoAES(const Instruction* instr) {
    657  USE(instr);
    658  Update();
    659  static Counter* counter = GetCounter("Crypto");
    660  counter->Increment();
    661 }
    662 
    663 
    664 void Instrument::VisitNEON2RegMisc(const Instruction* instr) {
    665  USE(instr);
    666  Update();
    667  static Counter* counter = GetCounter("NEON");
    668  counter->Increment();
    669 }
    670 
    671 
    672 void Instrument::VisitNEON3Same(const Instruction* instr) {
    673  USE(instr);
    674  Update();
    675  static Counter* counter = GetCounter("NEON");
    676  counter->Increment();
    677 }
    678 
    679 
    680 void Instrument::VisitNEON3Different(const Instruction* instr) {
    681  USE(instr);
    682  Update();
    683  static Counter* counter = GetCounter("NEON");
    684  counter->Increment();
    685 }
    686 
    687 
    688 void Instrument::VisitNEONAcrossLanes(const Instruction* instr) {
    689  USE(instr);
    690  Update();
    691  static Counter* counter = GetCounter("NEON");
    692  counter->Increment();
    693 }
    694 
    695 
    696 void Instrument::VisitNEONByIndexedElement(const Instruction* instr) {
    697  USE(instr);
    698  Update();
    699  static Counter* counter = GetCounter("NEON");
    700  counter->Increment();
    701 }
    702 
    703 
    704 void Instrument::VisitNEONCopy(const Instruction* instr) {
    705  USE(instr);
    706  Update();
    707  static Counter* counter = GetCounter("NEON");
    708  counter->Increment();
    709 }
    710 
    711 
    712 void Instrument::VisitNEONExtract(const Instruction* instr) {
    713  USE(instr);
    714  Update();
    715  static Counter* counter = GetCounter("NEON");
    716  counter->Increment();
    717 }
    718 
    719 
    720 void Instrument::VisitNEONLoadStoreMultiStruct(const Instruction* instr) {
    721  USE(instr);
    722  Update();
    723  static Counter* counter = GetCounter("NEON");
    724  counter->Increment();
    725 }
    726 
    727 
    728 void Instrument::VisitNEONLoadStoreMultiStructPostIndex(
    729    const Instruction* instr) {
    730  USE(instr);
    731  Update();
    732  static Counter* counter = GetCounter("NEON");
    733  counter->Increment();
    734 }
    735 
    736 
    737 void Instrument::VisitNEONLoadStoreSingleStruct(const Instruction* instr) {
    738  USE(instr);
    739  Update();
    740  static Counter* counter = GetCounter("NEON");
    741  counter->Increment();
    742 }
    743 
    744 
    745 void Instrument::VisitNEONLoadStoreSingleStructPostIndex(
    746    const Instruction* instr) {
    747  USE(instr);
    748  Update();
    749  static Counter* counter = GetCounter("NEON");
    750  counter->Increment();
    751 }
    752 
    753 
    754 void Instrument::VisitNEONModifiedImmediate(const Instruction* instr) {
    755  USE(instr);
    756  Update();
    757  static Counter* counter = GetCounter("NEON");
    758  counter->Increment();
    759 }
    760 
    761 
    762 void Instrument::VisitNEONScalar2RegMisc(const Instruction* instr) {
    763  USE(instr);
    764  Update();
    765  static Counter* counter = GetCounter("NEON");
    766  counter->Increment();
    767 }
    768 
    769 
    770 void Instrument::VisitNEONScalar3Diff(const Instruction* instr) {
    771  USE(instr);
    772  Update();
    773  static Counter* counter = GetCounter("NEON");
    774  counter->Increment();
    775 }
    776 
    777 
    778 void Instrument::VisitNEONScalar3Same(const Instruction* instr) {
    779  USE(instr);
    780  Update();
    781  static Counter* counter = GetCounter("NEON");
    782  counter->Increment();
    783 }
    784 
    785 
    786 void Instrument::VisitNEONScalarByIndexedElement(const Instruction* instr) {
    787  USE(instr);
    788  Update();
    789  static Counter* counter = GetCounter("NEON");
    790  counter->Increment();
    791 }
    792 
    793 
    794 void Instrument::VisitNEONScalarCopy(const Instruction* instr) {
    795  USE(instr);
    796  Update();
    797  static Counter* counter = GetCounter("NEON");
    798  counter->Increment();
    799 }
    800 
    801 
    802 void Instrument::VisitNEONScalarPairwise(const Instruction* instr) {
    803  USE(instr);
    804  Update();
    805  static Counter* counter = GetCounter("NEON");
    806  counter->Increment();
    807 }
    808 
    809 
    810 void Instrument::VisitNEONScalarShiftImmediate(const Instruction* instr) {
    811  USE(instr);
    812  Update();
    813  static Counter* counter = GetCounter("NEON");
    814  counter->Increment();
    815 }
    816 
    817 
    818 void Instrument::VisitNEONShiftImmediate(const Instruction* instr) {
    819  USE(instr);
    820  Update();
    821  static Counter* counter = GetCounter("NEON");
    822  counter->Increment();
    823 }
    824 
    825 
    826 void Instrument::VisitNEONTable(const Instruction* instr) {
    827  USE(instr);
    828  Update();
    829  static Counter* counter = GetCounter("NEON");
    830  counter->Increment();
    831 }
    832 
    833 
    834 void Instrument::VisitNEONPerm(const Instruction* instr) {
    835  USE(instr);
    836  Update();
    837  static Counter* counter = GetCounter("NEON");
    838  counter->Increment();
    839 }
    840 
    841 
    842 void Instrument::VisitUnallocated(const Instruction* instr) {
    843  USE(instr);
    844  Update();
    845  static Counter* counter = GetCounter("Other");
    846  counter->Increment();
    847 }
    848 
    849 
    850 void Instrument::VisitUnimplemented(const Instruction* instr) {
    851  USE(instr);
    852  Update();
    853  static Counter* counter = GetCounter("Other");
    854  counter->Increment();
    855 }
    856 
    857 
    858 }  // namespace vixl