Commit 81c2dfb9 by Ian Bolton Committed by Ian Bolton

AArch64 - Improve MOVI handling (4/5)

From-SVN: r199657
parent 48063b9d
2013-06-04 Ian Bolton <ian.bolton@arm.com> 2013-06-04 Ian Bolton <ian.bolton@arm.com>
* config/aarch64/aarch64.c (simd_immediate_info): Remove
element_char member.
(sizetochar): Return signed char.
(aarch64_simd_valid_immediate): Remove elchar and other
unnecessary variables.
(aarch64_output_simd_mov_immediate): Take rtx instead of &rtx.
Calculate element_char as required.
* config/aarch64/aarch64-protos.h: Update and move prototype
for aarch64_output_simd_mov_immediate.
* config/aarch64/aarch64-simd.md (*aarch64_simd_mov<mode>):
Update arguments.
2013-06-04 Ian Bolton <ian.bolton@arm.com>
* config/aarch64/aarch64.c (simd_immediate_info): Struct to hold * config/aarch64/aarch64.c (simd_immediate_info): Struct to hold
information completed by aarch64_simd_valid_immediate. information completed by aarch64_simd_valid_immediate.
(aarch64_legitimate_constant_p): Update arguments. (aarch64_legitimate_constant_p): Update arguments.
......
...@@ -149,6 +149,7 @@ bool aarch64_legitimate_pic_operand_p (rtx); ...@@ -149,6 +149,7 @@ bool aarch64_legitimate_pic_operand_p (rtx);
bool aarch64_move_imm (HOST_WIDE_INT, enum machine_mode); bool aarch64_move_imm (HOST_WIDE_INT, enum machine_mode);
bool aarch64_mov_operand_p (rtx, enum aarch64_symbol_context, bool aarch64_mov_operand_p (rtx, enum aarch64_symbol_context,
enum machine_mode); enum machine_mode);
char *aarch64_output_simd_mov_immediate (rtx, enum machine_mode, unsigned);
bool aarch64_pad_arg_upward (enum machine_mode, const_tree); bool aarch64_pad_arg_upward (enum machine_mode, const_tree);
bool aarch64_pad_reg_upward (enum machine_mode, const_tree, bool); bool aarch64_pad_reg_upward (enum machine_mode, const_tree, bool);
bool aarch64_regno_ok_for_base_p (int, bool); bool aarch64_regno_ok_for_base_p (int, bool);
...@@ -259,6 +260,4 @@ extern void aarch64_split_combinev16qi (rtx operands[3]); ...@@ -259,6 +260,4 @@ extern void aarch64_split_combinev16qi (rtx operands[3]);
extern void aarch64_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel); extern void aarch64_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel);
extern bool extern bool
aarch64_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel); aarch64_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel);
char* aarch64_output_simd_mov_immediate (rtx *, enum machine_mode, unsigned);
#endif /* GCC_AARCH64_PROTOS_H */ #endif /* GCC_AARCH64_PROTOS_H */
...@@ -409,7 +409,7 @@ ...@@ -409,7 +409,7 @@
case 4: return "ins\t%0.d[0], %1"; case 4: return "ins\t%0.d[0], %1";
case 5: return "mov\t%0, %1"; case 5: return "mov\t%0, %1";
case 6: case 6:
return aarch64_output_simd_mov_immediate (&operands[1], return aarch64_output_simd_mov_immediate (operands[1],
<MODE>mode, 64); <MODE>mode, 64);
default: gcc_unreachable (); default: gcc_unreachable ();
} }
...@@ -440,7 +440,7 @@ ...@@ -440,7 +440,7 @@
case 5: case 5:
return "#"; return "#";
case 6: case 6:
return aarch64_output_simd_mov_immediate (&operands[1], <MODE>mode, 128); return aarch64_output_simd_mov_immediate (operands[1], <MODE>mode, 128);
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
......
...@@ -92,7 +92,6 @@ struct simd_immediate_info ...@@ -92,7 +92,6 @@ struct simd_immediate_info
rtx value; rtx value;
int shift; int shift;
int element_width; int element_width;
unsigned char element_char;
bool mvn; bool mvn;
}; };
...@@ -6103,7 +6102,7 @@ aarch64_mangle_type (const_tree type) ...@@ -6103,7 +6102,7 @@ aarch64_mangle_type (const_tree type)
} }
/* Return the equivalent letter for size. */ /* Return the equivalent letter for size. */
static unsigned char static char
sizetochar (int size) sizetochar (int size)
{ {
switch (size) switch (size)
...@@ -6164,7 +6163,6 @@ aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, bool inverse, ...@@ -6164,7 +6163,6 @@ aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, bool inverse,
{ \ { \
immtype = (CLASS); \ immtype = (CLASS); \
elsize = (ELSIZE); \ elsize = (ELSIZE); \
elchar = sizetochar (elsize); \
eshift = (SHIFT); \ eshift = (SHIFT); \
emvn = (NEG); \ emvn = (NEG); \
break; \ break; \
...@@ -6173,25 +6171,20 @@ aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, bool inverse, ...@@ -6173,25 +6171,20 @@ aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, bool inverse,
unsigned int i, elsize = 0, idx = 0, n_elts = CONST_VECTOR_NUNITS (op); unsigned int i, elsize = 0, idx = 0, n_elts = CONST_VECTOR_NUNITS (op);
unsigned int innersize = GET_MODE_SIZE (GET_MODE_INNER (mode)); unsigned int innersize = GET_MODE_SIZE (GET_MODE_INNER (mode));
unsigned char bytes[16]; unsigned char bytes[16];
unsigned char elchar = 0;
int immtype = -1, matches; int immtype = -1, matches;
unsigned int invmask = inverse ? 0xff : 0; unsigned int invmask = inverse ? 0xff : 0;
int eshift, emvn; int eshift, emvn;
if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT) if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
{ {
bool simd_imm_zero = aarch64_simd_imm_zero_p (op, mode); if (! (aarch64_simd_imm_zero_p (op, mode)
int elem_width = GET_MODE_BITSIZE (GET_MODE (CONST_VECTOR_ELT (op, 0))); || aarch64_vect_float_const_representable_p (op)))
if (!(simd_imm_zero
|| aarch64_vect_float_const_representable_p (op)))
return false; return false;
if (info) if (info)
{ {
info->value = CONST_VECTOR_ELT (op, 0); info->value = CONST_VECTOR_ELT (op, 0);
info->element_width = elem_width; info->element_width = GET_MODE_BITSIZE (GET_MODE (info->value));
info->element_char = sizetochar (elem_width);
info->mvn = false; info->mvn = false;
info->shift = 0; info->shift = 0;
} }
...@@ -6299,7 +6292,6 @@ aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, bool inverse, ...@@ -6299,7 +6292,6 @@ aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, bool inverse,
if (info) if (info)
{ {
info->element_width = elsize; info->element_width = elsize;
info->element_char = elchar;
info->mvn = emvn != 0; info->mvn = emvn != 0;
info->shift = eshift; info->shift = eshift;
...@@ -7230,7 +7222,7 @@ aarch64_float_const_representable_p (rtx x) ...@@ -7230,7 +7222,7 @@ aarch64_float_const_representable_p (rtx x)
} }
char* char*
aarch64_output_simd_mov_immediate (rtx *const_vector, aarch64_output_simd_mov_immediate (rtx const_vector,
enum machine_mode mode, enum machine_mode mode,
unsigned width) unsigned width)
{ {
...@@ -7238,16 +7230,17 @@ aarch64_output_simd_mov_immediate (rtx *const_vector, ...@@ -7238,16 +7230,17 @@ aarch64_output_simd_mov_immediate (rtx *const_vector,
static char templ[40]; static char templ[40];
const char *mnemonic; const char *mnemonic;
unsigned int lane_count = 0; unsigned int lane_count = 0;
char element_char;
struct simd_immediate_info info; struct simd_immediate_info info;
/* This will return true to show const_vector is legal for use as either /* This will return true to show const_vector is legal for use as either
a AdvSIMD MOVI instruction (or, implicitly, MVNI) immediate. It will a AdvSIMD MOVI instruction (or, implicitly, MVNI) immediate. It will
also update INFO to show how the immediate should be generated. */ also update INFO to show how the immediate should be generated. */
is_valid = aarch64_simd_valid_immediate (*const_vector, mode, false, &info); is_valid = aarch64_simd_valid_immediate (const_vector, mode, false, &info);
gcc_assert (is_valid); gcc_assert (is_valid);
gcc_assert (info.element_width != 0); element_char = sizetochar (info.element_width);
lane_count = width / info.element_width; lane_count = width / info.element_width;
mode = GET_MODE_INNER (mode); mode = GET_MODE_INNER (mode);
...@@ -7269,7 +7262,7 @@ aarch64_output_simd_mov_immediate (rtx *const_vector, ...@@ -7269,7 +7262,7 @@ aarch64_output_simd_mov_immediate (rtx *const_vector,
snprintf (templ, sizeof (templ), "fmov\t%%d0, %s", float_buf); snprintf (templ, sizeof (templ), "fmov\t%%d0, %s", float_buf);
else else
snprintf (templ, sizeof (templ), "fmov\t%%0.%d%c, %s", snprintf (templ, sizeof (templ), "fmov\t%%0.%d%c, %s",
lane_count, info.element_char, float_buf); lane_count, element_char, float_buf);
return templ; return templ;
} }
} }
...@@ -7281,11 +7274,11 @@ aarch64_output_simd_mov_immediate (rtx *const_vector, ...@@ -7281,11 +7274,11 @@ aarch64_output_simd_mov_immediate (rtx *const_vector,
mnemonic, UINTVAL (info.value)); mnemonic, UINTVAL (info.value));
else if (info.shift) else if (info.shift)
snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " HOST_WIDE_INT_PRINT_HEX snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " HOST_WIDE_INT_PRINT_HEX
", lsl %d", mnemonic, lane_count, info.element_char, ", lsl %d", mnemonic, lane_count, element_char,
UINTVAL (info.value), info.shift); UINTVAL (info.value), info.shift);
else else
snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " HOST_WIDE_INT_PRINT_HEX, snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " HOST_WIDE_INT_PRINT_HEX,
mnemonic, lane_count, info.element_char, UINTVAL (info.value)); mnemonic, lane_count, element_char, UINTVAL (info.value));
return templ; return templ;
} }
......
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