From da0bce9c27299834b4fd4da16d98e616a3371ad6 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 6 Feb 1997 22:19:05 +0000 Subject: [PATCH] * interp.c (mips16_entry): Add support for floating point cases. (SignalException): Pass floating point cases to mips16_entry. (ValueFPR): Don't restrict fmt_single and fmt_word to even registers. (StoreFPR): Likewise. Also, don't clobber fpr + 1 for fmt_single or fmt_word. (COP_LW): Pass fmt_word rather than fmt_uninterpreted to StoreFPR, and then set the state to fmt_uninterpreted. (COP_SW): Temporarily set the state to fmt_word while calling ValueFPR. --- sim/mips/ChangeLog | 13 ++++++++++ sim/mips/interp.c | 64 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 61 insertions(+), 16 deletions(-) diff --git a/sim/mips/ChangeLog b/sim/mips/ChangeLog index f1291a5d00..4b71012e1f 100644 --- a/sim/mips/ChangeLog +++ b/sim/mips/ChangeLog @@ -1,3 +1,16 @@ +Thu Feb 6 17:16:15 1997 Ian Lance Taylor + + * interp.c (mips16_entry): Add support for floating point cases. + (SignalException): Pass floating point cases to mips16_entry. + (ValueFPR): Don't restrict fmt_single and fmt_word to even + registers. + (StoreFPR): Likewise. Also, don't clobber fpr + 1 for fmt_single + or fmt_word. + (COP_LW): Pass fmt_word rather than fmt_uninterpreted to StoreFPR, + and then set the state to fmt_uninterpreted. + (COP_SW): Temporarily set the state to fmt_word while calling + ValueFPR. + Tue Feb 4 16:48:25 1997 Ian Lance Taylor * gencode.c (build_instruction): The high order may be set in the diff --git a/sim/mips/interp.c b/sim/mips/interp.c index ac3bed06f4..480bda698c 100644 --- a/sim/mips/interp.c +++ b/sim/mips/interp.c @@ -1624,7 +1624,14 @@ sim_monitor(reason) uword64 paddr; int cca; if (AddressTranslation(A1,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL)) - V0 = callback->write(callback,(int)A0,(const char *)((int)paddr),(int)A2); + { + if (A0 == 1) + V0 = callback->write_stdout(callback,(const char *)((int)paddr), + (int)A2); + else + V0 = callback->write(callback,(int)A0,(const char *)((int)paddr), + (int)A2); + } else sim_error("Attempt to pass pointer that does not reference simulated memory"); } @@ -1895,11 +1902,11 @@ mips16_entry (insn) sregs = (insn & 0x0c0) >> 6; rreg = (insn & 0x020) >> 5; - /* These should be checked by the caller. */ - if (aregs == 5 || aregs == 6 || sregs == 3) + /* This should be checked by the caller. */ + if (sregs == 3) abort (); - if (aregs != 7) + if (aregs < 5) { int i; t_reg tsp; @@ -1947,6 +1954,19 @@ mips16_entry (insn) SP += 32; + if (aregs == 5) + { + FGR[0] = WORD64LO (GPR[4]); + fpr_state[0] = fmt_uninterpreted; + } + else if (aregs == 6) + { + FGR[0] = WORD64LO (GPR[5]); + FGR[1] = WORD64LO (GPR[4]); + fpr_state[0] = fmt_uninterpreted; + fpr_state[1] = fmt_uninterpreted; + } + PC = RA; } } @@ -2704,8 +2724,6 @@ SignalException (int exception,...) simulate a handler for them. */ else if ((IPC & 1) != 0 && (instruction & 0xf81f) == 0xe809 - && (instruction & 0x700) != 0x500 - && (instruction & 0x700) != 0x600 && (instruction & 0x0c0) != 0x0c0) { mips16_entry (instruction); break; @@ -3000,7 +3018,7 @@ ValueFPR(fpr,fmt) err = -1; break; } - } else if ((fpr & 1) == 0) { /* even registers only */ + } else { switch (fmt) { case fmt_single: case fmt_word: @@ -3010,7 +3028,11 @@ ValueFPR(fpr,fmt) case fmt_uninterpreted: case fmt_double: case fmt_long: - value = ((((uword64)FGR[fpr+1]) << 32) | (FGR[fpr] & 0xFFFFFFFF)); + if ((fpr & 1) == 0) { /* even registers only */ + value = ((((uword64)FGR[fpr+1]) << 32) | (FGR[fpr] & 0xFFFFFFFF)); + } else { + SignalException (ReservedInstruction, 0); + } break; default : @@ -3061,23 +3083,27 @@ StoreFPR(fpr,fmt,value) err = -1; break; } - } else if ((fpr & 1) == 0) { /* even register number only */ + } else { switch (fmt) { case fmt_single : case fmt_word : - FGR[fpr+1] = 0xDEADC0DE; FGR[fpr] = (value & 0xFFFFFFFF); - fpr_state[fpr + 1] = fmt; fpr_state[fpr] = fmt; break; case fmt_uninterpreted: case fmt_double : case fmt_long : - FGR[fpr+1] = (value >> 32); - FGR[fpr] = (value & 0xFFFFFFFF); - fpr_state[fpr + 1] = fmt; - fpr_state[fpr] = fmt; + if ((fpr & 1) == 0) { /* even register number only */ + FGR[fpr+1] = (value >> 32); + FGR[fpr] = (value & 0xFFFFFFFF); + fpr_state[fpr + 1] = fmt; + fpr_state[fpr] = fmt; + } else { + fpr_state[fpr] = fmt_unknown; + fpr_state[fpr + 1] = fmt_unknown; + SignalException (ReservedInstruction, 0); + } break; default : @@ -3754,7 +3780,8 @@ COP_LW(coproc_num,coproc_reg,memword) #ifdef DEBUG printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%08X%08X\n",memword,WORD64HI(memword),WORD64LO(memword)); #endif - StoreFPR(coproc_reg,fmt_uninterpreted,(uword64)memword); + StoreFPR(coproc_reg,fmt_word,(uword64)memword); + fpr_state[coproc_reg] = fmt_uninterpreted; break; #endif /* HASFPU */ @@ -3795,11 +3822,16 @@ COP_SW(coproc_num,coproc_reg) int coproc_num, coproc_reg; { unsigned int value = 0; + FP_formats hold; + switch (coproc_num) { #if defined(HASFPU) case 1: #if 1 + hold = fpr_state[coproc_reg]; + fpr_state[coproc_reg] = fmt_word; value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted); + fpr_state[coproc_reg] = hold; #else #if 1 value = (unsigned int)ValueFPR(coproc_reg,fpr_state[coproc_reg]); -- 2.34.1