X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Fmips%2Finterp.c;h=4e69b571bcf4d6c78a20309b1fcb2ca3e37291ce;hb=69d5a56645fdfd5d9cc9f57986224b0636010161;hp=8f2553e53add6cc974451d1f093ae541d82173c2;hpb=a48e8c8d21f3f0178c81d6b118d52991ba028d65;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/mips/interp.c b/sim/mips/interp.c index 8f2553e53a..4e69b571bc 100644 --- a/sim/mips/interp.c +++ b/sim/mips/interp.c @@ -14,8 +14,7 @@ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. $Revision$ - $Author$ - $Date$ + $Date$ NOTEs: @@ -39,6 +38,14 @@ code on the hardware. #include "sim-options.h" #include "sim-assert.h" +/* start-sanitize-sky */ +#ifdef TARGET_SKY +#include "sky-vu.h" +#include "sky-vpe.h" +#include "sky-libvpe.h" +#endif +/* end-sanitize-sky */ + #include "config.h" #include @@ -75,9 +82,7 @@ char* pr_uword64 PARAMS ((uword64 addr)); /* Get the simulator engine description, without including the code: */ -#if (WITH_IGEN) -#define LOADDRMASK (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3) -#else +#if !(WITH_IGEN) #define SIM_MANIFESTS #include "oengine.c" #undef SIM_MANIFESTS @@ -149,20 +154,36 @@ static void ColdReset PARAMS((SIM_DESC sd)); #define MONITOR_SIZE (1 << 11) #define MEM_SIZE (2 << 20) +/* start-sanitize-sky */ +#ifdef TARGET_SKY +#undef MEM_SIZE +#define MEM_SIZE (16 << 20) /* 16 MB */ +#endif +/* end-sanitize-sky */ + #if defined(TRACE) static char *tracefile = "trace.din"; /* default filename for trace log */ FILE *tracefh = NULL; static void open_trace PARAMS((SIM_DESC sd)); #endif /* TRACE */ -#define OPTION_DINERO_TRACE 200 -#define OPTION_DINERO_FILE 201 +static DECLARE_OPTION_HANDLER (mips_option_handler); + +enum { + OPTION_DINERO_TRACE = OPTION_START, + OPTION_DINERO_FILE +/* start-sanitize-sky */ + ,OPTION_FLOAT_TYPE +/* end-sanitize-sky */ +}; static SIM_RC -mips_option_handler (sd, opt, arg) +mips_option_handler (sd, cpu, opt, arg, is_command) SIM_DESC sd; + sim_cpu *cpu; int opt; char *arg; + int is_command; { int cpu_nr; switch (opt) @@ -173,7 +194,7 @@ mips_option_handler (sd, opt, arg) allow external control of the program points being traced (i.e. only from main onwards, excluding the run-time setup, etc.). */ - for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++) + for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++) { sim_cpu *cpu = STATE_CPU (sd, cpu_nr); if (arg == NULL) @@ -188,7 +209,7 @@ mips_option_handler (sd, opt, arg) STATE &= ~simTRACE; else { - fprintf (stderr, "Unreconized dinero-trace option `%s'\n", arg); + fprintf (stderr, "Unrecognized dinero-trace option `%s'\n", arg); return SIM_RC_FAIL; } } @@ -219,6 +240,20 @@ Re-compile simulator with \"-DTRACE\" to enable this option.\n"); #endif /* TRACE */ return SIM_RC_OK; +/* start-sanitize-sky */ + case OPTION_FLOAT_TYPE: + /* Use host (fast) or target (accurate) floating point implementation. */ + if (arg && strcmp (arg, "host") == 0) + STATE_FP_TYPE_OPT (sd) &= ~STATE_FP_TYPE_OPT_TARGET; + else if (arg && strcmp (arg, "target") == 0) + STATE_FP_TYPE_OPT (sd) |= STATE_FP_TYPE_OPT_TARGET; + else + { + fprintf (stderr, "Unrecognized float-type option `%s'\n", arg); + return SIM_RC_FAIL; + } + return SIM_RC_OK; +/* end-sanitize-sky */ } return SIM_RC_OK; @@ -232,6 +267,11 @@ static const OPTION mips_options[] = { {"dinero-file", required_argument, NULL, OPTION_DINERO_FILE}, '\0', "FILE", "Write dinero trace to FILE", mips_option_handler }, +/* start-sanitize-sky */ + { {"float-type", required_argument, NULL, OPTION_FLOAT_TYPE}, + '\0', "host|target", "Use host (fast) or target (accurate) floating point", + mips_option_handler }, +/* end-sanitize-sky */ { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL } }; @@ -262,15 +302,6 @@ static void device_init(SIM_DESC sd) { #endif } -/* start-sanitize-sky */ -#ifdef TARGET_SKY -static struct { - short i[16]; - int f[NUM_VU_REGS - 16]; -} vu_regs[2]; -#endif -/* end-sanitize-sky */ - /*---------------------------------------------------------------------------*/ /*-- GDB simulator interface ------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -296,7 +327,7 @@ sim_open (kind, cb, abfd, argv) if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) return 0; - sim_add_option_table (sd, mips_options); + sim_add_option_table (sd, NULL, mips_options); /* Allocate core managed memory */ @@ -306,10 +337,22 @@ sim_open (kind, cb, abfd, argv) are the kernel spaces K0 & K1. Both of these map to a single smaller sub region */ sim_do_command(sd," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */ +/* start-sanitize-sky */ +#ifndef TARGET_SKY +/* end-sanitize-sky */ sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x", K1BASE, K0SIZE, MEM_SIZE, /* actual size */ K0BASE); +/* start-sanitize-sky */ +#else + sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x,0x%0x", + K1BASE, K0SIZE, + MEM_SIZE, /* actual size */ + K0BASE, + 0); /* add alias at 0x0000 */ +#endif +/* end-sanitize-sky */ device_init(sd); @@ -386,34 +429,14 @@ sim_open (kind, cb, abfd, argv) /* start-sanitize-sky */ #ifdef TARGET_SKY /* Now the VU registers */ - for( rn = 0; rn < 16; rn++ ) { /* first the integer registers */ + for( rn = 0; rn < NUM_VU_INTEGER_REGS; rn++ ) { cpu->register_widths[rn + NUM_R5900_REGS] = 16; cpu->register_widths[rn + NUM_R5900_REGS + NUM_VU_REGS] = 16; - - /* Hack for now - to test gdb interface */ - vu_regs[0].i[rn] = rn + 0x100; - vu_regs[1].i[rn] = rn + 0x200; } - for( rn = 16; rn < NUM_VU_REGS; rn++ ) { /* then the FP registers */ - float f; - + for( rn = NUM_VU_INTEGER_REGS; rn < NUM_VU_REGS; rn++ ) { cpu->register_widths[rn + NUM_R5900_REGS] = 32; cpu->register_widths[rn + NUM_R5900_REGS + NUM_VU_REGS] = 32; - - /* Hack for now - to test gdb interface */ - if( rn < 24 ) { - f = rn - 16 + 100.0; - vu_regs[0].f[rn-16] = *((unsigned *) &f); - f = rn - 16 + 200.0; - vu_regs[1].f[rn-16] = *((unsigned *) &f); - } - else { - f = (rn - 24)/4 + (rn - 24)%4 + 1000.0; - vu_regs[0].f[rn-16] = *((unsigned *) &f); - f = (rn - 24)/4 + (rn - 24)%4 + 2000.0; - vu_regs[1].f[rn-16] = *((unsigned *) &f); - } } #endif /* end-sanitize-sky */ @@ -554,7 +577,7 @@ sim_write (sd,addr,buffer,size) int cca; if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isSTORE, &paddr, &cca, isRAW)) break; - if (sim_core_write_buffer (SD, CPU, sim_core_read_map, buffer + index, paddr, 1) != 1) + if (sim_core_write_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1) break; } @@ -583,7 +606,7 @@ sim_read (sd,addr,buffer,size) int cca; if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isLOAD, &paddr, &cca, isRAW)) break; - if (sim_core_read_buffer (SD, CPU, sim_core_read_map, buffer + index, paddr, 1) != 1) + if (sim_core_read_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1) break; } @@ -632,28 +655,101 @@ sim_store_register (sd,rn,memory,length) HI1 = T2H_8(*(unsigned64*)memory); return 8; } - /* end-sanitize-r5900 */ + /* start-sanitize-sky */ #ifdef TARGET_SKY - else if( rn > NUM_R5900_REGS ) { - rn = rn - NUM_R5900_REGS; - - if( rn < 16 ) - vu_regs[0].i[rn] = T2H_2( *(unsigned short *) memory ); - else if( rn < NUM_VU_REGS ) - vu_regs[0].f[rn - 16] = T2H_4( *(unsigned int *) memory ); - else { - rn = rn - NUM_VU_REGS; - - if( rn < 16 ) - vu_regs[1].i[rn] = T2H_2( *(unsigned short *) memory ); + if (rn >= NUM_R5900_REGS) + { + int size = 4; /* Default register size */ + + rn = rn - NUM_R5900_REGS; + + if (rn < NUM_VU_INTEGER_REGS) + size = write_vu_int_reg (&(vu0_device.state->regs), rn, memory); else if( rn < NUM_VU_REGS ) - vu_regs[1].f[rn - 16] = T2H_4( *(unsigned int *) memory ); - else - sim_io_eprintf( sd, "Invalid VU register (register store ignored)\n" ); + { + if (rn >= FIRST_VEC_REG) + { + rn -= FIRST_VEC_REG; + size = write_vu_vec_reg (&(vu0_device.state->regs), rn>>2, rn&3, + memory); + } + else switch (rn - NUM_VU_INTEGER_REGS) + { + case 0: + size = write_vu_special_reg (vu0_device.state, VU_REG_CIA, + memory); + break; + case 1: + size = write_vu_misc_reg (&(vu0_device.state->regs), VU_REG_MR, + memory); + break; + case 2: /* VU0 has no P register */ + break; + case 3: + size = write_vu_misc_reg (&(vu0_device.state->regs), VU_REG_MI, + memory); + break; + case 4: + size = write_vu_misc_reg (&(vu0_device.state->regs), VU_REG_MQ, + memory); + break; + default: + size = write_vu_acc_reg (&(vu0_device.state->regs), + rn - (NUM_VU_INTEGER_REGS + 5), + memory); + break; + } + } + else { + rn = rn - NUM_VU_REGS; + + if( rn < NUM_VU_INTEGER_REGS ) + size = write_vu_int_reg (&(vu1_device.state->regs), rn, memory); + else if( rn < NUM_VU_REGS ) + { + if (rn >= FIRST_VEC_REG) + { + rn -= FIRST_VEC_REG; + size = write_vu_vec_reg (&(vu1_device.state->regs), + rn >> 2, rn & 3, memory); + } + else switch (rn - NUM_VU_INTEGER_REGS) + { + case 0: + size = write_vu_special_reg (vu1_device.state, VU_REG_CIA, + memory); + break; + case 1: + size = write_vu_misc_reg (&(vu1_device.state->regs), + VU_REG_MR, memory); + break; + case 2: + size = write_vu_misc_reg (&(vu1_device.state->regs), + VU_REG_MP, memory); + break; + case 3: + size = write_vu_misc_reg (&(vu1_device.state->regs), + VU_REG_MI, memory); + break; + case 4: + size = write_vu_misc_reg (&(vu1_device.state->regs), + VU_REG_MQ, memory); + break; + default: + size = write_vu_acc_reg (&(vu1_device.state->regs), + rn - (NUM_VU_INTEGER_REGS + 5), + memory); + break; + } + } + else + sim_io_eprintf( sd, "Invalid VU register (register store ignored)\n" ); + } + + return size; } - } #endif /* end-sanitize-sky */ @@ -721,31 +817,104 @@ sim_fetch_register (sd,rn,memory,length) *((unsigned64*)memory) = H2T_8(HI1); return 8; } - /* end-sanitize-r5900 */ + /* start-sanitize-sky */ #ifdef TARGET_SKY - if( rn > NUM_R5900_REGS ) { - rn = rn - NUM_R5900_REGS; - - if( rn < 16 ) - *((unsigned short *) memory) = H2T_2( vu_regs[0].i[rn] ); - else if( rn < NUM_VU_REGS ) - *((unsigned int *) memory) = H2T_4( vu_regs[0].f[rn - 16] ); - else { - rn = rn - NUM_VU_REGS; - - if( rn < 16 ) - (*(unsigned short *) memory) = H2T_2( vu_regs[1].i[rn] ); - else if( rn < NUM_VU_REGS ) - (*(unsigned int *) memory) = H2T_4( vu_regs[1].f[rn - 16] ); + if (rn >= NUM_R5900_REGS) + { + int size = 4; /* default register width */ + + rn = rn - NUM_R5900_REGS; + + if (rn < NUM_VU_INTEGER_REGS) + size = read_vu_int_reg (&(vu0_device.state->regs), rn, memory); + else if (rn < NUM_VU_REGS) + { + if (rn >= FIRST_VEC_REG) + { + rn -= FIRST_VEC_REG; + size = read_vu_vec_reg (&(vu0_device.state->regs), rn>>2, rn & 3, + memory); + } + else switch (rn - NUM_VU_INTEGER_REGS) + { + case 0: + size = read_vu_special_reg (vu0_device.state, VU_REG_CIA, + memory); + + break; + case 1: + size = read_vu_misc_reg (&(vu0_device.state->regs), VU_REG_MR, + memory); + break; + case 2: /* VU0 has no P register */ + break; + case 3: + size = read_vu_misc_reg (&(vu0_device.state->regs), VU_REG_MI, + memory); + break; + case 4: + size = read_vu_misc_reg (&(vu0_device.state->regs), VU_REG_MQ, + memory); + break; + default: + size = read_vu_acc_reg (&(vu0_device.state->regs), + rn - (NUM_VU_INTEGER_REGS + 5), + memory); + break; + } + } else - sim_io_eprintf( sd, "Invalid VU register (register fetch ignored)\n" ); + { + rn = rn - NUM_VU_REGS; + + if (rn < NUM_VU_INTEGER_REGS) + size = read_vu_int_reg (&(vu1_device.state->regs), rn, memory); + else if (rn < NUM_VU_REGS) + { + if (rn >= FIRST_VEC_REG) + { + rn -= FIRST_VEC_REG; + size = read_vu_vec_reg (&(vu1_device.state->regs), + rn >> 2, rn & 3, memory); + } + else switch (rn - NUM_VU_INTEGER_REGS) + { + case 0: + size = read_vu_special_reg (vu1_device.state, VU_REG_CIA, + memory); + break; + case 1: + size = read_vu_misc_reg (&(vu1_device.state->regs), + VU_REG_MR, memory); + break; + case 2: + size = read_vu_misc_reg (&(vu1_device.state->regs), + VU_REG_MP, memory); + break; + case 3: + size = read_vu_misc_reg (&(vu1_device.state->regs), + VU_REG_MI, memory); + break; + case 4: + size = read_vu_misc_reg (&(vu1_device.state->regs), + VU_REG_MQ, memory); + break; + default: + size = read_vu_acc_reg (&(vu1_device.state->regs), + rn - (NUM_VU_INTEGER_REGS + 5), + memory); + break; + } + } + else + sim_io_eprintf( sd, "Invalid VU register (register fetch ignored)\n" ); + } + + return size; } - return -1; - } #endif - /* end-sanitize-sky */ /* Any floating point register */ @@ -776,43 +945,6 @@ sim_fetch_register (sd,rn,memory,length) } -void -sim_info (sd,verbose) - SIM_DESC sd; - int verbose; -{ - /* Accessed from the GDB "info files" command: */ - if (STATE_VERBOSE_P (sd) || verbose) - { - - sim_io_printf (sd, "MIPS %d-bit %s endian simulator\n", - WITH_TARGET_WORD_BITSIZE, - (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN ? "Big" : "Little")); - -#if !defined(FASTSIM) - /* It would be a useful feature, if when performing multi-cycle - simulations (rather than single-stepping) we keep the start and - end times of the execution, so that we can give a performance - figure for the simulator. */ -#endif /* !FASTSIM */ - sim_io_printf (sd, "Number of execution cycles = %ld\n", - (long) sim_events_time (sd)); - - /* print information pertaining to MIPS ISA and architecture being simulated */ - /* things that may be interesting */ - /* instructions executed - if available */ - /* cycles executed - if available */ - /* pipeline stalls - if available */ - /* virtual time taken */ - /* profiling size */ - /* profiling frequency */ - /* profile minpc */ - /* profile maxpc */ - } - profile_print (sd, STATE_VERBOSE_P (sd), NULL, NULL); -} - - SIM_RC sim_create_inferior (sd, abfd, argv,env) SIM_DESC sd; @@ -989,9 +1121,12 @@ sim_monitor (SIM_DESC sd, /* [A0 + 4] = instruction cache size */ /* [A0 + 8] = data cache size */ { - address_word value = MEM_SIZE /* FIXME STATE_MEM_SIZE (sd) */; + unsigned_4 value = MEM_SIZE /* FIXME STATE_MEM_SIZE (sd) */; + unsigned_4 zero = 0; H2T (value); - sim_write (sd, A0, (char *)&value, sizeof (value)); + sim_write (sd, A0 + 0, (char *)&value, 4); + sim_write (sd, A0 + 4, (char *)&zero, 4); + sim_write (sd, A0 + 8, (char *)&zero, 4); /* sim_io_eprintf (sd, "sim: get_mem_info() depreciated\n"); */ break; } @@ -1489,7 +1624,7 @@ load_memory (SIM_DESC sd, uword64* memvalp, uword64* memval1p, int CCA, - int AccessLength, + unsigned int AccessLength, address_word pAddr, address_word vAddr, int IorD) @@ -1516,9 +1651,9 @@ load_memory (SIM_DESC sd, if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK) { /* In reality this should be a Bus Error */ - sim_io_error (sd, "AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n", + sim_io_error (sd, "LOAD AccessLength of %d would extend over %d bit aligned boundary for physical address 0x%s\n", AccessLength, - (LOADDRMASK + 1) << 2, + (LOADDRMASK + 1) << 3, pr_addr (pAddr)); } @@ -1534,43 +1669,42 @@ load_memory (SIM_DESC sd, { case AccessLength_QUADWORD : { - unsigned_16 val = sim_core_read_aligned_16 (cpu, NULL_CIA, - sim_core_read_map, pAddr); + unsigned_16 val = sim_core_read_aligned_16 (cpu, NULL_CIA, read_map, pAddr); value1 = VH8_16 (val); value = VL8_16 (val); break; } case AccessLength_DOUBLEWORD : value = sim_core_read_aligned_8 (cpu, NULL_CIA, - sim_core_read_map, pAddr); + read_map, pAddr); break; case AccessLength_SEPTIBYTE : value = sim_core_read_misaligned_7 (cpu, NULL_CIA, - sim_core_read_map, pAddr); + read_map, pAddr); break; case AccessLength_SEXTIBYTE : value = sim_core_read_misaligned_6 (cpu, NULL_CIA, - sim_core_read_map, pAddr); + read_map, pAddr); break; case AccessLength_QUINTIBYTE : value = sim_core_read_misaligned_5 (cpu, NULL_CIA, - sim_core_read_map, pAddr); + read_map, pAddr); break; case AccessLength_WORD : value = sim_core_read_aligned_4 (cpu, NULL_CIA, - sim_core_read_map, pAddr); + read_map, pAddr); break; case AccessLength_TRIPLEBYTE : value = sim_core_read_misaligned_3 (cpu, NULL_CIA, - sim_core_read_map, pAddr); + read_map, pAddr); break; case AccessLength_HALFWORD : value = sim_core_read_aligned_2 (cpu, NULL_CIA, - sim_core_read_map, pAddr); + read_map, pAddr); break; case AccessLength_BYTE : value = sim_core_read_aligned_1 (cpu, NULL_CIA, - sim_core_read_map, pAddr); + read_map, pAddr); break; default: abort (); @@ -1581,13 +1715,13 @@ load_memory (SIM_DESC sd, (int)(pAddr & LOADDRMASK),pr_uword64(value1),pr_uword64(value)); #endif /* DEBUG */ - /* See also store_memory. */ - if (AccessLength <= AccessLength_DOUBLEWORD) + /* See also store_memory. Position data in correct byte lanes. */ + if (AccessLength <= LOADDRMASK) { if (BigEndianMem) /* for big endian target, byte (pAddr&LOADDRMASK == 0) is shifted to the most significant byte position. */ - value <<= (((7 - (pAddr & LOADDRMASK)) - AccessLength) * 8); + value <<= (((LOADDRMASK - (pAddr & LOADDRMASK)) - AccessLength) * 8); else /* For little endian target, byte (pAddr&LOADDRMASK == 0) is already in the correct postition. */ @@ -1622,7 +1756,7 @@ store_memory (SIM_DESC sd, sim_cpu *cpu, address_word cia, int CCA, - int AccessLength, + unsigned int AccessLength, uword64 MemElem, uword64 MemElem1, /* High order 64 bits */ address_word pAddr, @@ -1638,7 +1772,10 @@ store_memory (SIM_DESC sd, #endif /* WARN_MEM */ if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK) - sim_io_error(sd,"AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n",AccessLength,(LOADDRMASK + 1)<<2,pr_addr(pAddr)); + sim_io_error (sd, "STORE AccessLength of %d would extend over %d bit aligned boundary for physical address 0x%s\n", + AccessLength, + (LOADDRMASK + 1) << 3, + pr_addr(pAddr)); #if defined(TRACE) dotrace (SD, CPU, tracefh,1,(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"store"); @@ -1648,13 +1785,13 @@ store_memory (SIM_DESC sd, printf("DBG: StoreMemory: offset = %d MemElem = 0x%s%s\n",(unsigned int)(pAddr & LOADDRMASK),pr_uword64(MemElem1),pr_uword64(MemElem)); #endif /* DEBUG */ - /* See also load_memory */ - if (AccessLength <= AccessLength_DOUBLEWORD) + /* See also load_memory. Position data in correct byte lanes. */ + if (AccessLength <= LOADDRMASK) { if (BigEndianMem) /* for big endian target, byte (pAddr&LOADDRMASK == 0) is shifted to the most significant byte position. */ - MemElem >>= (((7 - (pAddr & LOADDRMASK)) - AccessLength) * 8); + MemElem >>= (((LOADDRMASK - (pAddr & LOADDRMASK)) - AccessLength) * 8); else /* For little endian target, byte (pAddr&LOADDRMASK == 0) is already in the correct postition. */ @@ -1670,41 +1807,40 @@ store_memory (SIM_DESC sd, case AccessLength_QUADWORD : { unsigned_16 val = U16_8 (MemElem1, MemElem); - sim_core_write_aligned_16 (cpu, NULL_CIA, - sim_core_write_map, pAddr, val); + sim_core_write_aligned_16 (cpu, NULL_CIA, write_map, pAddr, val); break; } case AccessLength_DOUBLEWORD : sim_core_write_aligned_8 (cpu, NULL_CIA, - sim_core_write_map, pAddr, MemElem); + write_map, pAddr, MemElem); break; case AccessLength_SEPTIBYTE : sim_core_write_misaligned_7 (cpu, NULL_CIA, - sim_core_write_map, pAddr, MemElem); + write_map, pAddr, MemElem); break; case AccessLength_SEXTIBYTE : sim_core_write_misaligned_6 (cpu, NULL_CIA, - sim_core_write_map, pAddr, MemElem); + write_map, pAddr, MemElem); break; case AccessLength_QUINTIBYTE : sim_core_write_misaligned_5 (cpu, NULL_CIA, - sim_core_write_map, pAddr, MemElem); + write_map, pAddr, MemElem); break; case AccessLength_WORD : sim_core_write_aligned_4 (cpu, NULL_CIA, - sim_core_write_map, pAddr, MemElem); + write_map, pAddr, MemElem); break; case AccessLength_TRIPLEBYTE : sim_core_write_misaligned_3 (cpu, NULL_CIA, - sim_core_write_map, pAddr, MemElem); + write_map, pAddr, MemElem); break; case AccessLength_HALFWORD : sim_core_write_aligned_2 (cpu, NULL_CIA, - sim_core_write_map, pAddr, MemElem); + write_map, pAddr, MemElem); break; case AccessLength_BYTE : sim_core_write_aligned_1 (cpu, NULL_CIA, - sim_core_write_map, pAddr, MemElem); + write_map, pAddr, MemElem); break; default: abort (); @@ -1819,7 +1955,7 @@ signal_exception (SIM_DESC sd, code = (instruction >> 6) & 0xFFFFF; sim_io_eprintf(sd,"Ignoring instruction `syscall %d' (PC 0x%s)\n", - code, pr_addr(cia)); + code, pr_addr(cia)); } break; @@ -2923,6 +3059,7 @@ SquareRoot(op,fmt) return(result); } +#if 0 uword64 Max (uword64 op1, uword64 op2, @@ -2990,7 +3127,9 @@ Max (uword64 op1, return(result); } +#endif +#if 0 uword64 Min (uword64 op1, uword64 op2, @@ -3058,6 +3197,7 @@ Min (uword64 op1, return(result); } +#endif uword64 convert (SIM_DESC sd, @@ -3232,6 +3372,35 @@ cop_ld (SIM_DESC sd, return; } + +/* start-sanitize-sky */ +#ifdef TARGET_SKY +void +cop_lq (SIM_DESC sd, + sim_cpu *cpu, + address_word cia, + int coproc_num, + int coproc_reg, + unsigned128 memword) +{ + switch (coproc_num) + { + case 2: + /* XXX COP2 */ + break; + + default: + sim_io_printf(sd,"COP_LQ(%d,%d,??) at PC = 0x%s : TODO (architecture specific)\n", + coproc_num,coproc_reg,pr_addr(cia)); + break; + } + + return; +} +#endif /* TARGET_SKY */ +/* end-sanitize-sky */ + + unsigned int cop_sw (SIM_DESC sd, sim_cpu *cpu, @@ -3291,6 +3460,35 @@ cop_sd (SIM_DESC sd, return(value); } + +/* start-sanitize-sky */ +#ifdef TARGET_SKY +unsigned128 +cop_sq (SIM_DESC sd, + sim_cpu *cpu, + address_word cia, + int coproc_num, + int coproc_reg) +{ + unsigned128 value = U16_8(0, 0); + switch (coproc_num) + { + case 2: + /* XXX COP2 */ + break; + + default: + sim_io_printf(sd,"COP_SQ(%d,%d) at PC = 0x%s : TODO (architecture specific)\n", + coproc_num,coproc_reg,pr_addr(cia)); + break; + } + + return(value); +} +#endif /* TARGET_SKY */ +/* end-sanitize-sky */ + + void decode_coproc (SIM_DESC sd, sim_cpu *cpu, @@ -3432,9 +3630,179 @@ decode_coproc (SIM_DESC sd, break; case 2: /* undefined co-processor */ - sim_io_eprintf(sd,"COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction,pr_addr(cia)); - break; - + { + int handle = 0; + + /* start-sanitize-sky */ +#ifdef TARGET_SKY + /* On the R5900, this refers to a "VU" vector co-processor. */ + + int i_25_21 = (instruction >> 21) & 0x1f; + int i_20_16 = (instruction >> 16) & 0x1f; + int i_15_11 = (instruction >> 11) & 0x1f; + int i_15_0 = instruction & 0xffff; + int i_10_1 = (instruction >> 1) & 0x3ff; + int i_5_0 = instruction & 0x03f; + int interlock = instruction & 0x01; + int co = (instruction >> 25) & 0x01; + /* setup for semantic.c-like actions below */ + typedef unsigned_4 instruction_word; + int CIA = cia; + int NIA = cia + 4; + sim_cpu* CPU_ = cpu; + + handle = 1; + + /* test COP2 usability */ + if(! (SR & status_CU2)) + { + SignalException(CoProcessorUnusable,instruction); + /* NOTREACHED */ + } + + /* classify & execute basic COP2 instructions */ + if(i_25_21 == 0x08 && i_20_16 == 0x00) /* BC2F */ + { + address_word offset = EXTEND16(i_15_0) << 2; + if(! vu0_busy()) DELAY_SLOT(cia + 4 + offset); + } + else if(i_25_21 == 0x08 && i_20_16==0x02) /* BC2FL */ + { + address_word offset = EXTEND16(i_15_0) << 2; + if(! vu0_busy()) DELAY_SLOT(cia + 4 + offset); + else NULLIFY_NEXT_INSTRUCTION(); + } + else if(i_25_21 == 0x08 && i_20_16 == 0x01) /* BC2T */ + { + address_word offset = EXTEND16(i_15_0) << 2; + if(vu0_busy()) DELAY_SLOT(cia + 4 + offset); + } + else if(i_25_21 == 0x08 && i_20_16 == 0x03) /* BC2TL */ + { + address_word offset = EXTEND16(i_15_0) << 2; + if(vu0_busy()) DELAY_SLOT(cia + 4 + offset); + else NULLIFY_NEXT_INSTRUCTION(); + } + else if((i_25_21 == 0x02 && i_10_1 == 0x000) || /* CFC2 */ + (i_25_21 == 0x01)) /* QMFC2 */ + { + int rt = i_20_16; + int id = i_15_11; + address_word vu_cr_addr; /* VU control register address */ + unsigned_4 data; + + /* interlock checking */ + if(vu0_busy_in_macro_mode()) /* busy in macro mode */ + { + /* interlock bit invalid here */ + if(interlock) + ; /* XXX: warning */ + + /* always check data hazard */ + while(vu0_macro_hazard_check(id)) + vu0_issue(sd); + } + else if(vu0_busy_in_micro_mode() && interlock) + { + while(vu0_busy_in_micro_mode()) + vu0_issue(sd); + } + + /* compute VU register address */ + if(i_25_21 == 0x01) /* QMFC2 */ + vu_cr_addr = VU0_REGISTER_WINDOW_START + (id * 16); + else /* CFC2 */ + vu_cr_addr = VU0_MST + (id * 16); + + /* read or write word */ + data = sim_core_read_aligned_4(cpu, cia, read_map, vu_cr_addr); + GPR[rt] = EXTEND64(data); + } + else if((i_25_21 == 0x06 && i_10_1 == 0x000) || /* CTC2 */ + (i_25_21 == 0x05)) /* QMTC2 */ + { + int rt = i_20_16; + int id = i_15_11; + address_word vu_cr_addr; /* VU control register address */ + unsigned_4 data; + + /* interlock checking */ + if(vu0_busy_in_macro_mode()) /* busy in macro mode */ + { + /* interlock bit invalid here */ + if(interlock) + ; /* XXX: warning */ + + /* always check data hazard */ + while(vu0_macro_hazard_check(id)) + vu0_issue(sd); + } + else if(vu0_busy_in_micro_mode()) + { + if(interlock) + { + while(! vu0_micro_interlock_released()) + vu0_issue(sd); + } + } + + /* compute VU register address */ + if(i_25_21 == 0x05) /* QMTC2 */ + vu_cr_addr = VU0_REGISTER_WINDOW_START + (id * 16); + else /* CTC2 */ + vu_cr_addr = VU0_MST + (id * 16); + + data = GPR[rt]; + sim_core_write_aligned_4(cpu, cia, write_map, vu_cr_addr, data); + } + else if( 0 /* XXX: ... upper ... */) + { + unsigned_4 vu_upper, vu_lower; + vu_upper = + 0x00000000 | /* bits 31 .. 25 */ + instruction & 0x01ffffff; /* bits 24 .. 0 */ + vu_lower = 0x8000033c; /* NOP */ + + while(vu0_busy_in_micro_mode()) + vu0_issue(sd); + + vu0_macro_issue(vu_upper, vu_lower); + } + else if( 0 /* XXX: ... lower ... */) + { + unsigned_4 vu_upper, vu_lower; + vu_upper = 0x000002ff; /* NOP */ + vu_lower = + 0x10000000 | /* bits 31 .. 25 */ + instruction & 0x01ffffff; /* bits 24 .. 0 */ + + while(vu0_busy_in_micro_mode()) + vu0_issue(sd); + + vu0_macro_issue(vu_upper, vu_lower); + } + /* XXX */ + /* ... other COP2 instructions ... */ + else + { + SignalException(ReservedInstruction, instruction); + /* NOTREACHED */ + } + + /* cleanup for semantic.c-like actions above */ + PC = NIA; + +#endif /* TARGET_SKY */ + /* end-sanitize-sky */ + + if(! handle) + { + sim_io_eprintf(sd,"COP2 instruction 0x%08X at PC = 0x%s : No handler present\n", + instruction,pr_addr(cia)); + } + } + break; + case 1: /* should not occur (FPU co-processor) */ case 3: /* should not occur (FPU co-processor) */ SignalException(ReservedInstruction,instruction); @@ -3444,6 +3812,7 @@ decode_coproc (SIM_DESC sd, return; } + /*-- instruction simulation -------------------------------------------------*/ /* When the IGEN simulator is being built, the function below is be