ChampSim
instruction.h
Go to the documentation of this file.
1 /*
2  * Copyright 2023 The ChampSim Contributors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef INSTRUCTION_H
18 #define INSTRUCTION_H
19 
20 #include <algorithm>
21 #include <array>
22 #include <cstdint>
23 #include <functional>
24 #include <limits>
25 #include <vector>
26 
27 #include "trace_instruction.h"
28 
29 // branch types
38  BRANCH_OTHER = 7
39 };
40 
42  uint64_t instr_id = 0;
43  uint64_t ip = 0;
44  uint64_t event_cycle = 0;
45 
46  bool is_branch = 0;
47  bool branch_taken = 0;
49  bool branch_mispredicted = 0; // A branch can be mispredicted even if the direction prediction is correct when the predicted target is not correct
50 
51  std::array<uint8_t, 2> asid = {std::numeric_limits<uint8_t>::max(), std::numeric_limits<uint8_t>::max()};
52 
54  uint64_t branch_target = 0;
55 
56  uint8_t dib_checked = 0;
57  uint8_t fetched = 0;
58  uint8_t decoded = 0;
59  uint8_t scheduled = 0;
60  uint8_t executed = 0;
61 
62  unsigned completed_mem_ops = 0;
64 
65  std::vector<uint8_t> destination_registers = {}; // output registers
66  std::vector<uint8_t> source_registers = {}; // input registers
67 
68  std::vector<uint64_t> destination_memory = {};
69  std::vector<uint64_t> source_memory = {};
70 
71  // these are indices of instructions in the ROB that depend on me
72  std::vector<std::reference_wrapper<ooo_model_instr>> registers_instrs_depend_on_me;
73 
74 private:
75  template <typename T>
76  ooo_model_instr(T instr, std::array<uint8_t, 2> local_asid) : ip(instr.ip), is_branch(instr.is_branch), branch_taken(instr.branch_taken), asid(local_asid)
77  {
78  std::remove_copy(std::begin(instr.destination_registers), std::end(instr.destination_registers), std::back_inserter(this->destination_registers), 0);
79  std::remove_copy(std::begin(instr.source_registers), std::end(instr.source_registers), std::back_inserter(this->source_registers), 0);
80  std::remove_copy(std::begin(instr.destination_memory), std::end(instr.destination_memory), std::back_inserter(this->destination_memory), 0);
81  std::remove_copy(std::begin(instr.source_memory), std::end(instr.source_memory), std::back_inserter(this->source_memory), 0);
82 
83  bool writes_sp = std::count(std::begin(destination_registers), std::end(destination_registers), champsim::REG_STACK_POINTER);
84  bool writes_ip = std::count(std::begin(destination_registers), std::end(destination_registers), champsim::REG_INSTRUCTION_POINTER);
85  bool reads_sp = std::count(std::begin(source_registers), std::end(source_registers), champsim::REG_STACK_POINTER);
86  bool reads_flags = std::count(std::begin(source_registers), std::end(source_registers), champsim::REG_FLAGS);
87  bool reads_ip = std::count(std::begin(source_registers), std::end(source_registers), champsim::REG_INSTRUCTION_POINTER);
88  bool reads_other = std::count_if(std::begin(source_registers), std::end(source_registers), [](uint8_t r) {
90  });
91 
92  // determine what kind of branch this is, if any
93  if (!reads_sp && !reads_flags && writes_ip && !reads_other) {
94  // direct jump
95  is_branch = true;
96  branch_taken = true;
98  } else if (!reads_sp && !reads_ip && !reads_flags && writes_ip && reads_other) {
99  // indirect branch
100  is_branch = true;
101  branch_taken = true;
103  } else if (!reads_sp && reads_ip && !writes_sp && writes_ip && (reads_flags || reads_other)) {
104  // conditional branch
105  is_branch = true;
106  branch_taken = instr.branch_taken; // don't change this
108  } else if (reads_sp && reads_ip && writes_sp && writes_ip && !reads_flags && !reads_other) {
109  // direct call
110  is_branch = true;
111  branch_taken = true;
113  } else if (reads_sp && reads_ip && writes_sp && writes_ip && !reads_flags && reads_other) {
114  // indirect call
115  is_branch = true;
116  branch_taken = true;
118  } else if (reads_sp && !reads_ip && writes_sp && writes_ip) {
119  // return
120  is_branch = true;
121  branch_taken = true;
123  } else if (writes_ip) {
124  // some other branch type that doesn't fit the above categories
125  is_branch = true;
126  branch_taken = instr.branch_taken; // don't change this
128  } else {
129  branch_taken = false;
130  }
131  }
132 
133 public:
134  ooo_model_instr(uint8_t cpu, input_instr instr) : ooo_model_instr(instr, {cpu, cpu}) {}
135  ooo_model_instr(uint8_t, cloudsuite_instr instr) : ooo_model_instr(instr, {instr.asid[0], instr.asid[1]}) {}
136 
137  std::size_t num_mem_ops() const { return std::size(destination_memory) + std::size(source_memory); }
138 
139  static bool program_order(const ooo_model_instr& lhs, const ooo_model_instr& rhs) { return lhs.instr_id < rhs.instr_id; }
140 };
141 
142 #endif
branch_type
Definition: instruction.h:30
@ BRANCH_INDIRECT_CALL
Definition: instruction.h:36
@ BRANCH_OTHER
Definition: instruction.h:38
@ NOT_BRANCH
Definition: instruction.h:31
@ BRANCH_DIRECT_JUMP
Definition: instruction.h:32
@ BRANCH_DIRECT_CALL
Definition: instruction.h:35
@ BRANCH_RETURN
Definition: instruction.h:37
@ BRANCH_CONDITIONAL
Definition: instruction.h:34
@ BRANCH_INDIRECT
Definition: instruction.h:33
constexpr char REG_STACK_POINTER
Definition: trace_instruction.h:25
constexpr char REG_INSTRUCTION_POINTER
Definition: trace_instruction.h:27
constexpr char REG_FLAGS
Definition: trace_instruction.h:26
Definition: trace_instruction.h:50
unsigned char asid[2]
Definition: trace_instruction.h:64
Definition: trace_instruction.h:35
Definition: instruction.h:41
uint64_t branch_target
Definition: instruction.h:54
std::size_t num_mem_ops() const
Definition: instruction.h:137
bool branch_prediction
Definition: instruction.h:48
uint8_t executed
Definition: instruction.h:60
bool branch_taken
Definition: instruction.h:47
uint64_t instr_id
Definition: instruction.h:42
std::vector< std::reference_wrapper< ooo_model_instr > > registers_instrs_depend_on_me
Definition: instruction.h:72
bool is_branch
Definition: instruction.h:46
unsigned completed_mem_ops
Definition: instruction.h:62
uint64_t event_cycle
Definition: instruction.h:44
std::array< uint8_t, 2 > asid
Definition: instruction.h:51
ooo_model_instr(uint8_t cpu, input_instr instr)
Definition: instruction.h:134
bool branch_mispredicted
Definition: instruction.h:49
uint8_t scheduled
Definition: instruction.h:59
std::vector< uint8_t > source_registers
Definition: instruction.h:66
std::vector< uint64_t > destination_memory
Definition: instruction.h:68
static bool program_order(const ooo_model_instr &lhs, const ooo_model_instr &rhs)
Definition: instruction.h:139
uint8_t fetched
Definition: instruction.h:57
ooo_model_instr(uint8_t, cloudsuite_instr instr)
Definition: instruction.h:135
std::vector< uint8_t > destination_registers
Definition: instruction.h:65
std::vector< uint64_t > source_memory
Definition: instruction.h:69
int num_reg_dependent
Definition: instruction.h:63
uint8_t decoded
Definition: instruction.h:58
uint64_t ip
Definition: instruction.h:43
uint8_t dib_checked
Definition: instruction.h:56
ooo_model_instr(T instr, std::array< uint8_t, 2 > local_asid)
Definition: instruction.h:76