[llvm-commits] [llvm-gcc-4.2] r54178 - in /llvm-gcc-4.2/trunk/gcc: config/arm/arm.md config/arm/cirrus.md config/arm/constraints.md config/arm/predicates.md config/i386/i386.md config/i386/sse.md testsuite/g++.dg/ext/interface4.h
Bill Wendling
isanbard at gmail.com
Tue Jul 29 15:54:46 PDT 2008
Author: void
Date: Tue Jul 29 17:54:46 2008
New Revision: 54178
URL: http://llvm.org/viewvc/llvm-project?rev=54178&view=rev
Log:
Merge .md files from Apple GCC's 4.2 branch.
Added:
llvm-gcc-4.2/trunk/gcc/testsuite/g++.dg/ext/interface4.h
Modified:
llvm-gcc-4.2/trunk/gcc/config/arm/arm.md
llvm-gcc-4.2/trunk/gcc/config/arm/cirrus.md
llvm-gcc-4.2/trunk/gcc/config/arm/constraints.md
llvm-gcc-4.2/trunk/gcc/config/arm/predicates.md
llvm-gcc-4.2/trunk/gcc/config/i386/i386.md
llvm-gcc-4.2/trunk/gcc/config/i386/sse.md
Modified: llvm-gcc-4.2/trunk/gcc/config/arm/arm.md
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/arm/arm.md?rev=54178&r1=54177&r2=54178&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/arm/arm.md (original)
+++ llvm-gcc-4.2/trunk/gcc/config/arm/arm.md Tue Jul 29 17:54:46 2008
@@ -95,6 +95,8 @@
; instruction stream.
; APPLE LOCAL ARM setjmp/longjmp interworking
(UNSPEC_JMP_XCHG 22) ; Indirect jump with possible change in ARM/Thumb state.
+ ; APPLE LOCAL ARM UXTB support
+ (UNSPEC_UXTB16 27) ; The UXTB16 instruction (ARM only)
]
)
@@ -127,6 +129,10 @@
(VUNSPEC_WCMP_GT 13) ; Used by the iwMMXT WCMPGT instructions
(VUNSPEC_EH_RETURN 20); Use to override the return address for exception
; handling.
+ ; APPLE LOCAL begin ARM strings in code
+ (VUNSPEC_POOL_STRING 21) ; `pool-entry(string)'. An entry in the constant
+ ; pool for a string.
+ ; APPLE LOCAL end ARM strings in code
]
)
@@ -352,11 +358,12 @@
;; Cirrus 64bit additions should not be split because we have a native
;; 64bit addition instructions.
+;; APPLE LOCAL begin 5831562 long long constants
(define_expand "adddi3"
[(parallel
[(set (match_operand:DI 0 "s_register_operand" "")
(plus:DI (match_operand:DI 1 "s_register_operand" "")
- (match_operand:DI 2 "s_register_operand" "")))
+ (match_operand:DI 2 "arm_add64_operand" "")))
(clobber (reg:CC CC_REGNUM))])]
"TARGET_EITHER"
"
@@ -377,8 +384,19 @@
if (GET_CODE (operands[2]) != REG)
operands[2] = force_reg (SImode, operands[2]);
}
+
+ if (TARGET_ARM
+ && (GET_CODE (operands[2]) == CONST_INT
+ || GET_CODE (operands[2]) == CONST_DOUBLE)
+ && !const64_ok_for_arm_immediate (operands[2]))
+ {
+ emit_insn (gen_subdi3 (operands[0], operands[1],
+ negate_rtx (DImode, operands[2])));
+ DONE;
+ }
"
)
+;; APPLE LOCAL end 5831562 long long constants
(define_insn "*thumb_adddi3"
[(set (match_operand:DI 0 "register_operand" "=l")
@@ -391,10 +409,11 @@
[(set_attr "length" "4")]
)
+;; APPLE LOCAL begin 5831562 long long constants
(define_insn_and_split "*arm_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")))
+ [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r")
+ (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0")
+ (match_operand:DI 2 "arm_rhs64_operand" "r, 0, Dd,Dd")))
(clobber (reg:CC CC_REGNUM))]
"TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
"#"
@@ -411,12 +430,13 @@
operands[0] = gen_lowpart (SImode, operands[0]);
operands[4] = gen_highpart (SImode, operands[1]);
operands[1] = gen_lowpart (SImode, operands[1]);
- operands[5] = gen_highpart (SImode, operands[2]);
+ operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
operands[2] = gen_lowpart (SImode, operands[2]);
}"
[(set_attr "conds" "clob")
(set_attr "length" "8")]
)
+;; APPLE LOCAL end 5831562 long long constants
(define_insn_and_split "*adddi_sesidi_di"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
@@ -573,6 +593,22 @@
""
)
+;; APPLE LOCAL begin ARM peephole
+;; And sometimes greg will generate the same thing this way...
+
+(define_peephole2
+ [(set (match_operand:SI 0 "arm_general_register_operand" "")
+ (reg:SI SP_REGNUM))
+ (set (match_dup 0)
+ (plus:SI (match_dup 0) (match_operand:SI 1 "const_int_operand" "")))]
+ "TARGET_THUMB
+ && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
+ && (INTVAL (operands[1]) & 3) == 0"
+ [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))]
+ ""
+)
+;; APPLE LOCAL end ARM peephole
+
(define_insn "*addsi3_compare0"
[(set (reg:CC_NOOV CC_REGNUM)
(compare:CC_NOOV
@@ -830,11 +866,12 @@
operands[2] = force_reg (DFmode, operands[2]);
")
+;; APPLE LOCAL begin 5831562 long long constants
(define_expand "subdi3"
[(parallel
[(set (match_operand:DI 0 "s_register_operand" "")
(minus:DI (match_operand:DI 1 "s_register_operand" "")
- (match_operand:DI 2 "s_register_operand" "")))
+ (match_operand:DI 2 "arm_add64_operand" "")))
(clobber (reg:CC CC_REGNUM))])]
"TARGET_EITHER"
"
@@ -854,19 +891,38 @@
if (GET_CODE (operands[2]) != REG)
operands[2] = force_reg (SImode, operands[2]);
}
- "
+
+ if (TARGET_ARM
+ && (GET_CODE (operands[2]) == CONST_INT
+ || GET_CODE (operands[2]) == CONST_DOUBLE)
+ && !const64_ok_for_arm_immediate (operands[2]))
+ {
+ emit_insn (gen_adddi3 (operands[0], operands[1],
+ negate_rtx (DImode, operands[2])));
+ DONE;
+ }
+ "
)
(define_insn "*arm_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")))
+ [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
+ (minus:DI (match_operand:DI 1 "s_register_operand" "0, r, 0, r ,0")
+ (match_operand:DI 2 "arm_rhs64_operand" "r, 0, 0,Dd,Dd")))
(clobber (reg:CC CC_REGNUM))]
"TARGET_ARM"
- "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
+ "*
+ if (which_alternative <= 2)
+ return \"subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2\";
+ else
+ {
+ operands[3] = gen_lowpart (SImode, operands[2]);
+ operands[2] = gen_highpart_mode (SImode, DImode, operands[2]);
+ return \"subs\\t%Q0, %Q1, %3\;sbc\\t%R0, %R1, %2\";
+ }"
[(set_attr "conds" "clob")
(set_attr "length" "8")]
)
+;; APPLE LOCAL end 5831562 long long constants
(define_insn "*thumb_subdi3"
[(set (match_operand:DI 0 "register_operand" "=l")
@@ -1336,6 +1392,57 @@
[(set_attr "insn" "smlalxy")
(set_attr "predicable" "yes")])
+;; APPLE LOCAL begin DImode multiply enhancement
+;; No DI * DI instruction exists (except on Cirrus), but leave this in
+;; the RTL stream through the early optimization phases
+;; to give them a chance to generate the mulsidi3, etc., patterns.
+
+(define_expand "muldi3"
+ [(parallel
+ [(set (match_operand:DI 0 "s_register_operand" "")
+ (mult:DI (match_operand:DI 1 "s_register_operand" "")
+ (match_operand:DI 2 "s_register_operand" "")))
+ (clobber (match_scratch:SI 3 ""))
+ (clobber (match_scratch:SI 4 ""))])]
+ "TARGET_ARM"
+ "
+ if (TARGET_HARD_FLOAT && TARGET_MAVERICK)
+ {
+ if (!cirrus_fp_register (operands[0], DImode))
+ operands[0] = force_reg (DImode, operands[0]);
+ if (!cirrus_fp_register (operands[1], DImode))
+ operands[1] = force_reg (DImode, operands[1]);
+ emit_insn (gen_cirrus_muldi3 (operands[0], operands[1], operands[2]));
+ DONE;
+ }
+ "
+)
+
+; Input and output registers cannot overlap in this pattern.
+
+(define_insn_and_split "*soft_muldi3"
+ [(set (match_operand:DI 0 "s_register_operand" "=&r")
+ (mult:DI (match_operand:DI 1 "s_register_operand" "%0")
+ (match_operand:DI 2 "s_register_operand" "r")))
+ (clobber (match_scratch:SI 3 "=&r"))
+ (clobber (match_scratch:SI 4 "=&r"))]
+ "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
+ ""
+ "&& reload_completed"
+ [(set (match_dup 3) (subreg:SI (match_dup 1) 0))
+ (set (match_dup 4) (subreg:SI (match_dup 1) 4))
+ (set (match_dup 0) (mult:DI (zero_extend:DI (match_dup 3))
+ (zero_extend:DI (subreg:SI (match_dup 2) 0))))
+ (set (subreg:SI (match_dup 0) 4) (plus:SI
+ (mult:SI (match_dup 4) (subreg:SI (match_dup 2) 0))
+ (subreg:SI (match_dup 0) 4)))
+ (set (subreg:SI (match_dup 0) 4) (plus:SI
+ (mult:SI (match_dup 3) (subreg:SI (match_dup 2) 4))
+ (subreg:SI (match_dup 0) 4)))]
+ ""
+)
+;; APPLE LOCAL end DImode multiply enhancement
+
(define_expand "mulsf3"
[(set (match_operand:SF 0 "s_register_operand" "")
(mult:SF (match_operand:SF 1 "s_register_operand" "")
@@ -1394,13 +1501,14 @@
;; Split up double word logical operations
+;; APPLE LOCAL begin 5831562 long long constants
;; Split up simple DImode logical operations. Simply perform the logical
;; operation on the upper and lower halves of the registers.
(define_split
[(set (match_operand:DI 0 "s_register_operand" "")
(match_operator:DI 6 "logical_binary_operator"
[(match_operand:DI 1 "s_register_operand" "")
- (match_operand:DI 2 "s_register_operand" "")]))]
+ (match_operand:DI 2 "arm_rhs64_operand" "")]))]
"TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
[(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
(set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
@@ -1410,10 +1518,11 @@
operands[0] = gen_lowpart (SImode, operands[0]);
operands[4] = gen_highpart (SImode, operands[1]);
operands[1] = gen_lowpart (SImode, operands[1]);
- operands[5] = gen_highpart (SImode, operands[2]);
+ operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
operands[2] = gen_lowpart (SImode, operands[2]);
}"
)
+;; APPLE LOCAL end 5831562 long long constants
(define_split
[(set (match_operand:DI 0 "s_register_operand" "")
@@ -1474,14 +1583,17 @@
}"
)
+;; APPLE LOCAL begin 5831562 long long constants
(define_insn "anddi3"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (match_operand:DI 1 "s_register_operand" "%0,r")
- (match_operand:DI 2 "s_register_operand" "r,r")))]
+ [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r")
+ (and:DI (match_operand:DI 1 "s_register_operand" "%0,r, 0, r")
+ (match_operand:DI 2 "arm_rhs64_operand" "r,r,Dd,Dd")))]
"TARGET_ARM && ! TARGET_IWMMXT"
"#"
- [(set_attr "length" "8")]
+ [(set_attr "length" "8")
+ (set_attr "predicable" "yes")]
)
+;; APPLE LOCAL end 5831562 long long constants
(define_insn_and_split "*anddi_zesidi_di"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
@@ -1576,28 +1688,19 @@
"
)
-(define_insn_and_split "*arm_andsi3_insn"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
- (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
- (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
+;; APPLE LOCAL begin ARM 4673027 suboptimal loop codegen
+(define_insn "*arm_andsi3_insn"
+ [(set (match_operand:SI 0 "s_register_operand" "=r,r")
+ (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
+ (match_operand:SI 2 "arm_not_operand" "rI,K")))]
"TARGET_ARM"
"@
and%?\\t%0, %1, %2
- bic%?\\t%0, %1, #%B2
- #"
- "TARGET_ARM
- && GET_CODE (operands[2]) == CONST_INT
- && !(const_ok_for_arm (INTVAL (operands[2]))
- || const_ok_for_arm (~INTVAL (operands[2])))"
- [(clobber (const_int 0))]
- "
- arm_split_constant (AND, SImode, curr_insn,
- INTVAL (operands[2]), operands[0], operands[1], 0);
- DONE;
- "
- [(set_attr "length" "4,4,16")
+ bic%?\\t%0, %1, #%B2"
+ [(set_attr "length" "4,4")
(set_attr "predicable" "yes")]
)
+;; APPLE LOCAL end ARM 4673027 suboptimal loop codegen
(define_insn "*thumb_andsi3_insn"
[(set (match_operand:SI 0 "register_operand" "=l")
@@ -1867,21 +1970,22 @@
;;; 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.
+;;; APPLE LOCAL begin ARM insv for Thumb
(define_expand "insv"
[(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 "reg_or_int_operand" ""))]
- "TARGET_ARM"
+ "TARGET_EITHER"
"
{
int start_bit = INTVAL (operands[2]);
int width = INTVAL (operands[1]);
HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
- rtx target, subtarget;
+ rtx target, subtarget, orig_target;
- target = operands[0];
+ target = orig_target = operands[0];
/* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
subreg as the final target. */
if (GET_CODE (target) == SUBREG)
@@ -1912,7 +2016,8 @@
emit_insn (gen_iorsi3 (subtarget, op1,
gen_int_mode (op3_value << start_bit, SImode)));
}
- else if (start_bit == 0
+ else if (TARGET_ARM
+ && start_bit == 0
&& !(const_ok_for_arm (mask)
|| const_ok_for_arm (~mask)))
{
@@ -1925,21 +2030,24 @@
rtx op0 = gen_reg_rtx (SImode);
rtx op1 = gen_reg_rtx (SImode);
- emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
+ emit_insn (gen_ashlsi3 (op0, operands[3],
+ gen_int_mode (32 - width, SImode)));
emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
emit_insn (gen_iorsi3 (op1, op1, op0));
emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
}
- else if ((width + start_bit == 32)
- && !(const_ok_for_arm (mask)
- || const_ok_for_arm (~mask)))
+ else if (width + start_bit == 32
+ && (TARGET_THUMB
+ || !(const_ok_for_arm (mask)
+ || const_ok_for_arm (~mask))))
{
/* Similar trick, but slightly less efficient. */
rtx op0 = gen_reg_rtx (SImode);
rtx op1 = gen_reg_rtx (SImode);
- emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
+ emit_insn (gen_ashlsi3 (op0, operands[3],
+ gen_int_mode (32 - width, SImode)));
emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
emit_insn (gen_iorsi3 (subtarget, op1, op0));
@@ -1950,7 +2058,8 @@
rtx op1 = gen_reg_rtx (SImode);
rtx op2 = gen_reg_rtx (SImode);
- if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
+ if (TARGET_THUMB
+ || !(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
{
rtx tmp = gen_reg_rtx (SImode);
@@ -1959,6 +2068,7 @@
}
/* Mask out any bits in operand[3] that are not needed. */
+ if (!TARGET_THUMB)
emit_insn (gen_andsi3 (op1, operands[3], op0));
if (GET_CODE (op0) == CONST_INT
@@ -1984,9 +2094,33 @@
emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
}
- if (start_bit != 0)
+ if (!TARGET_THUMB && start_bit != 0)
emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
+ /* The default code uses AND with constant which is an extra insn on thumb. */
+ if (TARGET_THUMB)
+ {
+ /* If we only want a low subreg, we don't need to worry about
+ bits beyond that. */
+ if (GET_CODE (orig_target) == SUBREG
+ && SUBREG_BYTE (orig_target) == 0
+ && GET_MODE_SIZE (GET_MODE (SUBREG_REG (orig_target)))
+ < GET_MODE_SIZE (SImode)
+ && width + start_bit
+ >= GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (orig_target))))
+ emit_insn (gen_ashlsi3 (op1, operands[3],
+ gen_int_mode (start_bit, SImode)));
+ else
+ {
+ /* Mask unneeded bits in operand[3], and simultaneously move
+ input to the right place in the word. */
+ emit_insn (gen_ashlsi3 (op1, operands[3],
+ gen_int_mode (32 - width, SImode)));
+ emit_insn (gen_lshrsi3 (op1, op1,
+ gen_int_mode (32 - width - start_bit, SImode)));
+ }
+ }
+
emit_insn (gen_iorsi3 (subtarget, op1, op2));
}
@@ -2003,6 +2137,7 @@
DONE;
}"
)
+;;; APPLE LOCAL end ARM insv for Thumb
; constants for op 2 will never be given to these patterns.
(define_insn_and_split "*anddi_notdi_di"
@@ -2135,15 +2270,17 @@
[(set_attr "conds" "set")]
)
+;; APPLE LOCAL begin 5831562 long long constants
(define_insn "iordi3"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (match_operand:DI 1 "s_register_operand" "%0,r")
- (match_operand:DI 2 "s_register_operand" "r,r")))]
+ [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r")
+ (ior:DI (match_operand:DI 1 "s_register_operand" "%0,r, 0, r")
+ (match_operand:DI 2 "arm_rhs64_operand" "r,r,Dd,Dd")))]
"TARGET_ARM && ! TARGET_IWMMXT"
"#"
[(set_attr "length" "8")
(set_attr "predicable" "yes")]
)
+;; APPLE LOCAL end 5831562 long long constants
(define_insn "*iordi_zesidi_di"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
@@ -2190,26 +2327,17 @@
"
)
-(define_insn_and_split "*arm_iorsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r")
- (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
- (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
+;; APPLE LOCAL begin ARM 4673027 suboptimal loop codegen
+(define_insn "*arm_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")))]
"TARGET_ARM"
- "@
- orr%?\\t%0, %1, %2
- #"
- "TARGET_ARM
- && GET_CODE (operands[2]) == CONST_INT
- && !const_ok_for_arm (INTVAL (operands[2]))"
- [(clobber (const_int 0))]
- "
- arm_split_constant (IOR, SImode, curr_insn,
- INTVAL (operands[2]), operands[0], operands[1], 0);
- DONE;
- "
- [(set_attr "length" "4,16")
+ "orr%?\\t%0, %1, %2"
+ [(set_attr "length" "4")
(set_attr "predicable" "yes")]
)
+;; APPLE LOCAL end ARM 4673027 suboptimal loop codegen
(define_insn "*thumb_iorsi3"
[(set (match_operand:SI 0 "register_operand" "=l")
@@ -2256,15 +2384,17 @@
[(set_attr "conds" "set")]
)
+;; APPLE LOCAL begin 5831562 long long constants
(define_insn "xordi3"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (xor:DI (match_operand:DI 1 "s_register_operand" "%0,r")
- (match_operand:DI 2 "s_register_operand" "r,r")))]
+ [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r")
+ (xor:DI (match_operand:DI 1 "s_register_operand" "%0,r, 0, r")
+ (match_operand:DI 2 "arm_rhs64_operand" "r,r,Dd,Dd")))]
"TARGET_ARM && !TARGET_IWMMXT"
"#"
[(set_attr "length" "8")
(set_attr "predicable" "yes")]
)
+;; APPLE LOCAL end 5831562 long long constants
(define_insn "*xordi_zesidi_di"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
@@ -3335,7 +3465,8 @@
}"
)
-(define_insn "*thumb_zero_extendhisi2"
+;; APPLE LOCAL ARM compact switch tables
+(define_insn "adjustable_thumb_zero_extendhisi2"
[(set (match_operand:SI 0 "register_operand" "=l")
(zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
"TARGET_THUMB && !arm_arch6"
@@ -3377,7 +3508,8 @@
(set_attr "pool_range" "60")]
)
-(define_insn "*thumb_zero_extendhisi2_v6"
+;; APPLE LOCAL ARM compact switch tables
+(define_insn "adjustable_thumb_zero_extendhisi2_v6"
[(set (match_operand:SI 0 "register_operand" "=l,l")
(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
"TARGET_THUMB && arm_arch6"
@@ -3694,7 +3826,8 @@
;; we try to verify the operands. Fortunately, we don't really need
;; the early-clobber: we can always use operand 0 if operand 2
;; overlaps the address.
-(define_insn "*thumb_extendhisi2_insn_v6"
+;; APPLE LOCAL ARM compact switch tables
+(define_insn "adjustable_thumb_extendhisi2_insn_v6"
[(set (match_operand:SI 0 "register_operand" "=l,l")
(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))
(clobber (match_scratch:SI 2 "=X,l"))]
@@ -3925,7 +4058,8 @@
(set_attr "predicable" "yes")]
)
-(define_insn "*thumb_extendqisi2"
+;; APPLE LOCAL ARM compact switch tables
+(define_insn "adjustable_thumb_extendqisi2"
[(set (match_operand:SI 0 "register_operand" "=l,l")
(sign_extend:SI (match_operand:QI 1 "memory_operand" "V,m")))]
"TARGET_THUMB && !arm_arch6"
@@ -4003,7 +4137,8 @@
(set_attr "pool_range" "32,32")]
)
-(define_insn "*thumb_extendqisi2_v6"
+;; APPLE LOCAL ARM compact switch tables
+(define_insn "adjustable_thumb_extendqisi2_v6"
[(set (match_operand:SI 0 "register_operand" "=l,l,l")
(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
"TARGET_THUMB && arm_arch6"
@@ -4218,12 +4353,14 @@
; offsets in a LDR which means we get better chances of sharing the pool
; entries. Finally, we can normally do a better job of scheduling
; LDR instructions than we can with LDM.
-; This pattern will only match if the one above did not.
+;; APPLE LOCAL begin ARM split 64-bit constants on Thumb
+; On ARM, This pattern will only match if the one above did not.
+; On Thumb, use this form always; don't try to do inline expansions.
(define_split
[(set (match_operand:ANY64 0 "arm_general_register_operand" "")
(match_operand:ANY64 1 "const_double_operand" ""))]
- "TARGET_ARM && reload_completed
- && arm_const_double_by_parts (operands[1])"
+ "TARGET_EITHER && reload_completed
+ && (TARGET_THUMB || arm_const_double_by_parts (operands[1]))"
[(set (match_dup 0) (match_dup 1))
(set (match_dup 2) (match_dup 3))]
"
@@ -4234,6 +4371,7 @@
operands[1] = gen_lowpart (SImode, operands[1]);
"
)
+;; APPLE LOCAL end ARM split 64-bit constants on Thumb
(define_split
[(set (match_operand:ANY64 0 "arm_general_register_operand" "")
@@ -4281,11 +4419,12 @@
"
)
+;; APPLE LOCAL begin compact switch tables
;;; ??? This should have alternatives for constants.
;;; ??? This was originally identical to the movdf_insn pattern.
;;; ??? The 'i' constraint looks funny, but it should always be replaced by
;;; thumb_reorg with a memory reference.
-(define_insn "*thumb_movdi_insn"
+(define_insn "adjustable_thumb_movdi_insn"
[(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
(match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))]
"TARGET_THUMB
@@ -4323,10 +4462,11 @@
return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
}
}"
- [(set_attr "length" "4,4,6,2,2,6,4,4")
+ [(set_attr "length" "4,4,6,2,2,4,4,4")
(set_attr "type" "*,*,*,load2,store2,load2,store2,*")
- (set_attr "pool_range" "*,*,*,*,*,1020,*,*")]
+ (set_attr "pool_range" "*,*,*,*,*,1018,*,*")]
)
+;; APPLE LOCAL end compact switch tables
(define_expand "movsi"
[(set (match_operand:SI 0 "general_operand" "")
@@ -4506,7 +4646,7 @@
"TARGET_THUMB && (flag_pic || (TARGET_MACHO && MACHO_DYNAMIC_NO_PIC_P))"
"ldr\\t%0, %1"
[(set_attr "type" "load1")
- (set (attr "pool_range") (const_int 1024))
+ (set (attr "pool_range") (const_int 1022))
(set_attr "length" "2")]
)
;; APPLE LOCAL end ARM pic support
@@ -4520,6 +4660,7 @@
"operands[2] = cfun->machine->pic_reg;"
)
+;; APPLE LOCAL begin ARM compact switch tables
(define_insn "*pic_load_addr_based_insn"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(unspec:SI [(match_operand 1 "" "")
@@ -4536,13 +4677,18 @@
[(set_attr "type" "load1")
(set (attr "pool_range")
(if_then_else (eq_attr "is_thumb" "yes")
- (const_int 1024)
+ (const_int 1020)
(const_int 4096)))
(set (attr "neg_pool_range")
(if_then_else (eq_attr "is_thumb" "yes")
(const_int 0)
- (const_int 4084)))]
+ (const_int 4084)))
+ (set (attr "length")
+ (if_then_else (eq_attr "is_thumb" "yes")
+ (const_int 2)
+ (const_int 4)))]
)
+;; APPLE LOCAL end ARM compact switch tables
;; APPLE LOCAL begin ARM pic support
(define_insn "pic_add_dot_plus_four"
@@ -4611,6 +4757,42 @@
""
)
+;; APPLE LOCAL begin ARM 4224487
+;; These short forms work for addresses of scalar globals. They
+;; are produced by combine. There is no Thumb counterpart, as
+;; [Rn+PC] is not a valid addressing mode on Thumb.
+
+(define_insn "*arm_pic_ldrsi"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mem:SI (unspec:SI [(label_ref (match_operand 1 "" ""))
+ (plus:SI (match_operand:SI 2 "register_operand" "r")
+ (const (plus:SI (pc) (const_int 8))))]
+ UNSPEC_PIC_BASE)))]
+ "TARGET_ARM && (flag_pic || (TARGET_MACHO && MACHO_DYNAMIC_NO_PIC_P))"
+ "*
+ (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
+ CODE_LABEL_NUMBER (operands[1]));
+ return \"ldr%?\\t%0, [%|pc, %2]\";
+ "
+ [(set_attr "predicable" "yes")]
+)
+
+(define_insn "*arm_pic_strsi"
+ [(set (mem:SI (unspec:SI [(label_ref (match_operand 1 "" ""))
+ (plus:SI (match_operand:SI 2 "register_operand" "r")
+ (const (plus:SI (pc) (const_int 8))))]
+ UNSPEC_PIC_BASE))
+ (match_operand:SI 0 "register_operand" "r"))]
+ "TARGET_ARM && (flag_pic || (TARGET_MACHO && MACHO_DYNAMIC_NO_PIC_P))"
+ "*
+ (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
+ CODE_LABEL_NUMBER (operands[1]));
+ return \"str%?\\t%0, [%|pc, %2]\";
+ "
+ [(set_attr "predicable" "yes")]
+)
+;; APPLE LOCAL end ARM 4224487
+
;; APPLE LOCAL begin ARM setjmp/longjmp interworking
;; If we'll be returning to thumb code, we need to set the low-order
;; bit of the resume address. builtin_setjmp_setup doesn't handle all
@@ -4979,7 +5161,8 @@
"
)
-(define_insn "*thumb_movhi_insn"
+;; APPLE LOCAL ARM compact switch tables
+(define_insn "adjustable_thumb_movhi_insn"
[(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
(match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))]
"TARGET_THUMB
@@ -5409,6 +5592,7 @@
(set_attr "neg_pool_range" "1008")]
)
+;; APPLE LOCAL begin ARM compact switch tables
;;; ??? This should have alternatives for constants.
;;; ??? This was originally identical to the movdi_insn pattern.
;;; ??? The 'F' constraint looks funny, but it should always be replaced by
@@ -5444,10 +5628,11 @@
return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
}
"
- [(set_attr "length" "4,2,2,6,4,4")
+ [(set_attr "length" "4,2,2,4,4,4")
(set_attr "type" "*,load2,store2,load2,store2,*")
- (set_attr "pool_range" "*,*,*,1020,*,*")]
+ (set_attr "pool_range" "*,*,*,1018,*,*")]
)
+;; APPLE LOCAL end ARM compact switch tables
(define_expand "movxf"
[(set (match_operand:XF 0 "general_operand" "")
@@ -5531,6 +5716,7 @@
(set_attr "predicable" "yes")]
)
+;; APPLE LOCAL begin ARM compact switch tables
(define_insn "*ldmsi_postinc4_thumb"
[(match_parallel 0 "load_multiple_operation"
[(set (match_operand:SI 1 "s_register_operand" "=l")
@@ -5546,8 +5732,10 @@
(mem:SI (plus:SI (match_dup 2) (const_int 12))))])]
"TARGET_THUMB && XVECLEN (operands[0], 0) == 5"
"ldmia\\t%1!, {%3, %4, %5, %6}"
- [(set_attr "type" "load4")]
+ [(set_attr "type" "load4")
+ (set_attr "length" "2")]
)
+;; APPLE LOCAL end ARM compact switch tables
(define_insn "*ldmsi_postinc3"
[(match_parallel 0 "load_multiple_operation"
@@ -5670,6 +5858,7 @@
(set_attr "type" "store4")]
)
+;; APPLE LOCAL begin ARM compact switch tables
(define_insn "*stmsi_postinc4_thumb"
[(match_parallel 0 "store_multiple_operation"
[(set (match_operand:SI 1 "s_register_operand" "=l")
@@ -5685,8 +5874,10 @@
(match_operand:SI 6 "arm_hard_register_operand" ""))])]
"TARGET_THUMB && XVECLEN (operands[0], 0) == 5"
"stmia\\t%1!, {%3, %4, %5, %6}"
- [(set_attr "type" "store4")]
+ [(set_attr "type" "store4")
+ (set_attr "length" "2")]
)
+;; APPLE LOCAL end ARM compact switch tables
(define_insn "*stmsi_postinc3"
[(match_parallel 0 "store_multiple_operation"
@@ -5787,6 +5978,17 @@
|| INTVAL (operands[2]) > 48)
FAIL;
+ /* APPLE LOCAL begin ARM use memcpy more at -Os */
+ if (optimize_size
+ && INTVAL (operands[2]) != 1
+ && INTVAL (operands[2]) != 2
+ && INTVAL (operands[2]) != 4
+ && INTVAL (operands[2]) != 8
+ && INTVAL (operands[2]) != 12
+ && INTVAL (operands[2]) != 16)
+ FAIL;
+ /* APPLE LOCAL end ARM use memcpy more at -Os */
+
thumb_expand_movmemqi (operands);
DONE;
}
@@ -6013,6 +6215,32 @@
(const_int 10)))))]
)
+;; APPLE LOCAL begin ARM add this peephole
+;; The above pattern is produced by combine in some cases, but not
+;; when one of the regs involved is hard, e.g. a function return value.
+;; This peephole catches that case. Valid only for low regs.
+
+(define_peephole2
+ [(set (match_operand:SI 0 "thumb_low_register_operand" "")
+ (match_operand:SI 1 "thumb_low_register_operand" ""))
+ (set (pc) (if_then_else
+ (match_operator 2 "arm_comparison_operator"
+ [(match_dup 0) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_THUMB"
+ [(parallel
+ [(set (pc)
+ (if_then_else
+ (match_op_dup 2
+ [(match_dup 1) (const_int 0)])
+ (label_ref (match_dup 3 ))
+ (pc)))
+ (set (match_dup 0) (match_dup 1))])]
+ ""
+)
+;; APPLE LOCAL end ARM add this peephole
+
(define_insn "*negated_cbranchsi4"
[(set (pc)
(if_then_else
@@ -6998,6 +7226,7 @@
"
)
+;; APPLE LOCAL begin ARM enhance conditional insn generation
(define_insn "*arm_cmpsi_insn"
[(set (reg:CC CC_REGNUM)
(compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
@@ -7006,8 +7235,10 @@
"@
cmp%?\\t%0, %1
cmn%?\\t%0, #%n1"
- [(set_attr "conds" "set")]
+ [(set_attr "conds" "set")
+ (set_attr "predicable" "yes")]
)
+;; APPLE LOCAL end ARM enhance conditional insn generation
(define_insn "*cmpsi_shiftsi"
[(set (reg:CC CC_REGNUM)
@@ -7715,16 +7946,16 @@
rtx callee;
/* APPLE LOCAL begin ARM dynamic */
-#if TARGET_MACHO
- if (MACHOPIC_INDIRECT)
- operands[0] = machopic_indirect_call_target (operands[0]);
-#endif
- /* APPLE LOCAL end ARM dynamic */
-
/* In an untyped call, we can get NULL for operand 2. */
if (operands[2] == NULL_RTX)
operands[2] = const0_rtx;
+#if TARGET_MACHO
+ if (MACHOPIC_INDIRECT
+ && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 0))
+ operands[0] = machopic_indirect_call_target (operands[0]);
+#endif
+
/* This is to decide if we should generate indirect calls by loading the
32 bit address of the callee into a register before performing the
branch and link. operand[2] encodes the long_call/short_call
@@ -7736,6 +7967,7 @@
parameter to arm_is_longcall_p is used to tell it which pattern
invoked it. */
callee = XEXP (operands[0], 0);
+ /* APPLE LOCAL end ARM dynamic */
if ((GET_CODE (callee) == SYMBOL_REF
&& arm_is_longcall_p (operands[0], INTVAL (operands[2]), 0))
@@ -7745,6 +7977,7 @@
}"
)
+;; APPLE LOCAL begin 5831528 make calls predicable
(define_insn "*call_reg_armv5"
[(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
(match_operand 1 "" ""))
@@ -7752,7 +7985,8 @@
(clobber (reg:SI LR_REGNUM))]
"TARGET_ARM && arm_arch5"
"blx%?\\t%0"
- [(set_attr "type" "call")]
+ [(set_attr "type" "call")
+ (set_attr "predicable" "yes")]
)
(define_insn "*call_reg_arm"
@@ -7766,7 +8000,8 @@
"
;; length is worst case, normally it is only two
[(set_attr "length" "12")
- (set_attr "type" "call")]
+ (set_attr "type" "call")
+ (set_attr "predicable" "yes")]
)
(define_insn "*call_mem"
@@ -7779,7 +8014,8 @@
return output_call_mem (operands);
"
[(set_attr "length" "12")
- (set_attr "type" "call")]
+ (set_attr "type" "call")
+ (set_attr "predicable" "yes")]
)
(define_insn "*call_reg_thumb_v5"
@@ -7825,18 +8061,19 @@
/* APPLE LOCAL begin ARM dynamic */
rtx callee;
+ /* In an untyped call, we can get NULL for operand 2. */
+ if (operands[3] == 0)
+ operands[3] = const0_rtx;
+
#if TARGET_MACHO
- if (MACHOPIC_INDIRECT)
+ if (MACHOPIC_INDIRECT
+ && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 0))
operands[1] = machopic_indirect_call_target (operands[1]);
#endif
callee = XEXP (operands[1], 0);
/* APPLE LOCAL end ARM dynamic */
- /* In an untyped call, we can get NULL for operand 2. */
- if (operands[3] == 0)
- operands[3] = const0_rtx;
-
/* See the comment in define_expand \"call\". */
if ((GET_CODE (callee) == SYMBOL_REF
&& arm_is_longcall_p (operands[1], INTVAL (operands[3]), 0))
@@ -7854,7 +8091,8 @@
(clobber (reg:SI LR_REGNUM))]
"TARGET_ARM && arm_arch5"
"blx%?\\t%1"
- [(set_attr "type" "call")]
+ [(set_attr "type" "call")
+ (set_attr "predicable" "yes")]
)
(define_insn "*call_value_reg_arm"
@@ -7868,7 +8106,8 @@
return output_call (&operands[1]);
"
[(set_attr "length" "12")
- (set_attr "type" "call")]
+ (set_attr "type" "call")
+ (set_attr "predicable" "yes")]
)
(define_insn "*call_value_mem"
@@ -7882,7 +8121,8 @@
return output_call_mem (&operands[1]);
"
[(set_attr "length" "12")
- (set_attr "type" "call")]
+ (set_attr "type" "call")
+ (set_attr "predicable" "yes")]
)
(define_insn "*call_value_reg_thumb_v5"
@@ -7927,12 +8167,30 @@
;; of questionnable value, as these patterns are not generally used
;; for dynamic code anyway (see rdar://4514281 for an example of what it
;; takes to get here).
-(define_insn "*call_symbol"
+(define_insn "*call_symbol_predicable"
[(call (mem:SI (match_operand:SI 0 "arm_branch_target" ""))
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))
(clobber (reg:SI LR_REGNUM))]
"TARGET_ARM
+ && !TARGET_INTERWORK
+ && (GET_CODE (operands[0]) == SYMBOL_REF)
+ && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
+ "*
+ {
+ return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
+ }"
+ [(set_attr "type" "call")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*call_symbol"
+ [(call (mem:SI (match_operand:SI 0 "arm_branch_target" ""))
+ (match_operand 1 "" ""))
+ (use (match_operand 2 "" ""))
+ (clobber (reg:SI LR_REGNUM))]
+ "TARGET_ARM
+ && TARGET_INTERWORK
&& (GET_CODE (operands[0]) == SYMBOL_REF)
&& !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
"*
@@ -7942,13 +8200,32 @@
[(set_attr "type" "call")]
)
-(define_insn "*call_value_symbol"
+(define_insn "*call_value_symbol_predicable"
[(set (match_operand 0 "" "")
(call (mem:SI (match_operand:SI 1 "arm_branch_target" ""))
(match_operand:SI 2 "" "")))
(use (match_operand 3 "" ""))
(clobber (reg:SI LR_REGNUM))]
"TARGET_ARM
+ && !TARGET_INTERWORK
+ && (GET_CODE (operands[1]) == SYMBOL_REF)
+ && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
+ "*
+ {
+ return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
+ }"
+ [(set_attr "type" "call")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*call_value_symbol"
+ [(set (match_operand 0 "" "")
+ (call (mem:SI (match_operand:SI 1 "arm_branch_target" ""))
+ (match_operand:SI 2 "" "")))
+ (use (match_operand 3 "" ""))
+ (clobber (reg:SI LR_REGNUM))]
+ "TARGET_ARM
+ && TARGET_INTERWORK
&& (GET_CODE (operands[1]) == SYMBOL_REF)
&& !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
"*
@@ -7957,6 +8234,7 @@
}"
[(set_attr "type" "call")]
)
+;; APPLE LOCAL end 5831528 make calls predicable
;; APPLE LOCAL end ARM pic support
;; APPLE LOCAL begin ARM dynamic
@@ -8046,30 +8324,38 @@
}"
)
+;; APPLE LOCAL begin ARM indirect sibcalls
(define_insn "*sibcall_insn"
- [(call (mem:SI (match_operand:SI 0 "" "X"))
- (match_operand 1 "" ""))
+ [(call (mem:SI (match_operand:SI 0 "arm_branch_target" "X"))
+ (match_operand 1 "" ""))
(return)
(use (match_operand 2 "" ""))]
- "TARGET_ARM && GET_CODE (operands[0]) == SYMBOL_REF"
+ "TARGET_ARM && (GET_CODE (operands[0]) == SYMBOL_REF || GET_CODE (operands[0]) == REG)"
"*
- return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
+ if (GET_CODE (operands[0]) == REG)
+ return \"bx%?\\t%0\";
+ else
+ return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
"
[(set_attr "type" "call")]
)
(define_insn "*sibcall_value_insn"
[(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:SI 1 "" "X"))
- (match_operand 2 "" "")))
+ (call (mem:SI (match_operand:SI 1 "arm_branch_target" "X"))
+ (match_operand 2 "" "")))
(return)
(use (match_operand 3 "" ""))]
- "TARGET_ARM && GET_CODE (operands[1]) == SYMBOL_REF"
+ "TARGET_ARM && (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == REG)"
"*
- return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
+ if (GET_CODE (operands[1]) == REG)
+ return \"bx%?\\t%1\";
+ else
+ return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
"
[(set_attr "type" "call")]
)
+;; APPLE LOCAL end ARM indirect sibcalls
;; Often the return insn will be the same as loading from memory, so set attr
(define_insn "return"
@@ -8296,7 +8582,8 @@
(match_operand:SI 2 "const_int_operand" "") ; total range
(match_operand:SI 3 "" "") ; table label
(match_operand:SI 4 "" "")] ; Out of range label
- "TARGET_ARM"
+;; APPLE LOCAL compact switch tables
+ "TARGET_EITHER"
"
{
rtx reg;
@@ -8309,12 +8596,33 @@
operands[0] = reg;
}
+ /* APPLE LOCAL begin compact switch tables */
+ if (TARGET_ARM)
+ {
+ /* APPLE LOCAL end compact switch tables */
if (!const_ok_for_arm (INTVAL (operands[2])))
operands[2] = force_reg (SImode, operands[2]);
emit_jump_insn (gen_casesi_internal (operands[0], operands[2], operands[3],
operands[4]));
DONE;
+ /* APPLE LOCAL begin compact switch tables */
+ }
+ else
+ {
+ /* Containing function must be 4-byte aligned, else we won't know what the
+ various .align directives do, e.g. around constant tables. */
+ cfun->needs_4byte_alignment = 1;
+ /* This is a function call, but the semantics are not the same as a normal
+ function call, so we put the parameter in R0 explicitly and hide the
+ call as a casesi node. The USE of R0 in the casesi_internal pattern
+ causes the value to be retained. */
+ emit_move_insn (gen_rtx_REG (Pmode, 0), operands[0]);
+ emit_jump_insn (gen_thumb_casesi_internal (operands[0], operands[2], operands[3],
+ operands[4]));
+ DONE;
+ }
+ /* APPLE LOCAL end compact switch tables */
}"
)
@@ -8340,6 +8648,86 @@
(set_attr "length" "12")]
)
+;; APPLE LOCAL begin compact switch tables
+;; This pattern represents the library call for Thumb switch tables.
+;; The functions' (sparse) register usage is recorded as clobbers.
+
+(define_insn "thumb_casesi_internal"
+ [(parallel [(set (pc)
+ (if_then_else
+ (leu (match_operand:SI 0 "s_register_operand" "l")
+ (match_operand:SI 1 "const_int_operand" "i"))
+ (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 2))
+ (label_ref (match_operand 2 "" ""))))
+ (label_ref (match_operand 3 "" ""))))
+ (clobber (reg:CC CC_REGNUM))
+ (clobber (reg:SI LR_REGNUM))
+ (clobber (reg:SI IP_REGNUM))
+ (use (reg:SI 0))
+ (use (label_ref (match_dup 2)))])]
+ "TARGET_THUMB"
+ "*
+ {
+ rtx body = PATTERN (next_real_insn (insn));
+ static char buf[255];
+ gcc_assert (GET_CODE (body) == ADDR_DIFF_VEC);
+ strcpy(buf, \"bl\\t\");
+ if (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
+ strcat(buf, \"L\");
+ if (GET_MODE (body) == QImode
+ && ADDR_DIFF_VEC_FLAGS (body).offset_unsigned)
+ {
+ register_switchu8_libfunc ();
+ strcat(buf, \"___switchu8\");
+ }
+ else if (GET_MODE (body) == QImode)
+ {
+ register_switch8_libfunc ();
+ strcat(buf, \"___switch8\");
+ }
+ else if (GET_MODE (body) == HImode)
+ {
+ register_switch16_libfunc ();
+ strcat(buf, \"___switch16\");
+ }
+ else
+ {
+ register_switch32_libfunc ();
+ /* The table is 4-byte aligned, and the call should
+ immediately precede the table. To do this, align
+ here; as it happens, 0x0000 is a NOP insn. The
+ insn_length is still 4 even if a NOP is inserted;
+ however, the computation in shorten_branches
+ comes out right because that 4 is counted against
+ the following label, which is marked as 4-byte
+ aligned. I.e. the shorten_branch code thinks it's
+ going to looks like
+ call
+ .align 2
+ zero padding
+ label:
+ when in fact it is
+ .align 2
+ NOP
+ call
+ .align 2
+ never any padding here
+ label:
+ and it gets the right address for the label.
+ Yes, this is overly tricky. */
+ assemble_align (32);
+ strcat(buf, \"___switch32\");
+ }
+ if (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
+ strcat(buf, \"$stub\");
+ return buf;
+ }
+ "
+ [(set_attr "conds" "clob")
+ (set_attr "length" "4")]
+)
+;; APPLE LOCAL end compact switch tables
+
;; APPLE LOCAL begin ARM setjmp/longjmp interworking
;; Indirect jump with possible change between ARM/Thumb state
(define_expand "indirect_jump_exchange"
@@ -10200,6 +10588,7 @@
;; Special patterns for dealing with the constant pool
+;; APPLE LOCAL begin ARM compact switch tables
(define_insn "align_4"
[(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
"TARGET_EITHER"
@@ -10207,6 +10596,7 @@
assemble_align (32);
return \"\";
"
+ [(set (attr "length") (const_int 0))]
)
(define_insn "align_8"
@@ -10216,6 +10606,7 @@
assemble_align (64);
return \"\";
"
+ [(set (attr "length") (const_int 0))]
)
(define_insn "consttable_end"
@@ -10225,7 +10616,9 @@
making_const_table = FALSE;
return \"\";
"
+ [(set_attr "length" "0")]
)
+;; APPLE LOCAL end ARM compact switch tables
(define_insn "consttable_1"
[(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
@@ -10395,11 +10788,14 @@
""
)
+;; APPLE LOCAL begin ARM compact switch tables
(define_insn "prologue_use"
[(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_PROLOGUE_USE)]
""
"%@ %0 needed for prologue"
+ [(set_attr "length" "0")]
)
+;; APPLE LOCAL end ARM compact switch tables
;; Patterns for exception handling
@@ -10448,6 +10844,86 @@
}"
)
+;; APPLE LOCAL begin ARM 4382996 improve assignments of NE
+
+;; Handle ((x op y) != 0)
+(define_insn_and_split "*arm_binary_ne_0"
+ [(set (match_operand:SI 0 "s_register_operand" "=r,r")
+ (ne:SI (match_operator:SI 3 "binary_cc_noclobber_operator"
+ [(match_operand:SI 1 "s_register_operand" "r,r")
+ (match_operand:SI 2 "arm_not_operand" "rI,K")])
+ (const_int 0)))
+ (clobber (reg:CC_NOOV CC_REGNUM))]
+ "TARGET_ARM"
+ "#"
+ "TARGET_ARM && reload_completed"
+ [(parallel [(set (reg:CC_NOOV CC_REGNUM)
+ (compare:CC_NOOV
+ (match_op_dup:SI 3 [(match_dup 1) (match_dup 2)])
+ (const_int 0)))
+ (set (match_dup 0)
+ (match_op_dup:SI 3 [(match_dup 1) (match_dup 2)]))])
+ (set (match_dup 0)
+ (if_then_else:SI
+ (ne:SI (reg:CC_NOOV CC_REGNUM) (const_int 0))
+ (const_int 1) (match_dup 0)))]
+ ""
+ [(set_attr "conds" "clob")
+ (set_attr "length" "8")]
+)
+
+;; A special pattern for ADD, because compare_scc gets recognized first,
+;; preventing the above form from being tried.
+
+(define_insn_and_split "*arm_add_ne_0"
+ [(set (match_operand:SI 0 "s_register_operand" "=r,r")
+ (ne:SI (neg:SI (match_operand:SI 1 "s_register_operand" "r,r"))
+ (match_operand:SI 2 "arm_not_operand" "rI,K")))
+ (clobber (reg:CC_NOOV CC_REGNUM))]
+ "TARGET_ARM"
+ "#"
+ "TARGET_ARM && reload_completed"
+ [(parallel [(set (reg:CC_NOOV CC_REGNUM)
+ (compare:CC_NOOV
+ (plus:SI (match_dup 1) (match_dup 2))
+ (const_int 0)))
+ (set (match_dup 0)
+ (plus:SI (match_dup 1) (match_dup 2)))])
+ (set (match_dup 0)
+ (if_then_else:SI
+ (ne:SI (reg:CC_NOOV CC_REGNUM) (const_int 0))
+ (const_int 1) (match_dup 0)))]
+ ""
+ [(set_attr "conds" "clob")
+ (set_attr "length" "8")]
+)
+
+;; A special pattern for MULT, since it requires early clobber semantics.
+
+(define_insn_and_split "*arm_mul_ne_0"
+ [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,r,r")
+ (ne:SI (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
+ (match_operand:SI 1 "arm_not_operand" "%?r,0,I,K"))
+ (const_int 0)))
+ (clobber (reg:CC_NOOV CC_REGNUM))]
+ "TARGET_ARM"
+ "#"
+ "TARGET_ARM && reload_completed"
+ [(parallel [(set (reg:CC_NOOV CC_REGNUM)
+ (compare:CC_NOOV
+ (mult:SI (match_dup 2) (match_dup 1))
+ (const_int 0)))
+ (set (match_dup 0)
+ (mult:SI (match_dup 2) (match_dup 1)))])
+ (set (match_dup 0)
+ (if_then_else:SI
+ (ne:SI (reg:CC_NOOV CC_REGNUM) (const_int 0))
+ (const_int 1) (match_dup 0)))]
+ ""
+ [(set_attr "conds" "clob")
+ (set_attr "length" "8")]
+)
+;; APPLE LOCAL end ARM 4382996 improve assignments of NE
;; TLS support
@@ -10479,7 +10955,65 @@
""
"trap")
;; APPLE LOCAL end ARM builtin_trap
-
+
+;; APPLE LOCAL begin bswap UXTB16 support
+(define_expand "bswapsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (bswap:SI (match_operand:SI 1 "s_register_operand" "")))]
+ "TARGET_EITHER && arm_arch6"
+ ""
+)
+
+(define_insn "*arm_bswapsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
+ "TARGET_ARM && arm_arch6"
+ "rev%?\\t%0, %1"
+ [(set_attr "predicable" "yes")]
+)
+
+(define_insn "*thumb_bswapsi2"
+ [(set (match_operand:SI 0 "register_operand" "=l")
+ (bswap:SI (match_operand:SI 1 "register_operand" "l")))]
+ "TARGET_THUMB && arm_arch6"
+ "rev\\t%0, %1"
+ [(set_attr "length" "2")]
+)
+
+(define_expand "bswapdi2"
+ [(set (match_operand:DI 0 "s_register_operand" "")
+ (bswap:DI (match_operand:DI 1 "s_register_operand" "")))]
+ "TARGET_EITHER && arm_arch6"
+ ""
+)
+
+(define_insn "*arm_bswapdi2"
+ [(set (match_operand:DI 0 "s_register_operand" "=&r")
+ (bswap:DI (match_operand:DI 1 "s_register_operand" "r")))]
+ "TARGET_ARM && arm_arch6"
+ "rev%?\\t%Q0, %R1\;rev%?\\t%R0, %Q1"
+ [(set_attr "predicable" "yes")
+ (set_attr "length" "8")]
+)
+
+(define_insn "*thumb_bswapdi2"
+ [(set (match_operand:DI 0 "register_operand" "=&l")
+ (bswap:DI (match_operand:DI 1 "register_operand" "l")))]
+ "TARGET_THUMB && arm_arch6"
+ "rev\\t%Q0, %R1\;rev\\t%R0, %Q1"
+ [(set_attr "length" "4")]
+)
+
+(define_insn "uxtb16"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
+ (match_operand:SI 2 "const_int_operand" "M")] UNSPEC_UXTB16))]
+ "TARGET_ARM && arm_arch6"
+ "uxtb16%?\\t%0, %1, ror %2"
+ [(set_attr "predicable" "yes")]
+)
+;; APPLE LOCAL end bswap UXTB16 support
+
;; Load the FPA co-processor patterns
(include "fpa.md")
;; Load the Maverick co-processor patterns
Modified: llvm-gcc-4.2/trunk/gcc/config/arm/cirrus.md
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/arm/cirrus.md?rev=54178&r1=54177&r2=54178&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/arm/cirrus.md (original)
+++ llvm-gcc-4.2/trunk/gcc/config/arm/cirrus.md Tue Jul 29 17:54:46 2008
@@ -120,7 +120,8 @@
(set_attr "cirrus" "normal")]
)
-(define_insn "muldi3"
+;; APPLE LOCAL DImode multiply enhancement
+(define_insn "cirrus_muldi3"
[(set (match_operand:DI 0 "cirrus_fp_register" "=v")
(mult:DI (match_operand:DI 2 "cirrus_fp_register" "v")
(match_operand:DI 1 "cirrus_fp_register" "v")))]
Modified: llvm-gcc-4.2/trunk/gcc/config/arm/constraints.md
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/arm/constraints.md?rev=54178&r1=54177&r2=54178&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/arm/constraints.md (original)
+++ llvm-gcc-4.2/trunk/gcc/config/arm/constraints.md Tue Jul 29 17:54:46 2008
@@ -30,7 +30,8 @@
;; in Thumb state: I, J, K, L, M, N, O
;; The following multi-letter normal constraints have been used:
-;; in ARM state: Da, Db, Dc
+;; APPLE LOCAL 5831562 long long constants
+;; in ARM state: Da, Db, Dc, Dd
;; The following memory constraints have been used:
;; in ARM state: Q, Uq, Uv, Uy
@@ -152,6 +153,15 @@
(match_test "TARGET_ARM && arm_const_double_inline_cost (op) == 4
&& !(optimize_size || arm_ld_sched)")))
+;; APPLE LOCAL begin 5831562 long long constants
+(define_constraint "Dd"
+ "@internal
+ In ARM state a const_int, const_double or const_vector that can
+ used directly in arithmetic instructions as two 32-bit immediates."
+ (and (match_code "const_double,const_int,const_vector")
+ (match_test "TARGET_ARM && const64_ok_for_arm_immediate (op)")))
+;; APPLE LOCAL end 5831562 long long constants
+
(define_memory_constraint "Uv"
"@internal
In ARM state a valid VFP load/store address."
Modified: llvm-gcc-4.2/trunk/gcc/config/arm/predicates.md
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/arm/predicates.md?rev=54178&r1=54177&r2=54178&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/arm/predicates.md (original)
+++ llvm-gcc-4.2/trunk/gcc/config/arm/predicates.md Tue Jul 29 17:54:46 2008
@@ -51,6 +51,19 @@
|| REGNO (op) >= FIRST_PSEUDO_REGISTER));
})
+;; APPLE LOCAL begin ARM add this peephole
+;; Any Thumb low register.
+(define_predicate "thumb_low_register_operand"
+ (match_code "reg,subreg")
+{
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ return (GET_CODE (op) == REG
+ && REGNO (op) <= LAST_LO_REGNUM);
+})
+;; APPLE LOCAL end ARM add this peephole
+
(define_predicate "f_register_operand"
(match_code "reg,subreg")
{
@@ -73,6 +86,16 @@
(and (match_code "const_int")
(match_test "const_ok_for_arm (INTVAL (op))")))
+;; APPLE LOCAL begin 5831562 long long constants
+(define_predicate "arm_immediate64_operand"
+ (and (match_code "const_int,const_double")
+ (match_test "const64_ok_for_arm_immediate (op)")))
+
+(define_predicate "arm_add_immediate64_operand"
+ (and (match_code "const_int,const_double")
+ (match_test "const64_ok_for_arm_add (op)")))
+;; APPLE LOCAL end 5831562 long long constants
+
(define_predicate "arm_neg_immediate_operand"
(and (match_code "const_int")
(match_test "const_ok_for_arm (-INTVAL (op))")))
@@ -86,6 +109,16 @@
(ior (match_operand 0 "s_register_operand")
(match_operand 0 "arm_immediate_operand")))
+;; APPLE LOCAL begin 5831562 long long constants
+(define_predicate "arm_rhs64_operand"
+ (ior (match_operand 0 "s_register_operand")
+ (match_operand 0 "arm_immediate64_operand")))
+
+(define_predicate "arm_add64_operand"
+ (ior (match_operand 0 "s_register_operand")
+ (match_operand 0 "arm_add_immediate64_operand")))
+;; APPLE LOCAL end 5831562 long long constants
+
(define_predicate "arm_rhsm_operand"
(ior (match_operand 0 "arm_rhs_operand")
(match_operand 0 "memory_operand")))
@@ -159,6 +192,14 @@
(and (match_code "plus,minus,ior,xor,and")
(match_test "mode == GET_MODE (op)")))
+;; APPLE LOCAL begin ARM 4382996 improve assignments of NE
+;; True for binary operators that can set the condition codes as a side effect,
+;; and that don't have early clobber semantics.
+(define_special_predicate "binary_cc_noclobber_operator"
+ (and (match_code "plus,minus,ior,xor,and,ashift,ashiftrt,lshiftrt")
+ (match_test "mode == GET_MODE (op)")))
+;; APPLE LOCAL end ARM 4382996 improve assignments of NE
+
;; True for logical binary operators.
(define_special_predicate "logical_binary_operator"
(and (match_code "ior,xor,and")
Modified: llvm-gcc-4.2/trunk/gcc/config/i386/i386.md
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/i386.md?rev=54178&r1=54177&r2=54178&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/i386/i386.md (original)
+++ llvm-gcc-4.2/trunk/gcc/config/i386/i386.md Tue Jul 29 17:54:46 2008
@@ -12137,6 +12137,24 @@
"#"
[(set_attr "type" "multi")])
+;; APPLE LOCAL begin mainline 5951842
+;; This pattern must be defined before *lshrti3_2 to prevent
+;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
+
+(define_insn "sse2_lshrti3"
+ [(set (match_operand:TI 0 "register_operand" "=x")
+ (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
+ (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
+ "TARGET_SSE2"
+{
+ operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
+ return "psrldq\t{%2, %0|%0, %2}";
+}
+ [(set_attr "type" "sseishft")
+ (set_attr "prefix_data16" "1")
+ (set_attr "mode" "TI")])
+;; APPLE LOCAL end mainline 5951842
+
(define_insn "*lshrti3_2"
[(set (match_operand:TI 0 "register_operand" "=r")
(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
@@ -19236,7 +19254,7 @@
(define_insn "x86_movdicc_0_m1_rex64"
[(set (match_operand:DI 0 "register_operand" "=r")
- (if_then_else:DI (match_operand:DI 1 "ix86_carry_flag_operator" "")
+ (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
(const_int -1)
(const_int 0)))
(clobber (reg:CC FLAGS_REG))]
@@ -19279,7 +19297,7 @@
(define_insn "x86_movsicc_0_m1"
[(set (match_operand:SI 0 "register_operand" "=r")
- (if_then_else:SI (match_operand:SI 1 "ix86_carry_flag_operator" "")
+ (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
(const_int -1)
(const_int 0)))
(clobber (reg:CC FLAGS_REG))]
Modified: llvm-gcc-4.2/trunk/gcc/config/i386/sse.md
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/sse.md?rev=54178&r1=54177&r2=54178&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/i386/sse.md (original)
+++ llvm-gcc-4.2/trunk/gcc/config/i386/sse.md Tue Jul 29 17:54:46 2008
@@ -3069,17 +3069,9 @@
operands[1] = gen_lowpart (TImode, operands[1]);
})
-(define_insn "sse2_lshrti3"
- [(set (match_operand:TI 0 "register_operand" "=x")
- (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
- (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
- "TARGET_SSE2"
-{
- operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
- return "psrldq\t{%2, %0|%0, %2}";
-}
- [(set_attr "type" "sseishft")
- (set_attr "mode" "TI")])
+;; APPLE LOCAL begin mainline 5951842
+;; moved sse2_lshrti3 to i386.md
+;; APPLE LOCAL end mainline 5951842
(define_expand "vec_shr_<mode>"
[(set (match_operand:SSEMODEI 0 "register_operand" "")
Added: llvm-gcc-4.2/trunk/gcc/testsuite/g++.dg/ext/interface4.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.dg/ext/interface4.h?rev=54178&view=auto
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/testsuite/g++.dg/ext/interface4.h (added)
+++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.dg/ext/interface4.h Tue Jul 29 17:54:46 2008
@@ -0,0 +1,8 @@
+#pragma interface
+namespace N {
+ typedef int A;
+}
+inline void g ( ) {
+ static N :: A a = 0;
+ a = a;
+}
More information about the llvm-commits
mailing list