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