Teach sparc backend about %gsr register and add intrinsics to access it.
* config/sparc/sparc.h (FIRST_PSEUDO_REGISTER): Bump to 103. (SPARC_GSR_REG): Define. (FIXED_REGISTERS): Mark GSR as fixed. (CALL_USED_REGISTERS): Mark GSR as call used. (HARD_REGNO_NREGS): GSR is always 1 register. (REG_CLASS_CONTENTS): Add GSR to ALL_REGS. (REG_ALLOC_ORDER, REG_LEAF_ALLOC_ORDER): Add GSR to the end. (REGISTER_NAMES): Add "%gsr". * config/sparc/sparc.md (UNSPEC_ALIGNADDR, UNSPEC_ALIGNADDRL): Delete. (UNSPEC_WRGSR): New unspec. (GSR_REG): New constant. (type): Add new insn type 'gsr'. (fpack16_vis, fpackfix_vis, fpack32_vis, faligndata<V64I:MODE>_vis)): Add use of GSR_REG. (wrgsr_vis, *wrgsr_sp64, wrgsr_v8plus, rdgsr_vis, *rdgsr_sp64, rdgsr_v8plus): New expanders and insns. (alignaddr<P:mode>_vis, alignaddrl<P:mode>_vis): Reimplement using patterns which show that this is a plus in addition to a modification of GSR_REG, instead of an unspec. * config/sparc/ultra1_2.md: Handle 'gsr'. * config/sparc/ultra3.md: Likewise. * config/sparc/niagara.md: Likewise. * config/sparc/niagara2.md: Likewise. * config/sparc/sparc.c (leaf_reg_remap, sparc_leaf_regs): Fill out end of table. (sparc_option_override): Make -mvis imply -mv8plus. (hard_32bit_mode_classes, hard_64bit_mode_classes): Add entries for %gsr. (sparc_vis_init_builtins): Build __builtin_vis_write_gsr and __builtin_vis_read_gsr. (sparc_expand_buildin): Handle builtins that take one argument and return void. (sparc_fold_builtin): Never fold writes to %gsr. * config/sparc/visintrin.h (__vis_write_gsr, __vis_read_gsr): New. * doc/extend.texi: Document new VIS intrinsics. From-SVN: r179159
This commit is contained in:
parent
6eaade31bb
commit
10b859c0d8
@ -1,3 +1,42 @@
|
||||
2011-09-24 David S. Miller <davem@davemloft.net>
|
||||
|
||||
* config/sparc/sparc.h (FIRST_PSEUDO_REGISTER): Bump to 103.
|
||||
(SPARC_GSR_REG): Define.
|
||||
(FIXED_REGISTERS): Mark GSR as fixed.
|
||||
(CALL_USED_REGISTERS): Mark GSR as call used.
|
||||
(HARD_REGNO_NREGS): GSR is always 1 register.
|
||||
(REG_CLASS_CONTENTS): Add GSR to ALL_REGS.
|
||||
(REG_ALLOC_ORDER, REG_LEAF_ALLOC_ORDER): Add GSR to the end.
|
||||
(REGISTER_NAMES): Add "%gsr".
|
||||
* config/sparc/sparc.md (UNSPEC_ALIGNADDR, UNSPEC_ALIGNADDRL):
|
||||
Delete.
|
||||
(UNSPEC_WRGSR): New unspec.
|
||||
(GSR_REG): New constant.
|
||||
(type): Add new insn type 'gsr'.
|
||||
(fpack16_vis, fpackfix_vis, fpack32_vis,
|
||||
faligndata<V64I:MODE>_vis)): Add use of GSR_REG.
|
||||
(wrgsr_vis, *wrgsr_sp64, wrgsr_v8plus, rdgsr_vis, *rdgsr_sp64,
|
||||
rdgsr_v8plus): New expanders and insns.
|
||||
(alignaddr<P:mode>_vis, alignaddrl<P:mode>_vis): Reimplement
|
||||
using patterns which show that this is a plus in addition to a
|
||||
modification of GSR_REG, instead of an unspec.
|
||||
* config/sparc/ultra1_2.md: Handle 'gsr'.
|
||||
* config/sparc/ultra3.md: Likewise.
|
||||
* config/sparc/niagara.md: Likewise.
|
||||
* config/sparc/niagara2.md: Likewise.
|
||||
* config/sparc/sparc.c (leaf_reg_remap, sparc_leaf_regs): Fill out
|
||||
end of table.
|
||||
(sparc_option_override): Make -mvis imply -mv8plus.
|
||||
(hard_32bit_mode_classes, hard_64bit_mode_classes): Add entries
|
||||
for %gsr.
|
||||
(sparc_vis_init_builtins): Build __builtin_vis_write_gsr and
|
||||
__builtin_vis_read_gsr.
|
||||
(sparc_expand_buildin): Handle builtins that take one argument and
|
||||
return void.
|
||||
(sparc_fold_builtin): Never fold writes to %gsr.
|
||||
* config/sparc/visintrin.h (__vis_write_gsr, __vis_read_gsr): New.
|
||||
* doc/extend.texi: Document new VIS intrinsics.
|
||||
|
||||
2011-09-23 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* ipa-inline-transform.c (inline_call): Add comment.
|
||||
|
@ -114,5 +114,5 @@
|
||||
*/
|
||||
(define_insn_reservation "niag_vis" 8
|
||||
(and (eq_attr "cpu" "niagara")
|
||||
(eq_attr "type" "fga,fgm_pack,fgm_mul,fgm_cmp,fgm_pdist,edge"))
|
||||
(eq_attr "type" "fga,fgm_pack,fgm_mul,fgm_cmp,fgm_pdist,edge,gsr"))
|
||||
"niag_pipe*8")
|
||||
|
@ -111,10 +111,10 @@
|
||||
|
||||
(define_insn_reservation "niag2_vis" 6
|
||||
(and (eq_attr "cpu" "niagara2")
|
||||
(eq_attr "type" "fga,fgm_pack,fgm_mul,fgm_cmp,fgm_pdist,edge"))
|
||||
(eq_attr "type" "fga,fgm_pack,fgm_mul,fgm_cmp,fgm_pdist,edge,gsr"))
|
||||
"niag2_pipe*6")
|
||||
|
||||
(define_insn_reservation "niag3_vis" 9
|
||||
(and (eq_attr "cpu" "niagara3")
|
||||
(eq_attr "type" "fga,fgm_pack,fgm_mul,fgm_cmp,fgm_pdist,edge"))
|
||||
(eq_attr "type" "fga,fgm_pack,fgm_mul,fgm_cmp,fgm_pdist,edge,gsr"))
|
||||
"niag2_pipe*9")
|
||||
|
@ -329,7 +329,7 @@ char leaf_reg_remap[] =
|
||||
72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87,
|
||||
88, 89, 90, 91, 92, 93, 94, 95,
|
||||
96, 97, 98, 99, 100};
|
||||
96, 97, 98, 99, 100, 101, 102};
|
||||
|
||||
/* Vector, indexed by hard register number, which contains 1
|
||||
for a register that is allowable in a candidate for leaf
|
||||
@ -347,7 +347,7 @@ char sparc_leaf_regs[] =
|
||||
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, 1, 1};
|
||||
|
||||
struct GTY(()) machine_function
|
||||
{
|
||||
@ -870,6 +870,10 @@ sparc_option_override (void)
|
||||
target_flags &= ~(MASK_V8 | MASK_SPARCLET | MASK_SPARCLITE);
|
||||
}
|
||||
|
||||
/* -mvis also implies -mv8plus on 32-bit */
|
||||
if (TARGET_VIS && ! TARGET_ARCH64)
|
||||
target_flags |= MASK_V8PLUS;
|
||||
|
||||
/* Use the deprecated v8 insns for sparc64 in 32 bit mode. */
|
||||
if (TARGET_V9 && TARGET_ARCH32)
|
||||
target_flags |= MASK_DEPRECATED_V8_INSNS;
|
||||
@ -4036,8 +4040,8 @@ static const int hard_32bit_mode_classes[] = {
|
||||
/* %fcc[0123] */
|
||||
CCFP_MODES, CCFP_MODES, CCFP_MODES, CCFP_MODES,
|
||||
|
||||
/* %icc */
|
||||
CC_MODES
|
||||
/* %icc, %sfp, %gsr */
|
||||
CC_MODES, 0, D_MODES
|
||||
};
|
||||
|
||||
static const int hard_64bit_mode_classes[] = {
|
||||
@ -4061,8 +4065,8 @@ static const int hard_64bit_mode_classes[] = {
|
||||
/* %fcc[0123] */
|
||||
CCFP_MODES, CCFP_MODES, CCFP_MODES, CCFP_MODES,
|
||||
|
||||
/* %icc */
|
||||
CC_MODES
|
||||
/* %icc, %sfp, %gsr */
|
||||
CC_MODES, 0, D_MODES
|
||||
};
|
||||
|
||||
int sparc_mode_class [NUM_MACHINE_MODES];
|
||||
@ -9168,6 +9172,10 @@ sparc_vis_init_builtins (void)
|
||||
v4hi, v4hi, 0);
|
||||
tree si_ftype_v2si_v2si = build_function_type_list (intSI_type_node,
|
||||
v2si, v2si, 0);
|
||||
tree void_ftype_di = build_function_type_list (void_type_node,
|
||||
intDI_type_node, 0);
|
||||
tree di_ftype_void = build_function_type_list (intDI_type_node,
|
||||
void_type_node, 0);
|
||||
|
||||
/* Packing and expanding vectors. */
|
||||
def_builtin ("__builtin_vis_fpack16", CODE_FOR_fpack16_vis,
|
||||
@ -9206,6 +9214,12 @@ sparc_vis_init_builtins (void)
|
||||
v2si_ftype_v2si_v2si);
|
||||
def_builtin ("__builtin_vis_faligndatadi", CODE_FOR_faligndatadi_vis,
|
||||
di_ftype_di_di);
|
||||
|
||||
def_builtin ("__builtin_vis_write_gsr", CODE_FOR_wrgsr_vis,
|
||||
void_ftype_di);
|
||||
def_builtin ("__builtin_vis_read_gsr", CODE_FOR_rdgsr_vis,
|
||||
di_ftype_void);
|
||||
|
||||
if (TARGET_ARCH64)
|
||||
{
|
||||
def_builtin ("__builtin_vis_alignaddr", CODE_FOR_alignaddrdi_vis,
|
||||
@ -9289,32 +9303,47 @@ sparc_expand_builtin (tree exp, rtx target,
|
||||
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
|
||||
unsigned int icode = DECL_FUNCTION_CODE (fndecl);
|
||||
rtx pat, op[4];
|
||||
enum machine_mode mode[4];
|
||||
int arg_count = 0;
|
||||
bool nonvoid;
|
||||
|
||||
mode[0] = insn_data[icode].operand[0].mode;
|
||||
if (!target
|
||||
|| GET_MODE (target) != mode[0]
|
||||
|| ! (*insn_data[icode].operand[0].predicate) (target, mode[0]))
|
||||
op[0] = gen_reg_rtx (mode[0]);
|
||||
else
|
||||
op[0] = target;
|
||||
nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
|
||||
|
||||
if (nonvoid)
|
||||
{
|
||||
enum machine_mode tmode = insn_data[icode].operand[0].mode;
|
||||
if (!target
|
||||
|| GET_MODE (target) != tmode
|
||||
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode))
|
||||
op[0] = gen_reg_rtx (tmode);
|
||||
else
|
||||
op[0] = target;
|
||||
}
|
||||
FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
|
||||
{
|
||||
const struct insn_operand_data *insn_op;
|
||||
|
||||
if (arg == error_mark_node)
|
||||
return NULL_RTX;
|
||||
|
||||
arg_count++;
|
||||
mode[arg_count] = insn_data[icode].operand[arg_count].mode;
|
||||
insn_op = &insn_data[icode].operand[arg_count - !nonvoid];
|
||||
op[arg_count] = expand_normal (arg);
|
||||
|
||||
if (! (*insn_data[icode].operand[arg_count].predicate) (op[arg_count],
|
||||
mode[arg_count]))
|
||||
op[arg_count] = copy_to_mode_reg (mode[arg_count], op[arg_count]);
|
||||
insn_op->mode))
|
||||
op[arg_count] = copy_to_mode_reg (insn_op->mode, op[arg_count]);
|
||||
}
|
||||
|
||||
switch (arg_count)
|
||||
{
|
||||
case 0:
|
||||
pat = GEN_FCN (icode) (op[0]);
|
||||
break;
|
||||
case 1:
|
||||
pat = GEN_FCN (icode) (op[0], op[1]);
|
||||
if (nonvoid)
|
||||
pat = GEN_FCN (icode) (op[0], op[1]);
|
||||
else
|
||||
pat = GEN_FCN (icode) (op[1]);
|
||||
break;
|
||||
case 2:
|
||||
pat = GEN_FCN (icode) (op[0], op[1], op[2]);
|
||||
@ -9331,7 +9360,10 @@ sparc_expand_builtin (tree exp, rtx target,
|
||||
|
||||
emit_insn (pat);
|
||||
|
||||
return op[0];
|
||||
if (nonvoid)
|
||||
return op[0];
|
||||
else
|
||||
return const0_rtx;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -9416,7 +9448,8 @@ sparc_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED,
|
||||
|
||||
if (ignore
|
||||
&& icode != CODE_FOR_alignaddrsi_vis
|
||||
&& icode != CODE_FOR_alignaddrdi_vis)
|
||||
&& icode != CODE_FOR_alignaddrdi_vis
|
||||
&& icode != CODE_FOR_wrgsr_vis)
|
||||
return build_zero_cst (rtype);
|
||||
|
||||
switch (icode)
|
||||
|
@ -691,7 +691,7 @@ extern enum cmodel sparc_cmodel;
|
||||
Register 100 is used as the integer condition code register.
|
||||
Register 101 is used as the soft frame pointer register. */
|
||||
|
||||
#define FIRST_PSEUDO_REGISTER 102
|
||||
#define FIRST_PSEUDO_REGISTER 103
|
||||
|
||||
#define SPARC_FIRST_FP_REG 32
|
||||
/* Additional V9 fp regs. */
|
||||
@ -704,6 +704,7 @@ extern enum cmodel sparc_cmodel;
|
||||
#define SPARC_FCC_REG 96
|
||||
/* Integer CC reg. We don't distinguish %icc from %xcc. */
|
||||
#define SPARC_ICC_REG 100
|
||||
#define SPARC_GSR_REG 102
|
||||
|
||||
/* Nonzero if REGNO is an fp reg. */
|
||||
#define SPARC_FP_REG_P(REGNO) \
|
||||
@ -757,7 +758,7 @@ extern enum cmodel sparc_cmodel;
|
||||
0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
\
|
||||
0, 0, 0, 0, 0, 1}
|
||||
0, 0, 0, 0, 0, 1, 1}
|
||||
|
||||
/* 1 for registers not available across function calls.
|
||||
These must include the FIXED_REGISTERS and also any
|
||||
@ -782,7 +783,7 @@ extern enum cmodel sparc_cmodel;
|
||||
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}
|
||||
|
||||
/* Return number of consecutive hard regs needed starting at reg REGNO
|
||||
to hold something of mode MODE.
|
||||
@ -796,11 +797,12 @@ extern enum cmodel sparc_cmodel;
|
||||
included in the hard register count). */
|
||||
|
||||
#define HARD_REGNO_NREGS(REGNO, MODE) \
|
||||
(TARGET_ARCH64 \
|
||||
? ((REGNO) < 32 || (REGNO) == FRAME_POINTER_REGNUM \
|
||||
? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD \
|
||||
: (GET_MODE_SIZE (MODE) + 3) / 4) \
|
||||
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
|
||||
((REGNO) == SPARC_GSR_REG ? 1 : \
|
||||
(TARGET_ARCH64 \
|
||||
? ((REGNO) < 32 || (REGNO) == FRAME_POINTER_REGNUM \
|
||||
? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD \
|
||||
: (GET_MODE_SIZE (MODE) + 3) / 4) \
|
||||
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
|
||||
|
||||
/* Due to the ARCH64 discrepancy above we must override this next
|
||||
macro too. */
|
||||
@ -985,7 +987,7 @@ enum reg_class { NO_REGS, FPCC_REGS, I64_REGS, GENERAL_REGS, FP_REGS,
|
||||
{0, -1, -1, 0}, /* EXTRA_FP_REGS */ \
|
||||
{-1, -1, 0, 0x20}, /* GENERAL_OR_FP_REGS */ \
|
||||
{-1, -1, -1, 0x20}, /* GENERAL_OR_EXTRA_FP_REGS */ \
|
||||
{-1, -1, -1, 0x3f}} /* ALL_REGS */
|
||||
{-1, -1, -1, 0x7f}} /* ALL_REGS */
|
||||
|
||||
/* The same information, inverted:
|
||||
Return the class number of the smallest class containing
|
||||
@ -1046,7 +1048,7 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
|
||||
88, 89, 90, 91, 92, 93, 94, 95, /* %f56-%f63 */ \
|
||||
39, 38, 37, 36, 35, 34, 33, 32, /* %f7-%f0 */ \
|
||||
96, 97, 98, 99, /* %fcc0-3 */ \
|
||||
100, 0, 14, 30, 101} /* %icc, %g0, %o6, %i6, %sfp */
|
||||
100, 0, 14, 30, 101, 102 } /* %icc, %g0, %o6, %i6, %sfp, %gsr */
|
||||
|
||||
/* This is the order in which to allocate registers for
|
||||
leaf functions. If all registers can fit in the global and
|
||||
@ -1085,7 +1087,7 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
|
||||
88, 89, 90, 91, 92, 93, 94, 95, /* %f56-%f63 */ \
|
||||
39, 38, 37, 36, 35, 34, 33, 32, /* %f7-%f0 */ \
|
||||
96, 97, 98, 99, /* %fcc0-3 */ \
|
||||
100, 0, 14, 30, 31, 101} /* %icc, %g0, %o6, %i6, %i7, %sfp */
|
||||
100, 0, 14, 30, 31, 101, 102 } /* %icc, %g0, %o6, %i6, %i7, %sfp, %gsr */
|
||||
|
||||
#define ADJUST_REG_ALLOC_ORDER order_regs_for_local_alloc ()
|
||||
|
||||
@ -1724,7 +1726,7 @@ do { \
|
||||
"%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47", \
|
||||
"%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55", \
|
||||
"%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63", \
|
||||
"%fcc0", "%fcc1", "%fcc2", "%fcc3", "%icc", "%sfp" }
|
||||
"%fcc0", "%fcc1", "%fcc2", "%fcc3", "%icc", "%sfp", "%gsr" }
|
||||
|
||||
/* Define additional names for use in asm clobbers and asm declarations. */
|
||||
|
||||
|
@ -58,7 +58,7 @@
|
||||
(UNSPEC_MUL8UL 46)
|
||||
(UNSPEC_MULDUL 47)
|
||||
(UNSPEC_ALIGNDATA 48)
|
||||
(UNSPEC_ALIGNADDR 49)
|
||||
(UNSPEC_WRGSR 49)
|
||||
(UNSPEC_PDIST 50)
|
||||
(UNSPEC_EDGE8 51)
|
||||
(UNSPEC_EDGE8L 52)
|
||||
@ -66,7 +66,6 @@
|
||||
(UNSPEC_EDGE16L 54)
|
||||
(UNSPEC_EDGE32 55)
|
||||
(UNSPEC_EDGE32L 56)
|
||||
(UNSPEC_ALIGNADDRL 57)
|
||||
|
||||
(UNSPEC_SP_SET 60)
|
||||
(UNSPEC_SP_TEST 61)
|
||||
@ -176,6 +175,7 @@
|
||||
(FCC3_REG 99)
|
||||
(CC_REG 100)
|
||||
(SFP_REG 101)
|
||||
(GSR_REG 102)
|
||||
])
|
||||
|
||||
(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
|
||||
@ -242,7 +242,7 @@
|
||||
fpcmp,
|
||||
fpmul,fpdivs,fpdivd,
|
||||
fpsqrts,fpsqrtd,
|
||||
fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,
|
||||
fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,gsr,
|
||||
cmove,
|
||||
ialuX,
|
||||
multi,savew,flushw,iflush,trap"
|
||||
@ -7752,7 +7752,8 @@
|
||||
(define_insn "fpack16_vis"
|
||||
[(set (match_operand:V4QI 0 "register_operand" "=f")
|
||||
(unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
|
||||
UNSPEC_FPACK16))]
|
||||
UNSPEC_FPACK16))
|
||||
(use (reg:DI GSR_REG))]
|
||||
"TARGET_VIS"
|
||||
"fpack16\t%1, %0"
|
||||
[(set_attr "type" "fga")
|
||||
@ -7761,7 +7762,8 @@
|
||||
(define_insn "fpackfix_vis"
|
||||
[(set (match_operand:V2HI 0 "register_operand" "=f")
|
||||
(unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
|
||||
UNSPEC_FPACKFIX))]
|
||||
UNSPEC_FPACKFIX))
|
||||
(use (reg:DI GSR_REG))]
|
||||
"TARGET_VIS"
|
||||
"fpackfix\t%1, %0"
|
||||
[(set_attr "type" "fga")
|
||||
@ -7771,7 +7773,8 @@
|
||||
[(set (match_operand:V8QI 0 "register_operand" "=e")
|
||||
(unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
|
||||
(match_operand:V8QI 2 "register_operand" "e")]
|
||||
UNSPEC_FPACK32))]
|
||||
UNSPEC_FPACK32))
|
||||
(use (reg:DI GSR_REG))]
|
||||
"TARGET_VIS"
|
||||
"fpack32\t%1, %2, %0"
|
||||
[(set_attr "type" "fga")
|
||||
@ -7871,6 +7874,66 @@
|
||||
[(set_attr "type" "fpmul")
|
||||
(set_attr "fptype" "double")])
|
||||
|
||||
(define_expand "wrgsr_vis"
|
||||
[(set (reg:DI GSR_REG) (unspec:DI [(match_operand:DI 0 "arith_operand" "")]
|
||||
UNSPEC_WRGSR))]
|
||||
"TARGET_VIS"
|
||||
{
|
||||
if (! TARGET_ARCH64)
|
||||
{
|
||||
emit_insn (gen_wrgsr_v8plus (operands[0]));
|
||||
DONE;
|
||||
}
|
||||
})
|
||||
|
||||
(define_insn "*wrgsr_sp64"
|
||||
[(set (reg:DI GSR_REG) (unspec:DI [(match_operand:DI 0 "arith_operand" "rI")]
|
||||
UNSPEC_WRGSR))]
|
||||
"TARGET_VIS && TARGET_ARCH64"
|
||||
"wr\t%%g0, %0, %%gsr"
|
||||
[(set_attr "type" "gsr")])
|
||||
|
||||
(define_insn "wrgsr_v8plus"
|
||||
[(set (reg:DI GSR_REG) (unspec:DI [(match_operand:DI 0 "arith_operand" "I,r")]
|
||||
UNSPEC_WRGSR))
|
||||
(clobber (match_scratch:SI 1 "=X,&h"))]
|
||||
"TARGET_VIS && ! TARGET_ARCH64"
|
||||
{
|
||||
if (GET_CODE (operands[0]) == CONST_INT
|
||||
|| sparc_check_64 (operands[0], insn))
|
||||
return "wr\t%%g0, %0, %%gsr";
|
||||
|
||||
output_asm_insn("srl\t%L0, 0, %L0", operands);
|
||||
return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
|
||||
}
|
||||
[(set_attr "type" "multi")])
|
||||
|
||||
(define_expand "rdgsr_vis"
|
||||
[(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
|
||||
"TARGET_VIS"
|
||||
{
|
||||
if (! TARGET_ARCH64)
|
||||
{
|
||||
emit_insn (gen_rdgsr_v8plus (operands[0]));
|
||||
DONE;
|
||||
}
|
||||
})
|
||||
|
||||
(define_insn "*rdgsr_sp64"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
|
||||
"TARGET_VIS && TARGET_ARCH64"
|
||||
"rd\t%%gsr, %0"
|
||||
[(set_attr "type" "gsr")])
|
||||
|
||||
(define_insn "rdgsr_v8plus"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
|
||||
(clobber (match_scratch:SI 1 "=&h"))]
|
||||
"TARGET_VIS && ! TARGET_ARCH64"
|
||||
{
|
||||
return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
|
||||
}
|
||||
[(set_attr "type" "multi")])
|
||||
|
||||
;; Using faligndata only makes sense after an alignaddr since the choice of
|
||||
;; bytes to take out of each operand is dependent on the results of the last
|
||||
;; alignaddr.
|
||||
@ -7878,25 +7941,57 @@
|
||||
[(set (match_operand:V64I 0 "register_operand" "=e")
|
||||
(unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
|
||||
(match_operand:V64I 2 "register_operand" "e")]
|
||||
UNSPEC_ALIGNDATA))]
|
||||
UNSPEC_ALIGNDATA))
|
||||
(use (reg:SI GSR_REG))]
|
||||
"TARGET_VIS"
|
||||
"faligndata\t%1, %2, %0"
|
||||
[(set_attr "type" "fga")
|
||||
(set_attr "fptype" "double")])
|
||||
|
||||
(define_insn "alignaddr<P:mode>_vis"
|
||||
[(set (match_operand:P 0 "register_operand" "=r")
|
||||
(unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
|
||||
(match_operand:P 2 "register_or_zero_operand" "rJ")]
|
||||
UNSPEC_ALIGNADDR))]
|
||||
(define_insn "alignaddrsi_vis"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
|
||||
(match_operand:SI 2 "register_or_zero_operand" "rJ")))
|
||||
(set (reg:SI GSR_REG)
|
||||
(ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
|
||||
(and:SI (plus:SI (match_dup 1) (match_dup 2))
|
||||
(const_int 7))))]
|
||||
"TARGET_VIS"
|
||||
"alignaddr\t%r1, %r2, %0")
|
||||
|
||||
(define_insn "alignaddrl<P:mode>_vis"
|
||||
[(set (match_operand:P 0 "register_operand" "=r")
|
||||
(unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
|
||||
(match_operand:P 2 "register_or_zero_operand" "rJ")]
|
||||
UNSPEC_ALIGNADDRL))]
|
||||
(define_insn "alignaddrdi_vis"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
|
||||
(match_operand:DI 2 "register_or_zero_operand" "rJ")))
|
||||
(set (reg:SI GSR_REG)
|
||||
(ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
|
||||
(and:SI (truncate:SI (plus:DI (match_dup 1) (match_dup 2)))
|
||||
(const_int 7))))]
|
||||
"TARGET_VIS"
|
||||
"alignaddr\t%r1, %r2, %0")
|
||||
|
||||
(define_insn "alignaddrlsi_vis"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
|
||||
(match_operand:SI 2 "register_or_zero_operand" "rJ")))
|
||||
(set (reg:SI GSR_REG)
|
||||
(ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
|
||||
(xor:SI (and:SI (plus:SI (match_dup 1) (match_dup 2))
|
||||
(const_int 7))
|
||||
(const_int 7))))]
|
||||
"TARGET_VIS"
|
||||
"alignaddrl\t%r1, %r2, %0")
|
||||
|
||||
(define_insn "alignaddrldi_vis"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
|
||||
(match_operand:DI 2 "register_or_zero_operand" "rJ")))
|
||||
(set (reg:SI GSR_REG)
|
||||
(ior:SI (and:SI (reg:SI GSR_REG) (const_int -8))
|
||||
(xor:SI (and:SI (truncate:SI (plus:DI (match_dup 1)
|
||||
(match_dup 2)))
|
||||
(const_int 7))
|
||||
(const_int 7))))]
|
||||
"TARGET_VIS"
|
||||
"alignaddrl\t%r1, %r2, %0")
|
||||
|
||||
|
@ -79,7 +79,7 @@
|
||||
|
||||
(define_insn_reservation "us1_single" 1
|
||||
(and (eq_attr "cpu" "ultrasparc")
|
||||
(eq_attr "type" "multi,savew,flushw,iflush,trap"))
|
||||
(eq_attr "type" "multi,savew,flushw,iflush,trap,gsr"))
|
||||
"us1_single_issue")
|
||||
|
||||
(define_insn_reservation "us1_simple_ieuN" 1
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
(define_insn_reservation "us3_single" 1
|
||||
(and (eq_attr "cpu" "ultrasparc3")
|
||||
(eq_attr "type" "multi,savew,flushw,iflush,trap,edge"))
|
||||
(eq_attr "type" "multi,savew,flushw,iflush,trap,edge,gsr"))
|
||||
"us3_single_issue")
|
||||
|
||||
(define_insn_reservation "us3_integer" 1
|
||||
|
@ -31,6 +31,20 @@ typedef unsigned char __v8qi __attribute__ ((__vector_size__ (8)));
|
||||
typedef unsigned char __v4qi __attribute__ ((__vector_size__ (4)));
|
||||
typedef int __i64 __attribute__ ((__mode__ (DI)));
|
||||
|
||||
extern __inline void
|
||||
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
|
||||
__vis_write_gsr (__i64 __A)
|
||||
{
|
||||
__builtin_vis_write_gsr (__A);
|
||||
}
|
||||
|
||||
extern __inline __i64
|
||||
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
|
||||
__vis_read_gsr (void)
|
||||
{
|
||||
return __builtin_vis_read_gsr ();
|
||||
}
|
||||
|
||||
extern __inline void *
|
||||
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
|
||||
__vis_alignaddr (void *__A, long __B)
|
||||
|
@ -12935,6 +12935,9 @@ typedef short v2hi __attribute__ ((vector_size (4)));
|
||||
typedef unsigned char v8qi __attribute__ ((vector_size (8)));
|
||||
typedef unsigned char v4qi __attribute__ ((vector_size (4)));
|
||||
|
||||
void __builtin_vis_write_gsr (int64_t);
|
||||
int64_t __builtin_vis_read_gsr (void);
|
||||
|
||||
void * __builtin_vis_alignaddr (void *, long);
|
||||
void * __builtin_vis_alignaddrl (void *, long);
|
||||
int64_t __builtin_vis_faligndatadi (int64_t, int64_t);
|
||||
|
Loading…
Reference in New Issue
Block a user