Commit c5aa1d12 by Ulrich Weigand Committed by Ulrich Weigand

s390-protos.h (s390_split_access_reg): Add prototype.

	* config/s390/s390-protos.h (s390_split_access_reg): Add prototype.
	* config/s390/s390.c (s390_split_access_reg): New function.
	(regclass_map): Add access registers.
	(get_thread_pointer): Use access register instead of UNSPEC_TP.
	* config/s390/s390.h (FIRST_PSEUDO_REGISTER): Set to 38.
	(ACCESS_REGNO_P, ACCESS_REG_P): New macros.
	(TP_REGNUM): New define.
	(FIXED_REGISTERS, CALL_USED_REGISTERS, CALL_REALLY_USED_REGISTERS,
	REG_ALLOC_ORDER): Add access registers.
	(HARD_REGNO_NREGS, HARD_REGNO_MODE_OK, CLASS_MAX_NREGS,
	CANNOT_CHANGE_MODE_CLASS): Support access registers.
	(enum reg_class): Add ACCESS_REGS.
	(REG_CLASS_NAMES, REG_CLASS_CONTENTS): Likewise.
	(REG_CLASS_FROM_LETTER): Add 't' constraint.
	(REGISTER_NAMES): Add access registers.
	* config/s390/s390.md (UNSPEC_TP): Remove.
	("*movdi_64"): Add access register alternatives.  Provide splitters
	to split DImode access register <-> GPR moves into SImode moves.
	("*movsi_zarch", "*movsi_esa"): Add access register alternatives.
	("movstrictsi"): Likewise.
	("get_tp_64", "get_tp_31"): Reimplement using access registers.
	("set_tp_64", "set_tp_31"): Likewise.
	("*set_tp"): New insn.

From-SVN: r90036
parent 57f60923
2004-11-03 Ulrich Weigand <uweigand@de.ibm.com>
* config/s390/s390-protos.h (s390_split_access_reg): Add prototype.
* config/s390/s390.c (s390_split_access_reg): New function.
(regclass_map): Add access registers.
(get_thread_pointer): Use access register instead of UNSPEC_TP.
* config/s390/s390.h (FIRST_PSEUDO_REGISTER): Set to 38.
(ACCESS_REGNO_P, ACCESS_REG_P): New macros.
(TP_REGNUM): New define.
(FIXED_REGISTERS, CALL_USED_REGISTERS, CALL_REALLY_USED_REGISTERS,
REG_ALLOC_ORDER): Add access registers.
(HARD_REGNO_NREGS, HARD_REGNO_MODE_OK, CLASS_MAX_NREGS,
CANNOT_CHANGE_MODE_CLASS): Support access registers.
(enum reg_class): Add ACCESS_REGS.
(REG_CLASS_NAMES, REG_CLASS_CONTENTS): Likewise.
(REG_CLASS_FROM_LETTER): Add 't' constraint.
(REGISTER_NAMES): Add access registers.
* config/s390/s390.md (UNSPEC_TP): Remove.
("*movdi_64"): Add access register alternatives. Provide splitters
to split DImode access register <-> GPR moves into SImode moves.
("*movsi_zarch", "*movsi_esa"): Add access register alternatives.
("movstrictsi"): Likewise.
("get_tp_64", "get_tp_31"): Reimplement using access registers.
("set_tp_64", "set_tp_31"): Likewise.
("*set_tp"): New insn.
2004-11-03 Kazu Hirata <kazu@cs.umass.edu> 2004-11-03 Kazu Hirata <kazu@cs.umass.edu>
* tree-phinodes.c (resize_phi_node): Copy only a portion of * tree-phinodes.c (resize_phi_node): Copy only a portion of
......
...@@ -90,6 +90,7 @@ extern void s390_expand_logical_operator (enum rtx_code, ...@@ -90,6 +90,7 @@ extern void s390_expand_logical_operator (enum rtx_code,
extern bool s390_logical_operator_ok_p (rtx *); extern bool s390_logical_operator_ok_p (rtx *);
extern void s390_narrow_logical_operator (enum rtx_code, rtx *, rtx *); extern void s390_narrow_logical_operator (enum rtx_code, rtx *, rtx *);
extern bool s390_pool_operand (rtx); extern bool s390_pool_operand (rtx);
extern void s390_split_access_reg (rtx, rtx *, rtx *);
extern bool s390_output_addr_const_extra (FILE*, rtx); extern bool s390_output_addr_const_extra (FILE*, rtx);
extern void print_operand_address (FILE *, rtx); extern void print_operand_address (FILE *, rtx);
......
...@@ -1355,7 +1355,8 @@ const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] = ...@@ -1355,7 +1355,8 @@ const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS,
FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS,
FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS,
ADDR_REGS, CC_REGS, ADDR_REGS, ADDR_REGS ADDR_REGS, CC_REGS, ADDR_REGS, ADDR_REGS,
ACCESS_REGS, ACCESS_REGS
}; };
/* Return attribute type of insn. */ /* Return attribute type of insn. */
...@@ -2019,6 +2020,22 @@ store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) ...@@ -2019,6 +2020,22 @@ store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
return 1; return 1;
} }
/* Split DImode access register reference REG (on 64-bit) into its constituent
low and high parts, and store them into LO and HI. Note that gen_lowpart/
gen_highpart cannot be used as they assume all registers are word-sized,
while our access registers have only half that size. */
void
s390_split_access_reg (rtx reg, rtx *lo, rtx *hi)
{
gcc_assert (TARGET_64BIT);
gcc_assert (ACCESS_REG_P (reg));
gcc_assert (GET_MODE (reg) == DImode);
gcc_assert (!(REGNO (reg) & 1));
*lo = gen_rtx_REG (SImode, REGNO (reg) + 1);
*hi = gen_rtx_REG (SImode, REGNO (reg));
}
/* Return true if OP contains a symbol reference */ /* Return true if OP contains a symbol reference */
...@@ -3033,10 +3050,9 @@ legitimize_pic_address (rtx orig, rtx reg) ...@@ -3033,10 +3050,9 @@ legitimize_pic_address (rtx orig, rtx reg)
static rtx static rtx
get_thread_pointer (void) get_thread_pointer (void)
{ {
rtx tp; rtx tp = gen_reg_rtx (Pmode);
tp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TP); emit_move_insn (tp, gen_rtx_REG (Pmode, TP_REGNUM));
tp = force_reg (Pmode, tp);
mark_reg_pointer (tp, BITS_PER_WORD); mark_reg_pointer (tp, BITS_PER_WORD);
return tp; return tp;
......
...@@ -307,13 +307,17 @@ if (INTEGRAL_MODE_P (MODE) && \ ...@@ -307,13 +307,17 @@ if (INTEGRAL_MODE_P (MODE) && \
GPR 14: Return address register GPR 14: Return address register
GPR 15: Stack pointer GPR 15: Stack pointer
Registers 32-34 are 'fake' hard registers that do not Registers 32-35 are 'fake' hard registers that do not
correspond to actual hardware: correspond to actual hardware:
Reg 32: Argument pointer Reg 32: Argument pointer
Reg 33: Condition code Reg 33: Condition code
Reg 34: Frame pointer */ Reg 34: Frame pointer
Reg 35: Return address pointer
#define FIRST_PSEUDO_REGISTER 36 Registers 36 and 37 are mapped to access registers
0 and 1, used to implement thread-local storage. */
#define FIRST_PSEUDO_REGISTER 38
/* Standard register usage. */ /* Standard register usage. */
#define GENERAL_REGNO_P(N) ((int)(N) >= 0 && (N) < 16) #define GENERAL_REGNO_P(N) ((int)(N) >= 0 && (N) < 16)
...@@ -321,17 +325,20 @@ if (INTEGRAL_MODE_P (MODE) && \ ...@@ -321,17 +325,20 @@ if (INTEGRAL_MODE_P (MODE) && \
#define FP_REGNO_P(N) ((N) >= 16 && (N) < (TARGET_IEEE_FLOAT? 32 : 20)) #define FP_REGNO_P(N) ((N) >= 16 && (N) < (TARGET_IEEE_FLOAT? 32 : 20))
#define CC_REGNO_P(N) ((N) == 33) #define CC_REGNO_P(N) ((N) == 33)
#define FRAME_REGNO_P(N) ((N) == 32 || (N) == 34 || (N) == 35) #define FRAME_REGNO_P(N) ((N) == 32 || (N) == 34 || (N) == 35)
#define ACCESS_REGNO_P(N) ((N) == 36 || (N) == 37)
#define GENERAL_REG_P(X) (REG_P (X) && GENERAL_REGNO_P (REGNO (X))) #define GENERAL_REG_P(X) (REG_P (X) && GENERAL_REGNO_P (REGNO (X)))
#define ADDR_REG_P(X) (REG_P (X) && ADDR_REGNO_P (REGNO (X))) #define ADDR_REG_P(X) (REG_P (X) && ADDR_REGNO_P (REGNO (X)))
#define FP_REG_P(X) (REG_P (X) && FP_REGNO_P (REGNO (X))) #define FP_REG_P(X) (REG_P (X) && FP_REGNO_P (REGNO (X)))
#define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X))) #define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
#define FRAME_REG_P(X) (REG_P (X) && FRAME_REGNO_P (REGNO (X))) #define FRAME_REG_P(X) (REG_P (X) && FRAME_REGNO_P (REGNO (X)))
#define ACCESS_REG_P(X) (REG_P (X) && ACCESS_REGNO_P (REGNO (X)))
#define SIBCALL_REGNUM 1 #define SIBCALL_REGNUM 1
#define BASE_REGNUM 13 #define BASE_REGNUM 13
#define RETURN_REGNUM 14 #define RETURN_REGNUM 14
#define CC_REGNUM 33 #define CC_REGNUM 33
#define TP_REGNUM 36
/* Set up fixed registers and calling convention: /* Set up fixed registers and calling convention:
...@@ -342,6 +349,7 @@ if (INTEGRAL_MODE_P (MODE) && \ ...@@ -342,6 +349,7 @@ if (INTEGRAL_MODE_P (MODE) && \
GPR 14 is always fixed on S/390 machines (as return address). GPR 14 is always fixed on S/390 machines (as return address).
GPR 15 is always fixed (as stack pointer). GPR 15 is always fixed (as stack pointer).
The 'fake' hard registers are call-clobbered and fixed. The 'fake' hard registers are call-clobbered and fixed.
The access registers are call-saved and fixed.
On 31-bit, FPRs 18-19 are call-clobbered; On 31-bit, FPRs 18-19 are call-clobbered;
on 64-bit, FPRs 24-31 are call-clobbered. on 64-bit, FPRs 24-31 are call-clobbered.
...@@ -356,7 +364,8 @@ if (INTEGRAL_MODE_P (MODE) && \ ...@@ -356,7 +364,8 @@ if (INTEGRAL_MODE_P (MODE) && \
0, 0, 0, 0, \ 0, 0, 0, 0, \
0, 0, 0, 0, \ 0, 0, 0, 0, \
0, 0, 0, 0, \ 0, 0, 0, 0, \
1, 1, 1, 1 } 1, 1, 1, 1, \
1, 1 }
#define CALL_USED_REGISTERS \ #define CALL_USED_REGISTERS \
{ 1, 1, 1, 1, \ { 1, 1, 1, 1, \
...@@ -367,7 +376,8 @@ if (INTEGRAL_MODE_P (MODE) && \ ...@@ -367,7 +376,8 @@ if (INTEGRAL_MODE_P (MODE) && \
1, 1, 1, 1, \ 1, 1, 1, 1, \
1, 1, 1, 1, \ 1, 1, 1, 1, \
1, 1, 1, 1, \ 1, 1, 1, 1, \
1, 1, 1, 1 } 1, 1, 1, 1, \
1, 1 }
#define CALL_REALLY_USED_REGISTERS \ #define CALL_REALLY_USED_REGISTERS \
{ 1, 1, 1, 1, \ { 1, 1, 1, 1, \
...@@ -378,7 +388,8 @@ if (INTEGRAL_MODE_P (MODE) && \ ...@@ -378,7 +388,8 @@ if (INTEGRAL_MODE_P (MODE) && \
1, 1, 1, 1, \ 1, 1, 1, 1, \
1, 1, 1, 1, \ 1, 1, 1, 1, \
1, 1, 1, 1, \ 1, 1, 1, 1, \
1, 1, 1, 1 } 1, 1, 1, 1, \
0, 0 }
#define CONDITIONAL_REGISTER_USAGE s390_conditional_register_usage () #define CONDITIONAL_REGISTER_USAGE s390_conditional_register_usage ()
...@@ -387,7 +398,7 @@ if (INTEGRAL_MODE_P (MODE) && \ ...@@ -387,7 +398,7 @@ if (INTEGRAL_MODE_P (MODE) && \
{ 1, 2, 3, 4, 5, 0, 13, 12, 11, 10, 9, 8, 7, 6, 14, \ { 1, 2, 3, 4, 5, 0, 13, 12, 11, 10, 9, 8, 7, 6, 14, \
16, 17, 18, 19, 20, 21, 22, 23, \ 16, 17, 18, 19, 20, 21, 22, 23, \
24, 25, 26, 27, 28, 29, 30, 31, \ 24, 25, 26, 27, 28, 29, 30, 31, \
15, 32, 33, 34, 35 } 15, 32, 33, 34, 35, 36, 37 }
/* Fitting values into registers. */ /* Fitting values into registers. */
...@@ -411,6 +422,8 @@ if (INTEGRAL_MODE_P (MODE) && \ ...@@ -411,6 +422,8 @@ if (INTEGRAL_MODE_P (MODE) && \
(GET_MODE_CLASS(MODE) == MODE_COMPLEX_FLOAT ? 2 : 1) : \ (GET_MODE_CLASS(MODE) == MODE_COMPLEX_FLOAT ? 2 : 1) : \
GENERAL_REGNO_P(REGNO)? \ GENERAL_REGNO_P(REGNO)? \
((GET_MODE_SIZE(MODE)+UNITS_PER_WORD-1) / UNITS_PER_WORD) : \ ((GET_MODE_SIZE(MODE)+UNITS_PER_WORD-1) / UNITS_PER_WORD) : \
ACCESS_REGNO_P(REGNO)? \
((GET_MODE_SIZE(MODE)+32-1) / 32) : \
1) 1)
#define HARD_REGNO_MODE_OK(REGNO, MODE) \ #define HARD_REGNO_MODE_OK(REGNO, MODE) \
...@@ -424,6 +437,9 @@ if (INTEGRAL_MODE_P (MODE) && \ ...@@ -424,6 +437,9 @@ if (INTEGRAL_MODE_P (MODE) && \
GET_MODE_CLASS (MODE) == MODE_CC : \ GET_MODE_CLASS (MODE) == MODE_CC : \
FRAME_REGNO_P(REGNO)? \ FRAME_REGNO_P(REGNO)? \
(enum machine_mode) (MODE) == Pmode : \ (enum machine_mode) (MODE) == Pmode : \
ACCESS_REGNO_P(REGNO)? \
(((MODE) == SImode || ((enum machine_mode) (MODE) == Pmode)) \
&& (HARD_REGNO_NREGS(REGNO, MODE) == 1 || !((REGNO) & 1))) : \
0) 0)
#define MODES_TIEABLE_P(MODE1, MODE2) \ #define MODES_TIEABLE_P(MODE1, MODE2) \
...@@ -435,48 +451,54 @@ if (INTEGRAL_MODE_P (MODE) && \ ...@@ -435,48 +451,54 @@ if (INTEGRAL_MODE_P (MODE) && \
#define CLASS_MAX_NREGS(CLASS, MODE) \ #define CLASS_MAX_NREGS(CLASS, MODE) \
((CLASS) == FP_REGS ? \ ((CLASS) == FP_REGS ? \
(GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT ? 2 : 1) : \ (GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT ? 2 : 1) : \
(CLASS) == ACCESS_REGS ? \
(GET_MODE_SIZE (MODE) + 32 - 1) / 32 : \
(GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
/* If a 4-byte value is loaded into a FPR, it is placed into the /* If a 4-byte value is loaded into a FPR, it is placed into the
*upper* half of the register, not the lower. Therefore, we *upper* half of the register, not the lower. Therefore, we
cannot use SUBREGs to switch between modes in FP registers. */ cannot use SUBREGs to switch between modes in FP registers.
Likewise for access registers, since they have only half the
word size on 64-bit. */
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
(GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
? reg_classes_intersect_p (FP_REGS, CLASS) : 0) ? reg_classes_intersect_p (FP_REGS, CLASS) \
|| reg_classes_intersect_p (ACCESS_REGS, CLASS) : 0)
/* Register classes. */ /* Register classes. */
/* We use the following register classes: /* We use the following register classes:
GENERAL_REGS All general purpose registers GENERAL_REGS All general purpose registers
CC_REGS Contains only the condition code register
ADDR_REGS All general purpose registers except %r0 ADDR_REGS All general purpose registers except %r0
(These registers can be used in address generation) (These registers can be used in address generation)
ADDR_CC_REGS Union of ADDR_REGS and CC_REGS
GENERAL_CC_REGS Union of GENERAL_REGS and CC_REGS
FP_REGS All floating point registers FP_REGS All floating point registers
CC_REGS The condition code register
ACCESS_REGS The access registers
GENERAL_FP_REGS Union of GENERAL_REGS and FP_REGS GENERAL_FP_REGS Union of GENERAL_REGS and FP_REGS
ADDR_FP_REGS Union of ADDR_REGS and FP_REGS ADDR_FP_REGS Union of ADDR_REGS and FP_REGS
GENERAL_CC_REGS Union of GENERAL_REGS and CC_REGS
ADDR_CC_REGS Union of ADDR_REGS and CC_REGS
NO_REGS No registers NO_REGS No registers
ALL_REGS All registers ALL_REGS All registers
Note that the 'fake' frame pointer and argument pointer registers Note that the 'fake' frame pointer and argument pointer registers
are included amongst the address registers here. The condition are included amongst the address registers here. */
code register is only included in ALL_REGS. */
enum reg_class enum reg_class
{ {
NO_REGS, CC_REGS, ADDR_REGS, GENERAL_REGS, NO_REGS, CC_REGS, ADDR_REGS, GENERAL_REGS, ACCESS_REGS,
ADDR_CC_REGS, GENERAL_CC_REGS, ADDR_CC_REGS, GENERAL_CC_REGS,
FP_REGS, ADDR_FP_REGS, GENERAL_FP_REGS, FP_REGS, ADDR_FP_REGS, GENERAL_FP_REGS,
ALL_REGS, LIM_REG_CLASSES ALL_REGS, LIM_REG_CLASSES
}; };
#define N_REG_CLASSES (int) LIM_REG_CLASSES #define N_REG_CLASSES (int) LIM_REG_CLASSES
#define REG_CLASS_NAMES \ #define REG_CLASS_NAMES \
{ "NO_REGS", "CC_REGS", "ADDR_REGS", "GENERAL_REGS", "ADDR_CC_REGS", \ { "NO_REGS", "CC_REGS", "ADDR_REGS", "GENERAL_REGS", "ACCESS_REGS", \
"GENERAL_CC_REGS", "FP_REGS", "ADDR_FP_REGS", "GENERAL_FP_REGS", "ALL_REGS" } "ADDR_CC_REGS", "GENERAL_CC_REGS", \
"FP_REGS", "ADDR_FP_REGS", "GENERAL_FP_REGS", "ALL_REGS" }
/* Class -> register mapping. */ /* Class -> register mapping. */
#define REG_CLASS_CONTENTS \ #define REG_CLASS_CONTENTS \
...@@ -485,12 +507,13 @@ enum reg_class ...@@ -485,12 +507,13 @@ enum reg_class
{ 0x00000000, 0x00000002 }, /* CC_REGS */ \ { 0x00000000, 0x00000002 }, /* CC_REGS */ \
{ 0x0000fffe, 0x0000000d }, /* ADDR_REGS */ \ { 0x0000fffe, 0x0000000d }, /* ADDR_REGS */ \
{ 0x0000ffff, 0x0000000d }, /* GENERAL_REGS */ \ { 0x0000ffff, 0x0000000d }, /* GENERAL_REGS */ \
{ 0x00000000, 0x00000030 }, /* ACCESS_REGS */ \
{ 0x0000fffe, 0x0000000f }, /* ADDR_CC_REGS */ \ { 0x0000fffe, 0x0000000f }, /* ADDR_CC_REGS */ \
{ 0x0000ffff, 0x0000000f }, /* GENERAL_CC_REGS */ \ { 0x0000ffff, 0x0000000f }, /* GENERAL_CC_REGS */ \
{ 0xffff0000, 0x00000000 }, /* FP_REGS */ \ { 0xffff0000, 0x00000000 }, /* FP_REGS */ \
{ 0xfffffffe, 0x0000000d }, /* ADDR_FP_REGS */ \ { 0xfffffffe, 0x0000000d }, /* ADDR_FP_REGS */ \
{ 0xffffffff, 0x0000000d }, /* GENERAL_FP_REGS */ \ { 0xffffffff, 0x0000000d }, /* GENERAL_FP_REGS */ \
{ 0xffffffff, 0x0000000f }, /* ALL_REGS */ \ { 0xffffffff, 0x0000003f }, /* ALL_REGS */ \
} }
/* Register -> class mapping. */ /* Register -> class mapping. */
...@@ -543,7 +566,8 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER]; ...@@ -543,7 +566,8 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
((C) == 'a' ? ADDR_REGS : \ ((C) == 'a' ? ADDR_REGS : \
(C) == 'd' ? GENERAL_REGS : \ (C) == 'd' ? GENERAL_REGS : \
(C) == 'f' ? FP_REGS : \ (C) == 'f' ? FP_REGS : \
(C) == 'c' ? CC_REGS : NO_REGS) (C) == 'c' ? CC_REGS : \
(C) == 't' ? ACCESS_REGS : NO_REGS)
#define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR) \ #define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR) \
s390_const_ok_for_constraint_p ((VALUE), (C), (STR)) s390_const_ok_for_constraint_p ((VALUE), (C), (STR))
...@@ -976,7 +1000,7 @@ extern int flag_pic; ...@@ -976,7 +1000,7 @@ extern int flag_pic;
"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", \ "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", \
"%f0", "%f2", "%f4", "%f6", "%f1", "%f3", "%f5", "%f7", \ "%f0", "%f2", "%f4", "%f6", "%f1", "%f3", "%f5", "%f7", \
"%f8", "%f10", "%f12", "%f14", "%f9", "%f11", "%f13", "%f15", \ "%f8", "%f10", "%f12", "%f14", "%f9", "%f11", "%f13", "%f15", \
"%ap", "%cc", "%fp", "%rp" \ "%ap", "%cc", "%fp", "%rp", "%a0", "%a1" \
} }
/* Emit a dtp-relative reference to a TLS variable. */ /* Emit a dtp-relative reference to a TLS variable. */
......
...@@ -112,7 +112,6 @@ ...@@ -112,7 +112,6 @@
(UNSPEC_INDNTPOFF 505) (UNSPEC_INDNTPOFF 505)
; TLS support ; TLS support
(UNSPEC_TP 510)
(UNSPEC_TLSLDM_NTPOFF 511) (UNSPEC_TLSLDM_NTPOFF 511)
(UNSPEC_TLS_LOAD 512) (UNSPEC_TLS_LOAD 512)
...@@ -887,9 +886,9 @@ ...@@ -887,9 +886,9 @@
(define_insn "*movdi_64" (define_insn "*movdi_64"
[(set (match_operand:DI 0 "nonimmediate_operand" [(set (match_operand:DI 0 "nonimmediate_operand"
"=d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,?Q") "=d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q")
(match_operand:DI 1 "general_operand" (match_operand:DI 1 "general_operand"
"K,N0HD0,N1HD0,N2HD0,N3HD0,L,d,m,d,*f,R,T,*f,*f,?Q"))] "K,N0HD0,N1HD0,N2HD0,N3HD0,L,d,m,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))]
"TARGET_64BIT" "TARGET_64BIT"
"@ "@
lghi\t%0,%h1 lghi\t%0,%h1
...@@ -906,10 +905,47 @@ ...@@ -906,10 +905,47 @@
ldy\t%0,%1 ldy\t%0,%1
std\t%1,%0 std\t%1,%0
stdy\t%1,%0 stdy\t%1,%0
#
#
stam\t%1,%N1,%S0
lam\t%0,%N0,%S1
#" #"
[(set_attr "op_type" "RI,RI,RI,RI,RI,RXY,RRE,RXY,RXY,RR,RX,RXY,RX,RXY,SS") [(set_attr "op_type" "RI,RI,RI,RI,RI,RXY,RRE,RXY,RXY,RR,RX,RXY,RX,RXY,NN,NN,RS,RS,SS")
(set_attr "type" "*,*,*,*,*,la,lr,load,store,floadd,floadd,floadd, (set_attr "type" "*,*,*,*,*,la,lr,load,store,floadd,floadd,floadd,
fstored,fstored,cs")]) fstored,fstored,*,*,*,*,cs")])
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "register_operand" ""))]
"TARGET_64BIT && ACCESS_REG_P (operands[1])"
[(set (match_dup 2) (match_dup 3))
(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
(set (strict_low_part (match_dup 2)) (match_dup 4))]
"operands[2] = gen_lowpart (SImode, operands[0]);
s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "register_operand" ""))]
"TARGET_64BIT && ACCESS_REG_P (operands[0])
&& dead_or_set_p (insn, operands[1])"
[(set (match_dup 3) (match_dup 2))
(set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
(set (match_dup 4) (match_dup 2))]
"operands[2] = gen_lowpart (SImode, operands[1]);
s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "register_operand" ""))]
"TARGET_64BIT && ACCESS_REG_P (operands[0])
&& !dead_or_set_p (insn, operands[1])"
[(set (match_dup 3) (match_dup 2))
(set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
(set (match_dup 4) (match_dup 2))
(set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
"operands[2] = gen_lowpart (SImode, operands[1]);
s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
(define_insn "*movdi_31" (define_insn "*movdi_31"
[(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,o,!*f,!*f,!*f,!R,!T,Q") [(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,o,!*f,!*f,!*f,!R,!T,Q")
...@@ -1063,9 +1099,9 @@ ...@@ -1063,9 +1099,9 @@
(define_insn "*movsi_zarch" (define_insn "*movsi_zarch"
[(set (match_operand:SI 0 "nonimmediate_operand" [(set (match_operand:SI 0 "nonimmediate_operand"
"=d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,?Q") "=d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q")
(match_operand:SI 1 "general_operand" (match_operand:SI 1 "general_operand"
"K,N0HS0,N1HS0,L,d,R,T,d,d,*f,R,T,*f,*f,?Q"))] "K,N0HS0,N1HS0,L,d,R,T,d,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))]
"TARGET_ZARCH" "TARGET_ZARCH"
"@ "@
lhi\t%0,%h1 lhi\t%0,%h1
...@@ -1082,13 +1118,17 @@ ...@@ -1082,13 +1118,17 @@
ley\t%0,%1 ley\t%0,%1
ste\t%1,%0 ste\t%1,%0
stey\t%1,%0 stey\t%1,%0
ear\t%0,%1
sar\t%0,%1
stam\t%1,%1,%S0
lam\t%0,%0,%S1
#" #"
[(set_attr "op_type" "RI,RI,RI,RXY,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS") [(set_attr "op_type" "RI,RI,RI,RXY,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,RRE,RRE,RS,RS,SS")
(set_attr "type" "*,*,*,la,lr,load,load,store,store,floads,floads,floads,fstores,fstores,cs")]) (set_attr "type" "*,*,*,la,lr,load,load,store,store,floads,floads,floads,fstores,fstores,*,*,*,*,cs")])
(define_insn "*movsi_esa" (define_insn "*movsi_esa"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!R,?Q") [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!R,d,t,Q,t,?Q")
(match_operand:SI 1 "general_operand" "K,d,R,d,*f,R,*f,?Q"))] (match_operand:SI 1 "general_operand" "K,d,R,d,*f,R,*f,t,d,t,Q,?Q"))]
"!TARGET_ZARCH" "!TARGET_ZARCH"
"@ "@
lhi\t%0,%h1 lhi\t%0,%h1
...@@ -1098,9 +1138,13 @@ ...@@ -1098,9 +1138,13 @@
ler\t%0,%1 ler\t%0,%1
le\t%0,%1 le\t%0,%1
ste\t%1,%0 ste\t%1,%0
ear\t%0,%1
sar\t%0,%1
stam\t%1,%1,%S0
lam\t%0,%0,%S1
#" #"
[(set_attr "op_type" "RI,RR,RX,RX,RR,RX,RX,SS") [(set_attr "op_type" "RI,RR,RX,RX,RR,RX,RX,RRE,RRE,RS,RS,SS")
(set_attr "type" "*,lr,load,store,floads,floads,fstores,cs")]) (set_attr "type" "*,lr,load,store,floads,floads,fstores,*,*,*,*,cs")])
(define_peephole2 (define_peephole2
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
...@@ -1321,15 +1365,16 @@ ...@@ -1321,15 +1365,16 @@
; ;
(define_insn "movstrictsi" (define_insn "movstrictsi"
[(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d")) [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d"))
(match_operand:SI 1 "general_operand" "d,R,T"))] (match_operand:SI 1 "general_operand" "d,R,T,t"))]
"TARGET_64BIT" "TARGET_64BIT"
"@ "@
lr\t%0,%1 lr\t%0,%1
l\t%0,%1 l\t%0,%1
ly\t%0,%1" ly\t%0,%1
[(set_attr "op_type" "RR,RX,RXY") ear\t%0,%1"
(set_attr "type" "lr,load,load")]) [(set_attr "op_type" "RR,RX,RXY,RRE")
(set_attr "type" "lr,load,load,*")])
; ;
; movdf instruction pattern(s). ; movdf instruction pattern(s).
...@@ -7438,46 +7483,34 @@ ...@@ -7438,46 +7483,34 @@
;;- Thread-local storage support. ;;- Thread-local storage support.
;; ;;
(define_insn "get_tp_64" (define_expand "get_tp_64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=??d,Q") [(set (match_operand:DI 0 "nonimmediate_operand" "") (reg:DI 36))]
(unspec:DI [(const_int 0)] UNSPEC_TP))]
"TARGET_64BIT" "TARGET_64BIT"
"@ "")
ear\t%0,%%a0\;sllg\t%0,%0,32\;ear\t%0,%%a1
stam\t%%a0,%%a1,%S0"
[(set_attr "op_type" "NN,RS")
(set_attr "atype" "reg,*")
(set_attr "type" "o3,*")
(set_attr "length" "14,*")])
(define_insn "get_tp_31" (define_expand "get_tp_31"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d,Q") [(set (match_operand:SI 0 "nonimmediate_operand" "") (reg:SI 36))]
(unspec:SI [(const_int 0)] UNSPEC_TP))]
"!TARGET_64BIT" "!TARGET_64BIT"
"@ "")
ear\t%0,%%a0
stam\t%%a0,%%a0,%S0"
[(set_attr "op_type" "RRE,RS")])
(define_insn "set_tp_64" (define_expand "set_tp_64"
[(unspec_volatile [(match_operand:DI 0 "general_operand" "??d,Q")] UNSPECV_SET_TP) [(set (reg:DI 36) (match_operand:DI 0 "nonimmediate_operand" ""))
(clobber (match_scratch:SI 1 "=d,X"))] (unspec_volatile [(reg:DI 36)] UNSPECV_SET_TP)]
"TARGET_64BIT" "TARGET_64BIT"
"@ "")
sar\t%%a1,%0\;srlg\t%1,%0,32\;sar\t%%a0,%1
lam\t%%a0,%%a1,%S0"
[(set_attr "op_type" "NN,RS")
(set_attr "atype" "reg,*")
(set_attr "type" "o3,*")
(set_attr "length" "14,*")])
(define_insn "set_tp_31" (define_expand "set_tp_31"
[(unspec_volatile [(match_operand:SI 0 "general_operand" "d,Q")] UNSPECV_SET_TP)] [(set (reg:SI 36) (match_operand:SI 0 "nonimmediate_operand" ""))
(unspec_volatile [(reg:SI 36)] UNSPECV_SET_TP)]
"!TARGET_64BIT" "!TARGET_64BIT"
"@ "")
sar\t%%a0,%0
lam\t%%a0,%%a0,%S0" (define_insn "*set_tp"
[(set_attr "op_type" "RRE,RS")]) [(unspec_volatile [(reg 36)] UNSPECV_SET_TP)]
""
""
[(set_attr "type" "none")
(set_attr "length" "0")])
(define_insn "*tls_load_64" (define_insn "*tls_load_64"
[(set (match_operand:DI 0 "register_operand" "=d") [(set (match_operand:DI 0 "register_operand" "=d")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment