diff options
Diffstat (limited to 'gcc/config/arm/arm.md')
-rw-r--r-- | gcc/config/arm/arm.md | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 9dee56538e4..3480d959b05 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -69,6 +69,7 @@ ; instructions setting registers for EH handling ; and stack frame generation. Operand 0 is the ; register to "use". + (UNSPEC_CHECK_ARCH 7); Set CCs to indicate 26-bit or 32-bit mode. ] ) @@ -179,7 +180,7 @@ (const_string "normal")) ; Load scheduling, set from the arm_ld_sched variable -; initialised by arm_override_options() +; initialized by arm_override_options() (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched"))) ; condition codes: this one is used by final_prescan_insn to speed up @@ -1837,7 +1838,8 @@ (match_operand:SI 1 "s_register_operand" "r") (match_operand:SI 2 "const_int_operand" "n") (match_operand:SI 3 "const_int_operand" "n")) - (const_int 0)))] + (const_int 0))) + (clobber (reg:CC CC_REGNUM))] "TARGET_ARM && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32 && INTVAL (operands[2]) > 0 @@ -1856,9 +1858,9 @@ ;;; ??? This pattern is bogus. If operand3 has bits outside the range ;;; represented by the bitfield, then this will produce incorrect results. ;;; Somewhere, the value needs to be truncated. On targets like the m68k, -;;; which have a real bitfield insert instruction, the truncation happens -;;; in the bitfield insert instruction itself. Since arm does not have a -;;; bitfield insert instruction, we would have to emit code here to truncate +;;; which have a real bit-field insert instruction, the truncation happens +;;; in the bit-field insert instruction itself. Since arm does not have a +;;; bit-field insert instruction, we would have to emit code here to truncate ;;; the value before we insert. This loses some of the advantage of having ;;; this insv pattern, so this pattern needs to be reevalutated. @@ -1866,7 +1868,7 @@ [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "") (match_operand:SI 1 "general_operand" "") (match_operand:SI 2 "general_operand" "")) - (match_operand:SI 3 "nonmemory_operand" ""))] + (match_operand:SI 3 "reg_or_int_operand" ""))] "TARGET_ARM" " { @@ -3912,7 +3914,7 @@ ;; DONE; ;;}") -;; Recognise garbage generated above. +;; Recognize garbage generated above. ;;(define_insn "" ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m") @@ -4204,7 +4206,7 @@ (use (label_ref (match_operand 1 "" "")))] "TARGET_THUMB && flag_pic" "* - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (operands[1])); return \"add\\t%0, %|pc\"; " @@ -4217,7 +4219,7 @@ (use (label_ref (match_operand 1 "" "")))] "TARGET_ARM && flag_pic" "* - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", + (*targetm.asm_out.internal_label) (asm_out_file, \"L\", CODE_LABEL_NUMBER (operands[1])); return \"add%?\\t%0, %|pc, %0\"; " @@ -4681,7 +4683,7 @@ " ) -;; Pattern to recognise insn generated default case above +;; Pattern to recognize insn generated default case above (define_insn "*movhi_insn_arch4" [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r") (match_operand:HI 1 "general_operand" "rI,K,r,m"))] @@ -6797,6 +6799,33 @@ (set_attr "type" "load")] ) +;; Generate a sequence of instructions to determine if the processor is +;; in 26-bit or 32-bit mode, and return the appropriate return address +;; mask. + +(define_expand "return_addr_mask" + [(set (match_dup 1) + (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH) + (const_int 0))) + (set (match_operand:SI 0 "s_register_operand" "") + (if_then_else:SI (eq (match_dup 1) (const_int 0)) + (const_int -1) + (const_int 67108860)))] ; 0x03fffffc + "TARGET_ARM" + " + operands[1] = gen_rtx_REG (CC_NOOVmode, 24); + ") + +(define_insn "*check_arch2" + [(set (match_operand:CC_NOOV 0 "cc_register" "") + (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH) + (const_int 0)))] + "TARGET_ARM" + "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc" + [(set_attr "length" "8") + (set_attr "conds" "set")] +) + ;; Call subroutine returning any type. (define_expand "untyped_call" @@ -8399,7 +8428,7 @@ ; We must watch to see that the source/destination register isn't also the ; same as the base address register, and that if the index is a register, ; that it is not the same as the base address register. In such cases the -; instruction that we would generate would have UNPREDICTABLE behaviour so +; instruction that we would generate would have UNPREDICTABLE behavior so ; we cannot use it. (define_peephole @@ -8840,7 +8869,8 @@ [(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 "const_int_operand" "n")))] + (match_operand:SI 2 "const_int_operand" "n"))) + (clobber (reg:CC CC_REGNUM))] "TARGET_ARM" "* operands[2] = GEN_INT (1 << INTVAL (operands[2])); @@ -8856,7 +8886,8 @@ (not:SI (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") (const_int 1) - (match_operand:SI 2 "const_int_operand" "n"))))] + (match_operand:SI 2 "const_int_operand" "n")))) + (clobber (reg:CC CC_REGNUM))] "TARGET_ARM" "* operands[2] = GEN_INT (1 << INTVAL (operands[2])); |