Patches contributed by Eötvös Lorand University
commit 3d0d14f983b55a570b976976284df4c434af3223
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Jan 30 13:30:11 2008 +0100
x86: lindent arch/i386/math-emu
lindent these files:
errors lines of code errors/KLOC
arch/x86/math-emu/ 2236 9424 237.2
arch/x86/math-emu/ 128 8706 14.7
no other changes. No code changed:
text data bss dec hex filename
5589802 612739 3833856 10036397 9924ad vmlinux.before
5589802 612739 3833856 10036397 9924ad vmlinux.after
the intent of this patch is to ease the automated tracking of kernel
code quality - it's just much easier for us to maintain it if every file
in arch/x86 is supposed to be clean.
NOTE: it is a known problem of lindent that it causes some style damage
of its own, but it's a safe tool (well, except for the gcc array range
initializers extension), so we did the bulk of the changes via lindent,
and did the manual fixups in a followup patch.
the resulting math-emu code has been tested by Thomas Gleixner on a real
386 DX CPU as well, and it works fine.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/arch/x86/math-emu/errors.c b/arch/x86/math-emu/errors.c
index a1b0d22f6978..7cb5bf3495b2 100644
--- a/arch/x86/math-emu/errors.c
+++ b/arch/x86/math-emu/errors.c
@@ -33,45 +33,41 @@
#undef PRINT_MESSAGES
/* */
-
#if 0
void Un_impl(void)
{
- u_char byte1, FPU_modrm;
- unsigned long address = FPU_ORIG_EIP;
-
- RE_ENTRANT_CHECK_OFF;
- /* No need to check access_ok(), we have previously fetched these bytes. */
- printk("Unimplemented FPU Opcode at eip=%p : ", (void __user *) address);
- if ( FPU_CS == __USER_CS )
- {
- while ( 1 )
- {
- FPU_get_user(byte1, (u_char __user *) address);
- if ( (byte1 & 0xf8) == 0xd8 ) break;
- printk("[%02x]", byte1);
- address++;
+ u_char byte1, FPU_modrm;
+ unsigned long address = FPU_ORIG_EIP;
+
+ RE_ENTRANT_CHECK_OFF;
+ /* No need to check access_ok(), we have previously fetched these bytes. */
+ printk("Unimplemented FPU Opcode at eip=%p : ", (void __user *)address);
+ if (FPU_CS == __USER_CS) {
+ while (1) {
+ FPU_get_user(byte1, (u_char __user *) address);
+ if ((byte1 & 0xf8) == 0xd8)
+ break;
+ printk("[%02x]", byte1);
+ address++;
+ }
+ printk("%02x ", byte1);
+ FPU_get_user(FPU_modrm, 1 + (u_char __user *) address);
+
+ if (FPU_modrm >= 0300)
+ printk("%02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8,
+ FPU_modrm & 7);
+ else
+ printk("/%d\n", (FPU_modrm >> 3) & 7);
+ } else {
+ printk("cs selector = %04x\n", FPU_CS);
}
- printk("%02x ", byte1);
- FPU_get_user(FPU_modrm, 1 + (u_char __user *) address);
-
- if (FPU_modrm >= 0300)
- printk("%02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
- else
- printk("/%d\n", (FPU_modrm >> 3) & 7);
- }
- else
- {
- printk("cs selector = %04x\n", FPU_CS);
- }
-
- RE_ENTRANT_CHECK_ON;
-
- EXCEPTION(EX_Invalid);
-}
-#endif /* 0 */
+ RE_ENTRANT_CHECK_ON;
+ EXCEPTION(EX_Invalid);
+
+}
+#endif /* 0 */
/*
Called for opcodes which are illegal and which are known to result in a
@@ -79,139 +75,152 @@ void Un_impl(void)
*/
void FPU_illegal(void)
{
- math_abort(FPU_info,SIGILL);
+ math_abort(FPU_info, SIGILL);
}
-
-
void FPU_printall(void)
{
- int i;
- static const char *tag_desc[] = { "Valid", "Zero", "ERROR", "Empty",
- "DeNorm", "Inf", "NaN" };
- u_char byte1, FPU_modrm;
- unsigned long address = FPU_ORIG_EIP;
-
- RE_ENTRANT_CHECK_OFF;
- /* No need to check access_ok(), we have previously fetched these bytes. */
- printk("At %p:", (void *) address);
- if ( FPU_CS == __USER_CS )
- {
+ int i;
+ static const char *tag_desc[] = { "Valid", "Zero", "ERROR", "Empty",
+ "DeNorm", "Inf", "NaN"
+ };
+ u_char byte1, FPU_modrm;
+ unsigned long address = FPU_ORIG_EIP;
+
+ RE_ENTRANT_CHECK_OFF;
+ /* No need to check access_ok(), we have previously fetched these bytes. */
+ printk("At %p:", (void *)address);
+ if (FPU_CS == __USER_CS) {
#define MAX_PRINTED_BYTES 20
- for ( i = 0; i < MAX_PRINTED_BYTES; i++ )
- {
- FPU_get_user(byte1, (u_char __user *) address);
- if ( (byte1 & 0xf8) == 0xd8 )
- {
- printk(" %02x", byte1);
- break;
- }
- printk(" [%02x]", byte1);
- address++;
- }
- if ( i == MAX_PRINTED_BYTES )
- printk(" [more..]\n");
- else
- {
- FPU_get_user(FPU_modrm, 1 + (u_char __user *) address);
-
- if (FPU_modrm >= 0300)
- printk(" %02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
- else
- printk(" /%d, mod=%d rm=%d\n",
- (FPU_modrm >> 3) & 7, (FPU_modrm >> 6) & 3, FPU_modrm & 7);
+ for (i = 0; i < MAX_PRINTED_BYTES; i++) {
+ FPU_get_user(byte1, (u_char __user *) address);
+ if ((byte1 & 0xf8) == 0xd8) {
+ printk(" %02x", byte1);
+ break;
+ }
+ printk(" [%02x]", byte1);
+ address++;
+ }
+ if (i == MAX_PRINTED_BYTES)
+ printk(" [more..]\n");
+ else {
+ FPU_get_user(FPU_modrm, 1 + (u_char __user *) address);
+
+ if (FPU_modrm >= 0300)
+ printk(" %02x (%02x+%d)\n", FPU_modrm,
+ FPU_modrm & 0xf8, FPU_modrm & 7);
+ else
+ printk(" /%d, mod=%d rm=%d\n",
+ (FPU_modrm >> 3) & 7,
+ (FPU_modrm >> 6) & 3, FPU_modrm & 7);
+ }
+ } else {
+ printk("%04x\n", FPU_CS);
}
- }
- else
- {
- printk("%04x\n", FPU_CS);
- }
- partial_status = status_word();
+ partial_status = status_word();
#ifdef DEBUGGING
-if ( partial_status & SW_Backward ) printk("SW: backward compatibility\n");
-if ( partial_status & SW_C3 ) printk("SW: condition bit 3\n");
-if ( partial_status & SW_C2 ) printk("SW: condition bit 2\n");
-if ( partial_status & SW_C1 ) printk("SW: condition bit 1\n");
-if ( partial_status & SW_C0 ) printk("SW: condition bit 0\n");
-if ( partial_status & SW_Summary ) printk("SW: exception summary\n");
-if ( partial_status & SW_Stack_Fault ) printk("SW: stack fault\n");
-if ( partial_status & SW_Precision ) printk("SW: loss of precision\n");
-if ( partial_status & SW_Underflow ) printk("SW: underflow\n");
-if ( partial_status & SW_Overflow ) printk("SW: overflow\n");
-if ( partial_status & SW_Zero_Div ) printk("SW: divide by zero\n");
-if ( partial_status & SW_Denorm_Op ) printk("SW: denormalized operand\n");
-if ( partial_status & SW_Invalid ) printk("SW: invalid operation\n");
+ if (partial_status & SW_Backward)
+ printk("SW: backward compatibility\n");
+ if (partial_status & SW_C3)
+ printk("SW: condition bit 3\n");
+ if (partial_status & SW_C2)
+ printk("SW: condition bit 2\n");
+ if (partial_status & SW_C1)
+ printk("SW: condition bit 1\n");
+ if (partial_status & SW_C0)
+ printk("SW: condition bit 0\n");
+ if (partial_status & SW_Summary)
+ printk("SW: exception summary\n");
+ if (partial_status & SW_Stack_Fault)
+ printk("SW: stack fault\n");
+ if (partial_status & SW_Precision)
+ printk("SW: loss of precision\n");
+ if (partial_status & SW_Underflow)
+ printk("SW: underflow\n");
+ if (partial_status & SW_Overflow)
+ printk("SW: overflow\n");
+ if (partial_status & SW_Zero_Div)
+ printk("SW: divide by zero\n");
+ if (partial_status & SW_Denorm_Op)
+ printk("SW: denormalized operand\n");
+ if (partial_status & SW_Invalid)
+ printk("SW: invalid operation\n");
#endif /* DEBUGGING */
- printk(" SW: b=%d st=%ld es=%d sf=%d cc=%d%d%d%d ef=%d%d%d%d%d%d\n",
- partial_status & 0x8000 ? 1 : 0, /* busy */
- (partial_status & 0x3800) >> 11, /* stack top pointer */
- partial_status & 0x80 ? 1 : 0, /* Error summary status */
- partial_status & 0x40 ? 1 : 0, /* Stack flag */
- partial_status & SW_C3?1:0, partial_status & SW_C2?1:0, /* cc */
- partial_status & SW_C1?1:0, partial_status & SW_C0?1:0, /* cc */
- partial_status & SW_Precision?1:0, partial_status & SW_Underflow?1:0,
- partial_status & SW_Overflow?1:0, partial_status & SW_Zero_Div?1:0,
- partial_status & SW_Denorm_Op?1:0, partial_status & SW_Invalid?1:0);
-
-printk(" CW: ic=%d rc=%ld%ld pc=%ld%ld iem=%d ef=%d%d%d%d%d%d\n",
- control_word & 0x1000 ? 1 : 0,
- (control_word & 0x800) >> 11, (control_word & 0x400) >> 10,
- (control_word & 0x200) >> 9, (control_word & 0x100) >> 8,
- control_word & 0x80 ? 1 : 0,
- control_word & SW_Precision?1:0, control_word & SW_Underflow?1:0,
- control_word & SW_Overflow?1:0, control_word & SW_Zero_Div?1:0,
- control_word & SW_Denorm_Op?1:0, control_word & SW_Invalid?1:0);
-
- for ( i = 0; i < 8; i++ )
- {
- FPU_REG *r = &st(i);
- u_char tagi = FPU_gettagi(i);
- switch (tagi)
- {
- case TAG_Empty:
- continue;
- break;
- case TAG_Zero:
- case TAG_Special:
- tagi = FPU_Special(r);
- case TAG_Valid:
- printk("st(%d) %c .%04lx %04lx %04lx %04lx e%+-6d ", i,
- getsign(r) ? '-' : '+',
- (long)(r->sigh >> 16),
- (long)(r->sigh & 0xFFFF),
- (long)(r->sigl >> 16),
- (long)(r->sigl & 0xFFFF),
- exponent(r) - EXP_BIAS + 1);
- break;
- default:
- printk("Whoops! Error in errors.c: tag%d is %d ", i, tagi);
- continue;
- break;
+ printk(" SW: b=%d st=%ld es=%d sf=%d cc=%d%d%d%d ef=%d%d%d%d%d%d\n", partial_status & 0x8000 ? 1 : 0, /* busy */
+ (partial_status & 0x3800) >> 11, /* stack top pointer */
+ partial_status & 0x80 ? 1 : 0, /* Error summary status */
+ partial_status & 0x40 ? 1 : 0, /* Stack flag */
+ partial_status & SW_C3 ? 1 : 0, partial_status & SW_C2 ? 1 : 0, /* cc */
+ partial_status & SW_C1 ? 1 : 0, partial_status & SW_C0 ? 1 : 0, /* cc */
+ partial_status & SW_Precision ? 1 : 0,
+ partial_status & SW_Underflow ? 1 : 0,
+ partial_status & SW_Overflow ? 1 : 0,
+ partial_status & SW_Zero_Div ? 1 : 0,
+ partial_status & SW_Denorm_Op ? 1 : 0,
+ partial_status & SW_Invalid ? 1 : 0);
+
+ printk(" CW: ic=%d rc=%ld%ld pc=%ld%ld iem=%d ef=%d%d%d%d%d%d\n",
+ control_word & 0x1000 ? 1 : 0,
+ (control_word & 0x800) >> 11, (control_word & 0x400) >> 10,
+ (control_word & 0x200) >> 9, (control_word & 0x100) >> 8,
+ control_word & 0x80 ? 1 : 0,
+ control_word & SW_Precision ? 1 : 0,
+ control_word & SW_Underflow ? 1 : 0,
+ control_word & SW_Overflow ? 1 : 0,
+ control_word & SW_Zero_Div ? 1 : 0,
+ control_word & SW_Denorm_Op ? 1 : 0,
+ control_word & SW_Invalid ? 1 : 0);
+
+ for (i = 0; i < 8; i++) {
+ FPU_REG *r = &st(i);
+ u_char tagi = FPU_gettagi(i);
+ switch (tagi) {
+ case TAG_Empty:
+ continue;
+ break;
+ case TAG_Zero:
+ case TAG_Special:
+ tagi = FPU_Special(r);
+ case TAG_Valid:
+ printk("st(%d) %c .%04lx %04lx %04lx %04lx e%+-6d ", i,
+ getsign(r) ? '-' : '+',
+ (long)(r->sigh >> 16),
+ (long)(r->sigh & 0xFFFF),
+ (long)(r->sigl >> 16),
+ (long)(r->sigl & 0xFFFF),
+ exponent(r) - EXP_BIAS + 1);
+ break;
+ default:
+ printk("Whoops! Error in errors.c: tag%d is %d ", i,
+ tagi);
+ continue;
+ break;
+ }
+ printk("%s\n", tag_desc[(int)(unsigned)tagi]);
}
- printk("%s\n", tag_desc[(int) (unsigned) tagi]);
- }
- RE_ENTRANT_CHECK_ON;
+ RE_ENTRANT_CHECK_ON;
}
static struct {
- int type;
- const char *name;
+ int type;
+ const char *name;
} exception_names[] = {
- { EX_StackOver, "stack overflow" },
- { EX_StackUnder, "stack underflow" },
- { EX_Precision, "loss of precision" },
- { EX_Underflow, "underflow" },
- { EX_Overflow, "overflow" },
- { EX_ZeroDiv, "divide by zero" },
- { EX_Denormal, "denormalized operand" },
- { EX_Invalid, "invalid operation" },
- { EX_INTERNAL, "INTERNAL BUG in "FPU_VERSION },
- { 0, NULL }
+ {
+ EX_StackOver, "stack overflow"}, {
+ EX_StackUnder, "stack underflow"}, {
+ EX_Precision, "loss of precision"}, {
+ EX_Underflow, "underflow"}, {
+ EX_Overflow, "overflow"}, {
+ EX_ZeroDiv, "divide by zero"}, {
+ EX_Denormal, "denormalized operand"}, {
+ EX_Invalid, "invalid operation"}, {
+ EX_INTERNAL, "INTERNAL BUG in " FPU_VERSION}, {
+ 0, NULL}
};
/*
@@ -295,445 +304,386 @@ static struct {
asmlinkage void FPU_exception(int n)
{
- int i, int_type;
-
- int_type = 0; /* Needed only to stop compiler warnings */
- if ( n & EX_INTERNAL )
- {
- int_type = n - EX_INTERNAL;
- n = EX_INTERNAL;
- /* Set lots of exception bits! */
- partial_status |= (SW_Exc_Mask | SW_Summary | SW_Backward);
- }
- else
- {
- /* Extract only the bits which we use to set the status word */
- n &= (SW_Exc_Mask);
- /* Set the corresponding exception bit */
- partial_status |= n;
- /* Set summary bits iff exception isn't masked */
- if ( partial_status & ~control_word & CW_Exceptions )
- partial_status |= (SW_Summary | SW_Backward);
- if ( n & (SW_Stack_Fault | EX_Precision) )
- {
- if ( !(n & SW_C1) )
- /* This bit distinguishes over- from underflow for a stack fault,
- and roundup from round-down for precision loss. */
- partial_status &= ~SW_C1;
+ int i, int_type;
+
+ int_type = 0; /* Needed only to stop compiler warnings */
+ if (n & EX_INTERNAL) {
+ int_type = n - EX_INTERNAL;
+ n = EX_INTERNAL;
+ /* Set lots of exception bits! */
+ partial_status |= (SW_Exc_Mask | SW_Summary | SW_Backward);
+ } else {
+ /* Extract only the bits which we use to set the status word */
+ n &= (SW_Exc_Mask);
+ /* Set the corresponding exception bit */
+ partial_status |= n;
+ /* Set summary bits iff exception isn't masked */
+ if (partial_status & ~control_word & CW_Exceptions)
+ partial_status |= (SW_Summary | SW_Backward);
+ if (n & (SW_Stack_Fault | EX_Precision)) {
+ if (!(n & SW_C1))
+ /* This bit distinguishes over- from underflow for a stack fault,
+ and roundup from round-down for precision loss. */
+ partial_status &= ~SW_C1;
+ }
}
- }
- RE_ENTRANT_CHECK_OFF;
- if ( (~control_word & n & CW_Exceptions) || (n == EX_INTERNAL) )
- {
+ RE_ENTRANT_CHECK_OFF;
+ if ((~control_word & n & CW_Exceptions) || (n == EX_INTERNAL)) {
#ifdef PRINT_MESSAGES
- /* My message from the sponsor */
- printk(FPU_VERSION" "__DATE__" (C) W. Metzenthen.\n");
+ /* My message from the sponsor */
+ printk(FPU_VERSION " " __DATE__ " (C) W. Metzenthen.\n");
#endif /* PRINT_MESSAGES */
-
- /* Get a name string for error reporting */
- for (i=0; exception_names[i].type; i++)
- if ( (exception_names[i].type & n) == exception_names[i].type )
- break;
-
- if (exception_names[i].type)
- {
+
+ /* Get a name string for error reporting */
+ for (i = 0; exception_names[i].type; i++)
+ if ((exception_names[i].type & n) ==
+ exception_names[i].type)
+ break;
+
+ if (exception_names[i].type) {
#ifdef PRINT_MESSAGES
- printk("FP Exception: %s!\n", exception_names[i].name);
+ printk("FP Exception: %s!\n", exception_names[i].name);
#endif /* PRINT_MESSAGES */
- }
- else
- printk("FPU emulator: Unknown Exception: 0x%04x!\n", n);
-
- if ( n == EX_INTERNAL )
- {
- printk("FPU emulator: Internal error type 0x%04x\n", int_type);
- FPU_printall();
- }
+ } else
+ printk("FPU emulator: Unknown Exception: 0x%04x!\n", n);
+
+ if (n == EX_INTERNAL) {
+ printk("FPU emulator: Internal error type 0x%04x\n",
+ int_type);
+ FPU_printall();
+ }
#ifdef PRINT_MESSAGES
- else
- FPU_printall();
+ else
+ FPU_printall();
#endif /* PRINT_MESSAGES */
- /*
- * The 80486 generates an interrupt on the next non-control FPU
- * instruction. So we need some means of flagging it.
- * We use the ES (Error Summary) bit for this.
- */
- }
- RE_ENTRANT_CHECK_ON;
+ /*
+ * The 80486 generates an interrupt on the next non-control FPU
+ * instruction. So we need some means of flagging it.
+ * We use the ES (Error Summary) bit for this.
+ */
+ }
+ RE_ENTRANT_CHECK_ON;
#ifdef __DEBUG__
- math_abort(FPU_info,SIGFPE);
+ math_abort(FPU_info, SIGFPE);
#endif /* __DEBUG__ */
}
-
/* Real operation attempted on a NaN. */
/* Returns < 0 if the exception is unmasked */
-int real_1op_NaN(FPU_REG *a)
+int real_1op_NaN(FPU_REG * a)
{
- int signalling, isNaN;
-
- isNaN = (exponent(a) == EXP_OVER) && (a->sigh & 0x80000000);
-
- /* The default result for the case of two "equal" NaNs (signs may
- differ) is chosen to reproduce 80486 behaviour */
- signalling = isNaN && !(a->sigh & 0x40000000);
-
- if ( !signalling )
- {
- if ( !isNaN ) /* pseudo-NaN, or other unsupported? */
- {
- if ( control_word & CW_Invalid )
- {
- /* Masked response */
- reg_copy(&CONST_QNaN, a);
- }
- EXCEPTION(EX_Invalid);
- return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;
+ int signalling, isNaN;
+
+ isNaN = (exponent(a) == EXP_OVER) && (a->sigh & 0x80000000);
+
+ /* The default result for the case of two "equal" NaNs (signs may
+ differ) is chosen to reproduce 80486 behaviour */
+ signalling = isNaN && !(a->sigh & 0x40000000);
+
+ if (!signalling) {
+ if (!isNaN) { /* pseudo-NaN, or other unsupported? */
+ if (control_word & CW_Invalid) {
+ /* Masked response */
+ reg_copy(&CONST_QNaN, a);
+ }
+ EXCEPTION(EX_Invalid);
+ return (!(control_word & CW_Invalid) ? FPU_Exception :
+ 0) | TAG_Special;
+ }
+ return TAG_Special;
}
- return TAG_Special;
- }
- if ( control_word & CW_Invalid )
- {
- /* The masked response */
- if ( !(a->sigh & 0x80000000) ) /* pseudo-NaN ? */
- {
- reg_copy(&CONST_QNaN, a);
+ if (control_word & CW_Invalid) {
+ /* The masked response */
+ if (!(a->sigh & 0x80000000)) { /* pseudo-NaN ? */
+ reg_copy(&CONST_QNaN, a);
+ }
+ /* ensure a Quiet NaN */
+ a->sigh |= 0x40000000;
}
- /* ensure a Quiet NaN */
- a->sigh |= 0x40000000;
- }
- EXCEPTION(EX_Invalid);
+ EXCEPTION(EX_Invalid);
- return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;
+ return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;
}
-
/* Real operation attempted on two operands, one a NaN. */
/* Returns < 0 if the exception is unmasked */
int real_2op_NaN(FPU_REG const *b, u_char tagb,
- int deststnr,
- FPU_REG const *defaultNaN)
+ int deststnr, FPU_REG const *defaultNaN)
{
- FPU_REG *dest = &st(deststnr);
- FPU_REG const *a = dest;
- u_char taga = FPU_gettagi(deststnr);
- FPU_REG const *x;
- int signalling, unsupported;
-
- if ( taga == TAG_Special )
- taga = FPU_Special(a);
- if ( tagb == TAG_Special )
- tagb = FPU_Special(b);
-
- /* TW_NaN is also used for unsupported data types. */
- unsupported = ((taga == TW_NaN)
- && !((exponent(a) == EXP_OVER) && (a->sigh & 0x80000000)))
- || ((tagb == TW_NaN)
- && !((exponent(b) == EXP_OVER) && (b->sigh & 0x80000000)));
- if ( unsupported )
- {
- if ( control_word & CW_Invalid )
- {
- /* Masked response */
- FPU_copy_to_regi(&CONST_QNaN, TAG_Special, deststnr);
- }
- EXCEPTION(EX_Invalid);
- return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;
- }
-
- if (taga == TW_NaN)
- {
- x = a;
- if (tagb == TW_NaN)
- {
- signalling = !(a->sigh & b->sigh & 0x40000000);
- if ( significand(b) > significand(a) )
- x = b;
- else if ( significand(b) == significand(a) )
- {
- /* The default result for the case of two "equal" NaNs (signs may
- differ) is chosen to reproduce 80486 behaviour */
- x = defaultNaN;
- }
- }
- else
- {
- /* return the quiet version of the NaN in a */
- signalling = !(a->sigh & 0x40000000);
+ FPU_REG *dest = &st(deststnr);
+ FPU_REG const *a = dest;
+ u_char taga = FPU_gettagi(deststnr);
+ FPU_REG const *x;
+ int signalling, unsupported;
+
+ if (taga == TAG_Special)
+ taga = FPU_Special(a);
+ if (tagb == TAG_Special)
+ tagb = FPU_Special(b);
+
+ /* TW_NaN is also used for unsupported data types. */
+ unsupported = ((taga == TW_NaN)
+ && !((exponent(a) == EXP_OVER)
+ && (a->sigh & 0x80000000)))
+ || ((tagb == TW_NaN)
+ && !((exponent(b) == EXP_OVER) && (b->sigh & 0x80000000)));
+ if (unsupported) {
+ if (control_word & CW_Invalid) {
+ /* Masked response */
+ FPU_copy_to_regi(&CONST_QNaN, TAG_Special, deststnr);
+ }
+ EXCEPTION(EX_Invalid);
+ return (!(control_word & CW_Invalid) ? FPU_Exception : 0) |
+ TAG_Special;
}
- }
- else
+
+ if (taga == TW_NaN) {
+ x = a;
+ if (tagb == TW_NaN) {
+ signalling = !(a->sigh & b->sigh & 0x40000000);
+ if (significand(b) > significand(a))
+ x = b;
+ else if (significand(b) == significand(a)) {
+ /* The default result for the case of two "equal" NaNs (signs may
+ differ) is chosen to reproduce 80486 behaviour */
+ x = defaultNaN;
+ }
+ } else {
+ /* return the quiet version of the NaN in a */
+ signalling = !(a->sigh & 0x40000000);
+ }
+ } else
#ifdef PARANOID
- if (tagb == TW_NaN)
+ if (tagb == TW_NaN)
#endif /* PARANOID */
- {
- signalling = !(b->sigh & 0x40000000);
- x = b;
- }
+ {
+ signalling = !(b->sigh & 0x40000000);
+ x = b;
+ }
#ifdef PARANOID
- else
- {
- signalling = 0;
- EXCEPTION(EX_INTERNAL|0x113);
- x = &CONST_QNaN;
- }
+ else {
+ signalling = 0;
+ EXCEPTION(EX_INTERNAL | 0x113);
+ x = &CONST_QNaN;
+ }
#endif /* PARANOID */
- if ( (!signalling) || (control_word & CW_Invalid) )
- {
- if ( ! x )
- x = b;
+ if ((!signalling) || (control_word & CW_Invalid)) {
+ if (!x)
+ x = b;
- if ( !(x->sigh & 0x80000000) ) /* pseudo-NaN ? */
- x = &CONST_QNaN;
+ if (!(x->sigh & 0x80000000)) /* pseudo-NaN ? */
+ x = &CONST_QNaN;
- FPU_copy_to_regi(x, TAG_Special, deststnr);
+ FPU_copy_to_regi(x, TAG_Special, deststnr);
- if ( !signalling )
- return TAG_Special;
+ if (!signalling)
+ return TAG_Special;
- /* ensure a Quiet NaN */
- dest->sigh |= 0x40000000;
- }
+ /* ensure a Quiet NaN */
+ dest->sigh |= 0x40000000;
+ }
- EXCEPTION(EX_Invalid);
+ EXCEPTION(EX_Invalid);
- return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;
+ return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;
}
-
/* Invalid arith operation on Valid registers */
/* Returns < 0 if the exception is unmasked */
asmlinkage int arith_invalid(int deststnr)
{
- EXCEPTION(EX_Invalid);
-
- if ( control_word & CW_Invalid )
- {
- /* The masked response */
- FPU_copy_to_regi(&CONST_QNaN, TAG_Special, deststnr);
- }
-
- return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Valid;
+ EXCEPTION(EX_Invalid);
-}
+ if (control_word & CW_Invalid) {
+ /* The masked response */
+ FPU_copy_to_regi(&CONST_QNaN, TAG_Special, deststnr);
+ }
+ return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Valid;
+
+}
/* Divide a finite number by zero */
asmlinkage int FPU_divide_by_zero(int deststnr, u_char sign)
{
- FPU_REG *dest = &st(deststnr);
- int tag = TAG_Valid;
+ FPU_REG *dest = &st(deststnr);
+ int tag = TAG_Valid;
+
+ if (control_word & CW_ZeroDiv) {
+ /* The masked response */
+ FPU_copy_to_regi(&CONST_INF, TAG_Special, deststnr);
+ setsign(dest, sign);
+ tag = TAG_Special;
+ }
- if ( control_word & CW_ZeroDiv )
- {
- /* The masked response */
- FPU_copy_to_regi(&CONST_INF, TAG_Special, deststnr);
- setsign(dest, sign);
- tag = TAG_Special;
- }
-
- EXCEPTION(EX_ZeroDiv);
+ EXCEPTION(EX_ZeroDiv);
- return (!(control_word & CW_ZeroDiv) ? FPU_Exception : 0) | tag;
+ return (!(control_word & CW_ZeroDiv) ? FPU_Exception : 0) | tag;
}
-
/* This may be called often, so keep it lean */
int set_precision_flag(int flags)
{
- if ( control_word & CW_Precision )
- {
- partial_status &= ~(SW_C1 & flags);
- partial_status |= flags; /* The masked response */
- return 0;
- }
- else
- {
- EXCEPTION(flags);
- return 1;
- }
+ if (control_word & CW_Precision) {
+ partial_status &= ~(SW_C1 & flags);
+ partial_status |= flags; /* The masked response */
+ return 0;
+ } else {
+ EXCEPTION(flags);
+ return 1;
+ }
}
-
/* This may be called often, so keep it lean */
asmlinkage void set_precision_flag_up(void)
{
- if ( control_word & CW_Precision )
- partial_status |= (SW_Precision | SW_C1); /* The masked response */
- else
- EXCEPTION(EX_Precision | SW_C1);
+ if (control_word & CW_Precision)
+ partial_status |= (SW_Precision | SW_C1); /* The masked response */
+ else
+ EXCEPTION(EX_Precision | SW_C1);
}
-
/* This may be called often, so keep it lean */
asmlinkage void set_precision_flag_down(void)
{
- if ( control_word & CW_Precision )
- { /* The masked response */
- partial_status &= ~SW_C1;
- partial_status |= SW_Precision;
- }
- else
- EXCEPTION(EX_Precision);
+ if (control_word & CW_Precision) { /* The masked response */
+ partial_status &= ~SW_C1;
+ partial_status |= SW_Precision;
+ } else
+ EXCEPTION(EX_Precision);
}
-
asmlinkage int denormal_operand(void)
{
- if ( control_word & CW_Denormal )
- { /* The masked response */
- partial_status |= SW_Denorm_Op;
- return TAG_Special;
- }
- else
- {
- EXCEPTION(EX_Denormal);
- return TAG_Special | FPU_Exception;
- }
+ if (control_word & CW_Denormal) { /* The masked response */
+ partial_status |= SW_Denorm_Op;
+ return TAG_Special;
+ } else {
+ EXCEPTION(EX_Denormal);
+ return TAG_Special | FPU_Exception;
+ }
}
-
-asmlinkage int arith_overflow(FPU_REG *dest)
+asmlinkage int arith_overflow(FPU_REG * dest)
{
- int tag = TAG_Valid;
+ int tag = TAG_Valid;
- if ( control_word & CW_Overflow )
- {
- /* The masked response */
+ if (control_word & CW_Overflow) {
+ /* The masked response */
/* ###### The response here depends upon the rounding mode */
- reg_copy(&CONST_INF, dest);
- tag = TAG_Special;
- }
- else
- {
- /* Subtract the magic number from the exponent */
- addexponent(dest, (-3 * (1 << 13)));
- }
-
- EXCEPTION(EX_Overflow);
- if ( control_word & CW_Overflow )
- {
- /* The overflow exception is masked. */
- /* By definition, precision is lost.
- The roundup bit (C1) is also set because we have
- "rounded" upwards to Infinity. */
- EXCEPTION(EX_Precision | SW_C1);
- return tag;
- }
-
- return tag;
+ reg_copy(&CONST_INF, dest);
+ tag = TAG_Special;
+ } else {
+ /* Subtract the magic number from the exponent */
+ addexponent(dest, (-3 * (1 << 13)));
+ }
-}
+ EXCEPTION(EX_Overflow);
+ if (control_word & CW_Overflow) {
+ /* The overflow exception is masked. */
+ /* By definition, precision is lost.
+ The roundup bit (C1) is also set because we have
+ "rounded" upwards to Infinity. */
+ EXCEPTION(EX_Precision | SW_C1);
+ return tag;
+ }
+ return tag;
-asmlinkage int arith_underflow(FPU_REG *dest)
-{
- int tag = TAG_Valid;
+}
- if ( control_word & CW_Underflow )
- {
- /* The masked response */
- if ( exponent16(dest) <= EXP_UNDER - 63 )
- {
- reg_copy(&CONST_Z, dest);
- partial_status &= ~SW_C1; /* Round down. */
- tag = TAG_Zero;
+asmlinkage int arith_underflow(FPU_REG * dest)
+{
+ int tag = TAG_Valid;
+
+ if (control_word & CW_Underflow) {
+ /* The masked response */
+ if (exponent16(dest) <= EXP_UNDER - 63) {
+ reg_copy(&CONST_Z, dest);
+ partial_status &= ~SW_C1; /* Round down. */
+ tag = TAG_Zero;
+ } else {
+ stdexp(dest);
+ }
+ } else {
+ /* Add the magic number to the exponent. */
+ addexponent(dest, (3 * (1 << 13)) + EXTENDED_Ebias);
}
- else
- {
- stdexp(dest);
+
+ EXCEPTION(EX_Underflow);
+ if (control_word & CW_Underflow) {
+ /* The underflow exception is masked. */
+ EXCEPTION(EX_Precision);
+ return tag;
}
- }
- else
- {
- /* Add the magic number to the exponent. */
- addexponent(dest, (3 * (1 << 13)) + EXTENDED_Ebias);
- }
-
- EXCEPTION(EX_Underflow);
- if ( control_word & CW_Underflow )
- {
- /* The underflow exception is masked. */
- EXCEPTION(EX_Precision);
- return tag;
- }
-
- return tag;
-}
+ return tag;
+}
void FPU_stack_overflow(void)
{
- if ( control_word & CW_Invalid )
- {
- /* The masked response */
- top--;
- FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
- }
+ if (control_word & CW_Invalid) {
+ /* The masked response */
+ top--;
+ FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
+ }
- EXCEPTION(EX_StackOver);
+ EXCEPTION(EX_StackOver);
- return;
+ return;
}
-
void FPU_stack_underflow(void)
{
- if ( control_word & CW_Invalid )
- {
- /* The masked response */
- FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
- }
+ if (control_word & CW_Invalid) {
+ /* The masked response */
+ FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
+ }
- EXCEPTION(EX_StackUnder);
+ EXCEPTION(EX_StackUnder);
- return;
+ return;
}
-
void FPU_stack_underflow_i(int i)
{
- if ( control_word & CW_Invalid )
- {
- /* The masked response */
- FPU_copy_to_regi(&CONST_QNaN, TAG_Special, i);
- }
+ if (control_word & CW_Invalid) {
+ /* The masked response */
+ FPU_copy_to_regi(&CONST_QNaN, TAG_Special, i);
+ }
- EXCEPTION(EX_StackUnder);
+ EXCEPTION(EX_StackUnder);
- return;
+ return;
}
-
void FPU_stack_underflow_pop(int i)
{
- if ( control_word & CW_Invalid )
- {
- /* The masked response */
- FPU_copy_to_regi(&CONST_QNaN, TAG_Special, i);
- FPU_pop();
- }
+ if (control_word & CW_Invalid) {
+ /* The masked response */
+ FPU_copy_to_regi(&CONST_QNaN, TAG_Special, i);
+ FPU_pop();
+ }
- EXCEPTION(EX_StackUnder);
+ EXCEPTION(EX_StackUnder);
- return;
+ return;
}
-
diff --git a/arch/x86/math-emu/exception.h b/arch/x86/math-emu/exception.h
index b463f21a811e..67f43a4683d5 100644
--- a/arch/x86/math-emu/exception.h
+++ b/arch/x86/math-emu/exception.h
@@ -9,7 +9,6 @@
#ifndef _EXCEPTION_H_
#define _EXCEPTION_H_
-
#ifdef __ASSEMBLY__
#define Const_(x) $##x
#else
@@ -20,8 +19,8 @@
#include "fpu_emu.h"
#endif /* SW_C1 */
-#define FPU_BUSY Const_(0x8000) /* FPU busy bit (8087 compatibility) */
-#define EX_ErrorSummary Const_(0x0080) /* Error summary status */
+#define FPU_BUSY Const_(0x8000) /* FPU busy bit (8087 compatibility) */
+#define EX_ErrorSummary Const_(0x0080) /* Error summary status */
/* Special exceptions: */
#define EX_INTERNAL Const_(0x8000) /* Internal error in wm-FPU-emu */
#define EX_StackOver Const_(0x0041|SW_C1) /* stack overflow */
@@ -34,11 +33,9 @@
#define EX_Denormal Const_(0x0002) /* denormalized operand */
#define EX_Invalid Const_(0x0001) /* invalid operation */
-
#define PRECISION_LOST_UP Const_((EX_Precision | SW_C1))
#define PRECISION_LOST_DOWN Const_(EX_Precision)
-
#ifndef __ASSEMBLY__
#ifdef DEBUG
@@ -48,6 +45,6 @@
#define EXCEPTION(x) FPU_exception(x)
#endif
-#endif /* __ASSEMBLY__ */
+#endif /* __ASSEMBLY__ */
#endif /* _EXCEPTION_H_ */
diff --git a/arch/x86/math-emu/fpu_arith.c b/arch/x86/math-emu/fpu_arith.c
index 6972dec01af6..aeab24e083c4 100644
--- a/arch/x86/math-emu/fpu_arith.c
+++ b/arch/x86/math-emu/fpu_arith.c
@@ -15,160 +15,138 @@
#include "control_w.h"
#include "status_w.h"
-
void fadd__(void)
{
- /* fadd st,st(i) */
- int i = FPU_rm;
- clear_C1();
- FPU_add(&st(i), FPU_gettagi(i), 0, control_word);
+ /* fadd st,st(i) */
+ int i = FPU_rm;
+ clear_C1();
+ FPU_add(&st(i), FPU_gettagi(i), 0, control_word);
}
-
void fmul__(void)
{
- /* fmul st,st(i) */
- int i = FPU_rm;
- clear_C1();
- FPU_mul(&st(i), FPU_gettagi(i), 0, control_word);
+ /* fmul st,st(i) */
+ int i = FPU_rm;
+ clear_C1();
+ FPU_mul(&st(i), FPU_gettagi(i), 0, control_word);
}
-
-
void fsub__(void)
{
- /* fsub st,st(i) */
- clear_C1();
- FPU_sub(0, FPU_rm, control_word);
+ /* fsub st,st(i) */
+ clear_C1();
+ FPU_sub(0, FPU_rm, control_word);
}
-
void fsubr_(void)
{
- /* fsubr st,st(i) */
- clear_C1();
- FPU_sub(REV, FPU_rm, control_word);
+ /* fsubr st,st(i) */
+ clear_C1();
+ FPU_sub(REV, FPU_rm, control_word);
}
-
void fdiv__(void)
{
- /* fdiv st,st(i) */
- clear_C1();
- FPU_div(0, FPU_rm, control_word);
+ /* fdiv st,st(i) */
+ clear_C1();
+ FPU_div(0, FPU_rm, control_word);
}
-
void fdivr_(void)
{
- /* fdivr st,st(i) */
- clear_C1();
- FPU_div(REV, FPU_rm, control_word);
+ /* fdivr st,st(i) */
+ clear_C1();
+ FPU_div(REV, FPU_rm, control_word);
}
-
-
void fadd_i(void)
{
- /* fadd st(i),st */
- int i = FPU_rm;
- clear_C1();
- FPU_add(&st(i), FPU_gettagi(i), i, control_word);
+ /* fadd st(i),st */
+ int i = FPU_rm;
+ clear_C1();
+ FPU_add(&st(i), FPU_gettagi(i), i, control_word);
}
-
void fmul_i(void)
{
- /* fmul st(i),st */
- clear_C1();
- FPU_mul(&st(0), FPU_gettag0(), FPU_rm, control_word);
+ /* fmul st(i),st */
+ clear_C1();
+ FPU_mul(&st(0), FPU_gettag0(), FPU_rm, control_word);
}
-
void fsubri(void)
{
- /* fsubr st(i),st */
- clear_C1();
- FPU_sub(DEST_RM, FPU_rm, control_word);
+ /* fsubr st(i),st */
+ clear_C1();
+ FPU_sub(DEST_RM, FPU_rm, control_word);
}
-
void fsub_i(void)
{
- /* fsub st(i),st */
- clear_C1();
- FPU_sub(REV|DEST_RM, FPU_rm, control_word);
+ /* fsub st(i),st */
+ clear_C1();
+ FPU_sub(REV | DEST_RM, FPU_rm, control_word);
}
-
void fdivri(void)
{
- /* fdivr st(i),st */
- clear_C1();
- FPU_div(DEST_RM, FPU_rm, control_word);
+ /* fdivr st(i),st */
+ clear_C1();
+ FPU_div(DEST_RM, FPU_rm, control_word);
}
-
void fdiv_i(void)
{
- /* fdiv st(i),st */
- clear_C1();
- FPU_div(REV|DEST_RM, FPU_rm, control_word);
+ /* fdiv st(i),st */
+ clear_C1();
+ FPU_div(REV | DEST_RM, FPU_rm, control_word);
}
-
-
void faddp_(void)
{
- /* faddp st(i),st */
- int i = FPU_rm;
- clear_C1();
- if ( FPU_add(&st(i), FPU_gettagi(i), i, control_word) >= 0 )
- FPU_pop();
+ /* faddp st(i),st */
+ int i = FPU_rm;
+ clear_C1();
+ if (FPU_add(&st(i), FPU_gettagi(i), i, control_word) >= 0)
+ FPU_pop();
}
-
void fmulp_(void)
{
- /* fmulp st(i),st */
- clear_C1();
- if ( FPU_mul(&st(0), FPU_gettag0(), FPU_rm, control_word) >= 0 )
- FPU_pop();
+ /* fmulp st(i),st */
+ clear_C1();
+ if (FPU_mul(&st(0), FPU_gettag0(), FPU_rm, control_word) >= 0)
+ FPU_pop();
}
-
-
void fsubrp(void)
{
- /* fsubrp st(i),st */
- clear_C1();
- if ( FPU_sub(DEST_RM, FPU_rm, control_word) >= 0 )
- FPU_pop();
+ /* fsubrp st(i),st */
+ clear_C1();
+ if (FPU_sub(DEST_RM, FPU_rm, control_word) >= 0)
+ FPU_pop();
}
-
void fsubp_(void)
{
- /* fsubp st(i),st */
- clear_C1();
- if ( FPU_sub(REV|DEST_RM, FPU_rm, control_word) >= 0 )
- FPU_pop();
+ /* fsubp st(i),st */
+ clear_C1();
+ if (FPU_sub(REV | DEST_RM, FPU_rm, control_word) >= 0)
+ FPU_pop();
}
-
void fdivrp(void)
{
- /* fdivrp st(i),st */
- clear_C1();
- if ( FPU_div(DEST_RM, FPU_rm, control_word) >= 0 )
- FPU_pop();
+ /* fdivrp st(i),st */
+ clear_C1();
+ if (FPU_div(DEST_RM, FPU_rm, control_word) >= 0)
+ FPU_pop();
}
-
void fdivp_(void)
{
- /* fdivp st(i),st */
- clear_C1();
- if ( FPU_div(REV|DEST_RM, FPU_rm, control_word) >= 0 )
- FPU_pop();
+ /* fdivp st(i),st */
+ clear_C1();
+ if (FPU_div(REV | DEST_RM, FPU_rm, control_word) >= 0)
+ FPU_pop();
}
diff --git a/arch/x86/math-emu/fpu_asm.h b/arch/x86/math-emu/fpu_asm.h
index 9ba12416df12..955b932735a4 100644
--- a/arch/x86/math-emu/fpu_asm.h
+++ b/arch/x86/math-emu/fpu_asm.h
@@ -14,7 +14,6 @@
#define EXCEPTION FPU_exception
-
#define PARAM1 8(%ebp)
#define PARAM2 12(%ebp)
#define PARAM3 16(%ebp)
diff --git a/arch/x86/math-emu/fpu_aux.c b/arch/x86/math-emu/fpu_aux.c
index 20886cfb9f76..491e737ce547 100644
--- a/arch/x86/math-emu/fpu_aux.c
+++ b/arch/x86/math-emu/fpu_aux.c
@@ -16,34 +16,34 @@
#include "status_w.h"
#include "control_w.h"
-
static void fnop(void)
{
}
static void fclex(void)
{
- partial_status &= ~(SW_Backward|SW_Summary|SW_Stack_Fault|SW_Precision|
- SW_Underflow|SW_Overflow|SW_Zero_Div|SW_Denorm_Op|
- SW_Invalid);
- no_ip_update = 1;
+ partial_status &=
+ ~(SW_Backward | SW_Summary | SW_Stack_Fault | SW_Precision |
+ SW_Underflow | SW_Overflow | SW_Zero_Div | SW_Denorm_Op |
+ SW_Invalid);
+ no_ip_update = 1;
}
/* Needs to be externally visible */
void finit(void)
{
- control_word = 0x037f;
- partial_status = 0;
- top = 0; /* We don't keep top in the status word internally. */
- fpu_tag_word = 0xffff;
- /* The behaviour is different from that detailed in
- Section 15.1.6 of the Intel manual */
- operand_address.offset = 0;
- operand_address.selector = 0;
- instruction_address.offset = 0;
- instruction_address.selector = 0;
- instruction_address.opcode = 0;
- no_ip_update = 1;
+ control_word = 0x037f;
+ partial_status = 0;
+ top = 0; /* We don't keep top in the status word internally. */
+ fpu_tag_word = 0xffff;
+ /* The behaviour is different from that detailed in
+ Section 15.1.6 of the Intel manual */
+ operand_address.offset = 0;
+ operand_address.selector = 0;
+ instruction_address.offset = 0;
+ instruction_address.selector = 0;
+ instruction_address.opcode = 0;
+ no_ip_update = 1;
}
/*
@@ -54,151 +54,134 @@ void finit(void)
#define fsetpm fnop
static FUNC const finit_table[] = {
- feni, fdisi, fclex, finit,
- fsetpm, FPU_illegal, FPU_illegal, FPU_illegal
+ feni, fdisi, fclex, finit,
+ fsetpm, FPU_illegal, FPU_illegal, FPU_illegal
};
void finit_(void)
{
- (finit_table[FPU_rm])();
+ (finit_table[FPU_rm]) ();
}
-
static void fstsw_ax(void)
{
- *(short *) &FPU_EAX = status_word();
- no_ip_update = 1;
+ *(short *)&FPU_EAX = status_word();
+ no_ip_update = 1;
}
static FUNC const fstsw_table[] = {
- fstsw_ax, FPU_illegal, FPU_illegal, FPU_illegal,
- FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
+ fstsw_ax, FPU_illegal, FPU_illegal, FPU_illegal,
+ FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
};
void fstsw_(void)
{
- (fstsw_table[FPU_rm])();
+ (fstsw_table[FPU_rm]) ();
}
-
static FUNC const fp_nop_table[] = {
- fnop, FPU_illegal, FPU_illegal, FPU_illegal,
- FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
+ fnop, FPU_illegal, FPU_illegal, FPU_illegal,
+ FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
};
void fp_nop(void)
{
- (fp_nop_table[FPU_rm])();
+ (fp_nop_table[FPU_rm]) ();
}
-
void fld_i_(void)
{
- FPU_REG *st_new_ptr;
- int i;
- u_char tag;
-
- if ( STACK_OVERFLOW )
- { FPU_stack_overflow(); return; }
-
- /* fld st(i) */
- i = FPU_rm;
- if ( NOT_EMPTY(i) )
- {
- reg_copy(&st(i), st_new_ptr);
- tag = FPU_gettagi(i);
- push();
- FPU_settag0(tag);
- }
- else
- {
- if ( control_word & CW_Invalid )
- {
- /* The masked response */
- FPU_stack_underflow();
+ FPU_REG *st_new_ptr;
+ int i;
+ u_char tag;
+
+ if (STACK_OVERFLOW) {
+ FPU_stack_overflow();
+ return;
}
- else
- EXCEPTION(EX_StackUnder);
- }
-}
+ /* fld st(i) */
+ i = FPU_rm;
+ if (NOT_EMPTY(i)) {
+ reg_copy(&st(i), st_new_ptr);
+ tag = FPU_gettagi(i);
+ push();
+ FPU_settag0(tag);
+ } else {
+ if (control_word & CW_Invalid) {
+ /* The masked response */
+ FPU_stack_underflow();
+ } else
+ EXCEPTION(EX_StackUnder);
+ }
+}
void fxch_i(void)
{
- /* fxch st(i) */
- FPU_REG t;
- int i = FPU_rm;
- FPU_REG *st0_ptr = &st(0), *sti_ptr = &st(i);
- long tag_word = fpu_tag_word;
- int regnr = top & 7, regnri = ((regnr + i) & 7);
- u_char st0_tag = (tag_word >> (regnr*2)) & 3;
- u_char sti_tag = (tag_word >> (regnri*2)) & 3;
-
- if ( st0_tag == TAG_Empty )
- {
- if ( sti_tag == TAG_Empty )
- {
- FPU_stack_underflow();
- FPU_stack_underflow_i(i);
- return;
+ /* fxch st(i) */
+ FPU_REG t;
+ int i = FPU_rm;
+ FPU_REG *st0_ptr = &st(0), *sti_ptr = &st(i);
+ long tag_word = fpu_tag_word;
+ int regnr = top & 7, regnri = ((regnr + i) & 7);
+ u_char st0_tag = (tag_word >> (regnr * 2)) & 3;
+ u_char sti_tag = (tag_word >> (regnri * 2)) & 3;
+
+ if (st0_tag == TAG_Empty) {
+ if (sti_tag == TAG_Empty) {
+ FPU_stack_underflow();
+ FPU_stack_underflow_i(i);
+ return;
+ }
+ if (control_word & CW_Invalid) {
+ /* Masked response */
+ FPU_copy_to_reg0(sti_ptr, sti_tag);
+ }
+ FPU_stack_underflow_i(i);
+ return;
}
- if ( control_word & CW_Invalid )
- {
- /* Masked response */
- FPU_copy_to_reg0(sti_ptr, sti_tag);
+ if (sti_tag == TAG_Empty) {
+ if (control_word & CW_Invalid) {
+ /* Masked response */
+ FPU_copy_to_regi(st0_ptr, st0_tag, i);
+ }
+ FPU_stack_underflow();
+ return;
}
- FPU_stack_underflow_i(i);
- return;
- }
- if ( sti_tag == TAG_Empty )
- {
- if ( control_word & CW_Invalid )
- {
- /* Masked response */
- FPU_copy_to_regi(st0_ptr, st0_tag, i);
- }
- FPU_stack_underflow();
- return;
- }
- clear_C1();
-
- reg_copy(st0_ptr, &t);
- reg_copy(sti_ptr, st0_ptr);
- reg_copy(&t, sti_ptr);
-
- tag_word &= ~(3 << (regnr*2)) & ~(3 << (regnri*2));
- tag_word |= (sti_tag << (regnr*2)) | (st0_tag << (regnri*2));
- fpu_tag_word = tag_word;
-}
+ clear_C1();
+ reg_copy(st0_ptr, &t);
+ reg_copy(sti_ptr, st0_ptr);
+ reg_copy(&t, sti_ptr);
+
+ tag_word &= ~(3 << (regnr * 2)) & ~(3 << (regnri * 2));
+ tag_word |= (sti_tag << (regnr * 2)) | (st0_tag << (regnri * 2));
+ fpu_tag_word = tag_word;
+}
void ffree_(void)
{
- /* ffree st(i) */
- FPU_settagi(FPU_rm, TAG_Empty);
+ /* ffree st(i) */
+ FPU_settagi(FPU_rm, TAG_Empty);
}
-
void ffreep(void)
{
- /* ffree st(i) + pop - unofficial code */
- FPU_settagi(FPU_rm, TAG_Empty);
- FPU_pop();
+ /* ffree st(i) + pop - unofficial code */
+ FPU_settagi(FPU_rm, TAG_Empty);
+ FPU_pop();
}
-
void fst_i_(void)
{
- /* fst st(i) */
- FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm);
+ /* fst st(i) */
+ FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm);
}
-
void fstp_i(void)
{
- /* fstp st(i) */
- FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm);
- FPU_pop();
+ /* fstp st(i) */
+ FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm);
+ FPU_pop();
}
-
diff --git a/arch/x86/math-emu/fpu_emu.h b/arch/x86/math-emu/fpu_emu.h
index 65120f523853..656dd4c04b1b 100644
--- a/arch/x86/math-emu/fpu_emu.h
+++ b/arch/x86/math-emu/fpu_emu.h
@@ -7,7 +7,6 @@
| |
+---------------------------------------------------------------------------*/
-
#ifndef _FPU_EMU_H_
#define _FPU_EMU_H_
@@ -28,15 +27,15 @@
#endif
#define EXP_BIAS Const(0)
-#define EXP_OVER Const(0x4000) /* smallest invalid large exponent */
-#define EXP_UNDER Const(-0x3fff) /* largest invalid small exponent */
-#define EXP_WAY_UNDER Const(-0x6000) /* Below the smallest denormal, but
- still a 16 bit nr. */
+#define EXP_OVER Const(0x4000) /* smallest invalid large exponent */
+#define EXP_UNDER Const(-0x3fff) /* largest invalid small exponent */
+#define EXP_WAY_UNDER Const(-0x6000) /* Below the smallest denormal, but
+ still a 16 bit nr. */
#define EXP_Infinity EXP_OVER
#define EXP_NaN EXP_OVER
#define EXTENDED_Ebias Const(0x3fff)
-#define EXTENDED_Emin (-0x3ffe) /* smallest valid exponent */
+#define EXTENDED_Emin (-0x3ffe) /* smallest valid exponent */
#define SIGN_POS Const(0)
#define SIGN_NEG Const(0x80)
@@ -44,10 +43,9 @@
#define SIGN_Positive Const(0)
#define SIGN_Negative Const(0x8000)
-
/* Keep the order TAG_Valid, TAG_Zero, TW_Denormal */
/* The following fold to 2 (Special) in the Tag Word */
-#define TW_Denormal Const(4) /* De-normal */
+#define TW_Denormal Const(4) /* De-normal */
#define TW_Infinity Const(5) /* + or - infinity */
#define TW_NaN Const(6) /* Not a Number */
#define TW_Unsupported Const(7) /* Not supported by an 80486 */
@@ -67,14 +65,13 @@
#define DEST_RM 0x20
#define LOADED 0x40
-#define FPU_Exception Const(0x80000000) /* Added to tag returns. */
-
+#define FPU_Exception Const(0x80000000) /* Added to tag returns. */
#ifndef __ASSEMBLY__
#include "fpu_system.h"
-#include <asm/sigcontext.h> /* for struct _fpstate */
+#include <asm/sigcontext.h> /* for struct _fpstate */
#include <asm/math_emu.h>
#include <linux/linkage.h>
@@ -112,30 +109,33 @@ extern u_char emulating;
#define PREFIX_DEFAULT 7
struct address {
- unsigned int offset;
- unsigned int selector:16;
- unsigned int opcode:11;
- unsigned int empty:5;
+ unsigned int offset;
+ unsigned int selector:16;
+ unsigned int opcode:11;
+ unsigned int empty:5;
};
struct fpu__reg {
- unsigned sigl;
- unsigned sigh;
- short exp;
+ unsigned sigl;
+ unsigned sigh;
+ short exp;
};
-typedef void (*FUNC)(void);
+typedef void (*FUNC) (void);
typedef struct fpu__reg FPU_REG;
-typedef void (*FUNC_ST0)(FPU_REG *st0_ptr, u_char st0_tag);
-typedef struct { u_char address_size, operand_size, segment; }
- overrides;
+typedef void (*FUNC_ST0) (FPU_REG * st0_ptr, u_char st0_tag);
+typedef struct {
+ u_char address_size, operand_size, segment;
+} overrides;
/* This structure is 32 bits: */
-typedef struct { overrides override;
- u_char default_mode; } fpu_addr_modes;
+typedef struct {
+ overrides override;
+ u_char default_mode;
+} fpu_addr_modes;
/* PROTECTED has a restricted meaning in the emulator; it is used
to signal that the emulator needs to do special things to ensure
that protection is respected in a segmented model. */
#define PROTECTED 4
-#define SIXTEEN 1 /* We rely upon this being 1 (true) */
+#define SIXTEEN 1 /* We rely upon this being 1 (true) */
#define VM86 SIXTEEN
#define PM16 (SIXTEEN | PROTECTED)
#define SEG32 PROTECTED
@@ -166,10 +166,10 @@ extern u_char const data_sizes_16[32];
#define signpositive(a) ( (signbyte(a) & 0x80) == 0 )
#define signnegative(a) (signbyte(a) & 0x80)
-static inline void reg_copy(FPU_REG const *x, FPU_REG *y)
+static inline void reg_copy(FPU_REG const *x, FPU_REG * y)
{
- *(short *)&(y->exp) = *(const short *)&(x->exp);
- *(long long *)&(y->sigl) = *(const long long *)&(x->sigl);
+ *(short *)&(y->exp) = *(const short *)&(x->exp);
+ *(long long *)&(y->sigl) = *(const long long *)&(x->sigl);
}
#define exponent(x) (((*(short *)&((x)->exp)) & 0x7fff) - EXTENDED_Ebias)
@@ -184,29 +184,28 @@ static inline void reg_copy(FPU_REG const *x, FPU_REG *y)
#define significand(x) ( ((unsigned long long *)&((x)->sigl))[0] )
-
/*----- Prototypes for functions written in assembler -----*/
/* extern void reg_move(FPU_REG *a, FPU_REG *b); */
-asmlinkage int FPU_normalize(FPU_REG *x);
-asmlinkage int FPU_normalize_nuo(FPU_REG *x);
+asmlinkage int FPU_normalize(FPU_REG * x);
+asmlinkage int FPU_normalize_nuo(FPU_REG * x);
asmlinkage int FPU_u_sub(FPU_REG const *arg1, FPU_REG const *arg2,
- FPU_REG *answ, unsigned int control_w, u_char sign,
+ FPU_REG * answ, unsigned int control_w, u_char sign,
int expa, int expb);
asmlinkage int FPU_u_mul(FPU_REG const *arg1, FPU_REG const *arg2,
- FPU_REG *answ, unsigned int control_w, u_char sign,
+ FPU_REG * answ, unsigned int control_w, u_char sign,
int expon);
asmlinkage int FPU_u_div(FPU_REG const *arg1, FPU_REG const *arg2,
- FPU_REG *answ, unsigned int control_w, u_char sign);
+ FPU_REG * answ, unsigned int control_w, u_char sign);
asmlinkage int FPU_u_add(FPU_REG const *arg1, FPU_REG const *arg2,
- FPU_REG *answ, unsigned int control_w, u_char sign,
+ FPU_REG * answ, unsigned int control_w, u_char sign,
int expa, int expb);
-asmlinkage int wm_sqrt(FPU_REG *n, int dummy1, int dummy2,
+asmlinkage int wm_sqrt(FPU_REG * n, int dummy1, int dummy2,
unsigned int control_w, u_char sign);
-asmlinkage unsigned FPU_shrx(void *l, unsigned x);
-asmlinkage unsigned FPU_shrxs(void *v, unsigned x);
+asmlinkage unsigned FPU_shrx(void *l, unsigned x);
+asmlinkage unsigned FPU_shrxs(void *v, unsigned x);
asmlinkage unsigned long FPU_div_small(unsigned long long *x, unsigned long y);
-asmlinkage int FPU_round(FPU_REG *arg, unsigned int extent, int dummy,
+asmlinkage int FPU_round(FPU_REG * arg, unsigned int extent, int dummy,
unsigned int control_w, u_char sign);
#ifndef MAKING_PROTO
diff --git a/arch/x86/math-emu/fpu_entry.c b/arch/x86/math-emu/fpu_entry.c
index 1853524c8b57..cbb8717f09fd 100644
--- a/arch/x86/math-emu/fpu_entry.c
+++ b/arch/x86/math-emu/fpu_entry.c
@@ -36,726 +36,720 @@
#include "control_w.h"
#include "status_w.h"
-#define __BAD__ FPU_illegal /* Illegal on an 80486, causes SIGILL */
+#define __BAD__ FPU_illegal /* Illegal on an 80486, causes SIGILL */
-#ifndef NO_UNDOC_CODE /* Un-documented FPU op-codes supported by default. */
+#ifndef NO_UNDOC_CODE /* Un-documented FPU op-codes supported by default. */
/* WARNING: These codes are not documented by Intel in their 80486 manual
and may not work on FPU clones or later Intel FPUs. */
/* Changes to support the un-doc codes provided by Linus Torvalds. */
-#define _d9_d8_ fstp_i /* unofficial code (19) */
-#define _dc_d0_ fcom_st /* unofficial code (14) */
-#define _dc_d8_ fcompst /* unofficial code (1c) */
-#define _dd_c8_ fxch_i /* unofficial code (0d) */
-#define _de_d0_ fcompst /* unofficial code (16) */
-#define _df_c0_ ffreep /* unofficial code (07) ffree + pop */
-#define _df_c8_ fxch_i /* unofficial code (0f) */
-#define _df_d0_ fstp_i /* unofficial code (17) */
-#define _df_d8_ fstp_i /* unofficial code (1f) */
+#define _d9_d8_ fstp_i /* unofficial code (19) */
+#define _dc_d0_ fcom_st /* unofficial code (14) */
+#define _dc_d8_ fcompst /* unofficial code (1c) */
+#define _dd_c8_ fxch_i /* unofficial code (0d) */
+#define _de_d0_ fcompst /* unofficial code (16) */
+#define _df_c0_ ffreep /* unofficial code (07) ffree + pop */
+#define _df_c8_ fxch_i /* unofficial code (0f) */
+#define _df_d0_ fstp_i /* unofficial code (17) */
+#define _df_d8_ fstp_i /* unofficial code (1f) */
static FUNC const st_instr_table[64] = {
- fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, _df_c0_,
- fmul__, fxch_i, __BAD__, __BAD__, fmul_i, _dd_c8_, fmulp_, _df_c8_,
- fcom_st, fp_nop, __BAD__, __BAD__, _dc_d0_, fst_i_, _de_d0_, _df_d0_,
- fcompst, _d9_d8_, __BAD__, __BAD__, _dc_d8_, fstp_i, fcompp, _df_d8_,
- fsub__, FPU_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
- fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
- fdiv__, FPU_triga, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
- fdivr_, FPU_trigb, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__,
+ fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, _df_c0_,
+ fmul__, fxch_i, __BAD__, __BAD__, fmul_i, _dd_c8_, fmulp_, _df_c8_,
+ fcom_st, fp_nop, __BAD__, __BAD__, _dc_d0_, fst_i_, _de_d0_, _df_d0_,
+ fcompst, _d9_d8_, __BAD__, __BAD__, _dc_d8_, fstp_i, fcompp, _df_d8_,
+ fsub__, FPU_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
+ fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
+ fdiv__, FPU_triga, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
+ fdivr_, FPU_trigb, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__,
};
-#else /* Support only documented FPU op-codes */
+#else /* Support only documented FPU op-codes */
static FUNC const st_instr_table[64] = {
- fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, __BAD__,
- fmul__, fxch_i, __BAD__, __BAD__, fmul_i, __BAD__, fmulp_, __BAD__,
- fcom_st, fp_nop, __BAD__, __BAD__, __BAD__, fst_i_, __BAD__, __BAD__,
- fcompst, __BAD__, __BAD__, __BAD__, __BAD__, fstp_i, fcompp, __BAD__,
- fsub__, FPU_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
- fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
- fdiv__, FPU_triga, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
- fdivr_, FPU_trigb, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__,
+ fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, __BAD__,
+ fmul__, fxch_i, __BAD__, __BAD__, fmul_i, __BAD__, fmulp_, __BAD__,
+ fcom_st, fp_nop, __BAD__, __BAD__, __BAD__, fst_i_, __BAD__, __BAD__,
+ fcompst, __BAD__, __BAD__, __BAD__, __BAD__, fstp_i, fcompp, __BAD__,
+ fsub__, FPU_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
+ fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
+ fdiv__, FPU_triga, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
+ fdivr_, FPU_trigb, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__,
};
#endif /* NO_UNDOC_CODE */
-
-#define _NONE_ 0 /* Take no special action */
-#define _REG0_ 1 /* Need to check for not empty st(0) */
-#define _REGI_ 2 /* Need to check for not empty st(0) and st(rm) */
-#define _REGi_ 0 /* Uses st(rm) */
-#define _PUSH_ 3 /* Need to check for space to push onto stack */
-#define _null_ 4 /* Function illegal or not implemented */
-#define _REGIi 5 /* Uses st(0) and st(rm), result to st(rm) */
-#define _REGIp 6 /* Uses st(0) and st(rm), result to st(rm) then pop */
-#define _REGIc 0 /* Compare st(0) and st(rm) */
-#define _REGIn 0 /* Uses st(0) and st(rm), but handle checks later */
+#define _NONE_ 0 /* Take no special action */
+#define _REG0_ 1 /* Need to check for not empty st(0) */
+#define _REGI_ 2 /* Need to check for not empty st(0) and st(rm) */
+#define _REGi_ 0 /* Uses st(rm) */
+#define _PUSH_ 3 /* Need to check for space to push onto stack */
+#define _null_ 4 /* Function illegal or not implemented */
+#define _REGIi 5 /* Uses st(0) and st(rm), result to st(rm) */
+#define _REGIp 6 /* Uses st(0) and st(rm), result to st(rm) then pop */
+#define _REGIc 0 /* Compare st(0) and st(rm) */
+#define _REGIn 0 /* Uses st(0) and st(rm), but handle checks later */
#ifndef NO_UNDOC_CODE
/* Un-documented FPU op-codes supported by default. (see above) */
static u_char const type_table[64] = {
- _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _REGi_,
- _REGI_, _REGIn, _null_, _null_, _REGIi, _REGI_, _REGIp, _REGI_,
- _REGIc, _NONE_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
- _REGIc, _REG0_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
- _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
- _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
- _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
- _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
+ _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _REGi_,
+ _REGI_, _REGIn, _null_, _null_, _REGIi, _REGI_, _REGIp, _REGI_,
+ _REGIc, _NONE_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
+ _REGIc, _REG0_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
+ _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
+ _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
+ _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
+ _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
};
-#else /* Support only documented FPU op-codes */
+#else /* Support only documented FPU op-codes */
static u_char const type_table[64] = {
- _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _null_,
- _REGI_, _REGIn, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
- _REGIc, _NONE_, _null_, _null_, _null_, _REG0_, _null_, _null_,
- _REGIc, _null_, _null_, _null_, _null_, _REG0_, _REGIc, _null_,
- _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
- _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
- _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
- _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
+ _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _null_,
+ _REGI_, _REGIn, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
+ _REGIc, _NONE_, _null_, _null_, _null_, _REG0_, _null_, _null_,
+ _REGIc, _null_, _null_, _null_, _null_, _REG0_, _REGIc, _null_,
+ _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
+ _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
+ _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
+ _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
};
#endif /* NO_UNDOC_CODE */
-
#ifdef RE_ENTRANT_CHECKING
-u_char emulating=0;
+u_char emulating = 0;
#endif /* RE_ENTRANT_CHECKING */
-static int valid_prefix(u_char *Byte, u_char __user **fpu_eip,
- overrides *override);
+static int valid_prefix(u_char * Byte, u_char __user ** fpu_eip,
+ overrides * override);
asmlinkage void math_emulate(long arg)
{
- u_char FPU_modrm, byte1;
- unsigned short code;
- fpu_addr_modes addr_modes;
- int unmasked;
- FPU_REG loaded_data;
- FPU_REG *st0_ptr;
- u_char loaded_tag, st0_tag;
- void __user *data_address;
- struct address data_sel_off;
- struct address entry_sel_off;
- unsigned long code_base = 0;
- unsigned long code_limit = 0; /* Initialized to stop compiler warnings */
- struct desc_struct code_descriptor;
+ u_char FPU_modrm, byte1;
+ unsigned short code;
+ fpu_addr_modes addr_modes;
+ int unmasked;
+ FPU_REG loaded_data;
+ FPU_REG *st0_ptr;
+ u_char loaded_tag, st0_tag;
+ void __user *data_address;
+ struct address data_sel_off;
+ struct address entry_sel_off;
+ unsigned long code_base = 0;
+ unsigned long code_limit = 0; /* Initialized to stop compiler warnings */
+ struct desc_struct code_descriptor;
#ifdef RE_ENTRANT_CHECKING
- if ( emulating )
- {
- printk("ERROR: wm-FPU-emu is not RE-ENTRANT!\n");
- }
- RE_ENTRANT_CHECK_ON;
+ if (emulating) {
+ printk("ERROR: wm-FPU-emu is not RE-ENTRANT!\n");
+ }
+ RE_ENTRANT_CHECK_ON;
#endif /* RE_ENTRANT_CHECKING */
- if (!used_math())
- {
- finit();
- set_used_math();
- }
-
- SETUP_DATA_AREA(arg);
-
- FPU_ORIG_EIP = FPU_EIP;
-
- if ( (FPU_EFLAGS & 0x00020000) != 0 )
- {
- /* Virtual 8086 mode */
- addr_modes.default_mode = VM86;
- FPU_EIP += code_base = FPU_CS << 4;
- code_limit = code_base + 0xffff; /* Assumes code_base <= 0xffff0000 */
- }
- else if ( FPU_CS == __USER_CS && FPU_DS == __USER_DS )
- {
- addr_modes.default_mode = 0;
- }
- else if ( FPU_CS == __KERNEL_CS )
- {
- printk("math_emulate: %04x:%08lx\n",FPU_CS,FPU_EIP);
- panic("Math emulation needed in kernel");
- }
- else
- {
-
- if ( (FPU_CS & 4) != 4 ) /* Must be in the LDT */
- {
- /* Can only handle segmented addressing via the LDT
- for now, and it must be 16 bit */
- printk("FPU emulator: Unsupported addressing mode\n");
- math_abort(FPU_info, SIGILL);
+ if (!used_math()) {
+ finit();
+ set_used_math();
}
- code_descriptor = LDT_DESCRIPTOR(FPU_CS);
- if ( SEG_D_SIZE(code_descriptor) )
- {
- /* The above test may be wrong, the book is not clear */
- /* Segmented 32 bit protected mode */
- addr_modes.default_mode = SEG32;
+ SETUP_DATA_AREA(arg);
+
+ FPU_ORIG_EIP = FPU_EIP;
+
+ if ((FPU_EFLAGS & 0x00020000) != 0) {
+ /* Virtual 8086 mode */
+ addr_modes.default_mode = VM86;
+ FPU_EIP += code_base = FPU_CS << 4;
+ code_limit = code_base + 0xffff; /* Assumes code_base <= 0xffff0000 */
+ } else if (FPU_CS == __USER_CS && FPU_DS == __USER_DS) {
+ addr_modes.default_mode = 0;
+ } else if (FPU_CS == __KERNEL_CS) {
+ printk("math_emulate: %04x:%08lx\n", FPU_CS, FPU_EIP);
+ panic("Math emulation needed in kernel");
+ } else {
+
+ if ((FPU_CS & 4) != 4) { /* Must be in the LDT */
+ /* Can only handle segmented addressing via the LDT
+ for now, and it must be 16 bit */
+ printk("FPU emulator: Unsupported addressing mode\n");
+ math_abort(FPU_info, SIGILL);
+ }
+
+ code_descriptor = LDT_DESCRIPTOR(FPU_CS);
+ if (SEG_D_SIZE(code_descriptor)) {
+ /* The above test may be wrong, the book is not clear */
+ /* Segmented 32 bit protected mode */
+ addr_modes.default_mode = SEG32;
+ } else {
+ /* 16 bit protected mode */
+ addr_modes.default_mode = PM16;
+ }
+ FPU_EIP += code_base = SEG_BASE_ADDR(code_descriptor);
+ code_limit = code_base
+ + (SEG_LIMIT(code_descriptor) +
+ 1) * SEG_GRANULARITY(code_descriptor)
+ - 1;
+ if (code_limit < code_base)
+ code_limit = 0xffffffff;
}
- else
- {
- /* 16 bit protected mode */
- addr_modes.default_mode = PM16;
+
+ FPU_lookahead = 1;
+ if (current->ptrace & PT_PTRACED)
+ FPU_lookahead = 0;
+
+ if (!valid_prefix(&byte1, (u_char __user **) & FPU_EIP,
+ &addr_modes.override)) {
+ RE_ENTRANT_CHECK_OFF;
+ printk
+ ("FPU emulator: Unknown prefix byte 0x%02x, probably due to\n"
+ "FPU emulator: self-modifying code! (emulation impossible)\n",
+ byte1);
+ RE_ENTRANT_CHECK_ON;
+ EXCEPTION(EX_INTERNAL | 0x126);
+ math_abort(FPU_info, SIGILL);
}
- FPU_EIP += code_base = SEG_BASE_ADDR(code_descriptor);
- code_limit = code_base
- + (SEG_LIMIT(code_descriptor)+1) * SEG_GRANULARITY(code_descriptor)
- - 1;
- if ( code_limit < code_base ) code_limit = 0xffffffff;
- }
-
- FPU_lookahead = 1;
- if (current->ptrace & PT_PTRACED)
- FPU_lookahead = 0;
-
- if ( !valid_prefix(&byte1, (u_char __user **)&FPU_EIP,
- &addr_modes.override) )
- {
- RE_ENTRANT_CHECK_OFF;
- printk("FPU emulator: Unknown prefix byte 0x%02x, probably due to\n"
- "FPU emulator: self-modifying code! (emulation impossible)\n",
- byte1);
- RE_ENTRANT_CHECK_ON;
- EXCEPTION(EX_INTERNAL|0x126);
- math_abort(FPU_info,SIGILL);
- }
-
-do_another_FPU_instruction:
-
- no_ip_update = 0;
-
- FPU_EIP++; /* We have fetched the prefix and first code bytes. */
-
- if ( addr_modes.default_mode )
- {
- /* This checks for the minimum instruction bytes.
- We also need to check any extra (address mode) code access. */
- if ( FPU_EIP > code_limit )
- math_abort(FPU_info,SIGSEGV);
- }
-
- if ( (byte1 & 0xf8) != 0xd8 )
- {
- if ( byte1 == FWAIT_OPCODE )
- {
- if (partial_status & SW_Summary)
- goto do_the_FPU_interrupt;
- else
- goto FPU_fwait_done;
+
+ do_another_FPU_instruction:
+
+ no_ip_update = 0;
+
+ FPU_EIP++; /* We have fetched the prefix and first code bytes. */
+
+ if (addr_modes.default_mode) {
+ /* This checks for the minimum instruction bytes.
+ We also need to check any extra (address mode) code access. */
+ if (FPU_EIP > code_limit)
+ math_abort(FPU_info, SIGSEGV);
}
+
+ if ((byte1 & 0xf8) != 0xd8) {
+ if (byte1 == FWAIT_OPCODE) {
+ if (partial_status & SW_Summary)
+ goto do_the_FPU_interrupt;
+ else
+ goto FPU_fwait_done;
+ }
#ifdef PARANOID
- EXCEPTION(EX_INTERNAL|0x128);
- math_abort(FPU_info,SIGILL);
+ EXCEPTION(EX_INTERNAL | 0x128);
+ math_abort(FPU_info, SIGILL);
#endif /* PARANOID */
- }
-
- RE_ENTRANT_CHECK_OFF;
- FPU_code_access_ok(1);
- FPU_get_user(FPU_modrm, (u_char __user *) FPU_EIP);
- RE_ENTRANT_CHECK_ON;
- FPU_EIP++;
-
- if (partial_status & SW_Summary)
- {
- /* Ignore the error for now if the current instruction is a no-wait
- control instruction */
- /* The 80486 manual contradicts itself on this topic,
- but a real 80486 uses the following instructions:
- fninit, fnstenv, fnsave, fnstsw, fnstenv, fnclex.
- */
- code = (FPU_modrm << 8) | byte1;
- if ( ! ( (((code & 0xf803) == 0xe003) || /* fnclex, fninit, fnstsw */
- (((code & 0x3003) == 0x3001) && /* fnsave, fnstcw, fnstenv,
- fnstsw */
- ((code & 0xc000) != 0xc000))) ) )
- {
- /*
- * We need to simulate the action of the kernel to FPU
- * interrupts here.
- */
- do_the_FPU_interrupt:
-
- FPU_EIP = FPU_ORIG_EIP; /* Point to current FPU instruction. */
-
- RE_ENTRANT_CHECK_OFF;
- current->thread.trap_no = 16;
- current->thread.error_code = 0;
- send_sig(SIGFPE, current, 1);
- return;
- }
- }
-
- entry_sel_off.offset = FPU_ORIG_EIP;
- entry_sel_off.selector = FPU_CS;
- entry_sel_off.opcode = (byte1 << 8) | FPU_modrm;
-
- FPU_rm = FPU_modrm & 7;
-
- if ( FPU_modrm < 0300 )
- {
- /* All of these instructions use the mod/rm byte to get a data address */
-
- if ( (addr_modes.default_mode & SIXTEEN)
- ^ (addr_modes.override.address_size == ADDR_SIZE_PREFIX) )
- data_address = FPU_get_address_16(FPU_modrm, &FPU_EIP, &data_sel_off,
- addr_modes);
- else
- data_address = FPU_get_address(FPU_modrm, &FPU_EIP, &data_sel_off,
- addr_modes);
-
- if ( addr_modes.default_mode )
- {
- if ( FPU_EIP-1 > code_limit )
- math_abort(FPU_info,SIGSEGV);
}
- if ( !(byte1 & 1) )
- {
- unsigned short status1 = partial_status;
-
- st0_ptr = &st(0);
- st0_tag = FPU_gettag0();
-
- /* Stack underflow has priority */
- if ( NOT_EMPTY_ST0 )
- {
- if ( addr_modes.default_mode & PROTECTED )
- {
- /* This table works for 16 and 32 bit protected mode */
- if ( access_limit < data_sizes_16[(byte1 >> 1) & 3] )
- math_abort(FPU_info,SIGSEGV);
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_access_ok(1);
+ FPU_get_user(FPU_modrm, (u_char __user *) FPU_EIP);
+ RE_ENTRANT_CHECK_ON;
+ FPU_EIP++;
+
+ if (partial_status & SW_Summary) {
+ /* Ignore the error for now if the current instruction is a no-wait
+ control instruction */
+ /* The 80486 manual contradicts itself on this topic,
+ but a real 80486 uses the following instructions:
+ fninit, fnstenv, fnsave, fnstsw, fnstenv, fnclex.
+ */
+ code = (FPU_modrm << 8) | byte1;
+ if (!((((code & 0xf803) == 0xe003) || /* fnclex, fninit, fnstsw */
+ (((code & 0x3003) == 0x3001) && /* fnsave, fnstcw, fnstenv,
+ fnstsw */
+ ((code & 0xc000) != 0xc000))))) {
+ /*
+ * We need to simulate the action of the kernel to FPU
+ * interrupts here.
+ */
+ do_the_FPU_interrupt:
+
+ FPU_EIP = FPU_ORIG_EIP; /* Point to current FPU instruction. */
+
+ RE_ENTRANT_CHECK_OFF;
+ current->thread.trap_no = 16;
+ current->thread.error_code = 0;
+ send_sig(SIGFPE, current, 1);
+ return;
}
+ }
- unmasked = 0; /* Do this here to stop compiler warnings. */
- switch ( (byte1 >> 1) & 3 )
- {
- case 0:
- unmasked = FPU_load_single((float __user *)data_address,
- &loaded_data);
- loaded_tag = unmasked & 0xff;
- unmasked &= ~0xff;
- break;
- case 1:
- loaded_tag = FPU_load_int32((long __user *)data_address, &loaded_data);
- break;
- case 2:
- unmasked = FPU_load_double((double __user *)data_address,
- &loaded_data);
- loaded_tag = unmasked & 0xff;
- unmasked &= ~0xff;
- break;
- case 3:
- default: /* Used here to suppress gcc warnings. */
- loaded_tag = FPU_load_int16((short __user *)data_address, &loaded_data);
- break;
- }
+ entry_sel_off.offset = FPU_ORIG_EIP;
+ entry_sel_off.selector = FPU_CS;
+ entry_sel_off.opcode = (byte1 << 8) | FPU_modrm;
- /* No more access to user memory, it is safe
- to use static data now */
-
- /* NaN operands have the next priority. */
- /* We have to delay looking at st(0) until after
- loading the data, because that data might contain an SNaN */
- if ( ((st0_tag == TAG_Special) && isNaN(st0_ptr)) ||
- ((loaded_tag == TAG_Special) && isNaN(&loaded_data)) )
- {
- /* Restore the status word; we might have loaded a
- denormal. */
- partial_status = status1;
- if ( (FPU_modrm & 0x30) == 0x10 )
- {
- /* fcom or fcomp */
- EXCEPTION(EX_Invalid);
- setcc(SW_C3 | SW_C2 | SW_C0);
- if ( (FPU_modrm & 0x08) && (control_word & CW_Invalid) )
- FPU_pop(); /* fcomp, masked, so we pop. */
- }
- else
- {
- if ( loaded_tag == TAG_Special )
- loaded_tag = FPU_Special(&loaded_data);
-#ifdef PECULIAR_486
- /* This is not really needed, but gives behaviour
- identical to an 80486 */
- if ( (FPU_modrm & 0x28) == 0x20 )
- /* fdiv or fsub */
- real_2op_NaN(&loaded_data, loaded_tag, 0, &loaded_data);
- else
-#endif /* PECULIAR_486 */
- /* fadd, fdivr, fmul, or fsubr */
- real_2op_NaN(&loaded_data, loaded_tag, 0, st0_ptr);
- }
- goto reg_mem_instr_done;
- }
+ FPU_rm = FPU_modrm & 7;
- if ( unmasked && !((FPU_modrm & 0x30) == 0x10) )
- {
- /* Is not a comparison instruction. */
- if ( (FPU_modrm & 0x38) == 0x38 )
- {
- /* fdivr */
- if ( (st0_tag == TAG_Zero) &&
- ((loaded_tag == TAG_Valid)
- || (loaded_tag == TAG_Special
- && isdenormal(&loaded_data))) )
- {
- if ( FPU_divide_by_zero(0, getsign(&loaded_data))
- < 0 )
- {
- /* We use the fact here that the unmasked
- exception in the loaded data was for a
- denormal operand */
- /* Restore the state of the denormal op bit */
- partial_status &= ~SW_Denorm_Op;
- partial_status |= status1 & SW_Denorm_Op;
- }
- else
- setsign(st0_ptr, getsign(&loaded_data));
- }
- }
- goto reg_mem_instr_done;
- }
+ if (FPU_modrm < 0300) {
+ /* All of these instructions use the mod/rm byte to get a data address */
- switch ( (FPU_modrm >> 3) & 7 )
- {
- case 0: /* fadd */
- clear_C1();
- FPU_add(&loaded_data, loaded_tag, 0, control_word);
- break;
- case 1: /* fmul */
- clear_C1();
- FPU_mul(&loaded_data, loaded_tag, 0, control_word);
- break;
- case 2: /* fcom */
- FPU_compare_st_data(&loaded_data, loaded_tag);
- break;
- case 3: /* fcomp */
- if ( !FPU_compare_st_data(&loaded_data, loaded_tag)
- && !unmasked )
- FPU_pop();
- break;
- case 4: /* fsub */
- clear_C1();
- FPU_sub(LOADED|loaded_tag, (int)&loaded_data, control_word);
- break;
- case 5: /* fsubr */
- clear_C1();
- FPU_sub(REV|LOADED|loaded_tag, (int)&loaded_data, control_word);
- break;
- case 6: /* fdiv */
- clear_C1();
- FPU_div(LOADED|loaded_tag, (int)&loaded_data, control_word);
- break;
- case 7: /* fdivr */
- clear_C1();
- if ( st0_tag == TAG_Zero )
- partial_status = status1; /* Undo any denorm tag,
- zero-divide has priority. */
- FPU_div(REV|LOADED|loaded_tag, (int)&loaded_data, control_word);
- break;
+ if ((addr_modes.default_mode & SIXTEEN)
+ ^ (addr_modes.override.address_size == ADDR_SIZE_PREFIX))
+ data_address =
+ FPU_get_address_16(FPU_modrm, &FPU_EIP,
+ &data_sel_off, addr_modes);
+ else
+ data_address =
+ FPU_get_address(FPU_modrm, &FPU_EIP, &data_sel_off,
+ addr_modes);
+
+ if (addr_modes.default_mode) {
+ if (FPU_EIP - 1 > code_limit)
+ math_abort(FPU_info, SIGSEGV);
}
- }
- else
- {
- if ( (FPU_modrm & 0x30) == 0x10 )
- {
- /* The instruction is fcom or fcomp */
- EXCEPTION(EX_StackUnder);
- setcc(SW_C3 | SW_C2 | SW_C0);
- if ( (FPU_modrm & 0x08) && (control_word & CW_Invalid) )
- FPU_pop(); /* fcomp */
+
+ if (!(byte1 & 1)) {
+ unsigned short status1 = partial_status;
+
+ st0_ptr = &st(0);
+ st0_tag = FPU_gettag0();
+
+ /* Stack underflow has priority */
+ if (NOT_EMPTY_ST0) {
+ if (addr_modes.default_mode & PROTECTED) {
+ /* This table works for 16 and 32 bit protected mode */
+ if (access_limit <
+ data_sizes_16[(byte1 >> 1) & 3])
+ math_abort(FPU_info, SIGSEGV);
+ }
+
+ unmasked = 0; /* Do this here to stop compiler warnings. */
+ switch ((byte1 >> 1) & 3) {
+ case 0:
+ unmasked =
+ FPU_load_single((float __user *)
+ data_address,
+ &loaded_data);
+ loaded_tag = unmasked & 0xff;
+ unmasked &= ~0xff;
+ break;
+ case 1:
+ loaded_tag =
+ FPU_load_int32((long __user *)
+ data_address,
+ &loaded_data);
+ break;
+ case 2:
+ unmasked =
+ FPU_load_double((double __user *)
+ data_address,
+ &loaded_data);
+ loaded_tag = unmasked & 0xff;
+ unmasked &= ~0xff;
+ break;
+ case 3:
+ default: /* Used here to suppress gcc warnings. */
+ loaded_tag =
+ FPU_load_int16((short __user *)
+ data_address,
+ &loaded_data);
+ break;
+ }
+
+ /* No more access to user memory, it is safe
+ to use static data now */
+
+ /* NaN operands have the next priority. */
+ /* We have to delay looking at st(0) until after
+ loading the data, because that data might contain an SNaN */
+ if (((st0_tag == TAG_Special) && isNaN(st0_ptr))
+ || ((loaded_tag == TAG_Special)
+ && isNaN(&loaded_data))) {
+ /* Restore the status word; we might have loaded a
+ denormal. */
+ partial_status = status1;
+ if ((FPU_modrm & 0x30) == 0x10) {
+ /* fcom or fcomp */
+ EXCEPTION(EX_Invalid);
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ if ((FPU_modrm & 0x08)
+ && (control_word &
+ CW_Invalid))
+ FPU_pop(); /* fcomp, masked, so we pop. */
+ } else {
+ if (loaded_tag == TAG_Special)
+ loaded_tag =
+ FPU_Special
+ (&loaded_data);
+#ifdef PECULIAR_486
+ /* This is not really needed, but gives behaviour
+ identical to an 80486 */
+ if ((FPU_modrm & 0x28) == 0x20)
+ /* fdiv or fsub */
+ real_2op_NaN
+ (&loaded_data,
+ loaded_tag, 0,
+ &loaded_data);
+ else
+#endif /* PECULIAR_486 */
+ /* fadd, fdivr, fmul, or fsubr */
+ real_2op_NaN
+ (&loaded_data,
+ loaded_tag, 0,
+ st0_ptr);
+ }
+ goto reg_mem_instr_done;
+ }
+
+ if (unmasked && !((FPU_modrm & 0x30) == 0x10)) {
+ /* Is not a comparison instruction. */
+ if ((FPU_modrm & 0x38) == 0x38) {
+ /* fdivr */
+ if ((st0_tag == TAG_Zero) &&
+ ((loaded_tag == TAG_Valid)
+ || (loaded_tag ==
+ TAG_Special
+ &&
+ isdenormal
+ (&loaded_data)))) {
+ if (FPU_divide_by_zero
+ (0,
+ getsign
+ (&loaded_data))
+ < 0) {
+ /* We use the fact here that the unmasked
+ exception in the loaded data was for a
+ denormal operand */
+ /* Restore the state of the denormal op bit */
+ partial_status
+ &=
+ ~SW_Denorm_Op;
+ partial_status
+ |=
+ status1 &
+ SW_Denorm_Op;
+ } else
+ setsign(st0_ptr,
+ getsign
+ (&loaded_data));
+ }
+ }
+ goto reg_mem_instr_done;
+ }
+
+ switch ((FPU_modrm >> 3) & 7) {
+ case 0: /* fadd */
+ clear_C1();
+ FPU_add(&loaded_data, loaded_tag, 0,
+ control_word);
+ break;
+ case 1: /* fmul */
+ clear_C1();
+ FPU_mul(&loaded_data, loaded_tag, 0,
+ control_word);
+ break;
+ case 2: /* fcom */
+ FPU_compare_st_data(&loaded_data,
+ loaded_tag);
+ break;
+ case 3: /* fcomp */
+ if (!FPU_compare_st_data
+ (&loaded_data, loaded_tag)
+ && !unmasked)
+ FPU_pop();
+ break;
+ case 4: /* fsub */
+ clear_C1();
+ FPU_sub(LOADED | loaded_tag,
+ (int)&loaded_data,
+ control_word);
+ break;
+ case 5: /* fsubr */
+ clear_C1();
+ FPU_sub(REV | LOADED | loaded_tag,
+ (int)&loaded_data,
+ control_word);
+ break;
+ case 6: /* fdiv */
+ clear_C1();
+ FPU_div(LOADED | loaded_tag,
+ (int)&loaded_data,
+ control_word);
+ break;
+ case 7: /* fdivr */
+ clear_C1();
+ if (st0_tag == TAG_Zero)
+ partial_status = status1; /* Undo any denorm tag,
+ zero-divide has priority. */
+ FPU_div(REV | LOADED | loaded_tag,
+ (int)&loaded_data,
+ control_word);
+ break;
+ }
+ } else {
+ if ((FPU_modrm & 0x30) == 0x10) {
+ /* The instruction is fcom or fcomp */
+ EXCEPTION(EX_StackUnder);
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ if ((FPU_modrm & 0x08)
+ && (control_word & CW_Invalid))
+ FPU_pop(); /* fcomp */
+ } else
+ FPU_stack_underflow();
+ }
+ reg_mem_instr_done:
+ operand_address = data_sel_off;
+ } else {
+ if (!(no_ip_update =
+ FPU_load_store(((FPU_modrm & 0x38) | (byte1 & 6))
+ >> 1, addr_modes, data_address))) {
+ operand_address = data_sel_off;
+ }
}
- else
- FPU_stack_underflow();
- }
- reg_mem_instr_done:
- operand_address = data_sel_off;
- }
- else
- {
- if ( !(no_ip_update =
- FPU_load_store(((FPU_modrm & 0x38) | (byte1 & 6)) >> 1,
- addr_modes, data_address)) )
- {
- operand_address = data_sel_off;
- }
- }
- }
- else
- {
- /* None of these instructions access user memory */
- u_char instr_index = (FPU_modrm & 0x38) | (byte1 & 7);
+ } else {
+ /* None of these instructions access user memory */
+ u_char instr_index = (FPU_modrm & 0x38) | (byte1 & 7);
#ifdef PECULIAR_486
- /* This is supposed to be undefined, but a real 80486 seems
- to do this: */
- operand_address.offset = 0;
- operand_address.selector = FPU_DS;
+ /* This is supposed to be undefined, but a real 80486 seems
+ to do this: */
+ operand_address.offset = 0;
+ operand_address.selector = FPU_DS;
#endif /* PECULIAR_486 */
- st0_ptr = &st(0);
- st0_tag = FPU_gettag0();
- switch ( type_table[(int) instr_index] )
- {
- case _NONE_: /* also _REGIc: _REGIn */
- break;
- case _REG0_:
- if ( !NOT_EMPTY_ST0 )
- {
- FPU_stack_underflow();
- goto FPU_instruction_done;
- }
- break;
- case _REGIi:
- if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
- {
- FPU_stack_underflow_i(FPU_rm);
- goto FPU_instruction_done;
- }
- break;
- case _REGIp:
- if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
- {
- FPU_stack_underflow_pop(FPU_rm);
- goto FPU_instruction_done;
- }
- break;
- case _REGI_:
- if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
- {
- FPU_stack_underflow();
- goto FPU_instruction_done;
- }
- break;
- case _PUSH_: /* Only used by the fld st(i) instruction */
- break;
- case _null_:
- FPU_illegal();
- goto FPU_instruction_done;
- default:
- EXCEPTION(EX_INTERNAL|0x111);
- goto FPU_instruction_done;
- }
- (*st_instr_table[(int) instr_index])();
+ st0_ptr = &st(0);
+ st0_tag = FPU_gettag0();
+ switch (type_table[(int)instr_index]) {
+ case _NONE_: /* also _REGIc: _REGIn */
+ break;
+ case _REG0_:
+ if (!NOT_EMPTY_ST0) {
+ FPU_stack_underflow();
+ goto FPU_instruction_done;
+ }
+ break;
+ case _REGIi:
+ if (!NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm)) {
+ FPU_stack_underflow_i(FPU_rm);
+ goto FPU_instruction_done;
+ }
+ break;
+ case _REGIp:
+ if (!NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm)) {
+ FPU_stack_underflow_pop(FPU_rm);
+ goto FPU_instruction_done;
+ }
+ break;
+ case _REGI_:
+ if (!NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm)) {
+ FPU_stack_underflow();
+ goto FPU_instruction_done;
+ }
+ break;
+ case _PUSH_: /* Only used by the fld st(i) instruction */
+ break;
+ case _null_:
+ FPU_illegal();
+ goto FPU_instruction_done;
+ default:
+ EXCEPTION(EX_INTERNAL | 0x111);
+ goto FPU_instruction_done;
+ }
+ (*st_instr_table[(int)instr_index]) ();
-FPU_instruction_done:
- ;
- }
+ FPU_instruction_done:
+ ;
+ }
- if ( ! no_ip_update )
- instruction_address = entry_sel_off;
+ if (!no_ip_update)
+ instruction_address = entry_sel_off;
-FPU_fwait_done:
+ FPU_fwait_done:
#ifdef DEBUG
- RE_ENTRANT_CHECK_OFF;
- FPU_printall();
- RE_ENTRANT_CHECK_ON;
+ RE_ENTRANT_CHECK_OFF;
+ FPU_printall();
+ RE_ENTRANT_CHECK_ON;
#endif /* DEBUG */
- if (FPU_lookahead && !need_resched())
- {
- FPU_ORIG_EIP = FPU_EIP - code_base;
- if ( valid_prefix(&byte1, (u_char __user **)&FPU_EIP,
- &addr_modes.override) )
- goto do_another_FPU_instruction;
- }
+ if (FPU_lookahead && !need_resched()) {
+ FPU_ORIG_EIP = FPU_EIP - code_base;
+ if (valid_prefix(&byte1, (u_char __user **) & FPU_EIP,
+ &addr_modes.override))
+ goto do_another_FPU_instruction;
+ }
- if ( addr_modes.default_mode )
- FPU_EIP -= code_base;
+ if (addr_modes.default_mode)
+ FPU_EIP -= code_base;
- RE_ENTRANT_CHECK_OFF;
+ RE_ENTRANT_CHECK_OFF;
}
-
/* Support for prefix bytes is not yet complete. To properly handle
all prefix bytes, further changes are needed in the emulator code
which accesses user address space. Access to separate segments is
important for msdos emulation. */
-static int valid_prefix(u_char *Byte, u_char __user **fpu_eip,
- overrides *override)
+static int valid_prefix(u_char * Byte, u_char __user ** fpu_eip,
+ overrides * override)
{
- u_char byte;
- u_char __user *ip = *fpu_eip;
-
- *override = (overrides) { 0, 0, PREFIX_DEFAULT }; /* defaults */
-
- RE_ENTRANT_CHECK_OFF;
- FPU_code_access_ok(1);
- FPU_get_user(byte, ip);
- RE_ENTRANT_CHECK_ON;
-
- while ( 1 )
- {
- switch ( byte )
- {
- case ADDR_SIZE_PREFIX:
- override->address_size = ADDR_SIZE_PREFIX;
- goto do_next_byte;
-
- case OP_SIZE_PREFIX:
- override->operand_size = OP_SIZE_PREFIX;
- goto do_next_byte;
-
- case PREFIX_CS:
- override->segment = PREFIX_CS_;
- goto do_next_byte;
- case PREFIX_ES:
- override->segment = PREFIX_ES_;
- goto do_next_byte;
- case PREFIX_SS:
- override->segment = PREFIX_SS_;
- goto do_next_byte;
- case PREFIX_FS:
- override->segment = PREFIX_FS_;
- goto do_next_byte;
- case PREFIX_GS:
- override->segment = PREFIX_GS_;
- goto do_next_byte;
- case PREFIX_DS:
- override->segment = PREFIX_DS_;
- goto do_next_byte;
+ u_char byte;
+ u_char __user *ip = *fpu_eip;
+
+ *override = (overrides) {
+ 0, 0, PREFIX_DEFAULT}; /* defaults */
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_access_ok(1);
+ FPU_get_user(byte, ip);
+ RE_ENTRANT_CHECK_ON;
+
+ while (1) {
+ switch (byte) {
+ case ADDR_SIZE_PREFIX:
+ override->address_size = ADDR_SIZE_PREFIX;
+ goto do_next_byte;
+
+ case OP_SIZE_PREFIX:
+ override->operand_size = OP_SIZE_PREFIX;
+ goto do_next_byte;
+
+ case PREFIX_CS:
+ override->segment = PREFIX_CS_;
+ goto do_next_byte;
+ case PREFIX_ES:
+ override->segment = PREFIX_ES_;
+ goto do_next_byte;
+ case PREFIX_SS:
+ override->segment = PREFIX_SS_;
+ goto do_next_byte;
+ case PREFIX_FS:
+ override->segment = PREFIX_FS_;
+ goto do_next_byte;
+ case PREFIX_GS:
+ override->segment = PREFIX_GS_;
+ goto do_next_byte;
+ case PREFIX_DS:
+ override->segment = PREFIX_DS_;
+ goto do_next_byte;
/* lock is not a valid prefix for FPU instructions,
let the cpu handle it to generate a SIGILL. */
/* case PREFIX_LOCK: */
- /* rep.. prefixes have no meaning for FPU instructions */
- case PREFIX_REPE:
- case PREFIX_REPNE:
-
- do_next_byte:
- ip++;
- RE_ENTRANT_CHECK_OFF;
- FPU_code_access_ok(1);
- FPU_get_user(byte, ip);
- RE_ENTRANT_CHECK_ON;
- break;
- case FWAIT_OPCODE:
- *Byte = byte;
- return 1;
- default:
- if ( (byte & 0xf8) == 0xd8 )
- {
- *Byte = byte;
- *fpu_eip = ip;
- return 1;
- }
- else
- {
- /* Not a valid sequence of prefix bytes followed by
- an FPU instruction. */
- *Byte = byte; /* Needed for error message. */
- return 0;
- }
+ /* rep.. prefixes have no meaning for FPU instructions */
+ case PREFIX_REPE:
+ case PREFIX_REPNE:
+
+ do_next_byte:
+ ip++;
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_access_ok(1);
+ FPU_get_user(byte, ip);
+ RE_ENTRANT_CHECK_ON;
+ break;
+ case FWAIT_OPCODE:
+ *Byte = byte;
+ return 1;
+ default:
+ if ((byte & 0xf8) == 0xd8) {
+ *Byte = byte;
+ *fpu_eip = ip;
+ return 1;
+ } else {
+ /* Not a valid sequence of prefix bytes followed by
+ an FPU instruction. */
+ *Byte = byte; /* Needed for error message. */
+ return 0;
+ }
+ }
}
- }
}
-
-void math_abort(struct info * info, unsigned int signal)
+void math_abort(struct info *info, unsigned int signal)
{
FPU_EIP = FPU_ORIG_EIP;
current->thread.trap_no = 16;
current->thread.error_code = 0;
- send_sig(signal,current,1);
+ send_sig(signal, current, 1);
RE_ENTRANT_CHECK_OFF;
- __asm__("movl %0,%%esp ; ret": :"g" (((long) info)-4));
+ __asm__("movl %0,%%esp ; ret": :"g"(((long)info) - 4));
#ifdef PARANOID
- printk("ERROR: wm-FPU-emu math_abort failed!\n");
+ printk("ERROR: wm-FPU-emu math_abort failed!\n");
#endif /* PARANOID */
}
-
-
#define S387 ((struct i387_soft_struct *)s387)
#define sstatus_word() \
((S387->swd & ~SW_Top & 0xffff) | ((S387->ftop << SW_Top_Shift) & SW_Top))
-int restore_i387_soft(void *s387, struct _fpstate __user *buf)
+int restore_i387_soft(void *s387, struct _fpstate __user * buf)
{
- u_char __user *d = (u_char __user *)buf;
- int offset, other, i, tags, regnr, tag, newtop;
-
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_READ, d, 7*4 + 8*10);
- if (__copy_from_user(&S387->cwd, d, 7*4))
- return -1;
- RE_ENTRANT_CHECK_ON;
-
- d += 7*4;
-
- S387->ftop = (S387->swd >> SW_Top_Shift) & 7;
- offset = (S387->ftop & 7) * 10;
- other = 80 - offset;
-
- RE_ENTRANT_CHECK_OFF;
- /* Copy all registers in stack order. */
- if (__copy_from_user(((u_char *)&S387->st_space)+offset, d, other))
- return -1;
- if ( offset )
- if (__copy_from_user((u_char *)&S387->st_space, d+other, offset))
- return -1;
- RE_ENTRANT_CHECK_ON;
-
- /* The tags may need to be corrected now. */
- tags = S387->twd;
- newtop = S387->ftop;
- for ( i = 0; i < 8; i++ )
- {
- regnr = (i+newtop) & 7;
- if ( ((tags >> ((regnr & 7)*2)) & 3) != TAG_Empty )
- {
- /* The loaded data over-rides all other cases. */
- tag = FPU_tagof((FPU_REG *)((u_char *)S387->st_space + 10*regnr));
- tags &= ~(3 << (regnr*2));
- tags |= (tag & 3) << (regnr*2);
+ u_char __user *d = (u_char __user *) buf;
+ int offset, other, i, tags, regnr, tag, newtop;
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_READ, d, 7 * 4 + 8 * 10);
+ if (__copy_from_user(&S387->cwd, d, 7 * 4))
+ return -1;
+ RE_ENTRANT_CHECK_ON;
+
+ d += 7 * 4;
+
+ S387->ftop = (S387->swd >> SW_Top_Shift) & 7;
+ offset = (S387->ftop & 7) * 10;
+ other = 80 - offset;
+
+ RE_ENTRANT_CHECK_OFF;
+ /* Copy all registers in stack order. */
+ if (__copy_from_user(((u_char *) & S387->st_space) + offset, d, other))
+ return -1;
+ if (offset)
+ if (__copy_from_user
+ ((u_char *) & S387->st_space, d + other, offset))
+ return -1;
+ RE_ENTRANT_CHECK_ON;
+
+ /* The tags may need to be corrected now. */
+ tags = S387->twd;
+ newtop = S387->ftop;
+ for (i = 0; i < 8; i++) {
+ regnr = (i + newtop) & 7;
+ if (((tags >> ((regnr & 7) * 2)) & 3) != TAG_Empty) {
+ /* The loaded data over-rides all other cases. */
+ tag =
+ FPU_tagof((FPU_REG *) ((u_char *) S387->st_space +
+ 10 * regnr));
+ tags &= ~(3 << (regnr * 2));
+ tags |= (tag & 3) << (regnr * 2);
+ }
}
- }
- S387->twd = tags;
+ S387->twd = tags;
- return 0;
+ return 0;
}
-
int save_i387_soft(void *s387, struct _fpstate __user * buf)
{
- u_char __user *d = (u_char __user *)buf;
- int offset = (S387->ftop & 7) * 10, other = 80 - offset;
+ u_char __user *d = (u_char __user *) buf;
+ int offset = (S387->ftop & 7) * 10, other = 80 - offset;
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_WRITE, d, 7*4 + 8*10);
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_WRITE, d, 7 * 4 + 8 * 10);
#ifdef PECULIAR_486
- S387->cwd &= ~0xe080;
- /* An 80486 sets nearly all of the reserved bits to 1. */
- S387->cwd |= 0xffff0040;
- S387->swd = sstatus_word() | 0xffff0000;
- S387->twd |= 0xffff0000;
- S387->fcs &= ~0xf8000000;
- S387->fos |= 0xffff0000;
+ S387->cwd &= ~0xe080;
+ /* An 80486 sets nearly all of the reserved bits to 1. */
+ S387->cwd |= 0xffff0040;
+ S387->swd = sstatus_word() | 0xffff0000;
+ S387->twd |= 0xffff0000;
+ S387->fcs &= ~0xf8000000;
+ S387->fos |= 0xffff0000;
#endif /* PECULIAR_486 */
- if (__copy_to_user(d, &S387->cwd, 7*4))
- return -1;
- RE_ENTRANT_CHECK_ON;
-
- d += 7*4;
-
- RE_ENTRANT_CHECK_OFF;
- /* Copy all registers in stack order. */
- if (__copy_to_user(d, ((u_char *)&S387->st_space)+offset, other))
- return -1;
- if ( offset )
- if (__copy_to_user(d+other, (u_char *)&S387->st_space, offset))
- return -1;
- RE_ENTRANT_CHECK_ON;
-
- return 1;
+ if (__copy_to_user(d, &S387->cwd, 7 * 4))
+ return -1;
+ RE_ENTRANT_CHECK_ON;
+
+ d += 7 * 4;
+
+ RE_ENTRANT_CHECK_OFF;
+ /* Copy all registers in stack order. */
+ if (__copy_to_user(d, ((u_char *) & S387->st_space) + offset, other))
+ return -1;
+ if (offset)
+ if (__copy_to_user
+ (d + other, (u_char *) & S387->st_space, offset))
+ return -1;
+ RE_ENTRANT_CHECK_ON;
+
+ return 1;
}
diff --git a/arch/x86/math-emu/fpu_etc.c b/arch/x86/math-emu/fpu_etc.c
index e3b5d465587f..e73631e0cde9 100644
--- a/arch/x86/math-emu/fpu_etc.c
+++ b/arch/x86/math-emu/fpu_etc.c
@@ -16,128 +16,115 @@
#include "status_w.h"
#include "reg_constant.h"
-
-static void fchs(FPU_REG *st0_ptr, u_char st0tag)
+static void fchs(FPU_REG * st0_ptr, u_char st0tag)
{
- if ( st0tag ^ TAG_Empty )
- {
- signbyte(st0_ptr) ^= SIGN_NEG;
- clear_C1();
- }
- else
- FPU_stack_underflow();
+ if (st0tag ^ TAG_Empty) {
+ signbyte(st0_ptr) ^= SIGN_NEG;
+ clear_C1();
+ } else
+ FPU_stack_underflow();
}
-
-static void fabs(FPU_REG *st0_ptr, u_char st0tag)
+static void fabs(FPU_REG * st0_ptr, u_char st0tag)
{
- if ( st0tag ^ TAG_Empty )
- {
- setpositive(st0_ptr);
- clear_C1();
- }
- else
- FPU_stack_underflow();
+ if (st0tag ^ TAG_Empty) {
+ setpositive(st0_ptr);
+ clear_C1();
+ } else
+ FPU_stack_underflow();
}
-
-static void ftst_(FPU_REG *st0_ptr, u_char st0tag)
+static void ftst_(FPU_REG * st0_ptr, u_char st0tag)
{
- switch (st0tag)
- {
- case TAG_Zero:
- setcc(SW_C3);
- break;
- case TAG_Valid:
- if (getsign(st0_ptr) == SIGN_POS)
- setcc(0);
- else
- setcc(SW_C0);
- break;
- case TAG_Special:
- switch ( FPU_Special(st0_ptr) )
- {
- case TW_Denormal:
- if (getsign(st0_ptr) == SIGN_POS)
- setcc(0);
- else
- setcc(SW_C0);
- if ( denormal_operand() < 0 )
- {
-#ifdef PECULIAR_486
- /* This is weird! */
- if (getsign(st0_ptr) == SIGN_POS)
+ switch (st0tag) {
+ case TAG_Zero:
setcc(SW_C3);
+ break;
+ case TAG_Valid:
+ if (getsign(st0_ptr) == SIGN_POS)
+ setcc(0);
+ else
+ setcc(SW_C0);
+ break;
+ case TAG_Special:
+ switch (FPU_Special(st0_ptr)) {
+ case TW_Denormal:
+ if (getsign(st0_ptr) == SIGN_POS)
+ setcc(0);
+ else
+ setcc(SW_C0);
+ if (denormal_operand() < 0) {
+#ifdef PECULIAR_486
+ /* This is weird! */
+ if (getsign(st0_ptr) == SIGN_POS)
+ setcc(SW_C3);
#endif /* PECULIAR_486 */
- return;
- }
- break;
- case TW_NaN:
- setcc(SW_C0|SW_C2|SW_C3); /* Operand is not comparable */
- EXCEPTION(EX_Invalid);
- break;
- case TW_Infinity:
- if (getsign(st0_ptr) == SIGN_POS)
- setcc(0);
- else
- setcc(SW_C0);
- break;
- default:
- setcc(SW_C0|SW_C2|SW_C3); /* Operand is not comparable */
- EXCEPTION(EX_INTERNAL|0x14);
- break;
+ return;
+ }
+ break;
+ case TW_NaN:
+ setcc(SW_C0 | SW_C2 | SW_C3); /* Operand is not comparable */
+ EXCEPTION(EX_Invalid);
+ break;
+ case TW_Infinity:
+ if (getsign(st0_ptr) == SIGN_POS)
+ setcc(0);
+ else
+ setcc(SW_C0);
+ break;
+ default:
+ setcc(SW_C0 | SW_C2 | SW_C3); /* Operand is not comparable */
+ EXCEPTION(EX_INTERNAL | 0x14);
+ break;
+ }
+ break;
+ case TAG_Empty:
+ setcc(SW_C0 | SW_C2 | SW_C3);
+ EXCEPTION(EX_StackUnder);
+ break;
}
- break;
- case TAG_Empty:
- setcc(SW_C0|SW_C2|SW_C3);
- EXCEPTION(EX_StackUnder);
- break;
- }
}
-
-static void fxam(FPU_REG *st0_ptr, u_char st0tag)
+static void fxam(FPU_REG * st0_ptr, u_char st0tag)
{
- int c = 0;
- switch (st0tag)
- {
- case TAG_Empty:
- c = SW_C3|SW_C0;
- break;
- case TAG_Zero:
- c = SW_C3;
- break;
- case TAG_Valid:
- c = SW_C2;
- break;
- case TAG_Special:
- switch ( FPU_Special(st0_ptr) )
- {
- case TW_Denormal:
- c = SW_C2|SW_C3; /* Denormal */
- break;
- case TW_NaN:
- /* We also use NaN for unsupported types. */
- if ( (st0_ptr->sigh & 0x80000000) && (exponent(st0_ptr) == EXP_OVER) )
- c = SW_C0;
- break;
- case TW_Infinity:
- c = SW_C2|SW_C0;
- break;
+ int c = 0;
+ switch (st0tag) {
+ case TAG_Empty:
+ c = SW_C3 | SW_C0;
+ break;
+ case TAG_Zero:
+ c = SW_C3;
+ break;
+ case TAG_Valid:
+ c = SW_C2;
+ break;
+ case TAG_Special:
+ switch (FPU_Special(st0_ptr)) {
+ case TW_Denormal:
+ c = SW_C2 | SW_C3; /* Denormal */
+ break;
+ case TW_NaN:
+ /* We also use NaN for unsupported types. */
+ if ((st0_ptr->sigh & 0x80000000)
+ && (exponent(st0_ptr) == EXP_OVER))
+ c = SW_C0;
+ break;
+ case TW_Infinity:
+ c = SW_C2 | SW_C0;
+ break;
+ }
}
- }
- if ( getsign(st0_ptr) == SIGN_NEG )
- c |= SW_C1;
- setcc(c);
+ if (getsign(st0_ptr) == SIGN_NEG)
+ c |= SW_C1;
+ setcc(c);
}
-
static FUNC_ST0 const fp_etc_table[] = {
- fchs, fabs, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal,
- ftst_, fxam, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal
+ fchs, fabs, (FUNC_ST0) FPU_illegal, (FUNC_ST0) FPU_illegal,
+ ftst_, fxam, (FUNC_ST0) FPU_illegal, (FUNC_ST0) FPU_illegal
};
void FPU_etc(void)
{
- (fp_etc_table[FPU_rm])(&st(0), FPU_gettag0());
+ (fp_etc_table[FPU_rm]) (&st(0), FPU_gettag0());
}
diff --git a/arch/x86/math-emu/fpu_proto.h b/arch/x86/math-emu/fpu_proto.h
index 37a8a7fe7e2b..0f6384102afd 100644
--- a/arch/x86/math-emu/fpu_proto.h
+++ b/arch/x86/math-emu/fpu_proto.h
@@ -5,7 +5,7 @@
extern void FPU_illegal(void);
extern void FPU_printall(void);
asmlinkage void FPU_exception(int n);
-extern int real_1op_NaN(FPU_REG *a);
+extern int real_1op_NaN(FPU_REG * a);
extern int real_2op_NaN(FPU_REG const *b, u_char tagb, int deststnr,
FPU_REG const *defaultNaN);
asmlinkage int arith_invalid(int deststnr);
@@ -14,8 +14,8 @@ extern int set_precision_flag(int flags);
asmlinkage void set_precision_flag_up(void);
asmlinkage void set_precision_flag_down(void);
asmlinkage int denormal_operand(void);
-asmlinkage int arith_overflow(FPU_REG *dest);
-asmlinkage int arith_underflow(FPU_REG *dest);
+asmlinkage int arith_overflow(FPU_REG * dest);
+asmlinkage int arith_underflow(FPU_REG * dest);
extern void FPU_stack_overflow(void);
extern void FPU_stack_underflow(void);
extern void FPU_stack_underflow_i(int i);
@@ -66,7 +66,7 @@ extern int FPU_Special(FPU_REG const *ptr);
extern int isNaN(FPU_REG const *ptr);
extern void FPU_pop(void);
extern int FPU_empty_i(int stnr);
-extern int FPU_stackoverflow(FPU_REG **st_new_ptr);
+extern int FPU_stackoverflow(FPU_REG ** st_new_ptr);
extern void FPU_copy_to_regi(FPU_REG const *r, u_char tag, int stnr);
extern void FPU_copy_to_reg1(FPU_REG const *r, u_char tag);
extern void FPU_copy_to_reg0(FPU_REG const *r, u_char tag);
@@ -75,26 +75,28 @@ extern void FPU_triga(void);
extern void FPU_trigb(void);
/* get_address.c */
extern void __user *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip,
- struct address *addr, fpu_addr_modes addr_modes);
+ struct address *addr,
+ fpu_addr_modes addr_modes);
extern void __user *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
- struct address *addr, fpu_addr_modes addr_modes);
+ struct address *addr,
+ fpu_addr_modes addr_modes);
/* load_store.c */
extern int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
- void __user *data_address);
+ void __user * data_address);
/* poly_2xm1.c */
-extern int poly_2xm1(u_char sign, FPU_REG *arg, FPU_REG *result);
+extern int poly_2xm1(u_char sign, FPU_REG * arg, FPU_REG * result);
/* poly_atan.c */
-extern void poly_atan(FPU_REG *st0_ptr, u_char st0_tag, FPU_REG *st1_ptr,
+extern void poly_atan(FPU_REG * st0_ptr, u_char st0_tag, FPU_REG * st1_ptr,
u_char st1_tag);
/* poly_l2.c */
-extern void poly_l2(FPU_REG *st0_ptr, FPU_REG *st1_ptr, u_char st1_sign);
-extern int poly_l2p1(u_char s0, u_char s1, FPU_REG *r0, FPU_REG *r1,
- FPU_REG *d);
+extern void poly_l2(FPU_REG * st0_ptr, FPU_REG * st1_ptr, u_char st1_sign);
+extern int poly_l2p1(u_char s0, u_char s1, FPU_REG * r0, FPU_REG * r1,
+ FPU_REG * d);
/* poly_sin.c */
-extern void poly_sine(FPU_REG *st0_ptr);
-extern void poly_cos(FPU_REG *st0_ptr);
+extern void poly_sine(FPU_REG * st0_ptr);
+extern void poly_cos(FPU_REG * st0_ptr);
/* poly_tan.c */
-extern void poly_tan(FPU_REG *st0_ptr);
+extern void poly_tan(FPU_REG * st0_ptr);
/* reg_add_sub.c */
extern int FPU_add(FPU_REG const *b, u_char tagb, int destrnr, int control_w);
extern int FPU_sub(int flags, int rm, int control_w);
@@ -109,32 +111,34 @@ extern void fucompp(void);
/* reg_constant.c */
extern void fconst(void);
/* reg_ld_str.c */
-extern int FPU_load_extended(long double __user *s, int stnr);
-extern int FPU_load_double(double __user *dfloat, FPU_REG *loaded_data);
-extern int FPU_load_single(float __user *single, FPU_REG *loaded_data);
-extern int FPU_load_int64(long long __user *_s);
-extern int FPU_load_int32(long __user *_s, FPU_REG *loaded_data);
-extern int FPU_load_int16(short __user *_s, FPU_REG *loaded_data);
-extern int FPU_load_bcd(u_char __user *s);
-extern int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag,
- long double __user *d);
-extern int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double __user *dfloat);
-extern int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float __user *single);
-extern int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long __user *d);
-extern int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long __user *d);
-extern int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short __user *d);
-extern int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char __user *d);
-extern int FPU_round_to_int(FPU_REG *r, u_char tag);
-extern u_char __user *fldenv(fpu_addr_modes addr_modes, u_char __user *s);
-extern void frstor(fpu_addr_modes addr_modes, u_char __user *data_address);
-extern u_char __user *fstenv(fpu_addr_modes addr_modes, u_char __user *d);
-extern void fsave(fpu_addr_modes addr_modes, u_char __user *data_address);
-extern int FPU_tagof(FPU_REG *ptr);
+extern int FPU_load_extended(long double __user * s, int stnr);
+extern int FPU_load_double(double __user * dfloat, FPU_REG * loaded_data);
+extern int FPU_load_single(float __user * single, FPU_REG * loaded_data);
+extern int FPU_load_int64(long long __user * _s);
+extern int FPU_load_int32(long __user * _s, FPU_REG * loaded_data);
+extern int FPU_load_int16(short __user * _s, FPU_REG * loaded_data);
+extern int FPU_load_bcd(u_char __user * s);
+extern int FPU_store_extended(FPU_REG * st0_ptr, u_char st0_tag,
+ long double __user * d);
+extern int FPU_store_double(FPU_REG * st0_ptr, u_char st0_tag,
+ double __user * dfloat);
+extern int FPU_store_single(FPU_REG * st0_ptr, u_char st0_tag,
+ float __user * single);
+extern int FPU_store_int64(FPU_REG * st0_ptr, u_char st0_tag,
+ long long __user * d);
+extern int FPU_store_int32(FPU_REG * st0_ptr, u_char st0_tag, long __user * d);
+extern int FPU_store_int16(FPU_REG * st0_ptr, u_char st0_tag, short __user * d);
+extern int FPU_store_bcd(FPU_REG * st0_ptr, u_char st0_tag, u_char __user * d);
+extern int FPU_round_to_int(FPU_REG * r, u_char tag);
+extern u_char __user *fldenv(fpu_addr_modes addr_modes, u_char __user * s);
+extern void frstor(fpu_addr_modes addr_modes, u_char __user * data_address);
+extern u_char __user *fstenv(fpu_addr_modes addr_modes, u_char __user * d);
+extern void fsave(fpu_addr_modes addr_modes, u_char __user * data_address);
+extern int FPU_tagof(FPU_REG * ptr);
/* reg_mul.c */
extern int FPU_mul(FPU_REG const *b, u_char tagb, int deststnr, int control_w);
extern int FPU_div(int flags, int regrm, int control_w);
/* reg_convert.c */
-extern int FPU_to_exp16(FPU_REG const *a, FPU_REG *x);
+extern int FPU_to_exp16(FPU_REG const *a, FPU_REG * x);
#endif /* _FPU_PROTO_H */
-
diff --git a/arch/x86/math-emu/fpu_tags.c b/arch/x86/math-emu/fpu_tags.c
index cb436fe20e4c..d9c657cd7746 100644
--- a/arch/x86/math-emu/fpu_tags.c
+++ b/arch/x86/math-emu/fpu_tags.c
@@ -14,114 +14,102 @@
#include "fpu_system.h"
#include "exception.h"
-
void FPU_pop(void)
{
- fpu_tag_word |= 3 << ((top & 7)*2);
- top++;
+ fpu_tag_word |= 3 << ((top & 7) * 2);
+ top++;
}
-
int FPU_gettag0(void)
{
- return (fpu_tag_word >> ((top & 7)*2)) & 3;
+ return (fpu_tag_word >> ((top & 7) * 2)) & 3;
}
-
int FPU_gettagi(int stnr)
{
- return (fpu_tag_word >> (((top+stnr) & 7)*2)) & 3;
+ return (fpu_tag_word >> (((top + stnr) & 7) * 2)) & 3;
}
-
int FPU_gettag(int regnr)
{
- return (fpu_tag_word >> ((regnr & 7)*2)) & 3;
+ return (fpu_tag_word >> ((regnr & 7) * 2)) & 3;
}
-
void FPU_settag0(int tag)
{
- int regnr = top;
- regnr &= 7;
- fpu_tag_word &= ~(3 << (regnr*2));
- fpu_tag_word |= (tag & 3) << (regnr*2);
+ int regnr = top;
+ regnr &= 7;
+ fpu_tag_word &= ~(3 << (regnr * 2));
+ fpu_tag_word |= (tag & 3) << (regnr * 2);
}
-
void FPU_settagi(int stnr, int tag)
{
- int regnr = stnr+top;
- regnr &= 7;
- fpu_tag_word &= ~(3 << (regnr*2));
- fpu_tag_word |= (tag & 3) << (regnr*2);
+ int regnr = stnr + top;
+ regnr &= 7;
+ fpu_tag_word &= ~(3 << (regnr * 2));
+ fpu_tag_word |= (tag & 3) << (regnr * 2);
}
-
void FPU_settag(int regnr, int tag)
{
- regnr &= 7;
- fpu_tag_word &= ~(3 << (regnr*2));
- fpu_tag_word |= (tag & 3) << (regnr*2);
+ regnr &= 7;
+ fpu_tag_word &= ~(3 << (regnr * 2));
+ fpu_tag_word |= (tag & 3) << (regnr * 2);
}
-
int FPU_Special(FPU_REG const *ptr)
{
- int exp = exponent(ptr);
-
- if ( exp == EXP_BIAS+EXP_UNDER )
- return TW_Denormal;
- else if ( exp != EXP_BIAS+EXP_OVER )
- return TW_NaN;
- else if ( (ptr->sigh == 0x80000000) && (ptr->sigl == 0) )
- return TW_Infinity;
- return TW_NaN;
+ int exp = exponent(ptr);
+
+ if (exp == EXP_BIAS + EXP_UNDER)
+ return TW_Denormal;
+ else if (exp != EXP_BIAS + EXP_OVER)
+ return TW_NaN;
+ else if ((ptr->sigh == 0x80000000) && (ptr->sigl == 0))
+ return TW_Infinity;
+ return TW_NaN;
}
-
int isNaN(FPU_REG const *ptr)
{
- return ( (exponent(ptr) == EXP_BIAS+EXP_OVER)
- && !((ptr->sigh == 0x80000000) && (ptr->sigl == 0)) );
+ return ((exponent(ptr) == EXP_BIAS + EXP_OVER)
+ && !((ptr->sigh == 0x80000000) && (ptr->sigl == 0)));
}
-
int FPU_empty_i(int stnr)
{
- int regnr = (top+stnr) & 7;
+ int regnr = (top + stnr) & 7;
- return ((fpu_tag_word >> (regnr*2)) & 3) == TAG_Empty;
+ return ((fpu_tag_word >> (regnr * 2)) & 3) == TAG_Empty;
}
-
-int FPU_stackoverflow(FPU_REG **st_new_ptr)
+int FPU_stackoverflow(FPU_REG ** st_new_ptr)
{
- *st_new_ptr = &st(-1);
+ *st_new_ptr = &st(-1);
- return ((fpu_tag_word >> (((top - 1) & 7)*2)) & 3) != TAG_Empty;
+ return ((fpu_tag_word >> (((top - 1) & 7) * 2)) & 3) != TAG_Empty;
}
-
void FPU_copy_to_regi(FPU_REG const *r, u_char tag, int stnr)
{
- reg_copy(r, &st(stnr));
- FPU_settagi(stnr, tag);
+ reg_copy(r, &st(stnr));
+ FPU_settagi(stnr, tag);
}
void FPU_copy_to_reg1(FPU_REG const *r, u_char tag)
{
- reg_copy(r, &st(1));
- FPU_settagi(1, tag);
+ reg_copy(r, &st(1));
+ FPU_settagi(1, tag);
}
void FPU_copy_to_reg0(FPU_REG const *r, u_char tag)
{
- int regnr = top;
- regnr &= 7;
+ int regnr = top;
+ regnr &= 7;
- reg_copy(r, &st(0));
+ reg_copy(r, &st(0));
- fpu_tag_word &= ~(3 << (regnr*2));
- fpu_tag_word |= (tag & 3) << (regnr*2);
+ fpu_tag_word &= ~(3 << (regnr * 2));
+ fpu_tag_word |= (tag & 3) << (regnr * 2);
}
diff --git a/arch/x86/math-emu/fpu_trig.c b/arch/x86/math-emu/fpu_trig.c
index 403cbde1d425..e5316a288a6e 100644
--- a/arch/x86/math-emu/fpu_trig.c
+++ b/arch/x86/math-emu/fpu_trig.c
@@ -15,11 +15,10 @@
#include "fpu_emu.h"
#include "status_w.h"
#include "control_w.h"
-#include "reg_constant.h"
+#include "reg_constant.h"
static void rem_kernel(unsigned long long st0, unsigned long long *y,
- unsigned long long st1,
- unsigned long long q, int n);
+ unsigned long long st1, unsigned long long q, int n);
#define BETTER_THAN_486
@@ -31,790 +30,708 @@ static void rem_kernel(unsigned long long st0, unsigned long long *y,
/* Limited measurements show no results worse than 64 bit precision
except for the results for arguments close to 2^63, where the
precision of the result sometimes degrades to about 63.9 bits */
-static int trig_arg(FPU_REG *st0_ptr, int even)
+static int trig_arg(FPU_REG * st0_ptr, int even)
{
- FPU_REG tmp;
- u_char tmptag;
- unsigned long long q;
- int old_cw = control_word, saved_status = partial_status;
- int tag, st0_tag = TAG_Valid;
-
- if ( exponent(st0_ptr) >= 63 )
- {
- partial_status |= SW_C2; /* Reduction incomplete. */
- return -1;
- }
-
- control_word &= ~CW_RC;
- control_word |= RC_CHOP;
-
- setpositive(st0_ptr);
- tag = FPU_u_div(st0_ptr, &CONST_PI2, &tmp, PR_64_BITS | RC_CHOP | 0x3f,
- SIGN_POS);
-
- FPU_round_to_int(&tmp, tag); /* Fortunately, this can't overflow
- to 2^64 */
- q = significand(&tmp);
- if ( q )
- {
- rem_kernel(significand(st0_ptr),
- &significand(&tmp),
- significand(&CONST_PI2),
- q, exponent(st0_ptr) - exponent(&CONST_PI2));
- setexponent16(&tmp, exponent(&CONST_PI2));
- st0_tag = FPU_normalize(&tmp);
- FPU_copy_to_reg0(&tmp, st0_tag);
- }
-
- if ( (even && !(q & 1)) || (!even && (q & 1)) )
- {
- st0_tag = FPU_sub(REV|LOADED|TAG_Valid, (int)&CONST_PI2, FULL_PRECISION);
+ FPU_REG tmp;
+ u_char tmptag;
+ unsigned long long q;
+ int old_cw = control_word, saved_status = partial_status;
+ int tag, st0_tag = TAG_Valid;
+
+ if (exponent(st0_ptr) >= 63) {
+ partial_status |= SW_C2; /* Reduction incomplete. */
+ return -1;
+ }
-#ifdef BETTER_THAN_486
- /* So far, the results are exact but based upon a 64 bit
- precision approximation to pi/2. The technique used
- now is equivalent to using an approximation to pi/2 which
- is accurate to about 128 bits. */
- if ( (exponent(st0_ptr) <= exponent(&CONST_PI2extra) + 64) || (q > 1) )
- {
- /* This code gives the effect of having pi/2 to better than
- 128 bits precision. */
-
- significand(&tmp) = q + 1;
- setexponent16(&tmp, 63);
- FPU_normalize(&tmp);
- tmptag =
- FPU_u_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION, SIGN_POS,
- exponent(&CONST_PI2extra) + exponent(&tmp));
- setsign(&tmp, getsign(&CONST_PI2extra));
- st0_tag = FPU_add(&tmp, tmptag, 0, FULL_PRECISION);
- if ( signnegative(st0_ptr) )
- {
- /* CONST_PI2extra is negative, so the result of the addition
- can be negative. This means that the argument is actually
- in a different quadrant. The correction is always < pi/2,
- so it can't overflow into yet another quadrant. */
- setpositive(st0_ptr);
- q++;
- }
+ control_word &= ~CW_RC;
+ control_word |= RC_CHOP;
+
+ setpositive(st0_ptr);
+ tag = FPU_u_div(st0_ptr, &CONST_PI2, &tmp, PR_64_BITS | RC_CHOP | 0x3f,
+ SIGN_POS);
+
+ FPU_round_to_int(&tmp, tag); /* Fortunately, this can't overflow
+ to 2^64 */
+ q = significand(&tmp);
+ if (q) {
+ rem_kernel(significand(st0_ptr),
+ &significand(&tmp),
+ significand(&CONST_PI2),
+ q, exponent(st0_ptr) - exponent(&CONST_PI2));
+ setexponent16(&tmp, exponent(&CONST_PI2));
+ st0_tag = FPU_normalize(&tmp);
+ FPU_copy_to_reg0(&tmp, st0_tag);
}
+
+ if ((even && !(q & 1)) || (!even && (q & 1))) {
+ st0_tag =
+ FPU_sub(REV | LOADED | TAG_Valid, (int)&CONST_PI2,
+ FULL_PRECISION);
+
+#ifdef BETTER_THAN_486
+ /* So far, the results are exact but based upon a 64 bit
+ precision approximation to pi/2. The technique used
+ now is equivalent to using an approximation to pi/2 which
+ is accurate to about 128 bits. */
+ if ((exponent(st0_ptr) <= exponent(&CONST_PI2extra) + 64)
+ || (q > 1)) {
+ /* This code gives the effect of having pi/2 to better than
+ 128 bits precision. */
+
+ significand(&tmp) = q + 1;
+ setexponent16(&tmp, 63);
+ FPU_normalize(&tmp);
+ tmptag =
+ FPU_u_mul(&CONST_PI2extra, &tmp, &tmp,
+ FULL_PRECISION, SIGN_POS,
+ exponent(&CONST_PI2extra) +
+ exponent(&tmp));
+ setsign(&tmp, getsign(&CONST_PI2extra));
+ st0_tag = FPU_add(&tmp, tmptag, 0, FULL_PRECISION);
+ if (signnegative(st0_ptr)) {
+ /* CONST_PI2extra is negative, so the result of the addition
+ can be negative. This means that the argument is actually
+ in a different quadrant. The correction is always < pi/2,
+ so it can't overflow into yet another quadrant. */
+ setpositive(st0_ptr);
+ q++;
+ }
+ }
#endif /* BETTER_THAN_486 */
- }
+ }
#ifdef BETTER_THAN_486
- else
- {
- /* So far, the results are exact but based upon a 64 bit
- precision approximation to pi/2. The technique used
- now is equivalent to using an approximation to pi/2 which
- is accurate to about 128 bits. */
- if ( ((q > 0) && (exponent(st0_ptr) <= exponent(&CONST_PI2extra) + 64))
- || (q > 1) )
- {
- /* This code gives the effect of having p/2 to better than
- 128 bits precision. */
-
- significand(&tmp) = q;
- setexponent16(&tmp, 63);
- FPU_normalize(&tmp); /* This must return TAG_Valid */
- tmptag = FPU_u_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION,
- SIGN_POS,
- exponent(&CONST_PI2extra) + exponent(&tmp));
- setsign(&tmp, getsign(&CONST_PI2extra));
- st0_tag = FPU_sub(LOADED|(tmptag & 0x0f), (int)&tmp,
- FULL_PRECISION);
- if ( (exponent(st0_ptr) == exponent(&CONST_PI2)) &&
- ((st0_ptr->sigh > CONST_PI2.sigh)
- || ((st0_ptr->sigh == CONST_PI2.sigh)
- && (st0_ptr->sigl > CONST_PI2.sigl))) )
- {
- /* CONST_PI2extra is negative, so the result of the
- subtraction can be larger than pi/2. This means
- that the argument is actually in a different quadrant.
- The correction is always < pi/2, so it can't overflow
- into yet another quadrant. */
- st0_tag = FPU_sub(REV|LOADED|TAG_Valid, (int)&CONST_PI2,
- FULL_PRECISION);
- q++;
- }
+ else {
+ /* So far, the results are exact but based upon a 64 bit
+ precision approximation to pi/2. The technique used
+ now is equivalent to using an approximation to pi/2 which
+ is accurate to about 128 bits. */
+ if (((q > 0)
+ && (exponent(st0_ptr) <= exponent(&CONST_PI2extra) + 64))
+ || (q > 1)) {
+ /* This code gives the effect of having p/2 to better than
+ 128 bits precision. */
+
+ significand(&tmp) = q;
+ setexponent16(&tmp, 63);
+ FPU_normalize(&tmp); /* This must return TAG_Valid */
+ tmptag =
+ FPU_u_mul(&CONST_PI2extra, &tmp, &tmp,
+ FULL_PRECISION, SIGN_POS,
+ exponent(&CONST_PI2extra) +
+ exponent(&tmp));
+ setsign(&tmp, getsign(&CONST_PI2extra));
+ st0_tag = FPU_sub(LOADED | (tmptag & 0x0f), (int)&tmp,
+ FULL_PRECISION);
+ if ((exponent(st0_ptr) == exponent(&CONST_PI2)) &&
+ ((st0_ptr->sigh > CONST_PI2.sigh)
+ || ((st0_ptr->sigh == CONST_PI2.sigh)
+ && (st0_ptr->sigl > CONST_PI2.sigl)))) {
+ /* CONST_PI2extra is negative, so the result of the
+ subtraction can be larger than pi/2. This means
+ that the argument is actually in a different quadrant.
+ The correction is always < pi/2, so it can't overflow
+ into yet another quadrant. */
+ st0_tag =
+ FPU_sub(REV | LOADED | TAG_Valid,
+ (int)&CONST_PI2, FULL_PRECISION);
+ q++;
+ }
+ }
}
- }
#endif /* BETTER_THAN_486 */
- FPU_settag0(st0_tag);
- control_word = old_cw;
- partial_status = saved_status & ~SW_C2; /* Reduction complete. */
+ FPU_settag0(st0_tag);
+ control_word = old_cw;
+ partial_status = saved_status & ~SW_C2; /* Reduction complete. */
- return (q & 3) | even;
+ return (q & 3) | even;
}
-
/* Convert a long to register */
static void convert_l2reg(long const *arg, int deststnr)
{
- int tag;
- long num = *arg;
- u_char sign;
- FPU_REG *dest = &st(deststnr);
-
- if (num == 0)
- {
- FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
- return;
- }
-
- if (num > 0)
- { sign = SIGN_POS; }
- else
- { num = -num; sign = SIGN_NEG; }
-
- dest->sigh = num;
- dest->sigl = 0;
- setexponent16(dest, 31);
- tag = FPU_normalize(dest);
- FPU_settagi(deststnr, tag);
- setsign(dest, sign);
- return;
-}
+ int tag;
+ long num = *arg;
+ u_char sign;
+ FPU_REG *dest = &st(deststnr);
+ if (num == 0) {
+ FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+ return;
+ }
+
+ if (num > 0) {
+ sign = SIGN_POS;
+ } else {
+ num = -num;
+ sign = SIGN_NEG;
+ }
-static void single_arg_error(FPU_REG *st0_ptr, u_char st0_tag)
+ dest->sigh = num;
+ dest->sigl = 0;
+ setexponent16(dest, 31);
+ tag = FPU_normalize(dest);
+ FPU_settagi(deststnr, tag);
+ setsign(dest, sign);
+ return;
+}
+
+static void single_arg_error(FPU_REG * st0_ptr, u_char st0_tag)
{
- if ( st0_tag == TAG_Empty )
- FPU_stack_underflow(); /* Puts a QNaN in st(0) */
- else if ( st0_tag == TW_NaN )
- real_1op_NaN(st0_ptr); /* return with a NaN in st(0) */
+ if (st0_tag == TAG_Empty)
+ FPU_stack_underflow(); /* Puts a QNaN in st(0) */
+ else if (st0_tag == TW_NaN)
+ real_1op_NaN(st0_ptr); /* return with a NaN in st(0) */
#ifdef PARANOID
- else
- EXCEPTION(EX_INTERNAL|0x0112);
+ else
+ EXCEPTION(EX_INTERNAL | 0x0112);
#endif /* PARANOID */
}
-
-static void single_arg_2_error(FPU_REG *st0_ptr, u_char st0_tag)
+static void single_arg_2_error(FPU_REG * st0_ptr, u_char st0_tag)
{
- int isNaN;
-
- switch ( st0_tag )
- {
- case TW_NaN:
- isNaN = (exponent(st0_ptr) == EXP_OVER) && (st0_ptr->sigh & 0x80000000);
- if ( isNaN && !(st0_ptr->sigh & 0x40000000) ) /* Signaling ? */
- {
- EXCEPTION(EX_Invalid);
- if ( control_word & CW_Invalid )
- {
- /* The masked response */
- /* Convert to a QNaN */
- st0_ptr->sigh |= 0x40000000;
- push();
- FPU_copy_to_reg0(st0_ptr, TAG_Special);
- }
- }
- else if ( isNaN )
- {
- /* A QNaN */
- push();
- FPU_copy_to_reg0(st0_ptr, TAG_Special);
- }
- else
- {
- /* pseudoNaN or other unsupported */
- EXCEPTION(EX_Invalid);
- if ( control_word & CW_Invalid )
- {
- /* The masked response */
- FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
- push();
- FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
- }
- }
- break; /* return with a NaN in st(0) */
+ int isNaN;
+
+ switch (st0_tag) {
+ case TW_NaN:
+ isNaN = (exponent(st0_ptr) == EXP_OVER)
+ && (st0_ptr->sigh & 0x80000000);
+ if (isNaN && !(st0_ptr->sigh & 0x40000000)) { /* Signaling ? */
+ EXCEPTION(EX_Invalid);
+ if (control_word & CW_Invalid) {
+ /* The masked response */
+ /* Convert to a QNaN */
+ st0_ptr->sigh |= 0x40000000;
+ push();
+ FPU_copy_to_reg0(st0_ptr, TAG_Special);
+ }
+ } else if (isNaN) {
+ /* A QNaN */
+ push();
+ FPU_copy_to_reg0(st0_ptr, TAG_Special);
+ } else {
+ /* pseudoNaN or other unsupported */
+ EXCEPTION(EX_Invalid);
+ if (control_word & CW_Invalid) {
+ /* The masked response */
+ FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
+ push();
+ FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
+ }
+ }
+ break; /* return with a NaN in st(0) */
#ifdef PARANOID
- default:
- EXCEPTION(EX_INTERNAL|0x0112);
+ default:
+ EXCEPTION(EX_INTERNAL | 0x0112);
#endif /* PARANOID */
- }
+ }
}
-
/*---------------------------------------------------------------------------*/
-static void f2xm1(FPU_REG *st0_ptr, u_char tag)
+static void f2xm1(FPU_REG * st0_ptr, u_char tag)
{
- FPU_REG a;
+ FPU_REG a;
- clear_C1();
+ clear_C1();
- if ( tag == TAG_Valid )
- {
- /* For an 80486 FPU, the result is undefined if the arg is >= 1.0 */
- if ( exponent(st0_ptr) < 0 )
- {
- denormal_arg:
+ if (tag == TAG_Valid) {
+ /* For an 80486 FPU, the result is undefined if the arg is >= 1.0 */
+ if (exponent(st0_ptr) < 0) {
+ denormal_arg:
- FPU_to_exp16(st0_ptr, &a);
+ FPU_to_exp16(st0_ptr, &a);
- /* poly_2xm1(x) requires 0 < st(0) < 1. */
- poly_2xm1(getsign(st0_ptr), &a, st0_ptr);
+ /* poly_2xm1(x) requires 0 < st(0) < 1. */
+ poly_2xm1(getsign(st0_ptr), &a, st0_ptr);
+ }
+ set_precision_flag_up(); /* 80486 appears to always do this */
+ return;
}
- set_precision_flag_up(); /* 80486 appears to always do this */
- return;
- }
- if ( tag == TAG_Zero )
- return;
+ if (tag == TAG_Zero)
+ return;
- if ( tag == TAG_Special )
- tag = FPU_Special(st0_ptr);
+ if (tag == TAG_Special)
+ tag = FPU_Special(st0_ptr);
- switch ( tag )
- {
- case TW_Denormal:
- if ( denormal_operand() < 0 )
- return;
- goto denormal_arg;
- case TW_Infinity:
- if ( signnegative(st0_ptr) )
- {
- /* -infinity gives -1 (p16-10) */
- FPU_copy_to_reg0(&CONST_1, TAG_Valid);
- setnegative(st0_ptr);
+ switch (tag) {
+ case TW_Denormal:
+ if (denormal_operand() < 0)
+ return;
+ goto denormal_arg;
+ case TW_Infinity:
+ if (signnegative(st0_ptr)) {
+ /* -infinity gives -1 (p16-10) */
+ FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+ setnegative(st0_ptr);
+ }
+ return;
+ default:
+ single_arg_error(st0_ptr, tag);
}
- return;
- default:
- single_arg_error(st0_ptr, tag);
- }
}
-
-static void fptan(FPU_REG *st0_ptr, u_char st0_tag)
+static void fptan(FPU_REG * st0_ptr, u_char st0_tag)
{
- FPU_REG *st_new_ptr;
- int q;
- u_char arg_sign = getsign(st0_ptr);
-
- /* Stack underflow has higher priority */
- if ( st0_tag == TAG_Empty )
- {
- FPU_stack_underflow(); /* Puts a QNaN in st(0) */
- if ( control_word & CW_Invalid )
- {
- st_new_ptr = &st(-1);
- push();
- FPU_stack_underflow(); /* Puts a QNaN in the new st(0) */
+ FPU_REG *st_new_ptr;
+ int q;
+ u_char arg_sign = getsign(st0_ptr);
+
+ /* Stack underflow has higher priority */
+ if (st0_tag == TAG_Empty) {
+ FPU_stack_underflow(); /* Puts a QNaN in st(0) */
+ if (control_word & CW_Invalid) {
+ st_new_ptr = &st(-1);
+ push();
+ FPU_stack_underflow(); /* Puts a QNaN in the new st(0) */
+ }
+ return;
}
- return;
- }
-
- if ( STACK_OVERFLOW )
- { FPU_stack_overflow(); return; }
-
- if ( st0_tag == TAG_Valid )
- {
- if ( exponent(st0_ptr) > -40 )
- {
- if ( (q = trig_arg(st0_ptr, 0)) == -1 )
- {
- /* Operand is out of range */
- return;
- }
-
- poly_tan(st0_ptr);
- setsign(st0_ptr, (q & 1) ^ (arg_sign != 0));
- set_precision_flag_up(); /* We do not really know if up or down */
+
+ if (STACK_OVERFLOW) {
+ FPU_stack_overflow();
+ return;
}
- else
- {
- /* For a small arg, the result == the argument */
- /* Underflow may happen */
- denormal_arg:
+ if (st0_tag == TAG_Valid) {
+ if (exponent(st0_ptr) > -40) {
+ if ((q = trig_arg(st0_ptr, 0)) == -1) {
+ /* Operand is out of range */
+ return;
+ }
+
+ poly_tan(st0_ptr);
+ setsign(st0_ptr, (q & 1) ^ (arg_sign != 0));
+ set_precision_flag_up(); /* We do not really know if up or down */
+ } else {
+ /* For a small arg, the result == the argument */
+ /* Underflow may happen */
+
+ denormal_arg:
+
+ FPU_to_exp16(st0_ptr, st0_ptr);
- FPU_to_exp16(st0_ptr, st0_ptr);
-
- st0_tag = FPU_round(st0_ptr, 1, 0, FULL_PRECISION, arg_sign);
- FPU_settag0(st0_tag);
+ st0_tag =
+ FPU_round(st0_ptr, 1, 0, FULL_PRECISION, arg_sign);
+ FPU_settag0(st0_tag);
+ }
+ push();
+ FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+ return;
}
- push();
- FPU_copy_to_reg0(&CONST_1, TAG_Valid);
- return;
- }
-
- if ( st0_tag == TAG_Zero )
- {
- push();
- FPU_copy_to_reg0(&CONST_1, TAG_Valid);
- setcc(0);
- return;
- }
-
- if ( st0_tag == TAG_Special )
- st0_tag = FPU_Special(st0_ptr);
-
- if ( st0_tag == TW_Denormal )
- {
- if ( denormal_operand() < 0 )
- return;
- goto denormal_arg;
- }
-
- if ( st0_tag == TW_Infinity )
- {
- /* The 80486 treats infinity as an invalid operand */
- if ( arith_invalid(0) >= 0 )
- {
- st_new_ptr = &st(-1);
- push();
- arith_invalid(0);
+ if (st0_tag == TAG_Zero) {
+ push();
+ FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+ setcc(0);
+ return;
+ }
+
+ if (st0_tag == TAG_Special)
+ st0_tag = FPU_Special(st0_ptr);
+
+ if (st0_tag == TW_Denormal) {
+ if (denormal_operand() < 0)
+ return;
+
+ goto denormal_arg;
}
- return;
- }
- single_arg_2_error(st0_ptr, st0_tag);
-}
+ if (st0_tag == TW_Infinity) {
+ /* The 80486 treats infinity as an invalid operand */
+ if (arith_invalid(0) >= 0) {
+ st_new_ptr = &st(-1);
+ push();
+ arith_invalid(0);
+ }
+ return;
+ }
+ single_arg_2_error(st0_ptr, st0_tag);
+}
-static void fxtract(FPU_REG *st0_ptr, u_char st0_tag)
+static void fxtract(FPU_REG * st0_ptr, u_char st0_tag)
{
- FPU_REG *st_new_ptr;
- u_char sign;
- register FPU_REG *st1_ptr = st0_ptr; /* anticipate */
-
- if ( STACK_OVERFLOW )
- { FPU_stack_overflow(); return; }
-
- clear_C1();
-
- if ( st0_tag == TAG_Valid )
- {
- long e;
-
- push();
- sign = getsign(st1_ptr);
- reg_copy(st1_ptr, st_new_ptr);
- setexponent16(st_new_ptr, exponent(st_new_ptr));
-
- denormal_arg:
-
- e = exponent16(st_new_ptr);
- convert_l2reg(&e, 1);
- setexponentpos(st_new_ptr, 0);
- setsign(st_new_ptr, sign);
- FPU_settag0(TAG_Valid); /* Needed if arg was a denormal */
- return;
- }
- else if ( st0_tag == TAG_Zero )
- {
- sign = getsign(st0_ptr);
-
- if ( FPU_divide_by_zero(0, SIGN_NEG) < 0 )
- return;
+ FPU_REG *st_new_ptr;
+ u_char sign;
+ register FPU_REG *st1_ptr = st0_ptr; /* anticipate */
- push();
- FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
- setsign(st_new_ptr, sign);
- return;
- }
+ if (STACK_OVERFLOW) {
+ FPU_stack_overflow();
+ return;
+ }
- if ( st0_tag == TAG_Special )
- st0_tag = FPU_Special(st0_ptr);
+ clear_C1();
- if ( st0_tag == TW_Denormal )
- {
- if (denormal_operand() < 0 )
- return;
+ if (st0_tag == TAG_Valid) {
+ long e;
- push();
- sign = getsign(st1_ptr);
- FPU_to_exp16(st1_ptr, st_new_ptr);
- goto denormal_arg;
- }
- else if ( st0_tag == TW_Infinity )
- {
- sign = getsign(st0_ptr);
- setpositive(st0_ptr);
- push();
- FPU_copy_to_reg0(&CONST_INF, TAG_Special);
- setsign(st_new_ptr, sign);
- return;
- }
- else if ( st0_tag == TW_NaN )
- {
- if ( real_1op_NaN(st0_ptr) < 0 )
- return;
+ push();
+ sign = getsign(st1_ptr);
+ reg_copy(st1_ptr, st_new_ptr);
+ setexponent16(st_new_ptr, exponent(st_new_ptr));
+
+ denormal_arg:
+
+ e = exponent16(st_new_ptr);
+ convert_l2reg(&e, 1);
+ setexponentpos(st_new_ptr, 0);
+ setsign(st_new_ptr, sign);
+ FPU_settag0(TAG_Valid); /* Needed if arg was a denormal */
+ return;
+ } else if (st0_tag == TAG_Zero) {
+ sign = getsign(st0_ptr);
+
+ if (FPU_divide_by_zero(0, SIGN_NEG) < 0)
+ return;
- push();
- FPU_copy_to_reg0(st0_ptr, TAG_Special);
- return;
- }
- else if ( st0_tag == TAG_Empty )
- {
- /* Is this the correct behaviour? */
- if ( control_word & EX_Invalid )
- {
- FPU_stack_underflow();
- push();
- FPU_stack_underflow();
+ push();
+ FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
+ setsign(st_new_ptr, sign);
+ return;
+ }
+
+ if (st0_tag == TAG_Special)
+ st0_tag = FPU_Special(st0_ptr);
+
+ if (st0_tag == TW_Denormal) {
+ if (denormal_operand() < 0)
+ return;
+
+ push();
+ sign = getsign(st1_ptr);
+ FPU_to_exp16(st1_ptr, st_new_ptr);
+ goto denormal_arg;
+ } else if (st0_tag == TW_Infinity) {
+ sign = getsign(st0_ptr);
+ setpositive(st0_ptr);
+ push();
+ FPU_copy_to_reg0(&CONST_INF, TAG_Special);
+ setsign(st_new_ptr, sign);
+ return;
+ } else if (st0_tag == TW_NaN) {
+ if (real_1op_NaN(st0_ptr) < 0)
+ return;
+
+ push();
+ FPU_copy_to_reg0(st0_ptr, TAG_Special);
+ return;
+ } else if (st0_tag == TAG_Empty) {
+ /* Is this the correct behaviour? */
+ if (control_word & EX_Invalid) {
+ FPU_stack_underflow();
+ push();
+ FPU_stack_underflow();
+ } else
+ EXCEPTION(EX_StackUnder);
}
- else
- EXCEPTION(EX_StackUnder);
- }
#ifdef PARANOID
- else
- EXCEPTION(EX_INTERNAL | 0x119);
+ else
+ EXCEPTION(EX_INTERNAL | 0x119);
#endif /* PARANOID */
}
-
static void fdecstp(void)
{
- clear_C1();
- top--;
+ clear_C1();
+ top--;
}
static void fincstp(void)
{
- clear_C1();
- top++;
+ clear_C1();
+ top++;
}
-
-static void fsqrt_(FPU_REG *st0_ptr, u_char st0_tag)
+static void fsqrt_(FPU_REG * st0_ptr, u_char st0_tag)
{
- int expon;
-
- clear_C1();
-
- if ( st0_tag == TAG_Valid )
- {
- u_char tag;
-
- if (signnegative(st0_ptr))
- {
- arith_invalid(0); /* sqrt(negative) is invalid */
- return;
- }
+ int expon;
+
+ clear_C1();
- /* make st(0) in [1.0 .. 4.0) */
- expon = exponent(st0_ptr);
-
- denormal_arg:
-
- setexponent16(st0_ptr, (expon & 1));
-
- /* Do the computation, the sign of the result will be positive. */
- tag = wm_sqrt(st0_ptr, 0, 0, control_word, SIGN_POS);
- addexponent(st0_ptr, expon >> 1);
- FPU_settag0(tag);
- return;
- }
-
- if ( st0_tag == TAG_Zero )
- return;
-
- if ( st0_tag == TAG_Special )
- st0_tag = FPU_Special(st0_ptr);
-
- if ( st0_tag == TW_Infinity )
- {
- if ( signnegative(st0_ptr) )
- arith_invalid(0); /* sqrt(-Infinity) is invalid */
- return;
- }
- else if ( st0_tag == TW_Denormal )
- {
- if (signnegative(st0_ptr))
- {
- arith_invalid(0); /* sqrt(negative) is invalid */
- return;
+ if (st0_tag == TAG_Valid) {
+ u_char tag;
+
+ if (signnegative(st0_ptr)) {
+ arith_invalid(0); /* sqrt(negative) is invalid */
+ return;
+ }
+
+ /* make st(0) in [1.0 .. 4.0) */
+ expon = exponent(st0_ptr);
+
+ denormal_arg:
+
+ setexponent16(st0_ptr, (expon & 1));
+
+ /* Do the computation, the sign of the result will be positive. */
+ tag = wm_sqrt(st0_ptr, 0, 0, control_word, SIGN_POS);
+ addexponent(st0_ptr, expon >> 1);
+ FPU_settag0(tag);
+ return;
}
- if ( denormal_operand() < 0 )
- return;
+ if (st0_tag == TAG_Zero)
+ return;
- FPU_to_exp16(st0_ptr, st0_ptr);
+ if (st0_tag == TAG_Special)
+ st0_tag = FPU_Special(st0_ptr);
- expon = exponent16(st0_ptr);
+ if (st0_tag == TW_Infinity) {
+ if (signnegative(st0_ptr))
+ arith_invalid(0); /* sqrt(-Infinity) is invalid */
+ return;
+ } else if (st0_tag == TW_Denormal) {
+ if (signnegative(st0_ptr)) {
+ arith_invalid(0); /* sqrt(negative) is invalid */
+ return;
+ }
- goto denormal_arg;
- }
+ if (denormal_operand() < 0)
+ return;
- single_arg_error(st0_ptr, st0_tag);
+ FPU_to_exp16(st0_ptr, st0_ptr);
-}
+ expon = exponent16(st0_ptr);
+
+ goto denormal_arg;
+ }
+ single_arg_error(st0_ptr, st0_tag);
-static void frndint_(FPU_REG *st0_ptr, u_char st0_tag)
+}
+
+static void frndint_(FPU_REG * st0_ptr, u_char st0_tag)
{
- int flags, tag;
+ int flags, tag;
- if ( st0_tag == TAG_Valid )
- {
- u_char sign;
+ if (st0_tag == TAG_Valid) {
+ u_char sign;
- denormal_arg:
+ denormal_arg:
- sign = getsign(st0_ptr);
+ sign = getsign(st0_ptr);
- if (exponent(st0_ptr) > 63)
- return;
+ if (exponent(st0_ptr) > 63)
+ return;
+
+ if (st0_tag == TW_Denormal) {
+ if (denormal_operand() < 0)
+ return;
+ }
+
+ /* Fortunately, this can't overflow to 2^64 */
+ if ((flags = FPU_round_to_int(st0_ptr, st0_tag)))
+ set_precision_flag(flags);
- if ( st0_tag == TW_Denormal )
- {
- if (denormal_operand() < 0 )
- return;
+ setexponent16(st0_ptr, 63);
+ tag = FPU_normalize(st0_ptr);
+ setsign(st0_ptr, sign);
+ FPU_settag0(tag);
+ return;
}
- /* Fortunately, this can't overflow to 2^64 */
- if ( (flags = FPU_round_to_int(st0_ptr, st0_tag)) )
- set_precision_flag(flags);
-
- setexponent16(st0_ptr, 63);
- tag = FPU_normalize(st0_ptr);
- setsign(st0_ptr, sign);
- FPU_settag0(tag);
- return;
- }
-
- if ( st0_tag == TAG_Zero )
- return;
-
- if ( st0_tag == TAG_Special )
- st0_tag = FPU_Special(st0_ptr);
-
- if ( st0_tag == TW_Denormal )
- goto denormal_arg;
- else if ( st0_tag == TW_Infinity )
- return;
- else
- single_arg_error(st0_ptr, st0_tag);
-}
+ if (st0_tag == TAG_Zero)
+ return;
+ if (st0_tag == TAG_Special)
+ st0_tag = FPU_Special(st0_ptr);
-static int fsin(FPU_REG *st0_ptr, u_char tag)
+ if (st0_tag == TW_Denormal)
+ goto denormal_arg;
+ else if (st0_tag == TW_Infinity)
+ return;
+ else
+ single_arg_error(st0_ptr, st0_tag);
+}
+
+static int fsin(FPU_REG * st0_ptr, u_char tag)
{
- u_char arg_sign = getsign(st0_ptr);
-
- if ( tag == TAG_Valid )
- {
- int q;
-
- if ( exponent(st0_ptr) > -40 )
- {
- if ( (q = trig_arg(st0_ptr, 0)) == -1 )
- {
- /* Operand is out of range */
- return 1;
- }
-
- poly_sine(st0_ptr);
-
- if (q & 2)
- changesign(st0_ptr);
-
- setsign(st0_ptr, getsign(st0_ptr) ^ arg_sign);
-
- /* We do not really know if up or down */
- set_precision_flag_up();
- return 0;
+ u_char arg_sign = getsign(st0_ptr);
+
+ if (tag == TAG_Valid) {
+ int q;
+
+ if (exponent(st0_ptr) > -40) {
+ if ((q = trig_arg(st0_ptr, 0)) == -1) {
+ /* Operand is out of range */
+ return 1;
+ }
+
+ poly_sine(st0_ptr);
+
+ if (q & 2)
+ changesign(st0_ptr);
+
+ setsign(st0_ptr, getsign(st0_ptr) ^ arg_sign);
+
+ /* We do not really know if up or down */
+ set_precision_flag_up();
+ return 0;
+ } else {
+ /* For a small arg, the result == the argument */
+ set_precision_flag_up(); /* Must be up. */
+ return 0;
+ }
}
- else
- {
- /* For a small arg, the result == the argument */
- set_precision_flag_up(); /* Must be up. */
- return 0;
+
+ if (tag == TAG_Zero) {
+ setcc(0);
+ return 0;
}
- }
-
- if ( tag == TAG_Zero )
- {
- setcc(0);
- return 0;
- }
-
- if ( tag == TAG_Special )
- tag = FPU_Special(st0_ptr);
-
- if ( tag == TW_Denormal )
- {
- if ( denormal_operand() < 0 )
- return 1;
-
- /* For a small arg, the result == the argument */
- /* Underflow may happen */
- FPU_to_exp16(st0_ptr, st0_ptr);
-
- tag = FPU_round(st0_ptr, 1, 0, FULL_PRECISION, arg_sign);
-
- FPU_settag0(tag);
-
- return 0;
- }
- else if ( tag == TW_Infinity )
- {
- /* The 80486 treats infinity as an invalid operand */
- arith_invalid(0);
- return 1;
- }
- else
- {
- single_arg_error(st0_ptr, tag);
- return 1;
- }
-}
+ if (tag == TAG_Special)
+ tag = FPU_Special(st0_ptr);
-static int f_cos(FPU_REG *st0_ptr, u_char tag)
-{
- u_char st0_sign;
-
- st0_sign = getsign(st0_ptr);
-
- if ( tag == TAG_Valid )
- {
- int q;
-
- if ( exponent(st0_ptr) > -40 )
- {
- if ( (exponent(st0_ptr) < 0)
- || ((exponent(st0_ptr) == 0)
- && (significand(st0_ptr) <= 0xc90fdaa22168c234LL)) )
- {
- poly_cos(st0_ptr);
-
- /* We do not really know if up or down */
- set_precision_flag_down();
-
- return 0;
- }
- else if ( (q = trig_arg(st0_ptr, FCOS)) != -1 )
- {
- poly_sine(st0_ptr);
-
- if ((q+1) & 2)
- changesign(st0_ptr);
-
- /* We do not really know if up or down */
- set_precision_flag_down();
-
- return 0;
- }
- else
- {
- /* Operand is out of range */
- return 1;
- }
+ if (tag == TW_Denormal) {
+ if (denormal_operand() < 0)
+ return 1;
+
+ /* For a small arg, the result == the argument */
+ /* Underflow may happen */
+ FPU_to_exp16(st0_ptr, st0_ptr);
+
+ tag = FPU_round(st0_ptr, 1, 0, FULL_PRECISION, arg_sign);
+
+ FPU_settag0(tag);
+
+ return 0;
+ } else if (tag == TW_Infinity) {
+ /* The 80486 treats infinity as an invalid operand */
+ arith_invalid(0);
+ return 1;
+ } else {
+ single_arg_error(st0_ptr, tag);
+ return 1;
}
- else
- {
- denormal_arg:
+}
+
+static int f_cos(FPU_REG * st0_ptr, u_char tag)
+{
+ u_char st0_sign;
+
+ st0_sign = getsign(st0_ptr);
- setcc(0);
- FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+ if (tag == TAG_Valid) {
+ int q;
+
+ if (exponent(st0_ptr) > -40) {
+ if ((exponent(st0_ptr) < 0)
+ || ((exponent(st0_ptr) == 0)
+ && (significand(st0_ptr) <=
+ 0xc90fdaa22168c234LL))) {
+ poly_cos(st0_ptr);
+
+ /* We do not really know if up or down */
+ set_precision_flag_down();
+
+ return 0;
+ } else if ((q = trig_arg(st0_ptr, FCOS)) != -1) {
+ poly_sine(st0_ptr);
+
+ if ((q + 1) & 2)
+ changesign(st0_ptr);
+
+ /* We do not really know if up or down */
+ set_precision_flag_down();
+
+ return 0;
+ } else {
+ /* Operand is out of range */
+ return 1;
+ }
+ } else {
+ denormal_arg:
+
+ setcc(0);
+ FPU_copy_to_reg0(&CONST_1, TAG_Valid);
#ifdef PECULIAR_486
- set_precision_flag_down(); /* 80486 appears to do this. */
+ set_precision_flag_down(); /* 80486 appears to do this. */
#else
- set_precision_flag_up(); /* Must be up. */
+ set_precision_flag_up(); /* Must be up. */
#endif /* PECULIAR_486 */
- return 0;
+ return 0;
+ }
+ } else if (tag == TAG_Zero) {
+ FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+ setcc(0);
+ return 0;
}
- }
- else if ( tag == TAG_Zero )
- {
- FPU_copy_to_reg0(&CONST_1, TAG_Valid);
- setcc(0);
- return 0;
- }
-
- if ( tag == TAG_Special )
- tag = FPU_Special(st0_ptr);
-
- if ( tag == TW_Denormal )
- {
- if ( denormal_operand() < 0 )
- return 1;
-
- goto denormal_arg;
- }
- else if ( tag == TW_Infinity )
- {
- /* The 80486 treats infinity as an invalid operand */
- arith_invalid(0);
- return 1;
- }
- else
- {
- single_arg_error(st0_ptr, tag); /* requires st0_ptr == &st(0) */
- return 1;
- }
-}
+ if (tag == TAG_Special)
+ tag = FPU_Special(st0_ptr);
+
+ if (tag == TW_Denormal) {
+ if (denormal_operand() < 0)
+ return 1;
+
+ goto denormal_arg;
+ } else if (tag == TW_Infinity) {
+ /* The 80486 treats infinity as an invalid operand */
+ arith_invalid(0);
+ return 1;
+ } else {
+ single_arg_error(st0_ptr, tag); /* requires st0_ptr == &st(0) */
+ return 1;
+ }
+}
-static void fcos(FPU_REG *st0_ptr, u_char st0_tag)
+static void fcos(FPU_REG * st0_ptr, u_char st0_tag)
{
- f_cos(st0_ptr, st0_tag);
+ f_cos(st0_ptr, st0_tag);
}
-
-static void fsincos(FPU_REG *st0_ptr, u_char st0_tag)
+static void fsincos(FPU_REG * st0_ptr, u_char st0_tag)
{
- FPU_REG *st_new_ptr;
- FPU_REG arg;
- u_char tag;
-
- /* Stack underflow has higher priority */
- if ( st0_tag == TAG_Empty )
- {
- FPU_stack_underflow(); /* Puts a QNaN in st(0) */
- if ( control_word & CW_Invalid )
- {
- st_new_ptr = &st(-1);
- push();
- FPU_stack_underflow(); /* Puts a QNaN in the new st(0) */
+ FPU_REG *st_new_ptr;
+ FPU_REG arg;
+ u_char tag;
+
+ /* Stack underflow has higher priority */
+ if (st0_tag == TAG_Empty) {
+ FPU_stack_underflow(); /* Puts a QNaN in st(0) */
+ if (control_word & CW_Invalid) {
+ st_new_ptr = &st(-1);
+ push();
+ FPU_stack_underflow(); /* Puts a QNaN in the new st(0) */
+ }
+ return;
}
- return;
- }
-
- if ( STACK_OVERFLOW )
- { FPU_stack_overflow(); return; }
-
- if ( st0_tag == TAG_Special )
- tag = FPU_Special(st0_ptr);
- else
- tag = st0_tag;
-
- if ( tag == TW_NaN )
- {
- single_arg_2_error(st0_ptr, TW_NaN);
- return;
- }
- else if ( tag == TW_Infinity )
- {
- /* The 80486 treats infinity as an invalid operand */
- if ( arith_invalid(0) >= 0 )
- {
- /* Masked response */
- push();
- arith_invalid(0);
+
+ if (STACK_OVERFLOW) {
+ FPU_stack_overflow();
+ return;
}
- return;
- }
-
- reg_copy(st0_ptr, &arg);
- if ( !fsin(st0_ptr, st0_tag) )
- {
- push();
- FPU_copy_to_reg0(&arg, st0_tag);
- f_cos(&st(0), st0_tag);
- }
- else
- {
- /* An error, so restore st(0) */
- FPU_copy_to_reg0(&arg, st0_tag);
- }
-}
+ if (st0_tag == TAG_Special)
+ tag = FPU_Special(st0_ptr);
+ else
+ tag = st0_tag;
+
+ if (tag == TW_NaN) {
+ single_arg_2_error(st0_ptr, TW_NaN);
+ return;
+ } else if (tag == TW_Infinity) {
+ /* The 80486 treats infinity as an invalid operand */
+ if (arith_invalid(0) >= 0) {
+ /* Masked response */
+ push();
+ arith_invalid(0);
+ }
+ return;
+ }
+
+ reg_copy(st0_ptr, &arg);
+ if (!fsin(st0_ptr, st0_tag)) {
+ push();
+ FPU_copy_to_reg0(&arg, st0_tag);
+ f_cos(&st(0), st0_tag);
+ } else {
+ /* An error, so restore st(0) */
+ FPU_copy_to_reg0(&arg, st0_tag);
+ }
+}
/*---------------------------------------------------------------------------*/
/* The following all require two arguments: st(0) and st(1) */
@@ -826,1020 +743,901 @@ static void fsincos(FPU_REG *st0_ptr, u_char st0_tag)
result must be zero.
*/
static void rem_kernel(unsigned long long st0, unsigned long long *y,
- unsigned long long st1,
- unsigned long long q, int n)
+ unsigned long long st1, unsigned long long q, int n)
{
- int dummy;
- unsigned long long x;
-
- x = st0 << n;
-
- /* Do the required multiplication and subtraction in the one operation */
-
- /* lsw x -= lsw st1 * lsw q */
- asm volatile ("mull %4; subl %%eax,%0; sbbl %%edx,%1"
- :"=m" (((unsigned *)&x)[0]), "=m" (((unsigned *)&x)[1]),
- "=a" (dummy)
- :"2" (((unsigned *)&st1)[0]), "m" (((unsigned *)&q)[0])
- :"%dx");
- /* msw x -= msw st1 * lsw q */
- asm volatile ("mull %3; subl %%eax,%0"
- :"=m" (((unsigned *)&x)[1]), "=a" (dummy)
- :"1" (((unsigned *)&st1)[1]), "m" (((unsigned *)&q)[0])
- :"%dx");
- /* msw x -= lsw st1 * msw q */
- asm volatile ("mull %3; subl %%eax,%0"
- :"=m" (((unsigned *)&x)[1]), "=a" (dummy)
- :"1" (((unsigned *)&st1)[0]), "m" (((unsigned *)&q)[1])
- :"%dx");
-
- *y = x;
+ int dummy;
+ unsigned long long x;
+
+ x = st0 << n;
+
+ /* Do the required multiplication and subtraction in the one operation */
+
+ /* lsw x -= lsw st1 * lsw q */
+ asm volatile ("mull %4; subl %%eax,%0; sbbl %%edx,%1":"=m"
+ (((unsigned *)&x)[0]), "=m"(((unsigned *)&x)[1]),
+ "=a"(dummy)
+ :"2"(((unsigned *)&st1)[0]), "m"(((unsigned *)&q)[0])
+ :"%dx");
+ /* msw x -= msw st1 * lsw q */
+ asm volatile ("mull %3; subl %%eax,%0":"=m" (((unsigned *)&x)[1]),
+ "=a"(dummy)
+ :"1"(((unsigned *)&st1)[1]), "m"(((unsigned *)&q)[0])
+ :"%dx");
+ /* msw x -= lsw st1 * msw q */
+ asm volatile ("mull %3; subl %%eax,%0":"=m" (((unsigned *)&x)[1]),
+ "=a"(dummy)
+ :"1"(((unsigned *)&st1)[0]), "m"(((unsigned *)&q)[1])
+ :"%dx");
+
+ *y = x;
}
-
/* Remainder of st(0) / st(1) */
/* This routine produces exact results, i.e. there is never any
rounding or truncation, etc of the result. */
-static void do_fprem(FPU_REG *st0_ptr, u_char st0_tag, int round)
+static void do_fprem(FPU_REG * st0_ptr, u_char st0_tag, int round)
{
- FPU_REG *st1_ptr = &st(1);
- u_char st1_tag = FPU_gettagi(1);
-
- if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) )
- {
- FPU_REG tmp, st0, st1;
- u_char st0_sign, st1_sign;
- u_char tmptag;
- int tag;
- int old_cw;
- int expdif;
- long long q;
- unsigned short saved_status;
- int cc;
-
- fprem_valid:
- /* Convert registers for internal use. */
- st0_sign = FPU_to_exp16(st0_ptr, &st0);
- st1_sign = FPU_to_exp16(st1_ptr, &st1);
- expdif = exponent16(&st0) - exponent16(&st1);
-
- old_cw = control_word;
- cc = 0;
-
- /* We want the status following the denorm tests, but don't want
- the status changed by the arithmetic operations. */
- saved_status = partial_status;
- control_word &= ~CW_RC;
- control_word |= RC_CHOP;
-
- if ( expdif < 64 )
- {
- /* This should be the most common case */
-
- if ( expdif > -2 )
- {
- u_char sign = st0_sign ^ st1_sign;
- tag = FPU_u_div(&st0, &st1, &tmp,
- PR_64_BITS | RC_CHOP | 0x3f,
- sign);
- setsign(&tmp, sign);
-
- if ( exponent(&tmp) >= 0 )
- {
- FPU_round_to_int(&tmp, tag); /* Fortunately, this can't
- overflow to 2^64 */
- q = significand(&tmp);
-
- rem_kernel(significand(&st0),
- &significand(&tmp),
- significand(&st1),
- q, expdif);
-
- setexponent16(&tmp, exponent16(&st1));
- }
- else
- {
- reg_copy(&st0, &tmp);
- q = 0;
- }
-
- if ( (round == RC_RND) && (tmp.sigh & 0xc0000000) )
- {
- /* We may need to subtract st(1) once more,
- to get a result <= 1/2 of st(1). */
- unsigned long long x;
- expdif = exponent16(&st1) - exponent16(&tmp);
- if ( expdif <= 1 )
- {
- if ( expdif == 0 )
- x = significand(&st1) - significand(&tmp);
- else /* expdif is 1 */
- x = (significand(&st1) << 1) - significand(&tmp);
- if ( (x < significand(&tmp)) ||
- /* or equi-distant (from 0 & st(1)) and q is odd */
- ((x == significand(&tmp)) && (q & 1) ) )
- {
- st0_sign = ! st0_sign;
- significand(&tmp) = x;
- q++;
+ FPU_REG *st1_ptr = &st(1);
+ u_char st1_tag = FPU_gettagi(1);
+
+ if (!((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid))) {
+ FPU_REG tmp, st0, st1;
+ u_char st0_sign, st1_sign;
+ u_char tmptag;
+ int tag;
+ int old_cw;
+ int expdif;
+ long long q;
+ unsigned short saved_status;
+ int cc;
+
+ fprem_valid:
+ /* Convert registers for internal use. */
+ st0_sign = FPU_to_exp16(st0_ptr, &st0);
+ st1_sign = FPU_to_exp16(st1_ptr, &st1);
+ expdif = exponent16(&st0) - exponent16(&st1);
+
+ old_cw = control_word;
+ cc = 0;
+
+ /* We want the status following the denorm tests, but don't want
+ the status changed by the arithmetic operations. */
+ saved_status = partial_status;
+ control_word &= ~CW_RC;
+ control_word |= RC_CHOP;
+
+ if (expdif < 64) {
+ /* This should be the most common case */
+
+ if (expdif > -2) {
+ u_char sign = st0_sign ^ st1_sign;
+ tag = FPU_u_div(&st0, &st1, &tmp,
+ PR_64_BITS | RC_CHOP | 0x3f,
+ sign);
+ setsign(&tmp, sign);
+
+ if (exponent(&tmp) >= 0) {
+ FPU_round_to_int(&tmp, tag); /* Fortunately, this can't
+ overflow to 2^64 */
+ q = significand(&tmp);
+
+ rem_kernel(significand(&st0),
+ &significand(&tmp),
+ significand(&st1),
+ q, expdif);
+
+ setexponent16(&tmp, exponent16(&st1));
+ } else {
+ reg_copy(&st0, &tmp);
+ q = 0;
+ }
+
+ if ((round == RC_RND)
+ && (tmp.sigh & 0xc0000000)) {
+ /* We may need to subtract st(1) once more,
+ to get a result <= 1/2 of st(1). */
+ unsigned long long x;
+ expdif =
+ exponent16(&st1) - exponent16(&tmp);
+ if (expdif <= 1) {
+ if (expdif == 0)
+ x = significand(&st1) -
+ significand(&tmp);
+ else /* expdif is 1 */
+ x = (significand(&st1)
+ << 1) -
+ significand(&tmp);
+ if ((x < significand(&tmp)) ||
+ /* or equi-distant (from 0 & st(1)) and q is odd */
+ ((x == significand(&tmp))
+ && (q & 1))) {
+ st0_sign = !st0_sign;
+ significand(&tmp) = x;
+ q++;
+ }
+ }
+ }
+
+ if (q & 4)
+ cc |= SW_C0;
+ if (q & 2)
+ cc |= SW_C3;
+ if (q & 1)
+ cc |= SW_C1;
+ } else {
+ control_word = old_cw;
+ setcc(0);
+ return;
}
- }
- }
-
- if (q & 4) cc |= SW_C0;
- if (q & 2) cc |= SW_C3;
- if (q & 1) cc |= SW_C1;
- }
- else
- {
- control_word = old_cw;
- setcc(0);
- return;
- }
- }
- else
- {
- /* There is a large exponent difference ( >= 64 ) */
- /* To make much sense, the code in this section should
- be done at high precision. */
- int exp_1, N;
- u_char sign;
-
- /* prevent overflow here */
- /* N is 'a number between 32 and 63' (p26-113) */
- reg_copy(&st0, &tmp);
- tmptag = st0_tag;
- N = (expdif & 0x0000001f) + 32; /* This choice gives results
- identical to an AMD 486 */
- setexponent16(&tmp, N);
- exp_1 = exponent16(&st1);
- setexponent16(&st1, 0);
- expdif -= N;
-
- sign = getsign(&tmp) ^ st1_sign;
- tag = FPU_u_div(&tmp, &st1, &tmp, PR_64_BITS | RC_CHOP | 0x3f,
- sign);
- setsign(&tmp, sign);
-
- FPU_round_to_int(&tmp, tag); /* Fortunately, this can't
- overflow to 2^64 */
-
- rem_kernel(significand(&st0),
- &significand(&tmp),
- significand(&st1),
- significand(&tmp),
- exponent(&tmp)
- );
- setexponent16(&tmp, exp_1 + expdif);
-
- /* It is possible for the operation to be complete here.
- What does the IEEE standard say? The Intel 80486 manual
- implies that the operation will never be completed at this
- point, and the behaviour of a real 80486 confirms this.
- */
- if ( !(tmp.sigh | tmp.sigl) )
- {
- /* The result is zero */
- control_word = old_cw;
- partial_status = saved_status;
- FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
- setsign(&st0, st0_sign);
+ } else {
+ /* There is a large exponent difference ( >= 64 ) */
+ /* To make much sense, the code in this section should
+ be done at high precision. */
+ int exp_1, N;
+ u_char sign;
+
+ /* prevent overflow here */
+ /* N is 'a number between 32 and 63' (p26-113) */
+ reg_copy(&st0, &tmp);
+ tmptag = st0_tag;
+ N = (expdif & 0x0000001f) + 32; /* This choice gives results
+ identical to an AMD 486 */
+ setexponent16(&tmp, N);
+ exp_1 = exponent16(&st1);
+ setexponent16(&st1, 0);
+ expdif -= N;
+
+ sign = getsign(&tmp) ^ st1_sign;
+ tag =
+ FPU_u_div(&tmp, &st1, &tmp,
+ PR_64_BITS | RC_CHOP | 0x3f, sign);
+ setsign(&tmp, sign);
+
+ FPU_round_to_int(&tmp, tag); /* Fortunately, this can't
+ overflow to 2^64 */
+
+ rem_kernel(significand(&st0),
+ &significand(&tmp),
+ significand(&st1),
+ significand(&tmp), exponent(&tmp)
+ );
+ setexponent16(&tmp, exp_1 + expdif);
+
+ /* It is possible for the operation to be complete here.
+ What does the IEEE standard say? The Intel 80486 manual
+ implies that the operation will never be completed at this
+ point, and the behaviour of a real 80486 confirms this.
+ */
+ if (!(tmp.sigh | tmp.sigl)) {
+ /* The result is zero */
+ control_word = old_cw;
+ partial_status = saved_status;
+ FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
+ setsign(&st0, st0_sign);
#ifdef PECULIAR_486
- setcc(SW_C2);
+ setcc(SW_C2);
#else
- setcc(0);
+ setcc(0);
#endif /* PECULIAR_486 */
- return;
- }
- cc = SW_C2;
- }
+ return;
+ }
+ cc = SW_C2;
+ }
- control_word = old_cw;
- partial_status = saved_status;
- tag = FPU_normalize_nuo(&tmp);
- reg_copy(&tmp, st0_ptr);
-
- /* The only condition to be looked for is underflow,
- and it can occur here only if underflow is unmasked. */
- if ( (exponent16(&tmp) <= EXP_UNDER) && (tag != TAG_Zero)
- && !(control_word & CW_Underflow) )
- {
- setcc(cc);
- tag = arith_underflow(st0_ptr);
- setsign(st0_ptr, st0_sign);
- FPU_settag0(tag);
- return;
- }
- else if ( (exponent16(&tmp) > EXP_UNDER) || (tag == TAG_Zero) )
- {
- stdexp(st0_ptr);
- setsign(st0_ptr, st0_sign);
- }
- else
- {
- tag = FPU_round(st0_ptr, 0, 0, FULL_PRECISION, st0_sign);
- }
- FPU_settag0(tag);
- setcc(cc);
+ control_word = old_cw;
+ partial_status = saved_status;
+ tag = FPU_normalize_nuo(&tmp);
+ reg_copy(&tmp, st0_ptr);
+
+ /* The only condition to be looked for is underflow,
+ and it can occur here only if underflow is unmasked. */
+ if ((exponent16(&tmp) <= EXP_UNDER) && (tag != TAG_Zero)
+ && !(control_word & CW_Underflow)) {
+ setcc(cc);
+ tag = arith_underflow(st0_ptr);
+ setsign(st0_ptr, st0_sign);
+ FPU_settag0(tag);
+ return;
+ } else if ((exponent16(&tmp) > EXP_UNDER) || (tag == TAG_Zero)) {
+ stdexp(st0_ptr);
+ setsign(st0_ptr, st0_sign);
+ } else {
+ tag =
+ FPU_round(st0_ptr, 0, 0, FULL_PRECISION, st0_sign);
+ }
+ FPU_settag0(tag);
+ setcc(cc);
- return;
- }
+ return;
+ }
- if ( st0_tag == TAG_Special )
- st0_tag = FPU_Special(st0_ptr);
- if ( st1_tag == TAG_Special )
- st1_tag = FPU_Special(st1_ptr);
+ if (st0_tag == TAG_Special)
+ st0_tag = FPU_Special(st0_ptr);
+ if (st1_tag == TAG_Special)
+ st1_tag = FPU_Special(st1_ptr);
- if ( ((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
+ if (((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
|| ((st0_tag == TW_Denormal) && (st1_tag == TAG_Valid))
- || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal)) )
- {
- if ( denormal_operand() < 0 )
- return;
- goto fprem_valid;
- }
- else if ( (st0_tag == TAG_Empty) || (st1_tag == TAG_Empty) )
- {
- FPU_stack_underflow();
- return;
- }
- else if ( st0_tag == TAG_Zero )
- {
- if ( st1_tag == TAG_Valid )
- {
- setcc(0); return;
- }
- else if ( st1_tag == TW_Denormal )
- {
- if ( denormal_operand() < 0 )
- return;
- setcc(0); return;
- }
- else if ( st1_tag == TAG_Zero )
- { arith_invalid(0); return; } /* fprem(?,0) always invalid */
- else if ( st1_tag == TW_Infinity )
- { setcc(0); return; }
- }
- else if ( (st0_tag == TAG_Valid) || (st0_tag == TW_Denormal) )
- {
- if ( st1_tag == TAG_Zero )
- {
- arith_invalid(0); /* fprem(Valid,Zero) is invalid */
- return;
- }
- else if ( st1_tag != TW_NaN )
- {
- if ( ((st0_tag == TW_Denormal) || (st1_tag == TW_Denormal))
- && (denormal_operand() < 0) )
- return;
-
- if ( st1_tag == TW_Infinity )
- {
- /* fprem(Valid,Infinity) is o.k. */
- setcc(0); return;
- }
- }
- }
- else if ( st0_tag == TW_Infinity )
- {
- if ( st1_tag != TW_NaN )
- {
- arith_invalid(0); /* fprem(Infinity,?) is invalid */
- return;
+ || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal))) {
+ if (denormal_operand() < 0)
+ return;
+ goto fprem_valid;
+ } else if ((st0_tag == TAG_Empty) || (st1_tag == TAG_Empty)) {
+ FPU_stack_underflow();
+ return;
+ } else if (st0_tag == TAG_Zero) {
+ if (st1_tag == TAG_Valid) {
+ setcc(0);
+ return;
+ } else if (st1_tag == TW_Denormal) {
+ if (denormal_operand() < 0)
+ return;
+ setcc(0);
+ return;
+ } else if (st1_tag == TAG_Zero) {
+ arith_invalid(0);
+ return;
+ } /* fprem(?,0) always invalid */
+ else if (st1_tag == TW_Infinity) {
+ setcc(0);
+ return;
+ }
+ } else if ((st0_tag == TAG_Valid) || (st0_tag == TW_Denormal)) {
+ if (st1_tag == TAG_Zero) {
+ arith_invalid(0); /* fprem(Valid,Zero) is invalid */
+ return;
+ } else if (st1_tag != TW_NaN) {
+ if (((st0_tag == TW_Denormal)
+ || (st1_tag == TW_Denormal))
+ && (denormal_operand() < 0))
+ return;
+
+ if (st1_tag == TW_Infinity) {
+ /* fprem(Valid,Infinity) is o.k. */
+ setcc(0);
+ return;
+ }
+ }
+ } else if (st0_tag == TW_Infinity) {
+ if (st1_tag != TW_NaN) {
+ arith_invalid(0); /* fprem(Infinity,?) is invalid */
+ return;
+ }
}
- }
- /* One of the registers must contain a NaN if we got here. */
+ /* One of the registers must contain a NaN if we got here. */
#ifdef PARANOID
- if ( (st0_tag != TW_NaN) && (st1_tag != TW_NaN) )
- EXCEPTION(EX_INTERNAL | 0x118);
+ if ((st0_tag != TW_NaN) && (st1_tag != TW_NaN))
+ EXCEPTION(EX_INTERNAL | 0x118);
#endif /* PARANOID */
- real_2op_NaN(st1_ptr, st1_tag, 0, st1_ptr);
+ real_2op_NaN(st1_ptr, st1_tag, 0, st1_ptr);
}
-
/* ST(1) <- ST(1) * log ST; pop ST */
-static void fyl2x(FPU_REG *st0_ptr, u_char st0_tag)
+static void fyl2x(FPU_REG * st0_ptr, u_char st0_tag)
{
- FPU_REG *st1_ptr = &st(1), exponent;
- u_char st1_tag = FPU_gettagi(1);
- u_char sign;
- int e, tag;
-
- clear_C1();
-
- if ( (st0_tag == TAG_Valid) && (st1_tag == TAG_Valid) )
- {
- both_valid:
- /* Both regs are Valid or Denormal */
- if ( signpositive(st0_ptr) )
- {
- if ( st0_tag == TW_Denormal )
- FPU_to_exp16(st0_ptr, st0_ptr);
- else
- /* Convert st(0) for internal use. */
- setexponent16(st0_ptr, exponent(st0_ptr));
-
- if ( (st0_ptr->sigh == 0x80000000) && (st0_ptr->sigl == 0) )
- {
- /* Special case. The result can be precise. */
- u_char esign;
- e = exponent16(st0_ptr);
- if ( e >= 0 )
- {
- exponent.sigh = e;
- esign = SIGN_POS;
- }
- else
- {
- exponent.sigh = -e;
- esign = SIGN_NEG;
+ FPU_REG *st1_ptr = &st(1), exponent;
+ u_char st1_tag = FPU_gettagi(1);
+ u_char sign;
+ int e, tag;
+
+ clear_C1();
+
+ if ((st0_tag == TAG_Valid) && (st1_tag == TAG_Valid)) {
+ both_valid:
+ /* Both regs are Valid or Denormal */
+ if (signpositive(st0_ptr)) {
+ if (st0_tag == TW_Denormal)
+ FPU_to_exp16(st0_ptr, st0_ptr);
+ else
+ /* Convert st(0) for internal use. */
+ setexponent16(st0_ptr, exponent(st0_ptr));
+
+ if ((st0_ptr->sigh == 0x80000000)
+ && (st0_ptr->sigl == 0)) {
+ /* Special case. The result can be precise. */
+ u_char esign;
+ e = exponent16(st0_ptr);
+ if (e >= 0) {
+ exponent.sigh = e;
+ esign = SIGN_POS;
+ } else {
+ exponent.sigh = -e;
+ esign = SIGN_NEG;
+ }
+ exponent.sigl = 0;
+ setexponent16(&exponent, 31);
+ tag = FPU_normalize_nuo(&exponent);
+ stdexp(&exponent);
+ setsign(&exponent, esign);
+ tag =
+ FPU_mul(&exponent, tag, 1, FULL_PRECISION);
+ if (tag >= 0)
+ FPU_settagi(1, tag);
+ } else {
+ /* The usual case */
+ sign = getsign(st1_ptr);
+ if (st1_tag == TW_Denormal)
+ FPU_to_exp16(st1_ptr, st1_ptr);
+ else
+ /* Convert st(1) for internal use. */
+ setexponent16(st1_ptr,
+ exponent(st1_ptr));
+ poly_l2(st0_ptr, st1_ptr, sign);
+ }
+ } else {
+ /* negative */
+ if (arith_invalid(1) < 0)
+ return;
}
- exponent.sigl = 0;
- setexponent16(&exponent, 31);
- tag = FPU_normalize_nuo(&exponent);
- stdexp(&exponent);
- setsign(&exponent, esign);
- tag = FPU_mul(&exponent, tag, 1, FULL_PRECISION);
- if ( tag >= 0 )
- FPU_settagi(1, tag);
- }
- else
- {
- /* The usual case */
- sign = getsign(st1_ptr);
- if ( st1_tag == TW_Denormal )
- FPU_to_exp16(st1_ptr, st1_ptr);
- else
- /* Convert st(1) for internal use. */
- setexponent16(st1_ptr, exponent(st1_ptr));
- poly_l2(st0_ptr, st1_ptr, sign);
- }
- }
- else
- {
- /* negative */
- if ( arith_invalid(1) < 0 )
- return;
- }
- FPU_pop();
-
- return;
- }
-
- if ( st0_tag == TAG_Special )
- st0_tag = FPU_Special(st0_ptr);
- if ( st1_tag == TAG_Special )
- st1_tag = FPU_Special(st1_ptr);
-
- if ( (st0_tag == TAG_Empty) || (st1_tag == TAG_Empty) )
- {
- FPU_stack_underflow_pop(1);
- return;
- }
- else if ( (st0_tag <= TW_Denormal) && (st1_tag <= TW_Denormal) )
- {
- if ( st0_tag == TAG_Zero )
- {
- if ( st1_tag == TAG_Zero )
- {
- /* Both args zero is invalid */
- if ( arith_invalid(1) < 0 )
- return;
- }
- else
- {
- u_char sign;
- sign = getsign(st1_ptr)^SIGN_NEG;
- if ( FPU_divide_by_zero(1, sign) < 0 )
- return;
+ FPU_pop();
- setsign(st1_ptr, sign);
- }
- }
- else if ( st1_tag == TAG_Zero )
- {
- /* st(1) contains zero, st(0) valid <> 0 */
- /* Zero is the valid answer */
- sign = getsign(st1_ptr);
-
- if ( signnegative(st0_ptr) )
- {
- /* log(negative) */
- if ( arith_invalid(1) < 0 )
return;
- }
- else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
- return;
- else
- {
- if ( exponent(st0_ptr) < 0 )
- sign ^= SIGN_NEG;
-
- FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
- setsign(st1_ptr, sign);
- }
}
- else
- {
- /* One or both operands are denormals. */
- if ( denormal_operand() < 0 )
- return;
- goto both_valid;
- }
- }
- else if ( (st0_tag == TW_NaN) || (st1_tag == TW_NaN) )
- {
- if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
- return;
- }
- /* One or both arg must be an infinity */
- else if ( st0_tag == TW_Infinity )
- {
- if ( (signnegative(st0_ptr)) || (st1_tag == TAG_Zero) )
- {
- /* log(-infinity) or 0*log(infinity) */
- if ( arith_invalid(1) < 0 )
- return;
- }
- else
- {
- u_char sign = getsign(st1_ptr);
- if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
- return;
+ if (st0_tag == TAG_Special)
+ st0_tag = FPU_Special(st0_ptr);
+ if (st1_tag == TAG_Special)
+ st1_tag = FPU_Special(st1_ptr);
- FPU_copy_to_reg1(&CONST_INF, TAG_Special);
- setsign(st1_ptr, sign);
- }
- }
- /* st(1) must be infinity here */
- else if ( ((st0_tag == TAG_Valid) || (st0_tag == TW_Denormal))
- && ( signpositive(st0_ptr) ) )
- {
- if ( exponent(st0_ptr) >= 0 )
- {
- if ( (exponent(st0_ptr) == 0) &&
- (st0_ptr->sigh == 0x80000000) &&
- (st0_ptr->sigl == 0) )
- {
- /* st(0) holds 1.0 */
- /* infinity*log(1) */
- if ( arith_invalid(1) < 0 )
+ if ((st0_tag == TAG_Empty) || (st1_tag == TAG_Empty)) {
+ FPU_stack_underflow_pop(1);
return;
- }
- /* else st(0) is positive and > 1.0 */
+ } else if ((st0_tag <= TW_Denormal) && (st1_tag <= TW_Denormal)) {
+ if (st0_tag == TAG_Zero) {
+ if (st1_tag == TAG_Zero) {
+ /* Both args zero is invalid */
+ if (arith_invalid(1) < 0)
+ return;
+ } else {
+ u_char sign;
+ sign = getsign(st1_ptr) ^ SIGN_NEG;
+ if (FPU_divide_by_zero(1, sign) < 0)
+ return;
+
+ setsign(st1_ptr, sign);
+ }
+ } else if (st1_tag == TAG_Zero) {
+ /* st(1) contains zero, st(0) valid <> 0 */
+ /* Zero is the valid answer */
+ sign = getsign(st1_ptr);
+
+ if (signnegative(st0_ptr)) {
+ /* log(negative) */
+ if (arith_invalid(1) < 0)
+ return;
+ } else if ((st0_tag == TW_Denormal)
+ && (denormal_operand() < 0))
+ return;
+ else {
+ if (exponent(st0_ptr) < 0)
+ sign ^= SIGN_NEG;
+
+ FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
+ setsign(st1_ptr, sign);
+ }
+ } else {
+ /* One or both operands are denormals. */
+ if (denormal_operand() < 0)
+ return;
+ goto both_valid;
+ }
+ } else if ((st0_tag == TW_NaN) || (st1_tag == TW_NaN)) {
+ if (real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0)
+ return;
+ }
+ /* One or both arg must be an infinity */
+ else if (st0_tag == TW_Infinity) {
+ if ((signnegative(st0_ptr)) || (st1_tag == TAG_Zero)) {
+ /* log(-infinity) or 0*log(infinity) */
+ if (arith_invalid(1) < 0)
+ return;
+ } else {
+ u_char sign = getsign(st1_ptr);
+
+ if ((st1_tag == TW_Denormal)
+ && (denormal_operand() < 0))
+ return;
+
+ FPU_copy_to_reg1(&CONST_INF, TAG_Special);
+ setsign(st1_ptr, sign);
+ }
}
- else
- {
- /* st(0) is positive and < 1.0 */
+ /* st(1) must be infinity here */
+ else if (((st0_tag == TAG_Valid) || (st0_tag == TW_Denormal))
+ && (signpositive(st0_ptr))) {
+ if (exponent(st0_ptr) >= 0) {
+ if ((exponent(st0_ptr) == 0) &&
+ (st0_ptr->sigh == 0x80000000) &&
+ (st0_ptr->sigl == 0)) {
+ /* st(0) holds 1.0 */
+ /* infinity*log(1) */
+ if (arith_invalid(1) < 0)
+ return;
+ }
+ /* else st(0) is positive and > 1.0 */
+ } else {
+ /* st(0) is positive and < 1.0 */
- if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
- return;
+ if ((st0_tag == TW_Denormal)
+ && (denormal_operand() < 0))
+ return;
- changesign(st1_ptr);
- }
- }
- else
- {
- /* st(0) must be zero or negative */
- if ( st0_tag == TAG_Zero )
- {
- /* This should be invalid, but a real 80486 is happy with it. */
+ changesign(st1_ptr);
+ }
+ } else {
+ /* st(0) must be zero or negative */
+ if (st0_tag == TAG_Zero) {
+ /* This should be invalid, but a real 80486 is happy with it. */
#ifndef PECULIAR_486
- sign = getsign(st1_ptr);
- if ( FPU_divide_by_zero(1, sign) < 0 )
- return;
+ sign = getsign(st1_ptr);
+ if (FPU_divide_by_zero(1, sign) < 0)
+ return;
#endif /* PECULIAR_486 */
- changesign(st1_ptr);
+ changesign(st1_ptr);
+ } else if (arith_invalid(1) < 0) /* log(negative) */
+ return;
}
- else if ( arith_invalid(1) < 0 ) /* log(negative) */
- return;
- }
- FPU_pop();
+ FPU_pop();
}
-
-static void fpatan(FPU_REG *st0_ptr, u_char st0_tag)
+static void fpatan(FPU_REG * st0_ptr, u_char st0_tag)
{
- FPU_REG *st1_ptr = &st(1);
- u_char st1_tag = FPU_gettagi(1);
- int tag;
+ FPU_REG *st1_ptr = &st(1);
+ u_char st1_tag = FPU_gettagi(1);
+ int tag;
- clear_C1();
- if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) )
- {
- valid_atan:
+ clear_C1();
+ if (!((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid))) {
+ valid_atan:
- poly_atan(st0_ptr, st0_tag, st1_ptr, st1_tag);
+ poly_atan(st0_ptr, st0_tag, st1_ptr, st1_tag);
- FPU_pop();
+ FPU_pop();
- return;
- }
+ return;
+ }
- if ( st0_tag == TAG_Special )
- st0_tag = FPU_Special(st0_ptr);
- if ( st1_tag == TAG_Special )
- st1_tag = FPU_Special(st1_ptr);
+ if (st0_tag == TAG_Special)
+ st0_tag = FPU_Special(st0_ptr);
+ if (st1_tag == TAG_Special)
+ st1_tag = FPU_Special(st1_ptr);
- if ( ((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
+ if (((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
|| ((st0_tag == TW_Denormal) && (st1_tag == TAG_Valid))
- || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal)) )
- {
- if ( denormal_operand() < 0 )
- return;
+ || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal))) {
+ if (denormal_operand() < 0)
+ return;
- goto valid_atan;
- }
- else if ( (st0_tag == TAG_Empty) || (st1_tag == TAG_Empty) )
- {
- FPU_stack_underflow_pop(1);
- return;
- }
- else if ( (st0_tag == TW_NaN) || (st1_tag == TW_NaN) )
- {
- if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) >= 0 )
- FPU_pop();
- return;
- }
- else if ( (st0_tag == TW_Infinity) || (st1_tag == TW_Infinity) )
- {
- u_char sign = getsign(st1_ptr);
- if ( st0_tag == TW_Infinity )
- {
- if ( st1_tag == TW_Infinity )
- {
- if ( signpositive(st0_ptr) )
- {
- FPU_copy_to_reg1(&CONST_PI4, TAG_Valid);
- }
- else
- {
- setpositive(st1_ptr);
- tag = FPU_u_add(&CONST_PI4, &CONST_PI2, st1_ptr,
- FULL_PRECISION, SIGN_POS,
- exponent(&CONST_PI4), exponent(&CONST_PI2));
- if ( tag >= 0 )
- FPU_settagi(1, tag);
- }
- }
- else
- {
- if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
+ goto valid_atan;
+ } else if ((st0_tag == TAG_Empty) || (st1_tag == TAG_Empty)) {
+ FPU_stack_underflow_pop(1);
+ return;
+ } else if ((st0_tag == TW_NaN) || (st1_tag == TW_NaN)) {
+ if (real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) >= 0)
+ FPU_pop();
return;
+ } else if ((st0_tag == TW_Infinity) || (st1_tag == TW_Infinity)) {
+ u_char sign = getsign(st1_ptr);
+ if (st0_tag == TW_Infinity) {
+ if (st1_tag == TW_Infinity) {
+ if (signpositive(st0_ptr)) {
+ FPU_copy_to_reg1(&CONST_PI4, TAG_Valid);
+ } else {
+ setpositive(st1_ptr);
+ tag =
+ FPU_u_add(&CONST_PI4, &CONST_PI2,
+ st1_ptr, FULL_PRECISION,
+ SIGN_POS,
+ exponent(&CONST_PI4),
+ exponent(&CONST_PI2));
+ if (tag >= 0)
+ FPU_settagi(1, tag);
+ }
+ } else {
+ if ((st1_tag == TW_Denormal)
+ && (denormal_operand() < 0))
+ return;
+
+ if (signpositive(st0_ptr)) {
+ FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
+ setsign(st1_ptr, sign); /* An 80486 preserves the sign */
+ FPU_pop();
+ return;
+ } else {
+ FPU_copy_to_reg1(&CONST_PI, TAG_Valid);
+ }
+ }
+ } else {
+ /* st(1) is infinity, st(0) not infinity */
+ if ((st0_tag == TW_Denormal)
+ && (denormal_operand() < 0))
+ return;
- if ( signpositive(st0_ptr) )
- {
- FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
- setsign(st1_ptr, sign); /* An 80486 preserves the sign */
- FPU_pop();
- return;
+ FPU_copy_to_reg1(&CONST_PI2, TAG_Valid);
}
- else
- {
- FPU_copy_to_reg1(&CONST_PI, TAG_Valid);
+ setsign(st1_ptr, sign);
+ } else if (st1_tag == TAG_Zero) {
+ /* st(0) must be valid or zero */
+ u_char sign = getsign(st1_ptr);
+
+ if ((st0_tag == TW_Denormal) && (denormal_operand() < 0))
+ return;
+
+ if (signpositive(st0_ptr)) {
+ /* An 80486 preserves the sign */
+ FPU_pop();
+ return;
}
- }
- }
- else
- {
- /* st(1) is infinity, st(0) not infinity */
- if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
- return;
- FPU_copy_to_reg1(&CONST_PI2, TAG_Valid);
- }
- setsign(st1_ptr, sign);
- }
- else if ( st1_tag == TAG_Zero )
- {
- /* st(0) must be valid or zero */
- u_char sign = getsign(st1_ptr);
-
- if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
- return;
+ FPU_copy_to_reg1(&CONST_PI, TAG_Valid);
+ setsign(st1_ptr, sign);
+ } else if (st0_tag == TAG_Zero) {
+ /* st(1) must be TAG_Valid here */
+ u_char sign = getsign(st1_ptr);
- if ( signpositive(st0_ptr) )
- {
- /* An 80486 preserves the sign */
- FPU_pop();
- return;
- }
+ if ((st1_tag == TW_Denormal) && (denormal_operand() < 0))
+ return;
- FPU_copy_to_reg1(&CONST_PI, TAG_Valid);
- setsign(st1_ptr, sign);
- }
- else if ( st0_tag == TAG_Zero )
- {
- /* st(1) must be TAG_Valid here */
- u_char sign = getsign(st1_ptr);
-
- if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
- return;
-
- FPU_copy_to_reg1(&CONST_PI2, TAG_Valid);
- setsign(st1_ptr, sign);
- }
+ FPU_copy_to_reg1(&CONST_PI2, TAG_Valid);
+ setsign(st1_ptr, sign);
+ }
#ifdef PARANOID
- else
- EXCEPTION(EX_INTERNAL | 0x125);
+ else
+ EXCEPTION(EX_INTERNAL | 0x125);
#endif /* PARANOID */
- FPU_pop();
- set_precision_flag_up(); /* We do not really know if up or down */
+ FPU_pop();
+ set_precision_flag_up(); /* We do not really know if up or down */
}
-
-static void fprem(FPU_REG *st0_ptr, u_char st0_tag)
+static void fprem(FPU_REG * st0_ptr, u_char st0_tag)
{
- do_fprem(st0_ptr, st0_tag, RC_CHOP);
+ do_fprem(st0_ptr, st0_tag, RC_CHOP);
}
-
-static void fprem1(FPU_REG *st0_ptr, u_char st0_tag)
+static void fprem1(FPU_REG * st0_ptr, u_char st0_tag)
{
- do_fprem(st0_ptr, st0_tag, RC_RND);
+ do_fprem(st0_ptr, st0_tag, RC_RND);
}
-
-static void fyl2xp1(FPU_REG *st0_ptr, u_char st0_tag)
+static void fyl2xp1(FPU_REG * st0_ptr, u_char st0_tag)
{
- u_char sign, sign1;
- FPU_REG *st1_ptr = &st(1), a, b;
- u_char st1_tag = FPU_gettagi(1);
+ u_char sign, sign1;
+ FPU_REG *st1_ptr = &st(1), a, b;
+ u_char st1_tag = FPU_gettagi(1);
- clear_C1();
- if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) )
- {
- valid_yl2xp1:
+ clear_C1();
+ if (!((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid))) {
+ valid_yl2xp1:
- sign = getsign(st0_ptr);
- sign1 = getsign(st1_ptr);
+ sign = getsign(st0_ptr);
+ sign1 = getsign(st1_ptr);
- FPU_to_exp16(st0_ptr, &a);
- FPU_to_exp16(st1_ptr, &b);
+ FPU_to_exp16(st0_ptr, &a);
+ FPU_to_exp16(st1_ptr, &b);
- if ( poly_l2p1(sign, sign1, &a, &b, st1_ptr) )
- return;
+ if (poly_l2p1(sign, sign1, &a, &b, st1_ptr))
+ return;
- FPU_pop();
- return;
- }
+ FPU_pop();
+ return;
+ }
- if ( st0_tag == TAG_Special )
- st0_tag = FPU_Special(st0_ptr);
- if ( st1_tag == TAG_Special )
- st1_tag = FPU_Special(st1_ptr);
+ if (st0_tag == TAG_Special)
+ st0_tag = FPU_Special(st0_ptr);
+ if (st1_tag == TAG_Special)
+ st1_tag = FPU_Special(st1_ptr);
- if ( ((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
+ if (((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
|| ((st0_tag == TW_Denormal) && (st1_tag == TAG_Valid))
- || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal)) )
- {
- if ( denormal_operand() < 0 )
- return;
-
- goto valid_yl2xp1;
- }
- else if ( (st0_tag == TAG_Empty) | (st1_tag == TAG_Empty) )
- {
- FPU_stack_underflow_pop(1);
- return;
- }
- else if ( st0_tag == TAG_Zero )
- {
- switch ( st1_tag )
- {
- case TW_Denormal:
- if ( denormal_operand() < 0 )
- return;
-
- case TAG_Zero:
- case TAG_Valid:
- setsign(st0_ptr, getsign(st0_ptr) ^ getsign(st1_ptr));
- FPU_copy_to_reg1(st0_ptr, st0_tag);
- break;
-
- case TW_Infinity:
- /* Infinity*log(1) */
- if ( arith_invalid(1) < 0 )
- return;
- break;
+ || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal))) {
+ if (denormal_operand() < 0)
+ return;
- case TW_NaN:
- if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
- return;
- break;
-
- default:
+ goto valid_yl2xp1;
+ } else if ((st0_tag == TAG_Empty) | (st1_tag == TAG_Empty)) {
+ FPU_stack_underflow_pop(1);
+ return;
+ } else if (st0_tag == TAG_Zero) {
+ switch (st1_tag) {
+ case TW_Denormal:
+ if (denormal_operand() < 0)
+ return;
+
+ case TAG_Zero:
+ case TAG_Valid:
+ setsign(st0_ptr, getsign(st0_ptr) ^ getsign(st1_ptr));
+ FPU_copy_to_reg1(st0_ptr, st0_tag);
+ break;
+
+ case TW_Infinity:
+ /* Infinity*log(1) */
+ if (arith_invalid(1) < 0)
+ return;
+ break;
+
+ case TW_NaN:
+ if (real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0)
+ return;
+ break;
+
+ default:
#ifdef PARANOID
- EXCEPTION(EX_INTERNAL | 0x116);
- return;
+ EXCEPTION(EX_INTERNAL | 0x116);
+ return;
#endif /* PARANOID */
- break;
- }
- }
- else if ( (st0_tag == TAG_Valid) || (st0_tag == TW_Denormal) )
- {
- switch ( st1_tag )
- {
- case TAG_Zero:
- if ( signnegative(st0_ptr) )
- {
- if ( exponent(st0_ptr) >= 0 )
- {
- /* st(0) holds <= -1.0 */
-#ifdef PECULIAR_486 /* Stupid 80486 doesn't worry about log(negative). */
- changesign(st1_ptr);
+ break;
+ }
+ } else if ((st0_tag == TAG_Valid) || (st0_tag == TW_Denormal)) {
+ switch (st1_tag) {
+ case TAG_Zero:
+ if (signnegative(st0_ptr)) {
+ if (exponent(st0_ptr) >= 0) {
+ /* st(0) holds <= -1.0 */
+#ifdef PECULIAR_486 /* Stupid 80486 doesn't worry about log(negative). */
+ changesign(st1_ptr);
#else
- if ( arith_invalid(1) < 0 )
- return;
+ if (arith_invalid(1) < 0)
+ return;
#endif /* PECULIAR_486 */
- }
- else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
- return;
- else
- changesign(st1_ptr);
- }
- else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
- return;
- break;
-
- case TW_Infinity:
- if ( signnegative(st0_ptr) )
- {
- if ( (exponent(st0_ptr) >= 0) &&
- !((st0_ptr->sigh == 0x80000000) &&
- (st0_ptr->sigl == 0)) )
- {
- /* st(0) holds < -1.0 */
-#ifdef PECULIAR_486 /* Stupid 80486 doesn't worry about log(negative). */
- changesign(st1_ptr);
+ } else if ((st0_tag == TW_Denormal)
+ && (denormal_operand() < 0))
+ return;
+ else
+ changesign(st1_ptr);
+ } else if ((st0_tag == TW_Denormal)
+ && (denormal_operand() < 0))
+ return;
+ break;
+
+ case TW_Infinity:
+ if (signnegative(st0_ptr)) {
+ if ((exponent(st0_ptr) >= 0) &&
+ !((st0_ptr->sigh == 0x80000000) &&
+ (st0_ptr->sigl == 0))) {
+ /* st(0) holds < -1.0 */
+#ifdef PECULIAR_486 /* Stupid 80486 doesn't worry about log(negative). */
+ changesign(st1_ptr);
#else
- if ( arith_invalid(1) < 0 ) return;
+ if (arith_invalid(1) < 0)
+ return;
#endif /* PECULIAR_486 */
+ } else if ((st0_tag == TW_Denormal)
+ && (denormal_operand() < 0))
+ return;
+ else
+ changesign(st1_ptr);
+ } else if ((st0_tag == TW_Denormal)
+ && (denormal_operand() < 0))
+ return;
+ break;
+
+ case TW_NaN:
+ if (real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0)
+ return;
}
- else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
- return;
- else
- changesign(st1_ptr);
- }
- else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
- return;
- break;
-
- case TW_NaN:
- if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
- return;
- }
- }
- else if ( st0_tag == TW_NaN )
- {
- if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
- return;
- }
- else if ( st0_tag == TW_Infinity )
- {
- if ( st1_tag == TW_NaN )
- {
- if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
- return;
- }
- else if ( signnegative(st0_ptr) )
- {
+ } else if (st0_tag == TW_NaN) {
+ if (real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0)
+ return;
+ } else if (st0_tag == TW_Infinity) {
+ if (st1_tag == TW_NaN) {
+ if (real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0)
+ return;
+ } else if (signnegative(st0_ptr)) {
#ifndef PECULIAR_486
- /* This should have higher priority than denormals, but... */
- if ( arith_invalid(1) < 0 ) /* log(-infinity) */
- return;
+ /* This should have higher priority than denormals, but... */
+ if (arith_invalid(1) < 0) /* log(-infinity) */
+ return;
#endif /* PECULIAR_486 */
- if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
- return;
+ if ((st1_tag == TW_Denormal)
+ && (denormal_operand() < 0))
+ return;
#ifdef PECULIAR_486
- /* Denormal operands actually get higher priority */
- if ( arith_invalid(1) < 0 ) /* log(-infinity) */
- return;
+ /* Denormal operands actually get higher priority */
+ if (arith_invalid(1) < 0) /* log(-infinity) */
+ return;
#endif /* PECULIAR_486 */
- }
- else if ( st1_tag == TAG_Zero )
- {
- /* log(infinity) */
- if ( arith_invalid(1) < 0 )
- return;
- }
-
- /* st(1) must be valid here. */
+ } else if (st1_tag == TAG_Zero) {
+ /* log(infinity) */
+ if (arith_invalid(1) < 0)
+ return;
+ }
- else if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
- return;
+ /* st(1) must be valid here. */
+
+ else if ((st1_tag == TW_Denormal) && (denormal_operand() < 0))
+ return;
- /* The Manual says that log(Infinity) is invalid, but a real
- 80486 sensibly says that it is o.k. */
- else
- {
- u_char sign = getsign(st1_ptr);
- FPU_copy_to_reg1(&CONST_INF, TAG_Special);
- setsign(st1_ptr, sign);
+ /* The Manual says that log(Infinity) is invalid, but a real
+ 80486 sensibly says that it is o.k. */
+ else {
+ u_char sign = getsign(st1_ptr);
+ FPU_copy_to_reg1(&CONST_INF, TAG_Special);
+ setsign(st1_ptr, sign);
+ }
}
- }
#ifdef PARANOID
- else
- {
- EXCEPTION(EX_INTERNAL | 0x117);
- return;
- }
+ else {
+ EXCEPTION(EX_INTERNAL | 0x117);
+ return;
+ }
#endif /* PARANOID */
- FPU_pop();
- return;
+ FPU_pop();
+ return;
}
-
-static void fscale(FPU_REG *st0_ptr, u_char st0_tag)
+static void fscale(FPU_REG * st0_ptr, u_char st0_tag)
{
- FPU_REG *st1_ptr = &st(1);
- u_char st1_tag = FPU_gettagi(1);
- int old_cw = control_word;
- u_char sign = getsign(st0_ptr);
-
- clear_C1();
- if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) )
- {
- long scale;
- FPU_REG tmp;
-
- /* Convert register for internal use. */
- setexponent16(st0_ptr, exponent(st0_ptr));
-
- valid_scale:
-
- if ( exponent(st1_ptr) > 30 )
- {
- /* 2^31 is far too large, would require 2^(2^30) or 2^(-2^30) */
-
- if ( signpositive(st1_ptr) )
- {
- EXCEPTION(EX_Overflow);
- FPU_copy_to_reg0(&CONST_INF, TAG_Special);
- }
- else
- {
- EXCEPTION(EX_Underflow);
- FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
- }
- setsign(st0_ptr, sign);
- return;
- }
-
- control_word &= ~CW_RC;
- control_word |= RC_CHOP;
- reg_copy(st1_ptr, &tmp);
- FPU_round_to_int(&tmp, st1_tag); /* This can never overflow here */
- control_word = old_cw;
- scale = signnegative(st1_ptr) ? -tmp.sigl : tmp.sigl;
- scale += exponent16(st0_ptr);
-
- setexponent16(st0_ptr, scale);
-
- /* Use FPU_round() to properly detect under/overflow etc */
- FPU_round(st0_ptr, 0, 0, control_word, sign);
-
- return;
- }
-
- if ( st0_tag == TAG_Special )
- st0_tag = FPU_Special(st0_ptr);
- if ( st1_tag == TAG_Special )
- st1_tag = FPU_Special(st1_ptr);
-
- if ( (st0_tag == TAG_Valid) || (st0_tag == TW_Denormal) )
- {
- switch ( st1_tag )
- {
- case TAG_Valid:
- /* st(0) must be a denormal */
- if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
- return;
-
- FPU_to_exp16(st0_ptr, st0_ptr); /* Will not be left on stack */
- goto valid_scale;
-
- case TAG_Zero:
- if ( st0_tag == TW_Denormal )
- denormal_operand();
- return;
-
- case TW_Denormal:
- denormal_operand();
- return;
-
- case TW_Infinity:
- if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
- return;
-
- if ( signpositive(st1_ptr) )
- FPU_copy_to_reg0(&CONST_INF, TAG_Special);
- else
- FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
- setsign(st0_ptr, sign);
- return;
+ FPU_REG *st1_ptr = &st(1);
+ u_char st1_tag = FPU_gettagi(1);
+ int old_cw = control_word;
+ u_char sign = getsign(st0_ptr);
+
+ clear_C1();
+ if (!((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid))) {
+ long scale;
+ FPU_REG tmp;
+
+ /* Convert register for internal use. */
+ setexponent16(st0_ptr, exponent(st0_ptr));
+
+ valid_scale:
+
+ if (exponent(st1_ptr) > 30) {
+ /* 2^31 is far too large, would require 2^(2^30) or 2^(-2^30) */
+
+ if (signpositive(st1_ptr)) {
+ EXCEPTION(EX_Overflow);
+ FPU_copy_to_reg0(&CONST_INF, TAG_Special);
+ } else {
+ EXCEPTION(EX_Underflow);
+ FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
+ }
+ setsign(st0_ptr, sign);
+ return;
+ }
- case TW_NaN:
- real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
- return;
- }
- }
- else if ( st0_tag == TAG_Zero )
- {
- switch ( st1_tag )
- {
- case TAG_Valid:
- case TAG_Zero:
- return;
+ control_word &= ~CW_RC;
+ control_word |= RC_CHOP;
+ reg_copy(st1_ptr, &tmp);
+ FPU_round_to_int(&tmp, st1_tag); /* This can never overflow here */
+ control_word = old_cw;
+ scale = signnegative(st1_ptr) ? -tmp.sigl : tmp.sigl;
+ scale += exponent16(st0_ptr);
- case TW_Denormal:
- denormal_operand();
- return;
+ setexponent16(st0_ptr, scale);
- case TW_Infinity:
- if ( signpositive(st1_ptr) )
- arith_invalid(0); /* Zero scaled by +Infinity */
- return;
+ /* Use FPU_round() to properly detect under/overflow etc */
+ FPU_round(st0_ptr, 0, 0, control_word, sign);
- case TW_NaN:
- real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
- return;
+ return;
}
- }
- else if ( st0_tag == TW_Infinity )
- {
- switch ( st1_tag )
- {
- case TAG_Valid:
- case TAG_Zero:
- return;
-
- case TW_Denormal:
- denormal_operand();
- return;
- case TW_Infinity:
- if ( signnegative(st1_ptr) )
- arith_invalid(0); /* Infinity scaled by -Infinity */
- return;
-
- case TW_NaN:
- real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
- return;
+ if (st0_tag == TAG_Special)
+ st0_tag = FPU_Special(st0_ptr);
+ if (st1_tag == TAG_Special)
+ st1_tag = FPU_Special(st1_ptr);
+
+ if ((st0_tag == TAG_Valid) || (st0_tag == TW_Denormal)) {
+ switch (st1_tag) {
+ case TAG_Valid:
+ /* st(0) must be a denormal */
+ if ((st0_tag == TW_Denormal)
+ && (denormal_operand() < 0))
+ return;
+
+ FPU_to_exp16(st0_ptr, st0_ptr); /* Will not be left on stack */
+ goto valid_scale;
+
+ case TAG_Zero:
+ if (st0_tag == TW_Denormal)
+ denormal_operand();
+ return;
+
+ case TW_Denormal:
+ denormal_operand();
+ return;
+
+ case TW_Infinity:
+ if ((st0_tag == TW_Denormal)
+ && (denormal_operand() < 0))
+ return;
+
+ if (signpositive(st1_ptr))
+ FPU_copy_to_reg0(&CONST_INF, TAG_Special);
+ else
+ FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
+ setsign(st0_ptr, sign);
+ return;
+
+ case TW_NaN:
+ real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
+ return;
+ }
+ } else if (st0_tag == TAG_Zero) {
+ switch (st1_tag) {
+ case TAG_Valid:
+ case TAG_Zero:
+ return;
+
+ case TW_Denormal:
+ denormal_operand();
+ return;
+
+ case TW_Infinity:
+ if (signpositive(st1_ptr))
+ arith_invalid(0); /* Zero scaled by +Infinity */
+ return;
+
+ case TW_NaN:
+ real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
+ return;
+ }
+ } else if (st0_tag == TW_Infinity) {
+ switch (st1_tag) {
+ case TAG_Valid:
+ case TAG_Zero:
+ return;
+
+ case TW_Denormal:
+ denormal_operand();
+ return;
+
+ case TW_Infinity:
+ if (signnegative(st1_ptr))
+ arith_invalid(0); /* Infinity scaled by -Infinity */
+ return;
+
+ case TW_NaN:
+ real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
+ return;
+ }
+ } else if (st0_tag == TW_NaN) {
+ if (st1_tag != TAG_Empty) {
+ real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
+ return;
+ }
}
- }
- else if ( st0_tag == TW_NaN )
- {
- if ( st1_tag != TAG_Empty )
- { real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr); return; }
- }
-
#ifdef PARANOID
- if ( !((st0_tag == TAG_Empty) || (st1_tag == TAG_Empty)) )
- {
- EXCEPTION(EX_INTERNAL | 0x115);
- return;
- }
+ if (!((st0_tag == TAG_Empty) || (st1_tag == TAG_Empty))) {
+ EXCEPTION(EX_INTERNAL | 0x115);
+ return;
+ }
#endif
- /* At least one of st(0), st(1) must be empty */
- FPU_stack_underflow();
+ /* At least one of st(0), st(1) must be empty */
+ FPU_stack_underflow();
}
-
/*---------------------------------------------------------------------------*/
static FUNC_ST0 const trig_table_a[] = {
- f2xm1, fyl2x, fptan, fpatan,
- fxtract, fprem1, (FUNC_ST0)fdecstp, (FUNC_ST0)fincstp
+ f2xm1, fyl2x, fptan, fpatan,
+ fxtract, fprem1, (FUNC_ST0) fdecstp, (FUNC_ST0) fincstp
};
void FPU_triga(void)
{
- (trig_table_a[FPU_rm])(&st(0), FPU_gettag0());
+ (trig_table_a[FPU_rm]) (&st(0), FPU_gettag0());
}
-
-static FUNC_ST0 const trig_table_b[] =
- {
- fprem, fyl2xp1, fsqrt_, fsincos, frndint_, fscale, (FUNC_ST0)fsin, fcos
- };
+static FUNC_ST0 const trig_table_b[] = {
+ fprem, fyl2xp1, fsqrt_, fsincos, frndint_, fscale, (FUNC_ST0) fsin, fcos
+};
void FPU_trigb(void)
{
- (trig_table_b[FPU_rm])(&st(0), FPU_gettag0());
+ (trig_table_b[FPU_rm]) (&st(0), FPU_gettag0());
}
diff --git a/arch/x86/math-emu/get_address.c b/arch/x86/math-emu/get_address.c
index 2e2c51a8bd3a..d701e2b39e44 100644
--- a/arch/x86/math-emu/get_address.c
+++ b/arch/x86/math-emu/get_address.c
@@ -17,7 +17,6 @@
| other processes using the emulator while swapping is in progress. |
+---------------------------------------------------------------------------*/
-
#include <linux/stddef.h>
#include <asm/uaccess.h>
@@ -27,31 +26,30 @@
#include "exception.h"
#include "fpu_emu.h"
-
#define FPU_WRITE_BIT 0x10
static int reg_offset[] = {
- offsetof(struct info,___eax),
- offsetof(struct info,___ecx),
- offsetof(struct info,___edx),
- offsetof(struct info,___ebx),
- offsetof(struct info,___esp),
- offsetof(struct info,___ebp),
- offsetof(struct info,___esi),
- offsetof(struct info,___edi)
+ offsetof(struct info, ___eax),
+ offsetof(struct info, ___ecx),
+ offsetof(struct info, ___edx),
+ offsetof(struct info, ___ebx),
+ offsetof(struct info, ___esp),
+ offsetof(struct info, ___ebp),
+ offsetof(struct info, ___esi),
+ offsetof(struct info, ___edi)
};
#define REG_(x) (*(long *)(reg_offset[(x)]+(u_char *) FPU_info))
static int reg_offset_vm86[] = {
- offsetof(struct info,___cs),
- offsetof(struct info,___vm86_ds),
- offsetof(struct info,___vm86_es),
- offsetof(struct info,___vm86_fs),
- offsetof(struct info,___vm86_gs),
- offsetof(struct info,___ss),
- offsetof(struct info,___vm86_ds)
- };
+ offsetof(struct info, ___cs),
+ offsetof(struct info, ___vm86_ds),
+ offsetof(struct info, ___vm86_es),
+ offsetof(struct info, ___vm86_fs),
+ offsetof(struct info, ___vm86_gs),
+ offsetof(struct info, ___ss),
+ offsetof(struct info, ___vm86_ds)
+};
#define VM86_REG_(x) (*(unsigned short *) \
(reg_offset_vm86[((unsigned)x)]+(u_char *) FPU_info))
@@ -60,158 +58,141 @@ static int reg_offset_vm86[] = {
#define ___GS ___ds
static int reg_offset_pm[] = {
- offsetof(struct info,___cs),
- offsetof(struct info,___ds),
- offsetof(struct info,___es),
- offsetof(struct info,___fs),
- offsetof(struct info,___GS),
- offsetof(struct info,___ss),
- offsetof(struct info,___ds)
- };
+ offsetof(struct info, ___cs),
+ offsetof(struct info, ___ds),
+ offsetof(struct info, ___es),
+ offsetof(struct info, ___fs),
+ offsetof(struct info, ___GS),
+ offsetof(struct info, ___ss),
+ offsetof(struct info, ___ds)
+};
#define PM_REG_(x) (*(unsigned short *) \
(reg_offset_pm[((unsigned)x)]+(u_char *) FPU_info))
-
/* Decode the SIB byte. This function assumes mod != 0 */
static int sib(int mod, unsigned long *fpu_eip)
{
- u_char ss,index,base;
- long offset;
-
- RE_ENTRANT_CHECK_OFF;
- FPU_code_access_ok(1);
- FPU_get_user(base, (u_char __user *) (*fpu_eip)); /* The SIB byte */
- RE_ENTRANT_CHECK_ON;
- (*fpu_eip)++;
- ss = base >> 6;
- index = (base >> 3) & 7;
- base &= 7;
-
- if ((mod == 0) && (base == 5))
- offset = 0; /* No base register */
- else
- offset = REG_(base);
-
- if (index == 4)
- {
- /* No index register */
- /* A non-zero ss is illegal */
- if ( ss )
- EXCEPTION(EX_Invalid);
- }
- else
- {
- offset += (REG_(index)) << ss;
- }
-
- if (mod == 1)
- {
- /* 8 bit signed displacement */
- long displacement;
- RE_ENTRANT_CHECK_OFF;
- FPU_code_access_ok(1);
- FPU_get_user(displacement, (signed char __user *) (*fpu_eip));
- offset += displacement;
- RE_ENTRANT_CHECK_ON;
- (*fpu_eip)++;
- }
- else if (mod == 2 || base == 5) /* The second condition also has mod==0 */
- {
- /* 32 bit displacement */
- long displacement;
- RE_ENTRANT_CHECK_OFF;
- FPU_code_access_ok(4);
- FPU_get_user(displacement, (long __user *) (*fpu_eip));
- offset += displacement;
- RE_ENTRANT_CHECK_ON;
- (*fpu_eip) += 4;
- }
-
- return offset;
-}
+ u_char ss, index, base;
+ long offset;
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_access_ok(1);
+ FPU_get_user(base, (u_char __user *) (*fpu_eip)); /* The SIB byte */
+ RE_ENTRANT_CHECK_ON;
+ (*fpu_eip)++;
+ ss = base >> 6;
+ index = (base >> 3) & 7;
+ base &= 7;
+
+ if ((mod == 0) && (base == 5))
+ offset = 0; /* No base register */
+ else
+ offset = REG_(base);
+
+ if (index == 4) {
+ /* No index register */
+ /* A non-zero ss is illegal */
+ if (ss)
+ EXCEPTION(EX_Invalid);
+ } else {
+ offset += (REG_(index)) << ss;
+ }
+
+ if (mod == 1) {
+ /* 8 bit signed displacement */
+ long displacement;
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_access_ok(1);
+ FPU_get_user(displacement, (signed char __user *)(*fpu_eip));
+ offset += displacement;
+ RE_ENTRANT_CHECK_ON;
+ (*fpu_eip)++;
+ } else if (mod == 2 || base == 5) { /* The second condition also has mod==0 */
+ /* 32 bit displacement */
+ long displacement;
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_access_ok(4);
+ FPU_get_user(displacement, (long __user *)(*fpu_eip));
+ offset += displacement;
+ RE_ENTRANT_CHECK_ON;
+ (*fpu_eip) += 4;
+ }
+ return offset;
+}
-static unsigned long vm86_segment(u_char segment,
- struct address *addr)
+static unsigned long vm86_segment(u_char segment, struct address *addr)
{
- segment--;
+ segment--;
#ifdef PARANOID
- if ( segment > PREFIX_SS_ )
- {
- EXCEPTION(EX_INTERNAL|0x130);
- math_abort(FPU_info,SIGSEGV);
- }
+ if (segment > PREFIX_SS_) {
+ EXCEPTION(EX_INTERNAL | 0x130);
+ math_abort(FPU_info, SIGSEGV);
+ }
#endif /* PARANOID */
- addr->selector = VM86_REG_(segment);
- return (unsigned long)VM86_REG_(segment) << 4;
+ addr->selector = VM86_REG_(segment);
+ return (unsigned long)VM86_REG_(segment) << 4;
}
-
/* This should work for 16 and 32 bit protected mode. */
static long pm_address(u_char FPU_modrm, u_char segment,
struct address *addr, long offset)
-{
- struct desc_struct descriptor;
- unsigned long base_address, limit, address, seg_top;
+{
+ struct desc_struct descriptor;
+ unsigned long base_address, limit, address, seg_top;
- segment--;
+ segment--;
#ifdef PARANOID
- /* segment is unsigned, so this also detects if segment was 0: */
- if ( segment > PREFIX_SS_ )
- {
- EXCEPTION(EX_INTERNAL|0x132);
- math_abort(FPU_info,SIGSEGV);
- }
+ /* segment is unsigned, so this also detects if segment was 0: */
+ if (segment > PREFIX_SS_) {
+ EXCEPTION(EX_INTERNAL | 0x132);
+ math_abort(FPU_info, SIGSEGV);
+ }
#endif /* PARANOID */
- switch ( segment )
- {
- /* gs isn't used by the kernel, so it still has its
- user-space value. */
- case PREFIX_GS_-1:
- /* N.B. - movl %seg, mem is a 2 byte write regardless of prefix */
- savesegment(gs, addr->selector);
- break;
- default:
- addr->selector = PM_REG_(segment);
- }
-
- descriptor = LDT_DESCRIPTOR(PM_REG_(segment));
- base_address = SEG_BASE_ADDR(descriptor);
- address = base_address + offset;
- limit = base_address
- + (SEG_LIMIT(descriptor)+1) * SEG_GRANULARITY(descriptor) - 1;
- if ( limit < base_address ) limit = 0xffffffff;
-
- if ( SEG_EXPAND_DOWN(descriptor) )
- {
- if ( SEG_G_BIT(descriptor) )
- seg_top = 0xffffffff;
- else
- {
- seg_top = base_address + (1 << 20);
- if ( seg_top < base_address ) seg_top = 0xffffffff;
+ switch (segment) {
+ /* gs isn't used by the kernel, so it still has its
+ user-space value. */
+ case PREFIX_GS_ - 1:
+ /* N.B. - movl %seg, mem is a 2 byte write regardless of prefix */
+ savesegment(gs, addr->selector);
+ break;
+ default:
+ addr->selector = PM_REG_(segment);
}
- access_limit =
- (address <= limit) || (address >= seg_top) ? 0 :
- ((seg_top-address) >= 255 ? 255 : seg_top-address);
- }
- else
- {
- access_limit =
- (address > limit) || (address < base_address) ? 0 :
- ((limit-address) >= 254 ? 255 : limit-address+1);
- }
- if ( SEG_EXECUTE_ONLY(descriptor) ||
- (!SEG_WRITE_PERM(descriptor) && (FPU_modrm & FPU_WRITE_BIT)) )
- {
- access_limit = 0;
- }
- return address;
-}
+ descriptor = LDT_DESCRIPTOR(PM_REG_(segment));
+ base_address = SEG_BASE_ADDR(descriptor);
+ address = base_address + offset;
+ limit = base_address
+ + (SEG_LIMIT(descriptor) + 1) * SEG_GRANULARITY(descriptor) - 1;
+ if (limit < base_address)
+ limit = 0xffffffff;
+
+ if (SEG_EXPAND_DOWN(descriptor)) {
+ if (SEG_G_BIT(descriptor))
+ seg_top = 0xffffffff;
+ else {
+ seg_top = base_address + (1 << 20);
+ if (seg_top < base_address)
+ seg_top = 0xffffffff;
+ }
+ access_limit =
+ (address <= limit) || (address >= seg_top) ? 0 :
+ ((seg_top - address) >= 255 ? 255 : seg_top - address);
+ } else {
+ access_limit =
+ (address > limit) || (address < base_address) ? 0 :
+ ((limit - address) >= 254 ? 255 : limit - address + 1);
+ }
+ if (SEG_EXECUTE_ONLY(descriptor) ||
+ (!SEG_WRITE_PERM(descriptor) && (FPU_modrm & FPU_WRITE_BIT))) {
+ access_limit = 0;
+ }
+ return address;
+}
/*
MOD R/M byte: MOD == 3 has a special use for the FPU
@@ -221,7 +202,6 @@ static long pm_address(u_char FPU_modrm, u_char segment,
..... ......... .........
MOD OPCODE(2) R/M
-
SIB byte
7 6 5 4 3 2 1 0
@@ -231,208 +211,194 @@ static long pm_address(u_char FPU_modrm, u_char segment,
*/
void __user *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip,
- struct address *addr,
- fpu_addr_modes addr_modes)
+ struct address *addr, fpu_addr_modes addr_modes)
+{
+ u_char mod;
+ unsigned rm = FPU_modrm & 7;
+ long *cpu_reg_ptr;
+ int address = 0; /* Initialized just to stop compiler warnings. */
+
+ /* Memory accessed via the cs selector is write protected
+ in `non-segmented' 32 bit protected mode. */
+ if (!addr_modes.default_mode && (FPU_modrm & FPU_WRITE_BIT)
+ && (addr_modes.override.segment == PREFIX_CS_)) {
+ math_abort(FPU_info, SIGSEGV);
+ }
+
+ addr->selector = FPU_DS; /* Default, for 32 bit non-segmented mode. */
+
+ mod = (FPU_modrm >> 6) & 3;
+
+ if (rm == 4 && mod != 3) {
+ address = sib(mod, fpu_eip);
+ } else {
+ cpu_reg_ptr = ®_(rm);
+ switch (mod) {
+ case 0:
+ if (rm == 5) {
+ /* Special case: disp32 */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_access_ok(4);
+ FPU_get_user(address,
+ (unsigned long __user
+ *)(*fpu_eip));
+ (*fpu_eip) += 4;
+ RE_ENTRANT_CHECK_ON;
+ addr->offset = address;
+ return (void __user *)address;
+ } else {
+ address = *cpu_reg_ptr; /* Just return the contents
+ of the cpu register */
+ addr->offset = address;
+ return (void __user *)address;
+ }
+ case 1:
+ /* 8 bit signed displacement */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_access_ok(1);
+ FPU_get_user(address, (signed char __user *)(*fpu_eip));
+ RE_ENTRANT_CHECK_ON;
+ (*fpu_eip)++;
+ break;
+ case 2:
+ /* 32 bit displacement */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_access_ok(4);
+ FPU_get_user(address, (long __user *)(*fpu_eip));
+ (*fpu_eip) += 4;
+ RE_ENTRANT_CHECK_ON;
+ break;
+ case 3:
+ /* Not legal for the FPU */
+ EXCEPTION(EX_Invalid);
+ }
+ address += *cpu_reg_ptr;
+ }
+
+ addr->offset = address;
+
+ switch (addr_modes.default_mode) {
+ case 0:
+ break;
+ case VM86:
+ address += vm86_segment(addr_modes.override.segment, addr);
+ break;
+ case PM16:
+ case SEG32:
+ address = pm_address(FPU_modrm, addr_modes.override.segment,
+ addr, address);
+ break;
+ default:
+ EXCEPTION(EX_INTERNAL | 0x133);
+ }
+
+ return (void __user *)address;
+}
+
+void __user *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
+ struct address *addr, fpu_addr_modes addr_modes)
{
- u_char mod;
- unsigned rm = FPU_modrm & 7;
- long *cpu_reg_ptr;
- int address = 0; /* Initialized just to stop compiler warnings. */
-
- /* Memory accessed via the cs selector is write protected
- in `non-segmented' 32 bit protected mode. */
- if ( !addr_modes.default_mode && (FPU_modrm & FPU_WRITE_BIT)
- && (addr_modes.override.segment == PREFIX_CS_) )
- {
- math_abort(FPU_info,SIGSEGV);
- }
-
- addr->selector = FPU_DS; /* Default, for 32 bit non-segmented mode. */
-
- mod = (FPU_modrm >> 6) & 3;
-
- if (rm == 4 && mod != 3)
- {
- address = sib(mod, fpu_eip);
- }
- else
- {
- cpu_reg_ptr = & REG_(rm);
- switch (mod)
- {
+ u_char mod;
+ unsigned rm = FPU_modrm & 7;
+ int address = 0; /* Default used for mod == 0 */
+
+ /* Memory accessed via the cs selector is write protected
+ in `non-segmented' 32 bit protected mode. */
+ if (!addr_modes.default_mode && (FPU_modrm & FPU_WRITE_BIT)
+ && (addr_modes.override.segment == PREFIX_CS_)) {
+ math_abort(FPU_info, SIGSEGV);
+ }
+
+ addr->selector = FPU_DS; /* Default, for 32 bit non-segmented mode. */
+
+ mod = (FPU_modrm >> 6) & 3;
+
+ switch (mod) {
case 0:
- if (rm == 5)
- {
- /* Special case: disp32 */
- RE_ENTRANT_CHECK_OFF;
- FPU_code_access_ok(4);
- FPU_get_user(address, (unsigned long __user *) (*fpu_eip));
- (*fpu_eip) += 4;
- RE_ENTRANT_CHECK_ON;
- addr->offset = address;
- return (void __user *) address;
- }
- else
- {
- address = *cpu_reg_ptr; /* Just return the contents
- of the cpu register */
- addr->offset = address;
- return (void __user *) address;
- }
+ if (rm == 6) {
+ /* Special case: disp16 */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_access_ok(2);
+ FPU_get_user(address,
+ (unsigned short __user *)(*fpu_eip));
+ (*fpu_eip) += 2;
+ RE_ENTRANT_CHECK_ON;
+ goto add_segment;
+ }
+ break;
case 1:
- /* 8 bit signed displacement */
- RE_ENTRANT_CHECK_OFF;
- FPU_code_access_ok(1);
- FPU_get_user(address, (signed char __user *) (*fpu_eip));
- RE_ENTRANT_CHECK_ON;
- (*fpu_eip)++;
- break;
+ /* 8 bit signed displacement */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_access_ok(1);
+ FPU_get_user(address, (signed char __user *)(*fpu_eip));
+ RE_ENTRANT_CHECK_ON;
+ (*fpu_eip)++;
+ break;
case 2:
- /* 32 bit displacement */
- RE_ENTRANT_CHECK_OFF;
- FPU_code_access_ok(4);
- FPU_get_user(address, (long __user *) (*fpu_eip));
- (*fpu_eip) += 4;
- RE_ENTRANT_CHECK_ON;
- break;
+ /* 16 bit displacement */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_access_ok(2);
+ FPU_get_user(address, (unsigned short __user *)(*fpu_eip));
+ (*fpu_eip) += 2;
+ RE_ENTRANT_CHECK_ON;
+ break;
case 3:
- /* Not legal for the FPU */
- EXCEPTION(EX_Invalid);
+ /* Not legal for the FPU */
+ EXCEPTION(EX_Invalid);
+ break;
+ }
+ switch (rm) {
+ case 0:
+ address += FPU_info->___ebx + FPU_info->___esi;
+ break;
+ case 1:
+ address += FPU_info->___ebx + FPU_info->___edi;
+ break;
+ case 2:
+ address += FPU_info->___ebp + FPU_info->___esi;
+ if (addr_modes.override.segment == PREFIX_DEFAULT)
+ addr_modes.override.segment = PREFIX_SS_;
+ break;
+ case 3:
+ address += FPU_info->___ebp + FPU_info->___edi;
+ if (addr_modes.override.segment == PREFIX_DEFAULT)
+ addr_modes.override.segment = PREFIX_SS_;
+ break;
+ case 4:
+ address += FPU_info->___esi;
+ break;
+ case 5:
+ address += FPU_info->___edi;
+ break;
+ case 6:
+ address += FPU_info->___ebp;
+ if (addr_modes.override.segment == PREFIX_DEFAULT)
+ addr_modes.override.segment = PREFIX_SS_;
+ break;
+ case 7:
+ address += FPU_info->___ebx;
+ break;
}
- address += *cpu_reg_ptr;
- }
-
- addr->offset = address;
-
- switch ( addr_modes.default_mode )
- {
- case 0:
- break;
- case VM86:
- address += vm86_segment(addr_modes.override.segment, addr);
- break;
- case PM16:
- case SEG32:
- address = pm_address(FPU_modrm, addr_modes.override.segment,
- addr, address);
- break;
- default:
- EXCEPTION(EX_INTERNAL|0x133);
- }
-
- return (void __user *)address;
-}
+ add_segment:
+ address &= 0xffff;
-void __user *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
- struct address *addr,
- fpu_addr_modes addr_modes)
-{
- u_char mod;
- unsigned rm = FPU_modrm & 7;
- int address = 0; /* Default used for mod == 0 */
-
- /* Memory accessed via the cs selector is write protected
- in `non-segmented' 32 bit protected mode. */
- if ( !addr_modes.default_mode && (FPU_modrm & FPU_WRITE_BIT)
- && (addr_modes.override.segment == PREFIX_CS_) )
- {
- math_abort(FPU_info,SIGSEGV);
- }
-
- addr->selector = FPU_DS; /* Default, for 32 bit non-segmented mode. */
-
- mod = (FPU_modrm >> 6) & 3;
-
- switch (mod)
- {
- case 0:
- if (rm == 6)
- {
- /* Special case: disp16 */
- RE_ENTRANT_CHECK_OFF;
- FPU_code_access_ok(2);
- FPU_get_user(address, (unsigned short __user *) (*fpu_eip));
- (*fpu_eip) += 2;
- RE_ENTRANT_CHECK_ON;
- goto add_segment;
+ addr->offset = address;
+
+ switch (addr_modes.default_mode) {
+ case 0:
+ break;
+ case VM86:
+ address += vm86_segment(addr_modes.override.segment, addr);
+ break;
+ case PM16:
+ case SEG32:
+ address = pm_address(FPU_modrm, addr_modes.override.segment,
+ addr, address);
+ break;
+ default:
+ EXCEPTION(EX_INTERNAL | 0x131);
}
- break;
- case 1:
- /* 8 bit signed displacement */
- RE_ENTRANT_CHECK_OFF;
- FPU_code_access_ok(1);
- FPU_get_user(address, (signed char __user *) (*fpu_eip));
- RE_ENTRANT_CHECK_ON;
- (*fpu_eip)++;
- break;
- case 2:
- /* 16 bit displacement */
- RE_ENTRANT_CHECK_OFF;
- FPU_code_access_ok(2);
- FPU_get_user(address, (unsigned short __user *) (*fpu_eip));
- (*fpu_eip) += 2;
- RE_ENTRANT_CHECK_ON;
- break;
- case 3:
- /* Not legal for the FPU */
- EXCEPTION(EX_Invalid);
- break;
- }
- switch ( rm )
- {
- case 0:
- address += FPU_info->___ebx + FPU_info->___esi;
- break;
- case 1:
- address += FPU_info->___ebx + FPU_info->___edi;
- break;
- case 2:
- address += FPU_info->___ebp + FPU_info->___esi;
- if ( addr_modes.override.segment == PREFIX_DEFAULT )
- addr_modes.override.segment = PREFIX_SS_;
- break;
- case 3:
- address += FPU_info->___ebp + FPU_info->___edi;
- if ( addr_modes.override.segment == PREFIX_DEFAULT )
- addr_modes.override.segment = PREFIX_SS_;
- break;
- case 4:
- address += FPU_info->___esi;
- break;
- case 5:
- address += FPU_info->___edi;
- break;
- case 6:
- address += FPU_info->___ebp;
- if ( addr_modes.override.segment == PREFIX_DEFAULT )
- addr_modes.override.segment = PREFIX_SS_;
- break;
- case 7:
- address += FPU_info->___ebx;
- break;
- }
-
- add_segment:
- address &= 0xffff;
-
- addr->offset = address;
-
- switch ( addr_modes.default_mode )
- {
- case 0:
- break;
- case VM86:
- address += vm86_segment(addr_modes.override.segment, addr);
- break;
- case PM16:
- case SEG32:
- address = pm_address(FPU_modrm, addr_modes.override.segment,
- addr, address);
- break;
- default:
- EXCEPTION(EX_INTERNAL|0x131);
- }
-
- return (void __user *)address ;
+
+ return (void __user *)address;
}
diff --git a/arch/x86/math-emu/load_store.c b/arch/x86/math-emu/load_store.c
index eebd6fb1c8a8..2931ff355218 100644
--- a/arch/x86/math-emu/load_store.c
+++ b/arch/x86/math-emu/load_store.c
@@ -26,247 +26,257 @@
#include "status_w.h"
#include "control_w.h"
-
-#define _NONE_ 0 /* st0_ptr etc not needed */
-#define _REG0_ 1 /* Will be storing st(0) */
-#define _PUSH_ 3 /* Need to check for space to push onto stack */
-#define _null_ 4 /* Function illegal or not implemented */
+#define _NONE_ 0 /* st0_ptr etc not needed */
+#define _REG0_ 1 /* Will be storing st(0) */
+#define _PUSH_ 3 /* Need to check for space to push onto stack */
+#define _null_ 4 /* Function illegal or not implemented */
#define pop_0() { FPU_settag0(TAG_Empty); top++; }
-
static u_char const type_table[32] = {
- _PUSH_, _PUSH_, _PUSH_, _PUSH_,
- _null_, _null_, _null_, _null_,
- _REG0_, _REG0_, _REG0_, _REG0_,
- _REG0_, _REG0_, _REG0_, _REG0_,
- _NONE_, _null_, _NONE_, _PUSH_,
- _NONE_, _PUSH_, _null_, _PUSH_,
- _NONE_, _null_, _NONE_, _REG0_,
- _NONE_, _REG0_, _NONE_, _REG0_
- };
+ _PUSH_, _PUSH_, _PUSH_, _PUSH_,
+ _null_, _null_, _null_, _null_,
+ _REG0_, _REG0_, _REG0_, _REG0_,
+ _REG0_, _REG0_, _REG0_, _REG0_,
+ _NONE_, _null_, _NONE_, _PUSH_,
+ _NONE_, _PUSH_, _null_, _PUSH_,
+ _NONE_, _null_, _NONE_, _REG0_,
+ _NONE_, _REG0_, _NONE_, _REG0_
+};
u_char const data_sizes_16[32] = {
- 4, 4, 8, 2, 0, 0, 0, 0,
- 4, 4, 8, 2, 4, 4, 8, 2,
- 14, 0, 94, 10, 2, 10, 0, 8,
- 14, 0, 94, 10, 2, 10, 2, 8
+ 4, 4, 8, 2, 0, 0, 0, 0,
+ 4, 4, 8, 2, 4, 4, 8, 2,
+ 14, 0, 94, 10, 2, 10, 0, 8,
+ 14, 0, 94, 10, 2, 10, 2, 8
};
static u_char const data_sizes_32[32] = {
- 4, 4, 8, 2, 0, 0, 0, 0,
- 4, 4, 8, 2, 4, 4, 8, 2,
- 28, 0,108, 10, 2, 10, 0, 8,
- 28, 0,108, 10, 2, 10, 2, 8
+ 4, 4, 8, 2, 0, 0, 0, 0,
+ 4, 4, 8, 2, 4, 4, 8, 2,
+ 28, 0, 108, 10, 2, 10, 0, 8,
+ 28, 0, 108, 10, 2, 10, 2, 8
};
int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
- void __user *data_address)
+ void __user * data_address)
{
- FPU_REG loaded_data;
- FPU_REG *st0_ptr;
- u_char st0_tag = TAG_Empty; /* This is just to stop a gcc warning. */
- u_char loaded_tag;
+ FPU_REG loaded_data;
+ FPU_REG *st0_ptr;
+ u_char st0_tag = TAG_Empty; /* This is just to stop a gcc warning. */
+ u_char loaded_tag;
- st0_ptr = NULL; /* Initialized just to stop compiler warnings. */
+ st0_ptr = NULL; /* Initialized just to stop compiler warnings. */
- if ( addr_modes.default_mode & PROTECTED )
- {
- if ( addr_modes.default_mode == SEG32 )
- {
- if ( access_limit < data_sizes_32[type] )
- math_abort(FPU_info,SIGSEGV);
- }
- else if ( addr_modes.default_mode == PM16 )
- {
- if ( access_limit < data_sizes_16[type] )
- math_abort(FPU_info,SIGSEGV);
- }
+ if (addr_modes.default_mode & PROTECTED) {
+ if (addr_modes.default_mode == SEG32) {
+ if (access_limit < data_sizes_32[type])
+ math_abort(FPU_info, SIGSEGV);
+ } else if (addr_modes.default_mode == PM16) {
+ if (access_limit < data_sizes_16[type])
+ math_abort(FPU_info, SIGSEGV);
+ }
#ifdef PARANOID
- else
- EXCEPTION(EX_INTERNAL|0x140);
+ else
+ EXCEPTION(EX_INTERNAL | 0x140);
#endif /* PARANOID */
- }
+ }
- switch ( type_table[type] )
- {
- case _NONE_:
- break;
- case _REG0_:
- st0_ptr = &st(0); /* Some of these instructions pop after
- storing */
- st0_tag = FPU_gettag0();
- break;
- case _PUSH_:
- {
- if ( FPU_gettagi(-1) != TAG_Empty )
- { FPU_stack_overflow(); return 0; }
- top--;
- st0_ptr = &st(0);
- }
- break;
- case _null_:
- FPU_illegal();
- return 0;
+ switch (type_table[type]) {
+ case _NONE_:
+ break;
+ case _REG0_:
+ st0_ptr = &st(0); /* Some of these instructions pop after
+ storing */
+ st0_tag = FPU_gettag0();
+ break;
+ case _PUSH_:
+ {
+ if (FPU_gettagi(-1) != TAG_Empty) {
+ FPU_stack_overflow();
+ return 0;
+ }
+ top--;
+ st0_ptr = &st(0);
+ }
+ break;
+ case _null_:
+ FPU_illegal();
+ return 0;
#ifdef PARANOID
- default:
- EXCEPTION(EX_INTERNAL|0x141);
- return 0;
+ default:
+ EXCEPTION(EX_INTERNAL | 0x141);
+ return 0;
#endif /* PARANOID */
- }
-
- switch ( type )
- {
- case 000: /* fld m32real */
- clear_C1();
- loaded_tag = FPU_load_single((float __user *)data_address, &loaded_data);
- if ( (loaded_tag == TAG_Special)
- && isNaN(&loaded_data)
- && (real_1op_NaN(&loaded_data) < 0) )
- {
- top++;
- break;
- }
- FPU_copy_to_reg0(&loaded_data, loaded_tag);
- break;
- case 001: /* fild m32int */
- clear_C1();
- loaded_tag = FPU_load_int32((long __user *)data_address, &loaded_data);
- FPU_copy_to_reg0(&loaded_data, loaded_tag);
- break;
- case 002: /* fld m64real */
- clear_C1();
- loaded_tag = FPU_load_double((double __user *)data_address, &loaded_data);
- if ( (loaded_tag == TAG_Special)
- && isNaN(&loaded_data)
- && (real_1op_NaN(&loaded_data) < 0) )
- {
- top++;
- break;
}
- FPU_copy_to_reg0(&loaded_data, loaded_tag);
- break;
- case 003: /* fild m16int */
- clear_C1();
- loaded_tag = FPU_load_int16((short __user *)data_address, &loaded_data);
- FPU_copy_to_reg0(&loaded_data, loaded_tag);
- break;
- case 010: /* fst m32real */
- clear_C1();
- FPU_store_single(st0_ptr, st0_tag, (float __user *)data_address);
- break;
- case 011: /* fist m32int */
- clear_C1();
- FPU_store_int32(st0_ptr, st0_tag, (long __user *)data_address);
- break;
- case 012: /* fst m64real */
- clear_C1();
- FPU_store_double(st0_ptr, st0_tag, (double __user *)data_address);
- break;
- case 013: /* fist m16int */
- clear_C1();
- FPU_store_int16(st0_ptr, st0_tag, (short __user *)data_address);
- break;
- case 014: /* fstp m32real */
- clear_C1();
- if ( FPU_store_single(st0_ptr, st0_tag, (float __user *)data_address) )
- pop_0(); /* pop only if the number was actually stored
- (see the 80486 manual p16-28) */
- break;
- case 015: /* fistp m32int */
- clear_C1();
- if ( FPU_store_int32(st0_ptr, st0_tag, (long __user *)data_address) )
- pop_0(); /* pop only if the number was actually stored
- (see the 80486 manual p16-28) */
- break;
- case 016: /* fstp m64real */
- clear_C1();
- if ( FPU_store_double(st0_ptr, st0_tag, (double __user *)data_address) )
- pop_0(); /* pop only if the number was actually stored
- (see the 80486 manual p16-28) */
- break;
- case 017: /* fistp m16int */
- clear_C1();
- if ( FPU_store_int16(st0_ptr, st0_tag, (short __user *)data_address) )
- pop_0(); /* pop only if the number was actually stored
- (see the 80486 manual p16-28) */
- break;
- case 020: /* fldenv m14/28byte */
- fldenv(addr_modes, (u_char __user *)data_address);
- /* Ensure that the values just loaded are not changed by
- fix-up operations. */
- return 1;
- case 022: /* frstor m94/108byte */
- frstor(addr_modes, (u_char __user *)data_address);
- /* Ensure that the values just loaded are not changed by
- fix-up operations. */
- return 1;
- case 023: /* fbld m80dec */
- clear_C1();
- loaded_tag = FPU_load_bcd((u_char __user *)data_address);
- FPU_settag0(loaded_tag);
- break;
- case 024: /* fldcw */
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_READ, data_address, 2);
- FPU_get_user(control_word, (unsigned short __user *) data_address);
- RE_ENTRANT_CHECK_ON;
- if ( partial_status & ~control_word & CW_Exceptions )
- partial_status |= (SW_Summary | SW_Backward);
- else
- partial_status &= ~(SW_Summary | SW_Backward);
+
+ switch (type) {
+ case 000: /* fld m32real */
+ clear_C1();
+ loaded_tag =
+ FPU_load_single((float __user *)data_address, &loaded_data);
+ if ((loaded_tag == TAG_Special)
+ && isNaN(&loaded_data)
+ && (real_1op_NaN(&loaded_data) < 0)) {
+ top++;
+ break;
+ }
+ FPU_copy_to_reg0(&loaded_data, loaded_tag);
+ break;
+ case 001: /* fild m32int */
+ clear_C1();
+ loaded_tag =
+ FPU_load_int32((long __user *)data_address, &loaded_data);
+ FPU_copy_to_reg0(&loaded_data, loaded_tag);
+ break;
+ case 002: /* fld m64real */
+ clear_C1();
+ loaded_tag =
+ FPU_load_double((double __user *)data_address,
+ &loaded_data);
+ if ((loaded_tag == TAG_Special)
+ && isNaN(&loaded_data)
+ && (real_1op_NaN(&loaded_data) < 0)) {
+ top++;
+ break;
+ }
+ FPU_copy_to_reg0(&loaded_data, loaded_tag);
+ break;
+ case 003: /* fild m16int */
+ clear_C1();
+ loaded_tag =
+ FPU_load_int16((short __user *)data_address, &loaded_data);
+ FPU_copy_to_reg0(&loaded_data, loaded_tag);
+ break;
+ case 010: /* fst m32real */
+ clear_C1();
+ FPU_store_single(st0_ptr, st0_tag,
+ (float __user *)data_address);
+ break;
+ case 011: /* fist m32int */
+ clear_C1();
+ FPU_store_int32(st0_ptr, st0_tag, (long __user *)data_address);
+ break;
+ case 012: /* fst m64real */
+ clear_C1();
+ FPU_store_double(st0_ptr, st0_tag,
+ (double __user *)data_address);
+ break;
+ case 013: /* fist m16int */
+ clear_C1();
+ FPU_store_int16(st0_ptr, st0_tag, (short __user *)data_address);
+ break;
+ case 014: /* fstp m32real */
+ clear_C1();
+ if (FPU_store_single
+ (st0_ptr, st0_tag, (float __user *)data_address))
+ pop_0(); /* pop only if the number was actually stored
+ (see the 80486 manual p16-28) */
+ break;
+ case 015: /* fistp m32int */
+ clear_C1();
+ if (FPU_store_int32
+ (st0_ptr, st0_tag, (long __user *)data_address))
+ pop_0(); /* pop only if the number was actually stored
+ (see the 80486 manual p16-28) */
+ break;
+ case 016: /* fstp m64real */
+ clear_C1();
+ if (FPU_store_double
+ (st0_ptr, st0_tag, (double __user *)data_address))
+ pop_0(); /* pop only if the number was actually stored
+ (see the 80486 manual p16-28) */
+ break;
+ case 017: /* fistp m16int */
+ clear_C1();
+ if (FPU_store_int16
+ (st0_ptr, st0_tag, (short __user *)data_address))
+ pop_0(); /* pop only if the number was actually stored
+ (see the 80486 manual p16-28) */
+ break;
+ case 020: /* fldenv m14/28byte */
+ fldenv(addr_modes, (u_char __user *) data_address);
+ /* Ensure that the values just loaded are not changed by
+ fix-up operations. */
+ return 1;
+ case 022: /* frstor m94/108byte */
+ frstor(addr_modes, (u_char __user *) data_address);
+ /* Ensure that the values just loaded are not changed by
+ fix-up operations. */
+ return 1;
+ case 023: /* fbld m80dec */
+ clear_C1();
+ loaded_tag = FPU_load_bcd((u_char __user *) data_address);
+ FPU_settag0(loaded_tag);
+ break;
+ case 024: /* fldcw */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_READ, data_address, 2);
+ FPU_get_user(control_word,
+ (unsigned short __user *)data_address);
+ RE_ENTRANT_CHECK_ON;
+ if (partial_status & ~control_word & CW_Exceptions)
+ partial_status |= (SW_Summary | SW_Backward);
+ else
+ partial_status &= ~(SW_Summary | SW_Backward);
#ifdef PECULIAR_486
- control_word |= 0x40; /* An 80486 appears to always set this bit */
+ control_word |= 0x40; /* An 80486 appears to always set this bit */
#endif /* PECULIAR_486 */
- return 1;
- case 025: /* fld m80real */
- clear_C1();
- loaded_tag = FPU_load_extended((long double __user *)data_address, 0);
- FPU_settag0(loaded_tag);
- break;
- case 027: /* fild m64int */
- clear_C1();
- loaded_tag = FPU_load_int64((long long __user *)data_address);
- if (loaded_tag == TAG_Error)
+ return 1;
+ case 025: /* fld m80real */
+ clear_C1();
+ loaded_tag =
+ FPU_load_extended((long double __user *)data_address, 0);
+ FPU_settag0(loaded_tag);
+ break;
+ case 027: /* fild m64int */
+ clear_C1();
+ loaded_tag = FPU_load_int64((long long __user *)data_address);
+ if (loaded_tag == TAG_Error)
+ return 0;
+ FPU_settag0(loaded_tag);
+ break;
+ case 030: /* fstenv m14/28byte */
+ fstenv(addr_modes, (u_char __user *) data_address);
+ return 1;
+ case 032: /* fsave */
+ fsave(addr_modes, (u_char __user *) data_address);
+ return 1;
+ case 033: /* fbstp m80dec */
+ clear_C1();
+ if (FPU_store_bcd
+ (st0_ptr, st0_tag, (u_char __user *) data_address))
+ pop_0(); /* pop only if the number was actually stored
+ (see the 80486 manual p16-28) */
+ break;
+ case 034: /* fstcw m16int */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_WRITE, data_address, 2);
+ FPU_put_user(control_word,
+ (unsigned short __user *)data_address);
+ RE_ENTRANT_CHECK_ON;
+ return 1;
+ case 035: /* fstp m80real */
+ clear_C1();
+ if (FPU_store_extended
+ (st0_ptr, st0_tag, (long double __user *)data_address))
+ pop_0(); /* pop only if the number was actually stored
+ (see the 80486 manual p16-28) */
+ break;
+ case 036: /* fstsw m2byte */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_WRITE, data_address, 2);
+ FPU_put_user(status_word(),
+ (unsigned short __user *)data_address);
+ RE_ENTRANT_CHECK_ON;
+ return 1;
+ case 037: /* fistp m64int */
+ clear_C1();
+ if (FPU_store_int64
+ (st0_ptr, st0_tag, (long long __user *)data_address))
+ pop_0(); /* pop only if the number was actually stored
+ (see the 80486 manual p16-28) */
+ break;
+ }
return 0;
- FPU_settag0(loaded_tag);
- break;
- case 030: /* fstenv m14/28byte */
- fstenv(addr_modes, (u_char __user *)data_address);
- return 1;
- case 032: /* fsave */
- fsave(addr_modes, (u_char __user *)data_address);
- return 1;
- case 033: /* fbstp m80dec */
- clear_C1();
- if ( FPU_store_bcd(st0_ptr, st0_tag, (u_char __user *)data_address) )
- pop_0(); /* pop only if the number was actually stored
- (see the 80486 manual p16-28) */
- break;
- case 034: /* fstcw m16int */
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_WRITE,data_address,2);
- FPU_put_user(control_word, (unsigned short __user *) data_address);
- RE_ENTRANT_CHECK_ON;
- return 1;
- case 035: /* fstp m80real */
- clear_C1();
- if ( FPU_store_extended(st0_ptr, st0_tag, (long double __user *)data_address) )
- pop_0(); /* pop only if the number was actually stored
- (see the 80486 manual p16-28) */
- break;
- case 036: /* fstsw m2byte */
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_WRITE,data_address,2);
- FPU_put_user(status_word(),(unsigned short __user *) data_address);
- RE_ENTRANT_CHECK_ON;
- return 1;
- case 037: /* fistp m64int */
- clear_C1();
- if ( FPU_store_int64(st0_ptr, st0_tag, (long long __user *)data_address) )
- pop_0(); /* pop only if the number was actually stored
- (see the 80486 manual p16-28) */
- break;
- }
- return 0;
}
diff --git a/arch/x86/math-emu/poly.h b/arch/x86/math-emu/poly.h
index 4db798114923..f317de7d8864 100644
--- a/arch/x86/math-emu/poly.h
+++ b/arch/x86/math-emu/poly.h
@@ -21,9 +21,9 @@
allows. 9-byte would probably be sufficient.
*/
typedef struct {
- unsigned long lsw;
- unsigned long midw;
- unsigned long msw;
+ unsigned long lsw;
+ unsigned long midw;
+ unsigned long msw;
} Xsig;
asmlinkage void mul64(unsigned long long const *a, unsigned long long const *b,
@@ -33,12 +33,12 @@ asmlinkage void polynomial_Xsig(Xsig *, const unsigned long long *x,
asmlinkage void mul32_Xsig(Xsig *, const unsigned long mult);
asmlinkage void mul64_Xsig(Xsig *, const unsigned long long *mult);
-asmlinkage void mul_Xsig_Xsig(Xsig *dest, const Xsig *mult);
+asmlinkage void mul_Xsig_Xsig(Xsig * dest, const Xsig * mult);
asmlinkage void shr_Xsig(Xsig *, const int n);
asmlinkage int round_Xsig(Xsig *);
asmlinkage int norm_Xsig(Xsig *);
-asmlinkage void div_Xsig(Xsig *x1, const Xsig *x2, const Xsig *dest);
+asmlinkage void div_Xsig(Xsig * x1, const Xsig * x2, const Xsig * dest);
/* Macro to extract the most significant 32 bits from a long long */
#define LL_MSW(x) (((unsigned long *)&x)[1])
@@ -49,7 +49,6 @@ asmlinkage void div_Xsig(Xsig *x1, const Xsig *x2, const Xsig *dest);
/* Macro to access the 8 ms bytes of an Xsig as a long long */
#define XSIG_LL(x) (*(unsigned long long *)&x.midw)
-
/*
Need to run gcc with optimizations on to get these to
actually be in-line.
@@ -63,59 +62,53 @@ asmlinkage void div_Xsig(Xsig *x1, const Xsig *x2, const Xsig *dest);
static inline unsigned long mul_32_32(const unsigned long arg1,
const unsigned long arg2)
{
- int retval;
- asm volatile ("mull %2; movl %%edx,%%eax" \
- :"=a" (retval) \
- :"0" (arg1), "g" (arg2) \
- :"dx");
- return retval;
+ int retval;
+ asm volatile ("mull %2; movl %%edx,%%eax":"=a" (retval)
+ :"0"(arg1), "g"(arg2)
+ :"dx");
+ return retval;
}
-
/* Add the 12 byte Xsig x2 to Xsig dest, with no checks for overflow. */
-static inline void add_Xsig_Xsig(Xsig *dest, const Xsig *x2)
+static inline void add_Xsig_Xsig(Xsig * dest, const Xsig * x2)
{
- asm volatile ("movl %1,%%edi; movl %2,%%esi;\n"
- "movl (%%esi),%%eax; addl %%eax,(%%edi);\n"
- "movl 4(%%esi),%%eax; adcl %%eax,4(%%edi);\n"
- "movl 8(%%esi),%%eax; adcl %%eax,8(%%edi);\n"
- :"=g" (*dest):"g" (dest), "g" (x2)
- :"ax","si","di");
+ asm volatile ("movl %1,%%edi; movl %2,%%esi;\n"
+ "movl (%%esi),%%eax; addl %%eax,(%%edi);\n"
+ "movl 4(%%esi),%%eax; adcl %%eax,4(%%edi);\n"
+ "movl 8(%%esi),%%eax; adcl %%eax,8(%%edi);\n":"=g"
+ (*dest):"g"(dest), "g"(x2)
+ :"ax", "si", "di");
}
-
/* Add the 12 byte Xsig x2 to Xsig dest, adjust exp if overflow occurs. */
/* Note: the constraints in the asm statement didn't always work properly
with gcc 2.5.8. Changing from using edi to using ecx got around the
problem, but keep fingers crossed! */
-static inline void add_two_Xsig(Xsig *dest, const Xsig *x2, long int *exp)
+static inline void add_two_Xsig(Xsig * dest, const Xsig * x2, long int *exp)
{
- asm volatile ("movl %2,%%ecx; movl %3,%%esi;\n"
- "movl (%%esi),%%eax; addl %%eax,(%%ecx);\n"
- "movl 4(%%esi),%%eax; adcl %%eax,4(%%ecx);\n"
- "movl 8(%%esi),%%eax; adcl %%eax,8(%%ecx);\n"
- "jnc 0f;\n"
- "rcrl 8(%%ecx); rcrl 4(%%ecx); rcrl (%%ecx)\n"
- "movl %4,%%ecx; incl (%%ecx)\n"
- "movl $1,%%eax; jmp 1f;\n"
- "0: xorl %%eax,%%eax;\n"
- "1:\n"
- :"=g" (*exp), "=g" (*dest)
- :"g" (dest), "g" (x2), "g" (exp)
- :"cx","si","ax");
+ asm volatile ("movl %2,%%ecx; movl %3,%%esi;\n"
+ "movl (%%esi),%%eax; addl %%eax,(%%ecx);\n"
+ "movl 4(%%esi),%%eax; adcl %%eax,4(%%ecx);\n"
+ "movl 8(%%esi),%%eax; adcl %%eax,8(%%ecx);\n"
+ "jnc 0f;\n"
+ "rcrl 8(%%ecx); rcrl 4(%%ecx); rcrl (%%ecx)\n"
+ "movl %4,%%ecx; incl (%%ecx)\n"
+ "movl $1,%%eax; jmp 1f;\n"
+ "0: xorl %%eax,%%eax;\n" "1:\n":"=g" (*exp), "=g"(*dest)
+ :"g"(dest), "g"(x2), "g"(exp)
+ :"cx", "si", "ax");
}
-
/* Negate (subtract from 1.0) the 12 byte Xsig */
/* This is faster in a loop on my 386 than using the "neg" instruction. */
-static inline void negate_Xsig(Xsig *x)
+static inline void negate_Xsig(Xsig * x)
{
- asm volatile("movl %1,%%esi;\n"
- "xorl %%ecx,%%ecx;\n"
- "movl %%ecx,%%eax; subl (%%esi),%%eax; movl %%eax,(%%esi);\n"
- "movl %%ecx,%%eax; sbbl 4(%%esi),%%eax; movl %%eax,4(%%esi);\n"
- "movl %%ecx,%%eax; sbbl 8(%%esi),%%eax; movl %%eax,8(%%esi);\n"
- :"=g" (*x):"g" (x):"si","ax","cx");
+ asm volatile ("movl %1,%%esi;\n"
+ "xorl %%ecx,%%ecx;\n"
+ "movl %%ecx,%%eax; subl (%%esi),%%eax; movl %%eax,(%%esi);\n"
+ "movl %%ecx,%%eax; sbbl 4(%%esi),%%eax; movl %%eax,4(%%esi);\n"
+ "movl %%ecx,%%eax; sbbl 8(%%esi),%%eax; movl %%eax,8(%%esi);\n":"=g"
+ (*x):"g"(x):"si", "ax", "cx");
}
#endif /* _POLY_H */
diff --git a/arch/x86/math-emu/poly_2xm1.c b/arch/x86/math-emu/poly_2xm1.c
index 9766ad5e9743..d8f2be3c8383 100644
--- a/arch/x86/math-emu/poly_2xm1.c
+++ b/arch/x86/math-emu/poly_2xm1.c
@@ -17,21 +17,19 @@
#include "control_w.h"
#include "poly.h"
-
#define HIPOWER 11
-static const unsigned long long lterms[HIPOWER] =
-{
- 0x0000000000000000LL, /* This term done separately as 12 bytes */
- 0xf5fdeffc162c7543LL,
- 0x1c6b08d704a0bfa6LL,
- 0x0276556df749cc21LL,
- 0x002bb0ffcf14f6b8LL,
- 0x0002861225ef751cLL,
- 0x00001ffcbfcd5422LL,
- 0x00000162c005d5f1LL,
- 0x0000000da96ccb1bLL,
- 0x0000000078d1b897LL,
- 0x000000000422b029LL
+static const unsigned long long lterms[HIPOWER] = {
+ 0x0000000000000000LL, /* This term done separately as 12 bytes */
+ 0xf5fdeffc162c7543LL,
+ 0x1c6b08d704a0bfa6LL,
+ 0x0276556df749cc21LL,
+ 0x002bb0ffcf14f6b8LL,
+ 0x0002861225ef751cLL,
+ 0x00001ffcbfcd5422LL,
+ 0x00000162c005d5f1LL,
+ 0x0000000da96ccb1bLL,
+ 0x0000000078d1b897LL,
+ 0x000000000422b029LL
};
static const Xsig hiterm = MK_XSIG(0xb17217f7, 0xd1cf79ab, 0xc8a39194);
@@ -45,112 +43,103 @@ static const Xsig shiftterm2 = MK_XSIG(0xb504f333, 0xf9de6484, 0x597d89b3);
static const Xsig shiftterm3 = MK_XSIG(0xd744fcca, 0xd69d6af4, 0x39a68bb9);
static const Xsig *shiftterm[] = { &shiftterm0, &shiftterm1,
- &shiftterm2, &shiftterm3 };
-
+ &shiftterm2, &shiftterm3
+};
/*--- poly_2xm1() -----------------------------------------------------------+
| Requires st(0) which is TAG_Valid and < 1. |
+---------------------------------------------------------------------------*/
-int poly_2xm1(u_char sign, FPU_REG *arg, FPU_REG *result)
+int poly_2xm1(u_char sign, FPU_REG * arg, FPU_REG * result)
{
- long int exponent, shift;
- unsigned long long Xll;
- Xsig accumulator, Denom, argSignif;
- u_char tag;
+ long int exponent, shift;
+ unsigned long long Xll;
+ Xsig accumulator, Denom, argSignif;
+ u_char tag;
- exponent = exponent16(arg);
+ exponent = exponent16(arg);
#ifdef PARANOID
- if ( exponent >= 0 ) /* Don't want a |number| >= 1.0 */
- {
- /* Number negative, too large, or not Valid. */
- EXCEPTION(EX_INTERNAL|0x127);
- return 1;
- }
+ if (exponent >= 0) { /* Don't want a |number| >= 1.0 */
+ /* Number negative, too large, or not Valid. */
+ EXCEPTION(EX_INTERNAL | 0x127);
+ return 1;
+ }
#endif /* PARANOID */
- argSignif.lsw = 0;
- XSIG_LL(argSignif) = Xll = significand(arg);
-
- if ( exponent == -1 )
- {
- shift = (argSignif.msw & 0x40000000) ? 3 : 2;
- /* subtract 0.5 or 0.75 */
- exponent -= 2;
- XSIG_LL(argSignif) <<= 2;
- Xll <<= 2;
- }
- else if ( exponent == -2 )
- {
- shift = 1;
- /* subtract 0.25 */
- exponent--;
- XSIG_LL(argSignif) <<= 1;
- Xll <<= 1;
- }
- else
- shift = 0;
-
- if ( exponent < -2 )
- {
- /* Shift the argument right by the required places. */
- if ( FPU_shrx(&Xll, -2-exponent) >= 0x80000000U )
- Xll++; /* round up */
- }
-
- accumulator.lsw = accumulator.midw = accumulator.msw = 0;
- polynomial_Xsig(&accumulator, &Xll, lterms, HIPOWER-1);
- mul_Xsig_Xsig(&accumulator, &argSignif);
- shr_Xsig(&accumulator, 3);
-
- mul_Xsig_Xsig(&argSignif, &hiterm); /* The leading term */
- add_two_Xsig(&accumulator, &argSignif, &exponent);
-
- if ( shift )
- {
- /* The argument is large, use the identity:
- f(x+a) = f(a) * (f(x) + 1) - 1;
- */
- shr_Xsig(&accumulator, - exponent);
- accumulator.msw |= 0x80000000; /* add 1.0 */
- mul_Xsig_Xsig(&accumulator, shiftterm[shift]);
- accumulator.msw &= 0x3fffffff; /* subtract 1.0 */
- exponent = 1;
- }
-
- if ( sign != SIGN_POS )
- {
- /* The argument is negative, use the identity:
- f(-x) = -f(x) / (1 + f(x))
- */
- Denom.lsw = accumulator.lsw;
- XSIG_LL(Denom) = XSIG_LL(accumulator);
- if ( exponent < 0 )
- shr_Xsig(&Denom, - exponent);
- else if ( exponent > 0 )
- {
- /* exponent must be 1 here */
- XSIG_LL(Denom) <<= 1;
- if ( Denom.lsw & 0x80000000 )
- XSIG_LL(Denom) |= 1;
- (Denom.lsw) <<= 1;
+ argSignif.lsw = 0;
+ XSIG_LL(argSignif) = Xll = significand(arg);
+
+ if (exponent == -1) {
+ shift = (argSignif.msw & 0x40000000) ? 3 : 2;
+ /* subtract 0.5 or 0.75 */
+ exponent -= 2;
+ XSIG_LL(argSignif) <<= 2;
+ Xll <<= 2;
+ } else if (exponent == -2) {
+ shift = 1;
+ /* subtract 0.25 */
+ exponent--;
+ XSIG_LL(argSignif) <<= 1;
+ Xll <<= 1;
+ } else
+ shift = 0;
+
+ if (exponent < -2) {
+ /* Shift the argument right by the required places. */
+ if (FPU_shrx(&Xll, -2 - exponent) >= 0x80000000U)
+ Xll++; /* round up */
+ }
+
+ accumulator.lsw = accumulator.midw = accumulator.msw = 0;
+ polynomial_Xsig(&accumulator, &Xll, lterms, HIPOWER - 1);
+ mul_Xsig_Xsig(&accumulator, &argSignif);
+ shr_Xsig(&accumulator, 3);
+
+ mul_Xsig_Xsig(&argSignif, &hiterm); /* The leading term */
+ add_two_Xsig(&accumulator, &argSignif, &exponent);
+
+ if (shift) {
+ /* The argument is large, use the identity:
+ f(x+a) = f(a) * (f(x) + 1) - 1;
+ */
+ shr_Xsig(&accumulator, -exponent);
+ accumulator.msw |= 0x80000000; /* add 1.0 */
+ mul_Xsig_Xsig(&accumulator, shiftterm[shift]);
+ accumulator.msw &= 0x3fffffff; /* subtract 1.0 */
+ exponent = 1;
+ }
+
+ if (sign != SIGN_POS) {
+ /* The argument is negative, use the identity:
+ f(-x) = -f(x) / (1 + f(x))
+ */
+ Denom.lsw = accumulator.lsw;
+ XSIG_LL(Denom) = XSIG_LL(accumulator);
+ if (exponent < 0)
+ shr_Xsig(&Denom, -exponent);
+ else if (exponent > 0) {
+ /* exponent must be 1 here */
+ XSIG_LL(Denom) <<= 1;
+ if (Denom.lsw & 0x80000000)
+ XSIG_LL(Denom) |= 1;
+ (Denom.lsw) <<= 1;
+ }
+ Denom.msw |= 0x80000000; /* add 1.0 */
+ div_Xsig(&accumulator, &Denom, &accumulator);
}
- Denom.msw |= 0x80000000; /* add 1.0 */
- div_Xsig(&accumulator, &Denom, &accumulator);
- }
- /* Convert to 64 bit signed-compatible */
- exponent += round_Xsig(&accumulator);
+ /* Convert to 64 bit signed-compatible */
+ exponent += round_Xsig(&accumulator);
- result = &st(0);
- significand(result) = XSIG_LL(accumulator);
- setexponent16(result, exponent);
+ result = &st(0);
+ significand(result) = XSIG_LL(accumulator);
+ setexponent16(result, exponent);
- tag = FPU_round(result, 1, 0, FULL_PRECISION, sign);
+ tag = FPU_round(result, 1, 0, FULL_PRECISION, sign);
- setsign(result, sign);
- FPU_settag0(tag);
+ setsign(result, sign);
+ FPU_settag0(tag);
- return 0;
+ return 0;
}
diff --git a/arch/x86/math-emu/poly_atan.c b/arch/x86/math-emu/poly_atan.c
index 82f702952f69..2f4ac8143fc3 100644
--- a/arch/x86/math-emu/poly_atan.c
+++ b/arch/x86/math-emu/poly_atan.c
@@ -18,28 +18,25 @@
#include "control_w.h"
#include "poly.h"
-
#define HIPOWERon 6 /* odd poly, negative terms */
-static const unsigned long long oddnegterms[HIPOWERon] =
-{
- 0x0000000000000000LL, /* Dummy (not for - 1.0) */
- 0x015328437f756467LL,
- 0x0005dda27b73dec6LL,
- 0x0000226bf2bfb91aLL,
- 0x000000ccc439c5f7LL,
- 0x0000000355438407LL
-} ;
+static const unsigned long long oddnegterms[HIPOWERon] = {
+ 0x0000000000000000LL, /* Dummy (not for - 1.0) */
+ 0x015328437f756467LL,
+ 0x0005dda27b73dec6LL,
+ 0x0000226bf2bfb91aLL,
+ 0x000000ccc439c5f7LL,
+ 0x0000000355438407LL
+};
#define HIPOWERop 6 /* odd poly, positive terms */
-static const unsigned long long oddplterms[HIPOWERop] =
-{
+static const unsigned long long oddplterms[HIPOWERop] = {
/* 0xaaaaaaaaaaaaaaabLL, transferred to fixedpterm[] */
- 0x0db55a71875c9ac2LL,
- 0x0029fce2d67880b0LL,
- 0x0000dfd3908b4596LL,
- 0x00000550fd61dab4LL,
- 0x0000001c9422b3f9LL,
- 0x000000003e3301e1LL
+ 0x0db55a71875c9ac2LL,
+ 0x0029fce2d67880b0LL,
+ 0x0000dfd3908b4596LL,
+ 0x00000550fd61dab4LL,
+ 0x0000001c9422b3f9LL,
+ 0x000000003e3301e1LL
};
static const unsigned long long denomterm = 0xebd9b842c5c53a0eLL;
@@ -48,182 +45,164 @@ static const Xsig fixedpterm = MK_XSIG(0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa);
static const Xsig pi_signif = MK_XSIG(0xc90fdaa2, 0x2168c234, 0xc4c6628b);
-
/*--- poly_atan() -----------------------------------------------------------+
| |
+---------------------------------------------------------------------------*/
-void poly_atan(FPU_REG *st0_ptr, u_char st0_tag,
- FPU_REG *st1_ptr, u_char st1_tag)
+void poly_atan(FPU_REG * st0_ptr, u_char st0_tag,
+ FPU_REG * st1_ptr, u_char st1_tag)
{
- u_char transformed, inverted,
- sign1, sign2;
- int exponent;
- long int dummy_exp;
- Xsig accumulator, Numer, Denom, accumulatore, argSignif,
- argSq, argSqSq;
- u_char tag;
-
- sign1 = getsign(st0_ptr);
- sign2 = getsign(st1_ptr);
- if ( st0_tag == TAG_Valid )
- {
- exponent = exponent(st0_ptr);
- }
- else
- {
- /* This gives non-compatible stack contents... */
- FPU_to_exp16(st0_ptr, st0_ptr);
- exponent = exponent16(st0_ptr);
- }
- if ( st1_tag == TAG_Valid )
- {
- exponent -= exponent(st1_ptr);
- }
- else
- {
- /* This gives non-compatible stack contents... */
- FPU_to_exp16(st1_ptr, st1_ptr);
- exponent -= exponent16(st1_ptr);
- }
-
- if ( (exponent < 0) || ((exponent == 0) &&
- ((st0_ptr->sigh < st1_ptr->sigh) ||
- ((st0_ptr->sigh == st1_ptr->sigh) &&
- (st0_ptr->sigl < st1_ptr->sigl))) ) )
- {
- inverted = 1;
- Numer.lsw = Denom.lsw = 0;
- XSIG_LL(Numer) = significand(st0_ptr);
- XSIG_LL(Denom) = significand(st1_ptr);
- }
- else
- {
- inverted = 0;
- exponent = -exponent;
- Numer.lsw = Denom.lsw = 0;
- XSIG_LL(Numer) = significand(st1_ptr);
- XSIG_LL(Denom) = significand(st0_ptr);
- }
- div_Xsig(&Numer, &Denom, &argSignif);
- exponent += norm_Xsig(&argSignif);
-
- if ( (exponent >= -1)
- || ((exponent == -2) && (argSignif.msw > 0xd413ccd0)) )
- {
- /* The argument is greater than sqrt(2)-1 (=0.414213562...) */
- /* Convert the argument by an identity for atan */
- transformed = 1;
-
- if ( exponent >= 0 )
- {
+ u_char transformed, inverted, sign1, sign2;
+ int exponent;
+ long int dummy_exp;
+ Xsig accumulator, Numer, Denom, accumulatore, argSignif, argSq, argSqSq;
+ u_char tag;
+
+ sign1 = getsign(st0_ptr);
+ sign2 = getsign(st1_ptr);
+ if (st0_tag == TAG_Valid) {
+ exponent = exponent(st0_ptr);
+ } else {
+ /* This gives non-compatible stack contents... */
+ FPU_to_exp16(st0_ptr, st0_ptr);
+ exponent = exponent16(st0_ptr);
+ }
+ if (st1_tag == TAG_Valid) {
+ exponent -= exponent(st1_ptr);
+ } else {
+ /* This gives non-compatible stack contents... */
+ FPU_to_exp16(st1_ptr, st1_ptr);
+ exponent -= exponent16(st1_ptr);
+ }
+
+ if ((exponent < 0) || ((exponent == 0) &&
+ ((st0_ptr->sigh < st1_ptr->sigh) ||
+ ((st0_ptr->sigh == st1_ptr->sigh) &&
+ (st0_ptr->sigl < st1_ptr->sigl))))) {
+ inverted = 1;
+ Numer.lsw = Denom.lsw = 0;
+ XSIG_LL(Numer) = significand(st0_ptr);
+ XSIG_LL(Denom) = significand(st1_ptr);
+ } else {
+ inverted = 0;
+ exponent = -exponent;
+ Numer.lsw = Denom.lsw = 0;
+ XSIG_LL(Numer) = significand(st1_ptr);
+ XSIG_LL(Denom) = significand(st0_ptr);
+ }
+ div_Xsig(&Numer, &Denom, &argSignif);
+ exponent += norm_Xsig(&argSignif);
+
+ if ((exponent >= -1)
+ || ((exponent == -2) && (argSignif.msw > 0xd413ccd0))) {
+ /* The argument is greater than sqrt(2)-1 (=0.414213562...) */
+ /* Convert the argument by an identity for atan */
+ transformed = 1;
+
+ if (exponent >= 0) {
#ifdef PARANOID
- if ( !( (exponent == 0) &&
- (argSignif.lsw == 0) && (argSignif.midw == 0) &&
- (argSignif.msw == 0x80000000) ) )
- {
- EXCEPTION(EX_INTERNAL|0x104); /* There must be a logic error */
- return;
- }
+ if (!((exponent == 0) &&
+ (argSignif.lsw == 0) && (argSignif.midw == 0) &&
+ (argSignif.msw == 0x80000000))) {
+ EXCEPTION(EX_INTERNAL | 0x104); /* There must be a logic error */
+ return;
+ }
#endif /* PARANOID */
- argSignif.msw = 0; /* Make the transformed arg -> 0.0 */
+ argSignif.msw = 0; /* Make the transformed arg -> 0.0 */
+ } else {
+ Numer.lsw = Denom.lsw = argSignif.lsw;
+ XSIG_LL(Numer) = XSIG_LL(Denom) = XSIG_LL(argSignif);
+
+ if (exponent < -1)
+ shr_Xsig(&Numer, -1 - exponent);
+ negate_Xsig(&Numer);
+
+ shr_Xsig(&Denom, -exponent);
+ Denom.msw |= 0x80000000;
+
+ div_Xsig(&Numer, &Denom, &argSignif);
+
+ exponent = -1 + norm_Xsig(&argSignif);
+ }
+ } else {
+ transformed = 0;
+ }
+
+ argSq.lsw = argSignif.lsw;
+ argSq.midw = argSignif.midw;
+ argSq.msw = argSignif.msw;
+ mul_Xsig_Xsig(&argSq, &argSq);
+
+ argSqSq.lsw = argSq.lsw;
+ argSqSq.midw = argSq.midw;
+ argSqSq.msw = argSq.msw;
+ mul_Xsig_Xsig(&argSqSq, &argSqSq);
+
+ accumulatore.lsw = argSq.lsw;
+ XSIG_LL(accumulatore) = XSIG_LL(argSq);
+
+ shr_Xsig(&argSq, 2 * (-1 - exponent - 1));
+ shr_Xsig(&argSqSq, 4 * (-1 - exponent - 1));
+
+ /* Now have argSq etc with binary point at the left
+ .1xxxxxxxx */
+
+ /* Do the basic fixed point polynomial evaluation */
+ accumulator.msw = accumulator.midw = accumulator.lsw = 0;
+ polynomial_Xsig(&accumulator, &XSIG_LL(argSqSq),
+ oddplterms, HIPOWERop - 1);
+ mul64_Xsig(&accumulator, &XSIG_LL(argSq));
+ negate_Xsig(&accumulator);
+ polynomial_Xsig(&accumulator, &XSIG_LL(argSqSq), oddnegterms,
+ HIPOWERon - 1);
+ negate_Xsig(&accumulator);
+ add_two_Xsig(&accumulator, &fixedpterm, &dummy_exp);
+
+ mul64_Xsig(&accumulatore, &denomterm);
+ shr_Xsig(&accumulatore, 1 + 2 * (-1 - exponent));
+ accumulatore.msw |= 0x80000000;
+
+ div_Xsig(&accumulator, &accumulatore, &accumulator);
+
+ mul_Xsig_Xsig(&accumulator, &argSignif);
+ mul_Xsig_Xsig(&accumulator, &argSq);
+
+ shr_Xsig(&accumulator, 3);
+ negate_Xsig(&accumulator);
+ add_Xsig_Xsig(&accumulator, &argSignif);
+
+ if (transformed) {
+ /* compute pi/4 - accumulator */
+ shr_Xsig(&accumulator, -1 - exponent);
+ negate_Xsig(&accumulator);
+ add_Xsig_Xsig(&accumulator, &pi_signif);
+ exponent = -1;
+ }
+
+ if (inverted) {
+ /* compute pi/2 - accumulator */
+ shr_Xsig(&accumulator, -exponent);
+ negate_Xsig(&accumulator);
+ add_Xsig_Xsig(&accumulator, &pi_signif);
+ exponent = 0;
}
- else
- {
- Numer.lsw = Denom.lsw = argSignif.lsw;
- XSIG_LL(Numer) = XSIG_LL(Denom) = XSIG_LL(argSignif);
-
- if ( exponent < -1 )
- shr_Xsig(&Numer, -1-exponent);
- negate_Xsig(&Numer);
-
- shr_Xsig(&Denom, -exponent);
- Denom.msw |= 0x80000000;
-
- div_Xsig(&Numer, &Denom, &argSignif);
-
- exponent = -1 + norm_Xsig(&argSignif);
+
+ if (sign1) {
+ /* compute pi - accumulator */
+ shr_Xsig(&accumulator, 1 - exponent);
+ negate_Xsig(&accumulator);
+ add_Xsig_Xsig(&accumulator, &pi_signif);
+ exponent = 1;
}
- }
- else
- {
- transformed = 0;
- }
-
- argSq.lsw = argSignif.lsw; argSq.midw = argSignif.midw;
- argSq.msw = argSignif.msw;
- mul_Xsig_Xsig(&argSq, &argSq);
-
- argSqSq.lsw = argSq.lsw; argSqSq.midw = argSq.midw; argSqSq.msw = argSq.msw;
- mul_Xsig_Xsig(&argSqSq, &argSqSq);
-
- accumulatore.lsw = argSq.lsw;
- XSIG_LL(accumulatore) = XSIG_LL(argSq);
-
- shr_Xsig(&argSq, 2*(-1-exponent-1));
- shr_Xsig(&argSqSq, 4*(-1-exponent-1));
-
- /* Now have argSq etc with binary point at the left
- .1xxxxxxxx */
-
- /* Do the basic fixed point polynomial evaluation */
- accumulator.msw = accumulator.midw = accumulator.lsw = 0;
- polynomial_Xsig(&accumulator, &XSIG_LL(argSqSq),
- oddplterms, HIPOWERop-1);
- mul64_Xsig(&accumulator, &XSIG_LL(argSq));
- negate_Xsig(&accumulator);
- polynomial_Xsig(&accumulator, &XSIG_LL(argSqSq), oddnegterms, HIPOWERon-1);
- negate_Xsig(&accumulator);
- add_two_Xsig(&accumulator, &fixedpterm, &dummy_exp);
-
- mul64_Xsig(&accumulatore, &denomterm);
- shr_Xsig(&accumulatore, 1 + 2*(-1-exponent));
- accumulatore.msw |= 0x80000000;
-
- div_Xsig(&accumulator, &accumulatore, &accumulator);
-
- mul_Xsig_Xsig(&accumulator, &argSignif);
- mul_Xsig_Xsig(&accumulator, &argSq);
-
- shr_Xsig(&accumulator, 3);
- negate_Xsig(&accumulator);
- add_Xsig_Xsig(&accumulator, &argSignif);
-
- if ( transformed )
- {
- /* compute pi/4 - accumulator */
- shr_Xsig(&accumulator, -1-exponent);
- negate_Xsig(&accumulator);
- add_Xsig_Xsig(&accumulator, &pi_signif);
- exponent = -1;
- }
-
- if ( inverted )
- {
- /* compute pi/2 - accumulator */
- shr_Xsig(&accumulator, -exponent);
- negate_Xsig(&accumulator);
- add_Xsig_Xsig(&accumulator, &pi_signif);
- exponent = 0;
- }
-
- if ( sign1 )
- {
- /* compute pi - accumulator */
- shr_Xsig(&accumulator, 1 - exponent);
- negate_Xsig(&accumulator);
- add_Xsig_Xsig(&accumulator, &pi_signif);
- exponent = 1;
- }
-
- exponent += round_Xsig(&accumulator);
-
- significand(st1_ptr) = XSIG_LL(accumulator);
- setexponent16(st1_ptr, exponent);
-
- tag = FPU_round(st1_ptr, 1, 0, FULL_PRECISION, sign2);
- FPU_settagi(1, tag);
-
- set_precision_flag_up(); /* We do not really know if up or down,
- use this as the default. */
+
+ exponent += round_Xsig(&accumulator);
+
+ significand(st1_ptr) = XSIG_LL(accumulator);
+ setexponent16(st1_ptr, exponent);
+
+ tag = FPU_round(st1_ptr, 1, 0, FULL_PRECISION, sign2);
+ FPU_settagi(1, tag);
+
+ set_precision_flag_up(); /* We do not really know if up or down,
+ use this as the default. */
}
diff --git a/arch/x86/math-emu/poly_l2.c b/arch/x86/math-emu/poly_l2.c
index dd00e1d5b074..c0102ae87511 100644
--- a/arch/x86/math-emu/poly_l2.c
+++ b/arch/x86/math-emu/poly_l2.c
@@ -10,7 +10,6 @@
| |
+---------------------------------------------------------------------------*/
-
#include "exception.h"
#include "reg_constant.h"
#include "fpu_emu.h"
@@ -18,255 +17,228 @@
#include "control_w.h"
#include "poly.h"
-
static void log2_kernel(FPU_REG const *arg, u_char argsign,
- Xsig *accum_result, long int *expon);
-
+ Xsig * accum_result, long int *expon);
/*--- poly_l2() -------------------------------------------------------------+
| Base 2 logarithm by a polynomial approximation. |
+---------------------------------------------------------------------------*/
-void poly_l2(FPU_REG *st0_ptr, FPU_REG *st1_ptr, u_char st1_sign)
+void poly_l2(FPU_REG * st0_ptr, FPU_REG * st1_ptr, u_char st1_sign)
{
- long int exponent, expon, expon_expon;
- Xsig accumulator, expon_accum, yaccum;
- u_char sign, argsign;
- FPU_REG x;
- int tag;
-
- exponent = exponent16(st0_ptr);
-
- /* From st0_ptr, make a number > sqrt(2)/2 and < sqrt(2) */
- if ( st0_ptr->sigh > (unsigned)0xb504f334 )
- {
- /* Treat as sqrt(2)/2 < st0_ptr < 1 */
- significand(&x) = - significand(st0_ptr);
- setexponent16(&x, -1);
- exponent++;
- argsign = SIGN_NEG;
- }
- else
- {
- /* Treat as 1 <= st0_ptr < sqrt(2) */
- x.sigh = st0_ptr->sigh - 0x80000000;
- x.sigl = st0_ptr->sigl;
- setexponent16(&x, 0);
- argsign = SIGN_POS;
- }
- tag = FPU_normalize_nuo(&x);
-
- if ( tag == TAG_Zero )
- {
- expon = 0;
- accumulator.msw = accumulator.midw = accumulator.lsw = 0;
- }
- else
- {
- log2_kernel(&x, argsign, &accumulator, &expon);
- }
-
- if ( exponent < 0 )
- {
- sign = SIGN_NEG;
- exponent = -exponent;
- }
- else
- sign = SIGN_POS;
- expon_accum.msw = exponent; expon_accum.midw = expon_accum.lsw = 0;
- if ( exponent )
- {
- expon_expon = 31 + norm_Xsig(&expon_accum);
- shr_Xsig(&accumulator, expon_expon - expon);
-
- if ( sign ^ argsign )
- negate_Xsig(&accumulator);
- add_Xsig_Xsig(&accumulator, &expon_accum);
- }
- else
- {
- expon_expon = expon;
- sign = argsign;
- }
-
- yaccum.lsw = 0; XSIG_LL(yaccum) = significand(st1_ptr);
- mul_Xsig_Xsig(&accumulator, &yaccum);
-
- expon_expon += round_Xsig(&accumulator);
-
- if ( accumulator.msw == 0 )
- {
- FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
- return;
- }
-
- significand(st1_ptr) = XSIG_LL(accumulator);
- setexponent16(st1_ptr, expon_expon + exponent16(st1_ptr) + 1);
-
- tag = FPU_round(st1_ptr, 1, 0, FULL_PRECISION, sign ^ st1_sign);
- FPU_settagi(1, tag);
-
- set_precision_flag_up(); /* 80486 appears to always do this */
-
- return;
+ long int exponent, expon, expon_expon;
+ Xsig accumulator, expon_accum, yaccum;
+ u_char sign, argsign;
+ FPU_REG x;
+ int tag;
+
+ exponent = exponent16(st0_ptr);
+
+ /* From st0_ptr, make a number > sqrt(2)/2 and < sqrt(2) */
+ if (st0_ptr->sigh > (unsigned)0xb504f334) {
+ /* Treat as sqrt(2)/2 < st0_ptr < 1 */
+ significand(&x) = -significand(st0_ptr);
+ setexponent16(&x, -1);
+ exponent++;
+ argsign = SIGN_NEG;
+ } else {
+ /* Treat as 1 <= st0_ptr < sqrt(2) */
+ x.sigh = st0_ptr->sigh - 0x80000000;
+ x.sigl = st0_ptr->sigl;
+ setexponent16(&x, 0);
+ argsign = SIGN_POS;
+ }
+ tag = FPU_normalize_nuo(&x);
-}
+ if (tag == TAG_Zero) {
+ expon = 0;
+ accumulator.msw = accumulator.midw = accumulator.lsw = 0;
+ } else {
+ log2_kernel(&x, argsign, &accumulator, &expon);
+ }
+
+ if (exponent < 0) {
+ sign = SIGN_NEG;
+ exponent = -exponent;
+ } else
+ sign = SIGN_POS;
+ expon_accum.msw = exponent;
+ expon_accum.midw = expon_accum.lsw = 0;
+ if (exponent) {
+ expon_expon = 31 + norm_Xsig(&expon_accum);
+ shr_Xsig(&accumulator, expon_expon - expon);
+
+ if (sign ^ argsign)
+ negate_Xsig(&accumulator);
+ add_Xsig_Xsig(&accumulator, &expon_accum);
+ } else {
+ expon_expon = expon;
+ sign = argsign;
+ }
+
+ yaccum.lsw = 0;
+ XSIG_LL(yaccum) = significand(st1_ptr);
+ mul_Xsig_Xsig(&accumulator, &yaccum);
+
+ expon_expon += round_Xsig(&accumulator);
+
+ if (accumulator.msw == 0) {
+ FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
+ return;
+ }
+
+ significand(st1_ptr) = XSIG_LL(accumulator);
+ setexponent16(st1_ptr, expon_expon + exponent16(st1_ptr) + 1);
+ tag = FPU_round(st1_ptr, 1, 0, FULL_PRECISION, sign ^ st1_sign);
+ FPU_settagi(1, tag);
+
+ set_precision_flag_up(); /* 80486 appears to always do this */
+
+ return;
+
+}
/*--- poly_l2p1() -----------------------------------------------------------+
| Base 2 logarithm by a polynomial approximation. |
| log2(x+1) |
+---------------------------------------------------------------------------*/
-int poly_l2p1(u_char sign0, u_char sign1,
- FPU_REG *st0_ptr, FPU_REG *st1_ptr, FPU_REG *dest)
+int poly_l2p1(u_char sign0, u_char sign1,
+ FPU_REG * st0_ptr, FPU_REG * st1_ptr, FPU_REG * dest)
{
- u_char tag;
- long int exponent;
- Xsig accumulator, yaccum;
+ u_char tag;
+ long int exponent;
+ Xsig accumulator, yaccum;
- if ( exponent16(st0_ptr) < 0 )
- {
- log2_kernel(st0_ptr, sign0, &accumulator, &exponent);
+ if (exponent16(st0_ptr) < 0) {
+ log2_kernel(st0_ptr, sign0, &accumulator, &exponent);
- yaccum.lsw = 0;
- XSIG_LL(yaccum) = significand(st1_ptr);
- mul_Xsig_Xsig(&accumulator, &yaccum);
+ yaccum.lsw = 0;
+ XSIG_LL(yaccum) = significand(st1_ptr);
+ mul_Xsig_Xsig(&accumulator, &yaccum);
- exponent += round_Xsig(&accumulator);
+ exponent += round_Xsig(&accumulator);
- exponent += exponent16(st1_ptr) + 1;
- if ( exponent < EXP_WAY_UNDER ) exponent = EXP_WAY_UNDER;
+ exponent += exponent16(st1_ptr) + 1;
+ if (exponent < EXP_WAY_UNDER)
+ exponent = EXP_WAY_UNDER;
- significand(dest) = XSIG_LL(accumulator);
- setexponent16(dest, exponent);
+ significand(dest) = XSIG_LL(accumulator);
+ setexponent16(dest, exponent);
- tag = FPU_round(dest, 1, 0, FULL_PRECISION, sign0 ^ sign1);
- FPU_settagi(1, tag);
+ tag = FPU_round(dest, 1, 0, FULL_PRECISION, sign0 ^ sign1);
+ FPU_settagi(1, tag);
- if ( tag == TAG_Valid )
- set_precision_flag_up(); /* 80486 appears to always do this */
- }
- else
- {
- /* The magnitude of st0_ptr is far too large. */
+ if (tag == TAG_Valid)
+ set_precision_flag_up(); /* 80486 appears to always do this */
+ } else {
+ /* The magnitude of st0_ptr is far too large. */
- if ( sign0 != SIGN_POS )
- {
- /* Trying to get the log of a negative number. */
-#ifdef PECULIAR_486 /* Stupid 80486 doesn't worry about log(negative). */
- changesign(st1_ptr);
+ if (sign0 != SIGN_POS) {
+ /* Trying to get the log of a negative number. */
+#ifdef PECULIAR_486 /* Stupid 80486 doesn't worry about log(negative). */
+ changesign(st1_ptr);
#else
- if ( arith_invalid(1) < 0 )
- return 1;
+ if (arith_invalid(1) < 0)
+ return 1;
#endif /* PECULIAR_486 */
- }
+ }
- /* 80486 appears to do this */
- if ( sign0 == SIGN_NEG )
- set_precision_flag_down();
- else
- set_precision_flag_up();
- }
+ /* 80486 appears to do this */
+ if (sign0 == SIGN_NEG)
+ set_precision_flag_down();
+ else
+ set_precision_flag_up();
+ }
- if ( exponent(dest) <= EXP_UNDER )
- EXCEPTION(EX_Underflow);
+ if (exponent(dest) <= EXP_UNDER)
+ EXCEPTION(EX_Underflow);
- return 0;
+ return 0;
}
-
-
-
#undef HIPOWER
#define HIPOWER 10
-static const unsigned long long logterms[HIPOWER] =
-{
- 0x2a8eca5705fc2ef0LL,
- 0xf6384ee1d01febceLL,
- 0x093bb62877cdf642LL,
- 0x006985d8a9ec439bLL,
- 0x0005212c4f55a9c8LL,
- 0x00004326a16927f0LL,
- 0x0000038d1d80a0e7LL,
- 0x0000003141cc80c6LL,
- 0x00000002b1668c9fLL,
- 0x000000002c7a46aaLL
+static const unsigned long long logterms[HIPOWER] = {
+ 0x2a8eca5705fc2ef0LL,
+ 0xf6384ee1d01febceLL,
+ 0x093bb62877cdf642LL,
+ 0x006985d8a9ec439bLL,
+ 0x0005212c4f55a9c8LL,
+ 0x00004326a16927f0LL,
+ 0x0000038d1d80a0e7LL,
+ 0x0000003141cc80c6LL,
+ 0x00000002b1668c9fLL,
+ 0x000000002c7a46aaLL
};
static const unsigned long leadterm = 0xb8000000;
-
/*--- log2_kernel() ---------------------------------------------------------+
| Base 2 logarithm by a polynomial approximation. |
| log2(x+1) |
+---------------------------------------------------------------------------*/
-static void log2_kernel(FPU_REG const *arg, u_char argsign, Xsig *accum_result,
+static void log2_kernel(FPU_REG const *arg, u_char argsign, Xsig * accum_result,
long int *expon)
{
- long int exponent, adj;
- unsigned long long Xsq;
- Xsig accumulator, Numer, Denom, argSignif, arg_signif;
-
- exponent = exponent16(arg);
- Numer.lsw = Denom.lsw = 0;
- XSIG_LL(Numer) = XSIG_LL(Denom) = significand(arg);
- if ( argsign == SIGN_POS )
- {
- shr_Xsig(&Denom, 2 - (1 + exponent));
- Denom.msw |= 0x80000000;
- div_Xsig(&Numer, &Denom, &argSignif);
- }
- else
- {
- shr_Xsig(&Denom, 1 - (1 + exponent));
- negate_Xsig(&Denom);
- if ( Denom.msw & 0x80000000 )
- {
- div_Xsig(&Numer, &Denom, &argSignif);
- exponent ++;
- }
- else
- {
- /* Denom must be 1.0 */
- argSignif.lsw = Numer.lsw; argSignif.midw = Numer.midw;
- argSignif.msw = Numer.msw;
+ long int exponent, adj;
+ unsigned long long Xsq;
+ Xsig accumulator, Numer, Denom, argSignif, arg_signif;
+
+ exponent = exponent16(arg);
+ Numer.lsw = Denom.lsw = 0;
+ XSIG_LL(Numer) = XSIG_LL(Denom) = significand(arg);
+ if (argsign == SIGN_POS) {
+ shr_Xsig(&Denom, 2 - (1 + exponent));
+ Denom.msw |= 0x80000000;
+ div_Xsig(&Numer, &Denom, &argSignif);
+ } else {
+ shr_Xsig(&Denom, 1 - (1 + exponent));
+ negate_Xsig(&Denom);
+ if (Denom.msw & 0x80000000) {
+ div_Xsig(&Numer, &Denom, &argSignif);
+ exponent++;
+ } else {
+ /* Denom must be 1.0 */
+ argSignif.lsw = Numer.lsw;
+ argSignif.midw = Numer.midw;
+ argSignif.msw = Numer.msw;
+ }
}
- }
#ifndef PECULIAR_486
- /* Should check here that |local_arg| is within the valid range */
- if ( exponent >= -2 )
- {
- if ( (exponent > -2) ||
- (argSignif.msw > (unsigned)0xafb0ccc0) )
- {
- /* The argument is too large */
+ /* Should check here that |local_arg| is within the valid range */
+ if (exponent >= -2) {
+ if ((exponent > -2) || (argSignif.msw > (unsigned)0xafb0ccc0)) {
+ /* The argument is too large */
+ }
}
- }
#endif /* PECULIAR_486 */
- arg_signif.lsw = argSignif.lsw; XSIG_LL(arg_signif) = XSIG_LL(argSignif);
- adj = norm_Xsig(&argSignif);
- accumulator.lsw = argSignif.lsw; XSIG_LL(accumulator) = XSIG_LL(argSignif);
- mul_Xsig_Xsig(&accumulator, &accumulator);
- shr_Xsig(&accumulator, 2*(-1 - (1 + exponent + adj)));
- Xsq = XSIG_LL(accumulator);
- if ( accumulator.lsw & 0x80000000 )
- Xsq++;
-
- accumulator.msw = accumulator.midw = accumulator.lsw = 0;
- /* Do the basic fixed point polynomial evaluation */
- polynomial_Xsig(&accumulator, &Xsq, logterms, HIPOWER-1);
-
- mul_Xsig_Xsig(&accumulator, &argSignif);
- shr_Xsig(&accumulator, 6 - adj);
-
- mul32_Xsig(&arg_signif, leadterm);
- add_two_Xsig(&accumulator, &arg_signif, &exponent);
-
- *expon = exponent + 1;
- accum_result->lsw = accumulator.lsw;
- accum_result->midw = accumulator.midw;
- accum_result->msw = accumulator.msw;
+ arg_signif.lsw = argSignif.lsw;
+ XSIG_LL(arg_signif) = XSIG_LL(argSignif);
+ adj = norm_Xsig(&argSignif);
+ accumulator.lsw = argSignif.lsw;
+ XSIG_LL(accumulator) = XSIG_LL(argSignif);
+ mul_Xsig_Xsig(&accumulator, &accumulator);
+ shr_Xsig(&accumulator, 2 * (-1 - (1 + exponent + adj)));
+ Xsq = XSIG_LL(accumulator);
+ if (accumulator.lsw & 0x80000000)
+ Xsq++;
+
+ accumulator.msw = accumulator.midw = accumulator.lsw = 0;
+ /* Do the basic fixed point polynomial evaluation */
+ polynomial_Xsig(&accumulator, &Xsq, logterms, HIPOWER - 1);
+
+ mul_Xsig_Xsig(&accumulator, &argSignif);
+ shr_Xsig(&accumulator, 6 - adj);
+
+ mul32_Xsig(&arg_signif, leadterm);
+ add_two_Xsig(&accumulator, &arg_signif, &exponent);
+
+ *expon = exponent + 1;
+ accum_result->lsw = accumulator.lsw;
+ accum_result->midw = accumulator.midw;
+ accum_result->msw = accumulator.msw;
}
diff --git a/arch/x86/math-emu/poly_sin.c b/arch/x86/math-emu/poly_sin.c
index a36313fb06f1..7273ae0c7692 100644
--- a/arch/x86/math-emu/poly_sin.c
+++ b/arch/x86/math-emu/poly_sin.c
@@ -11,7 +11,6 @@
| |
+---------------------------------------------------------------------------*/
-
#include "exception.h"
#include "reg_constant.h"
#include "fpu_emu.h"
@@ -19,379 +18,361 @@
#include "control_w.h"
#include "poly.h"
-
#define N_COEFF_P 4
#define N_COEFF_N 4
-static const unsigned long long pos_terms_l[N_COEFF_P] =
-{
- 0xaaaaaaaaaaaaaaabLL,
- 0x00d00d00d00cf906LL,
- 0x000006b99159a8bbLL,
- 0x000000000d7392e6LL
+static const unsigned long long pos_terms_l[N_COEFF_P] = {
+ 0xaaaaaaaaaaaaaaabLL,
+ 0x00d00d00d00cf906LL,
+ 0x000006b99159a8bbLL,
+ 0x000000000d7392e6LL
};
-static const unsigned long long neg_terms_l[N_COEFF_N] =
-{
- 0x2222222222222167LL,
- 0x0002e3bc74aab624LL,
- 0x0000000b09229062LL,
- 0x00000000000c7973LL
+static const unsigned long long neg_terms_l[N_COEFF_N] = {
+ 0x2222222222222167LL,
+ 0x0002e3bc74aab624LL,
+ 0x0000000b09229062LL,
+ 0x00000000000c7973LL
};
-
-
#define N_COEFF_PH 4
#define N_COEFF_NH 4
-static const unsigned long long pos_terms_h[N_COEFF_PH] =
-{
- 0x0000000000000000LL,
- 0x05b05b05b05b0406LL,
- 0x000049f93edd91a9LL,
- 0x00000000c9c9ed62LL
+static const unsigned long long pos_terms_h[N_COEFF_PH] = {
+ 0x0000000000000000LL,
+ 0x05b05b05b05b0406LL,
+ 0x000049f93edd91a9LL,
+ 0x00000000c9c9ed62LL
};
-static const unsigned long long neg_terms_h[N_COEFF_NH] =
-{
- 0xaaaaaaaaaaaaaa98LL,
- 0x001a01a01a019064LL,
- 0x0000008f76c68a77LL,
- 0x0000000000d58f5eLL
+static const unsigned long long neg_terms_h[N_COEFF_NH] = {
+ 0xaaaaaaaaaaaaaa98LL,
+ 0x001a01a01a019064LL,
+ 0x0000008f76c68a77LL,
+ 0x0000000000d58f5eLL
};
-
/*--- poly_sine() -----------------------------------------------------------+
| |
+---------------------------------------------------------------------------*/
-void poly_sine(FPU_REG *st0_ptr)
+void poly_sine(FPU_REG * st0_ptr)
{
- int exponent, echange;
- Xsig accumulator, argSqrd, argTo4;
- unsigned long fix_up, adj;
- unsigned long long fixed_arg;
- FPU_REG result;
+ int exponent, echange;
+ Xsig accumulator, argSqrd, argTo4;
+ unsigned long fix_up, adj;
+ unsigned long long fixed_arg;
+ FPU_REG result;
- exponent = exponent(st0_ptr);
+ exponent = exponent(st0_ptr);
- accumulator.lsw = accumulator.midw = accumulator.msw = 0;
+ accumulator.lsw = accumulator.midw = accumulator.msw = 0;
- /* Split into two ranges, for arguments below and above 1.0 */
- /* The boundary between upper and lower is approx 0.88309101259 */
- if ( (exponent < -1) || ((exponent == -1) && (st0_ptr->sigh <= 0xe21240aa)) )
- {
- /* The argument is <= 0.88309101259 */
+ /* Split into two ranges, for arguments below and above 1.0 */
+ /* The boundary between upper and lower is approx 0.88309101259 */
+ if ((exponent < -1)
+ || ((exponent == -1) && (st0_ptr->sigh <= 0xe21240aa))) {
+ /* The argument is <= 0.88309101259 */
+
+ argSqrd.msw = st0_ptr->sigh;
+ argSqrd.midw = st0_ptr->sigl;
+ argSqrd.lsw = 0;
+ mul64_Xsig(&argSqrd, &significand(st0_ptr));
+ shr_Xsig(&argSqrd, 2 * (-1 - exponent));
+ argTo4.msw = argSqrd.msw;
+ argTo4.midw = argSqrd.midw;
+ argTo4.lsw = argSqrd.lsw;
+ mul_Xsig_Xsig(&argTo4, &argTo4);
- argSqrd.msw = st0_ptr->sigh; argSqrd.midw = st0_ptr->sigl; argSqrd.lsw = 0;
- mul64_Xsig(&argSqrd, &significand(st0_ptr));
- shr_Xsig(&argSqrd, 2*(-1-exponent));
- argTo4.msw = argSqrd.msw; argTo4.midw = argSqrd.midw;
- argTo4.lsw = argSqrd.lsw;
- mul_Xsig_Xsig(&argTo4, &argTo4);
+ polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_l,
+ N_COEFF_N - 1);
+ mul_Xsig_Xsig(&accumulator, &argSqrd);
+ negate_Xsig(&accumulator);
- polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_l,
- N_COEFF_N-1);
- mul_Xsig_Xsig(&accumulator, &argSqrd);
- negate_Xsig(&accumulator);
+ polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_l,
+ N_COEFF_P - 1);
- polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_l,
- N_COEFF_P-1);
+ shr_Xsig(&accumulator, 2); /* Divide by four */
+ accumulator.msw |= 0x80000000; /* Add 1.0 */
- shr_Xsig(&accumulator, 2); /* Divide by four */
- accumulator.msw |= 0x80000000; /* Add 1.0 */
+ mul64_Xsig(&accumulator, &significand(st0_ptr));
+ mul64_Xsig(&accumulator, &significand(st0_ptr));
+ mul64_Xsig(&accumulator, &significand(st0_ptr));
- mul64_Xsig(&accumulator, &significand(st0_ptr));
- mul64_Xsig(&accumulator, &significand(st0_ptr));
- mul64_Xsig(&accumulator, &significand(st0_ptr));
+ /* Divide by four, FPU_REG compatible, etc */
+ exponent = 3 * exponent;
- /* Divide by four, FPU_REG compatible, etc */
- exponent = 3*exponent;
+ /* The minimum exponent difference is 3 */
+ shr_Xsig(&accumulator, exponent(st0_ptr) - exponent);
- /* The minimum exponent difference is 3 */
- shr_Xsig(&accumulator, exponent(st0_ptr) - exponent);
+ negate_Xsig(&accumulator);
+ XSIG_LL(accumulator) += significand(st0_ptr);
- negate_Xsig(&accumulator);
- XSIG_LL(accumulator) += significand(st0_ptr);
+ echange = round_Xsig(&accumulator);
- echange = round_Xsig(&accumulator);
+ setexponentpos(&result, exponent(st0_ptr) + echange);
+ } else {
+ /* The argument is > 0.88309101259 */
+ /* We use sin(st(0)) = cos(pi/2-st(0)) */
- setexponentpos(&result, exponent(st0_ptr) + echange);
- }
- else
- {
- /* The argument is > 0.88309101259 */
- /* We use sin(st(0)) = cos(pi/2-st(0)) */
+ fixed_arg = significand(st0_ptr);
- fixed_arg = significand(st0_ptr);
+ if (exponent == 0) {
+ /* The argument is >= 1.0 */
- if ( exponent == 0 )
- {
- /* The argument is >= 1.0 */
+ /* Put the binary point at the left. */
+ fixed_arg <<= 1;
+ }
+ /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
+ fixed_arg = 0x921fb54442d18469LL - fixed_arg;
+ /* There is a special case which arises due to rounding, to fix here. */
+ if (fixed_arg == 0xffffffffffffffffLL)
+ fixed_arg = 0;
- /* Put the binary point at the left. */
- fixed_arg <<= 1;
- }
- /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
- fixed_arg = 0x921fb54442d18469LL - fixed_arg;
- /* There is a special case which arises due to rounding, to fix here. */
- if ( fixed_arg == 0xffffffffffffffffLL )
- fixed_arg = 0;
+ XSIG_LL(argSqrd) = fixed_arg;
+ argSqrd.lsw = 0;
+ mul64_Xsig(&argSqrd, &fixed_arg);
- XSIG_LL(argSqrd) = fixed_arg; argSqrd.lsw = 0;
- mul64_Xsig(&argSqrd, &fixed_arg);
+ XSIG_LL(argTo4) = XSIG_LL(argSqrd);
+ argTo4.lsw = argSqrd.lsw;
+ mul_Xsig_Xsig(&argTo4, &argTo4);
- XSIG_LL(argTo4) = XSIG_LL(argSqrd); argTo4.lsw = argSqrd.lsw;
- mul_Xsig_Xsig(&argTo4, &argTo4);
+ polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_h,
+ N_COEFF_NH - 1);
+ mul_Xsig_Xsig(&accumulator, &argSqrd);
+ negate_Xsig(&accumulator);
- polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_h,
- N_COEFF_NH-1);
- mul_Xsig_Xsig(&accumulator, &argSqrd);
- negate_Xsig(&accumulator);
+ polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_h,
+ N_COEFF_PH - 1);
+ negate_Xsig(&accumulator);
- polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_h,
- N_COEFF_PH-1);
- negate_Xsig(&accumulator);
+ mul64_Xsig(&accumulator, &fixed_arg);
+ mul64_Xsig(&accumulator, &fixed_arg);
- mul64_Xsig(&accumulator, &fixed_arg);
- mul64_Xsig(&accumulator, &fixed_arg);
+ shr_Xsig(&accumulator, 3);
+ negate_Xsig(&accumulator);
- shr_Xsig(&accumulator, 3);
- negate_Xsig(&accumulator);
+ add_Xsig_Xsig(&accumulator, &argSqrd);
- add_Xsig_Xsig(&accumulator, &argSqrd);
+ shr_Xsig(&accumulator, 1);
- shr_Xsig(&accumulator, 1);
+ accumulator.lsw |= 1; /* A zero accumulator here would cause problems */
+ negate_Xsig(&accumulator);
- accumulator.lsw |= 1; /* A zero accumulator here would cause problems */
- negate_Xsig(&accumulator);
+ /* The basic computation is complete. Now fix the answer to
+ compensate for the error due to the approximation used for
+ pi/2
+ */
- /* The basic computation is complete. Now fix the answer to
- compensate for the error due to the approximation used for
- pi/2
- */
+ /* This has an exponent of -65 */
+ fix_up = 0x898cc517;
+ /* The fix-up needs to be improved for larger args */
+ if (argSqrd.msw & 0xffc00000) {
+ /* Get about 32 bit precision in these: */
+ fix_up -= mul_32_32(0x898cc517, argSqrd.msw) / 6;
+ }
+ fix_up = mul_32_32(fix_up, LL_MSW(fixed_arg));
- /* This has an exponent of -65 */
- fix_up = 0x898cc517;
- /* The fix-up needs to be improved for larger args */
- if ( argSqrd.msw & 0xffc00000 )
- {
- /* Get about 32 bit precision in these: */
- fix_up -= mul_32_32(0x898cc517, argSqrd.msw) / 6;
- }
- fix_up = mul_32_32(fix_up, LL_MSW(fixed_arg));
+ adj = accumulator.lsw; /* temp save */
+ accumulator.lsw -= fix_up;
+ if (accumulator.lsw > adj)
+ XSIG_LL(accumulator)--;
- adj = accumulator.lsw; /* temp save */
- accumulator.lsw -= fix_up;
- if ( accumulator.lsw > adj )
- XSIG_LL(accumulator) --;
+ echange = round_Xsig(&accumulator);
- echange = round_Xsig(&accumulator);
-
- setexponentpos(&result, echange - 1);
- }
+ setexponentpos(&result, echange - 1);
+ }
- significand(&result) = XSIG_LL(accumulator);
- setsign(&result, getsign(st0_ptr));
- FPU_copy_to_reg0(&result, TAG_Valid);
+ significand(&result) = XSIG_LL(accumulator);
+ setsign(&result, getsign(st0_ptr));
+ FPU_copy_to_reg0(&result, TAG_Valid);
#ifdef PARANOID
- if ( (exponent(&result) >= 0)
- && (significand(&result) > 0x8000000000000000LL) )
- {
- EXCEPTION(EX_INTERNAL|0x150);
- }
+ if ((exponent(&result) >= 0)
+ && (significand(&result) > 0x8000000000000000LL)) {
+ EXCEPTION(EX_INTERNAL | 0x150);
+ }
#endif /* PARANOID */
}
-
-
/*--- poly_cos() ------------------------------------------------------------+
| |
+---------------------------------------------------------------------------*/
-void poly_cos(FPU_REG *st0_ptr)
+void poly_cos(FPU_REG * st0_ptr)
{
- FPU_REG result;
- long int exponent, exp2, echange;
- Xsig accumulator, argSqrd, fix_up, argTo4;
- unsigned long long fixed_arg;
+ FPU_REG result;
+ long int exponent, exp2, echange;
+ Xsig accumulator, argSqrd, fix_up, argTo4;
+ unsigned long long fixed_arg;
#ifdef PARANOID
- if ( (exponent(st0_ptr) > 0)
- || ((exponent(st0_ptr) == 0)
- && (significand(st0_ptr) > 0xc90fdaa22168c234LL)) )
- {
- EXCEPTION(EX_Invalid);
- FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
- return;
- }
-#endif /* PARANOID */
-
- exponent = exponent(st0_ptr);
-
- accumulator.lsw = accumulator.midw = accumulator.msw = 0;
-
- if ( (exponent < -1) || ((exponent == -1) && (st0_ptr->sigh <= 0xb00d6f54)) )
- {
- /* arg is < 0.687705 */
-
- argSqrd.msw = st0_ptr->sigh; argSqrd.midw = st0_ptr->sigl;
- argSqrd.lsw = 0;
- mul64_Xsig(&argSqrd, &significand(st0_ptr));
-
- if ( exponent < -1 )
- {
- /* shift the argument right by the required places */
- shr_Xsig(&argSqrd, 2*(-1-exponent));
- }
-
- argTo4.msw = argSqrd.msw; argTo4.midw = argSqrd.midw;
- argTo4.lsw = argSqrd.lsw;
- mul_Xsig_Xsig(&argTo4, &argTo4);
-
- polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_h,
- N_COEFF_NH-1);
- mul_Xsig_Xsig(&accumulator, &argSqrd);
- negate_Xsig(&accumulator);
-
- polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_h,
- N_COEFF_PH-1);
- negate_Xsig(&accumulator);
-
- mul64_Xsig(&accumulator, &significand(st0_ptr));
- mul64_Xsig(&accumulator, &significand(st0_ptr));
- shr_Xsig(&accumulator, -2*(1+exponent));
-
- shr_Xsig(&accumulator, 3);
- negate_Xsig(&accumulator);
-
- add_Xsig_Xsig(&accumulator, &argSqrd);
-
- shr_Xsig(&accumulator, 1);
-
- /* It doesn't matter if accumulator is all zero here, the
- following code will work ok */
- negate_Xsig(&accumulator);
-
- if ( accumulator.lsw & 0x80000000 )
- XSIG_LL(accumulator) ++;
- if ( accumulator.msw == 0 )
- {
- /* The result is 1.0 */
- FPU_copy_to_reg0(&CONST_1, TAG_Valid);
- return;
- }
- else
- {
- significand(&result) = XSIG_LL(accumulator);
-
- /* will be a valid positive nr with expon = -1 */
- setexponentpos(&result, -1);
- }
- }
- else
- {
- fixed_arg = significand(st0_ptr);
-
- if ( exponent == 0 )
- {
- /* The argument is >= 1.0 */
-
- /* Put the binary point at the left. */
- fixed_arg <<= 1;
- }
- /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
- fixed_arg = 0x921fb54442d18469LL - fixed_arg;
- /* There is a special case which arises due to rounding, to fix here. */
- if ( fixed_arg == 0xffffffffffffffffLL )
- fixed_arg = 0;
-
- exponent = -1;
- exp2 = -1;
-
- /* A shift is needed here only for a narrow range of arguments,
- i.e. for fixed_arg approx 2^-32, but we pick up more... */
- if ( !(LL_MSW(fixed_arg) & 0xffff0000) )
- {
- fixed_arg <<= 16;
- exponent -= 16;
- exp2 -= 16;
+ if ((exponent(st0_ptr) > 0)
+ || ((exponent(st0_ptr) == 0)
+ && (significand(st0_ptr) > 0xc90fdaa22168c234LL))) {
+ EXCEPTION(EX_Invalid);
+ FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
+ return;
}
+#endif /* PARANOID */
- XSIG_LL(argSqrd) = fixed_arg; argSqrd.lsw = 0;
- mul64_Xsig(&argSqrd, &fixed_arg);
-
- if ( exponent < -1 )
- {
- /* shift the argument right by the required places */
- shr_Xsig(&argSqrd, 2*(-1-exponent));
- }
-
- argTo4.msw = argSqrd.msw; argTo4.midw = argSqrd.midw;
- argTo4.lsw = argSqrd.lsw;
- mul_Xsig_Xsig(&argTo4, &argTo4);
-
- polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_l,
- N_COEFF_N-1);
- mul_Xsig_Xsig(&accumulator, &argSqrd);
- negate_Xsig(&accumulator);
-
- polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_l,
- N_COEFF_P-1);
-
- shr_Xsig(&accumulator, 2); /* Divide by four */
- accumulator.msw |= 0x80000000; /* Add 1.0 */
-
- mul64_Xsig(&accumulator, &fixed_arg);
- mul64_Xsig(&accumulator, &fixed_arg);
- mul64_Xsig(&accumulator, &fixed_arg);
-
- /* Divide by four, FPU_REG compatible, etc */
- exponent = 3*exponent;
-
- /* The minimum exponent difference is 3 */
- shr_Xsig(&accumulator, exp2 - exponent);
-
- negate_Xsig(&accumulator);
- XSIG_LL(accumulator) += fixed_arg;
-
- /* The basic computation is complete. Now fix the answer to
- compensate for the error due to the approximation used for
- pi/2
- */
-
- /* This has an exponent of -65 */
- XSIG_LL(fix_up) = 0x898cc51701b839a2ll;
- fix_up.lsw = 0;
-
- /* The fix-up needs to be improved for larger args */
- if ( argSqrd.msw & 0xffc00000 )
- {
- /* Get about 32 bit precision in these: */
- fix_up.msw -= mul_32_32(0x898cc517, argSqrd.msw) / 2;
- fix_up.msw += mul_32_32(0x898cc517, argTo4.msw) / 24;
+ exponent = exponent(st0_ptr);
+
+ accumulator.lsw = accumulator.midw = accumulator.msw = 0;
+
+ if ((exponent < -1)
+ || ((exponent == -1) && (st0_ptr->sigh <= 0xb00d6f54))) {
+ /* arg is < 0.687705 */
+
+ argSqrd.msw = st0_ptr->sigh;
+ argSqrd.midw = st0_ptr->sigl;
+ argSqrd.lsw = 0;
+ mul64_Xsig(&argSqrd, &significand(st0_ptr));
+
+ if (exponent < -1) {
+ /* shift the argument right by the required places */
+ shr_Xsig(&argSqrd, 2 * (-1 - exponent));
+ }
+
+ argTo4.msw = argSqrd.msw;
+ argTo4.midw = argSqrd.midw;
+ argTo4.lsw = argSqrd.lsw;
+ mul_Xsig_Xsig(&argTo4, &argTo4);
+
+ polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_h,
+ N_COEFF_NH - 1);
+ mul_Xsig_Xsig(&accumulator, &argSqrd);
+ negate_Xsig(&accumulator);
+
+ polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_h,
+ N_COEFF_PH - 1);
+ negate_Xsig(&accumulator);
+
+ mul64_Xsig(&accumulator, &significand(st0_ptr));
+ mul64_Xsig(&accumulator, &significand(st0_ptr));
+ shr_Xsig(&accumulator, -2 * (1 + exponent));
+
+ shr_Xsig(&accumulator, 3);
+ negate_Xsig(&accumulator);
+
+ add_Xsig_Xsig(&accumulator, &argSqrd);
+
+ shr_Xsig(&accumulator, 1);
+
+ /* It doesn't matter if accumulator is all zero here, the
+ following code will work ok */
+ negate_Xsig(&accumulator);
+
+ if (accumulator.lsw & 0x80000000)
+ XSIG_LL(accumulator)++;
+ if (accumulator.msw == 0) {
+ /* The result is 1.0 */
+ FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+ return;
+ } else {
+ significand(&result) = XSIG_LL(accumulator);
+
+ /* will be a valid positive nr with expon = -1 */
+ setexponentpos(&result, -1);
+ }
+ } else {
+ fixed_arg = significand(st0_ptr);
+
+ if (exponent == 0) {
+ /* The argument is >= 1.0 */
+
+ /* Put the binary point at the left. */
+ fixed_arg <<= 1;
+ }
+ /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
+ fixed_arg = 0x921fb54442d18469LL - fixed_arg;
+ /* There is a special case which arises due to rounding, to fix here. */
+ if (fixed_arg == 0xffffffffffffffffLL)
+ fixed_arg = 0;
+
+ exponent = -1;
+ exp2 = -1;
+
+ /* A shift is needed here only for a narrow range of arguments,
+ i.e. for fixed_arg approx 2^-32, but we pick up more... */
+ if (!(LL_MSW(fixed_arg) & 0xffff0000)) {
+ fixed_arg <<= 16;
+ exponent -= 16;
+ exp2 -= 16;
+ }
+
+ XSIG_LL(argSqrd) = fixed_arg;
+ argSqrd.lsw = 0;
+ mul64_Xsig(&argSqrd, &fixed_arg);
+
+ if (exponent < -1) {
+ /* shift the argument right by the required places */
+ shr_Xsig(&argSqrd, 2 * (-1 - exponent));
+ }
+
+ argTo4.msw = argSqrd.msw;
+ argTo4.midw = argSqrd.midw;
+ argTo4.lsw = argSqrd.lsw;
+ mul_Xsig_Xsig(&argTo4, &argTo4);
+
+ polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_l,
+ N_COEFF_N - 1);
+ mul_Xsig_Xsig(&accumulator, &argSqrd);
+ negate_Xsig(&accumulator);
+
+ polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_l,
+ N_COEFF_P - 1);
+
+ shr_Xsig(&accumulator, 2); /* Divide by four */
+ accumulator.msw |= 0x80000000; /* Add 1.0 */
+
+ mul64_Xsig(&accumulator, &fixed_arg);
+ mul64_Xsig(&accumulator, &fixed_arg);
+ mul64_Xsig(&accumulator, &fixed_arg);
+
+ /* Divide by four, FPU_REG compatible, etc */
+ exponent = 3 * exponent;
+
+ /* The minimum exponent difference is 3 */
+ shr_Xsig(&accumulator, exp2 - exponent);
+
+ negate_Xsig(&accumulator);
+ XSIG_LL(accumulator) += fixed_arg;
+
+ /* The basic computation is complete. Now fix the answer to
+ compensate for the error due to the approximation used for
+ pi/2
+ */
+
+ /* This has an exponent of -65 */
+ XSIG_LL(fix_up) = 0x898cc51701b839a2ll;
+ fix_up.lsw = 0;
+
+ /* The fix-up needs to be improved for larger args */
+ if (argSqrd.msw & 0xffc00000) {
+ /* Get about 32 bit precision in these: */
+ fix_up.msw -= mul_32_32(0x898cc517, argSqrd.msw) / 2;
+ fix_up.msw += mul_32_32(0x898cc517, argTo4.msw) / 24;
+ }
+
+ exp2 += norm_Xsig(&accumulator);
+ shr_Xsig(&accumulator, 1); /* Prevent overflow */
+ exp2++;
+ shr_Xsig(&fix_up, 65 + exp2);
+
+ add_Xsig_Xsig(&accumulator, &fix_up);
+
+ echange = round_Xsig(&accumulator);
+
+ setexponentpos(&result, exp2 + echange);
+ significand(&result) = XSIG_LL(accumulator);
}
- exp2 += norm_Xsig(&accumulator);
- shr_Xsig(&accumulator, 1); /* Prevent overflow */
- exp2++;
- shr_Xsig(&fix_up, 65 + exp2);
-
- add_Xsig_Xsig(&accumulator, &fix_up);
-
- echange = round_Xsig(&accumulator);
-
- setexponentpos(&result, exp2 + echange);
- significand(&result) = XSIG_LL(accumulator);
- }
-
- FPU_copy_to_reg0(&result, TAG_Valid);
+ FPU_copy_to_reg0(&result, TAG_Valid);
#ifdef PARANOID
- if ( (exponent(&result) >= 0)
- && (significand(&result) > 0x8000000000000000LL) )
- {
- EXCEPTION(EX_INTERNAL|0x151);
- }
+ if ((exponent(&result) >= 0)
+ && (significand(&result) > 0x8000000000000000LL)) {
+ EXCEPTION(EX_INTERNAL | 0x151);
+ }
#endif /* PARANOID */
}
diff --git a/arch/x86/math-emu/poly_tan.c b/arch/x86/math-emu/poly_tan.c
index 8df3e03b6e6f..c0d181e39229 100644
--- a/arch/x86/math-emu/poly_tan.c
+++ b/arch/x86/math-emu/poly_tan.c
@@ -17,206 +17,196 @@
#include "control_w.h"
#include "poly.h"
-
#define HiPOWERop 3 /* odd poly, positive terms */
-static const unsigned long long oddplterm[HiPOWERop] =
-{
- 0x0000000000000000LL,
- 0x0051a1cf08fca228LL,
- 0x0000000071284ff7LL
+static const unsigned long long oddplterm[HiPOWERop] = {
+ 0x0000000000000000LL,
+ 0x0051a1cf08fca228LL,
+ 0x0000000071284ff7LL
};
#define HiPOWERon 2 /* odd poly, negative terms */
-static const unsigned long long oddnegterm[HiPOWERon] =
-{
- 0x1291a9a184244e80LL,
- 0x0000583245819c21LL
+static const unsigned long long oddnegterm[HiPOWERon] = {
+ 0x1291a9a184244e80LL,
+ 0x0000583245819c21LL
};
#define HiPOWERep 2 /* even poly, positive terms */
-static const unsigned long long evenplterm[HiPOWERep] =
-{
- 0x0e848884b539e888LL,
- 0x00003c7f18b887daLL
+static const unsigned long long evenplterm[HiPOWERep] = {
+ 0x0e848884b539e888LL,
+ 0x00003c7f18b887daLL
};
#define HiPOWERen 2 /* even poly, negative terms */
-static const unsigned long long evennegterm[HiPOWERen] =
-{
- 0xf1f0200fd51569ccLL,
- 0x003afb46105c4432LL
+static const unsigned long long evennegterm[HiPOWERen] = {
+ 0xf1f0200fd51569ccLL,
+ 0x003afb46105c4432LL
};
static const unsigned long long twothirds = 0xaaaaaaaaaaaaaaabLL;
-
/*--- poly_tan() ------------------------------------------------------------+
| |
+---------------------------------------------------------------------------*/
-void poly_tan(FPU_REG *st0_ptr)
+void poly_tan(FPU_REG * st0_ptr)
{
- long int exponent;
- int invert;
- Xsig argSq, argSqSq, accumulatoro, accumulatore, accum,
- argSignif, fix_up;
- unsigned long adj;
+ long int exponent;
+ int invert;
+ Xsig argSq, argSqSq, accumulatoro, accumulatore, accum,
+ argSignif, fix_up;
+ unsigned long adj;
- exponent = exponent(st0_ptr);
+ exponent = exponent(st0_ptr);
#ifdef PARANOID
- if ( signnegative(st0_ptr) ) /* Can't hack a number < 0.0 */
- { arith_invalid(0); return; } /* Need a positive number */
+ if (signnegative(st0_ptr)) { /* Can't hack a number < 0.0 */
+ arith_invalid(0);
+ return;
+ } /* Need a positive number */
#endif /* PARANOID */
- /* Split the problem into two domains, smaller and larger than pi/4 */
- if ( (exponent == 0) || ((exponent == -1) && (st0_ptr->sigh > 0xc90fdaa2)) )
- {
- /* The argument is greater than (approx) pi/4 */
- invert = 1;
- accum.lsw = 0;
- XSIG_LL(accum) = significand(st0_ptr);
-
- if ( exponent == 0 )
- {
- /* The argument is >= 1.0 */
- /* Put the binary point at the left. */
- XSIG_LL(accum) <<= 1;
- }
- /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
- XSIG_LL(accum) = 0x921fb54442d18469LL - XSIG_LL(accum);
- /* This is a special case which arises due to rounding. */
- if ( XSIG_LL(accum) == 0xffffffffffffffffLL )
- {
- FPU_settag0(TAG_Valid);
- significand(st0_ptr) = 0x8a51e04daabda360LL;
- setexponent16(st0_ptr, (0x41 + EXTENDED_Ebias) | SIGN_Negative);
- return;
+ /* Split the problem into two domains, smaller and larger than pi/4 */
+ if ((exponent == 0)
+ || ((exponent == -1) && (st0_ptr->sigh > 0xc90fdaa2))) {
+ /* The argument is greater than (approx) pi/4 */
+ invert = 1;
+ accum.lsw = 0;
+ XSIG_LL(accum) = significand(st0_ptr);
+
+ if (exponent == 0) {
+ /* The argument is >= 1.0 */
+ /* Put the binary point at the left. */
+ XSIG_LL(accum) <<= 1;
+ }
+ /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
+ XSIG_LL(accum) = 0x921fb54442d18469LL - XSIG_LL(accum);
+ /* This is a special case which arises due to rounding. */
+ if (XSIG_LL(accum) == 0xffffffffffffffffLL) {
+ FPU_settag0(TAG_Valid);
+ significand(st0_ptr) = 0x8a51e04daabda360LL;
+ setexponent16(st0_ptr,
+ (0x41 + EXTENDED_Ebias) | SIGN_Negative);
+ return;
+ }
+
+ argSignif.lsw = accum.lsw;
+ XSIG_LL(argSignif) = XSIG_LL(accum);
+ exponent = -1 + norm_Xsig(&argSignif);
+ } else {
+ invert = 0;
+ argSignif.lsw = 0;
+ XSIG_LL(accum) = XSIG_LL(argSignif) = significand(st0_ptr);
+
+ if (exponent < -1) {
+ /* shift the argument right by the required places */
+ if (FPU_shrx(&XSIG_LL(accum), -1 - exponent) >=
+ 0x80000000U)
+ XSIG_LL(accum)++; /* round up */
+ }
}
- argSignif.lsw = accum.lsw;
- XSIG_LL(argSignif) = XSIG_LL(accum);
- exponent = -1 + norm_Xsig(&argSignif);
- }
- else
- {
- invert = 0;
- argSignif.lsw = 0;
- XSIG_LL(accum) = XSIG_LL(argSignif) = significand(st0_ptr);
-
- if ( exponent < -1 )
- {
- /* shift the argument right by the required places */
- if ( FPU_shrx(&XSIG_LL(accum), -1-exponent) >= 0x80000000U )
- XSIG_LL(accum) ++; /* round up */
- }
- }
-
- XSIG_LL(argSq) = XSIG_LL(accum); argSq.lsw = accum.lsw;
- mul_Xsig_Xsig(&argSq, &argSq);
- XSIG_LL(argSqSq) = XSIG_LL(argSq); argSqSq.lsw = argSq.lsw;
- mul_Xsig_Xsig(&argSqSq, &argSqSq);
-
- /* Compute the negative terms for the numerator polynomial */
- accumulatoro.msw = accumulatoro.midw = accumulatoro.lsw = 0;
- polynomial_Xsig(&accumulatoro, &XSIG_LL(argSqSq), oddnegterm, HiPOWERon-1);
- mul_Xsig_Xsig(&accumulatoro, &argSq);
- negate_Xsig(&accumulatoro);
- /* Add the positive terms */
- polynomial_Xsig(&accumulatoro, &XSIG_LL(argSqSq), oddplterm, HiPOWERop-1);
-
-
- /* Compute the positive terms for the denominator polynomial */
- accumulatore.msw = accumulatore.midw = accumulatore.lsw = 0;
- polynomial_Xsig(&accumulatore, &XSIG_LL(argSqSq), evenplterm, HiPOWERep-1);
- mul_Xsig_Xsig(&accumulatore, &argSq);
- negate_Xsig(&accumulatore);
- /* Add the negative terms */
- polynomial_Xsig(&accumulatore, &XSIG_LL(argSqSq), evennegterm, HiPOWERen-1);
- /* Multiply by arg^2 */
- mul64_Xsig(&accumulatore, &XSIG_LL(argSignif));
- mul64_Xsig(&accumulatore, &XSIG_LL(argSignif));
- /* de-normalize and divide by 2 */
- shr_Xsig(&accumulatore, -2*(1+exponent) + 1);
- negate_Xsig(&accumulatore); /* This does 1 - accumulator */
-
- /* Now find the ratio. */
- if ( accumulatore.msw == 0 )
- {
- /* accumulatoro must contain 1.0 here, (actually, 0) but it
- really doesn't matter what value we use because it will
- have negligible effect in later calculations
- */
- XSIG_LL(accum) = 0x8000000000000000LL;
- accum.lsw = 0;
- }
- else
- {
- div_Xsig(&accumulatoro, &accumulatore, &accum);
- }
-
- /* Multiply by 1/3 * arg^3 */
- mul64_Xsig(&accum, &XSIG_LL(argSignif));
- mul64_Xsig(&accum, &XSIG_LL(argSignif));
- mul64_Xsig(&accum, &XSIG_LL(argSignif));
- mul64_Xsig(&accum, &twothirds);
- shr_Xsig(&accum, -2*(exponent+1));
-
- /* tan(arg) = arg + accum */
- add_two_Xsig(&accum, &argSignif, &exponent);
-
- if ( invert )
- {
- /* We now have the value of tan(pi_2 - arg) where pi_2 is an
- approximation for pi/2
- */
- /* The next step is to fix the answer to compensate for the
- error due to the approximation used for pi/2
- */
-
- /* This is (approx) delta, the error in our approx for pi/2
- (see above). It has an exponent of -65
- */
- XSIG_LL(fix_up) = 0x898cc51701b839a2LL;
- fix_up.lsw = 0;
-
- if ( exponent == 0 )
- adj = 0xffffffff; /* We want approx 1.0 here, but
- this is close enough. */
- else if ( exponent > -30 )
- {
- adj = accum.msw >> -(exponent+1); /* tan */
- adj = mul_32_32(adj, adj); /* tan^2 */
+ XSIG_LL(argSq) = XSIG_LL(accum);
+ argSq.lsw = accum.lsw;
+ mul_Xsig_Xsig(&argSq, &argSq);
+ XSIG_LL(argSqSq) = XSIG_LL(argSq);
+ argSqSq.lsw = argSq.lsw;
+ mul_Xsig_Xsig(&argSqSq, &argSqSq);
+
+ /* Compute the negative terms for the numerator polynomial */
+ accumulatoro.msw = accumulatoro.midw = accumulatoro.lsw = 0;
+ polynomial_Xsig(&accumulatoro, &XSIG_LL(argSqSq), oddnegterm,
+ HiPOWERon - 1);
+ mul_Xsig_Xsig(&accumulatoro, &argSq);
+ negate_Xsig(&accumulatoro);
+ /* Add the positive terms */
+ polynomial_Xsig(&accumulatoro, &XSIG_LL(argSqSq), oddplterm,
+ HiPOWERop - 1);
+
+ /* Compute the positive terms for the denominator polynomial */
+ accumulatore.msw = accumulatore.midw = accumulatore.lsw = 0;
+ polynomial_Xsig(&accumulatore, &XSIG_LL(argSqSq), evenplterm,
+ HiPOWERep - 1);
+ mul_Xsig_Xsig(&accumulatore, &argSq);
+ negate_Xsig(&accumulatore);
+ /* Add the negative terms */
+ polynomial_Xsig(&accumulatore, &XSIG_LL(argSqSq), evennegterm,
+ HiPOWERen - 1);
+ /* Multiply by arg^2 */
+ mul64_Xsig(&accumulatore, &XSIG_LL(argSignif));
+ mul64_Xsig(&accumulatore, &XSIG_LL(argSignif));
+ /* de-normalize and divide by 2 */
+ shr_Xsig(&accumulatore, -2 * (1 + exponent) + 1);
+ negate_Xsig(&accumulatore); /* This does 1 - accumulator */
+
+ /* Now find the ratio. */
+ if (accumulatore.msw == 0) {
+ /* accumulatoro must contain 1.0 here, (actually, 0) but it
+ really doesn't matter what value we use because it will
+ have negligible effect in later calculations
+ */
+ XSIG_LL(accum) = 0x8000000000000000LL;
+ accum.lsw = 0;
+ } else {
+ div_Xsig(&accumulatoro, &accumulatore, &accum);
}
- else
- adj = 0;
- adj = mul_32_32(0x898cc517, adj); /* delta * tan^2 */
-
- fix_up.msw += adj;
- if ( !(fix_up.msw & 0x80000000) ) /* did fix_up overflow ? */
- {
- /* Yes, we need to add an msb */
- shr_Xsig(&fix_up, 1);
- fix_up.msw |= 0x80000000;
- shr_Xsig(&fix_up, 64 + exponent);
+
+ /* Multiply by 1/3 * arg^3 */
+ mul64_Xsig(&accum, &XSIG_LL(argSignif));
+ mul64_Xsig(&accum, &XSIG_LL(argSignif));
+ mul64_Xsig(&accum, &XSIG_LL(argSignif));
+ mul64_Xsig(&accum, &twothirds);
+ shr_Xsig(&accum, -2 * (exponent + 1));
+
+ /* tan(arg) = arg + accum */
+ add_two_Xsig(&accum, &argSignif, &exponent);
+
+ if (invert) {
+ /* We now have the value of tan(pi_2 - arg) where pi_2 is an
+ approximation for pi/2
+ */
+ /* The next step is to fix the answer to compensate for the
+ error due to the approximation used for pi/2
+ */
+
+ /* This is (approx) delta, the error in our approx for pi/2
+ (see above). It has an exponent of -65
+ */
+ XSIG_LL(fix_up) = 0x898cc51701b839a2LL;
+ fix_up.lsw = 0;
+
+ if (exponent == 0)
+ adj = 0xffffffff; /* We want approx 1.0 here, but
+ this is close enough. */
+ else if (exponent > -30) {
+ adj = accum.msw >> -(exponent + 1); /* tan */
+ adj = mul_32_32(adj, adj); /* tan^2 */
+ } else
+ adj = 0;
+ adj = mul_32_32(0x898cc517, adj); /* delta * tan^2 */
+
+ fix_up.msw += adj;
+ if (!(fix_up.msw & 0x80000000)) { /* did fix_up overflow ? */
+ /* Yes, we need to add an msb */
+ shr_Xsig(&fix_up, 1);
+ fix_up.msw |= 0x80000000;
+ shr_Xsig(&fix_up, 64 + exponent);
+ } else
+ shr_Xsig(&fix_up, 65 + exponent);
+
+ add_two_Xsig(&accum, &fix_up, &exponent);
+
+ /* accum now contains tan(pi/2 - arg).
+ Use tan(arg) = 1.0 / tan(pi/2 - arg)
+ */
+ accumulatoro.lsw = accumulatoro.midw = 0;
+ accumulatoro.msw = 0x80000000;
+ div_Xsig(&accumulatoro, &accum, &accum);
+ exponent = -exponent - 1;
}
- else
- shr_Xsig(&fix_up, 65 + exponent);
-
- add_two_Xsig(&accum, &fix_up, &exponent);
-
- /* accum now contains tan(pi/2 - arg).
- Use tan(arg) = 1.0 / tan(pi/2 - arg)
- */
- accumulatoro.lsw = accumulatoro.midw = 0;
- accumulatoro.msw = 0x80000000;
- div_Xsig(&accumulatoro, &accum, &accum);
- exponent = - exponent - 1;
- }
-
- /* Transfer the result */
- round_Xsig(&accum);
- FPU_settag0(TAG_Valid);
- significand(st0_ptr) = XSIG_LL(accum);
- setexponent16(st0_ptr, exponent + EXTENDED_Ebias); /* Result is positive. */
+
+ /* Transfer the result */
+ round_Xsig(&accum);
+ FPU_settag0(TAG_Valid);
+ significand(st0_ptr) = XSIG_LL(accum);
+ setexponent16(st0_ptr, exponent + EXTENDED_Ebias); /* Result is positive. */
}
diff --git a/arch/x86/math-emu/reg_add_sub.c b/arch/x86/math-emu/reg_add_sub.c
index 7cd3b37ac084..deea48b9f13a 100644
--- a/arch/x86/math-emu/reg_add_sub.c
+++ b/arch/x86/math-emu/reg_add_sub.c
@@ -27,7 +27,7 @@
static
int add_sub_specials(FPU_REG const *a, u_char taga, u_char signa,
FPU_REG const *b, u_char tagb, u_char signb,
- FPU_REG *dest, int deststnr, int control_w);
+ FPU_REG * dest, int deststnr, int control_w);
/*
Operates on st(0) and st(n), or on st(0) and temporary data.
@@ -35,340 +35,299 @@ int add_sub_specials(FPU_REG const *a, u_char taga, u_char signa,
*/
int FPU_add(FPU_REG const *b, u_char tagb, int deststnr, int control_w)
{
- FPU_REG *a = &st(0);
- FPU_REG *dest = &st(deststnr);
- u_char signb = getsign(b);
- u_char taga = FPU_gettag0();
- u_char signa = getsign(a);
- u_char saved_sign = getsign(dest);
- int diff, tag, expa, expb;
-
- if ( !(taga | tagb) )
- {
- expa = exponent(a);
- expb = exponent(b);
-
- valid_add:
- /* Both registers are valid */
- if (!(signa ^ signb))
- {
- /* signs are the same */
- tag = FPU_u_add(a, b, dest, control_w, signa, expa, expb);
- }
- else
- {
- /* The signs are different, so do a subtraction */
- diff = expa - expb;
- if (!diff)
- {
- diff = a->sigh - b->sigh; /* This works only if the ms bits
- are identical. */
- if (!diff)
- {
- diff = a->sigl > b->sigl;
- if (!diff)
- diff = -(a->sigl < b->sigl);
+ FPU_REG *a = &st(0);
+ FPU_REG *dest = &st(deststnr);
+ u_char signb = getsign(b);
+ u_char taga = FPU_gettag0();
+ u_char signa = getsign(a);
+ u_char saved_sign = getsign(dest);
+ int diff, tag, expa, expb;
+
+ if (!(taga | tagb)) {
+ expa = exponent(a);
+ expb = exponent(b);
+
+ valid_add:
+ /* Both registers are valid */
+ if (!(signa ^ signb)) {
+ /* signs are the same */
+ tag =
+ FPU_u_add(a, b, dest, control_w, signa, expa, expb);
+ } else {
+ /* The signs are different, so do a subtraction */
+ diff = expa - expb;
+ if (!diff) {
+ diff = a->sigh - b->sigh; /* This works only if the ms bits
+ are identical. */
+ if (!diff) {
+ diff = a->sigl > b->sigl;
+ if (!diff)
+ diff = -(a->sigl < b->sigl);
+ }
+ }
+
+ if (diff > 0) {
+ tag =
+ FPU_u_sub(a, b, dest, control_w, signa,
+ expa, expb);
+ } else if (diff < 0) {
+ tag =
+ FPU_u_sub(b, a, dest, control_w, signb,
+ expb, expa);
+ } else {
+ FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+ /* sign depends upon rounding mode */
+ setsign(dest, ((control_w & CW_RC) != RC_DOWN)
+ ? SIGN_POS : SIGN_NEG);
+ return TAG_Zero;
+ }
}
- }
-
- if (diff > 0)
- {
- tag = FPU_u_sub(a, b, dest, control_w, signa, expa, expb);
- }
- else if ( diff < 0 )
- {
- tag = FPU_u_sub(b, a, dest, control_w, signb, expb, expa);
- }
- else
- {
- FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
- /* sign depends upon rounding mode */
- setsign(dest, ((control_w & CW_RC) != RC_DOWN)
- ? SIGN_POS : SIGN_NEG);
- return TAG_Zero;
- }
- }
- if ( tag < 0 )
- {
- setsign(dest, saved_sign);
- return tag;
+ if (tag < 0) {
+ setsign(dest, saved_sign);
+ return tag;
+ }
+ FPU_settagi(deststnr, tag);
+ return tag;
}
- FPU_settagi(deststnr, tag);
- return tag;
- }
- if ( taga == TAG_Special )
- taga = FPU_Special(a);
- if ( tagb == TAG_Special )
- tagb = FPU_Special(b);
+ if (taga == TAG_Special)
+ taga = FPU_Special(a);
+ if (tagb == TAG_Special)
+ tagb = FPU_Special(b);
- if ( ((taga == TAG_Valid) && (tagb == TW_Denormal))
+ if (((taga == TAG_Valid) && (tagb == TW_Denormal))
|| ((taga == TW_Denormal) && (tagb == TAG_Valid))
- || ((taga == TW_Denormal) && (tagb == TW_Denormal)) )
- {
- FPU_REG x, y;
+ || ((taga == TW_Denormal) && (tagb == TW_Denormal))) {
+ FPU_REG x, y;
+
+ if (denormal_operand() < 0)
+ return FPU_Exception;
+
+ FPU_to_exp16(a, &x);
+ FPU_to_exp16(b, &y);
+ a = &x;
+ b = &y;
+ expa = exponent16(a);
+ expb = exponent16(b);
+ goto valid_add;
+ }
- if ( denormal_operand() < 0 )
- return FPU_Exception;
+ if ((taga == TW_NaN) || (tagb == TW_NaN)) {
+ if (deststnr == 0)
+ return real_2op_NaN(b, tagb, deststnr, a);
+ else
+ return real_2op_NaN(a, taga, deststnr, a);
+ }
- FPU_to_exp16(a, &x);
- FPU_to_exp16(b, &y);
- a = &x;
- b = &y;
- expa = exponent16(a);
- expb = exponent16(b);
- goto valid_add;
- }
-
- if ( (taga == TW_NaN) || (tagb == TW_NaN) )
- {
- if ( deststnr == 0 )
- return real_2op_NaN(b, tagb, deststnr, a);
- else
- return real_2op_NaN(a, taga, deststnr, a);
- }
-
- return add_sub_specials(a, taga, signa, b, tagb, signb,
- dest, deststnr, control_w);
+ return add_sub_specials(a, taga, signa, b, tagb, signb,
+ dest, deststnr, control_w);
}
-
/* Subtract b from a. (a-b) -> dest */
int FPU_sub(int flags, int rm, int control_w)
{
- FPU_REG const *a, *b;
- FPU_REG *dest;
- u_char taga, tagb, signa, signb, saved_sign, sign;
- int diff, tag = 0, expa, expb, deststnr;
-
- a = &st(0);
- taga = FPU_gettag0();
-
- deststnr = 0;
- if ( flags & LOADED )
- {
- b = (FPU_REG *)rm;
- tagb = flags & 0x0f;
- }
- else
- {
- b = &st(rm);
- tagb = FPU_gettagi(rm);
-
- if ( flags & DEST_RM )
- deststnr = rm;
- }
-
- signa = getsign(a);
- signb = getsign(b);
-
- if ( flags & REV )
- {
- signa ^= SIGN_NEG;
- signb ^= SIGN_NEG;
- }
-
- dest = &st(deststnr);
- saved_sign = getsign(dest);
-
- if ( !(taga | tagb) )
- {
- expa = exponent(a);
- expb = exponent(b);
-
- valid_subtract:
- /* Both registers are valid */
-
- diff = expa - expb;
-
- if (!diff)
- {
- diff = a->sigh - b->sigh; /* Works only if ms bits are identical */
- if (!diff)
- {
- diff = a->sigl > b->sigl;
- if (!diff)
- diff = -(a->sigl < b->sigl);
- }
+ FPU_REG const *a, *b;
+ FPU_REG *dest;
+ u_char taga, tagb, signa, signb, saved_sign, sign;
+ int diff, tag = 0, expa, expb, deststnr;
+
+ a = &st(0);
+ taga = FPU_gettag0();
+
+ deststnr = 0;
+ if (flags & LOADED) {
+ b = (FPU_REG *) rm;
+ tagb = flags & 0x0f;
+ } else {
+ b = &st(rm);
+ tagb = FPU_gettagi(rm);
+
+ if (flags & DEST_RM)
+ deststnr = rm;
}
- switch ( (((int)signa)*2 + signb) / SIGN_NEG )
- {
- case 0: /* P - P */
- case 3: /* N - N */
- if (diff > 0)
- {
- /* |a| > |b| */
- tag = FPU_u_sub(a, b, dest, control_w, signa, expa, expb);
- }
- else if ( diff == 0 )
- {
- FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
-
- /* sign depends upon rounding mode */
- setsign(dest, ((control_w & CW_RC) != RC_DOWN)
- ? SIGN_POS : SIGN_NEG);
- return TAG_Zero;
- }
- else
- {
- sign = signa ^ SIGN_NEG;
- tag = FPU_u_sub(b, a, dest, control_w, sign, expb, expa);
- }
- break;
- case 1: /* P - N */
- tag = FPU_u_add(a, b, dest, control_w, SIGN_POS, expa, expb);
- break;
- case 2: /* N - P */
- tag = FPU_u_add(a, b, dest, control_w, SIGN_NEG, expa, expb);
- break;
+ signa = getsign(a);
+ signb = getsign(b);
+
+ if (flags & REV) {
+ signa ^= SIGN_NEG;
+ signb ^= SIGN_NEG;
+ }
+
+ dest = &st(deststnr);
+ saved_sign = getsign(dest);
+
+ if (!(taga | tagb)) {
+ expa = exponent(a);
+ expb = exponent(b);
+
+ valid_subtract:
+ /* Both registers are valid */
+
+ diff = expa - expb;
+
+ if (!diff) {
+ diff = a->sigh - b->sigh; /* Works only if ms bits are identical */
+ if (!diff) {
+ diff = a->sigl > b->sigl;
+ if (!diff)
+ diff = -(a->sigl < b->sigl);
+ }
+ }
+
+ switch ((((int)signa) * 2 + signb) / SIGN_NEG) {
+ case 0: /* P - P */
+ case 3: /* N - N */
+ if (diff > 0) {
+ /* |a| > |b| */
+ tag =
+ FPU_u_sub(a, b, dest, control_w, signa,
+ expa, expb);
+ } else if (diff == 0) {
+ FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+
+ /* sign depends upon rounding mode */
+ setsign(dest, ((control_w & CW_RC) != RC_DOWN)
+ ? SIGN_POS : SIGN_NEG);
+ return TAG_Zero;
+ } else {
+ sign = signa ^ SIGN_NEG;
+ tag =
+ FPU_u_sub(b, a, dest, control_w, sign, expb,
+ expa);
+ }
+ break;
+ case 1: /* P - N */
+ tag =
+ FPU_u_add(a, b, dest, control_w, SIGN_POS, expa,
+ expb);
+ break;
+ case 2: /* N - P */
+ tag =
+ FPU_u_add(a, b, dest, control_w, SIGN_NEG, expa,
+ expb);
+ break;
#ifdef PARANOID
- default:
- EXCEPTION(EX_INTERNAL|0x111);
- return -1;
+ default:
+ EXCEPTION(EX_INTERNAL | 0x111);
+ return -1;
#endif
+ }
+ if (tag < 0) {
+ setsign(dest, saved_sign);
+ return tag;
+ }
+ FPU_settagi(deststnr, tag);
+ return tag;
}
- if ( tag < 0 )
- {
- setsign(dest, saved_sign);
- return tag;
- }
- FPU_settagi(deststnr, tag);
- return tag;
- }
- if ( taga == TAG_Special )
- taga = FPU_Special(a);
- if ( tagb == TAG_Special )
- tagb = FPU_Special(b);
+ if (taga == TAG_Special)
+ taga = FPU_Special(a);
+ if (tagb == TAG_Special)
+ tagb = FPU_Special(b);
- if ( ((taga == TAG_Valid) && (tagb == TW_Denormal))
+ if (((taga == TAG_Valid) && (tagb == TW_Denormal))
|| ((taga == TW_Denormal) && (tagb == TAG_Valid))
- || ((taga == TW_Denormal) && (tagb == TW_Denormal)) )
- {
- FPU_REG x, y;
+ || ((taga == TW_Denormal) && (tagb == TW_Denormal))) {
+ FPU_REG x, y;
- if ( denormal_operand() < 0 )
- return FPU_Exception;
+ if (denormal_operand() < 0)
+ return FPU_Exception;
+
+ FPU_to_exp16(a, &x);
+ FPU_to_exp16(b, &y);
+ a = &x;
+ b = &y;
+ expa = exponent16(a);
+ expb = exponent16(b);
- FPU_to_exp16(a, &x);
- FPU_to_exp16(b, &y);
- a = &x;
- b = &y;
- expa = exponent16(a);
- expb = exponent16(b);
-
- goto valid_subtract;
- }
-
- if ( (taga == TW_NaN) || (tagb == TW_NaN) )
- {
- FPU_REG const *d1, *d2;
- if ( flags & REV )
- {
- d1 = b;
- d2 = a;
+ goto valid_subtract;
}
- else
- {
- d1 = a;
- d2 = b;
+
+ if ((taga == TW_NaN) || (tagb == TW_NaN)) {
+ FPU_REG const *d1, *d2;
+ if (flags & REV) {
+ d1 = b;
+ d2 = a;
+ } else {
+ d1 = a;
+ d2 = b;
+ }
+ if (flags & LOADED)
+ return real_2op_NaN(b, tagb, deststnr, d1);
+ if (flags & DEST_RM)
+ return real_2op_NaN(a, taga, deststnr, d2);
+ else
+ return real_2op_NaN(b, tagb, deststnr, d2);
}
- if ( flags & LOADED )
- return real_2op_NaN(b, tagb, deststnr, d1);
- if ( flags & DEST_RM )
- return real_2op_NaN(a, taga, deststnr, d2);
- else
- return real_2op_NaN(b, tagb, deststnr, d2);
- }
-
- return add_sub_specials(a, taga, signa, b, tagb, signb ^ SIGN_NEG,
- dest, deststnr, control_w);
-}
+ return add_sub_specials(a, taga, signa, b, tagb, signb ^ SIGN_NEG,
+ dest, deststnr, control_w);
+}
static
int add_sub_specials(FPU_REG const *a, u_char taga, u_char signa,
FPU_REG const *b, u_char tagb, u_char signb,
- FPU_REG *dest, int deststnr, int control_w)
+ FPU_REG * dest, int deststnr, int control_w)
{
- if ( ((taga == TW_Denormal) || (tagb == TW_Denormal))
- && (denormal_operand() < 0) )
- return FPU_Exception;
-
- if (taga == TAG_Zero)
- {
- if (tagb == TAG_Zero)
- {
- /* Both are zero, result will be zero. */
- u_char different_signs = signa ^ signb;
-
- FPU_copy_to_regi(a, TAG_Zero, deststnr);
- if ( different_signs )
- {
- /* Signs are different. */
- /* Sign of answer depends upon rounding mode. */
- setsign(dest, ((control_w & CW_RC) != RC_DOWN)
- ? SIGN_POS : SIGN_NEG);
- }
- else
- setsign(dest, signa); /* signa may differ from the sign of a. */
- return TAG_Zero;
- }
- else
- {
- reg_copy(b, dest);
- if ( (tagb == TW_Denormal) && (b->sigh & 0x80000000) )
- {
- /* A pseudoDenormal, convert it. */
- addexponent(dest, 1);
- tagb = TAG_Valid;
- }
- else if ( tagb > TAG_Empty )
- tagb = TAG_Special;
- setsign(dest, signb); /* signb may differ from the sign of b. */
- FPU_settagi(deststnr, tagb);
- return tagb;
- }
- }
- else if (tagb == TAG_Zero)
- {
- reg_copy(a, dest);
- if ( (taga == TW_Denormal) && (a->sigh & 0x80000000) )
- {
- /* A pseudoDenormal */
- addexponent(dest, 1);
- taga = TAG_Valid;
- }
- else if ( taga > TAG_Empty )
- taga = TAG_Special;
- setsign(dest, signa); /* signa may differ from the sign of a. */
- FPU_settagi(deststnr, taga);
- return taga;
- }
- else if (taga == TW_Infinity)
- {
- if ( (tagb != TW_Infinity) || (signa == signb) )
- {
- FPU_copy_to_regi(a, TAG_Special, deststnr);
- setsign(dest, signa); /* signa may differ from the sign of a. */
- return taga;
+ if (((taga == TW_Denormal) || (tagb == TW_Denormal))
+ && (denormal_operand() < 0))
+ return FPU_Exception;
+
+ if (taga == TAG_Zero) {
+ if (tagb == TAG_Zero) {
+ /* Both are zero, result will be zero. */
+ u_char different_signs = signa ^ signb;
+
+ FPU_copy_to_regi(a, TAG_Zero, deststnr);
+ if (different_signs) {
+ /* Signs are different. */
+ /* Sign of answer depends upon rounding mode. */
+ setsign(dest, ((control_w & CW_RC) != RC_DOWN)
+ ? SIGN_POS : SIGN_NEG);
+ } else
+ setsign(dest, signa); /* signa may differ from the sign of a. */
+ return TAG_Zero;
+ } else {
+ reg_copy(b, dest);
+ if ((tagb == TW_Denormal) && (b->sigh & 0x80000000)) {
+ /* A pseudoDenormal, convert it. */
+ addexponent(dest, 1);
+ tagb = TAG_Valid;
+ } else if (tagb > TAG_Empty)
+ tagb = TAG_Special;
+ setsign(dest, signb); /* signb may differ from the sign of b. */
+ FPU_settagi(deststnr, tagb);
+ return tagb;
+ }
+ } else if (tagb == TAG_Zero) {
+ reg_copy(a, dest);
+ if ((taga == TW_Denormal) && (a->sigh & 0x80000000)) {
+ /* A pseudoDenormal */
+ addexponent(dest, 1);
+ taga = TAG_Valid;
+ } else if (taga > TAG_Empty)
+ taga = TAG_Special;
+ setsign(dest, signa); /* signa may differ from the sign of a. */
+ FPU_settagi(deststnr, taga);
+ return taga;
+ } else if (taga == TW_Infinity) {
+ if ((tagb != TW_Infinity) || (signa == signb)) {
+ FPU_copy_to_regi(a, TAG_Special, deststnr);
+ setsign(dest, signa); /* signa may differ from the sign of a. */
+ return taga;
+ }
+ /* Infinity-Infinity is undefined. */
+ return arith_invalid(deststnr);
+ } else if (tagb == TW_Infinity) {
+ FPU_copy_to_regi(b, TAG_Special, deststnr);
+ setsign(dest, signb); /* signb may differ from the sign of b. */
+ return tagb;
}
- /* Infinity-Infinity is undefined. */
- return arith_invalid(deststnr);
- }
- else if (tagb == TW_Infinity)
- {
- FPU_copy_to_regi(b, TAG_Special, deststnr);
- setsign(dest, signb); /* signb may differ from the sign of b. */
- return tagb;
- }
-
#ifdef PARANOID
- EXCEPTION(EX_INTERNAL|0x101);
+ EXCEPTION(EX_INTERNAL | 0x101);
#endif
- return FPU_Exception;
+ return FPU_Exception;
}
-
diff --git a/arch/x86/math-emu/reg_compare.c b/arch/x86/math-emu/reg_compare.c
index f37c5b5a35ad..ecce55fc2e2e 100644
--- a/arch/x86/math-emu/reg_compare.c
+++ b/arch/x86/math-emu/reg_compare.c
@@ -20,362 +20,331 @@
#include "control_w.h"
#include "status_w.h"
-
static int compare(FPU_REG const *b, int tagb)
{
- int diff, exp0, expb;
- u_char st0_tag;
- FPU_REG *st0_ptr;
- FPU_REG x, y;
- u_char st0_sign, signb = getsign(b);
-
- st0_ptr = &st(0);
- st0_tag = FPU_gettag0();
- st0_sign = getsign(st0_ptr);
-
- if ( tagb == TAG_Special )
- tagb = FPU_Special(b);
- if ( st0_tag == TAG_Special )
- st0_tag = FPU_Special(st0_ptr);
-
- if ( ((st0_tag != TAG_Valid) && (st0_tag != TW_Denormal))
- || ((tagb != TAG_Valid) && (tagb != TW_Denormal)) )
- {
- if ( st0_tag == TAG_Zero )
- {
- if ( tagb == TAG_Zero ) return COMP_A_eq_B;
- if ( tagb == TAG_Valid )
- return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B);
- if ( tagb == TW_Denormal )
- return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
- | COMP_Denormal;
- }
- else if ( tagb == TAG_Zero )
- {
- if ( st0_tag == TAG_Valid )
- return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
- if ( st0_tag == TW_Denormal )
- return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
- | COMP_Denormal;
+ int diff, exp0, expb;
+ u_char st0_tag;
+ FPU_REG *st0_ptr;
+ FPU_REG x, y;
+ u_char st0_sign, signb = getsign(b);
+
+ st0_ptr = &st(0);
+ st0_tag = FPU_gettag0();
+ st0_sign = getsign(st0_ptr);
+
+ if (tagb == TAG_Special)
+ tagb = FPU_Special(b);
+ if (st0_tag == TAG_Special)
+ st0_tag = FPU_Special(st0_ptr);
+
+ if (((st0_tag != TAG_Valid) && (st0_tag != TW_Denormal))
+ || ((tagb != TAG_Valid) && (tagb != TW_Denormal))) {
+ if (st0_tag == TAG_Zero) {
+ if (tagb == TAG_Zero)
+ return COMP_A_eq_B;
+ if (tagb == TAG_Valid)
+ return ((signb ==
+ SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B);
+ if (tagb == TW_Denormal)
+ return ((signb ==
+ SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
+ | COMP_Denormal;
+ } else if (tagb == TAG_Zero) {
+ if (st0_tag == TAG_Valid)
+ return ((st0_sign ==
+ SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
+ if (st0_tag == TW_Denormal)
+ return ((st0_sign ==
+ SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
+ | COMP_Denormal;
+ }
+
+ if (st0_tag == TW_Infinity) {
+ if ((tagb == TAG_Valid) || (tagb == TAG_Zero))
+ return ((st0_sign ==
+ SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
+ else if (tagb == TW_Denormal)
+ return ((st0_sign ==
+ SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
+ | COMP_Denormal;
+ else if (tagb == TW_Infinity) {
+ /* The 80486 book says that infinities can be equal! */
+ return (st0_sign == signb) ? COMP_A_eq_B :
+ ((st0_sign ==
+ SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
+ }
+ /* Fall through to the NaN code */
+ } else if (tagb == TW_Infinity) {
+ if ((st0_tag == TAG_Valid) || (st0_tag == TAG_Zero))
+ return ((signb ==
+ SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B);
+ if (st0_tag == TW_Denormal)
+ return ((signb ==
+ SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
+ | COMP_Denormal;
+ /* Fall through to the NaN code */
+ }
+
+ /* The only possibility now should be that one of the arguments
+ is a NaN */
+ if ((st0_tag == TW_NaN) || (tagb == TW_NaN)) {
+ int signalling = 0, unsupported = 0;
+ if (st0_tag == TW_NaN) {
+ signalling =
+ (st0_ptr->sigh & 0xc0000000) == 0x80000000;
+ unsupported = !((exponent(st0_ptr) == EXP_OVER)
+ && (st0_ptr->
+ sigh & 0x80000000));
+ }
+ if (tagb == TW_NaN) {
+ signalling |=
+ (b->sigh & 0xc0000000) == 0x80000000;
+ unsupported |= !((exponent(b) == EXP_OVER)
+ && (b->sigh & 0x80000000));
+ }
+ if (signalling || unsupported)
+ return COMP_No_Comp | COMP_SNaN | COMP_NaN;
+ else
+ /* Neither is a signaling NaN */
+ return COMP_No_Comp | COMP_NaN;
+ }
+
+ EXCEPTION(EX_Invalid);
}
- if ( st0_tag == TW_Infinity )
- {
- if ( (tagb == TAG_Valid) || (tagb == TAG_Zero) )
- return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
- else if ( tagb == TW_Denormal )
- return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
- | COMP_Denormal;
- else if ( tagb == TW_Infinity )
- {
- /* The 80486 book says that infinities can be equal! */
- return (st0_sign == signb) ? COMP_A_eq_B :
- ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
- }
- /* Fall through to the NaN code */
- }
- else if ( tagb == TW_Infinity )
- {
- if ( (st0_tag == TAG_Valid) || (st0_tag == TAG_Zero) )
- return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B);
- if ( st0_tag == TW_Denormal )
- return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
- | COMP_Denormal;
- /* Fall through to the NaN code */
+ if (st0_sign != signb) {
+ return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
+ | (((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
+ COMP_Denormal : 0);
}
- /* The only possibility now should be that one of the arguments
- is a NaN */
- if ( (st0_tag == TW_NaN) || (tagb == TW_NaN) )
- {
- int signalling = 0, unsupported = 0;
- if ( st0_tag == TW_NaN )
- {
- signalling = (st0_ptr->sigh & 0xc0000000) == 0x80000000;
- unsupported = !((exponent(st0_ptr) == EXP_OVER)
- && (st0_ptr->sigh & 0x80000000));
- }
- if ( tagb == TW_NaN )
- {
- signalling |= (b->sigh & 0xc0000000) == 0x80000000;
- unsupported |= !((exponent(b) == EXP_OVER)
- && (b->sigh & 0x80000000));
- }
- if ( signalling || unsupported )
- return COMP_No_Comp | COMP_SNaN | COMP_NaN;
- else
- /* Neither is a signaling NaN */
- return COMP_No_Comp | COMP_NaN;
+ if ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) {
+ FPU_to_exp16(st0_ptr, &x);
+ FPU_to_exp16(b, &y);
+ st0_ptr = &x;
+ b = &y;
+ exp0 = exponent16(st0_ptr);
+ expb = exponent16(b);
+ } else {
+ exp0 = exponent(st0_ptr);
+ expb = exponent(b);
}
-
- EXCEPTION(EX_Invalid);
- }
-
- if (st0_sign != signb)
- {
- return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
- | ( ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
- COMP_Denormal : 0);
- }
-
- if ( (st0_tag == TW_Denormal) || (tagb == TW_Denormal) )
- {
- FPU_to_exp16(st0_ptr, &x);
- FPU_to_exp16(b, &y);
- st0_ptr = &x;
- b = &y;
- exp0 = exponent16(st0_ptr);
- expb = exponent16(b);
- }
- else
- {
- exp0 = exponent(st0_ptr);
- expb = exponent(b);
- }
#ifdef PARANOID
- if (!(st0_ptr->sigh & 0x80000000)) EXCEPTION(EX_Invalid);
- if (!(b->sigh & 0x80000000)) EXCEPTION(EX_Invalid);
+ if (!(st0_ptr->sigh & 0x80000000))
+ EXCEPTION(EX_Invalid);
+ if (!(b->sigh & 0x80000000))
+ EXCEPTION(EX_Invalid);
#endif /* PARANOID */
- diff = exp0 - expb;
- if ( diff == 0 )
- {
- diff = st0_ptr->sigh - b->sigh; /* Works only if ms bits are
- identical */
- if ( diff == 0 )
- {
- diff = st0_ptr->sigl > b->sigl;
- if ( diff == 0 )
- diff = -(st0_ptr->sigl < b->sigl);
+ diff = exp0 - expb;
+ if (diff == 0) {
+ diff = st0_ptr->sigh - b->sigh; /* Works only if ms bits are
+ identical */
+ if (diff == 0) {
+ diff = st0_ptr->sigl > b->sigl;
+ if (diff == 0)
+ diff = -(st0_ptr->sigl < b->sigl);
+ }
}
- }
-
- if ( diff > 0 )
- {
- return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
- | ( ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
- COMP_Denormal : 0);
- }
- if ( diff < 0 )
- {
- return ((st0_sign == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
- | ( ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
- COMP_Denormal : 0);
- }
-
- return COMP_A_eq_B
- | ( ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
- COMP_Denormal : 0);
-}
+ if (diff > 0) {
+ return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
+ | (((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
+ COMP_Denormal : 0);
+ }
+ if (diff < 0) {
+ return ((st0_sign == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
+ | (((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
+ COMP_Denormal : 0);
+ }
+ return COMP_A_eq_B
+ | (((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
+ COMP_Denormal : 0);
+
+}
/* This function requires that st(0) is not empty */
int FPU_compare_st_data(FPU_REG const *loaded_data, u_char loaded_tag)
{
- int f = 0, c;
-
- c = compare(loaded_data, loaded_tag);
-
- if (c & COMP_NaN)
- {
- EXCEPTION(EX_Invalid);
- f = SW_C3 | SW_C2 | SW_C0;
- }
- else
- switch (c & 7)
- {
- case COMP_A_lt_B:
- f = SW_C0;
- break;
- case COMP_A_eq_B:
- f = SW_C3;
- break;
- case COMP_A_gt_B:
- f = 0;
- break;
- case COMP_No_Comp:
- f = SW_C3 | SW_C2 | SW_C0;
- break;
+ int f = 0, c;
+
+ c = compare(loaded_data, loaded_tag);
+
+ if (c & COMP_NaN) {
+ EXCEPTION(EX_Invalid);
+ f = SW_C3 | SW_C2 | SW_C0;
+ } else
+ switch (c & 7) {
+ case COMP_A_lt_B:
+ f = SW_C0;
+ break;
+ case COMP_A_eq_B:
+ f = SW_C3;
+ break;
+ case COMP_A_gt_B:
+ f = 0;
+ break;
+ case COMP_No_Comp:
+ f = SW_C3 | SW_C2 | SW_C0;
+ break;
#ifdef PARANOID
- default:
- EXCEPTION(EX_INTERNAL|0x121);
- f = SW_C3 | SW_C2 | SW_C0;
- break;
+ default:
+ EXCEPTION(EX_INTERNAL | 0x121);
+ f = SW_C3 | SW_C2 | SW_C0;
+ break;
#endif /* PARANOID */
- }
- setcc(f);
- if (c & COMP_Denormal)
- {
- return denormal_operand() < 0;
- }
- return 0;
+ }
+ setcc(f);
+ if (c & COMP_Denormal) {
+ return denormal_operand() < 0;
+ }
+ return 0;
}
-
static int compare_st_st(int nr)
{
- int f = 0, c;
- FPU_REG *st_ptr;
-
- if ( !NOT_EMPTY(0) || !NOT_EMPTY(nr) )
- {
- setcc(SW_C3 | SW_C2 | SW_C0);
- /* Stack fault */
- EXCEPTION(EX_StackUnder);
- return !(control_word & CW_Invalid);
- }
-
- st_ptr = &st(nr);
- c = compare(st_ptr, FPU_gettagi(nr));
- if (c & COMP_NaN)
- {
- setcc(SW_C3 | SW_C2 | SW_C0);
- EXCEPTION(EX_Invalid);
- return !(control_word & CW_Invalid);
- }
- else
- switch (c & 7)
- {
- case COMP_A_lt_B:
- f = SW_C0;
- break;
- case COMP_A_eq_B:
- f = SW_C3;
- break;
- case COMP_A_gt_B:
- f = 0;
- break;
- case COMP_No_Comp:
- f = SW_C3 | SW_C2 | SW_C0;
- break;
+ int f = 0, c;
+ FPU_REG *st_ptr;
+
+ if (!NOT_EMPTY(0) || !NOT_EMPTY(nr)) {
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ /* Stack fault */
+ EXCEPTION(EX_StackUnder);
+ return !(control_word & CW_Invalid);
+ }
+
+ st_ptr = &st(nr);
+ c = compare(st_ptr, FPU_gettagi(nr));
+ if (c & COMP_NaN) {
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ EXCEPTION(EX_Invalid);
+ return !(control_word & CW_Invalid);
+ } else
+ switch (c & 7) {
+ case COMP_A_lt_B:
+ f = SW_C0;
+ break;
+ case COMP_A_eq_B:
+ f = SW_C3;
+ break;
+ case COMP_A_gt_B:
+ f = 0;
+ break;
+ case COMP_No_Comp:
+ f = SW_C3 | SW_C2 | SW_C0;
+ break;
#ifdef PARANOID
- default:
- EXCEPTION(EX_INTERNAL|0x122);
- f = SW_C3 | SW_C2 | SW_C0;
- break;
+ default:
+ EXCEPTION(EX_INTERNAL | 0x122);
+ f = SW_C3 | SW_C2 | SW_C0;
+ break;
#endif /* PARANOID */
- }
- setcc(f);
- if (c & COMP_Denormal)
- {
- return denormal_operand() < 0;
- }
- return 0;
+ }
+ setcc(f);
+ if (c & COMP_Denormal) {
+ return denormal_operand() < 0;
+ }
+ return 0;
}
-
static int compare_u_st_st(int nr)
{
- int f = 0, c;
- FPU_REG *st_ptr;
-
- if ( !NOT_EMPTY(0) || !NOT_EMPTY(nr) )
- {
- setcc(SW_C3 | SW_C2 | SW_C0);
- /* Stack fault */
- EXCEPTION(EX_StackUnder);
- return !(control_word & CW_Invalid);
- }
-
- st_ptr = &st(nr);
- c = compare(st_ptr, FPU_gettagi(nr));
- if (c & COMP_NaN)
- {
- setcc(SW_C3 | SW_C2 | SW_C0);
- if (c & COMP_SNaN) /* This is the only difference between
- un-ordered and ordinary comparisons */
- {
- EXCEPTION(EX_Invalid);
- return !(control_word & CW_Invalid);
+ int f = 0, c;
+ FPU_REG *st_ptr;
+
+ if (!NOT_EMPTY(0) || !NOT_EMPTY(nr)) {
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ /* Stack fault */
+ EXCEPTION(EX_StackUnder);
+ return !(control_word & CW_Invalid);
}
- return 0;
- }
- else
- switch (c & 7)
- {
- case COMP_A_lt_B:
- f = SW_C0;
- break;
- case COMP_A_eq_B:
- f = SW_C3;
- break;
- case COMP_A_gt_B:
- f = 0;
- break;
- case COMP_No_Comp:
- f = SW_C3 | SW_C2 | SW_C0;
- break;
+
+ st_ptr = &st(nr);
+ c = compare(st_ptr, FPU_gettagi(nr));
+ if (c & COMP_NaN) {
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ if (c & COMP_SNaN) { /* This is the only difference between
+ un-ordered and ordinary comparisons */
+ EXCEPTION(EX_Invalid);
+ return !(control_word & CW_Invalid);
+ }
+ return 0;
+ } else
+ switch (c & 7) {
+ case COMP_A_lt_B:
+ f = SW_C0;
+ break;
+ case COMP_A_eq_B:
+ f = SW_C3;
+ break;
+ case COMP_A_gt_B:
+ f = 0;
+ break;
+ case COMP_No_Comp:
+ f = SW_C3 | SW_C2 | SW_C0;
+ break;
#ifdef PARANOID
- default:
- EXCEPTION(EX_INTERNAL|0x123);
- f = SW_C3 | SW_C2 | SW_C0;
- break;
-#endif /* PARANOID */
- }
- setcc(f);
- if (c & COMP_Denormal)
- {
- return denormal_operand() < 0;
- }
- return 0;
+ default:
+ EXCEPTION(EX_INTERNAL | 0x123);
+ f = SW_C3 | SW_C2 | SW_C0;
+ break;
+#endif /* PARANOID */
+ }
+ setcc(f);
+ if (c & COMP_Denormal) {
+ return denormal_operand() < 0;
+ }
+ return 0;
}
/*---------------------------------------------------------------------------*/
void fcom_st(void)
{
- /* fcom st(i) */
- compare_st_st(FPU_rm);
+ /* fcom st(i) */
+ compare_st_st(FPU_rm);
}
-
void fcompst(void)
{
- /* fcomp st(i) */
- if ( !compare_st_st(FPU_rm) )
- FPU_pop();
+ /* fcomp st(i) */
+ if (!compare_st_st(FPU_rm))
+ FPU_pop();
}
-
void fcompp(void)
{
- /* fcompp */
- if (FPU_rm != 1)
- {
- FPU_illegal();
- return;
- }
- if ( !compare_st_st(1) )
- poppop();
+ /* fcompp */
+ if (FPU_rm != 1) {
+ FPU_illegal();
+ return;
+ }
+ if (!compare_st_st(1))
+ poppop();
}
-
void fucom_(void)
{
- /* fucom st(i) */
- compare_u_st_st(FPU_rm);
+ /* fucom st(i) */
+ compare_u_st_st(FPU_rm);
}
-
void fucomp(void)
{
- /* fucomp st(i) */
- if ( !compare_u_st_st(FPU_rm) )
- FPU_pop();
+ /* fucomp st(i) */
+ if (!compare_u_st_st(FPU_rm))
+ FPU_pop();
}
-
void fucompp(void)
{
- /* fucompp */
- if (FPU_rm == 1)
- {
- if ( !compare_u_st_st(1) )
- poppop();
- }
- else
- FPU_illegal();
+ /* fucompp */
+ if (FPU_rm == 1) {
+ if (!compare_u_st_st(1))
+ poppop();
+ } else
+ FPU_illegal();
}
diff --git a/arch/x86/math-emu/reg_constant.c b/arch/x86/math-emu/reg_constant.c
index a85015801969..04869e64b18e 100644
--- a/arch/x86/math-emu/reg_constant.c
+++ b/arch/x86/math-emu/reg_constant.c
@@ -16,29 +16,28 @@
#include "reg_constant.h"
#include "control_w.h"
-
#define MAKE_REG(s,e,l,h) { l, h, \
((EXTENDED_Ebias+(e)) | ((SIGN_##s != 0)*0x8000)) }
-FPU_REG const CONST_1 = MAKE_REG(POS, 0, 0x00000000, 0x80000000);
+FPU_REG const CONST_1 = MAKE_REG(POS, 0, 0x00000000, 0x80000000);
#if 0
-FPU_REG const CONST_2 = MAKE_REG(POS, 1, 0x00000000, 0x80000000);
+FPU_REG const CONST_2 = MAKE_REG(POS, 1, 0x00000000, 0x80000000);
FPU_REG const CONST_HALF = MAKE_REG(POS, -1, 0x00000000, 0x80000000);
-#endif /* 0 */
-static FPU_REG const CONST_L2T = MAKE_REG(POS, 1, 0xcd1b8afe, 0xd49a784b);
-static FPU_REG const CONST_L2E = MAKE_REG(POS, 0, 0x5c17f0bc, 0xb8aa3b29);
-FPU_REG const CONST_PI = MAKE_REG(POS, 1, 0x2168c235, 0xc90fdaa2);
-FPU_REG const CONST_PI2 = MAKE_REG(POS, 0, 0x2168c235, 0xc90fdaa2);
-FPU_REG const CONST_PI4 = MAKE_REG(POS, -1, 0x2168c235, 0xc90fdaa2);
-static FPU_REG const CONST_LG2 = MAKE_REG(POS, -2, 0xfbcff799, 0x9a209a84);
-static FPU_REG const CONST_LN2 = MAKE_REG(POS, -1, 0xd1cf79ac, 0xb17217f7);
+#endif /* 0 */
+static FPU_REG const CONST_L2T = MAKE_REG(POS, 1, 0xcd1b8afe, 0xd49a784b);
+static FPU_REG const CONST_L2E = MAKE_REG(POS, 0, 0x5c17f0bc, 0xb8aa3b29);
+FPU_REG const CONST_PI = MAKE_REG(POS, 1, 0x2168c235, 0xc90fdaa2);
+FPU_REG const CONST_PI2 = MAKE_REG(POS, 0, 0x2168c235, 0xc90fdaa2);
+FPU_REG const CONST_PI4 = MAKE_REG(POS, -1, 0x2168c235, 0xc90fdaa2);
+static FPU_REG const CONST_LG2 = MAKE_REG(POS, -2, 0xfbcff799, 0x9a209a84);
+static FPU_REG const CONST_LN2 = MAKE_REG(POS, -1, 0xd1cf79ac, 0xb17217f7);
/* Extra bits to take pi/2 to more than 128 bits precision. */
FPU_REG const CONST_PI2extra = MAKE_REG(NEG, -66,
- 0xfc8f8cbb, 0xece675d1);
+ 0xfc8f8cbb, 0xece675d1);
/* Only the sign (and tag) is used in internal zeroes */
-FPU_REG const CONST_Z = MAKE_REG(POS, EXP_UNDER, 0x0, 0x0);
+FPU_REG const CONST_Z = MAKE_REG(POS, EXP_UNDER, 0x0, 0x0);
/* Only the sign and significand (and tag) are used in internal NaNs */
/* The 80486 never generates one of these
@@ -48,24 +47,22 @@ FPU_REG const CONST_SNAN = MAKE_REG(POS, EXP_OVER, 0x00000001, 0x80000000);
FPU_REG const CONST_QNaN = MAKE_REG(NEG, EXP_OVER, 0x00000000, 0xC0000000);
/* Only the sign (and tag) is used in internal infinities */
-FPU_REG const CONST_INF = MAKE_REG(POS, EXP_OVER, 0x00000000, 0x80000000);
-
+FPU_REG const CONST_INF = MAKE_REG(POS, EXP_OVER, 0x00000000, 0x80000000);
static void fld_const(FPU_REG const *c, int adj, u_char tag)
{
- FPU_REG *st_new_ptr;
-
- if ( STACK_OVERFLOW )
- {
- FPU_stack_overflow();
- return;
- }
- push();
- reg_copy(c, st_new_ptr);
- st_new_ptr->sigl += adj; /* For all our fldxxx constants, we don't need to
- borrow or carry. */
- FPU_settag0(tag);
- clear_C1();
+ FPU_REG *st_new_ptr;
+
+ if (STACK_OVERFLOW) {
+ FPU_stack_overflow();
+ return;
+ }
+ push();
+ reg_copy(c, st_new_ptr);
+ st_new_ptr->sigl += adj; /* For all our fldxxx constants, we don't need to
+ borrow or carry. */
+ FPU_settag0(tag);
+ clear_C1();
}
/* A fast way to find out whether x is one of RC_DOWN or RC_CHOP
@@ -75,46 +72,46 @@ static void fld_const(FPU_REG const *c, int adj, u_char tag)
static void fld1(int rc)
{
- fld_const(&CONST_1, 0, TAG_Valid);
+ fld_const(&CONST_1, 0, TAG_Valid);
}
static void fldl2t(int rc)
{
- fld_const(&CONST_L2T, (rc == RC_UP) ? 1 : 0, TAG_Valid);
+ fld_const(&CONST_L2T, (rc == RC_UP) ? 1 : 0, TAG_Valid);
}
static void fldl2e(int rc)
{
- fld_const(&CONST_L2E, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
+ fld_const(&CONST_L2E, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
}
static void fldpi(int rc)
{
- fld_const(&CONST_PI, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
+ fld_const(&CONST_PI, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
}
static void fldlg2(int rc)
{
- fld_const(&CONST_LG2, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
+ fld_const(&CONST_LG2, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
}
static void fldln2(int rc)
{
- fld_const(&CONST_LN2, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
+ fld_const(&CONST_LN2, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
}
static void fldz(int rc)
{
- fld_const(&CONST_Z, 0, TAG_Zero);
+ fld_const(&CONST_Z, 0, TAG_Zero);
}
-typedef void (*FUNC_RC)(int);
+typedef void (*FUNC_RC) (int);
static FUNC_RC constants_table[] = {
- fld1, fldl2t, fldl2e, fldpi, fldlg2, fldln2, fldz, (FUNC_RC)FPU_illegal
+ fld1, fldl2t, fldl2e, fldpi, fldlg2, fldln2, fldz, (FUNC_RC) FPU_illegal
};
void fconst(void)
{
- (constants_table[FPU_rm])(control_word & CW_RC);
+ (constants_table[FPU_rm]) (control_word & CW_RC);
}
diff --git a/arch/x86/math-emu/reg_convert.c b/arch/x86/math-emu/reg_convert.c
index 45a258752703..afd31b31000d 100644
--- a/arch/x86/math-emu/reg_convert.c
+++ b/arch/x86/math-emu/reg_convert.c
@@ -13,41 +13,34 @@
#include "exception.h"
#include "fpu_emu.h"
-
-int FPU_to_exp16(FPU_REG const *a, FPU_REG *x)
+int FPU_to_exp16(FPU_REG const *a, FPU_REG * x)
{
- int sign = getsign(a);
-
- *(long long *)&(x->sigl) = *(const long long *)&(a->sigl);
-
- /* Set up the exponent as a 16 bit quantity. */
- setexponent16(x, exponent(a));
-
- if ( exponent16(x) == EXP_UNDER )
- {
- /* The number is a de-normal or pseudodenormal. */
- /* We only deal with the significand and exponent. */
-
- if (x->sigh & 0x80000000)
- {
- /* Is a pseudodenormal. */
- /* This is non-80486 behaviour because the number
- loses its 'denormal' identity. */
- addexponent(x, 1);
- }
- else
- {
- /* Is a denormal. */
- addexponent(x, 1);
- FPU_normalize_nuo(x);
+ int sign = getsign(a);
+
+ *(long long *)&(x->sigl) = *(const long long *)&(a->sigl);
+
+ /* Set up the exponent as a 16 bit quantity. */
+ setexponent16(x, exponent(a));
+
+ if (exponent16(x) == EXP_UNDER) {
+ /* The number is a de-normal or pseudodenormal. */
+ /* We only deal with the significand and exponent. */
+
+ if (x->sigh & 0x80000000) {
+ /* Is a pseudodenormal. */
+ /* This is non-80486 behaviour because the number
+ loses its 'denormal' identity. */
+ addexponent(x, 1);
+ } else {
+ /* Is a denormal. */
+ addexponent(x, 1);
+ FPU_normalize_nuo(x);
+ }
}
- }
- if ( !(x->sigh & 0x80000000) )
- {
- EXCEPTION(EX_INTERNAL | 0x180);
- }
+ if (!(x->sigh & 0x80000000)) {
+ EXCEPTION(EX_INTERNAL | 0x180);
+ }
- return sign;
+ return sign;
}
-
diff --git a/arch/x86/math-emu/reg_divide.c b/arch/x86/math-emu/reg_divide.c
index 5cee7ff920d9..6827012db341 100644
--- a/arch/x86/math-emu/reg_divide.c
+++ b/arch/x86/math-emu/reg_divide.c
@@ -26,182 +26,157 @@
*/
int FPU_div(int flags, int rm, int control_w)
{
- FPU_REG x, y;
- FPU_REG const *a, *b, *st0_ptr, *st_ptr;
- FPU_REG *dest;
- u_char taga, tagb, signa, signb, sign, saved_sign;
- int tag, deststnr;
-
- if ( flags & DEST_RM )
- deststnr = rm;
- else
- deststnr = 0;
-
- if ( flags & REV )
- {
- b = &st(0);
- st0_ptr = b;
- tagb = FPU_gettag0();
- if ( flags & LOADED )
- {
- a = (FPU_REG *)rm;
- taga = flags & 0x0f;
+ FPU_REG x, y;
+ FPU_REG const *a, *b, *st0_ptr, *st_ptr;
+ FPU_REG *dest;
+ u_char taga, tagb, signa, signb, sign, saved_sign;
+ int tag, deststnr;
+
+ if (flags & DEST_RM)
+ deststnr = rm;
+ else
+ deststnr = 0;
+
+ if (flags & REV) {
+ b = &st(0);
+ st0_ptr = b;
+ tagb = FPU_gettag0();
+ if (flags & LOADED) {
+ a = (FPU_REG *) rm;
+ taga = flags & 0x0f;
+ } else {
+ a = &st(rm);
+ st_ptr = a;
+ taga = FPU_gettagi(rm);
+ }
+ } else {
+ a = &st(0);
+ st0_ptr = a;
+ taga = FPU_gettag0();
+ if (flags & LOADED) {
+ b = (FPU_REG *) rm;
+ tagb = flags & 0x0f;
+ } else {
+ b = &st(rm);
+ st_ptr = b;
+ tagb = FPU_gettagi(rm);
+ }
}
- else
- {
- a = &st(rm);
- st_ptr = a;
- taga = FPU_gettagi(rm);
- }
- }
- else
- {
- a = &st(0);
- st0_ptr = a;
- taga = FPU_gettag0();
- if ( flags & LOADED )
- {
- b = (FPU_REG *)rm;
- tagb = flags & 0x0f;
- }
- else
- {
- b = &st(rm);
- st_ptr = b;
- tagb = FPU_gettagi(rm);
- }
- }
- signa = getsign(a);
- signb = getsign(b);
+ signa = getsign(a);
+ signb = getsign(b);
- sign = signa ^ signb;
+ sign = signa ^ signb;
- dest = &st(deststnr);
- saved_sign = getsign(dest);
+ dest = &st(deststnr);
+ saved_sign = getsign(dest);
- if ( !(taga | tagb) )
- {
- /* Both regs Valid, this should be the most common case. */
- reg_copy(a, &x);
- reg_copy(b, &y);
- setpositive(&x);
- setpositive(&y);
- tag = FPU_u_div(&x, &y, dest, control_w, sign);
+ if (!(taga | tagb)) {
+ /* Both regs Valid, this should be the most common case. */
+ reg_copy(a, &x);
+ reg_copy(b, &y);
+ setpositive(&x);
+ setpositive(&y);
+ tag = FPU_u_div(&x, &y, dest, control_w, sign);
- if ( tag < 0 )
- return tag;
+ if (tag < 0)
+ return tag;
- FPU_settagi(deststnr, tag);
- return tag;
- }
+ FPU_settagi(deststnr, tag);
+ return tag;
+ }
- if ( taga == TAG_Special )
- taga = FPU_Special(a);
- if ( tagb == TAG_Special )
- tagb = FPU_Special(b);
+ if (taga == TAG_Special)
+ taga = FPU_Special(a);
+ if (tagb == TAG_Special)
+ tagb = FPU_Special(b);
- if ( ((taga == TAG_Valid) && (tagb == TW_Denormal))
+ if (((taga == TAG_Valid) && (tagb == TW_Denormal))
|| ((taga == TW_Denormal) && (tagb == TAG_Valid))
- || ((taga == TW_Denormal) && (tagb == TW_Denormal)) )
- {
- if ( denormal_operand() < 0 )
- return FPU_Exception;
-
- FPU_to_exp16(a, &x);
- FPU_to_exp16(b, &y);
- tag = FPU_u_div(&x, &y, dest, control_w, sign);
- if ( tag < 0 )
- return tag;
-
- FPU_settagi(deststnr, tag);
- return tag;
- }
- else if ( (taga <= TW_Denormal) && (tagb <= TW_Denormal) )
- {
- if ( tagb != TAG_Zero )
- {
- /* Want to find Zero/Valid */
- if ( tagb == TW_Denormal )
- {
- if ( denormal_operand() < 0 )
- return FPU_Exception;
- }
-
- /* The result is zero. */
- FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
- setsign(dest, sign);
- return TAG_Zero;
+ || ((taga == TW_Denormal) && (tagb == TW_Denormal))) {
+ if (denormal_operand() < 0)
+ return FPU_Exception;
+
+ FPU_to_exp16(a, &x);
+ FPU_to_exp16(b, &y);
+ tag = FPU_u_div(&x, &y, dest, control_w, sign);
+ if (tag < 0)
+ return tag;
+
+ FPU_settagi(deststnr, tag);
+ return tag;
+ } else if ((taga <= TW_Denormal) && (tagb <= TW_Denormal)) {
+ if (tagb != TAG_Zero) {
+ /* Want to find Zero/Valid */
+ if (tagb == TW_Denormal) {
+ if (denormal_operand() < 0)
+ return FPU_Exception;
+ }
+
+ /* The result is zero. */
+ FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+ setsign(dest, sign);
+ return TAG_Zero;
+ }
+ /* We have an exception condition, either 0/0 or Valid/Zero. */
+ if (taga == TAG_Zero) {
+ /* 0/0 */
+ return arith_invalid(deststnr);
+ }
+ /* Valid/Zero */
+ return FPU_divide_by_zero(deststnr, sign);
}
- /* We have an exception condition, either 0/0 or Valid/Zero. */
- if ( taga == TAG_Zero )
- {
- /* 0/0 */
- return arith_invalid(deststnr);
+ /* Must have infinities, NaNs, etc */
+ else if ((taga == TW_NaN) || (tagb == TW_NaN)) {
+ if (flags & LOADED)
+ return real_2op_NaN((FPU_REG *) rm, flags & 0x0f, 0,
+ st0_ptr);
+
+ if (flags & DEST_RM) {
+ int tag;
+ tag = FPU_gettag0();
+ if (tag == TAG_Special)
+ tag = FPU_Special(st0_ptr);
+ return real_2op_NaN(st0_ptr, tag, rm,
+ (flags & REV) ? st0_ptr : &st(rm));
+ } else {
+ int tag;
+ tag = FPU_gettagi(rm);
+ if (tag == TAG_Special)
+ tag = FPU_Special(&st(rm));
+ return real_2op_NaN(&st(rm), tag, 0,
+ (flags & REV) ? st0_ptr : &st(rm));
+ }
+ } else if (taga == TW_Infinity) {
+ if (tagb == TW_Infinity) {
+ /* infinity/infinity */
+ return arith_invalid(deststnr);
+ } else {
+ /* tagb must be Valid or Zero */
+ if ((tagb == TW_Denormal) && (denormal_operand() < 0))
+ return FPU_Exception;
+
+ /* Infinity divided by Zero or Valid does
+ not raise and exception, but returns Infinity */
+ FPU_copy_to_regi(a, TAG_Special, deststnr);
+ setsign(dest, sign);
+ return taga;
+ }
+ } else if (tagb == TW_Infinity) {
+ if ((taga == TW_Denormal) && (denormal_operand() < 0))
+ return FPU_Exception;
+
+ /* The result is zero. */
+ FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+ setsign(dest, sign);
+ return TAG_Zero;
}
- /* Valid/Zero */
- return FPU_divide_by_zero(deststnr, sign);
- }
- /* Must have infinities, NaNs, etc */
- else if ( (taga == TW_NaN) || (tagb == TW_NaN) )
- {
- if ( flags & LOADED )
- return real_2op_NaN((FPU_REG *)rm, flags & 0x0f, 0, st0_ptr);
-
- if ( flags & DEST_RM )
- {
- int tag;
- tag = FPU_gettag0();
- if ( tag == TAG_Special )
- tag = FPU_Special(st0_ptr);
- return real_2op_NaN(st0_ptr, tag, rm, (flags & REV) ? st0_ptr : &st(rm));
- }
- else
- {
- int tag;
- tag = FPU_gettagi(rm);
- if ( tag == TAG_Special )
- tag = FPU_Special(&st(rm));
- return real_2op_NaN(&st(rm), tag, 0, (flags & REV) ? st0_ptr : &st(rm));
- }
- }
- else if (taga == TW_Infinity)
- {
- if (tagb == TW_Infinity)
- {
- /* infinity/infinity */
- return arith_invalid(deststnr);
- }
- else
- {
- /* tagb must be Valid or Zero */
- if ( (tagb == TW_Denormal) && (denormal_operand() < 0) )
- return FPU_Exception;
-
- /* Infinity divided by Zero or Valid does
- not raise and exception, but returns Infinity */
- FPU_copy_to_regi(a, TAG_Special, deststnr);
- setsign(dest, sign);
- return taga;
- }
- }
- else if (tagb == TW_Infinity)
- {
- if ( (taga == TW_Denormal) && (denormal_operand() < 0) )
- return FPU_Exception;
-
- /* The result is zero. */
- FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
- setsign(dest, sign);
- return TAG_Zero;
- }
#ifdef PARANOID
- else
- {
- EXCEPTION(EX_INTERNAL|0x102);
- return FPU_Exception;
- }
-#endif /* PARANOID */
+ else {
+ EXCEPTION(EX_INTERNAL | 0x102);
+ return FPU_Exception;
+ }
+#endif /* PARANOID */
return 0;
}
diff --git a/arch/x86/math-emu/reg_ld_str.c b/arch/x86/math-emu/reg_ld_str.c
index e976caef6498..0b2ca8dc2988 100644
--- a/arch/x86/math-emu/reg_ld_str.c
+++ b/arch/x86/math-emu/reg_ld_str.c
@@ -27,1084 +27,938 @@
#include "control_w.h"
#include "status_w.h"
-
-#define DOUBLE_Emax 1023 /* largest valid exponent */
+#define DOUBLE_Emax 1023 /* largest valid exponent */
#define DOUBLE_Ebias 1023
-#define DOUBLE_Emin (-1022) /* smallest valid exponent */
+#define DOUBLE_Emin (-1022) /* smallest valid exponent */
-#define SINGLE_Emax 127 /* largest valid exponent */
+#define SINGLE_Emax 127 /* largest valid exponent */
#define SINGLE_Ebias 127
-#define SINGLE_Emin (-126) /* smallest valid exponent */
-
+#define SINGLE_Emin (-126) /* smallest valid exponent */
-static u_char normalize_no_excep(FPU_REG *r, int exp, int sign)
+static u_char normalize_no_excep(FPU_REG * r, int exp, int sign)
{
- u_char tag;
+ u_char tag;
- setexponent16(r, exp);
+ setexponent16(r, exp);
- tag = FPU_normalize_nuo(r);
- stdexp(r);
- if ( sign )
- setnegative(r);
+ tag = FPU_normalize_nuo(r);
+ stdexp(r);
+ if (sign)
+ setnegative(r);
- return tag;
+ return tag;
}
-
-int FPU_tagof(FPU_REG *ptr)
+int FPU_tagof(FPU_REG * ptr)
{
- int exp;
-
- exp = exponent16(ptr) & 0x7fff;
- if ( exp == 0 )
- {
- if ( !(ptr->sigh | ptr->sigl) )
- {
- return TAG_Zero;
+ int exp;
+
+ exp = exponent16(ptr) & 0x7fff;
+ if (exp == 0) {
+ if (!(ptr->sigh | ptr->sigl)) {
+ return TAG_Zero;
+ }
+ /* The number is a de-normal or pseudodenormal. */
+ return TAG_Special;
+ }
+
+ if (exp == 0x7fff) {
+ /* Is an Infinity, a NaN, or an unsupported data type. */
+ return TAG_Special;
}
- /* The number is a de-normal or pseudodenormal. */
- return TAG_Special;
- }
-
- if ( exp == 0x7fff )
- {
- /* Is an Infinity, a NaN, or an unsupported data type. */
- return TAG_Special;
- }
-
- if ( !(ptr->sigh & 0x80000000) )
- {
- /* Unsupported data type. */
- /* Valid numbers have the ms bit set to 1. */
- /* Unnormal. */
- return TAG_Special;
- }
-
- return TAG_Valid;
-}
+ if (!(ptr->sigh & 0x80000000)) {
+ /* Unsupported data type. */
+ /* Valid numbers have the ms bit set to 1. */
+ /* Unnormal. */
+ return TAG_Special;
+ }
+
+ return TAG_Valid;
+}
/* Get a long double from user memory */
-int FPU_load_extended(long double __user *s, int stnr)
+int FPU_load_extended(long double __user * s, int stnr)
{
- FPU_REG *sti_ptr = &st(stnr);
+ FPU_REG *sti_ptr = &st(stnr);
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_READ, s, 10);
- __copy_from_user(sti_ptr, s, 10);
- RE_ENTRANT_CHECK_ON;
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_READ, s, 10);
+ __copy_from_user(sti_ptr, s, 10);
+ RE_ENTRANT_CHECK_ON;
- return FPU_tagof(sti_ptr);
+ return FPU_tagof(sti_ptr);
}
-
/* Get a double from user memory */
-int FPU_load_double(double __user *dfloat, FPU_REG *loaded_data)
+int FPU_load_double(double __user * dfloat, FPU_REG * loaded_data)
{
- int exp, tag, negative;
- unsigned m64, l64;
-
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_READ, dfloat, 8);
- FPU_get_user(m64, 1 + (unsigned long __user *) dfloat);
- FPU_get_user(l64, (unsigned long __user *) dfloat);
- RE_ENTRANT_CHECK_ON;
-
- negative = (m64 & 0x80000000) ? SIGN_Negative : SIGN_Positive;
- exp = ((m64 & 0x7ff00000) >> 20) - DOUBLE_Ebias + EXTENDED_Ebias;
- m64 &= 0xfffff;
- if ( exp > DOUBLE_Emax + EXTENDED_Ebias )
- {
- /* Infinity or NaN */
- if ((m64 == 0) && (l64 == 0))
- {
- /* +- infinity */
- loaded_data->sigh = 0x80000000;
- loaded_data->sigl = 0x00000000;
- exp = EXP_Infinity + EXTENDED_Ebias;
- tag = TAG_Special;
- }
- else
- {
- /* Must be a signaling or quiet NaN */
- exp = EXP_NaN + EXTENDED_Ebias;
- loaded_data->sigh = (m64 << 11) | 0x80000000;
- loaded_data->sigh |= l64 >> 21;
- loaded_data->sigl = l64 << 11;
- tag = TAG_Special; /* The calling function must look for NaNs */
- }
- }
- else if ( exp < DOUBLE_Emin + EXTENDED_Ebias )
- {
- /* Zero or de-normal */
- if ((m64 == 0) && (l64 == 0))
- {
- /* Zero */
- reg_copy(&CONST_Z, loaded_data);
- exp = 0;
- tag = TAG_Zero;
- }
- else
- {
- /* De-normal */
- loaded_data->sigh = m64 << 11;
- loaded_data->sigh |= l64 >> 21;
- loaded_data->sigl = l64 << 11;
-
- return normalize_no_excep(loaded_data, DOUBLE_Emin, negative)
- | (denormal_operand() < 0 ? FPU_Exception : 0);
- }
- }
- else
- {
- loaded_data->sigh = (m64 << 11) | 0x80000000;
- loaded_data->sigh |= l64 >> 21;
- loaded_data->sigl = l64 << 11;
+ int exp, tag, negative;
+ unsigned m64, l64;
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_READ, dfloat, 8);
+ FPU_get_user(m64, 1 + (unsigned long __user *)dfloat);
+ FPU_get_user(l64, (unsigned long __user *)dfloat);
+ RE_ENTRANT_CHECK_ON;
+
+ negative = (m64 & 0x80000000) ? SIGN_Negative : SIGN_Positive;
+ exp = ((m64 & 0x7ff00000) >> 20) - DOUBLE_Ebias + EXTENDED_Ebias;
+ m64 &= 0xfffff;
+ if (exp > DOUBLE_Emax + EXTENDED_Ebias) {
+ /* Infinity or NaN */
+ if ((m64 == 0) && (l64 == 0)) {
+ /* +- infinity */
+ loaded_data->sigh = 0x80000000;
+ loaded_data->sigl = 0x00000000;
+ exp = EXP_Infinity + EXTENDED_Ebias;
+ tag = TAG_Special;
+ } else {
+ /* Must be a signaling or quiet NaN */
+ exp = EXP_NaN + EXTENDED_Ebias;
+ loaded_data->sigh = (m64 << 11) | 0x80000000;
+ loaded_data->sigh |= l64 >> 21;
+ loaded_data->sigl = l64 << 11;
+ tag = TAG_Special; /* The calling function must look for NaNs */
+ }
+ } else if (exp < DOUBLE_Emin + EXTENDED_Ebias) {
+ /* Zero or de-normal */
+ if ((m64 == 0) && (l64 == 0)) {
+ /* Zero */
+ reg_copy(&CONST_Z, loaded_data);
+ exp = 0;
+ tag = TAG_Zero;
+ } else {
+ /* De-normal */
+ loaded_data->sigh = m64 << 11;
+ loaded_data->sigh |= l64 >> 21;
+ loaded_data->sigl = l64 << 11;
+
+ return normalize_no_excep(loaded_data, DOUBLE_Emin,
+ negative)
+ | (denormal_operand() < 0 ? FPU_Exception : 0);
+ }
+ } else {
+ loaded_data->sigh = (m64 << 11) | 0x80000000;
+ loaded_data->sigh |= l64 >> 21;
+ loaded_data->sigl = l64 << 11;
- tag = TAG_Valid;
- }
+ tag = TAG_Valid;
+ }
- setexponent16(loaded_data, exp | negative);
+ setexponent16(loaded_data, exp | negative);
- return tag;
+ return tag;
}
-
/* Get a float from user memory */
-int FPU_load_single(float __user *single, FPU_REG *loaded_data)
+int FPU_load_single(float __user * single, FPU_REG * loaded_data)
{
- unsigned m32;
- int exp, tag, negative;
-
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_READ, single, 4);
- FPU_get_user(m32, (unsigned long __user *) single);
- RE_ENTRANT_CHECK_ON;
-
- negative = (m32 & 0x80000000) ? SIGN_Negative : SIGN_Positive;
-
- if (!(m32 & 0x7fffffff))
- {
- /* Zero */
- reg_copy(&CONST_Z, loaded_data);
- addexponent(loaded_data, negative);
- return TAG_Zero;
- }
- exp = ((m32 & 0x7f800000) >> 23) - SINGLE_Ebias + EXTENDED_Ebias;
- m32 = (m32 & 0x7fffff) << 8;
- if ( exp < SINGLE_Emin + EXTENDED_Ebias )
- {
- /* De-normals */
- loaded_data->sigh = m32;
- loaded_data->sigl = 0;
-
- return normalize_no_excep(loaded_data, SINGLE_Emin, negative)
- | (denormal_operand() < 0 ? FPU_Exception : 0);
- }
- else if ( exp > SINGLE_Emax + EXTENDED_Ebias )
- {
- /* Infinity or NaN */
- if ( m32 == 0 )
- {
- /* +- infinity */
- loaded_data->sigh = 0x80000000;
- loaded_data->sigl = 0x00000000;
- exp = EXP_Infinity + EXTENDED_Ebias;
- tag = TAG_Special;
+ unsigned m32;
+ int exp, tag, negative;
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_READ, single, 4);
+ FPU_get_user(m32, (unsigned long __user *)single);
+ RE_ENTRANT_CHECK_ON;
+
+ negative = (m32 & 0x80000000) ? SIGN_Negative : SIGN_Positive;
+
+ if (!(m32 & 0x7fffffff)) {
+ /* Zero */
+ reg_copy(&CONST_Z, loaded_data);
+ addexponent(loaded_data, negative);
+ return TAG_Zero;
}
- else
- {
- /* Must be a signaling or quiet NaN */
- exp = EXP_NaN + EXTENDED_Ebias;
- loaded_data->sigh = m32 | 0x80000000;
- loaded_data->sigl = 0;
- tag = TAG_Special; /* The calling function must look for NaNs */
+ exp = ((m32 & 0x7f800000) >> 23) - SINGLE_Ebias + EXTENDED_Ebias;
+ m32 = (m32 & 0x7fffff) << 8;
+ if (exp < SINGLE_Emin + EXTENDED_Ebias) {
+ /* De-normals */
+ loaded_data->sigh = m32;
+ loaded_data->sigl = 0;
+
+ return normalize_no_excep(loaded_data, SINGLE_Emin, negative)
+ | (denormal_operand() < 0 ? FPU_Exception : 0);
+ } else if (exp > SINGLE_Emax + EXTENDED_Ebias) {
+ /* Infinity or NaN */
+ if (m32 == 0) {
+ /* +- infinity */
+ loaded_data->sigh = 0x80000000;
+ loaded_data->sigl = 0x00000000;
+ exp = EXP_Infinity + EXTENDED_Ebias;
+ tag = TAG_Special;
+ } else {
+ /* Must be a signaling or quiet NaN */
+ exp = EXP_NaN + EXTENDED_Ebias;
+ loaded_data->sigh = m32 | 0x80000000;
+ loaded_data->sigl = 0;
+ tag = TAG_Special; /* The calling function must look for NaNs */
+ }
+ } else {
+ loaded_data->sigh = m32 | 0x80000000;
+ loaded_data->sigl = 0;
+ tag = TAG_Valid;
}
- }
- else
- {
- loaded_data->sigh = m32 | 0x80000000;
- loaded_data->sigl = 0;
- tag = TAG_Valid;
- }
- setexponent16(loaded_data, exp | negative); /* Set the sign. */
+ setexponent16(loaded_data, exp | negative); /* Set the sign. */
- return tag;
+ return tag;
}
-
/* Get a long long from user memory */
-int FPU_load_int64(long long __user *_s)
+int FPU_load_int64(long long __user * _s)
{
- long long s;
- int sign;
- FPU_REG *st0_ptr = &st(0);
-
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_READ, _s, 8);
- if (copy_from_user(&s,_s,8))
- FPU_abort;
- RE_ENTRANT_CHECK_ON;
-
- if (s == 0)
- {
- reg_copy(&CONST_Z, st0_ptr);
- return TAG_Zero;
- }
-
- if (s > 0)
- sign = SIGN_Positive;
- else
- {
- s = -s;
- sign = SIGN_Negative;
- }
-
- significand(st0_ptr) = s;
-
- return normalize_no_excep(st0_ptr, 63, sign);
-}
+ long long s;
+ int sign;
+ FPU_REG *st0_ptr = &st(0);
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_READ, _s, 8);
+ if (copy_from_user(&s, _s, 8))
+ FPU_abort;
+ RE_ENTRANT_CHECK_ON;
+
+ if (s == 0) {
+ reg_copy(&CONST_Z, st0_ptr);
+ return TAG_Zero;
+ }
+
+ if (s > 0)
+ sign = SIGN_Positive;
+ else {
+ s = -s;
+ sign = SIGN_Negative;
+ }
+ significand(st0_ptr) = s;
+
+ return normalize_no_excep(st0_ptr, 63, sign);
+}
/* Get a long from user memory */
-int FPU_load_int32(long __user *_s, FPU_REG *loaded_data)
+int FPU_load_int32(long __user * _s, FPU_REG * loaded_data)
{
- long s;
- int negative;
+ long s;
+ int negative;
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_READ, _s, 4);
- FPU_get_user(s, _s);
- RE_ENTRANT_CHECK_ON;
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_READ, _s, 4);
+ FPU_get_user(s, _s);
+ RE_ENTRANT_CHECK_ON;
- if (s == 0)
- { reg_copy(&CONST_Z, loaded_data); return TAG_Zero; }
+ if (s == 0) {
+ reg_copy(&CONST_Z, loaded_data);
+ return TAG_Zero;
+ }
- if (s > 0)
- negative = SIGN_Positive;
- else
- {
- s = -s;
- negative = SIGN_Negative;
- }
+ if (s > 0)
+ negative = SIGN_Positive;
+ else {
+ s = -s;
+ negative = SIGN_Negative;
+ }
- loaded_data->sigh = s;
- loaded_data->sigl = 0;
+ loaded_data->sigh = s;
+ loaded_data->sigl = 0;
- return normalize_no_excep(loaded_data, 31, negative);
+ return normalize_no_excep(loaded_data, 31, negative);
}
-
/* Get a short from user memory */
-int FPU_load_int16(short __user *_s, FPU_REG *loaded_data)
+int FPU_load_int16(short __user * _s, FPU_REG * loaded_data)
{
- int s, negative;
+ int s, negative;
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_READ, _s, 2);
- /* Cast as short to get the sign extended. */
- FPU_get_user(s, _s);
- RE_ENTRANT_CHECK_ON;
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_READ, _s, 2);
+ /* Cast as short to get the sign extended. */
+ FPU_get_user(s, _s);
+ RE_ENTRANT_CHECK_ON;
- if (s == 0)
- { reg_copy(&CONST_Z, loaded_data); return TAG_Zero; }
+ if (s == 0) {
+ reg_copy(&CONST_Z, loaded_data);
+ return TAG_Zero;
+ }
- if (s > 0)
- negative = SIGN_Positive;
- else
- {
- s = -s;
- negative = SIGN_Negative;
- }
+ if (s > 0)
+ negative = SIGN_Positive;
+ else {
+ s = -s;
+ negative = SIGN_Negative;
+ }
- loaded_data->sigh = s << 16;
- loaded_data->sigl = 0;
+ loaded_data->sigh = s << 16;
+ loaded_data->sigl = 0;
- return normalize_no_excep(loaded_data, 15, negative);
+ return normalize_no_excep(loaded_data, 15, negative);
}
-
/* Get a packed bcd array from user memory */
-int FPU_load_bcd(u_char __user *s)
+int FPU_load_bcd(u_char __user * s)
{
- FPU_REG *st0_ptr = &st(0);
- int pos;
- u_char bcd;
- long long l=0;
- int sign;
-
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_READ, s, 10);
- RE_ENTRANT_CHECK_ON;
- for ( pos = 8; pos >= 0; pos--)
- {
- l *= 10;
- RE_ENTRANT_CHECK_OFF;
- FPU_get_user(bcd, s+pos);
- RE_ENTRANT_CHECK_ON;
- l += bcd >> 4;
- l *= 10;
- l += bcd & 0x0f;
- }
-
- RE_ENTRANT_CHECK_OFF;
- FPU_get_user(sign, s+9);
- sign = sign & 0x80 ? SIGN_Negative : SIGN_Positive;
- RE_ENTRANT_CHECK_ON;
-
- if ( l == 0 )
- {
- reg_copy(&CONST_Z, st0_ptr);
- addexponent(st0_ptr, sign); /* Set the sign. */
- return TAG_Zero;
- }
- else
- {
- significand(st0_ptr) = l;
- return normalize_no_excep(st0_ptr, 63, sign);
- }
+ FPU_REG *st0_ptr = &st(0);
+ int pos;
+ u_char bcd;
+ long long l = 0;
+ int sign;
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_READ, s, 10);
+ RE_ENTRANT_CHECK_ON;
+ for (pos = 8; pos >= 0; pos--) {
+ l *= 10;
+ RE_ENTRANT_CHECK_OFF;
+ FPU_get_user(bcd, s + pos);
+ RE_ENTRANT_CHECK_ON;
+ l += bcd >> 4;
+ l *= 10;
+ l += bcd & 0x0f;
+ }
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_get_user(sign, s + 9);
+ sign = sign & 0x80 ? SIGN_Negative : SIGN_Positive;
+ RE_ENTRANT_CHECK_ON;
+
+ if (l == 0) {
+ reg_copy(&CONST_Z, st0_ptr);
+ addexponent(st0_ptr, sign); /* Set the sign. */
+ return TAG_Zero;
+ } else {
+ significand(st0_ptr) = l;
+ return normalize_no_excep(st0_ptr, 63, sign);
+ }
}
/*===========================================================================*/
/* Put a long double into user memory */
-int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag, long double __user *d)
+int FPU_store_extended(FPU_REG * st0_ptr, u_char st0_tag,
+ long double __user * d)
{
- /*
- The only exception raised by an attempt to store to an
- extended format is the Invalid Stack exception, i.e.
- attempting to store from an empty register.
- */
-
- if ( st0_tag != TAG_Empty )
- {
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_WRITE, d, 10);
-
- FPU_put_user(st0_ptr->sigl, (unsigned long __user *) d);
- FPU_put_user(st0_ptr->sigh, (unsigned long __user *) ((u_char __user *)d + 4));
- FPU_put_user(exponent16(st0_ptr), (unsigned short __user *) ((u_char __user *)d + 8));
- RE_ENTRANT_CHECK_ON;
-
- return 1;
- }
-
- /* Empty register (stack underflow) */
- EXCEPTION(EX_StackUnder);
- if ( control_word & CW_Invalid )
- {
- /* The masked response */
- /* Put out the QNaN indefinite */
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_WRITE,d,10);
- FPU_put_user(0, (unsigned long __user *) d);
- FPU_put_user(0xc0000000, 1 + (unsigned long __user *) d);
- FPU_put_user(0xffff, 4 + (short __user *) d);
- RE_ENTRANT_CHECK_ON;
- return 1;
- }
- else
- return 0;
+ /*
+ The only exception raised by an attempt to store to an
+ extended format is the Invalid Stack exception, i.e.
+ attempting to store from an empty register.
+ */
+
+ if (st0_tag != TAG_Empty) {
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_WRITE, d, 10);
+
+ FPU_put_user(st0_ptr->sigl, (unsigned long __user *)d);
+ FPU_put_user(st0_ptr->sigh,
+ (unsigned long __user *)((u_char __user *) d + 4));
+ FPU_put_user(exponent16(st0_ptr),
+ (unsigned short __user *)((u_char __user *) d +
+ 8));
+ RE_ENTRANT_CHECK_ON;
+
+ return 1;
+ }
-}
+ /* Empty register (stack underflow) */
+ EXCEPTION(EX_StackUnder);
+ if (control_word & CW_Invalid) {
+ /* The masked response */
+ /* Put out the QNaN indefinite */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_WRITE, d, 10);
+ FPU_put_user(0, (unsigned long __user *)d);
+ FPU_put_user(0xc0000000, 1 + (unsigned long __user *)d);
+ FPU_put_user(0xffff, 4 + (short __user *)d);
+ RE_ENTRANT_CHECK_ON;
+ return 1;
+ } else
+ return 0;
+}
/* Put a double into user memory */
-int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double __user *dfloat)
+int FPU_store_double(FPU_REG * st0_ptr, u_char st0_tag, double __user * dfloat)
{
- unsigned long l[2];
- unsigned long increment = 0; /* avoid gcc warnings */
- int precision_loss;
- int exp;
- FPU_REG tmp;
+ unsigned long l[2];
+ unsigned long increment = 0; /* avoid gcc warnings */
+ int precision_loss;
+ int exp;
+ FPU_REG tmp;
- if ( st0_tag == TAG_Valid )
- {
- reg_copy(st0_ptr, &tmp);
- exp = exponent(&tmp);
+ if (st0_tag == TAG_Valid) {
+ reg_copy(st0_ptr, &tmp);
+ exp = exponent(&tmp);
- if ( exp < DOUBLE_Emin ) /* It may be a denormal */
- {
- addexponent(&tmp, -DOUBLE_Emin + 52); /* largest exp to be 51 */
+ if (exp < DOUBLE_Emin) { /* It may be a denormal */
+ addexponent(&tmp, -DOUBLE_Emin + 52); /* largest exp to be 51 */
- denormal_arg:
+ denormal_arg:
- if ( (precision_loss = FPU_round_to_int(&tmp, st0_tag)) )
- {
+ if ((precision_loss = FPU_round_to_int(&tmp, st0_tag))) {
#ifdef PECULIAR_486
- /* Did it round to a non-denormal ? */
- /* This behaviour might be regarded as peculiar, it appears
- that the 80486 rounds to the dest precision, then
- converts to decide underflow. */
- if ( !((tmp.sigh == 0x00100000) && (tmp.sigl == 0) &&
- (st0_ptr->sigl & 0x000007ff)) )
+ /* Did it round to a non-denormal ? */
+ /* This behaviour might be regarded as peculiar, it appears
+ that the 80486 rounds to the dest precision, then
+ converts to decide underflow. */
+ if (!
+ ((tmp.sigh == 0x00100000) && (tmp.sigl == 0)
+ && (st0_ptr->sigl & 0x000007ff)))
#endif /* PECULIAR_486 */
- {
- EXCEPTION(EX_Underflow);
- /* This is a special case: see sec 16.2.5.1 of
- the 80486 book */
- if ( !(control_word & CW_Underflow) )
- return 0;
- }
- EXCEPTION(precision_loss);
- if ( !(control_word & CW_Precision) )
- return 0;
- }
- l[0] = tmp.sigl;
- l[1] = tmp.sigh;
- }
- else
- {
- if ( tmp.sigl & 0x000007ff )
- {
- precision_loss = 1;
- switch (control_word & CW_RC)
- {
- case RC_RND:
- /* Rounding can get a little messy.. */
- increment = ((tmp.sigl & 0x7ff) > 0x400) | /* nearest */
- ((tmp.sigl & 0xc00) == 0xc00); /* odd -> even */
- break;
- case RC_DOWN: /* towards -infinity */
- increment = signpositive(&tmp) ? 0 : tmp.sigl & 0x7ff;
- break;
- case RC_UP: /* towards +infinity */
- increment = signpositive(&tmp) ? tmp.sigl & 0x7ff : 0;
- break;
- case RC_CHOP:
- increment = 0;
- break;
- }
-
- /* Truncate the mantissa */
- tmp.sigl &= 0xfffff800;
-
- if ( increment )
- {
- if ( tmp.sigl >= 0xfffff800 )
- {
- /* the sigl part overflows */
- if ( tmp.sigh == 0xffffffff )
- {
- /* The sigh part overflows */
- tmp.sigh = 0x80000000;
- exp++;
- if (exp >= EXP_OVER)
- goto overflow;
+ {
+ EXCEPTION(EX_Underflow);
+ /* This is a special case: see sec 16.2.5.1 of
+ the 80486 book */
+ if (!(control_word & CW_Underflow))
+ return 0;
+ }
+ EXCEPTION(precision_loss);
+ if (!(control_word & CW_Precision))
+ return 0;
}
- else
- {
- tmp.sigh ++;
+ l[0] = tmp.sigl;
+ l[1] = tmp.sigh;
+ } else {
+ if (tmp.sigl & 0x000007ff) {
+ precision_loss = 1;
+ switch (control_word & CW_RC) {
+ case RC_RND:
+ /* Rounding can get a little messy.. */
+ increment = ((tmp.sigl & 0x7ff) > 0x400) | /* nearest */
+ ((tmp.sigl & 0xc00) == 0xc00); /* odd -> even */
+ break;
+ case RC_DOWN: /* towards -infinity */
+ increment =
+ signpositive(&tmp) ? 0 : tmp.
+ sigl & 0x7ff;
+ break;
+ case RC_UP: /* towards +infinity */
+ increment =
+ signpositive(&tmp) ? tmp.
+ sigl & 0x7ff : 0;
+ break;
+ case RC_CHOP:
+ increment = 0;
+ break;
+ }
+
+ /* Truncate the mantissa */
+ tmp.sigl &= 0xfffff800;
+
+ if (increment) {
+ if (tmp.sigl >= 0xfffff800) {
+ /* the sigl part overflows */
+ if (tmp.sigh == 0xffffffff) {
+ /* The sigh part overflows */
+ tmp.sigh = 0x80000000;
+ exp++;
+ if (exp >= EXP_OVER)
+ goto overflow;
+ } else {
+ tmp.sigh++;
+ }
+ tmp.sigl = 0x00000000;
+ } else {
+ /* We only need to increment sigl */
+ tmp.sigl += 0x00000800;
+ }
+ }
+ } else
+ precision_loss = 0;
+
+ l[0] = (tmp.sigl >> 11) | (tmp.sigh << 21);
+ l[1] = ((tmp.sigh >> 11) & 0xfffff);
+
+ if (exp > DOUBLE_Emax) {
+ overflow:
+ EXCEPTION(EX_Overflow);
+ if (!(control_word & CW_Overflow))
+ return 0;
+ set_precision_flag_up();
+ if (!(control_word & CW_Precision))
+ return 0;
+
+ /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+ /* Overflow to infinity */
+ l[0] = 0x00000000; /* Set to */
+ l[1] = 0x7ff00000; /* + INF */
+ } else {
+ if (precision_loss) {
+ if (increment)
+ set_precision_flag_up();
+ else
+ set_precision_flag_down();
+ }
+ /* Add the exponent */
+ l[1] |= (((exp + DOUBLE_Ebias) & 0x7ff) << 20);
}
- tmp.sigl = 0x00000000;
- }
- else
- {
- /* We only need to increment sigl */
- tmp.sigl += 0x00000800;
- }
- }
- }
- else
- precision_loss = 0;
-
- l[0] = (tmp.sigl >> 11) | (tmp.sigh << 21);
- l[1] = ((tmp.sigh >> 11) & 0xfffff);
-
- if ( exp > DOUBLE_Emax )
- {
- overflow:
- EXCEPTION(EX_Overflow);
- if ( !(control_word & CW_Overflow) )
- return 0;
- set_precision_flag_up();
- if ( !(control_word & CW_Precision) )
- return 0;
-
- /* This is a special case: see sec 16.2.5.1 of the 80486 book */
- /* Overflow to infinity */
- l[0] = 0x00000000; /* Set to */
- l[1] = 0x7ff00000; /* + INF */
- }
- else
- {
- if ( precision_loss )
- {
- if ( increment )
- set_precision_flag_up();
- else
- set_precision_flag_down();
}
- /* Add the exponent */
- l[1] |= (((exp+DOUBLE_Ebias) & 0x7ff) << 20);
- }
- }
- }
- else if (st0_tag == TAG_Zero)
- {
- /* Number is zero */
- l[0] = 0;
- l[1] = 0;
- }
- else if ( st0_tag == TAG_Special )
- {
- st0_tag = FPU_Special(st0_ptr);
- if ( st0_tag == TW_Denormal )
- {
- /* A denormal will always underflow. */
+ } else if (st0_tag == TAG_Zero) {
+ /* Number is zero */
+ l[0] = 0;
+ l[1] = 0;
+ } else if (st0_tag == TAG_Special) {
+ st0_tag = FPU_Special(st0_ptr);
+ if (st0_tag == TW_Denormal) {
+ /* A denormal will always underflow. */
#ifndef PECULIAR_486
- /* An 80486 is supposed to be able to generate
- a denormal exception here, but... */
- /* Underflow has priority. */
- if ( control_word & CW_Underflow )
- denormal_operand();
+ /* An 80486 is supposed to be able to generate
+ a denormal exception here, but... */
+ /* Underflow has priority. */
+ if (control_word & CW_Underflow)
+ denormal_operand();
#endif /* PECULIAR_486 */
- reg_copy(st0_ptr, &tmp);
- goto denormal_arg;
- }
- else if (st0_tag == TW_Infinity)
- {
- l[0] = 0;
- l[1] = 0x7ff00000;
- }
- else if (st0_tag == TW_NaN)
- {
- /* Is it really a NaN ? */
- if ( (exponent(st0_ptr) == EXP_OVER)
- && (st0_ptr->sigh & 0x80000000) )
- {
- /* See if we can get a valid NaN from the FPU_REG */
- l[0] = (st0_ptr->sigl >> 11) | (st0_ptr->sigh << 21);
- l[1] = ((st0_ptr->sigh >> 11) & 0xfffff);
- if ( !(st0_ptr->sigh & 0x40000000) )
- {
- /* It is a signalling NaN */
- EXCEPTION(EX_Invalid);
- if ( !(control_word & CW_Invalid) )
- return 0;
- l[1] |= (0x40000000 >> 11);
+ reg_copy(st0_ptr, &tmp);
+ goto denormal_arg;
+ } else if (st0_tag == TW_Infinity) {
+ l[0] = 0;
+ l[1] = 0x7ff00000;
+ } else if (st0_tag == TW_NaN) {
+ /* Is it really a NaN ? */
+ if ((exponent(st0_ptr) == EXP_OVER)
+ && (st0_ptr->sigh & 0x80000000)) {
+ /* See if we can get a valid NaN from the FPU_REG */
+ l[0] =
+ (st0_ptr->sigl >> 11) | (st0_ptr->
+ sigh << 21);
+ l[1] = ((st0_ptr->sigh >> 11) & 0xfffff);
+ if (!(st0_ptr->sigh & 0x40000000)) {
+ /* It is a signalling NaN */
+ EXCEPTION(EX_Invalid);
+ if (!(control_word & CW_Invalid))
+ return 0;
+ l[1] |= (0x40000000 >> 11);
+ }
+ l[1] |= 0x7ff00000;
+ } else {
+ /* It is an unsupported data type */
+ EXCEPTION(EX_Invalid);
+ if (!(control_word & CW_Invalid))
+ return 0;
+ l[0] = 0;
+ l[1] = 0xfff80000;
+ }
}
- l[1] |= 0x7ff00000;
- }
- else
- {
- /* It is an unsupported data type */
- EXCEPTION(EX_Invalid);
- if ( !(control_word & CW_Invalid) )
- return 0;
- l[0] = 0;
- l[1] = 0xfff80000;
- }
+ } else if (st0_tag == TAG_Empty) {
+ /* Empty register (stack underflow) */
+ EXCEPTION(EX_StackUnder);
+ if (control_word & CW_Invalid) {
+ /* The masked response */
+ /* Put out the QNaN indefinite */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_WRITE, dfloat, 8);
+ FPU_put_user(0, (unsigned long __user *)dfloat);
+ FPU_put_user(0xfff80000,
+ 1 + (unsigned long __user *)dfloat);
+ RE_ENTRANT_CHECK_ON;
+ return 1;
+ } else
+ return 0;
}
- }
- else if ( st0_tag == TAG_Empty )
- {
- /* Empty register (stack underflow) */
- EXCEPTION(EX_StackUnder);
- if ( control_word & CW_Invalid )
- {
- /* The masked response */
- /* Put out the QNaN indefinite */
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_WRITE,dfloat,8);
- FPU_put_user(0, (unsigned long __user *) dfloat);
- FPU_put_user(0xfff80000, 1 + (unsigned long __user *) dfloat);
- RE_ENTRANT_CHECK_ON;
- return 1;
- }
- else
- return 0;
- }
- if ( getsign(st0_ptr) )
- l[1] |= 0x80000000;
-
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_WRITE,dfloat,8);
- FPU_put_user(l[0], (unsigned long __user *)dfloat);
- FPU_put_user(l[1], 1 + (unsigned long __user *)dfloat);
- RE_ENTRANT_CHECK_ON;
-
- return 1;
-}
+ if (getsign(st0_ptr))
+ l[1] |= 0x80000000;
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_WRITE, dfloat, 8);
+ FPU_put_user(l[0], (unsigned long __user *)dfloat);
+ FPU_put_user(l[1], 1 + (unsigned long __user *)dfloat);
+ RE_ENTRANT_CHECK_ON;
+
+ return 1;
+}
/* Put a float into user memory */
-int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float __user *single)
+int FPU_store_single(FPU_REG * st0_ptr, u_char st0_tag, float __user * single)
{
- long templ = 0;
- unsigned long increment = 0; /* avoid gcc warnings */
- int precision_loss;
- int exp;
- FPU_REG tmp;
+ long templ = 0;
+ unsigned long increment = 0; /* avoid gcc warnings */
+ int precision_loss;
+ int exp;
+ FPU_REG tmp;
- if ( st0_tag == TAG_Valid )
- {
+ if (st0_tag == TAG_Valid) {
- reg_copy(st0_ptr, &tmp);
- exp = exponent(&tmp);
+ reg_copy(st0_ptr, &tmp);
+ exp = exponent(&tmp);
- if ( exp < SINGLE_Emin )
- {
- addexponent(&tmp, -SINGLE_Emin + 23); /* largest exp to be 22 */
+ if (exp < SINGLE_Emin) {
+ addexponent(&tmp, -SINGLE_Emin + 23); /* largest exp to be 22 */
- denormal_arg:
+ denormal_arg:
- if ( (precision_loss = FPU_round_to_int(&tmp, st0_tag)) )
- {
+ if ((precision_loss = FPU_round_to_int(&tmp, st0_tag))) {
#ifdef PECULIAR_486
- /* Did it round to a non-denormal ? */
- /* This behaviour might be regarded as peculiar, it appears
- that the 80486 rounds to the dest precision, then
- converts to decide underflow. */
- if ( !((tmp.sigl == 0x00800000) &&
- ((st0_ptr->sigh & 0x000000ff) || st0_ptr->sigl)) )
+ /* Did it round to a non-denormal ? */
+ /* This behaviour might be regarded as peculiar, it appears
+ that the 80486 rounds to the dest precision, then
+ converts to decide underflow. */
+ if (!((tmp.sigl == 0x00800000) &&
+ ((st0_ptr->sigh & 0x000000ff)
+ || st0_ptr->sigl)))
#endif /* PECULIAR_486 */
- {
- EXCEPTION(EX_Underflow);
- /* This is a special case: see sec 16.2.5.1 of
- the 80486 book */
- if ( !(control_word & CW_Underflow) )
- return 0;
- }
- EXCEPTION(precision_loss);
- if ( !(control_word & CW_Precision) )
- return 0;
- }
- templ = tmp.sigl;
- }
- else
- {
- if ( tmp.sigl | (tmp.sigh & 0x000000ff) )
- {
- unsigned long sigh = tmp.sigh;
- unsigned long sigl = tmp.sigl;
-
- precision_loss = 1;
- switch (control_word & CW_RC)
- {
- case RC_RND:
- increment = ((sigh & 0xff) > 0x80) /* more than half */
- || (((sigh & 0xff) == 0x80) && sigl) /* more than half */
- || ((sigh & 0x180) == 0x180); /* round to even */
- break;
- case RC_DOWN: /* towards -infinity */
- increment = signpositive(&tmp)
- ? 0 : (sigl | (sigh & 0xff));
- break;
- case RC_UP: /* towards +infinity */
- increment = signpositive(&tmp)
- ? (sigl | (sigh & 0xff)) : 0;
- break;
- case RC_CHOP:
- increment = 0;
- break;
- }
-
- /* Truncate part of the mantissa */
- tmp.sigl = 0;
-
- if (increment)
- {
- if ( sigh >= 0xffffff00 )
- {
- /* The sigh part overflows */
- tmp.sigh = 0x80000000;
- exp++;
- if ( exp >= EXP_OVER )
- goto overflow;
- }
- else
- {
- tmp.sigh &= 0xffffff00;
- tmp.sigh += 0x100;
- }
- }
- else
- {
- tmp.sigh &= 0xffffff00; /* Finish the truncation */
- }
- }
- else
- precision_loss = 0;
-
- templ = (tmp.sigh >> 8) & 0x007fffff;
-
- if ( exp > SINGLE_Emax )
- {
- overflow:
- EXCEPTION(EX_Overflow);
- if ( !(control_word & CW_Overflow) )
- return 0;
- set_precision_flag_up();
- if ( !(control_word & CW_Precision) )
- return 0;
-
- /* This is a special case: see sec 16.2.5.1 of the 80486 book. */
- /* Masked response is overflow to infinity. */
- templ = 0x7f800000;
- }
- else
- {
- if ( precision_loss )
- {
- if ( increment )
- set_precision_flag_up();
- else
- set_precision_flag_down();
+ {
+ EXCEPTION(EX_Underflow);
+ /* This is a special case: see sec 16.2.5.1 of
+ the 80486 book */
+ if (!(control_word & CW_Underflow))
+ return 0;
+ }
+ EXCEPTION(precision_loss);
+ if (!(control_word & CW_Precision))
+ return 0;
+ }
+ templ = tmp.sigl;
+ } else {
+ if (tmp.sigl | (tmp.sigh & 0x000000ff)) {
+ unsigned long sigh = tmp.sigh;
+ unsigned long sigl = tmp.sigl;
+
+ precision_loss = 1;
+ switch (control_word & CW_RC) {
+ case RC_RND:
+ increment = ((sigh & 0xff) > 0x80) /* more than half */
+ ||(((sigh & 0xff) == 0x80) && sigl) /* more than half */
+ ||((sigh & 0x180) == 0x180); /* round to even */
+ break;
+ case RC_DOWN: /* towards -infinity */
+ increment = signpositive(&tmp)
+ ? 0 : (sigl | (sigh & 0xff));
+ break;
+ case RC_UP: /* towards +infinity */
+ increment = signpositive(&tmp)
+ ? (sigl | (sigh & 0xff)) : 0;
+ break;
+ case RC_CHOP:
+ increment = 0;
+ break;
+ }
+
+ /* Truncate part of the mantissa */
+ tmp.sigl = 0;
+
+ if (increment) {
+ if (sigh >= 0xffffff00) {
+ /* The sigh part overflows */
+ tmp.sigh = 0x80000000;
+ exp++;
+ if (exp >= EXP_OVER)
+ goto overflow;
+ } else {
+ tmp.sigh &= 0xffffff00;
+ tmp.sigh += 0x100;
+ }
+ } else {
+ tmp.sigh &= 0xffffff00; /* Finish the truncation */
+ }
+ } else
+ precision_loss = 0;
+
+ templ = (tmp.sigh >> 8) & 0x007fffff;
+
+ if (exp > SINGLE_Emax) {
+ overflow:
+ EXCEPTION(EX_Overflow);
+ if (!(control_word & CW_Overflow))
+ return 0;
+ set_precision_flag_up();
+ if (!(control_word & CW_Precision))
+ return 0;
+
+ /* This is a special case: see sec 16.2.5.1 of the 80486 book. */
+ /* Masked response is overflow to infinity. */
+ templ = 0x7f800000;
+ } else {
+ if (precision_loss) {
+ if (increment)
+ set_precision_flag_up();
+ else
+ set_precision_flag_down();
+ }
+ /* Add the exponent */
+ templ |= ((exp + SINGLE_Ebias) & 0xff) << 23;
+ }
}
- /* Add the exponent */
- templ |= ((exp+SINGLE_Ebias) & 0xff) << 23;
- }
- }
- }
- else if (st0_tag == TAG_Zero)
- {
- templ = 0;
- }
- else if ( st0_tag == TAG_Special )
- {
- st0_tag = FPU_Special(st0_ptr);
- if (st0_tag == TW_Denormal)
- {
- reg_copy(st0_ptr, &tmp);
-
- /* A denormal will always underflow. */
+ } else if (st0_tag == TAG_Zero) {
+ templ = 0;
+ } else if (st0_tag == TAG_Special) {
+ st0_tag = FPU_Special(st0_ptr);
+ if (st0_tag == TW_Denormal) {
+ reg_copy(st0_ptr, &tmp);
+
+ /* A denormal will always underflow. */
#ifndef PECULIAR_486
- /* An 80486 is supposed to be able to generate
- a denormal exception here, but... */
- /* Underflow has priority. */
- if ( control_word & CW_Underflow )
- denormal_operand();
-#endif /* PECULIAR_486 */
- goto denormal_arg;
- }
- else if (st0_tag == TW_Infinity)
- {
- templ = 0x7f800000;
- }
- else if (st0_tag == TW_NaN)
- {
- /* Is it really a NaN ? */
- if ( (exponent(st0_ptr) == EXP_OVER) && (st0_ptr->sigh & 0x80000000) )
- {
- /* See if we can get a valid NaN from the FPU_REG */
- templ = st0_ptr->sigh >> 8;
- if ( !(st0_ptr->sigh & 0x40000000) )
- {
- /* It is a signalling NaN */
- EXCEPTION(EX_Invalid);
- if ( !(control_word & CW_Invalid) )
- return 0;
- templ |= (0x40000000 >> 8);
+ /* An 80486 is supposed to be able to generate
+ a denormal exception here, but... */
+ /* Underflow has priority. */
+ if (control_word & CW_Underflow)
+ denormal_operand();
+#endif /* PECULIAR_486 */
+ goto denormal_arg;
+ } else if (st0_tag == TW_Infinity) {
+ templ = 0x7f800000;
+ } else if (st0_tag == TW_NaN) {
+ /* Is it really a NaN ? */
+ if ((exponent(st0_ptr) == EXP_OVER)
+ && (st0_ptr->sigh & 0x80000000)) {
+ /* See if we can get a valid NaN from the FPU_REG */
+ templ = st0_ptr->sigh >> 8;
+ if (!(st0_ptr->sigh & 0x40000000)) {
+ /* It is a signalling NaN */
+ EXCEPTION(EX_Invalid);
+ if (!(control_word & CW_Invalid))
+ return 0;
+ templ |= (0x40000000 >> 8);
+ }
+ templ |= 0x7f800000;
+ } else {
+ /* It is an unsupported data type */
+ EXCEPTION(EX_Invalid);
+ if (!(control_word & CW_Invalid))
+ return 0;
+ templ = 0xffc00000;
+ }
}
- templ |= 0x7f800000;
- }
- else
- {
- /* It is an unsupported data type */
- EXCEPTION(EX_Invalid);
- if ( !(control_word & CW_Invalid) )
- return 0;
- templ = 0xffc00000;
- }
- }
#ifdef PARANOID
- else
- {
- EXCEPTION(EX_INTERNAL|0x164);
- return 0;
- }
+ else {
+ EXCEPTION(EX_INTERNAL | 0x164);
+ return 0;
+ }
#endif
- }
- else if ( st0_tag == TAG_Empty )
- {
- /* Empty register (stack underflow) */
- EXCEPTION(EX_StackUnder);
- if ( control_word & EX_Invalid )
- {
- /* The masked response */
- /* Put out the QNaN indefinite */
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_WRITE,single,4);
- FPU_put_user(0xffc00000, (unsigned long __user *) single);
- RE_ENTRANT_CHECK_ON;
- return 1;
+ } else if (st0_tag == TAG_Empty) {
+ /* Empty register (stack underflow) */
+ EXCEPTION(EX_StackUnder);
+ if (control_word & EX_Invalid) {
+ /* The masked response */
+ /* Put out the QNaN indefinite */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_WRITE, single, 4);
+ FPU_put_user(0xffc00000,
+ (unsigned long __user *)single);
+ RE_ENTRANT_CHECK_ON;
+ return 1;
+ } else
+ return 0;
}
- else
- return 0;
- }
#ifdef PARANOID
- else
- {
- EXCEPTION(EX_INTERNAL|0x163);
- return 0;
- }
+ else {
+ EXCEPTION(EX_INTERNAL | 0x163);
+ return 0;
+ }
#endif
- if ( getsign(st0_ptr) )
- templ |= 0x80000000;
+ if (getsign(st0_ptr))
+ templ |= 0x80000000;
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_WRITE,single,4);
- FPU_put_user(templ,(unsigned long __user *) single);
- RE_ENTRANT_CHECK_ON;
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_WRITE, single, 4);
+ FPU_put_user(templ, (unsigned long __user *)single);
+ RE_ENTRANT_CHECK_ON;
- return 1;
+ return 1;
}
-
/* Put a long long into user memory */
-int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long __user *d)
+int FPU_store_int64(FPU_REG * st0_ptr, u_char st0_tag, long long __user * d)
{
- FPU_REG t;
- long long tll;
- int precision_loss;
-
- if ( st0_tag == TAG_Empty )
- {
- /* Empty register (stack underflow) */
- EXCEPTION(EX_StackUnder);
- goto invalid_operand;
- }
- else if ( st0_tag == TAG_Special )
- {
- st0_tag = FPU_Special(st0_ptr);
- if ( (st0_tag == TW_Infinity) ||
- (st0_tag == TW_NaN) )
- {
- EXCEPTION(EX_Invalid);
- goto invalid_operand;
+ FPU_REG t;
+ long long tll;
+ int precision_loss;
+
+ if (st0_tag == TAG_Empty) {
+ /* Empty register (stack underflow) */
+ EXCEPTION(EX_StackUnder);
+ goto invalid_operand;
+ } else if (st0_tag == TAG_Special) {
+ st0_tag = FPU_Special(st0_ptr);
+ if ((st0_tag == TW_Infinity) || (st0_tag == TW_NaN)) {
+ EXCEPTION(EX_Invalid);
+ goto invalid_operand;
+ }
}
- }
-
- reg_copy(st0_ptr, &t);
- precision_loss = FPU_round_to_int(&t, st0_tag);
- ((long *)&tll)[0] = t.sigl;
- ((long *)&tll)[1] = t.sigh;
- if ( (precision_loss == 1) ||
- ((t.sigh & 0x80000000) &&
- !((t.sigh == 0x80000000) && (t.sigl == 0) &&
- signnegative(&t))) )
- {
- EXCEPTION(EX_Invalid);
- /* This is a special case: see sec 16.2.5.1 of the 80486 book */
- invalid_operand:
- if ( control_word & EX_Invalid )
- {
- /* Produce something like QNaN "indefinite" */
- tll = 0x8000000000000000LL;
+
+ reg_copy(st0_ptr, &t);
+ precision_loss = FPU_round_to_int(&t, st0_tag);
+ ((long *)&tll)[0] = t.sigl;
+ ((long *)&tll)[1] = t.sigh;
+ if ((precision_loss == 1) ||
+ ((t.sigh & 0x80000000) &&
+ !((t.sigh == 0x80000000) && (t.sigl == 0) && signnegative(&t)))) {
+ EXCEPTION(EX_Invalid);
+ /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+ invalid_operand:
+ if (control_word & EX_Invalid) {
+ /* Produce something like QNaN "indefinite" */
+ tll = 0x8000000000000000LL;
+ } else
+ return 0;
+ } else {
+ if (precision_loss)
+ set_precision_flag(precision_loss);
+ if (signnegative(&t))
+ tll = -tll;
}
- else
- return 0;
- }
- else
- {
- if ( precision_loss )
- set_precision_flag(precision_loss);
- if ( signnegative(&t) )
- tll = - tll;
- }
-
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_WRITE,d,8);
- if (copy_to_user(d, &tll, 8))
- FPU_abort;
- RE_ENTRANT_CHECK_ON;
-
- return 1;
-}
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_WRITE, d, 8);
+ if (copy_to_user(d, &tll, 8))
+ FPU_abort;
+ RE_ENTRANT_CHECK_ON;
+
+ return 1;
+}
/* Put a long into user memory */
-int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long __user *d)
+int FPU_store_int32(FPU_REG * st0_ptr, u_char st0_tag, long __user * d)
{
- FPU_REG t;
- int precision_loss;
-
- if ( st0_tag == TAG_Empty )
- {
- /* Empty register (stack underflow) */
- EXCEPTION(EX_StackUnder);
- goto invalid_operand;
- }
- else if ( st0_tag == TAG_Special )
- {
- st0_tag = FPU_Special(st0_ptr);
- if ( (st0_tag == TW_Infinity) ||
- (st0_tag == TW_NaN) )
- {
- EXCEPTION(EX_Invalid);
- goto invalid_operand;
+ FPU_REG t;
+ int precision_loss;
+
+ if (st0_tag == TAG_Empty) {
+ /* Empty register (stack underflow) */
+ EXCEPTION(EX_StackUnder);
+ goto invalid_operand;
+ } else if (st0_tag == TAG_Special) {
+ st0_tag = FPU_Special(st0_ptr);
+ if ((st0_tag == TW_Infinity) || (st0_tag == TW_NaN)) {
+ EXCEPTION(EX_Invalid);
+ goto invalid_operand;
+ }
}
- }
-
- reg_copy(st0_ptr, &t);
- precision_loss = FPU_round_to_int(&t, st0_tag);
- if (t.sigh ||
- ((t.sigl & 0x80000000) &&
- !((t.sigl == 0x80000000) && signnegative(&t))) )
- {
- EXCEPTION(EX_Invalid);
- /* This is a special case: see sec 16.2.5.1 of the 80486 book */
- invalid_operand:
- if ( control_word & EX_Invalid )
- {
- /* Produce something like QNaN "indefinite" */
- t.sigl = 0x80000000;
+
+ reg_copy(st0_ptr, &t);
+ precision_loss = FPU_round_to_int(&t, st0_tag);
+ if (t.sigh ||
+ ((t.sigl & 0x80000000) &&
+ !((t.sigl == 0x80000000) && signnegative(&t)))) {
+ EXCEPTION(EX_Invalid);
+ /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+ invalid_operand:
+ if (control_word & EX_Invalid) {
+ /* Produce something like QNaN "indefinite" */
+ t.sigl = 0x80000000;
+ } else
+ return 0;
+ } else {
+ if (precision_loss)
+ set_precision_flag(precision_loss);
+ if (signnegative(&t))
+ t.sigl = -(long)t.sigl;
}
- else
- return 0;
- }
- else
- {
- if ( precision_loss )
- set_precision_flag(precision_loss);
- if ( signnegative(&t) )
- t.sigl = -(long)t.sigl;
- }
-
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_WRITE,d,4);
- FPU_put_user(t.sigl, (unsigned long __user *) d);
- RE_ENTRANT_CHECK_ON;
-
- return 1;
-}
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_WRITE, d, 4);
+ FPU_put_user(t.sigl, (unsigned long __user *)d);
+ RE_ENTRANT_CHECK_ON;
+
+ return 1;
+}
/* Put a short into user memory */
-int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short __user *d)
+int FPU_store_int16(FPU_REG * st0_ptr, u_char st0_tag, short __user * d)
{
- FPU_REG t;
- int precision_loss;
-
- if ( st0_tag == TAG_Empty )
- {
- /* Empty register (stack underflow) */
- EXCEPTION(EX_StackUnder);
- goto invalid_operand;
- }
- else if ( st0_tag == TAG_Special )
- {
- st0_tag = FPU_Special(st0_ptr);
- if ( (st0_tag == TW_Infinity) ||
- (st0_tag == TW_NaN) )
- {
- EXCEPTION(EX_Invalid);
- goto invalid_operand;
+ FPU_REG t;
+ int precision_loss;
+
+ if (st0_tag == TAG_Empty) {
+ /* Empty register (stack underflow) */
+ EXCEPTION(EX_StackUnder);
+ goto invalid_operand;
+ } else if (st0_tag == TAG_Special) {
+ st0_tag = FPU_Special(st0_ptr);
+ if ((st0_tag == TW_Infinity) || (st0_tag == TW_NaN)) {
+ EXCEPTION(EX_Invalid);
+ goto invalid_operand;
+ }
}
- }
-
- reg_copy(st0_ptr, &t);
- precision_loss = FPU_round_to_int(&t, st0_tag);
- if (t.sigh ||
- ((t.sigl & 0xffff8000) &&
- !((t.sigl == 0x8000) && signnegative(&t))) )
- {
- EXCEPTION(EX_Invalid);
- /* This is a special case: see sec 16.2.5.1 of the 80486 book */
- invalid_operand:
- if ( control_word & EX_Invalid )
- {
- /* Produce something like QNaN "indefinite" */
- t.sigl = 0x8000;
+
+ reg_copy(st0_ptr, &t);
+ precision_loss = FPU_round_to_int(&t, st0_tag);
+ if (t.sigh ||
+ ((t.sigl & 0xffff8000) &&
+ !((t.sigl == 0x8000) && signnegative(&t)))) {
+ EXCEPTION(EX_Invalid);
+ /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+ invalid_operand:
+ if (control_word & EX_Invalid) {
+ /* Produce something like QNaN "indefinite" */
+ t.sigl = 0x8000;
+ } else
+ return 0;
+ } else {
+ if (precision_loss)
+ set_precision_flag(precision_loss);
+ if (signnegative(&t))
+ t.sigl = -t.sigl;
}
- else
- return 0;
- }
- else
- {
- if ( precision_loss )
- set_precision_flag(precision_loss);
- if ( signnegative(&t) )
- t.sigl = -t.sigl;
- }
-
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_WRITE,d,2);
- FPU_put_user((short)t.sigl, d);
- RE_ENTRANT_CHECK_ON;
-
- return 1;
-}
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_WRITE, d, 2);
+ FPU_put_user((short)t.sigl, d);
+ RE_ENTRANT_CHECK_ON;
+
+ return 1;
+}
/* Put a packed bcd array into user memory */
-int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char __user *d)
+int FPU_store_bcd(FPU_REG * st0_ptr, u_char st0_tag, u_char __user * d)
{
- FPU_REG t;
- unsigned long long ll;
- u_char b;
- int i, precision_loss;
- u_char sign = (getsign(st0_ptr) == SIGN_NEG) ? 0x80 : 0;
-
- if ( st0_tag == TAG_Empty )
- {
- /* Empty register (stack underflow) */
- EXCEPTION(EX_StackUnder);
- goto invalid_operand;
- }
- else if ( st0_tag == TAG_Special )
- {
- st0_tag = FPU_Special(st0_ptr);
- if ( (st0_tag == TW_Infinity) ||
- (st0_tag == TW_NaN) )
- {
- EXCEPTION(EX_Invalid);
- goto invalid_operand;
+ FPU_REG t;
+ unsigned long long ll;
+ u_char b;
+ int i, precision_loss;
+ u_char sign = (getsign(st0_ptr) == SIGN_NEG) ? 0x80 : 0;
+
+ if (st0_tag == TAG_Empty) {
+ /* Empty register (stack underflow) */
+ EXCEPTION(EX_StackUnder);
+ goto invalid_operand;
+ } else if (st0_tag == TAG_Special) {
+ st0_tag = FPU_Special(st0_ptr);
+ if ((st0_tag == TW_Infinity) || (st0_tag == TW_NaN)) {
+ EXCEPTION(EX_Invalid);
+ goto invalid_operand;
+ }
+ }
+
+ reg_copy(st0_ptr, &t);
+ precision_loss = FPU_round_to_int(&t, st0_tag);
+ ll = significand(&t);
+
+ /* Check for overflow, by comparing with 999999999999999999 decimal. */
+ if ((t.sigh > 0x0de0b6b3) ||
+ ((t.sigh == 0x0de0b6b3) && (t.sigl > 0xa763ffff))) {
+ EXCEPTION(EX_Invalid);
+ /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+ invalid_operand:
+ if (control_word & CW_Invalid) {
+ /* Produce the QNaN "indefinite" */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_WRITE, d, 10);
+ for (i = 0; i < 7; i++)
+ FPU_put_user(0, d + i); /* These bytes "undefined" */
+ FPU_put_user(0xc0, d + 7); /* This byte "undefined" */
+ FPU_put_user(0xff, d + 8);
+ FPU_put_user(0xff, d + 9);
+ RE_ENTRANT_CHECK_ON;
+ return 1;
+ } else
+ return 0;
+ } else if (precision_loss) {
+ /* Precision loss doesn't stop the data transfer */
+ set_precision_flag(precision_loss);
}
- }
-
- reg_copy(st0_ptr, &t);
- precision_loss = FPU_round_to_int(&t, st0_tag);
- ll = significand(&t);
-
- /* Check for overflow, by comparing with 999999999999999999 decimal. */
- if ( (t.sigh > 0x0de0b6b3) ||
- ((t.sigh == 0x0de0b6b3) && (t.sigl > 0xa763ffff)) )
- {
- EXCEPTION(EX_Invalid);
- /* This is a special case: see sec 16.2.5.1 of the 80486 book */
- invalid_operand:
- if ( control_word & CW_Invalid )
- {
- /* Produce the QNaN "indefinite" */
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_WRITE,d,10);
- for ( i = 0; i < 7; i++)
- FPU_put_user(0, d+i); /* These bytes "undefined" */
- FPU_put_user(0xc0, d+7); /* This byte "undefined" */
- FPU_put_user(0xff, d+8);
- FPU_put_user(0xff, d+9);
- RE_ENTRANT_CHECK_ON;
- return 1;
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_WRITE, d, 10);
+ RE_ENTRANT_CHECK_ON;
+ for (i = 0; i < 9; i++) {
+ b = FPU_div_small(&ll, 10);
+ b |= (FPU_div_small(&ll, 10)) << 4;
+ RE_ENTRANT_CHECK_OFF;
+ FPU_put_user(b, d + i);
+ RE_ENTRANT_CHECK_ON;
}
- else
- return 0;
- }
- else if ( precision_loss )
- {
- /* Precision loss doesn't stop the data transfer */
- set_precision_flag(precision_loss);
- }
-
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_WRITE,d,10);
- RE_ENTRANT_CHECK_ON;
- for ( i = 0; i < 9; i++)
- {
- b = FPU_div_small(&ll, 10);
- b |= (FPU_div_small(&ll, 10)) << 4;
- RE_ENTRANT_CHECK_OFF;
- FPU_put_user(b, d+i);
- RE_ENTRANT_CHECK_ON;
- }
- RE_ENTRANT_CHECK_OFF;
- FPU_put_user(sign, d+9);
- RE_ENTRANT_CHECK_ON;
-
- return 1;
+ RE_ENTRANT_CHECK_OFF;
+ FPU_put_user(sign, d + 9);
+ RE_ENTRANT_CHECK_ON;
+
+ return 1;
}
/*===========================================================================*/
@@ -1117,259 +971,254 @@ int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char __user *d)
/* Overflow is signalled by a non-zero return value (in eax).
In the case of overflow, the returned significand always has the
largest possible value */
-int FPU_round_to_int(FPU_REG *r, u_char tag)
+int FPU_round_to_int(FPU_REG * r, u_char tag)
{
- u_char very_big;
- unsigned eax;
-
- if (tag == TAG_Zero)
- {
- /* Make sure that zero is returned */
- significand(r) = 0;
- return 0; /* o.k. */
- }
-
- if (exponent(r) > 63)
- {
- r->sigl = r->sigh = ~0; /* The largest representable number */
- return 1; /* overflow */
- }
-
- eax = FPU_shrxs(&r->sigl, 63 - exponent(r));
- very_big = !(~(r->sigh) | ~(r->sigl)); /* test for 0xfff...fff */
+ u_char very_big;
+ unsigned eax;
+
+ if (tag == TAG_Zero) {
+ /* Make sure that zero is returned */
+ significand(r) = 0;
+ return 0; /* o.k. */
+ }
+
+ if (exponent(r) > 63) {
+ r->sigl = r->sigh = ~0; /* The largest representable number */
+ return 1; /* overflow */
+ }
+
+ eax = FPU_shrxs(&r->sigl, 63 - exponent(r));
+ very_big = !(~(r->sigh) | ~(r->sigl)); /* test for 0xfff...fff */
#define half_or_more (eax & 0x80000000)
#define frac_part (eax)
#define more_than_half ((eax & 0x80000001) == 0x80000001)
- switch (control_word & CW_RC)
- {
- case RC_RND:
- if ( more_than_half /* nearest */
- || (half_or_more && (r->sigl & 1)) ) /* odd -> even */
- {
- if ( very_big ) return 1; /* overflow */
- significand(r) ++;
- return PRECISION_LOST_UP;
- }
- break;
- case RC_DOWN:
- if (frac_part && getsign(r))
- {
- if ( very_big ) return 1; /* overflow */
- significand(r) ++;
- return PRECISION_LOST_UP;
- }
- break;
- case RC_UP:
- if (frac_part && !getsign(r))
- {
- if ( very_big ) return 1; /* overflow */
- significand(r) ++;
- return PRECISION_LOST_UP;
+ switch (control_word & CW_RC) {
+ case RC_RND:
+ if (more_than_half /* nearest */
+ || (half_or_more && (r->sigl & 1))) { /* odd -> even */
+ if (very_big)
+ return 1; /* overflow */
+ significand(r)++;
+ return PRECISION_LOST_UP;
+ }
+ break;
+ case RC_DOWN:
+ if (frac_part && getsign(r)) {
+ if (very_big)
+ return 1; /* overflow */
+ significand(r)++;
+ return PRECISION_LOST_UP;
+ }
+ break;
+ case RC_UP:
+ if (frac_part && !getsign(r)) {
+ if (very_big)
+ return 1; /* overflow */
+ significand(r)++;
+ return PRECISION_LOST_UP;
+ }
+ break;
+ case RC_CHOP:
+ break;
}
- break;
- case RC_CHOP:
- break;
- }
- return eax ? PRECISION_LOST_DOWN : 0;
+ return eax ? PRECISION_LOST_DOWN : 0;
}
/*===========================================================================*/
-u_char __user *fldenv(fpu_addr_modes addr_modes, u_char __user *s)
+u_char __user *fldenv(fpu_addr_modes addr_modes, u_char __user * s)
{
- unsigned short tag_word = 0;
- u_char tag;
- int i;
-
- if ( (addr_modes.default_mode == VM86) ||
- ((addr_modes.default_mode == PM16)
- ^ (addr_modes.override.operand_size == OP_SIZE_PREFIX)) )
- {
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_READ, s, 0x0e);
- FPU_get_user(control_word, (unsigned short __user *) s);
- FPU_get_user(partial_status, (unsigned short __user *) (s+2));
- FPU_get_user(tag_word, (unsigned short __user *) (s+4));
- FPU_get_user(instruction_address.offset, (unsigned short __user *) (s+6));
- FPU_get_user(instruction_address.selector, (unsigned short __user *) (s+8));
- FPU_get_user(operand_address.offset, (unsigned short __user *) (s+0x0a));
- FPU_get_user(operand_address.selector, (unsigned short __user *) (s+0x0c));
- RE_ENTRANT_CHECK_ON;
- s += 0x0e;
- if ( addr_modes.default_mode == VM86 )
- {
- instruction_address.offset
- += (instruction_address.selector & 0xf000) << 4;
- operand_address.offset += (operand_address.selector & 0xf000) << 4;
+ unsigned short tag_word = 0;
+ u_char tag;
+ int i;
+
+ if ((addr_modes.default_mode == VM86) ||
+ ((addr_modes.default_mode == PM16)
+ ^ (addr_modes.override.operand_size == OP_SIZE_PREFIX))) {
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_READ, s, 0x0e);
+ FPU_get_user(control_word, (unsigned short __user *)s);
+ FPU_get_user(partial_status, (unsigned short __user *)(s + 2));
+ FPU_get_user(tag_word, (unsigned short __user *)(s + 4));
+ FPU_get_user(instruction_address.offset,
+ (unsigned short __user *)(s + 6));
+ FPU_get_user(instruction_address.selector,
+ (unsigned short __user *)(s + 8));
+ FPU_get_user(operand_address.offset,
+ (unsigned short __user *)(s + 0x0a));
+ FPU_get_user(operand_address.selector,
+ (unsigned short __user *)(s + 0x0c));
+ RE_ENTRANT_CHECK_ON;
+ s += 0x0e;
+ if (addr_modes.default_mode == VM86) {
+ instruction_address.offset
+ += (instruction_address.selector & 0xf000) << 4;
+ operand_address.offset +=
+ (operand_address.selector & 0xf000) << 4;
+ }
+ } else {
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_READ, s, 0x1c);
+ FPU_get_user(control_word, (unsigned short __user *)s);
+ FPU_get_user(partial_status, (unsigned short __user *)(s + 4));
+ FPU_get_user(tag_word, (unsigned short __user *)(s + 8));
+ FPU_get_user(instruction_address.offset,
+ (unsigned long __user *)(s + 0x0c));
+ FPU_get_user(instruction_address.selector,
+ (unsigned short __user *)(s + 0x10));
+ FPU_get_user(instruction_address.opcode,
+ (unsigned short __user *)(s + 0x12));
+ FPU_get_user(operand_address.offset,
+ (unsigned long __user *)(s + 0x14));
+ FPU_get_user(operand_address.selector,
+ (unsigned long __user *)(s + 0x18));
+ RE_ENTRANT_CHECK_ON;
+ s += 0x1c;
}
- }
- else
- {
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_READ, s, 0x1c);
- FPU_get_user(control_word, (unsigned short __user *) s);
- FPU_get_user(partial_status, (unsigned short __user *) (s+4));
- FPU_get_user(tag_word, (unsigned short __user *) (s+8));
- FPU_get_user(instruction_address.offset, (unsigned long __user *) (s+0x0c));
- FPU_get_user(instruction_address.selector, (unsigned short __user *) (s+0x10));
- FPU_get_user(instruction_address.opcode, (unsigned short __user *) (s+0x12));
- FPU_get_user(operand_address.offset, (unsigned long __user *) (s+0x14));
- FPU_get_user(operand_address.selector, (unsigned long __user *) (s+0x18));
- RE_ENTRANT_CHECK_ON;
- s += 0x1c;
- }
#ifdef PECULIAR_486
- control_word &= ~0xe080;
-#endif /* PECULIAR_486 */
-
- top = (partial_status >> SW_Top_Shift) & 7;
-
- if ( partial_status & ~control_word & CW_Exceptions )
- partial_status |= (SW_Summary | SW_Backward);
- else
- partial_status &= ~(SW_Summary | SW_Backward);
-
- for ( i = 0; i < 8; i++ )
- {
- tag = tag_word & 3;
- tag_word >>= 2;
-
- if ( tag == TAG_Empty )
- /* New tag is empty. Accept it */
- FPU_settag(i, TAG_Empty);
- else if ( FPU_gettag(i) == TAG_Empty )
- {
- /* Old tag is empty and new tag is not empty. New tag is determined
- by old reg contents */
- if ( exponent(&fpu_register(i)) == - EXTENDED_Ebias )
- {
- if ( !(fpu_register(i).sigl | fpu_register(i).sigh) )
- FPU_settag(i, TAG_Zero);
- else
- FPU_settag(i, TAG_Special);
- }
- else if ( exponent(&fpu_register(i)) == 0x7fff - EXTENDED_Ebias )
- {
- FPU_settag(i, TAG_Special);
- }
- else if ( fpu_register(i).sigh & 0x80000000 )
- FPU_settag(i, TAG_Valid);
- else
- FPU_settag(i, TAG_Special); /* An Un-normal */
- }
- /* Else old tag is not empty and new tag is not empty. Old tag
- remains correct */
- }
-
- return s;
-}
+ control_word &= ~0xe080;
+#endif /* PECULIAR_486 */
+
+ top = (partial_status >> SW_Top_Shift) & 7;
+
+ if (partial_status & ~control_word & CW_Exceptions)
+ partial_status |= (SW_Summary | SW_Backward);
+ else
+ partial_status &= ~(SW_Summary | SW_Backward);
+
+ for (i = 0; i < 8; i++) {
+ tag = tag_word & 3;
+ tag_word >>= 2;
+
+ if (tag == TAG_Empty)
+ /* New tag is empty. Accept it */
+ FPU_settag(i, TAG_Empty);
+ else if (FPU_gettag(i) == TAG_Empty) {
+ /* Old tag is empty and new tag is not empty. New tag is determined
+ by old reg contents */
+ if (exponent(&fpu_register(i)) == -EXTENDED_Ebias) {
+ if (!
+ (fpu_register(i).sigl | fpu_register(i).
+ sigh))
+ FPU_settag(i, TAG_Zero);
+ else
+ FPU_settag(i, TAG_Special);
+ } else if (exponent(&fpu_register(i)) ==
+ 0x7fff - EXTENDED_Ebias) {
+ FPU_settag(i, TAG_Special);
+ } else if (fpu_register(i).sigh & 0x80000000)
+ FPU_settag(i, TAG_Valid);
+ else
+ FPU_settag(i, TAG_Special); /* An Un-normal */
+ }
+ /* Else old tag is not empty and new tag is not empty. Old tag
+ remains correct */
+ }
+ return s;
+}
-void frstor(fpu_addr_modes addr_modes, u_char __user *data_address)
+void frstor(fpu_addr_modes addr_modes, u_char __user * data_address)
{
- int i, regnr;
- u_char __user *s = fldenv(addr_modes, data_address);
- int offset = (top & 7) * 10, other = 80 - offset;
-
- /* Copy all registers in stack order. */
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_READ,s,80);
- __copy_from_user(register_base+offset, s, other);
- if ( offset )
- __copy_from_user(register_base, s+other, offset);
- RE_ENTRANT_CHECK_ON;
-
- for ( i = 0; i < 8; i++ )
- {
- regnr = (i+top) & 7;
- if ( FPU_gettag(regnr) != TAG_Empty )
- /* The loaded data over-rides all other cases. */
- FPU_settag(regnr, FPU_tagof(&st(i)));
- }
+ int i, regnr;
+ u_char __user *s = fldenv(addr_modes, data_address);
+ int offset = (top & 7) * 10, other = 80 - offset;
+
+ /* Copy all registers in stack order. */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_READ, s, 80);
+ __copy_from_user(register_base + offset, s, other);
+ if (offset)
+ __copy_from_user(register_base, s + other, offset);
+ RE_ENTRANT_CHECK_ON;
+
+ for (i = 0; i < 8; i++) {
+ regnr = (i + top) & 7;
+ if (FPU_gettag(regnr) != TAG_Empty)
+ /* The loaded data over-rides all other cases. */
+ FPU_settag(regnr, FPU_tagof(&st(i)));
+ }
}
-
-u_char __user *fstenv(fpu_addr_modes addr_modes, u_char __user *d)
+u_char __user *fstenv(fpu_addr_modes addr_modes, u_char __user * d)
{
- if ( (addr_modes.default_mode == VM86) ||
- ((addr_modes.default_mode == PM16)
- ^ (addr_modes.override.operand_size == OP_SIZE_PREFIX)) )
- {
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_WRITE,d,14);
+ if ((addr_modes.default_mode == VM86) ||
+ ((addr_modes.default_mode == PM16)
+ ^ (addr_modes.override.operand_size == OP_SIZE_PREFIX))) {
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_WRITE, d, 14);
#ifdef PECULIAR_486
- FPU_put_user(control_word & ~0xe080, (unsigned long __user *) d);
+ FPU_put_user(control_word & ~0xe080, (unsigned long __user *)d);
#else
- FPU_put_user(control_word, (unsigned short __user *) d);
+ FPU_put_user(control_word, (unsigned short __user *)d);
#endif /* PECULIAR_486 */
- FPU_put_user(status_word(), (unsigned short __user *) (d+2));
- FPU_put_user(fpu_tag_word, (unsigned short __user *) (d+4));
- FPU_put_user(instruction_address.offset, (unsigned short __user *) (d+6));
- FPU_put_user(operand_address.offset, (unsigned short __user *) (d+0x0a));
- if ( addr_modes.default_mode == VM86 )
- {
- FPU_put_user((instruction_address.offset & 0xf0000) >> 4,
- (unsigned short __user *) (d+8));
- FPU_put_user((operand_address.offset & 0xf0000) >> 4,
- (unsigned short __user *) (d+0x0c));
- }
- else
- {
- FPU_put_user(instruction_address.selector, (unsigned short __user *) (d+8));
- FPU_put_user(operand_address.selector, (unsigned short __user *) (d+0x0c));
- }
- RE_ENTRANT_CHECK_ON;
- d += 0x0e;
- }
- else
- {
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_WRITE, d, 7*4);
+ FPU_put_user(status_word(), (unsigned short __user *)(d + 2));
+ FPU_put_user(fpu_tag_word, (unsigned short __user *)(d + 4));
+ FPU_put_user(instruction_address.offset,
+ (unsigned short __user *)(d + 6));
+ FPU_put_user(operand_address.offset,
+ (unsigned short __user *)(d + 0x0a));
+ if (addr_modes.default_mode == VM86) {
+ FPU_put_user((instruction_address.
+ offset & 0xf0000) >> 4,
+ (unsigned short __user *)(d + 8));
+ FPU_put_user((operand_address.offset & 0xf0000) >> 4,
+ (unsigned short __user *)(d + 0x0c));
+ } else {
+ FPU_put_user(instruction_address.selector,
+ (unsigned short __user *)(d + 8));
+ FPU_put_user(operand_address.selector,
+ (unsigned short __user *)(d + 0x0c));
+ }
+ RE_ENTRANT_CHECK_ON;
+ d += 0x0e;
+ } else {
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_WRITE, d, 7 * 4);
#ifdef PECULIAR_486
- control_word &= ~0xe080;
- /* An 80486 sets nearly all of the reserved bits to 1. */
- control_word |= 0xffff0040;
- partial_status = status_word() | 0xffff0000;
- fpu_tag_word |= 0xffff0000;
- I387.soft.fcs &= ~0xf8000000;
- I387.soft.fos |= 0xffff0000;
+ control_word &= ~0xe080;
+ /* An 80486 sets nearly all of the reserved bits to 1. */
+ control_word |= 0xffff0040;
+ partial_status = status_word() | 0xffff0000;
+ fpu_tag_word |= 0xffff0000;
+ I387.soft.fcs &= ~0xf8000000;
+ I387.soft.fos |= 0xffff0000;
#endif /* PECULIAR_486 */
- if (__copy_to_user(d, &control_word, 7*4))
- FPU_abort;
- RE_ENTRANT_CHECK_ON;
- d += 0x1c;
- }
-
- control_word |= CW_Exceptions;
- partial_status &= ~(SW_Summary | SW_Backward);
-
- return d;
-}
+ if (__copy_to_user(d, &control_word, 7 * 4))
+ FPU_abort;
+ RE_ENTRANT_CHECK_ON;
+ d += 0x1c;
+ }
+ control_word |= CW_Exceptions;
+ partial_status &= ~(SW_Summary | SW_Backward);
+
+ return d;
+}
-void fsave(fpu_addr_modes addr_modes, u_char __user *data_address)
+void fsave(fpu_addr_modes addr_modes, u_char __user * data_address)
{
- u_char __user *d;
- int offset = (top & 7) * 10, other = 80 - offset;
+ u_char __user *d;
+ int offset = (top & 7) * 10, other = 80 - offset;
- d = fstenv(addr_modes, data_address);
+ d = fstenv(addr_modes, data_address);
- RE_ENTRANT_CHECK_OFF;
- FPU_access_ok(VERIFY_WRITE,d,80);
+ RE_ENTRANT_CHECK_OFF;
+ FPU_access_ok(VERIFY_WRITE, d, 80);
- /* Copy all registers in stack order. */
- if (__copy_to_user(d, register_base+offset, other))
- FPU_abort;
- if ( offset )
- if (__copy_to_user(d+other, register_base, offset))
- FPU_abort;
- RE_ENTRANT_CHECK_ON;
+ /* Copy all registers in stack order. */
+ if (__copy_to_user(d, register_base + offset, other))
+ FPU_abort;
+ if (offset)
+ if (__copy_to_user(d + other, register_base, offset))
+ FPU_abort;
+ RE_ENTRANT_CHECK_ON;
- finit();
+ finit();
}
/*===========================================================================*/
diff --git a/arch/x86/math-emu/reg_mul.c b/arch/x86/math-emu/reg_mul.c
index 40f50b61bc67..36c37f71f713 100644
--- a/arch/x86/math-emu/reg_mul.c
+++ b/arch/x86/math-emu/reg_mul.c
@@ -20,7 +20,6 @@
#include "reg_constant.h"
#include "fpu_system.h"
-
/*
Multiply two registers to give a register result.
The sources are st(deststnr) and (b,tagb,signb).
@@ -29,104 +28,88 @@
/* This routine must be called with non-empty source registers */
int FPU_mul(FPU_REG const *b, u_char tagb, int deststnr, int control_w)
{
- FPU_REG *a = &st(deststnr);
- FPU_REG *dest = a;
- u_char taga = FPU_gettagi(deststnr);
- u_char saved_sign = getsign(dest);
- u_char sign = (getsign(a) ^ getsign(b));
- int tag;
-
+ FPU_REG *a = &st(deststnr);
+ FPU_REG *dest = a;
+ u_char taga = FPU_gettagi(deststnr);
+ u_char saved_sign = getsign(dest);
+ u_char sign = (getsign(a) ^ getsign(b));
+ int tag;
- if ( !(taga | tagb) )
- {
- /* Both regs Valid, this should be the most common case. */
+ if (!(taga | tagb)) {
+ /* Both regs Valid, this should be the most common case. */
- tag = FPU_u_mul(a, b, dest, control_w, sign, exponent(a) + exponent(b));
- if ( tag < 0 )
- {
- setsign(dest, saved_sign);
- return tag;
+ tag =
+ FPU_u_mul(a, b, dest, control_w, sign,
+ exponent(a) + exponent(b));
+ if (tag < 0) {
+ setsign(dest, saved_sign);
+ return tag;
+ }
+ FPU_settagi(deststnr, tag);
+ return tag;
}
- FPU_settagi(deststnr, tag);
- return tag;
- }
- if ( taga == TAG_Special )
- taga = FPU_Special(a);
- if ( tagb == TAG_Special )
- tagb = FPU_Special(b);
+ if (taga == TAG_Special)
+ taga = FPU_Special(a);
+ if (tagb == TAG_Special)
+ tagb = FPU_Special(b);
- if ( ((taga == TAG_Valid) && (tagb == TW_Denormal))
+ if (((taga == TAG_Valid) && (tagb == TW_Denormal))
|| ((taga == TW_Denormal) && (tagb == TAG_Valid))
- || ((taga == TW_Denormal) && (tagb == TW_Denormal)) )
- {
- FPU_REG x, y;
- if ( denormal_operand() < 0 )
- return FPU_Exception;
-
- FPU_to_exp16(a, &x);
- FPU_to_exp16(b, &y);
- tag = FPU_u_mul(&x, &y, dest, control_w, sign,
- exponent16(&x) + exponent16(&y));
- if ( tag < 0 )
- {
- setsign(dest, saved_sign);
- return tag;
- }
- FPU_settagi(deststnr, tag);
- return tag;
- }
- else if ( (taga <= TW_Denormal) && (tagb <= TW_Denormal) )
- {
- if ( ((tagb == TW_Denormal) || (taga == TW_Denormal))
- && (denormal_operand() < 0) )
- return FPU_Exception;
+ || ((taga == TW_Denormal) && (tagb == TW_Denormal))) {
+ FPU_REG x, y;
+ if (denormal_operand() < 0)
+ return FPU_Exception;
- /* Must have either both arguments == zero, or
- one valid and the other zero.
- The result is therefore zero. */
- FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
- /* The 80486 book says that the answer is +0, but a real
- 80486 behaves this way.
- IEEE-754 apparently says it should be this way. */
- setsign(dest, sign);
- return TAG_Zero;
- }
- /* Must have infinities, NaNs, etc */
- else if ( (taga == TW_NaN) || (tagb == TW_NaN) )
- {
- return real_2op_NaN(b, tagb, deststnr, &st(0));
- }
- else if ( ((taga == TW_Infinity) && (tagb == TAG_Zero))
- || ((tagb == TW_Infinity) && (taga == TAG_Zero)) )
- {
- return arith_invalid(deststnr); /* Zero*Infinity is invalid */
- }
- else if ( ((taga == TW_Denormal) || (tagb == TW_Denormal))
- && (denormal_operand() < 0) )
- {
- return FPU_Exception;
- }
- else if (taga == TW_Infinity)
- {
- FPU_copy_to_regi(a, TAG_Special, deststnr);
- setsign(dest, sign);
- return TAG_Special;
- }
- else if (tagb == TW_Infinity)
- {
- FPU_copy_to_regi(b, TAG_Special, deststnr);
- setsign(dest, sign);
- return TAG_Special;
- }
+ FPU_to_exp16(a, &x);
+ FPU_to_exp16(b, &y);
+ tag = FPU_u_mul(&x, &y, dest, control_w, sign,
+ exponent16(&x) + exponent16(&y));
+ if (tag < 0) {
+ setsign(dest, saved_sign);
+ return tag;
+ }
+ FPU_settagi(deststnr, tag);
+ return tag;
+ } else if ((taga <= TW_Denormal) && (tagb <= TW_Denormal)) {
+ if (((tagb == TW_Denormal) || (taga == TW_Denormal))
+ && (denormal_operand() < 0))
+ return FPU_Exception;
+ /* Must have either both arguments == zero, or
+ one valid and the other zero.
+ The result is therefore zero. */
+ FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+ /* The 80486 book says that the answer is +0, but a real
+ 80486 behaves this way.
+ IEEE-754 apparently says it should be this way. */
+ setsign(dest, sign);
+ return TAG_Zero;
+ }
+ /* Must have infinities, NaNs, etc */
+ else if ((taga == TW_NaN) || (tagb == TW_NaN)) {
+ return real_2op_NaN(b, tagb, deststnr, &st(0));
+ } else if (((taga == TW_Infinity) && (tagb == TAG_Zero))
+ || ((tagb == TW_Infinity) && (taga == TAG_Zero))) {
+ return arith_invalid(deststnr); /* Zero*Infinity is invalid */
+ } else if (((taga == TW_Denormal) || (tagb == TW_Denormal))
+ && (denormal_operand() < 0)) {
+ return FPU_Exception;
+ } else if (taga == TW_Infinity) {
+ FPU_copy_to_regi(a, TAG_Special, deststnr);
+ setsign(dest, sign);
+ return TAG_Special;
+ } else if (tagb == TW_Infinity) {
+ FPU_copy_to_regi(b, TAG_Special, deststnr);
+ setsign(dest, sign);
+ return TAG_Special;
+ }
#ifdef PARANOID
- else
- {
- EXCEPTION(EX_INTERNAL|0x102);
- return FPU_Exception;
- }
-#endif /* PARANOID */
+ else {
+ EXCEPTION(EX_INTERNAL | 0x102);
+ return FPU_Exception;
+ }
+#endif /* PARANOID */
return 0;
}
diff --git a/arch/x86/math-emu/status_w.h b/arch/x86/math-emu/status_w.h
index 59e73302aa60..54a3f226982d 100644
--- a/arch/x86/math-emu/status_w.h
+++ b/arch/x86/math-emu/status_w.h
@@ -10,7 +10,7 @@
#ifndef _STATUS_H_
#define _STATUS_H_
-#include "fpu_emu.h" /* for definition of PECULIAR_486 */
+#include "fpu_emu.h" /* for definition of PECULIAR_486 */
#ifdef __ASSEMBLY__
#define Const__(x) $##x
@@ -34,7 +34,7 @@
#define SW_Denorm_Op Const__(0x0002) /* denormalized operand */
#define SW_Invalid Const__(0x0001) /* invalid operation */
-#define SW_Exc_Mask Const__(0x27f) /* Status word exception bit mask */
+#define SW_Exc_Mask Const__(0x27f) /* Status word exception bit mask */
#ifndef __ASSEMBLY__
@@ -50,8 +50,8 @@
((partial_status & ~SW_Top & 0xffff) | ((top << SW_Top_Shift) & SW_Top))
static inline void setcc(int cc)
{
- partial_status &= ~(SW_C0|SW_C1|SW_C2|SW_C3);
- partial_status |= (cc) & (SW_C0|SW_C1|SW_C2|SW_C3);
+ partial_status &= ~(SW_C0 | SW_C1 | SW_C2 | SW_C3);
+ partial_status |= (cc) & (SW_C0 | SW_C1 | SW_C2 | SW_C3);
}
#ifdef PECULIAR_486
commit a4ec1effce83796209a0258602b0cf50026d86f2
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Jan 30 13:30:10 2008 +0100
x86: mach-voyager, lindent
lindent the mach-voyager files to get rid of more than 300 style errors:
errors lines of code errors/KLOC
arch/x86/mach-voyager/ [old] 409 3729 109.6
arch/x86/mach-voyager/ [new] 71 3678 19.3
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/arch/x86/mach-voyager/setup.c b/arch/x86/mach-voyager/setup.c
index 3bef977cb29b..81257a861984 100644
--- a/arch/x86/mach-voyager/setup.c
+++ b/arch/x86/mach-voyager/setup.c
@@ -44,7 +44,7 @@ void __init trap_init_hook(void)
{
}
-static struct irqaction irq0 = {
+static struct irqaction irq0 = {
.handler = timer_interrupt,
.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL,
.mask = CPU_MASK_NONE,
@@ -59,44 +59,47 @@ void __init time_init_hook(void)
/* Hook for machine specific memory setup. */
-char * __init machine_specific_memory_setup(void)
+char *__init machine_specific_memory_setup(void)
{
char *who;
who = "NOT VOYAGER";
- if(voyager_level == 5) {
+ if (voyager_level == 5) {
__u32 addr, length;
int i;
who = "Voyager-SUS";
e820.nr_map = 0;
- for(i=0; voyager_memory_detect(i, &addr, &length); i++) {
+ for (i = 0; voyager_memory_detect(i, &addr, &length); i++) {
add_memory_region(addr, length, E820_RAM);
}
return who;
- } else if(voyager_level == 4) {
+ } else if (voyager_level == 4) {
__u32 tom;
- __u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT)<<8;
+ __u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT) << 8;
/* select the DINO config space */
outb(VOYAGER_DINO, VOYAGER_CAT_CONFIG_PORT);
/* Read DINO top of memory register */
tom = ((inb(catbase + 0x4) & 0xf0) << 16)
- + ((inb(catbase + 0x5) & 0x7f) << 24);
+ + ((inb(catbase + 0x5) & 0x7f) << 24);
- if(inb(catbase) != VOYAGER_DINO) {
- printk(KERN_ERR "Voyager: Failed to get DINO for L4, setting tom to EXT_MEM_K\n");
- tom = (boot_params.screen_info.ext_mem_k)<<10;
+ if (inb(catbase) != VOYAGER_DINO) {
+ printk(KERN_ERR
+ "Voyager: Failed to get DINO for L4, setting tom to EXT_MEM_K\n");
+ tom = (boot_params.screen_info.ext_mem_k) << 10;
}
who = "Voyager-TOM";
add_memory_region(0, 0x9f000, E820_RAM);
/* map from 1M to top of memory */
- add_memory_region(1*1024*1024, tom - 1*1024*1024, E820_RAM);
+ add_memory_region(1 * 1024 * 1024, tom - 1 * 1024 * 1024,
+ E820_RAM);
/* FIXME: Should check the ASICs to see if I need to
* take out the 8M window. Just do it at the moment
* */
- add_memory_region(8*1024*1024, 8*1024*1024, E820_RESERVED);
+ add_memory_region(8 * 1024 * 1024, 8 * 1024 * 1024,
+ E820_RESERVED);
return who;
}
@@ -114,8 +117,7 @@ char * __init machine_specific_memory_setup(void)
unsigned long mem_size;
/* compare results from other methods and take the greater */
- if (boot_params.alt_mem_k
- < boot_params.screen_info.ext_mem_k) {
+ if (boot_params.alt_mem_k < boot_params.screen_info.ext_mem_k) {
mem_size = boot_params.screen_info.ext_mem_k;
who = "BIOS-88";
} else {
@@ -126,6 +128,6 @@ char * __init machine_specific_memory_setup(void)
e820.nr_map = 0;
add_memory_region(0, LOWMEMSIZE(), E820_RAM);
add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
- }
+ }
return who;
}
diff --git a/arch/x86/mach-voyager/voyager_basic.c b/arch/x86/mach-voyager/voyager_basic.c
index 9b77b39b71a6..6a949e4edde8 100644
--- a/arch/x86/mach-voyager/voyager_basic.c
+++ b/arch/x86/mach-voyager/voyager_basic.c
@@ -35,7 +35,7 @@
/*
* Power off function, if any
*/
-void (*pm_power_off)(void);
+void (*pm_power_off) (void);
EXPORT_SYMBOL(pm_power_off);
int voyager_level = 0;
@@ -43,39 +43,38 @@ int voyager_level = 0;
struct voyager_SUS *voyager_SUS = NULL;
#ifdef CONFIG_SMP
-static void
-voyager_dump(int dummy1, struct tty_struct *dummy3)
+static void voyager_dump(int dummy1, struct tty_struct *dummy3)
{
/* get here via a sysrq */
voyager_smp_dump();
}
static struct sysrq_key_op sysrq_voyager_dump_op = {
- .handler = voyager_dump,
- .help_msg = "Voyager",
- .action_msg = "Dump Voyager Status",
+ .handler = voyager_dump,
+ .help_msg = "Voyager",
+ .action_msg = "Dump Voyager Status",
};
#endif
-void
-voyager_detect(struct voyager_bios_info *bios)
+void voyager_detect(struct voyager_bios_info *bios)
{
- if(bios->len != 0xff) {
- int class = (bios->class_1 << 8)
- | (bios->class_2 & 0xff);
+ if (bios->len != 0xff) {
+ int class = (bios->class_1 << 8)
+ | (bios->class_2 & 0xff);
printk("Voyager System detected.\n"
" Class %x, Revision %d.%d\n",
class, bios->major, bios->minor);
- if(class == VOYAGER_LEVEL4)
+ if (class == VOYAGER_LEVEL4)
voyager_level = 4;
- else if(class < VOYAGER_LEVEL5_AND_ABOVE)
+ else if (class < VOYAGER_LEVEL5_AND_ABOVE)
voyager_level = 3;
else
voyager_level = 5;
printk(" Architecture Level %d\n", voyager_level);
- if(voyager_level < 4)
- printk("\n**WARNING**: Voyager HAL only supports Levels 4 and 5 Architectures at the moment\n\n");
+ if (voyager_level < 4)
+ printk
+ ("\n**WARNING**: Voyager HAL only supports Levels 4 and 5 Architectures at the moment\n\n");
/* install the power off handler */
pm_power_off = voyager_power_off;
#ifdef CONFIG_SMP
@@ -86,15 +85,13 @@ voyager_detect(struct voyager_bios_info *bios)
}
}
-void
-voyager_system_interrupt(int cpl, void *dev_id)
+void voyager_system_interrupt(int cpl, void *dev_id)
{
printk("Voyager: detected system interrupt\n");
}
/* Routine to read information from the extended CMOS area */
-__u8
-voyager_extended_cmos_read(__u16 addr)
+__u8 voyager_extended_cmos_read(__u16 addr)
{
outb(addr & 0xff, 0x74);
outb((addr >> 8) & 0xff, 0x75);
@@ -108,12 +105,11 @@ voyager_extended_cmos_read(__u16 addr)
typedef struct ClickMap {
struct Entry {
- __u32 Address;
- __u32 Length;
+ __u32 Address;
+ __u32 Length;
} Entry[CLICK_ENTRIES];
} ClickMap_t;
-
/* This routine is pretty much an awful hack to read the bios clickmap by
* mapping it into page 0. There are usually three regions in the map:
* Base Memory
@@ -122,8 +118,7 @@ typedef struct ClickMap {
*
* Returns are 0 for failure and 1 for success on extracting region.
*/
-int __init
-voyager_memory_detect(int region, __u32 *start, __u32 *length)
+int __init voyager_memory_detect(int region, __u32 * start, __u32 * length)
{
int i;
int retval = 0;
@@ -132,13 +127,14 @@ voyager_memory_detect(int region, __u32 *start, __u32 *length)
unsigned long map_addr;
unsigned long old;
- if(region >= CLICK_ENTRIES) {
+ if (region >= CLICK_ENTRIES) {
printk("Voyager: Illegal ClickMap region %d\n", region);
return 0;
}
- for(i = 0; i < sizeof(cmos); i++)
- cmos[i] = voyager_extended_cmos_read(VOYAGER_MEMORY_CLICKMAP + i);
+ for (i = 0; i < sizeof(cmos); i++)
+ cmos[i] =
+ voyager_extended_cmos_read(VOYAGER_MEMORY_CLICKMAP + i);
map_addr = *(unsigned long *)cmos;
@@ -147,10 +143,10 @@ voyager_memory_detect(int region, __u32 *start, __u32 *length)
pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
local_flush_tlb();
/* now clear everything out but page 0 */
- map = (ClickMap_t *)(map_addr & (~PAGE_MASK));
+ map = (ClickMap_t *) (map_addr & (~PAGE_MASK));
/* zero length is the end of the clickmap */
- if(map->Entry[region].Length != 0) {
+ if (map->Entry[region].Length != 0) {
*length = map->Entry[region].Length * CLICK_SIZE;
*start = map->Entry[region].Address;
retval = 1;
@@ -165,10 +161,9 @@ voyager_memory_detect(int region, __u32 *start, __u32 *length)
/* voyager specific handling code for timer interrupts. Used to hand
* off the timer tick to the SMP code, since the VIC doesn't have an
* internal timer (The QIC does, but that's another story). */
-void
-voyager_timer_interrupt(void)
+void voyager_timer_interrupt(void)
{
- if((jiffies & 0x3ff) == 0) {
+ if ((jiffies & 0x3ff) == 0) {
/* There seems to be something flaky in either
* hardware or software that is resetting the timer 0
@@ -186,18 +181,20 @@ voyager_timer_interrupt(void)
__u16 val;
spin_lock(&i8253_lock);
-
+
outb_p(0x00, 0x43);
val = inb_p(0x40);
val |= inb(0x40) << 8;
spin_unlock(&i8253_lock);
- if(val > LATCH) {
- printk("\nVOYAGER: countdown timer value too high (%d), resetting\n\n", val);
+ if (val > LATCH) {
+ printk
+ ("\nVOYAGER: countdown timer value too high (%d), resetting\n\n",
+ val);
spin_lock(&i8253_lock);
- outb(0x34,0x43);
- outb_p(LATCH & 0xff , 0x40); /* LSB */
- outb(LATCH >> 8 , 0x40); /* MSB */
+ outb(0x34, 0x43);
+ outb_p(LATCH & 0xff, 0x40); /* LSB */
+ outb(LATCH >> 8, 0x40); /* MSB */
spin_unlock(&i8253_lock);
}
}
@@ -206,14 +203,13 @@ voyager_timer_interrupt(void)
#endif
}
-void
-voyager_power_off(void)
+void voyager_power_off(void)
{
printk("VOYAGER Power Off\n");
- if(voyager_level == 5) {
+ if (voyager_level == 5) {
voyager_cat_power_off();
- } else if(voyager_level == 4) {
+ } else if (voyager_level == 4) {
/* This doesn't apparently work on most L4 machines,
* but the specs say to do this to get automatic power
* off. Unfortunately, if it doesn't power off the
@@ -222,10 +218,8 @@ voyager_power_off(void)
#if 0
int port;
-
/* enable the voyager Configuration Space */
- outb((inb(VOYAGER_MC_SETUP) & 0xf0) | 0x8,
- VOYAGER_MC_SETUP);
+ outb((inb(VOYAGER_MC_SETUP) & 0xf0) | 0x8, VOYAGER_MC_SETUP);
/* the port for the power off flag is an offset from the
floating base */
port = (inb(VOYAGER_SSPB_RELOCATION_PORT) << 8) + 0x21;
@@ -235,62 +229,57 @@ voyager_power_off(void)
}
/* and wait for it to happen */
local_irq_disable();
- for(;;)
+ for (;;)
halt();
}
/* copied from process.c */
-static inline void
-kb_wait(void)
+static inline void kb_wait(void)
{
int i;
- for (i=0; i<0x10000; i++)
+ for (i = 0; i < 0x10000; i++)
if ((inb_p(0x64) & 0x02) == 0)
break;
}
-void
-machine_shutdown(void)
+void machine_shutdown(void)
{
/* Architecture specific shutdown needed before a kexec */
}
-void
-machine_restart(char *cmd)
+void machine_restart(char *cmd)
{
printk("Voyager Warm Restart\n");
kb_wait();
- if(voyager_level == 5) {
+ if (voyager_level == 5) {
/* write magic values to the RTC to inform system that
* shutdown is beginning */
outb(0x8f, 0x70);
- outb(0x5 , 0x71);
-
+ outb(0x5, 0x71);
+
udelay(50);
- outb(0xfe,0x64); /* pull reset low */
- } else if(voyager_level == 4) {
- __u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT)<<8;
+ outb(0xfe, 0x64); /* pull reset low */
+ } else if (voyager_level == 4) {
+ __u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT) << 8;
__u8 basebd = inb(VOYAGER_MC_SETUP);
-
+
outb(basebd | 0x08, VOYAGER_MC_SETUP);
outb(0x02, catbase + 0x21);
}
local_irq_disable();
- for(;;)
+ for (;;)
halt();
}
-void
-machine_emergency_restart(void)
+void machine_emergency_restart(void)
{
/*for now, just hook this to a warm restart */
machine_restart(NULL);
}
-void
-mca_nmi_hook(void)
+void mca_nmi_hook(void)
{
__u8 dumpval __maybe_unused = inb(0xf823);
__u8 swnmi __maybe_unused = inb(0xf813);
@@ -301,8 +290,8 @@ mca_nmi_hook(void)
/* clear swnmi */
outb(0xff, 0xf813);
/* tell SUS to ignore dump */
- if(voyager_level == 5 && voyager_SUS != NULL) {
- if(voyager_SUS->SUS_mbox == VOYAGER_DUMP_BUTTON_NMI) {
+ if (voyager_level == 5 && voyager_SUS != NULL) {
+ if (voyager_SUS->SUS_mbox == VOYAGER_DUMP_BUTTON_NMI) {
voyager_SUS->kernel_mbox = VOYAGER_NO_COMMAND;
voyager_SUS->kernel_flags |= VOYAGER_OS_IN_PROGRESS;
udelay(1000);
@@ -310,15 +299,14 @@ mca_nmi_hook(void)
voyager_SUS->kernel_flags &= ~VOYAGER_OS_IN_PROGRESS;
}
}
- printk(KERN_ERR "VOYAGER: Dump switch pressed, printing CPU%d tracebacks\n", smp_processor_id());
+ printk(KERN_ERR
+ "VOYAGER: Dump switch pressed, printing CPU%d tracebacks\n",
+ smp_processor_id());
show_stack(NULL, NULL);
show_state();
}
-
-
-void
-machine_halt(void)
+void machine_halt(void)
{
/* treat a halt like a power off */
machine_power_off();
diff --git a/arch/x86/mach-voyager/voyager_cat.c b/arch/x86/mach-voyager/voyager_cat.c
index 2132ca652df1..17a7904f75b1 100644
--- a/arch/x86/mach-voyager/voyager_cat.c
+++ b/arch/x86/mach-voyager/voyager_cat.c
@@ -39,34 +39,32 @@
#define CAT_DATA (sspb + 0xd)
/* the internal cat functions */
-static void cat_pack(__u8 *msg, __u16 start_bit, __u8 *data,
- __u16 num_bits);
-static void cat_unpack(__u8 *msg, __u16 start_bit, __u8 *data,
+static void cat_pack(__u8 * msg, __u16 start_bit, __u8 * data, __u16 num_bits);
+static void cat_unpack(__u8 * msg, __u16 start_bit, __u8 * data,
__u16 num_bits);
-static void cat_build_header(__u8 *header, const __u16 len,
+static void cat_build_header(__u8 * header, const __u16 len,
const __u16 smallest_reg_bits,
const __u16 longest_reg_bits);
-static int cat_sendinst(voyager_module_t *modp, voyager_asic_t *asicp,
+static int cat_sendinst(voyager_module_t * modp, voyager_asic_t * asicp,
__u8 reg, __u8 op);
-static int cat_getdata(voyager_module_t *modp, voyager_asic_t *asicp,
- __u8 reg, __u8 *value);
-static int cat_shiftout(__u8 *data, __u16 data_bytes, __u16 header_bytes,
+static int cat_getdata(voyager_module_t * modp, voyager_asic_t * asicp,
+ __u8 reg, __u8 * value);
+static int cat_shiftout(__u8 * data, __u16 data_bytes, __u16 header_bytes,
__u8 pad_bits);
-static int cat_write(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg,
+static int cat_write(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg,
__u8 value);
-static int cat_read(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg,
- __u8 *value);
-static int cat_subread(voyager_module_t *modp, voyager_asic_t *asicp,
+static int cat_read(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg,
+ __u8 * value);
+static int cat_subread(voyager_module_t * modp, voyager_asic_t * asicp,
__u16 offset, __u16 len, void *buf);
-static int cat_senddata(voyager_module_t *modp, voyager_asic_t *asicp,
+static int cat_senddata(voyager_module_t * modp, voyager_asic_t * asicp,
__u8 reg, __u8 value);
-static int cat_disconnect(voyager_module_t *modp, voyager_asic_t *asicp);
-static int cat_connect(voyager_module_t *modp, voyager_asic_t *asicp);
+static int cat_disconnect(voyager_module_t * modp, voyager_asic_t * asicp);
+static int cat_connect(voyager_module_t * modp, voyager_asic_t * asicp);
-static inline const char *
-cat_module_name(int module_id)
+static inline const char *cat_module_name(int module_id)
{
- switch(module_id) {
+ switch (module_id) {
case 0x10:
return "Processor Slot 0";
case 0x11:
@@ -105,14 +103,14 @@ voyager_module_t *voyager_cat_list;
/* the I/O port assignments for the VIC and QIC */
static struct resource vic_res = {
- .name = "Voyager Interrupt Controller",
- .start = 0xFC00,
- .end = 0xFC6F
+ .name = "Voyager Interrupt Controller",
+ .start = 0xFC00,
+ .end = 0xFC6F
};
static struct resource qic_res = {
- .name = "Quad Interrupt Controller",
- .start = 0xFC70,
- .end = 0xFCFF
+ .name = "Quad Interrupt Controller",
+ .start = 0xFC70,
+ .end = 0xFCFF
};
/* This function is used to pack a data bit stream inside a message.
@@ -120,7 +118,7 @@ static struct resource qic_res = {
* Note: This function assumes that any unused bit in the data stream
* is set to zero so that the ors will work correctly */
static void
-cat_pack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits)
+cat_pack(__u8 * msg, const __u16 start_bit, __u8 * data, const __u16 num_bits)
{
/* compute initial shift needed */
const __u16 offset = start_bit % BITS_PER_BYTE;
@@ -130,7 +128,7 @@ cat_pack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits)
int i;
/* adjust if we have more than a byte of residue */
- if(residue >= BITS_PER_BYTE) {
+ if (residue >= BITS_PER_BYTE) {
residue -= BITS_PER_BYTE;
len++;
}
@@ -138,24 +136,25 @@ cat_pack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits)
/* clear out the bits. We assume here that if len==0 then
* residue >= offset. This is always true for the catbus
* operations */
- msg[byte] &= 0xff << (BITS_PER_BYTE - offset);
+ msg[byte] &= 0xff << (BITS_PER_BYTE - offset);
msg[byte++] |= data[0] >> offset;
- if(len == 0)
+ if (len == 0)
return;
- for(i = 1; i < len; i++)
- msg[byte++] = (data[i-1] << (BITS_PER_BYTE - offset))
- | (data[i] >> offset);
- if(residue != 0) {
+ for (i = 1; i < len; i++)
+ msg[byte++] = (data[i - 1] << (BITS_PER_BYTE - offset))
+ | (data[i] >> offset);
+ if (residue != 0) {
__u8 mask = 0xff >> residue;
- __u8 last_byte = data[i-1] << (BITS_PER_BYTE - offset)
- | (data[i] >> offset);
-
+ __u8 last_byte = data[i - 1] << (BITS_PER_BYTE - offset)
+ | (data[i] >> offset);
+
last_byte &= ~mask;
msg[byte] &= mask;
msg[byte] |= last_byte;
}
return;
}
+
/* unpack the data again (same arguments as cat_pack()). data buffer
* must be zero populated.
*
@@ -163,7 +162,7 @@ cat_pack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits)
* data (starting at bit 0 in data).
*/
static void
-cat_unpack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits)
+cat_unpack(__u8 * msg, const __u16 start_bit, __u8 * data, const __u16 num_bits)
{
/* compute initial shift needed */
const __u16 offset = start_bit % BITS_PER_BYTE;
@@ -172,97 +171,97 @@ cat_unpack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits)
__u16 byte = start_bit / BITS_PER_BYTE;
int i;
- if(last_bits != 0)
+ if (last_bits != 0)
len++;
/* special case: want < 8 bits from msg and we can get it from
* a single byte of the msg */
- if(len == 0 && BITS_PER_BYTE - offset >= num_bits) {
+ if (len == 0 && BITS_PER_BYTE - offset >= num_bits) {
data[0] = msg[byte] << offset;
data[0] &= 0xff >> (BITS_PER_BYTE - num_bits);
return;
}
- for(i = 0; i < len; i++) {
+ for (i = 0; i < len; i++) {
/* this annoying if has to be done just in case a read of
* msg one beyond the array causes a panic */
- if(offset != 0) {
+ if (offset != 0) {
data[i] = msg[byte++] << offset;
data[i] |= msg[byte] >> (BITS_PER_BYTE - offset);
- }
- else {
+ } else {
data[i] = msg[byte++];
}
}
/* do we need to truncate the final byte */
- if(last_bits != 0) {
- data[i-1] &= 0xff << (BITS_PER_BYTE - last_bits);
+ if (last_bits != 0) {
+ data[i - 1] &= 0xff << (BITS_PER_BYTE - last_bits);
}
return;
}
static void
-cat_build_header(__u8 *header, const __u16 len, const __u16 smallest_reg_bits,
+cat_build_header(__u8 * header, const __u16 len, const __u16 smallest_reg_bits,
const __u16 longest_reg_bits)
{
int i;
__u16 start_bit = (smallest_reg_bits - 1) % BITS_PER_BYTE;
__u8 *last_byte = &header[len - 1];
- if(start_bit == 0)
+ if (start_bit == 0)
start_bit = 1; /* must have at least one bit in the hdr */
-
- for(i=0; i < len; i++)
+
+ for (i = 0; i < len; i++)
header[i] = 0;
- for(i = start_bit; i > 0; i--)
+ for (i = start_bit; i > 0; i--)
*last_byte = ((*last_byte) << 1) + 1;
}
static int
-cat_sendinst(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg, __u8 op)
+cat_sendinst(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg, __u8 op)
{
__u8 parity, inst, inst_buf[4] = { 0 };
__u8 iseq[VOYAGER_MAX_SCAN_PATH], hseq[VOYAGER_MAX_REG_SIZE];
__u16 ibytes, hbytes, padbits;
int i;
-
+
/*
* Parity is the parity of the register number + 1 (READ_REGISTER
* and WRITE_REGISTER always add '1' to the number of bits == 1)
*/
- parity = (__u8)(1 + (reg & 0x01) +
- ((__u8)(reg & 0x02) >> 1) +
- ((__u8)(reg & 0x04) >> 2) +
- ((__u8)(reg & 0x08) >> 3)) % 2;
+ parity = (__u8) (1 + (reg & 0x01) +
+ ((__u8) (reg & 0x02) >> 1) +
+ ((__u8) (reg & 0x04) >> 2) +
+ ((__u8) (reg & 0x08) >> 3)) % 2;
inst = ((parity << 7) | (reg << 2) | op);
outb(VOYAGER_CAT_IRCYC, CAT_CMD);
- if(!modp->scan_path_connected) {
- if(asicp->asic_id != VOYAGER_CAT_ID) {
- printk("**WARNING***: cat_sendinst has disconnected scan path not to CAT asic\n");
+ if (!modp->scan_path_connected) {
+ if (asicp->asic_id != VOYAGER_CAT_ID) {
+ printk
+ ("**WARNING***: cat_sendinst has disconnected scan path not to CAT asic\n");
return 1;
}
outb(VOYAGER_CAT_HEADER, CAT_DATA);
outb(inst, CAT_DATA);
- if(inb(CAT_DATA) != VOYAGER_CAT_HEADER) {
+ if (inb(CAT_DATA) != VOYAGER_CAT_HEADER) {
CDEBUG(("VOYAGER CAT: cat_sendinst failed to get CAT_HEADER\n"));
return 1;
}
return 0;
}
ibytes = modp->inst_bits / BITS_PER_BYTE;
- if((padbits = modp->inst_bits % BITS_PER_BYTE) != 0) {
+ if ((padbits = modp->inst_bits % BITS_PER_BYTE) != 0) {
padbits = BITS_PER_BYTE - padbits;
ibytes++;
}
hbytes = modp->largest_reg / BITS_PER_BYTE;
- if(modp->largest_reg % BITS_PER_BYTE)
+ if (modp->largest_reg % BITS_PER_BYTE)
hbytes++;
CDEBUG(("cat_sendinst: ibytes=%d, hbytes=%d\n", ibytes, hbytes));
/* initialise the instruction sequence to 0xff */
- for(i=0; i < ibytes + hbytes; i++)
+ for (i = 0; i < ibytes + hbytes; i++)
iseq[i] = 0xff;
cat_build_header(hseq, hbytes, modp->smallest_reg, modp->largest_reg);
cat_pack(iseq, modp->inst_bits, hseq, hbytes * BITS_PER_BYTE);
@@ -271,11 +270,11 @@ cat_sendinst(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg, __u8 op)
cat_pack(iseq, asicp->bit_location, inst_buf, asicp->ireg_length);
#ifdef VOYAGER_CAT_DEBUG
printk("ins = 0x%x, iseq: ", inst);
- for(i=0; i< ibytes + hbytes; i++)
+ for (i = 0; i < ibytes + hbytes; i++)
printk("0x%x ", iseq[i]);
printk("\n");
#endif
- if(cat_shiftout(iseq, ibytes, hbytes, padbits)) {
+ if (cat_shiftout(iseq, ibytes, hbytes, padbits)) {
CDEBUG(("VOYAGER CAT: cat_sendinst: cat_shiftout failed\n"));
return 1;
}
@@ -284,72 +283,74 @@ cat_sendinst(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg, __u8 op)
}
static int
-cat_getdata(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg,
- __u8 *value)
+cat_getdata(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg,
+ __u8 * value)
{
- if(!modp->scan_path_connected) {
- if(asicp->asic_id != VOYAGER_CAT_ID) {
+ if (!modp->scan_path_connected) {
+ if (asicp->asic_id != VOYAGER_CAT_ID) {
CDEBUG(("VOYAGER CAT: ERROR: cat_getdata to CAT asic with scan path connected\n"));
return 1;
}
- if(reg > VOYAGER_SUBADDRHI)
+ if (reg > VOYAGER_SUBADDRHI)
outb(VOYAGER_CAT_RUN, CAT_CMD);
outb(VOYAGER_CAT_DRCYC, CAT_CMD);
outb(VOYAGER_CAT_HEADER, CAT_DATA);
*value = inb(CAT_DATA);
outb(0xAA, CAT_DATA);
- if(inb(CAT_DATA) != VOYAGER_CAT_HEADER) {
+ if (inb(CAT_DATA) != VOYAGER_CAT_HEADER) {
CDEBUG(("cat_getdata: failed to get VOYAGER_CAT_HEADER\n"));
return 1;
}
return 0;
- }
- else {
- __u16 sbits = modp->num_asics -1 + asicp->ireg_length;
+ } else {
+ __u16 sbits = modp->num_asics - 1 + asicp->ireg_length;
__u16 sbytes = sbits / BITS_PER_BYTE;
__u16 tbytes;
- __u8 string[VOYAGER_MAX_SCAN_PATH], trailer[VOYAGER_MAX_REG_SIZE];
+ __u8 string[VOYAGER_MAX_SCAN_PATH],
+ trailer[VOYAGER_MAX_REG_SIZE];
__u8 padbits;
int i;
-
+
outb(VOYAGER_CAT_DRCYC, CAT_CMD);
- if((padbits = sbits % BITS_PER_BYTE) != 0) {
+ if ((padbits = sbits % BITS_PER_BYTE) != 0) {
padbits = BITS_PER_BYTE - padbits;
sbytes++;
}
tbytes = asicp->ireg_length / BITS_PER_BYTE;
- if(asicp->ireg_length % BITS_PER_BYTE)
+ if (asicp->ireg_length % BITS_PER_BYTE)
tbytes++;
CDEBUG(("cat_getdata: tbytes = %d, sbytes = %d, padbits = %d\n",
- tbytes, sbytes, padbits));
+ tbytes, sbytes, padbits));
cat_build_header(trailer, tbytes, 1, asicp->ireg_length);
-
- for(i = tbytes - 1; i >= 0; i--) {
+ for (i = tbytes - 1; i >= 0; i--) {
outb(trailer[i], CAT_DATA);
string[sbytes + i] = inb(CAT_DATA);
}
- for(i = sbytes - 1; i >= 0; i--) {
+ for (i = sbytes - 1; i >= 0; i--) {
outb(0xaa, CAT_DATA);
string[i] = inb(CAT_DATA);
}
*value = 0;
- cat_unpack(string, padbits + (tbytes * BITS_PER_BYTE) + asicp->asic_location, value, asicp->ireg_length);
+ cat_unpack(string,
+ padbits + (tbytes * BITS_PER_BYTE) +
+ asicp->asic_location, value, asicp->ireg_length);
#ifdef VOYAGER_CAT_DEBUG
printk("value=0x%x, string: ", *value);
- for(i=0; i< tbytes+sbytes; i++)
+ for (i = 0; i < tbytes + sbytes; i++)
printk("0x%x ", string[i]);
printk("\n");
#endif
-
+
/* sanity check the rest of the return */
- for(i=0; i < tbytes; i++) {
+ for (i = 0; i < tbytes; i++) {
__u8 input = 0;
- cat_unpack(string, padbits + (i * BITS_PER_BYTE), &input, BITS_PER_BYTE);
- if(trailer[i] != input) {
+ cat_unpack(string, padbits + (i * BITS_PER_BYTE),
+ &input, BITS_PER_BYTE);
+ if (trailer[i] != input) {
CDEBUG(("cat_getdata: failed to sanity check rest of ret(%d) 0x%x != 0x%x\n", i, input, trailer[i]));
return 1;
}
@@ -360,14 +361,14 @@ cat_getdata(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg,
}
static int
-cat_shiftout(__u8 *data, __u16 data_bytes, __u16 header_bytes, __u8 pad_bits)
+cat_shiftout(__u8 * data, __u16 data_bytes, __u16 header_bytes, __u8 pad_bits)
{
int i;
-
- for(i = data_bytes + header_bytes - 1; i >= header_bytes; i--)
+
+ for (i = data_bytes + header_bytes - 1; i >= header_bytes; i--)
outb(data[i], CAT_DATA);
- for(i = header_bytes - 1; i >= 0; i--) {
+ for (i = header_bytes - 1; i >= 0; i--) {
__u8 header = 0;
__u8 input;
@@ -376,7 +377,7 @@ cat_shiftout(__u8 *data, __u16 data_bytes, __u16 header_bytes, __u8 pad_bits)
CDEBUG(("cat_shiftout: returned 0x%x\n", input));
cat_unpack(data, ((data_bytes + i) * BITS_PER_BYTE) - pad_bits,
&header, BITS_PER_BYTE);
- if(input != header) {
+ if (input != header) {
CDEBUG(("VOYAGER CAT: cat_shiftout failed to return header 0x%x != 0x%x\n", input, header));
return 1;
}
@@ -385,57 +386,57 @@ cat_shiftout(__u8 *data, __u16 data_bytes, __u16 header_bytes, __u8 pad_bits)
}
static int
-cat_senddata(voyager_module_t *modp, voyager_asic_t *asicp,
+cat_senddata(voyager_module_t * modp, voyager_asic_t * asicp,
__u8 reg, __u8 value)
{
outb(VOYAGER_CAT_DRCYC, CAT_CMD);
- if(!modp->scan_path_connected) {
- if(asicp->asic_id != VOYAGER_CAT_ID) {
+ if (!modp->scan_path_connected) {
+ if (asicp->asic_id != VOYAGER_CAT_ID) {
CDEBUG(("VOYAGER CAT: ERROR: scan path disconnected when asic != CAT\n"));
return 1;
}
outb(VOYAGER_CAT_HEADER, CAT_DATA);
outb(value, CAT_DATA);
- if(inb(CAT_DATA) != VOYAGER_CAT_HEADER) {
+ if (inb(CAT_DATA) != VOYAGER_CAT_HEADER) {
CDEBUG(("cat_senddata: failed to get correct header response to sent data\n"));
return 1;
}
- if(reg > VOYAGER_SUBADDRHI) {
+ if (reg > VOYAGER_SUBADDRHI) {
outb(VOYAGER_CAT_RUN, CAT_CMD);
outb(VOYAGER_CAT_END, CAT_CMD);
outb(VOYAGER_CAT_RUN, CAT_CMD);
}
-
+
return 0;
- }
- else {
+ } else {
__u16 hbytes = asicp->ireg_length / BITS_PER_BYTE;
- __u16 dbytes = (modp->num_asics - 1 + asicp->ireg_length)/BITS_PER_BYTE;
- __u8 padbits, dseq[VOYAGER_MAX_SCAN_PATH],
- hseq[VOYAGER_MAX_REG_SIZE];
+ __u16 dbytes =
+ (modp->num_asics - 1 + asicp->ireg_length) / BITS_PER_BYTE;
+ __u8 padbits, dseq[VOYAGER_MAX_SCAN_PATH],
+ hseq[VOYAGER_MAX_REG_SIZE];
int i;
- if((padbits = (modp->num_asics - 1
- + asicp->ireg_length) % BITS_PER_BYTE) != 0) {
+ if ((padbits = (modp->num_asics - 1
+ + asicp->ireg_length) % BITS_PER_BYTE) != 0) {
padbits = BITS_PER_BYTE - padbits;
dbytes++;
}
- if(asicp->ireg_length % BITS_PER_BYTE)
+ if (asicp->ireg_length % BITS_PER_BYTE)
hbytes++;
-
+
cat_build_header(hseq, hbytes, 1, asicp->ireg_length);
-
- for(i = 0; i < dbytes + hbytes; i++)
+
+ for (i = 0; i < dbytes + hbytes; i++)
dseq[i] = 0xff;
CDEBUG(("cat_senddata: dbytes=%d, hbytes=%d, padbits=%d\n",
dbytes, hbytes, padbits));
cat_pack(dseq, modp->num_asics - 1 + asicp->ireg_length,
hseq, hbytes * BITS_PER_BYTE);
- cat_pack(dseq, asicp->asic_location, &value,
+ cat_pack(dseq, asicp->asic_location, &value,
asicp->ireg_length);
#ifdef VOYAGER_CAT_DEBUG
printk("dseq ");
- for(i=0; i<hbytes+dbytes; i++) {
+ for (i = 0; i < hbytes + dbytes; i++) {
printk("0x%x ", dseq[i]);
}
printk("\n");
@@ -445,121 +446,125 @@ cat_senddata(voyager_module_t *modp, voyager_asic_t *asicp,
}
static int
-cat_write(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg,
- __u8 value)
+cat_write(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg, __u8 value)
{
- if(cat_sendinst(modp, asicp, reg, VOYAGER_WRITE_CONFIG))
+ if (cat_sendinst(modp, asicp, reg, VOYAGER_WRITE_CONFIG))
return 1;
return cat_senddata(modp, asicp, reg, value);
}
static int
-cat_read(voyager_module_t *modp, voyager_asic_t *asicp, __u8 reg,
- __u8 *value)
+cat_read(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg,
+ __u8 * value)
{
- if(cat_sendinst(modp, asicp, reg, VOYAGER_READ_CONFIG))
+ if (cat_sendinst(modp, asicp, reg, VOYAGER_READ_CONFIG))
return 1;
return cat_getdata(modp, asicp, reg, value);
}
static int
-cat_subaddrsetup(voyager_module_t *modp, voyager_asic_t *asicp, __u16 offset,
+cat_subaddrsetup(voyager_module_t * modp, voyager_asic_t * asicp, __u16 offset,
__u16 len)
{
__u8 val;
- if(len > 1) {
+ if (len > 1) {
/* set auto increment */
__u8 newval;
-
- if(cat_read(modp, asicp, VOYAGER_AUTO_INC_REG, &val)) {
+
+ if (cat_read(modp, asicp, VOYAGER_AUTO_INC_REG, &val)) {
CDEBUG(("cat_subaddrsetup: read of VOYAGER_AUTO_INC_REG failed\n"));
return 1;
}
- CDEBUG(("cat_subaddrsetup: VOYAGER_AUTO_INC_REG = 0x%x\n", val));
+ CDEBUG(("cat_subaddrsetup: VOYAGER_AUTO_INC_REG = 0x%x\n",
+ val));
newval = val | VOYAGER_AUTO_INC;
- if(newval != val) {
- if(cat_write(modp, asicp, VOYAGER_AUTO_INC_REG, val)) {
+ if (newval != val) {
+ if (cat_write(modp, asicp, VOYAGER_AUTO_INC_REG, val)) {
CDEBUG(("cat_subaddrsetup: write to VOYAGER_AUTO_INC_REG failed\n"));
return 1;
}
}
}
- if(cat_write(modp, asicp, VOYAGER_SUBADDRLO, (__u8)(offset &0xff))) {
+ if (cat_write(modp, asicp, VOYAGER_SUBADDRLO, (__u8) (offset & 0xff))) {
CDEBUG(("cat_subaddrsetup: write to SUBADDRLO failed\n"));
return 1;
}
- if(asicp->subaddr > VOYAGER_SUBADDR_LO) {
- if(cat_write(modp, asicp, VOYAGER_SUBADDRHI, (__u8)(offset >> 8))) {
+ if (asicp->subaddr > VOYAGER_SUBADDR_LO) {
+ if (cat_write
+ (modp, asicp, VOYAGER_SUBADDRHI, (__u8) (offset >> 8))) {
CDEBUG(("cat_subaddrsetup: write to SUBADDRHI failed\n"));
return 1;
}
cat_read(modp, asicp, VOYAGER_SUBADDRHI, &val);
- CDEBUG(("cat_subaddrsetup: offset = %d, hi = %d\n", offset, val));
+ CDEBUG(("cat_subaddrsetup: offset = %d, hi = %d\n", offset,
+ val));
}
cat_read(modp, asicp, VOYAGER_SUBADDRLO, &val);
CDEBUG(("cat_subaddrsetup: offset = %d, lo = %d\n", offset, val));
return 0;
}
-
+
static int
-cat_subwrite(voyager_module_t *modp, voyager_asic_t *asicp, __u16 offset,
- __u16 len, void *buf)
+cat_subwrite(voyager_module_t * modp, voyager_asic_t * asicp, __u16 offset,
+ __u16 len, void *buf)
{
int i, retval;
/* FIXME: need special actions for VOYAGER_CAT_ID here */
- if(asicp->asic_id == VOYAGER_CAT_ID) {
+ if (asicp->asic_id == VOYAGER_CAT_ID) {
CDEBUG(("cat_subwrite: ATTEMPT TO WRITE TO CAT ASIC\n"));
/* FIXME -- This is supposed to be handled better
* There is a problem writing to the cat asic in the
* PSI. The 30us delay seems to work, though */
udelay(30);
}
-
- if((retval = cat_subaddrsetup(modp, asicp, offset, len)) != 0) {
+
+ if ((retval = cat_subaddrsetup(modp, asicp, offset, len)) != 0) {
printk("cat_subwrite: cat_subaddrsetup FAILED\n");
return retval;
}
-
- if(cat_sendinst(modp, asicp, VOYAGER_SUBADDRDATA, VOYAGER_WRITE_CONFIG)) {
+
+ if (cat_sendinst
+ (modp, asicp, VOYAGER_SUBADDRDATA, VOYAGER_WRITE_CONFIG)) {
printk("cat_subwrite: cat_sendinst FAILED\n");
return 1;
}
- for(i = 0; i < len; i++) {
- if(cat_senddata(modp, asicp, 0xFF, ((__u8 *)buf)[i])) {
- printk("cat_subwrite: cat_sendata element at %d FAILED\n", i);
+ for (i = 0; i < len; i++) {
+ if (cat_senddata(modp, asicp, 0xFF, ((__u8 *) buf)[i])) {
+ printk
+ ("cat_subwrite: cat_sendata element at %d FAILED\n",
+ i);
return 1;
}
}
return 0;
}
static int
-cat_subread(voyager_module_t *modp, voyager_asic_t *asicp, __u16 offset,
+cat_subread(voyager_module_t * modp, voyager_asic_t * asicp, __u16 offset,
__u16 len, void *buf)
{
int i, retval;
- if((retval = cat_subaddrsetup(modp, asicp, offset, len)) != 0) {
+ if ((retval = cat_subaddrsetup(modp, asicp, offset, len)) != 0) {
CDEBUG(("cat_subread: cat_subaddrsetup FAILED\n"));
return retval;
}
- if(cat_sendinst(modp, asicp, VOYAGER_SUBADDRDATA, VOYAGER_READ_CONFIG)) {
+ if (cat_sendinst(modp, asicp, VOYAGER_SUBADDRDATA, VOYAGER_READ_CONFIG)) {
CDEBUG(("cat_subread: cat_sendinst failed\n"));
return 1;
}
- for(i = 0; i < len; i++) {
- if(cat_getdata(modp, asicp, 0xFF,
- &((__u8 *)buf)[i])) {
- CDEBUG(("cat_subread: cat_getdata element %d failed\n", i));
+ for (i = 0; i < len; i++) {
+ if (cat_getdata(modp, asicp, 0xFF, &((__u8 *) buf)[i])) {
+ CDEBUG(("cat_subread: cat_getdata element %d failed\n",
+ i));
return 1;
}
}
return 0;
}
-
/* buffer for storing EPROM data read in during initialisation */
static __initdata __u8 eprom_buf[0xFFFF];
static voyager_module_t *voyager_initial_module;
@@ -568,8 +573,7 @@ static voyager_module_t *voyager_initial_module;
* boot cpu *after* all memory initialisation has been done (so we can
* use kmalloc) but before smp initialisation, so we can probe the SMP
* configuration and pick up necessary information. */
-void __init
-voyager_cat_init(void)
+void __init voyager_cat_init(void)
{
voyager_module_t **modpp = &voyager_initial_module;
voyager_asic_t **asicpp;
@@ -578,27 +582,29 @@ voyager_cat_init(void)
unsigned long qic_addr = 0;
__u8 qabc_data[0x20];
__u8 num_submodules, val;
- voyager_eprom_hdr_t *eprom_hdr = (voyager_eprom_hdr_t *)&eprom_buf[0];
-
+ voyager_eprom_hdr_t *eprom_hdr = (voyager_eprom_hdr_t *) & eprom_buf[0];
+
__u8 cmos[4];
unsigned long addr;
-
+
/* initiallise the SUS mailbox */
- for(i=0; i<sizeof(cmos); i++)
+ for (i = 0; i < sizeof(cmos); i++)
cmos[i] = voyager_extended_cmos_read(VOYAGER_DUMP_LOCATION + i);
addr = *(unsigned long *)cmos;
- if((addr & 0xff000000) != 0xff000000) {
- printk(KERN_ERR "Voyager failed to get SUS mailbox (addr = 0x%lx\n", addr);
+ if ((addr & 0xff000000) != 0xff000000) {
+ printk(KERN_ERR
+ "Voyager failed to get SUS mailbox (addr = 0x%lx\n",
+ addr);
} else {
static struct resource res;
-
+
res.name = "voyager SUS";
res.start = addr;
- res.end = addr+0x3ff;
-
+ res.end = addr + 0x3ff;
+
request_resource(&iomem_resource, &res);
voyager_SUS = (struct voyager_SUS *)
- ioremap(addr, 0x400);
+ ioremap(addr, 0x400);
printk(KERN_NOTICE "Voyager SUS mailbox version 0x%x\n",
voyager_SUS->SUS_version);
voyager_SUS->kernel_version = VOYAGER_MAILBOX_VERSION;
@@ -609,8 +615,6 @@ voyager_cat_init(void)
voyager_extended_vic_processors = 0;
voyager_quad_processors = 0;
-
-
printk("VOYAGER: beginning CAT bus probe\n");
/* set up the SuperSet Port Block which tells us where the
* CAT communication port is */
@@ -618,14 +622,14 @@ voyager_cat_init(void)
VDEBUG(("VOYAGER DEBUG: sspb = 0x%x\n", sspb));
/* now find out if were 8 slot or normal */
- if((inb(VIC_PROC_WHO_AM_I) & EIGHT_SLOT_IDENTIFIER)
- == EIGHT_SLOT_IDENTIFIER) {
+ if ((inb(VIC_PROC_WHO_AM_I) & EIGHT_SLOT_IDENTIFIER)
+ == EIGHT_SLOT_IDENTIFIER) {
voyager_8slot = 1;
- printk(KERN_NOTICE "Voyager: Eight slot 51xx configuration detected\n");
+ printk(KERN_NOTICE
+ "Voyager: Eight slot 51xx configuration detected\n");
}
- for(i = VOYAGER_MIN_MODULE;
- i <= VOYAGER_MAX_MODULE; i++) {
+ for (i = VOYAGER_MIN_MODULE; i <= VOYAGER_MAX_MODULE; i++) {
__u8 input;
int asic;
__u16 eprom_size;
@@ -643,21 +647,21 @@ voyager_cat_init(void)
outb(0xAA, CAT_DATA);
input = inb(CAT_DATA);
outb(VOYAGER_CAT_END, CAT_CMD);
- if(input != VOYAGER_CAT_HEADER) {
+ if (input != VOYAGER_CAT_HEADER) {
continue;
}
CDEBUG(("VOYAGER DEBUG: found module id 0x%x, %s\n", i,
cat_module_name(i)));
- *modpp = kmalloc(sizeof(voyager_module_t), GFP_KERNEL); /*&voyager_module_storage[cat_count++];*/
- if(*modpp == NULL) {
+ *modpp = kmalloc(sizeof(voyager_module_t), GFP_KERNEL); /*&voyager_module_storage[cat_count++]; */
+ if (*modpp == NULL) {
printk("**WARNING** kmalloc failure in cat_init\n");
continue;
}
memset(*modpp, 0, sizeof(voyager_module_t));
/* need temporary asic for cat_subread. It will be
* filled in correctly later */
- (*modpp)->asic = kmalloc(sizeof(voyager_asic_t), GFP_KERNEL); /*&voyager_asic_storage[asic_count];*/
- if((*modpp)->asic == NULL) {
+ (*modpp)->asic = kmalloc(sizeof(voyager_asic_t), GFP_KERNEL); /*&voyager_asic_storage[asic_count]; */
+ if ((*modpp)->asic == NULL) {
printk("**WARNING** kmalloc failure in cat_init\n");
continue;
}
@@ -666,47 +670,52 @@ voyager_cat_init(void)
(*modpp)->asic->subaddr = VOYAGER_SUBADDR_HI;
(*modpp)->module_addr = i;
(*modpp)->scan_path_connected = 0;
- if(i == VOYAGER_PSI) {
+ if (i == VOYAGER_PSI) {
/* Exception leg for modules with no EEPROM */
printk("Module \"%s\"\n", cat_module_name(i));
continue;
}
-
+
CDEBUG(("cat_init: Reading eeprom for module 0x%x at offset %d\n", i, VOYAGER_XSUM_END_OFFSET));
outb(VOYAGER_CAT_RUN, CAT_CMD);
cat_disconnect(*modpp, (*modpp)->asic);
- if(cat_subread(*modpp, (*modpp)->asic,
- VOYAGER_XSUM_END_OFFSET, sizeof(eprom_size),
- &eprom_size)) {
- printk("**WARNING**: Voyager couldn't read EPROM size for module 0x%x\n", i);
+ if (cat_subread(*modpp, (*modpp)->asic,
+ VOYAGER_XSUM_END_OFFSET, sizeof(eprom_size),
+ &eprom_size)) {
+ printk
+ ("**WARNING**: Voyager couldn't read EPROM size for module 0x%x\n",
+ i);
outb(VOYAGER_CAT_END, CAT_CMD);
continue;
}
- if(eprom_size > sizeof(eprom_buf)) {
- printk("**WARNING**: Voyager insufficient size to read EPROM data, module 0x%x. Need %d\n", i, eprom_size);
+ if (eprom_size > sizeof(eprom_buf)) {
+ printk
+ ("**WARNING**: Voyager insufficient size to read EPROM data, module 0x%x. Need %d\n",
+ i, eprom_size);
outb(VOYAGER_CAT_END, CAT_CMD);
continue;
}
outb(VOYAGER_CAT_END, CAT_CMD);
outb(VOYAGER_CAT_RUN, CAT_CMD);
- CDEBUG(("cat_init: module 0x%x, eeprom_size %d\n", i, eprom_size));
- if(cat_subread(*modpp, (*modpp)->asic, 0,
- eprom_size, eprom_buf)) {
+ CDEBUG(("cat_init: module 0x%x, eeprom_size %d\n", i,
+ eprom_size));
+ if (cat_subread
+ (*modpp, (*modpp)->asic, 0, eprom_size, eprom_buf)) {
outb(VOYAGER_CAT_END, CAT_CMD);
continue;
}
outb(VOYAGER_CAT_END, CAT_CMD);
printk("Module \"%s\", version 0x%x, tracer 0x%x, asics %d\n",
cat_module_name(i), eprom_hdr->version_id,
- *((__u32 *)eprom_hdr->tracer), eprom_hdr->num_asics);
+ *((__u32 *) eprom_hdr->tracer), eprom_hdr->num_asics);
(*modpp)->ee_size = eprom_hdr->ee_size;
(*modpp)->num_asics = eprom_hdr->num_asics;
asicpp = &((*modpp)->asic);
sp_offset = eprom_hdr->scan_path_offset;
/* All we really care about are the Quad cards. We
- * identify them because they are in a processor slot
- * and have only four asics */
- if((i < 0x10 || (i>=0x14 && i < 0x1c) || i>0x1f)) {
+ * identify them because they are in a processor slot
+ * and have only four asics */
+ if ((i < 0x10 || (i >= 0x14 && i < 0x1c) || i > 0x1f)) {
modpp = &((*modpp)->next);
continue;
}
@@ -717,16 +726,17 @@ voyager_cat_init(void)
&num_submodules);
/* lowest two bits, active low */
num_submodules = ~(0xfc | num_submodules);
- CDEBUG(("VOYAGER CAT: %d submodules present\n", num_submodules));
- if(num_submodules == 0) {
+ CDEBUG(("VOYAGER CAT: %d submodules present\n",
+ num_submodules));
+ if (num_submodules == 0) {
/* fill in the dyadic extended processors */
__u8 cpu = i & 0x07;
printk("Module \"%s\": Dyadic Processor Card\n",
cat_module_name(i));
- voyager_extended_vic_processors |= (1<<cpu);
+ voyager_extended_vic_processors |= (1 << cpu);
cpu += 4;
- voyager_extended_vic_processors |= (1<<cpu);
+ voyager_extended_vic_processors |= (1 << cpu);
outb(VOYAGER_CAT_END, CAT_CMD);
continue;
}
@@ -740,28 +750,32 @@ voyager_cat_init(void)
cat_write(*modpp, (*modpp)->asic, VOYAGER_SUBMODSELECT, val);
outb(VOYAGER_CAT_END, CAT_CMD);
-
CDEBUG(("cat_init: Reading eeprom for module 0x%x at offset %d\n", i, VOYAGER_XSUM_END_OFFSET));
outb(VOYAGER_CAT_RUN, CAT_CMD);
cat_disconnect(*modpp, (*modpp)->asic);
- if(cat_subread(*modpp, (*modpp)->asic,
- VOYAGER_XSUM_END_OFFSET, sizeof(eprom_size),
- &eprom_size)) {
- printk("**WARNING**: Voyager couldn't read EPROM size for module 0x%x\n", i);
+ if (cat_subread(*modpp, (*modpp)->asic,
+ VOYAGER_XSUM_END_OFFSET, sizeof(eprom_size),
+ &eprom_size)) {
+ printk
+ ("**WARNING**: Voyager couldn't read EPROM size for module 0x%x\n",
+ i);
outb(VOYAGER_CAT_END, CAT_CMD);
continue;
}
- if(eprom_size > sizeof(eprom_buf)) {
- printk("**WARNING**: Voyager insufficient size to read EPROM data, module 0x%x. Need %d\n", i, eprom_size);
+ if (eprom_size > sizeof(eprom_buf)) {
+ printk
+ ("**WARNING**: Voyager insufficient size to read EPROM data, module 0x%x. Need %d\n",
+ i, eprom_size);
outb(VOYAGER_CAT_END, CAT_CMD);
continue;
}
outb(VOYAGER_CAT_END, CAT_CMD);
outb(VOYAGER_CAT_RUN, CAT_CMD);
- CDEBUG(("cat_init: module 0x%x, eeprom_size %d\n", i, eprom_size));
- if(cat_subread(*modpp, (*modpp)->asic, 0,
- eprom_size, eprom_buf)) {
+ CDEBUG(("cat_init: module 0x%x, eeprom_size %d\n", i,
+ eprom_size));
+ if (cat_subread
+ (*modpp, (*modpp)->asic, 0, eprom_size, eprom_buf)) {
outb(VOYAGER_CAT_END, CAT_CMD);
continue;
}
@@ -773,30 +787,35 @@ voyager_cat_init(void)
sp_offset = eprom_hdr->scan_path_offset;
/* get rid of the dummy CAT asic and read the real one */
kfree((*modpp)->asic);
- for(asic=0; asic < (*modpp)->num_asics; asic++) {
+ for (asic = 0; asic < (*modpp)->num_asics; asic++) {
int j;
- voyager_asic_t *asicp = *asicpp
- = kzalloc(sizeof(voyager_asic_t), GFP_KERNEL); /*&voyager_asic_storage[asic_count++];*/
+ voyager_asic_t *asicp = *asicpp = kzalloc(sizeof(voyager_asic_t), GFP_KERNEL); /*&voyager_asic_storage[asic_count++]; */
voyager_sp_table_t *sp_table;
voyager_at_t *asic_table;
voyager_jtt_t *jtag_table;
- if(asicp == NULL) {
- printk("**WARNING** kmalloc failure in cat_init\n");
+ if (asicp == NULL) {
+ printk
+ ("**WARNING** kmalloc failure in cat_init\n");
continue;
}
asicpp = &(asicp->next);
asicp->asic_location = asic;
- sp_table = (voyager_sp_table_t *)(eprom_buf + sp_offset);
+ sp_table =
+ (voyager_sp_table_t *) (eprom_buf + sp_offset);
asicp->asic_id = sp_table->asic_id;
- asic_table = (voyager_at_t *)(eprom_buf + sp_table->asic_data_offset);
- for(j=0; j<4; j++)
+ asic_table =
+ (voyager_at_t *) (eprom_buf +
+ sp_table->asic_data_offset);
+ for (j = 0; j < 4; j++)
asicp->jtag_id[j] = asic_table->jtag_id[j];
- jtag_table = (voyager_jtt_t *)(eprom_buf + asic_table->jtag_offset);
+ jtag_table =
+ (voyager_jtt_t *) (eprom_buf +
+ asic_table->jtag_offset);
asicp->ireg_length = jtag_table->ireg_len;
asicp->bit_location = (*modpp)->inst_bits;
(*modpp)->inst_bits += asicp->ireg_length;
- if(asicp->ireg_length > (*modpp)->largest_reg)
+ if (asicp->ireg_length > (*modpp)->largest_reg)
(*modpp)->largest_reg = asicp->ireg_length;
if (asicp->ireg_length < (*modpp)->smallest_reg ||
(*modpp)->smallest_reg == 0)
@@ -804,15 +823,13 @@ voyager_cat_init(void)
CDEBUG(("asic 0x%x, ireg_length=%d, bit_location=%d\n",
asicp->asic_id, asicp->ireg_length,
asicp->bit_location));
- if(asicp->asic_id == VOYAGER_QUAD_QABC) {
+ if (asicp->asic_id == VOYAGER_QUAD_QABC) {
CDEBUG(("VOYAGER CAT: QABC ASIC found\n"));
qabc_asic = asicp;
}
sp_offset += sizeof(voyager_sp_table_t);
}
- CDEBUG(("Module inst_bits = %d, largest_reg = %d, smallest_reg=%d\n",
- (*modpp)->inst_bits, (*modpp)->largest_reg,
- (*modpp)->smallest_reg));
+ CDEBUG(("Module inst_bits = %d, largest_reg = %d, smallest_reg=%d\n", (*modpp)->inst_bits, (*modpp)->largest_reg, (*modpp)->smallest_reg));
/* OK, now we have the QUAD ASICs set up, use them.
* we need to:
*
@@ -828,10 +845,11 @@ voyager_cat_init(void)
qic_addr = qabc_data[5] << 8;
qic_addr = (qic_addr | qabc_data[6]) << 8;
qic_addr = (qic_addr | qabc_data[7]) << 8;
- printk("Module \"%s\": Quad Processor Card; CPI 0x%lx, SET=0x%x\n",
- cat_module_name(i), qic_addr, qabc_data[8]);
+ printk
+ ("Module \"%s\": Quad Processor Card; CPI 0x%lx, SET=0x%x\n",
+ cat_module_name(i), qic_addr, qabc_data[8]);
#if 0 /* plumbing fails---FIXME */
- if((qabc_data[8] & 0xf0) == 0) {
+ if ((qabc_data[8] & 0xf0) == 0) {
/* FIXME: 32 way 8 CPU slot monster cannot be
* plumbed this way---need to check for it */
@@ -842,94 +860,97 @@ voyager_cat_init(void)
#ifdef VOYAGER_CAT_DEBUG
/* verify plumbing */
cat_subread(*modpp, qabc_asic, 8, 1, &qabc_data[8]);
- if((qabc_data[8] & 0xf0) == 0) {
- CDEBUG(("PLUMBING FAILED: 0x%x\n", qabc_data[8]));
+ if ((qabc_data[8] & 0xf0) == 0) {
+ CDEBUG(("PLUMBING FAILED: 0x%x\n",
+ qabc_data[8]));
}
#endif
}
#endif
{
- struct resource *res = kzalloc(sizeof(struct resource),GFP_KERNEL);
+ struct resource *res =
+ kzalloc(sizeof(struct resource), GFP_KERNEL);
res->name = kmalloc(128, GFP_KERNEL);
- sprintf((char *)res->name, "Voyager %s Quad CPI", cat_module_name(i));
+ sprintf((char *)res->name, "Voyager %s Quad CPI",
+ cat_module_name(i));
res->start = qic_addr;
res->end = qic_addr + 0x3ff;
request_resource(&iomem_resource, res);
}
qic_addr = (unsigned long)ioremap(qic_addr, 0x400);
-
- for(j = 0; j < 4; j++) {
+
+ for (j = 0; j < 4; j++) {
__u8 cpu;
- if(voyager_8slot) {
+ if (voyager_8slot) {
/* 8 slot has a different mapping,
* each slot has only one vic line, so
* 1 cpu in each slot must be < 8 */
- cpu = (i & 0x07) + j*8;
+ cpu = (i & 0x07) + j * 8;
} else {
- cpu = (i & 0x03) + j*4;
+ cpu = (i & 0x03) + j * 4;
}
- if( (qabc_data[8] & (1<<j))) {
- voyager_extended_vic_processors |= (1<<cpu);
+ if ((qabc_data[8] & (1 << j))) {
+ voyager_extended_vic_processors |= (1 << cpu);
}
- if(qabc_data[8] & (1<<(j+4)) ) {
+ if (qabc_data[8] & (1 << (j + 4))) {
/* Second SET register plumbed: Quad
* card has two VIC connected CPUs.
* Secondary cannot be booted as a VIC
* CPU */
- voyager_extended_vic_processors |= (1<<cpu);
- voyager_allowed_boot_processors &= (~(1<<cpu));
+ voyager_extended_vic_processors |= (1 << cpu);
+ voyager_allowed_boot_processors &=
+ (~(1 << cpu));
}
- voyager_quad_processors |= (1<<cpu);
+ voyager_quad_processors |= (1 << cpu);
voyager_quad_cpi_addr[cpu] = (struct voyager_qic_cpi *)
- (qic_addr+(j<<8));
+ (qic_addr + (j << 8));
CDEBUG(("CPU%d: CPI address 0x%lx\n", cpu,
(unsigned long)voyager_quad_cpi_addr[cpu]));
}
outb(VOYAGER_CAT_END, CAT_CMD);
-
-
*asicpp = NULL;
modpp = &((*modpp)->next);
}
*modpp = NULL;
- printk("CAT Bus Initialisation finished: extended procs 0x%x, quad procs 0x%x, allowed vic boot = 0x%x\n", voyager_extended_vic_processors, voyager_quad_processors, voyager_allowed_boot_processors);
+ printk
+ ("CAT Bus Initialisation finished: extended procs 0x%x, quad procs 0x%x, allowed vic boot = 0x%x\n",
+ voyager_extended_vic_processors, voyager_quad_processors,
+ voyager_allowed_boot_processors);
request_resource(&ioport_resource, &vic_res);
- if(voyager_quad_processors)
+ if (voyager_quad_processors)
request_resource(&ioport_resource, &qic_res);
/* set up the front power switch */
}
-int
-voyager_cat_readb(__u8 module, __u8 asic, int reg)
+int voyager_cat_readb(__u8 module, __u8 asic, int reg)
{
return 0;
}
-static int
-cat_disconnect(voyager_module_t *modp, voyager_asic_t *asicp)
+static int cat_disconnect(voyager_module_t * modp, voyager_asic_t * asicp)
{
__u8 val;
int err = 0;
- if(!modp->scan_path_connected)
+ if (!modp->scan_path_connected)
return 0;
- if(asicp->asic_id != VOYAGER_CAT_ID) {
+ if (asicp->asic_id != VOYAGER_CAT_ID) {
CDEBUG(("cat_disconnect: ASIC is not CAT\n"));
return 1;
}
err = cat_read(modp, asicp, VOYAGER_SCANPATH, &val);
- if(err) {
+ if (err) {
CDEBUG(("cat_disconnect: failed to read SCANPATH\n"));
return err;
}
val &= VOYAGER_DISCONNECT_ASIC;
err = cat_write(modp, asicp, VOYAGER_SCANPATH, val);
- if(err) {
+ if (err) {
CDEBUG(("cat_disconnect: failed to write SCANPATH\n"));
return err;
}
@@ -940,27 +961,26 @@ cat_disconnect(voyager_module_t *modp, voyager_asic_t *asicp)
return 0;
}
-static int
-cat_connect(voyager_module_t *modp, voyager_asic_t *asicp)
+static int cat_connect(voyager_module_t * modp, voyager_asic_t * asicp)
{
__u8 val;
int err = 0;
- if(modp->scan_path_connected)
+ if (modp->scan_path_connected)
return 0;
- if(asicp->asic_id != VOYAGER_CAT_ID) {
+ if (asicp->asic_id != VOYAGER_CAT_ID) {
CDEBUG(("cat_connect: ASIC is not CAT\n"));
return 1;
}
err = cat_read(modp, asicp, VOYAGER_SCANPATH, &val);
- if(err) {
+ if (err) {
CDEBUG(("cat_connect: failed to read SCANPATH\n"));
return err;
}
val |= VOYAGER_CONNECT_ASIC;
err = cat_write(modp, asicp, VOYAGER_SCANPATH, val);
- if(err) {
+ if (err) {
CDEBUG(("cat_connect: failed to write SCANPATH\n"));
return err;
}
@@ -971,11 +991,10 @@ cat_connect(voyager_module_t *modp, voyager_asic_t *asicp)
return 0;
}
-void
-voyager_cat_power_off(void)
+void voyager_cat_power_off(void)
{
/* Power the machine off by writing to the PSI over the CAT
- * bus */
+ * bus */
__u8 data;
voyager_module_t psi = { 0 };
voyager_asic_t psi_asic = { 0 };
@@ -1009,8 +1028,7 @@ voyager_cat_power_off(void)
struct voyager_status voyager_status = { 0 };
-void
-voyager_cat_psi(__u8 cmd, __u16 reg, __u8 *data)
+void voyager_cat_psi(__u8 cmd, __u16 reg, __u8 * data)
{
voyager_module_t psi = { 0 };
voyager_asic_t psi_asic = { 0 };
@@ -1027,7 +1045,7 @@ voyager_cat_psi(__u8 cmd, __u16 reg, __u8 *data)
outb(VOYAGER_PSI, VOYAGER_CAT_CONFIG_PORT);
outb(VOYAGER_CAT_RUN, CAT_CMD);
cat_disconnect(&psi, &psi_asic);
- switch(cmd) {
+ switch (cmd) {
case VOYAGER_PSI_READ:
cat_read(&psi, &psi_asic, reg, data);
break;
@@ -1047,8 +1065,7 @@ voyager_cat_psi(__u8 cmd, __u16 reg, __u8 *data)
outb(VOYAGER_CAT_END, CAT_CMD);
}
-void
-voyager_cat_do_common_interrupt(void)
+void voyager_cat_do_common_interrupt(void)
{
/* This is caused either by a memory parity error or something
* in the PSI */
@@ -1057,7 +1074,7 @@ voyager_cat_do_common_interrupt(void)
voyager_asic_t psi_asic = { 0 };
struct voyager_psi psi_reg;
int i;
- re_read:
+ re_read:
psi.asic = &psi_asic;
psi.asic->asic_id = VOYAGER_CAT_ID;
psi.asic->subaddr = VOYAGER_SUBADDR_HI;
@@ -1072,43 +1089,45 @@ voyager_cat_do_common_interrupt(void)
cat_disconnect(&psi, &psi_asic);
/* Read the status. NOTE: Need to read *all* the PSI regs here
* otherwise the cmn int will be reasserted */
- for(i = 0; i < sizeof(psi_reg.regs); i++) {
- cat_read(&psi, &psi_asic, i, &((__u8 *)&psi_reg.regs)[i]);
+ for (i = 0; i < sizeof(psi_reg.regs); i++) {
+ cat_read(&psi, &psi_asic, i, &((__u8 *) & psi_reg.regs)[i]);
}
outb(VOYAGER_CAT_END, CAT_CMD);
- if((psi_reg.regs.checkbit & 0x02) == 0) {
+ if ((psi_reg.regs.checkbit & 0x02) == 0) {
psi_reg.regs.checkbit |= 0x02;
cat_write(&psi, &psi_asic, 5, psi_reg.regs.checkbit);
printk("VOYAGER RE-READ PSI\n");
goto re_read;
}
outb(VOYAGER_CAT_RUN, CAT_CMD);
- for(i = 0; i < sizeof(psi_reg.subregs); i++) {
+ for (i = 0; i < sizeof(psi_reg.subregs); i++) {
/* This looks strange, but the PSI doesn't do auto increment
* correctly */
- cat_subread(&psi, &psi_asic, VOYAGER_PSI_SUPPLY_REG + i,
- 1, &((__u8 *)&psi_reg.subregs)[i]);
+ cat_subread(&psi, &psi_asic, VOYAGER_PSI_SUPPLY_REG + i,
+ 1, &((__u8 *) & psi_reg.subregs)[i]);
}
outb(VOYAGER_CAT_END, CAT_CMD);
#ifdef VOYAGER_CAT_DEBUG
printk("VOYAGER PSI: ");
- for(i=0; i<sizeof(psi_reg.regs); i++)
- printk("%02x ", ((__u8 *)&psi_reg.regs)[i]);
+ for (i = 0; i < sizeof(psi_reg.regs); i++)
+ printk("%02x ", ((__u8 *) & psi_reg.regs)[i]);
printk("\n ");
- for(i=0; i<sizeof(psi_reg.subregs); i++)
- printk("%02x ", ((__u8 *)&psi_reg.subregs)[i]);
+ for (i = 0; i < sizeof(psi_reg.subregs); i++)
+ printk("%02x ", ((__u8 *) & psi_reg.subregs)[i]);
printk("\n");
#endif
- if(psi_reg.regs.intstatus & PSI_MON) {
+ if (psi_reg.regs.intstatus & PSI_MON) {
/* switch off or power fail */
- if(psi_reg.subregs.supply & PSI_SWITCH_OFF) {
- if(voyager_status.switch_off) {
- printk(KERN_ERR "Voyager front panel switch turned off again---Immediate power off!\n");
+ if (psi_reg.subregs.supply & PSI_SWITCH_OFF) {
+ if (voyager_status.switch_off) {
+ printk(KERN_ERR
+ "Voyager front panel switch turned off again---Immediate power off!\n");
voyager_cat_power_off();
/* not reached */
} else {
- printk(KERN_ERR "Voyager front panel switch turned off\n");
+ printk(KERN_ERR
+ "Voyager front panel switch turned off\n");
voyager_status.switch_off = 1;
voyager_status.request_from_kernel = 1;
wake_up_process(voyager_thread);
@@ -1127,7 +1146,7 @@ voyager_cat_do_common_interrupt(void)
VDEBUG(("Voyager ac fail reg 0x%x\n",
psi_reg.subregs.ACfail));
- if((psi_reg.subregs.ACfail & AC_FAIL_STAT_CHANGE) == 0) {
+ if ((psi_reg.subregs.ACfail & AC_FAIL_STAT_CHANGE) == 0) {
/* No further update */
return;
}
@@ -1135,20 +1154,20 @@ voyager_cat_do_common_interrupt(void)
/* Don't bother trying to find out who failed.
* FIXME: This probably makes the code incorrect on
* anything other than a 345x */
- for(i=0; i< 5; i++) {
- if( psi_reg.subregs.ACfail &(1<<i)) {
+ for (i = 0; i < 5; i++) {
+ if (psi_reg.subregs.ACfail & (1 << i)) {
break;
}
}
printk(KERN_NOTICE "AC FAIL IN SUPPLY %d\n", i);
#endif
/* DON'T do this: it shuts down the AC PSI
- outb(VOYAGER_CAT_RUN, CAT_CMD);
- data = PSI_MASK_MASK | i;
- cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_MASK,
- 1, &data);
- outb(VOYAGER_CAT_END, CAT_CMD);
- */
+ outb(VOYAGER_CAT_RUN, CAT_CMD);
+ data = PSI_MASK_MASK | i;
+ cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_MASK,
+ 1, &data);
+ outb(VOYAGER_CAT_END, CAT_CMD);
+ */
printk(KERN_ERR "Voyager AC power failure\n");
outb(VOYAGER_CAT_RUN, CAT_CMD);
data = PSI_COLD_START;
@@ -1159,16 +1178,16 @@ voyager_cat_do_common_interrupt(void)
voyager_status.request_from_kernel = 1;
wake_up_process(voyager_thread);
}
-
-
- } else if(psi_reg.regs.intstatus & PSI_FAULT) {
+
+ } else if (psi_reg.regs.intstatus & PSI_FAULT) {
/* Major fault! */
- printk(KERN_ERR "Voyager PSI Detected major fault, immediate power off!\n");
+ printk(KERN_ERR
+ "Voyager PSI Detected major fault, immediate power off!\n");
voyager_cat_power_off();
/* not reached */
- } else if(psi_reg.regs.intstatus & (PSI_DC_FAIL | PSI_ALARM
- | PSI_CURRENT | PSI_DVM
- | PSI_PSCFAULT | PSI_STAT_CHG)) {
+ } else if (psi_reg.regs.intstatus & (PSI_DC_FAIL | PSI_ALARM
+ | PSI_CURRENT | PSI_DVM
+ | PSI_PSCFAULT | PSI_STAT_CHG)) {
/* other psi fault */
printk(KERN_WARNING "Voyager PSI status 0x%x\n", data);
diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c
index 88124dd35406..73c435ce10fd 100644
--- a/arch/x86/mach-voyager/voyager_smp.c
+++ b/arch/x86/mach-voyager/voyager_smp.c
@@ -32,7 +32,8 @@
DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) = { &init_mm, 0 };
/* CPU IRQ affinity -- set to all ones initially */
-static unsigned long cpu_irq_affinity[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1] = ~0UL };
+static unsigned long cpu_irq_affinity[NR_CPUS] __cacheline_aligned =
+ {[0 ... NR_CPUS-1] = ~0UL };
/* per CPU data structure (for /proc/cpuinfo et al), visible externally
* indexed physically */
@@ -76,7 +77,6 @@ EXPORT_SYMBOL(cpu_online_map);
* by scheduler but indexed physically */
cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
-
/* The internal functions */
static void send_CPI(__u32 cpuset, __u8 cpi);
static void ack_CPI(__u8 cpi);
@@ -101,94 +101,86 @@ int hard_smp_processor_id(void);
int safe_smp_processor_id(void);
/* Inline functions */
-static inline void
-send_one_QIC_CPI(__u8 cpu, __u8 cpi)
+static inline void send_one_QIC_CPI(__u8 cpu, __u8 cpi)
{
voyager_quad_cpi_addr[cpu]->qic_cpi[cpi].cpi =
- (smp_processor_id() << 16) + cpi;
+ (smp_processor_id() << 16) + cpi;
}
-static inline void
-send_QIC_CPI(__u32 cpuset, __u8 cpi)
+static inline void send_QIC_CPI(__u32 cpuset, __u8 cpi)
{
int cpu;
for_each_online_cpu(cpu) {
- if(cpuset & (1<<cpu)) {
+ if (cpuset & (1 << cpu)) {
#ifdef VOYAGER_DEBUG
- if(!cpu_isset(cpu, cpu_online_map))
- VDEBUG(("CPU%d sending cpi %d to CPU%d not in cpu_online_map\n", hard_smp_processor_id(), cpi, cpu));
+ if (!cpu_isset(cpu, cpu_online_map))
+ VDEBUG(("CPU%d sending cpi %d to CPU%d not in "
+ "cpu_online_map\n",
+ hard_smp_processor_id(), cpi, cpu));
#endif
send_one_QIC_CPI(cpu, cpi - QIC_CPI_OFFSET);
}
}
}
-static inline void
-wrapper_smp_local_timer_interrupt(void)
+static inline void wrapper_smp_local_timer_interrupt(void)
{
irq_enter();
smp_local_timer_interrupt();
irq_exit();
}
-static inline void
-send_one_CPI(__u8 cpu, __u8 cpi)
+static inline void send_one_CPI(__u8 cpu, __u8 cpi)
{
- if(voyager_quad_processors & (1<<cpu))
+ if (voyager_quad_processors & (1 << cpu))
send_one_QIC_CPI(cpu, cpi - QIC_CPI_OFFSET);
else
- send_CPI(1<<cpu, cpi);
+ send_CPI(1 << cpu, cpi);
}
-static inline void
-send_CPI_allbutself(__u8 cpi)
+static inline void send_CPI_allbutself(__u8 cpi)
{
__u8 cpu = smp_processor_id();
__u32 mask = cpus_addr(cpu_online_map)[0] & ~(1 << cpu);
send_CPI(mask, cpi);
}
-static inline int
-is_cpu_quad(void)
+static inline int is_cpu_quad(void)
{
__u8 cpumask = inb(VIC_PROC_WHO_AM_I);
return ((cpumask & QUAD_IDENTIFIER) == QUAD_IDENTIFIER);
}
-static inline int
-is_cpu_extended(void)
+static inline int is_cpu_extended(void)
{
__u8 cpu = hard_smp_processor_id();
- return(voyager_extended_vic_processors & (1<<cpu));
+ return (voyager_extended_vic_processors & (1 << cpu));
}
-static inline int
-is_cpu_vic_boot(void)
+static inline int is_cpu_vic_boot(void)
{
__u8 cpu = hard_smp_processor_id();
- return(voyager_extended_vic_processors
- & voyager_allowed_boot_processors & (1<<cpu));
+ return (voyager_extended_vic_processors
+ & voyager_allowed_boot_processors & (1 << cpu));
}
-
-static inline void
-ack_CPI(__u8 cpi)
+static inline void ack_CPI(__u8 cpi)
{
- switch(cpi) {
+ switch (cpi) {
case VIC_CPU_BOOT_CPI:
- if(is_cpu_quad() && !is_cpu_vic_boot())
+ if (is_cpu_quad() && !is_cpu_vic_boot())
ack_QIC_CPI(cpi);
else
ack_VIC_CPI(cpi);
break;
case VIC_SYS_INT:
- case VIC_CMN_INT:
+ case VIC_CMN_INT:
/* These are slightly strange. Even on the Quad card,
* They are vectored as VIC CPIs */
- if(is_cpu_quad())
+ if (is_cpu_quad())
ack_special_QIC_CPI(cpi);
else
ack_VIC_CPI(cpi);
@@ -205,11 +197,11 @@ ack_CPI(__u8 cpi)
* 8259 IRQs except that masks and things must be kept per processor
*/
static struct irq_chip vic_chip = {
- .name = "VIC",
- .startup = startup_vic_irq,
- .mask = mask_vic_irq,
- .unmask = unmask_vic_irq,
- .set_affinity = set_vic_irq_affinity,
+ .name = "VIC",
+ .startup = startup_vic_irq,
+ .mask = mask_vic_irq,
+ .unmask = unmask_vic_irq,
+ .set_affinity = set_vic_irq_affinity,
};
/* used to count up as CPUs are brought on line (starts at 0) */
@@ -223,7 +215,7 @@ static __u32 trampoline_base;
/* The per cpu profile stuff - used in smp_local_timer_interrupt */
static DEFINE_PER_CPU(int, prof_multiplier) = 1;
static DEFINE_PER_CPU(int, prof_old_multiplier) = 1;
-static DEFINE_PER_CPU(int, prof_counter) = 1;
+static DEFINE_PER_CPU(int, prof_counter) = 1;
/* the map used to check if a CPU has booted */
static __u32 cpu_booted_map;
@@ -246,9 +238,9 @@ static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned;
static __u16 vic_irq_enable_mask[NR_CPUS] __cacheline_aligned = { 0 };
/* Lock for enable/disable of VIC interrupts */
-static __cacheline_aligned DEFINE_SPINLOCK(vic_irq_lock);
+static __cacheline_aligned DEFINE_SPINLOCK(vic_irq_lock);
-/* The boot processor is correctly set up in PC mode when it
+/* The boot processor is correctly set up in PC mode when it
* comes up, but the secondaries need their master/slave 8259
* pairs initializing correctly */
@@ -262,8 +254,7 @@ static unsigned long vic_tick[NR_CPUS] __cacheline_aligned = { 0 };
static unsigned long vic_cpi_mailbox[NR_CPUS] __cacheline_aligned;
/* debugging routine to read the isr of the cpu's pic */
-static inline __u16
-vic_read_isr(void)
+static inline __u16 vic_read_isr(void)
{
__u16 isr;
@@ -275,17 +266,16 @@ vic_read_isr(void)
return isr;
}
-static __init void
-qic_setup(void)
+static __init void qic_setup(void)
{
- if(!is_cpu_quad()) {
+ if (!is_cpu_quad()) {
/* not a quad, no setup */
return;
}
outb(QIC_DEFAULT_MASK0, QIC_MASK_REGISTER0);
outb(QIC_CPI_ENABLE, QIC_MASK_REGISTER1);
-
- if(is_cpu_extended()) {
+
+ if (is_cpu_extended()) {
/* the QIC duplicate of the VIC base register */
outb(VIC_DEFAULT_CPI_BASE, QIC_VIC_CPI_BASE_REGISTER);
outb(QIC_DEFAULT_CPI_BASE, QIC_CPI_BASE_REGISTER);
@@ -295,8 +285,7 @@ qic_setup(void)
}
}
-static __init void
-vic_setup_pic(void)
+static __init void vic_setup_pic(void)
{
outb(1, VIC_REDIRECT_REGISTER_1);
/* clear the claim registers for dynamic routing */
@@ -333,7 +322,7 @@ vic_setup_pic(void)
/* ICW2: slave vector base */
outb(FIRST_EXTERNAL_VECTOR + 8, 0xA1);
-
+
/* ICW3: slave ID */
outb(0x02, 0xA1);
@@ -341,19 +330,18 @@ vic_setup_pic(void)
outb(0x01, 0xA1);
}
-static void
-do_quad_bootstrap(void)
+static void do_quad_bootstrap(void)
{
- if(is_cpu_quad() && is_cpu_vic_boot()) {
+ if (is_cpu_quad() && is_cpu_vic_boot()) {
int i;
unsigned long flags;
__u8 cpuid = hard_smp_processor_id();
local_irq_save(flags);
- for(i = 0; i<4; i++) {
+ for (i = 0; i < 4; i++) {
/* FIXME: this would be >>3 &0x7 on the 32 way */
- if(((cpuid >> 2) & 0x03) == i)
+ if (((cpuid >> 2) & 0x03) == i)
/* don't lower our own mask! */
continue;
@@ -368,12 +356,10 @@ do_quad_bootstrap(void)
}
}
-
/* Set up all the basic stuff: read the SMP config and make all the
* SMP information reflect only the boot cpu. All others will be
* brought on-line later. */
-void __init
-find_smp_config(void)
+void __init find_smp_config(void)
{
int i;
@@ -382,24 +368,31 @@ find_smp_config(void)
printk("VOYAGER SMP: Boot cpu is %d\n", boot_cpu_id);
/* initialize the CPU structures (moved from smp_boot_cpus) */
- for(i=0; i<NR_CPUS; i++) {
+ for (i = 0; i < NR_CPUS; i++) {
cpu_irq_affinity[i] = ~0;
}
cpu_online_map = cpumask_of_cpu(boot_cpu_id);
/* The boot CPU must be extended */
- voyager_extended_vic_processors = 1<<boot_cpu_id;
+ voyager_extended_vic_processors = 1 << boot_cpu_id;
/* initially, all of the first 8 CPUs can boot */
voyager_allowed_boot_processors = 0xff;
/* set up everything for just this CPU, we can alter
* this as we start the other CPUs later */
/* now get the CPU disposition from the extended CMOS */
- cpus_addr(phys_cpu_present_map)[0] = voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK);
- cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8;
- cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 2) << 16;
- cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 3) << 24;
+ cpus_addr(phys_cpu_present_map)[0] =
+ voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK);
+ cpus_addr(phys_cpu_present_map)[0] |=
+ voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8;
+ cpus_addr(phys_cpu_present_map)[0] |=
+ voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK +
+ 2) << 16;
+ cpus_addr(phys_cpu_present_map)[0] |=
+ voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK +
+ 3) << 24;
cpu_possible_map = phys_cpu_present_map;
- printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", cpus_addr(phys_cpu_present_map)[0]);
+ printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n",
+ cpus_addr(phys_cpu_present_map)[0]);
/* Here we set up the VIC to enable SMP */
/* enable the CPIs by writing the base vector to their register */
outb(VIC_DEFAULT_CPI_BASE, VIC_CPI_BASE_REGISTER);
@@ -427,8 +420,7 @@ find_smp_config(void)
/*
* The bootstrap kernel entry code has set these up. Save them
* for a given CPU, id is physical */
-void __init
-smp_store_cpu_info(int id)
+void __init smp_store_cpu_info(int id)
{
struct cpuinfo_x86 *c = &cpu_data(id);
@@ -438,21 +430,19 @@ smp_store_cpu_info(int id)
}
/* set up the trampoline and return the physical address of the code */
-static __u32 __init
-setup_trampoline(void)
+static __u32 __init setup_trampoline(void)
{
/* these two are global symbols in trampoline.S */
extern const __u8 trampoline_end[];
extern const __u8 trampoline_data[];
- memcpy((__u8 *)trampoline_base, trampoline_data,
+ memcpy((__u8 *) trampoline_base, trampoline_data,
trampoline_end - trampoline_data);
- return virt_to_phys((__u8 *)trampoline_base);
+ return virt_to_phys((__u8 *) trampoline_base);
}
/* Routine initially called when a non-boot CPU is brought online */
-static void __init
-start_secondary(void *unused)
+static void __init start_secondary(void *unused)
{
__u8 cpuid = hard_smp_processor_id();
/* external functions not defined in the headers */
@@ -464,17 +454,18 @@ start_secondary(void *unused)
ack_CPI(VIC_CPU_BOOT_CPI);
/* setup the 8259 master slave pair belonging to this CPU ---
- * we won't actually receive any until the boot CPU
- * relinquishes it's static routing mask */
+ * we won't actually receive any until the boot CPU
+ * relinquishes it's static routing mask */
vic_setup_pic();
qic_setup();
- if(is_cpu_quad() && !is_cpu_vic_boot()) {
+ if (is_cpu_quad() && !is_cpu_vic_boot()) {
/* clear the boot CPI */
__u8 dummy;
- dummy = voyager_quad_cpi_addr[cpuid]->qic_cpi[VIC_CPU_BOOT_CPI].cpi;
+ dummy =
+ voyager_quad_cpi_addr[cpuid]->qic_cpi[VIC_CPU_BOOT_CPI].cpi;
printk("read dummy %d\n", dummy);
}
@@ -516,7 +507,6 @@ start_secondary(void *unused)
cpu_idle();
}
-
/* Routine to kick start the given CPU and wait for it to report ready
* (or timeout in startup). When this routine returns, the requested
* CPU is either fully running and configured or known to be dead.
@@ -524,15 +514,14 @@ start_secondary(void *unused)
* We call this routine sequentially 1 CPU at a time, so no need for
* locking */
-static void __init
-do_boot_cpu(__u8 cpu)
+static void __init do_boot_cpu(__u8 cpu)
{
struct task_struct *idle;
int timeout;
unsigned long flags;
- int quad_boot = (1<<cpu) & voyager_quad_processors
- & ~( voyager_extended_vic_processors
- & voyager_allowed_boot_processors);
+ int quad_boot = (1 << cpu) & voyager_quad_processors
+ & ~(voyager_extended_vic_processors
+ & voyager_allowed_boot_processors);
/* This is an area in head.S which was used to set up the
* initial kernel stack. We need to alter this to give the
@@ -543,10 +532,10 @@ do_boot_cpu(__u8 cpu)
} stack_start;
/* This is the format of the CPI IDT gate (in real mode) which
* we're hijacking to boot the CPU */
- union IDTFormat {
+ union IDTFormat {
struct seg {
- __u16 Offset;
- __u16 Segment;
+ __u16 Offset;
+ __u16 Segment;
} idt;
__u32 val;
} hijack_source;
@@ -565,19 +554,19 @@ do_boot_cpu(__u8 cpu)
alternatives_smp_switch(1);
idle = fork_idle(cpu);
- if(IS_ERR(idle))
+ if (IS_ERR(idle))
panic("failed fork for CPU%d", cpu);
- idle->thread.eip = (unsigned long) start_secondary;
+ idle->thread.eip = (unsigned long)start_secondary;
/* init_tasks (in sched.c) is indexed logically */
- stack_start.esp = (void *) idle->thread.esp;
+ stack_start.esp = (void *)idle->thread.esp;
init_gdt(cpu);
- per_cpu(current_task, cpu) = idle;
+ per_cpu(current_task, cpu) = idle;
early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
irq_ctx_init(cpu);
/* Note: Don't modify initial ss override */
- VDEBUG(("VOYAGER SMP: Booting CPU%d at 0x%lx[%x:%x], stack %p\n", cpu,
+ VDEBUG(("VOYAGER SMP: Booting CPU%d at 0x%lx[%x:%x], stack %p\n", cpu,
(unsigned long)hijack_source.val, hijack_source.idt.Segment,
hijack_source.idt.Offset, stack_start.esp));
@@ -586,16 +575,23 @@ do_boot_cpu(__u8 cpu)
min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
flush_tlb_all();
- if(quad_boot) {
+ if (quad_boot) {
printk("CPU %d: non extended Quad boot\n", cpu);
- hijack_vector = (__u32 *)phys_to_virt((VIC_CPU_BOOT_CPI + QIC_DEFAULT_CPI_BASE)*4);
+ hijack_vector =
+ (__u32 *)
+ phys_to_virt((VIC_CPU_BOOT_CPI + QIC_DEFAULT_CPI_BASE) * 4);
*hijack_vector = hijack_source.val;
} else {
printk("CPU%d: extended VIC boot\n", cpu);
- hijack_vector = (__u32 *)phys_to_virt((VIC_CPU_BOOT_CPI + VIC_DEFAULT_CPI_BASE)*4);
+ hijack_vector =
+ (__u32 *)
+ phys_to_virt((VIC_CPU_BOOT_CPI + VIC_DEFAULT_CPI_BASE) * 4);
*hijack_vector = hijack_source.val;
/* VIC errata, may also receive interrupt at this address */
- hijack_vector = (__u32 *)phys_to_virt((VIC_CPU_BOOT_ERRATA_CPI + VIC_DEFAULT_CPI_BASE)*4);
+ hijack_vector =
+ (__u32 *)
+ phys_to_virt((VIC_CPU_BOOT_ERRATA_CPI +
+ VIC_DEFAULT_CPI_BASE) * 4);
*hijack_vector = hijack_source.val;
}
/* All non-boot CPUs start with interrupts fully masked. Need
@@ -603,73 +599,76 @@ do_boot_cpu(__u8 cpu)
* this in the VIC by masquerading as the processor we're
* about to boot and lowering its interrupt mask */
local_irq_save(flags);
- if(quad_boot) {
+ if (quad_boot) {
send_one_QIC_CPI(cpu, VIC_CPU_BOOT_CPI);
} else {
outb(VIC_CPU_MASQUERADE_ENABLE | cpu, VIC_PROCESSOR_ID);
/* here we're altering registers belonging to `cpu' */
-
+
outb(VIC_BOOT_INTERRUPT_MASK, 0x21);
/* now go back to our original identity */
outb(boot_cpu_id, VIC_PROCESSOR_ID);
/* and boot the CPU */
- send_CPI((1<<cpu), VIC_CPU_BOOT_CPI);
+ send_CPI((1 << cpu), VIC_CPU_BOOT_CPI);
}
cpu_booted_map = 0;
local_irq_restore(flags);
/* now wait for it to become ready (or timeout) */
- for(timeout = 0; timeout < 50000; timeout++) {
- if(cpu_booted_map)
+ for (timeout = 0; timeout < 50000; timeout++) {
+ if (cpu_booted_map)
break;
udelay(100);
}
/* reset the page table */
zap_low_mappings();
-
+
if (cpu_booted_map) {
VDEBUG(("CPU%d: Booted successfully, back in CPU %d\n",
cpu, smp_processor_id()));
-
+
printk("CPU%d: ", cpu);
print_cpu_info(&cpu_data(cpu));
wmb();
cpu_set(cpu, cpu_callout_map);
cpu_set(cpu, cpu_present_map);
- }
- else {
+ } else {
printk("CPU%d FAILED TO BOOT: ", cpu);
- if (*((volatile unsigned char *)phys_to_virt(start_phys_address))==0xA5)
+ if (*
+ ((volatile unsigned char *)phys_to_virt(start_phys_address))
+ == 0xA5)
printk("Stuck.\n");
else
printk("Not responding.\n");
-
+
cpucount--;
}
}
-void __init
-smp_boot_cpus(void)
+void __init smp_boot_cpus(void)
{
int i;
/* CAT BUS initialisation must be done after the memory */
/* FIXME: The L4 has a catbus too, it just needs to be
* accessed in a totally different way */
- if(voyager_level == 5) {
+ if (voyager_level == 5) {
voyager_cat_init();
/* now that the cat has probed the Voyager System Bus, sanity
* check the cpu map */
- if( ((voyager_quad_processors | voyager_extended_vic_processors)
- & cpus_addr(phys_cpu_present_map)[0]) != cpus_addr(phys_cpu_present_map)[0]) {
+ if (((voyager_quad_processors | voyager_extended_vic_processors)
+ & cpus_addr(phys_cpu_present_map)[0]) !=
+ cpus_addr(phys_cpu_present_map)[0]) {
/* should panic */
- printk("\n\n***WARNING*** Sanity check of CPU present map FAILED\n");
+ printk("\n\n***WARNING*** "
+ "Sanity check of CPU present map FAILED\n");
}
- } else if(voyager_level == 4)
- voyager_extended_vic_processors = cpus_addr(phys_cpu_present_map)[0];
+ } else if (voyager_level == 4)
+ voyager_extended_vic_processors =
+ cpus_addr(phys_cpu_present_map)[0];
/* this sets up the idle task to run on the current cpu */
voyager_extended_cpus = 1;
@@ -678,14 +677,14 @@ smp_boot_cpus(void)
//global_irq_holder = boot_cpu_id;
/* FIXME: Need to do something about this but currently only works
- * on CPUs with a tsc which none of mine have.
- smp_tune_scheduling();
+ * on CPUs with a tsc which none of mine have.
+ smp_tune_scheduling();
*/
smp_store_cpu_info(boot_cpu_id);
printk("CPU%d: ", boot_cpu_id);
print_cpu_info(&cpu_data(boot_cpu_id));
- if(is_cpu_quad()) {
+ if (is_cpu_quad()) {
/* booting on a Quad CPU */
printk("VOYAGER SMP: Boot CPU is Quad\n");
qic_setup();
@@ -697,11 +696,11 @@ smp_boot_cpus(void)
cpu_set(boot_cpu_id, cpu_online_map);
cpu_set(boot_cpu_id, cpu_callout_map);
-
- /* loop over all the extended VIC CPUs and boot them. The
+
+ /* loop over all the extended VIC CPUs and boot them. The
* Quad CPUs must be bootstrapped by their extended VIC cpu */
- for(i = 0; i < NR_CPUS; i++) {
- if(i == boot_cpu_id || !cpu_isset(i, phys_cpu_present_map))
+ for (i = 0; i < NR_CPUS; i++) {
+ if (i == boot_cpu_id || !cpu_isset(i, phys_cpu_present_map))
continue;
do_boot_cpu(i);
/* This udelay seems to be needed for the Quad boots
@@ -715,25 +714,26 @@ smp_boot_cpus(void)
for (i = 0; i < NR_CPUS; i++)
if (cpu_isset(i, cpu_online_map))
bogosum += cpu_data(i).loops_per_jiffy;
- printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
- cpucount+1,
- bogosum/(500000/HZ),
- (bogosum/(5000/HZ))%100);
+ printk(KERN_INFO "Total of %d processors activated "
+ "(%lu.%02lu BogoMIPS).\n",
+ cpucount + 1, bogosum / (500000 / HZ),
+ (bogosum / (5000 / HZ)) % 100);
}
voyager_extended_cpus = hweight32(voyager_extended_vic_processors);
- printk("VOYAGER: Extended (interrupt handling CPUs): %d, non-extended: %d\n", voyager_extended_cpus, num_booting_cpus() - voyager_extended_cpus);
+ printk("VOYAGER: Extended (interrupt handling CPUs): "
+ "%d, non-extended: %d\n", voyager_extended_cpus,
+ num_booting_cpus() - voyager_extended_cpus);
/* that's it, switch to symmetric mode */
outb(0, VIC_PRIORITY_REGISTER);
outb(0, VIC_CLAIM_REGISTER_0);
outb(0, VIC_CLAIM_REGISTER_1);
-
+
VDEBUG(("VOYAGER SMP: Booted with %d CPUs\n", num_booting_cpus()));
}
/* Reload the secondary CPUs task structure (this function does not
* return ) */
-void __init
-initialize_secondary(void)
+void __init initialize_secondary(void)
{
#if 0
// AC kernels only
@@ -745,11 +745,9 @@ initialize_secondary(void)
* basically just the stack pointer and the eip.
*/
- asm volatile(
- "movl %0,%%esp\n\t"
- "jmp *%1"
- :
- :"r" (current->thread.esp),"r" (current->thread.eip));
+ asm volatile ("movl %0,%%esp\n\t"
+ "jmp *%1"::"r" (current->thread.esp),
+ "r"(current->thread.eip));
}
/* handle a Voyager SYS_INT -- If we don't, the base board will
@@ -758,25 +756,23 @@ initialize_secondary(void)
* System interrupts occur because some problem was detected on the
* various busses. To find out what you have to probe all the
* hardware via the CAT bus. FIXME: At the moment we do nothing. */
-fastcall void
-smp_vic_sys_interrupt(struct pt_regs *regs)
+fastcall void smp_vic_sys_interrupt(struct pt_regs *regs)
{
ack_CPI(VIC_SYS_INT);
- printk("Voyager SYSTEM INTERRUPT\n");
+ printk("Voyager SYSTEM INTERRUPT\n");
}
/* Handle a voyager CMN_INT; These interrupts occur either because of
* a system status change or because a single bit memory error
* occurred. FIXME: At the moment, ignore all this. */
-fastcall void
-smp_vic_cmn_interrupt(struct pt_regs *regs)
+fastcall void smp_vic_cmn_interrupt(struct pt_regs *regs)
{
static __u8 in_cmn_int = 0;
static DEFINE_SPINLOCK(cmn_int_lock);
/* common ints are broadcast, so make sure we only do this once */
_raw_spin_lock(&cmn_int_lock);
- if(in_cmn_int)
+ if (in_cmn_int)
goto unlock_end;
in_cmn_int++;
@@ -784,12 +780,12 @@ smp_vic_cmn_interrupt(struct pt_regs *regs)
VDEBUG(("Voyager COMMON INTERRUPT\n"));
- if(voyager_level == 5)
+ if (voyager_level == 5)
voyager_cat_do_common_interrupt();
_raw_spin_lock(&cmn_int_lock);
in_cmn_int = 0;
- unlock_end:
+ unlock_end:
_raw_spin_unlock(&cmn_int_lock);
ack_CPI(VIC_CMN_INT);
}
@@ -797,26 +793,24 @@ smp_vic_cmn_interrupt(struct pt_regs *regs)
/*
* Reschedule call back. Nothing to do, all the work is done
* automatically when we return from the interrupt. */
-static void
-smp_reschedule_interrupt(void)
+static void smp_reschedule_interrupt(void)
{
/* do nothing */
}
-static struct mm_struct * flush_mm;
+static struct mm_struct *flush_mm;
static unsigned long flush_va;
static DEFINE_SPINLOCK(tlbstate_lock);
#define FLUSH_ALL 0xffffffff
/*
- * We cannot call mmdrop() because we are in interrupt context,
+ * We cannot call mmdrop() because we are in interrupt context,
* instead update mm->cpu_vm_mask.
*
* We need to reload %cr3 since the page tables may be going
* away from under us..
*/
-static inline void
-leave_mm (unsigned long cpu)
+static inline void leave_mm(unsigned long cpu)
{
if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK)
BUG();
@@ -824,12 +818,10 @@ leave_mm (unsigned long cpu)
load_cr3(swapper_pg_dir);
}
-
/*
* Invalidate call-back
*/
-static void
-smp_invalidate_interrupt(void)
+static void smp_invalidate_interrupt(void)
{
__u8 cpu = smp_processor_id();
@@ -837,9 +829,9 @@ smp_invalidate_interrupt(void)
return;
/* This will flood messages. Don't uncomment unless you see
* Problems with cross cpu invalidation
- VDEBUG(("VOYAGER SMP: CPU%d received INVALIDATE_CPI\n",
- smp_processor_id()));
- */
+ VDEBUG(("VOYAGER SMP: CPU%d received INVALIDATE_CPI\n",
+ smp_processor_id()));
+ */
if (flush_mm == per_cpu(cpu_tlbstate, cpu).active_mm) {
if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) {
@@ -857,11 +849,10 @@ smp_invalidate_interrupt(void)
/* All the new flush operations for 2.4 */
-
/* This routine is called with a physical cpu mask */
static void
-voyager_flush_tlb_others (unsigned long cpumask, struct mm_struct *mm,
- unsigned long va)
+voyager_flush_tlb_others(unsigned long cpumask, struct mm_struct *mm,
+ unsigned long va)
{
int stuck = 50000;
@@ -875,7 +866,7 @@ voyager_flush_tlb_others (unsigned long cpumask, struct mm_struct *mm,
BUG();
spin_lock(&tlbstate_lock);
-
+
flush_mm = mm;
flush_va = va;
atomic_set_mask(cpumask, &smp_invalidate_needed);
@@ -887,23 +878,23 @@ voyager_flush_tlb_others (unsigned long cpumask, struct mm_struct *mm,
while (smp_invalidate_needed) {
mb();
- if(--stuck == 0) {
- printk("***WARNING*** Stuck doing invalidate CPI (CPU%d)\n", smp_processor_id());
+ if (--stuck == 0) {
+ printk("***WARNING*** Stuck doing invalidate CPI "
+ "(CPU%d)\n", smp_processor_id());
break;
}
}
/* Uncomment only to debug invalidation problems
- VDEBUG(("VOYAGER SMP: Completed invalidate CPI (CPU%d)\n", cpu));
- */
+ VDEBUG(("VOYAGER SMP: Completed invalidate CPI (CPU%d)\n", cpu));
+ */
flush_mm = NULL;
flush_va = 0;
spin_unlock(&tlbstate_lock);
}
-void
-flush_tlb_current_task(void)
+void flush_tlb_current_task(void)
{
struct mm_struct *mm = current->mm;
unsigned long cpu_mask;
@@ -918,9 +909,7 @@ flush_tlb_current_task(void)
preempt_enable();
}
-
-void
-flush_tlb_mm (struct mm_struct * mm)
+void flush_tlb_mm(struct mm_struct *mm)
{
unsigned long cpu_mask;
@@ -940,7 +929,7 @@ flush_tlb_mm (struct mm_struct * mm)
preempt_enable();
}
-void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
{
struct mm_struct *mm = vma->vm_mm;
unsigned long cpu_mask;
@@ -949,10 +938,10 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id());
if (current->active_mm == mm) {
- if(current->mm)
+ if (current->mm)
__flush_tlb_one(va);
- else
- leave_mm(smp_processor_id());
+ else
+ leave_mm(smp_processor_id());
}
if (cpu_mask)
@@ -960,21 +949,21 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
preempt_enable();
}
+
EXPORT_SYMBOL(flush_tlb_page);
/* enable the requested IRQs */
-static void
-smp_enable_irq_interrupt(void)
+static void smp_enable_irq_interrupt(void)
{
__u8 irq;
__u8 cpu = get_cpu();
VDEBUG(("VOYAGER SMP: CPU%d enabling irq mask 0x%x\n", cpu,
- vic_irq_enable_mask[cpu]));
+ vic_irq_enable_mask[cpu]));
spin_lock(&vic_irq_lock);
- for(irq = 0; irq < 16; irq++) {
- if(vic_irq_enable_mask[cpu] & (1<<irq))
+ for (irq = 0; irq < 16; irq++) {
+ if (vic_irq_enable_mask[cpu] & (1 << irq))
enable_local_vic_irq(irq);
}
vic_irq_enable_mask[cpu] = 0;
@@ -982,17 +971,16 @@ smp_enable_irq_interrupt(void)
put_cpu_no_resched();
}
-
+
/*
* CPU halt call-back
*/
-static void
-smp_stop_cpu_function(void *dummy)
+static void smp_stop_cpu_function(void *dummy)
{
VDEBUG(("VOYAGER SMP: CPU%d is STOPPING\n", smp_processor_id()));
cpu_clear(smp_processor_id(), cpu_online_map);
local_irq_disable();
- for(;;)
+ for (;;)
halt();
}
@@ -1006,14 +994,13 @@ struct call_data_struct {
int wait;
};
-static struct call_data_struct * call_data;
+static struct call_data_struct *call_data;
/* execute a thread on a new CPU. The function to be called must be
* previously set up. This is used to schedule a function for
* execution on all CPUs - set up the function then broadcast a
* function_interrupt CPI to come here on each CPU */
-static void
-smp_call_function_interrupt(void)
+static void smp_call_function_interrupt(void)
{
void (*func) (void *info) = call_data->func;
void *info = call_data->info;
@@ -1027,16 +1014,17 @@ smp_call_function_interrupt(void)
* about to execute the function
*/
mb();
- if(!test_and_clear_bit(cpu, &call_data->started)) {
+ if (!test_and_clear_bit(cpu, &call_data->started)) {
/* If the bit wasn't set, this could be a replay */
- printk(KERN_WARNING "VOYAGER SMP: CPU %d received call funtion with no call pending\n", cpu);
+ printk(KERN_WARNING "VOYAGER SMP: CPU %d received call funtion"
+ " with no call pending\n", cpu);
return;
}
/*
* At this point the info structure may be out of scope unless wait==1
*/
irq_enter();
- (*func)(info);
+ (*func) (info);
__get_cpu_var(irq_stat).irq_call_count++;
irq_exit();
if (wait) {
@@ -1046,14 +1034,13 @@ smp_call_function_interrupt(void)
}
static int
-voyager_smp_call_function_mask (cpumask_t cpumask,
- void (*func) (void *info), void *info,
- int wait)
+voyager_smp_call_function_mask(cpumask_t cpumask,
+ void (*func) (void *info), void *info, int wait)
{
struct call_data_struct data;
u32 mask = cpus_addr(cpumask)[0];
- mask &= ~(1<<smp_processor_id());
+ mask &= ~(1 << smp_processor_id());
if (!mask)
return 0;
@@ -1093,7 +1080,7 @@ voyager_smp_call_function_mask (cpumask_t cpumask,
* so we use the system clock to interrupt one processor, which in
* turn, broadcasts a timer CPI to all the others --- we receive that
* CPI here. We don't use this actually for counting so losing
- * ticks doesn't matter
+ * ticks doesn't matter
*
* FIXME: For those CPUs which actually have a local APIC, we could
* try to use it to trigger this interrupt instead of having to
@@ -1101,8 +1088,7 @@ voyager_smp_call_function_mask (cpumask_t cpumask,
* no local APIC, so I can't do this
*
* This function is currently a placeholder and is unused in the code */
-fastcall void
-smp_apic_timer_interrupt(struct pt_regs *regs)
+fastcall void smp_apic_timer_interrupt(struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
wrapper_smp_local_timer_interrupt();
@@ -1110,8 +1096,7 @@ smp_apic_timer_interrupt(struct pt_regs *regs)
}
/* All of the QUAD interrupt GATES */
-fastcall void
-smp_qic_timer_interrupt(struct pt_regs *regs)
+fastcall void smp_qic_timer_interrupt(struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
ack_QIC_CPI(QIC_TIMER_CPI);
@@ -1119,60 +1104,54 @@ smp_qic_timer_interrupt(struct pt_regs *regs)
set_irq_regs(old_regs);
}
-fastcall void
-smp_qic_invalidate_interrupt(struct pt_regs *regs)
+fastcall void smp_qic_invalidate_interrupt(struct pt_regs *regs)
{
ack_QIC_CPI(QIC_INVALIDATE_CPI);
smp_invalidate_interrupt();
}
-fastcall void
-smp_qic_reschedule_interrupt(struct pt_regs *regs)
+fastcall void smp_qic_reschedule_interrupt(struct pt_regs *regs)
{
ack_QIC_CPI(QIC_RESCHEDULE_CPI);
smp_reschedule_interrupt();
}
-fastcall void
-smp_qic_enable_irq_interrupt(struct pt_regs *regs)
+fastcall void smp_qic_enable_irq_interrupt(struct pt_regs *regs)
{
ack_QIC_CPI(QIC_ENABLE_IRQ_CPI);
smp_enable_irq_interrupt();
}
-fastcall void
-smp_qic_call_function_interrupt(struct pt_regs *regs)
+fastcall void smp_qic_call_function_interrupt(struct pt_regs *regs)
{
ack_QIC_CPI(QIC_CALL_FUNCTION_CPI);
smp_call_function_interrupt();
}
-fastcall void
-smp_vic_cpi_interrupt(struct pt_regs *regs)
+fastcall void smp_vic_cpi_interrupt(struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
__u8 cpu = smp_processor_id();
- if(is_cpu_quad())
+ if (is_cpu_quad())
ack_QIC_CPI(VIC_CPI_LEVEL0);
else
ack_VIC_CPI(VIC_CPI_LEVEL0);
- if(test_and_clear_bit(VIC_TIMER_CPI, &vic_cpi_mailbox[cpu]))
+ if (test_and_clear_bit(VIC_TIMER_CPI, &vic_cpi_mailbox[cpu]))
wrapper_smp_local_timer_interrupt();
- if(test_and_clear_bit(VIC_INVALIDATE_CPI, &vic_cpi_mailbox[cpu]))
+ if (test_and_clear_bit(VIC_INVALIDATE_CPI, &vic_cpi_mailbox[cpu]))
smp_invalidate_interrupt();
- if(test_and_clear_bit(VIC_RESCHEDULE_CPI, &vic_cpi_mailbox[cpu]))
+ if (test_and_clear_bit(VIC_RESCHEDULE_CPI, &vic_cpi_mailbox[cpu]))
smp_reschedule_interrupt();
- if(test_and_clear_bit(VIC_ENABLE_IRQ_CPI, &vic_cpi_mailbox[cpu]))
+ if (test_and_clear_bit(VIC_ENABLE_IRQ_CPI, &vic_cpi_mailbox[cpu]))
smp_enable_irq_interrupt();
- if(test_and_clear_bit(VIC_CALL_FUNCTION_CPI, &vic_cpi_mailbox[cpu]))
+ if (test_and_clear_bit(VIC_CALL_FUNCTION_CPI, &vic_cpi_mailbox[cpu]))
smp_call_function_interrupt();
set_irq_regs(old_regs);
}
-static void
-do_flush_tlb_all(void* info)
+static void do_flush_tlb_all(void *info)
{
unsigned long cpu = smp_processor_id();
@@ -1181,65 +1160,56 @@ do_flush_tlb_all(void* info)
leave_mm(cpu);
}
-
/* flush the TLB of every active CPU in the system */
-void
-flush_tlb_all(void)
+void flush_tlb_all(void)
{
on_each_cpu(do_flush_tlb_all, 0, 1, 1);
}
/* used to set up the trampoline for other CPUs when the memory manager
* is sorted out */
-void __init
-smp_alloc_memory(void)
+void __init smp_alloc_memory(void)
{
- trampoline_base = (__u32)alloc_bootmem_low_pages(PAGE_SIZE);
- if(__pa(trampoline_base) >= 0x93000)
+ trampoline_base = (__u32) alloc_bootmem_low_pages(PAGE_SIZE);
+ if (__pa(trampoline_base) >= 0x93000)
BUG();
}
/* send a reschedule CPI to one CPU by physical CPU number*/
-static void
-voyager_smp_send_reschedule(int cpu)
+static void voyager_smp_send_reschedule(int cpu)
{
send_one_CPI(cpu, VIC_RESCHEDULE_CPI);
}
-
-int
-hard_smp_processor_id(void)
+int hard_smp_processor_id(void)
{
__u8 i;
__u8 cpumask = inb(VIC_PROC_WHO_AM_I);
- if((cpumask & QUAD_IDENTIFIER) == QUAD_IDENTIFIER)
+ if ((cpumask & QUAD_IDENTIFIER) == QUAD_IDENTIFIER)
return cpumask & 0x1F;
- for(i = 0; i < 8; i++) {
- if(cpumask & (1<<i))
+ for (i = 0; i < 8; i++) {
+ if (cpumask & (1 << i))
return i;
}
printk("** WARNING ** Illegal cpuid returned by VIC: %d", cpumask);
return 0;
}
-int
-safe_smp_processor_id(void)
+int safe_smp_processor_id(void)
{
return hard_smp_processor_id();
}
/* broadcast a halt to all other CPUs */
-static void
-voyager_smp_send_stop(void)
+static void voyager_smp_send_stop(void)
{
smp_call_function(smp_stop_cpu_function, NULL, 1, 1);
}
/* this function is triggered in time.c when a clock tick fires
* we need to re-broadcast the tick to all CPUs */
-void
-smp_vic_timer_interrupt(void)
+void smp_vic_timer_interrupt(void)
{
send_CPI_allbutself(VIC_TIMER_CPI);
smp_local_timer_interrupt();
@@ -1253,8 +1223,7 @@ smp_vic_timer_interrupt(void)
* multiplier is 1 and it can be changed by writing the new multiplier
* value into /proc/profile.
*/
-void
-smp_local_timer_interrupt(void)
+void smp_local_timer_interrupt(void)
{
int cpu = smp_processor_id();
long weight;
@@ -1269,18 +1238,18 @@ smp_local_timer_interrupt(void)
*
* Interrupts are already masked off at this point.
*/
- per_cpu(prof_counter,cpu) = per_cpu(prof_multiplier, cpu);
+ per_cpu(prof_counter, cpu) = per_cpu(prof_multiplier, cpu);
if (per_cpu(prof_counter, cpu) !=
- per_cpu(prof_old_multiplier, cpu)) {
+ per_cpu(prof_old_multiplier, cpu)) {
/* FIXME: need to update the vic timer tick here */
per_cpu(prof_old_multiplier, cpu) =
- per_cpu(prof_counter, cpu);
+ per_cpu(prof_counter, cpu);
}
update_process_times(user_mode_vm(get_irq_regs()));
}
- if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
+ if (((1 << cpu) & voyager_extended_vic_processors) == 0)
/* only extended VIC processors participate in
* interrupt distribution */
return;
@@ -1296,12 +1265,12 @@ smp_local_timer_interrupt(void)
* we can take more than 100K local irqs per second on a 100 MHz P5.
*/
- if((++vic_tick[cpu] & 0x7) != 0)
+ if ((++vic_tick[cpu] & 0x7) != 0)
return;
/* get here every 16 ticks (about every 1/6 of a second) */
/* Change our priority to give someone else a chance at getting
- * the IRQ. The algorithm goes like this:
+ * the IRQ. The algorithm goes like this:
*
* In the VIC, the dynamically routed interrupt is always
* handled by the lowest priority eligible (i.e. receiving
@@ -1325,18 +1294,18 @@ smp_local_timer_interrupt(void)
* affinity code since we now try to even up the interrupt
* counts when an affinity binding is keeping them on a
* particular CPU*/
- weight = (vic_intr_count[cpu]*voyager_extended_cpus
+ weight = (vic_intr_count[cpu] * voyager_extended_cpus
- vic_intr_total) >> 4;
weight += 4;
- if(weight > 7)
+ if (weight > 7)
weight = 7;
- if(weight < 0)
+ if (weight < 0)
weight = 0;
-
- outb((__u8)weight, VIC_PRIORITY_REGISTER);
+
+ outb((__u8) weight, VIC_PRIORITY_REGISTER);
#ifdef VOYAGER_DEBUG
- if((vic_tick[cpu] & 0xFFF) == 0) {
+ if ((vic_tick[cpu] & 0xFFF) == 0) {
/* print this message roughly every 25 secs */
printk("VOYAGER SMP: vic_tick[%d] = %lu, weight = %ld\n",
cpu, vic_tick[cpu], weight);
@@ -1345,15 +1314,14 @@ smp_local_timer_interrupt(void)
}
/* setup the profiling timer */
-int
-setup_profiling_timer(unsigned int multiplier)
+int setup_profiling_timer(unsigned int multiplier)
{
int i;
- if ( (!multiplier))
+ if ((!multiplier))
return -EINVAL;
- /*
+ /*
* Set the new multiplier for each CPU. CPUs don't start using the
* new values until the next timer interrupt in which they do process
* accounting.
@@ -1367,15 +1335,13 @@ setup_profiling_timer(unsigned int multiplier)
/* This is a bit of a mess, but forced on us by the genirq changes
* there's no genirq handler that really does what voyager wants
* so hack it up with the simple IRQ handler */
-static void fastcall
-handle_vic_irq(unsigned int irq, struct irq_desc *desc)
+static void fastcall handle_vic_irq(unsigned int irq, struct irq_desc *desc)
{
before_handle_vic_irq(irq);
handle_simple_irq(irq, desc);
after_handle_vic_irq(irq);
}
-
/* The CPIs are handled in the per cpu 8259s, so they must be
* enabled to be received: FIX: enabling the CPIs in the early
* boot sequence interferes with bug checking; enable them later
@@ -1385,13 +1351,12 @@ handle_vic_irq(unsigned int irq, struct irq_desc *desc)
#define QIC_SET_GATE(cpi, vector) \
set_intr_gate((cpi) + QIC_DEFAULT_CPI_BASE, (vector))
-void __init
-smp_intr_init(void)
+void __init smp_intr_init(void)
{
int i;
/* initialize the per cpu irq mask to all disabled */
- for(i = 0; i < NR_CPUS; i++)
+ for (i = 0; i < NR_CPUS; i++)
vic_irq_mask[i] = 0xFFFF;
VIC_SET_GATE(VIC_CPI_LEVEL0, vic_cpi_interrupt);
@@ -1404,42 +1369,40 @@ smp_intr_init(void)
QIC_SET_GATE(QIC_RESCHEDULE_CPI, qic_reschedule_interrupt);
QIC_SET_GATE(QIC_ENABLE_IRQ_CPI, qic_enable_irq_interrupt);
QIC_SET_GATE(QIC_CALL_FUNCTION_CPI, qic_call_function_interrupt);
-
- /* now put the VIC descriptor into the first 48 IRQs
+ /* now put the VIC descriptor into the first 48 IRQs
*
* This is for later: first 16 correspond to PC IRQs; next 16
* are Primary MC IRQs and final 16 are Secondary MC IRQs */
- for(i = 0; i < 48; i++)
+ for (i = 0; i < 48; i++)
set_irq_chip_and_handler(i, &vic_chip, handle_vic_irq);
}
/* send a CPI at level cpi to a set of cpus in cpuset (set 1 bit per
* processor to receive CPI */
-static void
-send_CPI(__u32 cpuset, __u8 cpi)
+static void send_CPI(__u32 cpuset, __u8 cpi)
{
int cpu;
__u32 quad_cpuset = (cpuset & voyager_quad_processors);
- if(cpi < VIC_START_FAKE_CPI) {
- /* fake CPI are only used for booting, so send to the
+ if (cpi < VIC_START_FAKE_CPI) {
+ /* fake CPI are only used for booting, so send to the
* extended quads as well---Quads must be VIC booted */
- outb((__u8)(cpuset), VIC_CPI_Registers[cpi]);
+ outb((__u8) (cpuset), VIC_CPI_Registers[cpi]);
return;
}
- if(quad_cpuset)
+ if (quad_cpuset)
send_QIC_CPI(quad_cpuset, cpi);
cpuset &= ~quad_cpuset;
cpuset &= 0xff; /* only first 8 CPUs vaild for VIC CPI */
- if(cpuset == 0)
+ if (cpuset == 0)
return;
for_each_online_cpu(cpu) {
- if(cpuset & (1<<cpu))
+ if (cpuset & (1 << cpu))
set_bit(cpi, &vic_cpi_mailbox[cpu]);
}
- if(cpuset)
- outb((__u8)cpuset, VIC_CPI_Registers[VIC_CPI_LEVEL0]);
+ if (cpuset)
+ outb((__u8) cpuset, VIC_CPI_Registers[VIC_CPI_LEVEL0]);
}
/* Acknowledge receipt of CPI in the QIC, clear in QIC hardware and
@@ -1448,20 +1411,19 @@ send_CPI(__u32 cpuset, __u8 cpi)
* DON'T make this inline otherwise the cache line read will be
* optimised away
* */
-static int
-ack_QIC_CPI(__u8 cpi) {
+static int ack_QIC_CPI(__u8 cpi)
+{
__u8 cpu = hard_smp_processor_id();
cpi &= 7;
- outb(1<<cpi, QIC_INTERRUPT_CLEAR1);
+ outb(1 << cpi, QIC_INTERRUPT_CLEAR1);
return voyager_quad_cpi_addr[cpu]->qic_cpi[cpi].cpi;
}
-static void
-ack_special_QIC_CPI(__u8 cpi)
+static void ack_special_QIC_CPI(__u8 cpi)
{
- switch(cpi) {
+ switch (cpi) {
case VIC_CMN_INT:
outb(QIC_CMN_INT, QIC_INTERRUPT_CLEAR0);
break;
@@ -1474,8 +1436,7 @@ ack_special_QIC_CPI(__u8 cpi)
}
/* Acknowledge receipt of CPI in the VIC (essentially an EOI) */
-static void
-ack_VIC_CPI(__u8 cpi)
+static void ack_VIC_CPI(__u8 cpi)
{
#ifdef VOYAGER_DEBUG
unsigned long flags;
@@ -1484,17 +1445,17 @@ ack_VIC_CPI(__u8 cpi)
local_irq_save(flags);
isr = vic_read_isr();
- if((isr & (1<<(cpi &7))) == 0) {
+ if ((isr & (1 << (cpi & 7))) == 0) {
printk("VOYAGER SMP: CPU%d lost CPI%d\n", cpu, cpi);
}
#endif
/* send specific EOI; the two system interrupts have
* bit 4 set for a separate vector but behave as the
* corresponding 3 bit intr */
- outb_p(0x60|(cpi & 7),0x20);
+ outb_p(0x60 | (cpi & 7), 0x20);
#ifdef VOYAGER_DEBUG
- if((vic_read_isr() & (1<<(cpi &7))) != 0) {
+ if ((vic_read_isr() & (1 << (cpi & 7))) != 0) {
printk("VOYAGER SMP: CPU%d still asserting CPI%d\n", cpu, cpi);
}
local_irq_restore(flags);
@@ -1502,12 +1463,11 @@ ack_VIC_CPI(__u8 cpi)
}
/* cribbed with thanks from irq.c */
-#define __byte(x,y) (((unsigned char *)&(y))[x])
+#define __byte(x,y) (((unsigned char *)&(y))[x])
#define cached_21(cpu) (__byte(0,vic_irq_mask[cpu]))
#define cached_A1(cpu) (__byte(1,vic_irq_mask[cpu]))
-static unsigned int
-startup_vic_irq(unsigned int irq)
+static unsigned int startup_vic_irq(unsigned int irq)
{
unmask_vic_irq(irq);
@@ -1535,13 +1495,12 @@ startup_vic_irq(unsigned int irq)
* broadcast an Interrupt enable CPI which causes all other CPUs to
* adjust their masks accordingly. */
-static void
-unmask_vic_irq(unsigned int irq)
+static void unmask_vic_irq(unsigned int irq)
{
/* linux doesn't to processor-irq affinity, so enable on
* all CPUs we know about */
int cpu = smp_processor_id(), real_cpu;
- __u16 mask = (1<<irq);
+ __u16 mask = (1 << irq);
__u32 processorList = 0;
unsigned long flags;
@@ -1549,78 +1508,72 @@ unmask_vic_irq(unsigned int irq)
irq, cpu, cpu_irq_affinity[cpu]));
spin_lock_irqsave(&vic_irq_lock, flags);
for_each_online_cpu(real_cpu) {
- if(!(voyager_extended_vic_processors & (1<<real_cpu)))
+ if (!(voyager_extended_vic_processors & (1 << real_cpu)))
continue;
- if(!(cpu_irq_affinity[real_cpu] & mask)) {
+ if (!(cpu_irq_affinity[real_cpu] & mask)) {
/* irq has no affinity for this CPU, ignore */
continue;
}
- if(real_cpu == cpu) {
+ if (real_cpu == cpu) {
enable_local_vic_irq(irq);
- }
- else if(vic_irq_mask[real_cpu] & mask) {
+ } else if (vic_irq_mask[real_cpu] & mask) {
vic_irq_enable_mask[real_cpu] |= mask;
- processorList |= (1<<real_cpu);
+ processorList |= (1 << real_cpu);
}
}
spin_unlock_irqrestore(&vic_irq_lock, flags);
- if(processorList)
+ if (processorList)
send_CPI(processorList, VIC_ENABLE_IRQ_CPI);
}
-static void
-mask_vic_irq(unsigned int irq)
+static void mask_vic_irq(unsigned int irq)
{
/* lazy disable, do nothing */
}
-static void
-enable_local_vic_irq(unsigned int irq)
+static void enable_local_vic_irq(unsigned int irq)
{
__u8 cpu = smp_processor_id();
__u16 mask = ~(1 << irq);
__u16 old_mask = vic_irq_mask[cpu];
vic_irq_mask[cpu] &= mask;
- if(vic_irq_mask[cpu] == old_mask)
+ if (vic_irq_mask[cpu] == old_mask)
return;
VDEBUG(("VOYAGER DEBUG: Enabling irq %d in hardware on CPU %d\n",
irq, cpu));
if (irq & 8) {
- outb_p(cached_A1(cpu),0xA1);
+ outb_p(cached_A1(cpu), 0xA1);
(void)inb_p(0xA1);
- }
- else {
- outb_p(cached_21(cpu),0x21);
+ } else {
+ outb_p(cached_21(cpu), 0x21);
(void)inb_p(0x21);
}
}
-static void
-disable_local_vic_irq(unsigned int irq)
+static void disable_local_vic_irq(unsigned int irq)
{
__u8 cpu = smp_processor_id();
__u16 mask = (1 << irq);
__u16 old_mask = vic_irq_mask[cpu];
- if(irq == 7)
+ if (irq == 7)
return;
vic_irq_mask[cpu] |= mask;
- if(old_mask == vic_irq_mask[cpu])
+ if (old_mask == vic_irq_mask[cpu])
return;
VDEBUG(("VOYAGER DEBUG: Disabling irq %d in hardware on CPU %d\n",
irq, cpu));
if (irq & 8) {
- outb_p(cached_A1(cpu),0xA1);
+ outb_p(cached_A1(cpu), 0xA1);
(void)inb_p(0xA1);
- }
- else {
- outb_p(cached_21(cpu),0x21);
+ } else {
+ outb_p(cached_21(cpu), 0x21);
(void)inb_p(0x21);
}
}
@@ -1631,8 +1584,7 @@ disable_local_vic_irq(unsigned int irq)
* interrupt in the vic, so we merely set a flag (IRQ_DISABLED). If
* this interrupt actually comes in, then we mask and ack here to push
* the interrupt off to another CPU */
-static void
-before_handle_vic_irq(unsigned int irq)
+static void before_handle_vic_irq(unsigned int irq)
{
irq_desc_t *desc = irq_desc + irq;
__u8 cpu = smp_processor_id();
@@ -1641,16 +1593,16 @@ before_handle_vic_irq(unsigned int irq)
vic_intr_total++;
vic_intr_count[cpu]++;
- if(!(cpu_irq_affinity[cpu] & (1<<irq))) {
+ if (!(cpu_irq_affinity[cpu] & (1 << irq))) {
/* The irq is not in our affinity mask, push it off
* onto another CPU */
- VDEBUG(("VOYAGER DEBUG: affinity triggered disable of irq %d on cpu %d\n",
- irq, cpu));
+ VDEBUG(("VOYAGER DEBUG: affinity triggered disable of irq %d "
+ "on cpu %d\n", irq, cpu));
disable_local_vic_irq(irq);
/* set IRQ_INPROGRESS to prevent the handler in irq.c from
* actually calling the interrupt routine */
desc->status |= IRQ_REPLAY | IRQ_INPROGRESS;
- } else if(desc->status & IRQ_DISABLED) {
+ } else if (desc->status & IRQ_DISABLED) {
/* Damn, the interrupt actually arrived, do the lazy
* disable thing. The interrupt routine in irq.c will
* not handle a IRQ_DISABLED interrupt, so nothing more
@@ -1667,8 +1619,7 @@ before_handle_vic_irq(unsigned int irq)
}
/* Finish the VIC interrupt: basically mask */
-static void
-after_handle_vic_irq(unsigned int irq)
+static void after_handle_vic_irq(unsigned int irq)
{
irq_desc_t *desc = irq_desc + irq;
@@ -1685,11 +1636,11 @@ after_handle_vic_irq(unsigned int irq)
#ifdef VOYAGER_DEBUG
/* DEBUG: before we ack, check what's in progress */
isr = vic_read_isr();
- if((isr & (1<<irq) && !(status & IRQ_REPLAY)) == 0) {
+ if ((isr & (1 << irq) && !(status & IRQ_REPLAY)) == 0) {
int i;
__u8 cpu = smp_processor_id();
__u8 real_cpu;
- int mask; /* Um... initialize me??? --RR */
+ int mask; /* Um... initialize me??? --RR */
printk("VOYAGER SMP: CPU%d lost interrupt %d\n",
cpu, irq);
@@ -1698,9 +1649,10 @@ after_handle_vic_irq(unsigned int irq)
outb(VIC_CPU_MASQUERADE_ENABLE | real_cpu,
VIC_PROCESSOR_ID);
isr = vic_read_isr();
- if(isr & (1<<irq)) {
- printk("VOYAGER SMP: CPU%d ack irq %d\n",
- real_cpu, irq);
+ if (isr & (1 << irq)) {
+ printk
+ ("VOYAGER SMP: CPU%d ack irq %d\n",
+ real_cpu, irq);
ack_vic_irq(irq);
}
outb(cpu, VIC_PROCESSOR_ID);
@@ -1711,7 +1663,7 @@ after_handle_vic_irq(unsigned int irq)
* receipt by another CPU so everything must be in
* order here */
ack_vic_irq(irq);
- if(status & IRQ_REPLAY) {
+ if (status & IRQ_REPLAY) {
/* replay is set if we disable the interrupt
* in the before_handle_vic_irq() routine, so
* clear the in progress bit here to allow the
@@ -1720,9 +1672,9 @@ after_handle_vic_irq(unsigned int irq)
}
#ifdef VOYAGER_DEBUG
isr = vic_read_isr();
- if((isr & (1<<irq)) != 0)
- printk("VOYAGER SMP: after_handle_vic_irq() after ack irq=%d, isr=0x%x\n",
- irq, isr);
+ if ((isr & (1 << irq)) != 0)
+ printk("VOYAGER SMP: after_handle_vic_irq() after "
+ "ack irq=%d, isr=0x%x\n", irq, isr);
#endif /* VOYAGER_DEBUG */
}
_raw_spin_unlock(&vic_irq_lock);
@@ -1731,7 +1683,6 @@ after_handle_vic_irq(unsigned int irq)
* may be intercepted by another CPU if reasserted */
}
-
/* Linux processor - interrupt affinity manipulations.
*
* For each processor, we maintain a 32 bit irq affinity mask.
@@ -1748,8 +1699,7 @@ after_handle_vic_irq(unsigned int irq)
* change the mask and then do an interrupt enable CPI to re-enable on
* the selected processors */
-void
-set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
+void set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
{
/* Only extended processors handle interrupts */
unsigned long real_mask;
@@ -1757,13 +1707,13 @@ set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
int cpu;
real_mask = cpus_addr(mask)[0] & voyager_extended_vic_processors;
-
- if(cpus_addr(mask)[0] == 0)
+
+ if (cpus_addr(mask)[0] == 0)
/* can't have no CPUs to accept the interrupt -- extremely
* bad things will happen */
return;
- if(irq == 0)
+ if (irq == 0)
/* can't change the affinity of the timer IRQ. This
* is due to the constraint in the voyager
* architecture that the CPI also comes in on and IRQ
@@ -1772,7 +1722,7 @@ set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
* will no-longer be able to accept VIC CPIs */
return;
- if(irq >= 32)
+ if (irq >= 32)
/* You can only have 32 interrupts in a voyager system
* (and 32 only if you have a secondary microchannel
* bus) */
@@ -1780,8 +1730,8 @@ set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
for_each_online_cpu(cpu) {
unsigned long cpu_mask = 1 << cpu;
-
- if(cpu_mask & real_mask) {
+
+ if (cpu_mask & real_mask) {
/* enable the interrupt for this cpu */
cpu_irq_affinity[cpu] |= irq_mask;
} else {
@@ -1800,25 +1750,23 @@ set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
unmask_vic_irq(irq);
}
-static void
-ack_vic_irq(unsigned int irq)
+static void ack_vic_irq(unsigned int irq)
{
if (irq & 8) {
- outb(0x62,0x20); /* Specific EOI to cascade */
- outb(0x60|(irq & 7),0xA0);
+ outb(0x62, 0x20); /* Specific EOI to cascade */
+ outb(0x60 | (irq & 7), 0xA0);
} else {
- outb(0x60 | (irq & 7),0x20);
+ outb(0x60 | (irq & 7), 0x20);
}
}
/* enable the CPIs. In the VIC, the CPIs are delivered by the 8259
* but are not vectored by it. This means that the 8259 mask must be
* lowered to receive them */
-static __init void
-vic_enable_cpi(void)
+static __init void vic_enable_cpi(void)
{
__u8 cpu = smp_processor_id();
-
+
/* just take a copy of the current mask (nop for boot cpu) */
vic_irq_mask[cpu] = vic_irq_mask[boot_cpu_id];
@@ -1827,7 +1775,7 @@ vic_enable_cpi(void)
/* for sys int and cmn int */
enable_local_vic_irq(7);
- if(is_cpu_quad()) {
+ if (is_cpu_quad()) {
outb(QIC_DEFAULT_MASK0, QIC_MASK_REGISTER0);
outb(QIC_CPI_ENABLE, QIC_MASK_REGISTER1);
VDEBUG(("VOYAGER SMP: QIC ENABLE CPI: CPU%d: MASK 0x%x\n",
@@ -1838,8 +1786,7 @@ vic_enable_cpi(void)
cpu, vic_irq_mask[cpu]));
}
-void
-voyager_smp_dump()
+void voyager_smp_dump()
{
int old_cpu = smp_processor_id(), cpu;
@@ -1865,10 +1812,10 @@ voyager_smp_dump()
cpu, vic_irq_mask[cpu], imr, irr, isr);
#if 0
/* These lines are put in to try to unstick an un ack'd irq */
- if(isr != 0) {
+ if (isr != 0) {
int irq;
- for(irq=0; irq<16; irq++) {
- if(isr & (1<<irq)) {
+ for (irq = 0; irq < 16; irq++) {
+ if (isr & (1 << irq)) {
printk("\tCPU%d: ack irq %d\n",
cpu, irq);
local_irq_save(flags);
@@ -1884,17 +1831,15 @@ voyager_smp_dump()
}
}
-void
-smp_voyager_power_off(void *dummy)
+void smp_voyager_power_off(void *dummy)
{
- if(smp_processor_id() == boot_cpu_id)
+ if (smp_processor_id() == boot_cpu_id)
voyager_power_off();
else
smp_stop_cpu_function(NULL);
}
-static void __init
-voyager_smp_prepare_cpus(unsigned int max_cpus)
+static void __init voyager_smp_prepare_cpus(unsigned int max_cpus)
{
/* FIXME: ignore max_cpus for now */
smp_boot_cpus();
@@ -1911,8 +1856,7 @@ static void __cpuinit voyager_smp_prepare_boot_cpu(void)
cpu_set(smp_processor_id(), cpu_present_map);
}
-static int __cpuinit
-voyager_cpu_up(unsigned int cpu)
+static int __cpuinit voyager_cpu_up(unsigned int cpu)
{
/* This only works at boot for x86. See "rewrite" above. */
if (cpu_isset(cpu, smp_commenced_mask))
@@ -1928,14 +1872,12 @@ voyager_cpu_up(unsigned int cpu)
return 0;
}
-static void __init
-voyager_smp_cpus_done(unsigned int max_cpus)
+static void __init voyager_smp_cpus_done(unsigned int max_cpus)
{
zap_low_mappings();
}
-void __init
-smp_setup_processor_id(void)
+void __init smp_setup_processor_id(void)
{
current_thread_info()->cpu = hard_smp_processor_id();
x86_write_percpu(cpu_number, hard_smp_processor_id());
diff --git a/arch/x86/mach-voyager/voyager_thread.c b/arch/x86/mach-voyager/voyager_thread.c
index 50f9366c411e..c69c931818ed 100644
--- a/arch/x86/mach-voyager/voyager_thread.c
+++ b/arch/x86/mach-voyager/voyager_thread.c
@@ -30,12 +30,10 @@
#include <asm/mtrr.h>
#include <asm/msr.h>
-
struct task_struct *voyager_thread;
static __u8 set_timeout;
-static int
-execute(const char *string)
+static int execute(const char *string)
{
int ret;
@@ -52,48 +50,48 @@ execute(const char *string)
NULL,
};
- if ((ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC)) != 0) {
- printk(KERN_ERR "Voyager failed to run \"%s\": %i\n",
- string, ret);
+ if ((ret =
+ call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC)) != 0) {
+ printk(KERN_ERR "Voyager failed to run \"%s\": %i\n", string,
+ ret);
}
return ret;
}
-static void
-check_from_kernel(void)
+static void check_from_kernel(void)
{
- if(voyager_status.switch_off) {
-
+ if (voyager_status.switch_off) {
+
/* FIXME: This should be configurable via proc */
execute("umask 600; echo 0 > /etc/initrunlvl; kill -HUP 1");
- } else if(voyager_status.power_fail) {
+ } else if (voyager_status.power_fail) {
VDEBUG(("Voyager daemon detected AC power failure\n"));
-
+
/* FIXME: This should be configureable via proc */
execute("umask 600; echo F > /etc/powerstatus; kill -PWR 1");
set_timeout = 1;
}
}
-static void
-check_continuing_condition(void)
+static void check_continuing_condition(void)
{
- if(voyager_status.power_fail) {
+ if (voyager_status.power_fail) {
__u8 data;
- voyager_cat_psi(VOYAGER_PSI_SUBREAD,
+ voyager_cat_psi(VOYAGER_PSI_SUBREAD,
VOYAGER_PSI_AC_FAIL_REG, &data);
- if((data & 0x1f) == 0) {
+ if ((data & 0x1f) == 0) {
/* all power restored */
- printk(KERN_NOTICE "VOYAGER AC power restored, cancelling shutdown\n");
+ printk(KERN_NOTICE
+ "VOYAGER AC power restored, cancelling shutdown\n");
/* FIXME: should be user configureable */
- execute("umask 600; echo O > /etc/powerstatus; kill -PWR 1");
+ execute
+ ("umask 600; echo O > /etc/powerstatus; kill -PWR 1");
set_timeout = 0;
}
}
}
-static int
-thread(void *unused)
+static int thread(void *unused)
{
printk(KERN_NOTICE "Voyager starting monitor thread\n");
@@ -102,7 +100,7 @@ thread(void *unused)
schedule_timeout(set_timeout ? HZ : MAX_SCHEDULE_TIMEOUT);
VDEBUG(("Voyager Daemon awoken\n"));
- if(voyager_status.request_from_kernel == 0) {
+ if (voyager_status.request_from_kernel == 0) {
/* probably awoken from timeout */
check_continuing_condition();
} else {
@@ -112,20 +110,18 @@ thread(void *unused)
}
}
-static int __init
-voyager_thread_start(void)
+static int __init voyager_thread_start(void)
{
voyager_thread = kthread_run(thread, NULL, "kvoyagerd");
if (IS_ERR(voyager_thread)) {
- printk(KERN_ERR "Voyager: Failed to create system monitor thread.\n");
+ printk(KERN_ERR
+ "Voyager: Failed to create system monitor thread.\n");
return PTR_ERR(voyager_thread);
}
return 0;
}
-
-static void __exit
-voyager_thread_stop(void)
+static void __exit voyager_thread_stop(void)
{
kthread_stop(voyager_thread);
}
commit 31183ba8fd05b6ddc67ab4d726167cbc52e1b346
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Jan 30 13:30:10 2008 +0100
x86: clean up arch/x86/kernel/aperture_64.c printk()s
clean up arch/x86/kernel/aperture_64.c printk()s.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index 250db0527f5d..52d2beac4556 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -66,14 +66,15 @@ static u32 __init allocate_aperture(void)
*/
p = __alloc_bootmem_nopanic(aper_size, aper_size, 0);
if (!p || __pa(p)+aper_size > 0xffffffff) {
- printk("Cannot allocate aperture memory hole (%p,%uK)\n",
- p, aper_size>>10);
+ printk(KERN_ERR
+ "Cannot allocate aperture memory hole (%p,%uK)\n",
+ p, aper_size>>10);
if (p)
free_bootmem(__pa(p), aper_size);
return 0;
}
- printk("Mapping aperture over %d KB of RAM @ %lx\n",
- aper_size >> 10, __pa(p));
+ printk(KERN_INFO "Mapping aperture over %d KB of RAM @ %lx\n",
+ aper_size >> 10, __pa(p));
insert_aperture_resource((u32)__pa(p), aper_size);
return (u32)__pa(p);
@@ -83,18 +84,20 @@ static int __init aperture_valid(u64 aper_base, u32 aper_size)
{
if (!aper_base)
return 0;
+
if (aper_size < 64*1024*1024) {
- printk("Aperture too small (%d MB)\n", aper_size>>20);
+ printk(KERN_ERR "Aperture too small (%d MB)\n", aper_size>>20);
return 0;
}
if (aper_base + aper_size > 0x100000000UL) {
- printk("Aperture beyond 4GB. Ignoring.\n");
+ printk(KERN_ERR "Aperture beyond 4GB. Ignoring.\n");
return 0;
}
if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
- printk("Aperture pointing to e820 RAM. Ignoring.\n");
+ printk(KERN_ERR "Aperture pointing to e820 RAM. Ignoring.\n");
return 0;
}
+
return 1;
}
@@ -133,10 +136,10 @@ static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order)
u32 aper_low, aper_hi;
u64 aper;
- printk("AGP bridge at %02x:%02x:%02x\n", num, slot, func);
+ printk(KERN_INFO "AGP bridge at %02x:%02x:%02x\n", num, slot, func);
apsizereg = read_pci_config_16(num, slot, func, cap + 0x14);
if (apsizereg == 0xffffffff) {
- printk("APSIZE in AGP bridge unreadable\n");
+ printk(KERN_ERR "APSIZE in AGP bridge unreadable\n");
return 0;
}
@@ -153,8 +156,8 @@ static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order)
aper_hi = read_pci_config(num, slot, func, 0x14);
aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32);
- printk("Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n",
- aper, 32 << *order, apsizereg);
+ printk(KERN_INFO "Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n",
+ aper, 32 << *order, apsizereg);
if (!aperture_valid(aper, (32*1024*1024) << *order))
return 0;
@@ -210,7 +213,7 @@ static __u32 __init search_agp_bridge(u32 *order, int *valid_agp)
}
}
}
- printk("No AGP bridge found\n");
+ printk(KERN_INFO "No AGP bridge found\n");
return 0;
}
@@ -240,8 +243,8 @@ void __init gart_iommu_hole_init(void)
aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff;
aper_base <<= 25;
- printk("CPU %d: aperture @ %Lx size %u MB\n", num-24,
- aper_base, aper_size>>20);
+ printk(KERN_INFO "CPU %d: aperture @ %Lx size %u MB\n",
+ num-24, aper_base, aper_size>>20);
if (!aperture_valid(aper_base, aper_size)) {
fix = 1;
@@ -277,10 +280,13 @@ void __init gart_iommu_hole_init(void)
force_iommu ||
valid_agp ||
fallback_aper_force) {
- printk("Your BIOS doesn't leave a aperture memory hole\n");
- printk("Please enable the IOMMU option in the BIOS setup\n");
- printk("This costs you %d MB of RAM\n",
- 32 << fallback_aper_order);
+ printk(KERN_ERR
+ "Your BIOS doesn't leave a aperture memory hole\n");
+ printk(KERN_ERR
+ "Please enable the IOMMU option in the BIOS setup\n");
+ printk(KERN_ERR
+ "This costs you %d MB of RAM\n",
+ 32 << fallback_aper_order);
aper_order = fallback_aper_order;
aper_alloc = allocate_aperture();
commit c140df973c07ac328aafd19d4f4c413f2f8902df
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Jan 30 13:30:09 2008 +0100
x86: clean up arch/x86/kernel/aperture_64.c
whitespace cleanup. No code changed:
text data bss dec hex filename
2080 76 4 2160 870 aperture_64.o.before
2080 76 4 2160 870 aperture_64.o.after
errors lines of code errors/KLOC
arch/x86/kernel/aperture_64.c 114 299 381.2
arch/x86/kernel/aperture_64.c 0 315 0
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index 5b6992799c9d..250db0527f5d 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -1,12 +1,12 @@
-/*
+/*
* Firmware replacement code.
- *
+ *
* Work around broken BIOSes that don't set an aperture or only set the
- * aperture in the AGP bridge.
- * If all fails map the aperture over some low memory. This is cheaper than
- * doing bounce buffering. The memory is lost. This is done at early boot
- * because only the bootmem allocator can allocate 32+MB.
- *
+ * aperture in the AGP bridge.
+ * If all fails map the aperture over some low memory. This is cheaper than
+ * doing bounce buffering. The memory is lost. This is done at early boot
+ * because only the bootmem allocator can allocate 32+MB.
+ *
* Copyright 2002 Andi Kleen, SuSE Labs.
*/
#include <linux/kernel.h>
@@ -30,7 +30,7 @@ int gart_iommu_aperture_disabled __initdata = 0;
int gart_iommu_aperture_allowed __initdata = 0;
int fallback_aper_order __initdata = 1; /* 64MB */
-int fallback_aper_force __initdata = 0;
+int fallback_aper_force __initdata = 0;
int fix_aperture __initdata = 1;
@@ -49,20 +49,20 @@ static void __init insert_aperture_resource(u32 aper_base, u32 aper_size)
/* This code runs before the PCI subsystem is initialized, so just
access the northbridge directly. */
-static u32 __init allocate_aperture(void)
+static u32 __init allocate_aperture(void)
{
u32 aper_size;
- void *p;
+ void *p;
- if (fallback_aper_order > 7)
- fallback_aper_order = 7;
- aper_size = (32 * 1024 * 1024) << fallback_aper_order;
+ if (fallback_aper_order > 7)
+ fallback_aper_order = 7;
+ aper_size = (32 * 1024 * 1024) << fallback_aper_order;
- /*
- * Aperture has to be naturally aligned. This means an 2GB aperture won't
- * have much chance of finding a place in the lower 4GB of memory.
- * Unfortunately we cannot move it up because that would make the
- * IOMMU useless.
+ /*
+ * Aperture has to be naturally aligned. This means a 2GB aperture
+ * won't have much chance of finding a place in the lower 4GB of
+ * memory. Unfortunately we cannot move it up because that would
+ * make the IOMMU useless.
*/
p = __alloc_bootmem_nopanic(aper_size, aper_size, 0);
if (!p || __pa(p)+aper_size > 0xffffffff) {
@@ -73,54 +73,60 @@ static u32 __init allocate_aperture(void)
return 0;
}
printk("Mapping aperture over %d KB of RAM @ %lx\n",
- aper_size >> 10, __pa(p));
+ aper_size >> 10, __pa(p));
insert_aperture_resource((u32)__pa(p), aper_size);
- return (u32)__pa(p);
+
+ return (u32)__pa(p);
}
static int __init aperture_valid(u64 aper_base, u32 aper_size)
-{
- if (!aper_base)
+{
+ if (!aper_base)
return 0;
- if (aper_size < 64*1024*1024) {
+ if (aper_size < 64*1024*1024) {
printk("Aperture too small (%d MB)\n", aper_size>>20);
return 0;
}
if (aper_base + aper_size > 0x100000000UL) {
printk("Aperture beyond 4GB. Ignoring.\n");
- return 0;
+ return 0;
}
if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
printk("Aperture pointing to e820 RAM. Ignoring.\n");
- return 0;
- }
+ return 0;
+ }
return 1;
-}
+}
/* Find a PCI capability */
-static __u32 __init find_cap(int num, int slot, int func, int cap)
-{
- u8 pos;
+static __u32 __init find_cap(int num, int slot, int func, int cap)
+{
int bytes;
- if (!(read_pci_config_16(num,slot,func,PCI_STATUS) & PCI_STATUS_CAP_LIST))
+ u8 pos;
+
+ if (!(read_pci_config_16(num, slot, func, PCI_STATUS) &
+ PCI_STATUS_CAP_LIST))
return 0;
- pos = read_pci_config_byte(num,slot,func,PCI_CAPABILITY_LIST);
- for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {
+
+ pos = read_pci_config_byte(num, slot, func, PCI_CAPABILITY_LIST);
+ for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {
u8 id;
- pos &= ~3;
- id = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_ID);
+
+ pos &= ~3;
+ id = read_pci_config_byte(num, slot, func, pos+PCI_CAP_LIST_ID);
if (id == 0xff)
break;
- if (id == cap)
- return pos;
- pos = read_pci_config_byte(num,slot,func,pos+PCI_CAP_LIST_NEXT);
- }
+ if (id == cap)
+ return pos;
+ pos = read_pci_config_byte(num, slot, func,
+ pos+PCI_CAP_LIST_NEXT);
+ }
return 0;
-}
+}
/* Read a standard AGPv3 bridge header */
static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order)
-{
+{
u32 apsize;
u32 apsizereg;
int nbits;
@@ -128,7 +134,7 @@ static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order)
u64 aper;
printk("AGP bridge at %02x:%02x:%02x\n", num, slot, func);
- apsizereg = read_pci_config_16(num,slot,func, cap + 0x14);
+ apsizereg = read_pci_config_16(num, slot, func, cap + 0x14);
if (apsizereg == 0xffffffff) {
printk("APSIZE in AGP bridge unreadable\n");
return 0;
@@ -136,80 +142,84 @@ static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order)
apsize = apsizereg & 0xfff;
/* Some BIOS use weird encodings not in the AGPv3 table. */
- if (apsize & 0xff)
- apsize |= 0xf00;
+ if (apsize & 0xff)
+ apsize |= 0xf00;
nbits = hweight16(apsize);
*order = 7 - nbits;
if ((int)*order < 0) /* < 32MB */
*order = 0;
-
- aper_low = read_pci_config(num,slot,func, 0x10);
- aper_hi = read_pci_config(num,slot,func,0x14);
+
+ aper_low = read_pci_config(num, slot, func, 0x10);
+ aper_hi = read_pci_config(num, slot, func, 0x14);
aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32);
- printk("Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n",
+ printk("Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n",
aper, 32 << *order, apsizereg);
if (!aperture_valid(aper, (32*1024*1024) << *order))
- return 0;
- return (u32)aper;
-}
-
-/* Look for an AGP bridge. Windows only expects the aperture in the
- AGP bridge and some BIOS forget to initialize the Northbridge too.
- Work around this here.
-
- Do an PCI bus scan by hand because we're running before the PCI
- subsystem.
+ return 0;
+ return (u32)aper;
+}
- All K8 AGP bridges are AGPv3 compliant, so we can do this scan
- generically. It's probably overkill to always scan all slots because
- the AGP bridges should be always an own bus on the HT hierarchy,
- but do it here for future safety. */
+/*
+ * Look for an AGP bridge. Windows only expects the aperture in the
+ * AGP bridge and some BIOS forget to initialize the Northbridge too.
+ * Work around this here.
+ *
+ * Do an PCI bus scan by hand because we're running before the PCI
+ * subsystem.
+ *
+ * All K8 AGP bridges are AGPv3 compliant, so we can do this scan
+ * generically. It's probably overkill to always scan all slots because
+ * the AGP bridges should be always an own bus on the HT hierarchy,
+ * but do it here for future safety.
+ */
static __u32 __init search_agp_bridge(u32 *order, int *valid_agp)
{
int num, slot, func;
/* Poor man's PCI discovery */
- for (num = 0; num < 256; num++) {
- for (slot = 0; slot < 32; slot++) {
- for (func = 0; func < 8; func++) {
+ for (num = 0; num < 256; num++) {
+ for (slot = 0; slot < 32; slot++) {
+ for (func = 0; func < 8; func++) {
u32 class, cap;
u8 type;
- class = read_pci_config(num,slot,func,
+ class = read_pci_config(num, slot, func,
PCI_CLASS_REVISION);
if (class == 0xffffffff)
- break;
-
- switch (class >> 16) {
+ break;
+
+ switch (class >> 16) {
case PCI_CLASS_BRIDGE_HOST:
case PCI_CLASS_BRIDGE_OTHER: /* needed? */
/* AGP bridge? */
- cap = find_cap(num,slot,func,PCI_CAP_ID_AGP);
+ cap = find_cap(num, slot, func,
+ PCI_CAP_ID_AGP);
if (!cap)
break;
- *valid_agp = 1;
- return read_agp(num,slot,func,cap,order);
- }
-
+ *valid_agp = 1;
+ return read_agp(num, slot, func, cap,
+ order);
+ }
+
/* No multi-function device? */
- type = read_pci_config_byte(num,slot,func,
+ type = read_pci_config_byte(num, slot, func,
PCI_HEADER_TYPE);
if (!(type & 0x80))
break;
- }
- }
+ }
+ }
}
- printk("No AGP bridge found\n");
+ printk("No AGP bridge found\n");
+
return 0;
}
void __init gart_iommu_hole_init(void)
-{
- int fix, num;
+{
u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0;
u64 aper_base, last_aper_base = 0;
- int valid_agp = 0;
+ int fix, num, valid_agp = 0;
if (gart_iommu_aperture_disabled || !fix_aperture ||
!early_pci_allowed())
@@ -218,24 +228,24 @@ void __init gart_iommu_hole_init(void)
printk(KERN_INFO "Checking aperture...\n");
fix = 0;
- for (num = 24; num < 32; num++) {
+ for (num = 24; num < 32; num++) {
if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00)))
continue;
iommu_detected = 1;
gart_iommu_aperture = 1;
- aper_order = (read_pci_config(0, num, 3, 0x90) >> 1) & 7;
- aper_size = (32 * 1024 * 1024) << aper_order;
+ aper_order = (read_pci_config(0, num, 3, 0x90) >> 1) & 7;
+ aper_size = (32 * 1024 * 1024) << aper_order;
aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff;
- aper_base <<= 25;
+ aper_base <<= 25;
- printk("CPU %d: aperture @ %Lx size %u MB\n", num-24,
+ printk("CPU %d: aperture @ %Lx size %u MB\n", num-24,
aper_base, aper_size>>20);
-
+
if (!aperture_valid(aper_base, aper_size)) {
- fix = 1;
- break;
+ fix = 1;
+ break;
}
if ((last_aper_order && aper_order != last_aper_order) ||
@@ -245,27 +255,28 @@ void __init gart_iommu_hole_init(void)
}
last_aper_order = aper_order;
last_aper_base = aper_base;
- }
+ }
if (!fix && !fallback_aper_force) {
if (last_aper_base) {
unsigned long n = (32 * 1024 * 1024) << last_aper_order;
+
insert_aperture_resource((u32)last_aper_base, n);
}
- return;
+ return;
}
if (!fallback_aper_force)
- aper_alloc = search_agp_bridge(&aper_order, &valid_agp);
-
- if (aper_alloc) {
+ aper_alloc = search_agp_bridge(&aper_order, &valid_agp);
+
+ if (aper_alloc) {
/* Got the aperture from the AGP bridge */
} else if (swiotlb && !valid_agp) {
/* Do nothing */
} else if ((!no_iommu && end_pfn > MAX_DMA32_PFN) ||
force_iommu ||
valid_agp ||
- fallback_aper_force) {
+ fallback_aper_force) {
printk("Your BIOS doesn't leave a aperture memory hole\n");
printk("Please enable the IOMMU option in the BIOS setup\n");
printk("This costs you %d MB of RAM\n",
@@ -273,27 +284,32 @@ void __init gart_iommu_hole_init(void)
aper_order = fallback_aper_order;
aper_alloc = allocate_aperture();
- if (!aper_alloc) {
- /* Could disable AGP and IOMMU here, but it's probably
- not worth it. But the later users cannot deal with
- bad apertures and turning on the aperture over memory
- causes very strange problems, so it's better to
- panic early. */
+ if (!aper_alloc) {
+ /*
+ * Could disable AGP and IOMMU here, but it's
+ * probably not worth it. But the later users
+ * cannot deal with bad apertures and turning
+ * on the aperture over memory causes very
+ * strange problems, so it's better to panic
+ * early.
+ */
panic("Not enough memory for aperture");
}
- } else {
- return;
- }
+ } else {
+ return;
+ }
/* Fix up the north bridges */
- for (num = 24; num < 32; num++) {
+ for (num = 24; num < 32; num++) {
if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00)))
- continue;
-
- /* Don't enable translation yet. That is done later.
- Assume this BIOS didn't initialise the GART so
- just overwrite all previous bits */
- write_pci_config(0, num, 3, 0x90, aper_order<<1);
- write_pci_config(0, num, 3, 0x94, aper_alloc>>25);
- }
-}
+ continue;
+
+ /*
+ * Don't enable translation yet. That is done later.
+ * Assume this BIOS didn't initialise the GART so
+ * just overwrite all previous bits
+ */
+ write_pci_config(0, num, 3, 0x90, aper_order<<1);
+ write_pci_config(0, num, 3, 0x94, aper_alloc>>25);
+ }
+}
commit 5ee613b6751cd91db4b6bd7c1dc9d2f9cf65cde2
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Jan 30 13:30:06 2008 +0100
x86: idle wakeup event in the HLT loop
do a proper idle-wakeup event on HLT as well - some CPUs stop the TSC
in HLT too, not just when going through the ACPI methods.
(the ACPI idle code already does this.)
[ update the 64-bit side too, as noticed by Jiri Slaby. ]
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 46d391d49de8..a63d2d2556ee 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -113,10 +113,19 @@ void default_idle(void)
smp_mb();
local_irq_disable();
- if (!need_resched())
+ if (!need_resched()) {
+ ktime_t t0, t1;
+ u64 t0n, t1n;
+
+ t0 = ktime_get();
+ t0n = ktime_to_ns(t0);
safe_halt(); /* enables interrupts racelessly */
- else
- local_irq_enable();
+ local_irq_disable();
+ t1 = ktime_get();
+ t1n = ktime_to_ns(t1);
+ sched_clock_idle_wakeup_event(t1n - t0n);
+ }
+ local_irq_enable();
current_thread_info()->status |= TS_POLLING;
} else {
/* loop is done by the caller */
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index c2db7ef93565..40fed477f3e5 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -116,9 +116,16 @@ static void default_idle(void)
smp_mb();
local_irq_disable();
if (!need_resched()) {
- /* Enables interrupts one instruction before HLT.
- x86 special cases this so there is no race. */
- safe_halt();
+ ktime_t t0, t1;
+ u64 t0n, t1n;
+
+ t0 = ktime_get();
+ t0n = ktime_to_ns(t0);
+ safe_halt(); /* enables interrupts racelessly */
+ local_irq_disable();
+ t1 = ktime_get();
+ t1n = ktime_to_ns(t1);
+ sched_clock_idle_wakeup_event(t1n - t0n);
} else
local_irq_enable();
current_thread_info()->status |= TS_POLLING;
commit f9fc58910ebc448b0b7d37af1bf57a896a78e9c4
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Jan 30 13:30:05 2008 +0100
x86: add DMI quirk for io-delay hangs on Compaq Presario V6000 laptops
add the DMI strings provided by Islam Amer <pharon@gmail.com>, for
the Compaq Presario V6000 (Quanta/30B7).
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/arch/x86/kernel/io_delay.c b/arch/x86/kernel/io_delay.c
index f052e34dc94c..bd49321034db 100644
--- a/arch/x86/kernel/io_delay.c
+++ b/arch/x86/kernel/io_delay.c
@@ -61,6 +61,14 @@ static int __init dmi_io_delay_0xed_port(const struct dmi_system_id *id)
* 0x80 is used:
*/
static struct dmi_system_id __initdata io_delay_0xed_port_dmi_table[] = {
+ {
+ .callback = dmi_io_delay_0xed_port,
+ .ident = "Compaq Presario V6000",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
+ DMI_MATCH(DMI_BOARD_NAME, "30B7")
+ }
+ },
{
.callback = dmi_io_delay_0xed_port,
.ident = "HP Pavilion dv9000z",
@@ -69,6 +77,14 @@ static struct dmi_system_id __initdata io_delay_0xed_port_dmi_table[] = {
DMI_MATCH(DMI_BOARD_NAME, "30B9")
}
},
+ {
+ .callback = dmi_io_delay_0xed_port,
+ .ident = "HP Pavilion tx1000",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
+ DMI_MATCH(DMI_BOARD_NAME, "30BF")
+ }
+ },
{ }
};
commit d0049e71c6e14a3b0a5b8cedaa1325a1a91fecb0
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Jan 30 13:30:05 2008 +0100
x86: make io_delay=0xed the default
make io_delay=0xed the default. This frees up port 0x80 which is
a debug port on some machines and locks up certain laptops.
Testing only for now. Try the io_delay=0x80 boot option if this does not
work for you.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index 77eda46f97b8..b747ab38814d 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -134,7 +134,7 @@ config IO_DELAY_TYPE_NONE
choice
prompt "IO delay type"
- default IO_DELAY_0X80
+ default IO_DELAY_0XED
config IO_DELAY_0X80
bool "port 0x80 based port-IO delay [recommended]"
commit 6e7c402590b75b6b45138792445ee0f0315a8473
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Jan 30 13:30:05 2008 +0100
x86: various changes and cleanups to in_p/out_p delay details
various changes to the in_p/out_p delay details:
- add the io_delay=none method
- make each method selectable from the kernel config
- simplify the delay code a bit by getting rid of an indirect function call
- add the /proc/sys/kernel/io_delay_type sysctl
- change 'io_delay=standard|alternate' to io_delay=0x80 and io_delay=0xed
- make the io delay config not depend on CONFIG_DEBUG_KERNEL
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: "David P. Reed" <dpreed@reed.com>
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 9e6056058425..b427b7c0e5d0 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -795,12 +795,14 @@ and is between 256 and 4096 characters. It is defined in the file
then look in the higher range.
io_delay= [X86-32,X86-64] I/O delay method
- standard
- Standard port 0x80 delay
- alternate
- Alternate port 0xed delay
+ 0x80
+ Standard port 0x80 based delay
+ 0xed
+ Alternate port 0xed based delay (needed on some systems)
udelay
- Simple two microsecond delay
+ Simple two microseconds delay
+ none
+ No delay
io7= [HW] IO7 for Marvel based alpha systems
See comment before marvel_specify_io7 in
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index 40aba670fb37..77eda46f97b8 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -112,13 +112,78 @@ config IOMMU_LEAK
Add a simple leak tracer to the IOMMU code. This is useful when you
are debugging a buggy device driver that leaks IOMMU mappings.
-config UDELAY_IO_DELAY
- bool "Delay I/O through udelay instead of outb"
- depends on DEBUG_KERNEL
+#
+# IO delay types:
+#
+
+config IO_DELAY_TYPE_0X80
+ int
+ default "0"
+
+config IO_DELAY_TYPE_0XED
+ int
+ default "1"
+
+config IO_DELAY_TYPE_UDELAY
+ int
+ default "2"
+
+config IO_DELAY_TYPE_NONE
+ int
+ default "3"
+
+choice
+ prompt "IO delay type"
+ default IO_DELAY_0X80
+
+config IO_DELAY_0X80
+ bool "port 0x80 based port-IO delay [recommended]"
+ help
+ This is the traditional Linux IO delay used for in/out_p.
+ It is the most tested hence safest selection here.
+
+config IO_DELAY_0XED
+ bool "port 0xed based port-IO delay"
+ help
+ Use port 0xed as the IO delay. This frees up port 0x80 which is
+ often used as a hardware-debug port.
+
+config IO_DELAY_UDELAY
+ bool "udelay based port-IO delay"
+ help
+ Use udelay(2) as the IO delay method. This provides the delay
+ while not having any side-effect on the IO port space.
+
+config IO_DELAY_NONE
+ bool "no port-IO delay"
help
- Make inb_p/outb_p use udelay() based delays by default. Please note
- that udelay() does not have the same bus-level side-effects that
- the normal outb based delay does meaning this could cause drivers
- to change behaviour and/or bugs to surface.
+ No port-IO delay. Will break on old boxes that require port-IO
+ delay for certain operations. Should work on most new machines.
+
+endchoice
+
+if IO_DELAY_0X80
+config DEFAULT_IO_DELAY_TYPE
+ int
+ default IO_DELAY_TYPE_0X80
+endif
+
+if IO_DELAY_0XED
+config DEFAULT_IO_DELAY_TYPE
+ int
+ default IO_DELAY_TYPE_0XED
+endif
+
+if IO_DELAY_UDELAY
+config DEFAULT_IO_DELAY_TYPE
+ int
+ default IO_DELAY_TYPE_UDELAY
+endif
+
+if IO_DELAY_NONE
+config DEFAULT_IO_DELAY_TYPE
+ int
+ default IO_DELAY_TYPE_NONE
+endif
endmenu
diff --git a/arch/x86/kernel/io_delay.c b/arch/x86/kernel/io_delay.c
index 4d955e74b974..f052e34dc94c 100644
--- a/arch/x86/kernel/io_delay.c
+++ b/arch/x86/kernel/io_delay.c
@@ -1,5 +1,9 @@
/*
* I/O delay strategies for inb_p/outb_p
+ *
+ * Allow for a DMI based override of port 0x80, needed for certain HP laptops
+ * and possibly other systems. Also allow for the gradual elimination of
+ * outb_p/inb_p API uses.
*/
#include <linux/kernel.h>
#include <linux/module.h>
@@ -8,98 +12,86 @@
#include <linux/dmi.h>
#include <asm/io.h>
-/*
- * Allow for a DMI based override of port 0x80 needed for certain HP laptops
- */
-#define IO_DELAY_PORT_STD 0x80
-#define IO_DELAY_PORT_ALT 0xed
-
-static void standard_io_delay(void)
-{
- asm volatile ("outb %%al, %0" : : "N" (IO_DELAY_PORT_STD));
-}
-
-static void alternate_io_delay(void)
-{
- asm volatile ("outb %%al, %0" : : "N" (IO_DELAY_PORT_ALT));
-}
-
-/*
- * 2 usecs is an upper-bound for the outb delay but note that udelay doesn't
- * have the bus-level side-effects that outb does
- */
-#define IO_DELAY_USECS 2
-
-/*
- * High on a hill was a lonely goatherd
- */
-static void udelay_io_delay(void)
-{
- udelay(IO_DELAY_USECS);
-}
+int io_delay_type __read_mostly = CONFIG_DEFAULT_IO_DELAY_TYPE;
+EXPORT_SYMBOL_GPL(io_delay_type);
-#ifndef CONFIG_UDELAY_IO_DELAY
-static void (*io_delay)(void) = standard_io_delay;
-#else
-static void (*io_delay)(void) = udelay_io_delay;
-#endif
+static int __initdata io_delay_override;
/*
* Paravirt wants native_io_delay to be a constant.
*/
void native_io_delay(void)
{
- io_delay();
+ switch (io_delay_type) {
+ default:
+ case CONFIG_IO_DELAY_TYPE_0X80:
+ asm volatile ("outb %al, $0x80");
+ break;
+ case CONFIG_IO_DELAY_TYPE_0XED:
+ asm volatile ("outb %al, $0xed");
+ break;
+ case CONFIG_IO_DELAY_TYPE_UDELAY:
+ /*
+ * 2 usecs is an upper-bound for the outb delay but
+ * note that udelay doesn't have the bus-level
+ * side-effects that outb does, nor does udelay() have
+ * precise timings during very early bootup (the delays
+ * are shorter until calibrated):
+ */
+ udelay(2);
+ case CONFIG_IO_DELAY_TYPE_NONE:
+ break;
+ }
}
EXPORT_SYMBOL(native_io_delay);
-#ifndef CONFIG_UDELAY_IO_DELAY
-static int __init dmi_alternate_io_delay_port(const struct dmi_system_id *id)
+static int __init dmi_io_delay_0xed_port(const struct dmi_system_id *id)
{
- printk(KERN_NOTICE "%s: using alternate I/O delay port\n", id->ident);
- io_delay = alternate_io_delay;
+ if (io_delay_type == CONFIG_IO_DELAY_TYPE_0X80) {
+ printk(KERN_NOTICE "%s: using 0xed I/O delay port\n",
+ id->ident);
+ io_delay_type = CONFIG_IO_DELAY_TYPE_0XED;
+ }
+
return 0;
}
-static struct dmi_system_id __initdata alternate_io_delay_port_dmi_table[] = {
+/*
+ * Quirk table for systems that misbehave (lock up, etc.) if port
+ * 0x80 is used:
+ */
+static struct dmi_system_id __initdata io_delay_0xed_port_dmi_table[] = {
{
- .callback = dmi_alternate_io_delay_port,
+ .callback = dmi_io_delay_0xed_port,
.ident = "HP Pavilion dv9000z",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
DMI_MATCH(DMI_BOARD_NAME, "30B9")
}
},
- {
- }
+ { }
};
-static int __initdata io_delay_override;
-
void __init io_delay_init(void)
{
if (!io_delay_override)
- dmi_check_system(alternate_io_delay_port_dmi_table);
+ dmi_check_system(io_delay_0xed_port_dmi_table);
}
-#endif
static int __init io_delay_param(char *s)
{
- if (!s)
- return -EINVAL;
-
- if (!strcmp(s, "standard"))
- io_delay = standard_io_delay;
- else if (!strcmp(s, "alternate"))
- io_delay = alternate_io_delay;
+ if (!strcmp(s, "0x80"))
+ io_delay_type = CONFIG_IO_DELAY_TYPE_0X80;
+ else if (!strcmp(s, "0xed"))
+ io_delay_type = CONFIG_IO_DELAY_TYPE_0XED;
else if (!strcmp(s, "udelay"))
- io_delay = udelay_io_delay;
+ io_delay_type = CONFIG_IO_DELAY_TYPE_UDELAY;
+ else if (!strcmp(s, "none"))
+ io_delay_type = CONFIG_IO_DELAY_TYPE_NONE;
else
return -EINVAL;
-#ifndef CONFIG_UDELAY_IO_DELAY
io_delay_override = 1;
-#endif
return 0;
}
diff --git a/include/asm-x86/io_32.h b/include/asm-x86/io_32.h
index a8d25c38b91c..2a04bd17eac5 100644
--- a/include/asm-x86/io_32.h
+++ b/include/asm-x86/io_32.h
@@ -250,15 +250,11 @@ static inline void flush_write_buffers(void)
#endif /* __KERNEL__ */
-#ifndef CONFIG_UDELAY_IO_DELAY
-extern void io_delay_init(void);
-#else
-static inline void io_delay_init(void)
-{
-}
-#endif
extern void native_io_delay(void);
+extern int io_delay_type;
+extern void io_delay_init(void);
+
#if defined(CONFIG_PARAVIRT)
#include <asm/paravirt.h>
#else
diff --git a/include/asm-x86/io_64.h b/include/asm-x86/io_64.h
index 5bebaf961692..dbcc03aa1c6a 100644
--- a/include/asm-x86/io_64.h
+++ b/include/asm-x86/io_64.h
@@ -35,15 +35,11 @@
* - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*/
-#ifndef CONFIG_UDELAY_IO_DELAY
-extern void io_delay_init(void);
-#else
-static inline void io_delay_init(void)
-{
-}
-#endif
extern void native_io_delay(void);
+extern int io_delay_type;
+extern void io_delay_init(void);
+
static inline void slow_down_io(void)
{
native_io_delay();
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 4bc8e48434a7..357b68ba23ec 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -53,6 +53,7 @@
#ifdef CONFIG_X86
#include <asm/nmi.h>
#include <asm/stacktrace.h>
+#include <asm/io.h>
#endif
static int deprecated_sysctl_warning(struct __sysctl_args *args);
@@ -727,6 +728,14 @@ static struct ctl_table kern_table[] = {
.mode = 0644,
.proc_handler = &proc_dointvec,
},
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "io_delay_type",
+ .data = &io_delay_type,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
#endif
#if defined(CONFIG_MMU)
{
commit 45fe4fe19120a22f7339f5bb110447170c25fca9
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Jan 30 13:30:03 2008 +0100
x86: make clockevents more robust
detect zero event-device multiplicators - they then cause
division-by-zero crashes if a clockevent has been initialized
incorrectly.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 5fb139fef9fa..3e59fce6dd43 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -41,6 +41,11 @@ unsigned long clockevent_delta2ns(unsigned long latch,
{
u64 clc = ((u64) latch << evt->shift);
+ if (unlikely(!evt->mult)) {
+ evt->mult = 1;
+ WARN_ON(1);
+ }
+
do_div(clc, evt->mult);
if (clc < 1000)
clc = 1000;
@@ -151,6 +156,14 @@ static void clockevents_notify_released(void)
void clockevents_register_device(struct clock_event_device *dev)
{
BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED);
+ /*
+ * A nsec2cyc multiplicator of 0 is invalid and we'd crash
+ * on it, so fix it up and emit a warning:
+ */
+ if (unlikely(!dev->mult)) {
+ dev->mult = 1;
+ WARN_ON(1);
+ }
spin_lock(&clockevents_lock);
commit df619e6bafeb8e129aba3173d384544d7fa6e3c2
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Jan 30 13:30:02 2008 +0100
x86: offer is_hpet_enabled() on !CONFIG_HPET_TIMER too
offer is_hpet_enabled() on !CONFIG_HPET_TIMER too.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/include/asm-x86/hpet.h b/include/asm-x86/hpet.h
index ad8d6e758785..624f600f7161 100644
--- a/include/asm-x86/hpet.h
+++ b/include/asm-x86/hpet.h
@@ -80,10 +80,11 @@ extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id);
#endif /* CONFIG_HPET_EMULATE_RTC */
-#else
+#else /* CONFIG_HPET_TIMER */
static inline int hpet_enable(void) { return 0; }
static inline unsigned long hpet_readl(unsigned long a) { return 0; }
+static inline int is_hpet_enabled(void) { return 0; }
-#endif /* CONFIG_HPET_TIMER */
+#endif
#endif /* ASM_X86_HPET_H */