aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/s390/s390.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/s390/s390.md')
-rw-r--r--gcc/config/s390/s390.md373
1 files changed, 322 insertions, 51 deletions
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 197aa67ebcb..26be40e5906 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -1,5 +1,5 @@
;;- Machine description for GNU compiler -- S/390 / zSeries version.
-;; Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+;; Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and
;; Ulrich Weigand (uweigand@de.ibm.com).
;; This file is part of GNU CC.
@@ -44,6 +44,34 @@
;; s_operand -- Matches a valid S operand in a RS, SI or SS type instruction.
;;
+;;
+;; UNSPEC usage
+;;
+
+(define_constants
+ [; TLS relocation specifiers
+ (UNSPEC_TLSGD 500)
+ (UNSPEC_TLSLDM 501)
+ (UNSPEC_NTPOFF 502)
+ (UNSPEC_DTPOFF 503)
+ (UNSPEC_GOTNTPOFF 504)
+ (UNSPEC_INDNTPOFF 505)
+
+ ; TLS support
+ (UNSPEC_TP 510)
+ (UNSPEC_TLSLDM_NTPOFF 511)
+ (UNSPEC_TLS_LOAD 512)
+ ])
+
+;;
+;; UNSPEC_VOLATILE usage
+;;
+
+(define_constants
+ [; TLS support
+ (UNSPECV_SET_TP 500)
+ ])
+
;; Define an insn type attribute. This is used in function unit delay
;; computations.
@@ -500,6 +528,31 @@
"ltr\\t%0,%0"
[(set_attr "op_type" "RR")])
+(define_insn "*tsthiCCT"
+ [(set (reg 33)
+ (compare (match_operand:HI 0 "nonimmediate_operand" "?Q,d")
+ (match_operand:HI 1 "const0_operand" "")))
+ (set (match_operand:HI 2 "register_operand" "=d,0")
+ (match_dup 0))]
+ "s390_match_ccmode(insn, CCTmode)"
+ "@
+ icm\\t%2,3,%0
+ tml\\t%0,65535"
+ [(set_attr "op_type" "RS,RI")
+ (set_attr "atype" "mem,reg")])
+
+(define_insn "*tsthiCCT_cconly"
+ [(set (reg 33)
+ (compare (match_operand:HI 0 "nonimmediate_operand" "?Q,d")
+ (match_operand:HI 1 "const0_operand" "")))
+ (clobber (match_scratch:HI 2 "=d,X"))]
+ "s390_match_ccmode(insn, CCTmode)"
+ "@
+ icm\\t%2,3,%0
+ tml\\t%0,65535"
+ [(set_attr "op_type" "RS,RI")
+ (set_attr "atype" "mem,reg")])
+
(define_insn "*tsthi"
[(set (reg 33)
(compare (match_operand:HI 0 "s_operand" "Q")
@@ -521,6 +574,30 @@
[(set_attr "op_type" "RS")
(set_attr "atype" "mem")])
+(define_insn "*tstqiCCT"
+ [(set (reg 33)
+ (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,d")
+ (match_operand:QI 1 "const0_operand" "")))
+ (set (match_operand:QI 2 "register_operand" "=d,0")
+ (match_dup 0))]
+ "s390_match_ccmode(insn, CCTmode)"
+ "@
+ icm\\t%2,1,%0
+ tml\\t%0,255"
+ [(set_attr "op_type" "RS,RI")
+ (set_attr "atype" "mem,reg")])
+
+(define_insn "*tstqiCCT_cconly"
+ [(set (reg 33)
+ (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,d")
+ (match_operand:QI 1 "const0_operand" "")))]
+ "s390_match_ccmode(insn, CCTmode)"
+ "@
+ cli\\t%0,0
+ tml\\t%0,255"
+ [(set_attr "op_type" "SI,RI")
+ (set_attr "atype" "mem,reg")])
+
(define_insn "*tstqi"
[(set (reg 33)
(compare (match_operand:QI 0 "s_operand" "Q")
@@ -844,18 +921,15 @@
; movdi instruction pattern(s).
;
-;; If generating PIC code and operands[1] is a symbolic CONST, emit a
-;; move to get the address of the symbolic object from the GOT.
-
(define_expand "movdi"
[(set (match_operand:DI 0 "general_operand" "")
(match_operand:DI 1 "general_operand" ""))]
""
"
{
- /* Handle PIC symbolic constants. */
- if (TARGET_64BIT && flag_pic && SYMBOLIC_CONST (operands[1]))
- emit_pic_move (operands, DImode);
+ /* Handle symbolic constants. */
+ if (TARGET_64BIT && SYMBOLIC_CONST (operands[1]))
+ emit_symbolic_move (operands);
/* During and after reload, we need to force constants
to the literal pool ourselves, if necessary. */
@@ -1008,18 +1082,15 @@
; movsi instruction pattern(s).
;
-;; If generating PIC code and operands[1] is a symbolic CONST, emit a
-;; move to get the address of the symbolic object from the GOT.
-
(define_expand "movsi"
[(set (match_operand:SI 0 "general_operand" "")
(match_operand:SI 1 "general_operand" ""))]
""
"
{
- /* Handle PIC symbolic constants. */
- if (!TARGET_64BIT && flag_pic && SYMBOLIC_CONST (operands[1]))
- emit_pic_move (operands, SImode);
+ /* Handle symbolic constants. */
+ if (!TARGET_64BIT && SYMBOLIC_CONST (operands[1]))
+ emit_symbolic_move (operands);
/* expr.c tries to load an effective address using
force_reg. This fails because we don't have a
@@ -2837,25 +2908,6 @@
; adddi3 instruction pattern(s).
;
-(define_insn "*la_64_cc"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (match_operand:QI 1 "address_operand" "p"))
- (clobber (reg:CC 33))]
- "TARGET_64BIT
- && preferred_la_operand_p (operands[1], 1)"
- "#"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")
- (set_attr "type" "la")])
-
-(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:QI 1 "address_operand" ""))
- (clobber (reg:CC 33))]
- "TARGET_64BIT && reload_completed
- && preferred_la_operand_p (operands[1], 0)"
- [(set (match_dup 0) (match_dup 1))])
-
(define_insn "*adddi3_sign"
[(set (match_operand:DI 0 "register_operand" "=d,d")
(plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
@@ -3025,6 +3077,32 @@
(set_attr "atype" "mem")
(set_attr "type" "la")])
+(define_peephole2
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_operand:QI 1 "address_operand" ""))
+ (clobber (reg:CC 33))])]
+ "TARGET_64BIT
+ && strict_memory_address_p (VOIDmode, operands[1])
+ && preferred_la_operand_p (operands[1])"
+ [(set (match_dup 0) (match_dup 1))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "register_operand" ""))
+ (parallel
+ [(set (match_dup 0)
+ (plus:DI (match_dup 0)
+ (match_operand:DI 2 "nonmemory_operand" "")))
+ (clobber (reg:CC 33))])]
+ "TARGET_64BIT
+ && !reg_overlap_mentioned_p (operands[0], operands[2])
+ && strict_memory_address_p (VOIDmode, gen_rtx_PLUS (DImode, operands[1], operands[2]))
+ && preferred_la_operand_p (gen_rtx_PLUS (DImode, operands[1], operands[2]))"
+ [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
+ "")
+
(define_expand "reload_indi"
[(parallel [(match_operand:DI 0 "register_operand" "=a")
(match_operand:DI 1 "s390_plus_operand" "")
@@ -3041,25 +3119,6 @@
; addsi3 instruction pattern(s).
;
-(define_insn "*la_31_cc"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (match_operand:QI 1 "address_operand" "p"))
- (clobber (reg:CC 33))]
- "!TARGET_64BIT
- && preferred_la_operand_p (operands[1], 1)"
- "#"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")
- (set_attr "type" "la")])
-
-(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (match_operand:QI 1 "address_operand" ""))
- (clobber (reg:CC 33))]
- "!TARGET_64BIT && reload_completed
- && preferred_la_operand_p (operands[1], 0)"
- [(set (match_dup 0) (match_dup 1))])
-
(define_insn "*addsi3_imm_cc"
[(set (reg 33)
(compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "0")
@@ -3208,6 +3267,32 @@
(set_attr "atype" "mem")
(set_attr "type" "la")])
+(define_peephole2
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand" "")
+ (match_operand:QI 1 "address_operand" ""))
+ (clobber (reg:CC 33))])]
+ "!TARGET_64BIT
+ && strict_memory_address_p (VOIDmode, operands[1])
+ && preferred_la_operand_p (operands[1])"
+ [(set (match_dup 0) (match_dup 1))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" ""))
+ (parallel
+ [(set (match_dup 0)
+ (plus:SI (match_dup 0)
+ (match_operand:SI 2 "nonmemory_operand" "")))
+ (clobber (reg:CC 33))])]
+ "!TARGET_64BIT
+ && !reg_overlap_mentioned_p (operands[0], operands[2])
+ && strict_memory_address_p (VOIDmode, gen_rtx_PLUS (SImode, operands[1], operands[2]))
+ && preferred_la_operand_p (gen_rtx_PLUS (SImode, operands[1], operands[2]))"
+ [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
+ "")
+
(define_insn "*la_31_and"
[(set (match_operand:SI 0 "register_operand" "=d")
(and:SI (match_operand:QI 1 "address_operand" "p")
@@ -6452,6 +6537,192 @@
(set_attr "type" "jsr")
(set_attr "atype" "mem")])
+;;
+;;- Thread-local storage support.
+;;
+
+(define_insn "get_tp_64"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=??d,Q")
+ (unspec:DI [(const_int 0)] UNSPEC_TP))]
+ "TARGET_64BIT"
+ "@
+ ear\\t%0,%%a0\;sllg\\t%0,%0,32\;ear\\t%0,%%a1
+ stam\\t%%a0,%%a1,%0"
+ [(set_attr "op_type" "NN,RS")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "o3,*")
+ (set_attr "length" "14,*")])
+
+(define_insn "get_tp_31"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=d,Q")
+ (unspec:SI [(const_int 0)] UNSPEC_TP))]
+ "!TARGET_64BIT"
+ "@
+ ear\\t%0,%%a0
+ stam\\t%%a0,%%a0,%0"
+ [(set_attr "op_type" "RRE,RS")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "set_tp_64"
+ [(unspec_volatile [(match_operand:DI 0 "general_operand" "??d,Q")] UNSPECV_SET_TP)
+ (clobber (match_scratch:SI 1 "=d,X"))]
+ "TARGET_64BIT"
+ "@
+ sar\\t%%a1,%0\;srlg\\t%1,%0,32\;sar\\t%%a0,%1
+ lam\\t%%a0,%%a1,%0"
+ [(set_attr "op_type" "NN,RS")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "o3,*")
+ (set_attr "length" "14,*")])
+
+(define_insn "set_tp_31"
+ [(unspec_volatile [(match_operand:SI 0 "general_operand" "d,Q")] UNSPECV_SET_TP)]
+ "!TARGET_64BIT"
+ "@
+ sar\\t%%a0,%0
+ lam\\t%%a0,%%a0,%0"
+ [(set_attr "op_type" "RRE,RS")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*tls_load_64"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
+ (match_operand:DI 2 "" "")]
+ UNSPEC_TLS_LOAD))]
+ "TARGET_64BIT"
+ "lg\\t%0,%1%J2"
+ [(set_attr "op_type" "RXE")
+ (set_attr "atype" "mem")])
+
+(define_insn "*tls_load_31"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
+ (match_operand:SI 2 "" "")]
+ UNSPEC_TLS_LOAD))]
+ "!TARGET_64BIT"
+ "l\\t%0,%1%J2"
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")])
+
+(define_expand "call_value_tls"
+ [(set (match_operand 0 "" "")
+ (call (const_int 0) (const_int 0)))
+ (use (match_operand 1 "" ""))]
+ ""
+ "
+{
+ rtx insn, sym;
+
+ if (!flag_pic)
+ abort ();
+
+ sym = s390_tls_get_offset ();
+ sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), 113);
+ sym = gen_rtx_CONST (Pmode, sym);
+
+ /* Unless we can use the bras(l) insn, force the
+ routine address into a register. */
+ if (!TARGET_SMALL_EXEC && !TARGET_64BIT)
+ {
+ rtx target = gen_reg_rtx (Pmode);
+ emit_move_insn (target, sym);
+ sym = target;
+ }
+
+ sym = gen_rtx_MEM (QImode, sym);
+
+ /* Emit insn. */
+ insn = emit_call_insn (
+ gen_call_value_tls_exp (operands[0], sym, const0_rtx,
+ gen_rtx_REG (Pmode, RETURN_REGNUM),
+ operands[1]));
+
+ /* The calling convention of __tls_get_offset uses the
+ GOT register implicitly. */
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), operands[0]);
+ CONST_OR_PURE_CALL_P (insn) = 1;
+
+ DONE;
+}")
+
+(define_expand "call_value_tls_exp"
+ [(parallel [(set (match_operand 0 "" "")
+ (call (match_operand 1 "" "")
+ (match_operand 2 "" "")))
+ (clobber (match_operand 3 "" ""))
+ (use (match_operand 4 "" ""))])]
+ ""
+ "")
+
+(define_insn "brasl_tls"
+ [(set (match_operand 0 "register_operand" "=df")
+ (call (mem:QI (match_operand:DI 1 "bras_sym_operand" "X"))
+ (match_operand:SI 2 "const_int_operand" "n")))
+ (clobber (match_operand:DI 3 "register_operand" "=r"))
+ (use (match_operand:DI 4 "" ""))]
+ "TARGET_64BIT"
+ "brasl\\t%3,%1%J4"
+ [(set_attr "op_type" "RIL")
+ (set_attr "type" "jsr")])
+
+(define_insn "bras_tls"
+ [(set (match_operand 0 "register_operand" "=df")
+ (call (mem:QI (match_operand:SI 1 "bras_sym_operand" "X"))
+ (match_operand:SI 2 "const_int_operand" "n")))
+ (clobber (match_operand:SI 3 "register_operand" "=r"))
+ (use (match_operand:SI 4 "" ""))]
+ "TARGET_SMALL_EXEC"
+ "bras\\t%3,%1%J4"
+ [(set_attr "op_type" "RI")
+ (set_attr "type" "jsr")])
+
+(define_insn "basr_tls_64"
+ [(set (match_operand 0 "register_operand" "=df")
+ (call (mem:QI (match_operand:DI 1 "register_operand" "a"))
+ (match_operand:SI 2 "const_int_operand" "n")))
+ (clobber (match_operand:DI 3 "register_operand" "=r"))
+ (use (match_operand:DI 4 "" ""))]
+ "TARGET_64BIT"
+ "basr\\t%3,%1%J4"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "jsr")])
+
+(define_insn "basr_tls_31"
+ [(set (match_operand 0 "register_operand" "=df")
+ (call (mem:QI (match_operand:SI 1 "register_operand" "a"))
+ (match_operand:SI 2 "const_int_operand" "n")))
+ (clobber (match_operand:SI 3 "register_operand" "=r"))
+ (use (match_operand:SI 4 "" ""))]
+ "!TARGET_64BIT"
+ "basr\\t%3,%1%J4"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "jsr")
+ (set_attr "atype" "mem")])
+
+(define_insn "bas_tls_64"
+ [(set (match_operand 0 "register_operand" "=df")
+ (call (mem:QI (match_operand:QI 1 "address_operand" "p"))
+ (match_operand:SI 2 "const_int_operand" "n")))
+ (clobber (match_operand:DI 3 "register_operand" "=r"))
+ (use (match_operand:DI 4 "" ""))]
+ "TARGET_64BIT"
+ "bas\\t%3,%a1%J4"
+ [(set_attr "op_type" "RX")
+ (set_attr "type" "jsr")
+ (set_attr "atype" "mem")])
+
+(define_insn "bas_tls_31"
+ [(set (match_operand 0 "register_operand" "=df")
+ (call (mem:QI (match_operand:QI 1 "address_operand" "p"))
+ (match_operand:SI 2 "const_int_operand" "n")))
+ (clobber (match_operand:SI 3 "register_operand" "=r"))
+ (use (match_operand:SI 4 "" ""))]
+ "!TARGET_64BIT"
+ "bas\\t%3,%a1%J4"
+ [(set_attr "op_type" "RX")
+ (set_attr "type" "jsr")
+ (set_attr "atype" "mem")])
;;
;;- Miscellaneous instructions.