--- gcc/config/i386.md 2018/04/24 18:00:07 1.1.1.3 +++ gcc/config/i386.md 2018/04/24 18:06:05 1.1.1.4 @@ -52,7 +52,10 @@ ;; operand 1 is a register containing the value to scan for. The mode ;; of the scas opcode will be the same as the mode of this operand. ;; operand 2 is the known alignment of operand 0. - +;; 1 This is a `sin' operation. The mode of the UNSPEC is MODE_FLOAT. +;; operand 0 is the argument for `sin'. +;; 2 This is a `cos' operation. The mode of the UNSPEC is MODE_FLOAT. +;; operand 0 is the argument for `cos'. ;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM". ;; But restricting MEM here would mean that gcc could not remove a redundant @@ -427,7 +430,7 @@ /* For small integers, we may actually use testb. */ if (GET_CODE (operands[1]) == CONST_INT && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) - && ! NON_QI_REG_P (operands[0])) + && (! REG_P (operands[0]) || QI_REG_P (operands[0]))) { /* We may set the sign bit spuriously. */ @@ -440,8 +443,7 @@ if ((INTVAL (operands[1]) & ~0xff00) == 0) { cc_status.flags |= CC_NOT_NEGATIVE; - operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]) >> 8); + operands[1] = GEN_INT (INTVAL (operands[1]) >> 8); if (QI_REG_P (operands[0])) return AS2 (test%B0,%1,%h0); @@ -456,9 +458,7 @@ && (INTVAL (operands[1]) & ~0xff0000) == 0) { cc_status.flags |= CC_NOT_NEGATIVE; - operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]) >> 16); - + operands[1] = GEN_INT (INTVAL (operands[1]) >> 16); operands[0] = adj_offsettable_operand (operands[0], 2); return AS2 (test%B0,%1,%b0); } @@ -466,9 +466,7 @@ if (GET_CODE (operands[0]) == MEM && (INTVAL (operands[1]) & ~0xff000000) == 0) { - operands[1] = gen_rtx (CONST_INT, VOIDmode, - (INTVAL (operands[1]) >> 24) & 0xff); - + operands[1] = GEN_INT ((INTVAL (operands[1]) >> 24) & 0xff); operands[0] = adj_offsettable_operand (operands[0], 3); return AS2 (test%B0,%1,%b0); } @@ -489,14 +487,13 @@ { if (GET_CODE (operands[1]) == CONST_INT && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) - && ! NON_QI_REG_P (operands[0])) + && (! REG_P (operands[0]) || QI_REG_P (operands[0]))) { if ((INTVAL (operands[1]) & 0xff00) == 0) { /* ??? This might not be necessary. */ if (INTVAL (operands[1]) & 0xffff0000) - operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1]) & 0xff); + operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); /* We may set the sign bit spuriously. */ cc_status.flags |= CC_NOT_NEGATIVE; @@ -505,8 +502,7 @@ if ((INTVAL (operands[1]) & 0xff) == 0) { - operands[1] = gen_rtx (CONST_INT, VOIDmode, - (INTVAL (operands[1]) >> 8) & 0xff); + operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff); if (QI_REG_P (operands[0])) return AS2 (test%B0,%1,%h0); @@ -760,7 +756,7 @@ abort (); xops[0] = AT_SP (SFmode); - xops[1] = gen_rtx (CONST_INT, VOIDmode, 4); + xops[1] = GEN_INT (4); xops[2] = stack_pointer_rtx; output_asm_insn (AS2 (sub%L2,%1,%2), xops); @@ -841,7 +837,7 @@ rtx xops[3]; xops[0] = AT_SP (SFmode); - xops[1] = gen_rtx (CONST_INT, VOIDmode, 8); + xops[1] = GEN_INT (8); xops[2] = stack_pointer_rtx; output_asm_insn (AS2 (sub%L2,%1,%2), xops); @@ -936,7 +932,7 @@ }") (define_insn "movdi" - [(set (match_operand:DI 0 "general_operand" "=&r,rm") + [(set (match_operand:DI 0 "general_operand" "=r,rm") (match_operand:DI 1 "general_operand" "m,riF"))] "" "* @@ -962,7 +958,7 @@ { rtx xops[2]; xops[0] = operands[0]; - xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xffff); + xops[1] = GEN_INT (0xffff); output_asm_insn (AS2 (and%L0,%1,%k0), xops); RET; } @@ -986,7 +982,7 @@ { rtx xops[2]; xops[0] = operands[0]; - xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xff); + xops[1] = GEN_INT (0xff); output_asm_insn (AS2 (and%L0,%1,%k0), xops); RET; } @@ -1010,7 +1006,7 @@ { rtx xops[2]; xops[0] = operands[0]; - xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xff); + xops[1] = GEN_INT (0xff); output_asm_insn (AS2 (and%L0,%1,%k0), xops); RET; } @@ -1309,11 +1305,26 @@ ;; This will convert from SImode or DImode to MODE_FLOAT. (define_insn "" - [(set (match_operand 0 "register_operand" "=f,f") - (match_operator 2 "float_op" - [(match_operand:DI 1 "general_operand" "m,!*r")]))] - "TARGET_80387 && GET_MODE (operands[0]) == GET_MODE (operands[2]) - && GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT" + [(set (match_operand:DF 0 "register_operand" "=f,f") + (float:DF (match_operand:DI 1 "general_operand" "m,!*r")))] + "TARGET_80387" + "* +{ + if (NON_STACK_REG_P (operands[1])) + { + output_op_from_reg (operands[1], AS1 (fild%z0,%1)); + RET; + } + else if (GET_CODE (operands[1]) == MEM) + return AS1 (fild%z1,%1); + else + abort (); +}") + +(define_insn "" + [(set (match_operand:SF 0 "register_operand" "=f,f") + (float:SF (match_operand:DI 1 "general_operand" "m,!*r")))] + "TARGET_80387" "* { if (NON_STACK_REG_P (operands[1])) @@ -1328,11 +1339,26 @@ }") (define_insn "" - [(set (match_operand 0 "register_operand" "=f,f") - (match_operator 2 "float_op" - [(match_operand:SI 1 "general_operand" "m,!*r")]))] - "TARGET_80387 && GET_MODE (operands[0]) == GET_MODE (operands[2]) - && GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT" + [(set (match_operand:DF 0 "register_operand" "=f,f") + (float:DF (match_operand:SI 1 "general_operand" "m,!*r")))] + "TARGET_80387" + "* +{ + if (NON_STACK_REG_P (operands[1])) + { + output_op_from_reg (operands[1], AS1 (fild%z0,%1)); + RET; + } + else if (GET_CODE (operands[1]) == MEM) + return AS1 (fild%z1,%1); + else + abort (); +}") + +(define_insn "" + [(set (match_operand:SF 0 "register_operand" "=f,f") + (float:SF (match_operand:SI 1 "general_operand" "m,!*r")))] + "TARGET_80387" "* { if (NON_STACK_REG_P (operands[1])) @@ -1384,8 +1410,20 @@ if (! TARGET_486 || ! REG_P (operands[2])) { CC_STATUS_INIT; - operands[1] = SET_SRC (PATTERN (insn)); - return AS2 (lea%L0,%a1,%0); + + if (operands[2] == stack_pointer_rtx) + { + rtx temp; + + temp = operands[1]; + operands[1] = operands[2]; + operands[2] = temp; + } + if (operands[2] != stack_pointer_rtx) + { + operands[1] = SET_SRC (PATTERN (insn)); + return AS2 (lea%L0,%a1,%0); + } } output_asm_insn (AS2 (mov%L0,%1,%0), operands); @@ -1810,8 +1848,7 @@ return AS2 (mov%B0,%2,%b0); } - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) & 0xff); + operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); return AS2 (and%B0,%2,%b0); } @@ -1825,8 +1862,7 @@ return AS2 (mov%B0,%2,%h0); } - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) >> 8); + operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff); return AS2 (and%B0,%2,%h0); } @@ -1851,7 +1887,7 @@ && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) { /* Can we ignore the upper byte? */ - if (! NON_QI_REG_P (operands[0]) + if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) && (INTVAL (operands[2]) & 0xff00) == 0xff00) { CC_STATUS_INIT; @@ -1862,8 +1898,7 @@ return AS2 (mov%B0,%2,%b0); } - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) & 0xff); + operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); return AS2 (and%B0,%2,%b0); } @@ -1879,8 +1914,7 @@ return AS2 (mov%B0,%2,%h0); } - operands[2] = gen_rtx (CONST_INT, VOIDmode, - (INTVAL (operands[2]) >> 8) & 0xff); + operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff); return AS2 (and%B0,%2,%h0); } } @@ -1932,7 +1966,8 @@ if (GET_CODE (operands[2]) == CONST_INT && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) { - if (! NON_QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff) == 0) + if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) + && (INTVAL (operands[2]) & ~0xff) == 0) { CC_STATUS_INIT; @@ -1945,8 +1980,7 @@ if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff00) == 0) { CC_STATUS_INIT; - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) >> 8); + operands[2] = GEN_INT (INTVAL (operands[2]) >> 8); if (INTVAL (operands[2]) == 0xff) return AS2 (mov%B0,%2,%h0); @@ -1969,13 +2003,12 @@ && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) { /* Can we ignore the upper byte? */ - if (! NON_QI_REG_P (operands[0]) + if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) && (INTVAL (operands[2]) & 0xff00) == 0) { CC_STATUS_INIT; if (INTVAL (operands[2]) & 0xffff0000) - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) & 0xffff); + operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff); if (INTVAL (operands[2]) == 0xff) return AS2 (mov%B0,%2,%b0); @@ -1989,8 +2022,7 @@ && (INTVAL (operands[2]) & 0xff) == 0) { CC_STATUS_INIT; - operands[2] = gen_rtx (CONST_INT, VOIDmode, - (INTVAL (operands[2]) >> 8) & 0xff); + operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff); if (INTVAL (operands[2]) == 0xff) return AS2 (mov%B0,%2,%h0); @@ -2022,7 +2054,8 @@ if (GET_CODE (operands[2]) == CONST_INT && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) { - if (! NON_QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff) == 0) + if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) + && (INTVAL (operands[2]) & ~0xff) == 0) { CC_STATUS_INIT; @@ -2035,8 +2068,7 @@ if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff00) == 0) { CC_STATUS_INIT; - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) >> 8); + operands[2] = GEN_INT (INTVAL (operands[2]) >> 8); if (INTVAL (operands[2]) == 0xff) return AS1 (not%B0,%h0); @@ -2059,13 +2091,12 @@ && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) { /* Can we ignore the upper byte? */ - if (! NON_QI_REG_P (operands[0]) + if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) && (INTVAL (operands[2]) & 0xff00) == 0) { CC_STATUS_INIT; if (INTVAL (operands[2]) & 0xffff0000) - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) & 0xffff); + operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff); if (INTVAL (operands[2]) == 0xff) return AS1 (not%B0,%b0); @@ -2079,8 +2110,7 @@ && (INTVAL (operands[2]) & 0xff) == 0) { CC_STATUS_INIT; - operands[2] = gen_rtx (CONST_INT, VOIDmode, - (INTVAL (operands[2]) >> 8) & 0xff); + operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff); if (INTVAL (operands[2]) == 0xff) return AS1 (not%B0,%h0); @@ -2180,21 +2210,59 @@ (define_insn "sqrtsf2" [(set (match_operand:SF 0 "register_operand" "=f") (sqrt:SF (match_operand:SF 1 "general_operand" "0")))] - "TARGET_80387" + "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)" "fsqrt") (define_insn "sqrtdf2" [(set (match_operand:DF 0 "register_operand" "=f") (sqrt:DF (match_operand:DF 1 "general_operand" "0")))] - "TARGET_80387" + "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)" "fsqrt") (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") (sqrt:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))] - "TARGET_80387" + "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)" "fsqrt") + +(define_insn "sindf2" + [(set (match_operand:DF 0 "register_operand" "=f") + (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))] + "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)" + "fsin") + +(define_insn "sinsf2" + [(set (match_operand:SF 0 "register_operand" "=f") + (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))] + "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)" + "fsin") + +(define_insn "" + [(set (match_operand:DF 0 "register_operand" "=f") + (unspec:DF [(float_extend:DF + (match_operand:SF 1 "register_operand" "0"))] 1))] + "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))] + "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)" + "fcos") + +(define_insn "cossf2" + [(set (match_operand:SF 0 "register_operand" "=f") + (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))] + "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)" + "fcos") + +(define_insn "" + [(set (match_operand:DF 0 "register_operand" "=f") + (unspec:DF [(float_extend:DF + (match_operand:SF 1 "register_operand" "0"))] 2))] + "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)" + "fcos") ;;- one complement instructions @@ -2285,8 +2353,7 @@ if (INTVAL (xops[0]) > 32) { - xops[0] = gen_rtx (CONST_INT, VOIDmode, INTVAL (xops[0]) - 32); - + xops[0] = GEN_INT (INTVAL (xops[0]) - 32); output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */ } } @@ -2323,7 +2390,7 @@ output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops); output_asm_insn (AS2 (sal%L2,%0,%2), xops); - xops[1] = gen_rtx (CONST_INT, VOIDmode, 7); /* shift count & 1 */ + xops[1] = GEN_INT (7); /* shift count & 1 */ output_asm_insn (AS2 (shr%B0,%1,%0), xops); @@ -2354,9 +2421,14 @@ else { CC_STATUS_INIT; + + if (operands[1] == stack_pointer_rtx) + { + output_asm_insn (AS2 (mov%L0,%1,%0), operands); + operands[1] = operands[0]; + } operands[1] = gen_rtx (MULT, SImode, operands[1], - gen_rtx (CONST_INT, VOIDmode, - 1 << INTVAL (operands[2]))); + GEN_INT (1 << INTVAL (operands[2]))); return AS2 (lea%L0,%a1,%0); } } @@ -2443,15 +2515,14 @@ if (INTVAL (xops[0]) > 31) { - xops[1] = gen_rtx (CONST_INT, VOIDmode, 31); + xops[1] = GEN_INT (31); output_asm_insn (AS2 (mov%L2,%3,%2), xops); output_asm_insn (AS2 (sar%L3,%1,%3), xops); /* shift by 32 */ if (INTVAL (xops[0]) > 32) { - xops[0] = gen_rtx (CONST_INT, VOIDmode, INTVAL (xops[0]) - 32); - - output_asm_insn (AS2 (sar%2,%0,%2), xops); /* Remaining shift */ + xops[0] = GEN_INT (INTVAL (xops[0]) - 32); + output_asm_insn (AS2 (sar%L2,%0,%2), xops); /* Remaining shift */ } } else @@ -2488,7 +2559,7 @@ output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops); output_asm_insn (AS2 (sar%L3,%0,%3), xops); - xops[1] = gen_rtx (CONST_INT, VOIDmode, 7); /* shift count & 1 */ + xops[1] = GEN_INT (7); /* shift count & 1 */ output_asm_insn (AS2 (shr%B0,%1,%0), xops); @@ -2585,9 +2656,8 @@ if (INTVAL (xops[0]) > 32) { - xops[0] = gen_rtx (CONST_INT, VOIDmode, INTVAL (xops[0]) - 32); - - output_asm_insn (AS2 (shr%2,%0,%2), xops); /* Remaining shift */ + xops[0] = GEN_INT (INTVAL (xops[0]) - 32); + output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */ } } else @@ -2624,7 +2694,7 @@ output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops); output_asm_insn (AS2 (shr%L3,%0,%3), xops); - xops[1] = gen_rtx (CONST_INT, VOIDmode, 7); /* shift count & 1 */ + xops[1] = GEN_INT (7); /* shift count & 1 */ output_asm_insn (AS2 (shr%B0,%1,%0), xops); @@ -2770,11 +2840,9 @@ if (GET_CODE (operands[3]) == CONST_INT) { unsigned int mask = (1 << INTVAL (operands[1])) - 1; - operands[1] = gen_rtx (CONST_INT, VOIDmode, - ~(mask << INTVAL (operands[2]))); + operands[1] = GEN_INT (~(mask << INTVAL (operands[2]))); output_asm_insn (AS2 (and%L0,%1,%0), operands); - operands[3] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[3]) << INTVAL (operands[2])); + operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2])); output_asm_insn (AS2 (or%L0,%3,%0), operands); } else @@ -2783,8 +2851,7 @@ if (INTVAL (operands[2])) output_asm_insn (AS2 (ror%L0,%2,%0), operands); output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands); - operands[2] = gen_rtx (CONST_INT, VOIDmode, - BITS_PER_WORD + operands[2] = GEN_INT (BITS_PER_WORD - INTVAL (operands[1]) - INTVAL (operands[2])); if (INTVAL (operands[2])) output_asm_insn (AS2 (ror%L0,%2,%0), operands); @@ -2900,6 +2967,68 @@ ;; don't allow a MEM in the operand predicate without allowing it in the ;; constraint. +;; ??? All bets are off if operand 0 is a volatile MEM reference. + +/* +(define_insn "" + [(set (cc0) (zero_extract (match_operand 0 "general_operand" "rm") + (match_operand:SI 1 "const_int_operand" "n") + (match_operand:SI 2 "const_int_operand" "n")))] + "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT + && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4 + && (GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0]))" + "* +{ + unsigned int mask; + + mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]); + operands[1] = GEN_INT (mask); + + if (! REG_P (operands[0]) || QI_REG_P (operands[0])) + { + if ((mask & ~0xff) == 0) + { + cc_status.flags |= CC_NOT_NEGATIVE; + return AS2 (test%B0,%1,%b0); + } + + if ((mask & ~0xff00) == 0) + { + cc_status.flags |= CC_NOT_NEGATIVE; + operands[1] = GEN_INT (mask >> 8); + + if (QI_REG_P (operands[0])) + return AS2 (test%B0,%1,%h0); + else + { + operands[0] = adj_offsettable_operand (operands[0], 1); + return AS2 (test%B0,%1,%b0); + } + } + + if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0) + { + cc_status.flags |= CC_NOT_NEGATIVE; + operands[1] = GEN_INT (mask >> 16); + operands[0] = adj_offsettable_operand (operands[0], 2); + return AS2 (test%B0,%1,%b0); + } + + if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0) + { + cc_status.flags |= CC_NOT_NEGATIVE; + operands[1] = GEN_INT (mask >> 24); + operands[0] = adj_offsettable_operand (operands[0], 3); + return AS2 (test%B0,%1,%b0); + } + } + + if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM) + return AS2 (test%L0,%1,%0); + + return AS2 (test%L1,%0,%1); +}") +*/ (define_insn "" [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r") (const_int 1) @@ -2916,9 +3045,13 @@ ;; For all sCOND expanders, also expand the compare or test insn that ;; generates cc0. Generate an equality comparison if `seq' or `sne'. +;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may +;; not have any input reloads. A MEM write might need an input reload +;; for the address of the MEM. So don't allow MEM as the SET_DEST. + (define_expand "seq" [(match_dup 1) - (set (match_operand:QI 0 "general_operand" "") + (set (match_operand:QI 0 "register_operand" "") (eq:QI (cc0) (const_int 0)))] "" " @@ -2931,7 +3064,7 @@ }") (define_insn "" - [(set (match_operand:QI 0 "general_operand" "=qm") + [(set (match_operand:QI 0 "register_operand" "=q") (eq:QI (cc0) (const_int 0)))] "" "* @@ -2944,7 +3077,7 @@ (define_expand "sne" [(match_dup 1) - (set (match_operand:QI 0 "general_operand" "") + (set (match_operand:QI 0 "register_operand" "") (ne:QI (cc0) (const_int 0)))] "" " @@ -2957,7 +3090,7 @@ }") (define_insn "" - [(set (match_operand:QI 0 "general_operand" "=qm") + [(set (match_operand:QI 0 "register_operand" "=q") (ne:QI (cc0) (const_int 0)))] "" "* @@ -2971,13 +3104,13 @@ (define_expand "sgt" [(match_dup 1) - (set (match_operand:QI 0 "general_operand" "") + (set (match_operand:QI 0 "register_operand" "") (gt:QI (cc0) (const_int 0)))] "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") (define_insn "" - [(set (match_operand:QI 0 "general_operand" "=qm") + [(set (match_operand:QI 0 "register_operand" "=q") (gt:QI (cc0) (const_int 0)))] "" "* @@ -2985,31 +3118,31 @@ if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) return AS1 (sete,%0); - OUTPUT_JUMP (\"setg %0\", \"seta %0\", 0); + OUTPUT_JUMP (\"setg %0\", \"seta %0\", NULL_PTR); }") (define_expand "sgtu" [(match_dup 1) - (set (match_operand:QI 0 "general_operand" "") + (set (match_operand:QI 0 "register_operand" "") (gtu:QI (cc0) (const_int 0)))] "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") (define_insn "" - [(set (match_operand:QI 0 "general_operand" "=qm") + [(set (match_operand:QI 0 "register_operand" "=q") (gtu:QI (cc0) (const_int 0)))] "" "* return \"seta %0\"; ") (define_expand "slt" [(match_dup 1) - (set (match_operand:QI 0 "general_operand" "") + (set (match_operand:QI 0 "register_operand" "") (lt:QI (cc0) (const_int 0)))] "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") (define_insn "" - [(set (match_operand:QI 0 "general_operand" "=qm") + [(set (match_operand:QI 0 "register_operand" "=q") (lt:QI (cc0) (const_int 0)))] "" "* @@ -3022,26 +3155,26 @@ (define_expand "sltu" [(match_dup 1) - (set (match_operand:QI 0 "general_operand" "") + (set (match_operand:QI 0 "register_operand" "") (ltu:QI (cc0) (const_int 0)))] "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") (define_insn "" - [(set (match_operand:QI 0 "general_operand" "=qm") + [(set (match_operand:QI 0 "register_operand" "=q") (ltu:QI (cc0) (const_int 0)))] "" "* return \"setb %0\"; ") (define_expand "sge" [(match_dup 1) - (set (match_operand:QI 0 "general_operand" "") + (set (match_operand:QI 0 "register_operand" "") (ge:QI (cc0) (const_int 0)))] "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") (define_insn "" - [(set (match_operand:QI 0 "general_operand" "=qm") + [(set (match_operand:QI 0 "register_operand" "=q") (ge:QI (cc0) (const_int 0)))] "" "* @@ -3054,26 +3187,26 @@ (define_expand "sgeu" [(match_dup 1) - (set (match_operand:QI 0 "general_operand" "") + (set (match_operand:QI 0 "register_operand" "") (geu:QI (cc0) (const_int 0)))] "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") (define_insn "" - [(set (match_operand:QI 0 "general_operand" "=qm") + [(set (match_operand:QI 0 "register_operand" "=q") (geu:QI (cc0) (const_int 0)))] "" "* return \"setae %0\"; ") (define_expand "sle" [(match_dup 1) - (set (match_operand:QI 0 "general_operand" "") + (set (match_operand:QI 0 "register_operand" "") (le:QI (cc0) (const_int 0)))] "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") (define_insn "" - [(set (match_operand:QI 0 "general_operand" "=qm") + [(set (match_operand:QI 0 "register_operand" "=q") (le:QI (cc0) (const_int 0)))] "" "* @@ -3081,18 +3214,18 @@ if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) return AS1 (setb,%0); - OUTPUT_JUMP (\"setle %0\", \"setbe %0\", 0); + OUTPUT_JUMP (\"setle %0\", \"setbe %0\", NULL_PTR); }") (define_expand "sleu" [(match_dup 1) - (set (match_operand:QI 0 "general_operand" "") + (set (match_operand:QI 0 "register_operand" "") (leu:QI (cc0) (const_int 0)))] "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") (define_insn "" - [(set (match_operand:QI 0 "general_operand" "=qm") + [(set (match_operand:QI 0 "register_operand" "=q") (leu:QI (cc0) (const_int 0)))] "" "* return \"setbe %0\"; ") @@ -3189,7 +3322,7 @@ if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) return AS1 (je,%l0); - OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", 0); + OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR); }") (define_expand "bgtu" @@ -3321,7 +3454,7 @@ if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) return AS1 (jb,%l0); - OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", 0); + OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR); }") (define_expand "bleu" @@ -3387,7 +3520,7 @@ if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) return AS1 (jne,%l0); - OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", 0); + OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR); }") (define_insn "" @@ -3459,7 +3592,7 @@ if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) return AS1 (jae,%l0); - OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", 0); + OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR); }") (define_insn "" @@ -3605,8 +3738,15 @@ "" " { + rtx addr; + if (flag_pic) current_function_uses_pic_offset_table = 1; + + /* With half-pic, force the address into a register. */ + addr = XEXP (operands[0], 0); + if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr)) + XEXP (operands[0], 0) = force_reg (Pmode, addr); }") (define_insn "" @@ -3632,7 +3772,7 @@ (match_operand:SI 1 "general_operand" "g")) (set (reg:SI 7) (plus:SI (reg:SI 7) (match_operand:SI 3 "immediate_operand" "i")))] - "" + "!HALF_PIC_P ()" "call %P0") (define_expand "call" @@ -3642,8 +3782,15 @@ "" " { + rtx addr; + if (flag_pic) current_function_uses_pic_offset_table = 1; + + /* With half-pic, force the address into a register. */ + addr = XEXP (operands[0], 0); + if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr)) + XEXP (operands[0], 0) = force_reg (Pmode, addr); }") (define_insn "" @@ -3667,7 +3814,7 @@ [(call (mem:QI (match_operand:SI 0 "symbolic_operand" "")) (match_operand:SI 1 "general_operand" "g"))] ;; Operand 1 not used on the i386. - "" + "!HALF_PIC_P ()" "call %P0") ;; Call subroutine, returning value in operand 0 @@ -3683,8 +3830,15 @@ "" " { + rtx addr; + if (flag_pic) current_function_uses_pic_offset_table = 1; + + /* With half-pic, force the address into a register. */ + addr = XEXP (operands[1], 0); + if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr)) + XEXP (operands[1], 0) = force_reg (Pmode, addr); }") (define_insn "" @@ -3714,7 +3868,7 @@ (match_operand:SI 2 "general_operand" "g"))) (set (reg:SI 7) (plus:SI (reg:SI 7) (match_operand:SI 4 "immediate_operand" "i")))] - "" + "!HALF_PIC_P ()" "call %P1") (define_expand "call_value" @@ -3725,8 +3879,15 @@ "" " { + rtx addr; + if (flag_pic) current_function_uses_pic_offset_table = 1; + + /* With half-pic, force the address into a register. */ + addr = XEXP (operands[1], 0); + if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr)) + XEXP (operands[1], 0) = force_reg (Pmode, addr); }") (define_insn "" @@ -3754,7 +3915,7 @@ (call (mem:QI (match_operand:SI 1 "symbolic_operand" "")) (match_operand:SI 2 "general_operand" "g")))] ;; Operand 2 not used on the i386. - "" + "!HALF_PIC_P ()" "call %P1") ;; Insn emitted into the body of a function to return from a function. @@ -3776,20 +3937,29 @@ "nop") (define_expand "movstrsi" - [(parallel [(set (mem:BLK (match_operand:BLK 0 "address_operand" "")) - (mem:BLK (match_operand:BLK 1 "address_operand" ""))) + [(parallel [(set (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" "")) (use (match_operand:SI 2 "const_int_operand" "")) (use (match_operand:SI 3 "const_int_operand" "")) (clobber (match_scratch:SI 4 "")) - (clobber (match_dup 0)) - (clobber (match_dup 1))])] + (clobber (match_dup 5)) + (clobber (match_dup 6))])] "" " { + rtx addr0, addr1; + if (GET_CODE (operands[2]) != CONST_INT) FAIL; - operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0)); - operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); + + addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); + addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); + + operands[5] = addr0; + operands[6] = addr1; + + operands[0] = gen_rtx (MEM, BLKmode, addr0); + operands[1] = gen_rtx (MEM, BLKmode, addr1); }") ;; It might seem that operands 0 & 1 could use predicate register_operand. @@ -3809,11 +3979,12 @@ { rtx xops[2]; + output_asm_insn (\"cld\", operands); if (GET_CODE (operands[2]) == CONST_INT) { if (INTVAL (operands[2]) & ~0x03) { - xops[0] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) >> 2); + xops[0] = GEN_INT ((INTVAL (operands[2]) >> 2) & 0x3fffffff); xops[1] = operands[4]; output_asm_insn (AS2 (mov%L1,%0,%1), xops); @@ -3834,21 +4005,29 @@ }") (define_expand "cmpstrsi" - [(parallel [(set (match_operand:QI 0 "general_operand" "") - (compare:CC - (mem:BLK (match_operand:BLK 1 "address_operand" "")) - (mem:BLK (match_operand:BLK 2 "address_operand" "")))) + [(parallel [(set (match_operand:SI 0 "general_operand" "") + (compare:CC (match_operand:BLK 1 "general_operand" "") + (match_operand:BLK 2 "general_operand" ""))) (use (match_operand:SI 3 "general_operand" "")) (use (match_operand:SI 4 "immediate_operand" "")) - (clobber (match_dup 1)) - (clobber (match_dup 2)) + (clobber (match_dup 5)) + (clobber (match_dup 6)) (clobber (match_dup 3))])] "" " { - operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); - operands[2] = copy_to_mode_reg (SImode, XEXP (operands[2], 0)); + rtx addr1, addr2; + + addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); + addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0)); operands[3] = copy_to_mode_reg (SImode, operands[3]); + + operands[5] = addr1; + operands[6] = addr2; + + operands[1] = gen_rtx (MEM, BLKmode, addr1); + operands[2] = gen_rtx (MEM, BLKmode, addr2); + }") ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is @@ -3863,7 +4042,7 @@ ;; code to handle zero-length compares. (define_insn "" - [(set (match_operand:QI 0 "general_operand" "=&q") + [(set (match_operand:SI 0 "general_operand" "=&r") (compare:CC (mem:BLK (match_operand:SI 1 "address_operand" "S")) (mem:BLK (match_operand:SI 2 "address_operand" "D")))) (use (match_operand:SI 3 "register_operand" "c")) @@ -3874,11 +4053,12 @@ "" "* { - rtx xops[3], label; + rtx xops[4], label; label = gen_label_rtx (); - output_asm_insn (AS2 (xor%B0,%0,%0), operands); + output_asm_insn (\"cld\", operands); + output_asm_insn (AS2 (xor%L0,%0,%0), operands); output_asm_insn (\"repz\;cmps%B2\", operands); output_asm_insn (\"je %l0\", &label); @@ -3887,9 +4067,12 @@ gen_rtx (PLUS, SImode, operands[1], constm1_rtx)); xops[2] = gen_rtx (MEM, QImode, gen_rtx (PLUS, SImode, operands[2], constm1_rtx)); + xops[3] = operands[3]; - output_asm_insn (AS2 (mov%B0,%1,%b0), xops); - output_asm_insn (AS2 (sub%B0,%2,%b0), xops); + output_asm_insn (AS2 (movz%B1%L0,%1,%0), xops); + output_asm_insn (AS2 (movz%B2%L3,%2,%3), xops); + + output_asm_insn (AS2 (sub%L0,%3,%0), xops); ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label)); RET; }") @@ -3908,9 +4091,12 @@ { rtx xops[2]; + cc_status.flags |= CC_NOT_SIGNED; + xops[0] = gen_rtx (REG, QImode, 0); xops[1] = CONST0_RTX (QImode); + output_asm_insn (\"cld\", operands); output_asm_insn (AS2 (test%B0,%1,%0), xops); return \"repz\;cmps%B2\"; }") @@ -4072,6 +4258,7 @@ xops[0] = operands[0]; xops[1] = constm1_rtx; + output_asm_insn (\"cld\", operands); output_asm_insn (AS2 (mov%L0,%1,%0), xops); return \"repnz\;scas%B2\"; }")