aboutsummaryrefslogtreecommitdiff
path: root/sim/frv/traps.c
diff options
context:
space:
mode:
authorDave Brolley <brolley@redhat.com>2003-10-08 18:19:33 +0000
committerDave Brolley <brolley@redhat.com>2003-10-08 18:19:33 +0000
commite930b1f54ff2768c5818eb0a450b1d98d46d273d (patch)
treebeff79b0fd16e78faffe78489d34d064d5618b43 /sim/frv/traps.c
parent7c3f9ad027b9ec2906f3367ca7be18e5fb8f6893 (diff)
downloadgdb-e930b1f54ff2768c5818eb0a450b1d98d46d273d.zip
gdb-e930b1f54ff2768c5818eb0a450b1d98d46d273d.tar.gz
gdb-e930b1f54ff2768c5818eb0a450b1d98d46d273d.tar.bz2
2003-10-06 Dave Brolley <brolley@redhat.com>
* profile-fr550.[ch]: New files. * configure.in: Move frv handling to alphabetically correct placement. * Makefile.in: Add fr550 support. * frv-sim.h,frv.c,interrups.c,memory.c,mloop.in,pipeline.c, profile.[ch],registers.c,traps.c: Add fr550 support. * arch.c,arch.h,cpu.c,cpu.h,cpuall.h,model.h,decode.c,decode.h,sem.c: Regenerate.
Diffstat (limited to 'sim/frv/traps.c')
-rw-r--r--sim/frv/traps.c100
1 files changed, 83 insertions, 17 deletions
diff --git a/sim/frv/traps.c b/sim/frv/traps.c
index 6ab8a2c..603dc21 100644
--- a/sim/frv/traps.c
+++ b/sim/frv/traps.c
@@ -1,5 +1,5 @@
/* frv trap support
- Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of the GNU simulators.
@@ -30,6 +30,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "bfd.h"
#include "libiberty.h"
+CGEN_ATTR_VALUE_TYPE frv_current_fm_slot;
+
/* The semantic code invokes this for invalid (unrecognized) instructions. */
SEM_PC
@@ -276,9 +278,11 @@ frv_itrap (SIM_CPU *current_cpu, PCADDR pc, USI base, SI offset)
void
frv_mtrap (SIM_CPU *current_cpu)
{
+ SIM_DESC sd = CPU_STATE (current_cpu);
+
/* Check the status of media exceptions in MSR0. */
SI msr = GET_MSR (0);
- if (GET_MSR_AOVF (msr) || GET_MSR_MTT (msr))
+ if (GET_MSR_AOVF (msr) || GET_MSR_MTT (msr) && STATE_ARCHITECTURE (sd)->mach != bfd_mach_fr550)
frv_queue_program_interrupt (current_cpu, FRV_MP_EXCEPTION);
}
@@ -584,11 +588,17 @@ frvbf_media_cr_not_aligned (SIM_CPU *current_cpu)
{
SIM_DESC sd = CPU_STATE (current_cpu);
- /* On the fr400 this generates an illegal_instruction interrupt. */
- if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400)
- frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
- else
- frv_set_mp_exception_registers (current_cpu, MTT_CR_NOT_ALIGNED, 0);
+ /* On some machines this generates an illegal_instruction interrupt. */
+ switch (STATE_ARCHITECTURE (sd)->mach)
+ {
+ case bfd_mach_fr400:
+ case bfd_mach_fr550:
+ frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
+ break;
+ default:
+ frv_set_mp_exception_registers (current_cpu, MTT_CR_NOT_ALIGNED, 0);
+ break;
+ }
}
/* Record state for media exception: media_acc_not_aligned. */
@@ -597,11 +607,17 @@ frvbf_media_acc_not_aligned (SIM_CPU *current_cpu)
{
SIM_DESC sd = CPU_STATE (current_cpu);
- /* On the fr400 this generates an illegal_instruction interrupt. */
- if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400)
- frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
- else
- frv_set_mp_exception_registers (current_cpu, MTT_ACC_NOT_ALIGNED, 0);
+ /* On some machines this generates an illegal_instruction interrupt. */
+ switch (STATE_ARCHITECTURE (sd)->mach)
+ {
+ case bfd_mach_fr400:
+ case bfd_mach_fr550:
+ frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
+ break;
+ default:
+ frv_set_mp_exception_registers (current_cpu, MTT_ACC_NOT_ALIGNED, 0);
+ break;
+ }
}
/* Record state for media exception: media_register_not_aligned. */
@@ -610,11 +626,17 @@ frvbf_media_register_not_aligned (SIM_CPU *current_cpu)
{
SIM_DESC sd = CPU_STATE (current_cpu);
- /* On the fr400 this generates an illegal_instruction interrupt. */
- if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400)
- frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
- else
- frv_set_mp_exception_registers (current_cpu, MTT_INVALID_FR, 0);
+ /* On some machines this generates an illegal_instruction interrupt. */
+ switch (STATE_ARCHITECTURE (sd)->mach)
+ {
+ case bfd_mach_fr400:
+ case bfd_mach_fr550:
+ frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
+ break;
+ default:
+ frv_set_mp_exception_registers (current_cpu, MTT_INVALID_FR, 0);
+ break;
+ }
}
/* Record state for media exception: media_overflow. */
@@ -725,6 +747,50 @@ frvbf_check_recovering_store (
} /* loop over active neear registers. */
}
+SI
+frvbf_check_acc_range (SIM_CPU *current_cpu, SI regno)
+{
+ /* Only applicable to fr550 */
+ SIM_DESC sd = CPU_STATE (current_cpu);
+ if (STATE_ARCHITECTURE (sd)->mach != bfd_mach_fr550)
+ return;
+
+ /* On the fr550, media insns in slots 0 and 2 can only access
+ accumulators acc0-acc3. Insns in slots 1 and 3 can only access
+ accumulators acc4-acc7 */
+ switch (frv_current_fm_slot)
+ {
+ case UNIT_FM0:
+ case UNIT_FM2:
+ if (regno <= 3)
+ return 1; /* all is ok */
+ break;
+ case UNIT_FM1:
+ case UNIT_FM3:
+ if (regno >= 4)
+ return 1; /* all is ok */
+ break;
+ }
+
+ /* The specified accumulator is out of range. Queue an illegal_instruction
+ interrupt. */
+ frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
+ return 0;
+}
+
+void
+frvbf_check_swap_address (SIM_CPU *current_cpu, SI address)
+{
+ /* Only applicable to fr550 */
+ SIM_DESC sd = CPU_STATE (current_cpu);
+ if (STATE_ARCHITECTURE (sd)->mach != bfd_mach_fr550)
+ return;
+
+ /* Adress must be aligned on a word boundary. */
+ if (address & 0x3)
+ frv_queue_data_access_exception_interrupt (current_cpu);
+}
+
static void
clear_nesr_neear (SIM_CPU *current_cpu, SI target_index, BI is_float)
{