Index: gcc/gcc/config/sparc/sparc.md |
diff --git a/gcc/gcc/config/sparc/sparc.md b/gcc/gcc/config/sparc/sparc.md |
index e5098a5592d69ac816b572145f1dbc6e8fb3e617..7eb8ece783a6f3ec03bec5bdf366bcd02f50a4b3 100644 |
--- a/gcc/gcc/config/sparc/sparc.md |
+++ b/gcc/gcc/config/sparc/sparc.md |
@@ -1,6 +1,6 @@ |
;; Machine description for SPARC chip for GCC |
;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, |
-;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 |
+;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 |
;; Free Software Foundation, Inc. |
;; Contributed by Michael Tiemann (tiemann@cygnus.com) |
;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans, |
@@ -38,6 +38,7 @@ |
(UNSPEC_EMB_TEXTHI 14) |
(UNSPEC_EMB_TEXTULO 15) |
(UNSPEC_EMB_SETHM 18) |
+ (UNSPEC_MOVE_GOTDATA 19) |
(UNSPEC_MEMBAR 20) |
@@ -76,6 +77,18 @@ |
(UNSPECV_LDSTUB 10) |
]) |
+ |
+(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) |
+(define_mode_iterator I [QI HI SI DI]) |
+(define_mode_iterator F [SF DF TF]) |
+ |
+;; We don't define V1SI because SI should work just fine. |
+(define_mode_iterator V32 [SF V2HI V4QI]) |
+(define_mode_iterator V32I [SI V2HI V4QI]) |
+ |
+(define_mode_iterator V64 [DF V2SI V4HI V8QI]) |
+(define_mode_iterator V64I [DI V2SI V4HI V8QI]) |
+ |
;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this |
;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name |
;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding |
@@ -130,25 +143,30 @@ |
;; True if branch/call has empty delay slot and will emit a nop in it |
(define_attr "empty_delay_slot" "false,true" |
- (symbol_ref "empty_delay_slot (insn)")) |
+ (symbol_ref "(empty_delay_slot (insn) |
+ ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)")) |
(define_attr "branch_type" "none,icc,fcc,reg" |
(const_string "none")) |
(define_attr "pic" "false,true" |
- (symbol_ref "flag_pic != 0")) |
+ (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)")) |
(define_attr "calls_alloca" "false,true" |
- (symbol_ref "cfun->calls_alloca != 0")) |
+ (symbol_ref "(cfun->calls_alloca != 0 |
+ ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)")) |
(define_attr "calls_eh_return" "false,true" |
- (symbol_ref "crtl->calls_eh_return !=0 ")) |
+ (symbol_ref "(crtl->calls_eh_return != 0 |
+ ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)")) |
(define_attr "leaf_function" "false,true" |
- (symbol_ref "current_function_uses_only_leaf_regs != 0")) |
+ (symbol_ref "(current_function_uses_only_leaf_regs != 0 |
+ ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)")) |
(define_attr "delayed_branch" "false,true" |
- (symbol_ref "flag_delayed_branch != 0")) |
+ (symbol_ref "(flag_delayed_branch != 0 |
+ ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)")) |
;; Length (in # of insns). |
;; Beware that setting a length greater or equal to 3 for conditional branches |
@@ -242,7 +260,8 @@ |
;; Attributes for instruction and branch scheduling |
(define_attr "tls_call_delay" "false,true" |
- (symbol_ref "tls_call_delay (insn)")) |
+ (symbol_ref "(tls_call_delay (insn) |
+ ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)")) |
(define_attr "in_call_delay" "false,true" |
(cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi") |
@@ -257,10 +276,14 @@ |
(const_string "false")))) |
(define_attr "eligible_for_sibcall_delay" "false,true" |
- (symbol_ref "eligible_for_sibcall_delay (insn)")) |
+ (symbol_ref "(eligible_for_sibcall_delay (insn) |
+ ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE |
+ : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)")) |
(define_attr "eligible_for_return_delay" "false,true" |
- (symbol_ref "eligible_for_return_delay (insn)")) |
+ (symbol_ref "(eligible_for_return_delay (insn) |
+ ? ELIGIBLE_FOR_RETURN_DELAY_TRUE |
+ : ELIGIBLE_FOR_RETURN_DELAY_FALSE)")) |
;; ??? !v9: Should implement the notion of predelay slots for floating-point |
;; branches. This would allow us to remove the nop always inserted before |
@@ -330,84 +353,11 @@ |
;; Compare instructions. |
-;; We generate RTL for comparisons and branches by having the cmpxx |
-;; patterns store away the operands. Then, the scc and bcc patterns |
-;; emit RTL for both the compare and the branch. |
-;; |
-;; We do this because we want to generate different code for an sne and |
-;; seq insn. In those cases, if the second operand of the compare is not |
-;; const0_rtx, we want to compute the xor of the two operands and test |
-;; it against zero. |
-;; |
-;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match |
-;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc |
-;; insns that actually require more than one machine instruction. |
- |
-(define_expand "cmpsi" |
- [(set (reg:CC 100) |
- (compare:CC (match_operand:SI 0 "compare_operand" "") |
- (match_operand:SI 1 "arith_operand" "")))] |
- "" |
-{ |
- if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx) |
- operands[0] = force_reg (SImode, operands[0]); |
- |
- sparc_compare_op0 = operands[0]; |
- sparc_compare_op1 = operands[1]; |
- DONE; |
-}) |
- |
-(define_expand "cmpdi" |
- [(set (reg:CCX 100) |
- (compare:CCX (match_operand:DI 0 "compare_operand" "") |
- (match_operand:DI 1 "arith_operand" "")))] |
- "TARGET_ARCH64" |
-{ |
- if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx) |
- operands[0] = force_reg (DImode, operands[0]); |
- |
- sparc_compare_op0 = operands[0]; |
- sparc_compare_op1 = operands[1]; |
- DONE; |
-}) |
- |
-(define_expand "cmpsf" |
- ;; The 96 here isn't ever used by anyone. |
- [(set (reg:CCFP 96) |
- (compare:CCFP (match_operand:SF 0 "register_operand" "") |
- (match_operand:SF 1 "register_operand" "")))] |
- "TARGET_FPU" |
-{ |
- sparc_compare_op0 = operands[0]; |
- sparc_compare_op1 = operands[1]; |
- DONE; |
-}) |
+;; These are just the DEFINE_INSNs to match the patterns and the |
+;; DEFINE_SPLITs for some of the scc insns that actually require |
+;; more than one machine instruction. DEFINE_EXPANDs are further down. |
-(define_expand "cmpdf" |
- ;; The 96 here isn't ever used by anyone. |
- [(set (reg:CCFP 96) |
- (compare:CCFP (match_operand:DF 0 "register_operand" "") |
- (match_operand:DF 1 "register_operand" "")))] |
- "TARGET_FPU" |
-{ |
- sparc_compare_op0 = operands[0]; |
- sparc_compare_op1 = operands[1]; |
- DONE; |
-}) |
- |
-(define_expand "cmptf" |
- ;; The 96 here isn't ever used by anyone. |
- [(set (reg:CCFP 96) |
- (compare:CCFP (match_operand:TF 0 "register_operand" "") |
- (match_operand:TF 1 "register_operand" "")))] |
- "TARGET_FPU" |
-{ |
- sparc_compare_op0 = operands[0]; |
- sparc_compare_op1 = operands[1]; |
- DONE; |
-}) |
- |
-;; Now the compare DEFINE_INSNs. |
+;; The compare DEFINE_INSNs. |
(define_insn "*cmpsi_insn" |
[(set (reg:CC 100) |
@@ -499,12 +449,41 @@ |
} |
[(set_attr "type" "fpcmp")]) |
-;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this |
-;; without jumps using the addx/subx instructions. For seq/sne on v9 we use |
-;; the same code as v8 (the addx/subx method has more applications). The |
-;; exception to this is "reg != 0" which can be done in one instruction on v9 |
-;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do |
-;; branches. |
+;; Next come the scc insns. |
+ |
+(define_expand "cstoresi4" |
+ [(use (match_operator 1 "comparison_operator" |
+ [(match_operand:SI 2 "compare_operand" "") |
+ (match_operand:SI 3 "arith_operand" "")])) |
+ (clobber (match_operand:SI 0 "register_operand"))] |
+ "" |
+{ |
+ if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx) |
+ operands[2] = force_reg (SImode, operands[2]); |
+ if (emit_scc_insn (operands)) DONE; else FAIL; |
+}) |
+ |
+(define_expand "cstoredi4" |
+ [(use (match_operator 1 "comparison_operator" |
+ [(match_operand:DI 2 "compare_operand" "") |
+ (match_operand:DI 3 "arith_operand" "")])) |
+ (clobber (match_operand:SI 0 "register_operand"))] |
+ "TARGET_ARCH64" |
+{ |
+ if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx) |
+ operands[2] = force_reg (DImode, operands[2]); |
+ if (emit_scc_insn (operands)) DONE; else FAIL; |
+}) |
+ |
+(define_expand "cstore<F:mode>4" |
+ [(use (match_operator 1 "comparison_operator" |
+ [(match_operand:F 2 "register_operand" "") |
+ (match_operand:F 3 "register_operand" "")])) |
+ (clobber (match_operand:SI 0 "register_operand"))] |
+ "TARGET_FPU" |
+ { if (emit_scc_insn (operands)) DONE; else FAIL; }) |
+ |
+ |
;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they |
;; generate addcc/subcc instructions. |
@@ -523,8 +502,8 @@ |
[(set (match_dup 3) |
(xor:DI (match_operand:DI 1 "register_operand" "") |
(match_operand:DI 2 "register_operand" ""))) |
- (set (match_operand:DI 0 "register_operand" "") |
- (eq:DI (match_dup 3) (const_int 0)))] |
+ (set (match_operand:SI 0 "register_operand" "") |
+ (eq:SI (match_dup 3) (const_int 0)))] |
"TARGET_ARCH64" |
{ operands[3] = gen_reg_rtx (DImode); }) |
@@ -542,338 +521,11 @@ |
[(set (match_dup 3) |
(xor:DI (match_operand:DI 1 "register_operand" "") |
(match_operand:DI 2 "register_operand" ""))) |
- (set (match_operand:DI 0 "register_operand" "") |
- (ne:DI (match_dup 3) (const_int 0)))] |
- "TARGET_ARCH64" |
- { operands[3] = gen_reg_rtx (DImode); }) |
- |
-(define_expand "seqdi_special_trunc" |
- [(set (match_dup 3) |
- (xor:DI (match_operand:DI 1 "register_operand" "") |
- (match_operand:DI 2 "register_operand" ""))) |
- (set (match_operand:SI 0 "register_operand" "") |
- (eq:SI (match_dup 3) (const_int 0)))] |
- "TARGET_ARCH64" |
- { operands[3] = gen_reg_rtx (DImode); }) |
- |
-(define_expand "snedi_special_trunc" |
- [(set (match_dup 3) |
- (xor:DI (match_operand:DI 1 "register_operand" "") |
- (match_operand:DI 2 "register_operand" ""))) |
(set (match_operand:SI 0 "register_operand" "") |
(ne:SI (match_dup 3) (const_int 0)))] |
"TARGET_ARCH64" |
{ operands[3] = gen_reg_rtx (DImode); }) |
-(define_expand "seqsi_special_extend" |
- [(set (match_dup 3) |
- (xor:SI (match_operand:SI 1 "register_operand" "") |
- (match_operand:SI 2 "register_operand" ""))) |
- (parallel [(set (match_operand:DI 0 "register_operand" "") |
- (eq:DI (match_dup 3) (const_int 0))) |
- (clobber (reg:CC 100))])] |
- "TARGET_ARCH64" |
- { operands[3] = gen_reg_rtx (SImode); }) |
- |
-(define_expand "snesi_special_extend" |
- [(set (match_dup 3) |
- (xor:SI (match_operand:SI 1 "register_operand" "") |
- (match_operand:SI 2 "register_operand" ""))) |
- (parallel [(set (match_operand:DI 0 "register_operand" "") |
- (ne:DI (match_dup 3) (const_int 0))) |
- (clobber (reg:CC 100))])] |
- "TARGET_ARCH64" |
- { operands[3] = gen_reg_rtx (SImode); }) |
- |
-;; ??? v9: Operand 0 needs a mode, so SImode was chosen. |
-;; However, the code handles both SImode and DImode. |
-(define_expand "seq" |
- [(set (match_operand:SI 0 "int_register_operand" "") |
- (eq:SI (match_dup 1) (const_int 0)))] |
- "" |
-{ |
- if (GET_MODE (sparc_compare_op0) == SImode) |
- { |
- rtx pat; |
- |
- if (GET_MODE (operands[0]) == SImode) |
- pat = gen_seqsi_special (operands[0], sparc_compare_op0, |
- sparc_compare_op1); |
- else if (! TARGET_ARCH64) |
- FAIL; |
- else |
- pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0, |
- sparc_compare_op1); |
- emit_insn (pat); |
- DONE; |
- } |
- else if (GET_MODE (sparc_compare_op0) == DImode) |
- { |
- rtx pat; |
- |
- if (! TARGET_ARCH64) |
- FAIL; |
- else if (GET_MODE (operands[0]) == SImode) |
- pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0, |
- sparc_compare_op1); |
- else |
- pat = gen_seqdi_special (operands[0], sparc_compare_op0, |
- sparc_compare_op1); |
- emit_insn (pat); |
- DONE; |
- } |
- else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ); |
- gcc_assert (code == NE); |
- emit_insn (gen_sne (operands[0])); |
- DONE; |
- } |
- else if (TARGET_V9) |
- { |
- if (gen_v9_scc (EQ, operands)) |
- DONE; |
- /* fall through */ |
- } |
- FAIL; |
-}) |
- |
-;; ??? v9: Operand 0 needs a mode, so SImode was chosen. |
-;; However, the code handles both SImode and DImode. |
-(define_expand "sne" |
- [(set (match_operand:SI 0 "int_register_operand" "") |
- (ne:SI (match_dup 1) (const_int 0)))] |
- "" |
-{ |
- if (GET_MODE (sparc_compare_op0) == SImode) |
- { |
- rtx pat; |
- |
- if (GET_MODE (operands[0]) == SImode) |
- pat = gen_snesi_special (operands[0], sparc_compare_op0, |
- sparc_compare_op1); |
- else if (! TARGET_ARCH64) |
- FAIL; |
- else |
- pat = gen_snesi_special_extend (operands[0], sparc_compare_op0, |
- sparc_compare_op1); |
- emit_insn (pat); |
- DONE; |
- } |
- else if (GET_MODE (sparc_compare_op0) == DImode) |
- { |
- rtx pat; |
- |
- if (! TARGET_ARCH64) |
- FAIL; |
- else if (GET_MODE (operands[0]) == SImode) |
- pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0, |
- sparc_compare_op1); |
- else |
- pat = gen_snedi_special (operands[0], sparc_compare_op0, |
- sparc_compare_op1); |
- emit_insn (pat); |
- DONE; |
- } |
- else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE); |
- gcc_assert (code == NE); |
- emit_insn (gen_sne (operands[0])); |
- DONE; |
- } |
- else if (TARGET_V9) |
- { |
- if (gen_v9_scc (NE, operands)) |
- DONE; |
- /* fall through */ |
- } |
- FAIL; |
-}) |
- |
-(define_expand "sgt" |
- [(set (match_operand:SI 0 "int_register_operand" "") |
- (gt:SI (match_dup 1) (const_int 0)))] |
- "" |
-{ |
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT); |
- gcc_assert (code == NE); |
- emit_insn (gen_sne (operands[0])); |
- DONE; |
- } |
- else if (TARGET_V9) |
- { |
- if (gen_v9_scc (GT, operands)) |
- DONE; |
- /* fall through */ |
- } |
- FAIL; |
-}) |
- |
-(define_expand "slt" |
- [(set (match_operand:SI 0 "int_register_operand" "") |
- (lt:SI (match_dup 1) (const_int 0)))] |
- "" |
-{ |
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT); |
- gcc_assert (code == NE); |
- emit_insn (gen_sne (operands[0])); |
- DONE; |
- } |
- else if (TARGET_V9) |
- { |
- if (gen_v9_scc (LT, operands)) |
- DONE; |
- /* fall through */ |
- } |
- FAIL; |
-}) |
- |
-(define_expand "sge" |
- [(set (match_operand:SI 0 "int_register_operand" "") |
- (ge:SI (match_dup 1) (const_int 0)))] |
- "" |
-{ |
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE); |
- gcc_assert (code == NE); |
- emit_insn (gen_sne (operands[0])); |
- DONE; |
- } |
- else if (TARGET_V9) |
- { |
- if (gen_v9_scc (GE, operands)) |
- DONE; |
- /* fall through */ |
- } |
- FAIL; |
-}) |
- |
-(define_expand "sle" |
- [(set (match_operand:SI 0 "int_register_operand" "") |
- (le:SI (match_dup 1) (const_int 0)))] |
- "" |
-{ |
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE); |
- gcc_assert (code == NE); |
- emit_insn (gen_sne (operands[0])); |
- DONE; |
- } |
- else if (TARGET_V9) |
- { |
- if (gen_v9_scc (LE, operands)) |
- DONE; |
- /* fall through */ |
- } |
- FAIL; |
-}) |
- |
-(define_expand "sgtu" |
- [(set (match_operand:SI 0 "int_register_operand" "") |
- (gtu:SI (match_dup 1) (const_int 0)))] |
- "" |
-{ |
- if (! TARGET_V9) |
- { |
- rtx tem, pat; |
- |
- /* We can do ltu easily, so if both operands are registers, swap them and |
- do a LTU. */ |
- if ((GET_CODE (sparc_compare_op0) == REG |
- || GET_CODE (sparc_compare_op0) == SUBREG) |
- && (GET_CODE (sparc_compare_op1) == REG |
- || GET_CODE (sparc_compare_op1) == SUBREG)) |
- { |
- tem = sparc_compare_op0; |
- sparc_compare_op0 = sparc_compare_op1; |
- sparc_compare_op1 = tem; |
- pat = gen_sltu (operands[0]); |
- if (pat == NULL_RTX) |
- FAIL; |
- emit_insn (pat); |
- DONE; |
- } |
- } |
- else |
- { |
- if (gen_v9_scc (GTU, operands)) |
- DONE; |
- } |
- FAIL; |
-}) |
- |
-(define_expand "sltu" |
- [(set (match_operand:SI 0 "int_register_operand" "") |
- (ltu:SI (match_dup 1) (const_int 0)))] |
- "" |
-{ |
- if (TARGET_V9) |
- { |
- if (gen_v9_scc (LTU, operands)) |
- DONE; |
- } |
- operands[1] = gen_compare_reg (LTU); |
-}) |
- |
-(define_expand "sgeu" |
- [(set (match_operand:SI 0 "int_register_operand" "") |
- (geu:SI (match_dup 1) (const_int 0)))] |
- "" |
-{ |
- if (TARGET_V9) |
- { |
- if (gen_v9_scc (GEU, operands)) |
- DONE; |
- } |
- operands[1] = gen_compare_reg (GEU); |
-}) |
- |
-(define_expand "sleu" |
- [(set (match_operand:SI 0 "int_register_operand" "") |
- (leu:SI (match_dup 1) (const_int 0)))] |
- "" |
-{ |
- if (! TARGET_V9) |
- { |
- rtx tem, pat; |
- |
- /* We can do geu easily, so if both operands are registers, swap them and |
- do a GEU. */ |
- if ((GET_CODE (sparc_compare_op0) == REG |
- || GET_CODE (sparc_compare_op0) == SUBREG) |
- && (GET_CODE (sparc_compare_op1) == REG |
- || GET_CODE (sparc_compare_op1) == SUBREG)) |
- { |
- tem = sparc_compare_op0; |
- sparc_compare_op0 = sparc_compare_op1; |
- sparc_compare_op1 = tem; |
- pat = gen_sgeu (operands[0]); |
- if (pat == NULL_RTX) |
- FAIL; |
- emit_insn (pat); |
- DONE; |
- } |
- } |
- else |
- { |
- if (gen_v9_scc (LEU, operands)) |
- DONE; |
- } |
- FAIL; |
-}) |
;; Now the DEFINE_INSNs for the scc cases. |
@@ -1265,344 +917,51 @@ |
;; These control RTL generation for conditional jump insns |
-;; The quad-word fp compare library routines all return nonzero to indicate |
-;; true, which is different from the equivalent libgcc routines, so we must |
-;; handle them specially here. |
- |
-(define_expand "beq" |
- [(set (pc) |
- (if_then_else (eq (match_dup 1) (const_int 0)) |
- (label_ref (match_operand 0 "" "")) |
- (pc)))] |
- "" |
-{ |
- if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx |
- && GET_CODE (sparc_compare_op0) == REG |
- && GET_MODE (sparc_compare_op0) == DImode) |
- { |
- emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]); |
- DONE; |
- } |
- else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ); |
- gcc_assert (code == NE); |
- emit_jump_insn (gen_bne (operands[0])); |
- DONE; |
- } |
- operands[1] = gen_compare_reg (EQ); |
-}) |
- |
-(define_expand "bne" |
+(define_expand "cbranchcc4" |
[(set (pc) |
- (if_then_else (ne (match_dup 1) (const_int 0)) |
- (label_ref (match_operand 0 "" "")) |
+ (if_then_else (match_operator 0 "comparison_operator" |
+ [(match_operand 1 "compare_operand" "") |
+ (match_operand 2 "const_zero_operand" "")]) |
+ (label_ref (match_operand 3 "" "")) |
(pc)))] |
"" |
-{ |
- if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx |
- && GET_CODE (sparc_compare_op0) == REG |
- && GET_MODE (sparc_compare_op0) == DImode) |
- { |
- emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]); |
- DONE; |
- } |
- else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE); |
- gcc_assert (code == NE); |
- emit_jump_insn (gen_bne (operands[0])); |
- DONE; |
- } |
- operands[1] = gen_compare_reg (NE); |
-}) |
- |
-(define_expand "bgt" |
- [(set (pc) |
- (if_then_else (gt (match_dup 1) (const_int 0)) |
- (label_ref (match_operand 0 "" "")) |
- (pc)))] |
- "" |
-{ |
- if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx |
- && GET_CODE (sparc_compare_op0) == REG |
- && GET_MODE (sparc_compare_op0) == DImode) |
- { |
- emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]); |
- DONE; |
- } |
- else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT); |
- gcc_assert (code == NE); |
- emit_jump_insn (gen_bne (operands[0])); |
- DONE; |
- } |
- operands[1] = gen_compare_reg (GT); |
-}) |
- |
-(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); |
-}) |
- |
-(define_expand "blt" |
- [(set (pc) |
- (if_then_else (lt (match_dup 1) (const_int 0)) |
- (label_ref (match_operand 0 "" "")) |
- (pc)))] |
- "" |
-{ |
- if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx |
- && GET_CODE (sparc_compare_op0) == REG |
- && GET_MODE (sparc_compare_op0) == DImode) |
- { |
- emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]); |
- DONE; |
- } |
- else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT); |
- gcc_assert (code == NE); |
- emit_jump_insn (gen_bne (operands[0])); |
- DONE; |
- } |
- operands[1] = gen_compare_reg (LT); |
-}) |
- |
-(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); |
-}) |
- |
-(define_expand "bge" |
- [(set (pc) |
- (if_then_else (ge (match_dup 1) (const_int 0)) |
- (label_ref (match_operand 0 "" "")) |
- (pc)))] |
- "" |
-{ |
- if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx |
- && GET_CODE (sparc_compare_op0) == REG |
- && GET_MODE (sparc_compare_op0) == DImode) |
- { |
- emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]); |
- DONE; |
- } |
- else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE); |
- gcc_assert (code == NE); |
- emit_jump_insn (gen_bne (operands[0])); |
- DONE; |
- } |
- operands[1] = gen_compare_reg (GE); |
-}) |
- |
-(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); |
-}) |
- |
-(define_expand "ble" |
- [(set (pc) |
- (if_then_else (le (match_dup 1) (const_int 0)) |
- (label_ref (match_operand 0 "" "")) |
- (pc)))] |
- "" |
-{ |
- if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx |
- && GET_CODE (sparc_compare_op0) == REG |
- && GET_MODE (sparc_compare_op0) == DImode) |
- { |
- emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]); |
- DONE; |
- } |
- else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE); |
- gcc_assert (code == NE); |
- emit_jump_insn (gen_bne (operands[0])); |
- DONE; |
- } |
- operands[1] = gen_compare_reg (LE); |
-}) |
- |
-(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); |
-}) |
- |
-(define_expand "bunordered" |
- [(set (pc) |
- (if_then_else (unordered (match_dup 1) (const_int 0)) |
- (label_ref (match_operand 0 "" "")) |
- (pc)))] |
- "" |
-{ |
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNORDERED); |
- gcc_assert (code == EQ); |
- emit_jump_insn (gen_beq (operands[0])); |
- DONE; |
- } |
- operands[1] = gen_compare_reg (UNORDERED); |
-}) |
- |
-(define_expand "bordered" |
- [(set (pc) |
- (if_then_else (ordered (match_dup 1) (const_int 0)) |
- (label_ref (match_operand 0 "" "")) |
- (pc)))] |
- "" |
-{ |
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED); |
- gcc_assert (code == NE); |
- emit_jump_insn (gen_bne (operands[0])); |
- DONE; |
- } |
- operands[1] = gen_compare_reg (ORDERED); |
-}) |
- |
-(define_expand "bungt" |
- [(set (pc) |
- (if_then_else (ungt (match_dup 1) (const_int 0)) |
- (label_ref (match_operand 0 "" "")) |
- (pc)))] |
- "" |
-{ |
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT); |
- gcc_assert (code == GT); |
- emit_jump_insn (gen_bgt (operands[0])); |
- DONE; |
- } |
- operands[1] = gen_compare_reg (UNGT); |
-}) |
+ "") |
-(define_expand "bunlt" |
- [(set (pc) |
- (if_then_else (unlt (match_dup 1) (const_int 0)) |
- (label_ref (match_operand 0 "" "")) |
- (pc)))] |
+(define_expand "cbranchsi4" |
+ [(use (match_operator 0 "comparison_operator" |
+ [(match_operand:SI 1 "compare_operand" "") |
+ (match_operand:SI 2 "arith_operand" "")])) |
+ (use (match_operand 3 ""))] |
"" |
{ |
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT); |
- gcc_assert (code == NE); |
- emit_jump_insn (gen_bne (operands[0])); |
- DONE; |
- } |
- operands[1] = gen_compare_reg (UNLT); |
+ if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx) |
+ operands[1] = force_reg (SImode, operands[1]); |
+ emit_conditional_branch_insn (operands); |
+ DONE; |
}) |
-(define_expand "buneq" |
- [(set (pc) |
- (if_then_else (uneq (match_dup 1) (const_int 0)) |
- (label_ref (match_operand 0 "" "")) |
- (pc)))] |
- "" |
+(define_expand "cbranchdi4" |
+ [(use (match_operator 0 "comparison_operator" |
+ [(match_operand:DI 1 "compare_operand" "") |
+ (match_operand:DI 2 "arith_operand" "")])) |
+ (use (match_operand 3 ""))] |
+ "TARGET_ARCH64" |
{ |
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ); |
- gcc_assert (code == EQ); |
- emit_jump_insn (gen_beq (operands[0])); |
- DONE; |
- } |
- operands[1] = gen_compare_reg (UNEQ); |
+ if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx) |
+ operands[1] = force_reg (DImode, operands[1]); |
+ emit_conditional_branch_insn (operands); |
+ DONE; |
}) |
-(define_expand "bunge" |
- [(set (pc) |
- (if_then_else (unge (match_dup 1) (const_int 0)) |
- (label_ref (match_operand 0 "" "")) |
- (pc)))] |
- "" |
-{ |
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE); |
- gcc_assert (code == NE); |
- emit_jump_insn (gen_bne (operands[0])); |
- DONE; |
- } |
- operands[1] = gen_compare_reg (UNGE); |
-}) |
+(define_expand "cbranch<F:mode>4" |
+ [(use (match_operator 0 "comparison_operator" |
+ [(match_operand:F 1 "register_operand" "") |
+ (match_operand:F 2 "register_operand" "")])) |
+ (use (match_operand 3 ""))] |
+ "TARGET_FPU" |
+ { emit_conditional_branch_insn (operands); DONE; }) |
-(define_expand "bunle" |
- [(set (pc) |
- (if_then_else (unle (match_dup 1) (const_int 0)) |
- (label_ref (match_operand 0 "" "")) |
- (pc)))] |
- "" |
-{ |
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE); |
- gcc_assert (code == NE); |
- emit_jump_insn (gen_bne (operands[0])); |
- DONE; |
- } |
- operands[1] = gen_compare_reg (UNLE); |
-}) |
-(define_expand "bltgt" |
- [(set (pc) |
- (if_then_else (ltgt (match_dup 1) (const_int 0)) |
- (label_ref (match_operand 0 "" "")) |
- (pc)))] |
- "" |
-{ |
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
- { |
- enum rtx_code code |
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT); |
- gcc_assert (code == NE); |
- emit_jump_insn (gen_bne (operands[0])); |
- DONE; |
- } |
- operands[1] = gen_compare_reg (LTGT); |
-}) |
- |
;; Now match both normal and inverted jump. |
;; XXX fpcmp nop braindamage |
@@ -1745,8 +1104,6 @@ |
(set_attr "branch_type" "reg")]) |
-(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) |
- |
;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic |
;; value subject to a PC-relative relocation. Operand 2 is a helper function |
;; that adds the PC value at the call point to operand 0. |
@@ -1868,13 +1225,40 @@ |
(lo_sum:SI (match_operand:SI 1 "register_operand" "r") |
(unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))] |
"flag_pic" |
- "or\t%1, %%lo(%a2), %0") |
+{ |
+#ifdef HAVE_AS_SPARC_GOTDATA_OP |
+ return "xor\t%1, %%gdop_lox10(%a2), %0"; |
+#else |
+ return "or\t%1, %%lo(%a2), %0"; |
+#endif |
+}) |
(define_insn "movsi_high_pic" |
[(set (match_operand:SI 0 "register_operand" "=r") |
(high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))] |
"flag_pic && check_pic (1)" |
- "sethi\t%%hi(%a1), %0") |
+{ |
+#ifdef HAVE_AS_SPARC_GOTDATA_OP |
+ return "sethi\t%%gdop_hix22(%a1), %0"; |
+#else |
+ return "sethi\t%%hi(%a1), %0"; |
+#endif |
+}) |
+ |
+(define_insn "movsi_pic_gotdata_op" |
+ [(set (match_operand:SI 0 "register_operand" "=r") |
+ (unspec:SI [(match_operand:SI 1 "register_operand" "r") |
+ (match_operand:SI 2 "register_operand" "r") |
+ (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))] |
+ "flag_pic && check_pic (1)" |
+{ |
+#ifdef HAVE_AS_SPARC_GOTDATA_OP |
+ return "ld\t[%1 + %2], %0, %%gdop(%a3)"; |
+#else |
+ return "ld\t[%1 + %2], %0"; |
+#endif |
+} |
+ [(set_attr "type" "load")]) |
(define_expand "movsi_pic_label_ref" |
[(set (match_dup 3) (high:SI |
@@ -2074,13 +1458,40 @@ |
(lo_sum:DI (match_operand:DI 1 "register_operand" "r") |
(unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))] |
"TARGET_ARCH64 && flag_pic" |
- "or\t%1, %%lo(%a2), %0") |
+{ |
+#ifdef HAVE_AS_SPARC_GOTDATA_OP |
+ return "xor\t%1, %%gdop_lox10(%a2), %0"; |
+#else |
+ return "or\t%1, %%lo(%a2), %0"; |
+#endif |
+}) |
(define_insn "movdi_high_pic" |
[(set (match_operand:DI 0 "register_operand" "=r") |
(high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))] |
"TARGET_ARCH64 && flag_pic && check_pic (1)" |
- "sethi\t%%hi(%a1), %0") |
+{ |
+#ifdef HAVE_AS_SPARC_GOTDATA_OP |
+ return "sethi\t%%gdop_hix22(%a1), %0"; |
+#else |
+ return "sethi\t%%hi(%a1), %0"; |
+#endif |
+}) |
+ |
+(define_insn "movdi_pic_gotdata_op" |
+ [(set (match_operand:DI 0 "register_operand" "=r") |
+ (unspec:DI [(match_operand:DI 1 "register_operand" "r") |
+ (match_operand:DI 2 "register_operand" "r") |
+ (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))] |
+ "TARGET_ARCH64 && flag_pic && check_pic (1)" |
+{ |
+#ifdef HAVE_AS_SPARC_GOTDATA_OP |
+ return "ldx\t[%1 + %2], %0, %%gdop(%a3)"; |
+#else |
+ return "ldx\t[%1 + %2], %0"; |
+#endif |
+} |
+ [(set_attr "type" "load")]) |
(define_insn "*sethi_di_medlow_embmedany_pic" |
[(set (match_operand:DI 0 "register_operand" "=r") |
@@ -2383,9 +1794,6 @@ |
;; Floating point and vector move instructions |
-;; We don't define V1SI because SI should work just fine. |
-(define_mode_iterator V32 [SF V2HI V4QI]) |
- |
;; Yes, you guessed it right, the former movsf expander. |
(define_expand "mov<V32:mode>" |
[(set (match_operand:V32 0 "nonimmediate_operand" "") |
@@ -2520,8 +1928,6 @@ |
[(set (match_dup 0) (high:SF (match_dup 1))) |
(set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))]) |
-(define_mode_iterator V64 [DF V2SI V4HI V8QI]) |
- |
;; Yes, you again guessed it right, the former movdf expander. |
(define_expand "mov<V64:mode>" |
[(set (match_operand:V64 0 "nonimmediate_operand" "") |
@@ -3063,8 +2469,6 @@ |
;; 3 contains the constant if one is present, but we handle either for |
;; generality (sparc.c puts a constant in operand 2). |
-(define_mode_iterator I [QI HI SI DI]) |
- |
(define_expand "mov<I:mode>cc" |
[(set (match_operand:I 0 "register_operand" "") |
(if_then_else:I (match_operand 1 "comparison_operator" "") |
@@ -3073,21 +2477,27 @@ |
"TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)" |
{ |
enum rtx_code code = GET_CODE (operands[1]); |
+ rtx cc_reg; |
- if (GET_MODE (sparc_compare_op0) == DImode |
+ if (GET_MODE (XEXP (operands[1], 0)) == DImode |
&& ! TARGET_ARCH64) |
FAIL; |
- if (sparc_compare_op1 == const0_rtx |
- && GET_CODE (sparc_compare_op0) == REG |
- && GET_MODE (sparc_compare_op0) == DImode |
+ if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD) |
+ operands[1] |
+ = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1), |
+ GET_CODE (operands[1])); |
+ |
+ if (XEXP (operands[1], 1) == const0_rtx |
+ && GET_CODE (XEXP (operands[1], 0)) == REG |
+ && GET_MODE (XEXP (operands[1], 0)) == DImode |
&& v9_regcmp_p (code)) |
- operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx); |
+ cc_reg = XEXP (operands[1], 0); |
else |
- operands[1] = gen_compare_operator (code); |
-}) |
+ cc_reg = gen_compare_reg (operands[1]); |
-(define_mode_iterator F [SF DF TF]) |
+ operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); |
+}) |
(define_expand "mov<F:mode>cc" |
[(set (match_operand:F 0 "register_operand" "") |
@@ -3097,18 +2507,26 @@ |
"TARGET_V9 && TARGET_FPU" |
{ |
enum rtx_code code = GET_CODE (operands[1]); |
+ rtx cc_reg; |
- if (GET_MODE (sparc_compare_op0) == DImode |
+ if (GET_MODE (XEXP (operands[1], 0)) == DImode |
&& ! TARGET_ARCH64) |
FAIL; |
- if (sparc_compare_op1 == const0_rtx |
- && GET_CODE (sparc_compare_op0) == REG |
- && GET_MODE (sparc_compare_op0) == DImode |
+ if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD) |
+ operands[1] |
+ = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1), |
+ GET_CODE (operands[1])); |
+ |
+ if (XEXP (operands[1], 1) == const0_rtx |
+ && GET_CODE (XEXP (operands[1], 0)) == REG |
+ && GET_MODE (XEXP (operands[1], 0)) == DImode |
&& v9_regcmp_p (code)) |
- operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx); |
+ cc_reg = XEXP (operands[1], 0); |
else |
- operands[1] = gen_compare_operator (code); |
+ cc_reg = gen_compare_reg (operands[1]); |
+ |
+ operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); |
}) |
;; Conditional move define_insns |
@@ -5123,9 +4541,6 @@ |
;; We define DImode `and' so with DImode `not' we can get |
;; DImode `andn'. Other combinations are possible. |
-(define_mode_iterator V64I [DI V2SI V4HI V8QI]) |
-(define_mode_iterator V32I [SI V2HI V4QI]) |
- |
(define_expand "and<V64I:mode>3" |
[(set (match_operand:V64I 0 "register_operand" "") |
(and:V64I (match_operand:V64I 1 "arith_double_operand" "") |
@@ -6917,6 +6332,14 @@ |
"" |
[(set_attr "length" "0")]) |
+(define_expand "probe_stack" |
+ [(set (match_operand 0 "memory_operand" "") (const_int 0))] |
+ "" |
+{ |
+ operands[0] |
+ = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS); |
+}) |
+ |
;; Prepare to return any type including a structure value. |
(define_expand "untyped_return" |
@@ -7037,7 +6460,6 @@ |
emit_move_insn (hard_frame_pointer_rtx, stack); |
emit_use (stack_pointer_rtx); |
- emit_use (static_chain_rtx); |
/* ??? The V9-specific version was disabled in rev 1.65. */ |
emit_jump_insn (gen_goto_handler_and_restore (labreg)); |
@@ -7424,14 +6846,28 @@ |
"ta\t5" |
[(set_attr "type" "trap")]) |
-(define_expand "conditional_trap" |
- [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)]) |
- (match_operand:SI 1 "arith_operand" ""))] |
+(define_expand "ctrapsi4" |
+ [(trap_if (match_operator 0 "noov_compare_operator" |
+ [(match_operand:SI 1 "compare_operand" "") |
+ (match_operand:SI 2 "arith_operand" "")]) |
+ (match_operand 3 ""))] |
"" |
- "operands[2] = gen_compare_reg (GET_CODE (operands[0])); |
- if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode) |
+ "operands[1] = gen_compare_reg (operands[0]); |
+ if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode) |
+ FAIL; |
+ operands[2] = const0_rtx;") |
+ |
+(define_expand "ctrapdi4" |
+ [(trap_if (match_operator 0 "noov_compare_operator" |
+ [(match_operand:DI 1 "compare_operand" "") |
+ (match_operand:DI 2 "arith_operand" "")]) |
+ (match_operand 3 ""))] |
+ "TARGET_ARCH64" |
+ "operands[1] = gen_compare_reg (operands[0]); |
+ if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode) |
FAIL; |
- operands[3] = const0_rtx;") |
+ operands[2] = const0_rtx;") |
+ |
(define_insn "" |
[(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)]) |
@@ -8061,6 +7497,7 @@ |
(match_operand 2 "" "")] |
"" |
{ |
+ rtx result, test; |
#ifdef TARGET_THREAD_SSP_OFFSET |
rtx tlsreg = gen_rtx_REG (Pmode, 7); |
rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET)); |
@@ -8068,19 +7505,18 @@ |
#endif |
if (TARGET_ARCH64) |
{ |
- rtx temp = gen_reg_rtx (Pmode); |
- emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1])); |
- sparc_compare_op0 = temp; |
- sparc_compare_op1 = const0_rtx; |
+ result = gen_reg_rtx (Pmode); |
+ emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1])); |
+ test = gen_rtx_EQ (VOIDmode, result, const0_rtx); |
+ emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2])); |
} |
else |
{ |
emit_insn (gen_stack_protect_testsi (operands[0], operands[1])); |
- sparc_compare_op0 = operands[0]; |
- sparc_compare_op1 = operands[1]; |
- sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG); |
+ result = gen_rtx_REG (CCmode, SPARC_ICC_REG); |
+ test = gen_rtx_EQ (VOIDmode, result, const0_rtx); |
+ emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2])); |
} |
- emit_jump_insn (gen_beq (operands[2])); |
DONE; |
}) |
@@ -8173,7 +7609,7 @@ |
;; (ior (not (op1)) (not (op2))) is the canonical form of NAND. |
-(define_insn "*nand<V64mode>_vis" |
+(define_insn "*nand<V64:mode>_vis" |
[(set (match_operand:V64 0 "register_operand" "=e") |
(ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e")) |
(not:V64 (match_operand:V64 2 "register_operand" "e"))))] |
@@ -8182,7 +7618,7 @@ |
[(set_attr "type" "fga") |
(set_attr "fptype" "double")]) |
-(define_insn "*nand<V32mode>_vis" |
+(define_insn "*nand<V32:mode>_vis" |
[(set (match_operand:V32 0 "register_operand" "=f") |
(ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f")) |
(not:V32 (match_operand:V32 2 "register_operand" "f"))))] |