void frvbf_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)); } }
/* Read a SI which spans two cache lines */ static DI read_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); }
psim_read_register(psim *system, int which_cpu, void *buf, const char reg[], transfer_mode mode) { register_descriptions description; char *cooked_buf; cpu *processor; /* find our processor */ if (which_cpu == MAX_NR_PROCESSORS) { if (system->last_cpu == system->nr_cpus || system->last_cpu == -1) which_cpu = 0; else which_cpu = system->last_cpu; } ASSERT(which_cpu >= 0 && which_cpu < system->nr_cpus); processor = system->processors[which_cpu]; /* find the register description */ description = register_description(reg); if (description.type == reg_invalid) return 0; cooked_buf = alloca (description.size); /* get the cooked value */ switch (description.type) { case reg_gpr: *(gpreg*)cooked_buf = cpu_registers(processor)->gpr[description.index]; break; case reg_spr: *(spreg*)cooked_buf = cpu_registers(processor)->spr[description.index]; break; case reg_sr: *(sreg*)cooked_buf = cpu_registers(processor)->sr[description.index]; break; case reg_fpr: *(fpreg*)cooked_buf = cpu_registers(processor)->fpr[description.index]; break; case reg_pc: *(unsigned_word*)cooked_buf = cpu_get_program_counter(processor); break; case reg_cr: *(creg*)cooked_buf = cpu_registers(processor)->cr; break; case reg_msr: *(msreg*)cooked_buf = cpu_registers(processor)->msr; break; case reg_fpscr: *(fpscreg*)cooked_buf = cpu_registers(processor)->fpscr; break; case reg_insns: *(unsigned_word*)cooked_buf = mon_get_number_of_insns(system->monitor, which_cpu); break; case reg_stalls: if (cpu_model(processor) == NULL) error("$stalls only valid if processor unit model enabled (-I)\n"); *(unsigned_word*)cooked_buf = model_get_number_of_stalls(cpu_model(processor)); break; case reg_cycles: if (cpu_model(processor) == NULL) error("$cycles only valid if processor unit model enabled (-I)\n"); *(unsigned_word*)cooked_buf = model_get_number_of_cycles(cpu_model(processor)); break; #ifdef WITH_ALTIVEC case reg_vr: *(vreg*)cooked_buf = cpu_registers(processor)->altivec.vr[description.index]; break; case reg_vscr: *(vscreg*)cooked_buf = cpu_registers(processor)->altivec.vscr; break; #endif #ifdef WITH_E500 case reg_gprh: *(gpreg*)cooked_buf = cpu_registers(processor)->e500.gprh[description.index]; break; case reg_evr: *(unsigned64*)cooked_buf = EVR(description.index); break; case reg_acc: *(accreg*)cooked_buf = cpu_registers(processor)->e500.acc; break; #endif default: printf_filtered("psim_read_register(processor=0x%lx,buf=0x%lx,reg=%s) %s\n", (unsigned long)processor, (unsigned long)buf, reg, "read of this register unimplemented"); break; } /* the PSIM internal values are in host order. To fetch raw data, they need to be converted into target order and then returned */ if (mode == raw_transfer) { /* FIXME - assumes that all registers are simple integers */ switch (description.size) { case 1: *(unsigned_1*)buf = H2T_1(*(unsigned_1*)cooked_buf); break; case 2: *(unsigned_2*)buf = H2T_2(*(unsigned_2*)cooked_buf); break; case 4: *(unsigned_4*)buf = H2T_4(*(unsigned_4*)cooked_buf); break; case 8: *(unsigned_8*)buf = H2T_8(*(unsigned_8*)cooked_buf); break; #ifdef WITH_ALTIVEC case 16: if (CURRENT_HOST_BYTE_ORDER != CURRENT_TARGET_BYTE_ORDER) { union { vreg v; unsigned_8 d[2]; } h, t; memcpy(&h.v/*dest*/, cooked_buf/*src*/, description.size); { _SWAP_8(t.d[0] =, h.d[1]); } { _SWAP_8(t.d[1] =, h.d[0]); } memcpy(buf/*dest*/, &t/*src*/, description.size); break; } else memcpy(buf/*dest*/, cooked_buf/*src*/, description.size); break; #endif } }