AArch64 - Improve MOVI handling (5/5)
From-SVN: r199658
This commit is contained in:
parent
81c2dfb933
commit
b7342d25ed
@ -1,3 +1,13 @@
|
||||
2013-06-04 Ian Bolton <ian.bolton@arm.com>
|
||||
|
||||
* config/aarch64/aarch64.md (*mov<mode>_aarch64): Call
|
||||
into function to generate MOVI instruction.
|
||||
* config/aarch64/aarch64.c (aarch64_simd_container_mode):
|
||||
New function.
|
||||
(aarch64_preferred_simd_mode): Turn into wrapper.
|
||||
(aarch64_output_scalar_simd_mov_immediate): New function.
|
||||
* config/aarch64/aarch64-protos.h: Add prototype for above.
|
||||
|
||||
2013-06-04 Ian Bolton <ian.bolton@arm.com>
|
||||
|
||||
* config/aarch64/aarch64.c (simd_immediate_info): Remove
|
||||
|
@ -149,6 +149,7 @@ bool aarch64_legitimate_pic_operand_p (rtx);
|
||||
bool aarch64_move_imm (HOST_WIDE_INT, enum machine_mode);
|
||||
bool aarch64_mov_operand_p (rtx, enum aarch64_symbol_context,
|
||||
enum machine_mode);
|
||||
char *aarch64_output_scalar_simd_mov_immediate (rtx, 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_reg_upward (enum machine_mode, const_tree, bool);
|
||||
|
@ -5989,30 +5989,55 @@ aarch64_vector_mode_supported_p (enum machine_mode mode)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return quad mode as the preferred SIMD mode. */
|
||||
/* Return appropriate SIMD container
|
||||
for MODE within a vector of WIDTH bits. */
|
||||
static enum machine_mode
|
||||
aarch64_simd_container_mode (enum machine_mode mode, unsigned width)
|
||||
{
|
||||
gcc_assert (width == 64 || width == 128);
|
||||
if (TARGET_SIMD)
|
||||
{
|
||||
if (width == 128)
|
||||
switch (mode)
|
||||
{
|
||||
case DFmode:
|
||||
return V2DFmode;
|
||||
case SFmode:
|
||||
return V4SFmode;
|
||||
case SImode:
|
||||
return V4SImode;
|
||||
case HImode:
|
||||
return V8HImode;
|
||||
case QImode:
|
||||
return V16QImode;
|
||||
case DImode:
|
||||
return V2DImode;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else
|
||||
switch (mode)
|
||||
{
|
||||
case SFmode:
|
||||
return V2SFmode;
|
||||
case SImode:
|
||||
return V2SImode;
|
||||
case HImode:
|
||||
return V4HImode;
|
||||
case QImode:
|
||||
return V8QImode;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return word_mode;
|
||||
}
|
||||
|
||||
/* Return 128-bit container as the preferred SIMD mode for MODE. */
|
||||
static enum machine_mode
|
||||
aarch64_preferred_simd_mode (enum machine_mode mode)
|
||||
{
|
||||
if (TARGET_SIMD)
|
||||
switch (mode)
|
||||
{
|
||||
case DFmode:
|
||||
return V2DFmode;
|
||||
case SFmode:
|
||||
return V4SFmode;
|
||||
case SImode:
|
||||
return V4SImode;
|
||||
case HImode:
|
||||
return V8HImode;
|
||||
case QImode:
|
||||
return V16QImode;
|
||||
case DImode:
|
||||
return V2DImode;
|
||||
break;
|
||||
|
||||
default:;
|
||||
}
|
||||
return word_mode;
|
||||
return aarch64_simd_container_mode (mode, 128);
|
||||
}
|
||||
|
||||
/* Return the bitmask of possible vector sizes for the vectorizer
|
||||
@ -7282,6 +7307,18 @@ aarch64_output_simd_mov_immediate (rtx const_vector,
|
||||
return templ;
|
||||
}
|
||||
|
||||
char*
|
||||
aarch64_output_scalar_simd_mov_immediate (rtx immediate,
|
||||
enum machine_mode mode)
|
||||
{
|
||||
enum machine_mode vmode;
|
||||
|
||||
gcc_assert (!VECTOR_MODE_P (mode));
|
||||
vmode = aarch64_simd_container_mode (mode, 64);
|
||||
rtx v_op = aarch64_simd_gen_const_vector_dup (vmode, INTVAL (immediate));
|
||||
return aarch64_output_simd_mov_immediate (v_op, vmode, 64);
|
||||
}
|
||||
|
||||
/* Split operands into moves from op[1] + op[2] into op[0]. */
|
||||
|
||||
void
|
||||
|
@ -774,17 +774,34 @@
|
||||
(match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
|
||||
"(register_operand (operands[0], <MODE>mode)
|
||||
|| aarch64_reg_or_zero (operands[1], <MODE>mode))"
|
||||
"@
|
||||
mov\\t%w0, %w1
|
||||
mov\\t%w0, %1
|
||||
movi\\t%0.<Vallxd>, %1
|
||||
ldr<size>\\t%w0, %1
|
||||
ldr\\t%<size>0, %1
|
||||
str<size>\\t%w1, %0
|
||||
str\\t%<size>1, %0
|
||||
umov\\t%w0, %1.<v>[0]
|
||||
dup\\t%0.<Vallxd>, %w1
|
||||
dup\\t%0, %1.<v>[0]"
|
||||
{
|
||||
switch (which_alternative)
|
||||
{
|
||||
case 0:
|
||||
return "mov\t%w0, %w1";
|
||||
case 1:
|
||||
return "mov\t%w0, %1";
|
||||
case 2:
|
||||
return aarch64_output_scalar_simd_mov_immediate (operands[1],
|
||||
<MODE>mode);
|
||||
case 3:
|
||||
return "ldr<size>\t%w0, %1";
|
||||
case 4:
|
||||
return "ldr\t%<size>0, %1";
|
||||
case 5:
|
||||
return "str<size>\t%w1, %0";
|
||||
case 6:
|
||||
return "str\t%<size>1, %0";
|
||||
case 7:
|
||||
return "umov\t%w0, %1.<v>[0]";
|
||||
case 8:
|
||||
return "dup\t%0.<Vallxd>, %w1";
|
||||
case 9:
|
||||
return "dup\t%0, %1.<v>[0]";
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
[(set_attr "v8type" "move,alu,alu,load1,load1,store1,store1,*,*,*")
|
||||
(set_attr "simd_type" "*,*,simd_move_imm,*,*,*,*,simd_movgp,simd_dupgp,simd_dup")
|
||||
(set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")
|
||||
|
@ -1,3 +1,7 @@
|
||||
2013-06-04 Ian Bolton <ian.bolton@arm.com>
|
||||
|
||||
* gcc.target/aarch64/movi_1.c: New test.
|
||||
|
||||
2013-06-04 Tobias Burnus <burnus@net-b.de>
|
||||
|
||||
PR fortran/37336
|
||||
|
13
gcc/testsuite/gcc.target/aarch64/movi_1.c
Normal file
13
gcc/testsuite/gcc.target/aarch64/movi_1.c
Normal file
@ -0,0 +1,13 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
void
|
||||
dummy (short* b)
|
||||
{
|
||||
/* { dg-final { scan-assembler "movi\tv\[0-9\]+\.4h, 0x4, lsl 8" } } */
|
||||
/* { dg-final { scan-assembler-not "movi\tv\[0-9\]+\.4h, 0x400" } } */
|
||||
/* { dg-final { scan-assembler-not "movi\tv\[0-9\]+\.4h, 1024" } } */
|
||||
register short x asm ("h8") = 1024;
|
||||
asm volatile ("" : : "w" (x));
|
||||
*b = x;
|
||||
}
|
Loading…
Reference in New Issue
Block a user