]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/x86/math-emu/reg_compare.c
Merge remote-tracking branch 'qcom/qcom/for-next'
[karo-tx-linux.git] / arch / x86 / math-emu / reg_compare.c
index f37c5b5a35ad54301c36a5dd21f1fe1c394a7cf2..b77360fdbf4a8cc8aa191147208d6acb50609d78 100644 (file)
 #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_i_st_st(int nr)
+{
+       int f, c;
+       FPU_REG *st_ptr;
+
+       if (!NOT_EMPTY(0) || !NOT_EMPTY(nr)) {
+               FPU_EFLAGS |= (X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF);
+               /* Stack fault */
+               EXCEPTION(EX_StackUnder);
+               return !(control_word & CW_Invalid);
+       }
+
+       partial_status &= ~SW_C0;
+       st_ptr = &st(nr);
+       c = compare(st_ptr, FPU_gettagi(nr));
+       if (c & COMP_NaN) {
+               FPU_EFLAGS |= (X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF);
+               EXCEPTION(EX_Invalid);
+               return !(control_word & CW_Invalid);
+       }
+
+       switch (c & 7) {
+       case COMP_A_lt_B:
+               f = X86_EFLAGS_CF;
+               break;
+       case COMP_A_eq_B:
+               f = X86_EFLAGS_ZF;
+               break;
+       case COMP_A_gt_B:
+               f = 0;
+               break;
+       case COMP_No_Comp:
+               f = X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF;
+               break;
+#ifdef PARANOID
+       default:
+               EXCEPTION(EX_INTERNAL | 0x122);
+               f = 0;
+               break;
+#endif /* PARANOID */
+       }
+       FPU_EFLAGS = (FPU_EFLAGS & ~(X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF)) | 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);
+       }
+
+       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;
+}
+
+static int compare_ui_st_st(int nr)
+{
+       int f = 0, c;
+       FPU_REG *st_ptr;
+
+       if (!NOT_EMPTY(0) || !NOT_EMPTY(nr)) {
+               FPU_EFLAGS |= (X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF);
+               /* 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;
+
+       partial_status &= ~SW_C0;
+       st_ptr = &st(nr);
+       c = compare(st_ptr, FPU_gettagi(nr));
+       if (c & COMP_NaN) {
+               FPU_EFLAGS |= (X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF);
+               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;
+       }
+
+       switch (c & 7) {
+       case COMP_A_lt_B:
+               f = X86_EFLAGS_CF;
+               break;
+       case COMP_A_eq_B:
+               f = X86_EFLAGS_ZF;
+               break;
+       case COMP_A_gt_B:
+               f = 0;
+               break;
+       case COMP_No_Comp:
+               f = X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF;
+               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 = 0;
+               break;
+#endif /* PARANOID */
+       }
+       FPU_EFLAGS = (FPU_EFLAGS & ~(X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF)) | 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();
+}
+
+/* P6+ compare-to-EFLAGS ops */
+
+void fcomi_(void)
+{
+       /* fcomi st(i) */
+       compare_i_st_st(FPU_rm);
+}
+
+void fcomip(void)
+{
+       /* fcomip st(i) */
+       if (!compare_i_st_st(FPU_rm))
+               FPU_pop();
+}
+
+void fucomi_(void)
+{
+       /* fucomi st(i) */
+       compare_ui_st_st(FPU_rm);
+}
+
+void fucomip(void)
+{
+       /* fucomip st(i) */
+       if (!compare_ui_st_st(FPU_rm))
+               FPU_pop();
 }