Example #1
0
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));
    }
}
Example #2
0
/* 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);
}
Example #3
0
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
        }
    }