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 "jit/arm64/vixl/Instrument-vixl.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     if (Counter* counter = js_new<Counter>(kCounterList[i].name, kCounterList[i].type))
142       (void)counters_.append(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   for (auto counter : counters_) {
155     js_delete(counter);
156   }
157 
158   if (output_stream_ != stdout) {
159     fclose(output_stream_);
160   }
161 }
162 
163 
Update()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 
DumpCounters()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 
DumpCounterNames()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 
HandleInstrumentationEvent(unsigned event)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 
DumpEventMarker(unsigned marker)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 
GetCounter(const char * name)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 
Enable()236 void Instrument::Enable() {
237   for (auto counter : counters_) {
238     counter->Enable();
239   }
240 }
241 
242 
Disable()243 void Instrument::Disable() {
244   for (auto counter : counters_) {
245     counter->Disable();
246   }
247 }
248 
249 
VisitPCRelAddressing(const Instruction * instr)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 
VisitAddSubImmediate(const Instruction * instr)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 
VisitLogicalImmediate(const Instruction * instr)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 
VisitMoveWideImmediate(const Instruction * instr)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 
VisitBitfield(const Instruction * instr)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 
VisitExtract(const Instruction * instr)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 
VisitUnconditionalBranch(const Instruction * instr)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 
VisitUnconditionalBranchToRegister(const Instruction * instr)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 
VisitCompareBranch(const Instruction * instr)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 
VisitTestBranch(const Instruction * instr)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 
VisitConditionalBranch(const Instruction * instr)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 
VisitSystem(const Instruction * instr)343 void Instrument::VisitSystem(const Instruction* instr) {
344   USE(instr);
345   Update();
346   static Counter* counter = GetCounter("Other");
347   counter->Increment();
348 }
349 
350 
VisitException(const Instruction * instr)351 void Instrument::VisitException(const Instruction* instr) {
352   USE(instr);
353   Update();
354   static Counter* counter = GetCounter("Other");
355   counter->Increment();
356 }
357 
358 
InstrumentLoadStorePair(const Instruction * instr)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 
VisitLoadStorePairPostIndex(const Instruction * instr)371 void Instrument::VisitLoadStorePairPostIndex(const Instruction* instr) {
372   Update();
373   InstrumentLoadStorePair(instr);
374 }
375 
376 
VisitLoadStorePairOffset(const Instruction * instr)377 void Instrument::VisitLoadStorePairOffset(const Instruction* instr) {
378   Update();
379   InstrumentLoadStorePair(instr);
380 }
381 
382 
VisitLoadStorePairPreIndex(const Instruction * instr)383 void Instrument::VisitLoadStorePairPreIndex(const Instruction* instr) {
384   Update();
385   InstrumentLoadStorePair(instr);
386 }
387 
388 
VisitLoadStorePairNonTemporal(const Instruction * instr)389 void Instrument::VisitLoadStorePairNonTemporal(const Instruction* instr) {
390   Update();
391   InstrumentLoadStorePair(instr);
392 }
393 
394 
VisitLoadStoreExclusive(const Instruction * instr)395 void Instrument::VisitLoadStoreExclusive(const Instruction* instr) {
396   USE(instr);
397   Update();
398   static Counter* counter = GetCounter("Other");
399   counter->Increment();
400 }
401 
402 
VisitLoadLiteral(const Instruction * instr)403 void Instrument::VisitLoadLiteral(const Instruction* instr) {
404   USE(instr);
405   Update();
406   static Counter* counter = GetCounter("Load Literal");
407   counter->Increment();
408 }
409 
410 
InstrumentLoadStore(const Instruction * instr)411 void Instrument::InstrumentLoadStore(const Instruction* instr) {
412   static Counter* load_int_counter = GetCounter("Load Integer");
413   static Counter* store_int_counter = GetCounter("Store Integer");
414   static Counter* load_fp_counter = GetCounter("Load FP");
415   static Counter* store_fp_counter = GetCounter("Store FP");
416 
417   switch (instr->Mask(LoadStoreMask)) {
418     case STRB_w:
419     case STRH_w:
420     case STR_w:
421       VIXL_FALLTHROUGH();
422     case STR_x:     store_int_counter->Increment(); break;
423     case STR_s:
424       VIXL_FALLTHROUGH();
425     case STR_d:     store_fp_counter->Increment(); break;
426     case LDRB_w:
427     case LDRH_w:
428     case LDR_w:
429     case LDR_x:
430     case LDRSB_x:
431     case LDRSH_x:
432     case LDRSW_x:
433     case LDRSB_w:
434       VIXL_FALLTHROUGH();
435     case LDRSH_w:   load_int_counter->Increment(); break;
436     case LDR_s:
437       VIXL_FALLTHROUGH();
438     case LDR_d:     load_fp_counter->Increment(); break;
439   }
440 }
441 
442 
VisitLoadStoreUnscaledOffset(const Instruction * instr)443 void Instrument::VisitLoadStoreUnscaledOffset(const Instruction* instr) {
444   Update();
445   InstrumentLoadStore(instr);
446 }
447 
448 
VisitLoadStorePostIndex(const Instruction * instr)449 void Instrument::VisitLoadStorePostIndex(const Instruction* instr) {
450   USE(instr);
451   Update();
452   InstrumentLoadStore(instr);
453 }
454 
455 
VisitLoadStorePreIndex(const Instruction * instr)456 void Instrument::VisitLoadStorePreIndex(const Instruction* instr) {
457   Update();
458   InstrumentLoadStore(instr);
459 }
460 
461 
VisitLoadStoreRegisterOffset(const Instruction * instr)462 void Instrument::VisitLoadStoreRegisterOffset(const Instruction* instr) {
463   Update();
464   InstrumentLoadStore(instr);
465 }
466 
467 
VisitLoadStoreUnsignedOffset(const Instruction * instr)468 void Instrument::VisitLoadStoreUnsignedOffset(const Instruction* instr) {
469   Update();
470   InstrumentLoadStore(instr);
471 }
472 
473 
VisitLogicalShifted(const Instruction * instr)474 void Instrument::VisitLogicalShifted(const Instruction* instr) {
475   USE(instr);
476   Update();
477   static Counter* counter = GetCounter("Logical DP");
478   counter->Increment();
479 }
480 
481 
VisitAddSubShifted(const Instruction * instr)482 void Instrument::VisitAddSubShifted(const Instruction* instr) {
483   USE(instr);
484   Update();
485   static Counter* counter = GetCounter("Add/Sub DP");
486   counter->Increment();
487 }
488 
489 
VisitAddSubExtended(const Instruction * instr)490 void Instrument::VisitAddSubExtended(const Instruction* instr) {
491   USE(instr);
492   Update();
493   static Counter* counter = GetCounter("Add/Sub DP");
494   counter->Increment();
495 }
496 
497 
VisitAddSubWithCarry(const Instruction * instr)498 void Instrument::VisitAddSubWithCarry(const Instruction* instr) {
499   USE(instr);
500   Update();
501   static Counter* counter = GetCounter("Add/Sub DP");
502   counter->Increment();
503 }
504 
505 
VisitConditionalCompareRegister(const Instruction * instr)506 void Instrument::VisitConditionalCompareRegister(const Instruction* instr) {
507   USE(instr);
508   Update();
509   static Counter* counter = GetCounter("Conditional Compare");
510   counter->Increment();
511 }
512 
513 
VisitConditionalCompareImmediate(const Instruction * instr)514 void Instrument::VisitConditionalCompareImmediate(const Instruction* instr) {
515   USE(instr);
516   Update();
517   static Counter* counter = GetCounter("Conditional Compare");
518   counter->Increment();
519 }
520 
521 
VisitConditionalSelect(const Instruction * instr)522 void Instrument::VisitConditionalSelect(const Instruction* instr) {
523   USE(instr);
524   Update();
525   static Counter* counter = GetCounter("Conditional Select");
526   counter->Increment();
527 }
528 
529 
VisitDataProcessing1Source(const Instruction * instr)530 void Instrument::VisitDataProcessing1Source(const Instruction* instr) {
531   USE(instr);
532   Update();
533   static Counter* counter = GetCounter("Other Int DP");
534   counter->Increment();
535 }
536 
537 
VisitDataProcessing2Source(const Instruction * instr)538 void Instrument::VisitDataProcessing2Source(const Instruction* instr) {
539   USE(instr);
540   Update();
541   static Counter* counter = GetCounter("Other Int DP");
542   counter->Increment();
543 }
544 
545 
VisitDataProcessing3Source(const Instruction * instr)546 void Instrument::VisitDataProcessing3Source(const Instruction* instr) {
547   USE(instr);
548   Update();
549   static Counter* counter = GetCounter("Other Int DP");
550   counter->Increment();
551 }
552 
553 
VisitFPCompare(const Instruction * instr)554 void Instrument::VisitFPCompare(const Instruction* instr) {
555   USE(instr);
556   Update();
557   static Counter* counter = GetCounter("FP DP");
558   counter->Increment();
559 }
560 
561 
VisitFPConditionalCompare(const Instruction * instr)562 void Instrument::VisitFPConditionalCompare(const Instruction* instr) {
563   USE(instr);
564   Update();
565   static Counter* counter = GetCounter("Conditional Compare");
566   counter->Increment();
567 }
568 
569 
VisitFPConditionalSelect(const Instruction * instr)570 void Instrument::VisitFPConditionalSelect(const Instruction* instr) {
571   USE(instr);
572   Update();
573   static Counter* counter = GetCounter("Conditional Select");
574   counter->Increment();
575 }
576 
577 
VisitFPImmediate(const Instruction * instr)578 void Instrument::VisitFPImmediate(const Instruction* instr) {
579   USE(instr);
580   Update();
581   static Counter* counter = GetCounter("FP DP");
582   counter->Increment();
583 }
584 
585 
VisitFPDataProcessing1Source(const Instruction * instr)586 void Instrument::VisitFPDataProcessing1Source(const Instruction* instr) {
587   USE(instr);
588   Update();
589   static Counter* counter = GetCounter("FP DP");
590   counter->Increment();
591 }
592 
593 
VisitFPDataProcessing2Source(const Instruction * instr)594 void Instrument::VisitFPDataProcessing2Source(const Instruction* instr) {
595   USE(instr);
596   Update();
597   static Counter* counter = GetCounter("FP DP");
598   counter->Increment();
599 }
600 
601 
VisitFPDataProcessing3Source(const Instruction * instr)602 void Instrument::VisitFPDataProcessing3Source(const Instruction* instr) {
603   USE(instr);
604   Update();
605   static Counter* counter = GetCounter("FP DP");
606   counter->Increment();
607 }
608 
609 
VisitFPIntegerConvert(const Instruction * instr)610 void Instrument::VisitFPIntegerConvert(const Instruction* instr) {
611   USE(instr);
612   Update();
613   static Counter* counter = GetCounter("FP DP");
614   counter->Increment();
615 }
616 
617 
VisitFPFixedPointConvert(const Instruction * instr)618 void Instrument::VisitFPFixedPointConvert(const Instruction* instr) {
619   USE(instr);
620   Update();
621   static Counter* counter = GetCounter("FP DP");
622   counter->Increment();
623 }
624 
625 
VisitCrypto2RegSHA(const Instruction * instr)626 void Instrument::VisitCrypto2RegSHA(const Instruction* instr) {
627   USE(instr);
628   Update();
629   static Counter* counter = GetCounter("Crypto");
630   counter->Increment();
631 }
632 
633 
VisitCrypto3RegSHA(const Instruction * instr)634 void Instrument::VisitCrypto3RegSHA(const Instruction* instr) {
635   USE(instr);
636   Update();
637   static Counter* counter = GetCounter("Crypto");
638   counter->Increment();
639 }
640 
641 
VisitCryptoAES(const Instruction * instr)642 void Instrument::VisitCryptoAES(const Instruction* instr) {
643   USE(instr);
644   Update();
645   static Counter* counter = GetCounter("Crypto");
646   counter->Increment();
647 }
648 
649 
VisitNEON2RegMisc(const Instruction * instr)650 void Instrument::VisitNEON2RegMisc(const Instruction* instr) {
651   USE(instr);
652   Update();
653   static Counter* counter = GetCounter("NEON");
654   counter->Increment();
655 }
656 
657 
VisitNEON3Same(const Instruction * instr)658 void Instrument::VisitNEON3Same(const Instruction* instr) {
659   USE(instr);
660   Update();
661   static Counter* counter = GetCounter("NEON");
662   counter->Increment();
663 }
664 
665 
VisitNEON3Different(const Instruction * instr)666 void Instrument::VisitNEON3Different(const Instruction* instr) {
667   USE(instr);
668   Update();
669   static Counter* counter = GetCounter("NEON");
670   counter->Increment();
671 }
672 
673 
VisitNEONAcrossLanes(const Instruction * instr)674 void Instrument::VisitNEONAcrossLanes(const Instruction* instr) {
675   USE(instr);
676   Update();
677   static Counter* counter = GetCounter("NEON");
678   counter->Increment();
679 }
680 
681 
VisitNEONByIndexedElement(const Instruction * instr)682 void Instrument::VisitNEONByIndexedElement(const Instruction* instr) {
683   USE(instr);
684   Update();
685   static Counter* counter = GetCounter("NEON");
686   counter->Increment();
687 }
688 
689 
VisitNEONCopy(const Instruction * instr)690 void Instrument::VisitNEONCopy(const Instruction* instr) {
691   USE(instr);
692   Update();
693   static Counter* counter = GetCounter("NEON");
694   counter->Increment();
695 }
696 
697 
VisitNEONExtract(const Instruction * instr)698 void Instrument::VisitNEONExtract(const Instruction* instr) {
699   USE(instr);
700   Update();
701   static Counter* counter = GetCounter("NEON");
702   counter->Increment();
703 }
704 
705 
VisitNEONLoadStoreMultiStruct(const Instruction * instr)706 void Instrument::VisitNEONLoadStoreMultiStruct(const Instruction* instr) {
707   USE(instr);
708   Update();
709   static Counter* counter = GetCounter("NEON");
710   counter->Increment();
711 }
712 
713 
VisitNEONLoadStoreMultiStructPostIndex(const Instruction * instr)714 void Instrument::VisitNEONLoadStoreMultiStructPostIndex(
715     const Instruction* instr) {
716   USE(instr);
717   Update();
718   static Counter* counter = GetCounter("NEON");
719   counter->Increment();
720 }
721 
722 
VisitNEONLoadStoreSingleStruct(const Instruction * instr)723 void Instrument::VisitNEONLoadStoreSingleStruct(const Instruction* instr) {
724   USE(instr);
725   Update();
726   static Counter* counter = GetCounter("NEON");
727   counter->Increment();
728 }
729 
730 
VisitNEONLoadStoreSingleStructPostIndex(const Instruction * instr)731 void Instrument::VisitNEONLoadStoreSingleStructPostIndex(
732     const Instruction* instr) {
733   USE(instr);
734   Update();
735   static Counter* counter = GetCounter("NEON");
736   counter->Increment();
737 }
738 
739 
VisitNEONModifiedImmediate(const Instruction * instr)740 void Instrument::VisitNEONModifiedImmediate(const Instruction* instr) {
741   USE(instr);
742   Update();
743   static Counter* counter = GetCounter("NEON");
744   counter->Increment();
745 }
746 
747 
VisitNEONScalar2RegMisc(const Instruction * instr)748 void Instrument::VisitNEONScalar2RegMisc(const Instruction* instr) {
749   USE(instr);
750   Update();
751   static Counter* counter = GetCounter("NEON");
752   counter->Increment();
753 }
754 
755 
VisitNEONScalar3Diff(const Instruction * instr)756 void Instrument::VisitNEONScalar3Diff(const Instruction* instr) {
757   USE(instr);
758   Update();
759   static Counter* counter = GetCounter("NEON");
760   counter->Increment();
761 }
762 
763 
VisitNEONScalar3Same(const Instruction * instr)764 void Instrument::VisitNEONScalar3Same(const Instruction* instr) {
765   USE(instr);
766   Update();
767   static Counter* counter = GetCounter("NEON");
768   counter->Increment();
769 }
770 
771 
VisitNEONScalarByIndexedElement(const Instruction * instr)772 void Instrument::VisitNEONScalarByIndexedElement(const Instruction* instr) {
773   USE(instr);
774   Update();
775   static Counter* counter = GetCounter("NEON");
776   counter->Increment();
777 }
778 
779 
VisitNEONScalarCopy(const Instruction * instr)780 void Instrument::VisitNEONScalarCopy(const Instruction* instr) {
781   USE(instr);
782   Update();
783   static Counter* counter = GetCounter("NEON");
784   counter->Increment();
785 }
786 
787 
VisitNEONScalarPairwise(const Instruction * instr)788 void Instrument::VisitNEONScalarPairwise(const Instruction* instr) {
789   USE(instr);
790   Update();
791   static Counter* counter = GetCounter("NEON");
792   counter->Increment();
793 }
794 
795 
VisitNEONScalarShiftImmediate(const Instruction * instr)796 void Instrument::VisitNEONScalarShiftImmediate(const Instruction* instr) {
797   USE(instr);
798   Update();
799   static Counter* counter = GetCounter("NEON");
800   counter->Increment();
801 }
802 
803 
VisitNEONShiftImmediate(const Instruction * instr)804 void Instrument::VisitNEONShiftImmediate(const Instruction* instr) {
805   USE(instr);
806   Update();
807   static Counter* counter = GetCounter("NEON");
808   counter->Increment();
809 }
810 
811 
VisitNEONTable(const Instruction * instr)812 void Instrument::VisitNEONTable(const Instruction* instr) {
813   USE(instr);
814   Update();
815   static Counter* counter = GetCounter("NEON");
816   counter->Increment();
817 }
818 
819 
VisitNEONPerm(const Instruction * instr)820 void Instrument::VisitNEONPerm(const Instruction* instr) {
821   USE(instr);
822   Update();
823   static Counter* counter = GetCounter("NEON");
824   counter->Increment();
825 }
826 
827 
VisitUnallocated(const Instruction * instr)828 void Instrument::VisitUnallocated(const Instruction* instr) {
829   USE(instr);
830   Update();
831   static Counter* counter = GetCounter("Other");
832   counter->Increment();
833 }
834 
835 
VisitUnimplemented(const Instruction * instr)836 void Instrument::VisitUnimplemented(const Instruction* instr) {
837   USE(instr);
838   Update();
839   static Counter* counter = GetCounter("Other");
840   counter->Increment();
841 }
842 
843 
844 }  // namespace vixl
845