/* 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
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "bfd.h"
-
+#include "libiberty.h"
+#include "gdb/signals.h"
/* system structure, actual size of processor array determined at
runtime */
INLINE_PSIM\
(void)
-psim_usage(int verbose)
+psim_usage (int verbose, int help, SIM_OPEN_KIND kind)
{
printf_filtered("Usage:\n");
printf_filtered("\n");
printf_filtered("\n");
print_options();
}
- error("");
+
+ if (kind == SIM_OPEN_STANDALONE)
+ {
+ if (REPORT_BUGS_TO[0])
+ printf ("Report bugs to %s\n", REPORT_BUGS_TO);
+ exit (help ? 0 : 1);
+ }
}
/* Test "string" for containing a string of digits that form a number
INLINE_PSIM\
(char **)
psim_options(device *root,
- char **argv)
+ char **argv,
+ SIM_OPEN_KIND kind)
{
device *current = root;
int argp;
while (*p != '\0') {
switch (*p) {
default:
- psim_usage(0);
- error ("");
- break;
+ printf_filtered ("Invalid Option: %s\n", argv[argp]);
+ psim_usage (0, 0, kind);
+ return NULL;
case 'c':
param = find_arg("Missing <count> option for -c (max-iterations)\n", &argp, argv);
tree_parse(root, "/openprom/options/max-iterations %s", param);
else
{
printf_filtered ("Invalid <endian> option for -E (target-endian)\n");
- psim_usage (0);
+ psim_usage (0, 0, kind);
+ return NULL;
}
break;
case 'f':
break;
case 'h':
case '?':
- psim_usage(1);
- break;
+ psim_usage (1, 1, kind);
+ return NULL;
case 'H':
- psim_usage(2);
- break;
+ psim_usage (2, 1, kind);
+ return NULL;
case 'i':
if (isdigit(p[1])) {
tree_parse(root, "/openprom/trace/print-info %c", p[1]);
else
tree_parse(root, "/openprom/trace/%s 1", param);
break;
+ case '-':
+ /* it's a long option of the form --optionname=optionvalue.
+ Such options can be passed through if we are invoked by
+ gdb. */
+ if (strstr(argv[argp], "architecture") != NULL) {
+ /* we must consume the argument here, so that we get out
+ of the loop. */
+ p = argv[argp] + strlen(argv[argp]) - 1;
+ printf_filtered("Warning - architecture parameter ignored\n");
+ }
+ else if (strcmp (argv[argp], "--help") == 0)
+ {
+ psim_usage (0, 1, kind);
+ return NULL;
+ }
+ else if (strncmp (argv[argp], "--sysroot=",
+ sizeof ("--sysroot=") - 1) == 0)
+ /* Ignore this option. */
+ p = argv[argp] + strlen(argv[argp]) - 1;
+ else if (strcmp (argv[argp], "--version") == 0)
+ {
+ extern const char version[];
+ printf ("GNU simulator %s%s\n", PKGVERSION, version);
+ if (kind == SIM_OPEN_STANDALONE)
+ exit (0);
+ else
+ return NULL;
+ }
+ else
+ {
+ printf_filtered ("Invalid option: %s\n", argv[argp]);
+ psim_usage (0, 0, kind);
+ return NULL;
+ }
+ break;
}
p += 1;
}
psim_halt(system,
psim_nr_cpus(system),
was_continuing,
- SIGINT);
+ GDB_SIGNAL_INT);
}
INLINE_PSIM\
"/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*/
/* storage manipulation functions */
INLINE_PSIM\
-(void)
+(int)
psim_read_register(psim *system,
int which_cpu,
void *buf,
transfer_mode mode)
{
register_descriptions description;
- char cooked_buf[sizeof(unsigned_8)];
+ char *cooked_buf;
cpu *processor;
/* find our processor */
/* 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) {
*(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,
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,
{
cpu *processor;
register_descriptions description;
- char cooked_buf[sizeof(unsigned_8)];
+ char *cooked_buf;
/* find our processor */
if (which_cpu == MAX_NR_PROCESSORS) {
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) {
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 {
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,
}
+ return description.size;
}