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