diff options
Diffstat (limited to 'sim/mips/cp1.c')
-rw-r--r-- | sim/mips/cp1.c | 1170 |
1 files changed, 623 insertions, 547 deletions
diff --git a/sim/mips/cp1.c b/sim/mips/cp1.c index 2a1a82b..d0cf8be 100644 --- a/sim/mips/cp1.c +++ b/sim/mips/cp1.c @@ -26,7 +26,7 @@ /*-- FPU support routines ---------------------------------------------------*/ /* Numbers are held in normalized form. The SINGLE and DOUBLE binary - formats conform to ANSI/IEEE Std 754-1985. */ + formats conform to ANSI/IEEE Std 754-1985. */ /* SINGLE precision floating: * seeeeeeeefffffffffffffffffffffff * s = 1bit = sign @@ -50,31 +50,31 @@ * i = 63bits = integer */ -/* Extract sign-bit: */ -#define FP_S_s(v) (((v) & ((unsigned)1 << 31)) ? 1 : 0) -#define FP_D_s(v) (((v) & ((uword64)1 << 63)) ? 1 : 0) -/* Extract biased exponent: */ -#define FP_S_be(v) (((v) >> 23) & 0xFF) -#define FP_D_be(v) (((v) >> 52) & 0x7FF) -/* Extract unbiased Exponent: */ -#define FP_S_e(v) (FP_S_be(v) - 0x7F) -#define FP_D_e(v) (FP_D_be(v) - 0x3FF) -/* Extract complete fraction field: */ -#define FP_S_f(v) ((v) & ~((unsigned)0x1FF << 23)) -#define FP_D_f(v) ((v) & ~((uword64)0xFFF << 52)) -/* Extract numbered fraction bit: */ -#define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0) -#define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0) - -/* Explicit QNaN values used when value required: */ +/* Extract sign-bit: */ +#define FP_S_s(v) (((v) & (((unsigned) 1) << 31)) ? 1 : 0) +#define FP_D_s(v) (((v) & (((uword64) 1) << 63)) ? 1 : 0) +/* Extract biased exponent: */ +#define FP_S_be(v) (((v) >> 23) & 0xFF) +#define FP_D_be(v) (((v) >> 52) & 0x7FF) +/* Extract unbiased Exponent: */ +#define FP_S_e(v) (FP_S_be (v) - 0x7F) +#define FP_D_e(v) (FP_D_be (v) - 0x3FF) +/* Extract complete fraction field: */ +#define FP_S_f(v) ((v) & ~(((unsigned) 0x1FF) << 23)) +#define FP_D_f(v) ((v) & ~(((uword64) 0xFFF) << 52)) +/* Extract numbered fraction bit: */ +#define FP_S_fb(b, v) (((v) & (1 << (23 - (b)))) ? 1 : 0) +#define FP_D_fb(b, v) (((v) & (1 << (52 - (b)))) ? 1 : 0) + +/* Explicit QNaN values used when value required: */ #define FPQNaN_SINGLE (0x7FBFFFFF) #define FPQNaN_WORD (0x7FFFFFFF) -#define FPQNaN_DOUBLE (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF) -#define FPQNaN_LONG (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF) +#define FPQNaN_DOUBLE ((((uword64) 0x7FF7FFFF) << 32) | 0xFFFFFFFF) +#define FPQNaN_LONG ((((uword64) 0x7FFFFFFF) << 32) | 0xFFFFFFFF) -/* Explicit Infinity values used when required: */ +/* Explicit Infinity values used when required: */ #define FPINF_SINGLE (0x7F800000) -#define FPINF_DOUBLE (((uword64)0x7FF00000 << 32) | 0x00000000) +#define FPINF_DOUBLE ((((uword64) 0x7FF00000) << 32) | 0x00000000) static const char *fpu_format_name (FP_formats fmt); #ifdef DEBUG @@ -91,104 +91,126 @@ value_fpr (SIM_DESC sd, uword64 value = 0; int err = 0; - /* Treat unused register values, as fixed-point 64bit values: */ + /* Treat unused register values, as fixed-point 64bit values: */ if ((fmt == fmt_uninterpreted) || (fmt == fmt_unknown)) + { #if 1 - /* If request to read data as "uninterpreted", then use the current - encoding: */ - fmt = FPR_STATE[fpr]; + /* If request to read data as "uninterpreted", then use the current + encoding: */ + fmt = FPR_STATE[fpr]; #else - fmt = fmt_long; + fmt = fmt_long; #endif + } - /* For values not yet accessed, set to the desired format: */ - if (FPR_STATE[fpr] == fmt_uninterpreted) { - FPR_STATE[fpr] = fmt; + /* For values not yet accessed, set to the desired format: */ + if (FPR_STATE[fpr] == fmt_uninterpreted) + { + FPR_STATE[fpr] = fmt; #ifdef DEBUG - printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr, fpu_format_name (fmt)); + printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr, + fpu_format_name (fmt)); #endif /* DEBUG */ - } - if (fmt != FPR_STATE[fpr]) { - sim_io_eprintf(sd,"FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",fpr, fpu_format_name (FPR_STATE[fpr]), fpu_format_name (fmt),pr_addr(cia)); - FPR_STATE[fpr] = fmt_unknown; - } - - if (FPR_STATE[fpr] == fmt_unknown) { - /* Set QNaN value: */ - switch (fmt) { - case fmt_single: - value = FPQNaN_SINGLE; - break; - - case fmt_double: - value = FPQNaN_DOUBLE; - break; - - case fmt_word: - value = FPQNaN_WORD; - break; - - case fmt_long: - value = FPQNaN_LONG; - break; - - default: - err = -1; - break; - } - } else if (SizeFGR() == 64) { - switch (fmt) { - case fmt_single: - case fmt_word: - value = (FGR[fpr] & 0xFFFFFFFF); - break; - - case fmt_uninterpreted: - case fmt_double: - case fmt_long: - value = FGR[fpr]; - break; - - default : - err = -1; - break; } - } else { - switch (fmt) { - case fmt_single: - case fmt_word: - value = (FGR[fpr] & 0xFFFFFFFF); - break; + if (fmt != FPR_STATE[fpr]) + { + sim_io_eprintf (sd, "FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n", + fpr, fpu_format_name (FPR_STATE[fpr]), + fpu_format_name (fmt), pr_addr (cia)); + FPR_STATE[fpr] = fmt_unknown; + } - case fmt_uninterpreted: - case fmt_double: - case fmt_long: - if ((fpr & 1) == 0) { /* even registers only */ + if (FPR_STATE[fpr] == fmt_unknown) + { + /* Set QNaN value: */ + switch (fmt) + { + case fmt_single: + value = FPQNaN_SINGLE; + break; + + case fmt_double: + value = FPQNaN_DOUBLE; + break; + + case fmt_word: + value = FPQNaN_WORD; + break; + + case fmt_long: + value = FPQNaN_LONG; + break; + + default: + err = -1; + break; + } + } + else if (SizeFGR () == 64) + { + switch (fmt) + { + case fmt_single: + case fmt_word: + value = (FGR[fpr] & 0xFFFFFFFF); + break; + + case fmt_uninterpreted: + case fmt_double: + case fmt_long: + value = FGR[fpr]; + break; + + default: + err = -1; + break; + } + } + else + { + switch (fmt) + { + case fmt_single: + case fmt_word: + value = (FGR[fpr] & 0xFFFFFFFF); + break; + + case fmt_uninterpreted: + case fmt_double: + case fmt_long: + if ((fpr & 1) == 0) + { + /* even registers only */ #ifdef DEBUG - printf("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n", - fpr+1, pr_uword64( (uword64) FGR[fpr+1] ), - fpr, pr_uword64( (uword64) FGR[fpr] )); + printf ("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n", + fpr + 1, pr_uword64 ((uword64) FGR[fpr+1]), + fpr, pr_uword64 ((uword64) FGR[fpr])); #endif - value = ((((uword64)FGR[fpr+1]) << 32) | (FGR[fpr] & 0xFFFFFFFF)); - } else { - SignalException(ReservedInstruction,0); - } - break; - - default : - err = -1; - break; + value = ((((uword64) FGR[fpr+1]) << 32) + | (FGR[fpr] & 0xFFFFFFFF)); + } + else + { + SignalException (ReservedInstruction, 0); + } + break; + + default : + err = -1; + break; + } } - } if (err) - SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR()"); + SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR ()"); #ifdef DEBUG - printf("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d\n",fpr, fpu_format_name (fmt),pr_uword64(value),pr_addr(cia),SizeFGR()); + printf ("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d\n", + fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia), + SizeFGR ()); #endif /* DEBUG */ - return(value); + return (value); } void @@ -202,649 +224,696 @@ store_fpr (SIM_DESC sd, int err = 0; #ifdef DEBUG - printf("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d,\n",fpr, fpu_format_name (fmt),pr_uword64(value),pr_addr(cia),SizeFGR()); + printf ("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d, \n", + fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia), + SizeFGR ()); #endif /* DEBUG */ - if (SizeFGR() == 64) { - switch (fmt) { - case fmt_uninterpreted_32: - fmt = fmt_uninterpreted; - case fmt_single : - case fmt_word : - if (STATE_VERBOSE_P(SD)) - sim_io_eprintf (SD, "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n", - pr_addr(cia)); - FGR[fpr] = (((uword64)0xDEADC0DE << 32) | (value & 0xFFFFFFFF)); - FPR_STATE[fpr] = fmt; - break; - - case fmt_uninterpreted_64: - fmt = fmt_uninterpreted; - case fmt_uninterpreted: - case fmt_double : - case fmt_long : - FGR[fpr] = value; - FPR_STATE[fpr] = fmt; - break; - - default : - FPR_STATE[fpr] = fmt_unknown; - err = -1; - break; + if (SizeFGR () == 64) + { + switch (fmt) + { + case fmt_uninterpreted_32: + fmt = fmt_uninterpreted; + case fmt_single : + case fmt_word : + if (STATE_VERBOSE_P (SD)) + sim_io_eprintf (SD, + "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n", + pr_addr (cia)); + FGR[fpr] = (((uword64) 0xDEADC0DE << 32) | (value & 0xFFFFFFFF)); + FPR_STATE[fpr] = fmt; + break; + + case fmt_uninterpreted_64: + fmt = fmt_uninterpreted; + case fmt_uninterpreted: + case fmt_double : + case fmt_long : + FGR[fpr] = value; + FPR_STATE[fpr] = fmt; + break; + + default : + FPR_STATE[fpr] = fmt_unknown; + err = -1; + break; + } } - } else { - switch (fmt) { - case fmt_uninterpreted_32: - fmt = fmt_uninterpreted; - case fmt_single : - case fmt_word : - FGR[fpr] = (value & 0xFFFFFFFF); - FPR_STATE[fpr] = fmt; - break; - - case fmt_uninterpreted_64: - fmt = fmt_uninterpreted; - case fmt_uninterpreted: - case fmt_double : - case fmt_long : - if ((fpr & 1) == 0) { /* even register number only */ - FGR[fpr+1] = (value >> 32); + else + { + switch (fmt) + { + case fmt_uninterpreted_32: + fmt = fmt_uninterpreted; + case fmt_single : + case fmt_word : FGR[fpr] = (value & 0xFFFFFFFF); - FPR_STATE[fpr + 1] = fmt; FPR_STATE[fpr] = fmt; - } else { + break; + + case fmt_uninterpreted_64: + fmt = fmt_uninterpreted; + case fmt_uninterpreted: + case fmt_double : + case fmt_long : + 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 : FPR_STATE[fpr] = fmt_unknown; - FPR_STATE[fpr + 1] = fmt_unknown; - SignalException(ReservedInstruction,0); + err = -1; + break; } - break; - - default : - FPR_STATE[fpr] = fmt_unknown; - err = -1; - break; } - } #if defined(WARN_RESULT) else - UndefinedResult(); + UndefinedResult (); #endif /* WARN_RESULT */ if (err) - SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()"); + SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()"); #ifdef DEBUG - printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr,pr_uword64(FGR[fpr]), fpu_format_name (fmt)); + printf ("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n", + fpr, pr_uword64 (FGR[fpr]), fpu_format_name (fmt)); #endif /* DEBUG */ return; } int -NaN(op,fmt) +NaN (op, fmt) uword64 op; - FP_formats fmt; + FP_formats fmt; { int boolean = 0; - switch (fmt) { - case fmt_single: - case fmt_word: - { - sim_fpu wop; - sim_fpu_32to (&wop, op); - boolean = sim_fpu_is_nan (&wop); - break; - } - case fmt_double: - case fmt_long: + switch (fmt) { - sim_fpu wop; - sim_fpu_64to (&wop, op); - boolean = sim_fpu_is_nan (&wop); - break; + case fmt_single: + case fmt_word: + { + sim_fpu wop; + sim_fpu_32to (&wop, op); + boolean = sim_fpu_is_nan (&wop); + break; + } + case fmt_double: + case fmt_long: + { + sim_fpu wop; + sim_fpu_64to (&wop, op); + boolean = sim_fpu_is_nan (&wop); + break; + } + default: + fprintf (stderr, "Bad switch\n"); + abort (); } - default: - fprintf (stderr, "Bad switch\n"); - abort (); - } #ifdef DEBUG -printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op), fpu_format_name (fmt)); + printf ("DBG: NaN: returning %d for 0x%s (format = %s)\n", + boolean, pr_addr (op), fpu_format_name (fmt)); #endif /* DEBUG */ - return(boolean); + return (boolean); } int -Infinity(op,fmt) +Infinity (op, fmt) uword64 op; - FP_formats fmt; + FP_formats fmt; { int boolean = 0; #ifdef DEBUG - printf("DBG: Infinity: format %s 0x%s\n", fpu_format_name (fmt),pr_addr(op)); + printf ("DBG: Infinity: format %s 0x%s\n", + fpu_format_name (fmt), pr_addr (op)); #endif /* DEBUG */ - switch (fmt) { - case fmt_single: - { - sim_fpu wop; - sim_fpu_32to (&wop, op); - boolean = sim_fpu_is_infinity (&wop); - break; - } - case fmt_double: + switch (fmt) { - sim_fpu wop; - sim_fpu_64to (&wop, op); - boolean = sim_fpu_is_infinity (&wop); + case fmt_single: + { + sim_fpu wop; + sim_fpu_32to (&wop, op); + boolean = sim_fpu_is_infinity (&wop); + break; + } + case fmt_double: + { + sim_fpu wop; + sim_fpu_64to (&wop, op); + boolean = sim_fpu_is_infinity (&wop); + break; + } + default: + printf ("DBG: TODO: unrecognised format (%s) for Infinity check\n", + fpu_format_name (fmt)); break; } - default: - printf("DBG: TODO: unrecognised format (%s) for Infinity check\n", fpu_format_name (fmt)); - break; - } #ifdef DEBUG - printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op), fpu_format_name (fmt)); + printf ("DBG: Infinity: returning %d for 0x%s (format = %s)\n", + boolean, pr_addr (op), fpu_format_name (fmt)); #endif /* DEBUG */ - return(boolean); + return (boolean); } int -Less(op1,op2,fmt) +Less (op1, op2, fmt) uword64 op1; uword64 op2; - FP_formats fmt; + FP_formats fmt; { int boolean = 0; /* Argument checking already performed by the FPCOMPARE code */ #ifdef DEBUG - printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n", fpu_format_name (fmt),pr_addr(op1),pr_addr(op2)); + printf ("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n", + fpu_format_name (fmt), pr_addr (op1), pr_addr (op2)); #endif /* DEBUG */ - /* The format type should already have been checked: */ - switch (fmt) { - case fmt_single: - { - sim_fpu wop1; - sim_fpu wop2; - sim_fpu_32to (&wop1, op1); - sim_fpu_32to (&wop2, op2); - boolean = sim_fpu_is_lt (&wop1, &wop2); - break; - } - case fmt_double: + /* The format type should already have been checked: */ + switch (fmt) { - sim_fpu wop1; - sim_fpu wop2; - sim_fpu_64to (&wop1, op1); - sim_fpu_64to (&wop2, op2); - boolean = sim_fpu_is_lt (&wop1, &wop2); - break; + case fmt_single: + { + sim_fpu wop1; + sim_fpu wop2; + sim_fpu_32to (&wop1, op1); + sim_fpu_32to (&wop2, op2); + boolean = sim_fpu_is_lt (&wop1, &wop2); + break; + } + case fmt_double: + { + sim_fpu wop1; + sim_fpu wop2; + sim_fpu_64to (&wop1, op1); + sim_fpu_64to (&wop2, op2); + boolean = sim_fpu_is_lt (&wop1, &wop2); + break; + } + default: + fprintf (stderr, "Bad switch\n"); + abort (); } - default: - fprintf (stderr, "Bad switch\n"); - abort (); - } #ifdef DEBUG - printf("DBG: Less: returning %d (format = %s)\n",boolean, fpu_format_name (fmt)); + printf ("DBG: Less: returning %d (format = %s)\n", + boolean, fpu_format_name (fmt)); #endif /* DEBUG */ - return(boolean); + return (boolean); } int -Equal(op1,op2,fmt) +Equal (op1, op2, fmt) uword64 op1; uword64 op2; - FP_formats fmt; + FP_formats fmt; { int boolean = 0; /* Argument checking already performed by the FPCOMPARE code */ #ifdef DEBUG - printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n", fpu_format_name (fmt),pr_addr(op1),pr_addr(op2)); + printf ("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n", + fpu_format_name (fmt), pr_addr (op1), pr_addr (op2)); #endif /* DEBUG */ - /* The format type should already have been checked: */ - switch (fmt) { - case fmt_single: - { - sim_fpu wop1; - sim_fpu wop2; - sim_fpu_32to (&wop1, op1); - sim_fpu_32to (&wop2, op2); - boolean = sim_fpu_is_eq (&wop1, &wop2); - break; - } - case fmt_double: + /* The format type should already have been checked: */ + switch (fmt) { - sim_fpu wop1; - sim_fpu wop2; - sim_fpu_64to (&wop1, op1); - sim_fpu_64to (&wop2, op2); - boolean = sim_fpu_is_eq (&wop1, &wop2); - break; + case fmt_single: + { + sim_fpu wop1; + sim_fpu wop2; + sim_fpu_32to (&wop1, op1); + sim_fpu_32to (&wop2, op2); + boolean = sim_fpu_is_eq (&wop1, &wop2); + break; + } + case fmt_double: + { + sim_fpu wop1; + sim_fpu wop2; + sim_fpu_64to (&wop1, op1); + sim_fpu_64to (&wop2, op2); + boolean = sim_fpu_is_eq (&wop1, &wop2); + break; + } + default: + fprintf (stderr, "Bad switch\n"); + abort (); } - default: - fprintf (stderr, "Bad switch\n"); - abort (); - } #ifdef DEBUG - printf("DBG: Equal: returning %d (format = %s)\n",boolean, fpu_format_name (fmt)); + printf ("DBG: Equal: returning %d (format = %s)\n", + boolean, fpu_format_name (fmt)); #endif /* DEBUG */ - return(boolean); + return (boolean); } uword64 -AbsoluteValue(op,fmt) +AbsoluteValue (op, fmt) uword64 op; - FP_formats fmt; + FP_formats fmt; { uword64 result = 0; #ifdef DEBUG - printf("DBG: AbsoluteValue: %s: op = 0x%s\n", fpu_format_name (fmt),pr_addr(op)); + printf ("DBG: AbsoluteValue: %s: op = 0x%s\n", + fpu_format_name (fmt), pr_addr (op)); #endif /* DEBUG */ - /* The format type should already have been checked: */ - switch (fmt) { - case fmt_single: - { - sim_fpu wop; - unsigned32 ans; - sim_fpu_32to (&wop, op); - sim_fpu_abs (&wop, &wop); - sim_fpu_to32 (&ans, &wop); - result = ans; - break; - } - case fmt_double: + /* The format type should already have been checked: */ + switch (fmt) { - sim_fpu wop; - unsigned64 ans; - sim_fpu_64to (&wop, op); - sim_fpu_abs (&wop, &wop); - sim_fpu_to64 (&ans, &wop); - result = ans; - break; + case fmt_single: + { + sim_fpu wop; + unsigned32 ans; + sim_fpu_32to (&wop, op); + sim_fpu_abs (&wop, &wop); + sim_fpu_to32 (&ans, &wop); + result = ans; + break; + } + case fmt_double: + { + sim_fpu wop; + unsigned64 ans; + sim_fpu_64to (&wop, op); + sim_fpu_abs (&wop, &wop); + sim_fpu_to64 (&ans, &wop); + result = ans; + break; + } + default: + fprintf (stderr, "Bad switch\n"); + abort (); } - default: - fprintf (stderr, "Bad switch\n"); - abort (); - } - return(result); + return (result); } uword64 -Negate(op,fmt) +Negate (op, fmt) uword64 op; - FP_formats fmt; + FP_formats fmt; { uword64 result = 0; #ifdef DEBUG - printf("DBG: Negate: %s: op = 0x%s\n", fpu_format_name (fmt),pr_addr(op)); + printf ("DBG: Negate: %s: op = 0x%s\n", + fpu_format_name (fmt), pr_addr (op)); #endif /* DEBUG */ - /* The format type should already have been checked: */ - switch (fmt) { - case fmt_single: - { - sim_fpu wop; - unsigned32 ans; - sim_fpu_32to (&wop, op); - sim_fpu_neg (&wop, &wop); - sim_fpu_to32 (&ans, &wop); - result = ans; - break; - } - case fmt_double: + /* The format type should already have been checked: */ + switch (fmt) { - sim_fpu wop; - unsigned64 ans; - sim_fpu_64to (&wop, op); - sim_fpu_neg (&wop, &wop); - sim_fpu_to64 (&ans, &wop); - result = ans; - break; + case fmt_single: + { + sim_fpu wop; + unsigned32 ans; + sim_fpu_32to (&wop, op); + sim_fpu_neg (&wop, &wop); + sim_fpu_to32 (&ans, &wop); + result = ans; + break; + } + case fmt_double: + { + sim_fpu wop; + unsigned64 ans; + sim_fpu_64to (&wop, op); + sim_fpu_neg (&wop, &wop); + sim_fpu_to64 (&ans, &wop); + result = ans; + break; + } + default: + fprintf (stderr, "Bad switch\n"); + abort (); } - default: - fprintf (stderr, "Bad switch\n"); - abort (); - } - return(result); + return (result); } uword64 -Add(op1,op2,fmt) +Add (op1, op2, fmt) uword64 op1; uword64 op2; - FP_formats fmt; + FP_formats fmt; { uword64 result = 0; #ifdef DEBUG - printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n", fpu_format_name (fmt),pr_addr(op1),pr_addr(op2)); + printf ("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n", + fpu_format_name (fmt), pr_addr (op1), pr_addr (op2)); #endif /* DEBUG */ /* The registers must specify FPRs valid for operands of type - "fmt". If they are not valid, the result is undefined. */ - - /* The format type should already have been checked: */ - switch (fmt) { - case fmt_single: - { - sim_fpu wop1; - sim_fpu wop2; - sim_fpu ans; - unsigned32 res; - sim_fpu_32to (&wop1, op1); - sim_fpu_32to (&wop2, op2); - sim_fpu_add (&ans, &wop1, &wop2); - sim_fpu_to32 (&res, &ans); - result = res; - break; - } - case fmt_double: + "fmt". If they are not valid, the result is undefined. */ + + /* The format type should already have been checked: */ + switch (fmt) { - sim_fpu wop1; - sim_fpu wop2; - sim_fpu ans; - unsigned64 res; - sim_fpu_64to (&wop1, op1); - sim_fpu_64to (&wop2, op2); - sim_fpu_add (&ans, &wop1, &wop2); - sim_fpu_to64 (&res, &ans); - result = res; - break; + case fmt_single: + { + sim_fpu wop1; + sim_fpu wop2; + sim_fpu ans; + unsigned32 res; + sim_fpu_32to (&wop1, op1); + sim_fpu_32to (&wop2, op2); + sim_fpu_add (&ans, &wop1, &wop2); + sim_fpu_to32 (&res, &ans); + result = res; + break; + } + case fmt_double: + { + sim_fpu wop1; + sim_fpu wop2; + sim_fpu ans; + unsigned64 res; + sim_fpu_64to (&wop1, op1); + sim_fpu_64to (&wop2, op2); + sim_fpu_add (&ans, &wop1, &wop2); + sim_fpu_to64 (&res, &ans); + result = res; + break; + } + default: + fprintf (stderr, "Bad switch\n"); + abort (); } - default: - fprintf (stderr, "Bad switch\n"); - abort (); - } #ifdef DEBUG - printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result), fpu_format_name (fmt)); + printf ("DBG: Add: returning 0x%s (format = %s)\n", + pr_addr (result), fpu_format_name (fmt)); #endif /* DEBUG */ - return(result); + return (result); } uword64 -Sub(op1,op2,fmt) +Sub (op1, op2, fmt) uword64 op1; uword64 op2; - FP_formats fmt; + FP_formats fmt; { uword64 result = 0; #ifdef DEBUG - printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n", fpu_format_name (fmt),pr_addr(op1),pr_addr(op2)); + printf ("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n", + fpu_format_name (fmt), pr_addr (op1), pr_addr (op2)); #endif /* DEBUG */ /* The registers must specify FPRs valid for operands of type - "fmt". If they are not valid, the result is undefined. */ + "fmt". If they are not valid, the result is undefined. */ - /* The format type should already have been checked: */ - switch (fmt) { - case fmt_single: - { - sim_fpu wop1; - sim_fpu wop2; - sim_fpu ans; - unsigned32 res; - sim_fpu_32to (&wop1, op1); - sim_fpu_32to (&wop2, op2); - sim_fpu_sub (&ans, &wop1, &wop2); - sim_fpu_to32 (&res, &ans); - result = res; - } - break; - case fmt_double: + /* The format type should already have been checked: */ + switch (fmt) { - sim_fpu wop1; - sim_fpu wop2; - sim_fpu ans; - unsigned64 res; - sim_fpu_64to (&wop1, op1); - sim_fpu_64to (&wop2, op2); - sim_fpu_sub (&ans, &wop1, &wop2); - sim_fpu_to64 (&res, &ans); - result = res; + case fmt_single: + { + sim_fpu wop1; + sim_fpu wop2; + sim_fpu ans; + unsigned32 res; + sim_fpu_32to (&wop1, op1); + sim_fpu_32to (&wop2, op2); + sim_fpu_sub (&ans, &wop1, &wop2); + sim_fpu_to32 (&res, &ans); + result = res; + } + break; + case fmt_double: + { + sim_fpu wop1; + sim_fpu wop2; + sim_fpu ans; + unsigned64 res; + sim_fpu_64to (&wop1, op1); + sim_fpu_64to (&wop2, op2); + sim_fpu_sub (&ans, &wop1, &wop2); + sim_fpu_to64 (&res, &ans); + result = res; + } + break; + default: + fprintf (stderr, "Bad switch\n"); + abort (); } - break; - default: - fprintf (stderr, "Bad switch\n"); - abort (); - } #ifdef DEBUG - printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result), fpu_format_name (fmt)); + printf ("DBG: Sub: returning 0x%s (format = %s)\n", + pr_addr (result), fpu_format_name (fmt)); #endif /* DEBUG */ - return(result); + return (result); } uword64 -Multiply(op1,op2,fmt) +Multiply (op1, op2, fmt) uword64 op1; uword64 op2; - FP_formats fmt; + FP_formats fmt; { uword64 result = 0; #ifdef DEBUG - printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n", fpu_format_name (fmt),pr_addr(op1),pr_addr(op2)); + printf ("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n", + fpu_format_name (fmt), pr_addr (op1), pr_addr (op2)); #endif /* DEBUG */ /* The registers must specify FPRs valid for operands of type - "fmt". If they are not valid, the result is undefined. */ + "fmt". If they are not valid, the result is undefined. */ - /* The format type should already have been checked: */ - switch (fmt) { - case fmt_single: - { - sim_fpu wop1; - sim_fpu wop2; - sim_fpu ans; - unsigned32 res; - sim_fpu_32to (&wop1, op1); - sim_fpu_32to (&wop2, op2); - sim_fpu_mul (&ans, &wop1, &wop2); - sim_fpu_to32 (&res, &ans); - result = res; - break; - } - case fmt_double: + /* The format type should already have been checked: */ + switch (fmt) { - sim_fpu wop1; - sim_fpu wop2; - sim_fpu ans; - unsigned64 res; - sim_fpu_64to (&wop1, op1); - sim_fpu_64to (&wop2, op2); - sim_fpu_mul (&ans, &wop1, &wop2); - sim_fpu_to64 (&res, &ans); - result = res; - break; + case fmt_single: + { + sim_fpu wop1; + sim_fpu wop2; + sim_fpu ans; + unsigned32 res; + sim_fpu_32to (&wop1, op1); + sim_fpu_32to (&wop2, op2); + sim_fpu_mul (&ans, &wop1, &wop2); + sim_fpu_to32 (&res, &ans); + result = res; + break; + } + case fmt_double: + { + sim_fpu wop1; + sim_fpu wop2; + sim_fpu ans; + unsigned64 res; + sim_fpu_64to (&wop1, op1); + sim_fpu_64to (&wop2, op2); + sim_fpu_mul (&ans, &wop1, &wop2); + sim_fpu_to64 (&res, &ans); + result = res; + break; + } + default: + fprintf (stderr, "Bad switch\n"); + abort (); } - default: - fprintf (stderr, "Bad switch\n"); - abort (); - } #ifdef DEBUG - printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result), fpu_format_name (fmt)); + printf ("DBG: Multiply: returning 0x%s (format = %s)\n", + pr_addr (result), fpu_format_name (fmt)); #endif /* DEBUG */ - return(result); + return (result); } uword64 -Divide(op1,op2,fmt) +Divide (op1, op2, fmt) uword64 op1; uword64 op2; - FP_formats fmt; + FP_formats fmt; { uword64 result = 0; #ifdef DEBUG - printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n", fpu_format_name (fmt),pr_addr(op1),pr_addr(op2)); + printf ("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n", + fpu_format_name (fmt), pr_addr (op1), pr_addr (op2)); #endif /* DEBUG */ /* The registers must specify FPRs valid for operands of type - "fmt". If they are not valid, the result is undefined. */ + "fmt". If they are not valid, the result is undefined. */ - /* The format type should already have been checked: */ - switch (fmt) { - case fmt_single: - { - sim_fpu wop1; - sim_fpu wop2; - sim_fpu ans; - unsigned32 res; - sim_fpu_32to (&wop1, op1); - sim_fpu_32to (&wop2, op2); - sim_fpu_div (&ans, &wop1, &wop2); - sim_fpu_to32 (&res, &ans); - result = res; - break; - } - case fmt_double: + /* The format type should already have been checked: */ + switch (fmt) { - sim_fpu wop1; - sim_fpu wop2; - sim_fpu ans; - unsigned64 res; - sim_fpu_64to (&wop1, op1); - sim_fpu_64to (&wop2, op2); - sim_fpu_div (&ans, &wop1, &wop2); - sim_fpu_to64 (&res, &ans); - result = res; - break; + case fmt_single: + { + sim_fpu wop1; + sim_fpu wop2; + sim_fpu ans; + unsigned32 res; + sim_fpu_32to (&wop1, op1); + sim_fpu_32to (&wop2, op2); + sim_fpu_div (&ans, &wop1, &wop2); + sim_fpu_to32 (&res, &ans); + result = res; + break; + } + case fmt_double: + { + sim_fpu wop1; + sim_fpu wop2; + sim_fpu ans; + unsigned64 res; + sim_fpu_64to (&wop1, op1); + sim_fpu_64to (&wop2, op2); + sim_fpu_div (&ans, &wop1, &wop2); + sim_fpu_to64 (&res, &ans); + result = res; + break; + } + default: + fprintf (stderr, "Bad switch\n"); + abort (); } - default: - fprintf (stderr, "Bad switch\n"); - abort (); - } #ifdef DEBUG - printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result), fpu_format_name (fmt)); + printf ("DBG: Divide: returning 0x%s (format = %s)\n", + pr_addr (result), fpu_format_name (fmt)); #endif /* DEBUG */ - return(result); + return (result); } uword64 UNUSED -Recip(op,fmt) +Recip (op, fmt) uword64 op; - FP_formats fmt; + FP_formats fmt; { uword64 result = 0; #ifdef DEBUG - printf("DBG: Recip: %s: op = 0x%s\n", fpu_format_name (fmt),pr_addr(op)); + printf ("DBG: Recip: %s: op = 0x%s\n", + fpu_format_name (fmt), pr_addr (op)); #endif /* DEBUG */ /* The registers must specify FPRs valid for operands of type - "fmt". If they are not valid, the result is undefined. */ + "fmt". If they are not valid, the result is undefined. */ - /* The format type should already have been checked: */ - switch (fmt) { - case fmt_single: - { - sim_fpu wop; - sim_fpu ans; - unsigned32 res; - sim_fpu_32to (&wop, op); - sim_fpu_inv (&ans, &wop); - sim_fpu_to32 (&res, &ans); - result = res; - break; - } - case fmt_double: + /* The format type should already have been checked: */ + switch (fmt) { - sim_fpu wop; - sim_fpu ans; - unsigned64 res; - sim_fpu_64to (&wop, op); - sim_fpu_inv (&ans, &wop); - sim_fpu_to64 (&res, &ans); - result = res; - break; + case fmt_single: + { + sim_fpu wop; + sim_fpu ans; + unsigned32 res; + sim_fpu_32to (&wop, op); + sim_fpu_inv (&ans, &wop); + sim_fpu_to32 (&res, &ans); + result = res; + break; + } + case fmt_double: + { + sim_fpu wop; + sim_fpu ans; + unsigned64 res; + sim_fpu_64to (&wop, op); + sim_fpu_inv (&ans, &wop); + sim_fpu_to64 (&res, &ans); + result = res; + break; + } + default: + fprintf (stderr, "Bad switch\n"); + abort (); } - default: - fprintf (stderr, "Bad switch\n"); - abort (); - } #ifdef DEBUG - printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result), fpu_format_name (fmt)); + printf ("DBG: Recip: returning 0x%s (format = %s)\n", + pr_addr (result), fpu_format_name (fmt)); #endif /* DEBUG */ - return(result); + return (result); } uword64 -SquareRoot(op,fmt) +SquareRoot (op, fmt) uword64 op; - FP_formats fmt; + FP_formats fmt; { uword64 result = 0; #ifdef DEBUG - printf("DBG: SquareRoot: %s: op = 0x%s\n", fpu_format_name (fmt),pr_addr(op)); + printf ("DBG: SquareRoot: %s: op = 0x%s\n", + fpu_format_name (fmt), pr_addr (op)); #endif /* DEBUG */ /* The registers must specify FPRs valid for operands of type - "fmt". If they are not valid, the result is undefined. */ + "fmt". If they are not valid, the result is undefined. */ - /* The format type should already have been checked: */ - switch (fmt) { - case fmt_single: - { - sim_fpu wop; - sim_fpu ans; - unsigned32 res; - sim_fpu_32to (&wop, op); - sim_fpu_sqrt (&ans, &wop); - sim_fpu_to32 (&res, &ans); - result = res; - break; - } - case fmt_double: + /* The format type should already have been checked: */ + switch (fmt) { - sim_fpu wop; - sim_fpu ans; - unsigned64 res; - sim_fpu_64to (&wop, op); - sim_fpu_sqrt (&ans, &wop); - sim_fpu_to64 (&res, &ans); - result = res; - break; + case fmt_single: + { + sim_fpu wop; + sim_fpu ans; + unsigned32 res; + sim_fpu_32to (&wop, op); + sim_fpu_sqrt (&ans, &wop); + sim_fpu_to32 (&res, &ans); + result = res; + break; + } + case fmt_double: + { + sim_fpu wop; + sim_fpu ans; + unsigned64 res; + sim_fpu_64to (&wop, op); + sim_fpu_sqrt (&ans, &wop); + sim_fpu_to64 (&res, &ans); + result = res; + break; + } + default: + fprintf (stderr, "Bad switch\n"); + abort (); } - default: - fprintf (stderr, "Bad switch\n"); - abort (); - } #ifdef DEBUG - printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result), fpu_format_name (fmt)); + printf ("DBG: SquareRoot: returning 0x%s (format = %s)\n", + pr_addr (result), fpu_format_name (fmt)); #endif /* DEBUG */ - return(result); + return (result); } #if 0 @@ -857,13 +926,14 @@ Max (uword64 op1, unsigned64 result; #ifdef DEBUG - printf("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n", fpu_format_name (fmt),pr_addr(op1),pr_addr(op2)); + printf ("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n", + fpu_format_name (fmt), pr_addr (op1), pr_addr (op2)); #endif /* DEBUG */ /* The registers must specify FPRs valid for operands of type - "fmt". If they are not valid, the result is undefined. */ + "fmt". If they are not valid, the result is undefined. */ - /* The format type should already have been checked: */ + /* The format type should already have been checked: */ switch (fmt) { case fmt_single: @@ -888,7 +958,7 @@ Max (uword64 op1, fprintf (stderr, "Bad switch\n"); abort (); } - + switch (cmp) { case SIM_FPU_IS_SNAN: @@ -910,12 +980,13 @@ Max (uword64 op1, } #ifdef DEBUG - printf("DBG: Max: returning 0x%s (format = %s)\n",pr_addr(result), fpu_format_name (fmt)); + printf ("DBG: Max: returning 0x%s (format = %s)\n", + pr_addr (result), fpu_format_name (fmt)); #endif /* DEBUG */ - return(result); + return (result); } -#endif +#endif #if 0 uword64 @@ -927,13 +998,14 @@ Min (uword64 op1, unsigned64 result; #ifdef DEBUG - printf("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n", fpu_format_name (fmt),pr_addr(op1),pr_addr(op2)); + printf ("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n", + fpu_format_name (fmt), pr_addr (op1), pr_addr (op2)); #endif /* DEBUG */ /* The registers must specify FPRs valid for operands of type - "fmt". If they are not valid, the result is undefined. */ + "fmt". If they are not valid, the result is undefined. */ - /* The format type should already have been checked: */ + /* The format type should already have been checked: */ switch (fmt) { case fmt_single: @@ -958,7 +1030,7 @@ Min (uword64 op1, fprintf (stderr, "Bad switch\n"); abort (); } - + switch (cmp) { case SIM_FPU_IS_SNAN: @@ -980,10 +1052,11 @@ Min (uword64 op1, } #ifdef DEBUG - printf("DBG: Min: returning 0x%s (format = %s)\n",pr_addr(result), fpu_format_name (fmt)); + printf ("DBG: Min: returning 0x%s (format = %s)\n", + pr_addr (result), fpu_format_name (fmt)); #endif /* DEBUG */ - return(result); + return (result); } #endif @@ -1003,7 +1076,9 @@ convert (SIM_DESC sd, #ifdef DEBUG #if 0 /* FIXME: doesn't compile */ - printf("DBG: Convert: mode %s : op 0x%s : from %s : to %s : (PC = 0x%s)\n", fpu_rounding_mode_name (rm),pr_addr(op), fpu_format_name (from), fpu_format_name (to),pr_addr(IPC)); + printf ("DBG: Convert: mode %s : op 0x%s : from %s : to %s : (PC = 0x%s)\n", + fpu_rounding_mode_name (rm), pr_addr (op), fpu_format_name (from), + fpu_format_name (to), pr_addr (IPC)); #endif #endif /* DEBUG */ @@ -1012,23 +1087,23 @@ convert (SIM_DESC sd, case FP_RM_NEAREST: /* Round result to nearest representable value. When two representable values are equally near, round to the value - that has a least significant bit of zero (i.e. is even). */ + that has a least significant bit of zero (i.e. is even). */ round = sim_fpu_round_near; break; case FP_RM_TOZERO: /* Round result to the value closest to, and not greater in - magnitude than, the result. */ + magnitude than, the result. */ round = sim_fpu_round_zero; break; case FP_RM_TOPINF: /* Round result to the value closest to, and not less than, - the result. */ + the result. */ round = sim_fpu_round_up; break; - + case FP_RM_TOMINF: /* Round result to the value closest to, and not greater than, - the result. */ + the result. */ round = sim_fpu_round_down; break; default: @@ -1036,7 +1111,7 @@ convert (SIM_DESC sd, fprintf (stderr, "Bad switch\n"); abort (); } - + /* Convert the input to sim_fpu internal format */ switch (from) { @@ -1062,7 +1137,7 @@ convert (SIM_DESC sd, using mode RM. When the destination is a fixed-point format, then a source value of Infinity, NaN or one which would round to an integer outside the fixed point range then an IEEE Invalid - Operation condition is raised. */ + Operation condition is raised. */ switch (to) { case fmt_single: @@ -1086,12 +1161,13 @@ convert (SIM_DESC sd, fprintf (stderr, "Bad switch\n"); abort (); } - + #ifdef DEBUG - printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result64), fpu_format_name (to)); + printf ("DBG: Convert: returning 0x%s (to format = %s)\n", + pr_addr (result64), fpu_format_name (to)); #endif /* DEBUG */ - return(result64); + return (result64); } static const char * |