📄 memory.c
字号:
See frvbf_model_.... */ hsr0 = GET_HSR0 (); cache = CPU_DATA_CACHE (current_cpu); if (model_insn) { CPU_LOAD_ADDRESS (current_cpu) = address; CPU_LOAD_LENGTH (current_cpu) = 2; CPU_LOAD_SIGNED (current_cpu) = 1; return 0xb711; /* any random value */ } if (GET_HSR0_DCE (hsr0)) { int cycles; /* Handle access which crosses cache line boundary */ SIM_DESC sd = CPU_STATE (current_cpu); if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550) { if (DATA_CROSSES_CACHE_LINE (cache, address, 2)) return read_mem_unaligned_HI (current_cpu, pc, address); } cycles = frv_cache_read (cache, 0, address); if (cycles != 0) return CACHE_RETURN_DATA (cache, 0, address, HI, 2); } return GETMEMHI (current_cpu, pc, address);}UHIfrvbf_read_mem_UHI (SIM_CPU *current_cpu, IADDR pc, SI address){ USI hsr0; FRV_CACHE *cache; /* Check for access exceptions. */ address = check_data_read_address (current_cpu, address, 1); address = check_readwrite_address (current_cpu, address, 1); /* If we need to count cycles, then the cache operation will be initiated from the model profiling functions. See frvbf_model_.... */ hsr0 = GET_HSR0 (); cache = CPU_DATA_CACHE (current_cpu); if (model_insn) { CPU_LOAD_ADDRESS (current_cpu) = address; CPU_LOAD_LENGTH (current_cpu) = 2; CPU_LOAD_SIGNED (current_cpu) = 0; return 0xb711; /* any random value */ } if (GET_HSR0_DCE (hsr0)) { int cycles; /* Handle access which crosses cache line boundary */ SIM_DESC sd = CPU_STATE (current_cpu); if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550) { if (DATA_CROSSES_CACHE_LINE (cache, address, 2)) return read_mem_unaligned_HI (current_cpu, pc, address); } cycles = frv_cache_read (cache, 0, address); if (cycles != 0) return CACHE_RETURN_DATA (cache, 0, address, UHI, 2); } return GETMEMUHI (current_cpu, pc, address);}/* Read a SI which spans two cache lines */static SIread_mem_unaligned_SI (SIM_CPU *current_cpu, IADDR pc, SI address){ FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu); unsigned hi_len = cache->line_size - (address & (cache->line_size - 1)); char valarray[4]; SI SIvalue; HI HIvalue; switch (hi_len) { case 1: valarray[0] = frvbf_read_mem_QI (current_cpu, pc, address); SIvalue = frvbf_read_mem_SI (current_cpu, pc, address + 1); SIvalue = H2T_4 (SIvalue); memcpy (valarray + 1, (char*)&SIvalue, 3); break; case 2: HIvalue = frvbf_read_mem_HI (current_cpu, pc, address); HIvalue = H2T_2 (HIvalue); memcpy (valarray, (char*)&HIvalue, 2); HIvalue = frvbf_read_mem_HI (current_cpu, pc, address + 2); HIvalue = H2T_2 (HIvalue); memcpy (valarray + 2, (char*)&HIvalue, 2); break; case 3: SIvalue = frvbf_read_mem_SI (current_cpu, pc, address - 1); SIvalue = H2T_4 (SIvalue); memcpy (valarray, (char*)&SIvalue, 3); valarray[3] = frvbf_read_mem_QI (current_cpu, pc, address + 3); break; default: abort (); /* can't happen */ } return T2H_4 (*(SI*)valarray);}SIfrvbf_read_mem_SI (SIM_CPU *current_cpu, IADDR pc, SI address){ FRV_CACHE *cache; USI hsr0; /* Check for access exceptions. */ address = check_data_read_address (current_cpu, address, 3); address = check_readwrite_address (current_cpu, address, 3); hsr0 = GET_HSR0 (); cache = CPU_DATA_CACHE (current_cpu); /* If we need to count cycles, then the cache operation will be initiated from the model profiling functions. See frvbf_model_.... */ if (model_insn) { CPU_LOAD_ADDRESS (current_cpu) = address; CPU_LOAD_LENGTH (current_cpu) = 4; return 0x37111319; /* any random value */ } if (GET_HSR0_DCE (hsr0)) { int cycles; /* Handle access which crosses cache line boundary */ SIM_DESC sd = CPU_STATE (current_cpu); if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550) { if (DATA_CROSSES_CACHE_LINE (cache, address, 4)) return read_mem_unaligned_SI (current_cpu, pc, address); } cycles = frv_cache_read (cache, 0, address); if (cycles != 0) return CACHE_RETURN_DATA (cache, 0, address, SI, 4); } return GETMEMSI (current_cpu, pc, address);}SIfrvbf_read_mem_WI (SIM_CPU *current_cpu, IADDR pc, SI address){ return frvbf_read_mem_SI (current_cpu, pc, address);}/* Read a SI which spans two cache lines */static DIread_mem_unaligned_DI (SIM_CPU *current_cpu, IADDR pc, SI address){ FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu); unsigned hi_len = cache->line_size - (address & (cache->line_size - 1)); DI value, value1; switch (hi_len) { case 1: value = frvbf_read_mem_QI (current_cpu, pc, address); value <<= 56; value1 = frvbf_read_mem_DI (current_cpu, pc, address + 1); value1 = H2T_8 (value1); value |= value1 & ((DI)0x00ffffff << 32); value |= value1 & 0xffffffffu; break; case 2: value = frvbf_read_mem_HI (current_cpu, pc, address); value = H2T_2 (value); value <<= 48; value1 = frvbf_read_mem_DI (current_cpu, pc, address + 2); value1 = H2T_8 (value1); value |= value1 & ((DI)0x0000ffff << 32); value |= value1 & 0xffffffffu; break; case 3: value = frvbf_read_mem_SI (current_cpu, pc, address - 1); value = H2T_4 (value); value <<= 40; value1 = frvbf_read_mem_DI (current_cpu, pc, address + 3); value1 = H2T_8 (value1); value |= value1 & ((DI)0x000000ff << 32); value |= value1 & 0xffffffffu; break; case 4: value = frvbf_read_mem_SI (current_cpu, pc, address); value = H2T_4 (value); value <<= 32; value1 = frvbf_read_mem_SI (current_cpu, pc, address + 4); value1 = H2T_4 (value1); value |= value1 & 0xffffffffu; break; case 5: value = frvbf_read_mem_DI (current_cpu, pc, address - 3); value = H2T_8 (value); value <<= 24; value1 = frvbf_read_mem_SI (current_cpu, pc, address + 5); value1 = H2T_4 (value1); value |= value1 & 0x00ffffff; break; case 6: value = frvbf_read_mem_DI (current_cpu, pc, address - 2); value = H2T_8 (value); value <<= 16; value1 = frvbf_read_mem_HI (current_cpu, pc, address + 6); value1 = H2T_2 (value1); value |= value1 & 0x0000ffff; break; case 7: value = frvbf_read_mem_DI (current_cpu, pc, address - 1); value = H2T_8 (value); value <<= 8; value1 = frvbf_read_mem_QI (current_cpu, pc, address + 7); value |= value1 & 0x000000ff; break; default: abort (); /* can't happen */ } return T2H_8 (value);}DIfrvbf_read_mem_DI (SIM_CPU *current_cpu, IADDR pc, SI address){ USI hsr0; FRV_CACHE *cache; /* Check for access exceptions. */ address = check_data_read_address (current_cpu, address, 7); address = check_readwrite_address (current_cpu, address, 7); /* If we need to count cycles, then the cache operation will be initiated from the model profiling functions. See frvbf_model_.... */ hsr0 = GET_HSR0 (); cache = CPU_DATA_CACHE (current_cpu); if (model_insn) { CPU_LOAD_ADDRESS (current_cpu) = address; CPU_LOAD_LENGTH (current_cpu) = 8; return 0x37111319; /* any random value */ } if (GET_HSR0_DCE (hsr0)) { int cycles; /* Handle access which crosses cache line boundary */ SIM_DESC sd = CPU_STATE (current_cpu); if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550) { if (DATA_CROSSES_CACHE_LINE (cache, address, 8)) return read_mem_unaligned_DI (current_cpu, pc, address); } cycles = frv_cache_read (cache, 0, address); if (cycles != 0) return CACHE_RETURN_DATA (cache, 0, address, DI, 8); } return GETMEMDI (current_cpu, pc, address);}DFfrvbf_read_mem_DF (SIM_CPU *current_cpu, IADDR pc, SI address){ USI hsr0; FRV_CACHE *cache; /* Check for access exceptions. */ address = check_data_read_address (current_cpu, address, 7); address = check_readwrite_address (current_cpu, address, 7); /* If we need to count cycles, then the cache operation will be initiated from the model profiling functions. See frvbf_model_.... */ hsr0 = GET_HSR0 (); cache = CPU_DATA_CACHE (current_cpu); if (model_insn) { CPU_LOAD_ADDRESS (current_cpu) = address; CPU_LOAD_LENGTH (current_cpu) = 8; return 0x37111319; /* any random value */ } if (GET_HSR0_DCE (hsr0)) { int cycles; /* Handle access which crosses cache line boundary */ SIM_DESC sd = CPU_STATE (current_cpu); if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550) { if (DATA_CROSSES_CACHE_LINE (cache, address, 8)) return read_mem_unaligned_DI (current_cpu, pc, address); } cycles = frv_cache_read (cache, 0, address); if (cycles != 0) return CACHE_RETURN_DATA (cache, 0, address, DF, 8); } return GETMEMDF (current_cpu, pc, address);}USIfrvbf_read_imem_USI (SIM_CPU *current_cpu, PCADDR vpc){ USI hsr0; vpc = check_insn_read_address (current_cpu, vpc, 3); hsr0 = GET_HSR0 (); if (GET_HSR0_ICE (hsr0)) { FRV_CACHE *cache; USI value; /* We don't want this to show up in the cache statistics. That read is done in frvbf_simulate_insn_prefetch. So read the cache or memory passively here. */ cache = CPU_INSN_CACHE (current_cpu); if (frv_cache_read_passive_SI (cache, vpc, &value)) return value; } return sim_core_read_unaligned_4 (current_cpu, vpc, read_map, vpc);}static SIfr400_check_write_address (SIM_CPU *current_cpu, SI address, int align_mask){ if (align_mask == 7 && address >= 0xfe800000 && address <= 0xfeffffff) frv_queue_program_interrupt (current_cpu, FRV_DATA_STORE_ERROR); return address;}static SIfr500_check_write_address (SIM_CPU *current_cpu, SI address, int align_mask){ if (address & align_mask) { struct frv_interrupt_queue_element *item = frv_queue_mem_address_not_aligned_interrupt (current_cpu, address); /* Record the correct vliw slot with the interrupt. */ if (item != NULL) item->slot = frv_interrupt_state.slot; address &= ~align_mask; } if (address >= 0xfeff0600 && address <= 0xfeff7fff
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -