diff options
author | Dave Brolley <brolley@redhat.com> | 2003-10-08 18:19:33 +0000 |
---|---|---|
committer | Dave Brolley <brolley@redhat.com> | 2003-10-08 18:19:33 +0000 |
commit | e930b1f54ff2768c5818eb0a450b1d98d46d273d (patch) | |
tree | beff79b0fd16e78faffe78489d34d064d5618b43 /sim/frv/traps.c | |
parent | 7c3f9ad027b9ec2906f3367ca7be18e5fb8f6893 (diff) | |
download | gdb-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.c | 100 |
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) { |