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