home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-11-12 | 191.7 KB | 6,275 lines |
- ;;- Machine description Acorn RISC Machine for GNU compiler
- ;; Copyright (C) 1991, 1993 Free Software Foundation, Inc.
- ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
- ;; and Martin Simmons (@harleqn.co.uk).
- ;; More major hacks by Richard Earnshaw (rwe11@cl.cam.ac.uk)
-
- ;; This file is part of GNU CC.
-
- ;; GNU CC is free software; you can redistribute it and/or modify
- ;; it under the terms of the GNU General Public License as published by
- ;; the Free Software Foundation; either version 2, or (at your option)
- ;; any later version.
-
- ;; GNU CC is distributed in the hope that it will be useful,
- ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;; GNU General Public License for more details.
-
- ;; You should have received a copy of the GNU General Public License
- ;; along with GNU CC; see the file COPYING. If not, write to
- ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
-
- ;; Every template must be output by arm_output_asm_insn, since this keeps
- ;; track of the offset of labels within the text segment. This is needed to
- ;; to be able to (correctly) output instructions for loading a value from a
- ;; function's constant pool, since different instructions are needed when the
- ;; constant pool is more than 4095 bytes away from the PC.
-
- ;; There are patterns in this file to support XFmode arithmetic.
- ;; Unfortunately RISCiX doesn't work well with these so they are disabled.
- ;; (See arm.h)
-
- ;; UNSPEC Usage:
- ;; 0 `sin' operation: operand 0 is the result, operand 1 the parameter,
- ;; the mode is MODE_FLOAT
- ;; 1 `cos' operation: operand 0 is the result, operand 1 the parameter,
- ;; the mode is MODE_FLOAT
-
- ;; Attributes
-
- ; condition codes: this one is used by final_prescan_insn to speed up
- ; conditionalizing instructions. It saves having to scan the rtl to see if
- ; it uses or alters the condition codes.
-
- ; USE means that the condition codes are used by the insn in the process of
- ; outputting code, this means (at present) that we can't use the insn in
- ; inlined branches
-
- ; SET means that the purpose of the insn is to set the condition codes in a
- ; well defined manner.
-
- ; CLOB means that the condition codes are altered in an undefined manner, if
- ; they are altered at all
-
- ; JUMP_CLOB is used when the conditions are not defined if a branch is taken,
- ; but are if the branch wasn't taken; the effect is to limit the branch
- ; elimination scanning.
-
- ; NOCOND means that the condition codes are niether altered nor affect the
- ; output of this insn
-
- (define_attr "conds" "use,set,clob,jump_clob,nocond"
- (const_string "nocond"))
-
- ; CPU attribute is used to determine whether condition codes are clobbered
- ; by a call insn: on the arm6 they are if in 32-bit addressing mode; on the
- ; arm2 and arm3 the condition codes are restored by the return.
-
- (define_attr "cpu" "arm2,arm3,arm6" (const (symbol_ref "arm_cpu_attr")))
-
- ; LENGTH, all instructions are 4 bytes
- (define_attr "length" "" (const_int 1))
-
- ; An assembler sequence may clobber the condition codes without us knowing
- (define_asm_attributes
- [(set_attr "conds" "clob")
- (set_attr "length" "1")])
-
- ; TYPE attribute is used to detect floating point instructions which, if
- ; running on a co-processor can run in parallel with other, basic instructions
- ; If write-buffer scheduling is enabled then it can also be used in the
- ; scheduling of writes.
-
- ; Classification of each insn
- ; normal any data instruction that doesn't hit memory or fp regs
- ; block blockage insn, this blocks all functional units
- ; float a floating point arithmetic operation (subject to expansion)
- ; float_em a floating point arithmetic operation that is normally emulated
- ; f_load a floating point load from memory
- ; f_store a floating point store to memory
- ; f_mem_r a transfer of a floating point register to a real reg via mem
- ; r_mem_f the reverse of f_mem_r
- ; f_2_r fast transfer float to arm (no memory needed)
- ; r_2_f fast transfer arm to float
- ; call a subroutine call
- ; load any load from memory
- ; store1 store 1 word to memory from arm registers
- ; store2 store 2 words
- ; store3 store 3 words
- ; store4 store 4 words
- ;
- (define_attr "type"
- "normal,block,float,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4"
- (const_string "normal"))
-
- (define_attr "write_conflict" "no,yes"
- (if_then_else (eq_attr "type"
- "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load")
- (const_string "yes")
- (const_string "no")))
-
- ; The write buffer on some of the arm6 processors is hard to model exactly.
- ; There is room in the buffer for up to two addresses and up to eight words
- ; of memory, but the two needn't be split evenly. When writing the two
- ; addresses are fully pipelined. However, a read from memory that is not
- ; currently in the cache will block until the writes have completed.
- ; It is normally the case that FCLK and MCLK will be in the ratio 2:1, so
- ; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous
- ; (they aren't allowed to be at present) then there is a startup cost of 1MCLK
- ; cycle to add as well.
-
- ;; (define_function_unit {name} {num-units} {n-users} {test}
- ;; {ready-delay} {issue-delay} [{conflict-list}])
- ;; This is not well tuned, but I don't have all the details.
- (define_function_unit "fpa" 1 1 (eq_attr "type" "float") 5 0)
-
- (define_function_unit "write_buf" 1 2 (eq_attr "type" "store1") 3 3
- [(eq_attr "write_conflict" "yes")])
- (define_function_unit "write_buf" 1 2 (eq_attr "type" "store2") 5 5
- [(eq_attr "write_conflict" "yes")])
- (define_function_unit "write_buf" 1 2 (eq_attr "type" "store3") 7 7
- [(eq_attr "write_conflict" "yes")])
- (define_function_unit "write_buf" 1 2 (eq_attr "type" "store4") 9 9
- [(eq_attr "write_conflict" "yes")])
- (define_function_unit "write_buf" 1 2 (eq_attr "type" "r_mem_f") 3 3
- [(eq_attr "write_conflict" "yes")])
-
- ;; Note: For DImode insns, there is normally no reason why operands should
- ;; not be in the same register, what we don't want is for something being
- ;; written to partially overlap something that is an input.
-
- ;; Addition insns.
-
- (define_insn "adddi3"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (plus:DI (match_operand:DI 1 "s_register_operand" "%0,0")
- (match_operand:DI 2 "s_register_operand" "r,0")))
- (clobber (reg:CC 24))]
- ""
- "*
- arm_output_asm_insn (\"adds\\t%0, %1, %2\", operands);
- return (arm_output_asm_insn (\"adc\\t%R0, %R1, %R2\", operands));
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (plus:DI (sign_extend:DI
- (match_operand:SI 1 "s_register_operand" "r,r"))
- (match_operand:DI 2 "s_register_operand" "r,0")))
- (clobber (reg:CC 24))]
- ""
- "*
- arm_output_asm_insn (\"adds\\t%0, %2, %1\", operands);
- return (arm_output_asm_insn (\"adc\\t%R0, %R2, %1, asr #31\", operands));
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (plus:DI (zero_extend:DI
- (match_operand:SI 1 "s_register_operand" "r,r"))
- (match_operand:DI 2 "s_register_operand" "r,0")))
- (clobber (reg:CC 24))]
- ""
- "*
- arm_output_asm_insn (\"adds\\t%0, %2, %1\", operands);
- return (arm_output_asm_insn (\"adc\\t%R0, %R2, #0\", operands));
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2")])
-
- (define_insn "addsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (plus:SI (match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "arm_add_operand" "rL")))]
- ""
- "*
- if (GET_CODE (operands[2]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[2])))
- {
- operands[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2]));
- return arm_output_asm_insn (\"sub\\t%0, %1, %2\", operands);
- }
- return arm_output_asm_insn (\"add\\t%0, %1, %2\", operands);
- ")
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (plus:SI (match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "arm_add_operand" "rL"))
- (const_int 0)))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "*
- if (GET_CODE (operands[2]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[2])))
- {
- operands[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2]));
- return arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
- }
- return (arm_output_asm_insn (\"adds\\t%0, %1, %2\", operands));
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CC 24)
- (compare:CC (match_operand:SI 1 "s_register_operand" "r")
- (neg:SI (match_operand:SI 2 "arm_add_operand" "rL"))))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "*
- if (GET_CODE (operands[2]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[2])))
- {
- operands[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2]));
- return arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
- }
- return (arm_output_asm_insn (\"adds\\t%0, %1, %2\", operands));
- "
- [(set_attr "conds" "set")])
-
- (define_insn "incscc"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (plus:SI (match_operator:SI 2 "comparison_operator"
- [(reg 24) (const_int 0)])
- (match_operand:SI 1 "s_register_operand" "0,?r")))]
- ""
- "*
- if (which_alternative == 1)
- arm_output_asm_insn (\"mov%D2\\t%0, %1\", operands);
- return arm_output_asm_insn (\"add%d2\\t%0, %1, #1\", operands);
- "
- [(set_attr "conds" "use")
- (set_attr "length" "*,2")])
-
- ; If a constant is too big to fit in a single instruction then the constant
- ; will be pre-loaded into a register taking at least two insns, we might be
- ; able to merge it with an add, but it depends on the exact value.
-
- (define_split
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (plus:SI (match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "immediate_operand" "n")))]
- "!(const_ok_for_arm (INTVAL (operands[2]))
- || const_ok_for_arm (-INTVAL (operands[2])))"
- [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
- (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
- "
- {
- unsigned int val = (unsigned) INTVAL (operands[2]);
- int i;
- unsigned int temp;
-
- /* this code is similar to the approach followed in movsi, but it must
- generate exactly two insns */
-
- for (i = 30; i >= 0; i -= 2)
- {
- if (val & (3 << i))
- {
- i -= 6;
- if (i < 0) i = 0;
- if (const_ok_for_arm (temp = (val & ~(255 << i))))
- {
- val &= 255 << i;
- break;
- }
- /* we might be able to do this as (larger number - small number) */
- temp = ((val >> i) & 255) + 1;
- if (temp > 255 && i < 24)
- {
- i += 2;
- temp = ((val >> i) & 255) + 1;
- }
- if (const_ok_for_arm ((temp << i) - val))
- {
- i = temp << i;
- temp = (unsigned) - (int) (i - val);
- val = i;
- break;
- }
- FAIL;
- }
- }
- /* if we got here, we have found a way of doing it in two instructions.
- the two constants are in val and temp */
- operands[2] = GEN_INT ((int)val);
- operands[3] = GEN_INT ((int)temp);
- }
- ")
-
- (define_insn "addsf3"
- [(set (match_operand:SF 0 "s_register_operand" "=f,f")
- (plus:SF (match_operand:SF 1 "s_register_operand" "f,f")
- (match_operand:SF 2 "fpu_add_operand" "fG,H")))]
- ""
- "*
- {
- REAL_VALUE_TYPE r;
-
- switch (which_alternative)
- {
- case 0:
- return arm_output_asm_insn (\"adfs\\t%0, %1, %2\", operands);
- case 1:
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
- r = REAL_VALUE_NEGATE (r);
- operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2]));
- return arm_output_asm_insn (\"sufs\\t%0, %1, %2\", operands);
- }
- }
- "
- [(set_attr "type" "float")])
-
- (define_insn "adddf3"
- [(set (match_operand:DF 0 "s_register_operand" "=f,f")
- (plus:DF (match_operand:DF 1 "s_register_operand" "f,f")
- (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
- ""
- "*
- {
- REAL_VALUE_TYPE r;
-
- switch (which_alternative)
- {
- case 0:
- return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands));
- case 1:
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
- r = REAL_VALUE_NEGATE (r);
- operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2]));
- return arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands);
- }
- }
- "
- [(set_attr "type" "float")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f,f")
- (plus:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f,f"))
- (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
- ""
- "*
- {
- REAL_VALUE_TYPE r;
-
- switch (which_alternative)
- {
- case 0:
- return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands));
- case 1:
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
- r = REAL_VALUE_NEGATE (r);
- operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2]));
- return arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands);
- }
- }
- "
- [(set_attr "type" "float")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (plus:DF (match_operand:DF 1 "s_register_operand" "f")
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
- ""
- "*
- return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (plus:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
- ""
- "*
- return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn "addxf3"
- [(set (match_operand:XF 0 "s_register_operand" "=f,f")
- (plus:XF (match_operand:XF 1 "s_register_operand" "f,f")
- (match_operand:XF 2 "fpu_add_operand" "fG,H")))]
- "ENABLE_XF_PATTERNS"
- "*
- {
- REAL_VALUE_TYPE r;
-
- switch (which_alternative)
- {
- case 0:
- return (arm_output_asm_insn (\"adfe\\t%0, %1, %2\", operands));
- case 1:
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
- r = REAL_VALUE_NEGATE (r);
- operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2]));
- return arm_output_asm_insn (\"sufe\\t%0, %1, %2\", operands);
- }
- }
- "
- [(set_attr "type" "float")])
-
- (define_insn "subdi3"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
- (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
- (match_operand:DI 2 "s_register_operand" "r,0,0")))
- (clobber (reg:CC 24))]
- ""
- "*
- arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
- return (arm_output_asm_insn (\"sbc\\t%R0, %R1, %R2\", operands));
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
- (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))))
- (clobber (reg:CC 24))]
- ""
- "*
- arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
- return (arm_output_asm_insn (\"sbc\\t%R0, %R1, #0\", operands));
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
- (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))))
- (clobber (reg:CC 24))]
- ""
- "*
- arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
- return (arm_output_asm_insn (\"sbc\\t%R0, %R1, %2, asr #31\", operands));
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (minus:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "?r,0")))
- (clobber (reg:CC 24))]
- ""
- "*
- arm_output_asm_insn (\"rsbs\\t%0, %1, %2\", operands);
- return (arm_output_asm_insn (\"rsc\\t%R0, %R1, #0\", operands));
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (minus:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "?r,0")))
- (clobber (reg:CC 24))]
- ""
- "*
- arm_output_asm_insn (\"rsbs\\t%0, %1, %2\", operands);
- return (arm_output_asm_insn (\"rsc\\t%R0, %R1, %2, asr #31\", operands));
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:DI 0 "s_register_operand" "=r")
- (minus:DI (zero_extend:DI
- (match_operand:SI 1 "s_register_operand" "r"))
- (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r"))))
- (clobber (reg:CC 24))]
- ""
- "*
- arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
- return (arm_output_asm_insn (\"rsc\\t%R0, %1, %1 @ extend carry\",
- operands));
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2")])
-
- (define_insn "subsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
- (match_operand:SI 2 "arm_rhs_operand" "rI,r")))]
- ""
- "*
- switch (which_alternative)
- {
- case 0:
- return (arm_output_asm_insn (\"sub\\t%0, %1, %2\", operands));
- case 1:
- return (arm_output_asm_insn (\"rsb\\t%0, %2, %1\", operands));
- }
- ")
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
- (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
- (const_int 0)))
- (set (match_operand:SI 0 "s_register_operand" "=r,r")
- (minus:SI (match_dup 1) (match_dup 2)))]
- ""
- "*
- switch (which_alternative)
- {
- case 0:
- return arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
- case 1:
- return arm_output_asm_insn (\"rsbs\\t%0, %2, %1\", operands);
- }
- "
- [(set_attr "conds" "set")])
-
- (define_insn "decscc"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
- (match_operator:SI 2 "comparison_operator"
- [(reg 24) (const_int 0)])))]
- ""
- "*
- if (which_alternative == 1)
- arm_output_asm_insn (\"mov%D2\\t%0, %1\", operands);
- return arm_output_asm_insn (\"sub%d2\\t%0, %1, #1\", operands);
- "
- [(set_attr "conds" "use")
- (set_attr "length" "*,2")])
-
- (define_insn "subsf3"
- [(set (match_operand:SF 0 "s_register_operand" "=f,f")
- (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
- (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
- ""
- "*
- switch (which_alternative)
- {
- case 0:
- return (arm_output_asm_insn (\"sufs\\t%0, %1, %2\", operands));
- case 1:
- return (arm_output_asm_insn (\"rsfs\\t%0, %2, %1\", operands));
- }
- "
- [(set_attr "type" "float")])
-
- (define_insn "subdf3"
- [(set (match_operand:DF 0 "s_register_operand" "=f,f")
- (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
- (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
- ""
- "*
- switch (which_alternative)
- {
- case 0:
- return (arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands));
- case 1:
- return (arm_output_asm_insn (\"rsfd\\t%0, %2, %1\", operands));
- }
- "
- [(set_attr "type" "float")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (minus:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
- ""
- "*
- return arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands);
- "
- [(set_attr "type" "float")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f,f")
- (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f,f"))))]
- ""
- "*
- switch (which_alternative)
- {
- case 0:
- return (arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands));
- case 1:
- return (arm_output_asm_insn (\"rsfd\\t%0, %2, %1\", operands));
- }
- "
- [(set_attr "type" "float")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (minus:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
- ""
- "*
- return arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands);
- "
- [(set_attr "type" "float")])
-
- (define_insn "subxf3"
- [(set (match_operand:XF 0 "s_register_operand" "=f,f")
- (minus:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
- (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
- "ENABLE_XF_PATTERNS"
- "*
- switch (which_alternative)
- {
- case 0:
- return (arm_output_asm_insn (\"sufe\\t%0, %1, %2\", operands));
- case 1:
- return (arm_output_asm_insn (\"rsfe\\t%0, %2, %1\", operands));
- }
- "
- [(set_attr "type" "float")])
-
- ;; Multiplication insns
-
- ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
- (define_insn "mulsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
- (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
- (match_operand:SI 1 "s_register_operand" "%?r,0")))]
- ""
- "*
- return (arm_output_asm_insn (\"mul\\t%0, %2, %1\", operands));
- ")
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (mult:SI
- (match_operand:SI 2 "s_register_operand" "r,r")
- (match_operand:SI 1 "s_register_operand" "%?r,0"))
- (const_int 0)))
- (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
- (mult:SI (match_dup 2) (match_dup 1)))]
- ""
- "*
- return (arm_output_asm_insn (\"muls\\t%0, %2, %1\", operands));
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (mult:SI
- (match_operand:SI 2 "s_register_operand" "r,r")
- (match_operand:SI 1 "s_register_operand" "%?r,0"))
- (const_int 0)))
- (clobber (match_scratch:SI 0 "=&r,&r"))]
- ""
- "*
- return (arm_output_asm_insn (\"muls\\t%0, %2, %1\", operands));
- "
- [(set_attr "conds" "set")])
-
- ;; Unnamed templates to match MLA instruction.
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
- (plus:SI
- (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
- (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
- (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
- ""
- "*
- return (arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands));
- ")
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (plus:SI
- (mult:SI
- (match_operand:SI 2 "s_register_operand" "r,r,r,r")
- (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
- (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
- (const_int 0)))
- (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
- (plus:SI (mult:SI (match_dup 2) (match_dup 1))
- (match_dup 3)))]
- ""
- "*
- return (arm_output_asm_insn (\"mlas\\t%0, %2, %1, %3\", operands));
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (plus:SI
- (mult:SI
- (match_operand:SI 2 "s_register_operand" "r,r,r,r")
- (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
- (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
- (const_int 0)))
- (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
- ""
- "*
- return (arm_output_asm_insn (\"mlas\\t%0, %2, %1, %3\", operands));
- "
- [(set_attr "conds" "set")])
-
- (define_insn "mulsf3"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (mult:SF (match_operand:SF 1 "s_register_operand" "f")
- (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
- ""
- "*
- return (arm_output_asm_insn (\"fmls\\t%0, %1, %2\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn "muldf3"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mult:DF (match_operand:DF 1 "s_register_operand" "f")
- (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
- ""
- "*
- return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mult:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
- ""
- "*
- return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mult:DF (match_operand:DF 1 "s_register_operand" "f")
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
- ""
- "*
- return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mult:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
- ""
- "*
- return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn "mulxf3"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (mult:XF (match_operand:XF 1 "s_register_operand" "f")
- (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
- "ENABLE_XF_PATTERNS"
- "*
- return (arm_output_asm_insn (\"mufe\\t%0, %1, %2\", operands));
- "
- [(set_attr "type" "float")])
-
- ;; Division insns
-
- (define_insn "divsf3"
- [(set (match_operand:SF 0 "s_register_operand" "=f,f")
- (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
- (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
- ""
- "*
- switch (which_alternative)
- {
- case 0:
- return (arm_output_asm_insn (\"fdvs\\t%0, %1, %2\", operands));
- case 1:
- return (arm_output_asm_insn (\"frds\\t%0, %2, %1\", operands));
- }
- "
- [(set_attr "type" "float")])
-
- (define_insn "divdf3"
- [(set (match_operand:DF 0 "s_register_operand" "=f,f")
- (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
- (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
- ""
- "*
- switch (which_alternative)
- {
- case 0:
- return (arm_output_asm_insn (\"dvfd\\t%0, %1, %2\", operands));
- case 1:
- return (arm_output_asm_insn (\"rdfd\\t%0, %2, %1\", operands));
- }
- "
- [(set_attr "type" "float")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (div:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
- ""
- "*
- return (arm_output_asm_insn (\"dvfd\\t%0, %1, %2\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (div:DF (match_operand:DF 1 "fpu_rhs_operand" "fG")
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
- ""
- "*
- return (arm_output_asm_insn (\"rdfd\\t%0, %2, %1\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (div:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
- ""
- "*
- return (arm_output_asm_insn (\"dvfd\\t%0, %1, %2\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn "divxf3"
- [(set (match_operand:XF 0 "s_register_operand" "=f,f")
- (div:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
- (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
- "ENABLE_XF_PATTERNS"
- "*
- switch (which_alternative)
- {
- case 0:
- return (arm_output_asm_insn (\"dvfe\\t%0, %1, %2\", operands));
- case 1:
- return (arm_output_asm_insn (\"rdfe\\t%0, %2, %1\", operands));
- }
- "
- [(set_attr "type" "float")])
-
- ;; Modulo insns
-
- (define_insn "modsf3"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (mod:SF (match_operand:SF 1 "s_register_operand" "f")
- (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
- ""
- "*
- return (arm_output_asm_insn (\"rmfs\\t%0, %1, %2\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn "moddf3"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mod:DF (match_operand:DF 1 "s_register_operand" "f")
- (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
- ""
- "*
- return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mod:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
- ""
- "*
- return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mod:DF (match_operand:DF 1 "s_register_operand" "f")
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
- ""
- "*
- return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mod:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
- ""
- "*
- return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn "modxf3"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (mod:XF (match_operand:XF 1 "s_register_operand" "f")
- (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
- "ENABLE_XF_PATTERNS"
- "*
- return (arm_output_asm_insn (\"rmfe\\t%0, %1, %2\", operands));
- "
- [(set_attr "type" "float")])
-
- ;; Boolean and,ior,xor insns
-
- (define_insn "anddi3"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (match_operand:DI 1 "s_register_operand" "%0,0")
- (match_operand:DI 2 "s_register_operand" "r,0")))]
- ""
- "*
- arm_output_asm_insn (\"and\\t%0, %1, %2\", operands);
- return (arm_output_asm_insn (\"and\\t%R0, %R1, %R2\", operands));
- "
- [(set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "?r,0")))]
- ""
- "*
- arm_output_asm_insn (\"and\\t%0, %1, %2\", operands);
- return arm_output_asm_insn (\"mov\\t%R0, #0\", operands);
- "
- [(set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "?r,0")))]
- ""
- "*
- arm_output_asm_insn (\"and\\t%0, %1, %2\", operands);
- return arm_output_asm_insn (\"and\\t%R0, %R1, %2, asr #31\", operands);
- "
- [(set_attr "length" "2")])
-
- (define_insn "andsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (and:SI (match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "arm_not_operand" "rK")))]
- ""
- "*
- if (GET_CODE (operands[2]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[2])))
- {
- operands[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
- return arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands);
- }
- return arm_output_asm_insn (\"and\\t%0, %1, %2\", operands);
- ")
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (and:SI (match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "arm_not_operand" "rK"))
- (const_int 0)))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (and:SI (match_dup 1) (match_dup 2)))]
- ""
- "*
- if (GET_CODE (operands[2]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[2])))
- {
- operands[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
- return arm_output_asm_insn (\"bics\\t%0, %1, %2\", operands);
- }
- return arm_output_asm_insn (\"ands\\t%0, %1, %2\", operands);
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (and:SI (match_operand:SI 0 "s_register_operand" "r")
- (match_operand:SI 1 "arm_rhs_operand" "rI"))
- (const_int 0)))]
- ""
- "*
- return arm_output_asm_insn (\"tst\\t%0, %1\", operands);
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (and:SI (match_operand:SI 0 "s_register_operand" "r")
- (match_operand:SI 1 "immediate_operand" "K"))
- (const_int 0)))
- (clobber (match_scratch:SI 3 "=r"))]
- "const_ok_for_arm (~INTVAL (operands[1]))"
- "*
- operands[1] = GEN_INT (~INTVAL (operands[1]));
- return arm_output_asm_insn (\"bics\\t%3, %0, %1\", operands);
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (zero_extract:SI
- (match_operand:SI 0 "s_register_operand" "r")
- (match_operand:SI 1 "immediate_operand" "n")
- (match_operand:SI 2 "immediate_operand" "n"))
- (const_int 0)))]
- "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
- && INTVAL (operands[1]) > 0
- && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
- && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32"
- "*
- {
- unsigned int mask = 0;
- int cnt = INTVAL (operands[1]);
-
- while (cnt--)
- mask = (mask << 1) | 1;
- operands[1] = gen_rtx (CONST_INT, VOIDmode, mask << INTVAL (operands[2]));
- return arm_output_asm_insn (\"tst\\t%0, %1\", operands);
- }
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (zero_extract:SI
- (match_operand:QI 0 "memory_operand" "m")
- (match_operand 1 "immediate_operand" "n")
- (match_operand 2 "immediate_operand" "n"))
- (const_int 0)))
- (clobber (match_scratch:QI 3 "=r"))]
- "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 8
- && INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8"
- "*
- {
- unsigned int mask = 0;
- int cnt = INTVAL (operands[1]);
-
- while (cnt--)
- mask = (mask << 1) | 1;
- operands[1] = gen_rtx (CONST_INT, VOIDmode, mask << INTVAL (operands[2]));
- arm_output_asm_insn (\"ldrb\\t%3, %0\", operands);
- return arm_output_asm_insn (\"tst\\t%3, %1\", operands);
- }
- "
- [(set_attr "conds" "set")
- (set_attr "length" "2")])
-
- ;; constants for op 2 will never be given to these patterns.
- (define_insn ""
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r,0"))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
- ""
- "*
- arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands);
- return arm_output_asm_insn (\"bic\\t%R0, %R1, %R2\", operands);
- "
- [(set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (not:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r")))
- (match_operand:DI 1 "s_register_operand" "?r,0")))]
- ""
- "*
- arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands);
- if (REGNO (operands[1]) != REGNO (operands[0]))
- return arm_output_asm_insn (\"mov\\t%R0, %R1\", operands);
- return \"\";
- "
- [(set_attr "length" "2,1")])
-
- (define_insn ""
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (not:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r")))
- (match_operand:DI 1 "s_register_operand" "?r,0")))]
- ""
- "*
- arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands);
- return arm_output_asm_insn (\"bic\\t%R0, %R1, %2, asr #31\", operands);
- "
- [(set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
- (match_operand:SI 1 "s_register_operand" "r")))]
- ""
- "*
- return (arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands));
- ")
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (and:SI
- (not:SI (match_operand:SI 2 "s_register_operand" "r"))
- (match_operand:SI 1 "s_register_operand" "r"))
- (const_int 0)))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
- ""
- "*
- return (arm_output_asm_insn (\"bics\\t%0, %1, %2\", operands));
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (and:SI
- (not:SI (match_operand:SI 2 "s_register_operand" "r"))
- (match_operand:SI 1 "s_register_operand" "r"))
- (const_int 0)))
- (clobber (match_scratch:SI 0 "=r"))]
- ""
- "*
- return (arm_output_asm_insn (\"bics\\t%0, %1, %2\", operands));
- "
- [(set_attr "conds" "set")])
-
- (define_insn "iordi3"
- [(set (match_operand:DI 0 "s_register_operand" "=&r")
- (ior:DI (match_operand:DI 1 "s_register_operand" "%0")
- (match_operand:DI 2 "s_register_operand" "r")))]
- ""
- "*
- arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands);
- return (arm_output_asm_insn (\"orr\\t%R0, %R1, %R2\", operands));
- "
- [(set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "?r,0")))]
- ""
- "*
- arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands);
- if (REGNO (operands[0]) != REGNO (operands[1]))
- return (arm_output_asm_insn (\"mov\\t%R0, %R1\", operands));
- return \"\";
- "
- [(set_attr "length" "2,1")])
-
- (define_insn ""
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "?r,0")))]
- ""
- "*
- arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands);
- return (arm_output_asm_insn (\"orr\\t%R0, %R1, %2, asr #31\", operands));
- "
- [(set_attr "length" "2")])
-
- (define_insn "iorsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (ior:SI (match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "arm_rhs_operand" "rI")))]
- ""
- "*
- return (arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands));
- ")
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
- (match_operand:SI 2 "arm_rhs_operand" "rI"))
- (const_int 0)))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (ior:SI (match_dup 1) (match_dup 2)))]
- ""
- "*
- return arm_output_asm_insn (\"orrs\\t%0, %1, %2\", operands);
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
- (match_operand:SI 2 "arm_rhs_operand" "rI"))
- (const_int 0)))
- (clobber (match_scratch:SI 0 "=r"))]
- ""
- "*
- return arm_output_asm_insn (\"orrs\\t%0, %1, %2\", operands);
- "
- [(set_attr "conds" "set")])
-
- (define_insn "xordi3"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (xor:DI (match_operand:DI 1 "s_register_operand" "%0,0")
- (match_operand:DI 2 "s_register_operand" "r,0")))]
- ""
- "*
- arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands);
- return arm_output_asm_insn (\"eor\\t%R0, %R1, %R2\", operands);
- "
- [(set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (xor:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "?r,0")))]
- ""
- "*
- arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands);
- if (REGNO (operands[0]) != REGNO (operands[1]))
- return arm_output_asm_insn (\"mov\\t%R0, %R1\", operands);
- return \"\";
- "
- [(set_attr "length" "2,1")])
-
- (define_insn ""
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (xor:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "?r,0")))]
- ""
- "*
- arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands);
- return arm_output_asm_insn (\"eor\\t%R0, %R1, %2, asr #31\", operands);
- "
- [(set_attr "length" "2")])
-
- (define_insn "xorsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (xor:SI (match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "arm_rhs_operand" "rI")))]
- ""
- "*
- return (arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands));
- ")
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "arm_rhs_operand" "rI"))
- (const_int 0)))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (xor:SI (match_dup 1) (match_dup 2)))]
- ""
- "*
- return arm_output_asm_insn (\"eors\\t%0, %1, %2\", operands);
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
- (match_operand:SI 1 "arm_rhs_operand" "rI"))
- (const_int 0)))]
- ""
- "*
- return arm_output_asm_insn (\"teq\\t%0, %1\", operands);
- "
- [(set_attr "conds" "set")])
-
- ;; by splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
- ;; (NOT D) we can sometimes merge the final NOT into one of the following
- ;; insns
-
- (define_split
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" "r"))
- (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI")))
- (match_operand:SI 3 "arm_rhs_operand" "rI")))
- (clobber (match_operand:SI 4 "s_register_operand" "=r"))]
- ""
- [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
- (not:SI (match_dup 3))))
- (set (match_dup 0) (not:SI (match_dup 4)))]
- ""
- )
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
- (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
- (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
- ""
- "*
- arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands);
- return arm_output_asm_insn (\"bic\\t%0, %0, %3\", operands);
- "
- [(set_attr "length" "2")])
-
-
-
- ;; Minimum and maximum insns
-
- (define_insn "smaxsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
- (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
- (clobber (reg:CC 24))]
- ""
- "*
- arm_output_asm_insn (\"cmp\\t%1, %2\", operands);
- if (which_alternative != 0)
- arm_output_asm_insn (\"movge\\t%0, %1\", operands);
- if (which_alternative != 1)
- return arm_output_asm_insn (\"movlt\\t%0, %2\", operands);
- return \"\";
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2,2,3")])
-
- (define_insn "sminsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
- (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
- (clobber (reg:CC 24))]
- ""
- "*
- arm_output_asm_insn (\"cmp\\t%1, %2\", operands);
- if (which_alternative != 0)
- arm_output_asm_insn (\"movle\\t%0, %1\", operands);
- if (which_alternative != 1)
- return arm_output_asm_insn (\"movgt\\t%0, %2\", operands);
- return \"\";
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2,2,3")])
-
- (define_insn "umaxsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
- (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
- (clobber (reg:CC 24))]
- ""
- "*
- arm_output_asm_insn (\"cmp\\t%1, %2\", operands);
- if (which_alternative != 0)
- arm_output_asm_insn (\"movcs\\t%0, %1\", operands);
- if (which_alternative != 1)
- return arm_output_asm_insn (\"movcc\\t%0, %2\", operands);
- return \"\";
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2,2,3")])
-
- (define_insn "uminsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
- (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
- (clobber (reg:CC 24))]
- ""
- "*
- arm_output_asm_insn (\"cmp\\t%1, %2\", operands);
- if (which_alternative != 0)
- arm_output_asm_insn (\"movcc\\t%0, %1\", operands);
- if (which_alternative != 1)
- return arm_output_asm_insn (\"movcs\\t%0, %2\", operands);
- return \"\";
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2,2,3")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "memory_operand" "=m")
- (match_operator:SI 3 "minmax_operator"
- [(match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "s_register_operand" "r")]))
- (clobber (reg:CC 24))]
- ""
- "*
- operands[3] = gen_rtx (minmax_code (operands[3]), SImode, operands[1],
- operands[2]);
- arm_output_asm_insn (\"cmp\\t%1, %2\", operands);
- arm_output_asm_insn (\"str%d3\\t%1, %0\", operands);
- return arm_output_asm_insn (\"str%D3\\t%2, %0\", operands);
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "3")
- (set_attr "type" "store1")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (match_operator:SI 4 "shiftable_operator"
- [(match_operator:SI 5 "minmax_operator"
- [(match_operand:SI 2 "s_register_operand" "r,r")
- (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
- (match_operand:SI 1 "s_register_operand" "0,?r")]))
- (clobber (reg:CC 24))]
- ""
- "*
- {
- char buf[100];
- enum rtx_code code = GET_CODE (operands[4]);
- char *inst = arithmetic_instr (operands[4], TRUE);
-
- operands[5] = gen_rtx (minmax_code (operands[5]), SImode, operands[2],
- operands[3]);
- arm_output_asm_insn (\"cmp\\t%2, %3\", operands);
- sprintf (buf, \"%s%%d5\\t%%0, %%1, %%2\", inst);
- arm_output_asm_insn (buf, operands);
- if (which_alternative != 0 || operands[3] != const0_rtx
- || (code != PLUS && code != MINUS && code != IOR && code != XOR))
- {
- sprintf (buf, \"%s%%D5\\t%%0, %%1, %%3\", inst);
- return arm_output_asm_insn (buf, operands);
- }
- return \"\";
- }
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "3")])
-
-
- ;; Shift and rotation insns
-
- (define_insn "ashlsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (ashift:SI (match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "arm_rhs_operand" "rn")))]
- ""
- "*
- return (output_shifted_move (ASHIFT, operands));
- ")
-
- (define_insn "ashrsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "arm_rhs_operand" "rn")))]
- ""
- "*
- return (output_shifted_move (ASHIFTRT, operands));
- ")
-
- ;; lshlsi3 is not defined because shift counts cannot be negative
- ;; An unnamed pattern is needed for expansion of zero_extend.
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (lshift:SI (match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "arm_rhs_operand" "rn")))]
- ""
- "*
- return (output_shifted_move (LSHIFT, operands));
- ")
-
- (define_insn "lshrsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "arm_rhs_operand" "rn")))]
- ""
- "*
- return (output_shifted_move (LSHIFTRT, operands));
- ")
-
- ;; rotlsi3 is not defined yet to see what happens
-
- (define_insn "rotrsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (rotatert:SI (match_operand:SI 1 "s_register_operand" "r,r")
- (match_operand:SI 2 "arm_rhs_operand" "r,n")))]
- ""
- "*
- switch (which_alternative)
- {
- case 0:
- return (arm_output_asm_insn (\"mov\\t%0, %1, ror %2\", operands));
- case 1:
- if (INTVAL(operands[2]) > 31)
- operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 32);
- return (arm_output_asm_insn (\"mov\\t%0, %1, ror %2\", operands));
- }
- ")
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (match_operator:SI 1 "shift_operator"
- [(match_operand:SI 2 "s_register_operand" "r")
- (match_operand:SI 3 "arm_rhs_operand" "rn")])
- (const_int 0)))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (match_op_dup 1 [(match_dup 2) (match_dup 3)]))]
- ""
- "*
- {
- char buf[100];
-
- sprintf (buf, \"movs\\t%%0, %%2, %s %%3\",
- shift_instr (GET_CODE (operands[1]), &operands[3]));
- return arm_output_asm_insn (buf, operands);
- }
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (match_operator:SI 1 "shift_operator"
- [(match_operand:SI 2 "s_register_operand" "r")
- (match_operand:SI 3 "arm_rhs_operand" "rn")])
- (const_int 0)))
- (clobber (match_scratch:SI 0 "=r"))]
- ""
- "*
- {
- char buf[100];
-
- sprintf (buf, \"movs\\t%%0, %%2, %s %%3\",
- shift_instr (GET_CODE (operands[1]), &operands[3]));
- return arm_output_asm_insn (buf, operands);
- }
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (not:SI (match_operator:SI 1 "shift_operator"
- [(match_operand:SI 2 "s_register_operand" "r")
- (match_operand:SI 3 "arm_rhs_operand" "rn")])))]
- ""
- "*
- {
- char buf[100];
- sprintf (buf, \"mvn\\t%%0, %%2, %s %%3\",
- shift_instr (GET_CODE (operands[1]), &operands[3]));
- return arm_output_asm_insn (buf, operands);
- }
- ")
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (not:SI (match_operator:SI 1 "shift_operator"
- [(match_operand:SI 2 "s_register_operand" "r")
- (match_operand:SI 3 "arm_rhs_operand" "rn")]))
- (const_int 0)))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (not:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])))]
- ""
- "*
- {
- char buf[100];
- sprintf (buf, \"mvns\\t%%0, %%2, %s %%3\",
- shift_instr (GET_CODE (operands[1]), &operands[3]));
- return arm_output_asm_insn (buf, operands);
- }
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (not:SI (match_operator:SI 1 "shift_operator"
- [(match_operand:SI 2 "s_register_operand" "r")
- (match_operand:SI 3 "arm_rhs_operand" "rn")]))
- (const_int 0)))
- (clobber (match_scratch:SI 0 "=r"))]
- ""
- "*
- {
- char buf[100];
- sprintf (buf, \"mvns\\t%%0, %%2, %s %%3\",
- shift_instr (GET_CODE (operands[1]), &operands[3]));
- return arm_output_asm_insn (buf, operands);
- }
- "
- [(set_attr "conds" "set")])
-
-
- ;; Unary arithmetic insns
-
- (define_insn "negdi2"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
- ""
- "*
- arm_output_asm_insn (\"rsbs\\t%0, %1, #0\", operands);
- return (arm_output_asm_insn (\"rsc\\t%R0, %R1, #0\", operands));
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2")])
-
- (define_insn "negsi2"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
- ""
- "*
- return (arm_output_asm_insn (\"rsb\\t%0, %1, #0\", operands));
- ")
-
- (define_insn "negsf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
- ""
- "*
- return (arm_output_asm_insn (\"mnfs\\t%0, %1\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn "negdf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
- ""
- "*
- return (arm_output_asm_insn (\"mnfd\\t%0, %1\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (neg:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))))]
- ""
- "*
- return (arm_output_asm_insn (\"mnfd\\t%0, %1\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn "negxf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (neg:XF (match_operand:XF 1 "s_register_operand" "f")))]
- "ENABLE_XF_PATTERNS"
- "*
- return (arm_output_asm_insn (\"mnfe\\t%0, %1\", operands));
- "
- [(set_attr "type" "float")])
-
- ;; abssi2 doesn't really clobber the condition codes if a different register
- ;; is being set. To keep things simple, assume during rtl manipulations that
- ;; it does, but tell the final scan operator the truth. Similarly for
- ;; (neg (abs...))
-
- (define_insn "abssi2"
- [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
- (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
- (clobber (reg 24))]
- ""
- "*
- switch (which_alternative)
- {
- case 0:
- arm_output_asm_insn (\"cmp\\t%0, #0\", operands);
- return arm_output_asm_insn (\"rsblt\\t%0, %0, #0\", operands);
- case 1:
- arm_output_asm_insn (\"eor\\t%0, %1, %1, asr #31\", operands);
- return arm_output_asm_insn (\"sub\\t%0, %0, %1, asr #31\", operands);
- }
- "
- [(set_attr "conds" "clob,*")
- (set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
- (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
- (clobber (reg 24))]
- ""
- "*
- switch (which_alternative)
- {
- case 0:
- arm_output_asm_insn (\"cmp\\t%0, #0\", operands);
- return arm_output_asm_insn (\"rsbgt\\t%0, %0, #0\", operands);
- case 1:
- arm_output_asm_insn (\"eor\\t%0, %1, %1, asr #31\", operands);
- return arm_output_asm_insn (\"rsb\\t%0, %0, %1, asr #31\", operands);
- }
- "
- [(set_attr "conds" "clob,*")
- (set_attr "length" "2")])
-
- (define_insn "abssf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
- ""
- "*
- return (arm_output_asm_insn (\"abss\\t%0, %1\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn "absdf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
- ""
- "*
- return (arm_output_asm_insn (\"absd\\t%0, %1\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (abs:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))))]
- ""
- "*
- return (arm_output_asm_insn (\"absd\\t%0, %1\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn "absxf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (abs:XF (match_operand:XF 1 "s_register_operand" "f")))]
- "ENABLE_XF_PATTERNS"
- "*
- return (arm_output_asm_insn (\"abse\\t%0, %1\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn "sqrtsf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
- ""
- "*
- return (arm_output_asm_insn (\"sqts\\t%0, %1\", operands));
- "
- [(set_attr "type" "float_em")])
-
- (define_insn "sqrtdf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
- ""
- "*
- return (arm_output_asm_insn (\"sqtd\\t%0, %1\", operands));
- "
- [(set_attr "type" "float_em")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (sqrt:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))))]
- ""
- "*
- return (arm_output_asm_insn (\"sqtd\\t%0, %1\", operands));
- "
- [(set_attr "type" "float_em")])
-
- (define_insn "sqrtxf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (sqrt:XF (match_operand:XF 1 "s_register_operand" "f")))]
- "ENABLE_XF_PATTERNS"
- "*
- return (arm_output_asm_insn (\"sqte\\t%0, %1\", operands));
- "
- [(set_attr "type" "float_em")])
-
- (define_insn "sinsf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 0))]
- ""
- "*
- return arm_output_asm_insn (\"sins\\t%0, %1\", operands);
- "
- [(set_attr "type" "float_em")])
-
- (define_insn "sindf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 0))]
- ""
- "*
- return arm_output_asm_insn (\"sind\\t%0, %1\", operands);
- "
- [(set_attr "type" "float_em")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (unspec:DF [(float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))] 0))]
- ""
- "*
- return arm_output_asm_insn (\"sind\\t%0, %1\", operands);
- "
- [(set_attr "type" "float_em")])
-
- (define_insn "sinxf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 0))]
- "ENABLE_XF_PATTERNS"
- "*
- return arm_output_asm_insn (\"sine\\t%0, %1\", operands);
- "
- [(set_attr "type" "float_em")])
-
- (define_insn "cossf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 1))]
- ""
- "*
- return arm_output_asm_insn (\"coss\\t%0, %1\", operands);
- "
- [(set_attr "type" "float_em")])
-
- (define_insn "cosdf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 1))]
- ""
- "*
- return arm_output_asm_insn (\"cosd\\t%0, %1\", operands);
- "
- [(set_attr "type" "float_em")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (unspec:DF [(float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))] 1))]
- ""
- "*
- return arm_output_asm_insn (\"cosd\\t%0, %1\", operands);
- "
- [(set_attr "type" "float_em")])
-
- (define_insn "cosxf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 1))]
- "ENABLE_XF_PATTERNS"
- "*
- return arm_output_asm_insn (\"cose\\t%0, %1\", operands);
- "
- [(set_attr "type" "float_em")])
-
- (define_insn "one_cmpldi2"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
- ""
- "*
- arm_output_asm_insn (\"mvn\\t%0, %1\", operands);
- return arm_output_asm_insn (\"mvn\\t%R0, %R1\", operands);
- "
- [(set_attr "length" "2")])
-
- (define_insn "one_cmplsi2"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
- ""
- "*
- return (arm_output_asm_insn (\"mvn\\t%0, %1\", operands));
- ")
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
- (const_int 0)))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (not:SI (match_dup 1)))]
- ""
- "*
- return (arm_output_asm_insn (\"mvns\\t%0, %1\", operands));
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
- (const_int 0)))
- (clobber (match_scratch:SI 0 "=r"))]
- ""
- "*
- return (arm_output_asm_insn (\"mvns\\t%0, %1\", operands));
- "
- [(set_attr "conds" "set")])
-
- ;; Fixed <--> Floating conversion insns
-
- (define_insn "floatsisf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
- ""
- "*
- return (arm_output_asm_insn (\"flts\\t%0, %1\", operands));
- "
- [(set_attr "type" "r_2_f")])
-
- (define_insn "floatsidf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
- ""
- "*
- return (arm_output_asm_insn (\"fltd\\t%0, %1\", operands));
- "
- [(set_attr "type" "r_2_f")])
-
- (define_insn "floatsixf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (float:XF (match_operand:SI 1 "s_register_operand" "r")))]
- "ENABLE_XF_PATTERNS"
- "*
- return (arm_output_asm_insn (\"flte\\t%0, %1\", operands));
- "
- [(set_attr "type" "r_2_f")])
-
- (define_insn "fix_truncsfsi2"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (fix:SI (match_operand:SF 1 "s_register_operand" "f")))]
- ""
- "*
- return arm_output_asm_insn (\"fixz\\t%0, %1\", operands);
- "
- [(set_attr "type" "f_2_r")])
-
- (define_insn "fix_truncdfsi2"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (fix:SI (match_operand:DF 1 "s_register_operand" "f")))]
- ""
- "*
- return arm_output_asm_insn (\"fixz\\t%0, %1\", operands);
- "
- [(set_attr "type" "f_2_r")])
-
- (define_insn "fix_truncxfsi2"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (fix:SI (match_operand:XF 1 "s_register_operand" "f")))]
- "ENABLE_XF_PATTERNS"
- "*
- return arm_output_asm_insn (\"fixz\\t%0, %1\", operands);
- "
- [(set_attr "type" "f_2_r")])
-
- ;; Truncation insns
-
- (define_insn "truncdfsf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (float_truncate:SF
- (match_operand:DF 1 "s_register_operand" "f")))]
- ""
- "*
- return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn "truncxfsf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (float_truncate:SF
- (match_operand:XF 1 "s_register_operand" "f")))]
- "ENABLE_XF_PATTERNS"
- "*
- return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn "truncxfdf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (float_truncate:DF
- (match_operand:XF 1 "s_register_operand" "f")))]
- "ENABLE_XF_PATTERNS"
- "*
- return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands));
- "
- [(set_attr "type" "float")])
-
- ;; Zero and sign extension instructions.
-
- (define_insn "zero_extendsidi2"
- [(set (match_operand:DI 0 "s_register_operand" "=r")
- (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
- ""
- "*
- if (REGNO (operands[1]) != REGNO (operands[0]))
- arm_output_asm_insn (\"mov\\t%0, %1\", operands);
- return arm_output_asm_insn (\"mov\\t%R0, #0\", operands);
- "
- [(set_attr "length" "2")])
-
- (define_insn "zero_extendqidi2"
- [(set (match_operand:DI 0 "s_register_operand" "=r,r")
- (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
- ""
- "*
- switch (which_alternative)
- {
- case 0:
- arm_output_asm_insn (\"and\\t%0, %1, #255\", operands);
- break;
- case 1:
- arm_output_asm_insn (\"ldrb\\t%0, %1\",operands);
- break;
- }
- return arm_output_asm_insn (\"mov\\t%R0, #0\", operands);
- "
- [(set_attr "length" "2")
- (set_attr "type" "*,load")])
-
- (define_insn "extendsidi2"
- [(set (match_operand:DI 0 "s_register_operand" "=r")
- (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
- ""
- "*
- if (REGNO (operands[1]) != REGNO (operands[0]))
- arm_output_asm_insn (\"mov\\t%0, %1\", operands);
- return arm_output_asm_insn (\"mov\\t%R0, %0, asr #31\", operands);
- "
- [(set_attr "length" "2")])
-
- (define_expand "zero_extendhisi2"
- [(set (match_dup 2)
- (ashift:SI (match_operand:HI 1 "s_register_operand" "")
- (const_int 16)))
- (set (match_operand:SI 0 "s_register_operand" "")
- (lshiftrt:SI (match_dup 2)
- (const_int 16)))]
- ""
- "
- { operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_reg_rtx (SImode); }")
-
- (define_insn "zero_extendqihi2"
- [(set (match_operand:HI 0 "s_register_operand" "=r")
- (zero_extend:HI
- (match_operand:QI 1 "s_register_operand" "r")))]
- ""
- "*
- return (arm_output_asm_insn (\"and\\t%0, %1, #255\\t@ zero_extendqihi2\", operands));
- ")
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (match_operand:QI 1 "s_register_operand" "r")
- (const_int 0)))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (zero_extend:HI (match_dup 1)))]
- ""
- "*
- return arm_output_asm_insn (\"ands\\t%0, %1, #255\", operands);
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (match_operand:QI 0 "s_register_operand" "r")
- (const_int 0)))]
- ""
- "*
- return arm_output_asm_insn (\"tst\\t%0, #255\", operands);
- "
- [(set_attr "conds" "set")])
-
- (define_insn "zero_extendqisi2"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (zero_extend:SI
- (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
- ""
- "*
- switch (which_alternative)
- {
- case 0:
- return (arm_output_asm_insn (\"and\\t%0, %1, #255\\t@ zero_extendqisi2\", operands));
- case 1:
- return (arm_output_asm_insn (\"ldrb\\t%0, %1\\t@ zero_extendqisi2\", operands));
- }
- "
- [(set_attr "type" "*,load")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (match_operand:QI 1 "s_register_operand" "r")
- (const_int 0)))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (zero_extend:SI (match_dup 1)))]
- ""
- "*
- return arm_output_asm_insn (\"ands\\t%0, %1, #255\", operands);
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (match_operand:QI 1 "s_register_operand" "r")
- (const_int 0)))
- (set (match_operand:QI 0 "s_register_operand" "=r")
- (match_dup 1))]
- ""
- "*
- return arm_output_asm_insn (\"ands\\t%0, %1, #255\", operands);
- "
- [(set_attr "conds" "set")])
-
- (define_expand "extendhisi2"
- [(set (match_dup 2)
- (ashift:SI (match_operand:HI 1 "s_register_operand" "")
- (const_int 16)))
- (set (match_operand:SI 0 "s_register_operand" "")
- (ashiftrt:SI (match_dup 2)
- (const_int 16)))]
- ""
- "
- { operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_reg_rtx (SImode); }")
-
- (define_expand "extendqihi2"
- [(set (match_dup 2)
- (ashift:SI (match_operand:QI 1 "s_register_operand" "")
- (const_int 24)))
- (set (match_operand:HI 0 "s_register_operand" "")
- (ashiftrt:SI (match_dup 2)
- (const_int 24)))]
- ""
- "
- { operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_reg_rtx (SImode); }")
-
- (define_expand "extendqisi2"
- [(set (match_dup 2)
- (ashift:SI (match_operand:QI 1 "s_register_operand" "")
- (const_int 24)))
- (set (match_operand:SI 0 "s_register_operand" "")
- (ashiftrt:SI (match_dup 2)
- (const_int 24)))]
- ""
- "
- { operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_reg_rtx (SImode); }")
-
- (define_insn "extendsfdf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
- ""
- "*
- return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands));
- "
- [(set_attr "type" "float")])
-
- (define_insn "extendsfxf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))]
- "ENABLE_XF_PATTERNS"
- "*
- return (arm_output_asm_insn (\"mvfe\\t%0, %1\", operands));
- ")
-
- (define_insn "extenddfxf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))]
- "ENABLE_XF_PATTERNS"
- "*
- return (arm_output_asm_insn (\"mvfe\\t%0, %1\", operands));
- "
- [(set_attr "type" "float")])
-
-
- ;; Move insns (including loads and stores)
-
- ;; XXX Just some ideas about movti.
- ;; I don't think these are a good idea on the arm, there just aren't enough
- ;; registers
- ;;(define_expand "loadti"
- ;; [(set (match_operand:TI 0 "s_register_operand" "")
- ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
- ;; "" "")
-
- ;;(define_expand "storeti"
- ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
- ;; (match_operand:TI 1 "s_register_operand" ""))]
- ;; "" "")
-
- ;;(define_expand "movti"
- ;; [(set (match_operand:TI 0 "general_operand" "")
- ;; (match_operand:TI 1 "general_operand" ""))]
- ;; ""
- ;; "
- ;;{
- ;; rtx insn;
- ;;
- ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
- ;; operands[1] = copy_to_reg (operands[1]);
- ;; if (GET_CODE (operands[0]) == MEM)
- ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
- ;; else if (GET_CODE (operands[1]) == MEM)
- ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
- ;; else
- ;; FAIL;
- ;;
- ;; emit_insn (insn);
- ;; DONE;
- ;;}")
-
- ;; Recognise garbage generated above.
-
- ;;(define_insn ""
- ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
- ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
- ;; ""
- ;; "*
- ;; {
- ;; register mem = (which_alternative < 3);
- ;; register char *template;
- ;;
- ;; operands[mem] = XEXP (operands[mem], 0);
- ;; switch (which_alternative)
- ;; {
- ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
- ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
- ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
- ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
- ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
- ;; case 5: template = \"stmia\\t%0, %M1\"; break;
- ;; }
- ;; return (arm_output_asm_insn (template, operands));
- ;; }")
-
-
- (define_insn "movdi"
- [(set (match_operand:DI 0 "di_operand" "=r,r,r,o<>,r")
- (match_operand:DI 1 "di_operand" "rK,n,o<>,r,F"))]
- ""
- "*
- return (output_move_double (operands));
- "
- [(set_attr "length" "2,8,2,2,8")
- (set_attr "type" "*,*,load,store2,*")])
-
- (define_expand "movsi"
- [(set (match_operand:SI 0 "general_operand" "")
- (match_operand:SI 1 "general_operand" ""))]
- ""
- "
- /* Everything except mem = const or mem = mem can be done easily */
- if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (SImode, operands[1]);
- if (GET_CODE (operands[1]) == CONST_INT
- && !(const_ok_for_arm (INTVAL (operands[1]))
- || const_ok_for_arm (~INTVAL (operands[1]))))
- {
- int n = INTVAL (operands[1]);
- rtx tmpreg, tmpreg2;
- int i, n_ones = 0, first = 1, last = 0;
-
- if (GET_CODE (operands[0]) != REG
- && GET_CODE (operands[0]) != SUBREG)
- abort ();
- for (i = 0; i < 32; i++)
- if (n & 1 << i)
- n_ones++;
- /* These loops go the opposite way around to those in arm.c so that
- the last constant may be more likely to be eliminted into the
- next instruction */
-
- if (n_ones > 16)
- {
- n = (~n) & 0xffffffff;
- for (i = 30; i >= 0; i -= 2)
- {
- if (n & (3 << i))
- {
- i -= 6;
- if (i < 0)
- i = 0;
- if ((n & (255 << i)) == n)
- last = 1;
- if (first)
- {
- rtx equal;
- rtx insn =
- emit_insn (gen_movsi (tmpreg = (reload_in_progress
- || reload_completed)
- ? operands[0]
- : gen_reg_rtx (SImode),
- equal = gen_rtx (CONST_INT, VOIDmode,
- ~(n & (255 << i)))));
- first = 0;
- }
- else
- {
- rtx constant;
- rtx insn =
- emit_insn (gen_subsi3 (tmpreg2 = (reload_in_progress
- || reload_completed
- || last)
- ? operands[0]
- : gen_reg_rtx (SImode),
- tmpreg,
- constant = gen_rtx (CONST_INT, VOIDmode,
- n & (255 << i))));
- tmpreg = tmpreg2;
- }
- n &= ~(255 << i);
- }
- }
- }
- else
- {
- for (i = 30; i >= 0; i -= 2)
- {
- if (n & (3 << i))
- {
- i -= 6;
- if (i < 0)
- i = 0;
- if ((n & (255 << i)) == n)
- last = 1;
- if (first)
- {
- rtx equal;
- rtx insn =
- emit_insn (gen_movsi (tmpreg = (reload_in_progress
- || reload_completed)
- ? operands[0]
- : gen_reg_rtx (SImode),
- equal = gen_rtx (CONST_INT, VOIDmode,
- n & (255 << i))));
- first = 0;
- }
- else
- {
- rtx constant;
- rtx insn =
- emit_insn (gen_addsi3 (tmpreg2 = (reload_in_progress
- || reload_completed
- || last)
- ? operands[0]
- : gen_reg_rtx (SImode),
- tmpreg,
- constant = gen_rtx (CONST_INT, VOIDmode,
- n & (255 << i))));
- tmpreg = tmpreg2;
- }
- n &= ~(255 << i);
- }
- }
- }
- DONE;
- }
- ")
-
- (define_insn ""
- [(set (match_operand:SI 0 "general_operand" "=r,r,r,m,r")
- (match_operand:SI 1 "general_operand" "m,K,r,r,S"))]
- "(register_operand (operands[0], SImode)
- && (GET_CODE (operands[1]) != CONST_INT
- || const_ok_for_arm (INTVAL (operands[1]))
- || const_ok_for_arm (~INTVAL (operands[1])))
- && (GET_CODE (operands[1]) != SYMBOL_REF
- || CONSTANT_ADDRESS_P (operands[1])))
- || register_operand (operands[1], SImode)"
- "*
- switch (which_alternative)
- {
- case 2:
- return (arm_output_asm_insn (\"mov\\t%0, %1\", operands));
- case 1:
- if (!const_ok_for_arm (INTVAL (operands[1])))
- {
- operands[1] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[1]));
- return arm_output_asm_insn (\"mvn\\t%0, %1\", operands);
- }
- return arm_output_asm_insn (\"mov\\t%0, %1\", operands);
- case 0:
- if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
- && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
- return (arm_output_llc (operands));
- else
- return (arm_output_asm_insn (\"ldr\\t%0, %1\", operands));
- case 3:
- return (arm_output_asm_insn (\"str\\t%1, %0\", operands));
- case 4:
- return output_load_symbol (operands);
- }
- "
- [(set_attr "length" "2,*,*,*,4")
- (set_attr "type" "load,*,*,store1,*")])
-
- ;; If copying one reg to another we can set the condition codes according to
- ;; its value. Such a move is common after a return from subroutine and the
- ;; result is being tested against zero.
-
- (define_insn ""
- [(set (reg:CC 24) (compare (match_operand:SI 1 "s_register_operand" "r")
- (const_int 0)))
- (set (match_operand:SI 0 "s_register_operand" "=r") (match_dup 1))]
- ""
- "*
- if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
- && REGNO (operands[0]) == REGNO (operands[1]))
- return arm_output_asm_insn (\"cmp\\t%0, #0\", operands);
- return arm_output_asm_insn (\"subs\\t%0, %1, #0\", operands);
- "
- [(set_attr "conds" "set")])
-
- ;; Subroutine to store a half word from a register into memory.
- ;; Operand 0 is the source register (HImode)
- ;; Operand 1 is the destination address in a register (SImode)
-
- ;; In both this routine and the next, we must be careful not to spill
- ;; a memory address of reg+large_const into a seperate PLUS insn, since this
- ;; can generate unrecognizable rtl.
-
- (define_expand "storehi"
- [;; store the low byte
- (set (mem:QI (match_operand:SI 1 "" "")) (match_dup 3))
- ;; extract the high byte
- (set (match_dup 2)
- (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
- ;; store the high byte
- (set (mem:QI (match_dup 4))
- (subreg:QI (match_dup 2) 0))] ;explicit subreg safe
- ""
- "
- {
- enum rtx_code code = GET_CODE (operands[1]);
-
- if ((code == PLUS || code == MINUS)
- && (GET_CODE (XEXP (operands[1], 1)) == REG
- || GET_CODE (XEXP (operands[1], 0)) != REG))
- operands[1] = force_reg (SImode, operands[1]);
- operands[4] = plus_constant (operands[1], 1);
- operands[3] = gen_lowpart (QImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[2] = gen_reg_rtx (SImode);
- }
- ")
-
- ;; Subroutine to store a half word integer constant into memory.
- ;; Operand 0 is the constant
- ;; Operand 1 is the destination address in a register (SImode)
-
- (define_expand "storeinthi"
- [;; store the low byte
- (set (mem:QI (match_operand:SI 1 "" "")) (match_operand 0 "" ""))
- ;; store the high byte
- (set (mem:QI (match_dup 3)) (match_dup 2))]
- ""
- "
- {
- int value = INTVAL (operands[0]);
- enum rtx_code code = GET_CODE (operands[1]);
-
- if ((code == PLUS || code == MINUS)
- && (GET_CODE (XEXP (operands[1], 1)) == REG
- || GET_CODE (XEXP (operands[1], 0)) != REG))
- operands[1] = force_reg (SImode, operands[1]);
-
- operands[0] = force_reg (QImode, gen_rtx (CONST_INT, VOIDmode, value & 255));
- operands[2] = force_reg (QImode,
- gen_rtx (CONST_INT, VOIDmode,(value>>8) & 255));
- operands[3] = plus_constant (operands[1], 1);
- }
- ")
-
- (define_expand "movhi"
- [(set (match_operand:HI 0 "general_operand" "")
- (match_operand:HI 1 "general_operand" ""))]
- ""
- "
- {
- rtx insn;
-
- if (reload_in_progress || reload_completed)
- insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]);
- else
- {
- if (GET_CODE (operands[0]) == MEM)
- {
- if (GET_CODE (operands[1]) == CONST_INT)
- {
- insn = gen_storeinthi (operands[1], XEXP (operands[0],0));
- }
- else
- {
- if (GET_CODE (operands[1]) == MEM)
- operands[1] = force_reg (HImode, operands[1]);
- insn = gen_storehi (operands[1], XEXP (operands[0], 0));
- }
- }
- else if (GET_CODE (operands[1]) == CONST_INT
- && !(const_ok_for_arm (INTVAL (operands[1]))
- || const_ok_for_arm (~INTVAL (operands[1]))))
- {
- rtx reg, reg2;
-
- /* no need to be clever, this will always take two insns.
- The top sixteen bits should be all zeros or all ones. */
- if (INTVAL (operands[1]) < 0)
- {
- emit_insn (gen_movsi (reg = gen_reg_rtx (SImode),
- GEN_INT (INTVAL (operands[1])
- | ~(0x0ff00))));
- emit_insn (gen_addsi3 (reg2 = gen_reg_rtx (SImode), reg,
- GEN_INT (-((~INTVAL (operands[1]))
- & 0xff))));
- }
- else
- {
- emit_insn (gen_movsi (reg = gen_reg_rtx (SImode),
- GEN_INT (INTVAL (operands[1]) & 0xff00)));
- emit_insn (gen_addsi3 (reg2 = gen_reg_rtx (SImode), reg,
- GEN_INT (INTVAL (operands[1]) & 0x00ff)));
- }
- insn = gen_rtx (SET, HImode, operands[0],
- gen_rtx (SUBREG, HImode, reg2, 0));
- }
- else
- insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]);
- }
-
- emit_insn (insn);
- DONE;
- }")
-
- ;; Pattern to recognise insn generated default case above
-
- (define_insn ""
- [(set (match_operand:HI 0 "general_operand" "=r,r,r,m")
- (match_operand:HI 1 "general_operand" "r,K,m,r"))]
- "(register_operand (operands[0], HImode)
- && (GET_CODE (operands[1]) != CONST_INT
- || const_ok_for_arm (INTVAL (operands[1]))
- || const_ok_for_arm (~INTVAL (operands[1]))))
- || register_operand (operands[1], HImode)"
- "*
- switch (which_alternative)
- {
- case 1:
- if (!const_ok_for_arm (INTVAL (operands[1])))
- {
- operands[1] = GEN_INT (~INTVAL (operands[1]));
- return arm_output_asm_insn (\"mvn\\t%0, %1\", operands);
- }
- /* fall through */
- case 0:
- return arm_output_asm_insn (\"mov\\t%0, %1\\t@movhi\", operands);
- case 2:
- return arm_output_asm_insn (\"ldr\\t%0, %1\\t@movhi\", operands);
- case 3:
- return arm_output_asm_insn (\"str\\t%1, %0\\t@movhi\", operands);
- }
- "
- [(set_attr "type" "*,*,load,store1")])
-
- (define_expand "reload_outhi"
- [(parallel [(match_operand:HI 0 "reload_memory_operand" "=o")
- (match_operand:HI 1 "s_register_operand" "r")
- (match_operand:SI 2 "s_register_operand" "=&r")])]
- ""
- "
- arm_reload_out_hi (operands);
- DONE;
- ")
-
- (define_expand "movqi"
- [(set (match_operand:QI 0 "general_operand" "")
- (match_operand:QI 1 "general_operand" ""))]
- ""
- "
- /* Everything except mem = const or mem = mem can be done easily */
-
- if (!(reload_in_progress || reload_completed))
- {
- rtx reg;
- if (GET_CODE (operands[1]) == CONST_INT)
- {
- emit_insn (gen_movsi (reg = gen_reg_rtx (SImode), operands[1]));
- operands[1] = gen_rtx (SUBREG, QImode, reg, 0);
- }
- }
- if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (QImode, operands[1]);
- ")
-
-
- (define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
- (match_operand:QI 1 "general_operand" "r,K,m,r"))]
- "register_operand (operands[0], QImode)
- || register_operand (operands[1], QImode)"
- "*
- switch (which_alternative)
- {
- case 1:
- if (INTVAL (operands[1]) < 0)
- {
- operands[1] = GEN_INT (~INTVAL (operands[1]));
- return arm_output_asm_insn (\"mvn\\t%0, %1\", operands);
- }
- case 0:
- return (arm_output_asm_insn (\"mov\\t%0, %1\", operands));
- case 2:
- return (arm_output_asm_insn (\"ldrb\\t%0, %1\", operands));
- case 3:
- return (arm_output_asm_insn (\"strb\\t%1, %0\", operands));
- }
- "
- [(set_attr "type" "*,*,load,store1")])
-
- (define_insn "movsf"
- [(set (match_operand:SF 0 "general_operand" "=f,f,f,m,f,r,r,r,m")
- (match_operand:SF 1 "general_operand" "fG,H,m,f,r,f,r,m,r"))]
- ""
- "*
- {
- REAL_VALUE_TYPE r;
-
- switch (which_alternative)
- {
- case 0:
- return arm_output_asm_insn (\"mvfs\\t%0, %1\", operands);
- case 1:
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
- r = REAL_VALUE_NEGATE (r);
- operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
- return arm_output_asm_insn (\"mnfs\\t%0, %1\", operands);
- case 2:
- return arm_output_asm_insn (\"ldfs\\t%0, %1\", operands);
- case 3:
- return arm_output_asm_insn (\"stfs\\t%1, %0\", operands);
- case 4:
- arm_output_asm_insn(\"stmfd\\tsp!, {%1}\", operands);
- return arm_output_asm_insn (\"ldfs\\t%0, [sp],#4\", operands);
- case 5:
- arm_output_asm_insn(\"stfs\\t%1, [sp,#-4]!\", operands);
- return arm_output_asm_insn (\"ldmfd\\tsp!, {%0}\", operands);
- case 6:
- return arm_output_asm_insn (\"mov\\t%0, %1\", operands);
- case 7:
- return arm_output_asm_insn (\"ldr\\t%0, %1\\t@ float\", operands);
- case 8:
- return arm_output_asm_insn (\"str\\t%1, %0\\t@ float\", operands);
- }
- }
- "
- [(set_attr "length" "1,1,1,1,2,2,1,1,1")
- (set_attr "type" "float,float,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")])
-
- (define_expand "movdf"
- [(parallel [(set (match_operand:DF 0 "general_operand" "")
- (match_operand:DF 1 "general_operand" ""))
- (clobber (match_scratch:SI 2 ""))])]
- ""
- "
- if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (DFmode, operands[1]);
- ")
-
- ;; Reloading a df mode value stored in integer regs to memory can require a
- ;; scratch reg.
- (define_expand "reload_outdf"
- [(parallel [(set (match_operand:DF 0 "reload_memory_operand" "=o")
- (match_operand:DF 1 "s_register_operand" "r"))
- (clobber (match_operand:SI 2 "s_register_operand" "=&r"))])]
- ""
- "")
-
- (define_insn ""
- [(set (match_operand:DF 0 "general_operand" "=r,Q,r,o,f,f,f,f,m,!f,!r,r")
- (match_operand:DF 1 "general_operand"
- "Q,r,?o,?r,?f,!G,!H,m,f,r,f,??r"))
- (clobber (match_scratch:SI 2 "=X,X,X,&r,X,X,X,X,X,X,X,X"))]
- "GET_CODE (operands[0]) != MEM || register_operand (operands[1], DFmode)"
- "*
- {
- REAL_VALUE_TYPE r;
- rtx ops[3];
-
- switch (which_alternative)
- {
- case 0:
- operands[1] = XEXP (operands[1], 0);
- return arm_output_asm_insn (\"ldmia\\t%1, {%0, %R0}\\t@ double\",
- operands);
- case 1:
- operands[0] = XEXP (operands[0], 0);
- return arm_output_asm_insn (\"stmia\\t%0, {%1, %R1}\\t@ double\",
- operands);
- case 2:
- ops[0] = operands[0];
- ops[1] = XEXP (XEXP (operands[1], 0), 0);
- ops[2] = XEXP (XEXP (operands[1], 0), 1);
- if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2])))
- arm_output_asm_insn (\"add\\t%0, %1, %2\", ops);
- else
- arm_output_asm_insn (\"sub\\t%0, %1, #%n2\", ops);
- return arm_output_asm_insn (\"ldmia\\t%0, {%0, %R0}\\t@ double\",
- operands);
- case 3:
-
- ops[0] = operands[2];
- ops[1] = XEXP (XEXP (operands[0], 0), 0);
- ops[2] = XEXP (XEXP (operands[0], 0), 1);
- if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2])))
- arm_output_asm_insn (\"add\\t%0, %1, %2\", ops);
- else
- arm_output_asm_insn (\"sub\\t%0, %1, #%n2\", ops);
- return arm_output_asm_insn (\"stmia\\t%2, {%1, %R1}\\t@ double\",
- operands);
- case 4:
- case 5:
- return arm_output_asm_insn (\"mvfd\\t%0, %1\", operands);
- case 6:
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
- r = REAL_VALUE_NEGATE (r);
- operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
- return arm_output_asm_insn (\"mnfd\\t%0, %1\", operands);
- case 7: return arm_output_asm_insn (\"ldfd\\t%0, %1\", operands);
- case 8: return arm_output_asm_insn (\"stfd\\t%1, %0\", operands);
- case 9: return output_mov_double_fpu_from_arm (operands);
- case 10: return output_mov_double_arm_from_fpu (operands);
- case 11: return output_move_double (operands);
- }
- }
- "
- [(set_attr "length" "1,1,2,2,1,1,1,1,1,2,2,2")
- (set_attr "type"
- "load,store2,load,store2,float,float,float,f_load,f_store,r_mem_f,f_mem_r,*")])
-
- (define_insn "movxf"
- [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r")
- (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
- "ENABLE_XF_PATTERNS"
- "*
- {
- REAL_VALUE_TYPE r;
-
- switch (which_alternative)
- {
- case 0: return arm_output_asm_insn (\"mvfe\\t%0, %1\", operands);
- case 1:
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
- r = REAL_VALUE_NEGATE (r);
- operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
- return arm_output_asm_insn (\"mnfe\\t%0, %1\", operands);
- case 2: return arm_output_asm_insn (\"ldfe\\t%0, %1\", operands);
- case 3: return arm_output_asm_insn (\"stfe\\t%1, %0\", operands);
- case 4: return output_mov_long_double_fpu_from_arm (operands);
- case 5: return output_mov_long_double_arm_from_fpu (operands);
- case 6: return output_mov_long_double_arm_from_arm (operands);
- }
- }
- "
- [(set_attr "length" "1,1,1,1,2,2,3")
- (set_attr "type" "float,float,f_load,f_store,r_mem_f,f_mem_r,*")])
-
-
- ;; load- and store-multiple insns
- ;; The arm can load/store any set of registers, provided that they are in
- ;; ascending order; but that is beyond GCC so stick with what it knows.
-
- (define_expand "load_multiple"
- [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
- (match_operand:SI 1 "" ""))
- (use (match_operand:SI 2 "" ""))])]
- ""
- "
- /* Support only fixed point registers */
- if (GET_CODE (operands[2]) != CONST_INT
- || INTVAL (operands[2]) > 14
- || INTVAL (operands[2]) < 2
- || GET_CODE (operands[1]) != MEM
- || GET_CODE (operands[0]) != REG
- || REGNO (operands[0]) > 14
- || REGNO (operands[0]) + INTVAL (operands[2]) > 15)
- FAIL;
-
- operands[3]
- = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
- force_reg (SImode, XEXP (operands[1], 0)),
- TRUE, FALSE);
- ")
-
- ;; Load multiple with write-back
-
- (define_insn ""
- [(match_parallel 0 "load_multiple_operation"
- [(set (match_operand:SI 1 "s_register_operand" "+r")
- (plus:SI (match_dup 1)
- (match_operand:SI 2 "immediate_operand" "n")))
- (set (match_operand:SI 3 "s_register_operand" "=r")
- (mem:SI (match_dup 1)))])]
- "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
- "*
- {
- rtx ops[3];
- int count = XVECLEN (operands[0], 0);
-
- ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
- ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1));
- ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2));
-
- return arm_output_asm_insn (\"ldmia\\t%0!, {%1-%2}\\t@ load multiple\", ops);
- }
- "
- [(set_attr "type" "load")])
-
- ;; Ordinary load multiple
-
- (define_insn ""
- [(match_parallel 0 "load_multiple_operation"
- [(set (match_operand:SI 1 "s_register_operand" "=r")
- (match_operand:SI 2 "indirect_operand" "Q"))])]
- ""
- "*
- {
- rtx ops[3];
- int count = XVECLEN (operands[0], 0);
-
- ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
- ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0));
- ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
-
- return arm_output_asm_insn (\"ldmia\\t%0, {%1-%2}\\t@ load multiple\", ops);
- }
- "
- [(set_attr "type" "load")])
-
- (define_expand "store_multiple"
- [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
- (match_operand:SI 1 "" ""))
- (use (match_operand:SI 2 "" ""))])]
- ""
- "
- /* Support only fixed point registers */
- if (GET_CODE (operands[2]) != CONST_INT
- || INTVAL (operands[2]) > 14
- || INTVAL (operands[2]) < 2
- || GET_CODE (operands[1]) != REG
- || GET_CODE (operands[0]) != MEM
- || REGNO (operands[1]) > 14
- || REGNO (operands[1]) + INTVAL (operands[2]) > 15)
- FAIL;
-
- operands[3]
- = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
- force_reg (SImode, XEXP (operands[0], 0)),
- TRUE, FALSE);
- ")
-
- ;; Store multiple with write-back
-
- (define_insn ""
- [(match_parallel 0 "store_multiple_operation"
- [(set (match_operand:SI 1 "s_register_operand" "+r")
- (plus:SI (match_dup 1)
- (match_operand:SI 2 "immediate_operand" "n")))
- (set (mem:SI (match_dup 1))
- (match_operand:SI 3 "s_register_operand" "r"))])]
- "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
- "*
- {
- rtx ops[3];
- int count = XVECLEN (operands[0], 0);
-
- ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
- ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1));
- ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2));
-
- return arm_output_asm_insn (\"stmia\\t%0!, {%1-%2}\\t@ str multiple\", ops);
- }
- "
- [(set (attr "type")
- (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
- (const_string "store2")
- (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5))
- (const_string "store3")]
- (const_string "store4")))])
-
- ;; Ordinary store multiple
-
- (define_insn ""
- [(match_parallel 0 "store_multiple_operation"
- [(set (match_operand:SI 2 "indirect_operand" "=Q")
- (match_operand:SI 1 "s_register_operand" "r"))])]
- ""
- "*
- {
- rtx ops[3];
- int count = XVECLEN (operands[0], 0);
-
- ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0);
- ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0));
- ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
-
- return arm_output_asm_insn (\"stmia\\t%0, {%1-%2}\\t@ str multiple\", ops);
- }
- "
- [(set (attr "type")
- (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
- (const_string "store2")
- (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
- (const_string "store3")]
- (const_string "store4")))])
-
- ;; Move a block of memory if it is word aligned and MORE than 2 words long.
- ;; We could let this apply for blocks of less than this, but it clobbers so
- ;; many registers that there is then probably a better way.
-
- ;; If optimizing, output redundant moves with REG_NOTES on them, this
- ;; produces better code.
-
- (define_expand "movstrsi"
- [(set (match_operand:BLK 0 "general_operand" "=m")
- (match_operand:BLK 1 "general_operand" "m"))
- (use (match_operand:SI 2 "immediate_operand" "n"))
- (use (match_operand:SI 3 "immediate_operand" "n"))
- (clobber (reg:SI 0))
- (clobber (reg:SI 1))
- (clobber (reg:SI 2))
- (clobber (reg:SI 3))
- (clobber (match_scratch:SI 4 "=+r"))
- (clobber (match_scratch:SI 5 "=+r"))]
- ""
- "
- {
- int words_to_go;
- int i, r;
- rtx const_sxteen = gen_rtx (CONST_INT, SImode, 16);
- rtx src = gen_reg_rtx (SImode);
- rtx dst = gen_reg_rtx (SImode);
- rtx st_src, st_dst, end_src, end_dst, fin_src, fin_dst;
- extern int optimize;
-
- if (GET_CODE (operands[2]) != CONST_INT
- || GET_CODE (operands[3]) != CONST_INT
- || INTVAL (operands[2]) % 4 != 0
- || INTVAL (operands[2]) < 4
- || INTVAL (operands[2]) > 64
- || INTVAL (operands[3]) < 4
- || INTVAL (operands[3]) % 4 != 0)
- FAIL;
- emit_move_insn (dst, st_dst = force_reg (SImode, XEXP (operands[0], 0)));
- emit_move_insn (src, st_src = force_reg (SImode, XEXP (operands[1], 0)));
- fin_src = src;
- fin_dst = dst;
-
- for (i = 0, words_to_go = INTVAL (operands[2]) / 4; words_to_go >= 2; i+=4)
- {
- emit_insn (arm_gen_load_multiple (0, words_to_go > 4 ? 4 : words_to_go,
- src, TRUE, TRUE));
- emit_insn (arm_gen_store_multiple (0, words_to_go > 4 ? 4 : words_to_go,
- dst, TRUE, TRUE));
- if (optimize)
- for (r = (words_to_go > 4) ? 3 : words_to_go - 1; r >= 0; r--)
- {
- rtx note;
- note = emit_move_insn (gen_reg_rtx (SImode),
- gen_rtx (REG, SImode, r));
- REG_NOTES (note) = gen_rtx (EXPR_LIST, REG_EQUIV,
- gen_rtx (MEM, SImode,
- plus_constant (st_src, 4*(i+r))),
- REG_NOTES (note));
- REG_NOTES (note) = gen_rtx (EXPR_LIST, REG_EQUIV,
- gen_rtx (MEM, SImode,
- plus_constant (st_dst, 4*(i+r))),
- REG_NOTES (note));
- }
- words_to_go -= words_to_go < 4 ? words_to_go : 4;
- }
- if (words_to_go)
- {
- rtx sreg;
-
- emit_move_insn (sreg = gen_reg_rtx (SImode), gen_rtx (MEM, SImode, src));
- emit_move_insn (fin_src = gen_reg_rtx (SImode), plus_constant (src, 4));
- emit_move_insn (gen_rtx (MEM, SImode, dst), sreg);
- emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4));
- }
- if (optimize)
- {
- /* Insns for the REG_NOTES: These notes tell the optimiser where the
- index registers have got to so that consecutive block moves of
- contiguous data work efficiently */
-
- end_src = emit_move_insn (fin_src, fin_src);
- REG_NOTES (end_src) = gen_rtx(EXPR_LIST, REG_EQUAL,
- plus_constant (st_src, INTVAL (operands[2])),
- REG_NOTES (end_src));
- end_dst = emit_move_insn (fin_dst, fin_dst);
- REG_NOTES (end_dst) = gen_rtx(EXPR_LIST, REG_EQUAL,
- plus_constant (st_dst, INTVAL (operands[2])),
- REG_NOTES (end_dst));
- }
- DONE;
- }
- ")
-
-
- ;; Comparison and test insns
-
- (define_expand "cmpsi"
- [(set (reg:CC 24)
- (compare:CC (match_operand:SI 0 "s_register_operand" "")
- (match_operand:SI 1 "arm_add_operand" "")))]
- ""
- "
- {
- arm_compare_op0 = operands[0];
- arm_compare_op1 = operands[1];
- arm_compare_fp = 0;
- DONE;
- }
- ")
-
- (define_expand "cmpsf"
- [(set (reg:CC 24)
- (compare:CC (match_operand:SF 0 "s_register_operand" "")
- (match_operand:SF 1 "fpu_rhs_operand" "")))]
- ""
- "
- {
- arm_compare_op0 = operands[0];
- arm_compare_op1 = operands[1];
- arm_compare_fp = 1;
- DONE;
- }
- ")
-
- (define_expand "cmpdf"
- [(set (reg:CC 24)
- (compare:CC (match_operand:DF 0 "s_register_operand" "")
- (match_operand:DF 1 "fpu_rhs_operand" "")))]
- ""
- "
- {
- arm_compare_op0 = operands[0];
- arm_compare_op1 = operands[1];
- arm_compare_fp = 1;
- DONE;
- }
- ")
-
- (define_expand "cmpxf"
- [(set (reg:CC 24)
- (compare:CC (match_operand:XF 0 "s_register_operand" "")
- (match_operand:XF 1 "fpu_rhs_operand" "")))]
- "ENABLE_XF_PATTERNS"
- "
- {
- arm_compare_op0 = operands[0];
- arm_compare_op1 = operands[1];
- arm_compare_fp = 1;
- DONE;
- }
- ")
-
- (define_insn ""
- [(set (match_operand 0 "cc_register" "")
- (compare (match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "arm_add_operand" "rL")))]
- ""
- "*
- if (GET_CODE (operands[2]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[2])))
- return arm_output_asm_insn (\"cmn\\t%1, #%n2\", operands);
- return arm_output_asm_insn (\"cmp\\t%1, %2\", operands);
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (match_operand 0 "cc_register" "")
- (compare (match_operand:SI 1 "s_register_operand" "r")
- (neg:SI (match_operand:SI 2 "s_register_operand" "r"))))]
- ""
- "*
- return arm_output_asm_insn (\"cmn\\t%1, %2\", operands);
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (match_operand 0 "cc_register" "")
- (compare (match_operand:SI 1 "s_register_operand" "r")
- (match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "arm_rhs_operand" "rn")])))]
- ""
- "*
- return output_shift_compare (operands, FALSE);
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (match_operand 0 "cc_register" "")
- (compare (match_operand:SI 1 "s_register_operand" "r")
- (neg:SI (match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "arm_rhs_operand" "rn")]))))]
- ""
- "*
- return output_shift_compare (operands, TRUE);
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CCFP 24)
- (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
- (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
- ""
- "*
- {
- REAL_VALUE_TYPE r;
-
- switch (which_alternative)
- {
- case 0:
- return arm_output_asm_insn (\"cmf\\t%0, %1\", operands);
- case 1:
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
- r = REAL_VALUE_NEGATE (r);
- operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
- return arm_output_asm_insn (\"cnf\\t%0, %1\", operands);
- }
- }
- "
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")])
-
- (define_insn ""
- [(set (reg:CCFP 24)
- (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
- (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
- ""
- "*
- {
- REAL_VALUE_TYPE r;
-
- switch (which_alternative)
- {
- case 0:
- return arm_output_asm_insn (\"cmf\\t%0, %1\", operands);
- case 1:
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
- r = REAL_VALUE_NEGATE (r);
- operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
- return arm_output_asm_insn (\"cnf\\t%0, %1\", operands);
- }
- }
- "
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")])
-
- (define_insn ""
- [(set (reg:CCFP 24)
- (compare:CCFP (float_extend:DF
- (match_operand:SF 0 "s_register_operand" "f,f"))
- (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
- ""
- "*
- {
- REAL_VALUE_TYPE r;
-
- switch (which_alternative)
- {
- case 0:
- return arm_output_asm_insn (\"cmf\\t%0, %1\", operands);
- case 1:
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
- r = REAL_VALUE_NEGATE (r);
- operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
- return arm_output_asm_insn (\"cnf\\t%0, %1\", operands);
- }
- }
- "
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")])
-
- (define_insn ""
- [(set (reg:CCFP 24)
- (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
- (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))))]
- ""
- "*
- return arm_output_asm_insn (\"cmf\\t%0, %1\", operands);
- "
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")])
-
- (define_insn ""
- [(set (reg:CCFP 24)
- (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
- (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
- "ENABLE_XF_PATTERNS"
- "*
- {
- REAL_VALUE_TYPE r;
-
- switch (which_alternative)
- {
- case 0:
- return arm_output_asm_insn (\"cmf\\t%0, %1\", operands);
- case 1:
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
- r = REAL_VALUE_NEGATE (r);
- operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
- return arm_output_asm_insn (\"cnf\\t%0, %1\", operands);
- }
- }
- "
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")])
-
- (define_insn ""
- [(set (reg:CCFPE 24)
- (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
- (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
- ""
- "*
- {
- REAL_VALUE_TYPE r;
-
- switch (which_alternative)
- {
- case 0:
- return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands);
- case 1:
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
- r = REAL_VALUE_NEGATE (r);
- operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
- return arm_output_asm_insn (\"cnfe\\t%0, %1\", operands);
- }
- }
- "
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")])
-
- (define_insn ""
- [(set (reg:CCFPE 24)
- (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
- (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
- ""
- "*
- {
- REAL_VALUE_TYPE r;
-
- switch (which_alternative)
- {
- case 0:
- return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands);
- case 1:
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
- r = REAL_VALUE_NEGATE (r);
- operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
- return arm_output_asm_insn (\"cnfe\\t%0, %1\", operands);
- }
- }
- "
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")])
-
- (define_insn ""
- [(set (reg:CCFPE 24)
- (compare:CCFPE (float_extend:DF
- (match_operand:SF 0 "s_register_operand" "f,f"))
- (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
- ""
- "*
- {
- REAL_VALUE_TYPE r;
-
- switch (which_alternative)
- {
- case 0:
- return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands);
- case 1:
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
- r = REAL_VALUE_NEGATE (r);
- operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
- return arm_output_asm_insn (\"cnfe\\t%0, %1\", operands);
- }
- }
- "
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")])
-
- (define_insn ""
- [(set (reg:CCFPE 24)
- (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
- (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))))]
- ""
- "*
- return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands);
- "
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")])
-
- (define_insn ""
- [(set (reg:CCFPE 24)
- (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
- (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
- "ENABLE_XF_PATTERNS"
- "*
- {
- REAL_VALUE_TYPE r;
-
- switch (which_alternative)
- {
- case 0:
- return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands);
- case 1:
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
- r = REAL_VALUE_NEGATE (r);
- operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1]));
- return arm_output_asm_insn (\"cnfe\\t%0, %1\", operands);
- }
- }
- "
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")])
-
- ; This insn allows redundant compares to be removed by cse, nothing should
- ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
- ; is deleted later on. The match_dup will match the mode here, so that
- ; mode changes of the condition codes aren't lost by this even though we don't
- ; specify what they are.
-
- (define_insn ""
- [(set (match_operand 0 "cc_register" "") (match_dup 0))]
- ""
- "\\t@ deleted compare"
- [(set_attr "conds" "set")
- (set_attr "length" "0")])
-
-
- ;; Conditional branch insns
-
- (define_expand "beq"
- [(set (pc)
- (if_then_else (eq (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_expand "bne"
- [(set (pc)
- (if_then_else (ne (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_expand "bgt"
- [(set (pc)
- (if_then_else (gt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_expand "ble"
- [(set (pc)
- (if_then_else (le (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_expand "bge"
- [(set (pc)
- (if_then_else (ge (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_expand "blt"
- [(set (pc)
- (if_then_else (lt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_expand "bgtu"
- [(set (pc)
- (if_then_else (gtu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_expand "bleu"
- [(set (pc)
- (if_then_else (leu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_expand "bgeu"
- [(set (pc)
- (if_then_else (geu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_expand "bltu"
- [(set (pc)
- (if_then_else (ltu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- ;; patterns to match conditional branch insns
-
- (define_insn ""
- [(set (pc)
- (if_then_else (match_operator 1 "comparison_operator"
- [(reg 24) (const_int 0)])
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
- {
- extern int arm_ccfsm_state;
-
- if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
- {
- arm_ccfsm_state += 2;
- return \"\";
- }
- return (arm_output_asm_insn (\"b%d1\\t%l0\", operands));
- }"
- [(set_attr "conds" "use")])
-
- (define_insn ""
- [(set (pc)
- (if_then_else (match_operator 1 "comparison_operator"
- [(reg 24) (const_int 0)])
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*
- {
- extern int arm_ccfsm_state;
-
- if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
- {
- arm_ccfsm_state += 2;
- return \"\";
- }
- return (arm_output_asm_insn (\"b%D1\\t%l0\", operands));
- }"
- [(set_attr "conds" "use")])
-
-
- ; scc insns
-
- (define_expand "seq"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (eq:SI (match_dup 1) (const_int 0)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_expand "sne"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (ne:SI (match_dup 1) (const_int 0)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_expand "sgt"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (gt:SI (match_dup 1) (const_int 0)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_expand "sle"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (le:SI (match_dup 1) (const_int 0)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_expand "sge"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (ge:SI (match_dup 1) (const_int 0)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_expand "slt"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (lt:SI (match_dup 1) (const_int 0)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_expand "sgtu"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (gtu:SI (match_dup 1) (const_int 0)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_expand "sleu"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (leu:SI (match_dup 1) (const_int 0)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_expand "sgeu"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (geu:SI (match_dup 1) (const_int 0)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_expand "sltu"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (ltu:SI (match_dup 1) (const_int 0)))]
- ""
- "
- {
- operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
- arm_compare_fp);
- }
- ")
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (match_operator:SI 1 "comparison_operator" [(reg 24) (const_int 0)]))]
- ""
- "*
- arm_output_asm_insn (\"mov%d1\\t%0, #1\", operands);
- return arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands);
- "
- [(set_attr "conds" "use")
- (set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (neg:SI (match_operator:SI 1 "comparison_operator"
- [(reg 24) (const_int 0)])))]
- ""
- "*
- arm_output_asm_insn (\"mvn%d1\\t%0, #0\", operands);
- return arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands);
- "
- [(set_attr "conds" "use")
- (set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (not:SI (match_operator:SI 1 "comparison_operator"
- [(reg 24) (const_int 0)])))]
- ""
- "*
- arm_output_asm_insn (\"mvn%d1\\t%0, #1\", operands);
- return arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands);
- "
- [(set_attr "conds" "use")
- (set_attr "length" "2")])
-
-
- ;; Jump and linkage insns
-
- (define_insn "jump"
- [(set (pc)
- (label_ref (match_operand 0 "" "")))]
- ""
- "*
- {
- extern int arm_ccfsm_state;
-
- if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
- {
- arm_ccfsm_state += 2;
- return \"\";
- }
- return (arm_output_asm_insn (\"b\\t%l0\", operands));
- }")
-
- (define_expand "call"
- [(parallel [(call (match_operand 0 "memory_operand" "")
- (match_operand 1 "general_operand" ""))
- (clobber (reg:SI 14))])]
- ""
- "")
-
- (define_insn ""
- [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
- (match_operand 1 "" "g"))
- (clobber (reg:SI 14))]
- ""
- "*
- return (output_call (operands));
- "
- [(set (attr "conds")
- (if_then_else (eq_attr "cpu" "arm6")
- (const_string "clob")
- (const_string "nocond")))
- ;; length is worst case, normally it is only two
- (set_attr "length" "3")
- (set_attr "type" "call")])
-
- (define_insn ""
- [(call (mem:SI (match_operand 0 "memory_operand" "m"))
- (match_operand 1 "general_operand" "g"))
- (clobber (reg:SI 14))]
- ""
- "*
- return (output_call_mem (operands));
- "
- [(set (attr "conds")
- (if_then_else (eq_attr "cpu" "arm6")
- (const_string "clob")
- (const_string "nocond")))
- (set_attr "length" "3")
- (set_attr "type" "call")])
-
- (define_expand "call_value"
- [(parallel [(set (match_operand 0 "" "=rf")
- (call (match_operand 1 "memory_operand" "m")
- (match_operand 2 "general_operand" "g")))
- (clobber (reg:SI 14))])]
- ""
- "")
-
- (define_insn ""
- [(set (match_operand 0 "" "=rf")
- (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
- (match_operand 2 "general_operand" "g")))
- (clobber (reg:SI 14))]
- ""
- "*
- return (output_call (&operands[1]));
- "
- [(set (attr "conds")
- (if_then_else (eq_attr "cpu" "arm6")
- (const_string "clob")
- (const_string "nocond")))
- (set_attr "length" "3")
- (set_attr "type" "call")])
-
- (define_insn ""
- [(set (match_operand 0 "" "=rf")
- (call (mem:SI (match_operand 1 "memory_operand" "m"))
- (match_operand 2 "general_operand" "g")))
- (clobber (reg:SI 14))]
- "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
- "*
- return (output_call_mem (&operands[1]));
- "
- [(set (attr "conds")
- (if_then_else (eq_attr "cpu" "arm6")
- (const_string "clob")
- (const_string "nocond")))
- (set_attr "length" "3")
- (set_attr "type" "call")])
-
- ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
- ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
-
- (define_insn ""
- [(call (mem:SI (match_operand:SI 0 "" "i"))
- (match_operand:SI 1 "general_operand" "g"))
- (clobber (reg:SI 14))]
- "GET_CODE (operands[0]) == SYMBOL_REF"
- "*
- return (arm_output_asm_insn (\"bl\\t%a0\", operands));
- "
- [(set (attr "conds")
- (if_then_else (eq_attr "cpu" "arm6")
- (const_string "clob")
- (const_string "nocond")))
- (set_attr "type" "call")])
-
- (define_insn ""
- [(set (match_operand 0 "s_register_operand" "=rf")
- (call (mem:SI (match_operand:SI 1 "" "i"))
- (match_operand:SI 2 "general_operand" "g")))
- (clobber (reg:SI 14))]
- "GET_CODE(operands[1]) == SYMBOL_REF"
- "*
- return (arm_output_asm_insn (\"bl\\t%a1\", operands));
- "
- [(set (attr "conds")
- (if_then_else (eq_attr "cpu" "arm6")
- (const_string "clob")
- (const_string "nocond")))
- (set_attr "type" "call")])
-
- ;; Often the return insn will be the same as loading from memory, so set attr
- (define_insn "return"
- [(return)]
- "USE_RETURN_INSN"
- "*
- {
- extern int arm_ccfsm_state;
-
- if (arm_ccfsm_state == 2)
- {
- arm_ccfsm_state += 2;
- return \"\";
- }
- return output_return_instruction (NULL, TRUE);
- }"
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (pc)
- (if_then_else (match_operator 0 "comparison_operator"
- [(reg 24) (const_int 0)])
- (return)
- (pc)))]
- "USE_RETURN_INSN"
- "*
- {
- extern int arm_ccfsm_state;
-
- if (arm_ccfsm_state == 2)
- {
- arm_ccfsm_state += 2;
- return \"\";
- }
- return output_return_instruction (operands[0], TRUE);
- }"
- [(set_attr "conds" "use")
- (set_attr "type" "load")])
-
- (define_insn ""
- [(set (pc)
- (if_then_else (match_operator 0 "comparison_operator"
- [(reg 24) (const_int 0)])
- (pc)
- (return)))]
- "USE_RETURN_INSN"
- "*
- {
- extern int arm_ccfsm_state;
-
- if (arm_ccfsm_state == 2)
- {
- arm_ccfsm_state += 2;
- return \"\";
- }
- return output_return_instruction
- (gen_rtx (reverse_condition (GET_CODE (operands[0])),
- GET_MODE (operands[0]), XEXP (operands[0], 0),
- XEXP (operands[0], 1)),
- TRUE);
- }"
- [(set_attr "conds" "use")
- (set_attr "type" "load")])
-
- ;; Call subroutine returning any type.
-
- (define_expand "untyped_call"
- [(parallel [(call (match_operand 0 "" "")
- (const_int 0))
- (match_operand 1 "" "")
- (match_operand 2 "" "")])]
- ""
- "
- {
- int i;
-
- emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
-
- for (i = 0; i < XVECLEN (operands[2], 0); i++)
- {
- rtx set = XVECEXP (operands[2], 0, i);
- emit_move_insn (SET_DEST (set), SET_SRC (set));
- }
-
- /* The optimizer does not know that the call sets the function value
- registers we stored in the result block. We avoid problems by
- claiming that all hard registers are used and clobbered at this
- point. */
- emit_insn (gen_blockage ());
-
- DONE;
- }")
-
- ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
- ;; all of memory. This blocks insns from being moved across this point.
-
- (define_insn "blockage"
- [(unspec_volatile [(const_int 0)] 0)]
- ""
- ""
- [(set_attr "length" "0")
- (set_attr "type" "block")])
-
- (define_insn "tablejump"
- [(set (pc)
- (match_operand:SI 0 "s_register_operand" "r"))
- (use (label_ref (match_operand 1 "" "")))]
- ""
- "*
- return arm_output_asm_insn (\"mov\\tpc, %0\\t@ table jump, label %l1\",
- operands);
- ")
-
- (define_insn ""
- [(set (pc)
- (match_operand:SI 0 "memory_operand" "m"))
- (use (label_ref (match_operand 1 "" "")))]
- ""
- "*
- return arm_output_asm_insn (\"ldr\\tpc, %0\\t@ table jump, label %l1\",
- operands);
- "
- [(set_attr "type" "load")])
-
- (define_insn "indirect_jump"
- [(set (pc)
- (match_operand:SI 0 "s_register_operand" "r"))]
- ""
- "*
- return arm_output_asm_insn (\"mov\\tpc, %0\\t@ indirect jump\", operands);
- ")
-
- (define_insn ""
- [(set (pc)
- (match_operand:SI 0 "memory_operand" "m"))]
- ""
- "*
- return arm_output_asm_insn (\"ldr\\tpc, %0\\t@ indirect jump\", operands);
- "
- [(set_attr "type" "load")])
-
- ;; Misc insns
-
- (define_insn "nop"
- [(const_int 0)]
- ""
- "*
- return arm_output_asm_insn (\"mov\\tr0, r0\\t@ nop\", operands);
- ")
-
- ;; Patterns to allow combination of arithmetic, cond code and shifts
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (match_operator:SI 1 "shiftable_operator"
- [(match_operator:SI 3 "shift_operator"
- [(match_operand:SI 4 "s_register_operand" "r")
- (match_operand:SI 5 "nonmemory_operand" "rI")])
- (match_operand:SI 2 "s_register_operand" "r")]))]
- ""
- "*
- return (output_arithmetic_with_shift (operands, TRUE, FALSE));
- ")
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
- [(match_operator:SI 3 "shift_operator"
- [(match_operand:SI 4 "s_register_operand" "r")
- (match_operand:SI 5 "nonmemory_operand" "rI")])
- (match_operand:SI 2 "s_register_operand" "r")])
- (const_int 0)))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
- (match_dup 2)]))]
- ""
- "*
- return (output_arithmetic_with_shift (operands, TRUE, TRUE));
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
- [(match_operator:SI 3 "shift_operator"
- [(match_operand:SI 4 "s_register_operand" "r")
- (match_operand:SI 5 "nonmemory_operand" "rI")])
- (match_operand:SI 2 "s_register_operand" "r")])
- (const_int 0)))
- (clobber (match_scratch:SI 0 "=r"))]
- ""
- "*
- return (output_arithmetic_with_shift (operands, TRUE, TRUE));
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (minus:SI (match_operand:SI 1 "s_register_operand" "r")
- (match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "nonmemory_operand" "rn")])))]
- ""
- "*
- {
- rtx ops[6];
-
- ops[0] = operands[0];
- ops[1] = gen_rtx (MINUS, SImode, operands[1], operands[2]);
- ops[2] = operands[1];
- ops[3] = operands[2];
- ops[4] = operands[3];
- ops[5] = operands[4];
- return output_arithmetic_with_shift (ops, FALSE, FALSE);
- }
- ")
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (minus:SI (match_operand:SI 1 "s_register_operand" "r")
- (match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "nonmemory_operand" "rn")]))
- (const_int 0)))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
- (match_dup 4)])))]
- ""
- "*
- {
- rtx ops[6];
-
- ops[0] = operands[0];
- ops[1] = gen_rtx (MINUS, SImode, operands[1], operands[2]);
- ops[2] = operands[1];
- ops[3] = operands[2];
- ops[4] = operands[3];
- ops[5] = operands[4];
- return output_arithmetic_with_shift (ops, FALSE, TRUE);
- }
- "
- [(set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (minus:SI (match_operand:SI 1 "s_register_operand" "r")
- (match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "nonmemory_operand" "rn")]))
- (const_int 0)))
- (clobber (match_scratch:SI 0 "=r"))]
- ""
- "*
- {
- rtx ops[6];
-
- ops[0] = operands[0];
- ops[1] = gen_rtx (MINUS, SImode, operands[1], operands[2]);
- ops[2] = operands[1];
- ops[3] = operands[2];
- ops[4] = operands[3];
- ops[5] = operands[4];
- return output_arithmetic_with_shift (ops, FALSE, TRUE);
- }
- "
- [(set_attr "conds" "set")])
-
- ;; These variants of the above insns can occur if the first operand is the
- ;; frame pointer and we eliminate that. This is a kludge, but there doesn't
- ;; seem to be a way around it. Most of the predicates have to be null
- ;; because the format can be generated part way through reload, so
- ;; if we don't match it as soon as it becomes available, reload doesn't know
- ;; how to reload pseudos that haven't got hard registers; the constraints will
- ;; sort everything out.
-
- (define_insn ""
- [(set (match_operand:SI 0 "" "=&r")
- (plus:SI (plus:SI (match_operator:SI 5 "shift_operator"
- [(match_operand:SI 3 "" "r")
- (match_operand:SI 4 "" "rn")])
- (match_operand:SI 2 "" "r"))
- (match_operand:SI 1 "const_int_operand" "n")))]
- "reload_in_progress"
- "*
- {
- char instr[100];
- sprintf (instr, \"add\\t%%0, %%2, %%3, %s %%4\",
- shift_instr (GET_CODE (operands[5]), &operands[4]));
- arm_output_asm_insn (instr, operands);
- operands[2] = operands[1];
- operands[1] = operands[0];
- return output_add_immediate (operands);
- }"
- ; we have no idea how long the add_immediate is, it could be up to 4.
- [(set_attr "length" "5")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (plus:SI
- (plus:SI
- (match_operator:SI 5 "shift_operator"
- [(match_operand:SI 3 "" "r")
- (match_operand:SI 4 "" "rn")])
- (match_operand:SI 1 "" "r"))
- (match_operand:SI 2 "const_int_operand" "n"))
- (const_int 0)))
- (set (match_operand:SI 0 "" "=&r")
- (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)])
- (match_dup 1))
- (match_dup 2)))]
- "reload_in_progress"
- "*
- {
- char instr[100];
- sprintf (instr, \"adds\\t%%0, %%0, %%3, %s %%4\",
- shift_instr (GET_CODE (operands[5]), &operands[4]));
- output_add_immediate (operands);
- return arm_output_asm_insn (instr, operands);
- }"
- [(set_attr "conds" "set")
- (set_attr "length" "5")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (plus:SI
- (plus:SI
- (match_operator:SI 5 "shift_operator"
- [(match_operand:SI 3 "" "r")
- (match_operand:SI 4 "" "rn")])
- (match_operand:SI 1 "" "r"))
- (match_operand:SI 2 "const_int_operand" "n"))
- (const_int 0)))
- (clobber (match_scratch:SI 0 "=&r"))]
- "reload_in_progress"
- "*
- {
- char instr[100];
- sprintf (instr, \"adds\\t%%0, %%0, %%3, %s %%4\",
- shift_instr (GET_CODE (operands[5]), &operands[4]));
- output_add_immediate (operands);
- return arm_output_asm_insn (instr, operands);
- }"
- [(set_attr "conds" "set")
- (set_attr "length" "5")])
-
- ;; These are similar, but are needed when the mla pattern contains the
- ;; eliminated register as operand 3.
-
- (define_insn ""
- [(set (match_operand:SI 0 "" "=&r,&r")
- (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r")
- (match_operand:SI 2 "" "r,r"))
- (match_operand:SI 3 "" "r,r"))
- (match_operand:SI 4 "const_int_operand" "n,n")))]
- "reload_in_progress"
- "*
- arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands);
- operands[2] = operands[4];
- operands[1] = operands[0];
- return output_add_immediate (operands);
- "
- [(set_attr "length" "5")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
- (match_operand:SI 3 "" "r")
- (match_operand:SI 4 "" "r"))
- (match_operand:SI 1 "" "r"))
- (match_operand:SI 2 "const_int_operand" "n"))
- (const_int 0)))
- (set (match_operand:SI 0 "" "=&r")
- (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1))
- (match_dup 2)))]
- "reload_in_progress"
- "*
- output_add_immediate (operands);
- return arm_output_asm_insn (\"mlas\\t%0, %3, %4, %0\", operands);
- "
- [(set_attr "length" "5")
- (set_attr "conds" "set")])
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
- (match_operand:SI 3 "" "r")
- (match_operand:SI 4 "" "r"))
- (match_operand:SI 1 "" "r"))
- (match_operand:SI 2 "const_int_operand" "n"))
- (const_int 0)))
- (clobber (match_scratch:SI 0 "=&r"))]
- "reload_in_progress"
- "*
- output_add_immediate (operands);
- return arm_output_asm_insn (\"mlas\\t%0, %3, %4, %0\", operands);
- "
- [(set_attr "length" "5")
- (set_attr "conds" "set")])
-
-
-
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (and:SI (match_operator 1 "comparison_operator"
- [(reg 24) (const_int 0)])
- (match_operand:SI 2 "s_register_operand" "r")))]
- ""
- "*
- arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands);
- return arm_output_asm_insn (\"and%d1\\t%0, %2, #1\", operands);
- "
- [(set_attr "conds" "use")
- (set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (ior:SI (match_operator 2 "comparison_operator"
- [(reg 24) (const_int 0)])
- (match_operand:SI 1 "s_register_operand" "0,?r")))]
- ""
- "*
- if (which_alternative != 0)
- arm_output_asm_insn (\"mov%D2\\t%0, %1\", operands);
- return arm_output_asm_insn (\"orr%d2\\t%0, %1, #1\", operands);
- "
- [(set_attr "conds" "use")
- (set_attr "length" "1,2")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (match_operator 1 "comparison_operator"
- [(match_operand:SI 2 "s_register_operand" "r")
- (match_operand:SI 3 "arm_add_operand" "rL")]))
- (clobber (reg 24))]
- ""
- "*
- if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
- return arm_output_asm_insn (\"mov\\t%0, %2, lsr #31\", operands);
- if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
- {
- arm_output_asm_insn (\"mvn\\t%0, %2\", operands);
- return arm_output_asm_insn (\"mov\\t%0, %0, lsr #31\", operands);
- }
- if (GET_CODE (operands[1]) == NE)
- {
- if (GET_CODE (operands[3]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[3])))
- arm_output_asm_insn (\"adds\\t%0, %2, #%n3\", operands);
- else
- arm_output_asm_insn (\"subs\\t%0, %2, %3\", operands);
- return arm_output_asm_insn (\"movne\\t%0, #1\", operands);
- }
- if (GET_CODE (operands[3]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[3])))
- arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%2, %3\", operands);
- arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands);
- return arm_output_asm_insn (\"mov%d1\\t%0, #1\", operands);
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "3")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=&r")
- (ior:SI (match_operator 1 "comparison_operator"
- [(match_operand:SI 2 "s_register_operand" "r")
- (match_operand:SI 3 "arm_rhs_operand" "rI")])
- (match_operator 4 "comparison_operator"
- [(match_operand:SI 5 "s_register_operand" "r")
- (match_operand:SI 6 "arm_rhs_operand" "rI")])))
- (clobber (reg 24))]
- ""
- "*
- {
- int dominant = comparison_dominates_p (GET_CODE (operands[4]),
- GET_CODE (operands[1]));
-
- arm_output_asm_insn (dominant ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
- operands);
- arm_output_asm_insn (\"mov\\t%0, #0\", operands);
- if (GET_CODE (operands[1]) == GET_CODE (operands[4])
- || comparison_dominates_p (GET_CODE (operands[1]),
- GET_CODE (operands[4]))
- || dominant)
- {
- arm_output_asm_insn (dominant ? \"cmp%D4\\t%2, %3\" : \"cmp%D1\\t%5,%6\",
- operands);
- }
- else
- {
- arm_output_asm_insn (\"mov%d1\\t%0, #1\", operands);
- arm_output_asm_insn (\"cmp\\t%5, %6\", operands);
- }
- return arm_output_asm_insn (dominant ? \"mov%d1\\t%0, #1\"
- : \"mov%d4\\t%0, #1\", operands);
- }
- "
- [(set_attr "conds" "clob")
- ; worst case length
- (set_attr "length" "5")])
-
- (define_split
- [(set (pc)
- (if_then_else (match_operator 5 "equality_operator"
- [(ior:SI (match_operator 6 "comparison_operator"
- [(match_operand:SI 0 "s_register_operand" "r")
- (match_operand:SI 1 "arm_add_operand" "rL")])
- (match_operator 7 "comparison_operator"
- [(match_operand:SI 2 "s_register_operand" "r")
- (match_operand:SI 3 "arm_add_operand" "rL")]))
- (const_int 0)])
- (label_ref (match_operand 4 "" ""))
- (pc)))
- (clobber (reg 24))]
- "(GET_CODE (operands[6]) == GET_CODE (operands[7])
- || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[7]))
- || comparison_dominates_p (GET_CODE (operands[7]), GET_CODE (operands[6])))"
- [(set (reg:CC 24)
- (compare:CC (ior:CC (match_op_dup 6
- [(match_dup 0) (match_dup 1)])
- (match_op_dup 7
- [(match_dup 2) (match_dup 3)]))
- (const_int 0)))
- (set (pc)
- (if_then_else (match_op_dup 5 [(reg:CC 24) (const_int 0)])
- (label_ref (match_dup 4))
- (pc)))]
- "
- {
- enum rtx_code code = comparison_dominates_p (GET_CODE (operands[6]),
- GET_CODE (operands[7]))
- ? GET_CODE (operands[7]) : GET_CODE (operands[6]);
-
- if (GET_CODE (operands[5]) == NE)
- operands[5] = gen_rtx (code, CCmode,
- XEXP (operands[5], 0), XEXP (operands[5], 1));
- else
- operands[5] = gen_rtx (reverse_condition (code), CCmode,
- XEXP (operands[5], 0), XEXP (operands[5], 1));
- }
- ")
-
- ;; Don't match these patterns if we can use a conditional compare, since they
- ;; tell the final prescan branch elimator code that full branch inlining
- ;; can't be done.
-
- (define_insn ""
- [(set (pc)
- (if_then_else (ne
- (ior:SI (match_operator 5 "comparison_operator"
- [(match_operand:SI 0 "s_register_operand" "r")
- (match_operand:SI 1 "arm_add_operand" "rL")])
- (match_operator 6 "comparison_operator"
- [(match_operand:SI 2 "s_register_operand" "r")
- (match_operand:SI 3 "arm_rhs_operand" "rL")]))
- (const_int 0))
- (label_ref (match_operand 4 "" ""))
- (pc)))
- (clobber (reg 24))]
- "!(GET_CODE (operands[5]) == GET_CODE (operands[6])
- || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[6]))
- || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[5])))"
- "*
- {
- extern int arm_ccfsm_state;
-
- if (GET_CODE (operands[1]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[1])))
- arm_output_asm_insn (\"cmn\\t%0, #%n1\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%0, %1\", operands);
- arm_output_asm_insn (\"b%d5\\t%l4\", operands);
- if (GET_CODE (operands[3]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[3])))
- arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%2, %3\", operands);
- if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
- {
- arm_ccfsm_state += 2;
- return \"\";
- }
- return arm_output_asm_insn (\"b%d6\\t%l4\", operands);
- }"
- [(set_attr "conds" "jump_clob")
- (set_attr "length" "4")])
-
- (define_insn ""
- [(set (reg:CC 24)
- (compare:CC (ior:CC (match_operator 4 "comparison_operator"
- [(match_operand:SI 0 "s_register_operand" "r")
- (match_operand:SI 1 "arm_add_operand" "rL")])
- (match_operator 5 "comparison_operator"
- [(match_operand:SI 2 "s_register_operand" "r")
- (match_operand:SI 3 "arm_add_operand" "rL")]))
- (const_int 0)))]
- "(GET_CODE (operands[4]) == GET_CODE (operands[5])
- || comparison_dominates_p (GET_CODE (operands[4]), GET_CODE (operands[5]))
- || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))"
- "*
- if (comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))
- {
- if (GET_CODE (operands[3]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[3])))
- arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%2, %3\", operands);
- if (GET_CODE (operands[1]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[1])))
- return arm_output_asm_insn (\"cmn%D5\\t%0, #%n1\", operands);
- return arm_output_asm_insn (\"cmp%D5\\t%0, %1\", operands);
- }
- if (GET_CODE (operands[1]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[1])))
- arm_output_asm_insn (\"cmn\\t%0, #%n1\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%0, %1\", operands);
- if (GET_CODE (operands[3]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[3])))
- return arm_output_asm_insn (\"cmn%D4\\t%2, #%n3\", operands);
- return arm_output_asm_insn (\"cmp%D4\\t%2, %3\", operands);
- "
- [(set_attr "conds" "set")
- (set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
- (if_then_else (match_operator 3 "equality_operator"
- [(match_operator 4 "comparison_operator"
- [(reg 24) (const_int 0)])
- (const_int 0)])
- (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
- ""
- "*
- if (GET_CODE (operands[3]) == NE)
- {
- if (which_alternative != 0)
- arm_output_asm_insn (\"mov%d4\\t%0, %1\", operands);
- if (which_alternative != 1)
- arm_output_asm_insn (\"mov%D4\\t%0, %2\", operands);
- return \"\";
- }
- if (which_alternative != 0)
- arm_output_asm_insn (\"mov%D4\\t%0, %1\", operands);
- if (which_alternative != 1)
- arm_output_asm_insn (\"mov%d4\\t%0, %2\", operands);
- return \"\";
- "
- [(set_attr "conds" "use")
- (set_attr "length" "1,1,2")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (match_operator:SI 5 "shiftable_operator"
- [(match_operator:SI 4 "comparison_operator"
- [(match_operand:SI 2 "s_register_operand" "r,r")
- (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
- (match_operand:SI 1 "s_register_operand" "0,?r")]))
- (clobber (reg 24))]
- ""
- "*
- {
- char *instr = arithmetic_instr (operands[5], TRUE);
- char pattern[100];
-
- if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
- {
- sprintf (pattern, \"%s\\t%%0, %%1, %%2, lsr #31\", instr);
- return arm_output_asm_insn (pattern, operands);
- }
- arm_output_asm_insn (\"cmp\\t%2, %3\", operands);
- if (GET_CODE (operands[5]) == AND)
- arm_output_asm_insn (\"mov%D4\\t%0, #0\", operands);
- else if (which_alternative != 0)
- arm_output_asm_insn (\"mov%D4\\t%0, %1\", operands);
- sprintf (pattern, \"%s%%d4\\t%%0, %%1, #1\", instr);
- return arm_output_asm_insn (pattern, operands);
- }
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "3")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
- (match_operator:SI 4 "comparison_operator"
- [(match_operand:SI 2 "s_register_operand" "r,r")
- (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
- (clobber (reg 24))]
- ""
- "*
- arm_output_asm_insn (\"cmp\\t%2, %3\", operands);
- if (which_alternative != 0)
- arm_output_asm_insn (\"mov%D4\\t%0, %1\", operands);
- return arm_output_asm_insn (\"sub%d4\\t%0, %1, #1\", operands);
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2,3")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=&r")
- (and:SI (match_operator 1 "comparison_operator"
- [(match_operand:SI 2 "s_register_operand" "r")
- (match_operand:SI 3 "arm_rhs_operand" "rI")])
- (match_operator 4 "comparison_operator"
- [(match_operand:SI 5 "s_register_operand" "r")
- (match_operand:SI 6 "arm_rhs_operand" "rI")])))
- (clobber (reg 24))]
- ""
- "*
- {
- int dominant =
- comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
- reverse_condition (GET_CODE (operands[4])))
- ? 1
- : comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
- reverse_condition (GET_CODE (operands[1])))
- ? 2 : 0;
- arm_output_asm_insn (dominant == 2 ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
- operands);
- arm_output_asm_insn (\"mov\\t%0, #1\", operands);
- if (GET_CODE (operands[1]) == GET_CODE (operands[4]) || dominant)
- {
- arm_output_asm_insn (dominant == 2 ? \"cmp%d4\\t%2, %3\"
- : \"cmp%d1\\t%5, %6\", operands);
- }
- else
- {
- arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands);
- arm_output_asm_insn (\"cmp\\t%5, %6\", operands);
- }
- return arm_output_asm_insn (dominant == 2 ? \"mov%D1\\t%0, #0\"
- : \"mov%D4\\t%0, #0\", operands);
- }
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "5")])
-
- (define_split
- [(set (pc)
- (if_then_else (match_operator 1 "equality_operator"
- [(and:SI (match_operator 2 "comparison_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "arm_add_operand" "rL")])
- (match_operator 0 "comparison_operator"
- [(match_operand:SI 5 "s_register_operand" "r")
- (match_operand:SI 6 "arm_add_operand" "rL")]))
- (const_int 0)])
- (label_ref (match_operand 7 "" ""))
- (pc)))
- (clobber (reg 24))]
- "(GET_CODE (operands[2]) == GET_CODE (operands[0])
- || comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
- reverse_condition (GET_CODE (operands[0])))
- || comparison_dominates_p (reverse_condition (GET_CODE (operands[0])),
- reverse_condition (GET_CODE (operands[2]))))"
- [(set (reg:CC 24)
- (compare:CC (ior:CC (match_op_dup 2
- [(match_dup 3) (match_dup 4)])
- (match_op_dup 0
- [(match_dup 5) (match_dup 6)]))
- (const_int 0)))
- (set (pc)
- (if_then_else (match_op_dup 1 [(reg:CC 24) (const_int 0)])
- (label_ref (match_dup 7))
- (pc)))]
- "
- {
- /* Use DeMorgans law to convert this into an IOR of the inverse conditions
- This is safe since we only do it for integer comparisons. */
- enum rtx_code code =
- comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
- reverse_condition (GET_CODE (operands[0])))
- ? GET_CODE (operands[0]) : GET_CODE (operands[2]);
-
- operands[2] = gen_rtx (reverse_condition (GET_CODE (operands[2])),
- GET_MODE (operands[2]), operands[3], operands[4]);
- operands[0] = gen_rtx (reverse_condition (GET_CODE (operands[0])),
- GET_MODE (operands[0]), operands[5], operands[6]);
- if (GET_CODE (operands[1]) == NE)
- operands[1] = gen_rtx (code, CCmode,
- XEXP (operands[1], 0), XEXP (operands[1], 1));
- else
- operands[1] = gen_rtx (reverse_condition (code), CCmode,
- XEXP (operands[1], 0), XEXP (operands[1], 1));
- }
- ")
-
- ;; Don't match these patterns if we can use a conditional compare, since they
- ;; tell the final prescan branch elimator code that full branch inlining
- ;; can't be done.
-
- (define_insn ""
- [(set (pc)
- (if_then_else (eq
- (and:SI (match_operator 1 "comparison_operator"
- [(match_operand:SI 2 "s_register_operand" "r")
- (match_operand:SI 3 "arm_add_operand" "rL")])
- (match_operator 4 "comparison_operator"
- [(match_operand:SI 5 "s_register_operand" "r")
- (match_operand:SI 6 "arm_rhs_operand" "rL")]))
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))
- (clobber (reg 24))]
- "!(GET_CODE (operands[1]) == GET_CODE (operands[4])
- || comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
- reverse_condition (GET_CODE (operands[4])))
- || comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
- reverse_condition (GET_CODE (operands[1]))))"
- "*
- {
- extern int arm_ccfsm_state;
-
- if (GET_CODE (operands[3]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[3])))
- arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%2, %3\", operands);
- arm_output_asm_insn (\"b%D1\\t%l0\", operands);
- if (GET_CODE (operands[6]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[6])))
- arm_output_asm_insn (\"cmn\\t%5, #%n6\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%5, %6\", operands);
- if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
- {
- arm_ccfsm_state += 2;
- return \"\";
- }
- return arm_output_asm_insn (\"b%D4\\t%l0\", operands);
- }"
- [(set_attr "conds" "jump_clob")
- (set_attr "length" "4")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (neg:SI (match_operator 3 "comparison_operator"
- [(match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "arm_rhs_operand" "rI")])))
- (clobber (reg 24))]
- ""
- "*
- if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
- return arm_output_asm_insn (\"mov\\t%0, %1, asr #31\", operands);
- if (GET_CODE (operands[3]) == NE)
- {
- arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
- return arm_output_asm_insn (\"mvnne\\t%0, #0\", operands);
- }
- if (GET_CODE (operands[3]) == GT)
- {
- arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
- return arm_output_asm_insn (\"mvnne\\t%0, %0, asr #31\", operands);
- }
- arm_output_asm_insn (\"cmp\\t%1, %2\", operands);
- arm_output_asm_insn (\"mov%D3\\t%0, #0\", operands);
- return arm_output_asm_insn (\"mvn%d3\\t%0, #0\", operands);
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "3")])
-
- (define_insn "movcond"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
- (if_then_else:SI (match_operator 5 "comparison_operator"
- [(match_operand:SI 3 "s_register_operand" "r,r,r")
- (match_operand:SI 4 "arm_add_operand" "rL,rL,rL")])
- (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
- (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
- (clobber (reg 24))]
- ""
- "*
- if (GET_CODE (operands[5]) == LT
- && (operands[4] == const0_rtx))
- {
- if (which_alternative != 1 && GET_CODE (operands[4]) == REG)
- {
- arm_output_asm_insn (\"ands\\t%0, %1, %3, asr #32\", operands);
- if (operands[2] == const0_rtx)
- return \"\";
- return arm_output_asm_insn (\"movcc\\t%0, %2\", operands);
- }
- else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
- {
- arm_output_asm_insn (\"bics\\t%0, %2, %3, asr #32\", operands);
- if (operands[1] == const0_rtx)
- return \"\";
- return arm_output_asm_insn (\"movcs\\t%0, %1\", operands);
- }
- /* The only case that falls through to here is when both ops 1 & 2
- are constants */
- }
- if (GET_CODE (operands[5]) == GE
- && (operands[4] == const0_rtx))
- {
- if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
- {
- arm_output_asm_insn (\"bics\\t%0, %1, %3, asr #32\", operands);
- if (operands[2] == const0_rtx)
- return \"\";
- return arm_output_asm_insn (\"movcs\\t%0, %2\", operands);
- }
- else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
- {
- arm_output_asm_insn (\"ands\\t%0, %2, %3, asr #32\", operands);
- if (operands[1] == const0_rtx)
- return \"\";
- return arm_output_asm_insn (\"movcc\\t%0, %1\", operands);
- }
- /* The only case that falls through to here is when both ops 1 & 2
- are constants */
- }
- if (GET_CODE (operands[4]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[4])))
- arm_output_asm_insn (\"cmn\\t%3, #%n4\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%3, %4\", operands);
- if (which_alternative != 0)
- arm_output_asm_insn (\"mov%d5\\t%0, %1\", operands);
- if (which_alternative != 1)
- arm_output_asm_insn (\"mov%D5\\t%0, %2\", operands);
- return \"\";
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2,2,3")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (if_then_else:SI (match_operator 9 "comparison_operator"
- [(match_operand:SI 5 "s_register_operand" "r")
- (match_operand:SI 6 "arm_add_operand" "rL")])
- (match_operator:SI 8 "shiftable_operator"
- [(match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "arm_rhs_operand" "rI")])
- (match_operator:SI 7 "shiftable_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "arm_rhs_operand" "rI")])))
- (clobber (reg 24))]
- ""
- "*
- {
- char pattern[100];
-
- if (GET_CODE (operands[6]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[6])))
- arm_output_asm_insn (\"cmn\\t%5, #%n6\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%5, %6\", operands);
- sprintf (pattern, \"%s%%d9\\t%%0, %%1, %%2\", arithmetic_instr (operands[8],
- FALSE));
- arm_output_asm_insn (pattern, operands);
- sprintf (pattern, \"%s%%D9\\t%%0, %%3, %%4\", arithmetic_instr (operands[7],
- FALSE));
- return arm_output_asm_insn (pattern, operands);
- }
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "3")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (if_then_else:SI (match_operator 6 "comparison_operator"
- [(match_operand:SI 2 "s_register_operand" "r,r")
- (match_operand:SI 3 "arm_add_operand" "rL,rL")])
- (match_operator:SI 7 "shiftable_operator"
- [(match_operand:SI 4 "s_register_operand" "r,r")
- (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
- (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
- (clobber (reg 24))]
- ""
- "*
- {
- char pattern[100];
-
- /* If we have an operation where (op x 0) is the identity operation and
- the condtional operator is LT or GE and we are comparing against zero and
- everything is in registers then we can do this in two instructions */
- if (operands[3] == const0_rtx
- && GET_CODE (operands[7]) != AND
- && GET_CODE (operands[5]) == REG
- && GET_CODE (operands[1]) == REG
- && REGNO (operands[1]) == REGNO (operands[4])
- && REGNO (operands[4]) != REGNO (operands[0]))
- {
- if (GET_CODE (operands[6]) == LT)
- {
- arm_output_asm_insn (\"and\\t%0, %5, %2, asr #31\", operands);
- sprintf (pattern, \"%s\\t%%0, %%4, %%0\",
- arithmetic_instr (operands[7], FALSE));
- return arm_output_asm_insn (pattern, operands);
- }
- else if (GET_CODE (operands[6]) == GE)
- {
- arm_output_asm_insn (\"bic\\t%0, %5, %2, asr #31\", operands);
- sprintf (pattern, \"%s\\t%%0, %%4, %%0\",
- arithmetic_instr (operands[7], FALSE));
- return arm_output_asm_insn (pattern, operands);
- }
- }
- if (GET_CODE (operands[3]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[3])))
- arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%2, %3\", operands);
- sprintf (pattern, \"%s%%d6\\t%%0, %%4, %%5\", arithmetic_instr (operands[7],
- FALSE));
- arm_output_asm_insn (pattern, operands);
- if (which_alternative != 0)
- {
- if (GET_CODE (operands[1]) == MEM)
- arm_output_asm_insn (\"ldr%D6\\t%0, %1\", operands);
- else
- arm_output_asm_insn (\"mov%D6\\t%0, %1\", operands);
- }
- return \"\";
- }
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2,3")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (if_then_else:SI (match_operator 6 "comparison_operator"
- [(match_operand:SI 4 "s_register_operand" "r,r")
- (match_operand:SI 5 "arm_add_operand" "rL,rL")])
- (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
- (match_operator:SI 7 "shiftable_operator"
- [(match_operand:SI 2 "s_register_operand" "r,r")
- (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
- (clobber (reg 24))]
- ""
- "*
- {
- char pattern[100];
-
- /* If we have an operation where (op x 0) is the identity operation and
- the condtional operator is LT or GE and we are comparing against zero and
- everything is in registers then we can do this in two instructions */
- if (operands[5] == const0_rtx
- && GET_CODE (operands[7]) != AND
- && GET_CODE (operands[3]) == REG
- && GET_CODE (operands[1]) == REG
- && REGNO (operands[1]) == REGNO (operands[2])
- && REGNO (operands[2]) != REGNO (operands[0]))
- {
- if (GET_CODE (operands[6]) == GE)
- {
- arm_output_asm_insn (\"and\\t%0, %3, %4, asr #31\", operands);
- sprintf (pattern, \"%s\\t%%0, %%2, %%0\",
- arithmetic_instr (operands[7], FALSE));
- return arm_output_asm_insn (pattern, operands);
- }
- else if (GET_CODE (operands[6]) == LT)
- {
- arm_output_asm_insn (\"bic\\t%0, %3, %4, asr #31\", operands);
- sprintf (pattern, \"%s\\t%%0, %%2, %%0\",
- arithmetic_instr (operands[7], FALSE));
- return arm_output_asm_insn (pattern, operands);
- }
- }
- if (GET_CODE (operands[5]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[5])))
- arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%4, %5\", operands);
- if (which_alternative != 0)
- {
- if (GET_CODE (operands[1]) == MEM)
- arm_output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
- else
- arm_output_asm_insn (\"mov%d6\\t%0, %1\", operands);
- }
- sprintf (pattern, \"%s%%D6\\t%%0, %%2, %%3\", arithmetic_instr (operands[7],
- FALSE));
- return arm_output_asm_insn (pattern, operands);
- }
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2,3")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (if_then_else:SI (match_operator 6 "comparison_operator"
- [(match_operand:SI 4 "s_register_operand" "r,r")
- (match_operand:SI 5 "arm_add_operand" "rL,rL")])
- (plus:SI
- (match_operand:SI 2 "s_register_operand" "r,r")
- (match_operand:SI 3 "arm_add_operand" "rL,rL"))
- (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
- (clobber (reg 24))]
- ""
- "*
- {
- if (GET_CODE (operands[5]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[5])))
- arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%4, %5\", operands);
- if (GET_CODE (operands[3]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[3])))
- arm_output_asm_insn (\"sub%d6\\t%0, %2, #%n3\", operands);
- else
- arm_output_asm_insn (\"add%d6\\t%0, %2, %3\", operands);
- if (which_alternative != 0)
- {
- if (GET_CODE (operands[1]) == MEM)
- arm_output_asm_insn (\"ldr%D6\\t%0, %1\", operands);
- else
- arm_output_asm_insn (\"mov%D6\\t%0, %1\", operands);
- }
- return \"\";
- }
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2,3")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (if_then_else:SI (match_operator 6 "comparison_operator"
- [(match_operand:SI 4 "s_register_operand" "r,r")
- (match_operand:SI 5 "arm_add_operand" "rL,rL")])
- (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
- (plus:SI
- (match_operand:SI 2 "s_register_operand" "r,r")
- (match_operand:SI 3 "arm_add_operand" "rL,rL"))))
- (clobber (reg 24))]
- ""
- "*
- {
- if (GET_CODE (operands[5]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[5])))
- arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%4, %5\", operands);
- if (GET_CODE (operands[3]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[3])))
- arm_output_asm_insn (\"sub%D6\\t%0, %2, #%n3\", operands);
- else
- arm_output_asm_insn (\"add%D6\\t%0, %2, %3\", operands);
- if (which_alternative != 0)
- {
- if (GET_CODE (operands[6]) == MEM)
- arm_output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
- else
- arm_output_asm_insn (\"mov%d6\\t%0, %1\", operands);
- }
- return \"\";
- }
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2,3")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (if_then_else:SI (match_operator 5 "comparison_operator"
- [(match_operand:SI 3 "s_register_operand" "r,r")
- (match_operand:SI 4 "arm_add_operand" "rL,rL")])
- (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
- (not:SI
- (match_operand:SI 2 "s_register_operand" "r,r"))))
- (clobber (reg 24))]
- ""
- "#"
- [(set_attr "conds" "clob")
- (set_attr "length" "2,3")])
-
- ;; if (GET_CODE (operands[3]) == CONST_INT
- ;; && !const_ok_for_arm (INTVAL (operands[3])))
- ;; arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands);
- ;; else
- ;; arm_output_asm_insn (\"cmp\\t%2, %3\", operands);
- ;; if (which_alternative != 0)
- ;; arm_output_asm_insn (\"mov%d1\\t%0, %4\", operands);
- ;; return arm_output_asm_insn (\"mvn%D1\\t%0, %5\", operands);
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (if_then_else:SI (match_operator 5 "comparison_operator"
- [(match_operand:SI 3 "s_register_operand" "r,r")
- (match_operand:SI 4 "arm_add_operand" "rL,rL")])
- (not:SI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
- (clobber (reg 24))]
- ""
- "*
- {
- char pattern[100];
-
- if (GET_CODE (operands[30]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[4])))
- arm_output_asm_insn (\"cmn\\t%3, #%n4\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%3, %4\", operands);
- if (which_alternative != 0)
- arm_output_asm_insn (\"mov%D5\\t%0, %1\", operands);
- return arm_output_asm_insn (\"mvn%d5\\t%0, %2\", operands);
-
- }
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2,3")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (if_then_else:SI (match_operator 6 "comparison_operator"
- [(match_operand:SI 4 "s_register_operand" "r,r")
- (match_operand:SI 5 "arm_add_operand" "rL,rL")])
- (match_operator:SI 7 "shift_operator"
- [(match_operand:SI 2 "s_register_operand" "r,r")
- (match_operand:SI 3 "arm_rhs_operand" "rn,rn")])
- (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
- (clobber (reg 24))]
- ""
- "*
- {
- char pattern[100];
-
- if (GET_CODE (operands[5]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[5])))
- arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%4, %5\", operands);
- if (which_alternative != 0)
- arm_output_asm_insn (\"mov%D6\\t%0, %1\", operands);
- sprintf (pattern, \"mov%%d6\\t%%0, %%2, %s %%3\",
- shift_instr (GET_CODE (operands[7]), &operands[3]));
- return arm_output_asm_insn (pattern, operands);
- }
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2,3")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (if_then_else:SI (match_operator 6 "comparison_operator"
- [(match_operand:SI 4 "s_register_operand" "r,r")
- (match_operand:SI 5 "arm_add_operand" "rL,rL")])
- (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
- (match_operator:SI 7 "shift_operator"
- [(match_operand:SI 2 "s_register_operand" "r,r")
- (match_operand:SI 3 "arm_rhs_operand" "rn,rn")])))
- (clobber (reg 24))]
- ""
- "*
- {
- char pattern[100];
-
- if (GET_CODE (operands[5]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[5])))
- arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%4, %5\", operands);
- if (which_alternative != 0)
- arm_output_asm_insn (\"mov%d6\\t%0, %1\", operands);
- sprintf (pattern, \"mov%%D6\\t%%0, %%2, %s %%3\",
- shift_instr (GET_CODE (operands[7]), &operands[3]));
- return arm_output_asm_insn (pattern, operands);
- }
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2,3")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (if_then_else:SI (match_operator 7 "comparison_operator"
- [(match_operand:SI 5 "s_register_operand" "r")
- (match_operand:SI 6 "arm_add_operand" "rL")])
- (match_operator:SI 8 "shift_operator"
- [(match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "arm_rhs_operand" "rn")])
- (match_operator:SI 9 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "arm_rhs_operand" "rI")])))
- (clobber (reg 24))]
- ""
- "*
- {
- char pattern[100];
-
- if (GET_CODE (operands[6]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[6])))
- arm_output_asm_insn (\"cmn\\t%5, #%n6\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%5, %6\", operands);
- sprintf (pattern, \"mov%%d7\\t%%0, %%1, %s %%2\",
- shift_instr (GET_CODE (operands[8]), &operands[2]));
- arm_output_asm_insn (pattern, operands);
- sprintf (pattern, \"mov%%D7\\t%%0, %%3, %s %%4\",
- shift_instr (GET_CODE (operands[9]), &operands[4]));
- return arm_output_asm_insn (pattern, operands);
- }
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "3")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (if_then_else:SI (match_operator 6 "comparison_operator"
- [(match_operand:SI 4 "s_register_operand" "r")
- (match_operand:SI 5 "arm_add_operand" "rL")])
- (not:SI (match_operand:SI 1 "s_register_operand" "r"))
- (match_operator:SI 7 "shiftable_operator"
- [(match_operand:SI 2 "s_register_operand" "r")
- (match_operand:SI 3 "arm_rhs_operand" "rI")])))
- (clobber (reg 24))]
- ""
- "*
- {
- char pattern[100];
-
- if (GET_CODE (operands[5]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[5])))
- arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%4, %5\", operands);
- arm_output_asm_insn (\"mvn%d6\\t%0, %1\", operands);
- sprintf (pattern, \"%s%%D6\\t%%0, %%2, %%3\", arithmetic_instr (operands[7],
- FALSE));
- return arm_output_asm_insn (pattern, operands);
- }
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "3")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (if_then_else:SI (match_operator 6 "comparison_operator"
- [(match_operand:SI 4 "s_register_operand" "r")
- (match_operand:SI 5 "arm_add_operand" "rL")])
- (match_operator:SI 7 "shiftable_operator"
- [(match_operand:SI 2 "s_register_operand" "r")
- (match_operand:SI 3 "arm_rhs_operand" "rI")])
- (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
- (clobber (reg 24))]
- ""
- "*
- {
- char pattern[100];
-
- if (GET_CODE (operands[5]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[5])))
- arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%4, %5\", operands);
- arm_output_asm_insn (\"mvn%D6\\t%0, %1\", operands);
- sprintf (pattern, \"%s%%d6\\t%%0, %%2, %%3\", arithmetic_instr (operands[7],
- FALSE));
- return arm_output_asm_insn (pattern, operands);
- }
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "3")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (if_then_else:SI (match_operator 5 "comparison_operator"
- [(match_operand:SI 3 "s_register_operand" "r,r")
- (match_operand:SI 4 "arm_add_operand" "rL,rL")])
- (neg:SI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
- (clobber (reg:CC 24))]
- ""
- "*
- if (GET_CODE (operands[4]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[4])))
- arm_output_asm_insn (\"cmn\\t%3, #%n4\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%3, %4\", operands);
- if (which_alternative != 0)
- arm_output_asm_insn (\"mov%D5\\t%0, %1\", operands);
- return arm_output_asm_insn (\"rsb%d5\\t%0, %2, #0\", operands);
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2,3")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (if_then_else:SI (match_operator 5 "comparison_operator"
- [(match_operand:SI 3 "s_register_operand" "r,r")
- (match_operand:SI 4 "arm_add_operand" "rL,rL")])
- (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
- (neg:SI
- (match_operand:SI 2 "s_register_operand" "r,r"))))
- (clobber (reg:CC 24))]
- ""
- "*
- if (GET_CODE (operands[4]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[4])))
- arm_output_asm_insn (\"cmn\\t%3, #%n4\", operands);
- else
- arm_output_asm_insn (\"cmp\\t%3, %4\", operands);
- if (which_alternative != 0)
- arm_output_asm_insn (\"mov%d5\\t%0, %1\", operands);
- return arm_output_asm_insn (\"rsb%D5\\t%0, %2, #0\", operands);
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2,3")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (match_operator:SI 1 "shiftable_operator"
- [(match_operand:SI 2 "memory_operand" "m")
- (match_operand:SI 3 "memory_operand" "m")]))
- (clobber (match_scratch:SI 4 "=r"))]
- "adjacent_mem_locations (operands[2], operands[3])"
- "*
- {
- rtx ldm[3];
- rtx arith[3];
- char pattern[100];
- int val1 = 0, val2 = 0;
-
- sprintf (pattern, \"%s\\t%%0, %%1, %%2\",
- arithmetic_instr (operands[1], FALSE));
- if (REGNO (operands[0]) > REGNO (operands[4]))
- {
- ldm[1] = operands[4];
- ldm[2] = operands[0];
- }
- else
- {
- ldm[1] = operands[0];
- ldm[2] = operands[4];
- }
- if (GET_CODE (XEXP (operands[2], 0)) != REG)
- val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
- if (GET_CODE (XEXP (operands[3], 0)) != REG)
- val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
- arith[0] = operands[0];
- if (val1 < val2)
- {
- arith[1] = ldm[1];
- arith[2] = ldm[2];
- }
- else
- {
- arith[1] = ldm[2];
- arith[2] = ldm[1];
- }
- if (val1 && val2)
- {
- rtx ops[3];
- ldm[0] = ops[0] = operands[4];
- ops[1] = XEXP (XEXP (operands[2], 0), 0);
- ops[2] = XEXP (XEXP (operands[2], 0), 1);
- output_add_immediate (ops);
- if (val1 < val2)
- arm_output_asm_insn (\"ldmia\\t%0, {%1, %2}\", ldm);
- else
- arm_output_asm_insn (\"ldmda\\t%0, {%1, %2}\", ldm);
- }
- else if (val1)
- {
- ldm[0] = XEXP (operands[3], 0);
- if (val1 < val2)
- arm_output_asm_insn (\"ldmda\\t%0, {%1, %2}\", ldm);
- else
- arm_output_asm_insn (\"ldmia\\t%0, {%1, %2}\", ldm);
- }
- else
- {
- ldm[0] = XEXP (operands[2], 0);
- if (val1 < val2)
- arm_output_asm_insn (\"ldmia\\t%0, {%1, %2}\", ldm);
- else
- arm_output_asm_insn (\"ldmda\\t%0, {%1, %2}\", ldm);
- }
- return arm_output_asm_insn (pattern, arith);
- }
- "
- [(set_attr "length" "3")
- (set_attr "type" "load")])
-
- ;; the arm can support extended pre-inc instructions
-
- ;; In all these cases, we use operands 0 and 1 for the register being
- ;; incremented because those are the operands that local-alloc will
- ;; tie and these are the pair most likely to be tieable (and the ones
- ;; that will benefit the most).
-
- ;; We reject the frame pointer if it occurs anywhere in these patterns since
- ;; elimination will cause too many headaches.
-
- (define_insn ""
- [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
- (match_operand:SI 2 "index_operand" "rJ")))
- (match_operand:QI 3 "s_register_operand" "r"))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && (GET_CODE (operands[2]) != REG
- || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
- "*
- return arm_output_asm_insn (\"strb\\t%3, [%0, %2]!\", operands);
- "
- [(set_attr "type" "store1")])
-
- (define_insn ""
- [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
- (match_operand:SI 2 "s_register_operand" "r")))
- (match_operand:QI 3 "s_register_operand" "r"))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (minus:SI (match_dup 1) (match_dup 2)))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && (GET_CODE (operands[2]) != REG
- || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
- "*
- return arm_output_asm_insn (\"strb\\t%3, [%0, -%2]!\", operands);
- "
- [(set_attr "type" "store1")])
-
- (define_insn ""
- [(set (match_operand:QI 3 "s_register_operand" "=r")
- (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
- (match_operand:SI 2 "index_operand" "rJ"))))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && (GET_CODE (operands[2]) != REG
- || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
- "*
- return arm_output_asm_insn (\"ldrb\\t%3, [%0, %2]!\", operands);
- "
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (match_operand:QI 3 "s_register_operand" "=r")
- (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
- (match_operand:SI 2 "s_register_operand" "r"))))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (minus:SI (match_dup 1) (match_dup 2)))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && (GET_CODE (operands[2]) != REG
- || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
- "*
- return arm_output_asm_insn (\"ldrb\\t%3, [%0, -%2]!\", operands);
- "
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (match_operand:SI 3 "s_register_operand" "=r")
- (zero_extend:SI
- (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
- (match_operand:SI 2 "index_operand" "rJ")))))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && (GET_CODE (operands[2]) != REG
- || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
- "*
- return arm_output_asm_insn (\"ldrb\\t%3, [%0, %2]!\\t@ z_extendqisi\",
- operands);
- "
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (match_operand:SI 3 "s_register_operand" "=r")
- (zero_extend:SI
- (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
- (match_operand:SI 2 "s_register_operand" "r")))))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (minus:SI (match_dup 1) (match_dup 2)))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && (GET_CODE (operands[2]) != REG
- || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
- "*
- return arm_output_asm_insn (\"ldrb\\t%3, [%0, -%2]!\\t@ z_extendqisi\",
- operands);
- "
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
- (match_operand:SI 2 "index_operand" "rJ")))
- (match_operand:SI 3 "s_register_operand" "r"))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && (GET_CODE (operands[2]) != REG
- || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
- "*
- return arm_output_asm_insn (\"str\\t%3, [%0, %2]!\", operands);
- "
- [(set_attr "type" "store1")])
-
- (define_insn ""
- [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
- (match_operand:SI 2 "s_register_operand" "r")))
- (match_operand:SI 3 "s_register_operand" "r"))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (minus:SI (match_dup 1) (match_dup 2)))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && (GET_CODE (operands[2]) != REG
- || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
- "*
- return arm_output_asm_insn (\"str\\t%3, [%0, -%2]!\", operands);
- "
- [(set_attr "type" "store1")])
-
- (define_insn ""
- [(set (match_operand:SI 3 "s_register_operand" "=r")
- (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
- (match_operand:SI 2 "index_operand" "rJ"))))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && (GET_CODE (operands[2]) != REG
- || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
- "*
- return arm_output_asm_insn (\"ldr\\t%3, [%0, %2]!\", operands);
- "
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (match_operand:SI 3 "s_register_operand" "=r")
- (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
- (match_operand:SI 2 "s_register_operand" "r"))))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (minus:SI (match_dup 1) (match_dup 2)))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && (GET_CODE (operands[2]) != REG
- || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
- "*
- return arm_output_asm_insn (\"ldr\\t%3, [%0, -%2]!\", operands);
- "
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (match_operand:HI 3 "s_register_operand" "=r")
- (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
- (match_operand:SI 2 "index_operand" "rJ"))))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && (GET_CODE (operands[2]) != REG
- || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
- "*
- return arm_output_asm_insn (\"ldr\\t%3, [%0, %2]!\\t@ loadhi\", operands);
- "
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (match_operand:HI 3 "s_register_operand" "=r")
- (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
- (match_operand:SI 2 "s_register_operand" "r"))))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (minus:SI (match_dup 1) (match_dup 2)))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && (GET_CODE (operands[2]) != REG
- || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
- "*
- return arm_output_asm_insn (\"ldr\\t%3, [%0, -%2]!\\t@ loadhi\", operands);
- "
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "const_shift_operand" "n")])
- (match_operand:SI 1 "s_register_operand" "0")))
- (match_operand:QI 5 "s_register_operand" "r"))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
- (match_dup 1)))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
- "*
- {
- char instr[100];
-
- sprintf (instr, \"strb\\t%%5, [%%0, %%3, %s %%4]!\",
- shift_instr (GET_CODE (operands[2]), &operands[4]));
- return arm_output_asm_insn (instr, operands);
- }
- "
- [(set_attr "type" "store1")])
-
- (define_insn ""
- [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
- (match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "const_shift_operand" "n")])))
- (match_operand:QI 5 "s_register_operand" "r"))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
- (match_dup 4)])))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
- "*
- {
- char instr[100];
-
- sprintf (instr, \"strb\\t%%5, [%%0, -%%3, %s %%4]!\",
- shift_instr (GET_CODE (operands[2]), &operands[4]));
- return arm_output_asm_insn (instr, operands);
- }
- "
- [(set_attr "type" "store1")])
-
- (define_insn ""
- [(set (match_operand:QI 5 "s_register_operand" "=r")
- (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "const_shift_operand" "n")])
- (match_operand:SI 1 "s_register_operand" "0"))))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
- (match_dup 1)))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
- "*
- {
- char instr[100];
-
- sprintf (instr, \"ldrb\\t%%5, [%%0, %%3, %s %%4]!\",
- shift_instr (GET_CODE (operands[2]), &operands[4]));
- return arm_output_asm_insn (instr, operands);
- }
- "
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (match_operand:QI 5 "s_register_operand" "=r")
- (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
- (match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "const_shift_operand" "n")]))))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
- (match_dup 4)])))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
- "*
- {
- char instr[100];
-
- sprintf (instr, \"ldrb\\t%%5, [%%0, -%%3, %s %%4]!\",
- shift_instr (GET_CODE (operands[2]), &operands[4]));
- return arm_output_asm_insn (instr, operands);
- }
- "
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "const_shift_operand" "n")])
- (match_operand:SI 1 "s_register_operand" "0")))
- (match_operand:SI 5 "s_register_operand" "r"))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
- (match_dup 1)))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
- "*
- {
- char instr[100];
-
- sprintf (instr, \"str\\t%%5, [%%0, %%3, %s %%4]!\",
- shift_instr (GET_CODE (operands[2]), &operands[4]));
- return arm_output_asm_insn (instr, operands);
- }
- "
- [(set_attr "type" "store1")])
-
- (define_insn ""
- [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
- (match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "const_shift_operand" "n")])))
- (match_operand:SI 5 "s_register_operand" "r"))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
- (match_dup 4)])))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
- "*
- {
- char instr[100];
-
- sprintf (instr, \"str\\t%%5, [%%0, -%%3, %s %%4]!\",
- shift_instr (GET_CODE (operands[2]), &operands[4]));
- return arm_output_asm_insn (instr, operands);
- }
- "
- [(set_attr "type" "store1")])
-
- (define_insn ""
- [(set (match_operand:SI 5 "s_register_operand" "=r")
- (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "const_shift_operand" "n")])
- (match_operand:SI 1 "s_register_operand" "0"))))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
- (match_dup 1)))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
- "*
- {
- char instr[100];
-
- sprintf (instr, \"ldr\\t%%5, [%%0, %%3, %s %%4]!\",
- shift_instr (GET_CODE (operands[2]), &operands[4]));
- return arm_output_asm_insn (instr, operands);
- }
- "
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (match_operand:SI 5 "s_register_operand" "=r")
- (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
- (match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "const_shift_operand" "n")]))))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
- (match_dup 4)])))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
- "*
- {
- char instr[100];
-
- sprintf (instr, \"ldr\\t%%5, [%%0, -%%3, %s %%4]!\",
- shift_instr (GET_CODE (operands[2]), &operands[4]));
- return arm_output_asm_insn (instr, operands);
- }
- "
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (match_operand:HI 5 "s_register_operand" "=r")
- (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "const_shift_operand" "n")])
- (match_operand:SI 1 "s_register_operand" "0"))))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
- (match_dup 1)))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
- "*
- {
- char instr[100];
-
- sprintf (instr, \"ldr\\t%%5, [%%0, %%3, %s %%4]!\\t@ loadhi\",
- shift_instr (GET_CODE (operands[2]), &operands[4]));
- return arm_output_asm_insn (instr, operands);
- }
- "
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (match_operand:HI 5 "s_register_operand" "=r")
- (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
- (match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "const_shift_operand" "n")]))))
- (set (match_operand:SI 0 "s_register_operand" "=r")
- (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
- (match_dup 4)])))]
- "REGNO (operands[0]) != FRAME_POINTER_REGNUM
- && REGNO (operands[1]) != FRAME_POINTER_REGNUM
- && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
- "*
- {
- char instr[100];
-
- sprintf (instr, \"ldr\\t%%5, [%%0, -%%3, %s %%4]!\\t@ loadhi\",
- shift_instr (GET_CODE (operands[2]), &operands[4]));
- return arm_output_asm_insn (instr, operands);
- }
- "
- [(set_attr "type" "load")])
-
- ; It can also support extended post-inc expressions, but combine doesn't
- ; try these....
- ; It doesn't seem worth adding peepholes for anything but the most common
- ; cases since, unlike combine, the increment must immediately follow the load
- ; for this pattern to match.
- ; When loading we must watch to see that the base register isn't trampled by
- ; the load. In such cases this isn't a post-inc expression.
-
- (define_peephole
- [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
- (match_operand:QI 2 "s_register_operand" "r"))
- (set (match_dup 0)
- (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
- ""
- "*
- return arm_output_asm_insn (\"strb\\t%2, [%0], %1\", operands);
- ")
-
- (define_peephole
- [(set (match_operand:QI 0 "s_register_operand" "=r")
- (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
- (set (match_dup 1)
- (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
- "REGNO(operands[0]) != REGNO(operands[1])
- && (GET_CODE (operands[2]) != REG
- || REGNO(operands[0]) != REGNO (operands[2]))"
- "*
- return arm_output_asm_insn (\"ldrb\\t%0, [%1], %2\", operands);
- ")
-
- (define_peephole
- [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
- (match_operand:SI 2 "s_register_operand" "r"))
- (set (match_dup 0)
- (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
- ""
- "*
- return arm_output_asm_insn (\"str\\t%2, [%0], %1\", operands);
- ")
-
- (define_peephole
- [(set (match_operand:HI 0 "s_register_operand" "=r")
- (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
- (set (match_dup 1)
- (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
- "REGNO(operands[0]) != REGNO(operands[1])
- && (GET_CODE (operands[2]) != REG
- || REGNO(operands[0]) != REGNO (operands[2]))"
- "*
- return arm_output_asm_insn (\"ldr\\t%0, [%1], %2\\t@ loadhi\", operands);
- ")
-
- (define_peephole
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
- (set (match_dup 1)
- (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
- "REGNO(operands[0]) != REGNO(operands[1])
- && (GET_CODE (operands[2]) != REG
- || REGNO(operands[0]) != REGNO (operands[2]))"
- "*
- return arm_output_asm_insn (\"ldr\\t%0, [%1], %2\", operands);
- ")
-
- ; This pattern is never tried by combine, so do it as a peephole
-
- (define_peephole
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (match_operand:SI 1 "s_register_operand" "r"))
- (set (match_operand 2 "cc_register" "")
- (compare (match_dup 1) (const_int 0)))]
- ""
- "*
- return arm_output_asm_insn (\"subs\\t%0, %1, #0\", operands);
- "
- [(set_attr "conds" "set")])
-
- ; Peepholes to spot possible load- and store-multiples, if the ordering is
- ; reversed, check that the memory references aren't volatile.
-
- (define_peephole
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
- (const_int 12))))
- (set (match_operand:SI 2 "s_register_operand" "=r")
- (mem:SI (plus:SI (match_dup 1) (const_int 8))))
- (set (match_operand:SI 3 "s_register_operand" "=r")
- (mem:SI (plus:SI (match_dup 1) (const_int 4))))
- (set (match_operand:SI 4 "s_register_operand" "=r")
- (mem:SI (match_dup 1)))]
- "REGNO (operands[0]) > REGNO (operands[2])
- && REGNO (operands[2]) > REGNO (operands[3])
- && REGNO (operands[3]) > REGNO (operands[4])
- && !(REGNO (operands[1]) == REGNO (operands[0])
- || REGNO (operands[1]) == REGNO (operands[2])
- || REGNO (operands[1]) == REGNO (operands[3])
- || REGNO (operands[1]) == REGNO (operands[4]))
- && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
- && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
- && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
- (prev_nonnote_insn (insn)))))
- && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
- (prev_nonnote_insn
- (prev_nonnote_insn (insn))))))"
- "*
- return arm_output_asm_insn (\"ldmia\\t%1, {%4, %3, %2, %0}\\t@ phole ldm\",
- operands);
- ")
-
- (define_peephole
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
- (const_int 8))))
- (set (match_operand:SI 2 "s_register_operand" "=r")
- (mem:SI (plus:SI (match_dup 1) (const_int 4))))
- (set (match_operand:SI 3 "s_register_operand" "=r")
- (mem:SI (match_dup 1)))]
- "REGNO (operands[0]) > REGNO (operands[2])
- && REGNO (operands[2]) > REGNO (operands[3])
- && !(REGNO (operands[1]) == REGNO (operands[0])
- || REGNO (operands[1]) == REGNO (operands[2])
- || REGNO (operands[1]) == REGNO (operands[3]))
- && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
- && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
- && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
- (prev_nonnote_insn (insn)))))"
- "*
- return arm_output_asm_insn (\"ldmia\\t%1, {%3, %2, %0}\\t@ phole ldm\",
- operands);
- ")
-
- (define_peephole
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
- (const_int 4))))
- (set (match_operand:SI 2 "s_register_operand" "=r")
- (mem:SI (match_dup 1)))]
- "REGNO (operands[0]) > REGNO (operands[2])
- && !(REGNO (operands[1]) == REGNO (operands[0])
- || REGNO (operands[1]) == REGNO (operands[2]))
- && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
- && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))"
- "*
- return arm_output_asm_insn (\"ldmia\\t%1, {%2, %0}\\t@ phole ldm\",
- operands);
- ")
-
- (define_peephole
- [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
- (const_int 12)))
- (match_operand:SI 0 "s_register_operand" "r"))
- (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
- (match_operand:SI 2 "s_register_operand" "r"))
- (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
- (match_operand:SI 3 "s_register_operand" "r"))
- (set (mem:SI (match_dup 1))
- (match_operand:SI 4 "s_register_operand" "r"))]
- "REGNO (operands[0]) > REGNO (operands[2])
- && REGNO (operands[2]) > REGNO (operands[3])
- && REGNO (operands[3]) > REGNO (operands[4])
- && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
- && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
- && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
- (prev_nonnote_insn (insn)))))
- && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
- (prev_nonnote_insn
- (prev_nonnote_insn (insn))))))"
- "*
- return arm_output_asm_insn (\"stmia\\t%1, {%4, %3, %2, %0}\\t@ phole stm\",
- operands);
- ")
-
- (define_peephole
- [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
- (const_int 8)))
- (match_operand:SI 0 "s_register_operand" "r"))
- (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
- (match_operand:SI 2 "s_register_operand" "r"))
- (set (mem:SI (match_dup 1))
- (match_operand:SI 3 "s_register_operand" "r"))]
- "REGNO (operands[0]) > REGNO (operands[2])
- && REGNO (operands[2]) > REGNO (operands[3])
- && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
- && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
- && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
- (prev_nonnote_insn (insn)))))"
- "*
- return arm_output_asm_insn (\"stmia\\t%1, {%3, %2, %0}\\t@ phole stm\",
- operands);
- ")
-
- (define_peephole
- [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
- (const_int 4)))
- (match_operand:SI 0 "s_register_operand" "r"))
- (set (mem:SI (match_dup 1))
- (match_operand:SI 2 "s_register_operand" "r"))]
- "REGNO (operands[0]) > REGNO (operands[2])
- && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
- && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))"
- "*
- return arm_output_asm_insn (\"stmia\\t%1, {%2, %0}\\t@ phole stm\",
- operands);
- ")
-
- ;; A call followed by return can be replaced by restoring the regs and
- ;; jumping to the subroutine, provided we aren't passing the address of
- ;; any of our local variables. If we call alloca then this is unsafe
- ;; since restoring the frame frees the memory, which is not what we want.
- ;; Sometimes the return might have been targeted by the final prescan:
- ;; if so then emit a propper return insn as well.
- ;; Unfortunately, if the frame pointer is required, we don't know if the
- ;; current function has any implicit stack pointer adjustments that will
- ;; be restored by the return: we can't therefore do a tail call.
- ;; Another unfortunate that we can't handle is if current_function_args_size
- ;; is non-zero: in this case elimination of the argument pointer assumed
- ;; that lr was pushed onto the stack, so eliminating upsets the offset
- ;; calculations.
-
- (define_peephole
- [(parallel [(call (mem:SI (match_operand:SI 0 "" "i"))
- (match_operand:SI 1 "general_operand" "g"))
- (clobber (reg:SI 14))])
- (return)]
- "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
- && !get_frame_size () && !current_function_calls_alloca
- && !frame_pointer_needed && !current_function_args_size)"
- "*
- {
- extern rtx arm_target_insn;
- extern int arm_ccfsm_state, arm_current_cc;
-
- if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
- {
- arm_current_cc ^= 1;
- output_return_instruction (NULL, TRUE);
- arm_ccfsm_state = 0;
- arm_target_insn = NULL;
- }
-
- output_return_instruction (NULL, FALSE);
- return (arm_output_asm_insn (\"b\\t%a0\", operands));
- }"
- [(set (attr "conds")
- (if_then_else (eq_attr "cpu" "arm6")
- (const_string "clob")
- (const_string "nocond")))
- (set_attr "length" "2")])
-
- (define_peephole
- [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
- (call (mem:SI (match_operand:SI 1 "" "i"))
- (match_operand:SI 2 "general_operand" "g")))
- (clobber (reg:SI 14))])
- (return)]
- "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
- && !get_frame_size () && !current_function_calls_alloca
- && !frame_pointer_needed && !current_function_args_size)"
- "*
- {
- extern rtx arm_target_insn;
- extern int arm_ccfsm_state, arm_current_cc;
-
- if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
- {
- arm_current_cc ^= 1;
- output_return_instruction (NULL, TRUE);
- arm_ccfsm_state = 0;
- arm_target_insn = NULL;
- }
-
- output_return_instruction (NULL, FALSE);
- return (arm_output_asm_insn (\"b\\t%a1\", operands));
- }"
- [(set (attr "conds")
- (if_then_else (eq_attr "cpu" "arm6")
- (const_string "clob")
- (const_string "nocond")))
- (set_attr "length" "2")])
-
- ;; As above but when this function is not void, we must be returning the
- ;; result of the called subroutine.
-
- (define_peephole
- [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
- (call (mem:SI (match_operand:SI 1 "" "i"))
- (match_operand:SI 2 "general_operand" "g")))
- (clobber (reg:SI 14))])
- (use (match_dup 0))
- (return)]
- "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
- && !get_frame_size () && !current_function_calls_alloca
- && !frame_pointer_needed && !current_function_args_size)"
- "*
- {
- extern rtx arm_target_insn;
- extern int arm_ccfsm_state, arm_current_cc;
-
- if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
- {
- arm_current_cc ^= 1;
- output_return_instruction (NULL, TRUE);
- arm_ccfsm_state = 0;
- arm_target_insn = NULL;
- }
-
- output_return_instruction (NULL, FALSE);
- return (arm_output_asm_insn (\"b\\t%a1\", operands));
- }"
- [(set (attr "conds")
- (if_then_else (eq_attr "cpu" "arm6")
- (const_string "clob")
- (const_string "nocond")))
- (set_attr "length" "2")])
-
- ;; If calling a subroutine and then jumping back to somewhere else, but not
- ;; too far away, then we can set the link register with the branch address
- ;; and jump direct to the subroutine. On return from the subroutine
- ;; execution continues at the branch; this avoids a prefetch stall.
- ;; We use the length attribute (via short_branch ()) to establish whether or
- ;; not this is possible, this is the same asthe sparc does.
-
- (define_peephole
- [(parallel[(call (mem:SI (match_operand:SI 0 "" "i"))
- (match_operand:SI 1 "general_operand" "g"))
- (clobber (reg:SI 14))])
- (set (pc)
- (label_ref (match_operand 2 "" "")))]
- "GET_CODE (operands[0]) == SYMBOL_REF
- && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
- && arm_insn_not_targeted (insn)"
- "*
- {
- int backward = arm_backwards_branch (INSN_UID (insn),
- INSN_UID (operands[2]));
-
- #if 0
- /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
- * above, leaving it out means that the code will still run on an arm 2 or 3
- */
- if (TARGET_6)
- {
- if (backward)
- arm_output_asm_insn (\"sub\\tlr, pc, #(8 + . -%l2)\", operands);
- else
- arm_output_asm_insn (\"add\\tlr, pc, #(%l2 - . -8)\", operands);
- }
- else
- #endif
- {
- arm_output_asm_insn (\"mov\\tlr, pc\\t@ protect cc\");
- if (backward)
- arm_output_asm_insn (\"sub\\tlr, lr, #(4 + . -%l2)\", operands);
- else
- arm_output_asm_insn (\"add\\tlr, lr, #(%l2 - . -4)\", operands);
- }
- return arm_output_asm_insn (\"b\\t%a0\", operands);
- }"
- [(set (attr "conds")
- (if_then_else (eq_attr "cpu" "arm6")
- (const_string "clob")
- (const_string "nocond")))
- (set (attr "length")
- (if_then_else (eq_attr "cpu" "arm6")
- (const_int 2)
- (const_int 3)))])
-
- (define_peephole
- [(parallel[(set (match_operand:SI 0 "s_register_operand" "=r")
- (call (mem:SI (match_operand:SI 1 "" "i"))
- (match_operand:SI 2 "general_operand" "g")))
- (clobber (reg:SI 14))])
- (set (pc)
- (label_ref (match_operand 3 "" "")))]
- "GET_CODE (operands[0]) == SYMBOL_REF
- && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
- && arm_insn_not_targeted (insn)"
- "*
- {
- int backward = arm_backwards_branch (INSN_UID (insn),
- INSN_UID (operands[3]));
-
- #if 0
- /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
- * above, leaving it out means that the code will still run on an arm 2 or 3
- */
- if (TARGET_6)
- {
- if (backward)
- arm_output_asm_insn (\"sub\\tlr, pc, #(8 + . -%l3)\", operands);
- else
- arm_output_asm_insn (\"add\\tlr, pc, #(%l3 - . -8)\", operands);
- }
- else
- #endif
- {
- arm_output_asm_insn (\"mov\\tlr, pc\\t@ protect cc\");
- if (backward)
- arm_output_asm_insn (\"sub\\tlr, lr, #(4 + . -%l3)\", operands);
- else
- arm_output_asm_insn (\"add\\tlr, lr, #(%l3 - . -4)\", operands);
- }
- return arm_output_asm_insn (\"b\\t%a1\", operands);
- }"
- [(set (attr "conds")
- (if_then_else (eq_attr "cpu" "arm6")
- (const_string "clob")
- (const_string "nocond")))
- (set (attr "length")
- (if_then_else (eq_attr "cpu" "arm6")
- (const_int 2)
- (const_int 3)))])
-
- (define_split
- [(set (pc)
- (if_then_else (match_operator 0 "comparison_operator"
- [(match_operator:SI 1 "shift_operator"
- [(match_operand:SI 2 "s_register_operand" "r")
- (match_operand:SI 3 "nonmemory_operand" "rn")])
- (match_operand:SI 4 "s_register_operand" "r")])
- (label_ref (match_operand 5 "" ""))
- (pc)))
- (clobber (reg 24))]
- ""
- [(set (reg:CC 24)
- (compare:CC (match_dup 4)
- (match_op_dup 1 [(match_dup 2) (match_dup 3)])))
- (set (pc)
- (if_then_else (match_op_dup 0 [(reg 24) (const_int 0)])
- (label_ref (match_dup 5))
- (pc)))]
- "
- operands[0] = gen_rtx (swap_condition (GET_CODE (operands[0])), VOIDmode,
- operands[1], operands[2]);
- ")
-
- (define_split
- [(set (match_operand:SI 0 "s_register_operand" "")
- (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
- (const_int 0))
- (neg:SI (match_operator:SI 2 "comparison_operator"
- [(match_operand:SI 3 "s_register_operand" "")
- (match_operand:SI 4 "arm_rhs_operand" "")]))))
- (clobber (match_operand:SI 5 "s_register_operand" ""))]
- ""
- [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
- (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
- (match_dup 5)))]
- "")
-
- ;; This pattern can be used because cc_noov mode implies that the following
- ;; branch will be an equality (EQ or NE), so the sign extension is not
- ;; needed. Combine doesn't eliminate these because by the time it sees the
- ;; branch it no-longer knows that the data came from memory.
-
- (define_insn ""
- [(set (reg:CC_NOOV 24)
- (compare:CC_NOOV
- (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "m") 0)
- (const_int 24))
- (match_operand 1 "immediate_operand" "I")))
- (clobber (match_scratch:SI 2 "=r"))]
- "((unsigned long) INTVAL (operands[1]))
- == (((unsigned long) INTVAL (operands[1])) >> 24) << 24"
- "*
- operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
- arm_output_asm_insn (\"ldrb\\t%2, %0\", operands);
- return arm_output_asm_insn (\"cmp\\t%2, %1\", operands);
- "
- [(set_attr "conds" "set")
- (set_attr "length" "2")
- (set_attr "type" "load")])
-
- (define_expand "save_stack_nonlocal"
- [(match_operand:DI 0 "memory_operand" "")
- (match_operand:SI 1 "s_register_operand" "")]
- ""
- "
- {
- /* We also need to save the frame pointer for non-local gotos */
- emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
- hard_frame_pointer_rtx);
- emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]);
- DONE;
- }")
-
- (define_expand "restore_stack_nonlocal"
- [(match_operand:SI 0 "s_register_operand" "")
- (match_operand:DI 1 "memory_operand" "")]
- ""
- "
- {
- /* Restore the frame pointer first, the stack pointer second. */
- emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode));
- emit_move_insn (hard_frame_pointer_rtx, operand_subword (operands[1], 0, 0,
- DImode));
- DONE;
- }")
-
- ;; This split is only used during output to reduce the number of patterns
- ;; that need assembler instructions adding to them. We allowed the setting
- ;; of the conditions to be implicit during rtl generation so that
- ;; the conditional compare patterns would work. However this conflicts to
- ;; some extend with the conditional data operations, so we have to split them
- ;; up again here.
-
- (define_split
- [(set (match_operand:SI 0 "s_register_operand" "")
- (if_then_else:SI (match_operator 1 "comparison_operator"
- [(match_operand 2 "" "") (match_operand 3 "" "")])
- (match_operand 4 "" "")
- (match_operand 5 "" "")))
- (clobber (reg 24))]
- "reload_completed"
- [(set (match_dup 6) (match_dup 7))
- (set (match_dup 0)
- (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
- (match_dup 4)
- (match_dup 5)))]
- "
- {
- enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2],
- operands[3]);
-
- operands[6] = gen_rtx (REG, mode, 24);
- operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]);
- }
- ")
-
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (if_then_else:SI (match_operator 4 "comparison_operator"
- [(match_operand 3 "cc_register" "") (const_int 0)])
- (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
- (not:SI
- (match_operand:SI 2 "s_register_operand" "r,r"))))]
- ""
- "*
- if (which_alternative != 0)
- arm_output_asm_insn (\"mov%d4\\t%0, %1\", operands);
- return arm_output_asm_insn (\"mvn%D4\\t%0, %2\", operands);
- "
- [(set_attr "conds" "use")
- (set_attr "length" "1,2")])
-
- ;; The next two patterns occur when an AND operation is followed by a
- ;; scc insn sequence
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
- (const_int 1)
- (match_operand:SI 2 "immediate_operand" "n")))]
- ""
- "*
- operands[2] = GEN_INT (1 << INTVAL (operands[2]));
- arm_output_asm_insn (\"ands\\t%0, %1, %2\", operands);
- return arm_output_asm_insn (\"mvnne\\t%0, #0\", operands);
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "2")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (not:SI
- (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
- (const_int 1)
- (match_operand:SI 2 "immediate_operand" "n"))))]
- ""
- "*
- operands[2] = GEN_INT (1 << INTVAL (operands[2]));
- arm_output_asm_insn (\"tst\\t%1, %2\", operands);
- arm_output_asm_insn (\"mvneq\\t%0, #0\", operands);
- return arm_output_asm_insn (\"movne\\t%0, #0\", operands);
- "
- [(set_attr "conds" "clob")
- (set_attr "length" "3")])
-