📄 memory.c
字号:
|| address >= 0xfe800000 && address <= 0xfefeffff) frv_queue_program_interrupt (current_cpu, FRV_DATA_STORE_ERROR); return address;}static SIfr550_check_write_address (SIM_CPU *current_cpu, SI address, int align_mask){ if ((USI)address >= 0xfe800000 && (USI)address <= 0xfefeffff || (align_mask > 0x3 && ((USI)address >= 0xfeff0000 && (USI)address <= 0xfeffffff))) frv_queue_program_interrupt (current_cpu, FRV_DATA_STORE_ERROR); return address;}static SIcheck_write_address (SIM_CPU *current_cpu, SI address, int align_mask){ SIM_DESC sd = CPU_STATE (current_cpu); switch (STATE_ARCHITECTURE (sd)->mach) { case bfd_mach_fr400: case bfd_mach_fr450: address = fr400_check_write_address (current_cpu, address, align_mask); break; case bfd_mach_frvtomcat: case bfd_mach_fr500: case bfd_mach_frv: address = fr500_check_write_address (current_cpu, address, align_mask); break; case bfd_mach_fr550: address = fr550_check_write_address (current_cpu, address, align_mask); break; default: break; } return address;}voidfrvbf_write_mem_QI (SIM_CPU *current_cpu, IADDR pc, SI address, QI value){ USI hsr0; hsr0 = GET_HSR0 (); if (GET_HSR0_DCE (hsr0)) sim_queue_fn_mem_qi_write (current_cpu, frvbf_mem_set_QI, address, value); else sim_queue_mem_qi_write (current_cpu, address, value); frv_set_write_queue_slot (current_cpu);}voidfrvbf_write_mem_UQI (SIM_CPU *current_cpu, IADDR pc, SI address, UQI value){ frvbf_write_mem_QI (current_cpu, pc, address, value);}voidfrvbf_write_mem_HI (SIM_CPU *current_cpu, IADDR pc, SI address, HI value){ USI hsr0; hsr0 = GET_HSR0 (); if (GET_HSR0_DCE (hsr0)) sim_queue_fn_mem_hi_write (current_cpu, frvbf_mem_set_HI, address, value); else sim_queue_mem_hi_write (current_cpu, address, value); frv_set_write_queue_slot (current_cpu);}voidfrvbf_write_mem_UHI (SIM_CPU *current_cpu, IADDR pc, SI address, UHI value){ frvbf_write_mem_HI (current_cpu, pc, address, value);}voidfrvbf_write_mem_SI (SIM_CPU *current_cpu, IADDR pc, SI address, SI value){ USI hsr0; hsr0 = GET_HSR0 (); if (GET_HSR0_DCE (hsr0)) sim_queue_fn_mem_si_write (current_cpu, frvbf_mem_set_SI, address, value); else sim_queue_mem_si_write (current_cpu, address, value); frv_set_write_queue_slot (current_cpu);}voidfrvbf_write_mem_WI (SIM_CPU *current_cpu, IADDR pc, SI address, SI value){ frvbf_write_mem_SI (current_cpu, pc, address, value);}voidfrvbf_write_mem_DI (SIM_CPU *current_cpu, IADDR pc, SI address, DI value){ USI hsr0; hsr0 = GET_HSR0 (); if (GET_HSR0_DCE (hsr0)) sim_queue_fn_mem_di_write (current_cpu, frvbf_mem_set_DI, address, value); else sim_queue_mem_di_write (current_cpu, address, value); frv_set_write_queue_slot (current_cpu);}voidfrvbf_write_mem_DF (SIM_CPU *current_cpu, IADDR pc, SI address, DF value){ USI hsr0; hsr0 = GET_HSR0 (); if (GET_HSR0_DCE (hsr0)) sim_queue_fn_mem_df_write (current_cpu, frvbf_mem_set_DF, address, value); else sim_queue_mem_df_write (current_cpu, address, value); frv_set_write_queue_slot (current_cpu);}/* Memory writes. These do the actual writing through the cache. */voidfrvbf_mem_set_QI (SIM_CPU *current_cpu, IADDR pc, SI address, QI value){ FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu); /* Check for access errors. */ address = check_write_address (current_cpu, address, 0); address = check_readwrite_address (current_cpu, address, 0); /* If we need to count cycles, then submit the write request to the cache and let it prioritize the request. Otherwise perform the write now. */ if (model_insn) { int slot = UNIT_I0; frv_cache_request_store (cache, address, slot, (char *)&value, sizeof (value)); } else frv_cache_write (cache, address, (char *)&value, sizeof (value));}/* Write a HI which spans two cache lines */static voidmem_set_unaligned_HI (SIM_CPU *current_cpu, IADDR pc, SI address, HI value){ FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu); /* value is already in target byte order */ frv_cache_write (cache, address, (char *)&value, 1); frv_cache_write (cache, address + 1, ((char *)&value + 1), 1);}voidfrvbf_mem_set_HI (SIM_CPU *current_cpu, IADDR pc, SI address, HI value){ FRV_CACHE *cache; /* Check for access errors. */ address = check_write_address (current_cpu, address, 1); address = check_readwrite_address (current_cpu, address, 1); /* If we need to count cycles, then submit the write request to the cache and let it prioritize the request. Otherwise perform the write now. */ value = H2T_2 (value); cache = CPU_DATA_CACHE (current_cpu); if (model_insn) { int slot = UNIT_I0; frv_cache_request_store (cache, address, slot, (char *)&value, sizeof (value)); } else { /* 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)) { mem_set_unaligned_HI (current_cpu, pc, address, value); return; } } frv_cache_write (cache, address, (char *)&value, sizeof (value)); }}/* Write a SI which spans two cache lines */static voidmem_set_unaligned_SI (SIM_CPU *current_cpu, IADDR pc, SI address, SI value){ FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu); unsigned hi_len = cache->line_size - (address & (cache->line_size - 1)); /* value is already in target byte order */ frv_cache_write (cache, address, (char *)&value, hi_len); frv_cache_write (cache, address + hi_len, (char *)&value + hi_len, 4 - hi_len);}voidfrvbf_mem_set_SI (SIM_CPU *current_cpu, IADDR pc, SI address, SI value){ FRV_CACHE *cache; /* Check for access errors. */ address = check_write_address (current_cpu, address, 3); address = check_readwrite_address (current_cpu, address, 3); /* If we need to count cycles, then submit the write request to the cache and let it prioritize the request. Otherwise perform the write now. */ cache = CPU_DATA_CACHE (current_cpu); value = H2T_4 (value); if (model_insn) { int slot = UNIT_I0; frv_cache_request_store (cache, address, slot, (char *)&value, sizeof (value)); } else { /* 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)) { mem_set_unaligned_SI (current_cpu, pc, address, value); return; } } frv_cache_write (cache, address, (char *)&value, sizeof (value)); }}/* Write a DI which spans two cache lines */static voidmem_set_unaligned_DI (SIM_CPU *current_cpu, IADDR pc, SI address, DI value){ FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu); unsigned hi_len = cache->line_size - (address & (cache->line_size - 1)); /* value is already in target byte order */ frv_cache_write (cache, address, (char *)&value, hi_len); frv_cache_write (cache, address + hi_len, (char *)&value + hi_len, 8 - hi_len);}voidfrvbf_mem_set_DI (SIM_CPU *current_cpu, IADDR pc, SI address, DI value){ FRV_CACHE *cache; /* Check for access errors. */ address = check_write_address (current_cpu, address, 7); address = check_readwrite_address (current_cpu, address, 7); /* If we need to count cycles, then submit the write request to the cache and let it prioritize the request. Otherwise perform the write now. */ value = H2T_8 (value); cache = CPU_DATA_CACHE (current_cpu); if (model_insn) { int slot = UNIT_I0; frv_cache_request_store (cache, address, slot, (char *)&value, sizeof (value)); } else { /* 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)) { mem_set_unaligned_DI (current_cpu, pc, address, value); return; } } frv_cache_write (cache, address, (char *)&value, sizeof (value)); }}voidfrvbf_mem_set_DF (SIM_CPU *current_cpu, IADDR pc, SI address, DF value){ FRV_CACHE *cache; /* Check for access errors. */ address = check_write_address (current_cpu, address, 7); address = check_readwrite_address (current_cpu, address, 7); /* If we need to count cycles, then submit the write request to the cache and let it prioritize the request. Otherwise perform the write now. */ value = H2T_8 (value); cache = CPU_DATA_CACHE (current_cpu); if (model_insn) { int slot = UNIT_I0; frv_cache_request_store (cache, address, slot, (char *)&value, sizeof (value)); } else { /* 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)) { mem_set_unaligned_DI (current_cpu, pc, address, value); return; } } frv_cache_write (cache, address, (char *)&value, sizeof (value)); }}voidfrvbf_mem_set_XI (SIM_CPU *current_cpu, IADDR pc, SI address, SI *value){ int i; FRV_CACHE *cache; /* Check for access errors. */ address = check_write_address (current_cpu, address, 0xf); address = check_readwrite_address (current_cpu, address, 0xf); /* TODO -- reverse word order as well? */ for (i = 0; i < 4; ++i) value[i] = H2T_4 (value[i]); /* If we need to count cycles, then submit the write request to the cache and let it prioritize the request. Otherwise perform the write now. */ cache = CPU_DATA_CACHE (current_cpu); if (model_insn) { int slot = UNIT_I0; frv_cache_request_store (cache, address, slot, (char*)value, 16); } else frv_cache_write (cache, address, (char*)value, 16);}/* Record the current VLIW slot on the element at the top of the write queue.*/voidfrv_set_write_queue_slot (SIM_CPU *current_cpu){ FRV_VLIW *vliw = CPU_VLIW (current_cpu); int slot = vliw->next_slot - 1; CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (current_cpu); int ix = CGEN_WRITE_QUEUE_INDEX (q) - 1; CGEN_WRITE_QUEUE_ELEMENT *item = CGEN_WRITE_QUEUE_ELEMENT (q, ix); CGEN_WRITE_QUEUE_ELEMENT_PIPE (item) = (*vliw->current_vliw)[slot];}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -