mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
57f60923b2
commit
c5aa1d125c
|
@ -1,3 +1,29 @@
|
||||||
|
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,
|
||||||
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] =
|
||||||
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)
|
||||||
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)
|
||||||
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) && \
|
||||||
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) && \
|
||||||
#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) && \
|
||||||
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) && \
|
||||||
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) && \
|
||||||
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) && \
|
||||||
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) && \
|
||||||
{ 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) && \
|
||||||
(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) && \
|
||||||
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) && \
|
||||||
#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
|
||||||
{ 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];
|
||||||
((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;
|
||||||
"%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 @@
|
||||||
(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 @@
|
||||||
|
|
||||||
(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 @@
|
||||||
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 @@
|
||||||
|
|
||||||
(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 @@
|
||||||
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 @@
|
||||||
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 @@
|
||||||
;
|
;
|
||||||
|
|
||||||
(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 @@
|
||||||
;;- 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")
|
||||||
|
|
Loading…
Reference in New Issue