aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/sparc/sparc.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/sparc/sparc.md')
-rw-r--r--gcc/config/sparc/sparc.md106
1 files changed, 75 insertions, 31 deletions
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index f8f5495..20cfca8 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -56,6 +56,8 @@
(match_operand 2 "arith_double_operand" ""))
(const_int 1) (const_int 3))
+ (eq_attr "type" "multi") (const_int 2)
+
(eq_attr "type" "move,unary")
(if_then_else (ior (match_operand 1 "arith_operand" "")
(match_operand 1 "arith_double_operand" ""))
@@ -451,8 +453,7 @@
(clobber (reg:CC 0))]
""
"subcc %%g0,%1,%%g0\;addx %2,-1,%0"
- [(set_attr "type" "unary")
- (set_attr "length" "2")])
+ [(set_attr "length" "2")])
;; We can also do GEU and LTU directly, but these operate after a
;; compare.
@@ -518,8 +519,7 @@
(plus:SI (match_operand:SI 1 "arith_operand" "%r")
(match_operand:SI 2 "arith_operand" "rI"))))]
""
- "addx %1,%2,%0"
- [(set_attr "type" "binary")])
+ "addx %1,%2,%0")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -536,8 +536,7 @@
(match_operand:SI 2 "arith_operand" "rI"))
(ltu:SI (reg:CC 0) (const_int 0))))]
""
- "subx %1,%2,%0"
- [(set_attr "type" "binary")])
+ "subx %1,%2,%0")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -545,8 +544,7 @@
(plus:SI (ltu:SI (reg:CC 0) (const_int 0))
(match_operand:SI 2 "arith_operand" "rI"))))]
""
- "subx %1,%2,%0"
- [(set_attr "type" "binary")])
+ "subx %1,%2,%0")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -572,7 +570,8 @@
(match_operator:SI 1 "normal_comp_operator" [(reg 0) (const_int 0)]))]
""
"* return output_scc_insn (operands, insn); "
- [(set_attr "type" "multi")])
+ [(set_attr "type" "multi")
+ (set_attr "length" "3")])
;; These control RTL generation for conditional jump insns
@@ -734,7 +733,7 @@
;; subreg sets.
;; We cannot combine the similar 'r' and 'f' constraints, because it causes
-;; problems with register allocation. Reload might try to put an interger
+;; problems with register allocation. Reload might try to put an integer
;; in an fp register, or an fp number is an integer register.
(define_insn ""
@@ -751,8 +750,8 @@
st %r1,%0
st %r1,%0
st %r1,[%%fp-4]\;ld [%%fp-4],%0"
- [(set_attr "type" "move,move,load,load,store,store,misc")
- (set_attr "length" "*,1,*,*,*,*,2")])
+ [(set_attr "type" "move,move,load,load,store,store,multi")
+ (set_attr "length" "*,1,*,*,*,*,*")])
;; Special pic pattern, for loading the address of a label into a register.
;; It clobbers o7 because the call puts the return address (i.e. pc value)
@@ -803,6 +802,16 @@
[(set_attr "type" "move")
(set_attr "length" "2")])
+;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
+;; confuse them with real addresses.
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
+ "check_pic (1)"
+ "sethi %%hi(%a1),%0"
+ [(set_attr "type" "move")
+ (set_attr "length" "1")])
+
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(high:SI (match_operand 1 "" "")))]
@@ -836,6 +845,18 @@
;; is not an "arith_operand".
[(set_attr "length" "1")])
+;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
+;; confuse them with real addresses.
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
+ ""
+ "or %1,%%lo(%a2),%0"
+ ;; Need to set length for this arith insn because operand2
+ ;; is not an "arith_operand".
+ [(set_attr "length" "1")])
+
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
@@ -944,7 +965,7 @@
(define_expand "movstrsi"
[(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
(mem:BLK (match_operand:BLK 1 "general_operand" "")))
- (use (match_operand:SI 2 "arith32_operand" ""))
+ (use (match_operand:SI 2 "nonmemory_operand" ""))
(use (match_operand:SI 3 "immediate_operand" ""))
(clobber (match_dup 0))
(clobber (match_dup 1))
@@ -967,7 +988,7 @@
(define_insn ""
[(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))
(mem:BLK (match_operand:SI 1 "register_operand" "r")))
- (use (match_operand:SI 2 "arith32_operand" "rn"))
+ (use (match_operand:SI 2 "nonmemory_operand" "rn"))
(use (match_operand:SI 3 "immediate_operand" "i"))
(clobber (match_dup 0))
(clobber (match_dup 1))
@@ -976,7 +997,8 @@
(clobber (reg:SI 1))]
""
"* return output_block_move (operands);"
- [(set_attr "type" "multi")])
+ [(set_attr "type" "multi")
+ (set_attr "length" "6")])
;; Floating point move insns
@@ -1071,7 +1093,7 @@
return output_fp_move_double (operands);
return output_move_double (operands);
}"
- [(set_attr "type" "move,store,load,misc,multi,fp,fpload,multi,fpstore")
+ [(set_attr "type" "move,store,load,multi,multi,fp,fpload,multi,fpstore")
(set_attr "length" "2,3,3,3,3,2,3,3,3")])
;; Floating-point move insns.
@@ -1099,8 +1121,7 @@
ld %1,%0
st %r1,%0
st %r1,%0"
- [(set_attr "type" "fp,move,multi,fpload,load,fpstore,store")
- (set_attr "length" "*,*,2,*,*,*,*")])
+ [(set_attr "type" "fp,move,multi,fpload,load,fpstore,store")])
(define_insn ""
[(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
@@ -1277,6 +1298,27 @@
"ldsb %1,%0"
[(set_attr "type" "load")])
+;; Special pattern for optimizing bit-field compares. This is needed
+;; because combine uses this as a canonical form.
+
+(define_insn ""
+ [(set (reg:CC 0)
+ (compare:CC
+ (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+ (match_operand:SI 1 "small_int" "n")
+ (match_operand:SI 2 "small_int" "n"))
+ (const_int 0)))]
+ "INTVAL (operands[2]) > 19"
+ "*
+{
+ int len = INTVAL (operands[1]);
+ int pos = 32 - INTVAL (operands[2]) - len;
+ unsigned mask = ((1 << len) - 1) << pos;
+
+ operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
+ return \"andcc %0,%1,%%g0\";
+}")
+
;; Conversions between float and double.
(define_insn "extendsfdf2"
@@ -1372,7 +1414,7 @@
{
rtx op2 = operands[2];
- /* If constant is postive, upper bits zeroed, otherwise unchanged
+ /* If constant is positive, upper bits zeroed, otherwise unchanged
* give the assembler a chance to pick the move instruction. */
if (GET_CODE (op2) == CONST_INT)
{
@@ -1430,8 +1472,8 @@
{
rtx op2 = operands[2];
- /* If constant is postive, upper bits zeroed, otherwise unchanged
- * give the assembler a chance to pick the move instruction. */
+ /* If constant is positive, upper bits zeroed, otherwise unchanged
+ /* If constant is positive, upper bits zeroed, otherwise unchanged
if (GET_CODE (op2) == CONST_INT)
{
int sign = INTVAL (op2);
@@ -1498,7 +1540,7 @@
{
rtx op2 = operands[2];
- /* If constant is postive, upper bits zeroed, otherwise unchanged
+ /* If constant is positive, upper bits zeroed, otherwise unchanged
* give the assembler a chance to pick the move instruction. */
if (GET_CODE (op2) == CONST_INT)
{
@@ -1558,7 +1600,7 @@
{
rtx op2 = operands[2];
- /* If constant is postive, upper bits zeroed, otherwise unchanged
+ /* If constant is positive, upper bits zeroed, otherwise unchanged
* give the assembler a chance to pick the move instruction. */
if (GET_CODE (op2) == CONST_INT)
{
@@ -2004,7 +2046,7 @@
;; Unconditional and other jump instructions
;; Note that for the Sparc, by setting the annul bit on an unconditional
;; branch, the following insn is never executed. This saves us a nop,
-;; but requires a debugger which can handle annuled branches.
+;; but requires a debugger which can handle annulled branches.
(define_insn "jump"
[(set (pc) (label_ref (match_operand 0 "" "")))]
""
@@ -2263,12 +2305,15 @@
(define_insn ""
[(unspec_volatile [(const_int 0)] 0)]
""
- "ta 3")
+ "ta 3"
+ [(set_attr "type" "misc")])
(define_insn ""
[(unspec_volatile [(const_int 0)] 1)]
""
- "jmp %%o0+0\;restore")
+ "jmp %%o0+0\;restore"
+ [(set_attr "type" "misc")
+ (set_attr "length" "2")])
;(define_insn "tail_call" ;; tail call
; [(set (pc) (match_operand 0 "memory_operand" "m"))]
@@ -2469,8 +2514,7 @@
(const_int 0)))]
"rtx_equal_p (operands[2], operands[0])
|| rtx_equal_p (operands[2], operands[1])"
- "orcc %1,%%g0,%0"
- [(set_attr "type" "move")])
+ "orcc %1,%%g0,%0")
;; Do {sign,zero}-extended compares somewhat more efficiently.
;; ??? Is this now the Right Way to do this? Or will SCRATCH
@@ -2604,7 +2648,8 @@
(match_operand:SF 0 "register_operand" "f"))
(return)]
"! TARGET_EPILOGUE"
- "ret\;fmovs %0,%%f0")
+ "ret\;fmovs %0,%%f0"
+ [(set_attr "type" "multi")])
;; Now peepholes to go a call followed by a jump.
@@ -2638,8 +2683,7 @@
(clobber (reg:CC 0))])
(set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]
""
- "subxcc %r1,0,%0"
- [(set_attr "type" "compare")])
+ "subxcc %r1,0,%0")
;;- Local variables:
;;- mode:emacs-lisp