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