diff options
Diffstat (limited to 'sim/ppc/psim.c')
-rw-r--r-- | sim/ppc/psim.c | 114 |
1 files changed, 101 insertions, 13 deletions
diff --git a/sim/ppc/psim.c b/sim/ppc/psim.c index 76bb4523342..c20effb6f59 100644 --- a/sim/ppc/psim.c +++ b/sim/ppc/psim.c @@ -1,6 +1,6 @@ /* This file is part of the program psim. - Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au> + Copyright 1994, 1995, 1996, 1997, 2003 Andrew Cagney This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -729,7 +729,8 @@ psim_stack(psim *system, "/openprom/init/stack"); if (stack_device != (device*)0) { unsigned_word stack_pointer; - psim_read_register(system, 0, &stack_pointer, "sp", cooked_transfer); + ASSERT (psim_read_register(system, 0, &stack_pointer, "sp", + cooked_transfer) > 0); device_ioctl(stack_device, NULL, /*cpu*/ 0, /*cia*/ @@ -766,7 +767,7 @@ psim_run(psim *system) /* storage manipulation functions */ INLINE_PSIM\ -(void) +(int) psim_read_register(psim *system, int which_cpu, void *buf, @@ -774,7 +775,7 @@ psim_read_register(psim *system, transfer_mode mode) { register_descriptions description; - char cooked_buf[sizeof(unsigned_8)]; + char *cooked_buf; cpu *processor; /* find our processor */ @@ -792,7 +793,8 @@ psim_read_register(psim *system, /* find the register description */ description = register_description(reg); if (description.type == reg_invalid) - error("psim_read_register() invalid register name `%s'\n", reg); + return 0; + cooked_buf = alloca (description.size); /* get the cooked value */ switch (description.type) { @@ -846,6 +848,30 @@ psim_read_register(psim *system, *(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, @@ -871,18 +897,34 @@ psim_read_register(psim *system, 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 } } else { memcpy(buf/*dest*/, cooked_buf/*src*/, description.size); } + return description.size; } INLINE_PSIM\ -(void) +(int) psim_write_register(psim *system, int which_cpu, const void *buf, @@ -891,7 +933,7 @@ psim_write_register(psim *system, { cpu *processor; register_descriptions description; - char cooked_buf[sizeof(unsigned_8)]; + char *cooked_buf; /* find our processor */ if (which_cpu == MAX_NR_PROCESSORS) { @@ -901,21 +943,23 @@ psim_write_register(psim *system, else which_cpu = system->last_cpu; } + + /* find the description of the register */ + description = register_description(reg); + if (description.type == reg_invalid) + return 0; + cooked_buf = alloca (description.size); + if (which_cpu == -1) { int i; for (i = 0; i < system->nr_cpus; i++) psim_write_register(system, i, buf, reg, mode); - return; + return description.size; } ASSERT(which_cpu >= 0 && which_cpu < system->nr_cpus); processor = system->processors[which_cpu]; - /* find the description of the register */ - description = register_description(reg); - if (description.type == reg_invalid) - error("psim_write_register() invalid register name %s\n", reg); - /* If the data is comming in raw (target order), need to cook it into host order before putting it into PSIM's internal structures */ if (mode == raw_transfer) { @@ -932,6 +976,20 @@ psim_write_register(psim *system, case 8: *(unsigned_8*)cooked_buf = T2H_8(*(unsigned_8*)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(&t.v/*dest*/, buf/*src*/, description.size); + { _SWAP_8(h.d[0] =, t.d[1]); } + { _SWAP_8(h.d[1] =, t.d[0]); } + memcpy(cooked_buf/*dest*/, &h/*src*/, description.size); + break; + } + else + memcpy(cooked_buf/*dest*/, buf/*src*/, description.size); +#endif } } else { @@ -973,6 +1031,35 @@ psim_write_register(psim *system, cpu_registers(processor)->fpscr = *(fpscreg*)cooked_buf; break; +#ifdef WITH_E500 + case reg_gprh: + cpu_registers(processor)->e500.gprh[description.index] = *(gpreg*)cooked_buf; + break; + + case reg_evr: + { + unsigned64 v; + v = *(unsigned64*)cooked_buf; + cpu_registers(processor)->e500.gprh[description.index] = v >> 32; + cpu_registers(processor)->gpr[description.index] = v; + break; + } + + case reg_acc: + cpu_registers(processor)->e500.acc = *(accreg*)cooked_buf; + break; +#endif + +#ifdef WITH_ALTIVEC + case reg_vr: + cpu_registers(processor)->altivec.vr[description.index] = *(vreg*)cooked_buf; + break; + + case reg_vscr: + cpu_registers(processor)->altivec.vscr = *(vscreg*)cooked_buf; + break; +#endif + default: printf_filtered("psim_write_register(processor=0x%lx,cooked_buf=0x%lx,reg=%s) %s\n", (unsigned long)processor, (unsigned long)cooked_buf, reg, @@ -981,6 +1068,7 @@ psim_write_register(psim *system, } + return description.size; } |