• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "instrument-aarch64.h"
28 
29 namespace vixl {
30 namespace aarch64 {
31 
Counter(const char * name,CounterType type)32 Counter::Counter(const char* name, CounterType type)
33     : count_(0), enabled_(false), type_(type) {
34   VIXL_ASSERT(name != NULL);
35   strncpy(name_, name, kCounterNameMaxLength - 1);
36   // Make sure `name_` is always NULL-terminated, even if the source's length is
37   // higher.
38   name_[kCounterNameMaxLength - 1] = '\0';
39 }
40 
41 
Enable()42 void Counter::Enable() { enabled_ = true; }
43 
44 
Disable()45 void Counter::Disable() { enabled_ = false; }
46 
47 
IsEnabled()48 bool Counter::IsEnabled() { return enabled_; }
49 
50 
Increment()51 void Counter::Increment() {
52   if (enabled_) {
53     count_++;
54   }
55 }
56 
57 
GetCount()58 uint64_t Counter::GetCount() {
59   uint64_t result = count_;
60   if (type_ == Gauge) {
61     // If the counter is a Gauge, reset the count after reading.
62     count_ = 0;
63   }
64   return result;
65 }
66 
67 
GetName()68 const char* Counter::GetName() { return name_; }
69 
70 
GetType()71 CounterType Counter::GetType() { return type_; }
72 
73 
74 struct CounterDescriptor {
75   const char* name;
76   CounterType type;
77 };
78 
79 
80 static const CounterDescriptor kCounterList[] =
81     {{"Instruction", Cumulative},
82 
83      {"Move Immediate", Gauge},
84      {"Add/Sub DP", Gauge},
85      {"Logical DP", Gauge},
86      {"Other Int DP", Gauge},
87      {"FP DP", Gauge},
88 
89      {"Conditional Select", Gauge},
90      {"Conditional Compare", Gauge},
91 
92      {"Unconditional Branch", Gauge},
93      {"Compare and Branch", Gauge},
94      {"Test and Branch", Gauge},
95      {"Conditional Branch", Gauge},
96 
97      {"Load Integer", Gauge},
98      {"Load FP", Gauge},
99      {"Load Pair", Gauge},
100      {"Load Literal", Gauge},
101 
102      {"Store Integer", Gauge},
103      {"Store FP", Gauge},
104      {"Store Pair", Gauge},
105 
106      {"PC Addressing", Gauge},
107      {"Other", Gauge},
108      {"NEON", Gauge},
109      {"Crypto", Gauge}};
110 
111 
Instrument(const char * datafile,uint64_t sample_period)112 Instrument::Instrument(const char* datafile, uint64_t sample_period)
113     : output_stream_(stdout), sample_period_(sample_period) {
114   // Set up the output stream. If datafile is non-NULL, use that file. If it
115   // can't be opened, or datafile is NULL, use stdout.
116   if (datafile != NULL) {
117     output_stream_ = fopen(datafile, "w");
118     if (output_stream_ == NULL) {
119       printf("Can't open output file %s. Using stdout.\n", datafile);
120       output_stream_ = stdout;
121     }
122   }
123 
124   static const int num_counters =
125       sizeof(kCounterList) / sizeof(CounterDescriptor);
126 
127   // Dump an instrumentation description comment at the top of the file.
128   fprintf(output_stream_, "# counters=%d\n", num_counters);
129   fprintf(output_stream_, "# sample_period=%" PRIu64 "\n", sample_period_);
130 
131   // Construct Counter objects from counter description array.
132   for (int i = 0; i < num_counters; i++) {
133     Counter* counter = new Counter(kCounterList[i].name, kCounterList[i].type);
134     counters_.push_back(counter);
135   }
136 
137   DumpCounterNames();
138 }
139 
140 
~Instrument()141 Instrument::~Instrument() {
142   // Dump any remaining instruction data to the output file.
143   DumpCounters();
144 
145   // Free all the counter objects.
146   std::list<Counter*>::iterator it;
147   for (it = counters_.begin(); it != counters_.end(); it++) {
148     delete *it;
149   }
150 
151   if (output_stream_ != stdout) {
152     fclose(output_stream_);
153   }
154 }
155 
156 
Update()157 void Instrument::Update() {
158   // Increment the instruction counter, and dump all counters if a sample period
159   // has elapsed.
160   static Counter* counter = GetCounter("Instruction");
161   VIXL_ASSERT(counter->GetType() == Cumulative);
162   counter->Increment();
163 
164   if ((sample_period_ != 0) && counter->IsEnabled() &&
165       (counter->GetCount() % sample_period_) == 0) {
166     DumpCounters();
167   }
168 }
169 
170 
DumpCounters()171 void Instrument::DumpCounters() {
172   // Iterate through the counter objects, dumping their values to the output
173   // stream.
174   std::list<Counter*>::const_iterator it;
175   for (it = counters_.begin(); it != counters_.end(); it++) {
176     fprintf(output_stream_, "%" PRIu64 ",", (*it)->GetCount());
177   }
178   fprintf(output_stream_, "\n");
179   fflush(output_stream_);
180 }
181 
182 
DumpCounterNames()183 void Instrument::DumpCounterNames() {
184   // Iterate through the counter objects, dumping the counter names to the
185   // output stream.
186   std::list<Counter*>::const_iterator it;
187   for (it = counters_.begin(); it != counters_.end(); it++) {
188     fprintf(output_stream_, "%s,", (*it)->GetName());
189   }
190   fprintf(output_stream_, "\n");
191   fflush(output_stream_);
192 }
193 
194 
HandleInstrumentationEvent(unsigned event)195 void Instrument::HandleInstrumentationEvent(unsigned event) {
196   switch (event) {
197     case InstrumentStateEnable:
198       Enable();
199       break;
200     case InstrumentStateDisable:
201       Disable();
202       break;
203     default:
204       DumpEventMarker(event);
205   }
206 }
207 
208 
DumpEventMarker(unsigned marker)209 void Instrument::DumpEventMarker(unsigned marker) {
210   // Dumpan event marker to the output stream as a specially formatted comment
211   // line.
212   static Counter* counter = GetCounter("Instruction");
213 
214   fprintf(output_stream_,
215           "# %c%c @ %" PRId64 "\n",
216           marker & 0xff,
217           (marker >> 8) & 0xff,
218           counter->GetCount());
219 }
220 
221 
GetCounter(const char * name)222 Counter* Instrument::GetCounter(const char* name) {
223   // Get a Counter object by name from the counter list.
224   std::list<Counter*>::const_iterator it;
225   for (it = counters_.begin(); it != counters_.end(); it++) {
226     if (strcmp((*it)->GetName(), name) == 0) {
227       return *it;
228     }
229   }
230 
231   // A Counter by that name does not exist: print an error message to stderr
232   // and the output file, and exit.
233   static const char* error_message =
234       "# Error: Unknown counter \"%s\". Exiting.\n";
235   fprintf(stderr, error_message, name);
236   fprintf(output_stream_, error_message, name);
237   exit(1);
238 }
239 
240 
Enable()241 void Instrument::Enable() {
242   std::list<Counter*>::iterator it;
243   for (it = counters_.begin(); it != counters_.end(); it++) {
244     (*it)->Enable();
245   }
246 }
247 
248 
Disable()249 void Instrument::Disable() {
250   std::list<Counter*>::iterator it;
251   for (it = counters_.begin(); it != counters_.end(); it++) {
252     (*it)->Disable();
253   }
254 }
255 
256 
VisitPCRelAddressing(const Instruction * instr)257 void Instrument::VisitPCRelAddressing(const Instruction* instr) {
258   USE(instr);
259   Update();
260   static Counter* counter = GetCounter("PC Addressing");
261   counter->Increment();
262 }
263 
264 
VisitAddSubImmediate(const Instruction * instr)265 void Instrument::VisitAddSubImmediate(const Instruction* instr) {
266   USE(instr);
267   Update();
268   static Counter* counter = GetCounter("Add/Sub DP");
269   counter->Increment();
270 }
271 
272 
VisitLogicalImmediate(const Instruction * instr)273 void Instrument::VisitLogicalImmediate(const Instruction* instr) {
274   USE(instr);
275   Update();
276   static Counter* counter = GetCounter("Logical DP");
277   counter->Increment();
278 }
279 
280 
VisitMoveWideImmediate(const Instruction * instr)281 void Instrument::VisitMoveWideImmediate(const Instruction* instr) {
282   Update();
283   static Counter* counter = GetCounter("Move Immediate");
284 
285   if (instr->IsMovn() && (instr->GetRd() == kZeroRegCode)) {
286     unsigned imm = instr->GetImmMoveWide();
287     HandleInstrumentationEvent(imm);
288   } else {
289     counter->Increment();
290   }
291 }
292 
293 
VisitBitfield(const Instruction * instr)294 void Instrument::VisitBitfield(const Instruction* instr) {
295   USE(instr);
296   Update();
297   static Counter* counter = GetCounter("Other Int DP");
298   counter->Increment();
299 }
300 
301 
VisitExtract(const Instruction * instr)302 void Instrument::VisitExtract(const Instruction* instr) {
303   USE(instr);
304   Update();
305   static Counter* counter = GetCounter("Other Int DP");
306   counter->Increment();
307 }
308 
309 
VisitUnconditionalBranch(const Instruction * instr)310 void Instrument::VisitUnconditionalBranch(const Instruction* instr) {
311   USE(instr);
312   Update();
313   static Counter* counter = GetCounter("Unconditional Branch");
314   counter->Increment();
315 }
316 
317 
VisitUnconditionalBranchToRegister(const Instruction * instr)318 void Instrument::VisitUnconditionalBranchToRegister(const Instruction* instr) {
319   USE(instr);
320   Update();
321   static Counter* counter = GetCounter("Unconditional Branch");
322   counter->Increment();
323 }
324 
325 
VisitCompareBranch(const Instruction * instr)326 void Instrument::VisitCompareBranch(const Instruction* instr) {
327   USE(instr);
328   Update();
329   static Counter* counter = GetCounter("Compare and Branch");
330   counter->Increment();
331 }
332 
333 
VisitTestBranch(const Instruction * instr)334 void Instrument::VisitTestBranch(const Instruction* instr) {
335   USE(instr);
336   Update();
337   static Counter* counter = GetCounter("Test and Branch");
338   counter->Increment();
339 }
340 
341 
VisitConditionalBranch(const Instruction * instr)342 void Instrument::VisitConditionalBranch(const Instruction* instr) {
343   USE(instr);
344   Update();
345   static Counter* counter = GetCounter("Conditional Branch");
346   counter->Increment();
347 }
348 
349 
VisitSystem(const Instruction * instr)350 void Instrument::VisitSystem(const Instruction* instr) {
351   USE(instr);
352   Update();
353   static Counter* counter = GetCounter("Other");
354   counter->Increment();
355 }
356 
357 
VisitException(const Instruction * instr)358 void Instrument::VisitException(const Instruction* instr) {
359   USE(instr);
360   Update();
361   static Counter* counter = GetCounter("Other");
362   counter->Increment();
363 }
364 
365 
InstrumentLoadStorePair(const Instruction * instr)366 void Instrument::InstrumentLoadStorePair(const Instruction* instr) {
367   static Counter* load_pair_counter = GetCounter("Load Pair");
368   static Counter* store_pair_counter = GetCounter("Store Pair");
369 
370   if (instr->Mask(LoadStorePairLBit) != 0) {
371     load_pair_counter->Increment();
372   } else {
373     store_pair_counter->Increment();
374   }
375 }
376 
377 
VisitLoadStorePairPostIndex(const Instruction * instr)378 void Instrument::VisitLoadStorePairPostIndex(const Instruction* instr) {
379   Update();
380   InstrumentLoadStorePair(instr);
381 }
382 
383 
VisitLoadStorePairOffset(const Instruction * instr)384 void Instrument::VisitLoadStorePairOffset(const Instruction* instr) {
385   Update();
386   InstrumentLoadStorePair(instr);
387 }
388 
389 
VisitLoadStorePairPreIndex(const Instruction * instr)390 void Instrument::VisitLoadStorePairPreIndex(const Instruction* instr) {
391   Update();
392   InstrumentLoadStorePair(instr);
393 }
394 
395 
VisitLoadStorePairNonTemporal(const Instruction * instr)396 void Instrument::VisitLoadStorePairNonTemporal(const Instruction* instr) {
397   Update();
398   InstrumentLoadStorePair(instr);
399 }
400 
401 
VisitLoadStoreExclusive(const Instruction * instr)402 void Instrument::VisitLoadStoreExclusive(const Instruction* instr) {
403   USE(instr);
404   Update();
405   static Counter* counter = GetCounter("Other");
406   counter->Increment();
407 }
408 
409 
VisitAtomicMemory(const Instruction * instr)410 void Instrument::VisitAtomicMemory(const Instruction* instr) {
411   USE(instr);
412   Update();
413   static Counter* counter = GetCounter("Other");
414   counter->Increment();
415 }
416 
417 
VisitLoadLiteral(const Instruction * instr)418 void Instrument::VisitLoadLiteral(const Instruction* instr) {
419   USE(instr);
420   Update();
421   static Counter* counter = GetCounter("Load Literal");
422   counter->Increment();
423 }
424 
425 
VisitLoadStorePAC(const Instruction * instr)426 void Instrument::VisitLoadStorePAC(const Instruction* instr) {
427   USE(instr);
428   Update();
429   static Counter* counter = GetCounter("Load Integer");
430   counter->Increment();
431 }
432 
433 
InstrumentLoadStore(const Instruction * instr)434 void Instrument::InstrumentLoadStore(const Instruction* instr) {
435   static Counter* load_int_counter = GetCounter("Load Integer");
436   static Counter* store_int_counter = GetCounter("Store Integer");
437   static Counter* load_fp_counter = GetCounter("Load FP");
438   static Counter* store_fp_counter = GetCounter("Store FP");
439 
440   switch (instr->Mask(LoadStoreMask)) {
441     case STRB_w:
442     case STRH_w:
443     case STR_w:
444       VIXL_FALLTHROUGH();
445     case STR_x:
446       store_int_counter->Increment();
447       break;
448     case STR_s:
449       VIXL_FALLTHROUGH();
450     case STR_d:
451       store_fp_counter->Increment();
452       break;
453     case LDRB_w:
454     case LDRH_w:
455     case LDR_w:
456     case LDR_x:
457     case LDRSB_x:
458     case LDRSH_x:
459     case LDRSW_x:
460     case LDRSB_w:
461       VIXL_FALLTHROUGH();
462     case LDRSH_w:
463       load_int_counter->Increment();
464       break;
465     case LDR_s:
466       VIXL_FALLTHROUGH();
467     case LDR_d:
468       load_fp_counter->Increment();
469       break;
470   }
471 }
472 
473 
VisitLoadStoreUnscaledOffset(const Instruction * instr)474 void Instrument::VisitLoadStoreUnscaledOffset(const Instruction* instr) {
475   Update();
476   InstrumentLoadStore(instr);
477 }
478 
479 
VisitLoadStorePostIndex(const Instruction * instr)480 void Instrument::VisitLoadStorePostIndex(const Instruction* instr) {
481   USE(instr);
482   Update();
483   InstrumentLoadStore(instr);
484 }
485 
486 
VisitLoadStorePreIndex(const Instruction * instr)487 void Instrument::VisitLoadStorePreIndex(const Instruction* instr) {
488   Update();
489   InstrumentLoadStore(instr);
490 }
491 
492 
VisitLoadStoreRegisterOffset(const Instruction * instr)493 void Instrument::VisitLoadStoreRegisterOffset(const Instruction* instr) {
494   Update();
495   InstrumentLoadStore(instr);
496 }
497 
VisitLoadStoreRCpcUnscaledOffset(const Instruction * instr)498 void Instrument::VisitLoadStoreRCpcUnscaledOffset(const Instruction* instr) {
499   Update();
500   switch (instr->Mask(LoadStoreRCpcUnscaledOffsetMask)) {
501     case STLURB:
502     case STLURH:
503     case STLUR_w:
504     case STLUR_x: {
505       static Counter* counter = GetCounter("Store Integer");
506       counter->Increment();
507       break;
508     }
509     case LDAPURB:
510     case LDAPURSB_w:
511     case LDAPURSB_x:
512     case LDAPURH:
513     case LDAPURSH_w:
514     case LDAPURSH_x:
515     case LDAPUR_w:
516     case LDAPURSW:
517     case LDAPUR_x: {
518       static Counter* counter = GetCounter("Load Integer");
519       counter->Increment();
520       break;
521     }
522   }
523 }
524 
525 
VisitLoadStoreUnsignedOffset(const Instruction * instr)526 void Instrument::VisitLoadStoreUnsignedOffset(const Instruction* instr) {
527   Update();
528   InstrumentLoadStore(instr);
529 }
530 
531 
VisitLogicalShifted(const Instruction * instr)532 void Instrument::VisitLogicalShifted(const Instruction* instr) {
533   USE(instr);
534   Update();
535   static Counter* counter = GetCounter("Logical DP");
536   counter->Increment();
537 }
538 
539 
VisitAddSubShifted(const Instruction * instr)540 void Instrument::VisitAddSubShifted(const Instruction* instr) {
541   USE(instr);
542   Update();
543   static Counter* counter = GetCounter("Add/Sub DP");
544   counter->Increment();
545 }
546 
547 
VisitAddSubExtended(const Instruction * instr)548 void Instrument::VisitAddSubExtended(const Instruction* instr) {
549   USE(instr);
550   Update();
551   static Counter* counter = GetCounter("Add/Sub DP");
552   counter->Increment();
553 }
554 
555 
VisitAddSubWithCarry(const Instruction * instr)556 void Instrument::VisitAddSubWithCarry(const Instruction* instr) {
557   USE(instr);
558   Update();
559   static Counter* counter = GetCounter("Add/Sub DP");
560   counter->Increment();
561 }
562 
563 
VisitRotateRightIntoFlags(const Instruction * instr)564 void Instrument::VisitRotateRightIntoFlags(const Instruction* instr) {
565   USE(instr);
566   Update();
567   static Counter* counter = GetCounter("Other");
568   counter->Increment();
569 }
570 
571 
VisitEvaluateIntoFlags(const Instruction * instr)572 void Instrument::VisitEvaluateIntoFlags(const Instruction* instr) {
573   USE(instr);
574   Update();
575   static Counter* counter = GetCounter("Other");
576   counter->Increment();
577 }
578 
579 
VisitConditionalCompareRegister(const Instruction * instr)580 void Instrument::VisitConditionalCompareRegister(const Instruction* instr) {
581   USE(instr);
582   Update();
583   static Counter* counter = GetCounter("Conditional Compare");
584   counter->Increment();
585 }
586 
587 
VisitConditionalCompareImmediate(const Instruction * instr)588 void Instrument::VisitConditionalCompareImmediate(const Instruction* instr) {
589   USE(instr);
590   Update();
591   static Counter* counter = GetCounter("Conditional Compare");
592   counter->Increment();
593 }
594 
595 
VisitConditionalSelect(const Instruction * instr)596 void Instrument::VisitConditionalSelect(const Instruction* instr) {
597   USE(instr);
598   Update();
599   static Counter* counter = GetCounter("Conditional Select");
600   counter->Increment();
601 }
602 
603 
VisitDataProcessing1Source(const Instruction * instr)604 void Instrument::VisitDataProcessing1Source(const Instruction* instr) {
605   USE(instr);
606   Update();
607   static Counter* counter = GetCounter("Other Int DP");
608   counter->Increment();
609 }
610 
611 
VisitDataProcessing2Source(const Instruction * instr)612 void Instrument::VisitDataProcessing2Source(const Instruction* instr) {
613   USE(instr);
614   Update();
615   static Counter* counter = GetCounter("Other Int DP");
616   counter->Increment();
617 }
618 
619 
VisitDataProcessing3Source(const Instruction * instr)620 void Instrument::VisitDataProcessing3Source(const Instruction* instr) {
621   USE(instr);
622   Update();
623   static Counter* counter = GetCounter("Other Int DP");
624   counter->Increment();
625 }
626 
627 
VisitFPCompare(const Instruction * instr)628 void Instrument::VisitFPCompare(const Instruction* instr) {
629   USE(instr);
630   Update();
631   static Counter* counter = GetCounter("FP DP");
632   counter->Increment();
633 }
634 
635 
VisitFPConditionalCompare(const Instruction * instr)636 void Instrument::VisitFPConditionalCompare(const Instruction* instr) {
637   USE(instr);
638   Update();
639   static Counter* counter = GetCounter("Conditional Compare");
640   counter->Increment();
641 }
642 
643 
VisitFPConditionalSelect(const Instruction * instr)644 void Instrument::VisitFPConditionalSelect(const Instruction* instr) {
645   USE(instr);
646   Update();
647   static Counter* counter = GetCounter("Conditional Select");
648   counter->Increment();
649 }
650 
651 
VisitFPImmediate(const Instruction * instr)652 void Instrument::VisitFPImmediate(const Instruction* instr) {
653   USE(instr);
654   Update();
655   static Counter* counter = GetCounter("FP DP");
656   counter->Increment();
657 }
658 
659 
VisitFPDataProcessing1Source(const Instruction * instr)660 void Instrument::VisitFPDataProcessing1Source(const Instruction* instr) {
661   USE(instr);
662   Update();
663   static Counter* counter = GetCounter("FP DP");
664   counter->Increment();
665 }
666 
667 
VisitFPDataProcessing2Source(const Instruction * instr)668 void Instrument::VisitFPDataProcessing2Source(const Instruction* instr) {
669   USE(instr);
670   Update();
671   static Counter* counter = GetCounter("FP DP");
672   counter->Increment();
673 }
674 
675 
VisitFPDataProcessing3Source(const Instruction * instr)676 void Instrument::VisitFPDataProcessing3Source(const Instruction* instr) {
677   USE(instr);
678   Update();
679   static Counter* counter = GetCounter("FP DP");
680   counter->Increment();
681 }
682 
683 
VisitFPIntegerConvert(const Instruction * instr)684 void Instrument::VisitFPIntegerConvert(const Instruction* instr) {
685   USE(instr);
686   Update();
687   static Counter* counter = GetCounter("FP DP");
688   counter->Increment();
689 }
690 
691 
VisitFPFixedPointConvert(const Instruction * instr)692 void Instrument::VisitFPFixedPointConvert(const Instruction* instr) {
693   USE(instr);
694   Update();
695   static Counter* counter = GetCounter("FP DP");
696   counter->Increment();
697 }
698 
699 
VisitCrypto2RegSHA(const Instruction * instr)700 void Instrument::VisitCrypto2RegSHA(const Instruction* instr) {
701   USE(instr);
702   Update();
703   static Counter* counter = GetCounter("Crypto");
704   counter->Increment();
705 }
706 
707 
VisitCrypto3RegSHA(const Instruction * instr)708 void Instrument::VisitCrypto3RegSHA(const Instruction* instr) {
709   USE(instr);
710   Update();
711   static Counter* counter = GetCounter("Crypto");
712   counter->Increment();
713 }
714 
715 
VisitCryptoAES(const Instruction * instr)716 void Instrument::VisitCryptoAES(const Instruction* instr) {
717   USE(instr);
718   Update();
719   static Counter* counter = GetCounter("Crypto");
720   counter->Increment();
721 }
722 
723 
VisitNEON2RegMisc(const Instruction * instr)724 void Instrument::VisitNEON2RegMisc(const Instruction* instr) {
725   USE(instr);
726   Update();
727   static Counter* counter = GetCounter("NEON");
728   counter->Increment();
729 }
730 
731 
VisitNEON2RegMiscFP16(const Instruction * instr)732 void Instrument::VisitNEON2RegMiscFP16(const Instruction* instr) {
733   USE(instr);
734   Update();
735   static Counter* counter = GetCounter("NEON");
736   counter->Increment();
737 }
738 
739 
VisitNEON3Same(const Instruction * instr)740 void Instrument::VisitNEON3Same(const Instruction* instr) {
741   USE(instr);
742   Update();
743   static Counter* counter = GetCounter("NEON");
744   counter->Increment();
745 }
746 
747 
VisitNEON3SameFP16(const Instruction * instr)748 void Instrument::VisitNEON3SameFP16(const Instruction* instr) {
749   USE(instr);
750   Update();
751   static Counter* counter = GetCounter("NEON");
752   counter->Increment();
753 }
754 
755 
VisitNEON3SameExtra(const Instruction * instr)756 void Instrument::VisitNEON3SameExtra(const Instruction* instr) {
757   USE(instr);
758   Update();
759   static Counter* counter = GetCounter("NEON");
760   counter->Increment();
761 }
762 
763 
VisitNEON3Different(const Instruction * instr)764 void Instrument::VisitNEON3Different(const Instruction* instr) {
765   USE(instr);
766   Update();
767   static Counter* counter = GetCounter("NEON");
768   counter->Increment();
769 }
770 
771 
VisitNEONAcrossLanes(const Instruction * instr)772 void Instrument::VisitNEONAcrossLanes(const Instruction* instr) {
773   USE(instr);
774   Update();
775   static Counter* counter = GetCounter("NEON");
776   counter->Increment();
777 }
778 
779 
VisitNEONByIndexedElement(const Instruction * instr)780 void Instrument::VisitNEONByIndexedElement(const Instruction* instr) {
781   USE(instr);
782   Update();
783   static Counter* counter = GetCounter("NEON");
784   counter->Increment();
785 }
786 
787 
VisitNEONCopy(const Instruction * instr)788 void Instrument::VisitNEONCopy(const Instruction* instr) {
789   USE(instr);
790   Update();
791   static Counter* counter = GetCounter("NEON");
792   counter->Increment();
793 }
794 
795 
VisitNEONExtract(const Instruction * instr)796 void Instrument::VisitNEONExtract(const Instruction* instr) {
797   USE(instr);
798   Update();
799   static Counter* counter = GetCounter("NEON");
800   counter->Increment();
801 }
802 
803 
VisitNEONLoadStoreMultiStruct(const Instruction * instr)804 void Instrument::VisitNEONLoadStoreMultiStruct(const Instruction* instr) {
805   USE(instr);
806   Update();
807   static Counter* counter = GetCounter("NEON");
808   counter->Increment();
809 }
810 
811 
VisitNEONLoadStoreMultiStructPostIndex(const Instruction * instr)812 void Instrument::VisitNEONLoadStoreMultiStructPostIndex(
813     const Instruction* instr) {
814   USE(instr);
815   Update();
816   static Counter* counter = GetCounter("NEON");
817   counter->Increment();
818 }
819 
820 
VisitNEONLoadStoreSingleStruct(const Instruction * instr)821 void Instrument::VisitNEONLoadStoreSingleStruct(const Instruction* instr) {
822   USE(instr);
823   Update();
824   static Counter* counter = GetCounter("NEON");
825   counter->Increment();
826 }
827 
828 
VisitNEONLoadStoreSingleStructPostIndex(const Instruction * instr)829 void Instrument::VisitNEONLoadStoreSingleStructPostIndex(
830     const Instruction* instr) {
831   USE(instr);
832   Update();
833   static Counter* counter = GetCounter("NEON");
834   counter->Increment();
835 }
836 
837 
VisitNEONModifiedImmediate(const Instruction * instr)838 void Instrument::VisitNEONModifiedImmediate(const Instruction* instr) {
839   USE(instr);
840   Update();
841   static Counter* counter = GetCounter("NEON");
842   counter->Increment();
843 }
844 
845 
VisitNEONScalar2RegMisc(const Instruction * instr)846 void Instrument::VisitNEONScalar2RegMisc(const Instruction* instr) {
847   USE(instr);
848   Update();
849   static Counter* counter = GetCounter("NEON");
850   counter->Increment();
851 }
852 
853 
VisitNEONScalar2RegMiscFP16(const Instruction * instr)854 void Instrument::VisitNEONScalar2RegMiscFP16(const Instruction* instr) {
855   USE(instr);
856   Update();
857   static Counter* counter = GetCounter("NEON");
858   counter->Increment();
859 }
860 
861 
VisitNEONScalar3Diff(const Instruction * instr)862 void Instrument::VisitNEONScalar3Diff(const Instruction* instr) {
863   USE(instr);
864   Update();
865   static Counter* counter = GetCounter("NEON");
866   counter->Increment();
867 }
868 
869 
VisitNEONScalar3Same(const Instruction * instr)870 void Instrument::VisitNEONScalar3Same(const Instruction* instr) {
871   USE(instr);
872   Update();
873   static Counter* counter = GetCounter("NEON");
874   counter->Increment();
875 }
876 
877 
VisitNEONScalar3SameFP16(const Instruction * instr)878 void Instrument::VisitNEONScalar3SameFP16(const Instruction* instr) {
879   USE(instr);
880   Update();
881   static Counter* counter = GetCounter("NEON");
882   counter->Increment();
883 }
884 
885 
VisitNEONScalar3SameExtra(const Instruction * instr)886 void Instrument::VisitNEONScalar3SameExtra(const Instruction* instr) {
887   USE(instr);
888   Update();
889   static Counter* counter = GetCounter("NEON");
890   counter->Increment();
891 }
892 
893 
VisitNEONScalarByIndexedElement(const Instruction * instr)894 void Instrument::VisitNEONScalarByIndexedElement(const Instruction* instr) {
895   USE(instr);
896   Update();
897   static Counter* counter = GetCounter("NEON");
898   counter->Increment();
899 }
900 
901 
VisitNEONScalarCopy(const Instruction * instr)902 void Instrument::VisitNEONScalarCopy(const Instruction* instr) {
903   USE(instr);
904   Update();
905   static Counter* counter = GetCounter("NEON");
906   counter->Increment();
907 }
908 
909 
VisitNEONScalarPairwise(const Instruction * instr)910 void Instrument::VisitNEONScalarPairwise(const Instruction* instr) {
911   USE(instr);
912   Update();
913   static Counter* counter = GetCounter("NEON");
914   counter->Increment();
915 }
916 
917 
VisitNEONScalarShiftImmediate(const Instruction * instr)918 void Instrument::VisitNEONScalarShiftImmediate(const Instruction* instr) {
919   USE(instr);
920   Update();
921   static Counter* counter = GetCounter("NEON");
922   counter->Increment();
923 }
924 
925 
VisitNEONShiftImmediate(const Instruction * instr)926 void Instrument::VisitNEONShiftImmediate(const Instruction* instr) {
927   USE(instr);
928   Update();
929   static Counter* counter = GetCounter("NEON");
930   counter->Increment();
931 }
932 
933 
VisitNEONTable(const Instruction * instr)934 void Instrument::VisitNEONTable(const Instruction* instr) {
935   USE(instr);
936   Update();
937   static Counter* counter = GetCounter("NEON");
938   counter->Increment();
939 }
940 
941 
VisitNEONPerm(const Instruction * instr)942 void Instrument::VisitNEONPerm(const Instruction* instr) {
943   USE(instr);
944   Update();
945   static Counter* counter = GetCounter("NEON");
946   counter->Increment();
947 }
948 
949 
VisitReserved(const Instruction * instr)950 void Instrument::VisitReserved(const Instruction* instr) {
951   USE(instr);
952   Update();
953   static Counter* counter = GetCounter("Other");
954   counter->Increment();
955 }
956 
957 
VisitUnallocated(const Instruction * instr)958 void Instrument::VisitUnallocated(const Instruction* instr) {
959   USE(instr);
960   Update();
961   static Counter* counter = GetCounter("Other");
962   counter->Increment();
963 }
964 
965 
VisitUnimplemented(const Instruction * instr)966 void Instrument::VisitUnimplemented(const Instruction* instr) {
967   USE(instr);
968   Update();
969   static Counter* counter = GetCounter("Other");
970   counter->Increment();
971 }
972 
973 
974 }  // namespace aarch64
975 }  // namespace vixl
976