From 69b2447b6a3fcc303e03cba8c7c50d745b0284d2 Mon Sep 17 00:00:00 2001 From: Kevin Qin Date: Mon, 18 Nov 2013 09:20:32 +0000 Subject: [PATCH] [AArch64 NEON]Add mov alias for simd copy instructions. Set some unspecified bits of INS/DUP to zero as ARMARM requested. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194996 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64InstrNEON.td | 96 +++++++++++++++++--------- test/MC/AArch64/neon-simd-copy.s | 46 +++++++++--- 2 files changed, 98 insertions(+), 44 deletions(-) diff --git a/lib/Target/AArch64/AArch64InstrNEON.td b/lib/Target/AArch64/AArch64InstrNEON.td index 2bcc0d9e1f6..766b0bc45ba 100644 --- a/lib/Target/AArch64/AArch64InstrNEON.td +++ b/lib/Target/AArch64/AArch64InstrNEON.td @@ -5289,21 +5289,6 @@ def neon_uimm4 : Operand, let PrintMethod = "printUImmHexOperand"; } -class NeonI_INS_main - : NeonI_copy<0b1, 0b0, 0b0011, - (outs VPR128:$Rd), (ins VPR128:$src, OpGPR:$Rn, OpImm:$Imm), - asmop # "\t$Rd." # Res # "[$Imm], $Rn", - [(set (ResTy VPR128:$Rd), - (ResTy (vector_insert - (ResTy VPR128:$src), - (OpTy OpGPR:$Rn), - (OpImm:$Imm))))], - NoItinerary> { - bits<4> Imm; - let Constraints = "$src = $Rd"; -} - // Bitwise Extract class NeonI_Extract op2, string asmop, string OpS, RegisterOperand OpVPR, Operand OpImm> @@ -6157,6 +6142,21 @@ defm SQDMLSL_lane_v3 : NI_2VEL_v3_qdma_pat<"SQDMLSLvve", "Neon_qdmlsl">; // End of implementation for instruction class (3V Elem) +class NeonI_INS_main + : NeonI_copy<0b1, 0b0, 0b0011, + (outs VPR128:$Rd), (ins VPR128:$src, OpGPR:$Rn, OpImm:$Imm), + asmop # "\t$Rd." # Res # "[$Imm], $Rn", + [(set (ResTy VPR128:$Rd), + (ResTy (vector_insert + (ResTy VPR128:$src), + (OpTy OpGPR:$Rn), + (OpImm:$Imm))))], + NoItinerary> { + bits<4> Imm; + let Constraints = "$src = $Rd"; +} + //Insert element (vector, from main) def INSbw : NeonI_INS_main<"ins", "b", v16i8, GPR32, i32, neon_uimm4_bare> { @@ -6175,6 +6175,15 @@ def INSdx : NeonI_INS_main<"ins", "d", v2i64, GPR64, i64, let Inst{20-16} = {Imm, 0b1, 0b0, 0b0, 0b0}; } +def : NeonInstAlias<"mov $Rd.b[$Imm], $Rn", + (INSbw VPR128:$Rd, GPR32:$Rn, neon_uimm4_bare:$Imm), 0>; +def : NeonInstAlias<"mov $Rd.h[$Imm], $Rn", + (INShw VPR128:$Rd, GPR32:$Rn, neon_uimm3_bare:$Imm), 0>; +def : NeonInstAlias<"mov $Rd.s[$Imm], $Rn", + (INSsw VPR128:$Rd, GPR32:$Rn, neon_uimm2_bare:$Imm), 0>; +def : NeonInstAlias<"mov $Rd.d[$Imm], $Rn", + (INSdx VPR128:$Rd, GPR64:$Rn, neon_uimm1_bare:$Imm), 0>; + class Neon_INS_main_pattern @@ -6214,20 +6223,33 @@ def INSELb : NeonI_INS_element<"ins", "b", neon_uimm4_bare> { } def INSELh : NeonI_INS_element<"ins", "h", neon_uimm3_bare> { let Inst{20-16} = {Immd{2}, Immd{1}, Immd{0}, 0b1, 0b0}; - let Inst{14-12} = {Immn{2}, Immn{1}, Immn{0}}; - // bit 11 is unspecified. + let Inst{14-11} = {Immn{2}, Immn{1}, Immn{0}, 0b0}; + // bit 11 is unspecified, but should be set to zero. } def INSELs : NeonI_INS_element<"ins", "s", neon_uimm2_bare> { let Inst{20-16} = {Immd{1}, Immd{0}, 0b1, 0b0, 0b0}; - let Inst{14-13} = {Immn{1}, Immn{0}}; - // bits 11-12 are unspecified. + let Inst{14-11} = {Immn{1}, Immn{0}, 0b0, 0b0}; + // bits 11-12 are unspecified, but should be set to zero. } def INSELd : NeonI_INS_element<"ins", "d", neon_uimm1_bare> { let Inst{20-16} = {Immd, 0b1, 0b0, 0b0, 0b0}; - let Inst{14} = Immn{0}; - // bits 11-13 are unspecified. + let Inst{14-11} = {Immn{0}, 0b0, 0b0, 0b0}; + // bits 11-13 are unspecified, but should be set to zero. } +def : NeonInstAlias<"mov $Rd.b[$Immd], $Rn.b[$Immn]", + (INSELb VPR128:$Rd, VPR128:$Rn, + neon_uimm4_bare:$Immd, neon_uimm4_bare:$Immn), 0>; +def : NeonInstAlias<"mov $Rd.h[$Immd], $Rn.h[$Immn]", + (INSELh VPR128:$Rd, VPR128:$Rn, + neon_uimm3_bare:$Immd, neon_uimm3_bare:$Immn), 0>; +def : NeonInstAlias<"mov $Rd.s[$Immd], $Rn.s[$Immn]", + (INSELs VPR128:$Rd, VPR128:$Rn, + neon_uimm2_bare:$Immd, neon_uimm2_bare:$Immn), 0>; +def : NeonInstAlias<"mov $Rd.d[$Immd], $Rn.d[$Immn]", + (INSELd VPR128:$Rd, VPR128:$Rn, + neon_uimm1_bare:$Immd, neon_uimm1_bare:$Immn), 0>; + multiclass Neon_INS_elt_pattern { @@ -6448,6 +6470,11 @@ def UMOVxd : NeonI_UMOV<"umov", "d", 0b1, v2i64, neon_uimm1_bare, let Inst{20-16} = {Imm, 0b1, 0b0, 0b0, 0b0}; } +def : NeonInstAlias<"mov $Rd, $Rn.s[$Imm]", + (UMOVws GPR32:$Rd, VPR128:$Rn, neon_uimm2_bare:$Imm), 0>; +def : NeonInstAlias<"mov $Rd, $Rn.d[$Imm]", + (UMOVxd GPR64:$Rd, VPR128:$Rn, neon_uimm1_bare:$Imm), 0>; + class Neon_UMOV_pattern @@ -6650,37 +6677,38 @@ class NeonI_DUP; def DUP16b : NeonI_DUP<0b1, "dup", ".16b", VPR128, v16i8, GPR32, i32> { - let Inst{16} = 0b1; - // bits 17-19 are unspecified. + let Inst{20-16} = 0b00001; + // bits 17-20 are unspecified, but should be set to zero. } def DUP8h : NeonI_DUP<0b1, "dup", ".8h", VPR128, v8i16, GPR32, i32> { - let Inst{17-16} = 0b10; - // bits 18-19 are unspecified. + let Inst{20-16} = 0b00010; + // bits 18-20 are unspecified, but should be set to zero. } def DUP4s : NeonI_DUP<0b1, "dup", ".4s", VPR128, v4i32, GPR32, i32> { - let Inst{18-16} = 0b100; - // bit 19 is unspecified. + let Inst{20-16} = 0b00100; + // bits 19-20 are unspecified, but should be set to zero. } def DUP2d : NeonI_DUP<0b1, "dup", ".2d", VPR128, v2i64, GPR64, i64> { - let Inst{19-16} = 0b1000; + let Inst{20-16} = 0b01000; + // bit 20 is unspecified, but should be set to zero. } def DUP8b : NeonI_DUP<0b0, "dup", ".8b", VPR64, v8i8, GPR32, i32> { - let Inst{16} = 0b1; - // bits 17-19 are unspecified. + let Inst{20-16} = 0b00001; + // bits 17-20 are unspecified, but should be set to zero. } def DUP4h : NeonI_DUP<0b0, "dup", ".4h", VPR64, v4i16, GPR32, i32> { - let Inst{17-16} = 0b10; - // bits 18-19 are unspecified. + let Inst{20-16} = 0b00010; + // bits 18-20 are unspecified, but should be set to zero. } def DUP2s : NeonI_DUP<0b0, "dup", ".2s", VPR64, v2i32, GPR32, i32> { - let Inst{18-16} = 0b100; - // bit 19 is unspecified. + let Inst{20-16} = 0b00100; + // bits 19-20 are unspecified, but should be set to zero. } // patterns for CONCAT_VECTORS diff --git a/test/MC/AArch64/neon-simd-copy.s b/test/MC/AArch64/neon-simd-copy.s index 67fe309f1d5..f254d65b3b0 100644 --- a/test/MC/AArch64/neon-simd-copy.s +++ b/test/MC/AArch64/neon-simd-copy.s @@ -11,11 +11,21 @@ ins v20.s[0], w30 ins v1.d[1], x7 + mov v2.b[2], w1 + mov v7.h[7], w14 + mov v20.s[0], w30 + mov v1.d[1], x7 + // CHECK: ins v2.b[2], w1 // encoding: [0x22,0x1c,0x05,0x4e] // CHECK: ins v7.h[7], w14 // encoding: [0xc7,0x1d,0x1e,0x4e] // CHECK: ins v20.s[0], w30 // encoding: [0xd4,0x1f,0x04,0x4e] // CHECK: ins v1.d[1], x7 // encoding: [0xe1,0x1c,0x18,0x4e] +// CHECK: ins v2.b[2], w1 // encoding: [0x22,0x1c,0x05,0x4e] +// CHECK: ins v7.h[7], w14 // encoding: [0xc7,0x1d,0x1e,0x4e] +// CHECK: ins v20.s[0], w30 // encoding: [0xd4,0x1f,0x04,0x4e] +// CHECK: ins v1.d[1], x7 // encoding: [0xe1,0x1c,0x18,0x4e] + //------------------------------------------------------------------------------ // Signed integer move (main, from element) @@ -30,7 +40,7 @@ // CHECK: smov w14, v6.h[4] // encoding: [0xce,0x2c,0x12,0x0e] // CHECK: smov x1, v0.b[15] // encoding: [0x01,0x2c,0x1f,0x4e] // CHECK: smov x14, v6.h[4] // encoding: [0xce,0x2c,0x12,0x4e] -// CHECK: smov x20, v9.s[2] // encoding: [0x34,0x2d,0x14,0x4e] +// CHECK: smov x20, v9.s[2] // encoding: [0x34,0x2d,0x14,0x4e] //------------------------------------------------------------------------------ @@ -41,25 +51,41 @@ umov w20, v9.s[2] umov x7, v18.d[1] + mov w20, v9.s[2] + mov x7, v18.d[1] + // CHECK: umov w1, v0.b[15] // encoding: [0x01,0x3c,0x1f,0x0e] // CHECK: umov w14, v6.h[4] // encoding: [0xce,0x3c,0x12,0x0e] // CHECK: umov w20, v9.s[2] // encoding: [0x34,0x3d,0x14,0x0e] // CHECK: umov x7, v18.d[1] // encoding: [0x47,0x3e,0x18,0x4e] +// CHECK: umov w20, v9.s[2] // encoding: [0x34,0x3d,0x14,0x0e] +// CHECK: umov x7, v18.d[1] // encoding: [0x47,0x3e,0x18,0x4e] + //------------------------------------------------------------------------------ // Insert element (vector, from element) //------------------------------------------------------------------------------ - Ins v1.b[14], v3.b[6] - Ins v6.h[7], v7.h[5] - Ins v15.s[3], v22.s[2] - Ins v0.d[0], v4.d[1] + ins v1.b[14], v3.b[6] + ins v6.h[7], v7.h[5] + ins v15.s[3], v22.s[2] + ins v0.d[0], v4.d[1] + + mov v1.b[14], v3.b[6] + mov v6.h[7], v7.h[5] + mov v15.s[3], v22.s[2] + mov v0.d[0], v4.d[1] // CHECK: ins v1.b[14], v3.b[6] // encoding: [0x61,0x34,0x1d,0x6e] // CHECK: ins v6.h[7], v7.h[5] // encoding: [0xe6,0x54,0x1e,0x6e] -// CHECK: ins v15.s[3], v22.s[2] // encoding: [0xcf,0x5e,0x1c,0x6e] +// CHECK: ins v15.s[3], v22.s[2] // encoding: [0xcf,0x46,0x1c,0x6e] // CHECK: ins v0.d[0], v4.d[1] // encoding: [0x80,0x44,0x08,0x6e] +// CHECK: ins v1.b[14], v3.b[6] // encoding: [0x61,0x34,0x1d,0x6e] +// CHECK: ins v6.h[7], v7.h[5] // encoding: [0xe6,0x54,0x1e,0x6e] +// CHECK: ins v15.s[3], v22.s[2] // encoding: [0xcf,0x46,0x1c,0x6e] +// CHECK: ins v0.d[0], v4.d[1] // encoding: [0x80,0x44,0x08,0x6e] + //------------------------------------------------------------------------------ // Duplicate to all lanes( vector, from element) //------------------------------------------------------------------------------ @@ -91,11 +117,11 @@ dup v5.2d, x0 // CHECK: dup v1.8b, w1 // encoding: [0x21,0x0c,0x01,0x0e] -// CHECK: dup v11.4h, w14 // encoding: [0xcb,0x0d,0x0a,0x0e] -// CHECK: dup v17.2s, w30 // encoding: [0xd1,0x0f,0x14,0x0e] +// CHECK: dup v11.4h, w14 // encoding: [0xcb,0x0d,0x02,0x0e] +// CHECK: dup v17.2s, w30 // encoding: [0xd1,0x0f,0x04,0x0e] // CHECK: dup v1.16b, w2 // encoding: [0x41,0x0c,0x01,0x4e] -// CHECK: dup v11.8h, w16 // encoding: [0x0b,0x0e,0x0a,0x4e] -// CHECK: dup v17.4s, w28 // encoding: [0x91,0x0f,0x14,0x4e] +// CHECK: dup v11.8h, w16 // encoding: [0x0b,0x0e,0x02,0x4e] +// CHECK: dup v17.4s, w28 // encoding: [0x91,0x0f,0x04,0x4e] // CHECK: dup v5.2d, x0 // encoding: [0x05,0x0c,0x08,0x4e]