These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / arch / x86 / math-emu / fpu_aux.c
index dc8adad..024f6e9 100644 (file)
@@ -30,7 +30,7 @@ static void fclex(void)
 }
 
 /* Needs to be externally visible */
-void finit_soft_fpu(struct i387_soft_struct *soft)
+void fpstate_init_soft(struct swregs_state *soft)
 {
        struct address *oaddr, *iaddr;
        memset(soft, 0, sizeof(*soft));
@@ -52,7 +52,7 @@ void finit_soft_fpu(struct i387_soft_struct *soft)
 
 void finit(void)
 {
-       finit_soft_fpu(&current->thread.fpu.state->soft);
+       fpstate_init_soft(&current->thread.fpu.state.soft);
 }
 
 /*
@@ -169,6 +169,76 @@ void fxch_i(void)
        fpu_tag_word = tag_word;
 }
 
+static void fcmovCC(void)
+{
+       /* fcmovCC st(i) */
+       int i = FPU_rm;
+       FPU_REG *st0_ptr = &st(0);
+       FPU_REG *sti_ptr = &st(i);
+       long tag_word = fpu_tag_word;
+       int regnr = top & 7;
+       int regnri = (top + i) & 7;
+       u_char sti_tag = (tag_word >> (regnri * 2)) & 3;
+
+       if (sti_tag == TAG_Empty) {
+               FPU_stack_underflow();
+               clear_C1();
+               return;
+       }
+       reg_copy(sti_ptr, st0_ptr);
+       tag_word &= ~(3 << (regnr * 2));
+       tag_word |= (sti_tag << (regnr * 2));
+       fpu_tag_word = tag_word;
+}
+
+void fcmovb(void)
+{
+       if (FPU_EFLAGS & X86_EFLAGS_CF)
+               fcmovCC();
+}
+
+void fcmove(void)
+{
+       if (FPU_EFLAGS & X86_EFLAGS_ZF)
+               fcmovCC();
+}
+
+void fcmovbe(void)
+{
+       if (FPU_EFLAGS & (X86_EFLAGS_CF|X86_EFLAGS_ZF))
+               fcmovCC();
+}
+
+void fcmovu(void)
+{
+       if (FPU_EFLAGS & X86_EFLAGS_PF)
+               fcmovCC();
+}
+
+void fcmovnb(void)
+{
+       if (!(FPU_EFLAGS & X86_EFLAGS_CF))
+               fcmovCC();
+}
+
+void fcmovne(void)
+{
+       if (!(FPU_EFLAGS & X86_EFLAGS_ZF))
+               fcmovCC();
+}
+
+void fcmovnbe(void)
+{
+       if (!(FPU_EFLAGS & (X86_EFLAGS_CF|X86_EFLAGS_ZF)))
+               fcmovCC();
+}
+
+void fcmovnu(void)
+{
+       if (!(FPU_EFLAGS & X86_EFLAGS_PF))
+               fcmovCC();
+}
+
 void ffree_(void)
 {
        /* ffree st(i) */