From 5dbc6990b16a969e470392abe48e8ff9552780b3 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 29 Nov 2020 16:10:36 +0100 Subject: x86: Factorize fpu save/restore * i386/i386/fpu.h (fpu_save, fpu_rstor): New macros. (fpu_save_context): Use fpu_save macro. * i386/i386/fpu.c (fp_save): Use fpu_save macro. (fp_load): Use fpu_rstor macro. --- i386/i386/fpu.c | 42 +++--------------------------------- i386/i386/fpu.h | 67 +++++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 49 insertions(+), 60 deletions(-) diff --git a/i386/i386/fpu.c b/i386/i386/fpu.c index b177dad2..03f43f9d 100644 --- a/i386/i386/fpu.c +++ b/i386/i386/fpu.c @@ -825,30 +825,9 @@ fp_save(thread_t thread) pcb_t pcb = thread->pcb; struct i386_fpsave_state *ifps = pcb->ims.ifps; - if (ifps != 0 && !ifps->fp_valid) { + if (ifps != 0 && !ifps->fp_valid) /* registers are in FPU */ - ifps->fp_valid = TRUE; - switch (fp_save_kind) { - case FP_XSAVE: - xsave(&ifps->xfp_save_state); - break; - case FP_XSAVEOPT: - xsaveopt(&ifps->xfp_save_state); - break; - case FP_XSAVEC: - xsavec(&ifps->xfp_save_state); - break; - case FP_XSAVES: - xsaves(&ifps->xfp_save_state); - break; - case FP_FXSAVE: - fxsave(&ifps->xfp_save_state); - break; - case FP_FNSAVE: - fnsave(&ifps->fp_save_state); - break; - } - } + fpu_save(ifps); } /* @@ -896,22 +875,7 @@ ASSERT_IPL(SPL0); printf("fp_load: invalid FPU state!\n"); fninit (); } else { - switch (fp_save_kind) { - case FP_XSAVE: - case FP_XSAVEOPT: - case FP_XSAVEC: - xrstor(ifps->xfp_save_state); - break; - case FP_XSAVES: - xrstors(ifps->xfp_save_state); - break; - case FP_FXSAVE: - fxrstor(ifps->xfp_save_state); - break; - case FP_FNSAVE: - frstor(ifps->fp_save_state); - break; - } + fpu_rstor(ifps); } ifps->fp_valid = FALSE; /* in FPU */ } diff --git a/i386/i386/fpu.h b/i386/i386/fpu.h index c77cc96d..33838cc0 100644 --- a/i386/i386/fpu.h +++ b/i386/i386/fpu.h @@ -142,6 +142,51 @@ static inline void set_xcr0(uint64_t value) { #define fpu_load_context(pcb) +#define fpu_save(ifps) \ + do { \ + switch (fp_save_kind) { \ + case FP_XSAVE: \ + xsave(&(ifps)->xfp_save_state); \ + break; \ + case FP_XSAVEOPT: \ + xsaveopt(&(ifps)->xfp_save_state); \ + break; \ + case FP_XSAVEC: \ + xsavec(&(ifps)->xfp_save_state); \ + break; \ + case FP_XSAVES: \ + xsaves(&(ifps)->xfp_save_state); \ + break; \ + case FP_FXSAVE: \ + fxsave(&(ifps)->xfp_save_state); \ + break; \ + case FP_FNSAVE: \ + fnsave(&(ifps)->fp_save_state); \ + break; \ + } \ + (ifps)->fp_valid = TRUE; \ + } while (0) + +#define fpu_rstor(ifps) \ + do { \ + switch (fp_save_kind) { \ + case FP_XSAVE: \ + case FP_XSAVEOPT: \ + case FP_XSAVEC: \ + xrstor((ifps)->xfp_save_state); \ + break; \ + case FP_XSAVES: \ + xrstors((ifps)->xfp_save_state); \ + break; \ + case FP_FXSAVE: \ + fxrstor((ifps)->xfp_save_state); \ + break; \ + case FP_FNSAVE: \ + frstor((ifps)->fp_save_state); \ + break; \ + } \ + } while (0) + /* * Save thread`s FPU context. * If only one CPU, we just set the task-switched bit, @@ -155,27 +200,7 @@ static inline void set_xcr0(uint64_t value) { ifps = (thread)->pcb->ims.ifps; \ if (ifps != 0 && !ifps->fp_valid) { \ /* registers are in FPU - save to memory */ \ - ifps->fp_valid = TRUE; \ - switch (fp_save_kind) { \ - case FP_XSAVE: \ - xsave(&ifps->xfp_save_state); \ - break; \ - case FP_XSAVEOPT: \ - xsaveopt(&ifps->xfp_save_state); \ - break; \ - case FP_XSAVEC: \ - xsavec(&ifps->xfp_save_state); \ - break; \ - case FP_XSAVES: \ - xsaves(&ifps->xfp_save_state); \ - break; \ - case FP_FXSAVE: \ - fxsave(&ifps->xfp_save_state); \ - break; \ - case FP_FNSAVE: \ - fnsave(&ifps->fp_save_state); \ - break; \ - } \ + fpu_save(ifps); \ set_ts(); \ } \ } -- cgit v1.2.3