Fix PPC simulator fdiv insn
Andrew Cagney
cagney@tpgi.com.au
Wed Feb 11 02:54:00 GMT 1998
Jason,
Probably interested in the below.
Andrew
Mon Feb 9 14:13:14 1998 Andrew Cagney <cagney@b1.cygnus.com>
* ppc-instructions (fdiv, fdivs): Check for divide by zero.
(is_invalid_zero_divide, invalid_zero_divide_operation): New
functions.
*** ./sim/ppc/ppc-instructions.orig Wed Feb 11 21:54:54 1998
--- ./sim/ppc/ppc-instructions Mon Feb 9 17:27:39 1998
***************
*** 1384,1389 ****
--- 1384,1429 ----
+ # detect divide by zero
+ int::function::is_invalid_zero_divide:cpu *processor, unsigned_word cia, unsigned64 fra, unsigned64 frb, int single
+ int fail = 0;
+ if (is_zero (frb)) {
+ FPSCR_SET_ZX (1);
+ fail = 1;
+ }
+ return fail;
+
+
+
+
+ # handle case of invalid operation
+ void::function::invalid_zero_divide_operation:cpu *processor, unsigned_word cia, unsigned64 *frt, unsigned64 fra, unsigned64 frb, int single
+ if (FPSCR & fpscr_ze) {
+ /* zero-divide exception enabled */
+ /* FRT unchaged */
+ FPSCR_SET_FR(0);
+ FPSCR_SET_FI(0);
+ /* fpscr_FPRF unchanged */
+ }
+ else {
+ /* zero-divide exception disabled */
+ FPSCR_SET_FR(0);
+ FPSCR_SET_FI(0);
+ if ((sign (fra) < 0 && sign (frb) < 0)
+ || (sign (fra) > 0 && sign (frb) > 0)) {
+ *frt = MASK64 (1, 11); /* 0 : 2047 : 0..0 */
+ FPSCR_SET_FPRF(fpscr_rf_pos_infinity);
+ }
+ else {
+ *frt = MASK64 (0, 11); /* 1 : 2047 : 0..0 */
+ FPSCR_SET_FPRF(fpscr_rf_neg_infinity);
+ }
+ }
+
+
+
+
+
#
# 0.0.0.0 Illegal instruction used for kernel mode emulation
#
***************
*** 3758,3763 ****
--- 3798,3810 ----
0, /*instruction_is_convert_to_32bit*/
0); /*single-precision*/
}
+ else if (is_invalid_zero_divide (processor, cia,
+ *frA, *frB,
+ 0 /*single?*/)) {
+ invalid_zero_divide_operation (processor, cia,
+ frT, *frA, *frB,
+ 0 /*single?*/);
+ }
else {
/*HACK!*/
double s = *(double*)frA / *(double*)frB;
***************
*** 3783,3788 ****
--- 3830,3842 ----
0, /*instruction_is_convert_to_64bit*/
0, /*instruction_is_convert_to_32bit*/
1); /*single-precision*/
+ }
+ else if (is_invalid_zero_divide (processor, cia,
+ *frA, *frB,
+ 1 /*single?*/)) {
+ invalid_zero_divide_operation (processor, cia,
+ frT, *frA, *frB,
+ 1 /*single?*/);
}
else {
/*HACK!*/
More information about the Gdb-patches
mailing list