Commit f313d112 by Nathan Sidwell Committed by Nathan Sidwell

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
parent 7b2eca00
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); ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 *) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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")))]
......
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