|
1 | 1 | import struct
|
2 | 2 |
|
3 |
| - |
| 3 | +instrs_sig_mutable = ['auipc','jal','jalr'] |
| 4 | +instrs_sig_update = ['sh','sb','sw','sd','c.sw','c.sd','c.swsp','c.sdsp','fsw','fsd',\ |
| 5 | + 'c.fsw','c.fsd','c.fswsp','c.fsdsp'] |
| 6 | +instrs_no_reg_tracking = ['beq','bne','blt','bge','bltu','bgeu','fence','c.j','c.jal','c.jalr',\ |
| 7 | + 'c.jr','c.beqz','c.bnez', 'c.ebreak'] + instrs_sig_update |
| 8 | +instrs_fcsr_affected = ['fmadd.s','fmsub.s','fnmsub.s','fnmadd.s','fadd.s','fsub.s','fmul.s','fdiv.s',\ |
| 9 | + 'fsqrt.s','fmin.s','fmax.s','fcvt.w.s','fcvt.wu.s','feq.s','flt.s',\ |
| 10 | + 'fle.s','fcvt.s.w','fcvt.s.wu','fcvt.l.s','fcvt.lu.s','fcvt.s.l',\ |
| 11 | + 'fcvt.s.lu', 'fmadd.d','fmsub.d','fnmsub.d','fnmadd.d','fadd.d','fsub.d',\ |
| 12 | + 'fmul.d','fdiv.d','fsqrt.d','fmin.d','fmax.d','fcvt.s.d','fcvt.d.s',\ |
| 13 | + 'feq.d','flt.d','fle.d','fcvt.w.d','fcvt.wu.d','fcvt.l.d','fcvt.lu.d',\ |
| 14 | + 'fcvt.d.l','fcvt.d.lu'] |
4 | 15 | unsgn_rs1 = ['sw','sd','sh','sb','ld','lw','lwu','lh','lhu','lb', 'lbu','flw','fld','fsw','fsd',\
|
5 | 16 | 'bgeu', 'bltu', 'sltiu', 'sltu','c.lw','c.ld','c.lwsp','c.ldsp',\
|
6 | 17 | 'c.sw','c.sd','c.swsp','c.sdsp','mulhu','divu','remu','divuw',\
|
@@ -112,6 +123,10 @@ def __init__(
|
112 | 123 | self.rd_nregs = 1
|
113 | 124 |
|
114 | 125 |
|
| 126 | + def is_sig_update(self): |
| 127 | + return self.instr_name in instrs_sig_update |
| 128 | + |
| 129 | + |
115 | 130 | def evaluate_instr_vars(self, xlen, flen, arch_state, csr_regfile, instr_vars):
|
116 | 131 | '''
|
117 | 132 | This function populates the provided instr_vars dictionary
|
@@ -179,6 +194,84 @@ def evaluate_instr_vars(self, xlen, flen, arch_state, csr_regfile, instr_vars):
|
179 | 194 | instr_vars.update(ext_specific_vars)
|
180 | 195 |
|
181 | 196 |
|
| 197 | + def get_elements_to_track(self, xlen): |
| 198 | + ''' |
| 199 | + This function returns the elements to track to aid in monitoring signature updates and related statistics. |
| 200 | + The returned value is a tuple of three elements: |
| 201 | +
|
| 202 | + - The first element is a list of registers to track whose values cannot be modified before storing |
| 203 | + - The second element is a list of registers to track whose value can be modified prior to storing |
| 204 | + - The third element is a list of instructions to track for signature updates other than those of tracked registers (mostly used for branch instructions) |
| 205 | + ''' |
| 206 | + regs_to_track_immutable = [] |
| 207 | + regs_to_track_mutable = [] |
| 208 | + instrs_to_track = [] |
| 209 | + |
| 210 | + if self.instr_name in instrs_no_reg_tracking: |
| 211 | + store_instrs = [] |
| 212 | + if self.is_sig_update(): |
| 213 | + store_instrs = [self.instr_name] |
| 214 | + else: |
| 215 | + if self.instr_name.startswith("c."): |
| 216 | + store_instrs = ['sd','c.sdsp'] if xlen == 64 else ['sw','c.swsp'] |
| 217 | + else: |
| 218 | + store_instrs = ['sd'] if xlen == 64 else ['sw'] |
| 219 | + instrs_to_track.append(store_instrs) |
| 220 | + elif self.instr_name in instrs_sig_mutable: |
| 221 | + if self.rd is not None: |
| 222 | + reg = self.rd[1] + str(self.rd[0]) |
| 223 | + regs_to_track_mutable.append(reg) |
| 224 | + else: |
| 225 | + if self.rd is not None: |
| 226 | + reg = self.rd[1] + str(self.rd[0]) |
| 227 | + regs_to_track_immutable.append(reg) |
| 228 | + |
| 229 | + if self.instr_name in instrs_fcsr_affected: |
| 230 | + regs_to_track_immutable.append('fcsr') |
| 231 | + |
| 232 | + if self.csr_commit is not None: |
| 233 | + for commit in self.csr_commit: |
| 234 | + if commit[0] == "CSR": |
| 235 | + csr_reg = commit[1] |
| 236 | + if csr_reg not in regs_to_track_immutable: |
| 237 | + regs_to_track_immutable.append(csr_reg) |
| 238 | + |
| 239 | + return (regs_to_track_immutable, regs_to_track_mutable, instrs_to_track) |
| 240 | + |
| 241 | + |
| 242 | + def get_changed_regs(self, arch_state, csr_regfile): |
| 243 | + ''' |
| 244 | + This function returns a list of registers whose value will be changed as |
| 245 | + a result of executing this instruction. |
| 246 | +
|
| 247 | + :param csr_regfile: Architectural state of CSR register files |
| 248 | + :param instr_vars: Dictionary to be populated by the evaluated instruction variables |
| 249 | + ''' |
| 250 | + changed_regs = [] |
| 251 | + |
| 252 | + if self.reg_commit is not None: |
| 253 | + reg = self.reg_commit[0] + self.reg_commit[1] |
| 254 | + |
| 255 | + prev_value = None |
| 256 | + if self.reg_commit[0] == 'x': |
| 257 | + prev_value = arch_state.x_rf[int(self.reg_commit[1])] |
| 258 | + elif self.reg_commit[0] == 'f': |
| 259 | + prev_value = arch_state.f_rf[int(self.reg_commit[1])] |
| 260 | + |
| 261 | + if prev_value != str(self.reg_commit[2][2:]): # this is a string check, but should we do an exact number check? |
| 262 | + changed_regs.append(reg) |
| 263 | + |
| 264 | + if self.csr_commit is not None: |
| 265 | + for commit in self.csr_commit: |
| 266 | + if commit[0] == "CSR": |
| 267 | + csr_reg = commit[1] |
| 268 | + |
| 269 | + if csr_regfile[csr_reg] != str(commit[2][2:]): |
| 270 | + changed_regs.append(csr_reg) |
| 271 | + |
| 272 | + return changed_regs |
| 273 | + |
| 274 | + |
182 | 275 | def update_arch_state(self, arch_state, csr_regfile):
|
183 | 276 | '''
|
184 | 277 | This function updates the arch state and csr regfiles
|
|
0 commit comments