• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014, ARM Limited
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 "vixl/a64/instrument-a64.h"
28 
29 namespace vixl {
30 
Counter(const char * name,CounterType type)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 
Enable()38 void Counter::Enable() {
39   enabled_ = true;
40 }
41 
42 
Disable()43 void Counter::Disable() {
44   enabled_ = false;
45 }
46 
47 
IsEnabled()48 bool Counter::IsEnabled() {
49   return enabled_;
50 }
51 
52 
Increment()53 void Counter::Increment() {
54   if (enabled_) {
55     count_++;
56   }
57 }
58 
59 
count()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 
name()70 const char* Counter::name() {
71   return name_;
72 }
73 
74 
type()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 
Instrument(const char * datafile,uint64_t sample_period)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     Counter* counter = new Counter(kCounterList[i].name, kCounterList[i].type);
142     counters_.push_back(counter);
143   }
144 
145   DumpCounterNames();
146 }
147 
148 
~Instrument()149 Instrument::~Instrument() {
150   // Dump any remaining instruction data to the output file.
151   DumpCounters();
152 
153   // Free all the counter objects.
154   std::list<Counter*>::iterator it;
155   for (it = counters_.begin(); it != counters_.end(); it++) {
156     delete *it;
157   }
158 
159   if (output_stream_ != stdout) {
160     fclose(output_stream_);
161   }
162 }
163 
164 
Update()165 void Instrument::Update() {
166   // Increment the instruction counter, and dump all counters if a sample period
167   // has elapsed.
168   static Counter* counter = GetCounter("Instruction");
169   VIXL_ASSERT(counter->type() == Cumulative);
170   counter->Increment();
171 
172   if (counter->IsEnabled() && (counter->count() % sample_period_) == 0) {
173     DumpCounters();
174   }
175 }
176 
177 
DumpCounters()178 void Instrument::DumpCounters() {
179   // Iterate through the counter objects, dumping their values to the output
180   // stream.
181   std::list<Counter*>::const_iterator it;
182   for (it = counters_.begin(); it != counters_.end(); it++) {
183     fprintf(output_stream_, "%" PRIu64 ",", (*it)->count());
184   }
185   fprintf(output_stream_, "\n");
186   fflush(output_stream_);
187 }
188 
189 
DumpCounterNames()190 void Instrument::DumpCounterNames() {
191   // Iterate through the counter objects, dumping the counter names to the
192   // output stream.
193   std::list<Counter*>::const_iterator it;
194   for (it = counters_.begin(); it != counters_.end(); it++) {
195     fprintf(output_stream_, "%s,", (*it)->name());
196   }
197   fprintf(output_stream_, "\n");
198   fflush(output_stream_);
199 }
200 
201 
HandleInstrumentationEvent(unsigned event)202 void Instrument::HandleInstrumentationEvent(unsigned event) {
203   switch (event) {
204     case InstrumentStateEnable: Enable(); break;
205     case InstrumentStateDisable: Disable(); break;
206     default: DumpEventMarker(event);
207   }
208 }
209 
210 
DumpEventMarker(unsigned marker)211 void Instrument::DumpEventMarker(unsigned marker) {
212   // Dumpan event marker to the output stream as a specially formatted comment
213   // line.
214   static Counter* counter = GetCounter("Instruction");
215 
216   fprintf(output_stream_, "# %c%c @ %" PRId64 "\n", marker & 0xff,
217           (marker >> 8) & 0xff, counter->count());
218 }
219 
220 
GetCounter(const char * name)221 Counter* Instrument::GetCounter(const char* name) {
222   // Get a Counter object by name from the counter list.
223   std::list<Counter*>::const_iterator it;
224   for (it = counters_.begin(); it != counters_.end(); it++) {
225     if (strcmp((*it)->name(), name) == 0) {
226       return *it;
227     }
228   }
229 
230   // A Counter by that name does not exist: print an error message to stderr
231   // and the output file, and exit.
232   static const char* error_message =
233     "# Error: Unknown counter \"%s\". Exiting.\n";
234   fprintf(stderr, error_message, name);
235   fprintf(output_stream_, error_message, name);
236   exit(1);
237 }
238 
239 
Enable()240 void Instrument::Enable() {
241   std::list<Counter*>::iterator it;
242   for (it = counters_.begin(); it != counters_.end(); it++) {
243     (*it)->Enable();
244   }
245 }
246 
247 
Disable()248 void Instrument::Disable() {
249   std::list<Counter*>::iterator it;
250   for (it = counters_.begin(); it != counters_.end(); it++) {
251     (*it)->Disable();
252   }
253 }
254 
255 
VisitPCRelAddressing(const Instruction * instr)256 void Instrument::VisitPCRelAddressing(const Instruction* instr) {
257   USE(instr);
258   Update();
259   static Counter* counter = GetCounter("PC Addressing");
260   counter->Increment();
261 }
262 
263 
VisitAddSubImmediate(const Instruction * instr)264 void Instrument::VisitAddSubImmediate(const Instruction* instr) {
265   USE(instr);
266   Update();
267   static Counter* counter = GetCounter("Add/Sub DP");
268   counter->Increment();
269 }
270 
271 
VisitLogicalImmediate(const Instruction * instr)272 void Instrument::VisitLogicalImmediate(const Instruction* instr) {
273   USE(instr);
274   Update();
275   static Counter* counter = GetCounter("Logical DP");
276   counter->Increment();
277 }
278 
279 
VisitMoveWideImmediate(const Instruction * instr)280 void Instrument::VisitMoveWideImmediate(const Instruction* instr) {
281   Update();
282   static Counter* counter = GetCounter("Move Immediate");
283 
284   if (instr->IsMovn() && (instr->Rd() == kZeroRegCode)) {
285     unsigned imm = instr->ImmMoveWide();
286     HandleInstrumentationEvent(imm);
287   } else {
288     counter->Increment();
289   }
290 }
291 
292 
VisitBitfield(const Instruction * instr)293 void Instrument::VisitBitfield(const Instruction* instr) {
294   USE(instr);
295   Update();
296   static Counter* counter = GetCounter("Other Int DP");
297   counter->Increment();
298 }
299 
300 
VisitExtract(const Instruction * instr)301 void Instrument::VisitExtract(const Instruction* instr) {
302   USE(instr);
303   Update();
304   static Counter* counter = GetCounter("Other Int DP");
305   counter->Increment();
306 }
307 
308 
VisitUnconditionalBranch(const Instruction * instr)309 void Instrument::VisitUnconditionalBranch(const Instruction* instr) {
310   USE(instr);
311   Update();
312   static Counter* counter = GetCounter("Unconditional Branch");
313   counter->Increment();
314 }
315 
316 
VisitUnconditionalBranchToRegister(const Instruction * instr)317 void Instrument::VisitUnconditionalBranchToRegister(const Instruction* instr) {
318   USE(instr);
319   Update();
320   static Counter* counter = GetCounter("Unconditional Branch");
321   counter->Increment();
322 }
323 
324 
VisitCompareBranch(const Instruction * instr)325 void Instrument::VisitCompareBranch(const Instruction* instr) {
326   USE(instr);
327   Update();
328   static Counter* counter = GetCounter("Compare and Branch");
329   counter->Increment();
330 }
331 
332 
VisitTestBranch(const Instruction * instr)333 void Instrument::VisitTestBranch(const Instruction* instr) {
334   USE(instr);
335   Update();
336   static Counter* counter = GetCounter("Test and Branch");
337   counter->Increment();
338 }
339 
340 
VisitConditionalBranch(const Instruction * instr)341 void Instrument::VisitConditionalBranch(const Instruction* instr) {
342   USE(instr);
343   Update();
344   static Counter* counter = GetCounter("Conditional Branch");
345   counter->Increment();
346 }
347 
348 
VisitSystem(const Instruction * instr)349 void Instrument::VisitSystem(const Instruction* instr) {
350   USE(instr);
351   Update();
352   static Counter* counter = GetCounter("Other");
353   counter->Increment();
354 }
355 
356 
VisitException(const Instruction * instr)357 void Instrument::VisitException(const Instruction* instr) {
358   USE(instr);
359   Update();
360   static Counter* counter = GetCounter("Other");
361   counter->Increment();
362 }
363 
364 
InstrumentLoadStorePair(const Instruction * instr)365 void Instrument::InstrumentLoadStorePair(const Instruction* instr) {
366   static Counter* load_pair_counter = GetCounter("Load Pair");
367   static Counter* store_pair_counter = GetCounter("Store Pair");
368 
369   if (instr->Mask(LoadStorePairLBit) != 0) {
370     load_pair_counter->Increment();
371   } else {
372     store_pair_counter->Increment();
373   }
374 }
375 
376 
VisitLoadStorePairPostIndex(const Instruction * instr)377 void Instrument::VisitLoadStorePairPostIndex(const Instruction* instr) {
378   Update();
379   InstrumentLoadStorePair(instr);
380 }
381 
382 
VisitLoadStorePairOffset(const Instruction * instr)383 void Instrument::VisitLoadStorePairOffset(const Instruction* instr) {
384   Update();
385   InstrumentLoadStorePair(instr);
386 }
387 
388 
VisitLoadStorePairPreIndex(const Instruction * instr)389 void Instrument::VisitLoadStorePairPreIndex(const Instruction* instr) {
390   Update();
391   InstrumentLoadStorePair(instr);
392 }
393 
394 
VisitLoadStorePairNonTemporal(const Instruction * instr)395 void Instrument::VisitLoadStorePairNonTemporal(const Instruction* instr) {
396   Update();
397   InstrumentLoadStorePair(instr);
398 }
399 
400 
VisitLoadStoreExclusive(const Instruction * instr)401 void Instrument::VisitLoadStoreExclusive(const Instruction* instr) {
402   USE(instr);
403   Update();
404   static Counter* counter = GetCounter("Other");
405   counter->Increment();
406 }
407 
408 
VisitLoadLiteral(const Instruction * instr)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 
InstrumentLoadStore(const Instruction * instr)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 
VisitLoadStoreUnscaledOffset(const Instruction * instr)449 void Instrument::VisitLoadStoreUnscaledOffset(const Instruction* instr) {
450   Update();
451   InstrumentLoadStore(instr);
452 }
453 
454 
VisitLoadStorePostIndex(const Instruction * instr)455 void Instrument::VisitLoadStorePostIndex(const Instruction* instr) {
456   USE(instr);
457   Update();
458   InstrumentLoadStore(instr);
459 }
460 
461 
VisitLoadStorePreIndex(const Instruction * instr)462 void Instrument::VisitLoadStorePreIndex(const Instruction* instr) {
463   Update();
464   InstrumentLoadStore(instr);
465 }
466 
467 
VisitLoadStoreRegisterOffset(const Instruction * instr)468 void Instrument::VisitLoadStoreRegisterOffset(const Instruction* instr) {
469   Update();
470   InstrumentLoadStore(instr);
471 }
472 
473 
VisitLoadStoreUnsignedOffset(const Instruction * instr)474 void Instrument::VisitLoadStoreUnsignedOffset(const Instruction* instr) {
475   Update();
476   InstrumentLoadStore(instr);
477 }
478 
479 
VisitLogicalShifted(const Instruction * instr)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 
VisitAddSubShifted(const Instruction * instr)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 
VisitAddSubExtended(const Instruction * instr)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 
VisitAddSubWithCarry(const Instruction * instr)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 
VisitConditionalCompareRegister(const Instruction * instr)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 
VisitConditionalCompareImmediate(const Instruction * instr)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 
VisitConditionalSelect(const Instruction * instr)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 
VisitDataProcessing1Source(const Instruction * instr)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 
VisitDataProcessing2Source(const Instruction * instr)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 
VisitDataProcessing3Source(const Instruction * instr)552 void Instrument::VisitDataProcessing3Source(const Instruction* instr) {
553   USE(instr);
554   Update();
555   static Counter* counter = GetCounter("Other Int DP");
556   counter->Increment();
557 }
558 
559 
VisitFPCompare(const Instruction * instr)560 void Instrument::VisitFPCompare(const Instruction* instr) {
561   USE(instr);
562   Update();
563   static Counter* counter = GetCounter("FP DP");
564   counter->Increment();
565 }
566 
567 
VisitFPConditionalCompare(const Instruction * instr)568 void Instrument::VisitFPConditionalCompare(const Instruction* instr) {
569   USE(instr);
570   Update();
571   static Counter* counter = GetCounter("Conditional Compare");
572   counter->Increment();
573 }
574 
575 
VisitFPConditionalSelect(const Instruction * instr)576 void Instrument::VisitFPConditionalSelect(const Instruction* instr) {
577   USE(instr);
578   Update();
579   static Counter* counter = GetCounter("Conditional Select");
580   counter->Increment();
581 }
582 
583 
VisitFPImmediate(const Instruction * instr)584 void Instrument::VisitFPImmediate(const Instruction* instr) {
585   USE(instr);
586   Update();
587   static Counter* counter = GetCounter("FP DP");
588   counter->Increment();
589 }
590 
591 
VisitFPDataProcessing1Source(const Instruction * instr)592 void Instrument::VisitFPDataProcessing1Source(const Instruction* instr) {
593   USE(instr);
594   Update();
595   static Counter* counter = GetCounter("FP DP");
596   counter->Increment();
597 }
598 
599 
VisitFPDataProcessing2Source(const Instruction * instr)600 void Instrument::VisitFPDataProcessing2Source(const Instruction* instr) {
601   USE(instr);
602   Update();
603   static Counter* counter = GetCounter("FP DP");
604   counter->Increment();
605 }
606 
607 
VisitFPDataProcessing3Source(const Instruction * instr)608 void Instrument::VisitFPDataProcessing3Source(const Instruction* instr) {
609   USE(instr);
610   Update();
611   static Counter* counter = GetCounter("FP DP");
612   counter->Increment();
613 }
614 
615 
VisitFPIntegerConvert(const Instruction * instr)616 void Instrument::VisitFPIntegerConvert(const Instruction* instr) {
617   USE(instr);
618   Update();
619   static Counter* counter = GetCounter("FP DP");
620   counter->Increment();
621 }
622 
623 
VisitFPFixedPointConvert(const Instruction * instr)624 void Instrument::VisitFPFixedPointConvert(const Instruction* instr) {
625   USE(instr);
626   Update();
627   static Counter* counter = GetCounter("FP DP");
628   counter->Increment();
629 }
630 
631 
VisitCrypto2RegSHA(const Instruction * instr)632 void Instrument::VisitCrypto2RegSHA(const Instruction* instr) {
633   USE(instr);
634   Update();
635   static Counter* counter = GetCounter("Crypto");
636   counter->Increment();
637 }
638 
639 
VisitCrypto3RegSHA(const Instruction * instr)640 void Instrument::VisitCrypto3RegSHA(const Instruction* instr) {
641   USE(instr);
642   Update();
643   static Counter* counter = GetCounter("Crypto");
644   counter->Increment();
645 }
646 
647 
VisitCryptoAES(const Instruction * instr)648 void Instrument::VisitCryptoAES(const Instruction* instr) {
649   USE(instr);
650   Update();
651   static Counter* counter = GetCounter("Crypto");
652   counter->Increment();
653 }
654 
655 
VisitNEON2RegMisc(const Instruction * instr)656 void Instrument::VisitNEON2RegMisc(const Instruction* instr) {
657   USE(instr);
658   Update();
659   static Counter* counter = GetCounter("NEON");
660   counter->Increment();
661 }
662 
663 
VisitNEON3Same(const Instruction * instr)664 void Instrument::VisitNEON3Same(const Instruction* instr) {
665   USE(instr);
666   Update();
667   static Counter* counter = GetCounter("NEON");
668   counter->Increment();
669 }
670 
671 
VisitNEON3Different(const Instruction * instr)672 void Instrument::VisitNEON3Different(const Instruction* instr) {
673   USE(instr);
674   Update();
675   static Counter* counter = GetCounter("NEON");
676   counter->Increment();
677 }
678 
679 
VisitNEONAcrossLanes(const Instruction * instr)680 void Instrument::VisitNEONAcrossLanes(const Instruction* instr) {
681   USE(instr);
682   Update();
683   static Counter* counter = GetCounter("NEON");
684   counter->Increment();
685 }
686 
687 
VisitNEONByIndexedElement(const Instruction * instr)688 void Instrument::VisitNEONByIndexedElement(const Instruction* instr) {
689   USE(instr);
690   Update();
691   static Counter* counter = GetCounter("NEON");
692   counter->Increment();
693 }
694 
695 
VisitNEONCopy(const Instruction * instr)696 void Instrument::VisitNEONCopy(const Instruction* instr) {
697   USE(instr);
698   Update();
699   static Counter* counter = GetCounter("NEON");
700   counter->Increment();
701 }
702 
703 
VisitNEONExtract(const Instruction * instr)704 void Instrument::VisitNEONExtract(const Instruction* instr) {
705   USE(instr);
706   Update();
707   static Counter* counter = GetCounter("NEON");
708   counter->Increment();
709 }
710 
711 
VisitNEONLoadStoreMultiStruct(const Instruction * instr)712 void Instrument::VisitNEONLoadStoreMultiStruct(const Instruction* instr) {
713   USE(instr);
714   Update();
715   static Counter* counter = GetCounter("NEON");
716   counter->Increment();
717 }
718 
719 
VisitNEONLoadStoreMultiStructPostIndex(const Instruction * instr)720 void Instrument::VisitNEONLoadStoreMultiStructPostIndex(
721     const Instruction* instr) {
722   USE(instr);
723   Update();
724   static Counter* counter = GetCounter("NEON");
725   counter->Increment();
726 }
727 
728 
VisitNEONLoadStoreSingleStruct(const Instruction * instr)729 void Instrument::VisitNEONLoadStoreSingleStruct(const Instruction* instr) {
730   USE(instr);
731   Update();
732   static Counter* counter = GetCounter("NEON");
733   counter->Increment();
734 }
735 
736 
VisitNEONLoadStoreSingleStructPostIndex(const Instruction * instr)737 void Instrument::VisitNEONLoadStoreSingleStructPostIndex(
738     const Instruction* instr) {
739   USE(instr);
740   Update();
741   static Counter* counter = GetCounter("NEON");
742   counter->Increment();
743 }
744 
745 
VisitNEONModifiedImmediate(const Instruction * instr)746 void Instrument::VisitNEONModifiedImmediate(const Instruction* instr) {
747   USE(instr);
748   Update();
749   static Counter* counter = GetCounter("NEON");
750   counter->Increment();
751 }
752 
753 
VisitNEONScalar2RegMisc(const Instruction * instr)754 void Instrument::VisitNEONScalar2RegMisc(const Instruction* instr) {
755   USE(instr);
756   Update();
757   static Counter* counter = GetCounter("NEON");
758   counter->Increment();
759 }
760 
761 
VisitNEONScalar3Diff(const Instruction * instr)762 void Instrument::VisitNEONScalar3Diff(const Instruction* instr) {
763   USE(instr);
764   Update();
765   static Counter* counter = GetCounter("NEON");
766   counter->Increment();
767 }
768 
769 
VisitNEONScalar3Same(const Instruction * instr)770 void Instrument::VisitNEONScalar3Same(const Instruction* instr) {
771   USE(instr);
772   Update();
773   static Counter* counter = GetCounter("NEON");
774   counter->Increment();
775 }
776 
777 
VisitNEONScalarByIndexedElement(const Instruction * instr)778 void Instrument::VisitNEONScalarByIndexedElement(const Instruction* instr) {
779   USE(instr);
780   Update();
781   static Counter* counter = GetCounter("NEON");
782   counter->Increment();
783 }
784 
785 
VisitNEONScalarCopy(const Instruction * instr)786 void Instrument::VisitNEONScalarCopy(const Instruction* instr) {
787   USE(instr);
788   Update();
789   static Counter* counter = GetCounter("NEON");
790   counter->Increment();
791 }
792 
793 
VisitNEONScalarPairwise(const Instruction * instr)794 void Instrument::VisitNEONScalarPairwise(const Instruction* instr) {
795   USE(instr);
796   Update();
797   static Counter* counter = GetCounter("NEON");
798   counter->Increment();
799 }
800 
801 
VisitNEONScalarShiftImmediate(const Instruction * instr)802 void Instrument::VisitNEONScalarShiftImmediate(const Instruction* instr) {
803   USE(instr);
804   Update();
805   static Counter* counter = GetCounter("NEON");
806   counter->Increment();
807 }
808 
809 
VisitNEONShiftImmediate(const Instruction * instr)810 void Instrument::VisitNEONShiftImmediate(const Instruction* instr) {
811   USE(instr);
812   Update();
813   static Counter* counter = GetCounter("NEON");
814   counter->Increment();
815 }
816 
817 
VisitNEONTable(const Instruction * instr)818 void Instrument::VisitNEONTable(const Instruction* instr) {
819   USE(instr);
820   Update();
821   static Counter* counter = GetCounter("NEON");
822   counter->Increment();
823 }
824 
825 
VisitNEONPerm(const Instruction * instr)826 void Instrument::VisitNEONPerm(const Instruction* instr) {
827   USE(instr);
828   Update();
829   static Counter* counter = GetCounter("NEON");
830   counter->Increment();
831 }
832 
833 
VisitUnallocated(const Instruction * instr)834 void Instrument::VisitUnallocated(const Instruction* instr) {
835   USE(instr);
836   Update();
837   static Counter* counter = GetCounter("Other");
838   counter->Increment();
839 }
840 
841 
VisitUnimplemented(const Instruction * instr)842 void Instrument::VisitUnimplemented(const Instruction* instr) {
843   USE(instr);
844   Update();
845   static Counter* counter = GetCounter("Other");
846   counter->Increment();
847 }
848 
849 
850 }  // namespace vixl
851