Commit gdb and sim support for v850e2 and v850e2v3 on behalf of
Rathish C <Rathish.C@kpitcummins.com>.
This commit is contained in:
parent
1c1b6f059a
commit
2aaed97917
11 changed files with 3380 additions and 29 deletions
|
@ -1,3 +1,12 @@
|
|||
2012-03-28 Rathish C <rathish.c@kpitcummins.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2012-03-28 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* NEWS: Add entry for Ada varobj support.
|
||||
|
|
139
gdb/v850-tdep.c
139
gdb/v850-tdep.c
|
@ -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 *gdbarch, int regnum)
|
|||
"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 *gdbarch, int regnum)
|
|||
"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 *
|
||||
|
@ -999,6 +1128,10 @@ v850_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
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);
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2012-03-28 Rathish C <rathish.c@kpitcummins.com>
|
||||
|
||||
* sim-trace.c: Update the function prototype of save_data_size.
|
||||
Move the enum data_fmt from here...
|
||||
* sim-trace.h: ...to here.
|
||||
Add function prototype of save_data.
|
||||
|
||||
2012-03-25 Mike Frysinger <vapier@gentoo.org>
|
||||
|
||||
* sim-core.h (sim_core_trans_addr): Add prototype.
|
||||
|
|
|
@ -497,17 +497,6 @@ trace_uninstall (SIM_DESC sd)
|
|||
}
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -519,7 +508,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,
|
||||
|
|
|
@ -249,9 +249,26 @@ extern void trace_generic PARAMS ((SIM_DESC sd,
|
|||
...))
|
||||
__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));
|
||||
|
|
|
@ -1,3 +1,58 @@
|
|||
2012-03-28 Rathish C <rathish.c@kpitcummins.com>
|
||||
|
||||
* sim-main.h (struct _v850_regs): Add new fields mpu0_sregs,
|
||||
mpu1_sregs, and fpu_sregs.
|
||||
(MPU0_SR, MPU1_SR, FPU_SR): New macros for accessing new fields
|
||||
in _v850_regs struct.
|
||||
(SP_REGNO): Define.
|
||||
(SP): Redefine using SP_REGNO.
|
||||
(PSW_REGNO, EIIC, FEIC, DBIC, DIR, EIWR, FEWR, DBWR, BSEL, PSW_NPV)
|
||||
(PSW_DMP, PSW_IMP, ECR_EICC, ECR_FECC, FPSR, FPSR_REGNO, FPEPC)
|
||||
(FPST, FPST_REGNO, FPCC, FPCFG, FPCFG_REGNO, FPSR_DEM, FPSR_SEM)
|
||||
(FPSR_RM, FPSR_RN, FPSR_FS, FPSR_PR, FPSR_XC, FPSR_XCE, FPSR_XCV)
|
||||
(FPSR_XCZ, FPSR_XCO, FPSR_XCU, FPSR_XCI, FPSR_XE, FPSR_XEV)
|
||||
(FPSR_XEZ, FPSR_XEO, FPSR_XEU, FPSR_XEI, FPSR_XP, FPSR_XPV)
|
||||
(FPSR_XPZ, FPSR_XPO, FPSR_XPU, FPSR_XPI, FPST_PR, FPST_XCE)
|
||||
(FPST_XCV, FPST_XCZ, FPST_XCO, FPST_XCU, FPST_XCI, FPST_XPV)
|
||||
(FPST_XPZ, FPST_XPO, FPST_XPU, FPST_XPI, FPCFG_RM, FPCFG_XEV)
|
||||
(FPCFG_XEZ, FPCFG_XEO, FPCFG_XEU, FPCFG_XEI, GET_FPCC, CLEAR_FPCC)
|
||||
(SET_FPCC, TEST_FPCC, FPSR_GET_ROUND, MPM, MPC, MPC_REGNO, TID)
|
||||
(PPA, PPM, PPC, DCC, DCV0, DCV1, SPAL, SPAU, IPA0L, IPA0U, IPA1L)
|
||||
(IPA1U, IPA2L, IPA2U, IPA3L, IPA3U, DPA0L, DPA0U, DPA1L, DPA1U)
|
||||
(DPA2L, DPA2U, DPA3L, DPA3U, PPC_PPE, SPAL_SPE, SPAL_SPS, VIP)
|
||||
(VMECR, VMTID, VMADR, VPECR, VPTID, VPADR, VDECR, VDTID, MPM_AUE)
|
||||
(MPM_MPE, VMECR_VMX, VMECR_VMR, VMECR_VMW, VMECR_VMS, VMECR_VMRMW)
|
||||
(VMECR_VMMS, IPA2ADDR, IPA_IPE, IPA_IPX, IPA_IPR, IPE0, IPE1, IPE2)
|
||||
(IPE3, IPX0, IPX1, IPX2, IPX3, IPR0, IPR1, IPR2, IPR3, DPA2ADDR)
|
||||
(DPA_DPE, DPA_DPR, DPA_DPW, DPE0, DPE1, DPE2, DPE3, DPR0, DPR1)
|
||||
(DPR2, DPR3, DPW0, DPW1, DPW2, DPW3, DCC_DCE0, DCC_DCE1, PPA2ADDR)
|
||||
(PPC_PPC, PPC_PPE, PPC_PPM): New macros.
|
||||
(FPU_COMPARE): New enum.
|
||||
(TRACE_FP_INPUT_FPU1, TRACE_FP_INPUT_FPU2, TRACE_FP_INPUT_FPU3)
|
||||
(TRACE_FP_INPUT_BOOL1_FPU2, TRACE_FP_INPUT_WORD2)
|
||||
(TRACE_FP_RESULT_WORD1, TRACE_FP_RESULT_WORD2): New macros.
|
||||
* simops.c (Add32): Update prototype.
|
||||
(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.
|
||||
* simops.h: Add function prototype for above mentioned functions.
|
||||
(check_cvt_fi, check_cvt_if, check_cvt_ff): Define.
|
||||
* v850-dc: Add entry for v850e2 and v850e2v3.
|
||||
* v850.igen: Add support for v850e2 and v850e2v3.
|
||||
|
||||
2012-03-24 Mike Frysinger <vapier@gentoo.org>
|
||||
|
||||
* aclocal.m4, config.in, configure: Regenerate.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
@ -2839,3 +2839,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
2079
sim/v850/v850.igen
2079
sim/v850/v850.igen
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue