mirror of git://gcc.gnu.org/git/gcc.git
nvptx-protos.h (nvptx_output_mov_insn): Declare.
* config/nvptx/nvptx-protos.h (nvptx_output_mov_insn): Declare. (nvptx_underlying_object_mode): Delete. * config/nvptx/nvptx.c (nvptx_underlying_object_mode): Delete. (output_reg): New. (nvptx_declare_function_name): Use output_reg. Remove punning buffer. (nvptx_output_mov_insn): New. (nvptx_print_operand): Separate SUBREG handling, remove 'f' case, Use output_reg. Merge 't' and 'u' handling. * config/nvptx/nvptx.h (NVPTX_PUNNING_BUFFER_REGNUM): Delete. (struct machine_function): Remvoe punning_buffer_size. (REGISTER_NAMES): Remove %punbuffer. * config/nvptx/nvptx.md (UNSPEC_CPLX_LOWPART, UNSPEC_CPLX_HIGHPART): Delete. (*mov<mode>_insn [QHSDIM): Remove unnecessary constraints, use nvptx_output_mov_insn. (*mov<mode>_insn [SDFM): Reorder constraints to match integer moc. Use nvptx_output_mov_insn. (highpartscsf2, set_highpartscsf2, lowpartscsf2, set_lowpartscsf2): Delete. (mov<mode> [SDCM]): Delete. From-SVN: r231180
This commit is contained in:
parent
7b2eca0029
commit
f313d112b0
|
|
@ -1,3 +1,27 @@
|
||||||
|
2015-12-02 Nathan Sidwell <nathan@acm.org>
|
||||||
|
|
||||||
|
* config/nvptx/nvptx-protos.h (nvptx_output_mov_insn): Declare.
|
||||||
|
(nvptx_underlying_object_mode): Delete.
|
||||||
|
* config/nvptx/nvptx.c (nvptx_underlying_object_mode): Delete.
|
||||||
|
(output_reg): New.
|
||||||
|
(nvptx_declare_function_name): Use output_reg. Remove punning
|
||||||
|
buffer.
|
||||||
|
(nvptx_output_mov_insn): New.
|
||||||
|
(nvptx_print_operand): Separate SUBREG handling, remove 'f' case,
|
||||||
|
Use output_reg. Merge 't' and 'u' handling.
|
||||||
|
* config/nvptx/nvptx.h (NVPTX_PUNNING_BUFFER_REGNUM): Delete.
|
||||||
|
(struct machine_function): Remvoe punning_buffer_size.
|
||||||
|
(REGISTER_NAMES): Remove %punbuffer.
|
||||||
|
* config/nvptx/nvptx.md (UNSPEC_CPLX_LOWPART,
|
||||||
|
UNSPEC_CPLX_HIGHPART): Delete.
|
||||||
|
(*mov<mode>_insn [QHSDIM): Remove unnecessary constraints, use
|
||||||
|
nvptx_output_mov_insn.
|
||||||
|
(*mov<mode>_insn [SDFM): Reorder constraints to match integer
|
||||||
|
moc. Use nvptx_output_mov_insn.
|
||||||
|
(highpartscsf2, set_highpartscsf2, lowpartscsf2,
|
||||||
|
set_lowpartscsf2): Delete.
|
||||||
|
(mov<mode> [SDCM]): Delete.
|
||||||
|
|
||||||
2015-12-02 Richard Biener <rguenther@suse.de>
|
2015-12-02 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
* tree.h (tree_invariant_p): Declare.
|
* tree.h (tree_invariant_p): Declare.
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,9 @@ extern void nvptx_expand_oacc_join (unsigned);
|
||||||
extern void nvptx_expand_call (rtx, rtx);
|
extern void nvptx_expand_call (rtx, rtx);
|
||||||
extern rtx nvptx_expand_compare (rtx);
|
extern rtx nvptx_expand_compare (rtx);
|
||||||
extern const char *nvptx_ptx_type_from_mode (machine_mode, bool);
|
extern const char *nvptx_ptx_type_from_mode (machine_mode, bool);
|
||||||
|
extern const char *nvptx_output_mov_insn (rtx, rtx);
|
||||||
extern const char *nvptx_output_call_insn (rtx_insn *, rtx, rtx);
|
extern const char *nvptx_output_call_insn (rtx_insn *, rtx, rtx);
|
||||||
extern const char *nvptx_output_return (void);
|
extern const char *nvptx_output_return (void);
|
||||||
extern machine_mode nvptx_underlying_object_mode (rtx);
|
|
||||||
extern const char *nvptx_section_from_addr_space (addr_space_t);
|
extern const char *nvptx_section_from_addr_space (addr_space_t);
|
||||||
extern bool nvptx_hard_regno_mode_ok (int, machine_mode);
|
extern bool nvptx_hard_regno_mode_ok (int, machine_mode);
|
||||||
extern rtx nvptx_maybe_convert_symbolic_operand (rtx);
|
extern rtx nvptx_maybe_convert_symbolic_operand (rtx);
|
||||||
|
|
|
||||||
|
|
@ -155,23 +155,6 @@ nvptx_option_override (void)
|
||||||
worker_red_align = GET_MODE_ALIGNMENT (SImode) / BITS_PER_UNIT;
|
worker_red_align = GET_MODE_ALIGNMENT (SImode) / BITS_PER_UNIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the mode to be used when declaring a ptx object for OBJ.
|
|
||||||
For objects with subparts such as complex modes this is the mode
|
|
||||||
of the subpart. */
|
|
||||||
|
|
||||||
machine_mode
|
|
||||||
nvptx_underlying_object_mode (rtx obj)
|
|
||||||
{
|
|
||||||
if (GET_CODE (obj) == SUBREG)
|
|
||||||
obj = SUBREG_REG (obj);
|
|
||||||
machine_mode mode = GET_MODE (obj);
|
|
||||||
if (mode == TImode)
|
|
||||||
return DImode;
|
|
||||||
if (COMPLEX_MODE_P (mode))
|
|
||||||
return GET_MODE_INNER (mode);
|
|
||||||
return mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return a ptx type for MODE. If PROMOTE, then use .u32 for QImode to
|
/* Return a ptx type for MODE. If PROMOTE, then use .u32 for QImode to
|
||||||
deal with ptx ideosyncracies. */
|
deal with ptx ideosyncracies. */
|
||||||
|
|
||||||
|
|
@ -257,6 +240,37 @@ maybe_split_mode (machine_mode mode)
|
||||||
return VOIDmode;
|
return VOIDmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Output a register, subreg, or register pair (with optional
|
||||||
|
enclosing braces). */
|
||||||
|
|
||||||
|
static void
|
||||||
|
output_reg (FILE *file, unsigned regno, machine_mode inner_mode,
|
||||||
|
int subreg_offset = -1)
|
||||||
|
{
|
||||||
|
if (inner_mode == VOIDmode)
|
||||||
|
{
|
||||||
|
if (HARD_REGISTER_NUM_P (regno))
|
||||||
|
fprintf (file, "%s", reg_names[regno]);
|
||||||
|
else
|
||||||
|
fprintf (file, "%%r%d", regno);
|
||||||
|
}
|
||||||
|
else if (subreg_offset >= 0)
|
||||||
|
{
|
||||||
|
output_reg (file, regno, VOIDmode);
|
||||||
|
fprintf (file, "$%d", subreg_offset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (subreg_offset == -1)
|
||||||
|
fprintf (file, "{");
|
||||||
|
output_reg (file, regno, inner_mode, GET_MODE_SIZE (inner_mode));
|
||||||
|
fprintf (file, ",");
|
||||||
|
output_reg (file, regno, inner_mode, 0);
|
||||||
|
if (subreg_offset == -1)
|
||||||
|
fprintf (file, "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Emit forking instructions for MASK. */
|
/* Emit forking instructions for MASK. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -724,16 +738,12 @@ nvptx_declare_function_name (FILE *file, const char *name, const_tree decl)
|
||||||
{
|
{
|
||||||
machine_mode mode = PSEUDO_REGNO_MODE (i);
|
machine_mode mode = PSEUDO_REGNO_MODE (i);
|
||||||
machine_mode split = maybe_split_mode (mode);
|
machine_mode split = maybe_split_mode (mode);
|
||||||
|
|
||||||
if (split != VOIDmode)
|
if (split != VOIDmode)
|
||||||
{
|
mode = split;
|
||||||
fprintf (file, "\t.reg%s %%r%d$%d;\n",
|
fprintf (file, "\t.reg%s ", nvptx_ptx_type_from_mode (mode, true));
|
||||||
nvptx_ptx_type_from_mode (split, true), i, 0);
|
output_reg (file, i, split, -2);
|
||||||
fprintf (file, "\t.reg%s %%r%d$%d;\n",
|
fprintf (file, ";\n");
|
||||||
nvptx_ptx_type_from_mode (split, true), i, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
fprintf (file, "\t.reg%s %%r%d;\n",
|
|
||||||
nvptx_ptx_type_from_mode (mode, true), i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -754,15 +764,6 @@ nvptx_declare_function_name (FILE *file, const char *name, const_tree decl)
|
||||||
BITS_PER_WORD);
|
BITS_PER_WORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfun->machine->punning_buffer_size > 0)
|
|
||||||
{
|
|
||||||
fprintf (file, "\t.reg.u%d %%punbuffer;\n"
|
|
||||||
"\t.local.align 8 .b8 %%punbuffer_ar[%d];\n",
|
|
||||||
BITS_PER_WORD, cfun->machine->punning_buffer_size);
|
|
||||||
fprintf (file, "\tcvta.local.u%d %%punbuffer, %%punbuffer_ar;\n",
|
|
||||||
BITS_PER_WORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Declare a local variable for the frame. */
|
/* Declare a local variable for the frame. */
|
||||||
sz = get_frame_size ();
|
sz = get_frame_size ();
|
||||||
if (sz > 0 || cfun->machine->has_call_with_sc)
|
if (sz > 0 || cfun->machine->has_call_with_sc)
|
||||||
|
|
@ -1755,6 +1756,7 @@ nvptx_globalize_label (FILE *, const char *)
|
||||||
|
|
||||||
/* Implement TARGET_ASM_ASSEMBLE_UNDEFINED_DECL. Write an extern
|
/* Implement TARGET_ASM_ASSEMBLE_UNDEFINED_DECL. Write an extern
|
||||||
declaration only for variable DECL with NAME to FILE. */
|
declaration only for variable DECL with NAME to FILE. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nvptx_assemble_undefined_decl (FILE *file, const char *name, const_tree decl)
|
nvptx_assemble_undefined_decl (FILE *file, const char *name, const_tree decl)
|
||||||
{
|
{
|
||||||
|
|
@ -1772,6 +1774,37 @@ nvptx_assemble_undefined_decl (FILE *file, const char *name, const_tree decl)
|
||||||
fprintf (file, ";\n\n");
|
fprintf (file, ";\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Output a pattern for a move instruction. */
|
||||||
|
|
||||||
|
const char *
|
||||||
|
nvptx_output_mov_insn (rtx dst, rtx src)
|
||||||
|
{
|
||||||
|
machine_mode dst_mode = GET_MODE (dst);
|
||||||
|
machine_mode dst_inner = (GET_CODE (dst) == SUBREG
|
||||||
|
? GET_MODE (XEXP (dst, 0)) : dst_mode);
|
||||||
|
machine_mode src_inner = (GET_CODE (src) == SUBREG
|
||||||
|
? GET_MODE (XEXP (src, 0)) : dst_mode);
|
||||||
|
|
||||||
|
if (REG_P (dst) && REGNO (dst) == NVPTX_RETURN_REGNUM && dst_mode == HImode)
|
||||||
|
/* Special handling for the return register. It's never really an
|
||||||
|
HI object, and only occurs as the destination of a move
|
||||||
|
insn. */
|
||||||
|
dst_inner = SImode;
|
||||||
|
|
||||||
|
if (src_inner == dst_inner)
|
||||||
|
return "%.\tmov%t0\t%0, %1;";
|
||||||
|
|
||||||
|
if (CONSTANT_P (src))
|
||||||
|
return (GET_MODE_CLASS (dst_inner) == MODE_INT
|
||||||
|
&& GET_MODE_CLASS (src_inner) != MODE_FLOAT
|
||||||
|
? "%.\tmov%t0\t%0, %1;" : "%.\tmov.b%T0\t%0, %1;");
|
||||||
|
|
||||||
|
if (GET_MODE_SIZE (dst_inner) == GET_MODE_SIZE (src_inner))
|
||||||
|
return "%.\tmov.b%T0\t%0, %1;";
|
||||||
|
|
||||||
|
return "%.\tcvt%t0%t1\t%0, %1;";
|
||||||
|
}
|
||||||
|
|
||||||
/* Output INSN, which is a call to CALLEE with result RESULT. For ptx, this
|
/* Output INSN, which is a call to CALLEE with result RESULT. For ptx, this
|
||||||
involves writing .param declarations and in/out copies into them. For
|
involves writing .param declarations and in/out copies into them. For
|
||||||
indirect calls, also write the .callprototype. */
|
indirect calls, also write the .callprototype. */
|
||||||
|
|
@ -1921,7 +1954,6 @@ nvptx_print_operand_address (FILE *file, machine_mode mode, rtx addr)
|
||||||
|
|
||||||
A -- print an address space identifier for a MEM
|
A -- print an address space identifier for a MEM
|
||||||
c -- print an opcode suffix for a comparison operator, including a type code
|
c -- print an opcode suffix for a comparison operator, including a type code
|
||||||
f -- print a full reg even for something that must always be split
|
|
||||||
S -- print a shuffle kind specified by CONST_INT
|
S -- print a shuffle kind specified by CONST_INT
|
||||||
t -- print a type opcode suffix, promoting QImode to 32 bits
|
t -- print a type opcode suffix, promoting QImode to 32 bits
|
||||||
T -- print a type size in bits
|
T -- print a type size in bits
|
||||||
|
|
@ -1930,9 +1962,6 @@ nvptx_print_operand_address (FILE *file, machine_mode mode, rtx addr)
|
||||||
static void
|
static void
|
||||||
nvptx_print_operand (FILE *file, rtx x, int code)
|
nvptx_print_operand (FILE *file, rtx x, int code)
|
||||||
{
|
{
|
||||||
rtx orig_x = x;
|
|
||||||
machine_mode op_mode;
|
|
||||||
|
|
||||||
if (code == '.')
|
if (code == '.')
|
||||||
{
|
{
|
||||||
x = current_insn_predicate;
|
x = current_insn_predicate;
|
||||||
|
|
@ -1954,6 +1983,7 @@ nvptx_print_operand (FILE *file, rtx x, int code)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum rtx_code x_code = GET_CODE (x);
|
enum rtx_code x_code = GET_CODE (x);
|
||||||
|
machine_mode mode = GET_MODE (x);
|
||||||
|
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
|
|
@ -1975,13 +2005,16 @@ nvptx_print_operand (FILE *file, rtx x, int code)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
op_mode = nvptx_underlying_object_mode (x);
|
|
||||||
fprintf (file, "%s", nvptx_ptx_type_from_mode (op_mode, true));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'u':
|
case 'u':
|
||||||
op_mode = nvptx_underlying_object_mode (x);
|
if (x_code == SUBREG)
|
||||||
fprintf (file, "%s", nvptx_ptx_type_from_mode (op_mode, false));
|
{
|
||||||
|
mode = GET_MODE (SUBREG_REG (x));
|
||||||
|
if (mode == TImode)
|
||||||
|
mode = DImode;
|
||||||
|
else if (COMPLEX_MODE_P (mode))
|
||||||
|
mode = GET_MODE_INNER (mode);
|
||||||
|
}
|
||||||
|
fprintf (file, "%s", nvptx_ptx_type_from_mode (mode, code == 't'));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'S':
|
case 'S':
|
||||||
|
|
@ -1994,7 +2027,7 @@ nvptx_print_operand (FILE *file, rtx x, int code)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'T':
|
case 'T':
|
||||||
fprintf (file, "%d", GET_MODE_BITSIZE (GET_MODE (x)));
|
fprintf (file, "%d", GET_MODE_BITSIZE (mode));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'j':
|
case 'j':
|
||||||
|
|
@ -2006,14 +2039,14 @@ nvptx_print_operand (FILE *file, rtx x, int code)
|
||||||
goto common;
|
goto common;
|
||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
op_mode = GET_MODE (XEXP (x, 0));
|
mode = GET_MODE (XEXP (x, 0));
|
||||||
switch (x_code)
|
switch (x_code)
|
||||||
{
|
{
|
||||||
case EQ:
|
case EQ:
|
||||||
fputs (".eq", file);
|
fputs (".eq", file);
|
||||||
break;
|
break;
|
||||||
case NE:
|
case NE:
|
||||||
if (FLOAT_MODE_P (op_mode))
|
if (FLOAT_MODE_P (mode))
|
||||||
fputs (".neu", file);
|
fputs (".neu", file);
|
||||||
else
|
else
|
||||||
fputs (".ne", file);
|
fputs (".ne", file);
|
||||||
|
|
@ -2069,38 +2102,39 @@ nvptx_print_operand (FILE *file, rtx x, int code)
|
||||||
default:
|
default:
|
||||||
gcc_unreachable ();
|
gcc_unreachable ();
|
||||||
}
|
}
|
||||||
if (FLOAT_MODE_P (op_mode)
|
if (FLOAT_MODE_P (mode)
|
||||||
|| x_code == EQ || x_code == NE
|
|| x_code == EQ || x_code == NE
|
||||||
|| x_code == GEU || x_code == GTU
|
|| x_code == GEU || x_code == GTU
|
||||||
|| x_code == LEU || x_code == LTU)
|
|| x_code == LEU || x_code == LTU)
|
||||||
fputs (nvptx_ptx_type_from_mode (op_mode, true), file);
|
fputs (nvptx_ptx_type_from_mode (mode, true), file);
|
||||||
else
|
else
|
||||||
fprintf (file, ".s%d", GET_MODE_BITSIZE (op_mode));
|
fprintf (file, ".s%d", GET_MODE_BITSIZE (mode));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
common:
|
common:
|
||||||
switch (x_code)
|
switch (x_code)
|
||||||
{
|
{
|
||||||
case SUBREG:
|
case SUBREG:
|
||||||
x = SUBREG_REG (x);
|
{
|
||||||
/* fall through */
|
rtx inner_x = SUBREG_REG (x);
|
||||||
|
machine_mode inner_mode = GET_MODE (inner_x);
|
||||||
|
machine_mode split = maybe_split_mode (inner_mode);
|
||||||
|
|
||||||
|
if (split != VOIDmode
|
||||||
|
&& (GET_MODE_SIZE (inner_mode) == GET_MODE_SIZE (mode)))
|
||||||
|
output_reg (file, REGNO (inner_x), split);
|
||||||
|
else
|
||||||
|
output_reg (file, REGNO (inner_x), split, SUBREG_BYTE (x));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case REG:
|
case REG:
|
||||||
if (HARD_REGISTER_P (x))
|
output_reg (file, REGNO (x), maybe_split_mode (mode));
|
||||||
fprintf (file, "%s", reg_names[REGNO (x)]);
|
|
||||||
else
|
|
||||||
fprintf (file, "%%r%d", REGNO (x));
|
|
||||||
if (code != 'f' && maybe_split_mode (GET_MODE (x)) != VOIDmode)
|
|
||||||
{
|
|
||||||
gcc_assert (GET_CODE (orig_x) == SUBREG
|
|
||||||
&& maybe_split_mode (GET_MODE (orig_x)) == VOIDmode);
|
|
||||||
fprintf (file, "$%d", SUBREG_BYTE (orig_x) / UNITS_PER_WORD);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MEM:
|
case MEM:
|
||||||
fputc ('[', file);
|
fputc ('[', file);
|
||||||
nvptx_print_address_operand (file, XEXP (x, 0), GET_MODE (x));
|
nvptx_print_address_operand (file, XEXP (x, 0), mode);
|
||||||
fputc (']', file);
|
fputc (']', file);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -2119,10 +2153,10 @@ nvptx_print_operand (FILE *file, rtx x, int code)
|
||||||
|
|
||||||
case CONST_DOUBLE:
|
case CONST_DOUBLE:
|
||||||
long vals[2];
|
long vals[2];
|
||||||
real_to_target (vals, CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x));
|
real_to_target (vals, CONST_DOUBLE_REAL_VALUE (x), mode);
|
||||||
vals[0] &= 0xffffffff;
|
vals[0] &= 0xffffffff;
|
||||||
vals[1] &= 0xffffffff;
|
vals[1] &= 0xffffffff;
|
||||||
if (GET_MODE (x) == SFmode)
|
if (mode == SFmode)
|
||||||
fprintf (file, "0f%08lx", vals[0]);
|
fprintf (file, "0f%08lx", vals[0]);
|
||||||
else
|
else
|
||||||
fprintf (file, "0d%08lx%08lx", vals[1], vals[0]);
|
fprintf (file, "0d%08lx%08lx", vals[1], vals[0]);
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,6 @@ enum reg_class
|
||||||
|
|
||||||
#define STACK_POINTER_REGNUM 1
|
#define STACK_POINTER_REGNUM 1
|
||||||
#define HARD_FRAME_POINTER_REGNUM 2
|
#define HARD_FRAME_POINTER_REGNUM 2
|
||||||
#define NVPTX_PUNNING_BUFFER_REGNUM 3
|
|
||||||
#define NVPTX_RETURN_REGNUM 4
|
#define NVPTX_RETURN_REGNUM 4
|
||||||
#define FRAME_POINTER_REGNUM 15
|
#define FRAME_POINTER_REGNUM 15
|
||||||
#define ARG_POINTER_REGNUM 14
|
#define ARG_POINTER_REGNUM 14
|
||||||
|
|
@ -231,7 +230,6 @@ struct GTY(()) machine_function
|
||||||
bool has_call_with_sc;
|
bool has_call_with_sc;
|
||||||
HOST_WIDE_INT outgoing_stdarg_size;
|
HOST_WIDE_INT outgoing_stdarg_size;
|
||||||
int ret_reg_mode; /* machine_mode not defined yet. */
|
int ret_reg_mode; /* machine_mode not defined yet. */
|
||||||
int punning_buffer_size;
|
|
||||||
rtx axis_predicate[2];
|
rtx axis_predicate[2];
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -264,7 +262,7 @@ struct GTY(()) machine_function
|
||||||
|
|
||||||
#define REGISTER_NAMES \
|
#define REGISTER_NAMES \
|
||||||
{ \
|
{ \
|
||||||
"%hr0", "%outargs", "%hfp", "%punbuffer", "%retval", "%retval_in", "%hr6", "%hr7", \
|
"%hr0", "%outargs", "%hfp", "%hr3", "%retval", "%retval_in", "%hr6", "%hr7", \
|
||||||
"%hr8", "%hr9", "%hr10", "%hr11", "%hr12", "%hr13", "%argp", "%frame" \
|
"%hr8", "%hr9", "%hr10", "%hr11", "%hr12", "%hr13", "%argp", "%frame" \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,6 @@
|
||||||
UNSPEC_TO_SHARED
|
UNSPEC_TO_SHARED
|
||||||
UNSPEC_TO_CONST
|
UNSPEC_TO_CONST
|
||||||
|
|
||||||
UNSPEC_CPLX_LOWPART
|
|
||||||
UNSPEC_CPLX_HIGHPART
|
|
||||||
|
|
||||||
UNSPEC_COPYSIGN
|
UNSPEC_COPYSIGN
|
||||||
UNSPEC_LOG2
|
UNSPEC_LOG2
|
||||||
UNSPEC_EXP2
|
UNSPEC_EXP2
|
||||||
|
|
@ -258,74 +255,31 @@
|
||||||
%.\\tsetp.eq.u32\\t%0, 1, 1;")
|
%.\\tsetp.eq.u32\\t%0, 1, 1;")
|
||||||
|
|
||||||
(define_insn "*mov<mode>_insn"
|
(define_insn "*mov<mode>_insn"
|
||||||
[(set (match_operand:QHSDIM 0 "nvptx_nonimmediate_operand" "=R,R,R,m")
|
[(set (match_operand:QHSDIM 0 "nvptx_nonimmediate_operand" "=R,R,m")
|
||||||
(match_operand:QHSDIM 1 "general_operand" "n,Ri,m,R"))]
|
(match_operand:QHSDIM 1 "general_operand" "Ri,m,R"))]
|
||||||
"!(MEM_P (operands[0])
|
"!MEM_P (operands[0])
|
||||||
&& (!REG_P (operands[1]) || REGNO (operands[1]) <= LAST_VIRTUAL_REGISTER))"
|
|| (REG_P (operands[1]) && REGNO (operands[1]) > LAST_VIRTUAL_REGISTER)"
|
||||||
{
|
{
|
||||||
if (which_alternative == 2)
|
if (which_alternative == 1)
|
||||||
return "%.\\tld%A1%u1\\t%0, %1;";
|
return "%.\\tld%A1%u1\\t%0, %1;";
|
||||||
if (which_alternative == 3)
|
if (which_alternative == 2)
|
||||||
return "%.\\tst%A0%u0\\t%0, %1;";
|
return "%.\\tst%A0%u0\\t%0, %1;";
|
||||||
|
|
||||||
rtx dst = operands[0];
|
return nvptx_output_mov_insn (operands[0], operands[1]);
|
||||||
rtx src = operands[1];
|
|
||||||
|
|
||||||
enum machine_mode dst_mode = nvptx_underlying_object_mode (dst);
|
|
||||||
enum machine_mode src_mode = nvptx_underlying_object_mode (src);
|
|
||||||
if (GET_CODE (dst) == SUBREG)
|
|
||||||
dst = SUBREG_REG (dst);
|
|
||||||
if (GET_CODE (src) == SUBREG)
|
|
||||||
src = SUBREG_REG (src);
|
|
||||||
if (src_mode == QImode)
|
|
||||||
src_mode = SImode;
|
|
||||||
if (dst_mode == QImode)
|
|
||||||
dst_mode = SImode;
|
|
||||||
if (CONSTANT_P (src))
|
|
||||||
{
|
|
||||||
if (GET_MODE_CLASS (dst_mode) != MODE_INT)
|
|
||||||
return "%.\\tmov.b%T0\\t%0, %1;";
|
|
||||||
else
|
|
||||||
return "%.\\tmov%t0\\t%0, %1;";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Special handling for the return register; we allow this register to
|
|
||||||
only occur in the destination of a move insn. */
|
|
||||||
if (REG_P (dst) && REGNO (dst) == NVPTX_RETURN_REGNUM
|
|
||||||
&& dst_mode == HImode)
|
|
||||||
dst_mode = SImode;
|
|
||||||
if (dst_mode == src_mode)
|
|
||||||
return "%.\\tmov%t0\\t%0, %1;";
|
|
||||||
/* Mode-punning between floating point and integer. */
|
|
||||||
if (GET_MODE_SIZE (dst_mode) == GET_MODE_SIZE (src_mode))
|
|
||||||
return "%.\\tmov.b%T0\\t%0, %1;";
|
|
||||||
return "%.\\tcvt%t0%t1\\t%0, %1;";
|
|
||||||
}
|
}
|
||||||
[(set_attr "subregs_ok" "true")])
|
[(set_attr "subregs_ok" "true")])
|
||||||
|
|
||||||
(define_insn "*mov<mode>_insn"
|
(define_insn "*mov<mode>_insn"
|
||||||
[(set (match_operand:SDFM 0 "nvptx_nonimmediate_operand" "=R,R,m")
|
[(set (match_operand:SDFM 0 "nvptx_nonimmediate_operand" "=R,R,m")
|
||||||
(match_operand:SDFM 1 "general_operand" "RF,m,R"))]
|
(match_operand:SDFM 1 "general_operand" "RF,m,R"))]
|
||||||
"!(MEM_P (operands[0]) && !REG_P (operands[1]))"
|
"!MEM_P (operands[0]) || REG_P (operands[1])"
|
||||||
{
|
{
|
||||||
if (which_alternative == 1)
|
if (which_alternative == 1)
|
||||||
return "%.\\tld%A1%u0\\t%0, %1;";
|
return "%.\\tld%A1%u0\\t%0, %1;";
|
||||||
if (which_alternative == 2)
|
if (which_alternative == 2)
|
||||||
return "%.\\tst%A0%u1\\t%0, %1;";
|
return "%.\\tst%A0%u1\\t%0, %1;";
|
||||||
|
|
||||||
rtx dst = operands[0];
|
return nvptx_output_mov_insn (operands[0], operands[1]);
|
||||||
rtx src = operands[1];
|
|
||||||
if (GET_CODE (dst) == SUBREG)
|
|
||||||
dst = SUBREG_REG (dst);
|
|
||||||
if (GET_CODE (src) == SUBREG)
|
|
||||||
src = SUBREG_REG (src);
|
|
||||||
enum machine_mode dst_mode = GET_MODE (dst);
|
|
||||||
enum machine_mode src_mode = GET_MODE (src);
|
|
||||||
if (dst_mode == src_mode)
|
|
||||||
return "%.\\tmov%t0\\t%0, %1;";
|
|
||||||
if (GET_MODE_SIZE (dst_mode) == GET_MODE_SIZE (src_mode))
|
|
||||||
return "%.\\tmov.b%T0\\t%0, %1;";
|
|
||||||
gcc_unreachable ();
|
|
||||||
}
|
}
|
||||||
[(set_attr "subregs_ok" "true")])
|
[(set_attr "subregs_ok" "true")])
|
||||||
|
|
||||||
|
|
@ -373,116 +327,6 @@
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
(define_insn "highpartscsf2"
|
|
||||||
[(set (match_operand:SF 0 "nvptx_register_operand" "=R")
|
|
||||||
(unspec:SF [(match_operand:SC 1 "nvptx_register_operand")]
|
|
||||||
UNSPEC_CPLX_HIGHPART))]
|
|
||||||
""
|
|
||||||
"%.\\tmov%t0\\t%0, %f1$1;")
|
|
||||||
|
|
||||||
(define_insn "set_highpartsfsc2"
|
|
||||||
[(set (match_operand:SC 0 "nvptx_register_operand" "+R")
|
|
||||||
(unspec:SC [(match_dup 0)
|
|
||||||
(match_operand:SF 1 "nvptx_register_operand")]
|
|
||||||
UNSPEC_CPLX_HIGHPART))]
|
|
||||||
""
|
|
||||||
"%.\\tmov%t1\\t%f0$1, %1;")
|
|
||||||
|
|
||||||
(define_insn "lowpartscsf2"
|
|
||||||
[(set (match_operand:SF 0 "nvptx_register_operand" "=R")
|
|
||||||
(unspec:SF [(match_operand:SC 1 "nvptx_register_operand")]
|
|
||||||
UNSPEC_CPLX_LOWPART))]
|
|
||||||
""
|
|
||||||
"%.\\tmov%t0\\t%0, %f1$0;")
|
|
||||||
|
|
||||||
(define_insn "set_lowpartsfsc2"
|
|
||||||
[(set (match_operand:SC 0 "nvptx_register_operand" "+R")
|
|
||||||
(unspec:SC [(match_dup 0)
|
|
||||||
(match_operand:SF 1 "nvptx_register_operand")]
|
|
||||||
UNSPEC_CPLX_LOWPART))]
|
|
||||||
""
|
|
||||||
"%.\\tmov%t1\\t%f0$0, %1;")
|
|
||||||
|
|
||||||
(define_expand "mov<mode>"
|
|
||||||
[(set (match_operand:SDCM 0 "nvptx_nonimmediate_operand" "")
|
|
||||||
(match_operand:SDCM 1 "general_operand" ""))]
|
|
||||||
""
|
|
||||||
{
|
|
||||||
enum machine_mode submode = <MODE>mode == SCmode ? SFmode : DFmode;
|
|
||||||
int sz = GET_MODE_SIZE (submode);
|
|
||||||
rtx xops[4];
|
|
||||||
rtx punning_reg = NULL_RTX;
|
|
||||||
rtx copyback = NULL_RTX;
|
|
||||||
|
|
||||||
if (GET_CODE (operands[0]) == SUBREG)
|
|
||||||
{
|
|
||||||
rtx inner = SUBREG_REG (operands[0]);
|
|
||||||
enum machine_mode inner_mode = GET_MODE (inner);
|
|
||||||
int sz2 = GET_MODE_SIZE (inner_mode);
|
|
||||||
gcc_assert (sz2 >= sz);
|
|
||||||
cfun->machine->punning_buffer_size
|
|
||||||
= MAX (cfun->machine->punning_buffer_size, sz2);
|
|
||||||
if (punning_reg == NULL_RTX)
|
|
||||||
punning_reg = gen_rtx_REG (Pmode, NVPTX_PUNNING_BUFFER_REGNUM);
|
|
||||||
copyback = gen_move_insn (inner, gen_rtx_MEM (inner_mode, punning_reg));
|
|
||||||
operands[0] = gen_rtx_MEM (<MODE>mode, punning_reg);
|
|
||||||
}
|
|
||||||
if (GET_CODE (operands[1]) == SUBREG)
|
|
||||||
{
|
|
||||||
rtx inner = SUBREG_REG (operands[1]);
|
|
||||||
enum machine_mode inner_mode = GET_MODE (inner);
|
|
||||||
int sz2 = GET_MODE_SIZE (inner_mode);
|
|
||||||
gcc_assert (sz2 >= sz);
|
|
||||||
cfun->machine->punning_buffer_size
|
|
||||||
= MAX (cfun->machine->punning_buffer_size, sz2);
|
|
||||||
if (punning_reg == NULL_RTX)
|
|
||||||
punning_reg = gen_rtx_REG (Pmode, NVPTX_PUNNING_BUFFER_REGNUM);
|
|
||||||
emit_move_insn (gen_rtx_MEM (inner_mode, punning_reg), inner);
|
|
||||||
operands[1] = gen_rtx_MEM (<MODE>mode, punning_reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (REG_P (operands[0]) && submode == SFmode)
|
|
||||||
{
|
|
||||||
xops[0] = gen_reg_rtx (submode);
|
|
||||||
xops[1] = gen_reg_rtx (submode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
xops[0] = gen_lowpart (submode, operands[0]);
|
|
||||||
if (MEM_P (operands[0]))
|
|
||||||
xops[1] = adjust_address_nv (operands[0], submode, sz);
|
|
||||||
else
|
|
||||||
xops[1] = gen_highpart (submode, operands[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (REG_P (operands[1]) && submode == SFmode)
|
|
||||||
{
|
|
||||||
xops[2] = gen_reg_rtx (submode);
|
|
||||||
xops[3] = gen_reg_rtx (submode);
|
|
||||||
emit_insn (gen_lowpartscsf2 (xops[2], operands[1]));
|
|
||||||
emit_insn (gen_highpartscsf2 (xops[3], operands[1]));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
xops[2] = gen_lowpart (submode, operands[1]);
|
|
||||||
if (MEM_P (operands[1]))
|
|
||||||
xops[3] = adjust_address_nv (operands[1], submode, sz);
|
|
||||||
else
|
|
||||||
xops[3] = gen_highpart (submode, operands[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit_move_insn (xops[0], xops[2]);
|
|
||||||
emit_move_insn (xops[1], xops[3]);
|
|
||||||
if (REG_P (operands[0]) && submode == SFmode)
|
|
||||||
{
|
|
||||||
emit_insn (gen_set_lowpartsfsc2 (operands[0], xops[0]));
|
|
||||||
emit_insn (gen_set_highpartsfsc2 (operands[0], xops[1]));
|
|
||||||
}
|
|
||||||
if (copyback)
|
|
||||||
emit_insn (copyback);
|
|
||||||
DONE;
|
|
||||||
})
|
|
||||||
|
|
||||||
(define_insn "zero_extendqihi2"
|
(define_insn "zero_extendqihi2"
|
||||||
[(set (match_operand:HI 0 "nvptx_register_operand" "=R,R")
|
[(set (match_operand:HI 0 "nvptx_register_operand" "=R,R")
|
||||||
(zero_extend:HI (match_operand:QI 1 "nvptx_reg_or_mem_operand" "R,m")))]
|
(zero_extend:HI (match_operand:QI 1 "nvptx_reg_or_mem_operand" "R,m")))]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue