Hello! FPSR_REG was introduced to implement reduction loop of fmod and remainder x87 sequences. There is no point to declare it as a generic CCmode register and also no point to mark it as clobbered in every asm insn.
2018-09-28 Uros Bizjak <ubiz...@gmail.com> * config/i386/i386.h (CC_REGNO): Remove FPSR_REG. * config/i386/i386.c (ix86_fixed_condition_code_regs): Use INVALID_REGNUM instead of FPSR_REG. (ix86_md_asm_adjust): Do not clobber FPSR_REG. * config/i386/i386.md: Update comment of FP compares. (fldenv): Do not clobber FPSR_REG. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Committed to mainline SVN. Uros.
Index: i386.c =================================================================== --- i386.c (revision 264693) +++ i386.c (working copy) @@ -21969,7 +21969,7 @@ static bool ix86_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2) { *p1 = FLAGS_REG; - *p2 = FPSR_REG; + *p2 = INVALID_REGNUM; return true; } @@ -43656,9 +43656,6 @@ ix86_md_asm_adjust (vec<rtx> &outputs, vec<rtx> &/ vec<const char *> &constraints, vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs) { - clobbers.safe_push (gen_rtx_REG (CCFPmode, FPSR_REG)); - SET_HARD_REG_BIT (clobbered_regs, FPSR_REG); - bool saw_asm_flag = false; start_sequence (); Index: i386.h =================================================================== --- i386.h (revision 264693) +++ i386.h (working copy) @@ -1501,7 +1501,7 @@ enum reg_class #define MMX_REGNO_P(N) IN_RANGE ((N), FIRST_MMX_REG, LAST_MMX_REG) #define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X))) -#define CC_REGNO_P(X) ((X) == FLAGS_REG || (X) == FPSR_REG) +#define CC_REGNO_P(X) ((X) == FLAGS_REG) #define MOD4_SSE_REG_P(X) (REG_P (X) && MOD4_SSE_REGNO_P (REGNO (X))) #define MOD4_SSE_REGNO_P(N) ((N) == XMM0_REG \ Index: i386.md =================================================================== --- i386.md (revision 264693) +++ i386.md (working copy) @@ -1463,10 +1463,10 @@ ;; FP compares, step 1: -;; Set the FP condition codes. +;; Set the FP condition codes and move fpsr to ax. -;; We may not use "#" to split and emit these, since the REG_DEAD notes -;; used to manage the reg stack popping would not be preserved. +;; We may not use "#" to split and emit these +;; due to reg-stack pops killing fpsr. (define_insn "*cmp<mode>_0_i387" [(set (match_operand:HI 0 "register_operand" "=a") @@ -1649,19 +1649,7 @@ (set_attr "fp_int_src" "true") (set_attr "mode" "<SWI24:MODE>")]) -;; FP compares, step 2 -;; Move the fpsw to ax. - -(define_insn "x86_fnstsw_1" - [(set (match_operand:HI 0 "register_operand" "=a") - (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))] - "TARGET_80387" - "fnstsw\t%0" - [(set_attr "length" "2") - (set_attr "mode" "SI") - (set_attr "unit" "i387")]) - -;; FP compares, step 3 +;; FP compares, step 2: ;; Get ax into flags, general case. (define_insn "x86_sahf_1" @@ -1683,7 +1671,7 @@ (set_attr "bdver1_decode" "direct") (set_attr "mode" "SI")]) -;; Pentium Pro can do steps 1 through 3 in one go. +;; Pentium Pro can do both steps in one go. ;; (these instructions set flags directly) (define_subst_attr "unord" "unord_subst" "" "u") @@ -15158,6 +15146,15 @@ } }) +(define_insn "x86_fnstsw_1" + [(set (match_operand:HI 0 "register_operand" "=a") + (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))] + "TARGET_80387" + "fnstsw\t%0" + [(set_attr "length" "2") + (set_attr "mode" "SI") + (set_attr "unit" "i387")]) + (define_insn "fpremxf4_i387" [(set (match_operand:XF 0 "register_operand" "=f") (unspec:XF [(match_operand:XF 2 "register_operand" "0") @@ -19606,7 +19603,6 @@ (define_insn "fldenv" [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")] UNSPECV_FLDENV) - (clobber (reg:CCFP FPSR_REG)) (clobber (reg:XF ST0_REG)) (clobber (reg:XF ST1_REG)) (clobber (reg:XF ST2_REG))