i386.md revision 53176
150650Sobrien; GCC machine description for Intel X86. 250650Sobrien;; Copyright (C) 1988, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. 318334Speter;; Mostly by William Schelter. 418334Speter 518334Speter;; This file is part of GNU CC. 618334Speter 718334Speter;; GNU CC is free software; you can redistribute it and/or modify 818334Speter;; it under the terms of the GNU General Public License as published by 918334Speter;; the Free Software Foundation; either version 2, or (at your option) 1018334Speter;; any later version. 1118334Speter 1218334Speter;; GNU CC is distributed in the hope that it will be useful, 1318334Speter;; but WITHOUT ANY WARRANTY; without even the implied warranty of 1418334Speter;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1518334Speter;; GNU General Public License for more details. 1618334Speter 1718334Speter;; You should have received a copy of the GNU General Public License 1818334Speter;; along with GNU CC; see the file COPYING. If not, write to 1918334Speter;; the Free Software Foundation, 59 Temple Place - Suite 330, 2050650Sobrien;; Boston, MA 02111-1307, USA. */ 2118334Speter 2218334Speter;; The original PO technology requires these to be ordered by speed, 2318334Speter;; so that assigner will pick the fastest. 2418334Speter 2518334Speter;; See file "rtl.def" for documentation on define_insn, match_*, et. al. 2618334Speter 2718334Speter;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code 2818334Speter;; updates for most instructions. 2918334Speter 3018334Speter;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register 3118334Speter;; constraint letters. 3218334Speter 3318334Speter;; the special asm out single letter directives following a '%' are: 3418334Speter;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of 3518334Speter;; operands[1]. 3618334Speter;; 'L' Print the opcode suffix for a 32-bit integer opcode. 3718334Speter;; 'W' Print the opcode suffix for a 16-bit integer opcode. 3818334Speter;; 'B' Print the opcode suffix for an 8-bit integer opcode. 3950650Sobrien;; 'Q' Print the opcode suffix for a 64-bit float opcode. 4018334Speter;; 'S' Print the opcode suffix for a 32-bit float opcode. 4118334Speter;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode. 4218334Speter;; 'J' Print the appropriate jump operand. 4318334Speter 4418334Speter;; 'b' Print the QImode name of the register for the indicated operand. 4518334Speter;; %b0 would print %al if operands[0] is reg 0. 4618334Speter;; 'w' Likewise, print the HImode name of the register. 4718334Speter;; 'k' Likewise, print the SImode name of the register. 4818334Speter;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh. 4918334Speter;; 'y' Print "st(0)" instead of "st" as a register. 5018334Speter 5118334Speter;; UNSPEC usage: 5218334Speter;; 0 This is a `scas' operation. The mode of the UNSPEC is always SImode. 5318334Speter;; operand 0 is the memory address to scan. 5418334Speter;; operand 1 is a register containing the value to scan for. The mode 5518334Speter;; of the scas opcode will be the same as the mode of this operand. 5618334Speter;; operand 2 is the known alignment of operand 0. 5718334Speter;; 1 This is a `sin' operation. The mode of the UNSPEC is MODE_FLOAT. 5818334Speter;; operand 0 is the argument for `sin'. 5918334Speter;; 2 This is a `cos' operation. The mode of the UNSPEC is MODE_FLOAT. 6018334Speter;; operand 0 is the argument for `cos'. 6150650Sobrien;; 3 This is part of a `stack probe' operation. The mode of the UNSPEC is 6250650Sobrien;; always SImode. operand 0 is the size of the stack allocation. 6350650Sobrien;; 4 This is the source of a fake SET of the frame pointer which is used to 6450650Sobrien;; prevent insns referencing it being scheduled across the initial 6550650Sobrien;; decrement of the stack pointer. 6650650Sobrien;; 5 This is a `bsf' operation. 6752296Sobrien;; 6 This is the @GOT offset of a PIC address. 6852296Sobrien;; 7 This is the @GOTOFF offset of a PIC address. 6952296Sobrien;; 8 This is a reference to a symbol's @PLT address. 7018334Speter 7150650Sobrien;; This shadows the processor_type enumeration, so changes must be made 7250650Sobrien;; to i386.h at the same time. 7350650Sobrien 7452296Sobrien;; $FreeBSD: head/contrib/gcc/config/i386/i386.md 53176 1999-11-15 04:28:55Z obrien $ 7552296Sobrien 7652296Sobrien(define_attr "type" 7752296Sobrien "integer,binary,memory,test,compare,fcompare,idiv,imul,lea,fld,fpop,fpdiv,fpmul" 7850650Sobrien (const_string "integer")) 7950650Sobrien 8052296Sobrien(define_attr "memory" "none,load,store" 8152296Sobrien (cond [(eq_attr "type" "idiv,lea") 8252296Sobrien (const_string "none") 8352296Sobrien 8452296Sobrien (eq_attr "type" "fld") 8552296Sobrien (const_string "load") 8652296Sobrien 8752296Sobrien (eq_attr "type" "test") 8852296Sobrien (if_then_else (match_operand 0 "memory_operand" "") 8952296Sobrien (const_string "load") 9052296Sobrien (const_string "none")) 9152296Sobrien 9252296Sobrien (eq_attr "type" "compare,fcompare") 9352296Sobrien (if_then_else (ior (match_operand 0 "memory_operand" "") 9452296Sobrien (match_operand 1 "memory_operand" "")) 9552296Sobrien (const_string "load") 9652296Sobrien (const_string "none")) 9752296Sobrien 9852296Sobrien (and (eq_attr "type" "integer,memory,fpop") 9952296Sobrien (match_operand 0 "memory_operand" "")) 10052296Sobrien (const_string "store") 10152296Sobrien 10252296Sobrien (and (eq_attr "type" "integer,memory,fpop") 10352296Sobrien (match_operand 1 "memory_operand" "")) 10452296Sobrien (const_string "load") 10552296Sobrien 10652296Sobrien (and (eq_attr "type" "binary,imul,fpmul,fpdiv") 10752296Sobrien (ior (match_operand 1 "memory_operand" "") 10852296Sobrien (match_operand 2 "memory_operand" ""))) 10952296Sobrien (const_string "load")] 11052296Sobrien 11152296Sobrien (const_string "none"))) 11252296Sobrien 11350650Sobrien;; Functional units 11450650Sobrien 11550650Sobrien; (define_function_unit NAME MULTIPLICITY SIMULTANEITY 11650650Sobrien; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST]) 11750650Sobrien 11850650Sobrien; pentiumpro has a reservation station with 5 ports 11950650Sobrien; port 0 has integer, float add, integer divide, float divide, float 12050650Sobrien; multiply, and shifter units. 12150650Sobrien; port 1 has integer, and jump units. 12250650Sobrien; port 2 has the load address generation unit 12350650Sobrien; ports 3 and 4 have the store address generation units 12450650Sobrien 12550650Sobrien; pentium has two integer pipelines, the main u pipe and the secondary v pipe. 12650650Sobrien; and a float pipeline 12750650Sobrien 12850650Sobrien;; Floating point 12950650Sobrien 13050650Sobrien(define_function_unit "fp" 1 0 13152296Sobrien (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "i386,i486")) 13250650Sobrien 5 5) 13350650Sobrien 13450650Sobrien(define_function_unit "fp" 1 0 13552296Sobrien (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "pentium,pentiumpro")) 13650650Sobrien 3 0) 13750650Sobrien 13850650Sobrien(define_function_unit "fp" 1 0 13950650Sobrien (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentium")) 14050650Sobrien 7 0) 14150650Sobrien 14250650Sobrien(define_function_unit "fp" 1 0 14350650Sobrien (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentiumpro")) 14450650Sobrien 5 0) 14550650Sobrien 14650650Sobrien(define_function_unit "fp" 1 0 14750650Sobrien (and (eq_attr "type" "idiv") (eq_attr "cpu" "pentiumpro")) 14850650Sobrien 10 10) 14950650Sobrien 15050650Sobrien(define_function_unit "fp" 1 0 15150650Sobrien (and (eq_attr "type" "imul") (eq_attr "cpu" "pentiumpro")) 15250650Sobrien 6 0) 15350650Sobrien 15450650Sobrien(define_function_unit "fp" 1 0 15550650Sobrien (eq_attr "type" "fpdiv") 15650650Sobrien 10 10) 15750650Sobrien 15850650Sobrien(define_function_unit "fp" 1 0 15952296Sobrien (and (eq_attr "type" "fld") (eq_attr "cpu" "!pentiumpro,k6")) 16050650Sobrien 1 0) 16150650Sobrien 16252296Sobrien;; K6 FPU is not pipelined. 16352296Sobrien(define_function_unit "fp" 1 0 16452296Sobrien (and (eq_attr "type" "fpop,fpmul,fcompare") (eq_attr "cpu" "k6")) 16552296Sobrien 2 2) 16650650Sobrien 16752296Sobrien;; i386 and i486 have one integer unit, which need not be modeled 16852296Sobrien 16952296Sobrien(define_function_unit "integer" 2 0 17052296Sobrien (and (eq_attr "type" "integer,binary,test,compare,lea") (eq_attr "cpu" "pentium,pentiumpro")) 17152296Sobrien 1 0) 17252296Sobrien 17352296Sobrien(define_function_unit "integer" 2 0 17452296Sobrien (and (eq_attr "cpu" "k6") 17552296Sobrien (and (eq_attr "type" "integer,binary,test,compare") 17652296Sobrien (eq_attr "memory" "!load"))) 17752296Sobrien 1 0) 17852296Sobrien 17952296Sobrien;; Internally, K6 converts REG OP MEM instructions into a load (2 cycles) 18052296Sobrien;; and a register operation (1 cycle). 18152296Sobrien(define_function_unit "integer" 2 0 18252296Sobrien (and (eq_attr "cpu" "k6") 18352296Sobrien (and (eq_attr "type" "integer,binary,test,compare") 18452296Sobrien (eq_attr "memory" "load"))) 18552296Sobrien 3 0) 18652296Sobrien 18752296Sobrien;; Multiplies use one of the integer units 18852296Sobrien(define_function_unit "integer" 2 0 18952296Sobrien (and (eq_attr "cpu" "pentium") (eq_attr "type" "imul")) 19052296Sobrien 11 11) 19152296Sobrien 19252296Sobrien(define_function_unit "integer" 2 0 19352296Sobrien (and (eq_attr "cpu" "k6") (eq_attr "type" "imul")) 19452296Sobrien 2 2) 19552296Sobrien 19652296Sobrien(define_function_unit "integer" 2 0 19752296Sobrien (and (eq_attr "cpu" "pentium") (eq_attr "type" "idiv")) 19852296Sobrien 25 25) 19952296Sobrien 20052296Sobrien(define_function_unit "integer" 2 0 20152296Sobrien (and (eq_attr "cpu" "k6") (eq_attr "type" "idiv")) 20252296Sobrien 17 17) 20352296Sobrien 20452296Sobrien;; Pentium Pro and K6 have a separate load unit. 20552296Sobrien(define_function_unit "load" 1 0 20652296Sobrien (and (eq_attr "cpu" "pentiumpro") (eq_attr "memory" "load")) 20752296Sobrien 3 0) 20852296Sobrien 20952296Sobrien(define_function_unit "load" 1 0 21052296Sobrien (and (eq_attr "cpu" "k6") (eq_attr "memory" "load")) 21152296Sobrien 2 0) 21252296Sobrien 21352296Sobrien;; Pentium Pro and K6 have a separate store unit. 21452296Sobrien(define_function_unit "store" 1 0 21552296Sobrien (and (eq_attr "cpu" "pentiumpro,k6") (eq_attr "memory" "store")) 21652296Sobrien 1 0) 21752296Sobrien 21852296Sobrien;; lea executes in the K6 store unit with 1 cycle latency 21952296Sobrien(define_function_unit "store" 1 0 22052296Sobrien (and (eq_attr "cpu" "k6") (eq_attr "type" "lea")) 22152296Sobrien 1 0) 22252296Sobrien 22350650Sobrien 22418334Speter;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM". 22518334Speter;; But restricting MEM here would mean that gcc could not remove a redundant 22618334Speter;; test in cases like "incl MEM / je TARGET". 22718334Speter;; 22818334Speter;; We don't want to allow a constant operand for test insns because 22918334Speter;; (set (cc0) (const_int foo)) has no mode information. Such insns will 23018334Speter;; be folded while optimizing anyway. 23118334Speter 23218334Speter;; All test insns have expanders that save the operands away without 23318334Speter;; actually generating RTL. The bCOND or sCOND (emitted immediately 23418334Speter;; after the tstM or cmp) will actually emit the tstM or cmpM. 23518334Speter 23650650Sobrien;; Processor type -- this attribute must exactly match the processor_type 23750650Sobrien;; enumeration in i386.h. 23850650Sobrien 23952296Sobrien(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6" 24050650Sobrien (const (symbol_ref "ix86_cpu"))) 24150650Sobrien 24218334Speter(define_insn "tstsi_1" 24318334Speter [(set (cc0) 24418334Speter (match_operand:SI 0 "nonimmediate_operand" "rm"))] 24518334Speter "" 24618334Speter "* 24718334Speter{ 24818334Speter if (REG_P (operands[0])) 24918334Speter return AS2 (test%L0,%0,%0); 25018334Speter 25118334Speter operands[1] = const0_rtx; 25218334Speter return AS2 (cmp%L0,%1,%0); 25352296Sobrien}" 25452296Sobrien [(set_attr "type" "test")]) 25518334Speter 25618334Speter(define_expand "tstsi" 25718334Speter [(set (cc0) 25818334Speter (match_operand:SI 0 "nonimmediate_operand" ""))] 25918334Speter "" 26018334Speter " 26118334Speter{ 26218334Speter i386_compare_gen = gen_tstsi_1; 26318334Speter i386_compare_op0 = operands[0]; 26450650Sobrien i386_compare_op1 = const0_rtx; 26518334Speter DONE; 26618334Speter}") 26718334Speter 26818334Speter(define_insn "tsthi_1" 26918334Speter [(set (cc0) 27018334Speter (match_operand:HI 0 "nonimmediate_operand" "rm"))] 27118334Speter "" 27218334Speter "* 27318334Speter{ 27418334Speter if (REG_P (operands[0])) 27518334Speter return AS2 (test%W0,%0,%0); 27618334Speter 27718334Speter operands[1] = const0_rtx; 27818334Speter return AS2 (cmp%W0,%1,%0); 27952296Sobrien}" 28052296Sobrien [(set_attr "type" "test")]) 28118334Speter 28218334Speter(define_expand "tsthi" 28318334Speter [(set (cc0) 28418334Speter (match_operand:HI 0 "nonimmediate_operand" ""))] 28518334Speter "" 28618334Speter " 28718334Speter{ 28818334Speter i386_compare_gen = gen_tsthi_1; 28918334Speter i386_compare_op0 = operands[0]; 29050650Sobrien i386_compare_op1 = const0_rtx; 29118334Speter DONE; 29218334Speter}") 29318334Speter 29418334Speter(define_insn "tstqi_1" 29518334Speter [(set (cc0) 29618334Speter (match_operand:QI 0 "nonimmediate_operand" "qm"))] 29718334Speter "" 29818334Speter "* 29918334Speter{ 30018334Speter if (REG_P (operands[0])) 30118334Speter return AS2 (test%B0,%0,%0); 30218334Speter 30318334Speter operands[1] = const0_rtx; 30418334Speter return AS2 (cmp%B0,%1,%0); 30552296Sobrien}" 30652296Sobrien [(set_attr "type" "test")]) 30718334Speter 30818334Speter(define_expand "tstqi" 30918334Speter [(set (cc0) 31018334Speter (match_operand:QI 0 "nonimmediate_operand" ""))] 31118334Speter "" 31218334Speter " 31318334Speter{ 31418334Speter i386_compare_gen = gen_tstqi_1; 31518334Speter i386_compare_op0 = operands[0]; 31650650Sobrien i386_compare_op1 = const0_rtx; 31718334Speter DONE; 31818334Speter}") 31918334Speter 32018334Speter(define_insn "tstsf_cc" 32118334Speter [(set (cc0) 32218334Speter (match_operand:SF 0 "register_operand" "f")) 32318334Speter (clobber (match_scratch:HI 1 "=a"))] 32418334Speter "TARGET_80387 && ! TARGET_IEEE_FP" 32518334Speter "* 32618334Speter{ 32718334Speter if (! STACK_TOP_P (operands[0])) 32818334Speter abort (); 32918334Speter 33018334Speter output_asm_insn (\"ftst\", operands); 33118334Speter 33218334Speter if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) 33318334Speter output_asm_insn (AS1 (fstp,%y0), operands); 33418334Speter 33518334Speter return output_fp_cc0_set (insn); 33652296Sobrien}" 33752296Sobrien [(set_attr "type" "test")]) 33818334Speter 33918334Speter;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode 34018334Speter;; isn't IEEE compliant. 34118334Speter 34218334Speter(define_expand "tstsf" 34318334Speter [(parallel [(set (cc0) 34418334Speter (match_operand:SF 0 "register_operand" "")) 34518334Speter (clobber (match_scratch:HI 1 ""))])] 34618334Speter "TARGET_80387 && ! TARGET_IEEE_FP" 34718334Speter " 34818334Speter{ 34918334Speter i386_compare_gen = gen_tstsf_cc; 35018334Speter i386_compare_op0 = operands[0]; 35150650Sobrien i386_compare_op1 = const0_rtx; 35218334Speter DONE; 35318334Speter}") 35418334Speter 35518334Speter(define_insn "tstdf_cc" 35618334Speter [(set (cc0) 35718334Speter (match_operand:DF 0 "register_operand" "f")) 35818334Speter (clobber (match_scratch:HI 1 "=a"))] 35918334Speter "TARGET_80387 && ! TARGET_IEEE_FP" 36018334Speter "* 36118334Speter{ 36218334Speter if (! STACK_TOP_P (operands[0])) 36318334Speter abort (); 36418334Speter 36518334Speter output_asm_insn (\"ftst\", operands); 36618334Speter 36718334Speter if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) 36818334Speter output_asm_insn (AS1 (fstp,%y0), operands); 36918334Speter 37018334Speter return output_fp_cc0_set (insn); 37152296Sobrien}" 37252296Sobrien [(set_attr "type" "test")]) 37318334Speter 37418334Speter;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode 37518334Speter;; isn't IEEE compliant. 37618334Speter 37718334Speter(define_expand "tstdf" 37818334Speter [(parallel [(set (cc0) 37918334Speter (match_operand:DF 0 "register_operand" "")) 38018334Speter (clobber (match_scratch:HI 1 ""))])] 38118334Speter "TARGET_80387 && ! TARGET_IEEE_FP" 38218334Speter " 38318334Speter{ 38418334Speter i386_compare_gen = gen_tstdf_cc; 38518334Speter i386_compare_op0 = operands[0]; 38650650Sobrien i386_compare_op1 = const0_rtx; 38718334Speter DONE; 38818334Speter}") 38918334Speter 39018334Speter(define_insn "tstxf_cc" 39118334Speter [(set (cc0) 39218334Speter (match_operand:XF 0 "register_operand" "f")) 39318334Speter (clobber (match_scratch:HI 1 "=a"))] 39418334Speter "TARGET_80387 && ! TARGET_IEEE_FP" 39518334Speter "* 39618334Speter{ 39718334Speter if (! STACK_TOP_P (operands[0])) 39818334Speter abort (); 39918334Speter 40018334Speter output_asm_insn (\"ftst\", operands); 40118334Speter 40218334Speter if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) 40318334Speter output_asm_insn (AS1 (fstp,%y0), operands); 40418334Speter 40518334Speter return output_fp_cc0_set (insn); 40652296Sobrien}" 40752296Sobrien [(set_attr "type" "test")]) 40818334Speter 40950650Sobrien;; Don't generate tstxf if generating IEEE code, since the `ftst' opcode 41018334Speter;; isn't IEEE compliant. 41118334Speter 41218334Speter(define_expand "tstxf" 41318334Speter [(parallel [(set (cc0) 41418334Speter (match_operand:XF 0 "register_operand" "")) 41518334Speter (clobber (match_scratch:HI 1 ""))])] 41618334Speter "TARGET_80387 && ! TARGET_IEEE_FP" 41718334Speter " 41818334Speter{ 41918334Speter i386_compare_gen = gen_tstxf_cc; 42018334Speter i386_compare_op0 = operands[0]; 42150650Sobrien i386_compare_op1 = const0_rtx; 42218334Speter DONE; 42318334Speter}") 42418334Speter 42518334Speter;;- compare instructions. See comments above tstM patterns about 42618334Speter;; expansion of these insns. 42718334Speter 42818334Speter(define_insn "cmpsi_1" 42918334Speter [(set (cc0) 43018334Speter (compare (match_operand:SI 0 "nonimmediate_operand" "mr,r") 43118334Speter (match_operand:SI 1 "general_operand" "ri,mr")))] 43218334Speter "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 43352296Sobrien "* return AS2 (cmp%L0,%1,%0);" 43452296Sobrien [(set_attr "type" "compare")]) 43518334Speter 43618334Speter(define_expand "cmpsi" 43718334Speter [(set (cc0) 43818334Speter (compare (match_operand:SI 0 "nonimmediate_operand" "") 43918334Speter (match_operand:SI 1 "general_operand" "")))] 44018334Speter "" 44118334Speter " 44218334Speter{ 44318334Speter if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 44418334Speter operands[0] = force_reg (SImode, operands[0]); 44518334Speter 44618334Speter i386_compare_gen = gen_cmpsi_1; 44718334Speter i386_compare_op0 = operands[0]; 44818334Speter i386_compare_op1 = operands[1]; 44918334Speter DONE; 45018334Speter}") 45118334Speter 45218334Speter(define_insn "cmphi_1" 45318334Speter [(set (cc0) 45418334Speter (compare (match_operand:HI 0 "nonimmediate_operand" "mr,r") 45518334Speter (match_operand:HI 1 "general_operand" "ri,mr")))] 45618334Speter "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 45752296Sobrien "* return AS2 (cmp%W0,%1,%0);" 45852296Sobrien [(set_attr "type" "compare")]) 45918334Speter 46018334Speter(define_expand "cmphi" 46118334Speter [(set (cc0) 46218334Speter (compare (match_operand:HI 0 "nonimmediate_operand" "") 46318334Speter (match_operand:HI 1 "general_operand" "")))] 46418334Speter "" 46518334Speter " 46618334Speter{ 46718334Speter if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 46818334Speter operands[0] = force_reg (HImode, operands[0]); 46918334Speter 47018334Speter i386_compare_gen = gen_cmphi_1; 47118334Speter i386_compare_op0 = operands[0]; 47218334Speter i386_compare_op1 = operands[1]; 47318334Speter DONE; 47418334Speter}") 47518334Speter 47618334Speter(define_insn "cmpqi_1" 47718334Speter [(set (cc0) 47818334Speter (compare (match_operand:QI 0 "nonimmediate_operand" "q,mq") 47918334Speter (match_operand:QI 1 "general_operand" "qm,nq")))] 48018334Speter "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 48152296Sobrien "* return AS2 (cmp%B0,%1,%0);" 48252296Sobrien [(set_attr "type" "compare")]) 48318334Speter 48418334Speter(define_expand "cmpqi" 48518334Speter [(set (cc0) 48618334Speter (compare (match_operand:QI 0 "nonimmediate_operand" "") 48718334Speter (match_operand:QI 1 "general_operand" "")))] 48818334Speter "" 48918334Speter " 49018334Speter{ 49118334Speter if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 49218334Speter operands[0] = force_reg (QImode, operands[0]); 49318334Speter 49418334Speter i386_compare_gen = gen_cmpqi_1; 49518334Speter i386_compare_op0 = operands[0]; 49618334Speter i386_compare_op1 = operands[1]; 49718334Speter DONE; 49818334Speter}") 49918334Speter 50018334Speter;; These implement float point compares. For each of DFmode and 50118334Speter;; SFmode, there is the normal insn, and an insn where the second operand 50218334Speter;; is converted to the desired mode. 50318334Speter 50418334Speter(define_insn "" 50518334Speter [(set (cc0) 50618334Speter (match_operator 2 "VOIDmode_compare_op" 50750650Sobrien [(match_operand:XF 0 "register_operand" "f") 50850650Sobrien (match_operand:XF 1 "register_operand" "f")])) 50918334Speter (clobber (match_scratch:HI 3 "=a"))] 51050650Sobrien "TARGET_80387" 51152296Sobrien "* return output_float_compare (insn, operands);" 51252296Sobrien [(set_attr "type" "fcompare")]) 51318334Speter 51418334Speter(define_insn "" 51518334Speter [(set (cc0) 51618334Speter (match_operator 2 "VOIDmode_compare_op" 51718334Speter [(match_operand:XF 0 "register_operand" "f") 51818334Speter (float_extend:XF 51918334Speter (match_operand:DF 1 "nonimmediate_operand" "fm"))])) 52018334Speter (clobber (match_scratch:HI 3 "=a"))] 52118334Speter "TARGET_80387" 52252296Sobrien "* return output_float_compare (insn, operands);" 52352296Sobrien [(set_attr "type" "fcompare")]) 52418334Speter 52518334Speter(define_insn "" 52618334Speter [(set (cc0) 52718334Speter (match_operator 2 "VOIDmode_compare_op" 52850650Sobrien [(float_extend:XF 52950650Sobrien (match_operand:DF 0 "nonimmediate_operand" "fm")) 53050650Sobrien (match_operand:XF 1 "register_operand" "f")])) 53150650Sobrien (clobber (match_scratch:HI 3 "=a"))] 53250650Sobrien "TARGET_80387" 53352296Sobrien "* return output_float_compare (insn, operands);" 53452296Sobrien [(set_attr "type" "fcompare")]) 53550650Sobrien 53650650Sobrien(define_insn "" 53750650Sobrien [(set (cc0) 53850650Sobrien (match_operator 2 "VOIDmode_compare_op" 53918334Speter [(match_operand:XF 0 "register_operand" "f") 54018334Speter (float_extend:XF 54118334Speter (match_operand:SF 1 "nonimmediate_operand" "fm"))])) 54218334Speter (clobber (match_scratch:HI 3 "=a"))] 54318334Speter "TARGET_80387" 54452296Sobrien "* return output_float_compare (insn, operands);" 54552296Sobrien [(set_attr "type" "fcompare")]) 54618334Speter 54718334Speter(define_insn "" 54818334Speter [(set (cc0) 54950650Sobrien (match_operator 2 "VOIDmode_compare_op" 55050650Sobrien [(float_extend:XF 55150650Sobrien (match_operand:SF 0 "nonimmediate_operand" "fm")) 55250650Sobrien (match_operand:XF 1 "register_operand" "f")])) 55350650Sobrien (clobber (match_scratch:HI 3 "=a"))] 55450650Sobrien "TARGET_80387" 55552296Sobrien "* return output_float_compare (insn, operands);" 55652296Sobrien [(set_attr "type" "fcompare")]) 55750650Sobrien 55850650Sobrien(define_insn "" 55950650Sobrien [(set (cc0) 56018334Speter (compare:CCFPEQ (match_operand:XF 0 "register_operand" "f") 56118334Speter (match_operand:XF 1 "register_operand" "f"))) 56218334Speter (clobber (match_scratch:HI 2 "=a"))] 56318334Speter "TARGET_80387" 56452296Sobrien "* return output_float_compare (insn, operands);" 56552296Sobrien [(set_attr "type" "fcompare")]) 56618334Speter 56718334Speter(define_insn "" 56818334Speter [(set (cc0) 56918334Speter (match_operator 2 "VOIDmode_compare_op" 57018334Speter [(match_operand:DF 0 "nonimmediate_operand" "f,fm") 57118334Speter (match_operand:DF 1 "nonimmediate_operand" "fm,f")])) 57218334Speter (clobber (match_scratch:HI 3 "=a,a"))] 57318334Speter "TARGET_80387 57418334Speter && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 57552296Sobrien "* return output_float_compare (insn, operands);" 57652296Sobrien [(set_attr "type" "fcompare")]) 57718334Speter 57818334Speter(define_insn "" 57918334Speter [(set (cc0) 58018334Speter (match_operator 2 "VOIDmode_compare_op" 58118334Speter [(match_operand:DF 0 "register_operand" "f") 58218334Speter (float_extend:DF 58318334Speter (match_operand:SF 1 "nonimmediate_operand" "fm"))])) 58418334Speter (clobber (match_scratch:HI 3 "=a"))] 58518334Speter "TARGET_80387" 58652296Sobrien "* return output_float_compare (insn, operands);" 58752296Sobrien [(set_attr "type" "fcompare")]) 58818334Speter 58918334Speter(define_insn "" 59018334Speter [(set (cc0) 59118334Speter (match_operator 2 "VOIDmode_compare_op" 59218334Speter [(float_extend:DF 59318334Speter (match_operand:SF 0 "nonimmediate_operand" "fm")) 59418334Speter (match_operand:DF 1 "register_operand" "f")])) 59518334Speter (clobber (match_scratch:HI 3 "=a"))] 59618334Speter "TARGET_80387" 59752296Sobrien "* return output_float_compare (insn, operands);" 59852296Sobrien [(set_attr "type" "fcompare")]) 59918334Speter 60018334Speter(define_insn "" 60118334Speter [(set (cc0) 60250650Sobrien (match_operator 2 "VOIDmode_compare_op" 60350650Sobrien [(float_extend:DF 60450650Sobrien (match_operand:SF 0 "register_operand" "f")) 60550650Sobrien (match_operand:DF 1 "nonimmediate_operand" "fm")])) 60650650Sobrien (clobber (match_scratch:HI 3 "=a"))] 60750650Sobrien "TARGET_80387" 60852296Sobrien "* return output_float_compare (insn, operands);" 60952296Sobrien [(set_attr "type" "fcompare")]) 61050650Sobrien 61150650Sobrien(define_insn "" 61250650Sobrien [(set (cc0) 61318334Speter (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f") 61418334Speter (match_operand:DF 1 "register_operand" "f"))) 61518334Speter (clobber (match_scratch:HI 2 "=a"))] 61618334Speter "TARGET_80387" 61752296Sobrien "* return output_float_compare (insn, operands);" 61852296Sobrien [(set_attr "type" "fcompare")]) 61918334Speter 62018334Speter;; These two insns will never be generated by combine due to the mode of 62118334Speter;; the COMPARE. 62218334Speter;(define_insn "" 62318334Speter; [(set (cc0) 62418334Speter; (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f") 62518334Speter; (float_extend:DF 62618334Speter; (match_operand:SF 1 "register_operand" "f")))) 62718334Speter; (clobber (match_scratch:HI 2 "=a"))] 62818334Speter; "TARGET_80387" 62918334Speter; "* return output_float_compare (insn, operands);") 63018334Speter; 63118334Speter;(define_insn "" 63218334Speter; [(set (cc0) 63318334Speter; (compare:CCFPEQ (float_extend:DF 63418334Speter; (match_operand:SF 0 "register_operand" "f")) 63518334Speter; (match_operand:DF 1 "register_operand" "f"))) 63618334Speter; (clobber (match_scratch:HI 2 "=a"))] 63718334Speter; "TARGET_80387" 63818334Speter; "* return output_float_compare (insn, operands);") 63918334Speter 64052296Sobrien(define_insn "*cmpsf_cc_1" 64118334Speter [(set (cc0) 64218334Speter (match_operator 2 "VOIDmode_compare_op" 64318334Speter [(match_operand:SF 0 "nonimmediate_operand" "f,fm") 64418334Speter (match_operand:SF 1 "nonimmediate_operand" "fm,f")])) 64518334Speter (clobber (match_scratch:HI 3 "=a,a"))] 64618334Speter "TARGET_80387 64718334Speter && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 64852296Sobrien "* return output_float_compare (insn, operands);" 64952296Sobrien [(set_attr "type" "fcompare")]) 65018334Speter 65118334Speter(define_insn "" 65218334Speter [(set (cc0) 65318334Speter (compare:CCFPEQ (match_operand:SF 0 "register_operand" "f") 65418334Speter (match_operand:SF 1 "register_operand" "f"))) 65518334Speter (clobber (match_scratch:HI 2 "=a"))] 65618334Speter "TARGET_80387" 65752296Sobrien "* return output_float_compare (insn, operands);" 65852296Sobrien [(set_attr "type" "fcompare")]) 65918334Speter 66018334Speter(define_expand "cmpxf" 66118334Speter [(set (cc0) 66218334Speter (compare (match_operand:XF 0 "register_operand" "") 66350650Sobrien (match_operand:XF 1 "register_operand" "")))] 66418334Speter "TARGET_80387" 66518334Speter " 66618334Speter{ 66718334Speter i386_compare_gen = gen_cmpxf_cc; 66818334Speter i386_compare_gen_eq = gen_cmpxf_ccfpeq; 66918334Speter i386_compare_op0 = operands[0]; 67018334Speter i386_compare_op1 = operands[1]; 67118334Speter DONE; 67218334Speter}") 67318334Speter 67418334Speter(define_expand "cmpdf" 67518334Speter [(set (cc0) 67618334Speter (compare (match_operand:DF 0 "register_operand" "") 67750650Sobrien (match_operand:DF 1 "general_operand" "")))] 67818334Speter "TARGET_80387" 67918334Speter " 68018334Speter{ 68118334Speter i386_compare_gen = gen_cmpdf_cc; 68218334Speter i386_compare_gen_eq = gen_cmpdf_ccfpeq; 68318334Speter i386_compare_op0 = operands[0]; 68450650Sobrien i386_compare_op1 = (immediate_operand (operands[1], DFmode)) 68550650Sobrien ? copy_to_mode_reg (DFmode, operands[1]) : operands[1]; 68618334Speter DONE; 68718334Speter}") 68818334Speter 68918334Speter(define_expand "cmpsf" 69018334Speter [(set (cc0) 69118334Speter (compare (match_operand:SF 0 "register_operand" "") 69250650Sobrien (match_operand:SF 1 "general_operand" "")))] 69318334Speter "TARGET_80387" 69418334Speter " 69518334Speter{ 69618334Speter i386_compare_gen = gen_cmpsf_cc; 69718334Speter i386_compare_gen_eq = gen_cmpsf_ccfpeq; 69818334Speter i386_compare_op0 = operands[0]; 69950650Sobrien i386_compare_op1 = (immediate_operand (operands[1], SFmode)) 70050650Sobrien ? copy_to_mode_reg (SFmode, operands[1]) : operands[1]; 70118334Speter DONE; 70218334Speter}") 70318334Speter 70418334Speter(define_expand "cmpxf_cc" 70518334Speter [(parallel [(set (cc0) 70618334Speter (compare (match_operand:XF 0 "register_operand" "") 70718334Speter (match_operand:XF 1 "register_operand" ""))) 70818334Speter (clobber (match_scratch:HI 2 ""))])] 70918334Speter "TARGET_80387" 71018334Speter "") 71118334Speter 71218334Speter(define_expand "cmpxf_ccfpeq" 71318334Speter [(parallel [(set (cc0) 71418334Speter (compare:CCFPEQ (match_operand:XF 0 "register_operand" "") 71518334Speter (match_operand:XF 1 "register_operand" ""))) 71618334Speter (clobber (match_scratch:HI 2 ""))])] 71718334Speter "TARGET_80387" 71850650Sobrien "") 71918334Speter 72018334Speter(define_expand "cmpdf_cc" 72118334Speter [(parallel [(set (cc0) 72218334Speter (compare (match_operand:DF 0 "register_operand" "") 72318334Speter (match_operand:DF 1 "register_operand" ""))) 72418334Speter (clobber (match_scratch:HI 2 ""))])] 72518334Speter "TARGET_80387" 72618334Speter "") 72718334Speter 72818334Speter(define_expand "cmpdf_ccfpeq" 72918334Speter [(parallel [(set (cc0) 73018334Speter (compare:CCFPEQ (match_operand:DF 0 "register_operand" "") 73118334Speter (match_operand:DF 1 "register_operand" ""))) 73218334Speter (clobber (match_scratch:HI 2 ""))])] 73318334Speter "TARGET_80387" 73418334Speter " 73518334Speter{ 73618334Speter if (! register_operand (operands[1], DFmode)) 73718334Speter operands[1] = copy_to_mode_reg (DFmode, operands[1]); 73818334Speter}") 73918334Speter 74018334Speter(define_expand "cmpsf_cc" 74118334Speter [(parallel [(set (cc0) 74218334Speter (compare (match_operand:SF 0 "register_operand" "") 74318334Speter (match_operand:SF 1 "register_operand" ""))) 74418334Speter (clobber (match_scratch:HI 2 ""))])] 74518334Speter "TARGET_80387" 74618334Speter "") 74718334Speter 74818334Speter(define_expand "cmpsf_ccfpeq" 74918334Speter [(parallel [(set (cc0) 75018334Speter (compare:CCFPEQ (match_operand:SF 0 "register_operand" "") 75118334Speter (match_operand:SF 1 "register_operand" ""))) 75218334Speter (clobber (match_scratch:HI 2 ""))])] 75318334Speter "TARGET_80387" 75418334Speter " 75518334Speter{ 75618334Speter if (! register_operand (operands[1], SFmode)) 75718334Speter operands[1] = copy_to_mode_reg (SFmode, operands[1]); 75818334Speter}") 75918334Speter 76018334Speter;; logical compare 76118334Speter 76218334Speter(define_insn "" 76318334Speter [(set (cc0) 76418334Speter (and:SI (match_operand:SI 0 "general_operand" "%ro") 76550650Sobrien (match_operand:SI 1 "nonmemory_operand" "ri")))] 76618334Speter "" 76718334Speter "* 76818334Speter{ 76918334Speter /* For small integers, we may actually use testb. */ 77018334Speter if (GET_CODE (operands[1]) == CONST_INT 77118334Speter && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) 77252296Sobrien && (! REG_P (operands[0]) || QI_REG_P (operands[0])) 77352296Sobrien /* A Pentium test is pairable only with eax. Not with ah or al. */ 77452296Sobrien && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM 77552296Sobrien || optimize_size)) 77618334Speter { 77718334Speter /* We may set the sign bit spuriously. */ 77818334Speter 77918334Speter if ((INTVAL (operands[1]) & ~0xff) == 0) 78018334Speter { 78118334Speter cc_status.flags |= CC_NOT_NEGATIVE; 78218334Speter return AS2 (test%B0,%1,%b0); 78318334Speter } 78418334Speter 78518334Speter if ((INTVAL (operands[1]) & ~0xff00) == 0) 78618334Speter { 78718334Speter cc_status.flags |= CC_NOT_NEGATIVE; 78818334Speter operands[1] = GEN_INT (INTVAL (operands[1]) >> 8); 78918334Speter 79018334Speter if (QI_REG_P (operands[0])) 79118334Speter return AS2 (test%B0,%1,%h0); 79218334Speter else 79318334Speter { 79418334Speter operands[0] = adj_offsettable_operand (operands[0], 1); 79518334Speter return AS2 (test%B0,%1,%b0); 79618334Speter } 79718334Speter } 79818334Speter 79918334Speter if (GET_CODE (operands[0]) == MEM 80018334Speter && (INTVAL (operands[1]) & ~0xff0000) == 0) 80118334Speter { 80218334Speter cc_status.flags |= CC_NOT_NEGATIVE; 80318334Speter operands[1] = GEN_INT (INTVAL (operands[1]) >> 16); 80418334Speter operands[0] = adj_offsettable_operand (operands[0], 2); 80518334Speter return AS2 (test%B0,%1,%b0); 80618334Speter } 80718334Speter 80818334Speter if (GET_CODE (operands[0]) == MEM 80918334Speter && (INTVAL (operands[1]) & ~0xff000000) == 0) 81018334Speter { 81118334Speter operands[1] = GEN_INT ((INTVAL (operands[1]) >> 24) & 0xff); 81218334Speter operands[0] = adj_offsettable_operand (operands[0], 3); 81318334Speter return AS2 (test%B0,%1,%b0); 81418334Speter } 81518334Speter } 81618334Speter 81718334Speter if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM) 81818334Speter return AS2 (test%L0,%1,%0); 81918334Speter 82018334Speter return AS2 (test%L1,%0,%1); 82152296Sobrien}" 82252296Sobrien [(set_attr "type" "compare")]) 82318334Speter 82418334Speter(define_insn "" 82518334Speter [(set (cc0) 82618334Speter (and:HI (match_operand:HI 0 "general_operand" "%ro") 82750650Sobrien (match_operand:HI 1 "nonmemory_operand" "ri")))] 82818334Speter "" 82918334Speter "* 83018334Speter{ 83118334Speter if (GET_CODE (operands[1]) == CONST_INT 83218334Speter && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) 83318334Speter && (! REG_P (operands[0]) || QI_REG_P (operands[0]))) 83418334Speter { 83518334Speter if ((INTVAL (operands[1]) & 0xff00) == 0) 83618334Speter { 83718334Speter /* ??? This might not be necessary. */ 83818334Speter if (INTVAL (operands[1]) & 0xffff0000) 83918334Speter operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); 84018334Speter 84118334Speter /* We may set the sign bit spuriously. */ 84218334Speter cc_status.flags |= CC_NOT_NEGATIVE; 84318334Speter return AS2 (test%B0,%1,%b0); 84418334Speter } 84518334Speter 84618334Speter if ((INTVAL (operands[1]) & 0xff) == 0) 84718334Speter { 84818334Speter operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff); 84918334Speter 85018334Speter if (QI_REG_P (operands[0])) 85118334Speter return AS2 (test%B0,%1,%h0); 85218334Speter else 85318334Speter { 85418334Speter operands[0] = adj_offsettable_operand (operands[0], 1); 85518334Speter return AS2 (test%B0,%1,%b0); 85618334Speter } 85718334Speter } 85818334Speter } 85918334Speter 86050650Sobrien /* use 32-bit test instruction if there are no sign issues */ 86150650Sobrien if (GET_CODE (operands[1]) == CONST_INT 86250650Sobrien && !(INTVAL (operands[1]) & ~0x7fff) 86350650Sobrien && i386_aligned_p (operands[0])) 86450650Sobrien return AS2 (test%L0,%1,%k0); 86550650Sobrien 86618334Speter if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM) 86718334Speter return AS2 (test%W0,%1,%0); 86818334Speter 86918334Speter return AS2 (test%W1,%0,%1); 87052296Sobrien}" 87152296Sobrien [(set_attr "type" "compare")]) 87218334Speter 87318334Speter(define_insn "" 87418334Speter [(set (cc0) 87550650Sobrien (and:QI (match_operand:QI 0 "nonimmediate_operand" "%qm") 87650650Sobrien (match_operand:QI 1 "nonmemory_operand" "qi")))] 87718334Speter "" 87818334Speter "* 87918334Speter{ 88018334Speter if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM) 88118334Speter return AS2 (test%B0,%1,%0); 88218334Speter 88318334Speter return AS2 (test%B1,%0,%1); 88452296Sobrien}" 88552296Sobrien [(set_attr "type" "compare")]) 88618334Speter 88718334Speter;; move instructions. 88818334Speter;; There is one for each machine mode, 88918334Speter;; and each is preceded by a corresponding push-insn pattern 89018334Speter;; (since pushes are not general_operands on the 386). 89118334Speter 89218334Speter(define_insn "" 89318334Speter [(set (match_operand:SI 0 "push_operand" "=<") 89450650Sobrien (match_operand:SI 1 "nonmemory_operand" "rn"))] 89550650Sobrien "flag_pic" 89652296Sobrien "* return AS1 (push%L0,%1);" 89752296Sobrien [(set_attr "memory" "store")]) 89818334Speter 89918334Speter(define_insn "" 90018334Speter [(set (match_operand:SI 0 "push_operand" "=<") 90118334Speter (match_operand:SI 1 "nonmemory_operand" "ri"))] 90250650Sobrien "!flag_pic" 90352296Sobrien "* return AS1 (push%L0,%1);" 90452296Sobrien [(set_attr "memory" "store")]) 90518334Speter 90650650Sobrien;; On a 386, it is faster to push MEM directly. 90750650Sobrien 90818334Speter(define_insn "" 90918334Speter [(set (match_operand:SI 0 "push_operand" "=<") 91050650Sobrien (match_operand:SI 1 "memory_operand" "m"))] 91150650Sobrien "TARGET_PUSH_MEMORY" 91252296Sobrien "* return AS1 (push%L0,%1);" 91352296Sobrien [(set_attr "type" "memory") 91452296Sobrien (set_attr "memory" "load")]) 91518334Speter 91618334Speter;; General case of fullword move. 91718334Speter 91818334Speter;; If generating PIC code and operands[1] is a symbolic CONST, emit a 91918334Speter;; move to get the address of the symbolic object from the GOT. 92018334Speter 92118334Speter(define_expand "movsi" 92218334Speter [(set (match_operand:SI 0 "general_operand" "") 92318334Speter (match_operand:SI 1 "general_operand" ""))] 92418334Speter "" 92518334Speter " 92618334Speter{ 92718334Speter extern int flag_pic; 92818334Speter 92918334Speter if (flag_pic && SYMBOLIC_CONST (operands[1])) 93018334Speter emit_pic_move (operands, SImode); 93118334Speter 93218334Speter /* Don't generate memory->memory moves, go through a register */ 93318334Speter else if (TARGET_MOVE 93452296Sobrien && no_new_pseudos == 0 93518334Speter && GET_CODE (operands[0]) == MEM 93618334Speter && GET_CODE (operands[1]) == MEM) 93718334Speter { 93818334Speter operands[1] = force_reg (SImode, operands[1]); 93918334Speter } 94018334Speter}") 94118334Speter 94218334Speter;; On i486, incl reg is faster than movl $1,reg. 94318334Speter 94418334Speter(define_insn "" 94552296Sobrien [(set (match_operand:SI 0 "general_operand" "=g,r,r") 94652296Sobrien (match_operand:SI 1 "general_operand" "rn,i,m"))] 94750650Sobrien "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM) 94850650Sobrien || (GET_CODE (operands[1]) != MEM)) 94950650Sobrien && flag_pic" 95018334Speter "* 95118334Speter{ 95218334Speter rtx link; 95352296Sobrien 95452296Sobrien /* K6: mov reg,0 is slightly faster than xor reg,reg but is 3 bytes 95552296Sobrien longer. */ 95652296Sobrien if ((ix86_cpu != PROCESSOR_K6 || optimize_size) 95752296Sobrien && operands[1] == const0_rtx && REG_P (operands[0])) 95818334Speter return AS2 (xor%L0,%0,%0); 95918334Speter 96018334Speter if (operands[1] == const1_rtx 96152296Sobrien /* PPRO and K6 prefer mov to inc to reduce dependencies. */ 96252296Sobrien && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO) 96318334Speter && (link = find_reg_note (insn, REG_WAS_0, 0)) 96418334Speter /* Make sure the insn that stored the 0 is still present. */ 96518334Speter && ! INSN_DELETED_P (XEXP (link, 0)) 96618334Speter && GET_CODE (XEXP (link, 0)) != NOTE 96718334Speter /* Make sure cross jumping didn't happen here. */ 96818334Speter && no_labels_between_p (XEXP (link, 0), insn) 96918334Speter /* Make sure the reg hasn't been clobbered. */ 97018334Speter && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) 97118334Speter /* Fastest way to change a 0 to a 1. */ 97218334Speter return AS1 (inc%L0,%0); 97318334Speter 97450650Sobrien if (SYMBOLIC_CONST (operands[1])) 97518334Speter return AS2 (lea%L0,%a1,%0); 97618334Speter 97718334Speter return AS2 (mov%L0,%1,%0); 97852296Sobrien}" 97952296Sobrien [(set_attr "type" "integer,integer,memory") 98052296Sobrien (set_attr "memory" "*,*,load")]) 98118334Speter 98218334Speter(define_insn "" 98350650Sobrien [(set (match_operand:SI 0 "general_operand" "=g,r") 98450650Sobrien (match_operand:SI 1 "general_operand" "ri,m"))] 98550650Sobrien "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM) 98650650Sobrien || (GET_CODE (operands[1]) != MEM)) 98750650Sobrien && !flag_pic" 98850650Sobrien "* 98950650Sobrien{ 99050650Sobrien rtx link; 99152296Sobrien 99252296Sobrien /* Use of xor was disabled for AMD K6 as recommended by the Optimization 99352296Sobrien Manual. My test shows, that this generally hurts the performance, because 99452296Sobrien mov is longer and takes longer to decode and decoding is the main 99552296Sobrien bottleneck of K6 when executing GCC code. */ 99652296Sobrien 99750650Sobrien if (operands[1] == const0_rtx && REG_P (operands[0])) 99850650Sobrien return AS2 (xor%L0,%0,%0); 99918334Speter 100050650Sobrien if (operands[1] == const1_rtx 100152296Sobrien /* PPRO and K6 prefer mov to inc to reduce dependencies. */ 100252296Sobrien && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO) 100350650Sobrien && (link = find_reg_note (insn, REG_WAS_0, 0)) 100450650Sobrien /* Make sure the insn that stored the 0 is still present. */ 100550650Sobrien && ! INSN_DELETED_P (XEXP (link, 0)) 100650650Sobrien && GET_CODE (XEXP (link, 0)) != NOTE 100750650Sobrien /* Make sure cross jumping didn't happen here. */ 100850650Sobrien && no_labels_between_p (XEXP (link, 0), insn) 100950650Sobrien /* Make sure the reg hasn't been clobbered. */ 101050650Sobrien && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) 101150650Sobrien /* Fastest way to change a 0 to a 1. */ 101250650Sobrien return AS1 (inc%L0,%0); 101350650Sobrien 101450650Sobrien return AS2 (mov%L0,%1,%0); 101552296Sobrien}" 101652296Sobrien [(set_attr "type" "integer,memory") 101752296Sobrien (set_attr "memory" "*,load")]) 101850650Sobrien 101918334Speter(define_insn "" 102018334Speter [(set (match_operand:HI 0 "push_operand" "=<") 102118334Speter (match_operand:HI 1 "nonmemory_operand" "ri"))] 102250650Sobrien "" 102352296Sobrien "* return AS1 (push%W0,%1);" 102452296Sobrien [(set_attr "type" "memory") 102552296Sobrien (set_attr "memory" "store")]) 102618334Speter 102718334Speter(define_insn "" 102818334Speter [(set (match_operand:HI 0 "push_operand" "=<") 102950650Sobrien (match_operand:HI 1 "memory_operand" "m"))] 103050650Sobrien "TARGET_PUSH_MEMORY" 103152296Sobrien "* return AS1 (push%W0,%1);" 103252296Sobrien [(set_attr "type" "memory") 103352296Sobrien (set_attr "memory" "load")]) 103418334Speter 103518334Speter;; On i486, an incl and movl are both faster than incw and movw. 103618334Speter 103718334Speter(define_expand "movhi" 103818334Speter [(set (match_operand:HI 0 "general_operand" "") 103918334Speter (match_operand:HI 1 "general_operand" ""))] 104018334Speter "" 104118334Speter " 104218334Speter{ 104318334Speter /* Don't generate memory->memory moves, go through a register */ 104418334Speter if (TARGET_MOVE 104552296Sobrien && no_new_pseudos == 0 104618334Speter && GET_CODE (operands[0]) == MEM 104718334Speter && GET_CODE (operands[1]) == MEM) 104818334Speter { 104918334Speter operands[1] = force_reg (HImode, operands[1]); 105018334Speter } 105118334Speter}") 105218334Speter 105318334Speter(define_insn "" 105418334Speter [(set (match_operand:HI 0 "general_operand" "=g,r") 105518334Speter (match_operand:HI 1 "general_operand" "ri,m"))] 105618334Speter "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" 105718334Speter "* 105818334Speter{ 105918334Speter rtx link; 106018334Speter if (REG_P (operands[0]) && operands[1] == const0_rtx) 106118334Speter return AS2 (xor%L0,%k0,%k0); 106218334Speter 106318334Speter if (REG_P (operands[0]) && operands[1] == const1_rtx 106452296Sobrien /* PPRO and K6 prefer mov to inc to reduce dependencies. */ 106552296Sobrien && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO) 106618334Speter && (link = find_reg_note (insn, REG_WAS_0, 0)) 106718334Speter /* Make sure the insn that stored the 0 is still present. */ 106818334Speter && ! INSN_DELETED_P (XEXP (link, 0)) 106918334Speter && GET_CODE (XEXP (link, 0)) != NOTE 107018334Speter /* Make sure cross jumping didn't happen here. */ 107118334Speter && no_labels_between_p (XEXP (link, 0), insn) 107218334Speter /* Make sure the reg hasn't been clobbered. */ 107318334Speter && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) 107418334Speter /* Fastest way to change a 0 to a 1. */ 107518334Speter return AS1 (inc%L0,%k0); 107618334Speter 107718334Speter if (REG_P (operands[0])) 107818334Speter { 107950650Sobrien if (i386_aligned_p (operands[1])) 108050650Sobrien { 108150650Sobrien operands[1] = i386_sext16_if_const (operands[1]); 108250650Sobrien return AS2 (mov%L0,%k1,%k0); 108350650Sobrien } 108452296Sobrien if (! TARGET_ZERO_EXTEND_WITH_AND) 108550650Sobrien { 108650650Sobrien /* movzwl is faster than movw on the Pentium Pro, 108750650Sobrien * although not as fast as an aligned movl. */ 108850650Sobrien#ifdef INTEL_SYNTAX 108950650Sobrien return AS2 (movzx,%1,%k0); 109050650Sobrien#else 109150650Sobrien return AS2 (movz%W0%L0,%1,%k0); 109250650Sobrien#endif 109350650Sobrien } 109418334Speter } 109518334Speter 109618334Speter return AS2 (mov%W0,%1,%0); 109752296Sobrien}" 109852296Sobrien [(set_attr "type" "integer,memory") 109952296Sobrien (set_attr "memory" "*,load")]) 110018334Speter 110118334Speter(define_expand "movstricthi" 110218334Speter [(set (strict_low_part (match_operand:HI 0 "general_operand" "")) 110318334Speter (match_operand:HI 1 "general_operand" ""))] 110418334Speter "" 110518334Speter " 110618334Speter{ 110718334Speter /* Don't generate memory->memory moves, go through a register */ 110818334Speter if (TARGET_MOVE 110952296Sobrien && no_new_pseudos == 0 111018334Speter && GET_CODE (operands[0]) == MEM 111118334Speter && GET_CODE (operands[1]) == MEM) 111218334Speter { 111318334Speter operands[1] = force_reg (HImode, operands[1]); 111418334Speter } 111518334Speter}") 111618334Speter 111718334Speter(define_insn "" 111818334Speter [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r")) 111918334Speter (match_operand:HI 1 "general_operand" "ri,m"))] 112018334Speter "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" 112118334Speter "* 112218334Speter{ 112318334Speter rtx link; 112452296Sobrien 112552296Sobrien /* Use of xor was disabled for AMD K6 as recommended by the Optimization 112652296Sobrien Manual. My test shows, that this generally hurts the performance, because 112752296Sobrien mov is longer and takes longer to decode and decoding is the main 112852296Sobrien bottleneck of K6 when executing GCC code. */ 112952296Sobrien 113018334Speter if (operands[1] == const0_rtx && REG_P (operands[0])) 113118334Speter return AS2 (xor%W0,%0,%0); 113218334Speter 113318334Speter if (operands[1] == const1_rtx 113452296Sobrien /* PPRO and K6 prefer mov to inc to reduce dependencies. */ 113552296Sobrien && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO) 113618334Speter && (link = find_reg_note (insn, REG_WAS_0, 0)) 113718334Speter /* Make sure the insn that stored the 0 is still present. */ 113818334Speter && ! INSN_DELETED_P (XEXP (link, 0)) 113918334Speter && GET_CODE (XEXP (link, 0)) != NOTE 114018334Speter /* Make sure cross jumping didn't happen here. */ 114118334Speter && no_labels_between_p (XEXP (link, 0), insn) 114218334Speter /* Make sure the reg hasn't been clobbered. */ 114318334Speter && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) 114418334Speter /* Fastest way to change a 0 to a 1. */ 114518334Speter return AS1 (inc%W0,%0); 114618334Speter 114718334Speter return AS2 (mov%W0,%1,%0); 114852296Sobrien}" 114952296Sobrien [(set_attr "type" "integer,memory")]) 115018334Speter 115118334Speter;; emit_push_insn when it calls move_by_pieces 115218334Speter;; requires an insn to "push a byte". 115318334Speter;; But actually we use pushw, which has the effect of rounding 115418334Speter;; the amount pushed up to a halfword. 115518334Speter(define_insn "" 115618334Speter [(set (match_operand:QI 0 "push_operand" "=<") 115750650Sobrien (match_operand:QI 1 "const_int_operand" "n"))] 115818334Speter "" 115950650Sobrien "* return AS1(push%W0,%1);") 116018334Speter 116118334Speter(define_insn "" 116218334Speter [(set (match_operand:QI 0 "push_operand" "=<") 116318334Speter (match_operand:QI 1 "register_operand" "q"))] 116450650Sobrien "" 116518334Speter "* 116618334Speter{ 116750650Sobrien operands[1] = gen_rtx_REG (HImode, REGNO (operands[1])); 116818334Speter return AS1 (push%W0,%1); 116918334Speter}") 117018334Speter 117118334Speter;; On i486, incb reg is faster than movb $1,reg. 117218334Speter 117318334Speter;; ??? Do a recognizer for zero_extract that looks just like this, but reads 117418334Speter;; or writes %ah, %bh, %ch, %dh. 117518334Speter 117618334Speter(define_expand "movqi" 117718334Speter [(set (match_operand:QI 0 "general_operand" "") 117818334Speter (match_operand:QI 1 "general_operand" ""))] 117918334Speter "" 118018334Speter " 118118334Speter{ 118218334Speter /* Don't generate memory->memory moves, go through a register */ 118318334Speter if (TARGET_MOVE 118452296Sobrien && no_new_pseudos == 0 118518334Speter && GET_CODE (operands[0]) == MEM 118618334Speter && GET_CODE (operands[1]) == MEM) 118718334Speter { 118818334Speter operands[1] = force_reg (QImode, operands[1]); 118918334Speter } 119018334Speter}") 119118334Speter 119218334Speter(define_insn "" 119350650Sobrien [(set (match_operand:QI 0 "nonimmediate_operand" "=q,*r,qm") 119450650Sobrien (match_operand:QI 1 "general_operand" "*g,*rn,qn"))] 119518334Speter "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" 119618334Speter "* 119718334Speter{ 119818334Speter rtx link; 119918334Speter 120052296Sobrien /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8. 120152296Sobrien It is at least as fast as xor on any processor except a Pentium. */ 120252296Sobrien 120318334Speter if (operands[1] == const1_rtx 120452296Sobrien && TARGET_PENTIUM 120518334Speter && (link = find_reg_note (insn, REG_WAS_0, 0)) 120618334Speter /* Make sure the insn that stored the 0 is still present. */ 120718334Speter && ! INSN_DELETED_P (XEXP (link, 0)) 120818334Speter && GET_CODE (XEXP (link, 0)) != NOTE 120918334Speter /* Make sure cross jumping didn't happen here. */ 121018334Speter && no_labels_between_p (XEXP (link, 0), insn) 121118334Speter /* Make sure the reg hasn't been clobbered. */ 121218334Speter && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) 121350650Sobrien { 121450650Sobrien /* Fastest way to change a 0 to a 1. 121550650Sobrien If inc%B0 isn't allowed, use inc%L0. */ 121650650Sobrien if (NON_QI_REG_P (operands[0])) 121750650Sobrien return AS1 (inc%L0,%k0); 121850650Sobrien else 121950650Sobrien return AS1 (inc%B0,%0); 122050650Sobrien } 122118334Speter 122218334Speter /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */ 122318334Speter if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1])) 122418334Speter return (AS2 (mov%L0,%k1,%k0)); 122518334Speter 122618334Speter return (AS2 (mov%B0,%1,%0)); 122718334Speter}") 122818334Speter 122918334Speter;; If it becomes necessary to support movstrictqi into %esi or %edi, 123018334Speter;; use the insn sequence: 123118334Speter;; 123218334Speter;; shrdl $8,srcreg,dstreg 123318334Speter;; rorl $24,dstreg 123418334Speter;; 123518334Speter;; If operands[1] is a constant, then an andl/orl sequence would be 123618334Speter;; faster. 123718334Speter 123818334Speter(define_expand "movstrictqi" 123918334Speter [(set (strict_low_part (match_operand:QI 0 "general_operand" "")) 124018334Speter (match_operand:QI 1 "general_operand" ""))] 124118334Speter "" 124218334Speter " 124318334Speter{ 124418334Speter /* Don't generate memory->memory moves, go through a register */ 124518334Speter if (TARGET_MOVE 124652296Sobrien && no_new_pseudos == 0 124718334Speter && GET_CODE (operands[0]) == MEM 124818334Speter && GET_CODE (operands[1]) == MEM) 124918334Speter { 125018334Speter operands[1] = force_reg (QImode, operands[1]); 125118334Speter } 125218334Speter}") 125318334Speter 125418334Speter(define_insn "" 125550650Sobrien [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 125618334Speter (match_operand:QI 1 "general_operand" "*qn,m"))] 125718334Speter "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" 125818334Speter "* 125918334Speter{ 126018334Speter rtx link; 126118334Speter 126252296Sobrien /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8. */ 126352296Sobrien 126418334Speter if (operands[1] == const1_rtx 126552296Sobrien && TARGET_PENTIUM 126650650Sobrien && ! NON_QI_REG_P (operands[0]) 126718334Speter && (link = find_reg_note (insn, REG_WAS_0, 0)) 126818334Speter /* Make sure the insn that stored the 0 is still present. */ 126918334Speter && ! INSN_DELETED_P (XEXP (link, 0)) 127018334Speter && GET_CODE (XEXP (link, 0)) != NOTE 127118334Speter /* Make sure cross jumping didn't happen here. */ 127218334Speter && no_labels_between_p (XEXP (link, 0), insn) 127318334Speter /* Make sure the reg hasn't been clobbered. */ 127418334Speter && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) 127518334Speter /* Fastest way to change a 0 to a 1. */ 127618334Speter return AS1 (inc%B0,%0); 127718334Speter 127818334Speter /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */ 127918334Speter if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1])) 128018334Speter { 128118334Speter abort (); 128218334Speter return (AS2 (mov%L0,%k1,%k0)); 128318334Speter } 128418334Speter 128518334Speter return AS2 (mov%B0,%1,%0); 128618334Speter}") 128718334Speter 128850650Sobrien(define_insn "movsf_push" 128918334Speter [(set (match_operand:SF 0 "push_operand" "=<,<") 129050650Sobrien (match_operand:SF 1 "general_operand" "*rfF,m"))] 129152296Sobrien "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM 129252296Sobrien || reload_in_progress || reload_completed" 129318334Speter "* 129418334Speter{ 129518334Speter if (STACK_REG_P (operands[1])) 129618334Speter { 129718334Speter rtx xops[3]; 129818334Speter 129918334Speter if (! STACK_TOP_P (operands[1])) 130018334Speter abort (); 130118334Speter 130218334Speter xops[0] = AT_SP (SFmode); 130318334Speter xops[1] = GEN_INT (4); 130418334Speter xops[2] = stack_pointer_rtx; 130518334Speter 130618334Speter output_asm_insn (AS2 (sub%L2,%1,%2), xops); 130718334Speter 130818334Speter if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) 130918334Speter output_asm_insn (AS1 (fstp%S0,%0), xops); 131018334Speter else 131118334Speter output_asm_insn (AS1 (fst%S0,%0), xops); 131250650Sobrien 131318334Speter RET; 131418334Speter } 131550650Sobrien 131650650Sobrien return AS1 (push%L0,%1); 131718334Speter}") 131818334Speter 131952296Sobrien(define_split 132052296Sobrien [(set (match_operand:SF 0 "push_operand" "") 132152296Sobrien (match_operand:SF 1 "general_operand" ""))] 132252296Sobrien "reload_completed && STACK_REG_P (operands[1])" 132352296Sobrien [(set (reg:SI 7) 132452296Sobrien (minus:SI (reg:SI 7) (const_int 4))) 132552296Sobrien (set (mem:SF (reg:SI 7)) 132652296Sobrien (match_dup 1))] 132752296Sobrien "") 132850650Sobrien 132950650Sobrien(define_expand "movsf" 133050650Sobrien [(set (match_operand:SF 0 "general_operand" "") 133150650Sobrien (match_operand:SF 1 "general_operand" ""))] 133218334Speter "" 133350650Sobrien " 133418334Speter{ 133550650Sobrien /* Don't generate memory->memory moves, go through a register */ 133650650Sobrien if (TARGET_MOVE 133752296Sobrien && no_new_pseudos == 0 133850650Sobrien && GET_CODE (operands[0]) == MEM 133950650Sobrien && GET_CODE (operands[1]) == MEM) 134018334Speter { 134150650Sobrien operands[1] = force_reg (SFmode, operands[1]); 134250650Sobrien } 134318334Speter 134450650Sobrien /* If we are loading a floating point constant that isn't 0 or 1 134552296Sobrien into a register, force the value to memory now, since we'll 134652296Sobrien get better code out the back end. */ 134750650Sobrien else if ((reload_in_progress | reload_completed) == 0 134852296Sobrien && GET_CODE (operands[0]) != MEM 134952296Sobrien && GET_CODE (operands[1]) == CONST_DOUBLE 135052296Sobrien && !standard_80387_constant_p (operands[1])) 135150650Sobrien { 135252296Sobrien operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); 135318334Speter } 135418334Speter}") 135518334Speter 135618334Speter;; For the purposes of regclass, prefer FLOAT_REGS. 135750650Sobrien(define_insn "" 135852296Sobrien [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r,!m") 135952296Sobrien (match_operand:SF 1 "general_operand" "fmG,f,*rmF,*rF"))] 136018334Speter "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" 136118334Speter "* 136218334Speter{ 136318334Speter int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; 136418334Speter 136518334Speter /* First handle a `pop' insn or a `fld %st(0)' */ 136618334Speter 136718334Speter if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1])) 136818334Speter { 136918334Speter if (stack_top_dies) 137018334Speter return AS1 (fstp,%y0); 137118334Speter else 137218334Speter return AS1 (fld,%y0); 137318334Speter } 137418334Speter 137518334Speter /* Handle other kinds of writes from the 387 */ 137618334Speter 137718334Speter if (STACK_TOP_P (operands[1])) 137818334Speter { 137918334Speter if (stack_top_dies) 138018334Speter return AS1 (fstp%z0,%y0); 138118334Speter else 138218334Speter return AS1 (fst%z0,%y0); 138318334Speter } 138418334Speter 138518334Speter /* Handle other kinds of reads to the 387 */ 138618334Speter 138718334Speter if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE) 138818334Speter return output_move_const_single (operands); 138918334Speter 139018334Speter if (STACK_TOP_P (operands[0])) 139118334Speter return AS1 (fld%z1,%y1); 139218334Speter 139318334Speter /* Handle all SFmode moves not involving the 387 */ 139418334Speter 139518334Speter return singlemove_string (operands); 139650650Sobrien}" 139750650Sobrien [(set_attr "type" "fld")]) 139818334Speter 139950650Sobrien 140018334Speter(define_insn "swapsf" 140118334Speter [(set (match_operand:SF 0 "register_operand" "f") 140218334Speter (match_operand:SF 1 "register_operand" "f")) 140318334Speter (set (match_dup 1) 140418334Speter (match_dup 0))] 140518334Speter "" 140618334Speter "* 140718334Speter{ 140818334Speter if (STACK_TOP_P (operands[0])) 140918334Speter return AS1 (fxch,%1); 141018334Speter else 141118334Speter return AS1 (fxch,%0); 141218334Speter}") 141318334Speter 141452296Sobrien 141550650Sobrien(define_insn "movdf_push" 141618334Speter [(set (match_operand:DF 0 "push_operand" "=<,<") 141750650Sobrien (match_operand:DF 1 "general_operand" "*rfF,o"))] 141852296Sobrien "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM 141952296Sobrien || reload_in_progress || reload_completed" 142018334Speter "* 142118334Speter{ 142218334Speter if (STACK_REG_P (operands[1])) 142318334Speter { 142418334Speter rtx xops[3]; 142518334Speter 142650650Sobrien xops[0] = AT_SP (DFmode); 142718334Speter xops[1] = GEN_INT (8); 142818334Speter xops[2] = stack_pointer_rtx; 142918334Speter 143018334Speter output_asm_insn (AS2 (sub%L2,%1,%2), xops); 143118334Speter 143218334Speter if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) 143318334Speter output_asm_insn (AS1 (fstp%Q0,%0), xops); 143418334Speter else 143518334Speter output_asm_insn (AS1 (fst%Q0,%0), xops); 143618334Speter 143718334Speter RET; 143818334Speter } 143950650Sobrien 144050650Sobrien if (which_alternative == 1) 144150650Sobrien return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode), 0, 0); 144250650Sobrien 144350650Sobrien return output_move_double (operands); 144418334Speter}") 144518334Speter 144652296Sobrien(define_split 144752296Sobrien [(set (match_operand:DF 0 "push_operand" "") 144852296Sobrien (match_operand:DF 1 "register_operand" ""))] 144952296Sobrien "reload_completed && STACK_REG_P (operands[1])" 145052296Sobrien [(set (reg:SI 7) 145152296Sobrien (minus:SI (reg:SI 7) (const_int 8))) 145252296Sobrien (set (mem:DF (reg:SI 7)) 145352296Sobrien (match_dup 1))] 145452296Sobrien "") 145550650Sobrien 145650650Sobrien(define_expand "movdf" 145750650Sobrien [(set (match_operand:DF 0 "general_operand" "") 145850650Sobrien (match_operand:DF 1 "general_operand" ""))] 145918334Speter "" 146050650Sobrien " 146118334Speter{ 146250650Sobrien /* Don't generate memory->memory moves, go through a register */ 146350650Sobrien if (TARGET_MOVE 146452296Sobrien && no_new_pseudos == 0 146550650Sobrien && GET_CODE (operands[0]) == MEM 146650650Sobrien && GET_CODE (operands[1]) == MEM) 146718334Speter { 146850650Sobrien operands[1] = force_reg (DFmode, operands[1]); 146950650Sobrien } 147018334Speter 147150650Sobrien /* If we are loading a floating point constant that isn't 0 or 1 into a 147250650Sobrien register, indicate we need the pic register loaded. This could be 147350650Sobrien optimized into stores of constants if the target eventually moves to 147450650Sobrien memory, but better safe than sorry. */ 147550650Sobrien else if ((reload_in_progress | reload_completed) == 0 147652296Sobrien && GET_CODE (operands[0]) != MEM 147752296Sobrien && GET_CODE (operands[1]) == CONST_DOUBLE 147852296Sobrien && !standard_80387_constant_p (operands[1])) 147950650Sobrien { 148052296Sobrien operands[1] = validize_mem (force_const_mem (DFmode, operands[1])); 148118334Speter } 148218334Speter}") 148318334Speter 148418334Speter;; For the purposes of regclass, prefer FLOAT_REGS. 148550650Sobrien(define_insn "" 148652296Sobrien [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r,!o") 148752296Sobrien (match_operand:DF 1 "general_operand" "fmG,f,*roF,*rF"))] 148850650Sobrien "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) 148950650Sobrien || (GET_CODE (operands[1]) != MEM)" 149018334Speter "* 149118334Speter{ 149218334Speter int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; 149318334Speter 149418334Speter /* First handle a `pop' insn or a `fld %st(0)' */ 149518334Speter 149618334Speter if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1])) 149718334Speter { 149818334Speter if (stack_top_dies) 149918334Speter return AS1 (fstp,%y0); 150018334Speter else 150118334Speter return AS1 (fld,%y0); 150218334Speter } 150318334Speter 150418334Speter /* Handle other kinds of writes from the 387 */ 150518334Speter 150618334Speter if (STACK_TOP_P (operands[1])) 150718334Speter { 150818334Speter if (stack_top_dies) 150918334Speter return AS1 (fstp%z0,%y0); 151018334Speter else 151118334Speter return AS1 (fst%z0,%y0); 151218334Speter } 151318334Speter 151418334Speter /* Handle other kinds of reads to the 387 */ 151518334Speter 151618334Speter if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE) 151718334Speter return output_move_const_single (operands); 151818334Speter 151918334Speter if (STACK_TOP_P (operands[0])) 152018334Speter return AS1 (fld%z1,%y1); 152118334Speter 152218334Speter /* Handle all DFmode moves not involving the 387 */ 152318334Speter 152418334Speter return output_move_double (operands); 152550650Sobrien}" 152650650Sobrien [(set_attr "type" "fld")]) 152718334Speter 152850650Sobrien 152950650Sobrien 153018334Speter(define_insn "swapdf" 153118334Speter [(set (match_operand:DF 0 "register_operand" "f") 153218334Speter (match_operand:DF 1 "register_operand" "f")) 153318334Speter (set (match_dup 1) 153418334Speter (match_dup 0))] 153518334Speter "" 153618334Speter "* 153718334Speter{ 153818334Speter if (STACK_TOP_P (operands[0])) 153918334Speter return AS1 (fxch,%1); 154018334Speter else 154118334Speter return AS1 (fxch,%0); 154218334Speter}") 154318334Speter 154450650Sobrien(define_insn "movxf_push" 154518334Speter [(set (match_operand:XF 0 "push_operand" "=<,<") 154650650Sobrien (match_operand:XF 1 "general_operand" "*rfF,o"))] 154752296Sobrien "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM 154852296Sobrien || reload_in_progress || reload_completed" 154918334Speter "* 155018334Speter{ 155118334Speter if (STACK_REG_P (operands[1])) 155218334Speter { 155318334Speter rtx xops[3]; 155418334Speter 155550650Sobrien xops[0] = AT_SP (XFmode); 155618334Speter xops[1] = GEN_INT (12); 155718334Speter xops[2] = stack_pointer_rtx; 155818334Speter 155918334Speter output_asm_insn (AS2 (sub%L2,%1,%2), xops); 156050650Sobrien 156118334Speter output_asm_insn (AS1 (fstp%T0,%0), xops); 156218334Speter if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) 156318334Speter output_asm_insn (AS1 (fld%T0,%0), xops); 156418334Speter 156518334Speter RET; 156618334Speter } 156750650Sobrien 156850650Sobrien if (which_alternative == 1) 156950650Sobrien return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode), 0, 0); 157050650Sobrien 157150650Sobrien return output_move_double (operands); 157218334Speter }") 157318334Speter 157452296Sobrien(define_split 157552296Sobrien [(set (match_operand:XF 0 "push_operand" "") 157652296Sobrien (match_operand:XF 1 "register_operand" ""))] 157752296Sobrien "reload_completed && STACK_REG_P (operands[1])" 157852296Sobrien [(set (reg:SI 7) 157952296Sobrien (minus:SI (reg:SI 7) (const_int 12))) 158052296Sobrien (set (mem:XF (reg:SI 7)) 158152296Sobrien (match_dup 1))] 158252296Sobrien "") 158350650Sobrien 158450650Sobrien(define_expand "movxf" 158550650Sobrien [(set (match_operand:XF 0 "general_operand" "") 158650650Sobrien (match_operand:XF 1 "general_operand" ""))] 158718334Speter "" 158850650Sobrien " 158918334Speter{ 159050650Sobrien /* Don't generate memory->memory moves, go through a register */ 159150650Sobrien if (TARGET_MOVE 159252296Sobrien && no_new_pseudos == 0 159350650Sobrien && GET_CODE (operands[0]) == MEM 159450650Sobrien && GET_CODE (operands[1]) == MEM) 159518334Speter { 159650650Sobrien operands[1] = force_reg (XFmode, operands[1]); 159750650Sobrien } 159818334Speter 159950650Sobrien /* If we are loading a floating point constant that isn't 0 or 1 160050650Sobrien into a register, indicate we need the pic register loaded. This could 160150650Sobrien be optimized into stores of constants if the target eventually moves 160250650Sobrien to memory, but better safe than sorry. */ 160350650Sobrien else if ((reload_in_progress | reload_completed) == 0 160452296Sobrien && GET_CODE (operands[0]) != MEM 160552296Sobrien && GET_CODE (operands[1]) == CONST_DOUBLE 160652296Sobrien && !standard_80387_constant_p (operands[1])) 160750650Sobrien { 160852296Sobrien operands[1] = validize_mem (force_const_mem (XFmode, operands[1])); 160918334Speter } 161018334Speter}") 161118334Speter 161218334Speter 161350650Sobrien(define_insn "" 161452296Sobrien [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!*r,!o") 161552296Sobrien (match_operand:XF 1 "general_operand" "fmG,f,*roF,*rF"))] 161650650Sobrien "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) 161750650Sobrien || (GET_CODE (operands[1]) != MEM)" 161818334Speter "* 161918334Speter{ 162018334Speter int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; 162118334Speter 162218334Speter /* First handle a `pop' insn or a `fld %st(0)' */ 162318334Speter 162418334Speter if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1])) 162518334Speter { 162618334Speter if (stack_top_dies) 162718334Speter return AS1 (fstp,%y0); 162818334Speter else 162918334Speter return AS1 (fld,%y0); 163018334Speter } 163118334Speter 163218334Speter /* Handle other kinds of writes from the 387 */ 163318334Speter 163418334Speter if (STACK_TOP_P (operands[1])) 163518334Speter { 163618334Speter output_asm_insn (AS1 (fstp%z0,%y0), operands); 163718334Speter if (! stack_top_dies) 163818334Speter return AS1 (fld%z0,%y0); 163918334Speter 164018334Speter RET; 164118334Speter } 164218334Speter 164318334Speter /* Handle other kinds of reads to the 387 */ 164418334Speter 164518334Speter if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE) 164618334Speter return output_move_const_single (operands); 164718334Speter 164818334Speter if (STACK_TOP_P (operands[0])) 164918334Speter return AS1 (fld%z1,%y1); 165018334Speter 165118334Speter /* Handle all XFmode moves not involving the 387 */ 165218334Speter 165318334Speter return output_move_double (operands); 165418334Speter}") 165518334Speter 165650650Sobrien(define_insn "swapxf" 165718334Speter [(set (match_operand:XF 0 "register_operand" "f") 165818334Speter (match_operand:XF 1 "register_operand" "f")) 165918334Speter (set (match_dup 1) 166018334Speter (match_dup 0))] 166118334Speter "" 166218334Speter "* 166318334Speter{ 166418334Speter if (STACK_TOP_P (operands[0])) 166518334Speter return AS1 (fxch,%1); 166618334Speter else 166718334Speter return AS1 (fxch,%0); 166818334Speter}") 166918334Speter 167018334Speter(define_insn "" 167150650Sobrien [(set (match_operand:DI 0 "push_operand" "=<") 167250650Sobrien (match_operand:DI 1 "general_operand" "riF"))] 167318334Speter "" 167450650Sobrien "* return output_move_double (operands);") 167518334Speter 167650650Sobrien(define_insn "" 167750650Sobrien [(set (match_operand:DI 0 "push_operand" "=<") 167850650Sobrien (match_operand:DI 1 "memory_operand" "o"))] 167950650Sobrien "TARGET_PUSH_MEMORY" 168050650Sobrien "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode),0,0);") 168118334Speter 168250650Sobrien(define_expand "movdi" 168350650Sobrien [(set (match_operand:DI 0 "general_operand" "") 168450650Sobrien (match_operand:DI 1 "general_operand" ""))] 168518334Speter "" 168650650Sobrien " 168718334Speter{ 168850650Sobrien /* Don't generate memory->memory moves, go through a register */ 168950650Sobrien if (TARGET_MOVE 169052296Sobrien && no_new_pseudos == 0 169150650Sobrien && GET_CODE (operands[0]) == MEM 169250650Sobrien && GET_CODE (operands[1]) == MEM) 169350650Sobrien { 169450650Sobrien operands[1] = force_reg (DImode, operands[1]); 169550650Sobrien } 169618334Speter}") 169718334Speter 169850650Sobrien(define_insn "" 169950650Sobrien [(set (match_operand:DI 0 "general_operand" "=g,r") 170050650Sobrien (match_operand:DI 1 "general_operand" "riF,m"))] 170150650Sobrien "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) 170250650Sobrien || (GET_CODE (operands[1]) != MEM)" 170352296Sobrien "* return output_move_double (operands);" 170452296Sobrien [(set_attr "type" "integer,memory") 170552296Sobrien (set_attr "memory" "*,load")]) 170650650Sobrien 170752296Sobrien(define_split 170852296Sobrien [(set (match_operand:DI 0 "nonimmediate_operand" "") 170952296Sobrien (match_operand:DI 1 "general_operand" ""))] 171052296Sobrien "reload_completed 171152296Sobrien && (offsettable_memref_p (operands[0]) 171252296Sobrien || nonmemory_operand (operands[0], DImode)) 171352296Sobrien && (offsettable_memref_p (operands[1]) 171452296Sobrien || nonmemory_operand (operands[1], DImode)) 171552296Sobrien && (! reg_overlap_mentioned_p (gen_lowpart (SImode, operands[0]), 171652296Sobrien operands[1]) 171752296Sobrien || ! reg_overlap_mentioned_p (gen_highpart (SImode, operands[0]), 171852296Sobrien operands[1]))" 171952296Sobrien [(set (match_dup 2) 172052296Sobrien (match_dup 4)) 172152296Sobrien (set (match_dup 3) 172252296Sobrien (match_dup 5))] 172352296Sobrien " 172452296Sobrien{ 172552296Sobrien split_di (&operands[0], 1, &operands[2], &operands[3]); 172652296Sobrien split_di (&operands[1], 1, &operands[4], &operands[5]); 172752296Sobrien 172852296Sobrien if (reg_overlap_mentioned_p (operands[2], operands[1])) 172952296Sobrien { 173052296Sobrien rtx tmp; 173152296Sobrien 173252296Sobrien tmp = operands[2]; 173352296Sobrien operands[2] = operands[3]; 173452296Sobrien operands[3] = tmp; 173552296Sobrien 173652296Sobrien tmp = operands[4]; 173752296Sobrien operands[4] = operands[5]; 173852296Sobrien operands[5] = tmp; 173952296Sobrien } 174052296Sobrien}") 174118334Speter 174218334Speter;;- conversion instructions 174318334Speter;;- NONE 174418334Speter 174518334Speter;;- zero extension instructions 174618334Speter;; See comments by `andsi' for when andl is faster than movzx. 174718334Speter 174852296Sobrien(define_expand "zero_extendhisi2" 174952296Sobrien [(set (match_operand:SI 0 "register_operand" "") 175052296Sobrien (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 175152296Sobrien "" 175252296Sobrien "") 175352296Sobrien 175452296Sobrien;; When optimizing for the PPro/PII or code size, always use movzwl. 175552296Sobrien;; We want to use a different pattern so we can use different constraints 175652296Sobrien;; than the generic pattern. 175752296Sobrien(define_insn "" 175852296Sobrien [(set (match_operand:SI 0 "register_operand" "=r") 175952296Sobrien (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 176052296Sobrien "(optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)" 176152296Sobrien "* return AS2 (movz%W0%L0,%1,%0);") 176252296Sobrien 176352296Sobrien(define_insn "" 176450650Sobrien [(set (match_operand:SI 0 "register_operand" "=r,&r,?r") 176550650Sobrien (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))] 176652296Sobrien "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)" 176718334Speter "* 176850650Sobrien { 176950650Sobrien rtx xops[2]; 177050650Sobrien 177150650Sobrien if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0) 177218334Speter && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])) 177318334Speter { 177418334Speter xops[0] = operands[0]; 177518334Speter xops[1] = GEN_INT (0xffff); 177618334Speter output_asm_insn (AS2 (and%L0,%1,%k0), xops); 177718334Speter RET; 177818334Speter } 177950650Sobrien if (TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])) 178050650Sobrien { 178150650Sobrien output_asm_insn (AS2 (xor%L0,%0,%0),operands); 178250650Sobrien output_asm_insn (AS2 (mov%W0,%1,%w0),operands); 178350650Sobrien RET; 178450650Sobrien } 178518334Speter 178650650Sobrien if (TARGET_ZERO_EXTEND_WITH_AND) 178750650Sobrien { 178850650Sobrien xops[0] = operands[0]; 178950650Sobrien xops[1] = GEN_INT (0xffff); 179050650Sobrien if (i386_aligned_p (operands[1])) 179150650Sobrien output_asm_insn (AS2 (mov%L0,%k1,%k0),operands); 179250650Sobrien else 179350650Sobrien output_asm_insn (AS2 (mov%W0,%1,%w0),operands); 179450650Sobrien output_asm_insn (AS2 (and%L0,%1,%k0), xops); 179550650Sobrien RET; 179650650Sobrien } 179750650Sobrien 179818334Speter#ifdef INTEL_SYNTAX 179918334Speter return AS2 (movzx,%1,%0); 180018334Speter#else 180118334Speter return AS2 (movz%W0%L0,%1,%0); 180218334Speter#endif 180318334Speter}") 180418334Speter 180550650Sobrien(define_split 180650650Sobrien [(set (match_operand:SI 0 "register_operand" "") 180750650Sobrien (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 180850650Sobrien "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])" 180950650Sobrien [(set (match_dup 0) 181050650Sobrien (const_int 0)) 181150650Sobrien (set (strict_low_part (match_dup 2)) 181250650Sobrien (match_dup 1))] 181350650Sobrien "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));") 181450650Sobrien 181550650Sobrien 181650650Sobrien(define_split 181750650Sobrien [(set (match_operand:SI 0 "register_operand" "") 181850650Sobrien (zero_extend:SI (match_operand:HI 1 "memory_operand" "")))] 181950650Sobrien "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && reg_overlap_mentioned_p (operands[0], operands[1])" 182050650Sobrien [(set (strict_low_part (match_dup 2)) 182150650Sobrien (match_dup 1)) 182250650Sobrien (set (match_dup 0) 182350650Sobrien (and:SI (match_dup 0) 182450650Sobrien (const_int 65535)))] 182550650Sobrien "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));") 182650650Sobrien 182752296Sobrien(define_expand "zero_extendqihi2" 182852296Sobrien [(set (match_operand:HI 0 "register_operand" "") 182952296Sobrien (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] 183052296Sobrien "" 183152296Sobrien "") 183252296Sobrien 183352296Sobrien(define_insn "" 183452296Sobrien [(set (match_operand:HI 0 "register_operand" "=r") 183552296Sobrien (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 183652296Sobrien "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO" 183752296Sobrien 183852296Sobrien "* return AS2 (movz%B0%W0,%1,%0);") 183952296Sobrien 184052296Sobrien(define_insn "" 184150650Sobrien [(set (match_operand:HI 0 "register_operand" "=q,&q,?r") 184250650Sobrien (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))] 184352296Sobrien "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)" 184418334Speter "* 184550650Sobrien { 184650650Sobrien rtx xops[2]; 184750650Sobrien 184850650Sobrien if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0) 184950650Sobrien && REG_P (operands[1]) 185050650Sobrien && REGNO (operands[0]) == REGNO (operands[1])) 185118334Speter { 185218334Speter xops[0] = operands[0]; 185318334Speter xops[1] = GEN_INT (0xff); 185418334Speter output_asm_insn (AS2 (and%L0,%1,%k0), xops); 185518334Speter RET; 185618334Speter } 185750650Sobrien if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0])) 185850650Sobrien { 185950650Sobrien if(!reg_overlap_mentioned_p(operands[0],operands[1])) 186050650Sobrien { 186150650Sobrien output_asm_insn (AS2 (xor%L0,%k0,%k0), operands); 186250650Sobrien output_asm_insn (AS2 (mov%B0,%1,%b0), operands); 186350650Sobrien } 186450650Sobrien else 186550650Sobrien { 186650650Sobrien xops[0] = operands[0]; 186750650Sobrien xops[1] = GEN_INT (0xff); 186850650Sobrien output_asm_insn (AS2 (mov%B0,%1,%b0),operands); 186950650Sobrien output_asm_insn (AS2 (and%L0,%1,%k0), xops); 187050650Sobrien } 187150650Sobrien RET; 187250650Sobrien } 187350650Sobrien 187418334Speter#ifdef INTEL_SYNTAX 187518334Speter return AS2 (movzx,%1,%0); 187618334Speter#else 187718334Speter return AS2 (movz%B0%W0,%1,%0); 187818334Speter#endif 187918334Speter}") 188018334Speter 188150650Sobrien(define_split 188250650Sobrien [(set (match_operand:HI 0 "register_operand" "") 188350650Sobrien (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] 188450650Sobrien "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND 188550650Sobrien && !reg_overlap_mentioned_p (operands[0], operands[1])" 188650650Sobrien [(set (match_dup 0) 188750650Sobrien (const_int 0)) 188850650Sobrien (set (strict_low_part (match_dup 2)) 188950650Sobrien (match_dup 1))] 189050650Sobrien "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));") 189150650Sobrien 189250650Sobrien 189350650Sobrien(define_split 189450650Sobrien [(set (match_operand:HI 0 "register_operand" "") 189550650Sobrien (zero_extend:HI (match_operand:QI 1 "memory_operand" "")))] 189650650Sobrien "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND 189750650Sobrien && reg_overlap_mentioned_p (operands[0], operands[1])" 189850650Sobrien [(set (strict_low_part (match_dup 2)) 189950650Sobrien (match_dup 1)) 190050650Sobrien (set (match_dup 0) 190150650Sobrien (and:HI (match_dup 0) 190250650Sobrien (const_int 255)))] 190350650Sobrien "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));") 190450650Sobrien 190550650Sobrien(define_split 190650650Sobrien [(set (match_operand:HI 0 "register_operand" "") 190750650Sobrien (zero_extend:HI (match_operand:QI 1 "register_operand" "")))] 190850650Sobrien "reload_completed && TARGET_ZERO_EXTEND_WITH_AND" 190950650Sobrien [(set (match_dup 0) 191050650Sobrien (match_dup 2)) 191150650Sobrien (set (match_dup 0) 191250650Sobrien (and:HI (match_dup 0) 191350650Sobrien (const_int 255)))] 191450650Sobrien "if (GET_CODE (operands[1]) == SUBREG && SUBREG_WORD (operands[1]) == 0) 191550650Sobrien operands[1] = SUBREG_REG (operands[1]); 191650650Sobrien if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG 191750650Sobrien || REGNO (operands[0]) == REGNO (operands[1])) 191850650Sobrien FAIL; 191950650Sobrien operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));") 192050650Sobrien 192152296Sobrien(define_expand "zero_extendqisi2" 192252296Sobrien [(set (match_operand:SI 0 "register_operand" "") 192352296Sobrien (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] 192452296Sobrien "" 192552296Sobrien "") 192652296Sobrien 192752296Sobrien(define_insn "" 192852296Sobrien [(set (match_operand:SI 0 "register_operand" "=r") 192952296Sobrien (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 193052296Sobrien "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO" 193152296Sobrien "* return AS2 (movz%B0%L0,%1,%0);") 193252296Sobrien 193352296Sobrien(define_insn "" 193450650Sobrien [(set (match_operand:SI 0 "register_operand" "=q,&q,?r") 193550650Sobrien (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))] 193652296Sobrien "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)" 193718334Speter "* 193850650Sobrien { 193950650Sobrien rtx xops[2]; 194050650Sobrien 194150650Sobrien if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0) 194250650Sobrien && REG_P (operands[1]) 194350650Sobrien && REGNO (operands[0]) == REGNO (operands[1])) 194418334Speter { 194518334Speter xops[0] = operands[0]; 194618334Speter xops[1] = GEN_INT (0xff); 194718334Speter output_asm_insn (AS2 (and%L0,%1,%k0), xops); 194818334Speter RET; 194918334Speter } 195050650Sobrien if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0])) 195150650Sobrien { 195250650Sobrien if(!reg_overlap_mentioned_p (operands[0], operands[1])) 195350650Sobrien { 195450650Sobrien output_asm_insn (AS2 (xor%L0,%0,%0),operands); 195550650Sobrien output_asm_insn (AS2 (mov%B0,%1,%b0),operands); 195650650Sobrien } 195750650Sobrien else 195850650Sobrien { 195950650Sobrien xops[0] = operands[0]; 196050650Sobrien xops[1] = GEN_INT (0xff); 196150650Sobrien output_asm_insn (AS2 (mov%B0,%1,%b0), operands); 196250650Sobrien output_asm_insn (AS2 (and%L0,%1,%k0), xops); 196350650Sobrien } 196450650Sobrien RET; 196550650Sobrien } 196618334Speter 196750650Sobrien if (TARGET_ZERO_EXTEND_WITH_AND && GET_CODE (operands[1]) == REG) 196850650Sobrien { 196950650Sobrien xops[0] = operands[0]; 197050650Sobrien xops[1] = GEN_INT (0xff); 197150650Sobrien operands[1] = gen_rtx_REG (SImode, REGNO (operands[1])); 197250650Sobrien output_asm_insn (AS2 (mov%L0,%1,%0), operands); 197350650Sobrien output_asm_insn (AS2 (and%L0,%1,%k0), xops); 197450650Sobrien RET; 197550650Sobrien } 197650650Sobrien 197718334Speter#ifdef INTEL_SYNTAX 197818334Speter return AS2 (movzx,%1,%0); 197918334Speter#else 198018334Speter return AS2 (movz%B0%L0,%1,%0); 198118334Speter#endif 198218334Speter}") 198318334Speter 198450650Sobrien(define_split 198550650Sobrien [(set (match_operand:SI 0 "register_operand" "") 198650650Sobrien (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] 198750650Sobrien "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND 198850650Sobrien && !reg_overlap_mentioned_p (operands[0], operands[1])" 198950650Sobrien [(set (match_dup 0) 199050650Sobrien (const_int 0)) 199150650Sobrien (set (strict_low_part (match_dup 2)) 199250650Sobrien (match_dup 1))] 199350650Sobrien "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));") 199450650Sobrien 199550650Sobrien 199650650Sobrien(define_split 199750650Sobrien [(set (match_operand:SI 0 "register_operand" "") 199850650Sobrien (zero_extend:SI (match_operand:QI 1 "memory_operand" "")))] 199950650Sobrien "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND 200050650Sobrien && reg_overlap_mentioned_p (operands[0], operands[1])" 200150650Sobrien [(set (strict_low_part (match_dup 2)) 200250650Sobrien (match_dup 1)) 200350650Sobrien (set (match_dup 0) 200450650Sobrien (and:SI (match_dup 0) 200550650Sobrien (const_int 255)))] 200650650Sobrien "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));") 200750650Sobrien 200850650Sobrien(define_split 200950650Sobrien [(set (match_operand:SI 0 "register_operand" "") 201050650Sobrien (zero_extend:SI (match_operand:QI 1 "register_operand" "")))] 201150650Sobrien "reload_completed && TARGET_ZERO_EXTEND_WITH_AND 201250650Sobrien && ! reg_overlap_mentioned_p (operands[0], operands[1])" 201350650Sobrien [(set (match_dup 0) 201450650Sobrien (match_dup 2)) 201550650Sobrien (set (match_dup 0) 201650650Sobrien (and:SI (match_dup 0) 201750650Sobrien (const_int 255)))] 201850650Sobrien "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));") 201950650Sobrien 202018334Speter(define_insn "zero_extendsidi2" 202152296Sobrien [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o") 202252296Sobrien (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))] 202318334Speter "" 202452296Sobrien "#") 202550650Sobrien 202652296Sobrien(define_split 202752296Sobrien [(set (match_operand:DI 0 "register_operand" "") 202852296Sobrien (zero_extend:DI (match_operand:SI 1 "register_operand" "")))] 202952296Sobrien "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])" 203052296Sobrien [(set (match_dup 4) (const_int 0))] 203152296Sobrien "split_di (&operands[0], 1, &operands[3], &operands[4]);") 203250650Sobrien 203352296Sobrien(define_split 203452296Sobrien [(set (match_operand:DI 0 "nonimmediate_operand" "") 203552296Sobrien (zero_extend:DI (match_operand:SI 1 "general_operand" "")))] 203652296Sobrien "reload_completed" 203752296Sobrien [(set (match_dup 3) (match_dup 1)) 203852296Sobrien (set (match_dup 4) (const_int 0))] 203952296Sobrien "split_di (&operands[0], 1, &operands[3], &operands[4]);") 204018334Speter 204118334Speter;;- sign extension instructions 204218334Speter 204318334Speter(define_insn "extendsidi2" 204452296Sobrien [(set (match_operand:DI 0 "nonimmediate_operand" "=A,?r,?Ar,*o") 204552296Sobrien (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,*r"))) 204652296Sobrien (clobber (match_scratch:SI 2 "=X,X,X,&r"))] 204718334Speter "" 204852296Sobrien "#") 204952296Sobrien 205052296Sobrien;; Extend to memory case when source register does die. 205152296Sobrien(define_split 205252296Sobrien [(set (match_operand:DI 0 "memory_operand" "") 205352296Sobrien (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 205452296Sobrien (clobber (match_operand:SI 2 "register_operand" ""))] 205552296Sobrien "(flow2_completed 205652296Sobrien && dead_or_set_p (insn, operands[1]) 205752296Sobrien && !reg_mentioned_p (operands[1], operands[0]))" 205852296Sobrien [(set (match_dup 3) (match_dup 1)) 205952296Sobrien (set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) 206052296Sobrien (set (match_dup 4) (match_dup 1))] 206152296Sobrien "split_di (&operands[0], 1, &operands[3], &operands[4]);") 206252296Sobrien 206352296Sobrien;; Extend to memory case when source register does not die. 206452296Sobrien(define_split 206552296Sobrien [(set (match_operand:DI 0 "memory_operand" "") 206652296Sobrien (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 206752296Sobrien (clobber (match_operand:SI 2 "register_operand" ""))] 206852296Sobrien "flow2_completed" 206952296Sobrien [(const_int 0)] 207052296Sobrien " 207118334Speter{ 207252296Sobrien split_di (&operands[0], 1, &operands[3], &operands[4]); 207352296Sobrien 207452296Sobrien emit_move_insn (operands[3], operands[1]); 207552296Sobrien 207652296Sobrien /* Generate a cltd if possible and doing so it profitable. */ 207752296Sobrien if (true_regnum (operands[1]) == 0 207852296Sobrien && true_regnum (operands[2]) == 1 207952296Sobrien && (optimize_size || !TARGET_PENTIUM)) 208018334Speter { 208152296Sobrien emit_insn (gen_ashrsi3_31 (operands[2], operands[1])); 208218334Speter } 208352296Sobrien else 208452296Sobrien { 208552296Sobrien emit_move_insn (operands[2], operands[1]); 208652296Sobrien emit_insn (gen_ashrsi3_31 (operands[2], operands[2])); 208752296Sobrien } 208852296Sobrien emit_move_insn (operands[4], operands[2]); 208952296Sobrien DONE; 209052296Sobrien}") 209118334Speter 209252296Sobrien;; Extend to register case. Optimize case where source and destination 209352296Sobrien;; registers match and cases where we can use cltd. 209452296Sobrien(define_split 209552296Sobrien [(set (match_operand:DI 0 "register_operand" "") 209652296Sobrien (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 209752296Sobrien (clobber (match_scratch:SI 2 ""))] 209852296Sobrien "reload_completed" 209952296Sobrien [(const_int 0)] 210052296Sobrien " 210152296Sobrien{ 210252296Sobrien split_di (&operands[0], 1, &operands[3], &operands[4]); 210318334Speter 210452296Sobrien if (true_regnum (operands[3]) != true_regnum (operands[1])) 210552296Sobrien emit_move_insn (operands[3], operands[1]); 210652296Sobrien 210752296Sobrien /* Generate a cltd if possible and doing so it profitable. */ 210852296Sobrien if (true_regnum (operands[3]) == 0 210952296Sobrien && (optimize_size || !TARGET_PENTIUM)) 211052296Sobrien { 211152296Sobrien emit_insn (gen_ashrsi3_31 (operands[4], operands[3])); 211252296Sobrien DONE; 211352296Sobrien } 211452296Sobrien 211552296Sobrien if (true_regnum (operands[4]) != true_regnum (operands[1])) 211652296Sobrien emit_move_insn (operands[4], operands[1]); 211752296Sobrien 211852296Sobrien emit_insn (gen_ashrsi3_31 (operands[4], operands[4])); 211952296Sobrien DONE; 212018334Speter}") 212118334Speter 212218334Speter;; Note that the i386 programmers' manual says that the opcodes 212318334Speter;; are named movsx..., but the assembler on Unix does not accept that. 212418334Speter;; We use what the Unix assembler expects. 212518334Speter 212618334Speter(define_insn "extendhisi2" 212750650Sobrien [(set (match_operand:SI 0 "register_operand" "=r") 212850650Sobrien (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 212918334Speter "" 213018334Speter "* 213118334Speter{ 213218334Speter if (REGNO (operands[0]) == 0 213352296Sobrien && REG_P (operands[1]) && REGNO (operands[1]) == 0 213452296Sobrien && (optimize_size || ix86_cpu != PROCESSOR_K6)) 213518334Speter#ifdef INTEL_SYNTAX 213618334Speter return \"cwde\"; 213718334Speter#else 213818334Speter return \"cwtl\"; 213918334Speter#endif 214018334Speter 214118334Speter#ifdef INTEL_SYNTAX 214218334Speter return AS2 (movsx,%1,%0); 214318334Speter#else 214418334Speter return AS2 (movs%W0%L0,%1,%0); 214518334Speter#endif 214618334Speter}") 214718334Speter 214818334Speter(define_insn "extendqihi2" 214950650Sobrien [(set (match_operand:HI 0 "register_operand" "=r") 215050650Sobrien (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 215118334Speter "" 215218334Speter "* 215318334Speter{ 215418334Speter if (REGNO (operands[0]) == 0 215552296Sobrien && REG_P (operands[1]) && REGNO (operands[1]) == 0 215652296Sobrien && (optimize_size || ix86_cpu != PROCESSOR_K6)) 215718334Speter return \"cbtw\"; 215818334Speter 215918334Speter#ifdef INTEL_SYNTAX 216018334Speter return AS2 (movsx,%1,%0); 216118334Speter#else 216218334Speter return AS2 (movs%B0%W0,%1,%0); 216318334Speter#endif 216418334Speter}") 216518334Speter 216618334Speter(define_insn "extendqisi2" 216750650Sobrien [(set (match_operand:SI 0 "register_operand" "=r") 216850650Sobrien (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 216918334Speter "" 217018334Speter "* 217118334Speter{ 217218334Speter#ifdef INTEL_SYNTAX 217318334Speter return AS2 (movsx,%1,%0); 217418334Speter#else 217518334Speter return AS2 (movs%B0%L0,%1,%0); 217618334Speter#endif 217718334Speter}") 217850650Sobrien 217918334Speter 218050650Sobrien;; Truncation of long long -> 32 bit 218150650Sobrien 218250650Sobrien(define_expand "truncdisi2" 218350650Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m") 218450650Sobrien (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))] 218550650Sobrien "" 218650650Sobrien " 218750650Sobrien{ 218850650Sobrien /* Don't generate memory->memory moves, go through a register */ 218950650Sobrien if (TARGET_MOVE 219050650Sobrien && (reload_in_progress | reload_completed) == 0 219150650Sobrien && GET_CODE (operands[0]) == MEM 219250650Sobrien && GET_CODE (operands[1]) == MEM) 219350650Sobrien { 219450650Sobrien rtx target = gen_reg_rtx (SImode); 219550650Sobrien emit_insn (gen_truncdisi2 (target, operands[1])); 219650650Sobrien emit_move_insn (operands[0], target); 219750650Sobrien DONE; 219850650Sobrien } 219950650Sobrien}") 220050650Sobrien 220150650Sobrien(define_insn "" 220250650Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m") 220350650Sobrien (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))] 220450650Sobrien "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" 220550650Sobrien "* 220650650Sobrien{ 220750650Sobrien rtx low[2], high[2], xops[2]; 220850650Sobrien 220950650Sobrien split_di (&operands[1], 1, low, high); 221050650Sobrien xops[0] = operands[0]; 221150650Sobrien xops[1] = low[0]; 221250650Sobrien if (!rtx_equal_p (xops[0], xops[1])) 221350650Sobrien output_asm_insn (AS2 (mov%L0,%1,%0), xops); 221450650Sobrien 221550650Sobrien RET; 221650650Sobrien}") 221750650Sobrien 221850650Sobrien(define_insn "" 221950650Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m") 222050650Sobrien (truncate:SI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r") 222150650Sobrien (const_int 32))))] 222250650Sobrien "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" 222350650Sobrien "* 222450650Sobrien{ 222550650Sobrien rtx low[2], high[2], xops[2]; 222650650Sobrien 222750650Sobrien split_di (&operands[1], 1, low, high); 222850650Sobrien xops[0] = operands[0]; 222950650Sobrien xops[1] = high[0]; 223050650Sobrien if (!rtx_equal_p (xops[0], xops[1])) 223150650Sobrien output_asm_insn (AS2 (mov%L0,%1,%0), xops); 223250650Sobrien 223350650Sobrien RET; 223450650Sobrien}") 223550650Sobrien 223650650Sobrien 223750650Sobrien 223818334Speter;; Conversions between float and double. 223918334Speter 224052296Sobrien(define_expand "extendsfdf2" 224152296Sobrien [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "") 224252296Sobrien (float_extend:DF 224352296Sobrien (match_operand:SF 1 "nonimmediate_operand" ""))) 224452296Sobrien (clobber (match_dup 2)) 224552296Sobrien (clobber (match_dup 3))])] 224652296Sobrien "TARGET_80387" 224752296Sobrien " 224852296Sobrien{ 224952296Sobrien if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 225052296Sobrien operands[1] = force_reg (SFmode, operands[1]); 225152296Sobrien 225252296Sobrien operands[2] = assign_386_stack_local (SFmode, 0); 225352296Sobrien operands[3] = assign_386_stack_local (DFmode, 0); 225452296Sobrien}") 225552296Sobrien 225652296Sobrien(define_insn "" 225752296Sobrien [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!f,!*r") 225818334Speter (float_extend:DF 225952296Sobrien (match_operand:SF 1 "nonimmediate_operand" "fm,f,*r,f"))) 226052296Sobrien (clobber (match_operand:SF 2 "memory_operand" "m,m,m,m")) 226152296Sobrien (clobber (match_operand:DF 3 "memory_operand" "m,m,m,o"))] 226252296Sobrien "TARGET_80387 && (GET_CODE (operands[0]) != MEM 226352296Sobrien || GET_CODE (operands[1]) != MEM)" 226418334Speter "* 226518334Speter{ 226652296Sobrien output_float_extend (insn, operands); 226752296Sobrien return \"\"; 226852296Sobrien}" 226952296Sobrien [(set_attr "type" "fld,fpop,fld,fpop")]) 227018334Speter 227152296Sobrien(define_split 227252296Sobrien [(set (match_operand:DF 0 "register_operand" "") 227352296Sobrien (float_extend:DF (match_operand:SF 1 "register_operand" ""))) 227452296Sobrien (clobber (match_operand:SF 2 "memory_operand" "")) 227552296Sobrien (clobber (match_operand:DF 3 "memory_operand" ""))] 227652296Sobrien "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])" 227752296Sobrien [(set (match_dup 2) 227852296Sobrien (match_dup 1)) 227952296Sobrien (set (match_dup 0) 228052296Sobrien (float_extend:DF (match_dup 2)))] 228152296Sobrien "") 228218334Speter 228352296Sobrien(define_split 228452296Sobrien [(set (match_operand:DF 0 "register_operand" "") 228552296Sobrien (float_extend:DF (match_operand:SF 1 "register_operand" ""))) 228652296Sobrien (clobber (match_operand:SF 2 "memory_operand" "")) 228752296Sobrien (clobber (match_operand:DF 3 "memory_operand" ""))] 228852296Sobrien "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])" 228952296Sobrien [(set (match_dup 3) 229052296Sobrien (float_extend:DF (match_dup 1))) 229152296Sobrien (set (match_dup 0) 229252296Sobrien (match_dup 3))] 229352296Sobrien "") 229418334Speter 229552296Sobrien(define_split 229652296Sobrien [(set (match_operand:DF 0 "nonimmediate_operand" "") 229752296Sobrien (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" ""))) 229852296Sobrien (clobber (match_operand:SF 2 "memory_operand" "")) 229952296Sobrien (clobber (match_operand:DF 3 "memory_operand" ""))] 230052296Sobrien "TARGET_80387 && reload_completed" 230152296Sobrien [(set (match_dup 0) 230252296Sobrien (float_extend:DF (match_dup 1)))] 230352296Sobrien "") 230418334Speter 230552296Sobrien(define_insn "" 230652296Sobrien [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m") 230752296Sobrien (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] 230852296Sobrien "TARGET_80387 && (GET_CODE (operands[0]) != MEM 230952296Sobrien || GET_CODE (operands[1]) != MEM)" 231052296Sobrien "* 231152296Sobrien{ 231252296Sobrien output_float_extend (insn, operands); 231352296Sobrien return \"\"; 231452296Sobrien}" 231552296Sobrien [(set_attr "type" "fld,fpop")]) 231618334Speter 231752296Sobrien(define_expand "extenddfxf2" 231852296Sobrien [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "") 231952296Sobrien (float_extend:XF 232052296Sobrien (match_operand:DF 1 "nonimmediate_operand" ""))) 232152296Sobrien (clobber (match_dup 2)) 232252296Sobrien (clobber (match_dup 3))])] 232352296Sobrien "TARGET_80387" 232452296Sobrien " 232552296Sobrien{ 232652296Sobrien if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 232752296Sobrien operands[1] = force_reg (DFmode, operands[1]); 232852296Sobrien 232952296Sobrien operands[2] = assign_386_stack_local (DFmode, 0); 233052296Sobrien operands[3] = assign_386_stack_local (XFmode, 0); 233118334Speter}") 233218334Speter 233352296Sobrien(define_insn "" 233452296Sobrien [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!f,!*r") 233518334Speter (float_extend:XF 233652296Sobrien (match_operand:DF 1 "nonimmediate_operand" "fm,f,*r,f"))) 233752296Sobrien (clobber (match_operand:DF 2 "memory_operand" "m,m,o,m")) 233852296Sobrien (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))] 233952296Sobrien "TARGET_80387 && (GET_CODE (operands[0]) != MEM 234052296Sobrien || GET_CODE (operands[1]) != MEM)" 234118334Speter "* 234218334Speter{ 234352296Sobrien output_float_extend (insn, operands); 234452296Sobrien return \"\"; 234552296Sobrien}" 234652296Sobrien [(set_attr "type" "fld,fpop,fld,fpop")]) 234718334Speter 234852296Sobrien(define_split 234952296Sobrien [(set (match_operand:XF 0 "register_operand" "") 235052296Sobrien (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 235152296Sobrien (clobber (match_operand:DF 2 "memory_operand" "")) 235252296Sobrien (clobber (match_operand:XF 3 "memory_operand" ""))] 235352296Sobrien "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])" 235452296Sobrien [(set (match_dup 2) 235552296Sobrien (match_dup 1)) 235652296Sobrien (set (match_dup 0) 235752296Sobrien (float_extend:XF (match_dup 2)))] 235852296Sobrien "") 235918334Speter 236052296Sobrien(define_split 236152296Sobrien [(set (match_operand:XF 0 "register_operand" "") 236252296Sobrien (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 236352296Sobrien (clobber (match_operand:DF 2 "memory_operand" "")) 236452296Sobrien (clobber (match_operand:XF 3 "memory_operand" ""))] 236552296Sobrien "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])" 236652296Sobrien [(set (match_dup 3) 236752296Sobrien (float_extend:XF (match_dup 1))) 236852296Sobrien (set (match_dup 0) 236952296Sobrien (match_dup 3))] 237052296Sobrien "") 237118334Speter 237252296Sobrien(define_split 237352296Sobrien [(set (match_operand:XF 0 "nonimmediate_operand" "") 237452296Sobrien (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" ""))) 237552296Sobrien (clobber (match_operand:DF 2 "memory_operand" "")) 237652296Sobrien (clobber (match_operand:XF 3 "memory_operand" ""))] 237752296Sobrien "TARGET_80387 && reload_completed" 237852296Sobrien [(set (match_dup 0) 237952296Sobrien (float_extend:XF (match_dup 1)))] 238052296Sobrien "") 238118334Speter 238252296Sobrien(define_insn "" 238352296Sobrien [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 238452296Sobrien (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))] 238552296Sobrien "TARGET_80387 && (GET_CODE (operands[0]) != MEM 238652296Sobrien || GET_CODE (operands[1]) != MEM)" 238752296Sobrien "* 238852296Sobrien{ 238952296Sobrien output_float_extend (insn, operands); 239052296Sobrien return \"\"; 239152296Sobrien}" 239252296Sobrien [(set_attr "type" "fld,fpop")]) 239318334Speter 239452296Sobrien(define_expand "extendsfxf2" 239552296Sobrien [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "") 239652296Sobrien (float_extend:XF 239752296Sobrien (match_operand:SF 1 "nonimmediate_operand" ""))) 239852296Sobrien (clobber (match_dup 2)) 239952296Sobrien (clobber (match_dup 3))])] 240052296Sobrien "TARGET_80387" 240152296Sobrien " 240252296Sobrien{ 240352296Sobrien if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 240452296Sobrien operands[1] = force_reg (SFmode, operands[1]); 240552296Sobrien 240652296Sobrien operands[2] = assign_386_stack_local (SFmode, 0); 240752296Sobrien operands[3] = assign_386_stack_local (XFmode, 0); 240818334Speter}") 240918334Speter 241052296Sobrien(define_insn "" 241152296Sobrien [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!f,!*r") 241218334Speter (float_extend:XF 241352296Sobrien (match_operand:SF 1 "nonimmediate_operand" "fm,f,*r,f"))) 241452296Sobrien (clobber (match_operand:SF 2 "memory_operand" "m,m,m,m")) 241552296Sobrien (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))] 241652296Sobrien "TARGET_80387 && (GET_CODE (operands[0]) != MEM 241752296Sobrien || GET_CODE (operands[1]) != MEM)" 241818334Speter "* 241918334Speter{ 242052296Sobrien output_float_extend (insn, operands); 242152296Sobrien return \"\"; 242252296Sobrien}" 242352296Sobrien [(set_attr "type" "fld,fpop,fld,fpop")]) 242418334Speter 242552296Sobrien(define_split 242652296Sobrien [(set (match_operand:XF 0 "register_operand" "") 242752296Sobrien (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 242852296Sobrien (clobber (match_operand:SF 2 "memory_operand" "")) 242952296Sobrien (clobber (match_operand:XF 3 "memory_operand" ""))] 243052296Sobrien "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])" 243152296Sobrien [(set (match_dup 2) 243252296Sobrien (match_dup 1)) 243352296Sobrien (set (match_dup 0) 243452296Sobrien (float_extend:XF (match_dup 2)))] 243552296Sobrien "") 243618334Speter 243752296Sobrien(define_split 243852296Sobrien [(set (match_operand:XF 0 "register_operand" "") 243952296Sobrien (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 244052296Sobrien (clobber (match_operand:SF 2 "memory_operand" "")) 244152296Sobrien (clobber (match_operand:XF 3 "memory_operand" ""))] 244252296Sobrien "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])" 244352296Sobrien [(set (match_dup 3) 244452296Sobrien (float_extend:XF (match_dup 1))) 244552296Sobrien (set (match_dup 0) 244652296Sobrien (match_dup 3))] 244752296Sobrien "") 244818334Speter 244952296Sobrien(define_split 245052296Sobrien [(set (match_operand:XF 0 "nonimmediate_operand" "") 245152296Sobrien (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" ""))) 245252296Sobrien (clobber (match_operand:SF 2 "memory_operand" "")) 245352296Sobrien (clobber (match_operand:XF 3 "memory_operand" ""))] 245452296Sobrien "TARGET_80387 && reload_completed" 245552296Sobrien [(set (match_dup 0) 245652296Sobrien (float_extend:XF (match_dup 1)))] 245752296Sobrien "") 245818334Speter 245952296Sobrien(define_insn "" 246052296Sobrien [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 246152296Sobrien (float_extend:XF 246252296Sobrien (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] 246352296Sobrien "TARGET_80387 && (GET_CODE (operands[0]) != MEM 246452296Sobrien || GET_CODE (operands[1]) != MEM)" 246552296Sobrien "* 246652296Sobrien{ 246752296Sobrien output_float_extend (insn, operands); 246852296Sobrien return \"\"; 246952296Sobrien}" 247052296Sobrien [(set_attr "type" "fld,fpop")]) 247118334Speter 247218334Speter(define_expand "truncdfsf2" 247318334Speter [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") 247418334Speter (float_truncate:SF 247518334Speter (match_operand:DF 1 "register_operand" ""))) 247618334Speter (clobber (match_dup 2))])] 247718334Speter "TARGET_80387" 247818334Speter " 247918334Speter{ 248018334Speter operands[2] = (rtx) assign_386_stack_local (SFmode, 0); 248118334Speter}") 248218334Speter 248318334Speter(define_insn "" 248452296Sobrien [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r") 248518334Speter (float_truncate:SF 248652296Sobrien (match_operand:DF 1 "register_operand" "0,f,f"))) 248752296Sobrien (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))] 248818334Speter "TARGET_80387" 248918334Speter "* 249018334Speter{ 249118334Speter int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; 249252296Sobrien rtx xops[1]; 249318334Speter 249452296Sobrien xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2]; 249552296Sobrien 249652296Sobrien if (stack_top_dies || STACK_REG_P (operands[0])) 249752296Sobrien output_asm_insn (AS1 (fstp%z0,%0), xops); 249818334Speter else 249952296Sobrien output_asm_insn (AS1 (fst%z0,%0), xops); 250018334Speter 250152296Sobrien if (STACK_REG_P (operands[0])) 250252296Sobrien return AS1 (fld%z2,%2); 250352296Sobrien else if (NON_STACK_REG_P (operands[0])) 250452296Sobrien return AS2 (mov%L0,%2,%0); 250552296Sobrien 250652296Sobrien return \"\"; 250752296Sobrien}" 250852296Sobrien [(set_attr "type" "fpop")]) 250952296Sobrien 251052296Sobrien(define_split 251152296Sobrien [(set (match_operand:SF 0 "register_operand" "") 251252296Sobrien (float_truncate:SF (match_operand:DF 1 "register_operand" ""))) 251352296Sobrien (clobber (match_operand:SF 2 "memory_operand" ""))] 251452296Sobrien "TARGET_80387 && reload_completed" 251552296Sobrien [(set (match_dup 2) 251652296Sobrien (float_truncate:SF (match_dup 1))) 251752296Sobrien (set (match_dup 0) 251852296Sobrien (match_dup 2))] 251952296Sobrien "") 252052296Sobrien 252152296Sobrien(define_split 252252296Sobrien [(set (match_operand:SF 0 "memory_operand" "") 252352296Sobrien (float_truncate:SF (match_operand:DF 1 "register_operand" ""))) 252452296Sobrien (clobber (match_operand:SF 2 "memory_operand" ""))] 252552296Sobrien "TARGET_80387 && reload_completed" 252652296Sobrien [(set (match_dup 0) 252752296Sobrien (float_truncate:SF (match_dup 1)))] 252852296Sobrien "") 252952296Sobrien 253052296Sobrien;; This cannot output into an f-reg because there is no way to be sure 253152296Sobrien;; of truncating in that case. 253252296Sobrien 253352296Sobrien(define_insn "" 253452296Sobrien [(set (match_operand:SF 0 "memory_operand" "=m") 253552296Sobrien (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))] 253618334Speter "TARGET_80387" 253718334Speter "* 253818334Speter{ 253918334Speter int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; 254018334Speter 254152296Sobrien if (stack_top_dies) 254252296Sobrien return AS1 (fstp%z0,%0); 254318334Speter else 254452296Sobrien return AS1 (fst%z0,%0); 254552296Sobrien}" 254652296Sobrien [(set_attr "type" "fpop")]) 254752296Sobrien 254852296Sobrien(define_expand "truncxfsf2" 254952296Sobrien [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") 255052296Sobrien (float_truncate:SF 255152296Sobrien (match_operand:XF 1 "register_operand" ""))) 255252296Sobrien (clobber (match_dup 2))])] 255352296Sobrien "TARGET_80387" 255452296Sobrien " 255552296Sobrien{ 255652296Sobrien operands[2] = (rtx) assign_386_stack_local (SFmode, 0); 255718334Speter}") 255818334Speter 255952296Sobrien(define_insn "" 256052296Sobrien [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r") 256152296Sobrien (float_truncate:SF 256252296Sobrien (match_operand:XF 1 "register_operand" "0,f,f"))) 256352296Sobrien (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))] 256418334Speter "TARGET_80387" 256518334Speter "* 256618334Speter{ 256718334Speter int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; 256852296Sobrien rtx xops[1]; 256918334Speter 257052296Sobrien xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2]; 257152296Sobrien 257252296Sobrien if (stack_top_dies || STACK_REG_P (operands[0])) 257352296Sobrien output_asm_insn (AS1 (fstp%z0,%0), xops); 257418334Speter else 257552296Sobrien output_asm_insn (AS1 (fst%z0,%0), xops); 257618334Speter 257752296Sobrien if (STACK_REG_P (operands[0])) 257852296Sobrien return AS1 (fld%z2,%2); 257952296Sobrien else if (NON_STACK_REG_P (operands[0])) 258052296Sobrien return AS2 (mov%L0,%2,%0); 258118334Speter 258252296Sobrien return \"\"; 258352296Sobrien}" 258452296Sobrien [(set_attr "type" "fpop")]) 258518334Speter 258652296Sobrien(define_split 258752296Sobrien [(set (match_operand:SF 0 "register_operand" "") 258852296Sobrien (float_truncate:SF (match_operand:XF 1 "register_operand" ""))) 258952296Sobrien (clobber (match_operand:SF 2 "memory_operand" ""))] 259052296Sobrien "TARGET_80387 && reload_completed" 259152296Sobrien [(set (match_dup 2) 259252296Sobrien (float_truncate:SF (match_dup 1))) 259352296Sobrien (set (match_dup 0) 259452296Sobrien (match_dup 2))] 259552296Sobrien "") 259652296Sobrien 259752296Sobrien(define_split 259852296Sobrien [(set (match_operand:SF 0 "memory_operand" "") 259952296Sobrien (float_truncate:SF (match_operand:XF 1 "register_operand" ""))) 260052296Sobrien (clobber (match_operand:SF 2 "memory_operand" ""))] 260152296Sobrien "TARGET_80387 && reload_completed" 260252296Sobrien [(set (match_dup 0) 260352296Sobrien (float_truncate:SF (match_dup 1)))] 260452296Sobrien "") 260552296Sobrien 260652296Sobrien(define_insn "" 260752296Sobrien [(set (match_operand:SF 0 "memory_operand" "=m") 260852296Sobrien (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))] 260918334Speter "TARGET_80387" 261052296Sobrien "* 261118334Speter{ 261252296Sobrien int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; 261318334Speter 261452296Sobrien if (stack_top_dies) 261552296Sobrien return AS1 (fstp%z0,%0); 261652296Sobrien else 261752296Sobrien return AS1 (fst%z0,%0); 261852296Sobrien}" 261952296Sobrien [(set_attr "type" "fpop")]) 262052296Sobrien 262152296Sobrien(define_expand "truncxfdf2" 262252296Sobrien [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "") 262352296Sobrien (float_truncate:DF 262452296Sobrien (match_operand:XF 1 "register_operand" ""))) 262552296Sobrien (clobber (match_dup 2))])] 262618334Speter "TARGET_80387" 262718334Speter " 262818334Speter{ 262952296Sobrien operands[2] = (rtx) assign_386_stack_local (DFmode, 0); 263018334Speter}") 263118334Speter 263252296Sobrien(define_insn "" 263352296Sobrien [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r") 263452296Sobrien (float_truncate:DF 263552296Sobrien (match_operand:XF 1 "register_operand" "0,f,f"))) 263652296Sobrien (clobber (match_operand:DF 2 "memory_operand" "m,m,o"))] 263718334Speter "TARGET_80387" 263852296Sobrien "* 263918334Speter{ 264052296Sobrien int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; 264152296Sobrien rtx xops[2]; 264218334Speter 264352296Sobrien xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2]; 264418334Speter 264552296Sobrien if (stack_top_dies || STACK_REG_P (operands[0])) 264652296Sobrien output_asm_insn (AS1 (fstp%z0,%0), xops); 264752296Sobrien else 264852296Sobrien output_asm_insn (AS1 (fst%z0,%0), xops); 264952296Sobrien 265052296Sobrien if (STACK_REG_P (operands[0])) 265152296Sobrien return AS1 (fld%z2,%2); 265252296Sobrien else if (NON_STACK_REG_P (operands[0])) 265352296Sobrien { 265452296Sobrien xops[0] = operands[0]; 265552296Sobrien xops[1] = operands[2]; 265652296Sobrien output_asm_insn (output_move_double (xops), xops); 265752296Sobrien } 265852296Sobrien 265952296Sobrien return \"\"; 266052296Sobrien}" 266152296Sobrien [(set_attr "type" "fpop")]) 266252296Sobrien 266352296Sobrien(define_split 266452296Sobrien [(set (match_operand:DF 0 "register_operand" "") 266552296Sobrien (float_truncate:DF (match_operand:XF 1 "register_operand" ""))) 266652296Sobrien (clobber (match_operand:DF 2 "memory_operand" ""))] 266752296Sobrien "TARGET_80387 && reload_completed" 266818334Speter [(set (match_dup 2) 266952296Sobrien (float_truncate:DF (match_dup 1))) 267052296Sobrien (set (match_dup 0) 267152296Sobrien (match_dup 2))] 267252296Sobrien "") 267352296Sobrien 267452296Sobrien(define_split 267552296Sobrien [(set (match_operand:DF 0 "memory_operand" "") 267652296Sobrien (float_truncate:DF (match_operand:XF 1 "register_operand" ""))) 267752296Sobrien (clobber (match_operand:DF 2 "memory_operand" ""))] 267852296Sobrien "TARGET_80387 && reload_completed" 267952296Sobrien [(set (match_dup 0) 268052296Sobrien (float_truncate:DF (match_dup 1)))] 268152296Sobrien "") 268252296Sobrien 268352296Sobrien(define_insn "" 268452296Sobrien [(set (match_operand:DF 0 "memory_operand" "=m") 268552296Sobrien (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))] 268618334Speter "TARGET_80387" 268752296Sobrien "* 268818334Speter{ 268952296Sobrien int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; 269018334Speter 269152296Sobrien if (stack_top_dies) 269252296Sobrien return AS1 (fstp%z0,%0); 269352296Sobrien else 269452296Sobrien return AS1 (fst%z0,%0); 269552296Sobrien}" 269652296Sobrien [(set_attr "type" "fpop")]) 269752296Sobrien 269852296Sobrien;; Conversions between floating point and fix point. 269952296Sobrien 270052296Sobrien(define_expand "fix_truncsfsi2" 270152296Sobrien [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 270252296Sobrien (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "")))) 270318334Speter (clobber (match_dup 2)) 270418334Speter (clobber (match_dup 3)) 270518334Speter (clobber (match_dup 4)) 270652296Sobrien (clobber (match_scratch:HI 5 ""))])] 270718334Speter "TARGET_80387" 270818334Speter " 270918334Speter{ 271052296Sobrien operands[2] = (rtx) assign_386_stack_local (HImode, 0); 271152296Sobrien operands[3] = (rtx) assign_386_stack_local (HImode, 1); 271252296Sobrien operands[4] = (rtx) assign_386_stack_local (SImode, 0); 271318334Speter}") 271418334Speter 271552296Sobrien(define_insn "" 271653176Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!&r") 271752296Sobrien (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f,f")))) 271852296Sobrien (clobber (match_operand:HI 2 "memory_operand" "m,m")) 271952296Sobrien (clobber (match_operand:HI 3 "memory_operand" "m,m")) 272052296Sobrien (clobber (match_operand:SI 4 "memory_operand" "m,m")) 272152296Sobrien (clobber (match_scratch:HI 5 "=&r,&r"))] 272252296Sobrien "TARGET_80387" 272352296Sobrien "* return output_fix_trunc (insn, operands);" 272452296Sobrien [(set_attr "type" "fpop")]) 272552296Sobrien 272618334Speter(define_expand "fix_truncsfdi2" 272752296Sobrien [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 272852296Sobrien (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "")))) 272952296Sobrien (clobber (match_dup 1)) 273018334Speter (clobber (match_dup 2)) 273118334Speter (clobber (match_dup 3)) 273218334Speter (clobber (match_dup 4)) 273352296Sobrien (clobber (match_scratch:HI 5 ""))])] 273418334Speter "TARGET_80387" 273518334Speter " 273618334Speter{ 273718334Speter operands[1] = copy_to_mode_reg (SFmode, operands[1]); 273852296Sobrien operands[2] = (rtx) assign_386_stack_local (HImode, 0); 273952296Sobrien operands[3] = (rtx) assign_386_stack_local (HImode, 1); 274052296Sobrien operands[4] = (rtx) assign_386_stack_local (DImode, 0); 274118334Speter}") 274218334Speter 274318334Speter(define_insn "" 274453176Sobrien [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!&r") 274552296Sobrien (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f,f")))) 274618334Speter (clobber (match_dup 1)) 274752296Sobrien (clobber (match_operand:HI 2 "memory_operand" "m,m")) 274852296Sobrien (clobber (match_operand:HI 3 "memory_operand" "m,m")) 274952296Sobrien (clobber (match_operand:DI 4 "memory_operand" "m,o")) 275052296Sobrien (clobber (match_scratch:HI 5 "=&r,&r"))] 275118334Speter "TARGET_80387" 275252296Sobrien "* return output_fix_trunc (insn, operands);" 275352296Sobrien [(set_attr "type" "fpop")]) 275418334Speter 275552296Sobrien(define_expand "fix_truncdfsi2" 275652296Sobrien [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 275752296Sobrien (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "")))) 275852296Sobrien (clobber (match_dup 2)) 275952296Sobrien (clobber (match_dup 3)) 276052296Sobrien (clobber (match_dup 4)) 276152296Sobrien (clobber (match_scratch:HI 5 ""))])] 276218334Speter "TARGET_80387" 276352296Sobrien " 276452296Sobrien{ 276552296Sobrien operands[2] = (rtx) assign_386_stack_local (HImode, 0); 276652296Sobrien operands[3] = (rtx) assign_386_stack_local (HImode, 1); 276752296Sobrien operands[4] = (rtx) assign_386_stack_local (SImode, 0); 276852296Sobrien}") 276918334Speter 277018334Speter(define_insn "" 277153176Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!&r") 277252296Sobrien (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f,f")))) 277352296Sobrien (clobber (match_operand:HI 2 "memory_operand" "m,m")) 277452296Sobrien (clobber (match_operand:HI 3 "memory_operand" "m,m")) 277552296Sobrien (clobber (match_operand:SI 4 "memory_operand" "m,m")) 277652296Sobrien (clobber (match_scratch:HI 5 "=&r,&r"))] 277718334Speter "TARGET_80387" 277852296Sobrien "* return output_fix_trunc (insn, operands);" 277952296Sobrien [(set_attr "type" "fpop")]) 278018334Speter 278152296Sobrien(define_expand "fix_truncdfdi2" 278252296Sobrien [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 278352296Sobrien (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "")))) 278452296Sobrien (clobber (match_dup 1)) 278518334Speter (clobber (match_dup 2)) 278618334Speter (clobber (match_dup 3)) 278752296Sobrien (clobber (match_dup 4)) 278852296Sobrien (clobber (match_scratch:HI 5 ""))])] 278918334Speter "TARGET_80387" 279018334Speter " 279118334Speter{ 279252296Sobrien operands[1] = copy_to_mode_reg (DFmode, operands[1]); 279352296Sobrien operands[2] = (rtx) assign_386_stack_local (HImode, 0); 279452296Sobrien operands[3] = (rtx) assign_386_stack_local (HImode, 1); 279552296Sobrien operands[4] = (rtx) assign_386_stack_local (DImode, 0); 279618334Speter}") 279718334Speter 279852296Sobrien(define_insn "" 279953176Sobrien [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!&r") 280052296Sobrien (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f,f")))) 280152296Sobrien (clobber (match_dup 1)) 280252296Sobrien (clobber (match_operand:HI 2 "memory_operand" "m,m")) 280352296Sobrien (clobber (match_operand:HI 3 "memory_operand" "m,m")) 280452296Sobrien (clobber (match_operand:DI 4 "memory_operand" "m,o")) 280552296Sobrien (clobber (match_scratch:HI 5 "=&r,&r"))] 280652296Sobrien "TARGET_80387" 280752296Sobrien "* return output_fix_trunc (insn, operands);" 280852296Sobrien [(set_attr "type" "fpop")]) 280952296Sobrien 281052296Sobrien(define_expand "fix_truncxfsi2" 281152296Sobrien [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 281252296Sobrien (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "")))) 281318334Speter (clobber (match_dup 2)) 281418334Speter (clobber (match_dup 3)) 281552296Sobrien (clobber (match_dup 4)) 281652296Sobrien (clobber (match_scratch:HI 5 ""))])] 281718334Speter "TARGET_80387" 281818334Speter " 281918334Speter{ 282052296Sobrien operands[2] = (rtx) assign_386_stack_local (HImode, 0); 282152296Sobrien operands[3] = (rtx) assign_386_stack_local (HImode, 1); 282252296Sobrien operands[4] = (rtx) assign_386_stack_local (SImode, 0); 282318334Speter}") 282418334Speter 282552296Sobrien(define_insn "" 282653176Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!&r") 282752296Sobrien (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f,f")))) 282852296Sobrien (clobber (match_operand:HI 2 "memory_operand" "m,m")) 282952296Sobrien (clobber (match_operand:HI 3 "memory_operand" "m,m")) 283052296Sobrien (clobber (match_operand:SI 4 "memory_operand" "m,m")) 283152296Sobrien (clobber (match_scratch:HI 5 "=&r,&r"))] 283252296Sobrien "TARGET_80387" 283352296Sobrien "* return output_fix_trunc (insn, operands);" 283452296Sobrien [(set_attr "type" "fpop")]) 283552296Sobrien 283652296Sobrien(define_expand "fix_truncxfdi2" 283752296Sobrien [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 283852296Sobrien (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "")))) 283952296Sobrien (clobber (match_dup 1)) 284018334Speter (clobber (match_dup 2)) 284118334Speter (clobber (match_dup 3)) 284252296Sobrien (clobber (match_dup 4)) 284352296Sobrien (clobber (match_scratch:HI 5 ""))])] 284418334Speter "TARGET_80387" 284518334Speter " 284618334Speter{ 284752296Sobrien operands[1] = copy_to_mode_reg (XFmode, operands[1]); 284852296Sobrien operands[2] = (rtx) assign_386_stack_local (HImode, 0); 284952296Sobrien operands[3] = (rtx) assign_386_stack_local (HImode, 1); 285052296Sobrien operands[4] = (rtx) assign_386_stack_local (DImode, 0); 285118334Speter}") 285218334Speter 285318334Speter(define_insn "" 285453176Sobrien [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!&r") 285552296Sobrien (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f,f")))) 285652296Sobrien (clobber (match_dup 1)) 285752296Sobrien (clobber (match_operand:HI 2 "memory_operand" "m,m")) 285852296Sobrien (clobber (match_operand:HI 3 "memory_operand" "m,m")) 285952296Sobrien (clobber (match_operand:DI 4 "memory_operand" "m,o")) 286052296Sobrien (clobber (match_scratch:HI 5 "=&r,&r"))] 286118334Speter "TARGET_80387" 286252296Sobrien "* return output_fix_trunc (insn, operands);" 286352296Sobrien [(set_attr "type" "fpop")]) 286452296Sobrien 286552296Sobrien;; Conversion between fixed point and floating point. 286618334Speter 286752296Sobrien;; ??? Possibly represent floatunssidf2 here in gcc2. 286852296Sobrien 286952296Sobrien(define_expand "floatsisf2" 287052296Sobrien [(parallel [(set (match_operand:SF 0 "register_operand" "") 287152296Sobrien (float:SF (match_operand:SI 1 "nonimmediate_operand" ""))) 287252296Sobrien (clobber (match_dup 2))])] 287352296Sobrien "TARGET_80387" 287452296Sobrien "operands[2] = assign_386_stack_local (SImode, 0);") 287552296Sobrien 287618334Speter(define_insn "" 287752296Sobrien [(set (match_operand:SF 0 "register_operand" "=f,f") 287852296Sobrien (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,!r"))) 287952296Sobrien (clobber (match_operand:SI 2 "memory_operand" "m,m"))] 288018334Speter "TARGET_80387" 288152296Sobrien "#") 288218334Speter 288352296Sobrien(define_split 288452296Sobrien [(set (match_operand:SF 0 "register_operand" "") 288552296Sobrien (float:SF (match_operand:SI 1 "memory_operand" ""))) 288652296Sobrien (clobber (match_operand:SI 2 "memory_operand" ""))] 288752296Sobrien "TARGET_80387 && reload_completed" 288852296Sobrien [(set (match_dup 0) 288952296Sobrien (float:SF (match_dup 1)))] 289052296Sobrien "") 289152296Sobrien 289252296Sobrien(define_split 289352296Sobrien [(set (match_operand:SF 0 "register_operand" "") 289452296Sobrien (float:SF (match_operand:SI 1 "register_operand" ""))) 289552296Sobrien (clobber (match_operand:SI 2 "memory_operand" ""))] 289652296Sobrien "TARGET_80387 && reload_completed" 289752296Sobrien [(set (match_dup 2) 289852296Sobrien (match_dup 1)) 289952296Sobrien (set (match_dup 0) 290052296Sobrien (float:SF (match_dup 2)))] 290152296Sobrien "") 290252296Sobrien 290318334Speter(define_insn "" 290452296Sobrien [(set (match_operand:SF 0 "register_operand" "=f") 290552296Sobrien (float:SF (match_operand:SI 1 "memory_operand" "m")))] 290618334Speter "TARGET_80387" 290752296Sobrien "* return AS1 (fild%z1,%1);" 290852296Sobrien [(set_attr "type" "fpop")]) 290918334Speter 291052296Sobrien(define_expand "floathisf2" 291152296Sobrien [(parallel [(set (match_operand:SF 0 "register_operand" "") 291252296Sobrien (float:SF (match_operand:HI 1 "nonimmediate_operand" ""))) 291352296Sobrien (clobber (match_dup 2))])] 291452296Sobrien "TARGET_80387" 291552296Sobrien "operands[2] = assign_386_stack_local (HImode, 0);") 291618334Speter 291752296Sobrien(define_insn "" 291852296Sobrien [(set (match_operand:SF 0 "register_operand" "=f,f") 291952296Sobrien (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,!r"))) 292052296Sobrien (clobber (match_operand:HI 2 "memory_operand" "m,m"))] 292152296Sobrien "TARGET_80387" 292252296Sobrien "#") 292352296Sobrien 292452296Sobrien(define_split 292518334Speter [(set (match_operand:SF 0 "register_operand" "") 292652296Sobrien (float:SF (match_operand:HI 1 "memory_operand" ""))) 292752296Sobrien (clobber (match_operand:HI 2 "memory_operand" ""))] 292852296Sobrien "TARGET_80387 && reload_completed" 292952296Sobrien [(set (match_dup 0) 293052296Sobrien (float:SF (match_dup 1)))] 293118334Speter "") 293218334Speter 293352296Sobrien(define_split 293452296Sobrien [(set (match_operand:SF 0 "register_operand" "") 293552296Sobrien (float:SF (match_operand:HI 1 "register_operand" ""))) 293652296Sobrien (clobber (match_operand:HI 2 "memory_operand" ""))] 293752296Sobrien "TARGET_80387 && reload_completed" 293852296Sobrien [(set (match_dup 2) 293952296Sobrien (match_dup 1)) 294052296Sobrien (set (match_dup 0) 294152296Sobrien (float:SF (match_dup 2)))] 294252296Sobrien "") 294352296Sobrien 294452296Sobrien(define_insn "" 294552296Sobrien [(set (match_operand:SF 0 "register_operand" "=f") 294652296Sobrien (float:SF (match_operand:HI 1 "memory_operand" "m")))] 294752296Sobrien "TARGET_80387" 294852296Sobrien "* return AS1 (fild%z1,%1);" 294952296Sobrien [(set_attr "type" "fpop")]) 295052296Sobrien 295118334Speter(define_expand "floatdisf2" 295252296Sobrien [(parallel [(set (match_operand:SF 0 "register_operand" "") 295352296Sobrien (float:SF (match_operand:DI 1 "nonimmediate_operand" ""))) 295452296Sobrien (clobber (match_dup 2))])] 295552296Sobrien "TARGET_80387" 295652296Sobrien "operands[2] = assign_386_stack_local (DImode, 0);") 295752296Sobrien 295852296Sobrien(define_insn "" 295952296Sobrien [(set (match_operand:SF 0 "register_operand" "=f,f") 296052296Sobrien (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,!r"))) 296152296Sobrien (clobber (match_operand:DI 2 "memory_operand" "m,o"))] 296252296Sobrien "TARGET_80387" 296352296Sobrien "#") 296452296Sobrien 296552296Sobrien(define_split 296618334Speter [(set (match_operand:SF 0 "register_operand" "") 296752296Sobrien (float:SF (match_operand:DI 1 "memory_operand" ""))) 296852296Sobrien (clobber (match_operand:DI 2 "memory_operand" ""))] 296952296Sobrien "TARGET_80387 && reload_completed" 297052296Sobrien [(set (match_dup 0) 297152296Sobrien (float:SF (match_dup 1)))] 297218334Speter "") 297318334Speter 297452296Sobrien(define_split 297552296Sobrien [(set (match_operand:SF 0 "register_operand" "") 297652296Sobrien (float:SF (match_operand:DI 1 "register_operand" ""))) 297752296Sobrien (clobber (match_operand:DI 2 "memory_operand" ""))] 297852296Sobrien "TARGET_80387 && reload_completed" 297952296Sobrien [(set (match_dup 2) 298052296Sobrien (match_dup 1)) 298152296Sobrien (set (match_dup 0) 298252296Sobrien (float:SF (match_dup 2)))] 298352296Sobrien "") 298452296Sobrien 298552296Sobrien(define_insn "" 298652296Sobrien [(set (match_operand:SF 0 "register_operand" "=f") 298752296Sobrien (float:SF (match_operand:DI 1 "memory_operand" "m")))] 298852296Sobrien "TARGET_80387" 298952296Sobrien "* return AS1 (fild%z1,%1);" 299052296Sobrien [(set_attr "type" "fpop")]) 299152296Sobrien 299218334Speter(define_expand "floatsidf2" 299352296Sobrien [(parallel [(set (match_operand:DF 0 "register_operand" "") 299452296Sobrien (float:DF (match_operand:SI 1 "nonimmediate_operand" ""))) 299552296Sobrien (clobber (match_dup 2))])] 299652296Sobrien "TARGET_80387" 299752296Sobrien "operands[2] = assign_386_stack_local (SImode, 0);") 299852296Sobrien 299952296Sobrien(define_insn "" 300052296Sobrien [(set (match_operand:DF 0 "register_operand" "=f,f") 300152296Sobrien (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,!r"))) 300252296Sobrien (clobber (match_operand:SI 2 "memory_operand" "m,m"))] 300352296Sobrien "TARGET_80387" 300452296Sobrien "#") 300552296Sobrien 300652296Sobrien(define_split 300718334Speter [(set (match_operand:DF 0 "register_operand" "") 300852296Sobrien (float:DF (match_operand:SI 1 "memory_operand" ""))) 300952296Sobrien (clobber (match_operand:SI 2 "memory_operand" ""))] 301052296Sobrien "TARGET_80387 && reload_completed" 301152296Sobrien [(set (match_dup 0) 301252296Sobrien (float:DF (match_dup 1)))] 301352296Sobrien "") 301452296Sobrien 301552296Sobrien(define_split 301652296Sobrien [(set (match_operand:DF 0 "register_operand" "") 301752296Sobrien (float:DF (match_operand:SI 1 "register_operand" ""))) 301852296Sobrien (clobber (match_operand:SI 2 "memory_operand" ""))] 301952296Sobrien "TARGET_80387 && reload_completed" 302052296Sobrien [(set (match_dup 2) 302152296Sobrien (match_dup 1)) 302252296Sobrien (set (match_dup 0) 302352296Sobrien (float:DF (match_dup 2)))] 302452296Sobrien "") 302552296Sobrien 302652296Sobrien(define_insn "" 302752296Sobrien [(set (match_operand:DF 0 "register_operand" "=f") 302852296Sobrien (float:DF (match_operand:SI 1 "memory_operand" "m")))] 302918334Speter "TARGET_80387" 303052296Sobrien "* return AS1 (fild%z1,%1);" 303152296Sobrien [(set_attr "type" "fpop")]) 303252296Sobrien 303352296Sobrien(define_expand "floathidf2" 303452296Sobrien [(parallel [(set (match_operand:DF 0 "register_operand" "") 303552296Sobrien (float:DF (match_operand:HI 1 "nonimmediate_operand" ""))) 303652296Sobrien (clobber (match_dup 2))])] 303752296Sobrien "TARGET_80387" 303852296Sobrien "operands[2] = assign_386_stack_local (HImode, 0);") 303952296Sobrien 304052296Sobrien(define_insn "" 304152296Sobrien [(set (match_operand:DF 0 "register_operand" "=f,f") 304252296Sobrien (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,!r"))) 304352296Sobrien (clobber (match_operand:HI 2 "memory_operand" "m,m"))] 304452296Sobrien "TARGET_80387" 304552296Sobrien "#") 304652296Sobrien 304752296Sobrien(define_split 304852296Sobrien [(set (match_operand:DF 0 "register_operand" "") 304952296Sobrien (float:DF (match_operand:HI 1 "memory_operand" ""))) 305052296Sobrien (clobber (match_operand:HI 2 "memory_operand" ""))] 305152296Sobrien "TARGET_80387 && reload_completed" 305252296Sobrien [(set (match_dup 0) 305352296Sobrien (float:DF (match_dup 1)))] 305418334Speter "") 305518334Speter 305652296Sobrien(define_split 305752296Sobrien [(set (match_operand:DF 0 "register_operand" "") 305852296Sobrien (float:DF (match_operand:HI 1 "register_operand" ""))) 305952296Sobrien (clobber (match_operand:HI 2 "memory_operand" ""))] 306052296Sobrien "TARGET_80387 && reload_completed" 306152296Sobrien [(set (match_dup 2) 306252296Sobrien (match_dup 1)) 306352296Sobrien (set (match_dup 0) 306452296Sobrien (float:DF (match_dup 2)))] 306552296Sobrien "") 306652296Sobrien 306752296Sobrien(define_insn "" 306852296Sobrien [(set (match_operand:DF 0 "register_operand" "=f") 306952296Sobrien (float:DF (match_operand:HI 1 "memory_operand" "m")))] 307052296Sobrien "TARGET_80387" 307152296Sobrien "* return AS1 (fild%z1,%1);" 307252296Sobrien [(set_attr "type" "fpop")]) 307352296Sobrien 307418334Speter(define_expand "floatdidf2" 307552296Sobrien [(parallel [(set (match_operand:DF 0 "register_operand" "") 307652296Sobrien (float:DF (match_operand:DI 1 "nonimmediate_operand" ""))) 307752296Sobrien (clobber (match_dup 2))])] 307852296Sobrien "TARGET_80387" 307952296Sobrien "operands[2] = assign_386_stack_local (DImode, 0);") 308052296Sobrien 308152296Sobrien(define_insn "" 308252296Sobrien [(set (match_operand:DF 0 "register_operand" "=f,f") 308352296Sobrien (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,!r"))) 308452296Sobrien (clobber (match_operand:DI 2 "memory_operand" "m,o"))] 308552296Sobrien "TARGET_80387" 308652296Sobrien "#") 308752296Sobrien 308852296Sobrien(define_split 308918334Speter [(set (match_operand:DF 0 "register_operand" "") 309052296Sobrien (float:DF (match_operand:DI 1 "memory_operand" ""))) 309152296Sobrien (clobber (match_operand:DI 2 "memory_operand" ""))] 309252296Sobrien "TARGET_80387 && reload_completed" 309352296Sobrien [(set (match_dup 0) 309452296Sobrien (float:DF (match_dup 1)))] 309518334Speter "") 309618334Speter 309752296Sobrien(define_split 309852296Sobrien [(set (match_operand:DF 0 "register_operand" "") 309952296Sobrien (float:DF (match_operand:DI 1 "register_operand" ""))) 310052296Sobrien (clobber (match_operand:DI 2 "memory_operand" ""))] 310152296Sobrien "TARGET_80387 && reload_completed" 310252296Sobrien [(set (match_dup 2) 310352296Sobrien (match_dup 1)) 310452296Sobrien (set (match_dup 0) 310552296Sobrien (float:DF (match_dup 2)))] 310652296Sobrien "") 310752296Sobrien 310852296Sobrien(define_insn "" 310952296Sobrien [(set (match_operand:DF 0 "register_operand" "=f") 311052296Sobrien (float:DF (match_operand:DI 1 "memory_operand" "m")))] 311152296Sobrien "TARGET_80387" 311252296Sobrien "* return AS1 (fild%z1,%1);" 311352296Sobrien [(set_attr "type" "fpop")]) 311452296Sobrien 311518334Speter(define_expand "floatsixf2" 311652296Sobrien [(parallel [(set (match_operand:XF 0 "register_operand" "") 311752296Sobrien (float:XF (match_operand:SI 1 "nonimmediate_operand" ""))) 311852296Sobrien (clobber (match_dup 2))])] 311952296Sobrien "TARGET_80387" 312052296Sobrien "operands[2] = assign_386_stack_local (SImode, 0);") 312152296Sobrien 312252296Sobrien(define_insn "" 312352296Sobrien [(set (match_operand:XF 0 "register_operand" "=f,f") 312452296Sobrien (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!r"))) 312552296Sobrien (clobber (match_operand:SI 2 "memory_operand" "m,m"))] 312652296Sobrien "TARGET_80387" 312752296Sobrien "#") 312852296Sobrien 312952296Sobrien(define_split 313018334Speter [(set (match_operand:XF 0 "register_operand" "") 313152296Sobrien (float:XF (match_operand:SI 1 "memory_operand" ""))) 313252296Sobrien (clobber (match_operand:SI 2 "memory_operand" ""))] 313352296Sobrien "TARGET_80387 && reload_completed" 313452296Sobrien [(set (match_dup 0) 313552296Sobrien (float:XF (match_dup 1)))] 313618334Speter "") 313718334Speter 313852296Sobrien(define_split 313918334Speter [(set (match_operand:XF 0 "register_operand" "") 314052296Sobrien (float:XF (match_operand:SI 1 "register_operand" ""))) 314152296Sobrien (clobber (match_operand:SI 2 "memory_operand" ""))] 314252296Sobrien "TARGET_80387 && reload_completed" 314352296Sobrien [(set (match_dup 2) 314452296Sobrien (match_dup 1)) 314552296Sobrien (set (match_dup 0) 314652296Sobrien (float:XF (match_dup 2)))] 314718334Speter "") 314818334Speter 314918334Speter(define_insn "" 315018334Speter [(set (match_operand:XF 0 "register_operand" "=f") 315152296Sobrien (float:XF (match_operand:SI 1 "memory_operand" "m")))] 315218334Speter "TARGET_80387" 315352296Sobrien "* return AS1 (fild%z1,%1);" 315452296Sobrien [(set_attr "type" "fpop")]) 315518334Speter 315652296Sobrien(define_expand "floathixf2" 315752296Sobrien [(parallel [(set (match_operand:XF 0 "register_operand" "") 315852296Sobrien (float:XF (match_operand:HI 1 "nonimmediate_operand" ""))) 315952296Sobrien (clobber (match_dup 2))])] 316018334Speter "TARGET_80387" 316152296Sobrien "operands[2] = assign_386_stack_local (HImode, 0);") 316218334Speter 316318334Speter(define_insn "" 316452296Sobrien [(set (match_operand:XF 0 "register_operand" "=f,f") 316552296Sobrien (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,!r"))) 316652296Sobrien (clobber (match_operand:HI 2 "memory_operand" "m,m"))] 316718334Speter "TARGET_80387" 316852296Sobrien "#") 316918334Speter 317052296Sobrien(define_split 317152296Sobrien [(set (match_operand:XF 0 "register_operand" "") 317252296Sobrien (float:XF (match_operand:HI 1 "memory_operand" ""))) 317352296Sobrien (clobber (match_operand:HI 2 "memory_operand" ""))] 317452296Sobrien "TARGET_80387 && reload_completed" 317552296Sobrien [(set (match_dup 0) 317652296Sobrien (float:XF (match_dup 1)))] 317752296Sobrien "") 317852296Sobrien 317952296Sobrien(define_split 318052296Sobrien [(set (match_operand:XF 0 "register_operand" "") 318152296Sobrien (float:XF (match_operand:HI 1 "register_operand" ""))) 318252296Sobrien (clobber (match_operand:HI 2 "memory_operand" ""))] 318352296Sobrien "TARGET_80387 && reload_completed" 318452296Sobrien [(set (match_dup 2) 318552296Sobrien (match_dup 1)) 318652296Sobrien (set (match_dup 0) 318752296Sobrien (float:XF (match_dup 2)))] 318852296Sobrien "") 318952296Sobrien 319018334Speter(define_insn "" 319152296Sobrien [(set (match_operand:XF 0 "register_operand" "=f") 319252296Sobrien (float:XF (match_operand:HI 1 "memory_operand" "m")))] 319318334Speter "TARGET_80387" 319452296Sobrien "* return AS1 (fild%z1,%1);" 319552296Sobrien [(set_attr "type" "fpop")]) 319618334Speter 319752296Sobrien(define_expand "floatdixf2" 319852296Sobrien [(parallel [(set (match_operand:XF 0 "register_operand" "") 319952296Sobrien (float:XF (match_operand:DI 1 "nonimmediate_operand" ""))) 320052296Sobrien (clobber (match_dup 2))])] 320152296Sobrien "TARGET_80387" 320252296Sobrien "operands[2] = assign_386_stack_local (DImode, 0);") 320352296Sobrien 320418334Speter(define_insn "" 320518334Speter [(set (match_operand:XF 0 "register_operand" "=f,f") 320652296Sobrien (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,!r"))) 320752296Sobrien (clobber (match_operand:DI 2 "memory_operand" "m,o"))] 320818334Speter "TARGET_80387" 320952296Sobrien "#") 321018334Speter 321152296Sobrien(define_split 321252296Sobrien [(set (match_operand:XF 0 "register_operand" "") 321352296Sobrien (float:XF (match_operand:DI 1 "memory_operand" ""))) 321452296Sobrien (clobber (match_operand:DI 2 "memory_operand" ""))] 321552296Sobrien "TARGET_80387 && reload_completed" 321652296Sobrien [(set (match_dup 0) 321752296Sobrien (float:XF (match_dup 1)))] 321852296Sobrien "") 321952296Sobrien 322052296Sobrien(define_split 322152296Sobrien [(set (match_operand:XF 0 "register_operand" "") 322252296Sobrien (float:XF (match_operand:DI 1 "register_operand" ""))) 322352296Sobrien (clobber (match_operand:DI 2 "memory_operand" ""))] 322452296Sobrien "TARGET_80387 && reload_completed" 322552296Sobrien [(set (match_dup 2) 322652296Sobrien (match_dup 1)) 322752296Sobrien (set (match_dup 0) 322852296Sobrien (float:XF (match_dup 2)))] 322952296Sobrien "") 323052296Sobrien 323118334Speter(define_insn "" 323252296Sobrien [(set (match_operand:XF 0 "register_operand" "=f") 323352296Sobrien (float:XF (match_operand:DI 1 "memory_operand" "m")))] 323418334Speter "TARGET_80387" 323552296Sobrien "* return AS1 (fild%z1,%1);" 323652296Sobrien [(set_attr "type" "fpop")]) 323718334Speter 323818334Speter;;- add instructions 323918334Speter 324052296Sobrien(define_insn "*addsidi3_1" 324150650Sobrien [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,!&r,!r,o,!o") 324250650Sobrien (plus:DI (match_operand:DI 1 "general_operand" "0,0,0,o,riF,riF,o") 324350650Sobrien (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,roi,roi,ri,ri")))) 324450650Sobrien (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,&r"))] 324550650Sobrien "" 324650650Sobrien "* 324750650Sobrien{ 324852296Sobrien rtx low[3], high[3], xops[7]; 324950650Sobrien 325050650Sobrien CC_STATUS_INIT; 325150650Sobrien 325250650Sobrien split_di (operands, 2, low, high); 325350650Sobrien high[2] = const0_rtx; 325450650Sobrien low[2] = operands[2]; 325550650Sobrien 325650650Sobrien if (!rtx_equal_p (operands[0], operands[1])) 325750650Sobrien { 325850650Sobrien xops[0] = high[0]; 325950650Sobrien xops[1] = low[0]; 326050650Sobrien xops[2] = high[1]; 326150650Sobrien xops[3] = low[1]; 326250650Sobrien 326350650Sobrien if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 326450650Sobrien { 326550650Sobrien output_asm_insn (AS2 (mov%L1,%3,%1), xops); 326650650Sobrien output_asm_insn (AS2 (mov%L0,%2,%0), xops); 326750650Sobrien } 326850650Sobrien else 326950650Sobrien { 327050650Sobrien xops[4] = high[2]; 327150650Sobrien xops[5] = low[2]; 327250650Sobrien xops[6] = operands[3]; 327350650Sobrien output_asm_insn (AS2 (mov%L6,%3,%6), xops); 327450650Sobrien output_asm_insn (AS2 (add%L6,%5,%6), xops); 327550650Sobrien output_asm_insn (AS2 (mov%L1,%6,%1), xops); 327650650Sobrien output_asm_insn (AS2 (mov%L6,%2,%6), xops); 327750650Sobrien output_asm_insn (AS2 (adc%L6,%4,%6), xops); 327850650Sobrien output_asm_insn (AS2 (mov%L0,%6,%0), xops); 327950650Sobrien RET; 328050650Sobrien } 328150650Sobrien } 328250650Sobrien 328350650Sobrien output_asm_insn (AS2 (add%L0,%2,%0), low); 328450650Sobrien output_asm_insn (AS2 (adc%L0,%2,%0), high); 328552296Sobrien cc_status.value1 = high[0]; 328652296Sobrien cc_status.flags = CC_NO_OVERFLOW; 328750650Sobrien RET; 328852296Sobrien}" 328952296Sobrien [(set_attr "type" "binary")]) 329050650Sobrien 329150650Sobrien(define_insn "addsidi3_2" 329250650Sobrien [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,&r,!&r,&r,o,o,!o") 329350650Sobrien (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,o,ri,ri,i,r")) 329450650Sobrien (match_operand:DI 1 "general_operand" "0,0,0,iF,ro,roiF,riF,o,o"))) 329550650Sobrien (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,X,&r,&r"))] 329650650Sobrien "" 329750650Sobrien "* 329850650Sobrien{ 329952296Sobrien rtx low[3], high[3], xops[7]; 330050650Sobrien 330150650Sobrien CC_STATUS_INIT; 330250650Sobrien 330350650Sobrien split_di (operands, 2, low, high); 330450650Sobrien high[2] = const0_rtx; 330550650Sobrien low[2] = operands[2]; 330650650Sobrien 330750650Sobrien if (!rtx_equal_p (operands[0], operands[1])) 330850650Sobrien { 330950650Sobrien xops[0] = high[0]; 331050650Sobrien xops[1] = low[0]; 331150650Sobrien xops[2] = high[1]; 331250650Sobrien xops[3] = low[1]; 331350650Sobrien 331450650Sobrien if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 331550650Sobrien { 331650650Sobrien if (rtx_equal_p (low[0], operands[2])) 331750650Sobrien { 331850650Sobrien output_asm_insn (AS2 (mov%L0,%2,%0), high); 331950650Sobrien output_asm_insn (AS2 (add%L0,%1,%0), low); 332050650Sobrien output_asm_insn (AS2 (adc%L0,%1,%0), high); 332150650Sobrien RET; 332250650Sobrien } 332350650Sobrien if (rtx_equal_p (high[0], operands[2])) 332450650Sobrien { 332550650Sobrien if (GET_CODE (operands[0]) != MEM) 332650650Sobrien { 332750650Sobrien output_asm_insn (AS2 (mov%L0,%2,%0), low); 332850650Sobrien output_asm_insn (AS2 (mov%L0,%2,%0), high); 332950650Sobrien output_asm_insn (AS2 (add%L0,%1,%0), low); 333050650Sobrien output_asm_insn (AS2 (adc%L0,%1,%0), high); 333150650Sobrien } 333250650Sobrien else 333350650Sobrien { 333450650Sobrien /* It's too late to ask for a scratch now - but this 333550650Sobrien will probably not happen too often. */ 333650650Sobrien output_asm_insn (AS2 (add%L1,%2,%1), low); 333750650Sobrien output_asm_insn (AS2 (mov%L0,%1,%0), low); 333850650Sobrien output_asm_insn (AS2 (mov%L1,%2,%1), low); 333950650Sobrien output_asm_insn (AS2 (mov%L0,%2,%0), high); 334050650Sobrien output_asm_insn (AS2 (adc%L0,%1,%0), high); 334150650Sobrien output_asm_insn (AS2 (sub%L1,%0,%1), low); 334250650Sobrien output_asm_insn (AS1 (neg%L1,%1), low); 334350650Sobrien } 334450650Sobrien RET; 334550650Sobrien } 334650650Sobrien output_asm_insn (AS2 (mov%L1,%3,%1), xops); 334750650Sobrien output_asm_insn (AS2 (mov%L0,%2,%0), xops); 334850650Sobrien } 334950650Sobrien else 335050650Sobrien { 335150650Sobrien xops[4] = high[2]; 335250650Sobrien xops[5] = low[2]; 335350650Sobrien xops[6] = operands[3]; 335450650Sobrien output_asm_insn (AS2 (mov%L6,%3,%6), xops); 335550650Sobrien output_asm_insn (AS2 (add%L6,%5,%6), xops); 335650650Sobrien output_asm_insn (AS2 (mov%L1,%6,%1), xops); 335750650Sobrien output_asm_insn (AS2 (mov%L6,%2,%6), xops); 335850650Sobrien output_asm_insn (AS2 (adc%L6,%4,%6), xops); 335950650Sobrien output_asm_insn (AS2 (mov%L0,%6,%0), xops); 336050650Sobrien RET; 336150650Sobrien } 336250650Sobrien } 336350650Sobrien 336450650Sobrien output_asm_insn (AS2 (add%L0,%2,%0), low); 336550650Sobrien output_asm_insn (AS2 (adc%L0,%2,%0), high); 336652296Sobrien cc_status.value1 = high[0]; 336752296Sobrien cc_status.flags = CC_NO_OVERFLOW; 336850650Sobrien RET; 336952296Sobrien}" 337052296Sobrien [(set_attr "type" "binary")]) 337150650Sobrien 337218334Speter(define_insn "adddi3" 337350650Sobrien [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o") 337450650Sobrien (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o") 337550650Sobrien (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o"))) 337650650Sobrien (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))] 337718334Speter "" 337818334Speter "* 337918334Speter{ 338018334Speter rtx low[3], high[3], xops[7], temp; 338118334Speter 338218334Speter CC_STATUS_INIT; 338318334Speter 338418334Speter if (rtx_equal_p (operands[0], operands[2])) 338518334Speter { 338618334Speter temp = operands[1]; 338718334Speter operands[1] = operands[2]; 338818334Speter operands[2] = temp; 338918334Speter } 339018334Speter 339118334Speter split_di (operands, 3, low, high); 339218334Speter if (!rtx_equal_p (operands[0], operands[1])) 339318334Speter { 339418334Speter xops[0] = high[0]; 339518334Speter xops[1] = low[0]; 339618334Speter xops[2] = high[1]; 339718334Speter xops[3] = low[1]; 339818334Speter 339918334Speter if (GET_CODE (operands[0]) != MEM) 340018334Speter { 340118334Speter output_asm_insn (AS2 (mov%L1,%3,%1), xops); 340218334Speter output_asm_insn (AS2 (mov%L0,%2,%0), xops); 340318334Speter } 340418334Speter else 340518334Speter { 340618334Speter xops[4] = high[2]; 340718334Speter xops[5] = low[2]; 340818334Speter xops[6] = operands[3]; 340918334Speter output_asm_insn (AS2 (mov%L6,%3,%6), xops); 341018334Speter output_asm_insn (AS2 (add%L6,%5,%6), xops); 341118334Speter output_asm_insn (AS2 (mov%L1,%6,%1), xops); 341218334Speter output_asm_insn (AS2 (mov%L6,%2,%6), xops); 341318334Speter output_asm_insn (AS2 (adc%L6,%4,%6), xops); 341418334Speter output_asm_insn (AS2 (mov%L0,%6,%0), xops); 341518334Speter RET; 341618334Speter } 341718334Speter } 341818334Speter 341952296Sobrien cc_status.value1 = high[0]; 342052296Sobrien cc_status.flags = CC_NO_OVERFLOW; 342152296Sobrien 342218334Speter if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG) 342318334Speter { 342418334Speter xops[0] = high[0]; 342518334Speter xops[1] = low[0]; 342618334Speter xops[2] = high[2]; 342718334Speter xops[3] = low[2]; 342818334Speter xops[4] = operands[3]; 342918334Speter 343018334Speter output_asm_insn (AS2 (mov%L4,%3,%4), xops); 343118334Speter output_asm_insn (AS2 (add%L1,%4,%1), xops); 343218334Speter output_asm_insn (AS2 (mov%L4,%2,%4), xops); 343318334Speter output_asm_insn (AS2 (adc%L0,%4,%0), xops); 343418334Speter } 343518334Speter 343618334Speter else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0) 343718334Speter { 343818334Speter output_asm_insn (AS2 (add%L0,%2,%0), low); 343918334Speter output_asm_insn (AS2 (adc%L0,%2,%0), high); 344018334Speter } 344118334Speter 344218334Speter else 344318334Speter output_asm_insn (AS2 (add%L0,%2,%0), high); 344418334Speter 344518334Speter RET; 344652296Sobrien}" 344752296Sobrien [(set_attr "type" "binary")]) 344818334Speter 344918334Speter;; On a 486, it is faster to do movl/addl than to do a single leal if 345018334Speter;; operands[1] and operands[2] are both registers. 345118334Speter 345250650Sobrien(define_expand "addsi3" 345350650Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "") 345450650Sobrien (plus:SI (match_operand:SI 1 "nonimmediate_operand" "") 345550650Sobrien (match_operand:SI 2 "general_operand" "")))] 345618334Speter "" 345750650Sobrien "IX86_EXPAND_BINARY_OPERATOR (PLUS, SImode, operands);") 345850650Sobrien 345950650Sobrien(define_insn "" 346050650Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r") 346150650Sobrien (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r") 346250650Sobrien (match_operand:SI 2 "general_operand" "rmi,ri,ri")))] 346350650Sobrien "ix86_binary_operator_ok (PLUS, SImode, operands)" 346418334Speter "* 346518334Speter{ 346650650Sobrien if (REG_P (operands[0]) && REG_P (operands[1]) 346752296Sobrien && (REG_P (operands[2]) || CONSTANT_P (operands[2])) 346850650Sobrien && REGNO (operands[0]) != REGNO (operands[1])) 346918334Speter { 347018334Speter if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2])) 347118334Speter return AS2 (add%L0,%1,%0); 347218334Speter 347318334Speter if (operands[2] == stack_pointer_rtx) 347418334Speter { 347518334Speter rtx temp; 347618334Speter 347718334Speter temp = operands[1]; 347818334Speter operands[1] = operands[2]; 347918334Speter operands[2] = temp; 348018334Speter } 348118334Speter 348218334Speter if (operands[2] != stack_pointer_rtx) 348318334Speter { 348418334Speter CC_STATUS_INIT; 348518334Speter operands[1] = SET_SRC (PATTERN (insn)); 348618334Speter return AS2 (lea%L0,%a1,%0); 348718334Speter } 348818334Speter } 348918334Speter 349050650Sobrien if (!rtx_equal_p (operands[0], operands[1])) 349150650Sobrien output_asm_insn (AS2 (mov%L0,%1,%0), operands); 349250650Sobrien 349318334Speter if (operands[2] == const1_rtx) 349418334Speter return AS1 (inc%L0,%0); 349518334Speter 349618334Speter if (operands[2] == constm1_rtx) 349718334Speter return AS1 (dec%L0,%0); 349818334Speter 349950650Sobrien /* subl $-128,%ebx is smaller than addl $128,%ebx. */ 350050650Sobrien if (GET_CODE (operands[2]) == CONST_INT 350150650Sobrien && INTVAL (operands[2]) == 128) 350250650Sobrien { 350350650Sobrien /* This doesn't compute the carry bit in the same way 350450650Sobrien * as add%L0, but we use inc and dec above and they 350550650Sobrien * don't set the carry bit at all. If inc/dec don't need 350650650Sobrien * a CC_STATUS_INIT, this doesn't either... */ 350750650Sobrien operands[2] = GEN_INT (-128); 350850650Sobrien return AS2 (sub%L0,%2,%0); 350950650Sobrien } 351050650Sobrien 351118334Speter return AS2 (add%L0,%2,%0); 351252296Sobrien}" 351352296Sobrien [(set_attr "type" "binary")]) 351418334Speter 351550650Sobrien;; addsi3 is faster, so put this after. 351650650Sobrien 351750650Sobrien(define_insn "movsi_lea" 351850650Sobrien [(set (match_operand:SI 0 "register_operand" "=r") 351950650Sobrien (match_operand:QI 1 "address_operand" "p"))] 352050650Sobrien "" 352150650Sobrien "* 352250650Sobrien{ 352350650Sobrien /* Adding a constant to a register is faster with an add. */ 352450650Sobrien /* ??? can this ever happen? */ 352550650Sobrien if (GET_CODE (operands[1]) == PLUS 352650650Sobrien && GET_CODE (XEXP (operands[1], 1)) == CONST_INT 352750650Sobrien && rtx_equal_p (operands[0], XEXP (operands[1], 0))) 352850650Sobrien { 352950650Sobrien operands[1] = XEXP (operands[1], 1); 353050650Sobrien 353150650Sobrien if (operands[1] == const1_rtx) 353250650Sobrien return AS1 (inc%L0,%0); 353350650Sobrien 353450650Sobrien if (operands[1] == constm1_rtx) 353550650Sobrien return AS1 (dec%L0,%0); 353650650Sobrien 353750650Sobrien return AS2 (add%L0,%1,%0); 353850650Sobrien } 353950650Sobrien 354050650Sobrien CC_STATUS_INIT; 354150650Sobrien return AS2 (lea%L0,%a1,%0); 354252296Sobrien}" 354352296Sobrien [(set_attr "type" "lea")]) 354450650Sobrien 354518334Speter;; ??? `lea' here, for three operand add? If leaw is used, only %bx, 354618334Speter;; %si and %di can appear in SET_SRC, and output_asm_insn might not be 354718334Speter;; able to handle the operand. But leal always works? 354818334Speter 354950650Sobrien(define_expand "addhi3" 355050650Sobrien [(set (match_operand:HI 0 "general_operand" "") 355150650Sobrien (plus:HI (match_operand:HI 1 "nonimmediate_operand" "") 355250650Sobrien (match_operand:HI 2 "general_operand" "")))] 355350650Sobrien "" 355450650Sobrien "IX86_EXPAND_BINARY_OPERATOR (PLUS, HImode, operands);") 355550650Sobrien 355650650Sobrien(define_insn "" 355752296Sobrien [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,?r") 355852296Sobrien (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r") 355952296Sobrien (match_operand:HI 2 "general_operand" "ri,rm,ri")))] 356050650Sobrien "ix86_binary_operator_ok (PLUS, HImode, operands)" 356118334Speter "* 356218334Speter{ 356352296Sobrien if (REG_P (operands[0]) && REG_P (operands[1]) 356452296Sobrien && (REG_P (operands[2]) || CONSTANT_P (operands[2])) 356552296Sobrien && REGNO (operands[0]) != REGNO (operands[1])) 356652296Sobrien { 356752296Sobrien if (operands[2] == stack_pointer_rtx) 356852296Sobrien abort (); 356952296Sobrien 357052296Sobrien CC_STATUS_INIT; 357152296Sobrien operands[1] 357252296Sobrien = gen_rtx_PLUS (SImode, 357352296Sobrien gen_rtx_REG (SImode, REGNO (operands[1])), 357452296Sobrien (! REG_P (operands[2]) 357552296Sobrien ? operands[2] 357652296Sobrien : gen_rtx_REG (SImode, REGNO (operands[2])))); 357752296Sobrien operands[0] = gen_rtx_REG (SImode, REGNO (operands[0])); 357852296Sobrien return AS2 (lea%L0,%a1,%0); 357952296Sobrien } 358052296Sobrien 358118334Speter /* ??? what about offsettable memory references? */ 358250650Sobrien if (!TARGET_PENTIUMPRO /* partial stalls are just too painful to risk. */ 358350650Sobrien && QI_REG_P (operands[0]) 358418334Speter && GET_CODE (operands[2]) == CONST_INT 358550650Sobrien && (INTVAL (operands[2]) & 0xff) == 0 358650650Sobrien && i386_cc_probably_useless_p (insn)) 358718334Speter { 358818334Speter int byteval = (INTVAL (operands[2]) >> 8) & 0xff; 358918334Speter CC_STATUS_INIT; 359018334Speter 359118334Speter if (byteval == 1) 359218334Speter return AS1 (inc%B0,%h0); 359318334Speter else if (byteval == 255) 359418334Speter return AS1 (dec%B0,%h0); 359518334Speter 359618334Speter operands[2] = GEN_INT (byteval); 359718334Speter return AS2 (add%B0,%2,%h0); 359818334Speter } 359918334Speter 360050650Sobrien /* Use a 32-bit operation when possible, to avoid the prefix penalty. */ 360150650Sobrien if (REG_P (operands[0]) 360250650Sobrien && i386_aligned_p (operands[2]) 360350650Sobrien && i386_cc_probably_useless_p (insn)) 360450650Sobrien { 360550650Sobrien CC_STATUS_INIT; 360650650Sobrien 360750650Sobrien if (GET_CODE (operands[2]) == CONST_INT) 360850650Sobrien { 360950650Sobrien HOST_WIDE_INT intval = 0xffff & INTVAL (operands[2]); 361050650Sobrien 361150650Sobrien if (intval == 1) 361250650Sobrien return AS1 (inc%L0,%k0); 361350650Sobrien 361450650Sobrien if (intval == 0xffff) 361550650Sobrien return AS1 (dec%L0,%k0); 361650650Sobrien 361750650Sobrien operands[2] = i386_sext16_if_const (operands[2]); 361850650Sobrien } 361950650Sobrien return AS2 (add%L0,%k2,%k0); 362050650Sobrien } 362150650Sobrien 362218334Speter if (operands[2] == const1_rtx) 362318334Speter return AS1 (inc%W0,%0); 362418334Speter 362518334Speter if (operands[2] == constm1_rtx 362618334Speter || (GET_CODE (operands[2]) == CONST_INT 362718334Speter && INTVAL (operands[2]) == 65535)) 362818334Speter return AS1 (dec%W0,%0); 362918334Speter 363018334Speter return AS2 (add%W0,%2,%0); 363152296Sobrien}" 363252296Sobrien [(set_attr "type" "binary")]) 363318334Speter 363450650Sobrien(define_expand "addqi3" 363550650Sobrien [(set (match_operand:QI 0 "general_operand" "") 363650650Sobrien (plus:QI (match_operand:QI 1 "general_operand" "") 363750650Sobrien (match_operand:QI 2 "general_operand" "")))] 363850650Sobrien "" 363950650Sobrien "IX86_EXPAND_BINARY_OPERATOR (PLUS, QImode, operands);") 364050650Sobrien 364150650Sobrien(define_insn "" 364252296Sobrien [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,?q") 364352296Sobrien (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q") 364452296Sobrien (match_operand:QI 2 "general_operand" "qn,qmn,qn")))] 364550650Sobrien "ix86_binary_operator_ok (PLUS, QImode, operands)" 364618334Speter "* 364718334Speter{ 364852296Sobrien if (REG_P (operands[0]) && REG_P (operands[1]) 364952296Sobrien && (REG_P (operands[2]) || CONSTANT_P (operands[2])) 365052296Sobrien && (REGNO (operands[0]) != REGNO (operands[1]) 365152296Sobrien || NON_QI_REG_P (operands[1]) 365252296Sobrien || (REG_P (operands[2]) && NON_QI_REG_P (operands[2])))) 365352296Sobrien { 365452296Sobrien if (operands[2] == stack_pointer_rtx) 365552296Sobrien abort (); 365652296Sobrien 365752296Sobrien CC_STATUS_INIT; 365852296Sobrien operands[1] 365952296Sobrien = gen_rtx_PLUS (SImode, 366052296Sobrien gen_rtx_REG (SImode, REGNO (operands[1])), 366152296Sobrien (! REG_P (operands[2]) 366252296Sobrien ? operands[2] 366352296Sobrien : gen_rtx_REG (SImode, REGNO (operands[2])))); 366452296Sobrien operands[0] = gen_rtx_REG (SImode, REGNO (operands[0])); 366552296Sobrien return AS2 (lea%L0,%a1,%0); 366652296Sobrien } 366718334Speter if (operands[2] == const1_rtx) 366818334Speter return AS1 (inc%B0,%0); 366918334Speter 367018334Speter if (operands[2] == constm1_rtx 367118334Speter || (GET_CODE (operands[2]) == CONST_INT 367218334Speter && INTVAL (operands[2]) == 255)) 367318334Speter return AS1 (dec%B0,%0); 367418334Speter 367518334Speter return AS2 (add%B0,%2,%0); 367652296Sobrien}" 367752296Sobrien [(set_attr "type" "binary")]) 367818334Speter 367918334Speter;Lennart Augustsson <augustss@cs.chalmers.se> 368018334Speter;says this pattern just makes slower code: 368118334Speter; pushl %ebp 368218334Speter; addl $-80,(%esp) 368318334Speter;instead of 368418334Speter; leal -80(%ebp),%eax 368518334Speter; pushl %eax 368618334Speter; 368718334Speter;(define_insn "" 368818334Speter; [(set (match_operand:SI 0 "push_operand" "=<") 368950650Sobrien; (plus:SI (match_operand:SI 1 "register_operand" "%r") 369050650Sobrien; (match_operand:SI 2 "nonmemory_operand" "ri")))] 369118334Speter; "" 369218334Speter; "* 369318334Speter;{ 369418334Speter; rtx xops[4]; 369518334Speter; xops[0] = operands[0]; 369618334Speter; xops[1] = operands[1]; 369718334Speter; xops[2] = operands[2]; 369850650Sobrien; xops[3] = gen_rtx_MEM (SImode, stack_pointer_rtx); 369918334Speter; output_asm_insn (\"push%z1 %1\", xops); 370018334Speter; output_asm_insn (AS2 (add%z3,%2,%3), xops); 370118334Speter; RET; 370218334Speter;}") 370318334Speter 370418334Speter;; The patterns that match these are at the end of this file. 370518334Speter 370618334Speter(define_expand "addxf3" 370718334Speter [(set (match_operand:XF 0 "register_operand" "") 370850650Sobrien (plus:XF (match_operand:XF 1 "register_operand" "") 370950650Sobrien (match_operand:XF 2 "register_operand" "")))] 371018334Speter "TARGET_80387" 371118334Speter "") 371218334Speter 371318334Speter(define_expand "adddf3" 371418334Speter [(set (match_operand:DF 0 "register_operand" "") 371518334Speter (plus:DF (match_operand:DF 1 "nonimmediate_operand" "") 371618334Speter (match_operand:DF 2 "nonimmediate_operand" "")))] 371718334Speter "TARGET_80387" 371818334Speter "") 371918334Speter 372018334Speter(define_expand "addsf3" 372118334Speter [(set (match_operand:SF 0 "register_operand" "") 372218334Speter (plus:SF (match_operand:SF 1 "nonimmediate_operand" "") 372318334Speter (match_operand:SF 2 "nonimmediate_operand" "")))] 372418334Speter "TARGET_80387" 372518334Speter "") 372618334Speter 372718334Speter;;- subtract instructions 372818334Speter 372950650Sobrien(define_insn "subsidi3" 373050650Sobrien [(set (match_operand:DI 0 "general_operand" "=&r,&ro,&r,!&r,o,o,!o") 373150650Sobrien (minus:DI (match_operand:DI 1 "general_operand" "0iF,0,roiF,roiF,riF,o,o") 373250650Sobrien (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,ri,i,r")))) 373350650Sobrien (clobber (match_scratch:SI 3 "=X,X,X,X,X,&r,&r"))] 373450650Sobrien "" 373550650Sobrien "* 373650650Sobrien{ 373750650Sobrien rtx low[3], high[3], xops[7]; 373850650Sobrien 373950650Sobrien CC_STATUS_INIT; 374050650Sobrien 374150650Sobrien split_di (operands, 2, low, high); 374250650Sobrien high[2] = const0_rtx; 374350650Sobrien low[2] = operands[2]; 374450650Sobrien 374550650Sobrien if (!rtx_equal_p (operands[0], operands[1])) 374650650Sobrien { 374750650Sobrien xops[0] = high[0]; 374850650Sobrien xops[1] = low[0]; 374950650Sobrien xops[2] = high[1]; 375050650Sobrien xops[3] = low[1]; 375150650Sobrien 375250650Sobrien if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 375350650Sobrien { 375450650Sobrien output_asm_insn (AS2 (mov%L1,%3,%1), xops); 375550650Sobrien output_asm_insn (AS2 (mov%L0,%2,%0), xops); 375650650Sobrien } 375750650Sobrien else 375850650Sobrien { 375950650Sobrien xops[4] = high[2]; 376050650Sobrien xops[5] = low[2]; 376150650Sobrien xops[6] = operands[3]; 376250650Sobrien output_asm_insn (AS2 (mov%L6,%3,%6), xops); 376350650Sobrien output_asm_insn (AS2 (sub%L6,%5,%6), xops); 376450650Sobrien output_asm_insn (AS2 (mov%L1,%6,%1), xops); 376550650Sobrien output_asm_insn (AS2 (mov%L6,%2,%6), xops); 376650650Sobrien output_asm_insn (AS2 (sbb%L6,%4,%6), xops); 376750650Sobrien output_asm_insn (AS2 (mov%L0,%6,%0), xops); 376850650Sobrien RET; 376950650Sobrien } 377050650Sobrien } 377150650Sobrien 377250650Sobrien output_asm_insn (AS2 (sub%L0,%2,%0), low); 377350650Sobrien output_asm_insn (AS2 (sbb%L0,%2,%0), high); 377452296Sobrien cc_status.value1 = high[0]; 377552296Sobrien cc_status.flags = CC_NO_OVERFLOW; 377652296Sobrien 377750650Sobrien RET; 377852296Sobrien}" 377952296Sobrien [(set_attr "type" "binary")]) 378050650Sobrien 378118334Speter(define_insn "subdi3" 378250650Sobrien [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o") 378350650Sobrien (minus:DI (match_operand:DI 1 "general_operand" "0,0,0iF,or,roiF,roiF") 378450650Sobrien (match_operand:DI 2 "general_operand" "or,riF,or,iF,roiF,roiF"))) 378550650Sobrien (clobber (match_scratch:SI 3 "=X,X,&r,&r,X,&r"))] 378618334Speter "" 378718334Speter "* 378818334Speter{ 378918334Speter rtx low[3], high[3], xops[7]; 379018334Speter 379118334Speter CC_STATUS_INIT; 379218334Speter 379318334Speter split_di (operands, 3, low, high); 379418334Speter 379518334Speter if (!rtx_equal_p (operands[0], operands[1])) 379618334Speter { 379718334Speter xops[0] = high[0]; 379818334Speter xops[1] = low[0]; 379918334Speter xops[2] = high[1]; 380018334Speter xops[3] = low[1]; 380118334Speter 380218334Speter if (GET_CODE (operands[0]) != MEM) 380318334Speter { 380418334Speter output_asm_insn (AS2 (mov%L1,%3,%1), xops); 380518334Speter output_asm_insn (AS2 (mov%L0,%2,%0), xops); 380618334Speter } 380718334Speter else 380818334Speter { 380918334Speter xops[4] = high[2]; 381018334Speter xops[5] = low[2]; 381118334Speter xops[6] = operands[3]; 381218334Speter output_asm_insn (AS2 (mov%L6,%3,%6), xops); 381318334Speter output_asm_insn (AS2 (sub%L6,%5,%6), xops); 381418334Speter output_asm_insn (AS2 (mov%L1,%6,%1), xops); 381518334Speter output_asm_insn (AS2 (mov%L6,%2,%6), xops); 381618334Speter output_asm_insn (AS2 (sbb%L6,%4,%6), xops); 381718334Speter output_asm_insn (AS2 (mov%L0,%6,%0), xops); 381818334Speter RET; 381918334Speter } 382018334Speter } 382118334Speter 382252296Sobrien cc_status.value1 = high[0]; 382352296Sobrien cc_status.flags = CC_NO_OVERFLOW; 382452296Sobrien 382518334Speter if (GET_CODE (operands[3]) == REG) 382618334Speter { 382718334Speter xops[0] = high[0]; 382818334Speter xops[1] = low[0]; 382918334Speter xops[2] = high[2]; 383018334Speter xops[3] = low[2]; 383118334Speter xops[4] = operands[3]; 383218334Speter 383318334Speter output_asm_insn (AS2 (mov%L4,%3,%4), xops); 383418334Speter output_asm_insn (AS2 (sub%L1,%4,%1), xops); 383518334Speter output_asm_insn (AS2 (mov%L4,%2,%4), xops); 383618334Speter output_asm_insn (AS2 (sbb%L0,%4,%0), xops); 383718334Speter } 383818334Speter 383918334Speter else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0) 384018334Speter { 384118334Speter output_asm_insn (AS2 (sub%L0,%2,%0), low); 384218334Speter output_asm_insn (AS2 (sbb%L0,%2,%0), high); 384318334Speter } 384418334Speter 384518334Speter else 384652296Sobrien output_asm_insn (AS2 (sub%L0,%2,%0), high); 384718334Speter 384852296Sobrien 384918334Speter RET; 385052296Sobrien}" 385152296Sobrien [(set_attr "type" "binary")]) 385218334Speter 385350650Sobrien(define_expand "subsi3" 385450650Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "") 385550650Sobrien (minus:SI (match_operand:SI 1 "nonimmediate_operand" "") 385650650Sobrien (match_operand:SI 2 "general_operand" "")))] 385750650Sobrien "" 385850650Sobrien "IX86_EXPAND_BINARY_OPERATOR (MINUS, SImode, operands);") 385950650Sobrien 386050650Sobrien(define_insn "" 386150650Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 386250650Sobrien (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 386318334Speter (match_operand:SI 2 "general_operand" "ri,rm")))] 386450650Sobrien "ix86_binary_operator_ok (MINUS, SImode, operands)" 386552296Sobrien "* return AS2 (sub%L0,%2,%0);" 386652296Sobrien [(set_attr "type" "binary")]) 386718334Speter 386850650Sobrien(define_expand "subhi3" 386950650Sobrien [(set (match_operand:HI 0 "general_operand" "") 387050650Sobrien (minus:HI (match_operand:HI 1 "nonimmediate_operand" "") 387150650Sobrien (match_operand:HI 2 "general_operand" "")))] 387250650Sobrien "" 387350650Sobrien "IX86_EXPAND_BINARY_OPERATOR (MINUS, HImode, operands);") 387450650Sobrien 387550650Sobrien(define_insn "" 387650650Sobrien [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 387750650Sobrien (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 387818334Speter (match_operand:HI 2 "general_operand" "ri,rm")))] 387950650Sobrien "ix86_binary_operator_ok (MINUS, HImode, operands)" 388050650Sobrien "* 388150650Sobrien{ 388250650Sobrien if (REG_P (operands[0]) 388350650Sobrien && i386_aligned_p (operands[2]) 388450650Sobrien && i386_cc_probably_useless_p (insn)) 388550650Sobrien { 388650650Sobrien CC_STATUS_INIT; 388750650Sobrien operands[2] = i386_sext16_if_const (operands[2]); 388850650Sobrien return AS2 (sub%L0,%k2,%k0); 388950650Sobrien } 389050650Sobrien return AS2 (sub%W0,%2,%0); 389152296Sobrien}" 389252296Sobrien [(set_attr "type" "binary")]) 389350650Sobrien 389450650Sobrien(define_expand "subqi3" 389550650Sobrien [(set (match_operand:QI 0 "general_operand" "") 389650650Sobrien (minus:QI (match_operand:QI 1 "general_operand" "") 389750650Sobrien (match_operand:QI 2 "general_operand" "")))] 389818334Speter "" 389950650Sobrien "IX86_EXPAND_BINARY_OPERATOR (MINUS, QImode, operands);") 390018334Speter 390150650Sobrien(define_insn "" 390250650Sobrien [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 390350650Sobrien (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 390418334Speter (match_operand:QI 2 "general_operand" "qn,qmn")))] 390550650Sobrien "ix86_binary_operator_ok (MINUS, QImode, operands)" 390652296Sobrien "* return AS2 (sub%B0,%2,%0);" 390752296Sobrien [(set_attr "type" "binary")]) 390818334Speter 390918334Speter;; The patterns that match these are at the end of this file. 391018334Speter 391118334Speter(define_expand "subxf3" 391218334Speter [(set (match_operand:XF 0 "register_operand" "") 391350650Sobrien (minus:XF (match_operand:XF 1 "register_operand" "") 391450650Sobrien (match_operand:XF 2 "register_operand" "")))] 391518334Speter "TARGET_80387" 391618334Speter "") 391718334Speter 391818334Speter(define_expand "subdf3" 391918334Speter [(set (match_operand:DF 0 "register_operand" "") 392018334Speter (minus:DF (match_operand:DF 1 "nonimmediate_operand" "") 392118334Speter (match_operand:DF 2 "nonimmediate_operand" "")))] 392218334Speter "TARGET_80387" 392318334Speter "") 392418334Speter 392518334Speter(define_expand "subsf3" 392618334Speter [(set (match_operand:SF 0 "register_operand" "") 392718334Speter (minus:SF (match_operand:SF 1 "nonimmediate_operand" "") 392818334Speter (match_operand:SF 2 "nonimmediate_operand" "")))] 392918334Speter "TARGET_80387" 393018334Speter "") 393118334Speter 393218334Speter;;- multiply instructions 393318334Speter 393418334Speter;(define_insn "mulqi3" 393550650Sobrien; [(set (match_operand:QI 0 "register_operand" "=a") 393650650Sobrien; (mult:QI (match_operand:QI 1 "register_operand" "%0") 393750650Sobrien; (match_operand:QI 2 "nonimmediate_operand" "qm")))] 393818334Speter; "" 393918334Speter; "imul%B0 %2,%0") 394018334Speter 394118334Speter(define_insn "mulhi3" 394250650Sobrien [(set (match_operand:HI 0 "register_operand" "=r,r") 394350650Sobrien (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%0,rm") 394418334Speter (match_operand:HI 2 "general_operand" "g,i")))] 394518334Speter "" 394618334Speter "* 394718334Speter{ 394818334Speter if (GET_CODE (operands[1]) == REG 394918334Speter && REGNO (operands[1]) == REGNO (operands[0]) 395018334Speter && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG)) 395118334Speter /* Assembler has weird restrictions. */ 395218334Speter return AS2 (imul%W0,%2,%0); 395318334Speter return AS3 (imul%W0,%2,%1,%0); 395450650Sobrien}" 395550650Sobrien [(set_attr "type" "imul")]) 395618334Speter 395718334Speter(define_insn "mulsi3" 395850650Sobrien [(set (match_operand:SI 0 "register_operand" "=r,r") 395950650Sobrien (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm") 396018334Speter (match_operand:SI 2 "general_operand" "g,i")))] 396118334Speter "" 396218334Speter "* 396318334Speter{ 396418334Speter if (GET_CODE (operands[1]) == REG 396518334Speter && REGNO (operands[1]) == REGNO (operands[0]) 396618334Speter && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG)) 396718334Speter /* Assembler has weird restrictions. */ 396818334Speter return AS2 (imul%L0,%2,%0); 396918334Speter return AS3 (imul%L0,%2,%1,%0); 397050650Sobrien}" 397150650Sobrien [(set_attr "type" "imul")]) 397218334Speter 397318334Speter(define_insn "umulqihi3" 397450650Sobrien [(set (match_operand:HI 0 "register_operand" "=a") 397550650Sobrien (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0")) 397618334Speter (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))] 397718334Speter "" 397850650Sobrien "mul%B0 %2" 397950650Sobrien [(set_attr "type" "imul")]) 398018334Speter 398118334Speter(define_insn "mulqihi3" 398250650Sobrien [(set (match_operand:HI 0 "register_operand" "=a") 398350650Sobrien (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0")) 398418334Speter (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))] 398518334Speter "" 398650650Sobrien "imul%B0 %2" 398750650Sobrien [(set_attr "type" "imul")]) 398818334Speter 398918334Speter(define_insn "umulsidi3" 399018334Speter [(set (match_operand:DI 0 "register_operand" "=A") 399118334Speter (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 399218334Speter (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))] 399318334Speter "TARGET_WIDE_MULTIPLY" 399450650Sobrien "mul%L0 %2" 399550650Sobrien [(set_attr "type" "imul")]) 399618334Speter 399718334Speter(define_insn "mulsidi3" 399818334Speter [(set (match_operand:DI 0 "register_operand" "=A") 399918334Speter (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0")) 400018334Speter (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))] 400118334Speter "TARGET_WIDE_MULTIPLY" 400250650Sobrien "imul%L0 %2" 400350650Sobrien [(set_attr "type" "imul")]) 400418334Speter 400518334Speter(define_insn "umulsi3_highpart" 400618334Speter [(set (match_operand:SI 0 "register_operand" "=d") 400718334Speter (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%a")) 400818334Speter (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))) 400918334Speter (const_int 32)))) 401018334Speter (clobber (match_scratch:SI 3 "=a"))] 401118334Speter "TARGET_WIDE_MULTIPLY" 401250650Sobrien "mul%L0 %2" 401350650Sobrien [(set_attr "type" "imul")]) 401418334Speter 401518334Speter(define_insn "smulsi3_highpart" 401618334Speter [(set (match_operand:SI 0 "register_operand" "=d") 401718334Speter (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%a")) 401818334Speter (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))) 401918334Speter (const_int 32)))) 402018334Speter (clobber (match_scratch:SI 3 "=a"))] 402118334Speter "TARGET_WIDE_MULTIPLY" 402250650Sobrien "imul%L0 %2" 402350650Sobrien [(set_attr "type" "imul")]) 402418334Speter 402518334Speter;; The patterns that match these are at the end of this file. 402618334Speter 402718334Speter(define_expand "mulxf3" 402818334Speter [(set (match_operand:XF 0 "register_operand" "") 402950650Sobrien (mult:XF (match_operand:XF 1 "register_operand" "") 403050650Sobrien (match_operand:XF 2 "register_operand" "")))] 403118334Speter "TARGET_80387" 403218334Speter "") 403318334Speter 403418334Speter(define_expand "muldf3" 403518334Speter [(set (match_operand:DF 0 "register_operand" "") 403650650Sobrien (mult:DF (match_operand:DF 1 "register_operand" "") 403718334Speter (match_operand:DF 2 "nonimmediate_operand" "")))] 403818334Speter "TARGET_80387" 403918334Speter "") 404018334Speter 404118334Speter(define_expand "mulsf3" 404218334Speter [(set (match_operand:SF 0 "register_operand" "") 404350650Sobrien (mult:SF (match_operand:SF 1 "register_operand" "") 404418334Speter (match_operand:SF 2 "nonimmediate_operand" "")))] 404518334Speter "TARGET_80387" 404618334Speter "") 404718334Speter 404818334Speter;;- divide instructions 404918334Speter 405018334Speter(define_insn "divqi3" 405150650Sobrien [(set (match_operand:QI 0 "register_operand" "=a") 405250650Sobrien (div:QI (match_operand:HI 1 "register_operand" "0") 405350650Sobrien (match_operand:QI 2 "nonimmediate_operand" "qm")))] 405418334Speter "" 405518334Speter "idiv%B0 %2") 405618334Speter 405718334Speter(define_insn "udivqi3" 405850650Sobrien [(set (match_operand:QI 0 "register_operand" "=a") 405950650Sobrien (udiv:QI (match_operand:HI 1 "register_operand" "0") 406050650Sobrien (match_operand:QI 2 "nonimmediate_operand" "qm")))] 406118334Speter "" 406250650Sobrien "div%B0 %2" 406350650Sobrien [(set_attr "type" "idiv")]) 406418334Speter 406518334Speter;; The patterns that match these are at the end of this file. 406618334Speter 406718334Speter(define_expand "divxf3" 406818334Speter [(set (match_operand:XF 0 "register_operand" "") 406950650Sobrien (div:XF (match_operand:XF 1 "register_operand" "") 407050650Sobrien (match_operand:XF 2 "register_operand" "")))] 407118334Speter "TARGET_80387" 407218334Speter "") 407318334Speter 407418334Speter(define_expand "divdf3" 407518334Speter [(set (match_operand:DF 0 "register_operand" "") 407650650Sobrien (div:DF (match_operand:DF 1 "register_operand" "") 407750650Sobrien (match_operand:DF 2 "nonimmediate_operand" "")))] 407850650Sobrien "TARGET_80387" 407950650Sobrien "") 408050650Sobrien 408118334Speter(define_expand "divsf3" 408218334Speter [(set (match_operand:SF 0 "register_operand" "") 408350650Sobrien (div:SF (match_operand:SF 1 "register_operand" "") 408418334Speter (match_operand:SF 2 "nonimmediate_operand" "")))] 408518334Speter "TARGET_80387" 408618334Speter "") 408718334Speter 408818334Speter;; Remainder instructions. 408918334Speter 409018334Speter(define_insn "divmodsi4" 409118334Speter [(set (match_operand:SI 0 "register_operand" "=a") 409218334Speter (div:SI (match_operand:SI 1 "register_operand" "0") 409350650Sobrien (match_operand:SI 2 "nonimmediate_operand" "rm"))) 409418334Speter (set (match_operand:SI 3 "register_operand" "=&d") 409518334Speter (mod:SI (match_dup 1) (match_dup 2)))] 409618334Speter "" 409718334Speter "* 409818334Speter{ 409918334Speter#ifdef INTEL_SYNTAX 410018334Speter output_asm_insn (\"cdq\", operands); 410118334Speter#else 410218334Speter output_asm_insn (\"cltd\", operands); 410318334Speter#endif 410418334Speter return AS1 (idiv%L0,%2); 410550650Sobrien}" 410650650Sobrien [(set_attr "type" "idiv")]) 410718334Speter 410818334Speter(define_insn "divmodhi4" 410918334Speter [(set (match_operand:HI 0 "register_operand" "=a") 411018334Speter (div:HI (match_operand:HI 1 "register_operand" "0") 411150650Sobrien (match_operand:HI 2 "nonimmediate_operand" "rm"))) 411218334Speter (set (match_operand:HI 3 "register_operand" "=&d") 411318334Speter (mod:HI (match_dup 1) (match_dup 2)))] 411418334Speter "" 411550650Sobrien "cwtd\;idiv%W0 %2" 411650650Sobrien [(set_attr "type" "idiv")]) 411718334Speter 411818334Speter;; ??? Can we make gcc zero extend operand[0]? 411918334Speter(define_insn "udivmodsi4" 412018334Speter [(set (match_operand:SI 0 "register_operand" "=a") 412118334Speter (udiv:SI (match_operand:SI 1 "register_operand" "0") 412250650Sobrien (match_operand:SI 2 "nonimmediate_operand" "rm"))) 412318334Speter (set (match_operand:SI 3 "register_operand" "=&d") 412418334Speter (umod:SI (match_dup 1) (match_dup 2)))] 412518334Speter "" 412618334Speter "* 412718334Speter{ 412818334Speter output_asm_insn (AS2 (xor%L3,%3,%3), operands); 412918334Speter return AS1 (div%L0,%2); 413050650Sobrien}" 413150650Sobrien [(set_attr "type" "idiv")]) 413218334Speter 413318334Speter;; ??? Can we make gcc zero extend operand[0]? 413418334Speter(define_insn "udivmodhi4" 413518334Speter [(set (match_operand:HI 0 "register_operand" "=a") 413618334Speter (udiv:HI (match_operand:HI 1 "register_operand" "0") 413750650Sobrien (match_operand:HI 2 "nonimmediate_operand" "rm"))) 413818334Speter (set (match_operand:HI 3 "register_operand" "=&d") 413918334Speter (umod:HI (match_dup 1) (match_dup 2)))] 414018334Speter "" 414118334Speter "* 414218334Speter{ 414318334Speter output_asm_insn (AS2 (xor%W0,%3,%3), operands); 414418334Speter return AS1 (div%W0,%2); 414550650Sobrien}" 414650650Sobrien [(set_attr "type" "idiv")]) 414718334Speter 414818334Speter/* 414918334Speter;;this should be a valid double division which we may want to add 415018334Speter 415118334Speter(define_insn "" 415218334Speter [(set (match_operand:SI 0 "register_operand" "=a") 415318334Speter (udiv:DI (match_operand:DI 1 "register_operand" "a") 415450650Sobrien (match_operand:SI 2 "nonimmediate_operand" "rm"))) 415518334Speter (set (match_operand:SI 3 "register_operand" "=d") 415618334Speter (umod:SI (match_dup 1) (match_dup 2)))] 415718334Speter "" 415850650Sobrien "div%L0 %2,%0" 415950650Sobrien [(set_attr "type" "idiv")]) 416018334Speter*/ 416118334Speter 416218334Speter;;- and instructions 416318334Speter 416418334Speter;; On i386, 416518334Speter;; movzbl %bl,%ebx 416618334Speter;; is faster than 416718334Speter;; andl $255,%ebx 416818334Speter;; 416918334Speter;; but if the reg is %eax, then the "andl" is faster. 417018334Speter;; 417118334Speter;; On i486, the "andl" is always faster than the "movzbl". 417218334Speter;; 417318334Speter;; On both i386 and i486, a three operand AND is as fast with movzbl or 417418334Speter;; movzwl as with andl, if operands[0] != operands[1]. 417518334Speter 417618334Speter;; The `r' in `rm' for operand 3 looks redundant, but it causes 417718334Speter;; optional reloads to be generated if op 3 is a pseudo in a stack slot. 417818334Speter 417918334Speter(define_insn "andsi3" 418050650Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 418150650Sobrien (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 418250650Sobrien (match_operand:SI 2 "general_operand" "ri,rm")))] 418318334Speter "" 418418334Speter "* 418518334Speter{ 418650650Sobrien HOST_WIDE_INT intval; 418750650Sobrien if (!rtx_equal_p (operands[0], operands[1]) 418850650Sobrien && rtx_equal_p (operands[0], operands[2])) 418918334Speter { 419050650Sobrien rtx tmp; 419150650Sobrien tmp = operands[1]; 419250650Sobrien operands[1] = operands[2]; 419350650Sobrien operands[2] = tmp; 419450650Sobrien } 419550650Sobrien switch (GET_CODE (operands[2])) 419650650Sobrien { 419750650Sobrien case CONST_INT: 419850650Sobrien if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) 419950650Sobrien break; 420050650Sobrien intval = INTVAL (operands[2]); 420150650Sobrien /* zero-extend 16->32? */ 420250650Sobrien if (intval == 0xffff && REG_P (operands[0]) 420318334Speter && (! REG_P (operands[1]) 420418334Speter || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0) 420550650Sobrien && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1]))) 420618334Speter { 420718334Speter /* ??? tege: Should forget CC_STATUS only if we clobber a 420818334Speter remembered operand. Fix that later. */ 420918334Speter CC_STATUS_INIT; 421018334Speter#ifdef INTEL_SYNTAX 421118334Speter return AS2 (movzx,%w1,%0); 421218334Speter#else 421318334Speter return AS2 (movz%W0%L0,%w1,%0); 421418334Speter#endif 421518334Speter } 421618334Speter 421750650Sobrien /* zero extend 8->32? */ 421850650Sobrien if (intval == 0xff && REG_P (operands[0]) 421918334Speter && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1])) 422018334Speter && (! REG_P (operands[1]) 422118334Speter || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0) 422250650Sobrien && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1]))) 422318334Speter { 422418334Speter /* ??? tege: Should forget CC_STATUS only if we clobber a 422518334Speter remembered operand. Fix that later. */ 422618334Speter CC_STATUS_INIT; 422718334Speter#ifdef INTEL_SYNTAX 422818334Speter return AS2 (movzx,%b1,%0); 422918334Speter#else 423018334Speter return AS2 (movz%B0%L0,%b1,%0); 423118334Speter#endif 423218334Speter } 423318334Speter 423450650Sobrien /* Check partial bytes.. non-QI-regs are not available */ 423550650Sobrien if (REG_P (operands[0]) && ! QI_REG_P (operands[0])) 423650650Sobrien break; 423750650Sobrien 423850650Sobrien /* only low byte has zero bits? */ 423950650Sobrien if (~(intval | 0xff) == 0) 424018334Speter { 424150650Sobrien intval &= 0xff; 424250650Sobrien if (REG_P (operands[0])) 424350650Sobrien { 424450650Sobrien if (intval == 0) 424550650Sobrien { 424650650Sobrien CC_STATUS_INIT; 424750650Sobrien return AS2 (xor%B0,%b0,%b0); 424850650Sobrien } 424918334Speter 425050650Sobrien /* we're better off with the 32-bit version if reg != EAX */ 425150650Sobrien /* the value is sign-extended in 8 bits */ 425250650Sobrien if (REGNO (operands[0]) != 0 && (intval & 0x80)) 425350650Sobrien break; 425418334Speter } 425518334Speter 425650650Sobrien CC_STATUS_INIT; 425750650Sobrien 425850650Sobrien operands[2] = GEN_INT (intval); 425950650Sobrien 426050650Sobrien if (intval == 0) 426150650Sobrien return AS2 (mov%B0,%2,%b0); 426250650Sobrien 426318334Speter return AS2 (and%B0,%2,%b0); 426418334Speter } 426518334Speter 426650650Sobrien /* only second byte has zero? */ 426750650Sobrien if (~(intval | 0xff00) == 0) 426818334Speter { 426918334Speter CC_STATUS_INIT; 427018334Speter 427150650Sobrien intval = (intval >> 8) & 0xff; 427250650Sobrien operands[2] = GEN_INT (intval); 427350650Sobrien if (intval == 0) 427418334Speter { 427550650Sobrien if (REG_P (operands[0])) 427650650Sobrien return AS2 (xor%B0,%h0,%h0); 427750650Sobrien operands[0] = adj_offsettable_operand (operands[0], 1); 427850650Sobrien return AS2 (mov%B0,%2,%b0); 427918334Speter } 428018334Speter 428150650Sobrien if (REG_P (operands[0])) 428250650Sobrien return AS2 (and%B0,%2,%h0); 428350650Sobrien 428450650Sobrien operands[0] = adj_offsettable_operand (operands[0], 1); 428550650Sobrien return AS2 (and%B0,%2,%b0); 428618334Speter } 428718334Speter 428850650Sobrien if (REG_P (operands[0])) 428950650Sobrien break; 429050650Sobrien 429150650Sobrien /* third byte has zero bits? */ 429250650Sobrien if (~(intval | 0xff0000) == 0) 429350650Sobrien { 429450650Sobrien intval = (intval >> 16) & 0xff; 429550650Sobrien operands[0] = adj_offsettable_operand (operands[0], 2); 429650650Sobrienbyte_and_operation: 429750650Sobrien CC_STATUS_INIT; 429850650Sobrien operands[2] = GEN_INT (intval); 429950650Sobrien if (intval == 0) 430050650Sobrien return AS2 (mov%B0,%2,%b0); 430150650Sobrien return AS2 (and%B0,%2,%b0); 430250650Sobrien } 430350650Sobrien 430450650Sobrien /* fourth byte has zero bits? */ 430550650Sobrien if (~(intval | 0xff000000) == 0) 430650650Sobrien { 430750650Sobrien intval = (intval >> 24) & 0xff; 430850650Sobrien operands[0] = adj_offsettable_operand (operands[0], 3); 430950650Sobrien goto byte_and_operation; 431050650Sobrien } 431150650Sobrien 431250650Sobrien /* Low word is zero? */ 431350650Sobrien if (intval == 0xffff0000) 431418334Speter { 431550650Sobrienword_zero_and_operation: 431650650Sobrien CC_STATUS_INIT; 431718334Speter operands[2] = const0_rtx; 431818334Speter return AS2 (mov%W0,%2,%w0); 431918334Speter } 432050650Sobrien 432150650Sobrien /* High word is zero? */ 432250650Sobrien if (intval == 0x0000ffff) 432350650Sobrien { 432450650Sobrien operands[0] = adj_offsettable_operand (operands[0], 2); 432550650Sobrien goto word_zero_and_operation; 432650650Sobrien } 432750650Sobrien 432850650Sobrien default: 432950650Sobrien break; 433018334Speter } 433118334Speter 433218334Speter return AS2 (and%L0,%2,%0); 433352296Sobrien}" 433452296Sobrien [(set_attr "type" "binary")]) 433518334Speter 433618334Speter(define_insn "andhi3" 433750650Sobrien [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 433850650Sobrien (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 433918334Speter (match_operand:HI 2 "general_operand" "ri,rm")))] 434018334Speter "" 434118334Speter "* 434218334Speter{ 434318334Speter if (GET_CODE (operands[2]) == CONST_INT 434418334Speter && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) 434518334Speter { 434618334Speter /* Can we ignore the upper byte? */ 434718334Speter if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) 434818334Speter && (INTVAL (operands[2]) & 0xff00) == 0xff00) 434918334Speter { 435018334Speter CC_STATUS_INIT; 435118334Speter 435218334Speter if ((INTVAL (operands[2]) & 0xff) == 0) 435318334Speter { 435418334Speter operands[2] = const0_rtx; 435518334Speter return AS2 (mov%B0,%2,%b0); 435618334Speter } 435718334Speter 435818334Speter operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); 435918334Speter return AS2 (and%B0,%2,%b0); 436018334Speter } 436118334Speter 436218334Speter /* Can we ignore the lower byte? */ 436318334Speter /* ??? what about offsettable memory references? */ 436418334Speter if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & 0xff) == 0xff) 436518334Speter { 436618334Speter CC_STATUS_INIT; 436718334Speter 436818334Speter if ((INTVAL (operands[2]) & 0xff00) == 0) 436918334Speter { 437018334Speter operands[2] = const0_rtx; 437118334Speter return AS2 (mov%B0,%2,%h0); 437218334Speter } 437318334Speter 437418334Speter operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff); 437518334Speter return AS2 (and%B0,%2,%h0); 437618334Speter } 437750650Sobrien 437850650Sobrien /* use 32-bit ops on registers when there are no sign issues.. */ 437950650Sobrien if (REG_P (operands[0])) 438050650Sobrien { 438150650Sobrien if (!(INTVAL (operands[2]) & ~0x7fff)) 438250650Sobrien return AS2 (and%L0,%2,%k0); 438350650Sobrien } 438418334Speter } 438518334Speter 438650650Sobrien if (REG_P (operands[0]) 438750650Sobrien && i386_aligned_p (operands[2])) 438850650Sobrien { 438950650Sobrien CC_STATUS_INIT; 439050650Sobrien /* If op[2] is constant, we should zero-extend it and */ 439150650Sobrien /* make a note that op[0] has been zero-extended, so */ 439250650Sobrien /* that we could use 32-bit ops on it forthwith, but */ 439350650Sobrien /* there is no such reg-note available. Instead we do */ 439450650Sobrien /* a sign extension as that can result in shorter asm */ 439550650Sobrien operands[2] = i386_sext16_if_const (operands[2]); 439650650Sobrien return AS2 (and%L0,%k2,%k0); 439750650Sobrien } 439850650Sobrien 439950650Sobrien /* Use a 32-bit word with the upper bits set, invalidate CC */ 440050650Sobrien if (GET_CODE (operands[2]) == CONST_INT 440150650Sobrien && i386_aligned_p (operands[0])) 440250650Sobrien { 440350650Sobrien HOST_WIDE_INT val = INTVAL (operands[2]); 440450650Sobrien CC_STATUS_INIT; 440550650Sobrien val |= ~0xffff; 440650650Sobrien if (val != INTVAL (operands[2])) 440750650Sobrien operands[2] = GEN_INT (val); 440850650Sobrien return AS2 (and%L0,%k2,%k0); 440950650Sobrien } 441050650Sobrien 441118334Speter return AS2 (and%W0,%2,%0); 441252296Sobrien}" 441352296Sobrien [(set_attr "type" "binary")]) 441418334Speter 441518334Speter(define_insn "andqi3" 441650650Sobrien [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 441750650Sobrien (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 441818334Speter (match_operand:QI 2 "general_operand" "qn,qmn")))] 441918334Speter "" 442052296Sobrien "* return AS2 (and%B0,%2,%0);" 442152296Sobrien [(set_attr "type" "binary")]) 442218334Speter 442318334Speter/* I am nervous about these two.. add them later.. 442418334Speter;I presume this means that we have something in say op0= eax which is small 442518334Speter;and we want to and it with memory so we can do this by just an 442618334Speter;andb m,%al and have success. 442718334Speter(define_insn "" 442818334Speter [(set (match_operand:SI 0 "general_operand" "=r") 442918334Speter (and:SI (zero_extend:SI 443018334Speter (match_operand:HI 1 "nonimmediate_operand" "rm")) 443118334Speter (match_operand:SI 2 "general_operand" "0")))] 443218334Speter "GET_CODE (operands[2]) == CONST_INT 443318334Speter && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))" 443418334Speter "and%W0 %1,%0") 443518334Speter 443618334Speter(define_insn "" 443750650Sobrien [(set (match_operand:SI 0 "register_operand" "=q") 443818334Speter (and:SI 443918334Speter (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")) 444050650Sobrien (match_operand:SI 2 "register_operand" "0")))] 444118334Speter "GET_CODE (operands[2]) == CONST_INT 444218334Speter && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))" 444318334Speter "and%L0 %1,%0") 444418334Speter 444518334Speter*/ 444618334Speter 444718334Speter;;- Bit set (inclusive or) instructions 444818334Speter 444950650Sobrien;; This optimizes known byte-wide operations to memory, and in some cases 445050650Sobrien;; to QI registers.. Note that we don't want to use the QI registers too 445150650Sobrien;; aggressively, because often the 32-bit register instruction is the same 445250650Sobrien;; size, and likely to be faster on PentiumPro. 445318334Speter(define_insn "iorsi3" 445450650Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 445550650Sobrien (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 445618334Speter (match_operand:SI 2 "general_operand" "ri,rm")))] 445718334Speter "" 445818334Speter "* 445918334Speter{ 446050650Sobrien HOST_WIDE_INT intval; 446150650Sobrien switch (GET_CODE (operands[2])) 446218334Speter { 446350650Sobrien case CONST_INT: 446450650Sobrien 446550650Sobrien if (REG_P (operands[0]) && ! QI_REG_P (operands[0])) 446650650Sobrien break; 446750650Sobrien 446850650Sobrien /* don't try to optimize volatile accesses */ 446950650Sobrien if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) 447050650Sobrien break; 447150650Sobrien 447250650Sobrien intval = INTVAL (operands[2]); 447350650Sobrien if ((intval & ~0xff) == 0) 447450650Sobrien { 447550650Sobrien if (REG_P (operands[0])) 447650650Sobrien { 447750650Sobrien /* Do low byte access only for %eax or when high bit is set */ 447850650Sobrien if (REGNO (operands[0]) != 0 && !(intval & 0x80)) 447950650Sobrien break; 448050650Sobrien } 448150650Sobrien 448250650Sobrienbyte_or_operation: 448350650Sobrien CC_STATUS_INIT; 448450650Sobrien 448550650Sobrien if (intval != INTVAL (operands[2])) 448650650Sobrien operands[2] = GEN_INT (intval); 448750650Sobrien 448850650Sobrien if (intval == 0xff) 448950650Sobrien return AS2 (mov%B0,%2,%b0); 449050650Sobrien 449150650Sobrien return AS2 (or%B0,%2,%b0); 449250650Sobrien } 449350650Sobrien 449450650Sobrien /* second byte? */ 449550650Sobrien if ((intval & ~0xff00) == 0) 449618334Speter { 449750650Sobrien intval >>= 8; 449818334Speter 449950650Sobrien if (REG_P (operands[0])) 450050650Sobrien { 450150650Sobrien CC_STATUS_INIT; 450250650Sobrien operands[2] = GEN_INT (intval); 450350650Sobrien if (intval == 0xff) 450450650Sobrien return AS2 (mov%B0,%2,%h0); 450518334Speter 450650650Sobrien return AS2 (or%B0,%2,%h0); 450750650Sobrien } 450850650Sobrien 450950650Sobrien operands[0] = adj_offsettable_operand (operands[0], 1); 451050650Sobrien goto byte_or_operation; 451118334Speter } 451218334Speter 451350650Sobrien if (REG_P (operands[0])) 451450650Sobrien break; 451550650Sobrien 451650650Sobrien /* third byte? */ 451750650Sobrien if ((intval & ~0xff0000) == 0) 451818334Speter { 451950650Sobrien intval >>= 16; 452050650Sobrien operands[0] = adj_offsettable_operand (operands[0], 2); 452150650Sobrien goto byte_or_operation; 452250650Sobrien } 452318334Speter 452450650Sobrien /* fourth byte? */ 452550650Sobrien if ((intval & ~0xff000000) == 0) 452650650Sobrien { 452750650Sobrien intval = (intval >> 24) & 0xff; 452850650Sobrien operands[0] = adj_offsettable_operand (operands[0], 3); 452950650Sobrien goto byte_or_operation; 453050650Sobrien } 453118334Speter 453250650Sobrien default: 453350650Sobrien break; 453418334Speter } 453518334Speter 453618334Speter return AS2 (or%L0,%2,%0); 453752296Sobrien}" 453852296Sobrien [(set_attr "type" "binary")]) 453918334Speter 454018334Speter(define_insn "iorhi3" 454150650Sobrien [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 454250650Sobrien (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 454318334Speter (match_operand:HI 2 "general_operand" "ri,rm")))] 454418334Speter "" 454518334Speter "* 454618334Speter{ 454750650Sobrien HOST_WIDE_INT intval; 454850650Sobrien switch (GET_CODE (operands[2])) 454918334Speter { 455050650Sobrien case CONST_INT: 455118334Speter 455250650Sobrien if (REG_P (operands[0]) && ! QI_REG_P (operands[0])) 455350650Sobrien break; 455418334Speter 455550650Sobrien /* don't try to optimize volatile accesses */ 455650650Sobrien if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) 455750650Sobrien break; 455850650Sobrien 455950650Sobrien intval = 0xffff & INTVAL (operands[2]); 456050650Sobrien 456150650Sobrien if ((intval & 0xff00) == 0) 456250650Sobrien { 456350650Sobrien if (REG_P (operands[0])) 456450650Sobrien { 456550650Sobrien /* Do low byte access only for %eax or when high bit is set */ 456650650Sobrien if (REGNO (operands[0]) != 0 && !(intval & 0x80)) 456750650Sobrien break; 456850650Sobrien } 456950650Sobrien 457050650Sobrienbyte_or_operation: 457150650Sobrien CC_STATUS_INIT; 457250650Sobrien 457350650Sobrien if (intval == 0xff) 457450650Sobrien return AS2 (mov%B0,%2,%b0); 457550650Sobrien 457650650Sobrien return AS2 (or%B0,%2,%b0); 457718334Speter } 457818334Speter 457950650Sobrien /* high byte? */ 458050650Sobrien if ((intval & 0xff) == 0) 458118334Speter { 458250650Sobrien intval >>= 8; 458350650Sobrien operands[2] = GEN_INT (intval); 458418334Speter 458550650Sobrien if (REG_P (operands[0])) 458650650Sobrien { 458750650Sobrien CC_STATUS_INIT; 458850650Sobrien if (intval == 0xff) 458950650Sobrien return AS2 (mov%B0,%2,%h0); 459018334Speter 459150650Sobrien return AS2 (or%B0,%2,%h0); 459250650Sobrien } 459350650Sobrien 459450650Sobrien operands[0] = adj_offsettable_operand (operands[0], 1); 459550650Sobrien 459650650Sobrien goto byte_or_operation; 459718334Speter } 459850650Sobrien 459950650Sobrien default: 460050650Sobrien break; 460118334Speter } 460218334Speter 460350650Sobrien if (REG_P (operands[0]) 460450650Sobrien && i386_aligned_p (operands[2])) 460550650Sobrien { 460650650Sobrien CC_STATUS_INIT; 460750650Sobrien operands[2] = i386_sext16_if_const (operands[2]); 460850650Sobrien return AS2 (or%L0,%k2,%k0); 460950650Sobrien } 461050650Sobrien 461150650Sobrien if (GET_CODE (operands[2]) == CONST_INT 461250650Sobrien && i386_aligned_p (operands[0])) 461350650Sobrien { 461450650Sobrien CC_STATUS_INIT; 461550650Sobrien intval = 0xffff & INTVAL (operands[2]); 461650650Sobrien if (intval != INTVAL (operands[2])) 461750650Sobrien operands[2] = GEN_INT (intval); 461850650Sobrien return AS2 (or%L0,%2,%k0); 461950650Sobrien } 462050650Sobrien 462118334Speter return AS2 (or%W0,%2,%0); 462252296Sobrien}" 462352296Sobrien [(set_attr "type" "binary")]) 462418334Speter 462518334Speter(define_insn "iorqi3" 462650650Sobrien [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 462750650Sobrien (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 462818334Speter (match_operand:QI 2 "general_operand" "qn,qmn")))] 462918334Speter "" 463052296Sobrien "* return AS2 (or%B0,%2,%0);" 463152296Sobrien [(set_attr "type" "binary")]) 463218334Speter 463318334Speter;;- xor instructions 463418334Speter 463518334Speter(define_insn "xorsi3" 463650650Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 463750650Sobrien (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 463818334Speter (match_operand:SI 2 "general_operand" "ri,rm")))] 463918334Speter "" 464018334Speter "* 464118334Speter{ 464250650Sobrien HOST_WIDE_INT intval; 464350650Sobrien switch (GET_CODE (operands[2])) 464418334Speter { 464550650Sobrien case CONST_INT: 464650650Sobrien 464750650Sobrien if (REG_P (operands[0]) && ! QI_REG_P (operands[0])) 464850650Sobrien break; 464950650Sobrien 465050650Sobrien /* don't try to optimize volatile accesses */ 465150650Sobrien if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) 465250650Sobrien break; 465350650Sobrien 465450650Sobrien intval = INTVAL (operands[2]); 465550650Sobrien if ((intval & ~0xff) == 0) 465650650Sobrien { 465750650Sobrien if (REG_P (operands[0])) 465850650Sobrien { 465950650Sobrien /* Do low byte access only for %eax or when high bit is set */ 466050650Sobrien if (REGNO (operands[0]) != 0 && !(intval & 0x80)) 466150650Sobrien break; 466250650Sobrien } 466350650Sobrien 466450650Sobrienbyte_xor_operation: 466550650Sobrien CC_STATUS_INIT; 466650650Sobrien 466752296Sobrien if (intval == 0xff 466852296Sobrien && (!TARGET_PENTIUM || optimize_size 466952296Sobrien || (GET_CODE (operands[0]) == MEM 467052296Sobrien && memory_address_info (XEXP (operands[0], 0), 1)))) 467150650Sobrien return AS1 (not%B0,%b0); 467250650Sobrien 467350650Sobrien if (intval != INTVAL (operands[2])) 467450650Sobrien operands[2] = GEN_INT (intval); 467550650Sobrien return AS2 (xor%B0,%2,%b0); 467650650Sobrien } 467750650Sobrien 467850650Sobrien /* second byte? */ 467950650Sobrien if ((intval & ~0xff00) == 0) 468018334Speter { 468150650Sobrien intval >>= 8; 468218334Speter 468350650Sobrien if (REG_P (operands[0])) 468450650Sobrien { 468550650Sobrien CC_STATUS_INIT; 468652296Sobrien if (intval == 0xff 468752296Sobrien && (!TARGET_PENTIUM || optimize_size 468852296Sobrien || (GET_CODE (operands[0]) == MEM 468952296Sobrien && memory_address_info (XEXP (operands[0], 0), 1)))) 469050650Sobrien return AS1 (not%B0,%h0); 469118334Speter 469250650Sobrien operands[2] = GEN_INT (intval); 469350650Sobrien return AS2 (xor%B0,%2,%h0); 469450650Sobrien } 469550650Sobrien 469650650Sobrien operands[0] = adj_offsettable_operand (operands[0], 1); 469750650Sobrien 469850650Sobrien goto byte_xor_operation; 469918334Speter } 470018334Speter 470150650Sobrien if (REG_P (operands[0])) 470250650Sobrien break; 470350650Sobrien 470450650Sobrien /* third byte? */ 470550650Sobrien if ((intval & ~0xff0000) == 0) 470618334Speter { 470750650Sobrien intval >>= 16; 470850650Sobrien operands[0] = adj_offsettable_operand (operands[0], 2); 470950650Sobrien goto byte_xor_operation; 471050650Sobrien } 471118334Speter 471250650Sobrien /* fourth byte? */ 471350650Sobrien if ((intval & ~0xff000000) == 0) 471450650Sobrien { 471550650Sobrien intval = (intval >> 24) & 0xff; 471650650Sobrien operands[0] = adj_offsettable_operand (operands[0], 3); 471750650Sobrien goto byte_xor_operation; 471850650Sobrien } 471918334Speter 472050650Sobrien default: 472150650Sobrien break; 472218334Speter } 472318334Speter 472418334Speter return AS2 (xor%L0,%2,%0); 472552296Sobrien}" 472652296Sobrien [(set_attr "type" "binary")]) 472718334Speter 472818334Speter(define_insn "xorhi3" 472950650Sobrien [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 473050650Sobrien (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 473118334Speter (match_operand:HI 2 "general_operand" "ri,rm")))] 473218334Speter "" 473318334Speter "* 473418334Speter{ 473518334Speter if (GET_CODE (operands[2]) == CONST_INT 473618334Speter && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) 473718334Speter { 473818334Speter /* Can we ignore the upper byte? */ 473918334Speter if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) 474018334Speter && (INTVAL (operands[2]) & 0xff00) == 0) 474118334Speter { 474218334Speter CC_STATUS_INIT; 474318334Speter if (INTVAL (operands[2]) & 0xffff0000) 474418334Speter operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff); 474518334Speter 474652296Sobrien if (INTVAL (operands[2]) == 0xff 474752296Sobrien && (!TARGET_PENTIUM || optimize_size 474852296Sobrien || (GET_CODE (operands[0]) == MEM 474952296Sobrien && memory_address_info (XEXP (operands[0], 0), 1)))) 475018334Speter return AS1 (not%B0,%b0); 475118334Speter 475218334Speter return AS2 (xor%B0,%2,%b0); 475318334Speter } 475418334Speter 475518334Speter /* Can we ignore the lower byte? */ 475618334Speter /* ??? what about offsettable memory references? */ 475718334Speter if (QI_REG_P (operands[0]) 475818334Speter && (INTVAL (operands[2]) & 0xff) == 0) 475918334Speter { 476018334Speter CC_STATUS_INIT; 476118334Speter operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff); 476218334Speter 476352296Sobrien if (INTVAL (operands[2]) == 0xff 476452296Sobrien && (!TARGET_PENTIUM || optimize_size 476552296Sobrien || (GET_CODE (operands[0]) == MEM 476652296Sobrien && memory_address_info (XEXP (operands[0], 0), 1)))) 476718334Speter return AS1 (not%B0,%h0); 476818334Speter 476918334Speter return AS2 (xor%B0,%2,%h0); 477018334Speter } 477118334Speter } 477218334Speter 477350650Sobrien if (REG_P (operands[0]) 477450650Sobrien && i386_aligned_p (operands[2])) 477550650Sobrien { 477650650Sobrien CC_STATUS_INIT; 477750650Sobrien operands[2] = i386_sext16_if_const (operands[2]); 477850650Sobrien return AS2 (xor%L0,%k2,%k0); 477950650Sobrien } 478050650Sobrien 478150650Sobrien if (GET_CODE (operands[2]) == CONST_INT 478250650Sobrien && i386_aligned_p (operands[0])) 478350650Sobrien { 478450650Sobrien HOST_WIDE_INT intval; 478550650Sobrien CC_STATUS_INIT; 478650650Sobrien intval = 0xffff & INTVAL (operands[2]); 478750650Sobrien if (intval != INTVAL (operands[2])) 478850650Sobrien operands[2] = GEN_INT (intval); 478950650Sobrien return AS2 (xor%L0,%2,%k0); 479050650Sobrien } 479150650Sobrien 479218334Speter return AS2 (xor%W0,%2,%0); 479352296Sobrien}" 479452296Sobrien [(set_attr "type" "binary")]) 479518334Speter 479618334Speter(define_insn "xorqi3" 479750650Sobrien [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 479850650Sobrien (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 479918334Speter (match_operand:QI 2 "general_operand" "qn,qm")))] 480018334Speter "" 480152296Sobrien "* return AS2 (xor%B0,%2,%0);" 480252296Sobrien [(set_attr "type" "binary")]) 480318334Speter 480450650Sobrien;; logical operations for DImode 480550650Sobrien 480650650Sobrien(define_insn "anddi3" 480752296Sobrien [(set (match_operand:DI 0 "general_operand" "=&r,&ro") 480852296Sobrien (and:DI (match_operand:DI 1 "general_operand" "%0,0") 480952296Sobrien (match_operand:DI 2 "general_operand" "oriF,riF")))] 481050650Sobrien "" 481152296Sobrien "#" 481252296Sobrien [(set_attr "type" "binary")]) 481350650Sobrien 481452296Sobrien 481550650Sobrien(define_insn "iordi3" 481652296Sobrien [(set (match_operand:DI 0 "general_operand" "=&r,&ro") 481752296Sobrien (ior:DI (match_operand:DI 1 "general_operand" "%0,0") 481852296Sobrien (match_operand:DI 2 "general_operand" "oriF,riF")))] 481950650Sobrien "" 482052296Sobrien "#" 482152296Sobrien [(set_attr "type" "binary")]) 482252296Sobrien 482350650Sobrien(define_insn "xordi3" 482452296Sobrien [(set (match_operand:DI 0 "general_operand" "=&r,&ro") 482552296Sobrien (xor:DI (match_operand:DI 1 "general_operand" "%0,0") 482652296Sobrien (match_operand:DI 2 "general_operand" "oriF,riF")))] 482750650Sobrien "" 482852296Sobrien "#" 482952296Sobrien [(set_attr "type" "binary")]) 483050650Sobrien 483150650Sobrien(define_split 483252296Sobrien [(set (match_operand:DI 0 "general_operand" "") 483352296Sobrien (match_operator:DI 3 "ix86_logical_operator" 483452296Sobrien [(match_operand:DI 1 "general_operand" "") 483552296Sobrien (match_operand:DI 2 "general_operand" "")]))] 483652296Sobrien "" 483752296Sobrien [(set (match_dup 4) (match_op_dup:SI 3 [(match_dup 6) (match_dup 8)])) 483852296Sobrien (set (match_dup 5) (match_op_dup:SI 3 [(match_dup 7) (match_dup 9)]))] 483952296Sobrien "split_di (&operands[0], 1, &operands[4], &operands[5]); 484052296Sobrien split_di (&operands[1], 1, &operands[6], &operands[7]); 484152296Sobrien split_di (&operands[2], 1, &operands[8], &operands[9]);") 484250650Sobrien 484318334Speter;;- negation instructions 484418334Speter 484518334Speter(define_insn "negdi2" 484618334Speter [(set (match_operand:DI 0 "general_operand" "=&ro") 484718334Speter (neg:DI (match_operand:DI 1 "general_operand" "0")))] 484818334Speter "" 484918334Speter "* 485018334Speter{ 485118334Speter rtx xops[2], low[1], high[1]; 485218334Speter 485318334Speter CC_STATUS_INIT; 485418334Speter 485518334Speter split_di (operands, 1, low, high); 485618334Speter xops[0] = const0_rtx; 485718334Speter xops[1] = high[0]; 485818334Speter 485918334Speter output_asm_insn (AS1 (neg%L0,%0), low); 486018334Speter output_asm_insn (AS2 (adc%L1,%0,%1), xops); 486118334Speter output_asm_insn (AS1 (neg%L0,%0), high); 486218334Speter RET; 486318334Speter}") 486418334Speter 486518334Speter(define_insn "negsi2" 486650650Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 486750650Sobrien (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))] 486818334Speter "" 486918334Speter "neg%L0 %0") 487018334Speter 487118334Speter(define_insn "neghi2" 487250650Sobrien [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 487350650Sobrien (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))] 487418334Speter "" 487552296Sobrien "* 487652296Sobrien if (REG_P (operands[0]) && i386_cc_probably_useless_p (insn)) 487752296Sobrien { 487852296Sobrien CC_STATUS_INIT; 487952296Sobrien return AS1(neg%L0,%k0); 488052296Sobrien } 488152296Sobrien return AS1(neg%W0,%0);") 488218334Speter 488318334Speter(define_insn "negqi2" 488450650Sobrien [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 488550650Sobrien (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))] 488618334Speter "" 488718334Speter "neg%B0 %0") 488818334Speter 488918334Speter(define_insn "negsf2" 489018334Speter [(set (match_operand:SF 0 "register_operand" "=f") 489150650Sobrien (neg:SF (match_operand:SF 1 "register_operand" "0")))] 489218334Speter "TARGET_80387" 489352296Sobrien "fchs" 489452296Sobrien [(set_attr "type" "fpop")]) 489518334Speter 489618334Speter(define_insn "negdf2" 489718334Speter [(set (match_operand:DF 0 "register_operand" "=f") 489850650Sobrien (neg:DF (match_operand:DF 1 "register_operand" "0")))] 489918334Speter "TARGET_80387" 490052296Sobrien "fchs" 490152296Sobrien [(set_attr "type" "fpop")]) 490218334Speter 490318334Speter(define_insn "" 490418334Speter [(set (match_operand:DF 0 "register_operand" "=f") 490550650Sobrien (neg:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))] 490618334Speter "TARGET_80387" 490752296Sobrien "fchs" 490852296Sobrien [(set_attr "type" "fpop")]) 490918334Speter 491018334Speter(define_insn "negxf2" 491118334Speter [(set (match_operand:XF 0 "register_operand" "=f") 491250650Sobrien (neg:XF (match_operand:XF 1 "register_operand" "0")))] 491318334Speter "TARGET_80387" 491452296Sobrien "fchs" 491552296Sobrien [(set_attr "type" "fpop")]) 491618334Speter 491718334Speter(define_insn "" 491818334Speter [(set (match_operand:XF 0 "register_operand" "=f") 491950650Sobrien (neg:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))] 492018334Speter "TARGET_80387" 492152296Sobrien "fchs" 492252296Sobrien [(set_attr "type" "fpop")]) 492318334Speter 492418334Speter;; Absolute value instructions 492518334Speter 492618334Speter(define_insn "abssf2" 492718334Speter [(set (match_operand:SF 0 "register_operand" "=f") 492850650Sobrien (abs:SF (match_operand:SF 1 "register_operand" "0")))] 492918334Speter "TARGET_80387" 493050650Sobrien "fabs" 493150650Sobrien [(set_attr "type" "fpop")]) 493218334Speter 493318334Speter(define_insn "absdf2" 493418334Speter [(set (match_operand:DF 0 "register_operand" "=f") 493550650Sobrien (abs:DF (match_operand:DF 1 "register_operand" "0")))] 493618334Speter "TARGET_80387" 493750650Sobrien "fabs" 493850650Sobrien [(set_attr "type" "fpop")]) 493918334Speter 494018334Speter(define_insn "" 494118334Speter [(set (match_operand:DF 0 "register_operand" "=f") 494250650Sobrien (abs:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))] 494318334Speter "TARGET_80387" 494450650Sobrien "fabs" 494550650Sobrien [(set_attr "type" "fpop")]) 494618334Speter 494718334Speter(define_insn "absxf2" 494818334Speter [(set (match_operand:XF 0 "register_operand" "=f") 494950650Sobrien (abs:XF (match_operand:XF 1 "register_operand" "0")))] 495018334Speter "TARGET_80387" 495150650Sobrien "fabs" 495250650Sobrien [(set_attr "type" "fpop")]) 495318334Speter 495418334Speter(define_insn "" 495518334Speter [(set (match_operand:XF 0 "register_operand" "=f") 495650650Sobrien (abs:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))] 495718334Speter "TARGET_80387" 495850650Sobrien "fabs" 495950650Sobrien [(set_attr "type" "fpop")]) 496018334Speter 496118334Speter(define_insn "sqrtsf2" 496218334Speter [(set (match_operand:SF 0 "register_operand" "=f") 496350650Sobrien (sqrt:SF (match_operand:SF 1 "register_operand" "0")))] 496450650Sobrien "! TARGET_NO_FANCY_MATH_387 && TARGET_80387" 496518334Speter "fsqrt") 496618334Speter 496718334Speter(define_insn "sqrtdf2" 496818334Speter [(set (match_operand:DF 0 "register_operand" "=f") 496950650Sobrien (sqrt:DF (match_operand:DF 1 "register_operand" "0")))] 497018334Speter "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 497118334Speter && (TARGET_IEEE_FP || flag_fast_math) " 497218334Speter "fsqrt") 497318334Speter 497418334Speter(define_insn "" 497518334Speter [(set (match_operand:DF 0 "register_operand" "=f") 497618334Speter (sqrt:DF (float_extend:DF 497750650Sobrien (match_operand:SF 1 "register_operand" "0"))))] 497850650Sobrien "! TARGET_NO_FANCY_MATH_387 && TARGET_80387" 497918334Speter "fsqrt") 498018334Speter 498118334Speter(define_insn "sqrtxf2" 498218334Speter [(set (match_operand:XF 0 "register_operand" "=f") 498350650Sobrien (sqrt:XF (match_operand:XF 1 "register_operand" "0")))] 498418334Speter "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 498518334Speter && (TARGET_IEEE_FP || flag_fast_math) " 498618334Speter "fsqrt") 498718334Speter 498818334Speter(define_insn "" 498918334Speter [(set (match_operand:XF 0 "register_operand" "=f") 499018334Speter (sqrt:XF (float_extend:XF 499150650Sobrien (match_operand:DF 1 "register_operand" "0"))))] 499250650Sobrien "! TARGET_NO_FANCY_MATH_387 && TARGET_80387" 499318334Speter "fsqrt") 499418334Speter 499518334Speter(define_insn "" 499618334Speter [(set (match_operand:XF 0 "register_operand" "=f") 499718334Speter (sqrt:XF (float_extend:XF 499850650Sobrien (match_operand:SF 1 "register_operand" "0"))))] 499950650Sobrien "! TARGET_NO_FANCY_MATH_387 && TARGET_80387" 500018334Speter "fsqrt") 500118334Speter 500218334Speter(define_insn "sindf2" 500318334Speter [(set (match_operand:DF 0 "register_operand" "=f") 500418334Speter (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))] 500550650Sobrien "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" 500618334Speter "fsin") 500718334Speter 500818334Speter(define_insn "sinsf2" 500918334Speter [(set (match_operand:SF 0 "register_operand" "=f") 501018334Speter (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))] 501150650Sobrien "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" 501218334Speter "fsin") 501318334Speter 501418334Speter(define_insn "" 501518334Speter [(set (match_operand:DF 0 "register_operand" "=f") 501618334Speter (unspec:DF [(float_extend:DF 501718334Speter (match_operand:SF 1 "register_operand" "0"))] 1))] 501850650Sobrien "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" 501918334Speter "fsin") 502018334Speter 502118334Speter(define_insn "sinxf2" 502218334Speter [(set (match_operand:XF 0 "register_operand" "=f") 502318334Speter (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))] 502450650Sobrien "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" 502518334Speter "fsin") 502618334Speter 502718334Speter(define_insn "cosdf2" 502818334Speter [(set (match_operand:DF 0 "register_operand" "=f") 502918334Speter (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))] 503050650Sobrien "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" 503118334Speter "fcos") 503218334Speter 503318334Speter(define_insn "cossf2" 503418334Speter [(set (match_operand:SF 0 "register_operand" "=f") 503518334Speter (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))] 503650650Sobrien "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" 503718334Speter "fcos") 503818334Speter 503918334Speter(define_insn "" 504018334Speter [(set (match_operand:DF 0 "register_operand" "=f") 504118334Speter (unspec:DF [(float_extend:DF 504218334Speter (match_operand:SF 1 "register_operand" "0"))] 2))] 504350650Sobrien "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" 504418334Speter "fcos") 504518334Speter 504618334Speter(define_insn "cosxf2" 504718334Speter [(set (match_operand:XF 0 "register_operand" "=f") 504818334Speter (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))] 504950650Sobrien "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" 505018334Speter "fcos") 505118334Speter 505218334Speter;;- one complement instructions 505318334Speter 505418334Speter(define_insn "one_cmplsi2" 505550650Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 505650650Sobrien (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))] 505718334Speter "" 505852296Sobrien "* 505952296Sobrien{ 506052296Sobrien /* A Pentium NOT is not pariable. Output it only in case of complex 506152296Sobrien memory address, because XOR will be inpariable anyway because 506252296Sobrien of immediate/displacement rule. */ 506318334Speter 506452296Sobrien if (TARGET_PENTIUM && !optimize_size 506552296Sobrien && (GET_CODE (operands[0]) != MEM 506652296Sobrien || memory_address_info (XEXP (operands[0], 0), 1) == 0)) 506752296Sobrien { 506852296Sobrien rtx xops[2]; 506952296Sobrien xops[0] = operands[0]; 507052296Sobrien xops[1] = GEN_INT (0xffffffff); 507152296Sobrien output_asm_insn (AS2 (xor%L0,%1,%0), xops); 507252296Sobrien RET; 507352296Sobrien } 507452296Sobrien else 507552296Sobrien return AS1 (not%L0,%0); 507652296Sobrien}") 507752296Sobrien 507818334Speter(define_insn "one_cmplhi2" 507950650Sobrien [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 508050650Sobrien (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))] 508118334Speter "" 508252296Sobrien "* 508352296Sobrien{ 508452296Sobrien /* A Pentium NOT is not pariable. Output it only in case of complex 508552296Sobrien memory address, because XOR will be inpariable anyway because 508652296Sobrien of immediate/displacement rule. */ 508718334Speter 508852296Sobrien if (TARGET_PENTIUM && !optimize_size 508952296Sobrien && (GET_CODE (operands[0]) != MEM 509052296Sobrien || memory_address_info (XEXP (operands[0], 0), 1) == 0)) 509152296Sobrien { 509252296Sobrien rtx xops[2]; 509352296Sobrien xops[0] = operands[0]; 509452296Sobrien xops[1] = GEN_INT (0xffff); 509552296Sobrien if (REG_P (operands[0]) 509652296Sobrien && i386_cc_probably_useless_p (insn)) 509752296Sobrien { 509852296Sobrien CC_STATUS_INIT; 509952296Sobrien output_asm_insn (AS2 (xor%L0,%1,%k0), xops); 510052296Sobrien } 510152296Sobrien else 510252296Sobrien output_asm_insn (AS2 (xor%W0,%1,%0), xops); 510352296Sobrien RET; 510452296Sobrien } 510552296Sobrien else 510652296Sobrien { 510752296Sobrien if (REG_P (operands[0]) 510852296Sobrien && i386_cc_probably_useless_p (insn)) 510952296Sobrien { 511052296Sobrien CC_STATUS_INIT; 511152296Sobrien return AS1 (not%L0,%k0); 511252296Sobrien } 511352296Sobrien return AS1 (not%W0,%0); 511452296Sobrien } 511552296Sobrien}") 511652296Sobrien 511718334Speter(define_insn "one_cmplqi2" 511850650Sobrien [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 511950650Sobrien (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))] 512018334Speter "" 512152296Sobrien "* 512252296Sobrien{ 512352296Sobrien /* A Pentium NOT is not pariable. Output it only in case of complex 512452296Sobrien memory address, because XOR will be inpariable anyway because 512552296Sobrien of immediate/displacement rule. */ 512652296Sobrien 512752296Sobrien if (TARGET_PENTIUM && !optimize_size 512852296Sobrien && (GET_CODE (operands[0]) != MEM 512952296Sobrien || memory_address_info (XEXP (operands[0], 0), 1) == 0)) 513052296Sobrien { 513152296Sobrien rtx xops[2]; 513252296Sobrien xops[0] = operands[0]; 513352296Sobrien xops[1] = GEN_INT (0xff); 513452296Sobrien output_asm_insn (AS2 (xor%B0,%1,%0), xops); 513552296Sobrien RET; 513652296Sobrien } 513752296Sobrien else 513852296Sobrien return AS1 (not%B0,%0); 513952296Sobrien}") 514018334Speter 514118334Speter;;- arithmetic shift instructions 514218334Speter 514318334Speter;; DImode shifts are implemented using the i386 "shift double" opcode, 514418334Speter;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count 514518334Speter;; is variable, then the count is in %cl and the "imm" operand is dropped 514618334Speter;; from the assembler input. 514718334Speter 514818334Speter;; This instruction shifts the target reg/mem as usual, but instead of 514918334Speter;; shifting in zeros, bits are shifted in from reg operand. If the insn 515018334Speter;; is a left shift double, bits are taken from the high order bits of 515118334Speter;; reg, else if the insn is a shift right double, bits are taken from the 515218334Speter;; low order bits of reg. So if %eax is "1234" and %edx is "5678", 515318334Speter;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345". 515418334Speter 515518334Speter;; Since sh[lr]d does not change the `reg' operand, that is done 515618334Speter;; separately, making all shifts emit pairs of shift double and normal 515718334Speter;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to 515818334Speter;; support a 63 bit shift, each shift where the count is in a reg expands 515950650Sobrien;; to a pair of shifts, a branch, a shift by 32 and a label. 516018334Speter 516118334Speter;; If the shift count is a constant, we need never emit more than one 516218334Speter;; shift pair, instead using moves and sign extension for counts greater 516318334Speter;; than 31. 516418334Speter 516518334Speter(define_expand "ashldi3" 516618334Speter [(set (match_operand:DI 0 "register_operand" "") 516718334Speter (ashift:DI (match_operand:DI 1 "register_operand" "") 516818334Speter (match_operand:QI 2 "nonmemory_operand" "")))] 516918334Speter "" 517018334Speter " 517118334Speter{ 517218334Speter if (GET_CODE (operands[2]) != CONST_INT 517318334Speter || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')) 517418334Speter { 517518334Speter operands[2] = copy_to_mode_reg (QImode, operands[2]); 517618334Speter emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1], 517718334Speter operands[2])); 517818334Speter } 517918334Speter else 518018334Speter emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2])); 518118334Speter 518218334Speter DONE; 518318334Speter}") 518418334Speter 518518334Speter(define_insn "ashldi3_const_int" 518618334Speter [(set (match_operand:DI 0 "register_operand" "=&r") 518718334Speter (ashift:DI (match_operand:DI 1 "register_operand" "0") 518818334Speter (match_operand:QI 2 "const_int_operand" "J")))] 518950650Sobrien "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')" 519018334Speter "* 519118334Speter{ 519218334Speter rtx xops[4], low[1], high[1]; 519318334Speter 519418334Speter CC_STATUS_INIT; 519518334Speter 519618334Speter split_di (operands, 1, low, high); 519718334Speter xops[0] = operands[2]; 519818334Speter xops[1] = const1_rtx; 519918334Speter xops[2] = low[0]; 520018334Speter xops[3] = high[0]; 520118334Speter 520218334Speter if (INTVAL (xops[0]) > 31) 520318334Speter { 520418334Speter output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */ 520518334Speter output_asm_insn (AS2 (xor%L2,%2,%2), xops); 520618334Speter 520718334Speter if (INTVAL (xops[0]) > 32) 520818334Speter { 520918334Speter xops[0] = GEN_INT (INTVAL (xops[0]) - 32); 521018334Speter output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */ 521118334Speter } 521218334Speter } 521318334Speter else 521418334Speter { 521518334Speter output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops); 521618334Speter output_asm_insn (AS2 (sal%L2,%0,%2), xops); 521718334Speter } 521818334Speter RET; 521918334Speter}") 522018334Speter 522118334Speter(define_insn "ashldi3_non_const_int" 522218334Speter [(set (match_operand:DI 0 "register_operand" "=&r") 522318334Speter (ashift:DI (match_operand:DI 1 "register_operand" "0") 522450650Sobrien (match_operand:QI 2 "register_operand" "c")))] 522518334Speter "" 522618334Speter "* 522718334Speter{ 522850650Sobrien rtx xops[5], low[1], high[1]; 522918334Speter 523018334Speter CC_STATUS_INIT; 523118334Speter 523218334Speter split_di (operands, 1, low, high); 523318334Speter xops[0] = operands[2]; 523450650Sobrien xops[1] = GEN_INT (32); 523518334Speter xops[2] = low[0]; 523618334Speter xops[3] = high[0]; 523750650Sobrien xops[4] = gen_label_rtx (); 523818334Speter 523918334Speter output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops); 524018334Speter output_asm_insn (AS2 (sal%L2,%0,%2), xops); 524150650Sobrien output_asm_insn (AS2 (test%B0,%1,%b0), xops); 524250650Sobrien output_asm_insn (AS1 (je,%X4), xops); 524350650Sobrien output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */ 524450650Sobrien output_asm_insn (AS2 (xor%L2,%2,%2), xops); 524550650Sobrien ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", 524650650Sobrien CODE_LABEL_NUMBER (xops[4])); 524718334Speter RET; 524818334Speter}") 524918334Speter 525052296Sobrien(define_expand "ashlsi3" 525152296Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "") 525252296Sobrien (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "") 525352296Sobrien (match_operand:SI 2 "nonmemory_operand" "")))] 525452296Sobrien "" 525552296Sobrien "") 525618334Speter 525752296Sobrien(define_expand "ashlhi3" 525852296Sobrien [(set (match_operand:HI 0 "nonimmediate_operand" "") 525952296Sobrien (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "") 526052296Sobrien (match_operand:HI 2 "nonmemory_operand" "")))] 526118334Speter "" 526252296Sobrien "") 526318334Speter 526452296Sobrien(define_expand "ashlqi3" 526552296Sobrien [(set (match_operand:QI 0 "nonimmediate_operand" "") 526652296Sobrien (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "") 526752296Sobrien (match_operand:QI 2 "nonmemory_operand" "")))] 526852296Sobrien "" 526952296Sobrien "") 527018334Speter 527152296Sobrien;; Pattern for shifts which can be encoded into an lea instruction. 527252296Sobrien;; This is kept as a separate pattern so that regmove can optimize cases 527352296Sobrien;; where we know the source and destination must match. 527452296Sobrien;; 527552296Sobrien;; Do not expose this pattern when optimizing for size since we never want 527652296Sobrien;; to use lea when optimizing for size since mov+sal is smaller than lea. 527718334Speter 527852296Sobrien(define_insn "" 527952296Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r") 528052296Sobrien (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r") 528152296Sobrien (match_operand:SI 2 "small_shift_operand" "M,M")))] 528252296Sobrien "! optimize_size" 528352296Sobrien "* return output_ashl (insn, operands);") 528418334Speter 528552296Sobrien;; Generic left shift pattern to catch all cases not handled by the 528652296Sobrien;; shift pattern above. 528752296Sobrien(define_insn "" 528852296Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 528952296Sobrien (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0") 529052296Sobrien (match_operand:SI 2 "nonmemory_operand" "cI")))] 529152296Sobrien "" 529252296Sobrien "* return output_ashl (insn, operands);") 529318334Speter 529452296Sobrien(define_insn "" 529552296Sobrien [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r") 529652296Sobrien (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r") 529752296Sobrien (match_operand:HI 2 "small_shift_operand" "M,M")))] 529852296Sobrien "! optimize_size" 529952296Sobrien "* return output_ashl (insn, operands);") 530052296Sobrien 530152296Sobrien(define_insn "" 530250650Sobrien [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 530350650Sobrien (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") 530418334Speter (match_operand:HI 2 "nonmemory_operand" "cI")))] 530518334Speter "" 530652296Sobrien "* return output_ashl (insn, operands);") 530718334Speter 530852296Sobrien(define_insn "" 530952296Sobrien [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q") 531052296Sobrien (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,q") 531152296Sobrien (match_operand:QI 2 "small_shift_operand" "M,M")))] 531252296Sobrien "! optimize_size" 531352296Sobrien "* return output_ashl (insn, operands);") 531418334Speter 531552296Sobrien;; Generic left shift pattern to catch all cases not handled by the 531652296Sobrien;; shift pattern above. 531752296Sobrien(define_insn "" 531850650Sobrien [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 531950650Sobrien (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0") 532018334Speter (match_operand:QI 2 "nonmemory_operand" "cI")))] 532118334Speter "" 532252296Sobrien "* return output_ashl (insn, operands);") 532318334Speter 532418334Speter;; See comment above `ashldi3' about how this works. 532518334Speter 532618334Speter(define_expand "ashrdi3" 532718334Speter [(set (match_operand:DI 0 "register_operand" "") 532818334Speter (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 532918334Speter (match_operand:QI 2 "nonmemory_operand" "")))] 533018334Speter "" 533118334Speter " 533218334Speter{ 533318334Speter if (GET_CODE (operands[2]) != CONST_INT 533418334Speter || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')) 533518334Speter { 533618334Speter operands[2] = copy_to_mode_reg (QImode, operands[2]); 533718334Speter emit_insn (gen_ashrdi3_non_const_int (operands[0], operands[1], 533818334Speter operands[2])); 533918334Speter } 534018334Speter else 534118334Speter emit_insn (gen_ashrdi3_const_int (operands[0], operands[1], operands[2])); 534218334Speter 534318334Speter DONE; 534418334Speter}") 534518334Speter 534650650Sobrien(define_insn "ashldi3_32" 534750650Sobrien [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m") 534850650Sobrien (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r") 534950650Sobrien (const_int 32)))] 535050650Sobrien "" 535150650Sobrien "* 535250650Sobrien{ 535350650Sobrien rtx low[2], high[2], xops[4]; 535450650Sobrien 535550650Sobrien split_di (operands, 2, low, high); 535650650Sobrien xops[0] = high[0]; 535750650Sobrien xops[1] = low[1]; 535850650Sobrien xops[2] = low[0]; 535950650Sobrien xops[3] = const0_rtx; 536050650Sobrien if (!rtx_equal_p (xops[0], xops[1])) 536150650Sobrien output_asm_insn (AS2 (mov%L0,%1,%0), xops); 536250650Sobrien 536350650Sobrien if (GET_CODE (low[0]) == MEM) 536450650Sobrien output_asm_insn (AS2 (mov%L2,%3,%2), xops); 536550650Sobrien else 536650650Sobrien output_asm_insn (AS2 (xor%L2,%2,%2), xops); 536750650Sobrien 536850650Sobrien RET; 536950650Sobrien}") 537050650Sobrien 537118334Speter(define_insn "ashrdi3_const_int" 537218334Speter [(set (match_operand:DI 0 "register_operand" "=&r") 537318334Speter (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") 537418334Speter (match_operand:QI 2 "const_int_operand" "J")))] 537550650Sobrien "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')" 537618334Speter "* 537718334Speter{ 537818334Speter rtx xops[4], low[1], high[1]; 537918334Speter 538018334Speter CC_STATUS_INIT; 538118334Speter 538218334Speter split_di (operands, 1, low, high); 538318334Speter xops[0] = operands[2]; 538418334Speter xops[1] = const1_rtx; 538518334Speter xops[2] = low[0]; 538618334Speter xops[3] = high[0]; 538718334Speter 538818334Speter if (INTVAL (xops[0]) > 31) 538918334Speter { 539018334Speter xops[1] = GEN_INT (31); 539118334Speter output_asm_insn (AS2 (mov%L2,%3,%2), xops); 539218334Speter output_asm_insn (AS2 (sar%L3,%1,%3), xops); /* shift by 32 */ 539318334Speter 539418334Speter if (INTVAL (xops[0]) > 32) 539518334Speter { 539618334Speter xops[0] = GEN_INT (INTVAL (xops[0]) - 32); 539718334Speter output_asm_insn (AS2 (sar%L2,%0,%2), xops); /* Remaining shift */ 539818334Speter } 539918334Speter } 540018334Speter else 540118334Speter { 540218334Speter output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops); 540318334Speter output_asm_insn (AS2 (sar%L3,%0,%3), xops); 540418334Speter } 540518334Speter 540618334Speter RET; 540718334Speter}") 540818334Speter 540918334Speter(define_insn "ashrdi3_non_const_int" 541018334Speter [(set (match_operand:DI 0 "register_operand" "=&r") 541118334Speter (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") 541250650Sobrien (match_operand:QI 2 "register_operand" "c")))] 541318334Speter "" 541418334Speter "* 541518334Speter{ 541650650Sobrien rtx xops[5], low[1], high[1]; 541718334Speter 541818334Speter CC_STATUS_INIT; 541918334Speter 542018334Speter split_di (operands, 1, low, high); 542118334Speter xops[0] = operands[2]; 542250650Sobrien xops[1] = GEN_INT (32); 542318334Speter xops[2] = low[0]; 542418334Speter xops[3] = high[0]; 542550650Sobrien xops[4] = gen_label_rtx (); 542618334Speter 542718334Speter output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops); 542818334Speter output_asm_insn (AS2 (sar%L3,%0,%3), xops); 542950650Sobrien output_asm_insn (AS2 (test%B0,%1,%b0), xops); 543050650Sobrien output_asm_insn (AS1 (je,%X4), xops); 543150650Sobrien xops[1] = GEN_INT (31); 543250650Sobrien output_asm_insn (AS2 (mov%L2,%3,%2), xops); 543350650Sobrien output_asm_insn (AS2 (sar%L3,%1,%3), xops); /* shift by 32 */ 543450650Sobrien ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", 543550650Sobrien CODE_LABEL_NUMBER (xops[4])); 543618334Speter RET; 543718334Speter}") 543818334Speter 543952296Sobrien(define_insn "ashrsi3_31" 544052296Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,d") 544152296Sobrien (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,a") 544252296Sobrien (const_int 31)))] 544352296Sobrien "!TARGET_PENTIUM || optimize_size" 544452296Sobrien "@ 544552296Sobrien sar%L0 $31,%0 544652296Sobrien cltd") 544752296Sobrien 544818334Speter(define_insn "ashrsi3" 544950650Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 545050650Sobrien (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 545118334Speter (match_operand:SI 2 "nonmemory_operand" "cI")))] 545218334Speter "" 545318334Speter "* 545418334Speter{ 545518334Speter if (REG_P (operands[2])) 545618334Speter return AS2 (sar%L0,%b2,%0); 545718334Speter else 545818334Speter return AS2 (sar%L0,%2,%0); 545918334Speter}") 546018334Speter 546118334Speter(define_insn "ashrhi3" 546250650Sobrien [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 546350650Sobrien (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 546418334Speter (match_operand:HI 2 "nonmemory_operand" "cI")))] 546518334Speter "" 546618334Speter "* 546718334Speter{ 546818334Speter if (REG_P (operands[2])) 546918334Speter return AS2 (sar%W0,%b2,%0); 547018334Speter else 547118334Speter return AS2 (sar%W0,%2,%0); 547218334Speter}") 547318334Speter 547418334Speter(define_insn "ashrqi3" 547550650Sobrien [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 547650650Sobrien (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 547718334Speter (match_operand:QI 2 "nonmemory_operand" "cI")))] 547818334Speter "" 547918334Speter "* 548018334Speter{ 548118334Speter if (REG_P (operands[2])) 548218334Speter return AS2 (sar%B0,%b2,%0); 548318334Speter else 548418334Speter return AS2 (sar%B0,%2,%0); 548518334Speter}") 548618334Speter 548718334Speter;;- logical shift instructions 548818334Speter 548918334Speter;; See comment above `ashldi3' about how this works. 549018334Speter 549118334Speter(define_expand "lshrdi3" 549218334Speter [(set (match_operand:DI 0 "register_operand" "") 549318334Speter (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 549418334Speter (match_operand:QI 2 "nonmemory_operand" "")))] 549518334Speter "" 549618334Speter " 549718334Speter{ 549818334Speter if (GET_CODE (operands[2]) != CONST_INT 549918334Speter || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')) 550018334Speter { 550118334Speter operands[2] = copy_to_mode_reg (QImode, operands[2]); 550218334Speter emit_insn (gen_lshrdi3_non_const_int (operands[0], operands[1], 550318334Speter operands[2])); 550418334Speter } 550518334Speter else 550618334Speter emit_insn (gen_lshrdi3_const_int (operands[0], operands[1], operands[2])); 550718334Speter 550818334Speter DONE; 550918334Speter}") 551018334Speter 551150650Sobrien(define_insn "lshrdi3_32" 551250650Sobrien [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m") 551350650Sobrien (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r") 551450650Sobrien (const_int 32)))] 551550650Sobrien "" 551650650Sobrien "* 551750650Sobrien{ 551850650Sobrien rtx low[2], high[2], xops[4]; 551950650Sobrien 552050650Sobrien split_di (operands, 2, low, high); 552150650Sobrien xops[0] = low[0]; 552250650Sobrien xops[1] = high[1]; 552350650Sobrien xops[2] = high[0]; 552450650Sobrien xops[3] = const0_rtx; 552550650Sobrien if (!rtx_equal_p (xops[0], xops[1])) 552650650Sobrien output_asm_insn (AS2 (mov%L0,%1,%0), xops); 552750650Sobrien 552850650Sobrien if (GET_CODE (low[0]) == MEM) 552950650Sobrien output_asm_insn (AS2 (mov%L2,%3,%2), xops); 553050650Sobrien else 553150650Sobrien output_asm_insn (AS2 (xor%L2,%2,%2), xops); 553250650Sobrien 553350650Sobrien RET; 553450650Sobrien}") 553550650Sobrien 553618334Speter(define_insn "lshrdi3_const_int" 553718334Speter [(set (match_operand:DI 0 "register_operand" "=&r") 553818334Speter (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") 553918334Speter (match_operand:QI 2 "const_int_operand" "J")))] 554050650Sobrien "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')" 554118334Speter "* 554218334Speter{ 554318334Speter rtx xops[4], low[1], high[1]; 554418334Speter 554518334Speter CC_STATUS_INIT; 554618334Speter 554718334Speter split_di (operands, 1, low, high); 554818334Speter xops[0] = operands[2]; 554918334Speter xops[1] = const1_rtx; 555018334Speter xops[2] = low[0]; 555118334Speter xops[3] = high[0]; 555218334Speter 555318334Speter if (INTVAL (xops[0]) > 31) 555418334Speter { 555518334Speter output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */ 555618334Speter output_asm_insn (AS2 (xor%L3,%3,%3), xops); 555718334Speter 555818334Speter if (INTVAL (xops[0]) > 32) 555918334Speter { 556018334Speter xops[0] = GEN_INT (INTVAL (xops[0]) - 32); 556118334Speter output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */ 556218334Speter } 556318334Speter } 556418334Speter else 556518334Speter { 556618334Speter output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops); 556718334Speter output_asm_insn (AS2 (shr%L3,%0,%3), xops); 556818334Speter } 556918334Speter 557018334Speter RET; 557118334Speter}") 557218334Speter 557318334Speter(define_insn "lshrdi3_non_const_int" 557418334Speter [(set (match_operand:DI 0 "register_operand" "=&r") 557518334Speter (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") 557650650Sobrien (match_operand:QI 2 "register_operand" "c")))] 557718334Speter "" 557818334Speter "* 557918334Speter{ 558050650Sobrien rtx xops[5], low[1], high[1]; 558118334Speter 558218334Speter CC_STATUS_INIT; 558318334Speter 558418334Speter split_di (operands, 1, low, high); 558518334Speter xops[0] = operands[2]; 558650650Sobrien xops[1] = GEN_INT (32); 558718334Speter xops[2] = low[0]; 558818334Speter xops[3] = high[0]; 558950650Sobrien xops[4] = gen_label_rtx (); 559018334Speter 559118334Speter output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops); 559218334Speter output_asm_insn (AS2 (shr%L3,%0,%3), xops); 559350650Sobrien output_asm_insn (AS2 (test%B0,%1,%b0), xops); 559450650Sobrien output_asm_insn (AS1 (je,%X4), xops); 559550650Sobrien output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */ 559650650Sobrien output_asm_insn (AS2 (xor%L3,%3,%3), xops); 559750650Sobrien ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", 559850650Sobrien CODE_LABEL_NUMBER (xops[4])); 559918334Speter RET; 560018334Speter}") 560118334Speter 560218334Speter(define_insn "lshrsi3" 560350650Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 560450650Sobrien (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 560518334Speter (match_operand:SI 2 "nonmemory_operand" "cI")))] 560618334Speter "" 560718334Speter "* 560818334Speter{ 560918334Speter if (REG_P (operands[2])) 561018334Speter return AS2 (shr%L0,%b2,%0); 561118334Speter else 561218334Speter return AS2 (shr%L0,%2,%1); 561318334Speter}") 561418334Speter 561518334Speter(define_insn "lshrhi3" 561650650Sobrien [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 561750650Sobrien (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 561818334Speter (match_operand:HI 2 "nonmemory_operand" "cI")))] 561918334Speter "" 562018334Speter "* 562118334Speter{ 562218334Speter if (REG_P (operands[2])) 562318334Speter return AS2 (shr%W0,%b2,%0); 562418334Speter else 562518334Speter return AS2 (shr%W0,%2,%0); 562618334Speter}") 562718334Speter 562818334Speter(define_insn "lshrqi3" 562950650Sobrien [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 563050650Sobrien (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 563118334Speter (match_operand:QI 2 "nonmemory_operand" "cI")))] 563218334Speter "" 563318334Speter "* 563418334Speter{ 563518334Speter if (REG_P (operands[2])) 563618334Speter return AS2 (shr%B0,%b2,%0); 563718334Speter else 563818334Speter return AS2 (shr%B0,%2,%0); 563918334Speter}") 564018334Speter 564118334Speter;;- rotate instructions 564218334Speter 564318334Speter(define_insn "rotlsi3" 564450650Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 564550650Sobrien (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0") 564618334Speter (match_operand:SI 2 "nonmemory_operand" "cI")))] 564718334Speter "" 564818334Speter "* 564918334Speter{ 565018334Speter if (REG_P (operands[2])) 565118334Speter return AS2 (rol%L0,%b2,%0); 565218334Speter else 565318334Speter return AS2 (rol%L0,%2,%0); 565418334Speter}") 565518334Speter 565618334Speter(define_insn "rotlhi3" 565750650Sobrien [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 565850650Sobrien (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0") 565918334Speter (match_operand:HI 2 "nonmemory_operand" "cI")))] 566018334Speter "" 566118334Speter "* 566218334Speter{ 566318334Speter if (REG_P (operands[2])) 566418334Speter return AS2 (rol%W0,%b2,%0); 566518334Speter else 566618334Speter return AS2 (rol%W0,%2,%0); 566718334Speter}") 566818334Speter 566918334Speter(define_insn "rotlqi3" 567050650Sobrien [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 567150650Sobrien (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0") 567218334Speter (match_operand:QI 2 "nonmemory_operand" "cI")))] 567318334Speter "" 567418334Speter "* 567518334Speter{ 567618334Speter if (REG_P (operands[2])) 567718334Speter return AS2 (rol%B0,%b2,%0); 567818334Speter else 567918334Speter return AS2 (rol%B0,%2,%0); 568018334Speter}") 568118334Speter 568218334Speter(define_insn "rotrsi3" 568350650Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 568450650Sobrien (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0") 568518334Speter (match_operand:SI 2 "nonmemory_operand" "cI")))] 568618334Speter "" 568718334Speter "* 568818334Speter{ 568918334Speter if (REG_P (operands[2])) 569018334Speter return AS2 (ror%L0,%b2,%0); 569118334Speter else 569218334Speter return AS2 (ror%L0,%2,%0); 569318334Speter}") 569418334Speter 569518334Speter(define_insn "rotrhi3" 569650650Sobrien [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 569750650Sobrien (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0") 569818334Speter (match_operand:HI 2 "nonmemory_operand" "cI")))] 569918334Speter "" 570018334Speter "* 570118334Speter{ 570218334Speter if (REG_P (operands[2])) 570318334Speter return AS2 (ror%W0,%b2,%0); 570418334Speter else 570518334Speter return AS2 (ror%W0,%2,%0); 570618334Speter}") 570718334Speter 570818334Speter(define_insn "rotrqi3" 570950650Sobrien [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 571050650Sobrien (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0") 571118334Speter (match_operand:QI 2 "nonmemory_operand" "cI")))] 571218334Speter "" 571318334Speter "* 571418334Speter{ 571518334Speter if (REG_P (operands[2])) 571618334Speter return AS2 (ror%B0,%b2,%0); 571718334Speter else 571818334Speter return AS2 (ror%B0,%2,%0); 571918334Speter}") 572018334Speter 572118334Speter/* 572218334Speter;; This usually looses. But try a define_expand to recognize a few case 572318334Speter;; we can do efficiently, such as accessing the "high" QImode registers, 572418334Speter;; %ah, %bh, %ch, %dh. 572550650Sobrien;; ??? Note this has a botch on the mode of operand 0, which needs to be 572650650Sobrien;; fixed if this is ever enabled. 572718334Speter(define_insn "insv" 572818334Speter [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r") 572950650Sobrien (match_operand:SI 1 "immediate_operand" "i") 573050650Sobrien (match_operand:SI 2 "immediate_operand" "i")) 573150650Sobrien (match_operand:SI 3 "nonmemory_operand" "ri"))] 573218334Speter "" 573318334Speter "* 573418334Speter{ 573518334Speter if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode)) 573618334Speter abort (); 573718334Speter if (GET_CODE (operands[3]) == CONST_INT) 573818334Speter { 573918334Speter unsigned int mask = (1 << INTVAL (operands[1])) - 1; 574018334Speter operands[1] = GEN_INT (~(mask << INTVAL (operands[2]))); 574118334Speter output_asm_insn (AS2 (and%L0,%1,%0), operands); 574218334Speter operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2])); 574318334Speter output_asm_insn (AS2 (or%L0,%3,%0), operands); 574418334Speter } 574518334Speter else 574618334Speter { 574750650Sobrien operands[0] = gen_rtx_REG (SImode, REGNO (operands[0])); 574818334Speter if (INTVAL (operands[2])) 574918334Speter output_asm_insn (AS2 (ror%L0,%2,%0), operands); 575018334Speter output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands); 575118334Speter operands[2] = GEN_INT (BITS_PER_WORD 575218334Speter - INTVAL (operands[1]) - INTVAL (operands[2])); 575318334Speter if (INTVAL (operands[2])) 575418334Speter output_asm_insn (AS2 (ror%L0,%2,%0), operands); 575518334Speter } 575618334Speter RET; 575718334Speter}") 575818334Speter*/ 575918334Speter/* 576018334Speter;; ??? There are problems with the mode of operand[3]. The point of this 576118334Speter;; is to represent an HImode move to a "high byte" register. 576218334Speter 576318334Speter(define_expand "insv" 576418334Speter [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "") 576518334Speter (match_operand:SI 1 "immediate_operand" "") 576618334Speter (match_operand:SI 2 "immediate_operand" "")) 576750650Sobrien (match_operand:QI 3 "nonmemory_operand" "ri"))] 576818334Speter "" 576918334Speter " 577018334Speter{ 577118334Speter if (GET_CODE (operands[1]) != CONST_INT 577218334Speter || GET_CODE (operands[2]) != CONST_INT) 577318334Speter FAIL; 577418334Speter 577518334Speter if (! (INTVAL (operands[1]) == 8 577618334Speter && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0)) 577718334Speter && ! INTVAL (operands[1]) == 1) 577818334Speter FAIL; 577918334Speter}") 578018334Speter*/ 578118334Speter 578218334Speter;; On i386, the register count for a bit operation is *not* truncated, 578318334Speter;; so SHIFT_COUNT_TRUNCATED must not be defined. 578418334Speter 578518334Speter;; On i486, the shift & or/and code is faster than bts or btr. If 578618334Speter;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code. 578718334Speter 578818334Speter;; On i386, bts is a little faster if operands[0] is a reg, and a 578918334Speter;; little slower if operands[0] is a MEM, than the shift & or/and code. 579018334Speter;; Use bts & btr, since they reload better. 579118334Speter 579218334Speter;; General bit set and clear. 579318334Speter(define_insn "" 579450650Sobrien [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+rm") 579518334Speter (const_int 1) 579650650Sobrien (match_operand:SI 2 "register_operand" "r")) 579718334Speter (match_operand:SI 3 "const_int_operand" "n"))] 579850650Sobrien "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT" 579918334Speter "* 580018334Speter{ 580118334Speter CC_STATUS_INIT; 580218334Speter 580318334Speter if (INTVAL (operands[3]) == 1) 580418334Speter return AS2 (bts%L0,%2,%0); 580518334Speter else 580618334Speter return AS2 (btr%L0,%2,%0); 580718334Speter}") 580818334Speter 580918334Speter;; Bit complement. See comments on previous pattern. 581018334Speter;; ??? Is this really worthwhile? 581118334Speter(define_insn "" 581250650Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 581318334Speter (xor:SI (ashift:SI (const_int 1) 581450650Sobrien (match_operand:SI 1 "register_operand" "r")) 581550650Sobrien (match_operand:SI 2 "nonimmediate_operand" "0")))] 581650650Sobrien "TARGET_USE_BIT_TEST && GET_CODE (operands[1]) != CONST_INT" 581718334Speter "* 581818334Speter{ 581918334Speter CC_STATUS_INIT; 582018334Speter 582118334Speter return AS2 (btc%L0,%1,%0); 582218334Speter}") 582318334Speter 582418334Speter(define_insn "" 582550650Sobrien [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 582650650Sobrien (xor:SI (match_operand:SI 1 "nonimmediate_operand" "0") 582718334Speter (ashift:SI (const_int 1) 582850650Sobrien (match_operand:SI 2 "register_operand" "r"))))] 582950650Sobrien "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT" 583018334Speter "* 583118334Speter{ 583218334Speter CC_STATUS_INIT; 583318334Speter 583418334Speter return AS2 (btc%L0,%2,%0); 583518334Speter}") 583618334Speter 583718334Speter;; Recognizers for bit-test instructions. 583818334Speter 583918334Speter;; The bt opcode allows a MEM in operands[0]. But on both i386 and 584018334Speter;; i486, it is faster to copy a MEM to REG and then use bt, than to use 584118334Speter;; bt on the MEM directly. 584218334Speter 584318334Speter;; ??? The first argument of a zero_extract must not be reloaded, so 584418334Speter;; don't allow a MEM in the operand predicate without allowing it in the 584518334Speter;; constraint. 584618334Speter 584718334Speter(define_insn "" 584818334Speter [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r") 584918334Speter (const_int 1) 585050650Sobrien (match_operand:SI 1 "register_operand" "r")))] 585118334Speter "GET_CODE (operands[1]) != CONST_INT" 585218334Speter "* 585318334Speter{ 585418334Speter cc_status.flags |= CC_Z_IN_NOT_C; 585518334Speter return AS2 (bt%L0,%1,%0); 585618334Speter}") 585718334Speter 585818334Speter(define_insn "" 585918334Speter [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r") 586018334Speter (match_operand:SI 1 "const_int_operand" "n") 586118334Speter (match_operand:SI 2 "const_int_operand" "n")))] 586218334Speter "" 586318334Speter "* 586418334Speter{ 586518334Speter unsigned int mask; 586618334Speter 586718334Speter mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]); 586818334Speter operands[1] = GEN_INT (mask); 586918334Speter 587052296Sobrien if (QI_REG_P (operands[0]) 587152296Sobrien /* A Pentium test is pairable only with eax. Not with ah or al. */ 587252296Sobrien && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM 587352296Sobrien || optimize_size)) 587418334Speter { 587518334Speter if ((mask & ~0xff) == 0) 587618334Speter { 587718334Speter cc_status.flags |= CC_NOT_NEGATIVE; 587818334Speter return AS2 (test%B0,%1,%b0); 587918334Speter } 588018334Speter 588118334Speter if ((mask & ~0xff00) == 0) 588218334Speter { 588318334Speter cc_status.flags |= CC_NOT_NEGATIVE; 588418334Speter operands[1] = GEN_INT (mask >> 8); 588518334Speter return AS2 (test%B0,%1,%h0); 588618334Speter } 588718334Speter } 588818334Speter 588918334Speter return AS2 (test%L0,%1,%0); 589018334Speter}") 589118334Speter 589218334Speter;; ??? All bets are off if operand 0 is a volatile MEM reference. 589318334Speter;; The CPU may access unspecified bytes around the actual target byte. 589418334Speter 589518334Speter(define_insn "" 589650650Sobrien [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m") 589718334Speter (match_operand:SI 1 "const_int_operand" "n") 589818334Speter (match_operand:SI 2 "const_int_operand" "n")))] 589918334Speter "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])" 590018334Speter "* 590118334Speter{ 590218334Speter unsigned int mask; 590318334Speter 590418334Speter mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]); 590518334Speter operands[1] = GEN_INT (mask); 590618334Speter 590752296Sobrien if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) 590852296Sobrien /* A Pentium test is pairable only with eax. Not with ah or al. */ 590952296Sobrien && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM 591052296Sobrien || optimize_size)) 591118334Speter { 591218334Speter if ((mask & ~0xff) == 0) 591318334Speter { 591418334Speter cc_status.flags |= CC_NOT_NEGATIVE; 591518334Speter return AS2 (test%B0,%1,%b0); 591618334Speter } 591718334Speter 591818334Speter if ((mask & ~0xff00) == 0) 591918334Speter { 592018334Speter cc_status.flags |= CC_NOT_NEGATIVE; 592118334Speter operands[1] = GEN_INT (mask >> 8); 592218334Speter 592318334Speter if (QI_REG_P (operands[0])) 592418334Speter return AS2 (test%B0,%1,%h0); 592518334Speter else 592618334Speter { 592718334Speter operands[0] = adj_offsettable_operand (operands[0], 1); 592818334Speter return AS2 (test%B0,%1,%b0); 592918334Speter } 593018334Speter } 593118334Speter 593218334Speter if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0) 593318334Speter { 593418334Speter cc_status.flags |= CC_NOT_NEGATIVE; 593518334Speter operands[1] = GEN_INT (mask >> 16); 593618334Speter operands[0] = adj_offsettable_operand (operands[0], 2); 593718334Speter return AS2 (test%B0,%1,%b0); 593818334Speter } 593918334Speter 594018334Speter if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0) 594118334Speter { 594218334Speter cc_status.flags |= CC_NOT_NEGATIVE; 594318334Speter operands[1] = GEN_INT (mask >> 24); 594418334Speter operands[0] = adj_offsettable_operand (operands[0], 3); 594518334Speter return AS2 (test%B0,%1,%b0); 594618334Speter } 594718334Speter } 594818334Speter 594918334Speter if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM) 595018334Speter return AS2 (test%L0,%1,%0); 595118334Speter 595218334Speter return AS2 (test%L1,%0,%1); 595318334Speter}") 595418334Speter 595518334Speter;; Store-flag instructions. 595618334Speter 595718334Speter;; For all sCOND expanders, also expand the compare or test insn that 595818334Speter;; generates cc0. Generate an equality comparison if `seq' or `sne'. 595918334Speter 596018334Speter(define_expand "seq" 596118334Speter [(match_dup 1) 596218334Speter (set (match_operand:QI 0 "register_operand" "") 596318334Speter (eq:QI (cc0) (const_int 0)))] 596418334Speter "" 596518334Speter " 596618334Speter{ 596718334Speter if (TARGET_IEEE_FP 596818334Speter && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT) 596918334Speter operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1); 597018334Speter else 597118334Speter operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); 597218334Speter}") 597318334Speter 597418334Speter(define_expand "sne" 597518334Speter [(match_dup 1) 597618334Speter (set (match_operand:QI 0 "register_operand" "") 597718334Speter (ne:QI (cc0) (const_int 0)))] 597818334Speter "" 597918334Speter " 598018334Speter{ 598118334Speter if (TARGET_IEEE_FP 598218334Speter && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT) 598318334Speter operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1); 598418334Speter else 598518334Speter operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); 598618334Speter}") 598718334Speter 598818334Speter(define_expand "sgt" 598918334Speter [(match_dup 1) 599018334Speter (set (match_operand:QI 0 "register_operand" "") 599118334Speter (gt:QI (cc0) (const_int 0)))] 599218334Speter "" 599318334Speter "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 599418334Speter 599518334Speter(define_expand "sgtu" 599618334Speter [(match_dup 1) 599718334Speter (set (match_operand:QI 0 "register_operand" "") 599818334Speter (gtu:QI (cc0) (const_int 0)))] 599918334Speter "" 600018334Speter "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 600118334Speter 600218334Speter(define_expand "slt" 600318334Speter [(match_dup 1) 600418334Speter (set (match_operand:QI 0 "register_operand" "") 600518334Speter (lt:QI (cc0) (const_int 0)))] 600618334Speter "" 600718334Speter "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 600818334Speter 600918334Speter(define_expand "sltu" 601018334Speter [(match_dup 1) 601118334Speter (set (match_operand:QI 0 "register_operand" "") 601218334Speter (ltu:QI (cc0) (const_int 0)))] 601318334Speter "" 601418334Speter "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 601518334Speter 601618334Speter(define_expand "sge" 601718334Speter [(match_dup 1) 601818334Speter (set (match_operand:QI 0 "register_operand" "") 601918334Speter (ge:QI (cc0) (const_int 0)))] 602018334Speter "" 602118334Speter "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 602218334Speter 602318334Speter(define_expand "sgeu" 602418334Speter [(match_dup 1) 602518334Speter (set (match_operand:QI 0 "register_operand" "") 602618334Speter (geu:QI (cc0) (const_int 0)))] 602718334Speter "" 602818334Speter "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 602918334Speter 603018334Speter(define_expand "sle" 603118334Speter [(match_dup 1) 603218334Speter (set (match_operand:QI 0 "register_operand" "") 603318334Speter (le:QI (cc0) (const_int 0)))] 603418334Speter "" 603518334Speter "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 603618334Speter 603718334Speter(define_expand "sleu" 603818334Speter [(match_dup 1) 603918334Speter (set (match_operand:QI 0 "register_operand" "") 604018334Speter (leu:QI (cc0) (const_int 0)))] 604118334Speter "" 604218334Speter "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 604318334Speter 604452296Sobrien;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may 604552296Sobrien;; not have any input reloads. A MEM write might need an input reload 604652296Sobrien;; for the address of the MEM. So don't allow MEM as the SET_DEST. 604752296Sobrien 604852296Sobrien(define_insn "*setcc" 604952296Sobrien [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 605052296Sobrien (match_operator:QI 1 "comparison_operator" [(cc0) (const_int 0)]))] 605152296Sobrien "reload_completed || register_operand (operands[0], QImode)" 605252296Sobrien "* 605352296Sobrien{ 605452296Sobrien enum rtx_code code = GET_CODE (operands[1]); 605552296Sobrien if (cc_prev_status.flags & CC_TEST_AX) 605652296Sobrien { 605752296Sobrien int eq; 605852296Sobrien HOST_WIDE_INT c; 605952296Sobrien operands[2] = gen_rtx_REG (SImode, 0); 606052296Sobrien switch (code) 606152296Sobrien { 606252296Sobrien case EQ: 606352296Sobrien c = 0x4000; 606452296Sobrien eq = 0; 606552296Sobrien break; 606652296Sobrien case NE: 606752296Sobrien c = 0x4000; 606852296Sobrien eq = 1; 606952296Sobrien break; 607052296Sobrien case GT: 607152296Sobrien c = 0x4100; 607252296Sobrien eq = 1; 607352296Sobrien break; 607452296Sobrien case LT: 607552296Sobrien c = 0x100; 607652296Sobrien eq = 0; 607752296Sobrien break; 607852296Sobrien case GE: 607952296Sobrien c = 0x100; 608052296Sobrien eq = 1; 608152296Sobrien break; 608252296Sobrien case LE: 608352296Sobrien c = 0x4100; 608452296Sobrien eq = 0; 608552296Sobrien break; 608652296Sobrien default: 608752296Sobrien abort (); 608852296Sobrien } 608952296Sobrien if (!TARGET_PENTIUM || optimize_size) 609052296Sobrien { 609152296Sobrien operands[3] = GEN_INT (c >> 8); 609252296Sobrien output_asm_insn (AS2 (test%B0,%3,%h2), operands); 609352296Sobrien } 609452296Sobrien else 609552296Sobrien { 609652296Sobrien operands[3] = GEN_INT (c); 609752296Sobrien output_asm_insn (AS2 (test%L0,%3,%2), operands); 609852296Sobrien } 609952296Sobrien return eq ? AS1 (sete,%0) : AS1 (setne, %0); 610052296Sobrien } 610152296Sobrien 610252296Sobrien if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT)) 610352296Sobrien return (char *)0; 610452296Sobrien return AS1(set%D1,%0); 610552296Sobrien}") 610652296Sobrien 610718334Speter 610818334Speter;; Basic conditional jump instructions. 610918334Speter;; We ignore the overflow flag for signed branch instructions. 611018334Speter 611118334Speter;; For all bCOND expanders, also expand the compare or test insn that 611218334Speter;; generates cc0. Generate an equality comparison if `beq' or `bne'. 611318334Speter 611418334Speter(define_expand "beq" 611518334Speter [(match_dup 1) 611618334Speter (set (pc) 611718334Speter (if_then_else (eq (cc0) 611818334Speter (const_int 0)) 611918334Speter (label_ref (match_operand 0 "" "")) 612018334Speter (pc)))] 612118334Speter "" 612218334Speter " 612318334Speter{ 612418334Speter if (TARGET_IEEE_FP 612518334Speter && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT) 612618334Speter operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1); 612718334Speter else 612818334Speter operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); 612918334Speter}") 613018334Speter 613118334Speter(define_expand "bne" 613218334Speter [(match_dup 1) 613318334Speter (set (pc) 613418334Speter (if_then_else (ne (cc0) 613518334Speter (const_int 0)) 613618334Speter (label_ref (match_operand 0 "" "")) 613718334Speter (pc)))] 613818334Speter "" 613918334Speter " 614018334Speter{ 614118334Speter if (TARGET_IEEE_FP 614218334Speter && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT) 614318334Speter operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1); 614418334Speter else 614518334Speter operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); 614618334Speter}") 614718334Speter 614850650Sobrien 614918334Speter(define_expand "bgt" 615018334Speter [(match_dup 1) 615118334Speter (set (pc) 615218334Speter (if_then_else (gt (cc0) 615318334Speter (const_int 0)) 615418334Speter (label_ref (match_operand 0 "" "")) 615518334Speter (pc)))] 615618334Speter "" 615718334Speter "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 615818334Speter 615918334Speter(define_expand "bgtu" 616018334Speter [(match_dup 1) 616118334Speter (set (pc) 616218334Speter (if_then_else (gtu (cc0) 616318334Speter (const_int 0)) 616418334Speter (label_ref (match_operand 0 "" "")) 616518334Speter (pc)))] 616618334Speter "" 616718334Speter "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 616818334Speter 616918334Speter(define_expand "blt" 617018334Speter [(match_dup 1) 617118334Speter (set (pc) 617218334Speter (if_then_else (lt (cc0) 617318334Speter (const_int 0)) 617418334Speter (label_ref (match_operand 0 "" "")) 617518334Speter (pc)))] 617618334Speter "" 617718334Speter "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 617818334Speter 617918334Speter 618018334Speter(define_expand "bltu" 618118334Speter [(match_dup 1) 618218334Speter (set (pc) 618318334Speter (if_then_else (ltu (cc0) 618418334Speter (const_int 0)) 618518334Speter (label_ref (match_operand 0 "" "")) 618618334Speter (pc)))] 618718334Speter "" 618818334Speter "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 618918334Speter 619018334Speter(define_expand "bge" 619118334Speter [(match_dup 1) 619218334Speter (set (pc) 619318334Speter (if_then_else (ge (cc0) 619418334Speter (const_int 0)) 619518334Speter (label_ref (match_operand 0 "" "")) 619618334Speter (pc)))] 619718334Speter "" 619818334Speter "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 619918334Speter 620018334Speter(define_expand "bgeu" 620118334Speter [(match_dup 1) 620218334Speter (set (pc) 620318334Speter (if_then_else (geu (cc0) 620418334Speter (const_int 0)) 620518334Speter (label_ref (match_operand 0 "" "")) 620618334Speter (pc)))] 620718334Speter "" 620818334Speter "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 620918334Speter 621018334Speter(define_expand "ble" 621118334Speter [(match_dup 1) 621218334Speter (set (pc) 621318334Speter (if_then_else (le (cc0) 621418334Speter (const_int 0)) 621518334Speter (label_ref (match_operand 0 "" "")) 621618334Speter (pc)))] 621718334Speter "" 621818334Speter "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 621918334Speter 622018334Speter(define_expand "bleu" 622118334Speter [(match_dup 1) 622218334Speter (set (pc) 622318334Speter (if_then_else (leu (cc0) 622418334Speter (const_int 0)) 622518334Speter (label_ref (match_operand 0 "" "")) 622618334Speter (pc)))] 622718334Speter "" 622818334Speter "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 622918334Speter 623018334Speter(define_insn "" 623118334Speter [(set (pc) 623252296Sobrien (if_then_else (match_operator 0 "comparison_operator" 623352296Sobrien [(cc0) (const_int 0)]) 623452296Sobrien (label_ref (match_operand 1 "" "")) 623518334Speter (pc)))] 623618334Speter "" 623718334Speter "* 623818334Speter{ 623952296Sobrien enum rtx_code code = GET_CODE (operands[0]); 624050650Sobrien if (cc_prev_status.flags & CC_TEST_AX) 624150650Sobrien { 624252296Sobrien int eq; 624352296Sobrien HOST_WIDE_INT c; 624452296Sobrien operands[2] = gen_rtx_REG (SImode, 0); 624552296Sobrien switch (code) 624652296Sobrien { 624752296Sobrien case EQ: 624852296Sobrien c = 0x4000; 624952296Sobrien eq = 0; 625052296Sobrien break; 625152296Sobrien case NE: 625252296Sobrien c = 0x4000; 625352296Sobrien eq = 1; 625452296Sobrien break; 625552296Sobrien case GT: 625652296Sobrien c = 0x4100; 625752296Sobrien eq = 1; 625852296Sobrien break; 625952296Sobrien case LT: 626052296Sobrien c = 0x100; 626152296Sobrien eq = 0; 626252296Sobrien break; 626352296Sobrien case GE: 626452296Sobrien c = 0x100; 626552296Sobrien eq = 1; 626652296Sobrien break; 626752296Sobrien case LE: 626852296Sobrien c = 0x4100; 626952296Sobrien eq = 0; 627052296Sobrien break; 627152296Sobrien default: 627252296Sobrien abort (); 627352296Sobrien } 627452296Sobrien if (!TARGET_PENTIUM || optimize_size) 627552296Sobrien { 627652296Sobrien operands[3] = GEN_INT (c >> 8); 627752296Sobrien output_asm_insn (AS2 (test%B0,%3,%h2), operands); 627852296Sobrien } 627952296Sobrien else 628052296Sobrien { 628152296Sobrien operands[3] = GEN_INT (c); 628252296Sobrien output_asm_insn (AS2 (test%L0,%3,%2), operands); 628352296Sobrien } 628452296Sobrien return eq ? AS1 (je,%l1) : AS1 (jne, %l1); 628550650Sobrien } 628652296Sobrien if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT)) 628752296Sobrien return (char *)0; 628818334Speter 628952296Sobrien return AS1(j%D0,%l1); 629018334Speter}") 629118334Speter 629218334Speter(define_insn "" 629318334Speter [(set (pc) 629452296Sobrien (if_then_else (match_operator 0 "comparison_operator" 629552296Sobrien [(cc0) (const_int 0)]) 629618334Speter (pc) 629752296Sobrien (label_ref (match_operand 1 "" ""))))] 629818334Speter "" 629918334Speter "* 630018334Speter{ 630152296Sobrien enum rtx_code code = GET_CODE (operands[0]); 630250650Sobrien if (cc_prev_status.flags & CC_TEST_AX) 630350650Sobrien { 630452296Sobrien int eq; 630552296Sobrien HOST_WIDE_INT c; 630652296Sobrien operands[2] = gen_rtx_REG (SImode, 0); 630752296Sobrien switch (code) 630852296Sobrien { 630952296Sobrien case EQ: 631052296Sobrien c = 0x4000; 631152296Sobrien eq = 1; 631252296Sobrien break; 631352296Sobrien case NE: 631452296Sobrien c = 0x4000; 631552296Sobrien eq = 0; 631652296Sobrien break; 631752296Sobrien case GT: 631852296Sobrien c = 0x4100; 631952296Sobrien eq = 0; 632052296Sobrien break; 632152296Sobrien case LT: 632252296Sobrien c = 0x100; 632352296Sobrien eq = 1; 632452296Sobrien break; 632552296Sobrien case GE: 632652296Sobrien c = 0x100; 632752296Sobrien eq = 0; 632852296Sobrien break; 632952296Sobrien case LE: 633052296Sobrien c = 0x4100; 633152296Sobrien eq = 1; 633252296Sobrien break; 633352296Sobrien default: 633452296Sobrien abort (); 633552296Sobrien } 633652296Sobrien if (!TARGET_PENTIUM || optimize_size) 633752296Sobrien { 633852296Sobrien operands[3] = GEN_INT (c >> 8); 633952296Sobrien output_asm_insn (AS2 (test%B0,%3,%h2), operands); 634052296Sobrien } 634152296Sobrien else 634252296Sobrien { 634352296Sobrien operands[3] = GEN_INT (c); 634452296Sobrien output_asm_insn (AS2 (test%L0,%3,%2), operands); 634552296Sobrien } 634652296Sobrien return eq ? AS1 (je,%l1) : AS1 (jne, %l1); 634750650Sobrien } 634852296Sobrien if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT)) 634952296Sobrien return (char *)0; 635018334Speter 635152296Sobrien return AS1(j%d0,%l1); 635218334Speter}") 635318334Speter 635418334Speter;; Unconditional and other jump instructions 635518334Speter 635618334Speter(define_insn "jump" 635718334Speter [(set (pc) 635818334Speter (label_ref (match_operand 0 "" "")))] 635918334Speter "" 636052296Sobrien "jmp %l0" 636152296Sobrien [(set_attr "memory" "none")]) 636218334Speter 636318334Speter(define_insn "indirect_jump" 636450650Sobrien [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))] 636518334Speter "" 636618334Speter "* 636718334Speter{ 636818334Speter CC_STATUS_INIT; 636918334Speter 637018334Speter return AS1 (jmp,%*%0); 637152296Sobrien}" 637252296Sobrien [(set_attr "memory" "none")]) 637318334Speter 637418334Speter;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i); 637518334Speter;; if S does not change i 637618334Speter 637718334Speter(define_expand "decrement_and_branch_until_zero" 637818334Speter [(parallel [(set (pc) 637918334Speter (if_then_else (ge (plus:SI (match_operand:SI 0 "general_operand" "") 638018334Speter (const_int -1)) 638118334Speter (const_int 0)) 638218334Speter (label_ref (match_operand 1 "" "")) 638318334Speter (pc))) 638418334Speter (set (match_dup 0) 638518334Speter (plus:SI (match_dup 0) 638618334Speter (const_int -1)))])] 638718334Speter "" 638818334Speter "") 638918334Speter 639018334Speter(define_insn "" 639118334Speter [(set (pc) 639218334Speter (if_then_else (match_operator 0 "arithmetic_comparison_operator" 639352296Sobrien [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+c*r,m") 639418334Speter (match_operand:SI 2 "general_operand" "rmi,ri")) 639518334Speter (const_int 0)]) 639618334Speter (label_ref (match_operand 3 "" "")) 639718334Speter (pc))) 639818334Speter (set (match_dup 1) 639918334Speter (plus:SI (match_dup 1) 640018334Speter (match_dup 2)))] 640118334Speter "" 640218334Speter "* 640318334Speter{ 640418334Speter CC_STATUS_INIT; 640552296Sobrien 640652296Sobrien if (GET_CODE (operands[1]) == REG && REGNO (operands[2]) == 2 && 640752296Sobrien operands[2] == constm1_rtx && ix86_cpu == PROCESSOR_K6) 640852296Sobrien return \"loop %l3\"; 640952296Sobrien 641018334Speter if (operands[2] == constm1_rtx) 641118334Speter output_asm_insn (AS1 (dec%L1,%1), operands); 641218334Speter 641350650Sobrien else if (operands[2] == const1_rtx) 641418334Speter output_asm_insn (AS1 (inc%L1,%1), operands); 641518334Speter 641618334Speter else 641718334Speter output_asm_insn (AS2 (add%L1,%2,%1), operands); 641818334Speter 641918334Speter return AS1 (%J0,%l3); 642018334Speter}") 642118334Speter 642218334Speter(define_insn "" 642318334Speter [(set (pc) 642418334Speter (if_then_else (match_operator 0 "arithmetic_comparison_operator" 642550650Sobrien [(minus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m") 642618334Speter (match_operand:SI 2 "general_operand" "rmi,ri")) 642718334Speter (const_int 0)]) 642818334Speter (label_ref (match_operand 3 "" "")) 642918334Speter (pc))) 643018334Speter (set (match_dup 1) 643118334Speter (minus:SI (match_dup 1) 643218334Speter (match_dup 2)))] 643318334Speter "" 643418334Speter "* 643518334Speter{ 643618334Speter CC_STATUS_INIT; 643718334Speter if (operands[2] == const1_rtx) 643818334Speter output_asm_insn (AS1 (dec%L1,%1), operands); 643918334Speter 644018334Speter else if (operands[1] == constm1_rtx) 644118334Speter output_asm_insn (AS1 (inc%L1,%1), operands); 644218334Speter 644318334Speter else 644418334Speter output_asm_insn (AS2 (sub%L1,%2,%1), operands); 644518334Speter 644618334Speter return AS1 (%J0,%l3); 644718334Speter}") 644818334Speter 644950650Sobrien(define_insn "" 645050650Sobrien [(set (pc) 645150650Sobrien (if_then_else (ne (match_operand:SI 0 "general_operand" "+g") 645250650Sobrien (const_int 0)) 645350650Sobrien (label_ref (match_operand 1 "" "")) 645450650Sobrien (pc))) 645550650Sobrien (set (match_dup 0) 645650650Sobrien (plus:SI (match_dup 0) 645750650Sobrien (const_int -1)))] 645850650Sobrien "" 645950650Sobrien "* 646050650Sobrien{ 646150650Sobrien CC_STATUS_INIT; 646250650Sobrien operands[2] = const1_rtx; 646350650Sobrien output_asm_insn (AS2 (sub%L0,%2,%0), operands); 646450650Sobrien return \"jnc %l1\"; 646550650Sobrien}") 646650650Sobrien 646750650Sobrien(define_insn "" 646850650Sobrien [(set (pc) 646950650Sobrien (if_then_else (eq (match_operand:SI 0 "general_operand" "+g") 647050650Sobrien (const_int 0)) 647150650Sobrien (label_ref (match_operand 1 "" "")) 647250650Sobrien (pc))) 647350650Sobrien (set (match_dup 0) 647450650Sobrien (plus:SI (match_dup 0) 647550650Sobrien (const_int -1)))] 647650650Sobrien "" 647750650Sobrien "* 647850650Sobrien{ 647950650Sobrien CC_STATUS_INIT; 648050650Sobrien operands[2] = const1_rtx; 648150650Sobrien output_asm_insn (AS2 (sub%L0,%2,%0), operands); 648250650Sobrien return \"jc %l1\"; 648350650Sobrien}") 648450650Sobrien 648550650Sobrien(define_insn "" 648650650Sobrien [(set (pc) 648750650Sobrien (if_then_else (ne (match_operand:SI 0 "general_operand" "+g") 648850650Sobrien (const_int 1)) 648950650Sobrien (label_ref (match_operand 1 "" "")) 649050650Sobrien (pc))) 649150650Sobrien (set (match_dup 0) 649250650Sobrien (plus:SI (match_dup 0) 649350650Sobrien (const_int -1)))] 649450650Sobrien "" 649550650Sobrien "* 649650650Sobrien{ 649750650Sobrien CC_STATUS_INIT; 649850650Sobrien output_asm_insn (AS1 (dec%L0,%0), operands); 649950650Sobrien return \"jnz %l1\"; 650050650Sobrien}") 650150650Sobrien 650250650Sobrien(define_insn "" 650350650Sobrien [(set (pc) 650450650Sobrien (if_then_else (eq (match_operand:SI 0 "general_operand" "+g") 650550650Sobrien (const_int 1)) 650650650Sobrien (label_ref (match_operand 1 "" "")) 650750650Sobrien (pc))) 650850650Sobrien (set (match_dup 0) 650950650Sobrien (plus:SI (match_dup 0) 651050650Sobrien (const_int -1)))] 651150650Sobrien "" 651250650Sobrien "* 651350650Sobrien{ 651450650Sobrien CC_STATUS_INIT; 651550650Sobrien output_asm_insn (AS1 (dec%L0,%0), operands); 651650650Sobrien return \"jz %l1\"; 651750650Sobrien}") 651850650Sobrien 651950650Sobrien(define_insn "" 652050650Sobrien [(set (pc) 652150650Sobrien (if_then_else (ne (match_operand:SI 0 "general_operand" "+g") 652250650Sobrien (const_int -1)) 652350650Sobrien (label_ref (match_operand 1 "" "")) 652450650Sobrien (pc))) 652550650Sobrien (set (match_dup 0) 652650650Sobrien (plus:SI (match_dup 0) 652750650Sobrien (const_int 1)))] 652850650Sobrien "" 652950650Sobrien "* 653050650Sobrien{ 653150650Sobrien CC_STATUS_INIT; 653250650Sobrien output_asm_insn (AS1 (inc%L0,%0), operands); 653350650Sobrien return \"jnz %l1\"; 653450650Sobrien}") 653550650Sobrien 653650650Sobrien(define_insn "" 653750650Sobrien [(set (pc) 653850650Sobrien (if_then_else (eq (match_operand:SI 0 "general_operand" "+g") 653950650Sobrien (const_int -1)) 654050650Sobrien (label_ref (match_operand 1 "" "")) 654150650Sobrien (pc))) 654250650Sobrien (set (match_dup 0) 654350650Sobrien (plus:SI (match_dup 0) 654450650Sobrien (const_int 1)))] 654550650Sobrien "" 654650650Sobrien "* 654750650Sobrien{ 654850650Sobrien CC_STATUS_INIT; 654950650Sobrien output_asm_insn (AS1 (inc%L0,%0), operands); 655050650Sobrien return \"jz %l1\"; 655150650Sobrien}") 655250650Sobrien 655318334Speter;; Implement switch statements when generating PIC code. Switches are 655418334Speter;; implemented by `tablejump' when not using -fpic. 655518334Speter 655618334Speter;; Emit code here to do the range checking and make the index zero based. 655718334Speter 655818334Speter(define_expand "casesi" 655918334Speter [(set (match_dup 5) 656050650Sobrien (match_operand:SI 0 "general_operand" "")) 656150650Sobrien (set (match_dup 6) 656250650Sobrien (minus:SI (match_dup 5) 656318334Speter (match_operand:SI 1 "general_operand" ""))) 656418334Speter (set (cc0) 656550650Sobrien (compare:CC (match_dup 6) 656618334Speter (match_operand:SI 2 "general_operand" ""))) 656718334Speter (set (pc) 656818334Speter (if_then_else (gtu (cc0) 656918334Speter (const_int 0)) 657018334Speter (label_ref (match_operand 4 "" "")) 657118334Speter (pc))) 657218334Speter (parallel 657318334Speter [(set (pc) 657418334Speter (minus:SI (reg:SI 3) 657550650Sobrien (mem:SI (plus:SI (mult:SI (match_dup 6) 657618334Speter (const_int 4)) 657718334Speter (label_ref (match_operand 3 "" "")))))) 657850650Sobrien (clobber (match_scratch:SI 7 ""))])] 657918334Speter "flag_pic" 658018334Speter " 658118334Speter{ 658218334Speter operands[5] = gen_reg_rtx (SImode); 658350650Sobrien operands[6] = gen_reg_rtx (SImode); 658418334Speter current_function_uses_pic_offset_table = 1; 658518334Speter}") 658618334Speter 658718334Speter;; Implement a casesi insn. 658818334Speter 658918334Speter;; Each entry in the "addr_diff_vec" looks like this as the result of the 659018334Speter;; two rules below: 659118334Speter;; 659218334Speter;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2] 659318334Speter;; 659418334Speter;; 1. An expression involving an external reference may only use the 659518334Speter;; addition operator, and only with an assembly-time constant. 659618334Speter;; The example above satisfies this because ".-.L2" is a constant. 659718334Speter;; 659818334Speter;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is 659918334Speter;; given the value of "GOT - .", where GOT is the actual address of 660018334Speter;; the Global Offset Table. Therefore, the .long above actually 660118334Speter;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The 660218334Speter;; expression "GOT - .L2" by itself would generate an error from as(1). 660318334Speter;; 660418334Speter;; The pattern below emits code that looks like this: 660518334Speter;; 660618334Speter;; movl %ebx,reg 660718334Speter;; subl TABLE@GOTOFF(%ebx,index,4),reg 660818334Speter;; jmp reg 660918334Speter;; 661018334Speter;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since 661118334Speter;; the addr_diff_vec is known to be part of this module. 661218334Speter;; 661318334Speter;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which 661418334Speter;; evaluates to just ".L2". 661518334Speter 661618334Speter(define_insn "" 661718334Speter [(set (pc) 661818334Speter (minus:SI (reg:SI 3) 661918334Speter (mem:SI (plus:SI 662018334Speter (mult:SI (match_operand:SI 0 "register_operand" "r") 662118334Speter (const_int 4)) 662218334Speter (label_ref (match_operand 1 "" "")))))) 662318334Speter (clobber (match_scratch:SI 2 "=&r"))] 662418334Speter "" 662518334Speter "* 662618334Speter{ 662718334Speter rtx xops[4]; 662818334Speter 662918334Speter xops[0] = operands[0]; 663018334Speter xops[1] = operands[1]; 663118334Speter xops[2] = operands[2]; 663218334Speter xops[3] = pic_offset_table_rtx; 663318334Speter 663418334Speter output_asm_insn (AS2 (mov%L2,%3,%2), xops); 663518334Speter output_asm_insn (\"sub%L2 %l1@GOTOFF(%3,%0,4),%2\", xops); 663618334Speter output_asm_insn (AS1 (jmp,%*%2), xops); 663750650Sobrien ASM_OUTPUT_ALIGN (asm_out_file, i386_align_jumps); 663818334Speter RET; 663918334Speter}") 664018334Speter 664118334Speter(define_insn "tablejump" 664250650Sobrien [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm")) 664318334Speter (use (label_ref (match_operand 1 "" "")))] 664418334Speter "" 664518334Speter "* 664618334Speter{ 664718334Speter CC_STATUS_INIT; 664818334Speter 664918334Speter return AS1 (jmp,%*%0); 665018334Speter}") 665118334Speter 665218334Speter;; Call insns. 665318334Speter 665418334Speter;; If generating PIC code, the predicate indirect_operand will fail 665518334Speter;; for operands[0] containing symbolic references on all of the named 665618334Speter;; call* patterns. Each named pattern is followed by an unnamed pattern 665718334Speter;; that matches any call to a symbolic CONST (ie, a symbol_ref). The 665818334Speter;; unnamed patterns are only used while generating PIC code, because 665918334Speter;; otherwise the named patterns match. 666018334Speter 666118334Speter;; Call subroutine returning no value. 666218334Speter 666318334Speter(define_expand "call_pop" 666418334Speter [(parallel [(call (match_operand:QI 0 "indirect_operand" "") 666518334Speter (match_operand:SI 1 "general_operand" "")) 666618334Speter (set (reg:SI 7) 666718334Speter (plus:SI (reg:SI 7) 666818334Speter (match_operand:SI 3 "immediate_operand" "")))])] 666918334Speter "" 667018334Speter " 667118334Speter{ 667218334Speter rtx addr; 667318334Speter 667452296Sobrien if (operands[3] == const0_rtx) 667552296Sobrien { 667652296Sobrien emit_insn (gen_call (operands[0], operands[1])); 667752296Sobrien DONE; 667852296Sobrien } 667952296Sobrien 668018334Speter if (flag_pic) 668118334Speter current_function_uses_pic_offset_table = 1; 668218334Speter 668318334Speter /* With half-pic, force the address into a register. */ 668418334Speter addr = XEXP (operands[0], 0); 668518334Speter if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr)) 668618334Speter XEXP (operands[0], 0) = force_reg (Pmode, addr); 668718334Speter 668818334Speter if (! expander_call_insn_operand (operands[0], QImode)) 668918334Speter operands[0] 669018334Speter = change_address (operands[0], VOIDmode, 669118334Speter copy_to_mode_reg (Pmode, XEXP (operands[0], 0))); 669218334Speter}") 669318334Speter 669418334Speter(define_insn "" 669518334Speter [(call (match_operand:QI 0 "call_insn_operand" "m") 669618334Speter (match_operand:SI 1 "general_operand" "g")) 669718334Speter (set (reg:SI 7) (plus:SI (reg:SI 7) 669818334Speter (match_operand:SI 3 "immediate_operand" "i")))] 669918334Speter "" 670018334Speter "* 670118334Speter{ 670218334Speter if (GET_CODE (operands[0]) == MEM 670318334Speter && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) 670418334Speter { 670518334Speter operands[0] = XEXP (operands[0], 0); 670618334Speter return AS1 (call,%*%0); 670718334Speter } 670818334Speter else 670918334Speter return AS1 (call,%P0); 671018334Speter}") 671118334Speter 671218334Speter(define_insn "" 671318334Speter [(call (mem:QI (match_operand:SI 0 "symbolic_operand" "")) 671418334Speter (match_operand:SI 1 "general_operand" "g")) 671518334Speter (set (reg:SI 7) (plus:SI (reg:SI 7) 671618334Speter (match_operand:SI 3 "immediate_operand" "i")))] 671718334Speter "!HALF_PIC_P ()" 671818334Speter "call %P0") 671918334Speter 672018334Speter(define_expand "call" 672118334Speter [(call (match_operand:QI 0 "indirect_operand" "") 672218334Speter (match_operand:SI 1 "general_operand" ""))] 672318334Speter ;; Operand 1 not used on the i386. 672418334Speter "" 672518334Speter " 672618334Speter{ 672718334Speter rtx addr; 672818334Speter 672918334Speter if (flag_pic) 673018334Speter current_function_uses_pic_offset_table = 1; 673118334Speter 673218334Speter /* With half-pic, force the address into a register. */ 673318334Speter addr = XEXP (operands[0], 0); 673418334Speter if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr)) 673518334Speter XEXP (operands[0], 0) = force_reg (Pmode, addr); 673618334Speter 673718334Speter if (! expander_call_insn_operand (operands[0], QImode)) 673818334Speter operands[0] 673918334Speter = change_address (operands[0], VOIDmode, 674018334Speter copy_to_mode_reg (Pmode, XEXP (operands[0], 0))); 674118334Speter}") 674218334Speter 674318334Speter(define_insn "" 674418334Speter [(call (match_operand:QI 0 "call_insn_operand" "m") 674518334Speter (match_operand:SI 1 "general_operand" "g"))] 674618334Speter ;; Operand 1 not used on the i386. 674718334Speter "" 674818334Speter "* 674918334Speter{ 675018334Speter if (GET_CODE (operands[0]) == MEM 675118334Speter && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) 675218334Speter { 675318334Speter operands[0] = XEXP (operands[0], 0); 675418334Speter return AS1 (call,%*%0); 675518334Speter } 675618334Speter else 675718334Speter return AS1 (call,%P0); 675818334Speter}") 675918334Speter 676018334Speter(define_insn "" 676118334Speter [(call (mem:QI (match_operand:SI 0 "symbolic_operand" "")) 676218334Speter (match_operand:SI 1 "general_operand" "g"))] 676318334Speter ;; Operand 1 not used on the i386. 676418334Speter "!HALF_PIC_P ()" 676518334Speter "call %P0") 676618334Speter 676718334Speter;; Call subroutine, returning value in operand 0 676818334Speter;; (which must be a hard register). 676918334Speter 677018334Speter(define_expand "call_value_pop" 677118334Speter [(parallel [(set (match_operand 0 "" "") 677218334Speter (call (match_operand:QI 1 "indirect_operand" "") 677318334Speter (match_operand:SI 2 "general_operand" ""))) 677418334Speter (set (reg:SI 7) 677518334Speter (plus:SI (reg:SI 7) 677618334Speter (match_operand:SI 4 "immediate_operand" "")))])] 677718334Speter "" 677818334Speter " 677918334Speter{ 678018334Speter rtx addr; 678118334Speter 678252296Sobrien if (operands[4] == const0_rtx) 678352296Sobrien { 678452296Sobrien emit_insn (gen_call_value (operands[0], operands[1], operands[2])); 678552296Sobrien DONE; 678652296Sobrien } 678752296Sobrien 678818334Speter if (flag_pic) 678918334Speter current_function_uses_pic_offset_table = 1; 679018334Speter 679118334Speter /* With half-pic, force the address into a register. */ 679218334Speter addr = XEXP (operands[1], 0); 679318334Speter if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr)) 679418334Speter XEXP (operands[1], 0) = force_reg (Pmode, addr); 679518334Speter 679618334Speter if (! expander_call_insn_operand (operands[1], QImode)) 679718334Speter operands[1] 679818334Speter = change_address (operands[1], VOIDmode, 679918334Speter copy_to_mode_reg (Pmode, XEXP (operands[1], 0))); 680018334Speter}") 680118334Speter 680218334Speter(define_insn "" 680318334Speter [(set (match_operand 0 "" "=rf") 680418334Speter (call (match_operand:QI 1 "call_insn_operand" "m") 680518334Speter (match_operand:SI 2 "general_operand" "g"))) 680618334Speter (set (reg:SI 7) (plus:SI (reg:SI 7) 680718334Speter (match_operand:SI 4 "immediate_operand" "i")))] 680818334Speter "" 680918334Speter "* 681018334Speter{ 681118334Speter if (GET_CODE (operands[1]) == MEM 681218334Speter && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) 681318334Speter { 681418334Speter operands[1] = XEXP (operands[1], 0); 681518334Speter output_asm_insn (AS1 (call,%*%1), operands); 681618334Speter } 681718334Speter else 681818334Speter output_asm_insn (AS1 (call,%P1), operands); 681918334Speter 682018334Speter RET; 682118334Speter}") 682218334Speter 682318334Speter(define_insn "" 682418334Speter [(set (match_operand 0 "" "=rf") 682518334Speter (call (mem:QI (match_operand:SI 1 "symbolic_operand" "")) 682618334Speter (match_operand:SI 2 "general_operand" "g"))) 682718334Speter (set (reg:SI 7) (plus:SI (reg:SI 7) 682818334Speter (match_operand:SI 4 "immediate_operand" "i")))] 682918334Speter "!HALF_PIC_P ()" 683018334Speter "call %P1") 683118334Speter 683218334Speter(define_expand "call_value" 683318334Speter [(set (match_operand 0 "" "") 683418334Speter (call (match_operand:QI 1 "indirect_operand" "") 683518334Speter (match_operand:SI 2 "general_operand" "")))] 683618334Speter ;; Operand 2 not used on the i386. 683718334Speter "" 683818334Speter " 683918334Speter{ 684018334Speter rtx addr; 684118334Speter 684218334Speter if (flag_pic) 684318334Speter current_function_uses_pic_offset_table = 1; 684418334Speter 684518334Speter /* With half-pic, force the address into a register. */ 684618334Speter addr = XEXP (operands[1], 0); 684718334Speter if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr)) 684818334Speter XEXP (operands[1], 0) = force_reg (Pmode, addr); 684918334Speter 685018334Speter if (! expander_call_insn_operand (operands[1], QImode)) 685118334Speter operands[1] 685218334Speter = change_address (operands[1], VOIDmode, 685318334Speter copy_to_mode_reg (Pmode, XEXP (operands[1], 0))); 685418334Speter}") 685518334Speter 685618334Speter(define_insn "" 685718334Speter [(set (match_operand 0 "" "=rf") 685818334Speter (call (match_operand:QI 1 "call_insn_operand" "m") 685918334Speter (match_operand:SI 2 "general_operand" "g")))] 686018334Speter ;; Operand 2 not used on the i386. 686118334Speter "" 686218334Speter "* 686318334Speter{ 686418334Speter if (GET_CODE (operands[1]) == MEM 686518334Speter && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) 686618334Speter { 686718334Speter operands[1] = XEXP (operands[1], 0); 686818334Speter output_asm_insn (AS1 (call,%*%1), operands); 686918334Speter } 687018334Speter else 687118334Speter output_asm_insn (AS1 (call,%P1), operands); 687218334Speter 687318334Speter RET; 687418334Speter}") 687518334Speter 687618334Speter(define_insn "" 687718334Speter [(set (match_operand 0 "" "=rf") 687818334Speter (call (mem:QI (match_operand:SI 1 "symbolic_operand" "")) 687918334Speter (match_operand:SI 2 "general_operand" "g")))] 688018334Speter ;; Operand 2 not used on the i386. 688118334Speter "!HALF_PIC_P ()" 688218334Speter "call %P1") 688318334Speter 688418334Speter;; Call subroutine returning any type. 688518334Speter 688618334Speter(define_expand "untyped_call" 688718334Speter [(parallel [(call (match_operand 0 "" "") 688818334Speter (const_int 0)) 688918334Speter (match_operand 1 "" "") 689018334Speter (match_operand 2 "" "")])] 689118334Speter "" 689218334Speter " 689318334Speter{ 689418334Speter int i; 689518334Speter 689618334Speter /* In order to give reg-stack an easier job in validating two 689718334Speter coprocessor registers as containing a possible return value, 689818334Speter simply pretend the untyped call returns a complex long double 689918334Speter value. */ 690050650Sobrien 690118334Speter emit_call_insn (TARGET_80387 690250650Sobrien ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG), 690350650Sobrien operands[0], const0_rtx) 690418334Speter : gen_call (operands[0], const0_rtx)); 690518334Speter 690618334Speter for (i = 0; i < XVECLEN (operands[2], 0); i++) 690718334Speter { 690818334Speter rtx set = XVECEXP (operands[2], 0, i); 690918334Speter emit_move_insn (SET_DEST (set), SET_SRC (set)); 691018334Speter } 691118334Speter 691218334Speter /* The optimizer does not know that the call sets the function value 691318334Speter registers we stored in the result block. We avoid problems by 691418334Speter claiming that all hard registers are used and clobbered at this 691518334Speter point. */ 691618334Speter emit_insn (gen_blockage ()); 691718334Speter 691818334Speter DONE; 691918334Speter}") 692018334Speter 692118334Speter;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 692218334Speter;; all of memory. This blocks insns from being moved across this point. 692318334Speter 692418334Speter(define_insn "blockage" 692518334Speter [(unspec_volatile [(const_int 0)] 0)] 692618334Speter "" 692752296Sobrien "" 692852296Sobrien [(set_attr "memory" "none")]) 692918334Speter 693018334Speter;; Insn emitted into the body of a function to return from a function. 693118334Speter;; This is only done if the function's epilogue is known to be simple. 693218334Speter;; See comments for simple_386_epilogue in i386.c. 693318334Speter 693450650Sobrien(define_expand "return" 693518334Speter [(return)] 693650650Sobrien "ix86_can_use_return_insn_p ()" 693750650Sobrien "") 693850650Sobrien 693950650Sobrien(define_insn "return_internal" 694050650Sobrien [(return)] 694150650Sobrien "reload_completed" 694252296Sobrien "ret" 694352296Sobrien [(set_attr "memory" "none")]) 694450650Sobrien 694550650Sobrien(define_insn "return_pop_internal" 694650650Sobrien [(return) 694750650Sobrien (use (match_operand:SI 0 "const_int_operand" ""))] 694850650Sobrien "reload_completed" 694952296Sobrien "ret %0" 695052296Sobrien [(set_attr "memory" "none")]) 695150650Sobrien 695250650Sobrien(define_insn "nop" 695350650Sobrien [(const_int 0)] 695450650Sobrien "" 695552296Sobrien "nop" 695652296Sobrien [(set_attr "memory" "none")]) 695750650Sobrien 695850650Sobrien(define_expand "prologue" 695950650Sobrien [(const_int 1)] 696050650Sobrien "" 696150650Sobrien " 696250650Sobrien{ 696350650Sobrien ix86_expand_prologue (); 696450650Sobrien DONE; 696550650Sobrien}") 696650650Sobrien 696750650Sobrien;; The use of UNSPEC here is currently not necessary - a simple SET of ebp 696850650Sobrien;; to itself would be enough. But this way we are safe even if some optimizer 696950650Sobrien;; becomes too clever in the future. 697050650Sobrien(define_insn "prologue_set_stack_ptr" 697150650Sobrien [(set (reg:SI 7) 697250650Sobrien (minus:SI (reg:SI 7) (match_operand:SI 0 "immediate_operand" "i"))) 697350650Sobrien (set (reg:SI 6) (unspec:SI [(reg:SI 6)] 4))] 697450650Sobrien "" 697518334Speter "* 697618334Speter{ 697750650Sobrien rtx xops [2]; 697850650Sobrien 697950650Sobrien xops[0] = operands[0]; 698050650Sobrien xops[1] = stack_pointer_rtx; 698150650Sobrien output_asm_insn (AS2 (sub%L1,%0,%1), xops); 698218334Speter RET; 698352296Sobrien}" 698452296Sobrien [(set_attr "memory" "none")]) 698518334Speter 698650650Sobrien(define_insn "prologue_set_got" 698750650Sobrien [(set (match_operand:SI 0 "" "") 698850650Sobrien (unspec_volatile 698950650Sobrien [(plus:SI (match_dup 0) 699050650Sobrien (plus:SI (match_operand:SI 1 "symbolic_operand" "") 699150650Sobrien (minus:SI (pc) (match_operand 2 "" ""))))] 1))] 699218334Speter "" 699350650Sobrien "* 699450650Sobrien{ 699550650Sobrien char buffer[64]; 699618334Speter 699750650Sobrien if (TARGET_DEEP_BRANCH_PREDICTION) 699850650Sobrien { 699950650Sobrien sprintf (buffer, \"addl %s,%%0\", XSTR (operands[1], 0)); 700050650Sobrien output_asm_insn (buffer, operands); 700150650Sobrien } 700250650Sobrien else 700350650Sobrien { 700450650Sobrien sprintf (buffer, \"addl %s+[.-%%X2],%%0\", XSTR (operands[1], 0)); 700550650Sobrien output_asm_insn (buffer, operands); 700650650Sobrien } 700750650Sobrien RET; 700850650Sobrien}") 700950650Sobrien 701050650Sobrien(define_insn "prologue_get_pc" 701150650Sobrien [(set (match_operand:SI 0 "" "") 701250650Sobrien (unspec_volatile [(plus:SI (pc) (match_operand 1 "" ""))] 2))] 701350650Sobrien "" 701450650Sobrien "* 701550650Sobrien{ 701650650Sobrien output_asm_insn (AS1 (call,%X1), operands); 701750650Sobrien if (! TARGET_DEEP_BRANCH_PREDICTION) 701850650Sobrien { 701950650Sobrien ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (operands[1])); 702050650Sobrien } 702150650Sobrien RET; 702252296Sobrien}" 702352296Sobrien [(set_attr "memory" "none")]) 702450650Sobrien 702550650Sobrien(define_insn "prologue_get_pc_and_set_got" 702650650Sobrien [(unspec_volatile [(match_operand:SI 0 "" "")] 3)] 702750650Sobrien "" 702850650Sobrien "* 702950650Sobrien{ 703050650Sobrien operands[1] = gen_label_rtx (); 703150650Sobrien output_asm_insn (AS1 (call,%X1), operands); 703250650Sobrien ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", 703350650Sobrien CODE_LABEL_NUMBER (operands[1])); 703450650Sobrien output_asm_insn (AS1 (pop%L0,%0), operands); 703552296Sobrien output_asm_insn (\"addl $%__GLOBAL_OFFSET_TABLE_+[.-%X1],%0\", operands); 703650650Sobrien RET; 703752296Sobrien}" 703852296Sobrien [(set_attr "memory" "none")]) 703950650Sobrien 704050650Sobrien(define_expand "epilogue" 704150650Sobrien [(const_int 1)] 704250650Sobrien "" 704350650Sobrien " 704450650Sobrien{ 704550650Sobrien ix86_expand_epilogue (); 704650650Sobrien DONE; 704750650Sobrien}") 704850650Sobrien 704950650Sobrien(define_insn "epilogue_set_stack_ptr" 705050650Sobrien [(set (reg:SI 7) (reg:SI 6)) 705150650Sobrien (clobber (reg:SI 6))] 705250650Sobrien "" 705350650Sobrien "* 705450650Sobrien{ 705550650Sobrien rtx xops [2]; 705650650Sobrien 705750650Sobrien xops[0] = frame_pointer_rtx; 705850650Sobrien xops[1] = stack_pointer_rtx; 705950650Sobrien output_asm_insn (AS2 (mov%L0,%0,%1), xops); 706050650Sobrien RET; 706152296Sobrien}" 706252296Sobrien [(set_attr "memory" "none")]) 706350650Sobrien 706450650Sobrien(define_insn "leave" 706550650Sobrien [(const_int 2) 706650650Sobrien (clobber (reg:SI 6)) 706750650Sobrien (clobber (reg:SI 7))] 706850650Sobrien "" 706952296Sobrien "leave" 707052296Sobrien [(set_attr "memory" "none")]) 707150650Sobrien 707250650Sobrien(define_insn "pop" 707350650Sobrien [(set (match_operand:SI 0 "register_operand" "r") 707450650Sobrien (mem:SI (reg:SI 7))) 707550650Sobrien (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))] 707650650Sobrien "" 707750650Sobrien "* 707850650Sobrien{ 707950650Sobrien output_asm_insn (AS1 (pop%L0,%P0), operands); 708050650Sobrien RET; 708152296Sobrien}" 708252296Sobrien [(set_attr "memory" "load")]) 708350650Sobrien 708418334Speter(define_expand "movstrsi" 708518334Speter [(parallel [(set (match_operand:BLK 0 "memory_operand" "") 708618334Speter (match_operand:BLK 1 "memory_operand" "")) 708718334Speter (use (match_operand:SI 2 "const_int_operand" "")) 708818334Speter (use (match_operand:SI 3 "const_int_operand" "")) 708918334Speter (clobber (match_scratch:SI 4 "")) 709018334Speter (clobber (match_dup 5)) 709118334Speter (clobber (match_dup 6))])] 709218334Speter "" 709318334Speter " 709418334Speter{ 709518334Speter rtx addr0, addr1; 709618334Speter 709718334Speter if (GET_CODE (operands[2]) != CONST_INT) 709818334Speter FAIL; 709918334Speter 710018334Speter addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); 710118334Speter addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); 710218334Speter 710318334Speter operands[5] = addr0; 710418334Speter operands[6] = addr1; 710518334Speter 710650650Sobrien operands[0] = change_address (operands[0], VOIDmode, addr0); 710750650Sobrien operands[1] = change_address (operands[1], VOIDmode, addr1); 710818334Speter}") 710918334Speter 711018334Speter;; It might seem that operands 0 & 1 could use predicate register_operand. 711118334Speter;; But strength reduction might offset the MEM expression. So we let 711218334Speter;; reload put the address into %edi & %esi. 711318334Speter 711418334Speter(define_insn "" 711518334Speter [(set (mem:BLK (match_operand:SI 0 "address_operand" "D")) 711618334Speter (mem:BLK (match_operand:SI 1 "address_operand" "S"))) 711718334Speter (use (match_operand:SI 2 "const_int_operand" "n")) 711818334Speter (use (match_operand:SI 3 "immediate_operand" "i")) 711918334Speter (clobber (match_scratch:SI 4 "=&c")) 712018334Speter (clobber (match_dup 0)) 712118334Speter (clobber (match_dup 1))] 712218334Speter "" 712318334Speter "* 712418334Speter{ 712518334Speter rtx xops[2]; 712618334Speter 712718334Speter output_asm_insn (\"cld\", operands); 712818334Speter if (GET_CODE (operands[2]) == CONST_INT) 712918334Speter { 713018334Speter if (INTVAL (operands[2]) & ~0x03) 713118334Speter { 713218334Speter xops[0] = GEN_INT ((INTVAL (operands[2]) >> 2) & 0x3fffffff); 713318334Speter xops[1] = operands[4]; 713418334Speter 713518334Speter output_asm_insn (AS2 (mov%L1,%0,%1), xops); 713618334Speter#ifdef INTEL_SYNTAX 713718334Speter output_asm_insn (\"rep movsd\", xops); 713818334Speter#else 713918334Speter output_asm_insn (\"rep\;movsl\", xops); 714018334Speter#endif 714118334Speter } 714218334Speter if (INTVAL (operands[2]) & 0x02) 714318334Speter output_asm_insn (\"movsw\", operands); 714418334Speter if (INTVAL (operands[2]) & 0x01) 714518334Speter output_asm_insn (\"movsb\", operands); 714618334Speter } 714718334Speter else 714818334Speter abort (); 714918334Speter RET; 715018334Speter}") 715118334Speter 715250650Sobrien(define_expand "clrstrsi" 715350650Sobrien [(set (match_dup 3) (const_int 0)) 715450650Sobrien (parallel [(set (match_operand:BLK 0 "memory_operand" "") 715550650Sobrien (const_int 0)) 715650650Sobrien (use (match_operand:SI 1 "const_int_operand" "")) 715750650Sobrien (use (match_operand:SI 2 "const_int_operand" "")) 715850650Sobrien (use (match_dup 3)) 715950650Sobrien (clobber (match_scratch:SI 4 "")) 716050650Sobrien (clobber (match_dup 5))])] 716150650Sobrien "" 716250650Sobrien " 716350650Sobrien{ 716452296Sobrien rtx addr0; 716550650Sobrien 716650650Sobrien if (GET_CODE (operands[1]) != CONST_INT) 716750650Sobrien FAIL; 716850650Sobrien 716950650Sobrien addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); 717050650Sobrien 717150650Sobrien operands[3] = gen_reg_rtx (SImode); 717250650Sobrien operands[5] = addr0; 717350650Sobrien 717450650Sobrien operands[0] = gen_rtx_MEM (BLKmode, addr0); 717550650Sobrien}") 717650650Sobrien 717750650Sobrien;; It might seem that operand 0 could use predicate register_operand. 717850650Sobrien;; But strength reduction might offset the MEM expression. So we let 717950650Sobrien;; reload put the address into %edi. 718050650Sobrien 718152296Sobrien(define_insn "*bzero" 718250650Sobrien [(set (mem:BLK (match_operand:SI 0 "address_operand" "D")) 718350650Sobrien (const_int 0)) 718450650Sobrien (use (match_operand:SI 1 "const_int_operand" "n")) 718550650Sobrien (use (match_operand:SI 2 "immediate_operand" "i")) 718650650Sobrien (use (match_operand:SI 3 "register_operand" "a")) 718750650Sobrien (clobber (match_scratch:SI 4 "=&c")) 718850650Sobrien (clobber (match_dup 0))] 718950650Sobrien "" 719050650Sobrien "* 719150650Sobrien{ 719250650Sobrien rtx xops[2]; 719350650Sobrien 719450650Sobrien output_asm_insn (\"cld\", operands); 719550650Sobrien if (GET_CODE (operands[1]) == CONST_INT) 719650650Sobrien { 719752296Sobrien unsigned int count = INTVAL (operands[1]) & 0xffffffff; 719852296Sobrien if (count & ~0x03) 719950650Sobrien { 720052296Sobrien xops[0] = GEN_INT (count / 4); 720150650Sobrien xops[1] = operands[4]; 720250650Sobrien 720352296Sobrien /* K6: stos takes 1 cycle, rep stos takes 8 + %ecx cycles. 720452296Sobrien 80386: 4/5+5n (+2 for set of ecx) 720552296Sobrien 80486: 5/7+5n (+1 for set of ecx) 720652296Sobrien */ 720752296Sobrien if (count / 4 < ((int) ix86_cpu < (int)PROCESSOR_PENTIUM ? 4 : 6)) 720852296Sobrien { 720952296Sobrien do 721050650Sobrien#ifdef INTEL_SYNTAX 721152296Sobrien output_asm_insn (\"stosd\", xops); 721250650Sobrien#else 721352296Sobrien output_asm_insn (\"stosl\", xops); 721450650Sobrien#endif 721552296Sobrien while ((count -= 4) > 3); 721652296Sobrien } 721752296Sobrien else 721852296Sobrien { 721952296Sobrien output_asm_insn (AS2 (mov%L1,%0,%1), xops); 722052296Sobrien#ifdef INTEL_SYNTAX 722152296Sobrien output_asm_insn (\"rep stosd\", xops); 722252296Sobrien#else 722352296Sobrien output_asm_insn (\"rep\;stosl\", xops); 722452296Sobrien#endif 722552296Sobrien } 722650650Sobrien } 722750650Sobrien if (INTVAL (operands[1]) & 0x02) 722850650Sobrien output_asm_insn (\"stosw\", operands); 722950650Sobrien if (INTVAL (operands[1]) & 0x01) 723050650Sobrien output_asm_insn (\"stosb\", operands); 723150650Sobrien } 723250650Sobrien else 723350650Sobrien abort (); 723450650Sobrien RET; 723550650Sobrien}") 723650650Sobrien 723718334Speter(define_expand "cmpstrsi" 723818334Speter [(parallel [(set (match_operand:SI 0 "general_operand" "") 723918334Speter (compare:SI (match_operand:BLK 1 "general_operand" "") 724018334Speter (match_operand:BLK 2 "general_operand" ""))) 724118334Speter (use (match_operand:SI 3 "general_operand" "")) 724218334Speter (use (match_operand:SI 4 "immediate_operand" "")) 724318334Speter (clobber (match_dup 5)) 724418334Speter (clobber (match_dup 6)) 724518334Speter (clobber (match_dup 3))])] 724618334Speter "" 724718334Speter " 724818334Speter{ 724918334Speter rtx addr1, addr2; 725018334Speter 725118334Speter addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); 725218334Speter addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0)); 725318334Speter operands[3] = copy_to_mode_reg (SImode, operands[3]); 725418334Speter 725518334Speter operands[5] = addr1; 725618334Speter operands[6] = addr2; 725718334Speter 725850650Sobrien operands[1] = gen_rtx_MEM (BLKmode, addr1); 725950650Sobrien operands[2] = gen_rtx_MEM (BLKmode, addr2); 726018334Speter 726118334Speter}") 726218334Speter 726318334Speter;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is 726418334Speter;; zero. Emit extra code to make sure that a zero-length compare is EQ. 726518334Speter 726618334Speter;; It might seem that operands 0 & 1 could use predicate register_operand. 726718334Speter;; But strength reduction might offset the MEM expression. So we let 726818334Speter;; reload put the address into %edi & %esi. 726918334Speter 727018334Speter;; ??? Most comparisons have a constant length, and it's therefore 727118334Speter;; possible to know that the length is non-zero, and to avoid the extra 727218334Speter;; code to handle zero-length compares. 727318334Speter 727418334Speter(define_insn "" 727550650Sobrien [(set (match_operand:SI 0 "register_operand" "=&r") 727618334Speter (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S")) 727718334Speter (mem:BLK (match_operand:SI 2 "address_operand" "D")))) 727818334Speter (use (match_operand:SI 3 "register_operand" "c")) 727918334Speter (use (match_operand:SI 4 "immediate_operand" "i")) 728018334Speter (clobber (match_dup 1)) 728118334Speter (clobber (match_dup 2)) 728218334Speter (clobber (match_dup 3))] 728318334Speter "" 728418334Speter "* 728518334Speter{ 728650650Sobrien rtx xops[2], label; 728718334Speter 728818334Speter label = gen_label_rtx (); 728918334Speter 729018334Speter output_asm_insn (\"cld\", operands); 729118334Speter output_asm_insn (AS2 (xor%L0,%0,%0), operands); 729218334Speter output_asm_insn (\"repz\;cmps%B2\", operands); 729318334Speter output_asm_insn (\"je %l0\", &label); 729418334Speter 729518334Speter xops[0] = operands[0]; 729650650Sobrien xops[1] = const1_rtx; 729750650Sobrien output_asm_insn (AS2 (sbb%L0,%0,%0), xops); 729850650Sobrien if (QI_REG_P (xops[0])) 729950650Sobrien output_asm_insn (AS2 (or%B0,%1,%b0), xops); 730050650Sobrien else 730150650Sobrien output_asm_insn (AS2 (or%L0,%1,%0), xops); 730250650Sobrien 730318334Speter ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label)); 730418334Speter RET; 730518334Speter}") 730618334Speter 730718334Speter(define_insn "" 730818334Speter [(set (cc0) 730918334Speter (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S")) 731018334Speter (mem:BLK (match_operand:SI 1 "address_operand" "D")))) 731118334Speter (use (match_operand:SI 2 "register_operand" "c")) 731218334Speter (use (match_operand:SI 3 "immediate_operand" "i")) 731318334Speter (clobber (match_dup 0)) 731418334Speter (clobber (match_dup 1)) 731518334Speter (clobber (match_dup 2))] 731618334Speter "" 731718334Speter "* 731818334Speter{ 731918334Speter rtx xops[2]; 732018334Speter 732118334Speter cc_status.flags |= CC_NOT_SIGNED; 732218334Speter 732350650Sobrien xops[0] = gen_rtx_REG (QImode, 0); 732418334Speter xops[1] = CONST0_RTX (QImode); 732518334Speter 732618334Speter output_asm_insn (\"cld\", operands); 732718334Speter output_asm_insn (AS2 (test%B0,%1,%0), xops); 732818334Speter return \"repz\;cmps%B2\"; 732918334Speter}") 733018334Speter 733150650Sobrien 733218334Speter;; Note, you cannot optimize away the branch following the bsfl by assuming 733318334Speter;; that the destination is not modified if the input is 0, since not all 733418334Speter;; x86 implementations do this. 733518334Speter 733650650Sobrien(define_expand "ffssi2" 733750650Sobrien [(set (match_operand:SI 0 "general_operand" "") 733850650Sobrien (ffs:SI (match_operand:SI 1 "general_operand" "")))] 733918334Speter "" 734050650Sobrien " 734118334Speter{ 734250650Sobrien rtx label = gen_label_rtx (), temp = gen_reg_rtx (SImode); 734318334Speter 734450650Sobrien emit_insn (gen_ffssi_1 (temp, operands[1])); 734550650Sobrien emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, SImode, 0, 0); 734650650Sobrien emit_jump_insn (gen_bne (label)); 734750650Sobrien emit_move_insn (temp, constm1_rtx); 734850650Sobrien emit_label (label); 734950650Sobrien temp = expand_binop (SImode, add_optab, temp, const1_rtx, 735050650Sobrien operands[0], 0, OPTAB_WIDEN); 735118334Speter 735250650Sobrien if (temp != operands[0]) 735350650Sobrien emit_move_insn (operands[0], temp); 735450650Sobrien DONE; 735518334Speter}") 735618334Speter 735750650Sobrien(define_insn "ffssi_1" 735850650Sobrien [(set (match_operand:SI 0 "register_operand" "=r") 735950650Sobrien (unspec:SI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))] 736018334Speter "" 736150650Sobrien "* return AS2 (bsf%L0,%1,%0);") 736218334Speter 736350650Sobrien(define_expand "ffshi2" 736450650Sobrien [(set (match_operand:SI 0 "general_operand" "") 736550650Sobrien (ffs:HI (match_operand:HI 1 "general_operand" "")))] 736618334Speter "" 736750650Sobrien " 736818334Speter{ 736950650Sobrien rtx label = gen_label_rtx (), temp = gen_reg_rtx (HImode); 737018334Speter 737150650Sobrien emit_insn (gen_ffshi_1 (temp, operands[1])); 737250650Sobrien emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, HImode, 0, 0); 737350650Sobrien emit_jump_insn (gen_bne (label)); 737450650Sobrien emit_move_insn (temp, constm1_rtx); 737550650Sobrien emit_label (label); 737650650Sobrien temp = expand_binop (HImode, add_optab, temp, const1_rtx, 737750650Sobrien operands[0], 0, OPTAB_WIDEN); 737818334Speter 737950650Sobrien if (temp != operands[0]) 738050650Sobrien emit_move_insn (operands[0], temp); 738150650Sobrien DONE; 738218334Speter}") 738350650Sobrien 738450650Sobrien(define_insn "ffshi_1" 738550650Sobrien [(set (match_operand:HI 0 "register_operand" "=r") 738650650Sobrien (unspec:HI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))] 738750650Sobrien "" 738850650Sobrien "* return AS2 (bsf%W0,%1,%0);") 738918334Speter 739018334Speter;; These patterns match the binary 387 instructions for addM3, subM3, 739118334Speter;; mulM3 and divM3. There are three patterns for each of DFmode and 739218334Speter;; SFmode. The first is the normal insn, the second the same insn but 739318334Speter;; with one operand a conversion, and the third the same insn but with 739452296Sobrien;; the other operand a conversion. 739518334Speter 739618334Speter(define_insn "" 739718334Speter [(set (match_operand:DF 0 "register_operand" "=f,f") 739818334Speter (match_operator:DF 3 "binary_387_op" 739918334Speter [(match_operand:DF 1 "nonimmediate_operand" "0,fm") 740018334Speter (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))] 740118334Speter "TARGET_80387" 740250650Sobrien "* return output_387_binary_op (insn, operands);" 740350650Sobrien [(set (attr "type") 740450650Sobrien (cond [(match_operand:DF 3 "is_mul" "") 740550650Sobrien (const_string "fpmul") 740650650Sobrien (match_operand:DF 3 "is_div" "") 740750650Sobrien (const_string "fpdiv") 740850650Sobrien ] 740950650Sobrien (const_string "fpop") 741050650Sobrien ) 741150650Sobrien )]) 741218334Speter 741318334Speter(define_insn "" 741418334Speter [(set (match_operand:XF 0 "register_operand" "=f,f") 741518334Speter (match_operator:XF 3 "binary_387_op" 741650650Sobrien [(match_operand:XF 1 "register_operand" "0,f") 741750650Sobrien (match_operand:XF 2 "register_operand" "f,0")]))] 741818334Speter "TARGET_80387" 741950650Sobrien "* return output_387_binary_op (insn, operands);" 742050650Sobrien [(set (attr "type") 742150650Sobrien (cond [(match_operand:DF 3 "is_mul" "") 742250650Sobrien (const_string "fpmul") 742350650Sobrien (match_operand:DF 3 "is_div" "") 742450650Sobrien (const_string "fpdiv") 742550650Sobrien ] 742650650Sobrien (const_string "fpop") 742750650Sobrien ) 742850650Sobrien )]) 742918334Speter 743018334Speter(define_insn "" 743118334Speter [(set (match_operand:XF 0 "register_operand" "=f,f") 743218334Speter (match_operator:XF 3 "binary_387_op" 743350650Sobrien [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0")) 743450650Sobrien (match_operand:XF 2 "register_operand" "0,f")]))] 743518334Speter "TARGET_80387" 743650650Sobrien "* return output_387_binary_op (insn, operands);" 743750650Sobrien [(set (attr "type") 743850650Sobrien (cond [(match_operand:DF 3 "is_mul" "") 743950650Sobrien (const_string "fpmul") 744050650Sobrien (match_operand:DF 3 "is_div" "") 744150650Sobrien (const_string "fpdiv") 744250650Sobrien ] 744350650Sobrien (const_string "fpop") 744450650Sobrien ) 744550650Sobrien )]) 744618334Speter 744718334Speter(define_insn "" 744818334Speter [(set (match_operand:XF 0 "register_operand" "=f,f") 744918334Speter (match_operator:XF 3 "binary_387_op" 745050650Sobrien [(match_operand:XF 1 "register_operand" "0,f") 745118334Speter (float_extend:XF 745250650Sobrien (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 745318334Speter "TARGET_80387" 745450650Sobrien "* return output_387_binary_op (insn, operands);" 745550650Sobrien [(set (attr "type") 745650650Sobrien (cond [(match_operand:DF 3 "is_mul" "") 745750650Sobrien (const_string "fpmul") 745850650Sobrien (match_operand:DF 3 "is_div" "") 745950650Sobrien (const_string "fpdiv") 746050650Sobrien ] 746150650Sobrien (const_string "fpop") 746250650Sobrien ) 746350650Sobrien )]) 746418334Speter 746518334Speter(define_insn "" 746618334Speter [(set (match_operand:DF 0 "register_operand" "=f,f") 746718334Speter (match_operator:DF 3 "binary_387_op" 746850650Sobrien [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0")) 746950650Sobrien (match_operand:DF 2 "register_operand" "0,f")]))] 747018334Speter "TARGET_80387" 747150650Sobrien "* return output_387_binary_op (insn, operands);" 747250650Sobrien [(set (attr "type") 747350650Sobrien (cond [(match_operand:DF 3 "is_mul" "") 747450650Sobrien (const_string "fpmul") 747550650Sobrien (match_operand:DF 3 "is_div" "") 747650650Sobrien (const_string "fpdiv") 747750650Sobrien ] 747850650Sobrien (const_string "fpop") 747950650Sobrien ) 748050650Sobrien )]) 748118334Speter 748218334Speter(define_insn "" 748318334Speter [(set (match_operand:DF 0 "register_operand" "=f,f") 748418334Speter (match_operator:DF 3 "binary_387_op" 748550650Sobrien [(match_operand:DF 1 "register_operand" "0,f") 748618334Speter (float_extend:DF 748750650Sobrien (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 748818334Speter "TARGET_80387" 748950650Sobrien "* return output_387_binary_op (insn, operands);" 749050650Sobrien [(set (attr "type") 749150650Sobrien (cond [(match_operand:DF 3 "is_mul" "") 749250650Sobrien (const_string "fpmul") 749350650Sobrien (match_operand:DF 3 "is_div" "") 749450650Sobrien (const_string "fpdiv") 749550650Sobrien ] 749650650Sobrien (const_string "fpop") 749750650Sobrien ) 749850650Sobrien )]) 749918334Speter 750018334Speter(define_insn "" 750118334Speter [(set (match_operand:SF 0 "register_operand" "=f,f") 750218334Speter (match_operator:SF 3 "binary_387_op" 750318334Speter [(match_operand:SF 1 "nonimmediate_operand" "0,fm") 750418334Speter (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))] 750518334Speter "TARGET_80387" 750650650Sobrien "* return output_387_binary_op (insn, operands);" 750750650Sobrien [(set (attr "type") 750850650Sobrien (cond [(match_operand:DF 3 "is_mul" "") 750950650Sobrien (const_string "fpmul") 751050650Sobrien (match_operand:DF 3 "is_div" "") 751150650Sobrien (const_string "fpdiv") 751250650Sobrien ] 751350650Sobrien (const_string "fpop") 751450650Sobrien ) 751550650Sobrien )]) 751618334Speter 751718334Speter(define_expand "strlensi" 751818334Speter [(parallel [(set (match_dup 4) 751918334Speter (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" "")) 752050650Sobrien (match_operand:QI 2 "immediate_operand" "") 752118334Speter (match_operand:SI 3 "immediate_operand" "")] 0)) 752218334Speter (clobber (match_dup 1))]) 752318334Speter (set (match_dup 5) 752418334Speter (not:SI (match_dup 4))) 752518334Speter (set (match_operand:SI 0 "register_operand" "") 752650650Sobrien (plus:SI (match_dup 5) 752750650Sobrien (const_int -1)))] 752818334Speter "" 752918334Speter " 753018334Speter{ 753150650Sobrien if (TARGET_UNROLL_STRLEN && operands[2] == const0_rtx && optimize > 1) 753250650Sobrien { 753350650Sobrien rtx address; 753450650Sobrien rtx scratch; 753550650Sobrien 753650650Sobrien /* well it seems that some optimizer does not combine a call like 753750650Sobrien foo(strlen(bar), strlen(bar)); 753850650Sobrien when the move and the subtraction is done here. It does calculate 753950650Sobrien the length just once when these instructions are done inside of 754050650Sobrien output_strlen_unroll(). But I think since &bar[strlen(bar)] is 754150650Sobrien often used and I use one fewer register for the lifetime of 754250650Sobrien output_strlen_unroll() this is better. */ 754350650Sobrien scratch = gen_reg_rtx (SImode); 754450650Sobrien address = force_reg (SImode, XEXP (operands[1], 0)); 754550650Sobrien 754650650Sobrien /* move address to scratch-register 754750650Sobrien this is done here because the i586 can do the following and 754850650Sobrien in the same cycle with the following move. */ 754950650Sobrien if (GET_CODE (operands[3]) != CONST_INT || INTVAL (operands[3]) < 4) 755050650Sobrien emit_insn (gen_movsi (scratch, address)); 755150650Sobrien 755250650Sobrien emit_insn (gen_movsi (operands[0], address)); 755350650Sobrien 755450650Sobrien if(TARGET_USE_Q_REG) 755550650Sobrien emit_insn (gen_strlensi_unroll5 (operands[0], 755650650Sobrien operands[3], 755750650Sobrien scratch, 755850650Sobrien operands[0])); 755950650Sobrien else 756050650Sobrien emit_insn (gen_strlensi_unroll4 (operands[0], 756150650Sobrien operands[3], 756250650Sobrien scratch, 756350650Sobrien operands[0])); 756450650Sobrien 756550650Sobrien /* gen_strlensi_unroll[45] returns the address of the zero 756650650Sobrien at the end of the string, like memchr(), so compute the 756750650Sobrien length by subtracting the startaddress. */ 756850650Sobrien emit_insn (gen_subsi3 (operands[0], operands[0], address)); 756950650Sobrien DONE; 757050650Sobrien } 757150650Sobrien 757218334Speter operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); 757318334Speter operands[4] = gen_reg_rtx (SImode); 757418334Speter operands[5] = gen_reg_rtx (SImode); 757518334Speter}") 757618334Speter 757718334Speter;; It might seem that operands 0 & 1 could use predicate register_operand. 757818334Speter;; But strength reduction might offset the MEM expression. So we let 757918334Speter;; reload put the address into %edi. 758018334Speter 758118334Speter(define_insn "" 758218334Speter [(set (match_operand:SI 0 "register_operand" "=&c") 758318334Speter (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D")) 758450650Sobrien (match_operand:QI 2 "immediate_operand" "a") 758518334Speter (match_operand:SI 3 "immediate_operand" "i")] 0)) 758618334Speter (clobber (match_dup 1))] 758718334Speter "" 758818334Speter "* 758918334Speter{ 759018334Speter rtx xops[2]; 759118334Speter 759218334Speter xops[0] = operands[0]; 759318334Speter xops[1] = constm1_rtx; 759418334Speter output_asm_insn (\"cld\", operands); 759518334Speter output_asm_insn (AS2 (mov%L0,%1,%0), xops); 759618334Speter return \"repnz\;scas%B2\"; 759718334Speter}") 759850650Sobrien 759950650Sobrien/* Conditional move define_insns. */ 760050650Sobrien 760150650Sobrien(define_expand "movsicc" 760250650Sobrien [(set (match_operand:SI 0 "register_operand" "") 760350650Sobrien (if_then_else:SI (match_operand 1 "comparison_operator" "") 760450650Sobrien (match_operand:SI 2 "nonimmediate_operand" "") 760550650Sobrien (match_operand:SI 3 "nonimmediate_operand" "")))] 760650650Sobrien "TARGET_CMOVE" 760750650Sobrien " 760850650Sobrien{ 760950650Sobrien if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT) 761050650Sobrien FAIL; 761150650Sobrien 761250650Sobrien operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), 761350650Sobrien GET_MODE (i386_compare_op0), 761450650Sobrien i386_compare_op0, i386_compare_op1); 761550650Sobrien}") 761650650Sobrien 761750650Sobrien(define_insn "" 761850650Sobrien [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 761950650Sobrien (if_then_else:SI (match_operator 1 "comparison_operator" 762050650Sobrien [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m") 762150650Sobrien (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")]) 762250650Sobrien (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0") 762350650Sobrien (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm")))] 762450650Sobrien "TARGET_CMOVE" 762550650Sobrien "#") 762650650Sobrien 762750650Sobrien(define_insn "" 762850650Sobrien [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 762950650Sobrien (if_then_else:SI (match_operator 1 "comparison_operator" 763050650Sobrien [(match_operand 2 "nonimmediate_operand" "r,m,r,m") 763150650Sobrien (match_operand 3 "general_operand" "rmi,ri,rmi,ri")]) 763250650Sobrien (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0") 763350650Sobrien (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm")))] 763450650Sobrien "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT" 763550650Sobrien "#") 763650650Sobrien 763750650Sobrien(define_split 763852296Sobrien [(set (match_operand:SI 0 "register_operand" "") 763950650Sobrien (if_then_else:SI (match_operator 1 "comparison_operator" 764050650Sobrien [(match_operand 2 "nonimmediate_operand" "") 764150650Sobrien (const_int 0)]) 764252296Sobrien (match_operand:SI 3 "nonimmediate_operand" "") 764352296Sobrien (match_operand:SI 4 "nonimmediate_operand" "")))] 764450650Sobrien "TARGET_CMOVE && reload_completed" 764550650Sobrien [(set (cc0) 764650650Sobrien (match_dup 2)) 764750650Sobrien (set (match_dup 0) 764850650Sobrien (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) 764950650Sobrien (match_dup 3) (match_dup 4)))] 765050650Sobrien "") 765150650Sobrien 765250650Sobrien(define_split 765352296Sobrien [(set (match_operand:SI 0 "register_operand" "") 765450650Sobrien (if_then_else:SI (match_operator 1 "comparison_operator" 765550650Sobrien [(match_operand 2 "nonimmediate_operand" "") 765650650Sobrien (match_operand 3 "general_operand" "")]) 765752296Sobrien (match_operand:SI 4 "nonimmediate_operand" "") 765852296Sobrien (match_operand:SI 5 "nonimmediate_operand" "")))] 765950650Sobrien "TARGET_CMOVE && reload_completed" 766050650Sobrien [(set (cc0) (compare (match_dup 2) (match_dup 3))) 766150650Sobrien (set (match_dup 0) 766250650Sobrien (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) 766350650Sobrien (match_dup 4) (match_dup 5)))] 766450650Sobrien "") 766550650Sobrien 766650650Sobrien(define_insn "" 766750650Sobrien [(set (match_operand:SI 0 "register_operand" "=r,r") 766850650Sobrien (if_then_else:SI (match_operator 1 "comparison_operator" 766950650Sobrien [(cc0) (const_int 0)]) 767050650Sobrien (match_operand:SI 2 "nonimmediate_operand" "rm,0") 767150650Sobrien (match_operand:SI 3 "nonimmediate_operand" "0,rm")))] 767250650Sobrien "TARGET_CMOVE && reload_completed" 767350650Sobrien "* return output_int_conditional_move (which_alternative, operands);") 767450650Sobrien 767550650Sobrien(define_expand "movhicc" 767650650Sobrien [(set (match_operand:HI 0 "register_operand" "") 767750650Sobrien (if_then_else:HI (match_operand 1 "comparison_operator" "") 767850650Sobrien (match_operand:HI 2 "nonimmediate_operand" "") 767950650Sobrien (match_operand:HI 3 "nonimmediate_operand" "")))] 768050650Sobrien "TARGET_CMOVE" 768150650Sobrien " 768250650Sobrien{ 768350650Sobrien if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT) 768450650Sobrien FAIL; 768550650Sobrien 768650650Sobrien operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), 768750650Sobrien GET_MODE (i386_compare_op0), 768850650Sobrien i386_compare_op0, i386_compare_op1); 768950650Sobrien}") 769050650Sobrien 769150650Sobrien(define_insn "" 769250650Sobrien [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") 769350650Sobrien (if_then_else:HI (match_operator 1 "comparison_operator" 769450650Sobrien [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m") 769550650Sobrien (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")]) 769650650Sobrien (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0") 769750650Sobrien (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm")))] 769850650Sobrien "TARGET_CMOVE" 769950650Sobrien "#") 770050650Sobrien 770150650Sobrien(define_insn "" 770250650Sobrien [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") 770350650Sobrien (if_then_else:HI (match_operator 1 "comparison_operator" 770450650Sobrien [(match_operand 2 "nonimmediate_operand" "r,m,r,m") 770550650Sobrien (match_operand 3 "general_operand" "rmi,ri,rmi,ri")]) 770650650Sobrien (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0") 770750650Sobrien (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm")))] 770850650Sobrien "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT" 770950650Sobrien "#") 771050650Sobrien 771150650Sobrien(define_split 771252296Sobrien [(set (match_operand:HI 0 "register_operand" "") 771350650Sobrien (if_then_else:HI (match_operator 1 "comparison_operator" 771450650Sobrien [(match_operand 2 "nonimmediate_operand" "") 771550650Sobrien (const_int 0)]) 771652296Sobrien (match_operand:HI 3 "nonimmediate_operand" "") 771752296Sobrien (match_operand:HI 4 "nonimmediate_operand" "")))] 771850650Sobrien "TARGET_CMOVE && reload_completed" 771950650Sobrien [(set (cc0) 772050650Sobrien (match_dup 2)) 772150650Sobrien (set (match_dup 0) 772250650Sobrien (if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)]) 772350650Sobrien (match_dup 3) (match_dup 4)))] 772450650Sobrien "") 772550650Sobrien 772650650Sobrien(define_split 772752296Sobrien [(set (match_operand:HI 0 "register_operand" "") 772850650Sobrien (if_then_else:HI (match_operator 1 "comparison_operator" 772950650Sobrien [(match_operand 2 "nonimmediate_operand" "") 773050650Sobrien (match_operand 3 "general_operand" "")]) 773152296Sobrien (match_operand:HI 4 "nonimmediate_operand" "") 773252296Sobrien (match_operand:HI 5 "nonimmediate_operand" "")))] 773350650Sobrien "TARGET_CMOVE && reload_completed" 773450650Sobrien [(set (cc0) 773550650Sobrien (compare (match_dup 2) (match_dup 3))) 773650650Sobrien (set (match_dup 0) 773750650Sobrien (if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)]) 773850650Sobrien (match_dup 4) (match_dup 5)))] 773950650Sobrien "") 774050650Sobrien 774150650Sobrien(define_insn "" 774250650Sobrien [(set (match_operand:HI 0 "register_operand" "=r,r") 774350650Sobrien (if_then_else:HI (match_operator 1 "comparison_operator" 774450650Sobrien [(cc0) (const_int 0)]) 774550650Sobrien (match_operand:HI 2 "nonimmediate_operand" "rm,0") 774650650Sobrien (match_operand:HI 3 "nonimmediate_operand" "0,rm")))] 774750650Sobrien "TARGET_CMOVE && reload_completed" 774850650Sobrien "* return output_int_conditional_move (which_alternative, operands);") 774950650Sobrien 775050650Sobrien(define_expand "movsfcc" 775150650Sobrien [(set (match_operand:SF 0 "register_operand" "") 775250650Sobrien (if_then_else:SF (match_operand 1 "comparison_operator" "") 775350650Sobrien (match_operand:SF 2 "register_operand" "") 775450650Sobrien (match_operand:SF 3 "register_operand" "")))] 775550650Sobrien "TARGET_CMOVE" 775650650Sobrien " 775750650Sobrien{ 775850650Sobrien rtx temp; 775950650Sobrien 776050650Sobrien if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT) 776150650Sobrien FAIL; 776250650Sobrien 776350650Sobrien /* The floating point conditional move instructions don't directly 776450650Sobrien support conditions resulting from a signed integer comparison. */ 776550650Sobrien 776650650Sobrien switch (GET_CODE (operands[1])) 776750650Sobrien { 776850650Sobrien case LT: 776950650Sobrien case LE: 777050650Sobrien case GE: 777150650Sobrien case GT: 777250650Sobrien temp = emit_store_flag (gen_reg_rtx (QImode), 777350650Sobrien GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1, 777450650Sobrien VOIDmode, 0, 0); 777550650Sobrien 777650650Sobrien if (!temp) 777750650Sobrien FAIL; 777850650Sobrien 777950650Sobrien operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx); 778050650Sobrien break; 778150650Sobrien 778250650Sobrien default: 778350650Sobrien operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), 778450650Sobrien GET_MODE (i386_compare_op0), 778550650Sobrien i386_compare_op0, i386_compare_op1); 778650650Sobrien break; 778750650Sobrien } 778850650Sobrien}") 778950650Sobrien 779050650Sobrien(define_insn "" 779150650Sobrien [(set (match_operand:SF 0 "register_operand" "=f,f,f,f") 779250650Sobrien (if_then_else:SF (match_operator 1 "comparison_operator" 779350650Sobrien [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m") 779450650Sobrien (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")]) 779550650Sobrien (match_operand:SF 4 "register_operand" "f,f,0,0") 779650650Sobrien (match_operand:SF 5 "register_operand" "0,0,f,f")))] 779750650Sobrien "TARGET_CMOVE 779850650Sobrien && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE 779950650Sobrien && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT" 780050650Sobrien "#") 780150650Sobrien 780250650Sobrien(define_insn "" 780350650Sobrien [(set (match_operand:SF 0 "register_operand" "=f,f,f,f") 780450650Sobrien (if_then_else:SF (match_operator 1 "comparison_operator" 780550650Sobrien [(match_operand 2 "nonimmediate_operand" "r,m,r,m") 780650650Sobrien (match_operand 3 "general_operand" "rmi,ri,rmi,ri")]) 780750650Sobrien (match_operand:SF 4 "register_operand" "f,f,0,0") 780850650Sobrien (match_operand:SF 5 "register_operand" "0,0,f,f")))] 780950650Sobrien "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT 781050650Sobrien && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE 781150650Sobrien && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT" 781250650Sobrien "#") 781350650Sobrien 781450650Sobrien(define_split 781552296Sobrien [(set (match_operand:SF 0 "register_operand" "") 781650650Sobrien (if_then_else:SF (match_operator 1 "comparison_operator" 781750650Sobrien [(match_operand 2 "nonimmediate_operand" "") 781850650Sobrien (const_int 0)]) 781952296Sobrien (match_operand:SF 3 "register_operand" "") 782052296Sobrien (match_operand:SF 4 "register_operand" "")))] 782150650Sobrien "TARGET_CMOVE && reload_completed" 782250650Sobrien [(set (cc0) 782350650Sobrien (match_dup 2)) 782450650Sobrien (set (match_dup 0) 782550650Sobrien (if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)]) 782650650Sobrien (match_dup 3) (match_dup 4)))] 782750650Sobrien "") 782850650Sobrien 782950650Sobrien(define_split 783052296Sobrien [(set (match_operand:SF 0 "register_operand" "") 783150650Sobrien (if_then_else:SF (match_operator 1 "comparison_operator" 783250650Sobrien [(match_operand 2 "nonimmediate_operand" "") 783350650Sobrien (match_operand 3 "general_operand" "")]) 783452296Sobrien (match_operand:SF 4 "register_operand" "") 783552296Sobrien (match_operand:SF 5 "register_operand" "")))] 783650650Sobrien "TARGET_CMOVE && reload_completed" 783750650Sobrien [(set (cc0) (compare (match_dup 2) (match_dup 3))) 783850650Sobrien (set (match_dup 0) 783950650Sobrien (if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)]) 784050650Sobrien (match_dup 4) (match_dup 5)))] 784150650Sobrien "") 784250650Sobrien 784350650Sobrien(define_insn "" 784450650Sobrien [(set (match_operand:SF 0 "register_operand" "=f,f") 784550650Sobrien (if_then_else:SF (match_operator 1 "comparison_operator" 784650650Sobrien [(cc0) (const_int 0)]) 784750650Sobrien (match_operand:SF 2 "register_operand" "f,0") 784850650Sobrien (match_operand:SF 3 "register_operand" "0,f")))] 784950650Sobrien "TARGET_CMOVE && reload_completed" 785050650Sobrien "* return output_fp_conditional_move (which_alternative, operands);") 785150650Sobrien 785250650Sobrien(define_expand "movdfcc" 785350650Sobrien [(set (match_operand:DF 0 "register_operand" "") 785450650Sobrien (if_then_else:DF (match_operand 1 "comparison_operator" "") 785550650Sobrien (match_operand:DF 2 "register_operand" "") 785650650Sobrien (match_operand:DF 3 "register_operand" "")))] 785750650Sobrien "TARGET_CMOVE" 785850650Sobrien " 785950650Sobrien{ 786050650Sobrien rtx temp; 786150650Sobrien 786250650Sobrien if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT) 786350650Sobrien FAIL; 786450650Sobrien 786550650Sobrien /* The floating point conditional move instructions don't directly 786650650Sobrien support conditions resulting from a signed integer comparison. */ 786750650Sobrien 786850650Sobrien switch (GET_CODE (operands[1])) 786950650Sobrien { 787050650Sobrien case LT: 787150650Sobrien case LE: 787250650Sobrien case GE: 787350650Sobrien case GT: 787450650Sobrien temp = emit_store_flag (gen_reg_rtx (QImode), 787550650Sobrien GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1, 787650650Sobrien VOIDmode, 0, 0); 787750650Sobrien 787850650Sobrien if (!temp) 787950650Sobrien FAIL; 788050650Sobrien 788150650Sobrien operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx); 788250650Sobrien break; 788350650Sobrien 788450650Sobrien default: 788550650Sobrien operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), 788650650Sobrien GET_MODE (i386_compare_op0), 788750650Sobrien i386_compare_op0, i386_compare_op1); 788850650Sobrien break; 788950650Sobrien } 789050650Sobrien}") 789150650Sobrien 789250650Sobrien(define_insn "" 789350650Sobrien [(set (match_operand:DF 0 "register_operand" "=f,f,f,f") 789450650Sobrien (if_then_else:DF (match_operator 1 "comparison_operator" 789550650Sobrien [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m") 789650650Sobrien (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")]) 789750650Sobrien (match_operand:DF 4 "register_operand" "f,f,0,0") 789850650Sobrien (match_operand:DF 5 "register_operand" "0,0,f,f")))] 789950650Sobrien "TARGET_CMOVE 790050650Sobrien && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE 790150650Sobrien && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT" 790250650Sobrien "#") 790350650Sobrien 790450650Sobrien(define_insn "" 790550650Sobrien [(set (match_operand:DF 0 "register_operand" "=f,f,f,f") 790650650Sobrien (if_then_else:DF (match_operator 1 "comparison_operator" 790750650Sobrien [(match_operand 2 "nonimmediate_operand" "r,m,r,m") 790850650Sobrien (match_operand 3 "general_operand" "rmi,ri,rmi,ri")]) 790950650Sobrien (match_operand:DF 4 "register_operand" "f,f,0,0") 791050650Sobrien (match_operand:DF 5 "register_operand" "0,0,f,f")))] 791150650Sobrien "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT 791250650Sobrien && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE 791350650Sobrien && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT" 791450650Sobrien "#") 791550650Sobrien 791650650Sobrien(define_split 791752296Sobrien [(set (match_operand:DF 0 "register_operand" "") 791850650Sobrien (if_then_else:DF (match_operator 1 "comparison_operator" 791950650Sobrien [(match_operand 2 "nonimmediate_operand" "") 792050650Sobrien (const_int 0)]) 792152296Sobrien (match_operand:DF 3 "register_operand" "") 792252296Sobrien (match_operand:DF 4 "register_operand" "")))] 792350650Sobrien "TARGET_CMOVE && reload_completed" 792450650Sobrien [(set (cc0) 792550650Sobrien (match_dup 2)) 792650650Sobrien (set (match_dup 0) 792750650Sobrien (if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)]) 792850650Sobrien (match_dup 3) (match_dup 4)))] 792950650Sobrien "") 793050650Sobrien 793150650Sobrien(define_split 793252296Sobrien [(set (match_operand:DF 0 "register_operand" "") 793350650Sobrien (if_then_else:DF (match_operator 1 "comparison_operator" 793450650Sobrien [(match_operand 2 "nonimmediate_operand" "") 793550650Sobrien (match_operand 3 "general_operand" "")]) 793652296Sobrien (match_operand:DF 4 "register_operand" "") 793752296Sobrien (match_operand:DF 5 "register_operand" "")))] 793850650Sobrien "TARGET_CMOVE && reload_completed" 793950650Sobrien [(set (cc0) (compare (match_dup 2) (match_dup 3))) 794050650Sobrien (set (match_dup 0) 794150650Sobrien (if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)]) 794250650Sobrien (match_dup 4) (match_dup 5)))] 794350650Sobrien "") 794450650Sobrien 794550650Sobrien(define_insn "" 794650650Sobrien [(set (match_operand:DF 0 "register_operand" "=f,f") 794750650Sobrien (if_then_else:DF (match_operator 1 "comparison_operator" 794850650Sobrien [(cc0) (const_int 0)]) 794950650Sobrien (match_operand:DF 2 "register_operand" "f,0") 795050650Sobrien (match_operand:DF 3 "register_operand" "0,f")))] 795150650Sobrien "TARGET_CMOVE && reload_completed" 795250650Sobrien "* return output_fp_conditional_move (which_alternative, operands);") 795350650Sobrien 795450650Sobrien(define_expand "movxfcc" 795550650Sobrien [(set (match_operand:XF 0 "register_operand" "") 795650650Sobrien (if_then_else:XF (match_operand 1 "comparison_operator" "") 795750650Sobrien (match_operand:XF 2 "register_operand" "") 795850650Sobrien (match_operand:XF 3 "register_operand" "")))] 795950650Sobrien "TARGET_CMOVE" 796050650Sobrien " 796150650Sobrien{ 796250650Sobrien rtx temp; 796350650Sobrien 796450650Sobrien if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT) 796550650Sobrien FAIL; 796650650Sobrien 796750650Sobrien /* The floating point conditional move instructions don't directly 796850650Sobrien support conditions resulting from a signed integer comparison. */ 796950650Sobrien 797050650Sobrien switch (GET_CODE (operands[1])) 797150650Sobrien { 797250650Sobrien case LT: 797350650Sobrien case LE: 797450650Sobrien case GE: 797550650Sobrien case GT: 797650650Sobrien temp = emit_store_flag (gen_reg_rtx (QImode), 797750650Sobrien GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1, 797850650Sobrien VOIDmode, 0, 0); 797950650Sobrien 798050650Sobrien if (!temp) 798150650Sobrien FAIL; 798250650Sobrien 798350650Sobrien operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx); 798450650Sobrien break; 798550650Sobrien 798650650Sobrien default: 798750650Sobrien operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), 798850650Sobrien GET_MODE (i386_compare_op0), 798950650Sobrien i386_compare_op0, i386_compare_op1); 799050650Sobrien break; 799150650Sobrien } 799250650Sobrien}") 799350650Sobrien 799450650Sobrien(define_insn "" 799550650Sobrien [(set (match_operand:XF 0 "register_operand" "=f,f,f,f") 799650650Sobrien (if_then_else:XF (match_operator 1 "comparison_operator" 799750650Sobrien [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m") 799850650Sobrien (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")]) 799950650Sobrien (match_operand:XF 4 "register_operand" "f,f,0,0") 800050650Sobrien (match_operand:XF 5 "register_operand" "0,0,f,f")))] 800150650Sobrien "TARGET_CMOVE 800250650Sobrien && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE 800350650Sobrien && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT" 800450650Sobrien "#") 800550650Sobrien 800650650Sobrien(define_insn "" 800750650Sobrien [(set (match_operand:XF 0 "register_operand" "=f,f,f,f") 800850650Sobrien (if_then_else:XF (match_operator 1 "comparison_operator" 800950650Sobrien [(match_operand 2 "nonimmediate_operand" "r,m,r,m") 801050650Sobrien (match_operand 3 "general_operand" "rmi,ri,rmi,ri")]) 801150650Sobrien (match_operand:XF 4 "register_operand" "f,f,0,0") 801250650Sobrien (match_operand:XF 5 "register_operand" "0,0,f,f")))] 801350650Sobrien "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT 801450650Sobrien && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE 801550650Sobrien && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT" 801650650Sobrien "#") 801750650Sobrien 801850650Sobrien(define_split 801952296Sobrien [(set (match_operand:XF 0 "register_operand" "") 802050650Sobrien (if_then_else:XF (match_operator 1 "comparison_operator" 802150650Sobrien [(match_operand 2 "nonimmediate_operand" "") 802250650Sobrien (const_int 0)]) 802352296Sobrien (match_operand:XF 3 "register_operand" "") 802452296Sobrien (match_operand:XF 4 "register_operand" "")))] 802550650Sobrien "TARGET_CMOVE && reload_completed" 802650650Sobrien [(set (cc0) 802750650Sobrien (match_dup 2)) 802850650Sobrien (set (match_dup 0) 802950650Sobrien (if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)]) 803050650Sobrien (match_dup 3) (match_dup 4)))] 803150650Sobrien "") 803250650Sobrien 803350650Sobrien(define_split 803452296Sobrien [(set (match_operand:XF 0 "register_operand" "") 803550650Sobrien (if_then_else:XF (match_operator 1 "comparison_operator" 803650650Sobrien [(match_operand 2 "nonimmediate_operand" "") 803750650Sobrien (match_operand 3 "general_operand" "")]) 803852296Sobrien (match_operand:XF 4 "register_operand" "") 803952296Sobrien (match_operand:XF 5 "register_operand" "")))] 804050650Sobrien "TARGET_CMOVE && reload_completed" 804150650Sobrien [(set (cc0) (compare (match_dup 2) (match_dup 3))) 804250650Sobrien (set (match_dup 0) 804350650Sobrien (if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)]) 804450650Sobrien (match_dup 4) (match_dup 5)))] 804550650Sobrien "") 804650650Sobrien 804750650Sobrien(define_insn "" 804850650Sobrien [(set (match_operand:XF 0 "register_operand" "=f,f") 804950650Sobrien (if_then_else:XF (match_operator 1 "comparison_operator" 805050650Sobrien [(cc0) (const_int 0)]) 805150650Sobrien (match_operand:XF 2 "register_operand" "f,0") 805250650Sobrien (match_operand:XF 3 "register_operand" "0,f")))] 805350650Sobrien "TARGET_CMOVE && reload_completed" 805450650Sobrien "* return output_fp_conditional_move (which_alternative, operands);") 805550650Sobrien 805650650Sobrien(define_expand "movdicc" 805750650Sobrien [(set (match_operand:DI 0 "register_operand" "") 805850650Sobrien (if_then_else:DI (match_operand 1 "comparison_operator" "") 805950650Sobrien (match_operand:DI 2 "nonimmediate_operand" "") 806050650Sobrien (match_operand:DI 3 "nonimmediate_operand" "")))] 806150650Sobrien "TARGET_CMOVE" 806250650Sobrien " 806350650Sobrien{ 806450650Sobrien if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT) 806550650Sobrien FAIL; 806650650Sobrien 806750650Sobrien operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), 806850650Sobrien GET_MODE (i386_compare_op0), 806950650Sobrien i386_compare_op0, i386_compare_op1); 807050650Sobrien}") 807150650Sobrien 807250650Sobrien(define_insn "" 807350650Sobrien [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r") 807450650Sobrien (if_then_else:DI (match_operator 1 "comparison_operator" 807550650Sobrien [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m") 807650650Sobrien (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")]) 807750650Sobrien (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0") 807850650Sobrien (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro")))] 807950650Sobrien "TARGET_CMOVE" 808050650Sobrien "#") 808150650Sobrien 808250650Sobrien(define_insn "" 808350650Sobrien [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r") 808450650Sobrien (if_then_else:DI (match_operator 1 "comparison_operator" 808550650Sobrien [(match_operand 2 "nonimmediate_operand" "r,m,r,m") 808650650Sobrien (match_operand 3 "general_operand" "rmi,ri,rmi,ri")]) 808750650Sobrien (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0") 808850650Sobrien (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro")))] 808950650Sobrien "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT" 809050650Sobrien "#") 809150650Sobrien 809250650Sobrien(define_split 809352296Sobrien [(set (match_operand:DI 0 "register_operand" "") 809450650Sobrien (if_then_else:DI (match_operator 1 "comparison_operator" 809550650Sobrien [(match_operand 2 "nonimmediate_operand" "") 809650650Sobrien (const_int 0)]) 809752296Sobrien (match_operand:DI 3 "nonimmediate_operand" "") 809852296Sobrien (match_operand:DI 4 "nonimmediate_operand" "")))] 809950650Sobrien "TARGET_CMOVE && reload_completed" 810050650Sobrien [(set (cc0) 810150650Sobrien (match_dup 2)) 810252296Sobrien (set (match_dup 5) 810352296Sobrien (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) 810452296Sobrien (match_dup 7) (match_dup 9))) 810552296Sobrien (set (match_dup 6) 810652296Sobrien (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) 810752296Sobrien (match_dup 8) (match_dup 10)))] 810852296Sobrien "split_di (&operands[0], 1, &operands[5], &operands[6]); 810952296Sobrien split_di (&operands[3], 1, &operands[7], &operands[8]); 811052296Sobrien split_di (&operands[4], 1, &operands[9], &operands[10]);") 811150650Sobrien 811250650Sobrien(define_split 811352296Sobrien [(set (match_operand:DI 0 "register_operand" "") 811450650Sobrien (if_then_else:DI (match_operator 1 "comparison_operator" 811550650Sobrien [(match_operand 2 "nonimmediate_operand" "") 811650650Sobrien (match_operand 3 "general_operand" "")]) 811752296Sobrien (match_operand:DI 4 "nonimmediate_operand" "") 811852296Sobrien (match_operand:DI 5 "nonimmediate_operand" "")))] 811950650Sobrien "TARGET_CMOVE && reload_completed" 812050650Sobrien [(set (cc0) (compare (match_dup 2) (match_dup 3))) 812152296Sobrien (set (match_dup 6) 812252296Sobrien (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) 812352296Sobrien (match_dup 8) (match_dup 10))) 812452296Sobrien (set (match_dup 7) 812552296Sobrien (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) 812652296Sobrien (match_dup 9) (match_dup 11)))] 812752296Sobrien "split_di (&operands[0], 1, &operands[6], &operands[7]); 812852296Sobrien split_di (&operands[4], 1, &operands[8], &operands[9]); 812952296Sobrien split_di (&operands[5], 1, &operands[10], &operands[11]);") 813050650Sobrien 813150650Sobrien(define_insn "strlensi_unroll" 813250650Sobrien [(set (match_operand:SI 0 "register_operand" "=&r,&r") 813350650Sobrien (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "r,r")) 813450650Sobrien (match_operand:SI 2 "immediate_operand" "i,i")] 0)) 813550650Sobrien (clobber (match_scratch:SI 3 "=&q,&r"))] 813650650Sobrien "optimize > 1" 813750650Sobrien "* return output_strlen_unroll (operands);") 813850650Sobrien 813950650Sobrien;; the only difference between the following patterns is the register preference 814050650Sobrien;; on a pentium using a q-register saves one clock cycle per 4 characters 814150650Sobrien 814250650Sobrien(define_insn "strlensi_unroll4" 814350650Sobrien [(set (match_operand:SI 0 "register_operand" "=r,r") 814450650Sobrien (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0,0")) 814550650Sobrien (match_operand:SI 1 "immediate_operand" "i,i") 814650650Sobrien (match_operand:SI 2 "register_operand" "+q,!r")] 0)) 814750650Sobrien (clobber (match_dup 2))] 814850650Sobrien "(TARGET_USE_ANY_REG && optimize > 1)" 814950650Sobrien "* return output_strlen_unroll (operands);") 815050650Sobrien 815150650Sobrien(define_insn "strlensi_unroll5" 815250650Sobrien [(set (match_operand:SI 0 "register_operand" "=r") 815350650Sobrien (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0")) 815450650Sobrien (match_operand:SI 1 "immediate_operand" "i") 815550650Sobrien (match_operand:SI 2 "register_operand" "+q")] 0)) 815650650Sobrien (clobber (match_dup 2))] 815750650Sobrien "(TARGET_USE_Q_REG && optimize > 1)" 815850650Sobrien "* return output_strlen_unroll (operands);" 815950650Sobrien) 816050650Sobrien 816150650Sobrien(define_insn "allocate_stack_worker" 816250650Sobrien [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3) 816350650Sobrien (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0))) 816450650Sobrien (clobber (match_dup 0))] 816550650Sobrien "TARGET_STACK_PROBE" 816652296Sobrien "* return AS1(call,__alloca);" 816752296Sobrien [(set_attr "memory" "none")]) 816850650Sobrien 816950650Sobrien(define_expand "allocate_stack" 817050650Sobrien [(set (match_operand:SI 0 "register_operand" "=r") 817150650Sobrien (minus:SI (reg:SI 7) (match_operand:SI 1 "general_operand" ""))) 817250650Sobrien (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 1)))] 817350650Sobrien "TARGET_STACK_PROBE" 817450650Sobrien " 817550650Sobrien{ 817650650Sobrien#ifdef CHECK_STACK_LIMIT 817750650Sobrien if (GET_CODE (operands[1]) == CONST_INT 817850650Sobrien && INTVAL (operands[1]) < CHECK_STACK_LIMIT) 817950650Sobrien emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, 818050650Sobrien operands[1])); 818150650Sobrien else 818250650Sobrien#endif 818350650Sobrien emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode, 818450650Sobrien operands[1]))); 818550650Sobrien 818650650Sobrien emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 818750650Sobrien DONE; 818850650Sobrien}") 818950650Sobrien 819050650Sobrien(define_expand "exception_receiver" 819150650Sobrien [(const_int 0)] 819250650Sobrien "flag_pic" 819350650Sobrien " 819450650Sobrien{ 819550650Sobrien load_pic_register (1); 819650650Sobrien DONE; 819750650Sobrien}") 8198