Commit 10b859c0 by David S. Miller Committed by David S. Miller

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
parent 6eaade31
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> 2011-09-23 Jan Hubicka <jh@suse.cz>
* ipa-inline-transform.c (inline_call): Add comment. * ipa-inline-transform.c (inline_call): Add comment.
...@@ -114,5 +114,5 @@ ...@@ -114,5 +114,5 @@
*/ */
(define_insn_reservation "niag_vis" 8 (define_insn_reservation "niag_vis" 8
(and (eq_attr "cpu" "niagara") (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") "niag_pipe*8")
...@@ -111,10 +111,10 @@ ...@@ -111,10 +111,10 @@
(define_insn_reservation "niag2_vis" 6 (define_insn_reservation "niag2_vis" 6
(and (eq_attr "cpu" "niagara2") (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") "niag2_pipe*6")
(define_insn_reservation "niag3_vis" 9 (define_insn_reservation "niag3_vis" 9
(and (eq_attr "cpu" "niagara3") (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") "niag2_pipe*9")
...@@ -329,7 +329,7 @@ char leaf_reg_remap[] = ...@@ -329,7 +329,7 @@ char leaf_reg_remap[] =
72, 73, 74, 75, 76, 77, 78, 79, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 80, 81, 82, 83, 84, 85, 86, 87,
88, 89, 90, 91, 92, 93, 94, 95, 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 /* Vector, indexed by hard register number, which contains 1
for a register that is allowable in a candidate for leaf for a register that is allowable in a candidate for leaf
...@@ -347,7 +347,7 @@ char sparc_leaf_regs[] = ...@@ -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, 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 struct GTY(()) machine_function
{ {
...@@ -870,6 +870,10 @@ sparc_option_override (void) ...@@ -870,6 +870,10 @@ sparc_option_override (void)
target_flags &= ~(MASK_V8 | MASK_SPARCLET | MASK_SPARCLITE); 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. */ /* Use the deprecated v8 insns for sparc64 in 32 bit mode. */
if (TARGET_V9 && TARGET_ARCH32) if (TARGET_V9 && TARGET_ARCH32)
target_flags |= MASK_DEPRECATED_V8_INSNS; target_flags |= MASK_DEPRECATED_V8_INSNS;
...@@ -4036,8 +4040,8 @@ static const int hard_32bit_mode_classes[] = { ...@@ -4036,8 +4040,8 @@ static const int hard_32bit_mode_classes[] = {
/* %fcc[0123] */ /* %fcc[0123] */
CCFP_MODES, CCFP_MODES, CCFP_MODES, CCFP_MODES, CCFP_MODES, CCFP_MODES, CCFP_MODES, CCFP_MODES,
/* %icc */ /* %icc, %sfp, %gsr */
CC_MODES CC_MODES, 0, D_MODES
}; };
static const int hard_64bit_mode_classes[] = { static const int hard_64bit_mode_classes[] = {
...@@ -4061,8 +4065,8 @@ static const int hard_64bit_mode_classes[] = { ...@@ -4061,8 +4065,8 @@ static const int hard_64bit_mode_classes[] = {
/* %fcc[0123] */ /* %fcc[0123] */
CCFP_MODES, CCFP_MODES, CCFP_MODES, CCFP_MODES, CCFP_MODES, CCFP_MODES, CCFP_MODES, CCFP_MODES,
/* %icc */ /* %icc, %sfp, %gsr */
CC_MODES CC_MODES, 0, D_MODES
}; };
int sparc_mode_class [NUM_MACHINE_MODES]; int sparc_mode_class [NUM_MACHINE_MODES];
...@@ -9168,6 +9172,10 @@ sparc_vis_init_builtins (void) ...@@ -9168,6 +9172,10 @@ sparc_vis_init_builtins (void)
v4hi, v4hi, 0); v4hi, v4hi, 0);
tree si_ftype_v2si_v2si = build_function_type_list (intSI_type_node, tree si_ftype_v2si_v2si = build_function_type_list (intSI_type_node,
v2si, v2si, 0); 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. */ /* Packing and expanding vectors. */
def_builtin ("__builtin_vis_fpack16", CODE_FOR_fpack16_vis, def_builtin ("__builtin_vis_fpack16", CODE_FOR_fpack16_vis,
...@@ -9206,6 +9214,12 @@ sparc_vis_init_builtins (void) ...@@ -9206,6 +9214,12 @@ sparc_vis_init_builtins (void)
v2si_ftype_v2si_v2si); v2si_ftype_v2si_v2si);
def_builtin ("__builtin_vis_faligndatadi", CODE_FOR_faligndatadi_vis, def_builtin ("__builtin_vis_faligndatadi", CODE_FOR_faligndatadi_vis,
di_ftype_di_di); 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) if (TARGET_ARCH64)
{ {
def_builtin ("__builtin_vis_alignaddr", CODE_FOR_alignaddrdi_vis, def_builtin ("__builtin_vis_alignaddr", CODE_FOR_alignaddrdi_vis,
...@@ -9289,32 +9303,47 @@ sparc_expand_builtin (tree exp, rtx target, ...@@ -9289,32 +9303,47 @@ sparc_expand_builtin (tree exp, rtx target,
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
unsigned int icode = DECL_FUNCTION_CODE (fndecl); unsigned int icode = DECL_FUNCTION_CODE (fndecl);
rtx pat, op[4]; rtx pat, op[4];
enum machine_mode mode[4];
int arg_count = 0; int arg_count = 0;
bool nonvoid;
mode[0] = insn_data[icode].operand[0].mode; nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
if (nonvoid)
{
enum machine_mode tmode = insn_data[icode].operand[0].mode;
if (!target if (!target
|| GET_MODE (target) != mode[0] || GET_MODE (target) != tmode
|| ! (*insn_data[icode].operand[0].predicate) (target, mode[0])) || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
op[0] = gen_reg_rtx (mode[0]); op[0] = gen_reg_rtx (tmode);
else else
op[0] = target; op[0] = target;
}
FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) 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++; 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); op[arg_count] = expand_normal (arg);
if (! (*insn_data[icode].operand[arg_count].predicate) (op[arg_count], if (! (*insn_data[icode].operand[arg_count].predicate) (op[arg_count],
mode[arg_count])) insn_op->mode))
op[arg_count] = copy_to_mode_reg (mode[arg_count], op[arg_count]); op[arg_count] = copy_to_mode_reg (insn_op->mode, op[arg_count]);
} }
switch (arg_count) switch (arg_count)
{ {
case 0:
pat = GEN_FCN (icode) (op[0]);
break;
case 1: case 1:
if (nonvoid)
pat = GEN_FCN (icode) (op[0], op[1]); pat = GEN_FCN (icode) (op[0], op[1]);
else
pat = GEN_FCN (icode) (op[1]);
break; break;
case 2: case 2:
pat = GEN_FCN (icode) (op[0], op[1], op[2]); pat = GEN_FCN (icode) (op[0], op[1], op[2]);
...@@ -9331,7 +9360,10 @@ sparc_expand_builtin (tree exp, rtx target, ...@@ -9331,7 +9360,10 @@ sparc_expand_builtin (tree exp, rtx target,
emit_insn (pat); emit_insn (pat);
if (nonvoid)
return op[0]; return op[0];
else
return const0_rtx;
} }
static int static int
...@@ -9416,7 +9448,8 @@ sparc_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, ...@@ -9416,7 +9448,8 @@ sparc_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED,
if (ignore if (ignore
&& icode != CODE_FOR_alignaddrsi_vis && 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); return build_zero_cst (rtype);
switch (icode) switch (icode)
......
...@@ -691,7 +691,7 @@ extern enum cmodel sparc_cmodel; ...@@ -691,7 +691,7 @@ extern enum cmodel sparc_cmodel;
Register 100 is used as the integer condition code register. Register 100 is used as the integer condition code register.
Register 101 is used as the soft frame pointer 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 #define SPARC_FIRST_FP_REG 32
/* Additional V9 fp regs. */ /* Additional V9 fp regs. */
...@@ -704,6 +704,7 @@ extern enum cmodel sparc_cmodel; ...@@ -704,6 +704,7 @@ extern enum cmodel sparc_cmodel;
#define SPARC_FCC_REG 96 #define SPARC_FCC_REG 96
/* Integer CC reg. We don't distinguish %icc from %xcc. */ /* Integer CC reg. We don't distinguish %icc from %xcc. */
#define SPARC_ICC_REG 100 #define SPARC_ICC_REG 100
#define SPARC_GSR_REG 102
/* Nonzero if REGNO is an fp reg. */ /* Nonzero if REGNO is an fp reg. */
#define SPARC_FP_REG_P(REGNO) \ #define SPARC_FP_REG_P(REGNO) \
...@@ -757,7 +758,7 @@ extern enum cmodel sparc_cmodel; ...@@ -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, 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. /* 1 for registers not available across function calls.
These must include the FIXED_REGISTERS and also any These must include the FIXED_REGISTERS and also any
...@@ -782,7 +783,7 @@ extern enum cmodel sparc_cmodel; ...@@ -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, 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 /* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE. to hold something of mode MODE.
...@@ -796,11 +797,12 @@ extern enum cmodel sparc_cmodel; ...@@ -796,11 +797,12 @@ extern enum cmodel sparc_cmodel;
included in the hard register count). */ included in the hard register count). */
#define HARD_REGNO_NREGS(REGNO, MODE) \ #define HARD_REGNO_NREGS(REGNO, MODE) \
((REGNO) == SPARC_GSR_REG ? 1 : \
(TARGET_ARCH64 \ (TARGET_ARCH64 \
? ((REGNO) < 32 || (REGNO) == FRAME_POINTER_REGNUM \ ? ((REGNO) < 32 || (REGNO) == FRAME_POINTER_REGNUM \
? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD \ ? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD \
: (GET_MODE_SIZE (MODE) + 3) / 4) \ : (GET_MODE_SIZE (MODE) + 3) / 4) \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
/* Due to the ARCH64 discrepancy above we must override this next /* Due to the ARCH64 discrepancy above we must override this next
macro too. */ macro too. */
...@@ -985,7 +987,7 @@ enum reg_class { NO_REGS, FPCC_REGS, I64_REGS, GENERAL_REGS, FP_REGS, ...@@ -985,7 +987,7 @@ enum reg_class { NO_REGS, FPCC_REGS, I64_REGS, GENERAL_REGS, FP_REGS,
{0, -1, -1, 0}, /* EXTRA_FP_REGS */ \ {0, -1, -1, 0}, /* EXTRA_FP_REGS */ \
{-1, -1, 0, 0x20}, /* GENERAL_OR_FP_REGS */ \ {-1, -1, 0, 0x20}, /* GENERAL_OR_FP_REGS */ \
{-1, -1, -1, 0x20}, /* GENERAL_OR_EXTRA_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: /* The same information, inverted:
Return the class number of the smallest class containing Return the class number of the smallest class containing
...@@ -1046,7 +1048,7 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER]; ...@@ -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 */ \ 88, 89, 90, 91, 92, 93, 94, 95, /* %f56-%f63 */ \
39, 38, 37, 36, 35, 34, 33, 32, /* %f7-%f0 */ \ 39, 38, 37, 36, 35, 34, 33, 32, /* %f7-%f0 */ \
96, 97, 98, 99, /* %fcc0-3 */ \ 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 /* This is the order in which to allocate registers for
leaf functions. If all registers can fit in the global and 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]; ...@@ -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 */ \ 88, 89, 90, 91, 92, 93, 94, 95, /* %f56-%f63 */ \
39, 38, 37, 36, 35, 34, 33, 32, /* %f7-%f0 */ \ 39, 38, 37, 36, 35, 34, 33, 32, /* %f7-%f0 */ \
96, 97, 98, 99, /* %fcc0-3 */ \ 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 () #define ADJUST_REG_ALLOC_ORDER order_regs_for_local_alloc ()
...@@ -1724,7 +1726,7 @@ do { \ ...@@ -1724,7 +1726,7 @@ do { \
"%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47", \ "%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47", \
"%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55", \ "%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55", \
"%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63", \ "%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. */ /* Define additional names for use in asm clobbers and asm declarations. */
......
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
(UNSPEC_MUL8UL 46) (UNSPEC_MUL8UL 46)
(UNSPEC_MULDUL 47) (UNSPEC_MULDUL 47)
(UNSPEC_ALIGNDATA 48) (UNSPEC_ALIGNDATA 48)
(UNSPEC_ALIGNADDR 49) (UNSPEC_WRGSR 49)
(UNSPEC_PDIST 50) (UNSPEC_PDIST 50)
(UNSPEC_EDGE8 51) (UNSPEC_EDGE8 51)
(UNSPEC_EDGE8L 52) (UNSPEC_EDGE8L 52)
...@@ -66,7 +66,6 @@ ...@@ -66,7 +66,6 @@
(UNSPEC_EDGE16L 54) (UNSPEC_EDGE16L 54)
(UNSPEC_EDGE32 55) (UNSPEC_EDGE32 55)
(UNSPEC_EDGE32L 56) (UNSPEC_EDGE32L 56)
(UNSPEC_ALIGNADDRL 57)
(UNSPEC_SP_SET 60) (UNSPEC_SP_SET 60)
(UNSPEC_SP_TEST 61) (UNSPEC_SP_TEST 61)
...@@ -176,6 +175,7 @@ ...@@ -176,6 +175,7 @@
(FCC3_REG 99) (FCC3_REG 99)
(CC_REG 100) (CC_REG 100)
(SFP_REG 101) (SFP_REG 101)
(GSR_REG 102)
]) ])
(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
...@@ -242,7 +242,7 @@ ...@@ -242,7 +242,7 @@
fpcmp, fpcmp,
fpmul,fpdivs,fpdivd, fpmul,fpdivs,fpdivd,
fpsqrts,fpsqrtd, fpsqrts,fpsqrtd,
fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge, fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,gsr,
cmove, cmove,
ialuX, ialuX,
multi,savew,flushw,iflush,trap" multi,savew,flushw,iflush,trap"
...@@ -7752,7 +7752,8 @@ ...@@ -7752,7 +7752,8 @@
(define_insn "fpack16_vis" (define_insn "fpack16_vis"
[(set (match_operand:V4QI 0 "register_operand" "=f") [(set (match_operand:V4QI 0 "register_operand" "=f")
(unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")] (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
UNSPEC_FPACK16))] UNSPEC_FPACK16))
(use (reg:DI GSR_REG))]
"TARGET_VIS" "TARGET_VIS"
"fpack16\t%1, %0" "fpack16\t%1, %0"
[(set_attr "type" "fga") [(set_attr "type" "fga")
...@@ -7761,7 +7762,8 @@ ...@@ -7761,7 +7762,8 @@
(define_insn "fpackfix_vis" (define_insn "fpackfix_vis"
[(set (match_operand:V2HI 0 "register_operand" "=f") [(set (match_operand:V2HI 0 "register_operand" "=f")
(unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")] (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
UNSPEC_FPACKFIX))] UNSPEC_FPACKFIX))
(use (reg:DI GSR_REG))]
"TARGET_VIS" "TARGET_VIS"
"fpackfix\t%1, %0" "fpackfix\t%1, %0"
[(set_attr "type" "fga") [(set_attr "type" "fga")
...@@ -7771,7 +7773,8 @@ ...@@ -7771,7 +7773,8 @@
[(set (match_operand:V8QI 0 "register_operand" "=e") [(set (match_operand:V8QI 0 "register_operand" "=e")
(unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e") (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
(match_operand:V8QI 2 "register_operand" "e")] (match_operand:V8QI 2 "register_operand" "e")]
UNSPEC_FPACK32))] UNSPEC_FPACK32))
(use (reg:DI GSR_REG))]
"TARGET_VIS" "TARGET_VIS"
"fpack32\t%1, %2, %0" "fpack32\t%1, %2, %0"
[(set_attr "type" "fga") [(set_attr "type" "fga")
...@@ -7871,6 +7874,66 @@ ...@@ -7871,6 +7874,66 @@
[(set_attr "type" "fpmul") [(set_attr "type" "fpmul")
(set_attr "fptype" "double")]) (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 ;; 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 ;; bytes to take out of each operand is dependent on the results of the last
;; alignaddr. ;; alignaddr.
...@@ -7878,25 +7941,57 @@ ...@@ -7878,25 +7941,57 @@
[(set (match_operand:V64I 0 "register_operand" "=e") [(set (match_operand:V64I 0 "register_operand" "=e")
(unspec:V64I [(match_operand:V64I 1 "register_operand" "e") (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
(match_operand:V64I 2 "register_operand" "e")] (match_operand:V64I 2 "register_operand" "e")]
UNSPEC_ALIGNDATA))] UNSPEC_ALIGNDATA))
(use (reg:SI GSR_REG))]
"TARGET_VIS" "TARGET_VIS"
"faligndata\t%1, %2, %0" "faligndata\t%1, %2, %0"
[(set_attr "type" "fga") [(set_attr "type" "fga")
(set_attr "fptype" "double")]) (set_attr "fptype" "double")])
(define_insn "alignaddr<P:mode>_vis" (define_insn "alignaddrsi_vis"
[(set (match_operand:P 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
(unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
(match_operand:P 2 "register_or_zero_operand" "rJ")] (match_operand:SI 2 "register_or_zero_operand" "rJ")))
UNSPEC_ALIGNADDR))] (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" "TARGET_VIS"
"alignaddr\t%r1, %r2, %0") "alignaddr\t%r1, %r2, %0")
(define_insn "alignaddrl<P:mode>_vis" (define_insn "alignaddrdi_vis"
[(set (match_operand:P 0 "register_operand" "=r") [(set (match_operand:DI 0 "register_operand" "=r")
(unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
(match_operand:P 2 "register_or_zero_operand" "rJ")] (match_operand:DI 2 "register_or_zero_operand" "rJ")))
UNSPEC_ALIGNADDRL))] (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" "TARGET_VIS"
"alignaddrl\t%r1, %r2, %0") "alignaddrl\t%r1, %r2, %0")
......
...@@ -79,7 +79,7 @@ ...@@ -79,7 +79,7 @@
(define_insn_reservation "us1_single" 1 (define_insn_reservation "us1_single" 1
(and (eq_attr "cpu" "ultrasparc") (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") "us1_single_issue")
(define_insn_reservation "us1_simple_ieuN" 1 (define_insn_reservation "us1_simple_ieuN" 1
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
(define_insn_reservation "us3_single" 1 (define_insn_reservation "us3_single" 1
(and (eq_attr "cpu" "ultrasparc3") (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") "us3_single_issue")
(define_insn_reservation "us3_integer" 1 (define_insn_reservation "us3_integer" 1
......
...@@ -31,6 +31,20 @@ typedef unsigned char __v8qi __attribute__ ((__vector_size__ (8))); ...@@ -31,6 +31,20 @@ typedef unsigned char __v8qi __attribute__ ((__vector_size__ (8)));
typedef unsigned char __v4qi __attribute__ ((__vector_size__ (4))); typedef unsigned char __v4qi __attribute__ ((__vector_size__ (4)));
typedef int __i64 __attribute__ ((__mode__ (DI))); 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 * extern __inline void *
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__vis_alignaddr (void *__A, long __B) __vis_alignaddr (void *__A, long __B)
......
...@@ -12935,6 +12935,9 @@ typedef short v2hi __attribute__ ((vector_size (4))); ...@@ -12935,6 +12935,9 @@ typedef short v2hi __attribute__ ((vector_size (4)));
typedef unsigned char v8qi __attribute__ ((vector_size (8))); typedef unsigned char v8qi __attribute__ ((vector_size (8)));
typedef unsigned char v4qi __attribute__ ((vector_size (4))); 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_alignaddr (void *, long);
void * __builtin_vis_alignaddrl (void *, long); void * __builtin_vis_alignaddrl (void *, long);
int64_t __builtin_vis_faligndatadi (int64_t, int64_t); int64_t __builtin_vis_faligndatadi (int64_t, int64_t);
......
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