--- gcc/config/i386/i386.md 2018/04/24 18:23:23 1.1.1.3 +++ gcc/config/i386/i386.md 2018/04/24 18:31:06 1.1.1.4 @@ -1,5 +1,5 @@ ;; GCC machine description for Intel X86. -;; Copyright (C) 1988, 1994 Free Software Foundation, Inc. +;; Copyright (C) 1988, 1994, 1995 Free Software Foundation, Inc. ;; Mostly by William Schelter. ;; This file is part of GNU CC. @@ -16,7 +16,8 @@ ;; You should have received a copy of the GNU General Public License ;; along with GNU CC; see the file COPYING. If not, write to -;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;; the Free Software Foundation, 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. ;; The original PO technology requires these to be ordered by speed, @@ -38,6 +39,8 @@ ;; 'B' Print the opcode suffix for an 8-bit integer opcode. ;; 'S' Print the opcode suffix for a 32-bit float opcode. ;; 'Q' Print the opcode suffix for a 64-bit float opcode. +;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode. +;; 'J' Print the appropriate jump operand. ;; 'b' Print the QImode name of the register for the indicated operand. ;; %b0 would print %al if operands[0] is reg 0. @@ -45,7 +48,6 @@ ;; 'k' Likewise, print the SImode name of the register. ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh. ;; 'y' Print "st(0)" instead of "st" as a register. -;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode. ;; UNSPEC usage: ;; 0 This is a `scas' operation. The mode of the UNSPEC is always SImode. @@ -2382,7 +2384,7 @@ [(set (match_operand:DI 0 "general_operand" "=&r,ro,o,&r,ro,o,&r,o,o,o") (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,o,riF,o,or,riF,riF,o") (match_operand:DI 2 "general_operand" "o,riF,o,0,0,0,oriF,riF,o,o"))) - (clobber (match_scratch:SI 3 "=X,X,&r,X,X,&r,X,X,&r,&r"))] + (clobber (match_scratch:SI 3 "=X,X,&r,X,&r,&r,X,&r,&r,&r"))] "" "* { @@ -2405,7 +2407,7 @@ xops[2] = high[1]; xops[3] = low[1]; - if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) + if (GET_CODE (operands[0]) != MEM) { output_asm_insn (AS2 (mov%L1,%3,%1), xops); output_asm_insn (AS2 (mov%L0,%2,%0), xops); @@ -2633,7 +2635,7 @@ [(set (match_operand:DI 0 "general_operand" "=&r,ro,&r,o,o") (minus:DI (match_operand:DI 1 "general_operand" "0,0,roiF,riF,o") (match_operand:DI 2 "general_operand" "o,riF,roiF,riF,o"))) - (clobber (match_scratch:SI 3 "=X,X,X,X,&r"))] + (clobber (match_scratch:SI 3 "=X,X,X,&r,&r"))] "" "* { @@ -2650,7 +2652,7 @@ xops[2] = high[1]; xops[3] = low[1]; - if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) + if (GET_CODE (operands[0]) != MEM) { output_asm_insn (AS2 (mov%L1,%3,%1), xops); output_asm_insn (AS2 (mov%L0,%2,%0), xops); @@ -3489,6 +3491,13 @@ && (TARGET_IEEE_FP || flag_fast_math) " "fsin") +(define_insn "sinxf2" + [(set (match_operand:XF 0 "register_operand" "=f") + (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))] + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 + && (TARGET_IEEE_FP || flag_fast_math) " + "fsin") + (define_insn "cosdf2" [(set (match_operand:DF 0 "register_operand" "=f") (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))] @@ -3510,6 +3519,13 @@ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math) " "fcos") + +(define_insn "cosxf2" + [(set (match_operand:XF 0 "register_operand" "=f") + (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))] + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 + && (TARGET_IEEE_FP || flag_fast_math) " + "fcos") ;;- one complement instructions @@ -4894,6 +4910,76 @@ return AS1 (jmp,%*%0); }") +;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i); +;; if S does not change i + +(define_expand "decrement_and_branch_until_zero" + [(parallel [(set (pc) + (if_then_else (ge (plus:SI (match_operand:SI 0 "general_operand" "") + (const_int -1)) + (const_int 0)) + (label_ref (match_operand 1 "" "")) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int -1)))])] + "" + "") + +(define_insn "" + [(set (pc) + (if_then_else (match_operator 0 "arithmetic_comparison_operator" + [(plus:SI (match_operand:SI 1 "general_operand" "+r,m") + (match_operand:SI 2 "general_operand" "rmi,ri")) + (const_int 0)]) + (label_ref (match_operand 3 "" "")) + (pc))) + (set (match_dup 1) + (plus:SI (match_dup 1) + (match_dup 2)))] + "" + "* +{ + CC_STATUS_INIT; + if (operands[2] == constm1_rtx) + output_asm_insn (AS1 (dec%L1,%1), operands); + + else if (operands[1] == const1_rtx) + output_asm_insn (AS1 (inc%L1,%1), operands); + + else + output_asm_insn (AS2 (add%L1,%2,%1), operands); + + return AS1 (%J0,%l3); +}") + +(define_insn "" + [(set (pc) + (if_then_else (match_operator 0 "arithmetic_comparison_operator" + [(minus:SI (match_operand:SI 1 "general_operand" "+r,m") + (match_operand:SI 2 "general_operand" "rmi,ri")) + (const_int 0)]) + (label_ref (match_operand 3 "" "")) + (pc))) + (set (match_dup 1) + (minus:SI (match_dup 1) + (match_dup 2)))] + "" + "* +{ + CC_STATUS_INIT; + if (operands[2] == const1_rtx) + output_asm_insn (AS1 (dec%L1,%1), operands); + + else if (operands[1] == constm1_rtx) + output_asm_insn (AS1 (inc%L1,%1), operands); + + else + output_asm_insn (AS2 (sub%L1,%2,%1), operands); + + return AS1 (%J0,%l3); +}") + ;; Implement switch statements when generating PIC code. Switches are ;; implemented by `tablejump' when not using -fpic. @@ -5222,7 +5308,14 @@ { int i; - emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); + /* In order to give reg-stack an easier job in validating two + coprocessor registers as containing a possible return value, + simply pretend the untyped call returns a complex long double + value. */ + emit_call_insn (TARGET_80387 + ? gen_call_value (gen_rtx (REG, XCmode, FIRST_FLOAT_REG), + operands[0], const0_rtx) + : gen_call (operands[0], const0_rtx)); for (i = 0; i < XVECLEN (operands[2], 0); i++) { @@ -5439,6 +5532,10 @@ "" "operands[2] = gen_reg_rtx (SImode);") +;; Note, you cannot optimize away the branch following the bsfl by assuming +;; that the destination is not modified if the input is 0, since not all +;; x86 implementations do this. + (define_insn "" [(set (match_operand:SI 0 "general_operand" "=&r") (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" "rm")) @@ -5453,7 +5550,6 @@ xops[0] = operands[0]; xops[1] = operands[1]; xops[2] = constm1_rtx; - /* Can there be a way to avoid the jump here? */ output_asm_insn (AS2 (bsf%L0,%1,%0), xops); #ifdef LOCAL_LABEL_PREFIX sprintf (buffer, \"jnz %sLFFSSI%d\",