]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/x86/math-emu/fpu_aux.c
Merge remote-tracking branch 'input-current/for-linus'
[karo-tx-linux.git] / arch / x86 / math-emu / fpu_aux.c
index dd76a05729b0106c95ae2bd925ca21a647214fd6..024f6e971174e88df9d96ffb66641f7835b8729d 100644 (file)
@@ -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) */