* [PATCH, V850] Add support for V850E2 and V850E2V3
@ 2011-01-19 14:59 Rathish C
2012-03-22 20:26 ` Kevin Buettner
0 siblings, 1 reply; 14+ messages in thread
From: Rathish C @ 2011-01-19 14:59 UTC (permalink / raw)
To: gdb-patches; +Cc: kevinb, Gina Verlekar
Hi Kevin,
Thank you for approving the patch.
I have updated the ChangeLog entry as per your comments.
Please find the updated patch "v850-gdb-v850e2-v850e2v3-support.patch".
2011-01-19 Rathish.C <rathish.c@kpitcummins.com>
* gdb/v850-tdep.c: Add the enum values for mpu and fpu registers.
(v850_register_name): Add the mpu and fpu register names.
(v850e_register_name): Add the mpu and fpu register names.
(v850e2_register_name): New function.
(v850_gdbarch_init): Add case for bfd_mach_v850e2 and
bfd_mach_v850e2v3.
* sim/common/sim-trace.c: Update the function prototype of
save_data_size.
Move the enum data_fmt from here...
* sim/common/sim-trace.h: to here.
Add function prototype of save_data.
* sim/v850/sim-main.h: Update the struct _v850_regs to include
mpu and fpu system registers.
Define the macros to access the mpu and fpu system registers.
(SEXT3): Define.
(TRACE_FP_INPUT_FPU1, TRACE_FP_INPUT_FPU2,
TRACE_FP_INPUT_FPU3): Define.
(TRACE_FP_INPUT_BOOL1_FPU2): Define.
(TRACE_FP_INPUT_WORD2): Define.
(TRACE_FP_RESULT_WORD1, TRACE_FP_RESULT_WORD2): Define.
* sim/v850/simops.c: Update the function prototype of Add32.
(update_fpsr): New function.
(SignalException): New function.
(SignalExceptionFPE): New function.
(check_invalid_snan): New function.
(v850_float_compare): New function.
(v850_div): New function.
(v850_divu): New function.
(v850_sar): New function.
(v850_shl): New function.
(v850_shr): New function.
(v850_satadd): New function.
(v850_satsub): New function.
(load_data_mem): New function.
(store_data_mem): New function.
(mpu_load_mem_test): New function.
(mpu_store_mem_test): New function.
* sim/v850/simops.h: Add function prototype for above
mentioned functions.
(check_cvt_fi, check_cvt_if, check_cvt_ff): Define.
* sim/v850/v850-dc: Add entry for v850e2 and v850e2v3.
* sim/v850/v850.igen: Add support for v850e2 and v850e2v3.
Thanks & Regards,
Rathish.C
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH, V850] Add support for V850E2 and V850E2V3
2011-01-19 14:59 [PATCH, V850] Add support for V850E2 and V850E2V3 Rathish C
@ 2012-03-22 20:26 ` Kevin Buettner
2012-03-28 10:49 ` Rathish C
0 siblings, 1 reply; 14+ messages in thread
From: Kevin Buettner @ 2012-03-22 20:26 UTC (permalink / raw)
To: Rathish C; +Cc: gdb-patches, Gina Verlekar
Hi Rathish,
I just noticed that the patch associated with the ChangeLog entry below
hasn't been committed yet. Please note that I approved your work in
this message:
http://sourceware.org/ml/gdb-patches/2011-01/msg00354.html
If you were awaiting approval of your new ChangeLog entry, then that
is approved too.
Kevin
On Wed, 19 Jan 2011 11:39:47 +0530
Rathish C <Rathish.C@kpitcummins.com> wrote:
>
> Hi Kevin,
>
> Thank you for approving the patch.
> I have updated the ChangeLog entry as per your comments.
>
> Please find the updated patch "v850-gdb-v850e2-v850e2v3-support.patch".
>
> 2011-01-19 Rathish.C <rathish.c@kpitcummins.com>
>
> * gdb/v850-tdep.c: Add the enum values for mpu and fpu registers.
> (v850_register_name): Add the mpu and fpu register names.
> (v850e_register_name): Add the mpu and fpu register names.
> (v850e2_register_name): New function.
> (v850_gdbarch_init): Add case for bfd_mach_v850e2 and
> bfd_mach_v850e2v3.
> * sim/common/sim-trace.c: Update the function prototype of
> save_data_size.
> Move the enum data_fmt from here...
> * sim/common/sim-trace.h: to here.
> Add function prototype of save_data.
> * sim/v850/sim-main.h: Update the struct _v850_regs to include
> mpu and fpu system registers.
> Define the macros to access the mpu and fpu system registers.
> (SEXT3): Define.
> (TRACE_FP_INPUT_FPU1, TRACE_FP_INPUT_FPU2,
> TRACE_FP_INPUT_FPU3): Define.
> (TRACE_FP_INPUT_BOOL1_FPU2): Define.
> (TRACE_FP_INPUT_WORD2): Define.
> (TRACE_FP_RESULT_WORD1, TRACE_FP_RESULT_WORD2): Define.
> * sim/v850/simops.c: Update the function prototype of Add32.
> (update_fpsr): New function.
> (SignalException): New function.
> (SignalExceptionFPE): New function.
> (check_invalid_snan): New function.
> (v850_float_compare): New function.
> (v850_div): New function.
> (v850_divu): New function.
> (v850_sar): New function.
> (v850_shl): New function.
> (v850_shr): New function.
> (v850_satadd): New function.
> (v850_satsub): New function.
> (load_data_mem): New function.
> (store_data_mem): New function.
> (mpu_load_mem_test): New function.
> (mpu_store_mem_test): New function.
> * sim/v850/simops.h: Add function prototype for above
> mentioned functions.
> (check_cvt_fi, check_cvt_if, check_cvt_ff): Define.
> * sim/v850/v850-dc: Add entry for v850e2 and v850e2v3.
> * sim/v850/v850.igen: Add support for v850e2 and v850e2v3.
>
> Thanks & Regards,
> Rathish.C
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [PATCH, V850] Add support for V850E2 and V850E2V3
2012-03-22 20:26 ` Kevin Buettner
@ 2012-03-28 10:49 ` Rathish C
2012-03-28 12:01 ` Kevin Buettner
2012-03-29 1:06 ` Kevin Buettner
0 siblings, 2 replies; 14+ messages in thread
From: Rathish C @ 2012-03-28 10:49 UTC (permalink / raw)
To: Kevin Buettner; +Cc: gdb-patches, Gina Verlekar
Hi Kevin,
Thanks for the approval. I don't have the log-in rights to commit the patch.
If possible, can you please commit the patch. Or else please let me know the
procedure to commit the patch.
Thanks & Regards,
Rathish C
> -----Original Message-----
> From: Kevin Buettner [mailto:kevinb@redhat.com]
> Sent: Friday, March 23, 2012 1:56 AM
> To: Rathish C
> Cc: gdb-patches@sourceware.org; Gina Verlekar
> Subject: Re: [PATCH, V850] Add support for V850E2 and V850E2V3
>
> Hi Rathish,
>
> I just noticed that the patch associated with the ChangeLog entry
> below
> hasn't been committed yet. Please note that I approved your work in
> this message:
>
> http://sourceware.org/ml/gdb-patches/2011-01/msg00354.html
>
> If you were awaiting approval of your new ChangeLog entry, then that
> is approved too.
>
> Kevin
>
> On Wed, 19 Jan 2011 11:39:47 +0530
> Rathish C <Rathish.C@kpitcummins.com> wrote:
>
> >
> > Hi Kevin,
> >
> > Thank you for approving the patch.
> > I have updated the ChangeLog entry as per your comments.
> >
> > Please find the updated patch "v850-gdb-v850e2-v850e2v3-
> support.patch".
> >
> > 2011-01-19 Rathish.C <rathish.c@kpitcummins.com>
> >
> > * gdb/v850-tdep.c: Add the enum values for mpu and fpu
> registers.
> > (v850_register_name): Add the mpu and fpu register names.
> > (v850e_register_name): Add the mpu and fpu register names.
> > (v850e2_register_name): New function.
> > (v850_gdbarch_init): Add case for bfd_mach_v850e2 and
> > bfd_mach_v850e2v3.
> > * sim/common/sim-trace.c: Update the function prototype of
> > save_data_size.
> > Move the enum data_fmt from here...
> > * sim/common/sim-trace.h: to here.
> > Add function prototype of save_data.
> > * sim/v850/sim-main.h: Update the struct _v850_regs to include
> > mpu and fpu system registers.
> > Define the macros to access the mpu and fpu system registers.
> > (SEXT3): Define.
> > (TRACE_FP_INPUT_FPU1, TRACE_FP_INPUT_FPU2,
> > TRACE_FP_INPUT_FPU3): Define.
> > (TRACE_FP_INPUT_BOOL1_FPU2): Define.
> > (TRACE_FP_INPUT_WORD2): Define.
> > (TRACE_FP_RESULT_WORD1, TRACE_FP_RESULT_WORD2): Define.
> > * sim/v850/simops.c: Update the function prototype of Add32.
> > (update_fpsr): New function.
> > (SignalException): New function.
> > (SignalExceptionFPE): New function.
> > (check_invalid_snan): New function.
> > (v850_float_compare): New function.
> > (v850_div): New function.
> > (v850_divu): New function.
> > (v850_sar): New function.
> > (v850_shl): New function.
> > (v850_shr): New function.
> > (v850_satadd): New function.
> > (v850_satsub): New function.
> > (load_data_mem): New function.
> > (store_data_mem): New function.
> > (mpu_load_mem_test): New function.
> > (mpu_store_mem_test): New function.
> > * sim/v850/simops.h: Add function prototype for above
> > mentioned functions.
> > (check_cvt_fi, check_cvt_if, check_cvt_ff): Define.
> > * sim/v850/v850-dc: Add entry for v850e2 and v850e2v3.
> > * sim/v850/v850.igen: Add support for v850e2 and v850e2v3.
> >
> > Thanks & Regards,
> > Rathish.C
> >
> >
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH, V850] Add support for V850E2 and V850E2V3
2012-03-28 10:49 ` Rathish C
@ 2012-03-28 12:01 ` Kevin Buettner
2012-03-28 14:45 ` Joel Brobecker
2012-03-29 1:06 ` Kevin Buettner
1 sibling, 1 reply; 14+ messages in thread
From: Kevin Buettner @ 2012-03-28 12:01 UTC (permalink / raw)
To: Rathish C; +Cc: gdb-patches, Gina Verlekar, Joel Brobecker
On Wed, 28 Mar 2012 10:49:03 +0000
Rathish C <Rathish.C@kpitcummins.com> wrote:
> Thanks for the approval. I don't have the log-in rights to commit the patch.
> If possible, can you please commit the patch. Or else please let me know the
> procedure to commit the patch.
Hi Rathish,
I am willing to commit your patch for you.
Before doing so, however, I would like to verify that you've completed
the necessary (copyright assignment) paperwork with the FSF?
I would guess that the answer is yes, since the v850e2 and v850e2v3
work has made it into bfd. But I wanted to double check to make sure
that the paperwork in question has been completed for gdb too.
Kevin
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH, V850] Add support for V850E2 and V850E2V3
2012-03-28 12:01 ` Kevin Buettner
@ 2012-03-28 14:45 ` Joel Brobecker
2012-03-29 1:07 ` Kevin Buettner
0 siblings, 1 reply; 14+ messages in thread
From: Joel Brobecker @ 2012-03-28 14:45 UTC (permalink / raw)
To: Kevin Buettner; +Cc: Rathish C, gdb-patches, Gina Verlekar
> Before doing so, however, I would like to verify that you've completed
> the necessary (copyright assignment) paperwork with the FSF?
I found a copyright assignment in the FSF records for KPIT Cummins
Infosystems Ltd, so if it is the correct company, it should be OK.
--
Joel
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH, V850] Add support for V850E2 and V850E2V3
2012-03-28 10:49 ` Rathish C
2012-03-28 12:01 ` Kevin Buettner
@ 2012-03-29 1:06 ` Kevin Buettner
1 sibling, 0 replies; 14+ messages in thread
From: Kevin Buettner @ 2012-03-29 1:06 UTC (permalink / raw)
To: gdb-patches
On Wed, 28 Mar 2012 10:49:03 +0000
Rathish C <Rathish.C@kpitcummins.com> wrote:
> If possible, can you please commit the patch.
Hi Rathish,
I've committed your patch for you. I tweaked a few of your ChangeLog
entries in the sim, but your name appears in each of the ChangeLog
entries thus giving you credit for this work.
You may wish to check over my commit to make sure that everything
still builds and works. Also, should it be the case that I made an
error in any of my ChangeLog tweaks, please let me know so that I can
make any necessary corrections.
Thanks,
Kevin
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH, V850] Add support for V850E2 and V850E2V3
2012-03-28 14:45 ` Joel Brobecker
@ 2012-03-29 1:07 ` Kevin Buettner
0 siblings, 0 replies; 14+ messages in thread
From: Kevin Buettner @ 2012-03-29 1:07 UTC (permalink / raw)
To: gdb-patches
On Wed, 28 Mar 2012 07:44:42 -0700
Joel Brobecker <brobecker@adacore.com> wrote:
> > Before doing so, however, I would like to verify that you've completed
> > the necessary (copyright assignment) paperwork with the FSF?
>
> I found a copyright assignment in the FSF records for KPIT Cummins
> Infosystems Ltd, so if it is the correct company, it should be OK.
Thank you for checking on this. Much appreciated.
Kevin
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH, V850] Add support for V850E2 and V850E2V3
2011-01-12 13:25 Rathish C
@ 2011-01-15 7:39 ` Kevin Buettner
0 siblings, 0 replies; 14+ messages in thread
From: Kevin Buettner @ 2011-01-15 7:39 UTC (permalink / raw)
To: gdb-patches
On Wed, 12 Jan 2011 18:37:27 +0530
Rathish C <Rathish.C@kpitcummins.com> wrote:
> I have removed the definition from the sim-main.h file and
> updated the patch accordingly.
Thanks for making this change.
> Please review the patch and let me know if there should be
> any other modifications in it.
Your most recent patch looks reasonable to me.
The gdb patch is still approved.
I've reviewed sim/MAINTAINERS and it appears that I may approve
patches for certain areas of the sim too. Therefore, I approve
your sim changes as well.
I found a few nits, however, in your ChangeLog entry...
> 2011-01-12 Rathish.C <rathish.c@kpitcummins.com>
>
> * gdb/v850-tdep.c: Add the enum values for mpu and fpu registers
Add a period (.) to the end of the above sentence.
> (v850_register_name): Add the mpu and fpu register names.
> (v850e_register_name): Add the mpu and fpu register names.
> (v850e2_register_name): New function.
> (v850_gdbarch_init): Add case for bfd_mach_v850e2 and
> bfd_mach_v850e2v3.
> * sim/common/sim-trace.c: Update the function prototype of
> save_data_size.
> Move the enum data_fmt from here
Add an ellipsis (...) after "here".
> * sim/common/sim-trace.h: to here.
> Add function prototype of save_data
Add a period to the end of the above sentence.
> * sim/v850/sim-main.h: Update the struct _v850_regs to include
> mpu and fpu system registers.
> Define the macros to access the mpu and fpu system registers.
> (SEXT3): Define.
> (TRACE_FP_INPUT_FPU1, TRACE_FP_INPUT_FPU2,
> TRACE_FP_INPUT_FPU3): Define.
> (TRACE_FP_INPUT_BOOL1_FPU2): Define.
> (TRACE_FP_INPUT_WORD2): Define.
> (TRACE_FP_RESULT_WORD1, TRACE_FP_RESULT_WORD2): Define.
> * sim/v850/simops.c: Update the function prototype of Add32
Add a period to the end of the above sentence.
> (update_fpsr): New function.
> (SignalException): New function.
> (SignalExceptionFPE): New function.
> (check_invalid_snan): New function.
> (v850_float_compare): New function.
> (v850_div): New function.
> (v850_divu): New function.
> (v850_sar): New function.
> (v850_shl): New function.
> (v850_shr): New function.
> (v850_satadd): New function.
> (v850_satsub): New function.
> (load_data_mem): New function.
> (store_data_mem): New function.
> (mpu_load_mem_test): New function.
> (mpu_store_mem_test): New function.
> * sim/v850/simops.h: Add function prototype for above
> mentioned functions.
> (check_cvt_fi, check_cvt_if, check_cvt_ff): Define.
> * sim/v850/v850-dc: Add entry for v850e2 and v850e2v3.
> * sim/v850/v850.igen: Add support for v850e2 and v850e2v3
Add a period to the end of the above sentence.
Kevin
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH, V850] Add support for V850E2 and V850E2V3
@ 2011-01-12 13:25 Rathish C
2011-01-15 7:39 ` Kevin Buettner
0 siblings, 1 reply; 14+ messages in thread
From: Rathish C @ 2011-01-12 13:25 UTC (permalink / raw)
To: gdb-patches; +Cc: kevinb, Gina Verlekar
[-- Attachment #1: Type: text/plain, Size: 3366 bytes --]
Hi,
Thank you for the review comments.
I have updated the patch based on the review comments from Kevin Buettner.
Please find the updated patch "v850-gdb-v850e2-v850e2v3-support.patch".
>
> Your changes to gdb/v850-tdep.c are approved.
>
Thank you for approving the changes to the gdb/v850-tdep.c file.
>
> I have one comment (see below) for the sim portion of the patch. The
> rest of the patch looks reasonable to me. (It's unclear to me whether or
> not I can approve sim patches...)
>
>
>
>> diff -upNr gdb-7.2.50-original/sim/v850/sim-main.h gdb-7.2.50-
>> modified/sim/v850/sim-main.h
>> --- gdb-7.2.50-original/sim/v850/sim-main.h 2002-11-30
>> 23:31:30.000000000 +0530
>> +++ gdb-7.2.50-modified/sim/v850/sim-main.h 2010-12-08
>> 14:52:40.000000000 +0530 [...]
>> @@ -61,6 +65,7 @@ struct sim_state {
>> #define STATE_CPU(sd,n) (&(sd)->cpu[n])
>> #else
>> #define STATE_CPU(sd,n) (&(sd)->cpu[0])
>> +#define CPU (STATE_CPU (sd, 0))
>> #endif
>
>
> Do you really need to define CPU here? It appears to me that a
> suitable definition for CPU is placed in support.h by igen at build
> time. If it turns out that you do need this definition, you should
> make sure that the WITH_SMP case is handled too.
>
Yes, the CPU definition is available in support.h in the
./sim/v850/support.h file.
I have removed the definition from the sim-main.h file and
updated the patch accordingly.
Please review the patch and let me know if there should be
any other modifications in it.
2011-01-12 Rathish.C <rathish.c@kpitcummins.com>
* gdb/v850-tdep.c: Add the enum values for mpu and fpu registers
(v850_register_name): Add the mpu and fpu register names.
(v850e_register_name): Add the mpu and fpu register names.
(v850e2_register_name): New function.
(v850_gdbarch_init): Add case for bfd_mach_v850e2 and
bfd_mach_v850e2v3.
* sim/common/sim-trace.c: Update the function prototype of
save_data_size.
Move the enum data_fmt from here
* sim/common/sim-trace.h: to here.
Add function prototype of save_data
* sim/v850/sim-main.h: Update the struct _v850_regs to include
mpu and fpu system registers.
Define the macros to access the mpu and fpu system registers.
(SEXT3): Define.
(TRACE_FP_INPUT_FPU1, TRACE_FP_INPUT_FPU2,
TRACE_FP_INPUT_FPU3): Define.
(TRACE_FP_INPUT_BOOL1_FPU2): Define.
(TRACE_FP_INPUT_WORD2): Define.
(TRACE_FP_RESULT_WORD1, TRACE_FP_RESULT_WORD2): Define.
* sim/v850/simops.c: Update the function prototype of Add32
(update_fpsr): New function.
(SignalException): New function.
(SignalExceptionFPE): New function.
(check_invalid_snan): New function.
(v850_float_compare): New function.
(v850_div): New function.
(v850_divu): New function.
(v850_sar): New function.
(v850_shl): New function.
(v850_shr): New function.
(v850_satadd): New function.
(v850_satsub): New function.
(load_data_mem): New function.
(store_data_mem): New function.
(mpu_load_mem_test): New function.
(mpu_store_mem_test): New function.
* sim/v850/simops.h: Add function prototype for above
mentioned functions.
(check_cvt_fi, check_cvt_if, check_cvt_ff): Define.
* sim/v850/v850-dc: Add entry for v850e2 and v850e2v3.
* sim/v850/v850.igen: Add support for v850e2 and v850e2v3
Thanks & Regards,
Rathish.C
[-- Attachment #2: v850-gdb-v850e2-v850e2v3-support.patch --]
[-- Type: application/octet-stream, Size: 94476 bytes --]
diff -upNr gdb-7.2.50-original/gdb/v850-tdep.c gdb-7.2.50-modified/gdb/v850-tdep.c
--- gdb-7.2.50-original/gdb/v850-tdep.c 2011-01-01 21:03:18.000000000 +0530
+++ gdb-7.2.50-modified/gdb/v850-tdep.c 2011-01-11 18:24:30.000000000 +0530
@@ -101,7 +101,97 @@ enum
E_R62_REGNUM,
E_R63_REGNUM,
E_R64_REGNUM, E_PC_REGNUM = E_R64_REGNUM,
- E_R65_REGNUM,
+ E_R65_REGNUM, E_NUM_OF_V850_REGS = E_R65_REGNUM, E_NUM_OF_V850E_REGS = E_R65_REGNUM,
+
+ /* mpu0 system registers */
+ E_R66_REGNUM,
+ E_R67_REGNUM,
+ E_R68_REGNUM,
+ E_R69_REGNUM,
+ E_R70_REGNUM,
+ E_R71_REGNUM,
+ E_R72_REGNUM,
+ E_R73_REGNUM,
+ E_R74_REGNUM,
+ E_R75_REGNUM,
+ E_R76_REGNUM,
+ E_R77_REGNUM,
+ E_R78_REGNUM,
+ E_R79_REGNUM,
+ E_R80_REGNUM,
+ E_R81_REGNUM,
+ E_R82_REGNUM,
+ E_R83_REGNUM,
+ E_R84_REGNUM,
+ E_R85_REGNUM,
+ E_R86_REGNUM,
+ E_R87_REGNUM,
+ E_R88_REGNUM,
+ E_R89_REGNUM,
+ E_R90_REGNUM,
+ E_R91_REGNUM,
+ E_R92_REGNUM,
+ E_R93_REGNUM,
+
+ /* mpu1 system registers */
+
+ E_R94_REGNUM,
+ E_R95_REGNUM,
+ E_R96_REGNUM,
+ E_R97_REGNUM,
+ E_R98_REGNUM,
+ E_R99_REGNUM,
+ E_R100_REGNUM,
+ E_R101_REGNUM,
+ E_R102_REGNUM,
+ E_R103_REGNUM,
+ E_R104_REGNUM,
+ E_R105_REGNUM,
+ E_R106_REGNUM,
+ E_R107_REGNUM,
+ E_R108_REGNUM,
+ E_R109_REGNUM,
+ E_R110_REGNUM,
+ E_R111_REGNUM,
+ E_R112_REGNUM,
+ E_R113_REGNUM,
+ E_R114_REGNUM,
+ E_R115_REGNUM,
+ E_R116_REGNUM,
+ E_R117_REGNUM,
+ E_R118_REGNUM,
+ E_R119_REGNUM,
+ E_R120_REGNUM,
+ E_R121_REGNUM,
+
+ /* fpu system registers */
+ E_R122_REGNUM,
+ E_R123_REGNUM,
+ E_R124_REGNUM,
+ E_R125_REGNUM,
+ E_R126_REGNUM,
+ E_R127_REGNUM,
+ E_R128_REGNUM, E_FPSR_REGNUM = E_R128_REGNUM,
+ E_R129_REGNUM, E_FPEPC_REGNUM = E_R129_REGNUM,
+ E_R130_REGNUM, E_FPST_REGNUM = E_R130_REGNUM,
+ E_R131_REGNUM, E_FPCC_REGNUM = E_R131_REGNUM,
+ E_R132_REGNUM, E_FPCFG_REGNUM = E_R132_REGNUM,
+ E_R133_REGNUM,
+ E_R134_REGNUM,
+ E_R135_REGNUM,
+ E_R136_REGNUM,
+ E_R137_REGNUM,
+ E_R138_REGNUM,
+ E_R139_REGNUM,
+ E_R140_REGNUM,
+ E_R141_REGNUM,
+ E_R142_REGNUM,
+ E_R143_REGNUM,
+ E_R144_REGNUM,
+ E_R145_REGNUM,
+ E_R146_REGNUM,
+ E_R147_REGNUM,
+ E_R148_REGNUM,
E_NUM_REGS
};
@@ -152,7 +242,7 @@ v850_register_name (struct gdbarch *gdba
"sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
"pc", "fp"
};
- if (regnum < 0 || regnum >= E_NUM_REGS)
+ if (regnum < 0 || regnum > E_NUM_OF_V850_REGS)
return NULL;
return v850_reg_names[regnum];
}
@@ -172,11 +262,50 @@ v850e_register_name (struct gdbarch *gdb
"sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
"pc", "fp"
};
- if (regnum < 0 || regnum >= E_NUM_REGS)
+ if (regnum < 0 || regnum > E_NUM_OF_V850E_REGS)
return NULL;
return v850e_reg_names[regnum];
}
+static const char *
+v850e2_register_name (struct gdbarch *gdbarch, int regnum)
+{
+ static const char *v850e2_reg_names[] =
+ {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+
+ "eipc", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7",
+ "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
+ "ctpc", "ctpsw", "dbpc", "dbpsw", "ctbp", "sr21", "sr22", "sr23",
+ "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
+ "pc", "fp"
+
+ /* mpu0 system registers */
+ "vip", "sr33", "sr34", "sr35", "vmecr", "vmtid", "vmadr", "sr39",
+ "vpecr", "vptid", "vpadr", "sr43", "vdecr", "vdtid", "sr46", "sr47",
+ "sr48", "sr49", "sr50", "sr51", "sr52", "sr53", "sr54", "sr55",
+ "sr56", "sr57", "sr58", "sr59",
+
+ /* mpu1 system registers */
+ "mpm", "mpc", "tid", "ppa", "ppm", "ppc", "dcc", "dcv0",
+ "dcv1", "sr69", "spal", "spau", "ipa0l", "ipa0u", "ipa1l", "ipa1u",
+ "iap2l", "ipa2u", "ipa3l", "ipa3u", "dpa0l", "dpa0u", "dpa1l", "dpa1u",
+ "dpa2l", "dpa2u", "dpa3l", "dpa3u",
+
+ /* fpu system registers */
+ "sr88", "sr89", "sr90", "sr91", "sr92", "sr93", "fpsr", "fpepc",
+ "fpst", "fpcc", "fpcfg", "sr99", "sr100", "sr101", "sr102", "sr103",
+ "sr104", "sr105", "sr106", "sr107", "sr108", "sr109", "sr110", "sr111",
+ "sr112", "sr113", "sr114", "sr115"
+ };
+ if (regnum < 0 || regnum >= E_NUM_REGS)
+ return NULL;
+ return v850e2_reg_names[regnum];
+}
+
/* Returns the default type for register N. */
static struct type *
@@ -996,6 +1125,10 @@ v850_gdbarch_init (struct gdbarch_info i
case bfd_mach_v850e1:
set_gdbarch_register_name (gdbarch, v850e_register_name);
break;
+ case bfd_mach_v850e2:
+ case bfd_mach_v850e2v3:
+ set_gdbarch_register_name (gdbarch, v850e2_register_name);
+ break;
}
set_gdbarch_num_regs (gdbarch, E_NUM_REGS);
diff -upNr gdb-7.2.50-original/sim/common/sim-trace.c gdb-7.2.50-modified/sim/common/sim-trace.c
--- gdb-7.2.50-original/sim/common/sim-trace.c 2011-01-01 21:03:56.000000000 +0530
+++ gdb-7.2.50-modified/sim/common/sim-trace.c 2011-01-11 18:24:56.000000000 +0530
@@ -486,17 +486,6 @@ trace_uninstall (SIM_DESC sd)
}
}
\f
-typedef enum {
- trace_fmt_invalid,
- trace_fmt_word,
- trace_fmt_fp,
- trace_fmt_fpu,
- trace_fmt_string,
- trace_fmt_bool,
- trace_fmt_addr,
- trace_fmt_instruction_incomplete,
-} data_fmt;
-
/* compute the nr of trace data units consumed by data */
static int
save_data_size (TRACE_DATA *data,
@@ -508,7 +497,7 @@ save_data_size (TRACE_DATA *data,
/* Archive DATA into the trace buffer */
-static void
+void
save_data (SIM_DESC sd,
TRACE_DATA *data,
data_fmt fmt,
diff -upNr gdb-7.2.50-original/sim/common/sim-trace.h gdb-7.2.50-modified/sim/common/sim-trace.h
--- gdb-7.2.50-original/sim/common/sim-trace.h 2011-01-01 21:03:56.000000000 +0530
+++ gdb-7.2.50-modified/sim/common/sim-trace.h 2011-01-11 18:24:56.000000000 +0530
@@ -243,9 +243,26 @@ extern void trace_generic PARAMS ((SIM_D
...))
__attribute__((format (printf, 4, 5)));
+typedef enum {
+ trace_fmt_invalid,
+ trace_fmt_word,
+ trace_fmt_fp,
+ trace_fmt_fpu,
+ trace_fmt_string,
+ trace_fmt_bool,
+ trace_fmt_addr,
+ trace_fmt_instruction_incomplete,
+} data_fmt;
+
/* Trace a varying number of word sized inputs/outputs. trace_result*
must be called to close the trace operation. */
+extern void save_data PARAMS ((SIM_DESC sd,
+ TRACE_DATA *data,
+ data_fmt fmt,
+ long size,
+ const void *buf));
+
extern void trace_input0 PARAMS ((SIM_DESC sd,
sim_cpu *cpu,
int trace_idx));
diff -upNr gdb-7.2.50-original/sim/v850/sim-main.h gdb-7.2.50-modified/sim/v850/sim-main.h
--- gdb-7.2.50-original/sim/v850/sim-main.h 2002-11-30 23:31:30.000000000 +0530
+++ gdb-7.2.50-modified/sim/v850/sim-main.h 2011-01-11 18:24:58.000000000 +0530
@@ -15,6 +15,7 @@
#include "sim-basics.h"
#include "sim-signal.h"
+#include "sim-fpu.h"
typedef address_word sim_cia;
@@ -39,7 +40,10 @@ typedef struct _v850_regs {
reg_t regs[32]; /* general-purpose registers */
reg_t sregs[32]; /* system registers, including psw */
reg_t pc;
- int dummy_mem; /* where invalid accesses go */
+ int dummy_mem; /* where invalid accesses go */
+ reg_t mpu0_sregs[28]; /* mpu0 system registers */
+ reg_t mpu1_sregs[28]; /* mpu1 system registers */
+ reg_t fpu_sregs[28]; /* fpu system registers */
} v850_regs;
struct _sim_cpu
@@ -122,11 +126,15 @@ nia = PC
/* new */
#define GR ((CPU)->reg.regs)
#define SR ((CPU)->reg.sregs)
+#define MPU0_SR ((STATE_CPU (sd, 0))->reg.mpu0_sregs)
+#define MPU1_SR ((STATE_CPU (sd, 0))->reg.mpu1_sregs)
+#define FPU_SR ((STATE_CPU (sd, 0))->reg.fpu_sregs)
/* old */
#define State (STATE_CPU (simulator, 0)->reg)
#define PC (State.pc)
-#define SP (State.regs[3])
+#define SP_REGNO 3
+#define SP (State.regs[SP_REGNO])
#define EP (State.regs[30])
#define EIPC (State.sregs[0])
@@ -135,11 +143,20 @@ nia = PC
#define FEPSW (State.sregs[3])
#define ECR (State.sregs[4])
#define PSW (State.sregs[5])
+#define PSW_REGNO 5
+#define EIIC (State.sregs[13])
+#define FEIC (State.sregs[14])
+#define DBIC (SR[15])
#define CTPC (SR[16])
#define CTPSW (SR[17])
#define DBPC (State.sregs[18])
#define DBPSW (State.sregs[19])
#define CTBP (State.sregs[20])
+#define DIR (SR[21])
+#define EIWR (SR[28])
+#define FEWR (SR[29])
+#define DBWR (SR[30])
+#define BSEL (SR[31])
#define PSW_US BIT32 (8)
#define PSW_NP 0x80
@@ -151,6 +168,210 @@ nia = PC
#define PSW_S 0x2
#define PSW_Z 0x1
+#define PSW_NPV (1<<18)
+#define PSW_DMP (1<<17)
+#define PSW_IMP (1<<16)
+
+#define ECR_EICC 0x0000ffff
+#define ECR_FECC 0xffff0000
+
+/* FPU */
+
+#define FPSR (FPU_SR[6])
+#define FPSR_REGNO 6
+#define FPEPC (FPU_SR[7])
+#define FPST (FPU_SR[8])
+#define FPST_REGNO 8
+#define FPCC (FPU_SR[9])
+#define FPCFG (FPU_SR[10])
+#define FPCFG_REGNO 10
+
+#define FPSR_DEM 0x00200000
+#define FPSR_SEM 0x00100000
+#define FPSR_RM 0x000c0000
+#define FPSR_RN 0x00000000
+#define FPSR_FS 0x00020000
+#define FPSR_PR 0x00010000
+
+#define FPSR_XC 0x0000fc00
+#define FPSR_XCE 0x00008000
+#define FPSR_XCV 0x00004000
+#define FPSR_XCZ 0x00002000
+#define FPSR_XCO 0x00001000
+#define FPSR_XCU 0x00000800
+#define FPSR_XCI 0x00000400
+
+#define FPSR_XE 0x000003e0
+#define FPSR_XEV 0x00000200
+#define FPSR_XEZ 0x00000100
+#define FPSR_XEO 0x00000080
+#define FPSR_XEU 0x00000040
+#define FPSR_XEI 0x00000020
+
+#define FPSR_XP 0x0000001f
+#define FPSR_XPV 0x00000010
+#define FPSR_XPZ 0x00000008
+#define FPSR_XPO 0x00000004
+#define FPSR_XPU 0x00000002
+#define FPSR_XPI 0x00000001
+
+#define FPST_PR 0x00008000
+#define FPST_XCE 0x00002000
+#define FPST_XCV 0x00001000
+#define FPST_XCZ 0x00000800
+#define FPST_XCO 0x00000400
+#define FPST_XCU 0x00000200
+#define FPST_XCI 0x00000100
+
+#define FPST_XPV 0x00000010
+#define FPST_XPZ 0x00000008
+#define FPST_XPO 0x00000004
+#define FPST_XPU 0x00000002
+#define FPST_XPI 0x00000001
+
+#define FPCFG_RM 0x00000180
+#define FPCFG_XEV 0x00000010
+#define FPCFG_XEZ 0x00000008
+#define FPCFG_XEO 0x00000004
+#define FPCFG_XEU 0x00000002
+#define FPCFG_XEI 0x00000001
+
+#define GET_FPCC()\
+ ((FPSR >> 24) &0xf)
+
+#define CLEAR_FPCC(bbb)\
+ (FPSR &= ~(1 << (bbb+24)))
+
+#define SET_FPCC(bbb)\
+ (FPSR |= 1 << (bbb+24))
+
+#define TEST_FPCC(bbb)\
+ ((FPSR & (1 << (bbb+24))) != 0)
+
+#define FPSR_GET_ROUND() \
+ (((FPSR & FPSR_RM) == FPSR_RN) ? sim_fpu_round_near \
+ : ((FPSR & FPSR_RM) == 0x00040000) ? sim_fpu_round_up \
+ : ((FPSR & FPSR_RM) == 0x00080000) ? sim_fpu_round_down \
+ : sim_fpu_round_zero)
+
+
+enum FPU_COMPARE {
+ FPU_CMP_F = 0,
+ FPU_CMP_UN,
+ FPU_CMP_EQ,
+ FPU_CMP_UEQ,
+ FPU_CMP_OLT,
+ FPU_CMP_ULT,
+ FPU_CMP_OLE,
+ FPU_CMP_ULE,
+ FPU_CMP_SF,
+ FPU_CMP_NGLE,
+ FPU_CMP_SEQ,
+ FPU_CMP_NGL,
+ FPU_CMP_LT,
+ FPU_CMP_NGE,
+ FPU_CMP_LE,
+ FPU_CMP_NGT
+};
+
+
+/* MPU */
+#define MPM (MPU1_SR[0])
+#define MPC (MPU1_SR[1])
+#define MPC_REGNO 1
+#define TID (MPU1_SR[2])
+#define PPA (MPU1_SR[3])
+#define PPM (MPU1_SR[4])
+#define PPC (MPU1_SR[5])
+#define DCC (MPU1_SR[6])
+#define DCV0 (MPU1_SR[7])
+#define DCV1 (MPU1_SR[8])
+#define SPAL (MPU1_SR[10])
+#define SPAU (MPU1_SR[11])
+#define IPA0L (MPU1_SR[12])
+#define IPA0U (MPU1_SR[13])
+#define IPA1L (MPU1_SR[14])
+#define IPA1U (MPU1_SR[15])
+#define IPA2L (MPU1_SR[16])
+#define IPA2U (MPU1_SR[17])
+#define IPA3L (MPU1_SR[18])
+#define IPA3U (MPU1_SR[19])
+#define DPA0L (MPU1_SR[20])
+#define DPA0U (MPU1_SR[21])
+#define DPA1L (MPU1_SR[22])
+#define DPA1U (MPU1_SR[23])
+#define DPA2L (MPU1_SR[24])
+#define DPA2U (MPU1_SR[25])
+#define DPA3L (MPU1_SR[26])
+#define DPA3U (MPU1_SR[27])
+
+#define PPC_PPE 0x1
+#define SPAL_SPE 0x1
+#define SPAL_SPS 0x10
+
+#define VIP (MPU0_SR[0])
+#define VMECR (MPU0_SR[4])
+#define VMTID (MPU0_SR[5])
+#define VMADR (MPU0_SR[6])
+#define VPECR (MPU0_SR[8])
+#define VPTID (MPU0_SR[9])
+#define VPADR (MPU0_SR[10])
+#define VDECR (MPU0_SR[12])
+#define VDTID (MPU0_SR[13])
+
+#define MPM_AUE 0x2
+#define MPM_MPE 0x1
+
+#define VMECR_VMX 0x2
+#define VMECR_VMR 0x4
+#define VMECR_VMW 0x8
+#define VMECR_VMS 0x10
+#define VMECR_VMRMW 0x20
+#define VMECR_VMMS 0x40
+
+#define IPA2ADDR(IPA) ((IPA) & 0x1fffff80)
+#define IPA_IPE 0x1
+#define IPA_IPX 0x2
+#define IPA_IPR 0x4
+#define IPE0 (IPA0L & IPA_IPE)
+#define IPE1 (IPA1L & IPA_IPE)
+#define IPE2 (IPA2L & IPA_IPE)
+#define IPE3 (IPA3L & IPA_IPE)
+#define IPX0 (IPA0L & IPA_IPX)
+#define IPX1 (IPA1L & IPA_IPX)
+#define IPX2 (IPA2L & IPA_IPX)
+#define IPX3 (IPA3L & IPA_IPX)
+#define IPR0 (IPA0L & IPA_IPR)
+#define IPR1 (IPA1L & IPA_IPR)
+#define IPR2 (IPA2L & IPA_IPR)
+#define IPR3 (IPA3L & IPA_IPR)
+
+#define DPA2ADDR(DPA) ((DPA) & 0x1fffff80)
+#define DPA_DPE 0x1
+#define DPA_DPR 0x4
+#define DPA_DPW 0x8
+#define DPE0 (DPA0L & DPA_DPE)
+#define DPE1 (DPA1L & DPA_DPE)
+#define DPE2 (DPA2L & DPA_DPE)
+#define DPE3 (DPA3L & DPA_DPE)
+#define DPR0 (DPA0L & DPA_DPR)
+#define DPR1 (DPA1L & DPA_DPR)
+#define DPR2 (DPA2L & DPA_DPR)
+#define DPR3 (DPA3L & DPA_DPR)
+#define DPW0 (DPA0L & DPA_DPW)
+#define DPW1 (DPA1L & DPA_DPW)
+#define DPW2 (DPA2L & DPA_DPW)
+#define DPW3 (DPA3L & DPA_DPW)
+
+#define DCC_DCE0 0x1
+#define DCC_DCE1 0x10000
+
+#define PPA2ADDR(PPA) ((PPA) & 0x1fffff80)
+#define PPC_PPC 0xfffffffe
+#define PPC_PPE 0x1
+#define PPC_PPM 0x0000fff8
+
+
#define SEXT3(x) ((((x)&0x7)^(~0x3))+0x4)
/* sign-extend a 4-bit number */
@@ -344,6 +565,79 @@ do { \
} \
} while (0)
+#define TRACE_FP_INPUT_FPU1(V0) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ { \
+ unsigned64 f0; \
+ sim_fpu_to64 (&f0, (V0)); \
+ trace_input_fp1 (SD, CPU, TRACE_FPU_IDX, f0); \
+ } \
+} while (0)
+
+#define TRACE_FP_INPUT_FPU2(V0, V1) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ { \
+ unsigned64 f0, f1; \
+ sim_fpu_to64 (&f0, (V0)); \
+ sim_fpu_to64 (&f1, (V1)); \
+ trace_input_fp2 (SD, CPU, TRACE_FPU_IDX, f0, f1); \
+ } \
+} while (0)
+
+#define TRACE_FP_INPUT_FPU3(V0, V1, V2) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ { \
+ unsigned64 f0, f1, f2; \
+ sim_fpu_to64 (&f0, (V0)); \
+ sim_fpu_to64 (&f1, (V1)); \
+ sim_fpu_to64 (&f2, (V2)); \
+ trace_input_fp3 (SD, CPU, TRACE_FPU_IDX, f0, f1, f2); \
+ } \
+} while (0)
+
+#define TRACE_FP_INPUT_BOOL1_FPU2(V0, V1, V2) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ { \
+ int d0 = (V0); \
+ unsigned64 f1, f2; \
+ TRACE_DATA *data = CPU_TRACE_DATA (CPU); \
+ TRACE_IDX (data) = TRACE_FPU_IDX; \
+ sim_fpu_to64 (&f1, (V1)); \
+ sim_fpu_to64 (&f2, (V2)); \
+ save_data (SD, data, trace_fmt_bool, sizeof (d0), &d0); \
+ save_data (SD, data, trace_fmt_fp, sizeof (fp_word), &f1); \
+ save_data (SD, data, trace_fmt_fp, sizeof (fp_word), &f2); \
+ } \
+} while (0)
+
+#define TRACE_FP_INPUT_WORD2(V0, V1) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ trace_input_word2 (SD, CPU, TRACE_FPU_IDX, (V0), (V1)); \
+} while (0)
+
+#define TRACE_FP_RESULT_FPU1(R0) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ { \
+ unsigned64 f0; \
+ sim_fpu_to64 (&f0, (R0)); \
+ trace_result_fp1 (SD, CPU, TRACE_FPU_IDX, f0); \
+ } \
+} while (0)
+
+#define TRACE_FP_RESULT_WORD1(R0) TRACE_FP_RESULT_WORD(R0)
+
+#define TRACE_FP_RESULT_WORD2(R0, R1) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ trace_result_word2 (SD, CPU, TRACE_FPU_IDX, (R0), (R1)); \
+} while (0)
+
#else
#define trace_input(NAME, IN1, IN2)
#define trace_output(RESULT)
diff -upNr gdb-7.2.50-original/sim/v850/simops.c gdb-7.2.50-modified/sim/v850/simops.c
--- gdb-7.2.50-original/sim/v850/simops.c 2008-02-06 10:11:26.000000000 +0530
+++ gdb-7.2.50-modified/sim/v850/simops.c 2011-01-11 18:24:58.000000000 +0530
@@ -320,7 +320,7 @@ condition_met (unsigned code)
return 1;
}
-static unsigned long
+unsigned long
Add32 (unsigned long a1, unsigned long a2, int * carry)
{
unsigned long result = (a1 + a2);
@@ -2761,3 +2761,717 @@ OP_307E0 (void)
return 4;
}
+/* V850E2R FPU functions */
+/*
+ sim_fpu_status_invalid_snan = 1, -V--- (sim spec.)
+ sim_fpu_status_invalid_qnan = 2, ----- (sim spec.)
+ sim_fpu_status_invalid_isi = 4, (inf - inf) -V---
+ sim_fpu_status_invalid_idi = 8, (inf / inf) -V---
+ sim_fpu_status_invalid_zdz = 16, (0 / 0) -V---
+ sim_fpu_status_invalid_imz = 32, (inf * 0) -V---
+ sim_fpu_status_invalid_cvi = 64, convert to integer -V---
+ sim_fpu_status_invalid_div0 = 128, (X / 0) --Z--
+ sim_fpu_status_invalid_cmp = 256, compare ----- (sim spec.)
+ sim_fpu_status_invalid_sqrt = 512, -V---
+ sim_fpu_status_rounded = 1024, I----
+ sim_fpu_status_inexact = 2048, I---- (sim spec.)
+ sim_fpu_status_overflow = 4096, I--O-
+ sim_fpu_status_underflow = 8192, I---U
+ sim_fpu_status_denorm = 16384, ----U (sim spec.)
+*/
+
+void update_fpsr (SIM_DESC sd, sim_fpu_status status, unsigned int mask, unsigned int double_op_p)
+{
+ unsigned int fpsr = FPSR & mask;
+
+ unsigned int flags = 0;
+
+ if (fpsr & FPSR_XEI
+ && ((status & (sim_fpu_status_rounded
+ | sim_fpu_status_overflow
+ | sim_fpu_status_inexact))
+ || (status & sim_fpu_status_underflow
+ && (fpsr & (FPSR_XEU | FPSR_XEI)) == 0
+ && fpsr & FPSR_FS)))
+ {
+ flags |= FPSR_XCI | FPSR_XPI;
+ }
+
+ if (fpsr & FPSR_XEV
+ && (status & (sim_fpu_status_invalid_isi
+ | sim_fpu_status_invalid_imz
+ | sim_fpu_status_invalid_zdz
+ | sim_fpu_status_invalid_idi
+ | sim_fpu_status_invalid_cvi
+ | sim_fpu_status_invalid_sqrt
+ | sim_fpu_status_invalid_snan)))
+ {
+ flags |= FPSR_XCV | FPSR_XPV;
+ }
+
+ if (fpsr & FPSR_XEZ
+ && (status & sim_fpu_status_invalid_div0))
+ {
+ flags |= FPSR_XCV | FPSR_XPV;
+ }
+
+ if (fpsr & FPSR_XEO
+ && (status & sim_fpu_status_overflow))
+ {
+ flags |= FPSR_XCO | FPSR_XPO;
+ }
+
+ if (((fpsr & FPSR_XEU) || (fpsr & FPSR_FS) == 0)
+ && (status & (sim_fpu_status_underflow
+ | sim_fpu_status_denorm)))
+ {
+ flags |= FPSR_XCU | FPSR_XPU;
+ }
+
+ if (flags)
+ {
+ FPSR &= ~FPSR_XC;
+ FPSR |= flags;
+
+ SignalExceptionFPE(sd, double_op_p);
+ }
+}
+
+/*
+ exception
+*/
+
+void SignalException(SIM_DESC sd)
+{
+ if (MPM & MPM_AUE)
+ {
+ PSW = PSW & ~(PSW_NPV | PSW_DMP | PSW_IMP);
+ }
+}
+
+void SignalExceptionFPE(SIM_DESC sd, unsigned int double_op_p)
+{
+ if (((PSW & (PSW_NP|PSW_ID)) == 0)
+ || !(FPSR & (double_op_p ? FPSR_DEM : FPSR_SEM)))
+ {
+ EIPC = PC;
+ EIPSW = PSW;
+ EIIC = (FPSR & (double_op_p ? FPSR_DEM : FPSR_SEM))
+ ? 0x71 : 0x72;
+ PSW |= (PSW_EP | PSW_ID);
+ PC = 0x70;
+
+ SignalException(sd);
+ }
+}
+
+
+void check_invalid_snan(SIM_DESC sd, sim_fpu_status status, unsigned int double_op_p)
+{
+ if ((FPSR & FPSR_XEI)
+ && (status & sim_fpu_status_invalid_snan))
+ {
+ FPSR &= ~FPSR_XC;
+ FPSR |= FPSR_XCV;
+ FPSR |= FPSR_XPV;
+ SignalExceptionFPE(sd, double_op_p);
+ }
+}
+
+int v850_float_compare(SIM_DESC sd, int cmp, sim_fpu wop1, sim_fpu wop2, int double_op_p)
+{
+ int result = -1;
+
+ if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2))
+ {
+ if (cmp & 0x8)
+ {
+ if (FPSR & FPSR_XEV)
+ {
+ FPSR |= FPSR_XCV | FPSR_XPV;
+ SignalExceptionFPE(sd, double_op_p);
+ }
+ }
+
+ switch (cmp)
+ {
+ case FPU_CMP_F:
+ result = 0;
+ break;
+ case FPU_CMP_UN:
+ result = 1;
+ break;
+ case FPU_CMP_EQ:
+ result = 0;
+ break;
+ case FPU_CMP_UEQ:
+ result = 1;
+ break;
+ case FPU_CMP_OLT:
+ result = 0;
+ break;
+ case FPU_CMP_ULT:
+ result = 1;
+ break;
+ case FPU_CMP_OLE:
+ result = 0;
+ break;
+ case FPU_CMP_ULE:
+ result = 1;
+ break;
+ case FPU_CMP_SF:
+ result = 0;
+ break;
+ case FPU_CMP_NGLE:
+ result = 1;
+ break;
+ case FPU_CMP_SEQ:
+ result = 0;
+ break;
+ case FPU_CMP_NGL:
+ result = 1;
+ break;
+ case FPU_CMP_LT:
+ result = 0;
+ break;
+ case FPU_CMP_NGE:
+ result = 1;
+ break;
+ case FPU_CMP_LE:
+ result = 0;
+ break;
+ case FPU_CMP_NGT:
+ result = 1;
+ break;
+ default:
+ abort();
+ }
+ }
+ else if (sim_fpu_is_infinity(&wop1) && sim_fpu_is_infinity(&wop2)
+ && sim_fpu_sign(&wop1) == sim_fpu_sign(&wop2))
+ {
+ switch (cmp)
+ {
+ case FPU_CMP_F:
+ result = 0;
+ break;
+ case FPU_CMP_UN:
+ result = 0;
+ break;
+ case FPU_CMP_EQ:
+ result = 1;
+ break;
+ case FPU_CMP_UEQ:
+ result = 1;
+ break;
+ case FPU_CMP_OLT:
+ result = 0;
+ break;
+ case FPU_CMP_ULT:
+ result = 0;
+ break;
+ case FPU_CMP_OLE:
+ result = 1;
+ break;
+ case FPU_CMP_ULE:
+ result = 1;
+ break;
+ case FPU_CMP_SF:
+ result = 0;
+ break;
+ case FPU_CMP_NGLE:
+ result = 0;
+ break;
+ case FPU_CMP_SEQ:
+ result = 1;
+ break;
+ case FPU_CMP_NGL:
+ result = 1;
+ break;
+ case FPU_CMP_LT:
+ result = 0;
+ break;
+ case FPU_CMP_NGE:
+ result = 0;
+ break;
+ case FPU_CMP_LE:
+ result = 1;
+ break;
+ case FPU_CMP_NGT:
+ result = 1;
+ break;
+ default:
+ abort();
+ }
+ }
+ else
+ {
+ int gt = 0,lt = 0,eq = 0, status;
+
+ status = sim_fpu_cmp( &wop1, &wop2 );
+
+ switch (status) {
+ case SIM_FPU_IS_SNAN:
+ case SIM_FPU_IS_QNAN:
+ abort();
+ break;
+
+ case SIM_FPU_IS_NINF:
+ lt = 1;
+ break;
+ case SIM_FPU_IS_PINF:
+ gt = 1;
+ break;
+ case SIM_FPU_IS_NNUMBER:
+ lt = 1;
+ break;
+ case SIM_FPU_IS_PNUMBER:
+ gt = 1;
+ break;
+ case SIM_FPU_IS_NDENORM:
+ lt = 1;
+ break;
+ case SIM_FPU_IS_PDENORM:
+ gt = 1;
+ break;
+ case SIM_FPU_IS_NZERO:
+ case SIM_FPU_IS_PZERO:
+ eq = 1;
+ break;
+ }
+
+ switch (cmp)
+ {
+ case FPU_CMP_F:
+ result = 0;
+ break;
+ case FPU_CMP_UN:
+ result = 0;
+ break;
+ case FPU_CMP_EQ:
+ result = eq;
+ break;
+ case FPU_CMP_UEQ:
+ result = eq;
+ break;
+ case FPU_CMP_OLT:
+ result = lt;
+ break;
+ case FPU_CMP_ULT:
+ result = lt;
+ break;
+ case FPU_CMP_OLE:
+ result = lt || eq;
+ break;
+ case FPU_CMP_ULE:
+ result = lt || eq;
+ break;
+ case FPU_CMP_SF:
+ result = 0;
+ break;
+ case FPU_CMP_NGLE:
+ result = 0;
+ break;
+ case FPU_CMP_SEQ:
+ result = eq;
+ break;
+ case FPU_CMP_NGL:
+ result = eq;
+ break;
+ case FPU_CMP_LT:
+ result = lt;
+ break;
+ case FPU_CMP_NGE:
+ result = lt;
+ break;
+ case FPU_CMP_LE:
+ result = lt || eq;
+ break;
+ case FPU_CMP_NGT:
+ result = lt || eq;
+ break;
+ }
+ }
+
+ ASSERT(result != -1);
+ return result;
+}
+
+void v850_div(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p, unsigned int *op3p)
+{
+ signed long int quotient;
+ signed long int remainder;
+ signed long int divide_by;
+ signed long int divide_this;
+ bfd_boolean overflow = FALSE;
+
+ /* Compute the result. */
+ divide_by = op0;
+ divide_this = op1;
+
+ if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31)))
+ {
+ overflow = TRUE;
+ divide_by = 1;
+ }
+
+ quotient = divide_this / divide_by;
+ remainder = divide_this % divide_by;
+
+ /* Set condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_OV);
+
+ if (overflow) PSW |= PSW_OV;
+ if (quotient == 0) PSW |= PSW_Z;
+ if (quotient < 0) PSW |= PSW_S;
+
+ *op2p = quotient;
+ *op3p = remainder;
+}
+
+void v850_divu(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p, unsigned int *op3p)
+{
+ unsigned long int quotient;
+ unsigned long int remainder;
+ unsigned long int divide_by;
+ unsigned long int divide_this;
+ bfd_boolean overflow = FALSE;
+
+ /* Compute the result. */
+
+ divide_by = op0;
+ divide_this = op1;
+
+ if (divide_by == 0)
+ {
+ overflow = TRUE;
+ divide_by = 1;
+ }
+
+ quotient = divide_this / divide_by;
+ remainder = divide_this % divide_by;
+
+ /* Set condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_OV);
+
+ if (overflow) PSW |= PSW_OV;
+ if (quotient == 0) PSW |= PSW_Z;
+ if (quotient & 0x80000000) PSW |= PSW_S;
+
+ *op2p = quotient;
+ *op3p = remainder;
+}
+
+
+void v850_sar(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
+{
+ unsigned int result, z, s, cy;
+
+ op0 &= 0x1f;
+ result = (signed)op1 >> op0;
+
+ /* Compute the condition codes. */
+ z = (result == 0);
+ s = (result & 0x80000000);
+ cy = (op1 & (1 << (op0 - 1)));
+
+ /* Store the result and condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
+ PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+ | (cy ? PSW_CY : 0));
+
+ *op2p = result;
+}
+
+void v850_shl(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
+{
+ unsigned int result, z, s, cy;
+
+ op0 &= 0x1f;
+ result = op1 << op0;
+
+ /* Compute the condition codes. */
+ z = (result == 0);
+ s = (result & 0x80000000);
+ cy = (op1 & (1 << (32 - op0)));
+
+ /* Store the result and condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
+ PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+ | (cy ? PSW_CY : 0));
+
+ *op2p = result;
+}
+
+void v850_shr(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
+{
+ unsigned int result, z, s, cy;
+
+ op0 &= 0x1f;
+ result = op1 >> op0;
+
+ /* Compute the condition codes. */
+ z = (result == 0);
+ s = (result & 0x80000000);
+ cy = (op1 & (1 << (op0 - 1)));
+
+ /* Store the result and condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
+ PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+ | (cy ? PSW_CY : 0));
+
+ *op2p = result;
+}
+
+void v850_satadd(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
+{
+ unsigned int result, z, s, cy, ov, sat;
+
+ result = op0 + op1;
+
+ /* Compute the condition codes. */
+ z = (result == 0);
+ s = (result & 0x80000000);
+ cy = (result < op0 || result < op1);
+ ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
+ && (op0 & 0x80000000) != (result & 0x80000000));
+ sat = ov;
+
+ /* Store the result and condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+ PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+ | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
+ | (sat ? PSW_SAT : 0));
+
+ /* Handle saturated results. */
+ if (sat && s)
+ {
+ result = 0x7fffffff;
+ PSW &= ~PSW_S;
+ }
+ else if (sat)
+ {
+ result = 0x80000000;
+ PSW |= PSW_S;
+ }
+
+ *op2p = result;
+}
+
+void v850_satsub(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
+{
+ unsigned int result, z, s, cy, ov, sat;
+
+ /* Compute the result. */
+ result = op1 - op0;
+
+ /* Compute the condition codes. */
+ z = (result == 0);
+ s = (result & 0x80000000);
+ cy = (op1 < op0);
+ ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
+ && (op1 & 0x80000000) != (result & 0x80000000));
+ sat = ov;
+
+ /* Store the result and condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+ PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+ | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
+ | (sat ? PSW_SAT : 0));
+
+ /* Handle saturated results. */
+ if (sat && s)
+ {
+ result = 0x7fffffff;
+ PSW &= ~PSW_S;
+ }
+ else if (sat)
+ {
+ result = 0x80000000;
+ PSW |= PSW_S;
+ }
+
+ *op2p = result;
+}
+
+unsigned32
+load_data_mem(sd, addr, len)
+ SIM_DESC sd;
+ SIM_ADDR addr;
+ int len;
+{
+ uint32 data;
+
+ switch (len)
+ {
+ case 1:
+ data = sim_core_read_unaligned_1 (STATE_CPU (sd, 0),
+ PC, read_map, addr);
+ break;
+ case 2:
+ data = sim_core_read_unaligned_2 (STATE_CPU (sd, 0),
+ PC, read_map, addr);
+ break;
+ case 4:
+ data = sim_core_read_unaligned_4 (STATE_CPU (sd, 0),
+ PC, read_map, addr);
+ break;
+ default:
+ abort ();
+ }
+ return data;
+}
+
+void
+store_data_mem(sd, addr, len, data)
+ SIM_DESC sd;
+ SIM_ADDR addr;
+ int len;
+ unsigned32 data;
+{
+ switch (len)
+ {
+ case 1:
+ store_mem(addr, 1, data);
+ break;
+ case 2:
+ store_mem(addr, 2, data);
+ break;
+ case 4:
+ store_mem(addr, 4, data);
+ break;
+ default:
+ abort ();
+ }
+}
+
+int mpu_load_mem_test(SIM_DESC sd, unsigned int addr, int size, int base_reg)
+{
+ int result = 1;
+
+ if (PSW & PSW_DMP)
+ {
+ if (IPE0 && addr >= IPA2ADDR(IPA0L) && addr <= IPA2ADDR(IPA0L) && IPR0)
+ {
+ /* text area */
+ }
+ else if (IPE1 && addr >= IPA2ADDR(IPA1L) && addr <= IPA2ADDR(IPA1L) && IPR1)
+ {
+ /* text area */
+ }
+ else if (IPE2 && addr >= IPA2ADDR(IPA2L) && addr <= IPA2ADDR(IPA2L) && IPR2)
+ {
+ /* text area */
+ }
+ else if (IPE3 && addr >= IPA2ADDR(IPA3L) && addr <= IPA2ADDR(IPA3L) && IPR3)
+ {
+ /* text area */
+ }
+ else if (addr >= PPA2ADDR(PPA & ~PPM) && addr <= DPA2ADDR(PPA | PPM))
+ {
+ /* preifarallel area */
+ }
+ else if (addr >= PPA2ADDR(SPAL) && addr <= DPA2ADDR(SPAU))
+ {
+ /* stack area */
+ }
+ else if (DPE0 && addr >= DPA2ADDR(DPA0L) && addr <= DPA2ADDR(DPA0L) && DPR0
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else if (DPE1 && addr >= DPA2ADDR(DPA1L) && addr <= DPA2ADDR(DPA1L) && DPR1
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else if (DPE2 && addr >= DPA2ADDR(DPA2L) && addr <= DPA2ADDR(DPA2L) && DPR2
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else if (DPE3 && addr >= DPA2ADDR(DPA3L) && addr <= DPA2ADDR(DPA3L) && DPR3
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else
+ {
+ VMECR &= ~(VMECR_VMW | VMECR_VMX);
+ VMECR |= VMECR_VMR;
+ VMADR = addr;
+ VMTID = TID;
+ FEIC = 0x431;
+
+ PC = 0x30;
+
+ SignalException(sd);
+ result = 0;
+ }
+ }
+
+ return result;
+}
+
+int mpu_store_mem_test(SIM_DESC sd, unsigned int addr, int size, int base_reg)
+{
+ int result = 1;
+
+ if (PSW & PSW_DMP)
+ {
+ if (addr >= PPA2ADDR(PPA & ~PPM) && addr <= DPA2ADDR(PPA | PPM))
+ {
+ /* preifarallel area */
+ }
+ else if (addr >= PPA2ADDR(SPAL) && addr <= DPA2ADDR(SPAU))
+ {
+ /* stack area */
+ }
+ else if (DPE0 && addr >= DPA2ADDR(DPA0L) && addr <= DPA2ADDR(DPA0L) && DPW0
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else if (DPE1 && addr >= DPA2ADDR(DPA1L) && addr <= DPA2ADDR(DPA1L) && DPW1
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else if (DPE2 && addr >= DPA2ADDR(DPA2L) && addr <= DPA2ADDR(DPA2L) && DPW2
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else if (DPE3 && addr >= DPA2ADDR(DPA3L) && addr <= DPA2ADDR(DPA3L) && DPW3
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else
+ {
+ if (addr >= PPA2ADDR(PPA & ~PPM) && addr <= DPA2ADDR(PPA | PPM))
+ {
+ FEIC = 0x432;
+ VPTID = TID;
+ VPADR = PC;
+#ifdef NOT_YET
+ VIP_PP;
+ VPECR;
+#endif
+ }
+ else
+ {
+ FEIC = 0x431;
+ VMTID = TID;
+ VMADR = VMECR;
+ VMECR &= ~(VMECR_VMW | VMECR_VMX);
+ VMECR |= VMECR_VMR;
+ PC = 0x30;
+ }
+ result = 0;
+ }
+ }
+
+ return result;
+}
+
diff -upNr gdb-7.2.50-original/sim/v850/simops.h gdb-7.2.50-modified/sim/v850/simops.h
--- gdb-7.2.50-original/sim/v850/simops.h 2003-04-06 14:21:04.000000000 +0530
+++ gdb-7.2.50-modified/sim/v850/simops.h 2011-01-11 18:24:58.000000000 +0530
@@ -75,4 +75,51 @@ int OP_22007E0 (void);
int OP_307F0 (void);
int OP_107F0 (void);
int OP_307E0 (void);
+
+int v850_float_compare(SIM_DESC sd, int cmp, sim_fpu wop1, sim_fpu wop2, int double_op_p);
+
+/* MEMORY ACCESS */
+unsigned32 load_data_mem(SIM_DESC sd, SIM_ADDR addr, int len);
+void store_data_mem(SIM_DESC sd, SIM_ADDR addr, int len, unsigned32 data);
+
+unsigned long Add32 (unsigned long a1, unsigned long a2, int * carry);
+
+/* FPU */
+
+/*
+ FPU: update FPSR flags
+ invalid, inexact, overflow, underflow
+ */
+
+extern void check_invalid_snan (SIM_DESC sd, sim_fpu_status, unsigned int);
+
+#define check_cvt_fi(sd, status, double_op_p) \
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI, double_op_p)
+
+#define check_cvt_if(sd, status, double_op_p) \
+ update_fpsr (sd, status, FPSR_XEI, double_op_p)
+
+#define check_cvt_ff(sd, status, double_op_p) \
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, double_op_p)
+
+extern void update_fpsr (SIM_DESC sd, sim_fpu_status, unsigned int, unsigned int);
+
+
+/*
+ Exception
+ */
+void SignalException (SIM_DESC sd);
+void SignalExceptionFPE (SIM_DESC sd, unsigned int double_op_p);
+
+int mpu_load_mem_test (SIM_DESC sd, unsigned int addr, int len, int base_reg);
+int mpu_store_mem_test (SIM_DESC sd, unsigned int addr, int len, int base_reg);
+
+void v850_sar (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p);
+void v850_shl (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p);
+void v850_shr (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p);
+void v850_satadd (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p);
+void v850_satsub (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p);
+void v850_div (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p, unsigned int *op3p);
+void v850_divu (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p, unsigned int *op3p);
+
#endif
diff -upNr gdb-7.2.50-original/sim/v850/v850-dc gdb-7.2.50-modified/sim/v850/v850-dc
--- gdb-7.2.50-original/sim/v850/v850-dc 2003-09-05 23:16:52.000000000 +0530
+++ gdb-7.2.50-modified/sim/v850/v850-dc 2011-01-11 18:24:58.000000000 +0530
@@ -12,7 +12,9 @@
switch,combine : 4 : 0 : : : : 1 : V,VII :
switch,combine : 4 : 0 : : : : 1 : V,XIII : v850e
switch,combine : 4 : 0 : : : : 1 : V,XIII : v850e1
-
+ switch,combine : 4 : 0 : : : : 1 : V,XIII : v850e2
+ switch,combine : 4 : 0 : : : : 1 : V,XIII : v850e2v3
+ switch,combine : 10 : 5 : : : : 0 : F_I : v850e2v3
# for opcode 63, 127, 1087 et.al.
@@ -27,3 +29,28 @@
# for opcode 66 - divh/break
switch,combine : 4 : 0 : : : : 0 : I :
+
+# for ilgop, macu
+ switch,combine : 10 : 9 : : : : 1 : X,XI : v850e2
+ switch,combine : 10 : 9 : : : : 1 : X,XI : v850e2v3
+
+#for cmovf.s, setf
+ switch,combine : 10 : 10 : : : : 1 :F_I,IX : v850e2v3
+
+# for cmovf.s trfsr
+ switch,combine : 15 : 11 : : : : 1 :F_I : v850e2v3
+
+# for trncf.sw, cvtf.sw
+ switch,combine : 0 : 0 : : : : 0 :F_I : v850e2v3
+ switch,combine : 3 : 3 : : : : 0 :F_I : v850e2v3
+
+# for rsqrtf.s, sqrtf.s
+ switch,combine : 1 : 1 : : : : 0 :F_I : v850e2v3
+
+# for maddf.s, trap
+ switch,combine : 8 : 8 : : : : 1 :F_I,X : v850e2v3
+ switch,combine : 10 : 10 : : : : 1 :F_I,X : v850e2v3
+
+# for jr32 jarl32
+ switch,combine : 4 : 0 : : : : 0 :VI : v850e2
+ switch,combine : 4 : 0 : : : : 0 :VI : v850e2v3
diff -upNr gdb-7.2.50-original/sim/v850/v850.igen gdb-7.2.50-modified/sim/v850/v850.igen
--- gdb-7.2.50-original/sim/v850/v850.igen 2008-02-06 10:11:26.000000000 +0530
+++ gdb-7.2.50-modified/sim/v850/v850.igen 2011-01-11 18:24:58.000000000 +0530
@@ -6,6 +6,7 @@
:option:::format-names:XI,XII,XIII
:option:::format-names:XIV,XV
:option:::format-names:Z
+:option:::format-names:F_I
:model:::v850:v850:
@@ -14,12 +15,22 @@
:model:::v850e:v850e:
:option:::multi-sim:true
:model:::v850e1:v850e1:
+:option:::multi-sim:true
+:model:::v850e2:v850e2:
+:option:::multi-sim:true
+:model:::v850e2v3:v850e2v3:
// Cache macros
:cache:::unsigned:reg1:RRRRR:(RRRRR)
:cache:::unsigned:reg2:rrrrr:(rrrrr)
:cache:::unsigned:reg3:wwwww:(wwwww)
+:cache:::unsigned:reg4:W,WWWW:((W << 4) + WWWW)
+
+:cache:::unsigned:reg1e:RRRR:(RRRR << 1)
+:cache:::unsigned:reg2e:rrrr:(rrrr << 1)
+:cache:::unsigned:reg3e:wwww:(wwww << 1)
+:cache:::unsigned:reg4e:mmmm:(mmmm << 1)
:cache:::unsigned:disp4:dddd:(dddd)
:cache:::unsigned:disp5:dddd:(dddd << 1)
@@ -29,7 +40,10 @@
:cache:::unsigned:disp9:ddddd,ddd:SEXT32 ((ddddd << 4) + (ddd << 1), 9 - 1)
:cache:::unsigned:disp16:dddddddddddddddd:EXTEND16 (dddddddddddddddd)
:cache:::unsigned:disp16:ddddddddddddddd: EXTEND16 (ddddddddddddddd << 1)
+:cache:::unsigned:disp17:d,ddddddddddddddd:SEXT32 (((d <<16) + (ddddddddddddddd << 1)), 17 - 1)
:cache:::unsigned:disp22:dddddd,ddddddddddddddd: SEXT32 ((dddddd << 16) + (ddddddddddddddd << 1), 22 - 1)
+:cache:::unsigned:disp23:ddddddd,dddddddddddddddd: SEXT32 ((ddddddd) + (dddddddddddddddd << 7), 23 - 1)
+:cache:::unsigned:disp23:dddddd,dddddddddddddddd: SEXT32 ((dddddd << 1) + (dddddddddddddddd << 7), 23 - 1)
:cache:::unsigned:imm5:iiiii:SEXT32 (iiiii, 4)
:cache:::unsigned:imm6:iiiiii:iiiiii
@@ -46,6 +60,7 @@
:cache:::unsigned:list18:LLLL,LLLLLLLLLLLL:((LLLL << 12) + LLLLLLLLLLLL)
:cache:::unsigned:bit3:bbb:bbb
+:cache:::unsigned:bit4:bbbb:bbbb
// What do we do with an illegal instruction?
@@ -58,8 +73,7 @@
-// Add
-
+// ADD
rrrrr,001110,RRRRR:I:::add
"add r<reg1>, r<reg2>"
{
@@ -83,6 +97,20 @@ rrrrr,110000,RRRRR + iiiiiiiiiiiiiiii:VI
+// ADF
+rrrrr,111111,RRRRR + wwwww,011101,cccc!13,0:XI:::adf
+*v850e2
+*v850e2v3
+"adf %s<cccc>, r<reg1>, r<reg2>, r<reg3>"
+{
+ int cond = condition_met (cccc);
+ TRACE_ALU_INPUT3 (cond, GR[reg1], GR[reg2]);
+ GR[reg3] = GR[reg1] + GR[reg2] + (cond ? 1 : 0);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+
+
// AND
rrrrr,001010,RRRRR:I:::and
"and r<reg1>, r<reg2>"
@@ -153,12 +181,27 @@ ddddd,1011,ddd,cccc:III:::Bcond
}
}
+00000111111,d,cccc + ddddddddddddddd,1:VII:::Bcond
+"breakpoint":((disp17 == 0) && (cccc == 0x05))
+"b%s<cccc> <disp17>"
+*v850e2v3
+{
+ int cond;
+ cond = condition_met (cccc);
+ if (cond)
+ nia = cia + disp17;
+ TRACE_BRANCH_INPUT1 (cond);
+ TRACE_BRANCH_RESULT (nia);
+}
+
// BSH
rrrrr,11111100000 + wwwww,01101000010:XII:::bsh
*v850e
*v850e1
+*v850e2
+*v850e2v3
"bsh r<reg2>, r<reg3>"
{
unsigned32 value;
@@ -178,10 +221,14 @@ rrrrr,11111100000 + wwwww,01101000010:XI
TRACE_ALU_RESULT (GR[reg3]);
}
+
+
// BSW
rrrrr,11111100000 + wwwww,01101000000:XII:::bsw
*v850e
*v850e1
+*v850e2
+*v850e2v3
"bsw r<reg2>, r<reg3>"
{
#define WORDHASNULLBYTE(x) (((x) - 0x01010101) & ~(x)&0x80808080)
@@ -204,10 +251,14 @@ rrrrr,11111100000 + wwwww,01101000000:XI
TRACE_ALU_RESULT (GR[reg3]);
}
+
+
// CALLT
0000001000,iiiiii:II:::callt
*v850e
*v850e1
+*v850e2
+*v850e2v3
"callt <imm6>"
{
unsigned32 adr;
@@ -221,6 +272,55 @@ rrrrr,11111100000 + wwwww,01101000000:XI
}
+
+// CAXI
+rrrrr,111111,RRRRR + wwwww,00011101110:IX:::caxi
+*v850e2
+*v850e2v3
+"caxi [reg1], reg2, reg3"
+{
+ unsigned int z,s,cy,ov;
+ unsigned32 addr;
+ unsigned32 token,result;
+
+ addr = GR[reg1];
+
+ if (mpu_load_mem_test(sd, addr, 4, reg1)
+ && mpu_store_mem_test(sd, addr, 4, reg1))
+ {
+ token = load_data_mem (sd, addr, 4);
+
+ TRACE_ALU_INPUT2 (token, GR[reg2]);
+
+ result = GR[reg2] - token;
+
+ z = (result == 0);
+ s = (result & 0x80000000);
+ cy = (GR[reg2] < token);
+ ov = ((GR[reg2] & 0x80000000) != (token & 0x80000000)
+ && (GR[reg2] & 0x80000000) != (result & 0x80000000));
+
+ if (result == 0)
+ {
+ store_data_mem (sd, addr, 4, GR[reg3]);
+ GR[reg3] = token;
+ }
+ else
+ {
+ store_data_mem (sd, addr, 4, token);
+ GR[reg3] = token;
+ }
+
+ /* Set condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+ PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+ | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
+
+ TRACE_ALU_RESULT1 (GR[reg3]);
+ }
+}
+
+
// CLR1
10,bbb,111110,RRRRR + dddddddddddddddd:VIII:::clr1
"clr1 <bit3>, <disp16>[r<reg1>]"
@@ -231,16 +331,21 @@ rrrrr,11111100000 + wwwww,01101000000:XI
rrrrr,111111,RRRRR + 0000000011100100:IX:::clr1
*v850e
*v850e1
+*v850e2
+*v850e2v3
"clr1 r<reg2>, [r<reg1>]"
{
COMPAT_2 (OP_E407E0 ());
}
+
// CTRET
0000011111100000 + 0000000101000100:X:::ctret
*v850e
*v850e1
+*v850e2
+*v850e2v3
"ctret"
{
nia = (CTPC & ~1);
@@ -248,10 +353,14 @@ rrrrr,111111,RRRRR + 0000000011100100:IX
TRACE_BRANCH1 (PSW);
}
+
+
// CMOV
rrrrr,111111,RRRRR + wwwww,011001,cccc,0:XI:::cmov
*v850e
*v850e1
+*v850e2
+*v850e2v3
"cmov %s<cccc>, r<reg1>, r<reg2>, r<reg3>"
{
int cond = condition_met (cccc);
@@ -263,6 +372,8 @@ rrrrr,111111,RRRRR + wwwww,011001,cccc,0
rrrrr,111111,iiiii + wwwww,011000,cccc,0:XII:::cmov
*v850e
*v850e1
+*v850e2
+*v850e2v3
"cmov %s<cccc>, <imm5>, r<reg2>, r<reg3>"
{
int cond = condition_met (cccc);
@@ -271,6 +382,8 @@ rrrrr,111111,iiiii + wwwww,011000,cccc,0
TRACE_ALU_RESULT (GR[reg3]);
}
+
+
// CMP
rrrrr,001111,RRRRR:I:::cmp
"cmp r<reg1>, r<reg2>"
@@ -301,6 +414,8 @@ rrrrr,010011,iiiii:II:::cmp
0000011001,iiiii,L + LLLLLLLLLLL,RRRRR:XIII:::dispose
*v850e
*v850e1
+*v850e2
+*v850e2v3
"dispose <imm5>, <list12>":RRRRR == 0
"dispose <imm5>, <list12>, [reg1]"
{
@@ -329,10 +444,13 @@ rrrrr,010011,iiiii:II:::cmp
}
+
// DIV
rrrrr,111111,RRRRR + wwwww,01011000000:XI:::div
*v850e
*v850e1
+*v850e2
+*v850e2v3
"div r<reg1>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_2C007E0 ());
@@ -390,6 +508,8 @@ rrrrr!0,000010,RRRRR!0:I:::divh
rrrrr,111111,RRRRR + wwwww,01010000000:XI:::divh
*v850e
*v850e1
+*v850e2
+*v850e2v3
"divh r<reg1>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_28007E0 ());
@@ -400,6 +520,8 @@ rrrrr,111111,RRRRR + wwwww,01010000000:X
rrrrr,111111,RRRRR + wwwww,01010000010:XI:::divhu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"divhu r<reg1>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_28207E0 ());
@@ -410,12 +532,60 @@ rrrrr,111111,RRRRR + wwwww,01010000010:X
rrrrr,111111,RRRRR + wwwww,01011000010:XI:::divu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"divu r<reg1>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_2C207E0 ());
}
+// DIVQ
+rrrrr,111111,RRRRR + wwwww,01011111100:XI:::divq
+*v850e2
+*v850e2v3
+"divq r<reg1>, r<reg2>, r<reg3>"
+{
+ unsigned int quotient;
+ unsigned int remainder;
+ unsigned int divide_by;
+ unsigned int divide_this;
+
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+
+ divide_by = GR[reg1];
+ divide_this = GR[reg2];
+ v850_div (sd, divide_by, divide_this, "ient, &remainder);
+ GR[reg2] = quotient;
+ GR[reg3] = remainder;
+
+ TRACE_ALU_RESULT2 (GR[reg2], GR[reg3]);
+}
+
+
+// DIVQU
+rrrrr,111111,RRRRR + wwwww,01011111110:XI:::divqu
+*v850e2
+*v850e2v3
+"divq r<reg1>, r<reg2>, r<reg3>"
+{
+ unsigned int quotient;
+ unsigned int remainder;
+ unsigned int divide_by;
+ unsigned int divide_this;
+
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+
+ divide_by = GR[reg1];
+ divide_this = GR[reg2];
+ v850_divu (sd, divide_by, divide_this, "ient, &remainder);
+ GR[reg2] = quotient;
+ GR[reg3] = remainder;
+
+ TRACE_ALU_RESULT2 (GR[reg2], GR[reg3]);
+}
+
+
// EI
1000011111100000 + 0000000101100000:X:::ei
"ei"
@@ -425,6 +595,76 @@ rrrrr,111111,RRRRR + wwwww,01011000010:X
+// EIRET
+0000011111100000 + 0000000101001000:X:::eiret
+"eiret"
+*v850e2
+*v850e2v3
+{
+ TRACE_ALU_INPUT1 (MPM & MPM_AUE);
+
+ nia = EIPC; /* next PC */
+ if (MPM & MPM_AUE)
+ {
+ PSW = EIPSW;
+ }
+ else
+ {
+ PSW = (PSW & (PSW_NPV | PSW_DMP | PSW_IMP))
+ | (EIPSW & ~(PSW_NPV | PSW_DMP | PSW_IMP));
+ }
+
+ TRACE_ALU_RESULT1 (PSW);
+ TRACE_BRANCH_RESULT (nia);
+}
+
+
+
+// FERET
+0000011111100000 + 0000000101001010:X:::feret
+"feret"
+*v850e2
+*v850e2v3
+{
+ TRACE_ALU_INPUT1 (MPM & MPM_AUE);
+
+ nia = FEPC; /* next PC */
+ if (MPM & MPM_AUE)
+ {
+ PSW = FEPSW;
+ }
+ else
+ {
+ PSW = (PSW & (PSW_NPV | PSW_DMP | PSW_IMP))
+ | (FEPSW & ~(PSW_NPV | PSW_DMP | PSW_IMP));
+ }
+
+ TRACE_ALU_RESULT1 (PSW);
+ TRACE_BRANCH_RESULT (nia);
+}
+
+
+// FETRAP
+0,bbbb!0,00001000000:I:::fetrap
+"fetrap"
+*v850e2
+*v850e2v3
+{
+ TRACE_ALU_INPUT0 ();
+
+ FEPC = PC + 2;
+ FEPSW = PSW;
+ ECR &= ~ECR_FECC;
+ ECR |= (0x30 + bit4) << 16;
+ FEIC = 0x30 + bit4;
+ PSW |= PSW_EP | PSW_ID | PSW_NP;
+ nia = 0x30; /* next PC */
+
+ TRACE_ALU_RESULT1 (PSW);
+ TRACE_BRANCH_RESULT (nia);
+}
+
+
// HALT
0000011111100000 + 0000000100100000:X:::halt
"halt"
@@ -434,10 +674,33 @@ rrrrr,111111,RRRRR + wwwww,01011000010:X
+// HSH
+rrrrr,11111100000 + wwwww,01101000110:XII:::hsh
+*v850e2
+*v850e2v3
+"hsh r<reg2>, r<reg3>"
+{
+ unsigned32 value;
+ TRACE_ALU_INPUT1 (GR[reg2]);
+
+ value = 0xffff & GR[reg2];
+ GR[reg3] = GR[reg2];
+
+ PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+
+ if (value == 0) { PSW |= PSW_Z; PSW |= PSW_CY; }
+ if (value & 0x80000000) PSW |= PSW_S;
+
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+
// HSW
rrrrr,11111100000 + wwwww,01101000100:XII:::hsw
*v850e
*v850e1
+*v850e2
+*v850e2v3
"hsw r<reg2>, r<reg3>"
{
unsigned32 value;
@@ -469,6 +732,16 @@ rrrrr!0,11110,dddddd + ddddddddddddddd,0
TRACE_BRANCH1 (GR[reg2]);
}
+00000010111,RRRRR!0 + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::jarl32
+*v850e2
+*v850e2v3
+"jarl <imm32>, r<reg1>"
+{
+ GR[reg1] = nia;
+ nia = (cia + imm32) & ~1;
+
+ TRACE_BRANCH_RESULT (nia);
+}
// JMP
@@ -479,6 +752,15 @@ rrrrr!0,11110,dddddd + ddddddddddddddd,0
TRACE_BRANCH0 ();
}
+00000110111,RRRRR + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::jmp32
+*v850e2
+*v850e2v3
+"jmp <imm32>[r<reg1>]"
+{
+ nia = (GR[reg1] + imm32) & ~1;
+
+ TRACE_BRANCH_RESULT (nia);
+}
// JR
@@ -490,6 +772,17 @@ rrrrr!0,11110,dddddd + ddddddddddddddd,0
}
+// JR32
+00000010111,00000 + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::jr32
+*v850e2
+*v850e2v3
+"jr <imm32>"
+{
+ nia = (cia + imm32) & ~1;
+
+ TRACE_BRANCH_RESULT (nia);
+}
+
// LD
rrrrr,111000,RRRRR + dddddddddddddddd:VII:::ld.b
@@ -498,47 +791,368 @@ rrrrr,111000,RRRRR + dddddddddddddddd:VI
COMPAT_2 (OP_700 ());
}
+00000111100,RRRRR+wwwww,ddddddd,0101+dddddddddddddddd:XIV:::ld.b
+"ld.b <disp23>[r<reg1>], r<reg3>"
+*v850e2v3
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ unsigned32 result = EXTEND8 (load_data_mem (sd, addr, 1));
+ GR[reg3] = result;
+ TRACE_LD (addr, result);
+}
+
rrrrr,111001,RRRRR + ddddddddddddddd,0:VII:::ld.h
"ld.h <disp16>[r<reg1>], r<reg2>"
{
COMPAT_2 (OP_720 ());
}
+00000111100,RRRRR+wwwww,dddddd,00111+dddddddddddddddd:XIV:::ld.h
+*v850e2v3
+"ld.h <disp23>[r<reg1>], r<reg3>"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ unsigned32 result = EXTEND16 (load_data_mem (sd, addr, 2));
+ GR[reg3] = result;
+ TRACE_LD (addr, result);
+}
+
rrrrr,111001,RRRRR + ddddddddddddddd,1:VII:::ld.w
"ld.w <disp16>[r<reg1>], r<reg2>"
{
COMPAT_2 (OP_10720 ());
}
+00000111100,RRRRR+wwwww,dddddd,01001+dddddddddddddddd:XIV:::ld.w
+*v850e2v3
+"ld.w <disp23>[r<reg1>], r<reg3>"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ unsigned32 result = load_data_mem (sd, addr, 4);
+ GR[reg3] = result;
+ TRACE_LD (addr, result);
+}
+
rrrrr!0,11110,b,RRRRR + ddddddddddddddd,1:VII:::ld.bu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"ld.bu <disp16>[r<reg1>], r<reg2>"
{
COMPAT_2 (OP_10780 ());
}
+00000111101,RRRRR+wwwww,ddddddd,0101+dddddddddddddddd:XIV:::ld.bu
+*v850e2v3
+"ld.bu <disp23>[r<reg1>], r<reg3>"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ unsigned32 result = load_data_mem (sd, addr, 1);
+ GR[reg3] = result;
+ TRACE_LD (addr, result);
+}
+
rrrrr!0,111111,RRRRR + ddddddddddddddd,1:VII:::ld.hu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"ld.hu <disp16>[r<reg1>], r<reg2>"
{
COMPAT_2 (OP_107E0 ());
}
+00000111101,RRRRR+wwwww,dddddd,00111+dddddddddddddddd:XIV:::ld.hu
+*v850e2v3
+"ld.hu <disp23>[r<reg1>], r<reg3>"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ unsigned32 result = load_data_mem (sd, addr, 2);
+ GR[reg3] = result;
+ TRACE_LD (addr, result);
+}
+
+
// LDSR
regID,111111,RRRRR + 0000000000100000:IX:::ldsr
"ldsr r<reg1>, s<regID>"
{
+ uint32 sreg = GR[reg1];
TRACE_ALU_INPUT1 (GR[reg1]);
- if (&PSW == &SR[regID])
- PSW = (GR[reg1] & (CPU)->psw_mask);
+ if ((idecode_issue == idecode_v850e2_issue
+ || idecode_issue == idecode_v850e2v3_issue)
+ && regID < 28)
+ {
+ int protect_p = (PSW & PSW_NPV) ? 1 : 0;
+
+
+ switch (BSEL & 0xffff)
+ {
+ case 0x0000:
+ if ((PSW & PSW_NPV)
+ && ((regID >= 8 && regID <= 12)
+ || (regID >= 22 && regID <= 27)
+ || regID == PSW_REGNO))
+ {
+ protect_p = 0;
+ }
+ break;
+ case 0x1000: /* MPU0 */
+ break;
+ case 0x1001: /* MPU1 */
+ break;
+ case 0x2000: /* FPU */
+ if ((PSW & PSW_NPV)
+ && ((/* regID >= 0 && */ regID <= 5)
+ || regID == 8
+ || regID == 9
+ || regID == 10
+ || (regID >= 11 && regID <= 26)))
+ {
+ protect_p = 0;
+ }
+ break;
+ case 0xff00:
+ if ((PSW & PSW_NPV)
+ && (regID == 6
+ || regID == 7
+ || regID == 8
+ || regID == 9
+ || regID == 10
+ || (regID >= 11 && regID <= 15)
+ || regID == 18
+ || regID == 19
+ || (regID >= 21 && regID <= 27)))
+ {
+ protect_p = 0;
+ }
+ break;
+ case 0xffff:
+ if ((PSW & PSW_NPV)
+ && (regID == 6
+ || regID == 7
+ || regID == 8
+ || regID == 9
+ || regID == 10
+ || regID == 11
+ || regID == 12
+ || regID == 15
+ || regID == 18
+ || regID == 19
+ || (regID >= 21 && regID <= 27)))
+ {
+ protect_p = 0;
+ }
+ break;
+ }
+
+ if (!protect_p)
+ {
+ switch (BSEL & 0xffff)
+ {
+ case 0x0000:
+ case 0xff00: /* user0 bank */
+ case 0xffff: /* user1 bank */
+ if(regID == PSW_REGNO)
+ {
+ SR[regID] = sreg & ((PSW & PSW_NPV) ? 0xf : ~0);
+ }
+ else
+ {
+ SR[regID] = sreg;
+ }
+ break;
+ case 0x1000:
+ MPU0_SR[regID] = sreg;
+ break;
+ case 0x1001:
+ if (regID == MPC_REGNO)
+ {
+ PPC &= ~PPC_PPE;
+ SPAL &= ~SPAL_SPE;
+ IPA0L &= ~IPA_IPE;
+ IPA1L &= ~IPA_IPE;
+ IPA2L &= ~IPA_IPE;
+ IPA3L &= ~IPA_IPE;
+ DPA0L &= ~DPA_DPE;
+ DPA1L &= ~DPA_DPE;
+ DCC &= ~(DCC_DCE0 | DCC_DCE1);
+ }
+ else
+ {
+ MPU1_SR[regID] = sreg;
+ }
+ break;
+ case 0x2000: /* FPU */
+ if (regID == FPST_REGNO)
+ {
+ unsigned int val = FPSR & ~(FPSR_PR | FPSR_XC | FPSR_XP);
+
+ val |= ((sreg & FPST_PR) ? FPSR_PR : 0)
+ | ((sreg & FPST_XCE) ? FPSR_XCE : 0)
+ | ((sreg & FPST_XCV) ? FPSR_XCV : 0)
+ | ((sreg & FPST_XCZ) ? FPSR_XCZ : 0)
+ | ((sreg & FPST_XCO) ? FPSR_XCO : 0)
+ | ((sreg & FPST_XCU) ? FPSR_XCU : 0)
+ | ((sreg & FPST_XCI) ? FPSR_XCI : 0)
+ | ((sreg & FPST_XPV) ? FPSR_XPV : 0)
+ | ((sreg & FPST_XPZ) ? FPSR_XPZ : 0)
+ | ((sreg & FPST_XPO) ? FPSR_XPO : 0)
+ | ((sreg & FPST_XPU) ? FPSR_XPU : 0)
+ | ((sreg & FPST_XPI) ? FPSR_XPI : 0);
+ FPSR = val;
+ }
+ else if (regID == FPCFG_REGNO)
+ {
+ unsigned int val = FPSR & ~(FPSR_RM | FPSR_XE);
+
+ val |= (((sreg & FPCFG_RM) >> 7) << 18)
+ | ((sreg & FPCFG_XEV) ? FPSR_XEV : 0)
+ | ((sreg & FPCFG_XEZ) ? FPSR_XEZ : 0)
+ | ((sreg & FPCFG_XEO) ? FPSR_XEO : 0)
+ | ((sreg & FPCFG_XEU) ? FPSR_XEU : 0)
+ | ((sreg & FPCFG_XEI) ? FPSR_XEI : 0);
+ FPSR = val;
+ }
+
+ FPU_SR[regID] = sreg;
+ break;
+ }
+ }
+ }
else
- SR[regID] = GR[reg1];
+ {
+ SR[regID] = sreg;
+ }
+
+ TRACE_ALU_RESULT (sreg);
+}
+
+
+
+// MAC
+rrrrr,111111,RRRRR + wwww,0011110,mmmm,0:XI:::mac
+*v850e2
+*v850e2v3
+"mac r<reg1>, r<reg2>, r<reg3e>, r<reg4e>"
+{
+ unsigned long op0;
+ unsigned long op1;
+ unsigned long op2;
+ unsigned long op2hi;
+ unsigned long lo;
+ unsigned long mid1;
+ unsigned long mid2;
+ unsigned long hi;
+ unsigned long RdLo;
+ unsigned long RdHi;
+ int carry;
+ bfd_boolean sign;
+
+ op0 = GR[reg1];
+ op1 = GR[reg2];
+ op2 = GR[reg3e];
+ op2hi = GR[reg3e+1];
+
+ TRACE_ALU_INPUT4 (op0, op1, op2, op2hi);
+
+ sign = (op0 ^ op1) & 0x80000000;
+
+ if (((signed long) op0) < 0)
+ op0 = - op0;
+
+ if (((signed long) op1) < 0)
+ op1 = - op1;
+
+ /* We can split the 32x32 into four 16x16 operations. This ensures
+ that we do not lose precision on 32bit only hosts: */
+ lo = ( (op0 & 0xFFFF) * (op1 & 0xFFFF));
+ mid1 = ( (op0 & 0xFFFF) * ((op1 >> 16) & 0xFFFF));
+ mid2 = (((op0 >> 16) & 0xFFFF) * (op1 & 0xFFFF));
+ hi = (((op0 >> 16) & 0xFFFF) * ((op1 >> 16) & 0xFFFF));
+
+ /* We now need to add all of these results together, taking care
+ to propogate the carries from the additions: */
+ RdLo = Add32 (lo, (mid1 << 16), & carry);
+ RdHi = carry;
+ RdLo = Add32 (RdLo, (mid2 << 16), & carry);
+ RdHi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi);
+
+ if (sign)
+ {
+ RdLo = ~ RdLo;
+ RdHi = ~ RdHi;
+ if (RdLo == 0xFFFFFFFF)
+ {
+ RdLo = 0;
+ RdHi += 1;
+ }
+ else
+ RdLo += 1;
+ }
+
+ RdLo = Add32 (RdLo, op2, & carry);
+ RdHi += carry + op2hi;
+
+ /* Store the result and condition codes. */
+ GR[reg4e] = RdLo;
+ GR[reg4e + 1 ] = RdHi;
+
+ TRACE_ALU_RESULT2 (RdLo, RdHi);
+}
+
+
+
+// MACU
+rrrrr,111111,RRRRR + wwww,0011111,mmmm,0:XI:::macu
+*v850e2
+*v850e2v3
+"macu r<reg1>, r<reg2>, r<reg3e>, r<reg4e>"
+{
+ unsigned long op0;
+ unsigned long op1;
+ unsigned long op2;
+ unsigned long op2hi;
+ unsigned long lo;
+ unsigned long mid1;
+ unsigned long mid2;
+ unsigned long hi;
+ unsigned long RdLo;
+ unsigned long RdHi;
+ int carry;
+
+ op0 = GR[reg1];
+ op1 = GR[reg2];
+ op2 = GR[reg3e];
+ op2hi = GR[reg3e + 1];
+
+ TRACE_ALU_INPUT4 (op0, op1, op2, op2hi);
+
+ /* We can split the 32x32 into four 16x16 operations. This ensures
+ that we do not lose precision on 32bit only hosts: */
+ lo = ( (op0 & 0xFFFF) * (op1 & 0xFFFF));
+ mid1 = ( (op0 & 0xFFFF) * ((op1 >> 16) & 0xFFFF));
+ mid2 = (((op0 >> 16) & 0xFFFF) * (op1 & 0xFFFF));
+ hi = (((op0 >> 16) & 0xFFFF) * ((op1 >> 16) & 0xFFFF));
- TRACE_ALU_RESULT (SR[regID]);
+ /* We now need to add all of these results together, taking care
+ to propogate the carries from the additions: */
+ RdLo = Add32 (lo, (mid1 << 16), & carry);
+ RdHi = carry;
+ RdLo = Add32 (RdLo, (mid2 << 16), & carry);
+ RdHi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi);
+
+ RdLo = Add32 (RdLo, op2, & carry);
+ RdHi += carry + op2hi;
+
+ /* Store the result and condition codes. */
+ GR[reg4e] = RdLo;
+ GR[reg4e+1] = RdHi;
+
+ TRACE_ALU_RESULT2 (RdLo, RdHi);
}
@@ -552,7 +1166,6 @@ rrrrr!0,000000,RRRRR:I:::mov
TRACE_ALU_RESULT (GR[reg2]);
}
-
rrrrr!0,010000,iiiii:II:::mov
"mov <imm5>, r<reg2>"
{
@@ -562,6 +1175,8 @@ rrrrr!0,010000,iiiii:II:::mov
00000110001,RRRRR + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::mov
*v850e
*v850e1
+*v850e2
+*v850e2v3
"mov <imm32>, r<reg1>"
{
SAVE_2;
@@ -596,6 +1211,8 @@ rrrrr!0,110010,RRRRR + iiiiiiiiiiiiiiii:
rrrrr,111111,RRRRR + wwwww,01000100000:XI:::mul
*v850e
*v850e1
+*v850e2
+*v850e2v3
"mul r<reg1>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_22007E0 ());
@@ -604,6 +1221,8 @@ rrrrr,111111,RRRRR + wwwww,01000100000:X
rrrrr,111111,iiiii + wwwww,01001,IIII,00:XII:::mul
*v850e
*v850e1
+*v850e2
+*v850e2v3
"mul <imm9>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_24007E0 ());
@@ -638,6 +1257,8 @@ rrrrr!0,110111,RRRRR + iiiiiiiiiiiiiiii:
rrrrr,111111,RRRRR + wwwww,01000100010:XI:::mulu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"mulu r<reg1>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_22207E0 ());
@@ -646,6 +1267,8 @@ rrrrr,111111,RRRRR + wwwww,01000100010:X
rrrrr,111111,iiiii + wwwww,01001,IIII,10:XII:::mulu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"mulu <imm9>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_24207E0 ());
@@ -681,6 +1304,8 @@ rrrrr,000001,RRRRR:I:::not
rrrrr,111111,RRRRR + 0000000011100010:IX:::not1
*v850e
*v850e1
+*v850e2
+*v850e2v3
"not1 r<reg2>, r<reg1>"
{
COMPAT_2 (OP_E207E0 ());
@@ -710,6 +1335,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI
0000011110,iiiii,L + LLLLLLLLLLL,00001:XIII:::prepare
*v850e
*v850e1
+*v850e2
+*v850e2v3
"prepare <list12>, <imm5>"
{
int i;
@@ -735,6 +1362,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI
0000011110,iiiii,L + LLLLLLLLLLL,00011:XIII:::prepare00
*v850e
*v850e1
+*v850e2
+*v850e2v3
"prepare <list12>, <imm5>, sp"
{
COMPAT_2 (OP_30780 ());
@@ -743,6 +1372,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI
0000011110,iiiii,L + LLLLLLLLLLL,01011 + iiiiiiiiiiiiiiii:XIII:::prepare01
*v850e
*v850e1
+*v850e2
+*v850e2v3
"prepare <list12>, <imm5>, <uimm16>"
{
COMPAT_2 (OP_B0780 ());
@@ -751,6 +1382,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI
0000011110,iiiii,L + LLLLLLLLLLL,10011 + iiiiiiiiiiiiiiii:XIII:::prepare10
*v850e
*v850e1
+*v850e2
+*v850e2v3
"prepare <list12>, <imm5>, <uimm16>"
{
COMPAT_2 (OP_130780 ());
@@ -759,6 +1392,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI
0000011110,iiiii,L + LLLLLLLLLLL,11011 + iiiiiiiiiiiiiiii + dddddddddddddddd:XIII:::prepare11
*v850e
*v850e1
+*v850e2
+*v850e2v3
"prepare <list12>, <imm5>, <uimm32>"
{
COMPAT_2 (OP_1B0780 ());
@@ -803,12 +1438,23 @@ rrrrr,010101,iiiii:II:::sar
COMPAT_1 (OP_2A0 ());
}
+rrrrr,111111,RRRRR + wwwww,00010100010:XI:::sar
+*v850e2
+*v850e2v3
+"sar r<reg1>, r<reg2>, r<reg3>"
+{
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+ v850_sar(sd, GR[reg1], GR[reg2], &GR[reg3]);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
// SASF
rrrrr,1111110,cccc + 0000001000000000:IX:::sasf
*v850e
*v850e1
+*v850e2
+*v850e2v3
"sasf %s<cccc>, r<reg2>"
{
COMPAT_2 (OP_20007E0 ());
@@ -816,7 +1462,6 @@ rrrrr,1111110,cccc + 0000001000000000:IX
-
// SATADD
rrrrr!0,000110,RRRRR:I:::satadd
"satadd r<reg1>, r<reg2>"
@@ -830,6 +1475,16 @@ rrrrr!0,010001,iiiii:II:::satadd
COMPAT_1 (OP_220 ());
}
+rrrrr,111111,RRRRR + wwwww,01110111010:XI:::satadd
+*v850e2
+*v850e2v3
+"satadd r<reg1>, r<reg2>, r<reg3>"
+{
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+ v850_satadd (sd, GR[reg1], GR[reg2], &GR[reg3]);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
// SATSUB
@@ -839,6 +1494,16 @@ rrrrr!0,000101,RRRRR:I:::satsub
COMPAT_1 (OP_A0 ());
}
+rrrrr,111111,RRRRR + wwwww,01110011010:XI:::satsub
+*v850e2
+*v850e2v3
+"satsub r<reg1>, r<reg2>, r<reg3>"
+{
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+ v850_satsub (sd, GR[reg1], GR[reg2], &GR[reg3]);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
// SATSUBI
@@ -859,6 +1524,234 @@ rrrrr!0,000100,RRRRR:I:::satsubr
+//SBF
+rrrrr,111111,RRRRR + wwwww,011100,cccc!13,0:XI:::sbf
+*v850e2
+*v850e2v3
+"sbf %s<cccc>, r<reg1>, r<reg2>, r<reg3>"
+{
+ int cond = condition_met (cccc);
+ TRACE_ALU_INPUT3 (cond, GR[reg1], GR[reg2]);
+ GR[reg3] = GR[reg2] - GR[reg1] - (cond ? 1 : 0);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+
+
+// SCH0L
+rrrrr,11111100000 + wwwww,01101100100:IX:::sch0l
+*v850e2
+*v850e2v3
+"sch0l r<reg2>, r<reg3>"
+{
+ unsigned int pos, op0;
+
+ TRACE_ALU_INPUT1 (GR[reg2]);
+
+ op0 = GR[reg2];
+
+ if (op0 == 0xffffffff)
+ {
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW |= PSW_Z;
+ pos = 0;
+ }
+ else if (op0 == 0xfffffffe)
+ {
+ PSW |= PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ pos = 32;
+ }
+ else
+ {
+ pos = 1;
+ while (op0 & 0x80000000)
+ {
+ op0 <<= 1;
+ pos++;
+ }
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ }
+
+ GR[reg3] = pos;
+
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+
+
+// SCH0R
+rrrrr,11111100000 + wwwww,01101100000:IX:::sch0r
+*v850e2
+*v850e2v3
+"sch0r r<reg2>, r<reg3>"
+{
+ unsigned int pos, op0;
+
+ TRACE_ALU_INPUT1 (GR[reg2]);
+
+ op0 = GR[reg2];
+
+ if (op0 == 0xffffffff)
+ {
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW |= PSW_Z;
+ pos = 0;
+ }
+ else if (op0 == 0x7fffffff)
+ {
+ PSW |= PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ pos = 32;
+ }
+ else
+ {
+ pos = 1;
+ while (op0 & 0x00000001)
+ {
+ op0 >>= 1;
+ pos++;
+ }
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ }
+
+ GR[reg3] = pos;
+
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+// SCH1L
+rrrrr,11111100000 + wwwww,01101100110:IX:::sch1l
+*v850e2
+*v850e2v3
+"sch1l r<reg2>, r<reg3>"
+{
+ unsigned int pos, op0;
+
+ TRACE_ALU_INPUT1 (GR[reg2]);
+
+ op0 = GR[reg2];
+
+ if (op0 == 0x00000000)
+ {
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW |= PSW_Z;
+ pos = 0;
+ }
+ else if (op0 == 0x00000001)
+ {
+ PSW |= PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ pos = 32;
+ }
+ else
+ {
+ pos = 1;
+ while (!(op0 & 0x80000000))
+ {
+ op0 <<= 1;
+ pos++;
+ }
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ }
+
+ GR[reg3] = pos;
+
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+// SCH1R
+rrrrr,11111100000 + wwwww,01101100010:IX:::sch1r
+*v850e2
+*v850e2v3
+"sch1r r<reg2>, r<reg3>"
+{
+ unsigned int pos, op0;
+
+ TRACE_ALU_INPUT1 (GR[reg2]);
+
+ op0 = GR[reg2];
+
+ if (op0 == 0x00000000)
+ {
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW |= PSW_Z;
+ pos = 0;
+ }
+ else if (op0 == 0x80000000)
+ {
+ PSW |= PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ pos = 32;
+ }
+ else
+ {
+ pos = 1;
+ while (!(op0 & 0x00000001))
+ {
+ op0 >>= 1;
+ pos++;
+ }
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ }
+
+ GR[reg3] = pos;
+
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+//SHL
+rrrrr,111111,RRRRR + wwwww,00011000010:XI:::shl
+*v850e2
+*v850e2v3
+"shl r<reg1>, r<reg2>, r<reg3>"
+{
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+ v850_shl(sd, GR[reg1], GR[reg2], &GR[reg3]);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+//SHR
+rrrrr,111111,RRRRR + wwwww,00010000010:XI:::shr
+*v850e2
+*v850e2v3
+"shr r<reg1>, r<reg2>, r<reg3>"
+{
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+ v850_shr(sd, GR[reg1], GR[reg2], &GR[reg3]);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+
+
// SETF
rrrrr,1111110,cccc + 0000000000000000:IX:::setf
"setf %s<cccc>, r<reg2>"
@@ -878,6 +1771,8 @@ rrrrr,1111110,cccc + 0000000000000000:IX
rrrrr,111111,RRRRR + 0000000011100000:IX:::set1
*v850e
*v850e1
+*v850e2
+*v850e2v3
"set1 r<reg2>, [r<reg1>]"
{
COMPAT_2 (OP_E007E0 ());
@@ -966,6 +1861,8 @@ rrrrr,1010,dddddd,0:IV:::sld.w
rrrrr!0,0000110,dddd:IV:::sld.bu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"sld.b <disp4>[ep], r<reg2>":(PSW & PSW_US)
"sld.bu <disp4>[ep], r<reg2>"
{
@@ -987,6 +1884,8 @@ rrrrr!0,0000110,dddd:IV:::sld.bu
rrrrr!0,0000111,dddd:IV:::sld.hu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"sld.h <disp5>[ep], r<reg2>":(PSW & PSW_US)
"sld.hu <disp5>[ep], r<reg2>"
{
@@ -1005,6 +1904,8 @@ rrrrr!0,0000111,dddd:IV:::sld.hu
}
}
+
+
// SST
rrrrr,0111,ddddddd:IV:::sst.b
"sst.b r<reg2>, <disp7>[ep]"
@@ -1031,29 +1932,113 @@ rrrrr,111010,RRRRR + dddddddddddddddd:VI
COMPAT_2 (OP_740 ());
}
+00000111100,RRRRR + wwwww,ddddddd,1101 + dddddddddddddddd:XIV:::st.b
+*v850e2v3
+"st.b r<reg3>, <disp23>[r<reg1>]"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ store_data_mem (sd, addr, 1, GR[reg3]);
+ TRACE_ST (addr, GR[reg3]);
+}
+
rrrrr,111011,RRRRR + ddddddddddddddd,0:VII:::st.h
"st.h r<reg2>, <disp16>[r<reg1>]"
{
COMPAT_2 (OP_760 ());
}
+00000111101,RRRRR+wwwww,dddddd,01101+dddddddddddddddd:XIV:::st.h
+*v850e2v3
+"st.h r<reg3>, <disp23>[r<reg1>]"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ store_data_mem (sd, addr, 2, GR[reg3]);
+ TRACE_ST (addr, GR[reg3]);
+}
+
rrrrr,111011,RRRRR + ddddddddddddddd,1:VII:::st.w
"st.w r<reg2>, <disp16>[r<reg1>]"
{
COMPAT_2 (OP_10760 ());
}
+00000111100,RRRRR+wwwww,dddddd,01111+dddddddddddddddd:XIV:::st.w
+*v850e2v3
+"st.w r<reg3>, <disp23>[r<reg1>]"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ store_data_mem (sd, addr, 4, GR[reg3]);
+ TRACE_ST (addr, GR[reg3]);
+}
+
+
// STSR
rrrrr,111111,regID + 0000000001000000:IX:::stsr
"stsr s<regID>, r<reg2>"
{
- TRACE_ALU_INPUT1 (SR[regID]);
- GR[reg2] = SR[regID];
- TRACE_ALU_RESULT (GR[reg2]);
-}
+ uint32 sreg = 0;
-// SUB
-rrrrr,001101,RRRRR:I:::sub
+ if ((idecode_issue == idecode_v850e2_issue
+ || idecode_issue == idecode_v850e2v3_issue)
+ && regID < 28)
+ {
+ switch (BSEL & 0xffff)
+ {
+ case 0x0000:
+ case 0xff00: /* USER 0 */
+ case 0xffff: /* USER 1 */
+ sreg = SR[regID];
+ break;
+ case 0x1000:
+ sreg = MPU0_SR[regID];
+ break;
+ case 0x1001:
+ sreg = MPU1_SR[regID];
+ break;
+ case 0x2000:
+ if (regID == FPST_REGNO)
+ {
+ sreg = ((FPSR & FPSR_PR) ? FPST_PR : 0)
+ | ((FPSR & FPSR_XCE) ? FPST_XCE : 0)
+ | ((FPSR & FPSR_XCV) ? FPST_XCV : 0)
+ | ((FPSR & FPSR_XCZ) ? FPST_XCZ : 0)
+ | ((FPSR & FPSR_XCO) ? FPST_XCO : 0)
+ | ((FPSR & FPSR_XCU) ? FPST_XCU : 0)
+ | ((FPSR & FPSR_XCI) ? FPST_XCI : 0)
+ | ((FPSR & FPSR_XPV) ? FPST_XPV : 0)
+ | ((FPSR & FPSR_XPZ) ? FPST_XPZ : 0)
+ | ((FPSR & FPSR_XPO) ? FPST_XPO : 0)
+ | ((FPSR & FPSR_XPU) ? FPST_XPU : 0)
+ | ((FPSR & FPSR_XPI) ? FPST_XPI : 0);
+ }
+ else if (regID == FPCFG_REGNO)
+ {
+ sreg = (((FPSR & FPSR_RM) >> 18) << 7)
+ | ((FPSR & FPSR_XEV) ? FPCFG_XEV : 0)
+ | ((FPSR & FPSR_XEZ) ? FPCFG_XEZ : 0)
+ | ((FPSR & FPSR_XEO) ? FPCFG_XEO : 0)
+ | ((FPSR & FPSR_XEU) ? FPCFG_XEU : 0)
+ | ((FPSR & FPSR_XEI) ? FPCFG_XEI : 0);
+ }
+ else
+ {
+ sreg = FPU_SR[regID];
+ }
+ break;
+ }
+ }
+ else
+ {
+ sreg = SR[regID];
+ }
+
+ TRACE_ALU_INPUT1 (sreg);
+ GR[reg2] = sreg;
+ TRACE_ALU_RESULT (GR[reg2]);
+}
+
+// SUB
+rrrrr,001101,RRRRR:I:::sub
"sub r<reg1>, r<reg2>"
{
COMPAT_1 (OP_1A0 ());
@@ -1070,6 +2055,8 @@ rrrrr,001100,RRRRR:I:::subr
00000000010,RRRRR:I:::switch
*v850e
*v850e1
+*v850e2
+*v850e2v3
"switch r<reg1>"
{
unsigned long adr;
@@ -1084,6 +2071,8 @@ rrrrr,001100,RRRRR:I:::subr
00000000101,RRRRR:I:::sxb
*v850e
*v850e1
+*v850e2
+*v850e2v3
"sxb r<reg1>"
{
TRACE_ALU_INPUT1 (GR[reg1]);
@@ -1095,6 +2084,8 @@ rrrrr,001100,RRRRR:I:::subr
00000000111,RRRRR:I:::sxh
*v850e
*v850e1
+*v850e2
+*v850e2v3
"sxh r<reg1>"
{
TRACE_ALU_INPUT1 (GR[reg1]);
@@ -1126,6 +2117,8 @@ rrrrr,001011,RRRRR:I:::tst
rrrrr,111111,RRRRR + 0000000011100110:IX:::tst1
*v850e
*v850e1
+*v850e2
+*v850e2v3
"tst1 r<reg2>, [r<reg1>]"
{
COMPAT_2 (OP_E607E0 ());
@@ -1149,6 +2142,8 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI
00000000100,RRRRR:I:::zxb
*v850e
*v850e1
+*v850e2
+*v850e2v3
"zxb r<reg1>"
{
TRACE_ALU_INPUT1 (GR[reg1]);
@@ -1160,6 +2155,8 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI
00000000110,RRRRR:I:::zxh
*v850e
*v850e1
+*v850e2
+*v850e2v3
"zxh r<reg1>"
{
TRACE_ALU_INPUT1 (GR[reg1]);
@@ -1178,6 +2175,8 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI
11111,000010,00000:I:::dbtrap
*v850e1
+*v850e2
+*v850e2v3
"dbtrap"
{
DBPC = cia + 2;
@@ -1197,9 +2196,1069 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI
// Return from debug trap: 0x146007e0
0000011111100000 + 0000000101000110:X:::dbret
*v850e1
+*v850e2
+*v850e2v3
"dbret"
{
nia = DBPC;
PSW = DBPSW;
TRACE_BRANCH1 (PSW);
}
+
+
+//
+// FLOAT
+//
+
+// Map condition code to a string
+:%s::::FFFF:int FFFF
+{
+ switch (FFFF)
+ {
+ case 0: return "f";
+ case 1: return "un";
+ case 2: return "eq";
+ case 3: return "ueq";
+ case 4: return "olt";
+ case 5: return "ult";
+ case 6: return "ole";
+ case 7: return "ule";
+ case 8: return "sf";
+ case 9: return "ngle";
+ case 10: return "seq";
+ case 11: return "ngl";
+ case 12: return "lt";
+ case 13: return "nge";
+ case 14: return "le";
+ case 15: return "ngt";
+ }
+ return "(null)";
+}
+
+// ABSF.D
+rrrr,011111100000 + wwww,010001011000:F_I:::absf_d
+*v850e2v3
+"absf.d r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_abs (&ans, &wop);
+ check_invalid_snan(sd, status, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// ABSF.S
+rrrrr,11111100000 + wwwww,10001001000:F_I:::absf_s
+*v850e2v3
+"absf.s r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_abs (&ans, &wop);
+ check_invalid_snan(sd, status, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// ADDF.D
+rrrr,0111111,RRRR,0 + wwww,010001110000:F_I:::addf_d
+*v850e2v3
+"addf.d r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_add (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// ADDF.S
+rrrrr,111111,RRRRR + wwwww,10001100000:F_I:::addf_s
+*v850e2v3
+"addf.s r<reg1>, r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_add (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// CMOVF.D
+rrrr,0111111,RRRR,0 + wwww!0,01000001,bbb,0:F_I:::cmovf_d
+*v850e2v3
+"cmovf.d <bbb>, r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ unsigned int ophi,oplow;
+ sim_fpu ans, wop1, wop2;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_BOOL1_FPU2 (TEST_FPCC(bbb), &wop1, &wop2);
+
+ if (TEST_FPCC(bbb))
+ {
+ ophi = GR[reg1e+1];
+ oplow = GR[reg1e];
+ ans = wop1;
+ }
+ else
+ {
+ ophi = GR[reg2e+1];
+ oplow = GR[reg2e];
+ ans = wop2;
+ }
+
+ GR[reg3e+1] = ophi;
+ GR[reg3e] = oplow;
+ TRACE_FP_RESULT_FPU1 (&ans);;
+}
+
+// CMOVF.S
+rrrrr,111111,RRRRR + wwwww!0,1000000,bbb,0:F_I:::cmovf_s
+*v850e2v3
+"cmovf.d <bbb>, r<reg1>, r<reg2>, r<reg3>"
+{
+ unsigned int op;
+ sim_fpu ans, wop1, wop2;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_BOOL1_FPU2 (TEST_FPCC(bbb), &wop1, &wop2);
+
+ if (TEST_FPCC(bbb))
+ {
+ op = GR[reg1];
+ ans = wop1;
+ }
+ else
+ {
+ op = GR[reg2];
+ ans = wop2;
+ }
+
+ GR[reg3] = op;
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// CMPF.D
+rrrr,0111111,RRRR,0 + 0,FFFF,1000011,bbb,0:F_I:::cmpf_d
+*v850e2v3
+"cmpf.d %s<FFFF>, r<reg1e>, r<reg2e>":(bbb == 0)
+"cmpf.d %s<FFFF>, r<reg1e>, r<reg2e>, <bbb>"
+{
+ int result;
+ sim_fpu wop1;
+ sim_fpu wop2;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ result = v850_float_compare(sd, FFFF, wop1, wop2, 1);
+
+ if (result)
+ SET_FPCC(bbb);
+ else
+ CLEAR_FPCC(bbb);
+
+ TRACE_FP_RESULT_BOOL (result);
+}
+
+// CMPF.S
+rrrrr,111111,RRRRR + 0,FFFF,1000010,bbb,0:F_I:::cmpf_s
+*v850e2v3
+"cmpf.s %s<FFFF>, r<reg1>, r<reg2>":(bbb == 0)
+"cmpf.s %s<FFFF>, r<reg1>, r<reg2>, <bbb>"
+{
+ int result;
+ sim_fpu wop1;
+ sim_fpu wop2;
+
+ sim_fpu_32to( &wop1, GR[reg1] );
+ sim_fpu_32to( &wop2, GR[reg2] );
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ result = v850_float_compare(sd, FFFF, wop1, wop2, 0);
+
+ if (result)
+ SET_FPCC(bbb);
+ else
+ CLEAR_FPCC(bbb);
+
+ TRACE_FP_RESULT_BOOL (result);
+}
+
+// CVTF.DL
+rrrr,011111100100 + wwww,010001010100:F_I:::cvtf_dl
+*v850e2v3
+"cvtf.dl r<reg2e>, r<reg3e>"
+{
+ unsigned64 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+ status |= sim_fpu_to64i (&ans, &wop, FPSR_GET_ROUND());
+
+ check_cvt_fi(sd, status, 1);
+
+ GR[reg3e] = ans;
+ GR[reg3e+1] = ans>>32L;
+ TRACE_FP_RESULT_WORD2 (GR[reg3e], GR[reg3e+1]);
+}
+
+// CVTF.DS
+rrrr,011111100011 + wwwww,10001010010:F_I:::cvtf_ds
+*v850e2v3
+"cvtf.ds r<reg2e>, r<reg3>"
+{
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ check_cvt_fi(sd, status, 0);
+
+ sim_fpu_to32 (&GR[reg3], &wop);
+ TRACE_FP_RESULT_FPU1 (&wop);
+}
+
+// CVTF.DW
+rrrr,011111100100 + wwwww,10001010000:F_I:::cvtf_dw
+*v850e2v3
+"cvtf.dw r<reg2e>, r<reg3>"
+{
+ uint32 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+ status |= sim_fpu_to32i (&ans, &wop, FPSR_GET_ROUND());
+
+ check_cvt_fi(sd, status, 1);
+
+ GR[reg3] = ans;
+ TRACE_FP_RESULT_WORD1 (ans);
+}
+
+// CVTF.LD
+rrrr,011111100001 + wwww,010001010010:F_I:::cvtf_ld
+*v850e2v3
+"cvtf.ld r<reg2e>, r<reg3e>"
+{
+ signed64 op;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ op = ((signed64)GR[reg2e+1] << 32L) | GR[reg2e];
+ TRACE_FP_INPUT_WORD2 (GR[reg2e], GR[reg2e+1]);
+
+ sim_fpu_i64to (&wop, op, FPSR_GET_ROUND());
+ status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+
+ check_cvt_if(sd, status, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &wop);
+ TRACE_FP_RESULT_FPU1 (&wop);
+}
+
+// CVTF.LS
+rrrr,011111100001 + wwwww,10001000010:F_I:::cvtf_ls
+*v850e2v3
+"cvtf.ls r<reg2e>, r<reg3>"
+{
+ signed64 op;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ op = ((signed64)GR[reg2e+1] << 32L) | GR[reg2e];
+ TRACE_FP_INPUT_WORD2 (GR[reg2e], GR[reg2e+1]);
+
+ sim_fpu_i64to (&wop, op, FPSR_GET_ROUND());
+ status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+
+ check_cvt_if(sd, status, 0);
+
+ sim_fpu_to32 (&GR[reg3], &wop);
+ TRACE_FP_RESULT_FPU1 (&wop);
+}
+
+// CVTF.SD
+rrrrr,11111100010 + wwww,010001010010:F_I:::cvtf_sd
+*v850e2v3
+"cvtf.sd r<reg2>, r<reg3e>"
+{
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+ status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ check_cvt_ff(sd, status, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &wop);
+ TRACE_FP_RESULT_FPU1 (&wop);
+}
+
+// CVTF.SL
+rrrrr,11111100100 + wwww,010001000100:F_I:::cvtf_sl
+*v850e2v3
+"cvtf.sl r<reg2>, r<reg3e>"
+{
+ signed64 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+ status |= sim_fpu_to64i (&ans, &wop, FPSR_GET_ROUND());
+
+ check_cvt_fi(sd, status, 0);
+
+ GR[reg3e] = ans;
+ GR[reg3e+1] = ans >> 32L;
+ TRACE_FP_RESULT_WORD2 (GR[reg3e], GR[reg3e+1]);
+}
+
+// CVTF.SW
+rrrrr,11111100100 + wwwww,10001000000:F_I:::cvtf_sw
+*v850e2v3
+"cvtf.sw r<reg2>, r<reg3>"
+{
+ uint32 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+ status |= sim_fpu_to32i (&ans, &wop, sim_fpu_round_zero);
+
+ check_cvt_fi(sd, status, 0);
+
+ GR[reg3] = ans;
+ TRACE_FP_RESULT_WORD1 (ans);
+}
+
+// CVTF.WD
+rrrrr,11111100000 + wwww,010001010010:F_I:::cvtf_wd
+*v850e2v3
+"cvtf.wd r<reg2>, r<reg3e>"
+{
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ TRACE_FP_INPUT_WORD1 (GR[reg2]);
+ sim_fpu_i32to (&wop, GR[reg2], FPSR_GET_ROUND());
+ status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+
+ check_cvt_if(sd, status, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &wop);
+ TRACE_FP_RESULT_FPU1 (&wop);
+}
+
+// CVTF.WS
+rrrrr,11111100000 + wwwww,10001000010:F_I:::cvtf_ws
+*v850e2v3
+"cvtf.ws r<reg2>, r<reg3>"
+{
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ TRACE_FP_INPUT_WORD1 (GR[reg2]);
+ sim_fpu_i32to (&wop, GR[reg2], FPSR_GET_ROUND());
+ status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+
+ check_cvt_if(sd, status, 0);
+
+ sim_fpu_to32 (&GR[reg3], &wop);
+ TRACE_FP_RESULT_FPU1 (&wop);
+}
+
+// DIVF.D
+rrrr,0111111,RRRR,0 + wwww,010001111110:F_I:::divf_d
+*v850e2v3
+"divf.d r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_div (&ans, &wop2, &wop1);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// DIVF.S
+rrrrr,111111,RRRRR + wwwww,10001101110:F_I:::divf_s
+*v850e2v3
+"divf.s r<reg1>, r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_div (&ans, &wop2, &wop1);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MADDF.S
+rrrrr,111111,RRRRR + wwwww,101,W,00,WWWW,0:F_I:::maddf_s
+*v850e2v3
+"maddf.s r<reg1>, r<reg2>, r<reg3>, r<reg4>"
+{
+ sim_fpu ans, wop1, wop2, wop3;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ sim_fpu_32to (&wop3, GR[reg3]);
+ TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3);
+
+ status = sim_fpu_mul (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop1 = ans;
+ status |= sim_fpu_add (&ans, &wop1, &wop3);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg4], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MAXF.D
+rrrr,0111111,RRRR,0 + wwww,010001111000:F_I:::maxf_d
+*v850e2v3
+"maxf.d r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop1, wop2;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2))
+ {
+ if (FPSR & FPSR_XEV)
+ {
+ SignalExceptionFPE(sd, 1);
+ }
+ else
+ {
+ ans = sim_fpu_qnan;
+ }
+ }
+ else if (FPSR & FPSR_FS
+ && ((sim_fpu_is_zero (&wop1) || sim_fpu_is_denorm (&wop1))
+ && (sim_fpu_is_zero (&wop2) || sim_fpu_is_denorm (&wop2))))
+ {
+ ans = sim_fpu_zero;
+ }
+ else
+ {
+ sim_fpu_max (&ans, &wop1, &wop2);
+ }
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MAXF.S
+rrrrr,111111,RRRRR + wwwww,10001101000:F_I:::maxf_s
+*v850e2v3
+"maxf.s r<reg1>, r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop1, wop2;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2))
+ {
+ if (FPSR & FPSR_XEV)
+ {
+ SignalExceptionFPE(sd, 0);
+ }
+ else
+ {
+ ans = sim_fpu_qnan;
+ }
+ }
+ else if ((FPSR & FPSR_FS)
+ && ((sim_fpu_is_zero (&wop1) || sim_fpu_is_denorm (&wop1))
+ && (sim_fpu_is_zero (&wop2)|| sim_fpu_is_denorm (&wop2))))
+ {
+ ans = sim_fpu_zero;
+ }
+ else
+ {
+ sim_fpu_max (&ans, &wop1, &wop2);
+ }
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MINF.D
+rrrr,0111111,RRRR,0 + wwww,010001111010:F_I:::minf_d
+*v850e2v3
+"minf.d r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop1, wop2;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2))
+ {
+ if (FPSR & FPSR_XEV)
+ {
+ SignalExceptionFPE(sd, 1);
+ }
+ else
+ {
+ ans = sim_fpu_qnan;
+ }
+ }
+ else if (FPSR & FPSR_FS
+ && ((sim_fpu_is_zero (&wop1) || sim_fpu_is_denorm (&wop1))
+ && (sim_fpu_is_zero (&wop2) || sim_fpu_is_denorm (&wop2))))
+ {
+ ans = sim_fpu_zero;
+ }
+ else
+ {
+ sim_fpu_min (&ans, &wop1, &wop2);
+ }
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MINF.S
+rrrrr,111111,RRRRR + wwwww,10001101010:F_I:::minf_s
+*v850e2v3
+"minf.s r<reg1>, r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop1, wop2;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2))
+ {
+ if (FPSR & FPSR_XEV)
+ {
+ SignalExceptionFPE(sd, 0);
+ }
+ else
+ {
+ ans = sim_fpu_qnan;
+ }
+ }
+ else if (FPSR & FPSR_FS
+ && ((sim_fpu_is_zero (&wop1) || sim_fpu_is_denorm (&wop1))
+ && (sim_fpu_is_zero (&wop2) || sim_fpu_is_denorm (&wop2))))
+ {
+ ans = sim_fpu_zero;
+ }
+ else
+ {
+ sim_fpu_min (&ans, &wop1, &wop2);
+ }
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MSUBF.S
+rrrrr,111111,RRRRR + wwwww,101,W,01,WWWW,0:F_I:::msubf_s
+*v850e2v3
+"msubf.s r<reg1>, r<reg2>, r<reg3>, r<reg4>"
+{
+ sim_fpu ans, wop1, wop2, wop3;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ sim_fpu_32to (&wop3, GR[reg3]);
+ TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3);
+
+ status = sim_fpu_mul (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop1 = ans;
+ status |= sim_fpu_sub (&ans, &wop1, &wop3);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg4], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MULF.D
+rrrr,0111111,RRRR,0 + wwww,010001110100:F_I:::mulf_d
+*v850e2v3
+"mulf.d r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_mul (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MULF.S
+rrrrr,111111,RRRRR + wwwww,10001100100:F_I:::mulf_s
+*v850e2v3
+"mulf.s r<reg1>, r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_mul (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// NEGF.D
+rrrr,011111100001 + wwww,010001011000:F_I:::negf_d
+*v850e2v3
+"negf.d r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_neg (&ans, &wop);
+
+ check_invalid_snan(sd, status, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// NEGF.S
+rrrrr,11111100001 + wwwww,10001001000:F_I:::negf_s
+*v850e2v3
+"negf.s r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_neg (&ans, &wop);
+
+ check_invalid_snan(sd, status, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// NMADDF.S
+rrrrr,111111,RRRRR + wwwww,101,W,10,WWWW,0:F_I:::nmaddf_s
+*v850e2v3
+"nmaddf.s r<reg1>, r<reg2>, r<reg3>, r<reg4>"
+{
+ sim_fpu ans, wop1, wop2, wop3;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ sim_fpu_32to (&wop3, GR[reg3]);
+ TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3);
+
+ status = sim_fpu_mul (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop1 = ans;
+ status |= sim_fpu_add (&ans, &wop1, &wop3);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop1 = ans;
+ status |= sim_fpu_neg (&ans, &wop1);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg4], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// NMSUBF.S
+rrrrr,111111,RRRRR + wwwww,101,W,11,WWWW,0:F_I:::nmsubf_s
+*v850e2v3
+"nmsubf.s r<reg1>, r<reg2>, r<reg3>, r<reg4>"
+{
+ sim_fpu ans, wop1, wop2, wop3;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ sim_fpu_32to (&wop3, GR[reg3]);
+ TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3);
+
+ status = sim_fpu_mul (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop1 = ans;
+ status |= sim_fpu_sub (&ans, &wop1, &wop3);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop1 = ans;
+ status |= sim_fpu_neg (&ans, &wop1);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg4], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// RECIPF.D
+rrrr,011111100001 + wwww,010001011110:F_I:::recipf.d
+*v850e2v3
+"recipf.d r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_div (&ans, &sim_fpu_one, &wop);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// RECIPF.S
+rrrrr,11111100001 + wwwww,10001001110:F_I:::recipf.s
+*v850e2v3
+"recipf.s r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_div (&ans, &sim_fpu_one, &wop);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// RSQRTF.D
+rrrr,011111100010 + wwww,010001011110:F_I:::rsqrtf.d
+*v850e2v3
+"rsqrtf.d r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_sqrt (&ans, &wop);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop = ans;
+ status = sim_fpu_div (&ans, &sim_fpu_one, &wop);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// RSQRTF.S
+rrrrr,11111100010 + wwwww,10001001110:F_I:::rsqrtf.s
+*v850e2v3
+"rsqrtf.s r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_sqrt (&ans, &wop);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop = ans;
+ status = sim_fpu_div (&ans, &sim_fpu_one, &wop);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// SQRTF.D
+rrrr,011111100000 + wwww,010001011110:F_I:::sqrtf.d
+*v850e2v3
+"sqrtf.d r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_sqrt (&ans, &wop);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// SQRTF.S
+rrrrr,11111100000 + wwwww,10001001110:F_I:::sqrtf.s
+*v850e2v3
+"sqrtf.s r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_sqrt (&ans, &wop);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// SUBF.D
+rrrr,0111111,RRRR,0 + wwww,010001110010:F_I:::subf.d
+*v850e2v3
+"subf.d r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_sub (&ans, &wop2, &wop1);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// SUBF.S
+rrrrr,111111,RRRRR + wwwww,10001100010:F_I:::subf.s
+*v850e2v3
+"subf.s r<reg1>, r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_sub (&ans, &wop2, &wop1);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// TRFSR
+0000011111100000 + 000001000000,bbb,0:F_I:::trfsr
+*v850e2v3
+"trfsr":(bbb == 0)
+"trfsr <bbb>"
+{
+ TRACE_ALU_INPUT1 (GET_FPCC());
+
+ if (TEST_FPCC (bbb))
+ PSW |= PSW_Z;
+ else
+ PSW &= ~PSW_Z;
+
+ TRACE_ALU_RESULT1 (PSW);
+}
+
+// TRNCF.DL
+rrrr,011111100001 + wwww,010001010100:F_I:::trncf_dl
+*v850e2v3
+"trncf.dl r<reg2e>, r<reg3e>"
+{
+ signed64 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_64 (&wop, sim_fpu_round_zero, sim_fpu_denorm_zero);
+ status |= sim_fpu_to64i (&ans, &wop, sim_fpu_round_zero);
+
+ check_cvt_fi(sd, status, 1);
+
+ GR[reg3e] = ans;
+ GR[reg3e+1] = ans>>32L;
+ TRACE_FP_RESULT_WORD2 (GR[reg3e], GR[reg3e+1]);
+}
+
+// TRNCF.DW
+rrrr,011111100001 + wwwww,10001010000:F_I:::trncf_dw
+*v850e2v3
+"trncf.dw r<reg2e>, r<reg3>"
+{
+ uint32 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_32 (&wop, sim_fpu_round_zero, sim_fpu_denorm_zero);
+ status |= sim_fpu_to32i (&ans, &wop, sim_fpu_round_zero);
+
+ check_cvt_fi(sd, status, 1);
+
+ GR[reg3] = ans;
+ TRACE_FP_RESULT_WORD1 (ans);
+}
+
+// TRNCF.SL
+rrrrr,11111100001 + wwww,010001000100:F_I:::trncf_sl
+*v850e2v3
+"trncf.sl r<reg2>, r<reg3e>"
+{
+ signed64 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_64 (&wop, sim_fpu_round_zero, sim_fpu_denorm_zero);
+ status |= sim_fpu_to64i (&ans, &wop, sim_fpu_round_zero);
+
+ GR[reg3e] = ans;
+ GR[reg3e+1] = ans >> 32L;
+ TRACE_FP_RESULT_WORD2 (GR[reg3e], GR[reg3e+1]);
+}
+
+// TRNCF.SW
+rrrrr,11111100001 + wwwww,10001000000:F_I:::trncf_sw
+*v850e2v3
+"trncf.sw r<reg2>, r<reg3>"
+{
+ uint32 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_32 (&wop, sim_fpu_round_zero, sim_fpu_denorm_zero);
+ status |= sim_fpu_to32i (&ans, &wop, sim_fpu_round_zero);
+
+ check_cvt_fi(sd, status, 0);
+
+ GR[reg3] = ans;
+ TRACE_FP_RESULT_WORD1 (ans);
+}
+
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH, V850] Add support for V850E2 and V850E2V3
2010-12-10 14:49 Rathish C
@ 2010-12-13 16:47 ` Kevin Buettner
0 siblings, 0 replies; 14+ messages in thread
From: Kevin Buettner @ 2010-12-13 16:47 UTC (permalink / raw)
To: gdb-patches
Hi Rathish,
Thanks for making the changes that I requested.
Your changes to gdb/v850-tdep.c are approved.
I have one comment (see below) for the sim portion of the patch. The
rest of the patch looks reasonable to me. (It's unclear to me whether or
not I can approve sim patches...)
Kevin
On Fri, 10 Dec 2010 20:19:24 +0530
Rathish C <Rathish.C@kpitcummins.com> wrote:
> diff -upNr gdb-7.2.50-original/sim/v850/sim-main.h gdb-7.2.50-modified/sim/v850/sim-main.h
> --- gdb-7.2.50-original/sim/v850/sim-main.h 2002-11-30 23:31:30.000000000 +0530
> +++ gdb-7.2.50-modified/sim/v850/sim-main.h 2010-12-08 14:52:40.000000000 +0530
[...]
> @@ -61,6 +65,7 @@ struct sim_state {
> #define STATE_CPU(sd,n) (&(sd)->cpu[n])
> #else
> #define STATE_CPU(sd,n) (&(sd)->cpu[0])
> +#define CPU (STATE_CPU (sd, 0))
> #endif
Do you really need to define CPU here? It appears to me that a
suitable definition for CPU is placed in support.h by igen at build
time. If it turns out that you do need this definition, you should
make sure that the WITH_SMP case is handled too.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH, V850] Add support for V850E2 and V850E2V3
@ 2010-12-10 14:49 Rathish C
2010-12-13 16:47 ` Kevin Buettner
0 siblings, 1 reply; 14+ messages in thread
From: Rathish C @ 2010-12-10 14:49 UTC (permalink / raw)
To: gdb-patches; +Cc: kevinb, Gina Verlekar
[-- Attachment #1: Type: text/plain, Size: 3245 bytes --]
Hi,
Thank you for the review comments.
I have updated the patch based on the review comments from Kevin Buettner.
Please find the updated patch "v850-gdb-v850e2-v850e2v3-support.patch".
>
> Why are you changing the register number for E_PC_REGNUM? I
> assume you've already changed gcc so that the dwarf2 return address
> column ends up being this new number. Won't this make it impossible
> to use an old compiler with a new debugger and vice versa?
>
I have updated the patch to have the same value for the E_PC_REGNUM.
The enum members for the new registers for E2V3 are added at the end
of the enum.
>
> Does the original v850 really have all of these new registers? (The
> v850 manual that I looked at does not show them...)
>
No, the registers are not available for v850 target. It is only
available in E2 targets. The patch has been modified accordingly.
The patch adds support for new target variants of V850 i.e. V850E2 and V850E2V3. These processors are upwardly compatible with earlier V850 targets already supported in the current binutils port. V850E2V3 target supports floating point operations. Hence, those instructions along with registers supported by V850E2V3 are defined in the current patch.
The GCC, Binutils and Newlib part of the support have been posted and accepted.
Please review the patch and let me know if there should be any modifications in it.
2010-12-10 Rathish.C <rathish.c@kpitcummins.com>
* gdb/v850-tdep.c: Add the enum values for mpu and fpu registers
(v850_register_name): Add the mpu and fpu register names.
(v850e_register_name): Add the mpu and fpu register names.
(v850e2_register_name): New function.
(v850_gdbarch_init): Add case for bfd_mach_v850e2 and
bfd_mach_v850e2v3.
* sim/common/sim-trace.c: Update the function prototype of
save_data_size.
Move the enum data_fmt from here
* sim/common/sim-trace.h: to here.
Add function prototype of save_data
* sim/v850/sim-main.h: Update the struct _v850_regs to include
mpu and fpu system registers.
Define the macros to access the mpu and fpu system registers.
(SEXT3): Define.
(TRACE_FP_INPUT_FPU1, TRACE_FP_INPUT_FPU2,
TRACE_FP_INPUT_FPU3): Define.
(TRACE_FP_INPUT_BOOL1_FPU2): Define.
(TRACE_FP_INPUT_WORD2): Define.
(TRACE_FP_RESULT_WORD1, TRACE_FP_RESULT_WORD2): Define.
* sim/v850/simops.c: Update the function prototype of Add32
(update_fpsr): New function.
(SignalException): New function.
(SignalExceptionFPE): New function.
(check_invalid_snan): New function.
(v850_float_compare): New function.
(v850_div): New function.
(v850_divu): New function.
(v850_sar): New function.
(v850_shl): New function.
(v850_shr): New function.
(v850_satadd): New function.
(v850_satsub): New function.
(load_data_mem): New function.
(store_data_mem): New function.
(mpu_load_mem_test): New function.
(mpu_store_mem_test): New function.
* sim/v850/simops.h: Add function prototype for above
mentioned functions.
(check_cvt_fi, check_cvt_if, check_cvt_ff): Define.
* sim/v850/v850-dc: Add entry for v850e2 and v850e2v3.
* sim/v850/v850.igen: Add support for v850e2 and v850e2v3
Thanks & Regards,
Rathish.C
[-- Attachment #2: v850-gdb-v850e2-v850e2v3-support.patch --]
[-- Type: application/octet-stream, Size: 94612 bytes --]
diff -upNr gdb-7.2.50-original/gdb/v850-tdep.c gdb-7.2.50-modified/gdb/v850-tdep.c
--- gdb-7.2.50-original/gdb/v850-tdep.c 2010-09-10 04:34:46.000000000 +0530
+++ gdb-7.2.50-modified/gdb/v850-tdep.c 2010-12-09 18:16:03.000000000 +0530
@@ -101,7 +101,97 @@ enum
E_R62_REGNUM,
E_R63_REGNUM,
E_R64_REGNUM, E_PC_REGNUM = E_R64_REGNUM,
- E_R65_REGNUM,
+ E_R65_REGNUM, E_NUM_OF_V850_REGS = E_R65_REGNUM, E_NUM_OF_V850E_REGS = E_R65_REGNUM,
+
+ /* mpu0 system registers */
+ E_R66_REGNUM,
+ E_R67_REGNUM,
+ E_R68_REGNUM,
+ E_R69_REGNUM,
+ E_R70_REGNUM,
+ E_R71_REGNUM,
+ E_R72_REGNUM,
+ E_R73_REGNUM,
+ E_R74_REGNUM,
+ E_R75_REGNUM,
+ E_R76_REGNUM,
+ E_R77_REGNUM,
+ E_R78_REGNUM,
+ E_R79_REGNUM,
+ E_R80_REGNUM,
+ E_R81_REGNUM,
+ E_R82_REGNUM,
+ E_R83_REGNUM,
+ E_R84_REGNUM,
+ E_R85_REGNUM,
+ E_R86_REGNUM,
+ E_R87_REGNUM,
+ E_R88_REGNUM,
+ E_R89_REGNUM,
+ E_R90_REGNUM,
+ E_R91_REGNUM,
+ E_R92_REGNUM,
+ E_R93_REGNUM,
+
+ /* mpu1 system registers */
+
+ E_R94_REGNUM,
+ E_R95_REGNUM,
+ E_R96_REGNUM,
+ E_R97_REGNUM,
+ E_R98_REGNUM,
+ E_R99_REGNUM,
+ E_R100_REGNUM,
+ E_R101_REGNUM,
+ E_R102_REGNUM,
+ E_R103_REGNUM,
+ E_R104_REGNUM,
+ E_R105_REGNUM,
+ E_R106_REGNUM,
+ E_R107_REGNUM,
+ E_R108_REGNUM,
+ E_R109_REGNUM,
+ E_R110_REGNUM,
+ E_R111_REGNUM,
+ E_R112_REGNUM,
+ E_R113_REGNUM,
+ E_R114_REGNUM,
+ E_R115_REGNUM,
+ E_R116_REGNUM,
+ E_R117_REGNUM,
+ E_R118_REGNUM,
+ E_R119_REGNUM,
+ E_R120_REGNUM,
+ E_R121_REGNUM,
+
+ /* fpu system registers */
+ E_R122_REGNUM,
+ E_R123_REGNUM,
+ E_R124_REGNUM,
+ E_R125_REGNUM,
+ E_R126_REGNUM,
+ E_R127_REGNUM,
+ E_R128_REGNUM, E_FPSR_REGNUM = E_R128_REGNUM,
+ E_R129_REGNUM, E_FPEPC_REGNUM = E_R129_REGNUM,
+ E_R130_REGNUM, E_FPST_REGNUM = E_R130_REGNUM,
+ E_R131_REGNUM, E_FPCC_REGNUM = E_R131_REGNUM,
+ E_R132_REGNUM, E_FPCFG_REGNUM = E_R132_REGNUM,
+ E_R133_REGNUM,
+ E_R134_REGNUM,
+ E_R135_REGNUM,
+ E_R136_REGNUM,
+ E_R137_REGNUM,
+ E_R138_REGNUM,
+ E_R139_REGNUM,
+ E_R140_REGNUM,
+ E_R141_REGNUM,
+ E_R142_REGNUM,
+ E_R143_REGNUM,
+ E_R144_REGNUM,
+ E_R145_REGNUM,
+ E_R146_REGNUM,
+ E_R147_REGNUM,
+ E_R148_REGNUM,
E_NUM_REGS
};
@@ -152,7 +242,7 @@ v850_register_name (struct gdbarch *gdba
"sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
"pc", "fp"
};
- if (regnum < 0 || regnum >= E_NUM_REGS)
+ if (regnum < 0 || regnum > E_NUM_OF_V850_REGS)
return NULL;
return v850_reg_names[regnum];
}
@@ -172,11 +262,50 @@ v850e_register_name (struct gdbarch *gdb
"sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
"pc", "fp"
};
- if (regnum < 0 || regnum >= E_NUM_REGS)
+ if (regnum < 0 || regnum > E_NUM_OF_V850E_REGS)
return NULL;
return v850e_reg_names[regnum];
}
+static const char *
+v850e2_register_name (struct gdbarch *gdbarch, int regnum)
+{
+ static const char *v850e2_reg_names[] =
+ {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+
+ "eipc", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7",
+ "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
+ "ctpc", "ctpsw", "dbpc", "dbpsw", "ctbp", "sr21", "sr22", "sr23",
+ "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
+ "pc", "fp"
+
+ /* mpu0 system registers */
+ "vip", "sr33", "sr34", "sr35", "vmecr", "vmtid", "vmadr", "sr39",
+ "vpecr", "vptid", "vpadr", "sr43", "vdecr", "vdtid", "sr46", "sr47",
+ "sr48", "sr49", "sr50", "sr51", "sr52", "sr53", "sr54", "sr55",
+ "sr56", "sr57", "sr58", "sr59",
+
+ /* mpu1 system registers */
+ "mpm", "mpc", "tid", "ppa", "ppm", "ppc", "dcc", "dcv0",
+ "dcv1", "sr69", "spal", "spau", "ipa0l", "ipa0u", "ipa1l", "ipa1u",
+ "iap2l", "ipa2u", "ipa3l", "ipa3u", "dpa0l", "dpa0u", "dpa1l", "dpa1u",
+ "dpa2l", "dpa2u", "dpa3l", "dpa3u",
+
+ /* fpu system registers */
+ "sr88", "sr89", "sr90", "sr91", "sr92", "sr93", "fpsr", "fpepc",
+ "fpst", "fpcc", "fpcfg", "sr99", "sr100", "sr101", "sr102", "sr103",
+ "sr104", "sr105", "sr106", "sr107", "sr108", "sr109", "sr110", "sr111",
+ "sr112", "sr113", "sr114", "sr115"
+ };
+ if (regnum < 0 || regnum >= E_NUM_REGS)
+ return NULL;
+ return v850e2_reg_names[regnum];
+}
+
/* Returns the default type for register N. */
static struct type *
@@ -996,6 +1125,10 @@ v850_gdbarch_init (struct gdbarch_info i
case bfd_mach_v850e1:
set_gdbarch_register_name (gdbarch, v850e_register_name);
break;
+ case bfd_mach_v850e2:
+ case bfd_mach_v850e2v3:
+ set_gdbarch_register_name (gdbarch, v850e2_register_name);
+ break;
}
set_gdbarch_num_regs (gdbarch, E_NUM_REGS);
diff -upNr gdb-7.2.50-original/sim/common/sim-trace.c gdb-7.2.50-modified/sim/common/sim-trace.c
--- gdb-7.2.50-original/sim/common/sim-trace.c 2010-04-12 22:23:33.000000000 +0530
+++ gdb-7.2.50-modified/sim/common/sim-trace.c 2010-12-08 14:37:57.000000000 +0530
@@ -486,17 +486,6 @@ trace_uninstall (SIM_DESC sd)
}
}
\f
-typedef enum {
- trace_fmt_invalid,
- trace_fmt_word,
- trace_fmt_fp,
- trace_fmt_fpu,
- trace_fmt_string,
- trace_fmt_bool,
- trace_fmt_addr,
- trace_fmt_instruction_incomplete,
-} data_fmt;
-
/* compute the nr of trace data units consumed by data */
static int
save_data_size (TRACE_DATA *data,
@@ -508,7 +497,7 @@ save_data_size (TRACE_DATA *data,
/* Archive DATA into the trace buffer */
-static void
+void
save_data (SIM_DESC sd,
TRACE_DATA *data,
data_fmt fmt,
diff -upNr gdb-7.2.50-original/sim/common/sim-trace.h gdb-7.2.50-modified/sim/common/sim-trace.h
--- gdb-7.2.50-original/sim/common/sim-trace.h 2010-01-01 15:33:27.000000000 +0530
+++ gdb-7.2.50-modified/sim/common/sim-trace.h 2010-12-08 14:37:59.000000000 +0530
@@ -243,9 +243,26 @@ extern void trace_generic PARAMS ((SIM_D
...))
__attribute__((format (printf, 4, 5)));
+typedef enum {
+ trace_fmt_invalid,
+ trace_fmt_word,
+ trace_fmt_fp,
+ trace_fmt_fpu,
+ trace_fmt_string,
+ trace_fmt_bool,
+ trace_fmt_addr,
+ trace_fmt_instruction_incomplete,
+} data_fmt;
+
/* Trace a varying number of word sized inputs/outputs. trace_result*
must be called to close the trace operation. */
+extern void save_data PARAMS ((SIM_DESC sd,
+ TRACE_DATA *data,
+ data_fmt fmt,
+ long size,
+ const void *buf));
+
extern void trace_input0 PARAMS ((SIM_DESC sd,
sim_cpu *cpu,
int trace_idx));
diff -upNr gdb-7.2.50-original/sim/v850/sim-main.h gdb-7.2.50-modified/sim/v850/sim-main.h
--- gdb-7.2.50-original/sim/v850/sim-main.h 2002-11-30 23:31:30.000000000 +0530
+++ gdb-7.2.50-modified/sim/v850/sim-main.h 2010-12-08 14:52:40.000000000 +0530
@@ -15,6 +15,7 @@
#include "sim-basics.h"
#include "sim-signal.h"
+#include "sim-fpu.h"
typedef address_word sim_cia;
@@ -39,7 +40,10 @@ typedef struct _v850_regs {
reg_t regs[32]; /* general-purpose registers */
reg_t sregs[32]; /* system registers, including psw */
reg_t pc;
- int dummy_mem; /* where invalid accesses go */
+ int dummy_mem; /* where invalid accesses go */
+ reg_t mpu0_sregs[28]; /* mpu0 system registers */
+ reg_t mpu1_sregs[28]; /* mpu1 system registers */
+ reg_t fpu_sregs[28]; /* fpu system registers */
} v850_regs;
struct _sim_cpu
@@ -61,6 +65,7 @@ struct sim_state {
#define STATE_CPU(sd,n) (&(sd)->cpu[n])
#else
#define STATE_CPU(sd,n) (&(sd)->cpu[0])
+#define CPU (STATE_CPU (sd, 0))
#endif
#if 0
SIM_ADDR rom_size;
@@ -122,11 +127,15 @@ nia = PC
/* new */
#define GR ((CPU)->reg.regs)
#define SR ((CPU)->reg.sregs)
+#define MPU0_SR ((CPU)->reg.mpu0_sregs)
+#define MPU1_SR ((CPU)->reg.mpu1_sregs)
+#define FPU_SR ((CPU)->reg.fpu_sregs)
/* old */
#define State (STATE_CPU (simulator, 0)->reg)
#define PC (State.pc)
-#define SP (State.regs[3])
+#define SP_REGNO 3
+#define SP (State.regs[SP_REGNO])
#define EP (State.regs[30])
#define EIPC (State.sregs[0])
@@ -135,11 +144,20 @@ nia = PC
#define FEPSW (State.sregs[3])
#define ECR (State.sregs[4])
#define PSW (State.sregs[5])
+#define PSW_REGNO 5
+#define EIIC (SR[13])
+#define FEIC (SR[14])
+#define DBIC (SR[15])
#define CTPC (SR[16])
#define CTPSW (SR[17])
#define DBPC (State.sregs[18])
#define DBPSW (State.sregs[19])
#define CTBP (State.sregs[20])
+#define DIR (SR[21])
+#define EIWR (SR[28])
+#define FEWR (SR[29])
+#define DBWR (SR[30])
+#define BSEL (SR[31])
#define PSW_US BIT32 (8)
#define PSW_NP 0x80
@@ -151,6 +169,210 @@ nia = PC
#define PSW_S 0x2
#define PSW_Z 0x1
+#define PSW_NPV (1<<18)
+#define PSW_DMP (1<<17)
+#define PSW_IMP (1<<16)
+
+#define ECR_EICC 0x0000ffff
+#define ECR_FECC 0xffff0000
+
+/* FPU */
+
+#define FPSR (FPU_SR[6])
+#define FPSR_REGNO 6
+#define FPEPC (FPU_SR[7])
+#define FPST (FPU_SR[8])
+#define FPST_REGNO 8
+#define FPCC (FPU_SR[9])
+#define FPCFG (FPU_SR[10])
+#define FPCFG_REGNO 10
+
+#define FPSR_DEM 0x00200000
+#define FPSR_SEM 0x00100000
+#define FPSR_RM 0x000c0000
+#define FPSR_RN 0x00000000
+#define FPSR_FS 0x00020000
+#define FPSR_PR 0x00010000
+
+#define FPSR_XC 0x0000fc00
+#define FPSR_XCE 0x00008000
+#define FPSR_XCV 0x00004000
+#define FPSR_XCZ 0x00002000
+#define FPSR_XCO 0x00001000
+#define FPSR_XCU 0x00000800
+#define FPSR_XCI 0x00000400
+
+#define FPSR_XE 0x000003e0
+#define FPSR_XEV 0x00000200
+#define FPSR_XEZ 0x00000100
+#define FPSR_XEO 0x00000080
+#define FPSR_XEU 0x00000040
+#define FPSR_XEI 0x00000020
+
+#define FPSR_XP 0x0000001f
+#define FPSR_XPV 0x00000010
+#define FPSR_XPZ 0x00000008
+#define FPSR_XPO 0x00000004
+#define FPSR_XPU 0x00000002
+#define FPSR_XPI 0x00000001
+
+#define FPST_PR 0x00008000
+#define FPST_XCE 0x00002000
+#define FPST_XCV 0x00001000
+#define FPST_XCZ 0x00000800
+#define FPST_XCO 0x00000400
+#define FPST_XCU 0x00000200
+#define FPST_XCI 0x00000100
+
+#define FPST_XPV 0x00000010
+#define FPST_XPZ 0x00000008
+#define FPST_XPO 0x00000004
+#define FPST_XPU 0x00000002
+#define FPST_XPI 0x00000001
+
+#define FPCFG_RM 0x00000180
+#define FPCFG_XEV 0x00000010
+#define FPCFG_XEZ 0x00000008
+#define FPCFG_XEO 0x00000004
+#define FPCFG_XEU 0x00000002
+#define FPCFG_XEI 0x00000001
+
+#define GET_FPCC()\
+ ((FPSR >> 24) &0xf)
+
+#define CLEAR_FPCC(bbb)\
+ (FPSR &= ~(1 << (bbb+24)))
+
+#define SET_FPCC(bbb)\
+ (FPSR |= 1 << (bbb+24))
+
+#define TEST_FPCC(bbb)\
+ ((FPSR & (1 << (bbb+24))) != 0)
+
+#define FPSR_GET_ROUND() \
+ (((FPSR & FPSR_RM) == FPSR_RN) ? sim_fpu_round_near \
+ : ((FPSR & FPSR_RM) == 0x00040000) ? sim_fpu_round_up \
+ : ((FPSR & FPSR_RM) == 0x00080000) ? sim_fpu_round_down \
+ : sim_fpu_round_zero)
+
+
+enum FPU_COMPARE {
+ FPU_CMP_F = 0,
+ FPU_CMP_UN,
+ FPU_CMP_EQ,
+ FPU_CMP_UEQ,
+ FPU_CMP_OLT,
+ FPU_CMP_ULT,
+ FPU_CMP_OLE,
+ FPU_CMP_ULE,
+ FPU_CMP_SF,
+ FPU_CMP_NGLE,
+ FPU_CMP_SEQ,
+ FPU_CMP_NGL,
+ FPU_CMP_LT,
+ FPU_CMP_NGE,
+ FPU_CMP_LE,
+ FPU_CMP_NGT
+};
+
+
+/* MPU */
+#define MPM (MPU1_SR[0])
+#define MPC (MPU1_SR[1])
+#define MPC_REGNO 1
+#define TID (MPU1_SR[2])
+#define PPA (MPU1_SR[3])
+#define PPM (MPU1_SR[4])
+#define PPC (MPU1_SR[5])
+#define DCC (MPU1_SR[6])
+#define DCV0 (MPU1_SR[7])
+#define DCV1 (MPU1_SR[8])
+#define SPAL (MPU1_SR[10])
+#define SPAU (MPU1_SR[11])
+#define IPA0L (MPU1_SR[12])
+#define IPA0U (MPU1_SR[13])
+#define IPA1L (MPU1_SR[14])
+#define IPA1U (MPU1_SR[15])
+#define IPA2L (MPU1_SR[16])
+#define IPA2U (MPU1_SR[17])
+#define IPA3L (MPU1_SR[18])
+#define IPA3U (MPU1_SR[19])
+#define DPA0L (MPU1_SR[20])
+#define DPA0U (MPU1_SR[21])
+#define DPA1L (MPU1_SR[22])
+#define DPA1U (MPU1_SR[23])
+#define DPA2L (MPU1_SR[24])
+#define DPA2U (MPU1_SR[25])
+#define DPA3L (MPU1_SR[26])
+#define DPA3U (MPU1_SR[27])
+
+#define PPC_PPE 0x1
+#define SPAL_SPE 0x1
+#define SPAL_SPS 0x10
+
+#define VIP (MPU0_SR[0])
+#define VMECR (MPU0_SR[4])
+#define VMTID (MPU0_SR[5])
+#define VMADR (MPU0_SR[6])
+#define VPECR (MPU0_SR[8])
+#define VPTID (MPU0_SR[9])
+#define VPADR (MPU0_SR[10])
+#define VDECR (MPU0_SR[12])
+#define VDTID (MPU0_SR[13])
+
+#define MPM_AUE 0x2
+#define MPM_MPE 0x1
+
+#define VMECR_VMX 0x2
+#define VMECR_VMR 0x4
+#define VMECR_VMW 0x8
+#define VMECR_VMS 0x10
+#define VMECR_VMRMW 0x20
+#define VMECR_VMMS 0x40
+
+#define IPA2ADDR(IPA) ((IPA) & 0x1fffff80)
+#define IPA_IPE 0x1
+#define IPA_IPX 0x2
+#define IPA_IPR 0x4
+#define IPE0 (IPA0L & IPA_IPE)
+#define IPE1 (IPA1L & IPA_IPE)
+#define IPE2 (IPA2L & IPA_IPE)
+#define IPE3 (IPA3L & IPA_IPE)
+#define IPX0 (IPA0L & IPA_IPX)
+#define IPX1 (IPA1L & IPA_IPX)
+#define IPX2 (IPA2L & IPA_IPX)
+#define IPX3 (IPA3L & IPA_IPX)
+#define IPR0 (IPA0L & IPA_IPR)
+#define IPR1 (IPA1L & IPA_IPR)
+#define IPR2 (IPA2L & IPA_IPR)
+#define IPR3 (IPA3L & IPA_IPR)
+
+#define DPA2ADDR(DPA) ((DPA) & 0x1fffff80)
+#define DPA_DPE 0x1
+#define DPA_DPR 0x4
+#define DPA_DPW 0x8
+#define DPE0 (DPA0L & DPA_DPE)
+#define DPE1 (DPA1L & DPA_DPE)
+#define DPE2 (DPA2L & DPA_DPE)
+#define DPE3 (DPA3L & DPA_DPE)
+#define DPR0 (DPA0L & DPA_DPR)
+#define DPR1 (DPA1L & DPA_DPR)
+#define DPR2 (DPA2L & DPA_DPR)
+#define DPR3 (DPA3L & DPA_DPR)
+#define DPW0 (DPA0L & DPA_DPW)
+#define DPW1 (DPA1L & DPA_DPW)
+#define DPW2 (DPA2L & DPA_DPW)
+#define DPW3 (DPA3L & DPA_DPW)
+
+#define DCC_DCE0 0x1
+#define DCC_DCE1 0x10000
+
+#define PPA2ADDR(PPA) ((PPA) & 0x1fffff80)
+#define PPC_PPC 0xfffffffe
+#define PPC_PPE 0x1
+#define PPC_PPM 0x0000fff8
+
+
#define SEXT3(x) ((((x)&0x7)^(~0x3))+0x4)
/* sign-extend a 4-bit number */
@@ -344,6 +566,79 @@ do { \
} \
} while (0)
+#define TRACE_FP_INPUT_FPU1(V0) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ { \
+ unsigned64 f0; \
+ sim_fpu_to64 (&f0, (V0)); \
+ trace_input_fp1 (SD, CPU, TRACE_FPU_IDX, f0); \
+ } \
+} while (0)
+
+#define TRACE_FP_INPUT_FPU2(V0, V1) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ { \
+ unsigned64 f0, f1; \
+ sim_fpu_to64 (&f0, (V0)); \
+ sim_fpu_to64 (&f1, (V1)); \
+ trace_input_fp2 (SD, CPU, TRACE_FPU_IDX, f0, f1); \
+ } \
+} while (0)
+
+#define TRACE_FP_INPUT_FPU3(V0, V1, V2) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ { \
+ unsigned64 f0, f1, f2; \
+ sim_fpu_to64 (&f0, (V0)); \
+ sim_fpu_to64 (&f1, (V1)); \
+ sim_fpu_to64 (&f2, (V2)); \
+ trace_input_fp3 (SD, CPU, TRACE_FPU_IDX, f0, f1, f2); \
+ } \
+} while (0)
+
+#define TRACE_FP_INPUT_BOOL1_FPU2(V0, V1, V2) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ { \
+ int d0 = (V0); \
+ unsigned64 f1, f2; \
+ TRACE_DATA *data = CPU_TRACE_DATA (CPU); \
+ TRACE_IDX (data) = TRACE_FPU_IDX; \
+ sim_fpu_to64 (&f1, (V1)); \
+ sim_fpu_to64 (&f2, (V2)); \
+ save_data (SD, data, trace_fmt_bool, sizeof (d0), &d0); \
+ save_data (SD, data, trace_fmt_fp, sizeof (fp_word), &f1); \
+ save_data (SD, data, trace_fmt_fp, sizeof (fp_word), &f2); \
+ } \
+} while (0)
+
+#define TRACE_FP_INPUT_WORD2(V0, V1) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ trace_input_word2 (SD, CPU, TRACE_FPU_IDX, (V0), (V1)); \
+} while (0)
+
+#define TRACE_FP_RESULT_FPU1(R0) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ { \
+ unsigned64 f0; \
+ sim_fpu_to64 (&f0, (R0)); \
+ trace_result_fp1 (SD, CPU, TRACE_FPU_IDX, f0); \
+ } \
+} while (0)
+
+#define TRACE_FP_RESULT_WORD1(R0) TRACE_FP_RESULT_WORD(R0)
+
+#define TRACE_FP_RESULT_WORD2(R0, R1) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ trace_result_word2 (SD, CPU, TRACE_FPU_IDX, (R0), (R1)); \
+} while (0)
+
#else
#define trace_input(NAME, IN1, IN2)
#define trace_output(RESULT)
diff -upNr gdb-7.2.50-original/sim/v850/simops.c gdb-7.2.50-modified/sim/v850/simops.c
--- gdb-7.2.50-original/sim/v850/simops.c 2008-02-06 10:11:26.000000000 +0530
+++ gdb-7.2.50-modified/sim/v850/simops.c 2010-12-08 14:52:54.000000000 +0530
@@ -320,7 +320,7 @@ condition_met (unsigned code)
return 1;
}
-static unsigned long
+unsigned long
Add32 (unsigned long a1, unsigned long a2, int * carry)
{
unsigned long result = (a1 + a2);
@@ -2761,3 +2761,717 @@ OP_307E0 (void)
return 4;
}
+/* V850E2R FPU functions */
+/*
+ sim_fpu_status_invalid_snan = 1, -V--- (sim spec.)
+ sim_fpu_status_invalid_qnan = 2, ----- (sim spec.)
+ sim_fpu_status_invalid_isi = 4, (inf - inf) -V---
+ sim_fpu_status_invalid_idi = 8, (inf / inf) -V---
+ sim_fpu_status_invalid_zdz = 16, (0 / 0) -V---
+ sim_fpu_status_invalid_imz = 32, (inf * 0) -V---
+ sim_fpu_status_invalid_cvi = 64, convert to integer -V---
+ sim_fpu_status_invalid_div0 = 128, (X / 0) --Z--
+ sim_fpu_status_invalid_cmp = 256, compare ----- (sim spec.)
+ sim_fpu_status_invalid_sqrt = 512, -V---
+ sim_fpu_status_rounded = 1024, I----
+ sim_fpu_status_inexact = 2048, I---- (sim spec.)
+ sim_fpu_status_overflow = 4096, I--O-
+ sim_fpu_status_underflow = 8192, I---U
+ sim_fpu_status_denorm = 16384, ----U (sim spec.)
+*/
+
+void update_fpsr (SIM_DESC sd, sim_fpu_status status, unsigned int mask, unsigned int double_op_p)
+{
+ unsigned int fpsr = FPSR & mask;
+
+ unsigned int flags = 0;
+
+ if (fpsr & FPSR_XEI
+ && ((status & (sim_fpu_status_rounded
+ | sim_fpu_status_overflow
+ | sim_fpu_status_inexact))
+ || (status & sim_fpu_status_underflow
+ && (fpsr & (FPSR_XEU | FPSR_XEI)) == 0
+ && fpsr & FPSR_FS)))
+ {
+ flags |= FPSR_XCI | FPSR_XPI;
+ }
+
+ if (fpsr & FPSR_XEV
+ && (status & (sim_fpu_status_invalid_isi
+ | sim_fpu_status_invalid_imz
+ | sim_fpu_status_invalid_zdz
+ | sim_fpu_status_invalid_idi
+ | sim_fpu_status_invalid_cvi
+ | sim_fpu_status_invalid_sqrt
+ | sim_fpu_status_invalid_snan)))
+ {
+ flags |= FPSR_XCV | FPSR_XPV;
+ }
+
+ if (fpsr & FPSR_XEZ
+ && (status & sim_fpu_status_invalid_div0))
+ {
+ flags |= FPSR_XCV | FPSR_XPV;
+ }
+
+ if (fpsr & FPSR_XEO
+ && (status & sim_fpu_status_overflow))
+ {
+ flags |= FPSR_XCO | FPSR_XPO;
+ }
+
+ if (((fpsr & FPSR_XEU) || (fpsr & FPSR_FS) == 0)
+ && (status & (sim_fpu_status_underflow
+ | sim_fpu_status_denorm)))
+ {
+ flags |= FPSR_XCU | FPSR_XPU;
+ }
+
+ if (flags)
+ {
+ FPSR &= ~FPSR_XC;
+ FPSR |= flags;
+
+ SignalExceptionFPE(sd, double_op_p);
+ }
+}
+
+/*
+ exception
+*/
+
+void SignalException(SIM_DESC sd)
+{
+ if (MPM & MPM_AUE)
+ {
+ PSW = PSW & ~(PSW_NPV | PSW_DMP | PSW_IMP);
+ }
+}
+
+void SignalExceptionFPE(SIM_DESC sd, unsigned int double_op_p)
+{
+ if (((PSW & (PSW_NP|PSW_ID)) == 0)
+ || !(FPSR & (double_op_p ? FPSR_DEM : FPSR_SEM)))
+ {
+ EIPC = PC;
+ EIPSW = PSW;
+ EIIC = (FPSR & (double_op_p ? FPSR_DEM : FPSR_SEM))
+ ? 0x71 : 0x72;
+ PSW |= (PSW_EP | PSW_ID);
+ PC = 0x70;
+
+ SignalException(sd);
+ }
+}
+
+
+void check_invalid_snan(SIM_DESC sd, sim_fpu_status status, unsigned int double_op_p)
+{
+ if ((FPSR & FPSR_XEI)
+ && (status & sim_fpu_status_invalid_snan))
+ {
+ FPSR &= ~FPSR_XC;
+ FPSR |= FPSR_XCV;
+ FPSR |= FPSR_XPV;
+ SignalExceptionFPE(sd, double_op_p);
+ }
+}
+
+int v850_float_compare(SIM_DESC sd, int cmp, sim_fpu wop1, sim_fpu wop2, int double_op_p)
+{
+ int result = -1;
+
+ if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2))
+ {
+ if (cmp & 0x8)
+ {
+ if (FPSR & FPSR_XEV)
+ {
+ FPSR |= FPSR_XCV | FPSR_XPV;
+ SignalExceptionFPE(sd, double_op_p);
+ }
+ }
+
+ switch (cmp)
+ {
+ case FPU_CMP_F:
+ result = 0;
+ break;
+ case FPU_CMP_UN:
+ result = 1;
+ break;
+ case FPU_CMP_EQ:
+ result = 0;
+ break;
+ case FPU_CMP_UEQ:
+ result = 1;
+ break;
+ case FPU_CMP_OLT:
+ result = 0;
+ break;
+ case FPU_CMP_ULT:
+ result = 1;
+ break;
+ case FPU_CMP_OLE:
+ result = 0;
+ break;
+ case FPU_CMP_ULE:
+ result = 1;
+ break;
+ case FPU_CMP_SF:
+ result = 0;
+ break;
+ case FPU_CMP_NGLE:
+ result = 1;
+ break;
+ case FPU_CMP_SEQ:
+ result = 0;
+ break;
+ case FPU_CMP_NGL:
+ result = 1;
+ break;
+ case FPU_CMP_LT:
+ result = 0;
+ break;
+ case FPU_CMP_NGE:
+ result = 1;
+ break;
+ case FPU_CMP_LE:
+ result = 0;
+ break;
+ case FPU_CMP_NGT:
+ result = 1;
+ break;
+ default:
+ abort();
+ }
+ }
+ else if (sim_fpu_is_infinity(&wop1) && sim_fpu_is_infinity(&wop2)
+ && sim_fpu_sign(&wop1) == sim_fpu_sign(&wop2))
+ {
+ switch (cmp)
+ {
+ case FPU_CMP_F:
+ result = 0;
+ break;
+ case FPU_CMP_UN:
+ result = 0;
+ break;
+ case FPU_CMP_EQ:
+ result = 1;
+ break;
+ case FPU_CMP_UEQ:
+ result = 1;
+ break;
+ case FPU_CMP_OLT:
+ result = 0;
+ break;
+ case FPU_CMP_ULT:
+ result = 0;
+ break;
+ case FPU_CMP_OLE:
+ result = 1;
+ break;
+ case FPU_CMP_ULE:
+ result = 1;
+ break;
+ case FPU_CMP_SF:
+ result = 0;
+ break;
+ case FPU_CMP_NGLE:
+ result = 0;
+ break;
+ case FPU_CMP_SEQ:
+ result = 1;
+ break;
+ case FPU_CMP_NGL:
+ result = 1;
+ break;
+ case FPU_CMP_LT:
+ result = 0;
+ break;
+ case FPU_CMP_NGE:
+ result = 0;
+ break;
+ case FPU_CMP_LE:
+ result = 1;
+ break;
+ case FPU_CMP_NGT:
+ result = 1;
+ break;
+ default:
+ abort();
+ }
+ }
+ else
+ {
+ int gt = 0,lt = 0,eq = 0, status;
+
+ status = sim_fpu_cmp( &wop1, &wop2 );
+
+ switch (status) {
+ case SIM_FPU_IS_SNAN:
+ case SIM_FPU_IS_QNAN:
+ abort();
+ break;
+
+ case SIM_FPU_IS_NINF:
+ lt = 1;
+ break;
+ case SIM_FPU_IS_PINF:
+ gt = 1;
+ break;
+ case SIM_FPU_IS_NNUMBER:
+ lt = 1;
+ break;
+ case SIM_FPU_IS_PNUMBER:
+ gt = 1;
+ break;
+ case SIM_FPU_IS_NDENORM:
+ lt = 1;
+ break;
+ case SIM_FPU_IS_PDENORM:
+ gt = 1;
+ break;
+ case SIM_FPU_IS_NZERO:
+ case SIM_FPU_IS_PZERO:
+ eq = 1;
+ break;
+ }
+
+ switch (cmp)
+ {
+ case FPU_CMP_F:
+ result = 0;
+ break;
+ case FPU_CMP_UN:
+ result = 0;
+ break;
+ case FPU_CMP_EQ:
+ result = eq;
+ break;
+ case FPU_CMP_UEQ:
+ result = eq;
+ break;
+ case FPU_CMP_OLT:
+ result = lt;
+ break;
+ case FPU_CMP_ULT:
+ result = lt;
+ break;
+ case FPU_CMP_OLE:
+ result = lt || eq;
+ break;
+ case FPU_CMP_ULE:
+ result = lt || eq;
+ break;
+ case FPU_CMP_SF:
+ result = 0;
+ break;
+ case FPU_CMP_NGLE:
+ result = 0;
+ break;
+ case FPU_CMP_SEQ:
+ result = eq;
+ break;
+ case FPU_CMP_NGL:
+ result = eq;
+ break;
+ case FPU_CMP_LT:
+ result = lt;
+ break;
+ case FPU_CMP_NGE:
+ result = lt;
+ break;
+ case FPU_CMP_LE:
+ result = lt || eq;
+ break;
+ case FPU_CMP_NGT:
+ result = lt || eq;
+ break;
+ }
+ }
+
+ ASSERT(result != -1);
+ return result;
+}
+
+void v850_div(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p, unsigned int *op3p)
+{
+ signed long int quotient;
+ signed long int remainder;
+ signed long int divide_by;
+ signed long int divide_this;
+ bfd_boolean overflow = FALSE;
+
+ /* Compute the result. */
+ divide_by = op0;
+ divide_this = op1;
+
+ if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31)))
+ {
+ overflow = TRUE;
+ divide_by = 1;
+ }
+
+ quotient = divide_this / divide_by;
+ remainder = divide_this % divide_by;
+
+ /* Set condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_OV);
+
+ if (overflow) PSW |= PSW_OV;
+ if (quotient == 0) PSW |= PSW_Z;
+ if (quotient < 0) PSW |= PSW_S;
+
+ *op2p = quotient;
+ *op3p = remainder;
+}
+
+void v850_divu(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p, unsigned int *op3p)
+{
+ unsigned long int quotient;
+ unsigned long int remainder;
+ unsigned long int divide_by;
+ unsigned long int divide_this;
+ bfd_boolean overflow = FALSE;
+
+ /* Compute the result. */
+
+ divide_by = op0;
+ divide_this = op1;
+
+ if (divide_by == 0)
+ {
+ overflow = TRUE;
+ divide_by = 1;
+ }
+
+ quotient = divide_this / divide_by;
+ remainder = divide_this % divide_by;
+
+ /* Set condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_OV);
+
+ if (overflow) PSW |= PSW_OV;
+ if (quotient == 0) PSW |= PSW_Z;
+ if (quotient & 0x80000000) PSW |= PSW_S;
+
+ *op2p = quotient;
+ *op3p = remainder;
+}
+
+
+void v850_sar(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
+{
+ unsigned int result, z, s, cy;
+
+ op0 &= 0x1f;
+ result = (signed)op1 >> op0;
+
+ /* Compute the condition codes. */
+ z = (result == 0);
+ s = (result & 0x80000000);
+ cy = (op1 & (1 << (op0 - 1)));
+
+ /* Store the result and condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
+ PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+ | (cy ? PSW_CY : 0));
+
+ *op2p = result;
+}
+
+void v850_shl(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
+{
+ unsigned int result, z, s, cy;
+
+ op0 &= 0x1f;
+ result = op1 << op0;
+
+ /* Compute the condition codes. */
+ z = (result == 0);
+ s = (result & 0x80000000);
+ cy = (op1 & (1 << (32 - op0)));
+
+ /* Store the result and condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
+ PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+ | (cy ? PSW_CY : 0));
+
+ *op2p = result;
+}
+
+void v850_shr(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
+{
+ unsigned int result, z, s, cy;
+
+ op0 &= 0x1f;
+ result = op1 >> op0;
+
+ /* Compute the condition codes. */
+ z = (result == 0);
+ s = (result & 0x80000000);
+ cy = (op1 & (1 << (op0 - 1)));
+
+ /* Store the result and condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
+ PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+ | (cy ? PSW_CY : 0));
+
+ *op2p = result;
+}
+
+void v850_satadd(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
+{
+ unsigned int result, z, s, cy, ov, sat;
+
+ result = op0 + op1;
+
+ /* Compute the condition codes. */
+ z = (result == 0);
+ s = (result & 0x80000000);
+ cy = (result < op0 || result < op1);
+ ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
+ && (op0 & 0x80000000) != (result & 0x80000000));
+ sat = ov;
+
+ /* Store the result and condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+ PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+ | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
+ | (sat ? PSW_SAT : 0));
+
+ /* Handle saturated results. */
+ if (sat && s)
+ {
+ result = 0x7fffffff;
+ PSW &= ~PSW_S;
+ }
+ else if (sat)
+ {
+ result = 0x80000000;
+ PSW |= PSW_S;
+ }
+
+ *op2p = result;
+}
+
+void v850_satsub(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
+{
+ unsigned int result, z, s, cy, ov, sat;
+
+ /* Compute the result. */
+ result = op1 - op0;
+
+ /* Compute the condition codes. */
+ z = (result == 0);
+ s = (result & 0x80000000);
+ cy = (op1 < op0);
+ ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
+ && (op1 & 0x80000000) != (result & 0x80000000));
+ sat = ov;
+
+ /* Store the result and condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+ PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+ | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
+ | (sat ? PSW_SAT : 0));
+
+ /* Handle saturated results. */
+ if (sat && s)
+ {
+ result = 0x7fffffff;
+ PSW &= ~PSW_S;
+ }
+ else if (sat)
+ {
+ result = 0x80000000;
+ PSW |= PSW_S;
+ }
+
+ *op2p = result;
+}
+
+unsigned32
+load_data_mem(sd, addr, len)
+ SIM_DESC sd;
+ SIM_ADDR addr;
+ int len;
+{
+ uint32 data;
+
+ switch (len)
+ {
+ case 1:
+ data = sim_core_read_unaligned_1 (STATE_CPU (sd, 0),
+ PC, read_map, addr);
+ break;
+ case 2:
+ data = sim_core_read_unaligned_2 (STATE_CPU (sd, 0),
+ PC, read_map, addr);
+ break;
+ case 4:
+ data = sim_core_read_unaligned_4 (STATE_CPU (sd, 0),
+ PC, read_map, addr);
+ break;
+ default:
+ abort ();
+ }
+ return data;
+}
+
+void
+store_data_mem(sd, addr, len, data)
+ SIM_DESC sd;
+ SIM_ADDR addr;
+ int len;
+ unsigned32 data;
+{
+ switch (len)
+ {
+ case 1:
+ store_mem(addr, 1, data);
+ break;
+ case 2:
+ store_mem(addr, 2, data);
+ break;
+ case 4:
+ store_mem(addr, 4, data);
+ break;
+ default:
+ abort ();
+ }
+}
+
+int mpu_load_mem_test(SIM_DESC sd, unsigned int addr, int size, int base_reg)
+{
+ int result = 1;
+
+ if (PSW & PSW_DMP)
+ {
+ if (IPE0 && addr >= IPA2ADDR(IPA0L) && addr <= IPA2ADDR(IPA0L) && IPR0)
+ {
+ /* text area */
+ }
+ else if (IPE1 && addr >= IPA2ADDR(IPA1L) && addr <= IPA2ADDR(IPA1L) && IPR1)
+ {
+ /* text area */
+ }
+ else if (IPE2 && addr >= IPA2ADDR(IPA2L) && addr <= IPA2ADDR(IPA2L) && IPR2)
+ {
+ /* text area */
+ }
+ else if (IPE3 && addr >= IPA2ADDR(IPA3L) && addr <= IPA2ADDR(IPA3L) && IPR3)
+ {
+ /* text area */
+ }
+ else if (addr >= PPA2ADDR(PPA & ~PPM) && addr <= DPA2ADDR(PPA | PPM))
+ {
+ /* preifarallel area */
+ }
+ else if (addr >= PPA2ADDR(SPAL) && addr <= DPA2ADDR(SPAU))
+ {
+ /* stack area */
+ }
+ else if (DPE0 && addr >= DPA2ADDR(DPA0L) && addr <= DPA2ADDR(DPA0L) && DPR0
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else if (DPE1 && addr >= DPA2ADDR(DPA1L) && addr <= DPA2ADDR(DPA1L) && DPR1
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else if (DPE2 && addr >= DPA2ADDR(DPA2L) && addr <= DPA2ADDR(DPA2L) && DPR2
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else if (DPE3 && addr >= DPA2ADDR(DPA3L) && addr <= DPA2ADDR(DPA3L) && DPR3
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else
+ {
+ VMECR &= ~(VMECR_VMW | VMECR_VMX);
+ VMECR |= VMECR_VMR;
+ VMADR = addr;
+ VMTID = TID;
+ FEIC = 0x431;
+
+ PC = 0x30;
+
+ SignalException(sd);
+ result = 0;
+ }
+ }
+
+ return result;
+}
+
+int mpu_store_mem_test(SIM_DESC sd, unsigned int addr, int size, int base_reg)
+{
+ int result = 1;
+
+ if (PSW & PSW_DMP)
+ {
+ if (addr >= PPA2ADDR(PPA & ~PPM) && addr <= DPA2ADDR(PPA | PPM))
+ {
+ /* preifarallel area */
+ }
+ else if (addr >= PPA2ADDR(SPAL) && addr <= DPA2ADDR(SPAU))
+ {
+ /* stack area */
+ }
+ else if (DPE0 && addr >= DPA2ADDR(DPA0L) && addr <= DPA2ADDR(DPA0L) && DPW0
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else if (DPE1 && addr >= DPA2ADDR(DPA1L) && addr <= DPA2ADDR(DPA1L) && DPW1
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else if (DPE2 && addr >= DPA2ADDR(DPA2L) && addr <= DPA2ADDR(DPA2L) && DPW2
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else if (DPE3 && addr >= DPA2ADDR(DPA3L) && addr <= DPA2ADDR(DPA3L) && DPW3
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else
+ {
+ if (addr >= PPA2ADDR(PPA & ~PPM) && addr <= DPA2ADDR(PPA | PPM))
+ {
+ FEIC = 0x432;
+ VPTID = TID;
+ VPADR = PC;
+#ifdef NOT_YET
+ VIP_PP;
+ VPECR;
+#endif
+ }
+ else
+ {
+ FEIC = 0x431;
+ VMTID = TID;
+ VMADR = VMECR;
+ VMECR &= ~(VMECR_VMW | VMECR_VMX);
+ VMECR |= VMECR_VMR;
+ PC = 0x30;
+ }
+ result = 0;
+ }
+ }
+
+ return result;
+}
+
diff -upNr gdb-7.2.50-original/sim/v850/simops.h gdb-7.2.50-modified/sim/v850/simops.h
--- gdb-7.2.50-original/sim/v850/simops.h 2003-04-06 14:21:04.000000000 +0530
+++ gdb-7.2.50-modified/sim/v850/simops.h 2010-12-08 14:52:56.000000000 +0530
@@ -75,4 +75,51 @@ int OP_22007E0 (void);
int OP_307F0 (void);
int OP_107F0 (void);
int OP_307E0 (void);
+
+int v850_float_compare(SIM_DESC sd, int cmp, sim_fpu wop1, sim_fpu wop2, int double_op_p);
+
+/* MEMORY ACCESS */
+unsigned32 load_data_mem(SIM_DESC sd, SIM_ADDR addr, int len);
+void store_data_mem(SIM_DESC sd, SIM_ADDR addr, int len, unsigned32 data);
+
+unsigned long Add32 (unsigned long a1, unsigned long a2, int * carry);
+
+/* FPU */
+
+/*
+ FPU: update FPSR flags
+ invalid, inexact, overflow, underflow
+ */
+
+extern void check_invalid_snan (SIM_DESC sd, sim_fpu_status, unsigned int);
+
+#define check_cvt_fi(sd, status, double_op_p) \
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI, double_op_p)
+
+#define check_cvt_if(sd, status, double_op_p) \
+ update_fpsr (sd, status, FPSR_XEI, double_op_p)
+
+#define check_cvt_ff(sd, status, double_op_p) \
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, double_op_p)
+
+extern void update_fpsr (SIM_DESC sd, sim_fpu_status, unsigned int, unsigned int);
+
+
+/*
+ Exception
+ */
+void SignalException (SIM_DESC sd);
+void SignalExceptionFPE (SIM_DESC sd, unsigned int double_op_p);
+
+int mpu_load_mem_test (SIM_DESC sd, unsigned int addr, int len, int base_reg);
+int mpu_store_mem_test (SIM_DESC sd, unsigned int addr, int len, int base_reg);
+
+void v850_sar (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p);
+void v850_shl (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p);
+void v850_shr (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p);
+void v850_satadd (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p);
+void v850_satsub (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p);
+void v850_div (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p, unsigned int *op3p);
+void v850_divu (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p, unsigned int *op3p);
+
#endif
diff -upNr gdb-7.2.50-original/sim/v850/v850-dc gdb-7.2.50-modified/sim/v850/v850-dc
--- gdb-7.2.50-original/sim/v850/v850-dc 2003-09-05 23:16:52.000000000 +0530
+++ gdb-7.2.50-modified/sim/v850/v850-dc 2010-12-08 14:53:11.000000000 +0530
@@ -12,7 +12,9 @@
switch,combine : 4 : 0 : : : : 1 : V,VII :
switch,combine : 4 : 0 : : : : 1 : V,XIII : v850e
switch,combine : 4 : 0 : : : : 1 : V,XIII : v850e1
-
+ switch,combine : 4 : 0 : : : : 1 : V,XIII : v850e2
+ switch,combine : 4 : 0 : : : : 1 : V,XIII : v850e2v3
+ switch,combine : 10 : 5 : : : : 0 : F_I : v850e2v3
# for opcode 63, 127, 1087 et.al.
@@ -27,3 +29,28 @@
# for opcode 66 - divh/break
switch,combine : 4 : 0 : : : : 0 : I :
+
+# for ilgop, macu
+ switch,combine : 10 : 9 : : : : 1 : X,XI : v850e2
+ switch,combine : 10 : 9 : : : : 1 : X,XI : v850e2v3
+
+#for cmovf.s, setf
+ switch,combine : 10 : 10 : : : : 1 :F_I,IX : v850e2v3
+
+# for cmovf.s trfsr
+ switch,combine : 15 : 11 : : : : 1 :F_I : v850e2v3
+
+# for trncf.sw, cvtf.sw
+ switch,combine : 0 : 0 : : : : 0 :F_I : v850e2v3
+ switch,combine : 3 : 3 : : : : 0 :F_I : v850e2v3
+
+# for rsqrtf.s, sqrtf.s
+ switch,combine : 1 : 1 : : : : 0 :F_I : v850e2v3
+
+# for maddf.s, trap
+ switch,combine : 8 : 8 : : : : 1 :F_I,X : v850e2v3
+ switch,combine : 10 : 10 : : : : 1 :F_I,X : v850e2v3
+
+# for jr32 jarl32
+ switch,combine : 4 : 0 : : : : 0 :VI : v850e2
+ switch,combine : 4 : 0 : : : : 0 :VI : v850e2v3
diff -upNr gdb-7.2.50-original/sim/v850/v850.igen gdb-7.2.50-modified/sim/v850/v850.igen
--- gdb-7.2.50-original/sim/v850/v850.igen 2008-02-06 10:11:26.000000000 +0530
+++ gdb-7.2.50-modified/sim/v850/v850.igen 2010-12-08 17:33:09.000000000 +0530
@@ -6,6 +6,7 @@
:option:::format-names:XI,XII,XIII
:option:::format-names:XIV,XV
:option:::format-names:Z
+:option:::format-names:F_I
:model:::v850:v850:
@@ -14,12 +15,22 @@
:model:::v850e:v850e:
:option:::multi-sim:true
:model:::v850e1:v850e1:
+:option:::multi-sim:true
+:model:::v850e2:v850e2:
+:option:::multi-sim:true
+:model:::v850e2v3:v850e2v3:
// Cache macros
:cache:::unsigned:reg1:RRRRR:(RRRRR)
:cache:::unsigned:reg2:rrrrr:(rrrrr)
:cache:::unsigned:reg3:wwwww:(wwwww)
+:cache:::unsigned:reg4:W,WWWW:((W << 4) + WWWW)
+
+:cache:::unsigned:reg1e:RRRR:(RRRR << 1)
+:cache:::unsigned:reg2e:rrrr:(rrrr << 1)
+:cache:::unsigned:reg3e:wwww:(wwww << 1)
+:cache:::unsigned:reg4e:mmmm:(mmmm << 1)
:cache:::unsigned:disp4:dddd:(dddd)
:cache:::unsigned:disp5:dddd:(dddd << 1)
@@ -29,7 +40,10 @@
:cache:::unsigned:disp9:ddddd,ddd:SEXT32 ((ddddd << 4) + (ddd << 1), 9 - 1)
:cache:::unsigned:disp16:dddddddddddddddd:EXTEND16 (dddddddddddddddd)
:cache:::unsigned:disp16:ddddddddddddddd: EXTEND16 (ddddddddddddddd << 1)
+:cache:::unsigned:disp17:d,ddddddddddddddd:SEXT32 (((d <<16) + (ddddddddddddddd << 1)), 17 - 1)
:cache:::unsigned:disp22:dddddd,ddddddddddddddd: SEXT32 ((dddddd << 16) + (ddddddddddddddd << 1), 22 - 1)
+:cache:::unsigned:disp23:ddddddd,dddddddddddddddd: SEXT32 ((ddddddd) + (dddddddddddddddd << 7), 23 - 1)
+:cache:::unsigned:disp23:dddddd,dddddddddddddddd: SEXT32 ((dddddd << 1) + (dddddddddddddddd << 7), 23 - 1)
:cache:::unsigned:imm5:iiiii:SEXT32 (iiiii, 4)
:cache:::unsigned:imm6:iiiiii:iiiiii
@@ -46,6 +60,7 @@
:cache:::unsigned:list18:LLLL,LLLLLLLLLLLL:((LLLL << 12) + LLLLLLLLLLLL)
:cache:::unsigned:bit3:bbb:bbb
+:cache:::unsigned:bit4:bbbb:bbbb
// What do we do with an illegal instruction?
@@ -58,8 +73,7 @@
-// Add
-
+// ADD
rrrrr,001110,RRRRR:I:::add
"add r<reg1>, r<reg2>"
{
@@ -83,6 +97,20 @@ rrrrr,110000,RRRRR + iiiiiiiiiiiiiiii:VI
+// ADF
+rrrrr,111111,RRRRR + wwwww,011101,cccc!13,0:XI:::adf
+*v850e2
+*v850e2v3
+"adf %s<cccc>, r<reg1>, r<reg2>, r<reg3>"
+{
+ int cond = condition_met (cccc);
+ TRACE_ALU_INPUT3 (cond, GR[reg1], GR[reg2]);
+ GR[reg3] = GR[reg1] + GR[reg2] + (cond ? 1 : 0);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+
+
// AND
rrrrr,001010,RRRRR:I:::and
"and r<reg1>, r<reg2>"
@@ -153,12 +181,27 @@ ddddd,1011,ddd,cccc:III:::Bcond
}
}
+00000111111,d,cccc + ddddddddddddddd,1:VII:::Bcond
+"breakpoint":((disp17 == 0) && (cccc == 0x05))
+"b%s<cccc> <disp17>"
+*v850e2v3
+{
+ int cond;
+ cond = condition_met (cccc);
+ if (cond)
+ nia = cia + disp17;
+ TRACE_BRANCH_INPUT1 (cond);
+ TRACE_BRANCH_RESULT (nia);
+}
+
// BSH
rrrrr,11111100000 + wwwww,01101000010:XII:::bsh
*v850e
*v850e1
+*v850e2
+*v850e2v3
"bsh r<reg2>, r<reg3>"
{
unsigned32 value;
@@ -178,10 +221,14 @@ rrrrr,11111100000 + wwwww,01101000010:XI
TRACE_ALU_RESULT (GR[reg3]);
}
+
+
// BSW
rrrrr,11111100000 + wwwww,01101000000:XII:::bsw
*v850e
*v850e1
+*v850e2
+*v850e2v3
"bsw r<reg2>, r<reg3>"
{
#define WORDHASNULLBYTE(x) (((x) - 0x01010101) & ~(x)&0x80808080)
@@ -204,10 +251,14 @@ rrrrr,11111100000 + wwwww,01101000000:XI
TRACE_ALU_RESULT (GR[reg3]);
}
+
+
// CALLT
0000001000,iiiiii:II:::callt
*v850e
*v850e1
+*v850e2
+*v850e2v3
"callt <imm6>"
{
unsigned32 adr;
@@ -221,6 +272,55 @@ rrrrr,11111100000 + wwwww,01101000000:XI
}
+
+// CAXI
+rrrrr,111111,RRRRR + wwwww,00011101110:IX:::caxi
+*v850e2
+*v850e2v3
+"caxi [reg1], reg2, reg3"
+{
+ unsigned int z,s,cy,ov;
+ unsigned32 addr;
+ unsigned32 token,result;
+
+ addr = GR[reg1];
+
+ if (mpu_load_mem_test(sd, addr, 4, reg1)
+ && mpu_store_mem_test(sd, addr, 4, reg1))
+ {
+ token = load_data_mem (sd, addr, 4);
+
+ TRACE_ALU_INPUT2 (token, GR[reg2]);
+
+ result = GR[reg2] - token;
+
+ z = (result == 0);
+ s = (result & 0x80000000);
+ cy = (GR[reg2] < token);
+ ov = ((GR[reg2] & 0x80000000) != (token & 0x80000000)
+ && (GR[reg2] & 0x80000000) != (result & 0x80000000));
+
+ if (result == 0)
+ {
+ store_data_mem (sd, addr, 4, GR[reg3]);
+ GR[reg3] = token;
+ }
+ else
+ {
+ store_data_mem (sd, addr, 4, token);
+ GR[reg3] = token;
+ }
+
+ /* Set condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+ PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+ | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
+
+ TRACE_ALU_RESULT1 (GR[reg3]);
+ }
+}
+
+
// CLR1
10,bbb,111110,RRRRR + dddddddddddddddd:VIII:::clr1
"clr1 <bit3>, <disp16>[r<reg1>]"
@@ -231,16 +331,21 @@ rrrrr,11111100000 + wwwww,01101000000:XI
rrrrr,111111,RRRRR + 0000000011100100:IX:::clr1
*v850e
*v850e1
+*v850e2
+*v850e2v3
"clr1 r<reg2>, [r<reg1>]"
{
COMPAT_2 (OP_E407E0 ());
}
+
// CTRET
0000011111100000 + 0000000101000100:X:::ctret
*v850e
*v850e1
+*v850e2
+*v850e2v3
"ctret"
{
nia = (CTPC & ~1);
@@ -248,10 +353,14 @@ rrrrr,111111,RRRRR + 0000000011100100:IX
TRACE_BRANCH1 (PSW);
}
+
+
// CMOV
rrrrr,111111,RRRRR + wwwww,011001,cccc,0:XI:::cmov
*v850e
*v850e1
+*v850e2
+*v850e2v3
"cmov %s<cccc>, r<reg1>, r<reg2>, r<reg3>"
{
int cond = condition_met (cccc);
@@ -263,6 +372,8 @@ rrrrr,111111,RRRRR + wwwww,011001,cccc,0
rrrrr,111111,iiiii + wwwww,011000,cccc,0:XII:::cmov
*v850e
*v850e1
+*v850e2
+*v850e2v3
"cmov %s<cccc>, <imm5>, r<reg2>, r<reg3>"
{
int cond = condition_met (cccc);
@@ -271,6 +382,8 @@ rrrrr,111111,iiiii + wwwww,011000,cccc,0
TRACE_ALU_RESULT (GR[reg3]);
}
+
+
// CMP
rrrrr,001111,RRRRR:I:::cmp
"cmp r<reg1>, r<reg2>"
@@ -301,6 +414,8 @@ rrrrr,010011,iiiii:II:::cmp
0000011001,iiiii,L + LLLLLLLLLLL,RRRRR:XIII:::dispose
*v850e
*v850e1
+*v850e2
+*v850e2v3
"dispose <imm5>, <list12>":RRRRR == 0
"dispose <imm5>, <list12>, [reg1]"
{
@@ -329,10 +444,13 @@ rrrrr,010011,iiiii:II:::cmp
}
+
// DIV
rrrrr,111111,RRRRR + wwwww,01011000000:XI:::div
*v850e
*v850e1
+*v850e2
+*v850e2v3
"div r<reg1>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_2C007E0 ());
@@ -390,6 +508,8 @@ rrrrr!0,000010,RRRRR!0:I:::divh
rrrrr,111111,RRRRR + wwwww,01010000000:XI:::divh
*v850e
*v850e1
+*v850e2
+*v850e2v3
"divh r<reg1>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_28007E0 ());
@@ -400,6 +520,8 @@ rrrrr,111111,RRRRR + wwwww,01010000000:X
rrrrr,111111,RRRRR + wwwww,01010000010:XI:::divhu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"divhu r<reg1>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_28207E0 ());
@@ -410,12 +532,60 @@ rrrrr,111111,RRRRR + wwwww,01010000010:X
rrrrr,111111,RRRRR + wwwww,01011000010:XI:::divu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"divu r<reg1>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_2C207E0 ());
}
+// DIVQ
+rrrrr,111111,RRRRR + wwwww,01011111100:XI:::divq
+*v850e2
+*v850e2v3
+"divq r<reg1>, r<reg2>, r<reg3>"
+{
+ unsigned int quotient;
+ unsigned int remainder;
+ unsigned int divide_by;
+ unsigned int divide_this;
+
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+
+ divide_by = GR[reg1];
+ divide_this = GR[reg2];
+ v850_div (sd, divide_by, divide_this, "ient, &remainder);
+ GR[reg2] = quotient;
+ GR[reg3] = remainder;
+
+ TRACE_ALU_RESULT2 (GR[reg2], GR[reg3]);
+}
+
+
+// DIVQU
+rrrrr,111111,RRRRR + wwwww,01011111110:XI:::divqu
+*v850e2
+*v850e2v3
+"divq r<reg1>, r<reg2>, r<reg3>"
+{
+ unsigned int quotient;
+ unsigned int remainder;
+ unsigned int divide_by;
+ unsigned int divide_this;
+
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+
+ divide_by = GR[reg1];
+ divide_this = GR[reg2];
+ v850_divu (sd, divide_by, divide_this, "ient, &remainder);
+ GR[reg2] = quotient;
+ GR[reg3] = remainder;
+
+ TRACE_ALU_RESULT2 (GR[reg2], GR[reg3]);
+}
+
+
// EI
1000011111100000 + 0000000101100000:X:::ei
"ei"
@@ -425,6 +595,76 @@ rrrrr,111111,RRRRR + wwwww,01011000010:X
+// EIRET
+0000011111100000 + 0000000101001000:X:::eiret
+"eiret"
+*v850e2
+*v850e2v3
+{
+ TRACE_ALU_INPUT1 (MPM & MPM_AUE);
+
+ nia = EIPC; /* next PC */
+ if (MPM & MPM_AUE)
+ {
+ PSW = EIPSW;
+ }
+ else
+ {
+ PSW = (PSW & (PSW_NPV | PSW_DMP | PSW_IMP))
+ | (EIPSW & ~(PSW_NPV | PSW_DMP | PSW_IMP));
+ }
+
+ TRACE_ALU_RESULT1 (PSW);
+ TRACE_BRANCH_RESULT (nia);
+}
+
+
+
+// FERET
+0000011111100000 + 0000000101001010:X:::feret
+"feret"
+*v850e2
+*v850e2v3
+{
+ TRACE_ALU_INPUT1 (MPM & MPM_AUE);
+
+ nia = FEPC; /* next PC */
+ if (MPM & MPM_AUE)
+ {
+ PSW = FEPSW;
+ }
+ else
+ {
+ PSW = (PSW & (PSW_NPV | PSW_DMP | PSW_IMP))
+ | (FEPSW & ~(PSW_NPV | PSW_DMP | PSW_IMP));
+ }
+
+ TRACE_ALU_RESULT1 (PSW);
+ TRACE_BRANCH_RESULT (nia);
+}
+
+
+// FETRAP
+0,bbbb!0,00001000000:I:::fetrap
+"fetrap"
+*v850e2
+*v850e2v3
+{
+ TRACE_ALU_INPUT0 ();
+
+ FEPC = PC + 2;
+ FEPSW = PSW;
+ ECR &= ~ECR_FECC;
+ ECR |= (0x30 + bit4) << 16;
+ FEIC = 0x30 + bit4;
+ PSW |= PSW_EP | PSW_ID | PSW_NP;
+ nia = 0x30; /* next PC */
+
+ TRACE_ALU_RESULT1 (PSW);
+ TRACE_BRANCH_RESULT (nia);
+}
+
+
// HALT
0000011111100000 + 0000000100100000:X:::halt
"halt"
@@ -434,10 +674,33 @@ rrrrr,111111,RRRRR + wwwww,01011000010:X
+// HSH
+rrrrr,11111100000 + wwwww,01101000110:XII:::hsh
+*v850e2
+*v850e2v3
+"hsh r<reg2>, r<reg3>"
+{
+ unsigned32 value;
+ TRACE_ALU_INPUT1 (GR[reg2]);
+
+ value = 0xffff & GR[reg2];
+ GR[reg3] = GR[reg2];
+
+ PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+
+ if (value == 0) { PSW |= PSW_Z; PSW |= PSW_CY; }
+ if (value & 0x80000000) PSW |= PSW_S;
+
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+
// HSW
rrrrr,11111100000 + wwwww,01101000100:XII:::hsw
*v850e
*v850e1
+*v850e2
+*v850e2v3
"hsw r<reg2>, r<reg3>"
{
unsigned32 value;
@@ -469,6 +732,16 @@ rrrrr!0,11110,dddddd + ddddddddddddddd,0
TRACE_BRANCH1 (GR[reg2]);
}
+00000010111,RRRRR!0 + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::jarl32
+*v850e2
+*v850e2v3
+"jarl <imm32>, r<reg1>"
+{
+ GR[reg1] = nia;
+ nia = (cia + imm32) & ~1;
+
+ TRACE_BRANCH_RESULT (nia);
+}
// JMP
@@ -479,6 +752,15 @@ rrrrr!0,11110,dddddd + ddddddddddddddd,0
TRACE_BRANCH0 ();
}
+00000110111,RRRRR + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::jmp32
+*v850e2
+*v850e2v3
+"jmp <imm32>[r<reg1>]"
+{
+ nia = (GR[reg1] + imm32) & ~1;
+
+ TRACE_BRANCH_RESULT (nia);
+}
// JR
@@ -490,6 +772,17 @@ rrrrr!0,11110,dddddd + ddddddddddddddd,0
}
+// JR32
+00000010111,00000 + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::jr32
+*v850e2
+*v850e2v3
+"jr <imm32>"
+{
+ nia = (cia + imm32) & ~1;
+
+ TRACE_BRANCH_RESULT (nia);
+}
+
// LD
rrrrr,111000,RRRRR + dddddddddddddddd:VII:::ld.b
@@ -498,47 +791,368 @@ rrrrr,111000,RRRRR + dddddddddddddddd:VI
COMPAT_2 (OP_700 ());
}
+00000111100,RRRRR+wwwww,ddddddd,0101+dddddddddddddddd:XIV:::ld.b
+"ld.b <disp23>[r<reg1>], r<reg3>"
+*v850e2v3
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ unsigned32 result = EXTEND8 (load_data_mem (sd, addr, 1));
+ GR[reg3] = result;
+ TRACE_LD (addr, result);
+}
+
rrrrr,111001,RRRRR + ddddddddddddddd,0:VII:::ld.h
"ld.h <disp16>[r<reg1>], r<reg2>"
{
COMPAT_2 (OP_720 ());
}
+00000111100,RRRRR+wwwww,dddddd,00111+dddddddddddddddd:XIV:::ld.h
+*v850e2v3
+"ld.h <disp23>[r<reg1>], r<reg3>"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ unsigned32 result = EXTEND16 (load_data_mem (sd, addr, 2));
+ GR[reg3] = result;
+ TRACE_LD (addr, result);
+}
+
rrrrr,111001,RRRRR + ddddddddddddddd,1:VII:::ld.w
"ld.w <disp16>[r<reg1>], r<reg2>"
{
COMPAT_2 (OP_10720 ());
}
+00000111100,RRRRR+wwwww,dddddd,01001+dddddddddddddddd:XIV:::ld.w
+*v850e2v3
+"ld.w <disp23>[r<reg1>], r<reg3>"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ unsigned32 result = load_data_mem (sd, addr, 4);
+ GR[reg3] = result;
+ TRACE_LD (addr, result);
+}
+
rrrrr!0,11110,b,RRRRR + ddddddddddddddd,1:VII:::ld.bu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"ld.bu <disp16>[r<reg1>], r<reg2>"
{
COMPAT_2 (OP_10780 ());
}
+00000111101,RRRRR+wwwww,ddddddd,0101+dddddddddddddddd:XIV:::ld.bu
+*v850e2v3
+"ld.bu <disp23>[r<reg1>], r<reg3>"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ unsigned32 result = load_data_mem (sd, addr, 1);
+ GR[reg3] = result;
+ TRACE_LD (addr, result);
+}
+
rrrrr!0,111111,RRRRR + ddddddddddddddd,1:VII:::ld.hu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"ld.hu <disp16>[r<reg1>], r<reg2>"
{
COMPAT_2 (OP_107E0 ());
}
+00000111101,RRRRR+wwwww,dddddd,00111+dddddddddddddddd:XIV:::ld.hu
+*v850e2v3
+"ld.hu <disp23>[r<reg1>], r<reg3>"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ unsigned32 result = load_data_mem (sd, addr, 2);
+ GR[reg3] = result;
+ TRACE_LD (addr, result);
+}
+
+
// LDSR
regID,111111,RRRRR + 0000000000100000:IX:::ldsr
"ldsr r<reg1>, s<regID>"
{
+ uint32 sreg = GR[reg1];
TRACE_ALU_INPUT1 (GR[reg1]);
- if (&PSW == &SR[regID])
- PSW = (GR[reg1] & (CPU)->psw_mask);
+ if ((idecode_issue == idecode_v850e2_issue
+ || idecode_issue == idecode_v850e2v3_issue)
+ && regID < 28)
+ {
+ int protect_p = (PSW & PSW_NPV) ? 1 : 0;
+
+
+ switch (BSEL & 0xffff)
+ {
+ case 0x0000:
+ if ((PSW & PSW_NPV)
+ && ((regID >= 8 && regID <= 12)
+ || (regID >= 22 && regID <= 27)
+ || regID == PSW_REGNO))
+ {
+ protect_p = 0;
+ }
+ break;
+ case 0x1000: /* MPU0 */
+ break;
+ case 0x1001: /* MPU1 */
+ break;
+ case 0x2000: /* FPU */
+ if ((PSW & PSW_NPV)
+ && ((/* regID >= 0 && */ regID <= 5)
+ || regID == 8
+ || regID == 9
+ || regID == 10
+ || (regID >= 11 && regID <= 26)))
+ {
+ protect_p = 0;
+ }
+ break;
+ case 0xff00:
+ if ((PSW & PSW_NPV)
+ && (regID == 6
+ || regID == 7
+ || regID == 8
+ || regID == 9
+ || regID == 10
+ || (regID >= 11 && regID <= 15)
+ || regID == 18
+ || regID == 19
+ || (regID >= 21 && regID <= 27)))
+ {
+ protect_p = 0;
+ }
+ break;
+ case 0xffff:
+ if ((PSW & PSW_NPV)
+ && (regID == 6
+ || regID == 7
+ || regID == 8
+ || regID == 9
+ || regID == 10
+ || regID == 11
+ || regID == 12
+ || regID == 15
+ || regID == 18
+ || regID == 19
+ || (regID >= 21 && regID <= 27)))
+ {
+ protect_p = 0;
+ }
+ break;
+ }
+
+ if (!protect_p)
+ {
+ switch (BSEL & 0xffff)
+ {
+ case 0x0000:
+ case 0xff00: /* user0 bank */
+ case 0xffff: /* user1 bank */
+ if(regID == PSW_REGNO)
+ {
+ SR[regID] = sreg & ((PSW & PSW_NPV) ? 0xf : ~0);
+ }
+ else
+ {
+ SR[regID] = sreg;
+ }
+ break;
+ case 0x1000:
+ MPU0_SR[regID] = sreg;
+ break;
+ case 0x1001:
+ if (regID == MPC_REGNO)
+ {
+ PPC &= ~PPC_PPE;
+ SPAL &= ~SPAL_SPE;
+ IPA0L &= ~IPA_IPE;
+ IPA1L &= ~IPA_IPE;
+ IPA2L &= ~IPA_IPE;
+ IPA3L &= ~IPA_IPE;
+ DPA0L &= ~DPA_DPE;
+ DPA1L &= ~DPA_DPE;
+ DCC &= ~(DCC_DCE0 | DCC_DCE1);
+ }
+ else
+ {
+ MPU1_SR[regID] = sreg;
+ }
+ break;
+ case 0x2000: /* FPU */
+ if (regID == FPST_REGNO)
+ {
+ unsigned int val = FPSR & ~(FPSR_PR | FPSR_XC | FPSR_XP);
+
+ val |= ((sreg & FPST_PR) ? FPSR_PR : 0)
+ | ((sreg & FPST_XCE) ? FPSR_XCE : 0)
+ | ((sreg & FPST_XCV) ? FPSR_XCV : 0)
+ | ((sreg & FPST_XCZ) ? FPSR_XCZ : 0)
+ | ((sreg & FPST_XCO) ? FPSR_XCO : 0)
+ | ((sreg & FPST_XCU) ? FPSR_XCU : 0)
+ | ((sreg & FPST_XCI) ? FPSR_XCI : 0)
+ | ((sreg & FPST_XPV) ? FPSR_XPV : 0)
+ | ((sreg & FPST_XPZ) ? FPSR_XPZ : 0)
+ | ((sreg & FPST_XPO) ? FPSR_XPO : 0)
+ | ((sreg & FPST_XPU) ? FPSR_XPU : 0)
+ | ((sreg & FPST_XPI) ? FPSR_XPI : 0);
+ FPSR = val;
+ }
+ else if (regID == FPCFG_REGNO)
+ {
+ unsigned int val = FPSR & ~(FPSR_RM | FPSR_XE);
+
+ val |= (((sreg & FPCFG_RM) >> 7) << 18)
+ | ((sreg & FPCFG_XEV) ? FPSR_XEV : 0)
+ | ((sreg & FPCFG_XEZ) ? FPSR_XEZ : 0)
+ | ((sreg & FPCFG_XEO) ? FPSR_XEO : 0)
+ | ((sreg & FPCFG_XEU) ? FPSR_XEU : 0)
+ | ((sreg & FPCFG_XEI) ? FPSR_XEI : 0);
+ FPSR = val;
+ }
+
+ FPU_SR[regID] = sreg;
+ break;
+ }
+ }
+ }
else
- SR[regID] = GR[reg1];
+ {
+ SR[regID] = sreg;
+ }
+
+ TRACE_ALU_RESULT (sreg);
+}
+
+
+
+// MAC
+rrrrr,111111,RRRRR + wwww,0011110,mmmm,0:XI:::mac
+*v850e2
+*v850e2v3
+"mac r<reg1>, r<reg2>, r<reg3e>, r<reg4e>"
+{
+ unsigned long op0;
+ unsigned long op1;
+ unsigned long op2;
+ unsigned long op2hi;
+ unsigned long lo;
+ unsigned long mid1;
+ unsigned long mid2;
+ unsigned long hi;
+ unsigned long RdLo;
+ unsigned long RdHi;
+ int carry;
+ bfd_boolean sign;
+
+ op0 = GR[reg1];
+ op1 = GR[reg2];
+ op2 = GR[reg3e];
+ op2hi = GR[reg3e+1];
+
+ TRACE_ALU_INPUT4 (op0, op1, op2, op2hi);
+
+ sign = (op0 ^ op1) & 0x80000000;
+
+ if (((signed long) op0) < 0)
+ op0 = - op0;
+
+ if (((signed long) op1) < 0)
+ op1 = - op1;
+
+ /* We can split the 32x32 into four 16x16 operations. This ensures
+ that we do not lose precision on 32bit only hosts: */
+ lo = ( (op0 & 0xFFFF) * (op1 & 0xFFFF));
+ mid1 = ( (op0 & 0xFFFF) * ((op1 >> 16) & 0xFFFF));
+ mid2 = (((op0 >> 16) & 0xFFFF) * (op1 & 0xFFFF));
+ hi = (((op0 >> 16) & 0xFFFF) * ((op1 >> 16) & 0xFFFF));
+
+ /* We now need to add all of these results together, taking care
+ to propogate the carries from the additions: */
+ RdLo = Add32 (lo, (mid1 << 16), & carry);
+ RdHi = carry;
+ RdLo = Add32 (RdLo, (mid2 << 16), & carry);
+ RdHi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi);
+
+ if (sign)
+ {
+ RdLo = ~ RdLo;
+ RdHi = ~ RdHi;
+ if (RdLo == 0xFFFFFFFF)
+ {
+ RdLo = 0;
+ RdHi += 1;
+ }
+ else
+ RdLo += 1;
+ }
+
+ RdLo = Add32 (RdLo, op2, & carry);
+ RdHi += carry + op2hi;
+
+ /* Store the result and condition codes. */
+ GR[reg4e] = RdLo;
+ GR[reg4e + 1 ] = RdHi;
+
+ TRACE_ALU_RESULT2 (RdLo, RdHi);
+}
+
+
+
+// MACU
+rrrrr,111111,RRRRR + wwww,0011111,mmmm,0:XI:::macu
+*v850e2
+*v850e2v3
+"macu r<reg1>, r<reg2>, r<reg3e>, r<reg4e>"
+{
+ unsigned long op0;
+ unsigned long op1;
+ unsigned long op2;
+ unsigned long op2hi;
+ unsigned long lo;
+ unsigned long mid1;
+ unsigned long mid2;
+ unsigned long hi;
+ unsigned long RdLo;
+ unsigned long RdHi;
+ int carry;
+
+ op0 = GR[reg1];
+ op1 = GR[reg2];
+ op2 = GR[reg3e];
+ op2hi = GR[reg3e + 1];
+
+ TRACE_ALU_INPUT4 (op0, op1, op2, op2hi);
+
+ /* We can split the 32x32 into four 16x16 operations. This ensures
+ that we do not lose precision on 32bit only hosts: */
+ lo = ( (op0 & 0xFFFF) * (op1 & 0xFFFF));
+ mid1 = ( (op0 & 0xFFFF) * ((op1 >> 16) & 0xFFFF));
+ mid2 = (((op0 >> 16) & 0xFFFF) * (op1 & 0xFFFF));
+ hi = (((op0 >> 16) & 0xFFFF) * ((op1 >> 16) & 0xFFFF));
- TRACE_ALU_RESULT (SR[regID]);
+ /* We now need to add all of these results together, taking care
+ to propogate the carries from the additions: */
+ RdLo = Add32 (lo, (mid1 << 16), & carry);
+ RdHi = carry;
+ RdLo = Add32 (RdLo, (mid2 << 16), & carry);
+ RdHi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi);
+
+ RdLo = Add32 (RdLo, op2, & carry);
+ RdHi += carry + op2hi;
+
+ /* Store the result and condition codes. */
+ GR[reg4e] = RdLo;
+ GR[reg4e+1] = RdHi;
+
+ TRACE_ALU_RESULT2 (RdLo, RdHi);
}
@@ -552,7 +1166,6 @@ rrrrr!0,000000,RRRRR:I:::mov
TRACE_ALU_RESULT (GR[reg2]);
}
-
rrrrr!0,010000,iiiii:II:::mov
"mov <imm5>, r<reg2>"
{
@@ -562,6 +1175,8 @@ rrrrr!0,010000,iiiii:II:::mov
00000110001,RRRRR + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::mov
*v850e
*v850e1
+*v850e2
+*v850e2v3
"mov <imm32>, r<reg1>"
{
SAVE_2;
@@ -596,6 +1211,8 @@ rrrrr!0,110010,RRRRR + iiiiiiiiiiiiiiii:
rrrrr,111111,RRRRR + wwwww,01000100000:XI:::mul
*v850e
*v850e1
+*v850e2
+*v850e2v3
"mul r<reg1>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_22007E0 ());
@@ -604,6 +1221,8 @@ rrrrr,111111,RRRRR + wwwww,01000100000:X
rrrrr,111111,iiiii + wwwww,01001,IIII,00:XII:::mul
*v850e
*v850e1
+*v850e2
+*v850e2v3
"mul <imm9>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_24007E0 ());
@@ -638,6 +1257,8 @@ rrrrr!0,110111,RRRRR + iiiiiiiiiiiiiiii:
rrrrr,111111,RRRRR + wwwww,01000100010:XI:::mulu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"mulu r<reg1>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_22207E0 ());
@@ -646,6 +1267,8 @@ rrrrr,111111,RRRRR + wwwww,01000100010:X
rrrrr,111111,iiiii + wwwww,01001,IIII,10:XII:::mulu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"mulu <imm9>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_24207E0 ());
@@ -681,6 +1304,8 @@ rrrrr,000001,RRRRR:I:::not
rrrrr,111111,RRRRR + 0000000011100010:IX:::not1
*v850e
*v850e1
+*v850e2
+*v850e2v3
"not1 r<reg2>, r<reg1>"
{
COMPAT_2 (OP_E207E0 ());
@@ -710,6 +1335,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI
0000011110,iiiii,L + LLLLLLLLLLL,00001:XIII:::prepare
*v850e
*v850e1
+*v850e2
+*v850e2v3
"prepare <list12>, <imm5>"
{
int i;
@@ -735,6 +1362,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI
0000011110,iiiii,L + LLLLLLLLLLL,00011:XIII:::prepare00
*v850e
*v850e1
+*v850e2
+*v850e2v3
"prepare <list12>, <imm5>, sp"
{
COMPAT_2 (OP_30780 ());
@@ -743,6 +1372,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI
0000011110,iiiii,L + LLLLLLLLLLL,01011 + iiiiiiiiiiiiiiii:XIII:::prepare01
*v850e
*v850e1
+*v850e2
+*v850e2v3
"prepare <list12>, <imm5>, <uimm16>"
{
COMPAT_2 (OP_B0780 ());
@@ -751,6 +1382,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI
0000011110,iiiii,L + LLLLLLLLLLL,10011 + iiiiiiiiiiiiiiii:XIII:::prepare10
*v850e
*v850e1
+*v850e2
+*v850e2v3
"prepare <list12>, <imm5>, <uimm16>"
{
COMPAT_2 (OP_130780 ());
@@ -759,6 +1392,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI
0000011110,iiiii,L + LLLLLLLLLLL,11011 + iiiiiiiiiiiiiiii + dddddddddddddddd:XIII:::prepare11
*v850e
*v850e1
+*v850e2
+*v850e2v3
"prepare <list12>, <imm5>, <uimm32>"
{
COMPAT_2 (OP_1B0780 ());
@@ -803,12 +1438,23 @@ rrrrr,010101,iiiii:II:::sar
COMPAT_1 (OP_2A0 ());
}
+rrrrr,111111,RRRRR + wwwww,00010100010:XI:::sar
+*v850e2
+*v850e2v3
+"sar r<reg1>, r<reg2>, r<reg3>"
+{
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+ v850_sar(sd, GR[reg1], GR[reg2], &GR[reg3]);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
// SASF
rrrrr,1111110,cccc + 0000001000000000:IX:::sasf
*v850e
*v850e1
+*v850e2
+*v850e2v3
"sasf %s<cccc>, r<reg2>"
{
COMPAT_2 (OP_20007E0 ());
@@ -816,7 +1462,6 @@ rrrrr,1111110,cccc + 0000001000000000:IX
-
// SATADD
rrrrr!0,000110,RRRRR:I:::satadd
"satadd r<reg1>, r<reg2>"
@@ -830,6 +1475,16 @@ rrrrr!0,010001,iiiii:II:::satadd
COMPAT_1 (OP_220 ());
}
+rrrrr,111111,RRRRR + wwwww,01110111010:XI:::satadd
+*v850e2
+*v850e2v3
+"satadd r<reg1>, r<reg2>, r<reg3>"
+{
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+ v850_satadd (sd, GR[reg1], GR[reg2], &GR[reg3]);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
// SATSUB
@@ -839,6 +1494,16 @@ rrrrr!0,000101,RRRRR:I:::satsub
COMPAT_1 (OP_A0 ());
}
+rrrrr,111111,RRRRR + wwwww,01110011010:XI:::satsub
+*v850e2
+*v850e2v3
+"satsub r<reg1>, r<reg2>, r<reg3>"
+{
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+ v850_satsub (sd, GR[reg1], GR[reg2], &GR[reg3]);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
// SATSUBI
@@ -859,6 +1524,234 @@ rrrrr!0,000100,RRRRR:I:::satsubr
+//SBF
+rrrrr,111111,RRRRR + wwwww,011100,cccc!13,0:XI:::sbf
+*v850e2
+*v850e2v3
+"sbf %s<cccc>, r<reg1>, r<reg2>, r<reg3>"
+{
+ int cond = condition_met (cccc);
+ TRACE_ALU_INPUT3 (cond, GR[reg1], GR[reg2]);
+ GR[reg3] = GR[reg2] - GR[reg1] - (cond ? 1 : 0);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+
+
+// SCH0L
+rrrrr,11111100000 + wwwww,01101100100:IX:::sch0l
+*v850e2
+*v850e2v3
+"sch0l r<reg2>, r<reg3>"
+{
+ unsigned int pos, op0;
+
+ TRACE_ALU_INPUT1 (GR[reg2]);
+
+ op0 = GR[reg2];
+
+ if (op0 == 0xffffffff)
+ {
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW |= PSW_Z;
+ pos = 0;
+ }
+ else if (op0 == 0xfffffffe)
+ {
+ PSW |= PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ pos = 32;
+ }
+ else
+ {
+ pos = 1;
+ while (op0 & 0x80000000)
+ {
+ op0 <<= 1;
+ pos++;
+ }
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ }
+
+ GR[reg3] = pos;
+
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+
+
+// SCH0R
+rrrrr,11111100000 + wwwww,01101100000:IX:::sch0r
+*v850e2
+*v850e2v3
+"sch0r r<reg2>, r<reg3>"
+{
+ unsigned int pos, op0;
+
+ TRACE_ALU_INPUT1 (GR[reg2]);
+
+ op0 = GR[reg2];
+
+ if (op0 == 0xffffffff)
+ {
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW |= PSW_Z;
+ pos = 0;
+ }
+ else if (op0 == 0x7fffffff)
+ {
+ PSW |= PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ pos = 32;
+ }
+ else
+ {
+ pos = 1;
+ while (op0 & 0x00000001)
+ {
+ op0 >>= 1;
+ pos++;
+ }
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ }
+
+ GR[reg3] = pos;
+
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+// SCH1L
+rrrrr,11111100000 + wwwww,01101100110:IX:::sch1l
+*v850e2
+*v850e2v3
+"sch1l r<reg2>, r<reg3>"
+{
+ unsigned int pos, op0;
+
+ TRACE_ALU_INPUT1 (GR[reg2]);
+
+ op0 = GR[reg2];
+
+ if (op0 == 0x00000000)
+ {
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW |= PSW_Z;
+ pos = 0;
+ }
+ else if (op0 == 0x00000001)
+ {
+ PSW |= PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ pos = 32;
+ }
+ else
+ {
+ pos = 1;
+ while (!(op0 & 0x80000000))
+ {
+ op0 <<= 1;
+ pos++;
+ }
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ }
+
+ GR[reg3] = pos;
+
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+// SCH1R
+rrrrr,11111100000 + wwwww,01101100010:IX:::sch1r
+*v850e2
+*v850e2v3
+"sch1r r<reg2>, r<reg3>"
+{
+ unsigned int pos, op0;
+
+ TRACE_ALU_INPUT1 (GR[reg2]);
+
+ op0 = GR[reg2];
+
+ if (op0 == 0x00000000)
+ {
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW |= PSW_Z;
+ pos = 0;
+ }
+ else if (op0 == 0x80000000)
+ {
+ PSW |= PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ pos = 32;
+ }
+ else
+ {
+ pos = 1;
+ while (!(op0 & 0x00000001))
+ {
+ op0 >>= 1;
+ pos++;
+ }
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ }
+
+ GR[reg3] = pos;
+
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+//SHL
+rrrrr,111111,RRRRR + wwwww,00011000010:XI:::shl
+*v850e2
+*v850e2v3
+"shl r<reg1>, r<reg2>, r<reg3>"
+{
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+ v850_shl(sd, GR[reg1], GR[reg2], &GR[reg3]);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+//SHR
+rrrrr,111111,RRRRR + wwwww,00010000010:XI:::shr
+*v850e2
+*v850e2v3
+"shr r<reg1>, r<reg2>, r<reg3>"
+{
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+ v850_shr(sd, GR[reg1], GR[reg2], &GR[reg3]);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+
+
// SETF
rrrrr,1111110,cccc + 0000000000000000:IX:::setf
"setf %s<cccc>, r<reg2>"
@@ -878,6 +1771,8 @@ rrrrr,1111110,cccc + 0000000000000000:IX
rrrrr,111111,RRRRR + 0000000011100000:IX:::set1
*v850e
*v850e1
+*v850e2
+*v850e2v3
"set1 r<reg2>, [r<reg1>]"
{
COMPAT_2 (OP_E007E0 ());
@@ -966,6 +1861,8 @@ rrrrr,1010,dddddd,0:IV:::sld.w
rrrrr!0,0000110,dddd:IV:::sld.bu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"sld.b <disp4>[ep], r<reg2>":(PSW & PSW_US)
"sld.bu <disp4>[ep], r<reg2>"
{
@@ -987,6 +1884,8 @@ rrrrr!0,0000110,dddd:IV:::sld.bu
rrrrr!0,0000111,dddd:IV:::sld.hu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"sld.h <disp5>[ep], r<reg2>":(PSW & PSW_US)
"sld.hu <disp5>[ep], r<reg2>"
{
@@ -1005,6 +1904,8 @@ rrrrr!0,0000111,dddd:IV:::sld.hu
}
}
+
+
// SST
rrrrr,0111,ddddddd:IV:::sst.b
"sst.b r<reg2>, <disp7>[ep]"
@@ -1031,29 +1932,113 @@ rrrrr,111010,RRRRR + dddddddddddddddd:VI
COMPAT_2 (OP_740 ());
}
+00000111100,RRRRR + wwwww,ddddddd,1101 + dddddddddddddddd:XIV:::st.b
+*v850e2v3
+"st.b r<reg3>, <disp23>[r<reg1>]"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ store_data_mem (sd, addr, 1, GR[reg3]);
+ TRACE_ST (addr, GR[reg3]);
+}
+
rrrrr,111011,RRRRR + ddddddddddddddd,0:VII:::st.h
"st.h r<reg2>, <disp16>[r<reg1>]"
{
COMPAT_2 (OP_760 ());
}
+00000111101,RRRRR+wwwww,dddddd,01101+dddddddddddddddd:XIV:::st.h
+*v850e2v3
+"st.h r<reg3>, <disp23>[r<reg1>]"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ store_data_mem (sd, addr, 2, GR[reg3]);
+ TRACE_ST (addr, GR[reg3]);
+}
+
rrrrr,111011,RRRRR + ddddddddddddddd,1:VII:::st.w
"st.w r<reg2>, <disp16>[r<reg1>]"
{
COMPAT_2 (OP_10760 ());
}
+00000111100,RRRRR+wwwww,dddddd,01111+dddddddddddddddd:XIV:::st.w
+*v850e2v3
+"st.w r<reg3>, <disp23>[r<reg1>]"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ store_data_mem (sd, addr, 4, GR[reg3]);
+ TRACE_ST (addr, GR[reg3]);
+}
+
+
// STSR
rrrrr,111111,regID + 0000000001000000:IX:::stsr
"stsr s<regID>, r<reg2>"
{
- TRACE_ALU_INPUT1 (SR[regID]);
- GR[reg2] = SR[regID];
- TRACE_ALU_RESULT (GR[reg2]);
-}
+ uint32 sreg = 0;
-// SUB
-rrrrr,001101,RRRRR:I:::sub
+ if ((idecode_issue == idecode_v850e2_issue
+ || idecode_issue == idecode_v850e2v3_issue)
+ && regID < 28)
+ {
+ switch (BSEL & 0xffff)
+ {
+ case 0x0000:
+ case 0xff00: /* USER 0 */
+ case 0xffff: /* USER 1 */
+ sreg = SR[regID];
+ break;
+ case 0x1000:
+ sreg = MPU0_SR[regID];
+ break;
+ case 0x1001:
+ sreg = MPU1_SR[regID];
+ break;
+ case 0x2000:
+ if (regID == FPST_REGNO)
+ {
+ sreg = ((FPSR & FPSR_PR) ? FPST_PR : 0)
+ | ((FPSR & FPSR_XCE) ? FPST_XCE : 0)
+ | ((FPSR & FPSR_XCV) ? FPST_XCV : 0)
+ | ((FPSR & FPSR_XCZ) ? FPST_XCZ : 0)
+ | ((FPSR & FPSR_XCO) ? FPST_XCO : 0)
+ | ((FPSR & FPSR_XCU) ? FPST_XCU : 0)
+ | ((FPSR & FPSR_XCI) ? FPST_XCI : 0)
+ | ((FPSR & FPSR_XPV) ? FPST_XPV : 0)
+ | ((FPSR & FPSR_XPZ) ? FPST_XPZ : 0)
+ | ((FPSR & FPSR_XPO) ? FPST_XPO : 0)
+ | ((FPSR & FPSR_XPU) ? FPST_XPU : 0)
+ | ((FPSR & FPSR_XPI) ? FPST_XPI : 0);
+ }
+ else if (regID == FPCFG_REGNO)
+ {
+ sreg = (((FPSR & FPSR_RM) >> 18) << 7)
+ | ((FPSR & FPSR_XEV) ? FPCFG_XEV : 0)
+ | ((FPSR & FPSR_XEZ) ? FPCFG_XEZ : 0)
+ | ((FPSR & FPSR_XEO) ? FPCFG_XEO : 0)
+ | ((FPSR & FPSR_XEU) ? FPCFG_XEU : 0)
+ | ((FPSR & FPSR_XEI) ? FPCFG_XEI : 0);
+ }
+ else
+ {
+ sreg = FPU_SR[regID];
+ }
+ break;
+ }
+ }
+ else
+ {
+ sreg = SR[regID];
+ }
+
+ TRACE_ALU_INPUT1 (sreg);
+ GR[reg2] = sreg;
+ TRACE_ALU_RESULT (GR[reg2]);
+}
+
+// SUB
+rrrrr,001101,RRRRR:I:::sub
"sub r<reg1>, r<reg2>"
{
COMPAT_1 (OP_1A0 ());
@@ -1070,6 +2055,8 @@ rrrrr,001100,RRRRR:I:::subr
00000000010,RRRRR:I:::switch
*v850e
*v850e1
+*v850e2
+*v850e2v3
"switch r<reg1>"
{
unsigned long adr;
@@ -1084,6 +2071,8 @@ rrrrr,001100,RRRRR:I:::subr
00000000101,RRRRR:I:::sxb
*v850e
*v850e1
+*v850e2
+*v850e2v3
"sxb r<reg1>"
{
TRACE_ALU_INPUT1 (GR[reg1]);
@@ -1095,6 +2084,8 @@ rrrrr,001100,RRRRR:I:::subr
00000000111,RRRRR:I:::sxh
*v850e
*v850e1
+*v850e2
+*v850e2v3
"sxh r<reg1>"
{
TRACE_ALU_INPUT1 (GR[reg1]);
@@ -1126,6 +2117,8 @@ rrrrr,001011,RRRRR:I:::tst
rrrrr,111111,RRRRR + 0000000011100110:IX:::tst1
*v850e
*v850e1
+*v850e2
+*v850e2v3
"tst1 r<reg2>, [r<reg1>]"
{
COMPAT_2 (OP_E607E0 ());
@@ -1149,6 +2142,8 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI
00000000100,RRRRR:I:::zxb
*v850e
*v850e1
+*v850e2
+*v850e2v3
"zxb r<reg1>"
{
TRACE_ALU_INPUT1 (GR[reg1]);
@@ -1160,6 +2155,8 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI
00000000110,RRRRR:I:::zxh
*v850e
*v850e1
+*v850e2
+*v850e2v3
"zxh r<reg1>"
{
TRACE_ALU_INPUT1 (GR[reg1]);
@@ -1178,6 +2175,8 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI
11111,000010,00000:I:::dbtrap
*v850e1
+*v850e2
+*v850e2v3
"dbtrap"
{
DBPC = cia + 2;
@@ -1197,9 +2196,1069 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI
// Return from debug trap: 0x146007e0
0000011111100000 + 0000000101000110:X:::dbret
*v850e1
+*v850e2
+*v850e2v3
"dbret"
{
nia = DBPC;
PSW = DBPSW;
TRACE_BRANCH1 (PSW);
}
+
+
+//
+// FLOAT
+//
+
+// Map condition code to a string
+:%s::::FFFF:int FFFF
+{
+ switch (FFFF)
+ {
+ case 0: return "f";
+ case 1: return "un";
+ case 2: return "eq";
+ case 3: return "ueq";
+ case 4: return "olt";
+ case 5: return "ult";
+ case 6: return "ole";
+ case 7: return "ule";
+ case 8: return "sf";
+ case 9: return "ngle";
+ case 10: return "seq";
+ case 11: return "ngl";
+ case 12: return "lt";
+ case 13: return "nge";
+ case 14: return "le";
+ case 15: return "ngt";
+ }
+ return "(null)";
+}
+
+// ABSF.D
+rrrr,011111100000 + wwww,010001011000:F_I:::absf_d
+*v850e2v3
+"absf.d r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_abs (&ans, &wop);
+ check_invalid_snan(sd, status, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// ABSF.S
+rrrrr,11111100000 + wwwww,10001001000:F_I:::absf_s
+*v850e2v3
+"absf.s r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_abs (&ans, &wop);
+ check_invalid_snan(sd, status, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// ADDF.D
+rrrr,0111111,RRRR,0 + wwww,010001110000:F_I:::addf_d
+*v850e2v3
+"addf.d r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_add (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// ADDF.S
+rrrrr,111111,RRRRR + wwwww,10001100000:F_I:::addf_s
+*v850e2v3
+"addf.s r<reg1>, r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_add (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// CMOVF.D
+rrrr,0111111,RRRR,0 + wwww!0,01000001,bbb,0:F_I:::cmovf_d
+*v850e2v3
+"cmovf.d <bbb>, r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ unsigned int ophi,oplow;
+ sim_fpu ans, wop1, wop2;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_BOOL1_FPU2 (TEST_FPCC(bbb), &wop1, &wop2);
+
+ if (TEST_FPCC(bbb))
+ {
+ ophi = GR[reg1e+1];
+ oplow = GR[reg1e];
+ ans = wop1;
+ }
+ else
+ {
+ ophi = GR[reg2e+1];
+ oplow = GR[reg2e];
+ ans = wop2;
+ }
+
+ GR[reg3e+1] = ophi;
+ GR[reg3e] = oplow;
+ TRACE_FP_RESULT_FPU1 (&ans);;
+}
+
+// CMOVF.S
+rrrrr,111111,RRRRR + wwwww!0,1000000,bbb,0:F_I:::cmovf_s
+*v850e2v3
+"cmovf.d <bbb>, r<reg1>, r<reg2>, r<reg3>"
+{
+ unsigned int op;
+ sim_fpu ans, wop1, wop2;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_BOOL1_FPU2 (TEST_FPCC(bbb), &wop1, &wop2);
+
+ if (TEST_FPCC(bbb))
+ {
+ op = GR[reg1];
+ ans = wop1;
+ }
+ else
+ {
+ op = GR[reg2];
+ ans = wop2;
+ }
+
+ GR[reg3] = op;
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// CMPF.D
+rrrr,0111111,RRRR,0 + 0,FFFF,1000011,bbb,0:F_I:::cmpf_d
+*v850e2v3
+"cmpf.d %s<FFFF>, r<reg1e>, r<reg2e>":(bbb == 0)
+"cmpf.d %s<FFFF>, r<reg1e>, r<reg2e>, <bbb>"
+{
+ int result;
+ sim_fpu wop1;
+ sim_fpu wop2;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ result = v850_float_compare(sd, FFFF, wop1, wop2, 1);
+
+ if (result)
+ SET_FPCC(bbb);
+ else
+ CLEAR_FPCC(bbb);
+
+ TRACE_FP_RESULT_BOOL (result);
+}
+
+// CMPF.S
+rrrrr,111111,RRRRR + 0,FFFF,1000010,bbb,0:F_I:::cmpf_s
+*v850e2v3
+"cmpf.s %s<FFFF>, r<reg1>, r<reg2>":(bbb == 0)
+"cmpf.s %s<FFFF>, r<reg1>, r<reg2>, <bbb>"
+{
+ int result;
+ sim_fpu wop1;
+ sim_fpu wop2;
+
+ sim_fpu_32to( &wop1, GR[reg1] );
+ sim_fpu_32to( &wop2, GR[reg2] );
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ result = v850_float_compare(sd, FFFF, wop1, wop2, 0);
+
+ if (result)
+ SET_FPCC(bbb);
+ else
+ CLEAR_FPCC(bbb);
+
+ TRACE_FP_RESULT_BOOL (result);
+}
+
+// CVTF.DL
+rrrr,011111100100 + wwww,010001010100:F_I:::cvtf_dl
+*v850e2v3
+"cvtf.dl r<reg2e>, r<reg3e>"
+{
+ unsigned64 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+ status |= sim_fpu_to64i (&ans, &wop, FPSR_GET_ROUND());
+
+ check_cvt_fi(sd, status, 1);
+
+ GR[reg3e] = ans;
+ GR[reg3e+1] = ans>>32L;
+ TRACE_FP_RESULT_WORD2 (GR[reg3e], GR[reg3e+1]);
+}
+
+// CVTF.DS
+rrrr,011111100011 + wwwww,10001010010:F_I:::cvtf_ds
+*v850e2v3
+"cvtf.ds r<reg2e>, r<reg3>"
+{
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ check_cvt_fi(sd, status, 0);
+
+ sim_fpu_to32 (&GR[reg3], &wop);
+ TRACE_FP_RESULT_FPU1 (&wop);
+}
+
+// CVTF.DW
+rrrr,011111100100 + wwwww,10001010000:F_I:::cvtf_dw
+*v850e2v3
+"cvtf.dw r<reg2e>, r<reg3>"
+{
+ uint32 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+ status |= sim_fpu_to32i (&ans, &wop, FPSR_GET_ROUND());
+
+ check_cvt_fi(sd, status, 1);
+
+ GR[reg3] = ans;
+ TRACE_FP_RESULT_WORD1 (ans);
+}
+
+// CVTF.LD
+rrrr,011111100001 + wwww,010001010010:F_I:::cvtf_ld
+*v850e2v3
+"cvtf.ld r<reg2e>, r<reg3e>"
+{
+ signed64 op;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ op = ((signed64)GR[reg2e+1] << 32L) | GR[reg2e];
+ TRACE_FP_INPUT_WORD2 (GR[reg2e], GR[reg2e+1]);
+
+ sim_fpu_i64to (&wop, op, FPSR_GET_ROUND());
+ status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+
+ check_cvt_if(sd, status, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &wop);
+ TRACE_FP_RESULT_FPU1 (&wop);
+}
+
+// CVTF.LS
+rrrr,011111100001 + wwwww,10001000010:F_I:::cvtf_ls
+*v850e2v3
+"cvtf.ls r<reg2e>, r<reg3>"
+{
+ signed64 op;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ op = ((signed64)GR[reg2e+1] << 32L) | GR[reg2e];
+ TRACE_FP_INPUT_WORD2 (GR[reg2e], GR[reg2e+1]);
+
+ sim_fpu_i64to (&wop, op, FPSR_GET_ROUND());
+ status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+
+ check_cvt_if(sd, status, 0);
+
+ sim_fpu_to32 (&GR[reg3], &wop);
+ TRACE_FP_RESULT_FPU1 (&wop);
+}
+
+// CVTF.SD
+rrrrr,11111100010 + wwww,010001010010:F_I:::cvtf_sd
+*v850e2v3
+"cvtf.sd r<reg2>, r<reg3e>"
+{
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+ status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ check_cvt_ff(sd, status, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &wop);
+ TRACE_FP_RESULT_FPU1 (&wop);
+}
+
+// CVTF.SL
+rrrrr,11111100100 + wwww,010001000100:F_I:::cvtf_sl
+*v850e2v3
+"cvtf.sl r<reg2>, r<reg3e>"
+{
+ signed64 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+ status |= sim_fpu_to64i (&ans, &wop, FPSR_GET_ROUND());
+
+ check_cvt_fi(sd, status, 0);
+
+ GR[reg3e] = ans;
+ GR[reg3e+1] = ans >> 32L;
+ TRACE_FP_RESULT_WORD2 (GR[reg3e], GR[reg3e+1]);
+}
+
+// CVTF.SW
+rrrrr,11111100100 + wwwww,10001000000:F_I:::cvtf_sw
+*v850e2v3
+"cvtf.sw r<reg2>, r<reg3>"
+{
+ uint32 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+ status |= sim_fpu_to32i (&ans, &wop, sim_fpu_round_zero);
+
+ check_cvt_fi(sd, status, 0);
+
+ GR[reg3] = ans;
+ TRACE_FP_RESULT_WORD1 (ans);
+}
+
+// CVTF.WD
+rrrrr,11111100000 + wwww,010001010010:F_I:::cvtf_wd
+*v850e2v3
+"cvtf.wd r<reg2>, r<reg3e>"
+{
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ TRACE_FP_INPUT_WORD1 (GR[reg2]);
+ sim_fpu_i32to (&wop, GR[reg2], FPSR_GET_ROUND());
+ status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+
+ check_cvt_if(sd, status, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &wop);
+ TRACE_FP_RESULT_FPU1 (&wop);
+}
+
+// CVTF.WS
+rrrrr,11111100000 + wwwww,10001000010:F_I:::cvtf_ws
+*v850e2v3
+"cvtf.ws r<reg2>, r<reg3>"
+{
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ TRACE_FP_INPUT_WORD1 (GR[reg2]);
+ sim_fpu_i32to (&wop, GR[reg2], FPSR_GET_ROUND());
+ status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+
+ check_cvt_if(sd, status, 0);
+
+ sim_fpu_to32 (&GR[reg3], &wop);
+ TRACE_FP_RESULT_FPU1 (&wop);
+}
+
+// DIVF.D
+rrrr,0111111,RRRR,0 + wwww,010001111110:F_I:::divf_d
+*v850e2v3
+"divf.d r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_div (&ans, &wop2, &wop1);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// DIVF.S
+rrrrr,111111,RRRRR + wwwww,10001101110:F_I:::divf_s
+*v850e2v3
+"divf.s r<reg1>, r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_div (&ans, &wop2, &wop1);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MADDF.S
+rrrrr,111111,RRRRR + wwwww,101,W,00,WWWW,0:F_I:::maddf_s
+*v850e2v3
+"maddf.s r<reg1>, r<reg2>, r<reg3>, r<reg4>"
+{
+ sim_fpu ans, wop1, wop2, wop3;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ sim_fpu_32to (&wop3, GR[reg3]);
+ TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3);
+
+ status = sim_fpu_mul (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop1 = ans;
+ status |= sim_fpu_add (&ans, &wop1, &wop3);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg4], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MAXF.D
+rrrr,0111111,RRRR,0 + wwww,010001111000:F_I:::maxf_d
+*v850e2v3
+"maxf.d r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop1, wop2;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2))
+ {
+ if (FPSR & FPSR_XEV)
+ {
+ SignalExceptionFPE(sd, 1);
+ }
+ else
+ {
+ ans = sim_fpu_qnan;
+ }
+ }
+ else if (FPSR & FPSR_FS
+ && ((sim_fpu_is_zero (&wop1) || sim_fpu_is_denorm (&wop1))
+ && (sim_fpu_is_zero (&wop2) || sim_fpu_is_denorm (&wop2))))
+ {
+ ans = sim_fpu_zero;
+ }
+ else
+ {
+ sim_fpu_max (&ans, &wop1, &wop2);
+ }
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MAXF.S
+rrrrr,111111,RRRRR + wwwww,10001101000:F_I:::maxf_s
+*v850e2v3
+"maxf.s r<reg1>, r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop1, wop2;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2))
+ {
+ if (FPSR & FPSR_XEV)
+ {
+ SignalExceptionFPE(sd, 0);
+ }
+ else
+ {
+ ans = sim_fpu_qnan;
+ }
+ }
+ else if ((FPSR & FPSR_FS)
+ && ((sim_fpu_is_zero (&wop1) || sim_fpu_is_denorm (&wop1))
+ && (sim_fpu_is_zero (&wop2)|| sim_fpu_is_denorm (&wop2))))
+ {
+ ans = sim_fpu_zero;
+ }
+ else
+ {
+ sim_fpu_max (&ans, &wop1, &wop2);
+ }
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MINF.D
+rrrr,0111111,RRRR,0 + wwww,010001111010:F_I:::minf_d
+*v850e2v3
+"minf.d r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop1, wop2;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2))
+ {
+ if (FPSR & FPSR_XEV)
+ {
+ SignalExceptionFPE(sd, 1);
+ }
+ else
+ {
+ ans = sim_fpu_qnan;
+ }
+ }
+ else if (FPSR & FPSR_FS
+ && ((sim_fpu_is_zero (&wop1) || sim_fpu_is_denorm (&wop1))
+ && (sim_fpu_is_zero (&wop2) || sim_fpu_is_denorm (&wop2))))
+ {
+ ans = sim_fpu_zero;
+ }
+ else
+ {
+ sim_fpu_min (&ans, &wop1, &wop2);
+ }
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MINF.S
+rrrrr,111111,RRRRR + wwwww,10001101010:F_I:::minf_s
+*v850e2v3
+"minf.s r<reg1>, r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop1, wop2;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2))
+ {
+ if (FPSR & FPSR_XEV)
+ {
+ SignalExceptionFPE(sd, 0);
+ }
+ else
+ {
+ ans = sim_fpu_qnan;
+ }
+ }
+ else if (FPSR & FPSR_FS
+ && ((sim_fpu_is_zero (&wop1) || sim_fpu_is_denorm (&wop1))
+ && (sim_fpu_is_zero (&wop2) || sim_fpu_is_denorm (&wop2))))
+ {
+ ans = sim_fpu_zero;
+ }
+ else
+ {
+ sim_fpu_min (&ans, &wop1, &wop2);
+ }
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MSUBF.S
+rrrrr,111111,RRRRR + wwwww,101,W,01,WWWW,0:F_I:::msubf_s
+*v850e2v3
+"msubf.s r<reg1>, r<reg2>, r<reg3>, r<reg4>"
+{
+ sim_fpu ans, wop1, wop2, wop3;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ sim_fpu_32to (&wop3, GR[reg3]);
+ TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3);
+
+ status = sim_fpu_mul (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop1 = ans;
+ status |= sim_fpu_sub (&ans, &wop1, &wop3);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg4], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MULF.D
+rrrr,0111111,RRRR,0 + wwww,010001110100:F_I:::mulf_d
+*v850e2v3
+"mulf.d r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_mul (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MULF.S
+rrrrr,111111,RRRRR + wwwww,10001100100:F_I:::mulf_s
+*v850e2v3
+"mulf.s r<reg1>, r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_mul (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// NEGF.D
+rrrr,011111100001 + wwww,010001011000:F_I:::negf_d
+*v850e2v3
+"negf.d r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_neg (&ans, &wop);
+
+ check_invalid_snan(sd, status, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// NEGF.S
+rrrrr,11111100001 + wwwww,10001001000:F_I:::negf_s
+*v850e2v3
+"negf.s r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_neg (&ans, &wop);
+
+ check_invalid_snan(sd, status, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// NMADDF.S
+rrrrr,111111,RRRRR + wwwww,101,W,10,WWWW,0:F_I:::nmaddf_s
+*v850e2v3
+"nmaddf.s r<reg1>, r<reg2>, r<reg3>, r<reg4>"
+{
+ sim_fpu ans, wop1, wop2, wop3;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ sim_fpu_32to (&wop3, GR[reg3]);
+ TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3);
+
+ status = sim_fpu_mul (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop1 = ans;
+ status |= sim_fpu_add (&ans, &wop1, &wop3);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop1 = ans;
+ status |= sim_fpu_neg (&ans, &wop1);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg4], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// NMSUBF.S
+rrrrr,111111,RRRRR + wwwww,101,W,11,WWWW,0:F_I:::nmsubf_s
+*v850e2v3
+"nmsubf.s r<reg1>, r<reg2>, r<reg3>, r<reg4>"
+{
+ sim_fpu ans, wop1, wop2, wop3;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ sim_fpu_32to (&wop3, GR[reg3]);
+ TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3);
+
+ status = sim_fpu_mul (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop1 = ans;
+ status |= sim_fpu_sub (&ans, &wop1, &wop3);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop1 = ans;
+ status |= sim_fpu_neg (&ans, &wop1);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg4], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// RECIPF.D
+rrrr,011111100001 + wwww,010001011110:F_I:::recipf.d
+*v850e2v3
+"recipf.d r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_div (&ans, &sim_fpu_one, &wop);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// RECIPF.S
+rrrrr,11111100001 + wwwww,10001001110:F_I:::recipf.s
+*v850e2v3
+"recipf.s r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_div (&ans, &sim_fpu_one, &wop);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// RSQRTF.D
+rrrr,011111100010 + wwww,010001011110:F_I:::rsqrtf.d
+*v850e2v3
+"rsqrtf.d r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_sqrt (&ans, &wop);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop = ans;
+ status = sim_fpu_div (&ans, &sim_fpu_one, &wop);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// RSQRTF.S
+rrrrr,11111100010 + wwwww,10001001110:F_I:::rsqrtf.s
+*v850e2v3
+"rsqrtf.s r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_sqrt (&ans, &wop);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop = ans;
+ status = sim_fpu_div (&ans, &sim_fpu_one, &wop);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// SQRTF.D
+rrrr,011111100000 + wwww,010001011110:F_I:::sqrtf.d
+*v850e2v3
+"sqrtf.d r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_sqrt (&ans, &wop);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// SQRTF.S
+rrrrr,11111100000 + wwwww,10001001110:F_I:::sqrtf.s
+*v850e2v3
+"sqrtf.s r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_sqrt (&ans, &wop);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// SUBF.D
+rrrr,0111111,RRRR,0 + wwww,010001110010:F_I:::subf.d
+*v850e2v3
+"subf.d r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_sub (&ans, &wop2, &wop1);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// SUBF.S
+rrrrr,111111,RRRRR + wwwww,10001100010:F_I:::subf.s
+*v850e2v3
+"subf.s r<reg1>, r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_sub (&ans, &wop2, &wop1);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// TRFSR
+0000011111100000 + 000001000000,bbb,0:F_I:::trfsr
+*v850e2v3
+"trfsr":(bbb == 0)
+"trfsr <bbb>"
+{
+ TRACE_ALU_INPUT1 (GET_FPCC());
+
+ if (TEST_FPCC (bbb))
+ PSW |= PSW_Z;
+ else
+ PSW &= ~PSW_Z;
+
+ TRACE_ALU_RESULT1 (PSW);
+}
+
+// TRNCF.DL
+rrrr,011111100001 + wwww,010001010100:F_I:::trncf_dl
+*v850e2v3
+"trncf.dl r<reg2e>, r<reg3e>"
+{
+ signed64 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_64 (&wop, sim_fpu_round_zero, sim_fpu_denorm_zero);
+ status |= sim_fpu_to64i (&ans, &wop, sim_fpu_round_zero);
+
+ check_cvt_fi(sd, status, 1);
+
+ GR[reg3e] = ans;
+ GR[reg3e+1] = ans>>32L;
+ TRACE_FP_RESULT_WORD2 (GR[reg3e], GR[reg3e+1]);
+}
+
+// TRNCF.DW
+rrrr,011111100001 + wwwww,10001010000:F_I:::trncf_dw
+*v850e2v3
+"trncf.dw r<reg2e>, r<reg3>"
+{
+ uint32 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_32 (&wop, sim_fpu_round_zero, sim_fpu_denorm_zero);
+ status |= sim_fpu_to32i (&ans, &wop, sim_fpu_round_zero);
+
+ check_cvt_fi(sd, status, 1);
+
+ GR[reg3] = ans;
+ TRACE_FP_RESULT_WORD1 (ans);
+}
+
+// TRNCF.SL
+rrrrr,11111100001 + wwww,010001000100:F_I:::trncf_sl
+*v850e2v3
+"trncf.sl r<reg2>, r<reg3e>"
+{
+ signed64 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_64 (&wop, sim_fpu_round_zero, sim_fpu_denorm_zero);
+ status |= sim_fpu_to64i (&ans, &wop, sim_fpu_round_zero);
+
+ GR[reg3e] = ans;
+ GR[reg3e+1] = ans >> 32L;
+ TRACE_FP_RESULT_WORD2 (GR[reg3e], GR[reg3e+1]);
+}
+
+// TRNCF.SW
+rrrrr,11111100001 + wwwww,10001000000:F_I:::trncf_sw
+*v850e2v3
+"trncf.sw r<reg2>, r<reg3>"
+{
+ uint32 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_32 (&wop, sim_fpu_round_zero, sim_fpu_denorm_zero);
+ status |= sim_fpu_to32i (&ans, &wop, sim_fpu_round_zero);
+
+ check_cvt_fi(sd, status, 0);
+
+ GR[reg3] = ans;
+ TRACE_FP_RESULT_WORD1 (ans);
+}
+
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH, V850] Add support for V850E2 and V850E2V3
2010-09-21 19:55 Rathish C
@ 2010-09-21 22:49 ` Kevin Buettner
2010-09-21 22:49 ` Kevin Buettner
0 siblings, 1 reply; 14+ messages in thread
From: Kevin Buettner @ 2010-09-21 22:49 UTC (permalink / raw)
To: gdb-patches
On Tue, 21 Sep 2010 18:09:14 +0530
Rathish C <Rathish.C@kpitcummins.com> wrote:
> diff -upNr gdb-7.2.50-orig/gdb/v850-tdep.c gdb-7.2.50-modified/src/gdb/v850-tdep.c
> --- gdb-7.2.50-orig/gdb/v850-tdep.c 2010-09-10 04:34:46.000000000 +0530
> +++ gdb-7.2.50-modified/gdb/v850-tdep.c 2010-09-18 19:06:34.000000000 +0530
> @@ -100,8 +100,100 @@ enum
> E_R61_REGNUM,
> E_R62_REGNUM,
> E_R63_REGNUM,
> - E_R64_REGNUM, E_PC_REGNUM = E_R64_REGNUM,
> +
> + /* mpu0 system registers */
> + E_R64_REGNUM,
[...]
> + /* pc etc. */
> + E_R148_REGNUM, E_PC_REGNUM = E_R148_REGNUM,
> + E_R149_REGNUM,
Why are you changing the register number for E_PC_REGNUM? I
assume you've already changed gcc so that the dwarf2 return address
column ends up being this new number. Won't this make it impossible
to use an old compiler with a new debugger and vice versa?
> @@ -142,14 +234,32 @@ static const char *
> v850_register_name (struct gdbarch *gdbarch, int regnum)
> {
> static const char *v850_reg_names[] =
> - { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
> - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
> - "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
> + {
> + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
> + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
> + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
> "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
> +
> "eipc", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7",
> "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
> "sr16", "sr17", "sr18", "sr19", "sr20", "sr21", "sr22", "sr23",
> "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
> +
> + "sr32", "sr33", "sr34", "sr35", "sr36", "sr37", "sr38", "sr39",
> + "sr40", "sr41", "sr42", "sr43", "sr44", "sr45", "sr46", "sr47",
> + "sr48", "sr49", "sr50", "sr51", "sr52", "sr53", "sr54", "sr55",
> + "sr56", "sr57", "sr58", "sr59",
> +
> + "sr60", "sr61", "sr62", "sr63", "sr64", "sr65", "sr66", "sr67",
> + "sr68", "sr69", "sr70", "sr71", "sr72", "sr73", "sr74", "sr75",
> + "sr76", "sr77", "sr78", "sr79", "sr80", "sr81", "sr82", "sr83",
> + "sr84", "sr85", "sr86", "sr87",
> +
> + "sr88", "sr89", "sr90", "sr91", "sr92", "sr93", "sr94", "sr95",
> + "sr96", "sr97", "sr98", "sr99", "sr100", "sr101", "sr102", "sr103",
> + "sr104", "sr105", "sr106", "sr107", "sr108", "sr109", "sr110", "sr111",
> + "sr112", "sr113", "sr114", "sr115",
> +
Does the original v850 really have all of these new registers? (The
v850 manual that I looked at does not show them...)
Kevin
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH, V850] Add support for V850E2 and V850E2V3
2010-09-21 22:49 ` Kevin Buettner
@ 2010-09-21 22:49 ` Kevin Buettner
0 siblings, 0 replies; 14+ messages in thread
From: Kevin Buettner @ 2010-09-21 22:49 UTC (permalink / raw)
To: gdb-patches
On Tue, 21 Sep 2010 13:50:05 -0700
Kevin Buettner <kevinb@redhat.com> wrote:
> > - E_R64_REGNUM, E_PC_REGNUM = E_R64_REGNUM,
> > +
> > + /* mpu0 system registers */
> > + E_R64_REGNUM,
> [...]
> > + /* pc etc. */
> > + E_R148_REGNUM, E_PC_REGNUM = E_R148_REGNUM,
> > + E_R149_REGNUM,
>
> Why are you changing the register number for E_PC_REGNUM? I
> assume you've already changed gcc so that the dwarf2 return address
> column ends up being this new number. Won't this make it impossible
> to use an old compiler with a new debugger and vice versa?
Another issue with moving E_PC_REGNUM is that existing debugging stubs
use the old value.
In my opinion, you should be leaving the register order and names
the same for the existing v850 architectures.
Kevin
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH, V850] Add support for V850E2 and V850E2V3
@ 2010-09-21 19:55 Rathish C
2010-09-21 22:49 ` Kevin Buettner
0 siblings, 1 reply; 14+ messages in thread
From: Rathish C @ 2010-09-21 19:55 UTC (permalink / raw)
To: gdb-patches; +Cc: Gina Verlekar
[-- Attachment #1: Type: text/plain, Size: 2407 bytes --]
Hi,
Please find attached the "v850-gdb-v850e2-v850e2v3-support.patch".
The patch adds support for new target variants of V850 i.e. V850E2 and
V850E2V3. These processors are upwardly compatible with earlier V850
targets already supported in the current binutils port. V850E2V3 target
supports floating point operations. Hence, those instructions along with
registers supported by V850E2V3 are defined in the current patch.
The GCC and Newlib part of the support have been posted and accepted.
Please review the patch and let me know if there should be any
modifications in it.
2010-09-21 Rathish.C <rathish.c@kpitcummins.com>
* gdb/v850-tdep.c: Add the enum values for mpu and fpu registers
(v850_register_name): Add the mpu and fpu register names.
(v850e_register_name): Add the mpu and fpu register names.
(v850e2_register_name): New function.
(v850_gdbarch_init): Add case for bfd_mach_v850e2 and
bfd_mach_v850e2v3.
* sim/common/sim-trace.c: Update the function prototype of
save_data_size.
Move the enum data_fmt from here
* sim/common/sim-trace.h: to here.
Add function prototype of save_data
* sim/v850/sim-main.h: Update the struct _v850_regs to include
mpu and fpu system registers.
Define the macros to access the mpu and fpu system registers.
(SEXT3): Define.
(TRACE_FP_INPUT_FPU1, TRACE_FP_INPUT_FPU2,
TRACE_FP_INPUT_FPU3): Define.
(TRACE_FP_INPUT_BOOL1_FPU2): Define.
(TRACE_FP_INPUT_WORD2): Define.
(TRACE_FP_RESULT_WORD1, TRACE_FP_RESULT_WORD2): Define.
* sim/v850/simops.c: Update the function prototype of Add32
(update_fpsr): New function.
(SignalException): New function.
(SignalExceptionFPE): New function.
(check_invalid_snan): New function.
(v850_float_compare): New function.
(v850_div): New function.
(v850_divu): New function.
(v850_sar): New function.
(v850_shl): New function.
(v850_shr): New function.
(v850_satadd): New function.
(v850_satsub): New function.
(load_data_mem): New function.
(store_data_mem): New function.
(mpu_load_mem_test): New function.
(mpu_store_mem_test): New function.
* sim/v850/simops.h: Add function prototype for above
mentioned functions.
(check_cvt_fi, check_cvt_if, check_cvt_ff): Define.
* sim/v850/v850-dc: Add entry for v850e2 and v850e2v3.
* sim/v850/v850.igen: Add support for v850e2 and v850e2v3
Thanks & Regards,
Rathish.C
[-- Attachment #2: v850-gdb-v850e2-v850e2v3-support.patch --]
[-- Type: application/octet-stream, Size: 97130 bytes --]
diff -upNr gdb-7.2.50-orig/gdb/v850-tdep.c gdb-7.2.50-modified/src/gdb/v850-tdep.c
--- gdb-7.2.50-orig/gdb/v850-tdep.c 2010-09-10 04:34:46.000000000 +0530
+++ gdb-7.2.50-modified/gdb/v850-tdep.c 2010-09-18 19:06:34.000000000 +0530
@@ -100,8 +100,100 @@ enum
E_R61_REGNUM,
E_R62_REGNUM,
E_R63_REGNUM,
- E_R64_REGNUM, E_PC_REGNUM = E_R64_REGNUM,
+
+ /* mpu0 system registers */
+ E_R64_REGNUM,
E_R65_REGNUM,
+ E_R66_REGNUM,
+ E_R67_REGNUM,
+ E_R68_REGNUM,
+ E_R69_REGNUM,
+ E_R70_REGNUM,
+ E_R71_REGNUM,
+ E_R72_REGNUM,
+ E_R73_REGNUM,
+ E_R74_REGNUM,
+ E_R75_REGNUM,
+ E_R76_REGNUM,
+ E_R77_REGNUM,
+ E_R78_REGNUM,
+ E_R79_REGNUM,
+ E_R80_REGNUM,
+ E_R81_REGNUM,
+ E_R82_REGNUM,
+ E_R83_REGNUM,
+ E_R84_REGNUM,
+ E_R85_REGNUM,
+ E_R86_REGNUM,
+ E_R87_REGNUM,
+ E_R88_REGNUM,
+ E_R89_REGNUM,
+ E_R90_REGNUM,
+ E_R91_REGNUM,
+
+ /* mpu1 system registers */
+ E_R92_REGNUM,
+ E_R93_REGNUM,
+ E_R94_REGNUM,
+ E_R95_REGNUM,
+ E_R96_REGNUM,
+ E_R97_REGNUM,
+ E_R98_REGNUM,
+ E_R99_REGNUM,
+ E_R100_REGNUM,
+ E_R101_REGNUM,
+ E_R102_REGNUM,
+ E_R103_REGNUM,
+ E_R104_REGNUM,
+ E_R105_REGNUM,
+ E_R106_REGNUM,
+ E_R107_REGNUM,
+ E_R108_REGNUM,
+ E_R109_REGNUM,
+ E_R110_REGNUM,
+ E_R111_REGNUM,
+ E_R112_REGNUM,
+ E_R113_REGNUM,
+ E_R114_REGNUM,
+ E_R115_REGNUM,
+ E_R116_REGNUM,
+ E_R117_REGNUM,
+ E_R118_REGNUM,
+ E_R119_REGNUM,
+
+ /* fpu system registers */
+ E_R120_REGNUM,
+ E_R121_REGNUM,
+ E_R122_REGNUM,
+ E_R123_REGNUM,
+ E_R124_REGNUM,
+ E_R125_REGNUM,
+ E_R126_REGNUM, E_FPSR_REGNUM = E_R126_REGNUM,
+ E_R127_REGNUM, E_FPEPC_REGNUM = E_R127_REGNUM,
+ E_R128_REGNUM, E_FPST_REGNUM = E_R128_REGNUM,
+ E_R129_REGNUM, E_FPCC_REGNUM = E_R129_REGNUM,
+ E_R130_REGNUM, E_FPCFG_REGNUM = E_R130_REGNUM,
+ E_R131_REGNUM,
+ E_R132_REGNUM,
+ E_R133_REGNUM,
+ E_R134_REGNUM,
+ E_R135_REGNUM,
+ E_R136_REGNUM,
+ E_R137_REGNUM,
+ E_R138_REGNUM,
+ E_R139_REGNUM,
+ E_R140_REGNUM,
+ E_R141_REGNUM,
+ E_R142_REGNUM,
+ E_R143_REGNUM,
+ E_R144_REGNUM,
+ E_R145_REGNUM,
+ E_R146_REGNUM,
+ E_R147_REGNUM,
+
+ /* pc etc. */
+ E_R148_REGNUM, E_PC_REGNUM = E_R148_REGNUM,
+ E_R149_REGNUM,
E_NUM_REGS
};
@@ -142,14 +234,32 @@ static const char *
v850_register_name (struct gdbarch *gdbarch, int regnum)
{
static const char *v850_reg_names[] =
- { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+
"eipc", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7",
"sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
"sr16", "sr17", "sr18", "sr19", "sr20", "sr21", "sr22", "sr23",
"sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
+
+ "sr32", "sr33", "sr34", "sr35", "sr36", "sr37", "sr38", "sr39",
+ "sr40", "sr41", "sr42", "sr43", "sr44", "sr45", "sr46", "sr47",
+ "sr48", "sr49", "sr50", "sr51", "sr52", "sr53", "sr54", "sr55",
+ "sr56", "sr57", "sr58", "sr59",
+
+ "sr60", "sr61", "sr62", "sr63", "sr64", "sr65", "sr66", "sr67",
+ "sr68", "sr69", "sr70", "sr71", "sr72", "sr73", "sr74", "sr75",
+ "sr76", "sr77", "sr78", "sr79", "sr80", "sr81", "sr82", "sr83",
+ "sr84", "sr85", "sr86", "sr87",
+
+ "sr88", "sr89", "sr90", "sr91", "sr92", "sr93", "sr94", "sr95",
+ "sr96", "sr97", "sr98", "sr99", "sr100", "sr101", "sr102", "sr103",
+ "sr104", "sr105", "sr106", "sr107", "sr108", "sr109", "sr110", "sr111",
+ "sr112", "sr113", "sr114", "sr115",
+
"pc", "fp"
};
if (regnum < 0 || regnum >= E_NUM_REGS)
@@ -166,10 +276,27 @@ v850e_register_name (struct gdbarch *gdb
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+
"eipc", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7",
"sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
"ctpc", "ctpsw", "dbpc", "dbpsw", "ctbp", "sr21", "sr22", "sr23",
"sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
+
+ "sr32", "sr33", "sr34", "sr35", "sr36", "sr37", "sr38", "sr39",
+ "sr40", "sr41", "sr42", "sr43", "sr44", "sr45", "sr46", "sr47",
+ "sr48", "sr49", "sr50", "sr51", "sr52", "sr53", "sr54", "sr55",
+ "sr56", "sr57", "sr58", "sr59",
+
+ "sr60", "sr61", "sr62", "sr63", "sr64", "sr65", "sr66", "sr67",
+ "sr68", "sr69", "sr70", "sr71", "sr72", "sr73", "sr74", "sr75",
+ "sr76", "sr77", "sr78", "sr79", "sr80", "sr81", "sr82", "sr83",
+ "sr84", "sr85", "sr86", "sr87",
+
+ "sr88", "sr89", "sr90", "sr91", "sr92", "sr93", "sr94", "sr95",
+ "sr96", "sr97", "sr98", "sr99", "sr100", "sr101", "sr102", "sr103",
+ "sr104", "sr105", "sr106", "sr107", "sr108", "sr109", "sr110", "sr111",
+ "sr112", "sr113", "sr114", "sr115",
+
"pc", "fp"
};
if (regnum < 0 || regnum >= E_NUM_REGS)
@@ -177,6 +304,46 @@ v850e_register_name (struct gdbarch *gdb
return v850e_reg_names[regnum];
}
+static const char *
+v850e2_register_name (struct gdbarch *gdbarch, int regnum)
+{
+ static const char *v850e2_reg_names[] =
+ {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+
+ "eipc", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7",
+ "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
+ "ctpc", "ctpsw", "dbpc", "dbpsw", "ctbp", "sr21", "sr22", "sr23",
+ "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
+
+ /* mpu0 system registers */
+ "vip", "sr33", "sr34", "sr35", "vmecr", "vmtid", "vmadr", "sr39",
+ "vpecr", "vptid", "vpadr", "sr43", "vdecr", "vdtid", "sr46", "sr47",
+ "sr48", "sr49", "sr50", "sr51", "sr52", "sr53", "sr54", "sr55",
+ "sr56", "sr57", "sr58", "sr59",
+
+ /* mpu1 system registers */
+ "mpm", "mpc", "tid", "ppa", "ppm", "ppc", "dcc", "dcv0",
+ "dcv1", "sr69", "spal", "spau", "ipa0l", "ipa0u", "ipa1l", "ipa1u",
+ "iap2l", "ipa2u", "ipa3l", "ipa3u", "dpa0l", "dpa0u", "dpa1l", "dpa1u",
+ "dpa2l", "dpa2u", "dpa3l", "dpa3u",
+
+ /* fpu system registers */
+ "sr88", "sr89", "sr90", "sr91", "sr92", "sr93", "fpsr", "fpepc",
+ "fpst", "fpcc", "fpcfg", "sr99", "sr100", "sr101", "sr102", "sr103",
+ "sr104", "sr105", "sr106", "sr107", "sr108", "sr109", "sr110", "sr111",
+ "sr112", "sr113", "sr114", "sr115",
+
+ "pc", "fp"
+ };
+ if (regnum < 0 || regnum >= E_NUM_REGS)
+ return NULL;
+ return v850e2_reg_names[regnum];
+}
+
/* Returns the default type for register N. */
static struct type *
@@ -996,6 +1163,10 @@ v850_gdbarch_init (struct gdbarch_info i
case bfd_mach_v850e1:
set_gdbarch_register_name (gdbarch, v850e_register_name);
break;
+ case bfd_mach_v850e2:
+ case bfd_mach_v850e2v3:
+ set_gdbarch_register_name (gdbarch, v850e2_register_name);
+ break;
}
set_gdbarch_num_regs (gdbarch, E_NUM_REGS);
diff -upNr gdb-7.2.50-orig/sim/common/sim-trace.c gdb-7.2.50-modified/src/sim/common/sim-trace.c
--- gdb-7.2.50-orig/sim/common/sim-trace.c 2010-04-12 22:23:33.000000000 +0530
+++ gdb-7.2.50-modified/sim/common/sim-trace.c 2010-09-18 19:47:35.000000000 +0530
@@ -486,17 +486,6 @@ trace_uninstall (SIM_DESC sd)
}
}
\f
-typedef enum {
- trace_fmt_invalid,
- trace_fmt_word,
- trace_fmt_fp,
- trace_fmt_fpu,
- trace_fmt_string,
- trace_fmt_bool,
- trace_fmt_addr,
- trace_fmt_instruction_incomplete,
-} data_fmt;
-
/* compute the nr of trace data units consumed by data */
static int
save_data_size (TRACE_DATA *data,
@@ -508,7 +497,7 @@ save_data_size (TRACE_DATA *data,
/* Archive DATA into the trace buffer */
-static void
+void
save_data (SIM_DESC sd,
TRACE_DATA *data,
data_fmt fmt,
diff -upNr gdb-7.2.50-orig/sim/common/sim-trace.h gdb-7.2.50-modified/src/sim/common/sim-trace.h
--- gdb-7.2.50-orig/sim/common/sim-trace.h 2010-01-01 15:33:27.000000000 +0530
+++ gdb-7.2.50-modified/sim/common/sim-trace.h 2010-09-18 19:46:46.000000000 +0530
@@ -243,9 +243,26 @@ extern void trace_generic PARAMS ((SIM_D
...))
__attribute__((format (printf, 4, 5)));
+typedef enum {
+ trace_fmt_invalid,
+ trace_fmt_word,
+ trace_fmt_fp,
+ trace_fmt_fpu,
+ trace_fmt_string,
+ trace_fmt_bool,
+ trace_fmt_addr,
+ trace_fmt_instruction_incomplete,
+} data_fmt;
+
/* Trace a varying number of word sized inputs/outputs. trace_result*
must be called to close the trace operation. */
+extern void save_data PARAMS ((SIM_DESC sd,
+ TRACE_DATA *data,
+ data_fmt fmt,
+ long size,
+ const void *buf));
+
extern void trace_input0 PARAMS ((SIM_DESC sd,
sim_cpu *cpu,
int trace_idx));
diff -upNr gdb-7.2.50-orig/sim/v850/sim-main.h gdb-7.2.50-modified/src/sim/v850/sim-main.h
--- gdb-7.2.50-orig/sim/v850/sim-main.h 2002-11-30 23:31:30.000000000 +0530
+++ gdb-7.2.50-modified/sim/v850/sim-main.h 2010-09-18 19:54:40.000000000 +0530
@@ -15,6 +15,7 @@
#include "sim-basics.h"
#include "sim-signal.h"
+#include "sim-fpu.h"
typedef address_word sim_cia;
@@ -38,6 +39,9 @@ typedef unsigned32 reg_t;
typedef struct _v850_regs {
reg_t regs[32]; /* general-purpose registers */
reg_t sregs[32]; /* system registers, including psw */
+ reg_t mpu0_sregs[28]; /* mpu0 system registers */
+ reg_t mpu1_sregs[28]; /* mpu1 system registers */
+ reg_t fpu_sregs[28]; /* fpu system registers */
reg_t pc;
int dummy_mem; /* where invalid accesses go */
} v850_regs;
@@ -61,6 +65,7 @@ struct sim_state {
#define STATE_CPU(sd,n) (&(sd)->cpu[n])
#else
#define STATE_CPU(sd,n) (&(sd)->cpu[0])
+#define CPU (STATE_CPU (sd, 0))
#endif
#if 0
SIM_ADDR rom_size;
@@ -122,11 +127,15 @@ nia = PC
/* new */
#define GR ((CPU)->reg.regs)
#define SR ((CPU)->reg.sregs)
+#define MPU0_SR ((CPU)->reg.mpu0_sregs)
+#define MPU1_SR ((CPU)->reg.mpu1_sregs)
+#define FPU_SR ((CPU)->reg.fpu_sregs)
/* old */
#define State (STATE_CPU (simulator, 0)->reg)
#define PC (State.pc)
-#define SP (State.regs[3])
+#define SP_REGNO 3
+#define SP (State.regs[SP_REGNO])
#define EP (State.regs[30])
#define EIPC (State.sregs[0])
@@ -135,11 +144,20 @@ nia = PC
#define FEPSW (State.sregs[3])
#define ECR (State.sregs[4])
#define PSW (State.sregs[5])
+#define PSW_REGNO 5
+#define EIIC (SR[13])
+#define FEIC (SR[14])
+#define DBIC (SR[15])
#define CTPC (SR[16])
#define CTPSW (SR[17])
#define DBPC (State.sregs[18])
#define DBPSW (State.sregs[19])
#define CTBP (State.sregs[20])
+#define DIR (SR[21])
+#define EIWR (SR[28])
+#define FEWR (SR[29])
+#define DBWR (SR[30])
+#define BSEL (SR[31])
#define PSW_US BIT32 (8)
#define PSW_NP 0x80
@@ -151,6 +169,210 @@ nia = PC
#define PSW_S 0x2
#define PSW_Z 0x1
+#define PSW_NPV (1<<18)
+#define PSW_DMP (1<<17)
+#define PSW_IMP (1<<16)
+
+#define ECR_EICC 0x0000ffff
+#define ECR_FECC 0xffff0000
+
+/* FPU */
+
+#define FPSR (FPU_SR[6])
+#define FPSR_REGNO 6
+#define FPEPC (FPU_SR[7])
+#define FPST (FPU_SR[8])
+#define FPST_REGNO 8
+#define FPCC (FPU_SR[9])
+#define FPCFG (FPU_SR[10])
+#define FPCFG_REGNO 10
+
+#define FPSR_DEM 0x00200000
+#define FPSR_SEM 0x00100000
+#define FPSR_RM 0x000c0000
+#define FPSR_RN 0x00000000
+#define FPSR_FS 0x00020000
+#define FPSR_PR 0x00010000
+
+#define FPSR_XC 0x0000fc00
+#define FPSR_XCE 0x00008000
+#define FPSR_XCV 0x00004000
+#define FPSR_XCZ 0x00002000
+#define FPSR_XCO 0x00001000
+#define FPSR_XCU 0x00000800
+#define FPSR_XCI 0x00000400
+
+#define FPSR_XE 0x000003e0
+#define FPSR_XEV 0x00000200
+#define FPSR_XEZ 0x00000100
+#define FPSR_XEO 0x00000080
+#define FPSR_XEU 0x00000040
+#define FPSR_XEI 0x00000020
+
+#define FPSR_XP 0x0000001f
+#define FPSR_XPV 0x00000010
+#define FPSR_XPZ 0x00000008
+#define FPSR_XPO 0x00000004
+#define FPSR_XPU 0x00000002
+#define FPSR_XPI 0x00000001
+
+#define FPST_PR 0x00008000
+#define FPST_XCE 0x00002000
+#define FPST_XCV 0x00001000
+#define FPST_XCZ 0x00000800
+#define FPST_XCO 0x00000400
+#define FPST_XCU 0x00000200
+#define FPST_XCI 0x00000100
+
+#define FPST_XPV 0x00000010
+#define FPST_XPZ 0x00000008
+#define FPST_XPO 0x00000004
+#define FPST_XPU 0x00000002
+#define FPST_XPI 0x00000001
+
+#define FPCFG_RM 0x00000180
+#define FPCFG_XEV 0x00000010
+#define FPCFG_XEZ 0x00000008
+#define FPCFG_XEO 0x00000004
+#define FPCFG_XEU 0x00000002
+#define FPCFG_XEI 0x00000001
+
+#define GET_FPCC()\
+ ((FPSR >> 24) &0xf)
+
+#define CLEAR_FPCC(bbb)\
+ (FPSR &= ~(1 << (bbb+24)))
+
+#define SET_FPCC(bbb)\
+ (FPSR |= 1 << (bbb+24))
+
+#define TEST_FPCC(bbb)\
+ ((FPSR & (1 << (bbb+24))) != 0)
+
+#define FPSR_GET_ROUND() \
+ (((FPSR & FPSR_RM) == FPSR_RN) ? sim_fpu_round_near \
+ : ((FPSR & FPSR_RM) == 0x00040000) ? sim_fpu_round_up \
+ : ((FPSR & FPSR_RM) == 0x00080000) ? sim_fpu_round_down \
+ : sim_fpu_round_zero)
+
+
+enum FPU_COMPARE {
+ FPU_CMP_F = 0,
+ FPU_CMP_UN,
+ FPU_CMP_EQ,
+ FPU_CMP_UEQ,
+ FPU_CMP_OLT,
+ FPU_CMP_ULT,
+ FPU_CMP_OLE,
+ FPU_CMP_ULE,
+ FPU_CMP_SF,
+ FPU_CMP_NGLE,
+ FPU_CMP_SEQ,
+ FPU_CMP_NGL,
+ FPU_CMP_LT,
+ FPU_CMP_NGE,
+ FPU_CMP_LE,
+ FPU_CMP_NGT
+};
+
+
+/* MPU */
+#define MPM (MPU1_SR[0])
+#define MPC (MPU1_SR[1])
+#define MPC_REGNO 1
+#define TID (MPU1_SR[2])
+#define PPA (MPU1_SR[3])
+#define PPM (MPU1_SR[4])
+#define PPC (MPU1_SR[5])
+#define DCC (MPU1_SR[6])
+#define DCV0 (MPU1_SR[7])
+#define DCV1 (MPU1_SR[8])
+#define SPAL (MPU1_SR[10])
+#define SPAU (MPU1_SR[11])
+#define IPA0L (MPU1_SR[12])
+#define IPA0U (MPU1_SR[13])
+#define IPA1L (MPU1_SR[14])
+#define IPA1U (MPU1_SR[15])
+#define IPA2L (MPU1_SR[16])
+#define IPA2U (MPU1_SR[17])
+#define IPA3L (MPU1_SR[18])
+#define IPA3U (MPU1_SR[19])
+#define DPA0L (MPU1_SR[20])
+#define DPA0U (MPU1_SR[21])
+#define DPA1L (MPU1_SR[22])
+#define DPA1U (MPU1_SR[23])
+#define DPA2L (MPU1_SR[24])
+#define DPA2U (MPU1_SR[25])
+#define DPA3L (MPU1_SR[26])
+#define DPA3U (MPU1_SR[27])
+
+#define PPC_PPE 0x1
+#define SPAL_SPE 0x1
+#define SPAL_SPS 0x10
+
+#define VIP (MPU0_SR[0])
+#define VMECR (MPU0_SR[4])
+#define VMTID (MPU0_SR[5])
+#define VMADR (MPU0_SR[6])
+#define VPECR (MPU0_SR[8])
+#define VPTID (MPU0_SR[9])
+#define VPADR (MPU0_SR[10])
+#define VDECR (MPU0_SR[12])
+#define VDTID (MPU0_SR[13])
+
+#define MPM_AUE 0x2
+#define MPM_MPE 0x1
+
+#define VMECR_VMX 0x2
+#define VMECR_VMR 0x4
+#define VMECR_VMW 0x8
+#define VMECR_VMS 0x10
+#define VMECR_VMRMW 0x20
+#define VMECR_VMMS 0x40
+
+#define IPA2ADDR(IPA) ((IPA) & 0x1fffff80)
+#define IPA_IPE 0x1
+#define IPA_IPX 0x2
+#define IPA_IPR 0x4
+#define IPE0 (IPA0L & IPA_IPE)
+#define IPE1 (IPA1L & IPA_IPE)
+#define IPE2 (IPA2L & IPA_IPE)
+#define IPE3 (IPA3L & IPA_IPE)
+#define IPX0 (IPA0L & IPA_IPX)
+#define IPX1 (IPA1L & IPA_IPX)
+#define IPX2 (IPA2L & IPA_IPX)
+#define IPX3 (IPA3L & IPA_IPX)
+#define IPR0 (IPA0L & IPA_IPR)
+#define IPR1 (IPA1L & IPA_IPR)
+#define IPR2 (IPA2L & IPA_IPR)
+#define IPR3 (IPA3L & IPA_IPR)
+
+#define DPA2ADDR(DPA) ((DPA) & 0x1fffff80)
+#define DPA_DPE 0x1
+#define DPA_DPR 0x4
+#define DPA_DPW 0x8
+#define DPE0 (DPA0L & DPA_DPE)
+#define DPE1 (DPA1L & DPA_DPE)
+#define DPE2 (DPA2L & DPA_DPE)
+#define DPE3 (DPA3L & DPA_DPE)
+#define DPR0 (DPA0L & DPA_DPR)
+#define DPR1 (DPA1L & DPA_DPR)
+#define DPR2 (DPA2L & DPA_DPR)
+#define DPR3 (DPA3L & DPA_DPR)
+#define DPW0 (DPA0L & DPA_DPW)
+#define DPW1 (DPA1L & DPA_DPW)
+#define DPW2 (DPA2L & DPA_DPW)
+#define DPW3 (DPA3L & DPA_DPW)
+
+#define DCC_DCE0 0x1
+#define DCC_DCE1 0x10000
+
+#define PPA2ADDR(PPA) ((PPA) & 0x1fffff80)
+#define PPC_PPC 0xfffffffe
+#define PPC_PPE 0x1
+#define PPC_PPM 0x0000fff8
+
+
#define SEXT3(x) ((((x)&0x7)^(~0x3))+0x4)
/* sign-extend a 4-bit number */
@@ -344,6 +566,79 @@ do { \
} \
} while (0)
+#define TRACE_FP_INPUT_FPU1(V0) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ { \
+ unsigned64 f0; \
+ sim_fpu_to64 (&f0, (V0)); \
+ trace_input_fp1 (SD, CPU, TRACE_FPU_IDX, f0); \
+ } \
+} while (0)
+
+#define TRACE_FP_INPUT_FPU2(V0, V1) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ { \
+ unsigned64 f0, f1; \
+ sim_fpu_to64 (&f0, (V0)); \
+ sim_fpu_to64 (&f1, (V1)); \
+ trace_input_fp2 (SD, CPU, TRACE_FPU_IDX, f0, f1); \
+ } \
+} while (0)
+
+#define TRACE_FP_INPUT_FPU3(V0, V1, V2) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ { \
+ unsigned64 f0, f1, f2; \
+ sim_fpu_to64 (&f0, (V0)); \
+ sim_fpu_to64 (&f1, (V1)); \
+ sim_fpu_to64 (&f2, (V2)); \
+ trace_input_fp3 (SD, CPU, TRACE_FPU_IDX, f0, f1, f2); \
+ } \
+} while (0)
+
+#define TRACE_FP_INPUT_BOOL1_FPU2(V0, V1, V2) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ { \
+ int d0 = (V0); \
+ unsigned64 f1, f2; \
+ TRACE_DATA *data = CPU_TRACE_DATA (CPU); \
+ TRACE_IDX (data) = TRACE_FPU_IDX; \
+ sim_fpu_to64 (&f1, (V1)); \
+ sim_fpu_to64 (&f2, (V2)); \
+ save_data (SD, data, trace_fmt_bool, sizeof (d0), &d0); \
+ save_data (SD, data, trace_fmt_fp, sizeof (fp_word), &f1); \
+ save_data (SD, data, trace_fmt_fp, sizeof (fp_word), &f2); \
+ } \
+} while (0)
+
+#define TRACE_FP_INPUT_WORD2(V0, V1) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ trace_input_word2 (SD, CPU, TRACE_FPU_IDX, (V0), (V1)); \
+} while (0)
+
+#define TRACE_FP_RESULT_FPU1(R0) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ { \
+ unsigned64 f0; \
+ sim_fpu_to64 (&f0, (R0)); \
+ trace_result_fp1 (SD, CPU, TRACE_FPU_IDX, f0); \
+ } \
+} while (0)
+
+#define TRACE_FP_RESULT_WORD1(R0) TRACE_FP_RESULT_WORD(R0)
+
+#define TRACE_FP_RESULT_WORD2(R0, R1) \
+do { \
+ if (TRACE_FPU_P (CPU)) \
+ trace_result_word2 (SD, CPU, TRACE_FPU_IDX, (R0), (R1)); \
+} while (0)
+
#else
#define trace_input(NAME, IN1, IN2)
#define trace_output(RESULT)
diff -upNr gdb-7.2.50-orig/sim/v850/simops.c gdb-7.2.50-modified/src/sim/v850/simops.c
--- gdb-7.2.50-orig/sim/v850/simops.c 2008-02-06 10:11:26.000000000 +0530
+++ gdb-7.2.50-modified/sim/v850/simops.c 2010-09-18 19:53:00.000000000 +0530
@@ -320,7 +320,7 @@ condition_met (unsigned code)
return 1;
}
-static unsigned long
+unsigned long
Add32 (unsigned long a1, unsigned long a2, int * carry)
{
unsigned long result = (a1 + a2);
@@ -2761,3 +2761,717 @@ OP_307E0 (void)
return 4;
}
+/* V850E2R FPU functions */
+/*
+ sim_fpu_status_invalid_snan = 1, -V--- (sim spec.)
+ sim_fpu_status_invalid_qnan = 2, ----- (sim spec.)
+ sim_fpu_status_invalid_isi = 4, (inf - inf) -V---
+ sim_fpu_status_invalid_idi = 8, (inf / inf) -V---
+ sim_fpu_status_invalid_zdz = 16, (0 / 0) -V---
+ sim_fpu_status_invalid_imz = 32, (inf * 0) -V---
+ sim_fpu_status_invalid_cvi = 64, convert to integer -V---
+ sim_fpu_status_invalid_div0 = 128, (X / 0) --Z--
+ sim_fpu_status_invalid_cmp = 256, compare ----- (sim spec.)
+ sim_fpu_status_invalid_sqrt = 512, -V---
+ sim_fpu_status_rounded = 1024, I----
+ sim_fpu_status_inexact = 2048, I---- (sim spec.)
+ sim_fpu_status_overflow = 4096, I--O-
+ sim_fpu_status_underflow = 8192, I---U
+ sim_fpu_status_denorm = 16384, ----U (sim spec.)
+*/
+
+void update_fpsr (SIM_DESC sd, sim_fpu_status status, unsigned int mask, unsigned int double_op_p)
+{
+ unsigned int fpsr = FPSR & mask;
+
+ unsigned int flags = 0;
+
+ if (fpsr & FPSR_XEI
+ && ((status & (sim_fpu_status_rounded
+ | sim_fpu_status_overflow
+ | sim_fpu_status_inexact))
+ || (status & sim_fpu_status_underflow
+ && (fpsr & (FPSR_XEU | FPSR_XEI)) == 0
+ && fpsr & FPSR_FS)))
+ {
+ flags |= FPSR_XCI | FPSR_XPI;
+ }
+
+ if (fpsr & FPSR_XEV
+ && (status & (sim_fpu_status_invalid_isi
+ | sim_fpu_status_invalid_imz
+ | sim_fpu_status_invalid_zdz
+ | sim_fpu_status_invalid_idi
+ | sim_fpu_status_invalid_cvi
+ | sim_fpu_status_invalid_sqrt
+ | sim_fpu_status_invalid_snan)))
+ {
+ flags |= FPSR_XCV | FPSR_XPV;
+ }
+
+ if (fpsr & FPSR_XEZ
+ && (status & sim_fpu_status_invalid_div0))
+ {
+ flags |= FPSR_XCV | FPSR_XPV;
+ }
+
+ if (fpsr & FPSR_XEO
+ && (status & sim_fpu_status_overflow))
+ {
+ flags |= FPSR_XCO | FPSR_XPO;
+ }
+
+ if (((fpsr & FPSR_XEU) || (fpsr & FPSR_FS) == 0)
+ && (status & (sim_fpu_status_underflow
+ | sim_fpu_status_denorm)))
+ {
+ flags |= FPSR_XCU | FPSR_XPU;
+ }
+
+ if (flags)
+ {
+ FPSR &= ~FPSR_XC;
+ FPSR |= flags;
+
+ SignalExceptionFPE(sd, double_op_p);
+ }
+}
+
+/*
+ exception
+*/
+
+void SignalException(SIM_DESC sd)
+{
+ if (MPM & MPM_AUE)
+ {
+ PSW = PSW & ~(PSW_NPV | PSW_DMP | PSW_IMP);
+ }
+}
+
+void SignalExceptionFPE(SIM_DESC sd, unsigned int double_op_p)
+{
+ if (((PSW & (PSW_NP|PSW_ID)) == 0)
+ || !(FPSR & (double_op_p ? FPSR_DEM : FPSR_SEM)))
+ {
+ EIPC = PC;
+ EIPSW = PSW;
+ EIIC = (FPSR & (double_op_p ? FPSR_DEM : FPSR_SEM))
+ ? 0x71 : 0x72;
+ PSW |= (PSW_EP | PSW_ID);
+ PC = 0x70;
+
+ SignalException(sd);
+ }
+}
+
+
+void check_invalid_snan(SIM_DESC sd, sim_fpu_status status, unsigned int double_op_p)
+{
+ if ((FPSR & FPSR_XEI)
+ && (status & sim_fpu_status_invalid_snan))
+ {
+ FPSR &= ~FPSR_XC;
+ FPSR |= FPSR_XCV;
+ FPSR |= FPSR_XPV;
+ SignalExceptionFPE(sd, double_op_p);
+ }
+}
+
+int v850_float_compare(SIM_DESC sd, int cmp, sim_fpu wop1, sim_fpu wop2, int double_op_p)
+{
+ int result = -1;
+
+ if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2))
+ {
+ if (cmp & 0x8)
+ {
+ if (FPSR & FPSR_XEV)
+ {
+ FPSR |= FPSR_XCV | FPSR_XPV;
+ SignalExceptionFPE(sd, double_op_p);
+ }
+ }
+
+ switch (cmp)
+ {
+ case FPU_CMP_F:
+ result = 0;
+ break;
+ case FPU_CMP_UN:
+ result = 1;
+ break;
+ case FPU_CMP_EQ:
+ result = 0;
+ break;
+ case FPU_CMP_UEQ:
+ result = 1;
+ break;
+ case FPU_CMP_OLT:
+ result = 0;
+ break;
+ case FPU_CMP_ULT:
+ result = 1;
+ break;
+ case FPU_CMP_OLE:
+ result = 0;
+ break;
+ case FPU_CMP_ULE:
+ result = 1;
+ break;
+ case FPU_CMP_SF:
+ result = 0;
+ break;
+ case FPU_CMP_NGLE:
+ result = 1;
+ break;
+ case FPU_CMP_SEQ:
+ result = 0;
+ break;
+ case FPU_CMP_NGL:
+ result = 1;
+ break;
+ case FPU_CMP_LT:
+ result = 0;
+ break;
+ case FPU_CMP_NGE:
+ result = 1;
+ break;
+ case FPU_CMP_LE:
+ result = 0;
+ break;
+ case FPU_CMP_NGT:
+ result = 1;
+ break;
+ default:
+ abort();
+ }
+ }
+ else if (sim_fpu_is_infinity(&wop1) && sim_fpu_is_infinity(&wop2)
+ && sim_fpu_sign(&wop1) == sim_fpu_sign(&wop2))
+ {
+ switch (cmp)
+ {
+ case FPU_CMP_F:
+ result = 0;
+ break;
+ case FPU_CMP_UN:
+ result = 0;
+ break;
+ case FPU_CMP_EQ:
+ result = 1;
+ break;
+ case FPU_CMP_UEQ:
+ result = 1;
+ break;
+ case FPU_CMP_OLT:
+ result = 0;
+ break;
+ case FPU_CMP_ULT:
+ result = 0;
+ break;
+ case FPU_CMP_OLE:
+ result = 1;
+ break;
+ case FPU_CMP_ULE:
+ result = 1;
+ break;
+ case FPU_CMP_SF:
+ result = 0;
+ break;
+ case FPU_CMP_NGLE:
+ result = 0;
+ break;
+ case FPU_CMP_SEQ:
+ result = 1;
+ break;
+ case FPU_CMP_NGL:
+ result = 1;
+ break;
+ case FPU_CMP_LT:
+ result = 0;
+ break;
+ case FPU_CMP_NGE:
+ result = 0;
+ break;
+ case FPU_CMP_LE:
+ result = 1;
+ break;
+ case FPU_CMP_NGT:
+ result = 1;
+ break;
+ default:
+ abort();
+ }
+ }
+ else
+ {
+ int gt = 0,lt = 0,eq = 0, status;
+
+ status = sim_fpu_cmp( &wop1, &wop2 );
+
+ switch (status) {
+ case SIM_FPU_IS_SNAN:
+ case SIM_FPU_IS_QNAN:
+ abort();
+ break;
+
+ case SIM_FPU_IS_NINF:
+ lt = 1;
+ break;
+ case SIM_FPU_IS_PINF:
+ gt = 1;
+ break;
+ case SIM_FPU_IS_NNUMBER:
+ lt = 1;
+ break;
+ case SIM_FPU_IS_PNUMBER:
+ gt = 1;
+ break;
+ case SIM_FPU_IS_NDENORM:
+ lt = 1;
+ break;
+ case SIM_FPU_IS_PDENORM:
+ gt = 1;
+ break;
+ case SIM_FPU_IS_NZERO:
+ case SIM_FPU_IS_PZERO:
+ eq = 1;
+ break;
+ }
+
+ switch (cmp)
+ {
+ case FPU_CMP_F:
+ result = 0;
+ break;
+ case FPU_CMP_UN:
+ result = 0;
+ break;
+ case FPU_CMP_EQ:
+ result = eq;
+ break;
+ case FPU_CMP_UEQ:
+ result = eq;
+ break;
+ case FPU_CMP_OLT:
+ result = lt;
+ break;
+ case FPU_CMP_ULT:
+ result = lt;
+ break;
+ case FPU_CMP_OLE:
+ result = lt || eq;
+ break;
+ case FPU_CMP_ULE:
+ result = lt || eq;
+ break;
+ case FPU_CMP_SF:
+ result = 0;
+ break;
+ case FPU_CMP_NGLE:
+ result = 0;
+ break;
+ case FPU_CMP_SEQ:
+ result = eq;
+ break;
+ case FPU_CMP_NGL:
+ result = eq;
+ break;
+ case FPU_CMP_LT:
+ result = lt;
+ break;
+ case FPU_CMP_NGE:
+ result = lt;
+ break;
+ case FPU_CMP_LE:
+ result = lt || eq;
+ break;
+ case FPU_CMP_NGT:
+ result = lt || eq;
+ break;
+ }
+ }
+
+ ASSERT(result != -1);
+ return result;
+}
+
+void v850_div(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p, unsigned int *op3p)
+{
+ signed long int quotient;
+ signed long int remainder;
+ signed long int divide_by;
+ signed long int divide_this;
+ bfd_boolean overflow = FALSE;
+
+ /* Compute the result. */
+ divide_by = op0;
+ divide_this = op1;
+
+ if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31)))
+ {
+ overflow = TRUE;
+ divide_by = 1;
+ }
+
+ quotient = divide_this / divide_by;
+ remainder = divide_this % divide_by;
+
+ /* Set condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_OV);
+
+ if (overflow) PSW |= PSW_OV;
+ if (quotient == 0) PSW |= PSW_Z;
+ if (quotient < 0) PSW |= PSW_S;
+
+ *op2p = quotient;
+ *op3p = remainder;
+}
+
+void v850_divu(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p, unsigned int *op3p)
+{
+ unsigned long int quotient;
+ unsigned long int remainder;
+ unsigned long int divide_by;
+ unsigned long int divide_this;
+ bfd_boolean overflow = FALSE;
+
+ /* Compute the result. */
+
+ divide_by = op0;
+ divide_this = op1;
+
+ if (divide_by == 0)
+ {
+ overflow = TRUE;
+ divide_by = 1;
+ }
+
+ quotient = divide_this / divide_by;
+ remainder = divide_this % divide_by;
+
+ /* Set condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_OV);
+
+ if (overflow) PSW |= PSW_OV;
+ if (quotient == 0) PSW |= PSW_Z;
+ if (quotient & 0x80000000) PSW |= PSW_S;
+
+ *op2p = quotient;
+ *op3p = remainder;
+}
+
+
+void v850_sar(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
+{
+ unsigned int result, z, s, cy;
+
+ op0 &= 0x1f;
+ result = (signed)op1 >> op0;
+
+ /* Compute the condition codes. */
+ z = (result == 0);
+ s = (result & 0x80000000);
+ cy = (op1 & (1 << (op0 - 1)));
+
+ /* Store the result and condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
+ PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+ | (cy ? PSW_CY : 0));
+
+ *op2p = result;
+}
+
+void v850_shl(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
+{
+ unsigned int result, z, s, cy;
+
+ op0 &= 0x1f;
+ result = op1 << op0;
+
+ /* Compute the condition codes. */
+ z = (result == 0);
+ s = (result & 0x80000000);
+ cy = (op1 & (1 << (32 - op0)));
+
+ /* Store the result and condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
+ PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+ | (cy ? PSW_CY : 0));
+
+ *op2p = result;
+}
+
+void v850_shr(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
+{
+ unsigned int result, z, s, cy;
+
+ op0 &= 0x1f;
+ result = op1 >> op0;
+
+ /* Compute the condition codes. */
+ z = (result == 0);
+ s = (result & 0x80000000);
+ cy = (op1 & (1 << (op0 - 1)));
+
+ /* Store the result and condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY);
+ PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+ | (cy ? PSW_CY : 0));
+
+ *op2p = result;
+}
+
+void v850_satadd(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
+{
+ unsigned int result, z, s, cy, ov, sat;
+
+ result = op0 + op1;
+
+ /* Compute the condition codes. */
+ z = (result == 0);
+ s = (result & 0x80000000);
+ cy = (result < op0 || result < op1);
+ ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
+ && (op0 & 0x80000000) != (result & 0x80000000));
+ sat = ov;
+
+ /* Store the result and condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+ PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+ | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
+ | (sat ? PSW_SAT : 0));
+
+ /* Handle saturated results. */
+ if (sat && s)
+ {
+ result = 0x7fffffff;
+ PSW &= ~PSW_S;
+ }
+ else if (sat)
+ {
+ result = 0x80000000;
+ PSW |= PSW_S;
+ }
+
+ *op2p = result;
+}
+
+void v850_satsub(SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p)
+{
+ unsigned int result, z, s, cy, ov, sat;
+
+ /* Compute the result. */
+ result = op1 - op0;
+
+ /* Compute the condition codes. */
+ z = (result == 0);
+ s = (result & 0x80000000);
+ cy = (op1 < op0);
+ ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
+ && (op1 & 0x80000000) != (result & 0x80000000));
+ sat = ov;
+
+ /* Store the result and condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+ PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+ | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)
+ | (sat ? PSW_SAT : 0));
+
+ /* Handle saturated results. */
+ if (sat && s)
+ {
+ result = 0x7fffffff;
+ PSW &= ~PSW_S;
+ }
+ else if (sat)
+ {
+ result = 0x80000000;
+ PSW |= PSW_S;
+ }
+
+ *op2p = result;
+}
+
+unsigned32
+load_data_mem(sd, addr, len)
+ SIM_DESC sd;
+ SIM_ADDR addr;
+ int len;
+{
+ uint32 data;
+
+ switch (len)
+ {
+ case 1:
+ data = sim_core_read_unaligned_1 (STATE_CPU (sd, 0),
+ PC, read_map, addr);
+ break;
+ case 2:
+ data = sim_core_read_unaligned_2 (STATE_CPU (sd, 0),
+ PC, read_map, addr);
+ break;
+ case 4:
+ data = sim_core_read_unaligned_4 (STATE_CPU (sd, 0),
+ PC, read_map, addr);
+ break;
+ default:
+ abort ();
+ }
+ return data;
+}
+
+void
+store_data_mem(sd, addr, len, data)
+ SIM_DESC sd;
+ SIM_ADDR addr;
+ int len;
+ unsigned32 data;
+{
+ switch (len)
+ {
+ case 1:
+ store_mem(addr, 1, data);
+ break;
+ case 2:
+ store_mem(addr, 2, data);
+ break;
+ case 4:
+ store_mem(addr, 4, data);
+ break;
+ default:
+ abort ();
+ }
+}
+
+int mpu_load_mem_test(SIM_DESC sd, unsigned int addr, int size, int base_reg)
+{
+ int result = 1;
+
+ if (PSW & PSW_DMP)
+ {
+ if (IPE0 && addr >= IPA2ADDR(IPA0L) && addr <= IPA2ADDR(IPA0L) && IPR0)
+ {
+ /* text area */
+ }
+ else if (IPE1 && addr >= IPA2ADDR(IPA1L) && addr <= IPA2ADDR(IPA1L) && IPR1)
+ {
+ /* text area */
+ }
+ else if (IPE2 && addr >= IPA2ADDR(IPA2L) && addr <= IPA2ADDR(IPA2L) && IPR2)
+ {
+ /* text area */
+ }
+ else if (IPE3 && addr >= IPA2ADDR(IPA3L) && addr <= IPA2ADDR(IPA3L) && IPR3)
+ {
+ /* text area */
+ }
+ else if (addr >= PPA2ADDR(PPA & ~PPM) && addr <= DPA2ADDR(PPA | PPM))
+ {
+ /* preifarallel area */
+ }
+ else if (addr >= PPA2ADDR(SPAL) && addr <= DPA2ADDR(SPAU))
+ {
+ /* stack area */
+ }
+ else if (DPE0 && addr >= DPA2ADDR(DPA0L) && addr <= DPA2ADDR(DPA0L) && DPR0
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else if (DPE1 && addr >= DPA2ADDR(DPA1L) && addr <= DPA2ADDR(DPA1L) && DPR1
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else if (DPE2 && addr >= DPA2ADDR(DPA2L) && addr <= DPA2ADDR(DPA2L) && DPR2
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else if (DPE3 && addr >= DPA2ADDR(DPA3L) && addr <= DPA2ADDR(DPA3L) && DPR3
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else
+ {
+ VMECR &= ~(VMECR_VMW | VMECR_VMX);
+ VMECR |= VMECR_VMR;
+ VMADR = addr;
+ VMTID = TID;
+ FEIC = 0x431;
+
+ PC = 0x30;
+
+ SignalException(sd);
+ result = 0;
+ }
+ }
+
+ return result;
+}
+
+int mpu_store_mem_test(SIM_DESC sd, unsigned int addr, int size, int base_reg)
+{
+ int result = 1;
+
+ if (PSW & PSW_DMP)
+ {
+ if (addr >= PPA2ADDR(PPA & ~PPM) && addr <= DPA2ADDR(PPA | PPM))
+ {
+ /* preifarallel area */
+ }
+ else if (addr >= PPA2ADDR(SPAL) && addr <= DPA2ADDR(SPAU))
+ {
+ /* stack area */
+ }
+ else if (DPE0 && addr >= DPA2ADDR(DPA0L) && addr <= DPA2ADDR(DPA0L) && DPW0
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else if (DPE1 && addr >= DPA2ADDR(DPA1L) && addr <= DPA2ADDR(DPA1L) && DPW1
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else if (DPE2 && addr >= DPA2ADDR(DPA2L) && addr <= DPA2ADDR(DPA2L) && DPW2
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else if (DPE3 && addr >= DPA2ADDR(DPA3L) && addr <= DPA2ADDR(DPA3L) && DPW3
+ && ((SPAL & SPAL_SPS) ? base_reg == SP_REGNO : 1))
+ {
+ /* data area */
+ }
+ else
+ {
+ if (addr >= PPA2ADDR(PPA & ~PPM) && addr <= DPA2ADDR(PPA | PPM))
+ {
+ FEIC = 0x432;
+ VPTID = TID;
+ VPADR = PC;
+#ifdef NOT_YET
+ VIP_PP;
+ VPECR;
+#endif
+ }
+ else
+ {
+ FEIC = 0x431;
+ VMTID = TID;
+ VMADR = VMECR;
+ VMECR &= ~(VMECR_VMW | VMECR_VMX);
+ VMECR |= VMECR_VMR;
+ PC = 0x30;
+ }
+ result = 0;
+ }
+ }
+
+ return result;
+}
+
diff -upNr gdb-7.2.50-orig/sim/v850/simops.h gdb-7.2.50-modified/src/sim/v850/simops.h
--- gdb-7.2.50-orig/sim/v850/simops.h 2003-04-06 14:21:04.000000000 +0530
+++ gdb-7.2.50-modified/sim/v850/simops.h 2010-09-18 18:14:56.000000000 +0530
@@ -75,4 +75,51 @@ int OP_22007E0 (void);
int OP_307F0 (void);
int OP_107F0 (void);
int OP_307E0 (void);
+
+int v850_float_compare(SIM_DESC sd, int cmp, sim_fpu wop1, sim_fpu wop2, int double_op_p);
+
+/* MEMORY ACCESS */
+unsigned32 load_data_mem(SIM_DESC sd, SIM_ADDR addr, int len);
+void store_data_mem(SIM_DESC sd, SIM_ADDR addr, int len, unsigned32 data);
+
+unsigned long Add32 (unsigned long a1, unsigned long a2, int * carry);
+
+/* FPU */
+
+/*
+ FPU: update FPSR flags
+ invalid, inexact, overflow, underflow
+ */
+
+extern void check_invalid_snan (SIM_DESC sd, sim_fpu_status, unsigned int);
+
+#define check_cvt_fi(sd, status, double_op_p) \
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI, double_op_p)
+
+#define check_cvt_if(sd, status, double_op_p) \
+ update_fpsr (sd, status, FPSR_XEI, double_op_p)
+
+#define check_cvt_ff(sd, status, double_op_p) \
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, double_op_p)
+
+extern void update_fpsr (SIM_DESC sd, sim_fpu_status, unsigned int, unsigned int);
+
+
+/*
+ Exception
+ */
+void SignalException (SIM_DESC sd);
+void SignalExceptionFPE (SIM_DESC sd, unsigned int double_op_p);
+
+int mpu_load_mem_test (SIM_DESC sd, unsigned int addr, int len, int base_reg);
+int mpu_store_mem_test (SIM_DESC sd, unsigned int addr, int len, int base_reg);
+
+void v850_sar (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p);
+void v850_shl (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p);
+void v850_shr (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p);
+void v850_satadd (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p);
+void v850_satsub (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p);
+void v850_div (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p, unsigned int *op3p);
+void v850_divu (SIM_DESC sd, unsigned int op0, unsigned int op1, unsigned int *op2p, unsigned int *op3p);
+
#endif
diff -upNr gdb-7.2.50-orig/sim/v850/v850-dc gdb-7.2.50-modified/src/sim/v850/v850-dc
--- gdb-7.2.50-orig/sim/v850/v850-dc 2003-09-05 23:16:52.000000000 +0530
+++ gdb-7.2.50-modified/sim/v850/v850-dc 2010-09-18 17:56:36.000000000 +0530
@@ -12,7 +12,9 @@
switch,combine : 4 : 0 : : : : 1 : V,VII :
switch,combine : 4 : 0 : : : : 1 : V,XIII : v850e
switch,combine : 4 : 0 : : : : 1 : V,XIII : v850e1
-
+ switch,combine : 4 : 0 : : : : 1 : V,XIII : v850e2
+ switch,combine : 4 : 0 : : : : 1 : V,XIII : v850e2v3
+ switch,combine : 10 : 5 : : : : 0 : F_I : v850e2v3
# for opcode 63, 127, 1087 et.al.
@@ -27,3 +29,28 @@
# for opcode 66 - divh/break
switch,combine : 4 : 0 : : : : 0 : I :
+
+# for ilgop, macu
+ switch,combine : 10 : 9 : : : : 1 : X,XI : v850e2
+ switch,combine : 10 : 9 : : : : 1 : X,XI : v850e2v3
+
+#for cmovf.s, setf
+ switch,combine : 10 : 10 : : : : 1 :F_I,IX : v850e2v3
+
+# for cmovf.s trfsr
+ switch,combine : 15 : 11 : : : : 1 :F_I : v850e2v3
+
+# for trncf.sw, cvtf.sw
+ switch,combine : 0 : 0 : : : : 0 :F_I : v850e2v3
+ switch,combine : 3 : 3 : : : : 0 :F_I : v850e2v3
+
+# for rsqrtf.s, sqrtf.s
+ switch,combine : 1 : 1 : : : : 0 :F_I : v850e2v3
+
+# for maddf.s, trap
+ switch,combine : 8 : 8 : : : : 1 :F_I,X : v850e2v3
+ switch,combine : 10 : 10 : : : : 1 :F_I,X : v850e2v3
+
+# for jr32 jarl32
+ switch,combine : 4 : 0 : : : : 0 :VI : v850e2
+ switch,combine : 4 : 0 : : : : 0 :VI : v850e2v3
diff -upNr gdb-7.2.50-orig/sim/v850/v850.igen gdb-7.2.50-modified/sim/v850/v850.igen
--- gdb-7.2.50-orig/sim/v850/v850.igen 2008-02-06 10:11:26.000000000 +0530
+++ gdb-7.2.50-modified/sim/v850/v850.igen 2010-09-20 14:06:40.000000000 +0530
@@ -6,6 +6,7 @@
:option:::format-names:XI,XII,XIII
:option:::format-names:XIV,XV
:option:::format-names:Z
+:option:::format-names:F_I
:model:::v850:v850:
@@ -14,12 +15,22 @@
:model:::v850e:v850e:
:option:::multi-sim:true
:model:::v850e1:v850e1:
+:option:::multi-sim:true
+:model:::v850e2:v850e2:
+:option:::multi-sim:true
+:model:::v850e2v3:v850e2v3:
// Cache macros
:cache:::unsigned:reg1:RRRRR:(RRRRR)
:cache:::unsigned:reg2:rrrrr:(rrrrr)
:cache:::unsigned:reg3:wwwww:(wwwww)
+:cache:::unsigned:reg4:W,WWWW:((W << 4) + WWWW)
+
+:cache:::unsigned:reg1e:RRRR:(RRRR << 1)
+:cache:::unsigned:reg2e:rrrr:(rrrr << 1)
+:cache:::unsigned:reg3e:wwww:(wwww << 1)
+:cache:::unsigned:reg4e:mmmm:(mmmm << 1)
:cache:::unsigned:disp4:dddd:(dddd)
:cache:::unsigned:disp5:dddd:(dddd << 1)
@@ -29,7 +40,10 @@
:cache:::unsigned:disp9:ddddd,ddd:SEXT32 ((ddddd << 4) + (ddd << 1), 9 - 1)
:cache:::unsigned:disp16:dddddddddddddddd:EXTEND16 (dddddddddddddddd)
:cache:::unsigned:disp16:ddddddddddddddd: EXTEND16 (ddddddddddddddd << 1)
+:cache:::unsigned:disp17:d,ddddddddddddddd:SEXT32 (((d <<16) + (ddddddddddddddd << 1)), 17 - 1)
:cache:::unsigned:disp22:dddddd,ddddddddddddddd: SEXT32 ((dddddd << 16) + (ddddddddddddddd << 1), 22 - 1)
+:cache:::unsigned:disp23:ddddddd,dddddddddddddddd: SEXT32 ((ddddddd) + (dddddddddddddddd << 7), 23 - 1)
+:cache:::unsigned:disp23:dddddd,dddddddddddddddd: SEXT32 ((dddddd << 1) + (dddddddddddddddd << 7), 23 - 1)
:cache:::unsigned:imm5:iiiii:SEXT32 (iiiii, 4)
:cache:::unsigned:imm6:iiiiii:iiiiii
@@ -46,6 +60,7 @@
:cache:::unsigned:list18:LLLL,LLLLLLLLLLLL:((LLLL << 12) + LLLLLLLLLLLL)
:cache:::unsigned:bit3:bbb:bbb
+:cache:::unsigned:bit4:bbbb:bbbb
// What do we do with an illegal instruction?
@@ -58,8 +73,7 @@
-// Add
-
+// ADD
rrrrr,001110,RRRRR:I:::add
"add r<reg1>, r<reg2>"
{
@@ -83,6 +97,20 @@ rrrrr,110000,RRRRR + iiiiiiiiiiiiiiii:VI
+// ADF
+rrrrr,111111,RRRRR + wwwww,011101,cccc!13,0:XI:::adf
+*v850e2
+*v850e2v3
+"adf %s<cccc>, r<reg1>, r<reg2>, r<reg3>"
+{
+ int cond = condition_met (cccc);
+ TRACE_ALU_INPUT3 (cond, GR[reg1], GR[reg2]);
+ GR[reg3] = GR[reg1] + GR[reg2] + (cond ? 1 : 0);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+
+
// AND
rrrrr,001010,RRRRR:I:::and
"and r<reg1>, r<reg2>"
@@ -153,12 +181,27 @@ ddddd,1011,ddd,cccc:III:::Bcond
}
}
+00000111111,d,cccc + ddddddddddddddd,1:VII:::Bcond
+"breakpoint":((disp17 == 0) && (cccc == 0x05))
+"b%s<cccc> <disp17>"
+*v850e2v3
+{
+ int cond;
+ cond = condition_met (cccc);
+ if (cond)
+ nia = cia + disp17;
+ TRACE_BRANCH_INPUT1 (cond);
+ TRACE_BRANCH_RESULT (nia);
+}
+
// BSH
rrrrr,11111100000 + wwwww,01101000010:XII:::bsh
*v850e
*v850e1
+*v850e2
+*v850e2v3
"bsh r<reg2>, r<reg3>"
{
unsigned32 value;
@@ -178,10 +221,14 @@ rrrrr,11111100000 + wwwww,01101000010:XI
TRACE_ALU_RESULT (GR[reg3]);
}
+
+
// BSW
rrrrr,11111100000 + wwwww,01101000000:XII:::bsw
*v850e
*v850e1
+*v850e2
+*v850e2v3
"bsw r<reg2>, r<reg3>"
{
#define WORDHASNULLBYTE(x) (((x) - 0x01010101) & ~(x)&0x80808080)
@@ -204,10 +251,14 @@ rrrrr,11111100000 + wwwww,01101000000:XI
TRACE_ALU_RESULT (GR[reg3]);
}
+
+
// CALLT
0000001000,iiiiii:II:::callt
*v850e
*v850e1
+*v850e2
+*v850e2v3
"callt <imm6>"
{
unsigned32 adr;
@@ -221,6 +272,55 @@ rrrrr,11111100000 + wwwww,01101000000:XI
}
+
+// CAXI
+rrrrr,111111,RRRRR + wwwww,00011101110:IX:::caxi
+*v850e2
+*v850e2v3
+"caxi [reg1], reg2, reg3"
+{
+ unsigned int z,s,cy,ov;
+ unsigned32 addr;
+ unsigned32 token,result;
+
+ addr = GR[reg1];
+
+ if (mpu_load_mem_test(sd, addr, 4, reg1)
+ && mpu_store_mem_test(sd, addr, 4, reg1))
+ {
+ token = load_data_mem (sd, addr, 4);
+
+ TRACE_ALU_INPUT2 (token, GR[reg2]);
+
+ result = GR[reg2] - token;
+
+ z = (result == 0);
+ s = (result & 0x80000000);
+ cy = (GR[reg2] < token);
+ ov = ((GR[reg2] & 0x80000000) != (token & 0x80000000)
+ && (GR[reg2] & 0x80000000) != (result & 0x80000000));
+
+ if (result == 0)
+ {
+ store_data_mem (sd, addr, 4, GR[reg3]);
+ GR[reg3] = token;
+ }
+ else
+ {
+ store_data_mem (sd, addr, 4, token);
+ GR[reg3] = token;
+ }
+
+ /* Set condition codes. */
+ PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+ PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
+ | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
+
+ TRACE_ALU_RESULT1 (GR[reg3]);
+ }
+}
+
+
// CLR1
10,bbb,111110,RRRRR + dddddddddddddddd:VIII:::clr1
"clr1 <bit3>, <disp16>[r<reg1>]"
@@ -231,16 +331,21 @@ rrrrr,11111100000 + wwwww,01101000000:XI
rrrrr,111111,RRRRR + 0000000011100100:IX:::clr1
*v850e
*v850e1
+*v850e2
+*v850e2v3
"clr1 r<reg2>, [r<reg1>]"
{
COMPAT_2 (OP_E407E0 ());
}
+
// CTRET
0000011111100000 + 0000000101000100:X:::ctret
*v850e
*v850e1
+*v850e2
+*v850e2v3
"ctret"
{
nia = (CTPC & ~1);
@@ -248,10 +353,14 @@ rrrrr,111111,RRRRR + 0000000011100100:IX
TRACE_BRANCH1 (PSW);
}
+
+
// CMOV
rrrrr,111111,RRRRR + wwwww,011001,cccc,0:XI:::cmov
*v850e
*v850e1
+*v850e2
+*v850e2v3
"cmov %s<cccc>, r<reg1>, r<reg2>, r<reg3>"
{
int cond = condition_met (cccc);
@@ -263,6 +372,8 @@ rrrrr,111111,RRRRR + wwwww,011001,cccc,0
rrrrr,111111,iiiii + wwwww,011000,cccc,0:XII:::cmov
*v850e
*v850e1
+*v850e2
+*v850e2v3
"cmov %s<cccc>, <imm5>, r<reg2>, r<reg3>"
{
int cond = condition_met (cccc);
@@ -271,6 +382,8 @@ rrrrr,111111,iiiii + wwwww,011000,cccc,0
TRACE_ALU_RESULT (GR[reg3]);
}
+
+
// CMP
rrrrr,001111,RRRRR:I:::cmp
"cmp r<reg1>, r<reg2>"
@@ -301,6 +414,8 @@ rrrrr,010011,iiiii:II:::cmp
0000011001,iiiii,L + LLLLLLLLLLL,RRRRR:XIII:::dispose
*v850e
*v850e1
+*v850e2
+*v850e2v3
"dispose <imm5>, <list12>":RRRRR == 0
"dispose <imm5>, <list12>, [reg1]"
{
@@ -329,10 +444,13 @@ rrrrr,010011,iiiii:II:::cmp
}
+
// DIV
rrrrr,111111,RRRRR + wwwww,01011000000:XI:::div
*v850e
*v850e1
+*v850e2
+*v850e2v3
"div r<reg1>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_2C007E0 ());
@@ -390,6 +508,8 @@ rrrrr!0,000010,RRRRR!0:I:::divh
rrrrr,111111,RRRRR + wwwww,01010000000:XI:::divh
*v850e
*v850e1
+*v850e2
+*v850e2v3
"divh r<reg1>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_28007E0 ());
@@ -400,6 +520,8 @@ rrrrr,111111,RRRRR + wwwww,01010000000:X
rrrrr,111111,RRRRR + wwwww,01010000010:XI:::divhu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"divhu r<reg1>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_28207E0 ());
@@ -410,12 +532,60 @@ rrrrr,111111,RRRRR + wwwww,01010000010:X
rrrrr,111111,RRRRR + wwwww,01011000010:XI:::divu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"divu r<reg1>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_2C207E0 ());
}
+// DIVQ
+rrrrr,111111,RRRRR + wwwww,01011111100:XI:::divq
+*v850e2
+*v850e2v3
+"divq r<reg1>, r<reg2>, r<reg3>"
+{
+ unsigned int quotient;
+ unsigned int remainder;
+ unsigned int divide_by;
+ unsigned int divide_this;
+
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+
+ divide_by = GR[reg1];
+ divide_this = GR[reg2];
+ v850_div (sd, divide_by, divide_this, "ient, &remainder);
+ GR[reg2] = quotient;
+ GR[reg3] = remainder;
+
+ TRACE_ALU_RESULT2 (GR[reg2], GR[reg3]);
+}
+
+
+// DIVQU
+rrrrr,111111,RRRRR + wwwww,01011111110:XI:::divqu
+*v850e2
+*v850e2v3
+"divq r<reg1>, r<reg2>, r<reg3>"
+{
+ unsigned int quotient;
+ unsigned int remainder;
+ unsigned int divide_by;
+ unsigned int divide_this;
+
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+
+ divide_by = GR[reg1];
+ divide_this = GR[reg2];
+ v850_divu (sd, divide_by, divide_this, "ient, &remainder);
+ GR[reg2] = quotient;
+ GR[reg3] = remainder;
+
+ TRACE_ALU_RESULT2 (GR[reg2], GR[reg3]);
+}
+
+
// EI
1000011111100000 + 0000000101100000:X:::ei
"ei"
@@ -425,6 +595,76 @@ rrrrr,111111,RRRRR + wwwww,01011000010:X
+// EIRET
+0000011111100000 + 0000000101001000:X:::eiret
+"eiret"
+*v850e2
+*v850e2v3
+{
+ TRACE_ALU_INPUT1 (MPM & MPM_AUE);
+
+ nia = EIPC; /* next PC */
+ if (MPM & MPM_AUE)
+ {
+ PSW = EIPSW;
+ }
+ else
+ {
+ PSW = (PSW & (PSW_NPV | PSW_DMP | PSW_IMP))
+ | (EIPSW & ~(PSW_NPV | PSW_DMP | PSW_IMP));
+ }
+
+ TRACE_ALU_RESULT1 (PSW);
+ TRACE_BRANCH_RESULT (nia);
+}
+
+
+
+// FERET
+0000011111100000 + 0000000101001010:X:::feret
+"feret"
+*v850e2
+*v850e2v3
+{
+ TRACE_ALU_INPUT1 (MPM & MPM_AUE);
+
+ nia = FEPC; /* next PC */
+ if (MPM & MPM_AUE)
+ {
+ PSW = FEPSW;
+ }
+ else
+ {
+ PSW = (PSW & (PSW_NPV | PSW_DMP | PSW_IMP))
+ | (FEPSW & ~(PSW_NPV | PSW_DMP | PSW_IMP));
+ }
+
+ TRACE_ALU_RESULT1 (PSW);
+ TRACE_BRANCH_RESULT (nia);
+}
+
+
+// FETRAP
+0,bbbb!0,00001000000:I:::fetrap
+"fetrap"
+*v850e2
+*v850e2v3
+{
+ TRACE_ALU_INPUT0 ();
+
+ FEPC = PC + 2;
+ FEPSW = PSW;
+ ECR &= ~ECR_FECC;
+ ECR |= (0x30 + bit4) << 16;
+ FEIC = 0x30 + bit4;
+ PSW |= PSW_EP | PSW_ID | PSW_NP;
+ nia = 0x30; /* next PC */
+
+ TRACE_ALU_RESULT1 (PSW);
+ TRACE_BRANCH_RESULT (nia);
+}
+
+
// HALT
0000011111100000 + 0000000100100000:X:::halt
"halt"
@@ -434,10 +674,33 @@ rrrrr,111111,RRRRR + wwwww,01011000010:X
+// HSH
+rrrrr,11111100000 + wwwww,01101000110:XII:::hsh
+*v850e2
+*v850e2v3
+"hsh r<reg2>, r<reg3>"
+{
+ unsigned32 value;
+ TRACE_ALU_INPUT1 (GR[reg2]);
+
+ value = 0xffff & GR[reg2];
+ GR[reg3] = GR[reg2];
+
+ PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
+
+ if (value == 0) { PSW |= PSW_Z; PSW |= PSW_CY; }
+ if (value & 0x80000000) PSW |= PSW_S;
+
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+
// HSW
rrrrr,11111100000 + wwwww,01101000100:XII:::hsw
*v850e
*v850e1
+*v850e2
+*v850e2v3
"hsw r<reg2>, r<reg3>"
{
unsigned32 value;
@@ -469,6 +732,16 @@ rrrrr!0,11110,dddddd + ddddddddddddddd,0
TRACE_BRANCH1 (GR[reg2]);
}
+00000010111,RRRRR!0 + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::jarl32
+*v850e2
+*v850e2v3
+"jarl <imm32>, r<reg1>"
+{
+ GR[reg1] = nia;
+ nia = (cia + imm32) & ~1;
+
+ TRACE_BRANCH_RESULT (nia);
+}
// JMP
@@ -479,6 +752,15 @@ rrrrr!0,11110,dddddd + ddddddddddddddd,0
TRACE_BRANCH0 ();
}
+00000110111,RRRRR + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::jmp32
+*v850e2
+*v850e2v3
+"jmp <imm32>[r<reg1>]"
+{
+ nia = (GR[reg1] + imm32) & ~1;
+
+ TRACE_BRANCH_RESULT (nia);
+}
// JR
@@ -490,6 +772,17 @@ rrrrr!0,11110,dddddd + ddddddddddddddd,0
}
+// JR32
+00000010111,00000 + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::jr32
+*v850e2
+*v850e2v3
+"jr <imm32>"
+{
+ nia = (cia + imm32) & ~1;
+
+ TRACE_BRANCH_RESULT (nia);
+}
+
// LD
rrrrr,111000,RRRRR + dddddddddddddddd:VII:::ld.b
@@ -498,47 +791,368 @@ rrrrr,111000,RRRRR + dddddddddddddddd:VI
COMPAT_2 (OP_700 ());
}
+00000111100,RRRRR+wwwww,ddddddd,0101+dddddddddddddddd:XIV:::ld.b
+"ld.b <disp23>[r<reg1>], r<reg3>"
+*v850e2v3
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ unsigned32 result = EXTEND8 (load_data_mem (sd, addr, 1));
+ GR[reg3] = result;
+ TRACE_LD (addr, result);
+}
+
rrrrr,111001,RRRRR + ddddddddddddddd,0:VII:::ld.h
"ld.h <disp16>[r<reg1>], r<reg2>"
{
COMPAT_2 (OP_720 ());
}
+00000111100,RRRRR+wwwww,dddddd,00111+dddddddddddddddd:XIV:::ld.h
+*v850e2v3
+"ld.h <disp23>[r<reg1>], r<reg3>"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ unsigned32 result = EXTEND16 (load_data_mem (sd, addr, 2));
+ GR[reg3] = result;
+ TRACE_LD (addr, result);
+}
+
rrrrr,111001,RRRRR + ddddddddddddddd,1:VII:::ld.w
"ld.w <disp16>[r<reg1>], r<reg2>"
{
COMPAT_2 (OP_10720 ());
}
+00000111100,RRRRR+wwwww,dddddd,01001+dddddddddddddddd:XIV:::ld.w
+*v850e2v3
+"ld.w <disp23>[r<reg1>], r<reg3>"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ unsigned32 result = load_data_mem (sd, addr, 4);
+ GR[reg3] = result;
+ TRACE_LD (addr, result);
+}
+
rrrrr!0,11110,b,RRRRR + ddddddddddddddd,1:VII:::ld.bu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"ld.bu <disp16>[r<reg1>], r<reg2>"
{
COMPAT_2 (OP_10780 ());
}
+00000111101,RRRRR+wwwww,ddddddd,0101+dddddddddddddddd:XIV:::ld.bu
+*v850e2v3
+"ld.bu <disp23>[r<reg1>], r<reg3>"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ unsigned32 result = load_data_mem (sd, addr, 1);
+ GR[reg3] = result;
+ TRACE_LD (addr, result);
+}
+
rrrrr!0,111111,RRRRR + ddddddddddddddd,1:VII:::ld.hu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"ld.hu <disp16>[r<reg1>], r<reg2>"
{
COMPAT_2 (OP_107E0 ());
}
+00000111101,RRRRR+wwwww,dddddd,00111+dddddddddddddddd:XIV:::ld.hu
+*v850e2v3
+"ld.hu <disp23>[r<reg1>], r<reg3>"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ unsigned32 result = load_data_mem (sd, addr, 2);
+ GR[reg3] = result;
+ TRACE_LD (addr, result);
+}
+
+
// LDSR
regID,111111,RRRRR + 0000000000100000:IX:::ldsr
"ldsr r<reg1>, s<regID>"
{
+ uint32 sreg = GR[reg1];
TRACE_ALU_INPUT1 (GR[reg1]);
- if (&PSW == &SR[regID])
- PSW = (GR[reg1] & (CPU)->psw_mask);
+ if ((idecode_issue == idecode_v850e2_issue
+ || idecode_issue == idecode_v850e2v3_issue)
+ && regID < 28)
+ {
+ int protect_p = (PSW & PSW_NPV) ? 1 : 0;
+
+
+ switch (BSEL & 0xffff)
+ {
+ case 0x0000:
+ if ((PSW & PSW_NPV)
+ && ((regID >= 8 && regID <= 12)
+ || (regID >= 22 && regID <= 27)
+ || regID == PSW_REGNO))
+ {
+ protect_p = 0;
+ }
+ break;
+ case 0x1000: /* MPU0 */
+ break;
+ case 0x1001: /* MPU1 */
+ break;
+ case 0x2000: /* FPU */
+ if ((PSW & PSW_NPV)
+ && ((/* regID >= 0 && */ regID <= 5)
+ || regID == 8
+ || regID == 9
+ || regID == 10
+ || (regID >= 11 && regID <= 26)))
+ {
+ protect_p = 0;
+ }
+ break;
+ case 0xff00:
+ if ((PSW & PSW_NPV)
+ && (regID == 6
+ || regID == 7
+ || regID == 8
+ || regID == 9
+ || regID == 10
+ || (regID >= 11 && regID <= 15)
+ || regID == 18
+ || regID == 19
+ || (regID >= 21 && regID <= 27)))
+ {
+ protect_p = 0;
+ }
+ break;
+ case 0xffff:
+ if ((PSW & PSW_NPV)
+ && (regID == 6
+ || regID == 7
+ || regID == 8
+ || regID == 9
+ || regID == 10
+ || regID == 11
+ || regID == 12
+ || regID == 15
+ || regID == 18
+ || regID == 19
+ || (regID >= 21 && regID <= 27)))
+ {
+ protect_p = 0;
+ }
+ break;
+ }
+
+ if (!protect_p)
+ {
+ switch (BSEL & 0xffff)
+ {
+ case 0x0000:
+ case 0xff00: /* user0 bank */
+ case 0xffff: /* user1 bank */
+ if(regID == PSW_REGNO)
+ {
+ SR[regID] = sreg & ((PSW & PSW_NPV) ? 0xf : ~0);
+ }
+ else
+ {
+ SR[regID] = sreg;
+ }
+ break;
+ case 0x1000:
+ MPU0_SR[regID] = sreg;
+ break;
+ case 0x1001:
+ if (regID == MPC_REGNO)
+ {
+ PPC &= ~PPC_PPE;
+ SPAL &= ~SPAL_SPE;
+ IPA0L &= ~IPA_IPE;
+ IPA1L &= ~IPA_IPE;
+ IPA2L &= ~IPA_IPE;
+ IPA3L &= ~IPA_IPE;
+ DPA0L &= ~DPA_DPE;
+ DPA1L &= ~DPA_DPE;
+ DCC &= ~(DCC_DCE0 | DCC_DCE1);
+ }
+ else
+ {
+ MPU1_SR[regID] = sreg;
+ }
+ break;
+ case 0x2000: /* FPU */
+ if (regID == FPST_REGNO)
+ {
+ unsigned int val = FPSR & ~(FPSR_PR | FPSR_XC | FPSR_XP);
+
+ val |= ((sreg & FPST_PR) ? FPSR_PR : 0)
+ | ((sreg & FPST_XCE) ? FPSR_XCE : 0)
+ | ((sreg & FPST_XCV) ? FPSR_XCV : 0)
+ | ((sreg & FPST_XCZ) ? FPSR_XCZ : 0)
+ | ((sreg & FPST_XCO) ? FPSR_XCO : 0)
+ | ((sreg & FPST_XCU) ? FPSR_XCU : 0)
+ | ((sreg & FPST_XCI) ? FPSR_XCI : 0)
+ | ((sreg & FPST_XPV) ? FPSR_XPV : 0)
+ | ((sreg & FPST_XPZ) ? FPSR_XPZ : 0)
+ | ((sreg & FPST_XPO) ? FPSR_XPO : 0)
+ | ((sreg & FPST_XPU) ? FPSR_XPU : 0)
+ | ((sreg & FPST_XPI) ? FPSR_XPI : 0);
+ FPSR = val;
+ }
+ else if (regID == FPCFG_REGNO)
+ {
+ unsigned int val = FPSR & ~(FPSR_RM | FPSR_XE);
+
+ val |= (((sreg & FPCFG_RM) >> 7) << 18)
+ | ((sreg & FPCFG_XEV) ? FPSR_XEV : 0)
+ | ((sreg & FPCFG_XEZ) ? FPSR_XEZ : 0)
+ | ((sreg & FPCFG_XEO) ? FPSR_XEO : 0)
+ | ((sreg & FPCFG_XEU) ? FPSR_XEU : 0)
+ | ((sreg & FPCFG_XEI) ? FPSR_XEI : 0);
+ FPSR = val;
+ }
+
+ FPU_SR[regID] = sreg;
+ break;
+ }
+ }
+ }
else
- SR[regID] = GR[reg1];
+ {
+ SR[regID] = sreg;
+ }
+
+ TRACE_ALU_RESULT (sreg);
+}
+
+
+
+// MAC
+rrrrr,111111,RRRRR + wwww,0011110,mmmm,0:XI:::mac
+*v850e2
+*v850e2v3
+"mac r<reg1>, r<reg2>, r<reg3e>, r<reg4e>"
+{
+ unsigned long op0;
+ unsigned long op1;
+ unsigned long op2;
+ unsigned long op2hi;
+ unsigned long lo;
+ unsigned long mid1;
+ unsigned long mid2;
+ unsigned long hi;
+ unsigned long RdLo;
+ unsigned long RdHi;
+ int carry;
+ bfd_boolean sign;
+
+ op0 = GR[reg1];
+ op1 = GR[reg2];
+ op2 = GR[reg3e];
+ op2hi = GR[reg3e+1];
+
+ TRACE_ALU_INPUT4 (op0, op1, op2, op2hi);
+
+ sign = (op0 ^ op1) & 0x80000000;
+
+ if (((signed long) op0) < 0)
+ op0 = - op0;
+
+ if (((signed long) op1) < 0)
+ op1 = - op1;
+
+ /* We can split the 32x32 into four 16x16 operations. This ensures
+ that we do not lose precision on 32bit only hosts: */
+ lo = ( (op0 & 0xFFFF) * (op1 & 0xFFFF));
+ mid1 = ( (op0 & 0xFFFF) * ((op1 >> 16) & 0xFFFF));
+ mid2 = (((op0 >> 16) & 0xFFFF) * (op1 & 0xFFFF));
+ hi = (((op0 >> 16) & 0xFFFF) * ((op1 >> 16) & 0xFFFF));
+
+ /* We now need to add all of these results together, taking care
+ to propogate the carries from the additions: */
+ RdLo = Add32 (lo, (mid1 << 16), & carry);
+ RdHi = carry;
+ RdLo = Add32 (RdLo, (mid2 << 16), & carry);
+ RdHi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi);
+
+ if (sign)
+ {
+ RdLo = ~ RdLo;
+ RdHi = ~ RdHi;
+ if (RdLo == 0xFFFFFFFF)
+ {
+ RdLo = 0;
+ RdHi += 1;
+ }
+ else
+ RdLo += 1;
+ }
+
+ RdLo = Add32 (RdLo, op2, & carry);
+ RdHi += carry + op2hi;
+
+ /* Store the result and condition codes. */
+ GR[reg3e] = RdLo;
+ GR[reg3e + 1 ] = RdHi;
+
+ TRACE_ALU_RESULT2 (RdLo, RdHi);
+}
+
+
+
+// MACU
+rrrrr,111111,RRRRR + wwww,0011111,mmmm,0:XI:::macu
+*v850e2
+*v850e2v3
+"macu r<reg1>, r<reg2>, r<reg3e>, r<reg4e>"
+{
+ unsigned long op0;
+ unsigned long op1;
+ unsigned long op2;
+ unsigned long op2hi;
+ unsigned long lo;
+ unsigned long mid1;
+ unsigned long mid2;
+ unsigned long hi;
+ unsigned long RdLo;
+ unsigned long RdHi;
+ int carry;
+
+ op0 = GR[reg1];
+ op1 = GR[reg2];
+ op2 = GR[reg3e];
+ op2hi = GR[reg3e + 1];
+
+ TRACE_ALU_INPUT4 (op0, op1, op2, op2hi);
+
+ /* We can split the 32x32 into four 16x16 operations. This ensures
+ that we do not lose precision on 32bit only hosts: */
+ lo = ( (op0 & 0xFFFF) * (op1 & 0xFFFF));
+ mid1 = ( (op0 & 0xFFFF) * ((op1 >> 16) & 0xFFFF));
+ mid2 = (((op0 >> 16) & 0xFFFF) * (op1 & 0xFFFF));
+ hi = (((op0 >> 16) & 0xFFFF) * ((op1 >> 16) & 0xFFFF));
- TRACE_ALU_RESULT (SR[regID]);
+ /* We now need to add all of these results together, taking care
+ to propogate the carries from the additions: */
+ RdLo = Add32 (lo, (mid1 << 16), & carry);
+ RdHi = carry;
+ RdLo = Add32 (RdLo, (mid2 << 16), & carry);
+ RdHi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi);
+
+ RdLo = Add32 (RdLo, op2, & carry);
+ RdHi += carry + op2hi;
+
+ /* Store the result and condition codes. */
+ GR[reg4e] = RdLo;
+ GR[reg4e] = RdHi;
+
+ TRACE_ALU_RESULT2 (RdLo, RdHi);
}
@@ -552,7 +1166,6 @@ rrrrr!0,000000,RRRRR:I:::mov
TRACE_ALU_RESULT (GR[reg2]);
}
-
rrrrr!0,010000,iiiii:II:::mov
"mov <imm5>, r<reg2>"
{
@@ -562,6 +1175,8 @@ rrrrr!0,010000,iiiii:II:::mov
00000110001,RRRRR + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::mov
*v850e
*v850e1
+*v850e2
+*v850e2v3
"mov <imm32>, r<reg1>"
{
SAVE_2;
@@ -596,6 +1211,8 @@ rrrrr!0,110010,RRRRR + iiiiiiiiiiiiiiii:
rrrrr,111111,RRRRR + wwwww,01000100000:XI:::mul
*v850e
*v850e1
+*v850e2
+*v850e2v3
"mul r<reg1>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_22007E0 ());
@@ -604,6 +1221,8 @@ rrrrr,111111,RRRRR + wwwww,01000100000:X
rrrrr,111111,iiiii + wwwww,01001,IIII,00:XII:::mul
*v850e
*v850e1
+*v850e2
+*v850e2v3
"mul <imm9>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_24007E0 ());
@@ -638,6 +1257,8 @@ rrrrr!0,110111,RRRRR + iiiiiiiiiiiiiiii:
rrrrr,111111,RRRRR + wwwww,01000100010:XI:::mulu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"mulu r<reg1>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_22207E0 ());
@@ -646,6 +1267,8 @@ rrrrr,111111,RRRRR + wwwww,01000100010:X
rrrrr,111111,iiiii + wwwww,01001,IIII,10:XII:::mulu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"mulu <imm9>, r<reg2>, r<reg3>"
{
COMPAT_2 (OP_24207E0 ());
@@ -681,6 +1304,8 @@ rrrrr,000001,RRRRR:I:::not
rrrrr,111111,RRRRR + 0000000011100010:IX:::not1
*v850e
*v850e1
+*v850e2
+*v850e2v3
"not1 r<reg2>, r<reg1>"
{
COMPAT_2 (OP_E207E0 ());
@@ -710,6 +1335,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI
0000011110,iiiii,L + LLLLLLLLLLL,00001:XIII:::prepare
*v850e
*v850e1
+*v850e2
+*v850e2v3
"prepare <list12>, <imm5>"
{
int i;
@@ -735,6 +1362,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI
0000011110,iiiii,L + LLLLLLLLLLL,00011:XIII:::prepare00
*v850e
*v850e1
+*v850e2
+*v850e2v3
"prepare <list12>, <imm5>, sp"
{
COMPAT_2 (OP_30780 ());
@@ -743,6 +1372,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI
0000011110,iiiii,L + LLLLLLLLLLL,01011 + iiiiiiiiiiiiiiii:XIII:::prepare01
*v850e
*v850e1
+*v850e2
+*v850e2v3
"prepare <list12>, <imm5>, <uimm16>"
{
COMPAT_2 (OP_B0780 ());
@@ -751,6 +1382,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI
0000011110,iiiii,L + LLLLLLLLLLL,10011 + iiiiiiiiiiiiiiii:XIII:::prepare10
*v850e
*v850e1
+*v850e2
+*v850e2v3
"prepare <list12>, <imm5>, <uimm16>"
{
COMPAT_2 (OP_130780 ());
@@ -759,6 +1392,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI
0000011110,iiiii,L + LLLLLLLLLLL,11011 + iiiiiiiiiiiiiiii + dddddddddddddddd:XIII:::prepare11
*v850e
*v850e1
+*v850e2
+*v850e2v3
"prepare <list12>, <imm5>, <uimm32>"
{
COMPAT_2 (OP_1B0780 ());
@@ -803,12 +1438,23 @@ rrrrr,010101,iiiii:II:::sar
COMPAT_1 (OP_2A0 ());
}
+rrrrr,111111,RRRRR + wwwww,00010100010:XI:::sar
+*v850e2
+*v850e2v3
+"sar r<reg1>, r<reg2>, r<reg3>"
+{
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+ v850_sar(sd, GR[reg1], GR[reg2], &GR[reg3]);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
// SASF
rrrrr,1111110,cccc + 0000001000000000:IX:::sasf
*v850e
*v850e1
+*v850e2
+*v850e2v3
"sasf %s<cccc>, r<reg2>"
{
COMPAT_2 (OP_20007E0 ());
@@ -816,7 +1462,6 @@ rrrrr,1111110,cccc + 0000001000000000:IX
-
// SATADD
rrrrr!0,000110,RRRRR:I:::satadd
"satadd r<reg1>, r<reg2>"
@@ -830,6 +1475,16 @@ rrrrr!0,010001,iiiii:II:::satadd
COMPAT_1 (OP_220 ());
}
+rrrrr,111111,RRRRR + wwwww,01110111010:XI:::satadd
+*v850e2
+*v850e2v3
+"satadd r<reg1>, r<reg2>, r<reg3>"
+{
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+ v850_satadd (sd, GR[reg1], GR[reg2], &GR[reg3]);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
// SATSUB
@@ -839,6 +1494,16 @@ rrrrr!0,000101,RRRRR:I:::satsub
COMPAT_1 (OP_A0 ());
}
+rrrrr,111111,RRRRR + wwwww,01110011010:XI:::satsub
+*v850e2
+*v850e2v3
+"satsub r<reg1>, r<reg2>, r<reg3>"
+{
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+ v850_satsub (sd, GR[reg1], GR[reg2], &GR[reg3]);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
// SATSUBI
@@ -859,6 +1524,234 @@ rrrrr!0,000100,RRRRR:I:::satsubr
+//SBF
+rrrrr,111111,RRRRR + wwwww,011100,cccc!13,0:XI:::sbf
+*v850e2
+*v850e2v3
+"sbf %s<cccc>, r<reg1>, r<reg2>, r<reg3>"
+{
+ int cond = condition_met (cccc);
+ TRACE_ALU_INPUT3 (cond, GR[reg1], GR[reg2]);
+ GR[reg3] = GR[reg2] - GR[reg1] - (cond ? 1 : 0);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+
+
+// SCH0L
+rrrrr,11111100000 + wwwww,01101100100:IX:::sch0l
+*v850e2
+*v850e2v3
+"sch0l r<reg2>, r<reg3>"
+{
+ unsigned int pos, op0;
+
+ TRACE_ALU_INPUT1 (GR[reg2]);
+
+ op0 = GR[reg2];
+
+ if (op0 == 0xffffffff)
+ {
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW |= PSW_Z;
+ pos = 0;
+ }
+ else if (op0 == 0xfffffffe)
+ {
+ PSW |= PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ pos = 32;
+ }
+ else
+ {
+ pos = 1;
+ while (op0 & 0x80000000)
+ {
+ op0 <<= 1;
+ pos++;
+ }
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ }
+
+ GR[reg3] = pos;
+
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+
+
+// SCH0R
+rrrrr,11111100000 + wwwww,01101100000:IX:::sch0r
+*v850e2
+*v850e2v3
+"sch0r r<reg2>, r<reg3>"
+{
+ unsigned int pos, op0;
+
+ TRACE_ALU_INPUT1 (GR[reg2]);
+
+ op0 = GR[reg2];
+
+ if (op0 == 0xffffffff)
+ {
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW |= PSW_Z;
+ pos = 0;
+ }
+ else if (op0 == 0x7fffffff)
+ {
+ PSW |= PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ pos = 32;
+ }
+ else
+ {
+ pos = 1;
+ while (op0 & 0x00000001)
+ {
+ op0 >>= 1;
+ pos++;
+ }
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ }
+
+ GR[reg3] = pos;
+
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+// SCH1L
+rrrrr,11111100000 + wwwww,01101100110:IX:::sch1l
+*v850e2
+*v850e2v3
+"sch1l r<reg2>, r<reg3>"
+{
+ unsigned int pos, op0;
+
+ TRACE_ALU_INPUT1 (GR[reg2]);
+
+ op0 = GR[reg2];
+
+ if (op0 == 0x00000000)
+ {
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW |= PSW_Z;
+ pos = 0;
+ }
+ else if (op0 == 0x00000001)
+ {
+ PSW |= PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ pos = 32;
+ }
+ else
+ {
+ pos = 1;
+ while (!(op0 & 0x80000000))
+ {
+ op0 <<= 1;
+ pos++;
+ }
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ }
+
+ GR[reg3] = pos;
+
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+// SCH1R
+rrrrr,11111100000 + wwwww,01101100010:IX:::sch1r
+*v850e2
+*v850e2v3
+"sch1r r<reg2>, r<reg3>"
+{
+ unsigned int pos, op0;
+
+ TRACE_ALU_INPUT1 (GR[reg2]);
+
+ op0 = GR[reg2];
+
+ if (op0 == 0x00000000)
+ {
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW |= PSW_Z;
+ pos = 0;
+ }
+ else if (op0 == 0x80000000)
+ {
+ PSW |= PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ pos = 32;
+ }
+ else
+ {
+ pos = 1;
+ while (!(op0 & 0x00000001))
+ {
+ op0 >>= 1;
+ pos++;
+ }
+ PSW &= ~PSW_CY;
+ PSW &= ~PSW_OV;
+ PSW &= ~PSW_S;
+ PSW &= ~PSW_Z;
+ }
+
+ GR[reg3] = pos;
+
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+//SHL
+rrrrr,111111,RRRRR + wwwww,00011000010:XI:::shl
+*v850e2
+*v850e2v3
+"shl r<reg1>, r<reg2>, r<reg3>"
+{
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+ v850_shl(sd, GR[reg1], GR[reg2], &GR[reg3]);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+//SHR
+rrrrr,111111,RRRRR + wwwww,00010000010:XI:::shr
+*v850e2
+*v850e2v3
+"shr r<reg1>, r<reg2>, r<reg3>"
+{
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]);
+ v850_shr(sd, GR[reg1], GR[reg2], &GR[reg3]);
+ TRACE_ALU_RESULT1 (GR[reg3]);
+}
+
+
+
// SETF
rrrrr,1111110,cccc + 0000000000000000:IX:::setf
"setf %s<cccc>, r<reg2>"
@@ -878,6 +1771,8 @@ rrrrr,1111110,cccc + 0000000000000000:IX
rrrrr,111111,RRRRR + 0000000011100000:IX:::set1
*v850e
*v850e1
+*v850e2
+*v850e2v3
"set1 r<reg2>, [r<reg1>]"
{
COMPAT_2 (OP_E007E0 ());
@@ -966,6 +1861,8 @@ rrrrr,1010,dddddd,0:IV:::sld.w
rrrrr!0,0000110,dddd:IV:::sld.bu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"sld.b <disp4>[ep], r<reg2>":(PSW & PSW_US)
"sld.bu <disp4>[ep], r<reg2>"
{
@@ -987,6 +1884,8 @@ rrrrr!0,0000110,dddd:IV:::sld.bu
rrrrr!0,0000111,dddd:IV:::sld.hu
*v850e
*v850e1
+*v850e2
+*v850e2v3
"sld.h <disp5>[ep], r<reg2>":(PSW & PSW_US)
"sld.hu <disp5>[ep], r<reg2>"
{
@@ -1005,6 +1904,8 @@ rrrrr!0,0000111,dddd:IV:::sld.hu
}
}
+
+
// SST
rrrrr,0111,ddddddd:IV:::sst.b
"sst.b r<reg2>, <disp7>[ep]"
@@ -1031,29 +1932,113 @@ rrrrr,111010,RRRRR + dddddddddddddddd:VI
COMPAT_2 (OP_740 ());
}
+00000111100,RRRRR + wwwww,ddddddd,1101 + dddddddddddddddd:XIV:::st.b
+*v850e2v3
+"st.b r<reg3>, <disp23>[r<reg1>]"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ store_data_mem (sd, addr, 1, GR[reg3]);
+ TRACE_ST (addr, GR[reg3]);
+}
+
rrrrr,111011,RRRRR + ddddddddddddddd,0:VII:::st.h
"st.h r<reg2>, <disp16>[r<reg1>]"
{
COMPAT_2 (OP_760 ());
}
+00000111101,RRRRR+wwwww,dddddd,01101+dddddddddddddddd:XIV:::st.h
+*v850e2v3
+"st.h r<reg3>, <disp23>[r<reg1>]"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ store_data_mem (sd, addr, 2, GR[reg3]);
+ TRACE_ST (addr, GR[reg3]);
+}
+
rrrrr,111011,RRRRR + ddddddddddddddd,1:VII:::st.w
"st.w r<reg2>, <disp16>[r<reg1>]"
{
COMPAT_2 (OP_10760 ());
}
+00000111100,RRRRR+wwwww,dddddd,01111+dddddddddddddddd:XIV:::st.w
+*v850e2v3
+"st.w r<reg3>, <disp23>[r<reg1>]"
+{
+ unsigned32 addr = GR[reg1] + disp23;
+ store_data_mem (sd, addr, 4, GR[reg3]);
+ TRACE_ST (addr, GR[reg3]);
+}
+
+
// STSR
rrrrr,111111,regID + 0000000001000000:IX:::stsr
"stsr s<regID>, r<reg2>"
{
- TRACE_ALU_INPUT1 (SR[regID]);
- GR[reg2] = SR[regID];
- TRACE_ALU_RESULT (GR[reg2]);
-}
+ uint32 sreg = 0;
-// SUB
-rrrrr,001101,RRRRR:I:::sub
+ if ((idecode_issue == idecode_v850e2_issue
+ || idecode_issue == idecode_v850e2v3_issue)
+ && regID < 28)
+ {
+ switch (BSEL & 0xffff)
+ {
+ case 0x0000:
+ case 0xff00: /* USER 0 */
+ case 0xffff: /* USER 1 */
+ sreg = SR[regID];
+ break;
+ case 0x1000:
+ sreg = MPU0_SR[regID];
+ break;
+ case 0x1001:
+ sreg = MPU1_SR[regID];
+ break;
+ case 0x2000:
+ if (regID == FPST_REGNO)
+ {
+ sreg = ((FPSR & FPSR_PR) ? FPST_PR : 0)
+ | ((FPSR & FPSR_XCE) ? FPST_XCE : 0)
+ | ((FPSR & FPSR_XCV) ? FPST_XCV : 0)
+ | ((FPSR & FPSR_XCZ) ? FPST_XCZ : 0)
+ | ((FPSR & FPSR_XCO) ? FPST_XCO : 0)
+ | ((FPSR & FPSR_XCU) ? FPST_XCU : 0)
+ | ((FPSR & FPSR_XCI) ? FPST_XCI : 0)
+ | ((FPSR & FPSR_XPV) ? FPST_XPV : 0)
+ | ((FPSR & FPSR_XPZ) ? FPST_XPZ : 0)
+ | ((FPSR & FPSR_XPO) ? FPST_XPO : 0)
+ | ((FPSR & FPSR_XPU) ? FPST_XPU : 0)
+ | ((FPSR & FPSR_XPI) ? FPST_XPI : 0);
+ }
+ else if (regID == FPCFG_REGNO)
+ {
+ sreg = (((FPSR & FPSR_RM) >> 18) << 7)
+ | ((FPSR & FPSR_XEV) ? FPCFG_XEV : 0)
+ | ((FPSR & FPSR_XEZ) ? FPCFG_XEZ : 0)
+ | ((FPSR & FPSR_XEO) ? FPCFG_XEO : 0)
+ | ((FPSR & FPSR_XEU) ? FPCFG_XEU : 0)
+ | ((FPSR & FPSR_XEI) ? FPCFG_XEI : 0);
+ }
+ else
+ {
+ sreg = FPU_SR[regID];
+ }
+ break;
+ }
+ }
+ else
+ {
+ sreg = SR[regID];
+ }
+
+ TRACE_ALU_INPUT1 (sreg);
+ GR[reg2] = sreg;
+ TRACE_ALU_RESULT (GR[reg2]);
+}
+
+// SUB
+rrrrr,001101,RRRRR:I:::sub
"sub r<reg1>, r<reg2>"
{
COMPAT_1 (OP_1A0 ());
@@ -1070,6 +2055,8 @@ rrrrr,001100,RRRRR:I:::subr
00000000010,RRRRR:I:::switch
*v850e
*v850e1
+*v850e2
+*v850e2v3
"switch r<reg1>"
{
unsigned long adr;
@@ -1084,6 +2071,8 @@ rrrrr,001100,RRRRR:I:::subr
00000000101,RRRRR:I:::sxb
*v850e
*v850e1
+*v850e2
+*v850e2v3
"sxb r<reg1>"
{
TRACE_ALU_INPUT1 (GR[reg1]);
@@ -1095,6 +2084,8 @@ rrrrr,001100,RRRRR:I:::subr
00000000111,RRRRR:I:::sxh
*v850e
*v850e1
+*v850e2
+*v850e2v3
"sxh r<reg1>"
{
TRACE_ALU_INPUT1 (GR[reg1]);
@@ -1126,6 +2117,8 @@ rrrrr,001011,RRRRR:I:::tst
rrrrr,111111,RRRRR + 0000000011100110:IX:::tst1
*v850e
*v850e1
+*v850e2
+*v850e2v3
"tst1 r<reg2>, [r<reg1>]"
{
COMPAT_2 (OP_E607E0 ());
@@ -1149,6 +2142,8 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI
00000000100,RRRRR:I:::zxb
*v850e
*v850e1
+*v850e2
+*v850e2v3
"zxb r<reg1>"
{
TRACE_ALU_INPUT1 (GR[reg1]);
@@ -1160,6 +2155,8 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI
00000000110,RRRRR:I:::zxh
*v850e
*v850e1
+*v850e2
+*v850e2v3
"zxh r<reg1>"
{
TRACE_ALU_INPUT1 (GR[reg1]);
@@ -1178,6 +2175,8 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI
11111,000010,00000:I:::dbtrap
*v850e1
+*v850e2
+*v850e2v3
"dbtrap"
{
DBPC = cia + 2;
@@ -1197,9 +2196,1071 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI
// Return from debug trap: 0x146007e0
0000011111100000 + 0000000101000110:X:::dbret
*v850e1
+*v850e2
+*v850e2v3
"dbret"
{
nia = DBPC;
PSW = DBPSW;
TRACE_BRANCH1 (PSW);
}
+
+
+//
+// FLOAT
+//
+
+// Map condition code to a string
+:%s::::FFFF:int FFFF
+{
+ switch (FFFF)
+ {
+ case 0: return "f";
+ case 1: return "un";
+ case 2: return "eq";
+ case 3: return "ueq";
+ case 4: return "olt";
+ case 5: return "ult";
+ case 6: return "ole";
+ case 7: return "ule";
+ case 8: return "sf";
+ case 9: return "ngle";
+ case 10: return "seq";
+ case 11: return "ngl";
+ case 12: return "lt";
+ case 13: return "nge";
+ case 14: return "le";
+ case 15: return "ngt";
+ }
+ return "(null)";
+}
+
+// ABSF.D
+rrrr,011111100000 + wwww,010001011000:F_I:::absf_d
+*v850e2v3
+"absf.d r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_abs (&ans, &wop);
+ check_invalid_snan(sd, status, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// ABSF.S
+rrrrr,11111100000 + wwwww,10001001000:F_I:::absf_s
+*v850e2v3
+"absf.s r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_abs (&ans, &wop);
+ check_invalid_snan(sd, status, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// ADDF.D
+rrrr,0111111,RRRR,0 + wwww,010001110000:F_I:::addf_d
+*v850e2v3
+"addf.d r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_add (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// ADDF.S
+rrrrr,111111,RRRRR + wwwww,10001100000:F_I:::addf_s
+*v850e2v3
+"addf.s r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_add (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// CMOVF.D
+rrrr,0111111,RRRR,0 + wwww!0,01000001,bbb,0:F_I:::cmovf_d
+*v850e2v3
+"cmovf.d <bbb>, r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ unsigned int ophi,oplow;
+ sim_fpu ans, wop1, wop2;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_BOOL1_FPU2 (TEST_FPCC(bbb), &wop1, &wop2);
+
+ if (TEST_FPCC(bbb))
+ {
+ ophi = GR[reg1e+1];
+ oplow = GR[reg1e];
+ ans = wop1;
+ }
+ else
+ {
+ ophi = GR[reg2e+1];
+ oplow = GR[reg2e];
+ ans = wop2;
+ }
+
+ GR[reg3e+1] = ophi;
+ GR[reg3e] = oplow;
+ TRACE_FP_RESULT_FPU1 (&ans);;
+}
+
+// CMOVF.S
+rrrrr,111111,RRRRR + wwwww!0,1000000,bbb,0:F_I:::cmovf_s
+*v850e2v3
+"cmovf.d <bbb>, r<reg1>, r<reg2>, r<reg3>"
+{
+ unsigned int op;
+ sim_fpu ans, wop1, wop2;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_BOOL1_FPU2 (TEST_FPCC(bbb), &wop1, &wop2);
+
+ if (TEST_FPCC(bbb))
+ {
+ op = GR[reg1];
+ ans = wop1;
+ }
+ else
+ {
+ op = GR[reg2];
+ ans = wop2;
+ }
+
+ GR[reg3] = op;
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// CMPF.D
+rrrr,0111111,RRRR,0 + 0,FFFF,1000011,bbb,0:F_I:::cmpf_d
+*v850e2v3
+"cmpf.d %s<FFFF>, r<reg1e>, r<reg2e>":(bbb == 0)
+"cmpf.d %s<FFFF>, r<reg1e>, r<reg2e>, <bbb>"
+{
+ int result;
+ sim_fpu wop1;
+ sim_fpu wop2;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ result = v850_float_compare(sd, FFFF, wop1, wop2, 1);
+
+ if (result)
+ SET_FPCC(bbb);
+ else
+ CLEAR_FPCC(bbb);
+
+ TRACE_FP_RESULT_BOOL (result);
+}
+
+// CMPF.S
+rrrrr,111111,RRRRR + 0,FFFF,1000010,bbb,0:F_I:::cmpf_s
+*v850e2v3
+"cmpf.s %s<FFFF>, r<reg1>, r<reg2>":(bbb == 0)
+"cmpf.s %s<FFFF>, r<reg1>, r<reg2>, <bbb>"
+{
+ int result;
+ sim_fpu wop1;
+ sim_fpu wop2;
+
+ sim_fpu_32to( &wop1, GR[reg1] );
+ sim_fpu_32to( &wop2, GR[reg2] );
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ result = v850_float_compare(sd, FFFF, wop1, wop2, 0);
+
+ if (result)
+ SET_FPCC(bbb);
+ else
+ CLEAR_FPCC(bbb);
+
+ TRACE_FP_RESULT_BOOL (result);
+}
+
+// CVTF.DL
+rrrr,011111100100 + wwww,010001010100:F_I:::cvtf_dl
+*v850e2v3
+"cvtf.dl r<reg2e>, r<reg3e>"
+{
+ unsigned64 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+ status |= sim_fpu_to64i (&ans, &wop, FPSR_GET_ROUND());
+
+ check_cvt_fi(sd, status, 1);
+
+ GR[reg3e] = ans;
+ GR[reg3e+1] = ans>>32L;
+ TRACE_FP_RESULT_WORD2 (GR[reg3e], GR[reg3e+1]);
+}
+
+// CVTF.DS
+rrrr,011111100011 + wwwww,10001010010:F_I:::cvtf_ds
+*v850e2v3
+"cvtf.ds r<reg2e>, r<reg3>"
+{
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ check_cvt_fi(sd, status, 0);
+
+ sim_fpu_to32 (&GR[reg3], &wop);
+ TRACE_FP_RESULT_FPU1 (&wop);
+}
+
+// CVTF.DW
+rrrr,011111100100 + wwwww,10001010000:F_I:::cvtf_dw
+*v850e2v3
+"cvtf.dw r<reg2e>, r<reg3>"
+{
+ uint32 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+ status |= sim_fpu_to32i (&ans, &wop, FPSR_GET_ROUND());
+
+ check_cvt_fi(sd, status, 1);
+
+ GR[reg3] = ans;
+ TRACE_FP_RESULT_WORD1 (ans);
+}
+
+// CVTF.LD
+rrrr,011111100001 + wwww,010001010010:F_I:::cvtf_ld
+*v850e2v3
+"cvtf.ld r<reg2e>, r<reg3e>"
+{
+ signed64 op;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ op = ((signed64)GR[reg2e+1] << 32L) | GR[reg2e];
+ TRACE_FP_INPUT_WORD2 (GR[reg2e], GR[reg2e+1]);
+
+ sim_fpu_i64to (&wop, op, FPSR_GET_ROUND());
+ status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+
+ check_cvt_if(sd, status, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &wop);
+ TRACE_FP_RESULT_FPU1 (&wop);
+}
+
+// CVTF.LS
+rrrr,011111100001 + wwwww,10001000010:F_I:::cvtf_ls
+*v850e2v3
+"cvtf.ls r<reg2e>, r<reg3>"
+{
+ signed64 op;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ op = ((signed64)GR[reg2e+1] << 32L) | GR[reg2e];
+ TRACE_FP_INPUT_WORD2 (GR[reg2e], GR[reg2e+1]);
+
+ sim_fpu_i64to (&wop, op, FPSR_GET_ROUND());
+ status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+
+ check_cvt_if(sd, status, 0);
+
+ sim_fpu_to32 (&GR[reg3], &wop);
+ TRACE_FP_RESULT_FPU1 (&wop);
+}
+
+// CVTF.SD
+rrrrr,11111100010 + wwww,010001010010:F_I:::cvtf_sd
+*v850e2v3
+"cvtf.sd r<reg2>, r<reg3e>"
+{
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+ status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ check_cvt_ff(sd, status, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &wop);
+ TRACE_FP_RESULT_FPU1 (&wop);
+}
+
+// CVTF.SL
+rrrrr,11111100100 + wwww,010001000100:F_I:::cvtf_sl
+*v850e2v3
+"cvtf.sl r<reg2>, r<reg3e>"
+{
+ signed64 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+ status |= sim_fpu_to64i (&ans, &wop, FPSR_GET_ROUND());
+
+ check_cvt_fi(sd, status, 0);
+
+ GR[reg3e] = ans;
+ GR[reg3e+1] = ans >> 32L;
+ TRACE_FP_RESULT_WORD2 (GR[reg3e], GR[reg3e+1]);
+}
+
+// CVTF.SW
+rrrrr,11111100100 + wwwww,10001000000:F_I:::cvtf_sw
+*v850e2v3
+"cvtf.sw r<reg2>, r<reg3>"
+{
+ uint32 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+ status |= sim_fpu_to32i (&ans, &wop, sim_fpu_round_zero);
+
+ check_cvt_fi(sd, status, 0);
+
+ GR[reg3] = ans;
+ TRACE_FP_RESULT_WORD1 (ans);
+}
+
+// CVTF.WD
+rrrrr,11111100000 + wwww,010001010010:F_I:::cvtf_wd
+*v850e2v3
+"cvtf.wd r<reg2>, r<reg3e>"
+{
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ TRACE_FP_INPUT_WORD1 (GR[reg2]);
+ sim_fpu_i32to (&wop, GR[reg2], FPSR_GET_ROUND());
+ status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+
+ check_cvt_if(sd, status, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &wop);
+ TRACE_FP_RESULT_FPU1 (&wop);
+}
+
+// CVTF.WS
+rrrrr,11111100000 + wwwww,10001000010:F_I:::cvtf_ws
+*v850e2v3
+"cvtf.ws r<reg2>, r<reg3>"
+{
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ TRACE_FP_INPUT_WORD1 (GR[reg2]);
+ sim_fpu_i32to (&wop, GR[reg2], FPSR_GET_ROUND());
+ status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero);
+
+ check_cvt_if(sd, status, 0);
+
+ sim_fpu_to32 (&GR[reg3], &wop);
+ TRACE_FP_RESULT_FPU1 (&wop);
+}
+
+// DIVF.D
+rrrr,0111111,RRRR,0 + wwww,010001111110:F_I:::divf_d
+*v850e2v3
+"divf.d r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_div (&ans, &wop2, &wop1);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// DIVF.S
+rrrrr,111111,RRRRR + wwwww,10001101110:F_I:::divf_s
+*v850e2v3
+"divf.s r<reg1>, r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_div (&ans, &wop2, &wop1);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MADDF.S
+rrrrr,111111,RRRRR + wwwww,101,W,00,WWWW,0:F_I:::maddf_s
+*v850e2v3
+"maddf.s r<reg1>, r<reg2>, r<reg3>, r<reg4>"
+{
+ sim_fpu ans, wop1, wop2, wop3;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ sim_fpu_32to (&wop3, GR[reg3]);
+ TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3);
+
+ status = sim_fpu_mul (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop1 = ans;
+ status |= sim_fpu_add (&ans, &wop1, &wop3);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg4], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MAXF.D
+rrrr,0111111,RRRR,0 + wwww,010001111000:F_I:::maxf_d
+*v850e2v3
+"maxf.d r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop1, wop2;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2))
+ {
+ if (FPSR & FPSR_XEV)
+ {
+ SignalExceptionFPE(sd, 1);
+ }
+ else
+ {
+ ans = sim_fpu_qnan;
+ }
+ }
+ else if (FPSR & FPSR_FS
+ && ((sim_fpu_is_zero (&wop1) || sim_fpu_is_denorm (&wop1))
+ && (sim_fpu_is_zero (&wop2) || sim_fpu_is_denorm (&wop2))))
+ {
+ ans = sim_fpu_zero;
+ }
+ else
+ {
+ sim_fpu_max (&ans, &wop1, &wop2);
+ }
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MAXF.S
+rrrrr,111111,RRRRR + wwwww,10001101000:F_I:::maxf_s
+*v850e2v3
+"maxf.s r<reg1>, r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop1, wop2;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2))
+ {
+ if (FPSR & FPSR_XEV)
+ {
+ SignalExceptionFPE(sd, 0);
+ }
+ else
+ {
+ ans = sim_fpu_qnan;
+ }
+ }
+ else if ((FPSR & FPSR_FS)
+ && ((sim_fpu_is_zero (&wop1) || sim_fpu_is_denorm (&wop1))
+ && (sim_fpu_is_zero (&wop2)|| sim_fpu_is_denorm (&wop2))))
+ {
+ ans = sim_fpu_zero;
+ }
+ else
+ {
+ sim_fpu_max (&ans, &wop1, &wop2);
+ }
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MINF.D
+rrrr,0111111,RRRR,0 + wwww,010001111010:F_I:::minf_d
+*v850e2v3
+"minf.d r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop1, wop2;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2))
+ {
+ if (FPSR & FPSR_XEV)
+ {
+ SignalExceptionFPE(sd, 1);
+ }
+ else
+ {
+ ans = sim_fpu_qnan;
+ }
+ }
+ else if (FPSR & FPSR_FS
+ && ((sim_fpu_is_zero (&wop1) || sim_fpu_is_denorm (&wop1))
+ && (sim_fpu_is_zero (&wop2) || sim_fpu_is_denorm (&wop2))))
+ {
+ ans = sim_fpu_zero;
+ }
+ else
+ {
+ sim_fpu_min (&ans, &wop1, &wop2);
+ }
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MINF.S
+rrrrr,111111,RRRRR + wwwww,10001101010:F_I:::minf_s
+*v850e2v3
+"minf.s r<reg1>, r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop1, wop2;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2))
+ {
+ if (FPSR & FPSR_XEV)
+ {
+ SignalExceptionFPE(sd, 0);
+ }
+ else
+ {
+ ans = sim_fpu_qnan;
+ }
+ }
+ else if (FPSR & FPSR_FS
+ && ((sim_fpu_is_zero (&wop1) || sim_fpu_is_denorm (&wop1))
+ && (sim_fpu_is_zero (&wop2) || sim_fpu_is_denorm (&wop2))))
+ {
+ ans = sim_fpu_zero;
+ }
+ else
+ {
+ sim_fpu_min (&ans, &wop1, &wop2);
+ }
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MSUBF.S
+rrrrr,111111,RRRRR + wwwww,101,W,01,WWWW,0:F_I:::msubf_s
+*v850e2v3
+"msubf.s r<reg1>, r<reg2>, r<reg3>, r<reg4>"
+{
+ sim_fpu ans, wop1, wop2, wop3;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ sim_fpu_32to (&wop3, GR[reg3]);
+ TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3);
+
+ status = sim_fpu_mul (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop1 = ans;
+ status |= sim_fpu_sub (&ans, &wop1, &wop3);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg4], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MULF.D
+rrrr,0111111,RRRR,0 + wwww,010001110100:F_I:::mulf_d
+*v850e2v3
+"mulf.d r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_mul (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// MULF.S
+rrrrr,111111,RRRRR + wwwww,10001100100:F_I:::mulf_s
+*v850e2v3
+"mulf.s r<reg1>, r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ status = sim_fpu_mul (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// NEGF.D
+rrrr,011111100001 + wwww,010001011000:F_I:::negf_d
+*v850e2v3
+"negf.d r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_neg (&ans, &wop);
+
+ check_invalid_snan(sd, status, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// NEGF.S
+rrrrr,11111100001 + wwwww,10001001000:F_I:::negf_s
+*v850e2v3
+"negf.s r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_neg (&ans, &wop);
+
+ check_invalid_snan(sd, status, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// NMADDF.S
+rrrrr,111111,RRRRR + wwwww,101,W,10,WWWW,0:F_I:::nmaddf_s
+*v850e2v3
+"nmaddf.s r<reg1>, r<reg2>, r<reg3>, r<reg4>"
+{
+ sim_fpu ans, wop1, wop2, wop3;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ sim_fpu_32to (&wop3, GR[reg3]);
+ TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3);
+
+ status = sim_fpu_mul (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop1 = ans;
+ status |= sim_fpu_add (&ans, &wop1, &wop3);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop1 = ans;
+ status |= sim_fpu_neg (&ans, &wop1);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg4], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// NMSUBF.S
+rrrrr,111111,RRRRR + wwwww,101,W,11,WWWW,0:F_I:::nmsubf_s
+*v850e2v3
+"nmsubf.s r<reg1>, r<reg2>, r<reg3>, r<reg4>"
+{
+ sim_fpu ans, wop1, wop2, wop3;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ sim_fpu_32to (&wop3, GR[reg3]);
+ TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3);
+
+ status = sim_fpu_mul (&ans, &wop1, &wop2);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop1 = ans;
+ status |= sim_fpu_sub (&ans, &wop1, &wop3);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop1 = ans;
+ status |= sim_fpu_neg (&ans, &wop1);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg4], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// RECIPF.D
+rrrr,011111100001 + wwww,010001011110:F_I:::recipf.d
+*v850e2v3
+"recipf.d r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_div (&ans, &sim_fpu_one, &wop);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// RECIPF.S
+rrrrr,11111100001 + wwwww,10001001110:F_I:::recipf.s
+*v850e2v3
+"recipf.s r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_div (&ans, &sim_fpu_one, &wop);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// RSQRTF.D
+rrrr,011111100010 + wwww,010001011110:F_I:::rsqrtf.d
+*v850e2v3
+"rsqrtf.d r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_sqrt (&ans, &wop);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop = ans;
+ status = sim_fpu_div (&ans, &sim_fpu_one, &wop);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// RSQRTF.S
+rrrrr,11111100010 + wwwww,10001001110:F_I:::rsqrtf.s
+*v850e2v3
+"rsqrtf.s r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_sqrt (&ans, &wop);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+ wop = ans;
+ status = sim_fpu_div (&ans, &sim_fpu_one, &wop);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// SQRTF.D
+rrrr,011111100000 + wwww,010001011110:F_I:::sqrtf.d
+*v850e2v3
+"sqrtf.d r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_sqrt (&ans, &wop);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// SQRTF.S
+rrrrr,11111100000 + wwwww,10001001110:F_I:::sqrtf.s
+*v850e2v3
+"sqrtf.s r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_sqrt (&ans, &wop);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// SUBF.D
+rrrr,0111111,RRRR,0 + wwww,010001110010:F_I:::subf.d
+*v850e2v3
+"subf.d r<reg1e>, r<reg2e>, r<reg3e>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]);
+ sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ //status = sim_fpu_sub (&ans, &wop1, &wop2);
+ status = sim_fpu_sub (&ans, &wop2, &wop1);
+ status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1);
+
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// SUBF.S
+rrrrr,111111,RRRRR + wwwww,10001100010:F_I:::subf.s
+*v850e2v3
+"subf.s r<reg1>, r<reg2>, r<reg3>"
+{
+ sim_fpu ans, wop1, wop2;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop1, GR[reg1]);
+ sim_fpu_32to (&wop2, GR[reg2]);
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2);
+
+ //status = sim_fpu_sub (&ans, &wop1, &wop2);
+ status = sim_fpu_sub (&ans, &wop2, &wop1);
+ status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact);
+
+ update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0);
+
+ sim_fpu_to32 (&GR[reg3], &ans);
+ TRACE_FP_RESULT_FPU1 (&ans);
+}
+
+// TRFSR
+0000011111100000 + 000001000000,bbb,0:F_I:::trfsr
+*v850e2v3
+"trfsr":(bbb == 0)
+"trfsr <bbb>"
+{
+ TRACE_ALU_INPUT1 (GET_FPCC());
+
+ if (TEST_FPCC (bbb))
+ PSW |= PSW_Z;
+ else
+ PSW &= ~PSW_Z;
+
+ TRACE_ALU_RESULT1 (PSW);
+}
+
+// TRNCF.DL
+rrrr,011111100001 + wwww,010001010100:F_I:::trncf_dl
+*v850e2v3
+"trncf.dl r<reg2e>, r<reg3e>"
+{
+ signed64 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_64 (&wop, sim_fpu_round_zero, sim_fpu_denorm_zero);
+ status |= sim_fpu_to64i (&ans, &wop, sim_fpu_round_zero);
+
+ check_cvt_fi(sd, status, 1);
+
+ GR[reg3e] = ans;
+ GR[reg3e+1] = ans>>32L;
+ TRACE_FP_RESULT_WORD2 (GR[reg3e], GR[reg3e+1]);
+}
+
+// TRNCF.DW
+rrrr,011111100001 + wwwww,10001010000:F_I:::trncf_dw
+*v850e2v3
+"trncf.dw r<reg2e>, r<reg3>"
+{
+ uint32 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_32 (&wop, sim_fpu_round_zero, sim_fpu_denorm_zero);
+ status |= sim_fpu_to32i (&ans, &wop, sim_fpu_round_zero);
+
+ check_cvt_fi(sd, status, 1);
+
+ GR[reg3] = ans;
+ TRACE_FP_RESULT_WORD1 (ans);
+}
+
+// TRNCF.SL
+rrrrr,11111100001 + wwww,010001000100:F_I:::trncf_sl
+*v850e2v3
+"trncf.sl r<reg2>, r<reg3e>"
+{
+ signed64 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_64 (&wop, sim_fpu_round_zero, sim_fpu_denorm_zero);
+ status |= sim_fpu_to64i (&ans, &wop, sim_fpu_round_zero);
+
+ GR[reg3e] = ans;
+ GR[reg3e+1] = ans >> 32L;
+ TRACE_FP_RESULT_WORD2 (GR[reg3e], GR[reg3e+1]);
+}
+
+// TRNCF.SW
+rrrrr,11111100001 + wwwww,10001000000:F_I:::trncf_sw
+*v850e2v3
+"trncf.sw r<reg2>, r<reg3>"
+{
+ uint32 ans;
+ sim_fpu wop;
+ sim_fpu_status status;
+
+ sim_fpu_32to (&wop, GR[reg2]);
+ TRACE_FP_INPUT_FPU1 (&wop);
+
+ status = sim_fpu_round_32 (&wop, sim_fpu_round_zero, sim_fpu_denorm_zero);
+ status |= sim_fpu_to32i (&ans, &wop, sim_fpu_round_zero);
+
+ check_cvt_fi(sd, status, 0);
+
+ GR[reg3] = ans;
+ TRACE_FP_RESULT_WORD1 (ans);
+}
+
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2012-03-29 1:07 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-19 14:59 [PATCH, V850] Add support for V850E2 and V850E2V3 Rathish C
2012-03-22 20:26 ` Kevin Buettner
2012-03-28 10:49 ` Rathish C
2012-03-28 12:01 ` Kevin Buettner
2012-03-28 14:45 ` Joel Brobecker
2012-03-29 1:07 ` Kevin Buettner
2012-03-29 1:06 ` Kevin Buettner
-- strict thread matches above, loose matches on Subject: below --
2011-01-12 13:25 Rathish C
2011-01-15 7:39 ` Kevin Buettner
2010-12-10 14:49 Rathish C
2010-12-13 16:47 ` Kevin Buettner
2010-09-21 19:55 Rathish C
2010-09-21 22:49 ` Kevin Buettner
2010-09-21 22:49 ` Kevin Buettner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).