def processStateElement(self, aStateElem): if aStateElem.getStateElementType() != EStateElementType.GPR: self.error("Unexpected StateElement type %s" % aStateElem.getStateElementType()) # This implementation loads the memory block pointer GPR out of order, # so that it can be used to process all subsequent StateElements. if not self._mMemBlockAddrLoaded: load_gpr64_seq = LoadGPR64(self.genThread) load_gpr64_seq.load(self.mMemBlockPtrIndex, self.mMemBlockStartAddr) self._mMemBlockAddrLoaded = True gpr_index = aStateElem.getRegisterIndex() if gpr_index in self.mGprIndices: if self.getGlobalState("AppRegisterWidth") == 32: instr = "LW##RISCV" else: instr = "LD##RISCV" self.genInstruction( instr, { "rd": gpr_index, "rs1": self.mMemBlockPtrIndex, "simm12": (gpr_index * 8), "NoRestriction": 1, }, ) elif gpr_index != self.mMemBlockPtrIndex: load_gpr64_seq = LoadGPR64(self.genThread) load_gpr64_seq.load(gpr_index, aStateElem.getValues()[0]) return True
def processStateElement(self, aStateElem): if aStateElem.getStateElementType() != EStateElementType.GPR: self.error('Unexpected StateElement type %s' % aStateElem.getStateElementType()) # This implementation loads the memory block pointer GPR out of order, so that it can be # used to process all subsequent StateElements. if not self._mMemBlockAddrLoaded: load_gpr64_seq = LoadGPR64(self.genThread) load_gpr64_seq.load(self.mMemBlockPtrIndex, self.mMemBlockStartAddr) self._mMemBlockAddrLoaded = True gpr_index = aStateElem.getRegisterIndex() if gpr_index in self.mGprIndices: self.genInstruction( 'LD##RISCV', { 'rd': gpr_index, 'rs1': self.mMemBlockPtrIndex, 'simm12': (gpr_index * 8), 'NoRestriction': 1 }) elif gpr_index != self.mMemBlockPtrIndex: load_gpr64_seq = LoadGPR64(self.genThread) load_gpr64_seq.load(gpr_index, aStateElem.getValues()[0]) return True
def _testExclusiveStoreLoad(self, aTargetAddr): src_reg_index = self.getRandomGPR(exclude="0") self.reserveRegister("x%d" % src_reg_index) if self.getGlobalState("AppRegisterWidth") == 64: load_gpr64_seq = LoadGPR64(self.genThread) test_val = RandomUtils.random64() load_gpr64_seq.load(src_reg_index, test_val) instr = "SD##RISCV" else: load_gpr32_seq = LoadGPR64(self.genThread) test_val = RandomUtils.random32() load_gpr32_seq.load(src_reg_index, test_val) instr = "SW##RISCV" self.genInstruction( instr, {"rs2": src_reg_index, "LSTarget": aTargetAddr} ) self.unreserveRegister("x%d" % src_reg_index) if self.getGlobalState("AppRegisterWidth") == 32: instr_map = RV32_G_map - BranchJump_map else: instr_map = RV_G_map - BranchJump_map for _ in range(RandomUtils.random32(5, 10)): instr = instr_map.pick(self.genThread) self.genInstruction(instr) if self.getGlobalState("AppRegisterWidth") == 32: instr = "LW##RISCV" else: instr = "LD##RISCV" instr_id = self.genInstruction(instr, {"LSTarget": aTargetAddr}) instr_record = self.queryInstructionRecord(instr_id) dest_reg_index = instr_record["Dests"]["rd"] if dest_reg_index != 0: dest_reg_name = "x%d" % dest_reg_index (dest_reg_val, valid) = self.readRegister(dest_reg_name) self._assertValidRegisterValue(dest_reg_name, valid) gen_mode = self.getPEstate("GenMode") no_iss = gen_mode & 0x1 if (no_iss != 1) and (dest_reg_val != test_val): self.error( "Unexpected destination register value; Expected=0x%x, " "Actual=0x%x" % (test_val, dest_reg_val) )
def processStateElements(self, aStateElems): if aStateElems[0].getStateElementType() != EStateElementType.VmContext: self.error( 'This StateTransitionHandler can only process StateElements of type %s' % EStateElementType.VmContext) (reg_val_gpr_index, ) = self._mHelperGprSet.acquireHelperGprs(1) # Consolidate StateElements by register, so we only need to set each register once reg_fields = self._groupStateElementFieldsByRegister(aStateElems) load_gpr64_seq = LoadGPR64(self.genThread) for (reg_name, (reg_field_names, reg_field_values)) in reg_fields.items(): # Ensure the register is initialized before attempting to read it self.randomInitializeRegister(reg_name) (reg_val, _) = self.readRegister(reg_name) for (i, reg_field_name) in enumerate(reg_field_names): reg_val = combineRegisterValueWithFieldValue( self, reg_name, reg_val, reg_field_name, reg_field_values[i]) load_gpr64_seq.load(reg_val_gpr_index, reg_val) self.genInstruction( 'CSRRW#register#RISCV', { 'rd': 0, 'rs1': reg_val_gpr_index, 'csr': self.getRegisterIndex(reg_name) }) self.updateVm() self._mHelperGprSet.releaseHelperGprs()
def processStateElement(self, aStateElem): if aStateElem.getStateElementType( ) != EStateElementType.SystemRegister: return False (reg_val_gpr_index, scratch_gpr_index) = self._mHelperGprSet.acquireHelperGprs( 2, aValidate=False) load_gpr64_seq = LoadGPR64(self.genThread) load_gpr64_seq.load(reg_val_gpr_index, aStateElem.getValues()[0]) if aStateElem.getName() == 'vtype': self._processVtypeStateElement(reg_val_gpr_index) elif aStateElem.getName() == 'vl': self._processVlStateElement(aStateElem, reg_val_gpr_index, scratch_gpr_index) else: self.genInstruction( 'CSRRW#register#RISCV', { 'rd': 0, 'rs1': reg_val_gpr_index, 'csr': aStateElem.getRegisterIndex() }) self._mHelperGprSet.releaseHelperGprs() return True
def processStateElements(self, aStateElems): if aStateElems[0].getStateElementType() != EStateElementType.Memory: self.error( 'This StateTransitionHandler can only process StateElements of type %s' % EStateElementType.Memory) (base_reg_index, mem_val_reg_index) = self._mHelperGprSet.acquireHelperGprs(2) load_gpr64_seq = LoadGPR64(self.genThread) offset_limit = 2**11 base_addr = -offset_limit for state_elem in aStateElems: load_gpr64_seq.load(mem_val_reg_index, state_elem.getValues()[0]) # This is a minor optimization for the likely case in which the starting addresses of # consecutive State Elements are close together. Instead of loading the base register # from scratch, we can offset from its current value. offset = state_elem.getStartAddress() - base_addr if (offset < -offset_limit) or (offset >= offset_limit): base_addr = state_elem.getStartAddress() load_gpr64_seq.load(base_reg_index, base_addr) offset = 0 self.genInstruction( 'SD##RISCV', { 'rs1': base_reg_index, 'rs2': mem_val_reg_index, 'simm12': offset, 'NoRestriction': 1 }) self._mHelperGprSet.releaseHelperGprs()
def _verify_memory_state(aSequence, aExpectedMemStateData): load_gpr64_seq = LoadGPR64(aSequence.genThread) (base_reg_index, mem_val_reg_index) = aSequence.getRandomGPRs(2, exclude="0") for (mem_start_addr, expected_mem_val) in aExpectedMemStateData: load_gpr64_seq.load(base_reg_index, mem_start_addr) if aSequence.getGlobalState("AppRegisterWidth") == 32: aSequence.genInstruction( "LW##RISCV", { "rd": mem_val_reg_index, "rs1": base_reg_index, "simm12": 0, "NoRestriction": 1, }, ) else: aSequence.genInstruction( "LD##RISCV", { "rd": mem_val_reg_index, "rs1": base_reg_index, "simm12": 0, "NoRestriction": 1, }, ) mem_val_reg_name = "x%d" % mem_val_reg_index (mem_val, valid) = aSequence.readRegister(mem_val_reg_name) assert_valid_register_value(aSequence, mem_val_reg_name, valid) if mem_val != expected_mem_val: aSequence.error( "Value at address 0x%x does not match the specified State. " "Expected=0x%x, Actual=0x%x" % (mem_start_addr, expected_mem_val, mem_val))
def processStateElement(self, aStateElem): if aStateElem.getStateElementType() != EStateElementType.PC: return False target_addr = aStateElem.getValues()[0] # Try using a PC-relative branch first to limit the number of generated instructions; fall # back to a register branch if that fails. (branch_offset, is_valid, num_hw) = self.getBranchOffset(self.getPEstate('PC'), target_addr, 20, 1) if is_valid: self.genInstruction('JAL##RISCV', { 'rd': 0, 'simm20': branch_offset, 'NoRestriction': 1 }) else: (branch_gpr_index, ) = self._mHelperGprSet.acquireHelperGprs(1) load_gpr = LoadGPR64(self.genThread) load_gpr.load(branch_gpr_index, target_addr) self.genInstruction('JALR##RISCV', { 'rd': 0, 'rs1': branch_gpr_index, 'simm12': 0, 'NoRestriction': 1 }) self._mHelperGprSet.releaseHelperGprs() return True
def generate(self, **kargs): # Disable floating point, so the StateTransition can enable it sys_reg_name = "misa" (sys_reg_val, valid) = self.readRegister(sys_reg_name) state_transition_test_utils.assert_valid_register_value( self, sys_reg_name, valid) load_gpr64_seq = LoadGPR64(self.genThread) rand_gpr_index = self.getRandomGPR(exclude="0") load_gpr64_seq.load(rand_gpr_index, 0x0000028) self.genInstruction( "CSRRC#register#RISCV", { "rd": 0, "rs1": rand_gpr_index, "csr": self.getRegisterIndex(sys_reg_name), }, ) state = self._createState() StateTransition.transitionToState(state, EStateTransitionOrderMode.ByPriority) state_transition_test_utils.verify_state(self, self._mExpectedStateData)
def processStateElements(self, aStateElems): if aStateElems[0].getStateElementType() != EStateElementType.Memory: self.error("This StateTransitionHandler can only process " "StateElements of type %s" % EStateElementType.Memory) ( base_reg_index, mem_val_reg_index, ) = self._mHelperGprSet.acquireHelperGprs(2) load_gpr64_seq = LoadGPR64(self.genThread) offset_limit = 2**11 base_addr = -offset_limit for state_elem in aStateElems: load_gpr64_seq.load(mem_val_reg_index, state_elem.getValues()[0]) # This is a minor optimization for the likely case in which the # starting addresses of consecutive State Elements are close # together. Instead of loading the base register from scratch, we # can offset from its current value. offset = state_elem.getStartAddress() - base_addr if (offset < -offset_limit) or (offset >= offset_limit): base_addr = state_elem.getStartAddress() load_gpr64_seq.load(base_reg_index, base_addr) offset = 0 self._genStoreInstruction(base_reg_index, mem_val_reg_index, offset) self._mHelperGprSet.releaseHelperGprs()
def _switchPrivilegeLevel(self, aParams): except_request_results = self.exceptionRequest('SystemCall', aParams) ret_code = except_request_results['RetCode'] if ret_code != 0: return ret_code self._assignRegisters(except_request_results['DataBlockAddrRegIndex'], except_request_results['ActionCodeRegIndex']) load_gpr64_seq = LoadGPR64(self.genThread) load_gpr64_seq.load(self._mDataBlockAddrRegIndex, except_request_results['DataBlockAddr']) self._genPrivilegeLevelSwitchInstructions( except_request_results['InstrSeqCode'], except_request_results['PrivilegeLevel'], except_request_results['TargetAddr'], except_request_results['IntermediateRetAddr']) self._unassignRegisters() self.genSequence('UpdatePeState', {'RecordId': except_request_results['RecordId']}) self.updateVm() return ret_code
def processStateElement(self, aStateElem): if aStateElem.getStateElementType( ) != EStateElementType.FloatingPointRegister: return False (reg_val_gpr_index, ) = self._mHelperGprSet.acquireHelperGprs(1) load_gpr64_seq = LoadGPR64(self.genThread) load_gpr64_seq.load(reg_val_gpr_index, aStateElem.getValues()[0]) (mem_block_ptr_index, ) = self._mHelperGprSet.acquireHelperGprs(1) self.initializeMemoryBlock(mem_block_ptr_index, [aStateElem]) fp_load_instr = "FLW##RISCV" if aStateElem.getName().startswith( "S") else "FLD##RISCV" self.genInstruction( fp_load_instr, { "rd": aStateElem.getRegisterIndex(), "rs1": mem_block_ptr_index, "simm12": 0, "NoRestriction": 1, }, ) self._mHelperGprSet.releaseHelperGprs() return True
def processStateElement(self, aStateElem): if aStateElem.getStateElementType() != EStateElementType.VmContext: return False (reg_val_gpr_index, ) = self._mHelperGprSet.acquireHelperGprs(1) # Ensure the register is initialized before attempting to read it self.randomInitializeRegister(aStateElem.getRegisterName()) (reg_val, _) = self.readRegister(aStateElem.getRegisterName()) reg_val = combine_register_value_with_field_value( self, aStateElem.getRegisterName(), reg_val, aStateElem.getRegisterFieldName(), aStateElem.getValues()[0], ) load_gpr64_seq = LoadGPR64(self.genThread) load_gpr64_seq.load(reg_val_gpr_index, reg_val) self.genInstruction( "CSRRW#register#RISCV", { "rd": 0, "rs1": reg_val_gpr_index, "csr": self.getRegisterIndex(aStateElem.getRegisterName()), }, ) self.updateVm() self._mHelperGprSet.releaseHelperGprs() return True
def processStateElements(self, aStateElems): if aStateElems[0].getStateElementType( ) != EStateElementType.SystemRegister: self.error("This StateTransitionHandler can only process " "StateElements of type %s" % EStateElementType.SystemRegister) ( mem_block_ptr_index, reg_val_gpr_index, scratch_gpr_index, ) = self._mHelperGprSet.acquireHelperGprs(3) self.initializeMemoryBlock(mem_block_ptr_index, aStateElems) (mem_block_ptr_val, _) = self.readRegister("x%d" % mem_block_ptr_index) load_gpr64_seq = LoadGPR64(self.genThread) offset_limit = 2**11 offset = 0 for state_elem in aStateElems: # This is a minor optimization that offsets from the memory block # pointer when possible rather than adjusting its value if offset >= offset_limit: mem_block_ptr_val += offset load_gpr64_seq.load(mem_block_ptr_index, mem_block_ptr_val) offset = 0 self._genLoadInstruction(reg_val_gpr_index, mem_block_ptr_index, offset) self._processSystemRegisterStateElement(state_elem, reg_val_gpr_index, scratch_gpr_index) offset += 8 self._mHelperGprSet.releaseHelperGprs()
def processStateElement(self, aStateElem): if aStateElem.getStateElementType() != EStateElementType.VmContext: return False (reg_val_gpr_index, ) = self._mHelperGprSet.acquireHelperGprs(1) # Ensure the register is initialized before attempting to read it self.randomInitializeRegister(aStateElem.getRegisterName()) (reg_val, _) = self.readRegister(aStateElem.getRegisterName()) reg_val = combineRegisterValueWithFieldValue( self, aStateElem.getRegisterName(), reg_val, aStateElem.getRegisterFieldName(), aStateElem.getValues()[0]) load_gpr64_seq = LoadGPR64(self.genThread) load_gpr64_seq.load(reg_val_gpr_index, reg_val) self.genInstruction( 'CSRRW#register#RISCV', { 'rd': 0, 'rs1': reg_val_gpr_index, 'csr': self.getRegisterIndex(aStateElem.getRegisterName()) }) self.updateVm() self._mHelperGprSet.releaseHelperGprs() return True
def _switchPrivilegeLevel(self, aParams): except_request_results = self.exceptionRequest("SystemCall", aParams) ret_code = except_request_results["RetCode"] if ret_code != 0: return ret_code self._assignRegisters( except_request_results["DataBlockAddrRegIndex"], except_request_results["ActionCodeRegIndex"], ) load_gpr64_seq = LoadGPR64(self.genThread) load_gpr64_seq.load( self._mDataBlockAddrRegIndex, except_request_results["DataBlockAddr"], ) self._genPrivilegeLevelSwitchInstructions( except_request_results["InstrSeqCode"], except_request_results["PrivilegeLevel"], except_request_results["TargetAddr"], except_request_results["IntermediateRetAddr"], ) self._unassignRegisters() self.genSequence("UpdatePeState", {"RecordId": except_request_results["RecordId"]}) self.updateVm() return ret_code
def processStateElement(self, aStateElem): if aStateElem.getStateElementType() != EStateElementType.GPR: return False load_gpr64_seq = LoadGPR64(self.genThread) load_gpr64_seq.load(aStateElem.getRegisterIndex(), aStateElem.getValues()[0]) return True
def releaseHelperGprs(self): load_gpr64_seq = LoadGPR64(self._mStateTransHandler.genThread) for (i, non_arbitrary_gpr_index) in enumerate( self._mNonArbitraryGprIndices): load_gpr64_seq.load(non_arbitrary_gpr_index, self._mNonArbitraryGprOrigValues[i]) self._mNonArbitraryGprOrigValues = [] self._mNonArbitraryGprIndices = [] self._mArbitraryGprIndices = []
def _generateInstructionParameters(self): instr_params = {} load_gpr64_seq = LoadGPR64(self.genThread) (avl_reg_index, vtype_reg_index) = self.getRandomGPRs(2, exclude='0') load_gpr64_seq.load(avl_reg_index, self.mAvl) instr_params['rs1'] = avl_reg_index load_gpr64_seq.load(vtype_reg_index, self.mVtype) instr_params['rs2'] = vtype_reg_index return instr_params
def _generateInstructionParameters(self): instr_params = {} load_gpr64_seq = LoadGPR64(self.genThread) avl_reg_index = self.getRandomGPR(exclude='0') load_gpr64_seq.load(avl_reg_index, self.mAvl) instr_params['rs1'] = avl_reg_index avl_reg_index = self.getRandomGPR(exclude='0') instr_params['zimm10'] = self.mVtype return instr_params
def _initializeStackPointer(self, aLoadStackPointer): self.initializeRegister(self._mSpName, self._mStackTop) if aLoadStackPointer: load_gpr64_seq = LoadGPR64(self.genThread) load_gpr64_seq.load(self._mSpIndex, self._mStackTop) # Reserve the stack register to prevent its corruption by randomly-generated instructions self.reserveRegister(self._mSpName, 'ReadWrite') Log.debug('DEBUG [ExceptionHandlerStackRISCV::_initializeStackPointer] STACK REG: %s (index: %d), value: 0x%x\n' % (self._mSpName, self._mSpIndex, self._mStackTop))
def _verifyMemoryState(aSequence, aExpectedMemStateData): load_gpr64_seq = LoadGPR64(aSequence.genThread) (base_reg_index, mem_val_reg_index) = aSequence.getRandomGPRs(2, exclude='0') for (mem_start_addr, expected_mem_val) in aExpectedMemStateData: load_gpr64_seq.load(base_reg_index, mem_start_addr) aSequence.genInstruction('LD##RISCV', {'rd': mem_val_reg_index, 'rs1': base_reg_index, 'simm12': 0, 'NoRestriction': 1}) mem_val_reg_name = 'x%d' % mem_val_reg_index (mem_val, valid) = aSequence.readRegister(mem_val_reg_name) assertValidRegisterValue(aSequence, mem_val_reg_name, valid) if mem_val != expected_mem_val: aSequence.error('Value at address 0x%x does not match the specified State. Expected=0x%x, Actual=0x%x' % (mem_start_addr, expected_mem_val, mem_val))
def _configureExceptionDelegation(self, aExceptCodes): # Spike appears to only allow exception codes 0, 3, 8, 12, 13 and 15 to be delegated. The # logic below harmlessly ignores this constraint for simplicity and in case Spike's # implementation changes in the future. There does not appear to be any provisions in the # RISCV Privileged Architecture Specification that mandate such a restrictive delegation # scheme. medeleg_val = 0 for except_code in aExceptCodes: medeleg_val |= (RandomUtils.random32(0, 1) << except_code) load_gpr64_seq = LoadGPR64(self.genThread) medeleg_val_reg_index = self.getRandomGPR(exclude='0') load_gpr64_seq.load(medeleg_val_reg_index, medeleg_val)
def _loadRandomizedGprValue(self, aGprIndex): gpr_val = 0 if RandomUtils.random32(0, 1) == 0: gpr_name = 'x%d' % aGprIndex self.randomInitializeRegister(gpr_name) (gpr_val, valid) = self.readRegister(gpr_name) exception_handlers_test_utils.assertValidGprValue( self, aGprIndex, valid) else: load_gpr64_seq = LoadGPR64(self.genThread) gpr_val = RandomUtils.random64() load_gpr64_seq.load(aGprIndex, gpr_val) return gpr_val
def generate(self, **kargs): self.randomInitializeRegister('D0') for reg_index in range(1, 32): self.randomInitializeRegister('D%d' % reg_index) self.initializeRegister('x%d' % reg_index, RandomUtils.random64(0x0, 0x7FFFFFFFFFFF)) instructions = ('LD##RISCV', 'SD##RISCV') for _ in range(RandomUtils.random32(100, 200)): self.genInstruction(self.choice(instructions), {'NoPreamble': 1}) load_gpr64_seq = LoadGPR64(self.genThread) for reg_index in range(1, 32): load_gpr64_seq.load( reg_index, RandomUtils.random64(0x800000000000, 0x7FFFFFFFFFFFFFFF))
def _loadRandomizedGprValue(self, aGprIndex): gpr_val = 0 if RandomUtils.random32(0, 1) == 0: gpr_name = "x%d" % aGprIndex self.randomInitializeRegister(gpr_name) (gpr_val, valid) = self.readRegister(gpr_name) exception_handlers_test_utils.assert_valid_gpr_value( self, aGprIndex, valid) else: load_gpr64_seq = LoadGPR64(self.genThread) gpr_val = (RandomUtils.random32() if self.getGlobalState("AppRegisterWidth") == 32 else RandomUtils.random64()) load_gpr64_seq.load(aGprIndex, gpr_val) return gpr_val
def initializeMemoryBlock(self, aMemBlockPtrIndex, aStateElems): mem_block_size = 0 alignment = 0 for state_elem in aStateElems: byte_count = len(state_elem.getValues()) * 8 mem_block_size += byte_count # Align the memory block to the largest StateElement size if byte_count > alignment: alignment = byte_count mem_block_start_addr = self.genVA(Size=mem_block_size, Align=alignment, Type='D') self._initializeMemoryWithStateElementValues(mem_block_start_addr, aStateElems) load_gpr64_seq = LoadGPR64(self.genThread) load_gpr64_seq.load(aMemBlockPtrIndex, mem_block_start_addr)
def processStateElements(self, aStateElems): if aStateElems[0].getStateElementType( ) != EStateElementType.SystemRegister: self.error( 'This StateTransitionHandler can only process StateElements of type %s' % EStateElementType.SystemRegister) (mem_block_ptr_index, reg_val_gpr_index, scratch_gpr_index) = self._mHelperGprSet.acquireHelperGprs(3) self.initializeMemoryBlock(mem_block_ptr_index, aStateElems) (mem_block_ptr_val, _) = self.readRegister('x%d' % mem_block_ptr_index) load_gpr64_seq = LoadGPR64(self.genThread) offset_limit = 2**11 offset = 0 for state_elem in aStateElems: # This is a minor optimization that offsets from the memory block pointer when possible # rather than adjusting its value if offset >= offset_limit: mem_block_ptr_val += offset load_gpr64_seq.load(mem_block_ptr_index, mem_block_ptr_val) offset = 0 self.genInstruction( 'LD##RISCV', { 'rd': reg_val_gpr_index, 'rs1': mem_block_ptr_index, 'simm12': offset, 'NoRestriction': 1 }) if state_elem.getName() == 'vtype': self._processVtypeStateElement(reg_val_gpr_index) elif state_elem.getName() == 'vl': self._processVlStateElement(state_elem, reg_val_gpr_index, scratch_gpr_index) else: self.genInstruction( 'CSRRW#register#RISCV', { 'rd': 0, 'rs1': reg_val_gpr_index, 'csr': state_elem.getRegisterIndex() }) offset += 8 self._mHelperGprSet.releaseHelperGprs()
def generate(self, **kwargs): with ThreadSplitterContextManager(self): pc = PcConfig.get_base_boot_pc() (skip_boot, skip_boot_valid) = self.getOption("SkipBootCode") if skip_boot_valid and skip_boot == 1: pc = PcConfig.get_base_initial_pc() ( boot_pc_reg_index, thread_id_reg_index, pc_offset_reg_index, ) = self.getRandomGPRs(3, exclude="0") assembly_helper = AssemblyHelperRISCV(self) assembly_helper.genReadSystemRegister( thread_id_reg_index, "mhartid" ) # Get the thread ID load_gpr64_seq = LoadGPR64(self.genThread) load_gpr64_seq.load( pc_offset_reg_index, PcConfig.get_boot_pc_offset() ) self.genInstruction( "MUL##RISCV", { "rd": pc_offset_reg_index, "rs1": thread_id_reg_index, "rs2": pc_offset_reg_index, }, ) # Multiply the base PC offset by the thread ID load_gpr64_seq.load(boot_pc_reg_index, PcConfig.get_base_boot_pc()) assembly_helper.genAddRegister( boot_pc_reg_index, pc_offset_reg_index ) # Add the thread PC offset to the base initial PC self.genInstruction( "JALR##RISCV", { "rd": 0, "rs1": boot_pc_reg_index, "simm12": 0, "NoBnt": 1, "NoRestriction": 1, }, ) # Branch to calculated address
def processStateElement(self, aStateElem): if aStateElem.getStateElementType( ) != EStateElementType.FloatingPointRegister: return False (reg_val_gpr_index, ) = self._mHelperGprSet.acquireHelperGprs(1) # TODO(Noah): Handle Q regisers when the Q extension is supported. load_gpr64_seq = LoadGPR64(self.genThread) load_gpr64_seq.load(reg_val_gpr_index, aStateElem.getValues()[0]) self.genInstruction('FMV.D.X##RISCV', { 'rd': aStateElem.getRegisterIndex(), 'rs1': reg_val_gpr_index }) self._mHelperGprSet.releaseHelperGprs() return True