[Hexagon] Adding vector shift instructions and tests.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227619 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Colin LeMahieu 2015-01-30 21:58:46 +00:00
parent 24b999d7d0
commit a032778dcf
5 changed files with 188 additions and 15 deletions

View File

@ -3995,6 +3995,10 @@ class T_S2op_shift <string mnemonic, bits<3> MajOp, bits<3> MinOp, SDNode OpNd>
[(set (i32 IntRegs:$dst), (OpNd (i32 IntRegs:$src),
(u5ImmPred:$u5)))]>;
// Vector arithmetic shift right by immediate with truncate and pack
let isCodeGenOnly = 0 in
def S2_asr_i_svw_trun : T_S2op_2_id <"vasrw", 0b110, 0b010>;
// Arithmetic/logical shift right/left by immediate
let Itinerary = S_2op_tc_1_SLOT23, isCodeGenOnly = 0 in {
def S2_asr_i_r : T_S2op_shift <"asr", 0b000, 0b000, sra>;
@ -5759,6 +5763,9 @@ class T_S3op_8 <string opc, bits<3> MinOp, bit isSat, bit isRnd, bit hasShift, b
let Inst{4-0} = Rd;
}
let isCodeGenOnly = 0 in
def S2_asr_r_svw_trun : T_S3op_8<"vasrw", 0b010, 0, 0, 0>;
let Defs = [USR_OVF], Itinerary = S_3op_tc_2_SLOT23, isCodeGenOnly = 0 in
def S2_vcrotate : T_S3op_shiftVect < "vcrotate", 0b11, 0b00>;
@ -5987,3 +5994,9 @@ include "HexagonInstrInfoV5.td"
//===----------------------------------------------------------------------===//
// V5 Instructions -
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// ALU32/64/Vector +
//===----------------------------------------------------------------------===///
include "HexagonInstrInfoVector.td"

View File

@ -779,12 +779,35 @@ class T_ASRHUB<bit isSat>
let Inst{5} = isSat;
let Inst{4-0} = Rd;
}
let isCodeGenOnly = 0 in {
def S5_asrhub_rnd_sat : T_ASRHUB <0>;
def S5_asrhub_sat : T_ASRHUB <1>;
}
def S5_asrhub_rnd_sat_goodsyntax
: SInst <(outs IntRegs:$Rd), (ins DoubleRegs:$Rss, u4Imm:$u4),
"$Rd = vasrhub($Rss, #$u4):rnd:sat">, Requires<[HasV5T]>;
// S5_vasrhrnd: Vector arithmetic shift right by immediate with round.
let hasSideEffects = 0, isCodeGenOnly = 0 in
def S5_vasrhrnd : SInst <(outs DoubleRegs:$Rdd),
(ins DoubleRegs:$Rss, u4Imm:$u4),
"$Rdd = vasrh($Rss, #$u4):raw">,
Requires<[HasV5T]> {
bits<5> Rdd;
bits<5> Rss;
bits<4> u4;
let IClass = 0b1000;
let Inst{27-21} = 0b0000001;
let Inst{20-16} = Rss;
let Inst{13-12} = 0b00;
let Inst{11-8} = u4;
let Inst{7-5} = 0b000;
let Inst{4-0} = Rdd;
}
// Floating point reciprocal square root approximation
let Uses = [USR], isPredicateLate = 1, isFP = 1,
hasSideEffects = 0, hasNewValue = 1, opNewValue = 0,

View File

@ -0,0 +1,67 @@
//===- HexagonInstrInfoVector.td - Hexagon Vector Patterns -*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file describes the Hexagon Vector instructions in TableGen format.
//
//===----------------------------------------------------------------------===//
def V2I1: PatLeaf<(v2i1 PredRegs:$R)>;
def V4I1: PatLeaf<(v4i1 PredRegs:$R)>;
def V8I1: PatLeaf<(v8i1 PredRegs:$R)>;
def V4I8: PatLeaf<(v4i8 IntRegs:$R)>;
def V2I16: PatLeaf<(v2i16 IntRegs:$R)>;
def V8I8: PatLeaf<(v8i8 DoubleRegs:$R)>;
def V4I16: PatLeaf<(v4i16 DoubleRegs:$R)>;
def V2I32: PatLeaf<(v2i32 DoubleRegs:$R)>;
// Vector shift support. Vector shifting in Hexagon is rather different
// from internal representation of LLVM.
// LLVM assumes all shifts (in vector case) will have the form
// <VT> = SHL/SRA/SRL <VT> by <VT>
// while Hexagon has the following format:
// <VT> = SHL/SRA/SRL <VT> by <IT/i32>
// As a result, special care is needed to guarantee correctness and
// performance.
class vshift_v4i16<SDNode Op, string Str, bits<3>MajOp, bits<3>MinOp>
: S_2OpInstImm<Str, MajOp, MinOp, u4Imm,
[(set (v4i16 DoubleRegs:$dst),
(Op (v4i16 DoubleRegs:$src1), u4ImmPred:$src2))]> {
bits<4> src2;
let Inst{11-8} = src2;
}
class vshift_v2i32<SDNode Op, string Str, bits<3>MajOp, bits<3>MinOp>
: S_2OpInstImm<Str, MajOp, MinOp, u5Imm,
[(set (v2i32 DoubleRegs:$dst),
(Op (v2i32 DoubleRegs:$src1), u5ImmPred:$src2))]> {
bits<5> src2;
let Inst{12-8} = src2;
}
let isCodeGenOnly = 0 in {
def S2_asr_i_vw : vshift_v2i32<sra, "vasrw", 0b010, 0b000>;
def S2_lsr_i_vw : vshift_v2i32<srl, "vlsrw", 0b010, 0b001>;
def S2_asl_i_vw : vshift_v2i32<shl, "vaslw", 0b010, 0b010>;
def S2_asr_i_vh : vshift_v4i16<sra, "vasrh", 0b100, 0b000>;
def S2_lsr_i_vh : vshift_v4i16<srl, "vlsrh", 0b100, 0b001>;
def S2_asl_i_vh : vshift_v4i16<shl, "vaslh", 0b100, 0b010>;
// Vector shift words by register
def S2_asr_r_vw : T_S3op_shiftVect < "vasrw", 0b00, 0b00>;
def S2_lsr_r_vw : T_S3op_shiftVect < "vlsrw", 0b00, 0b01>;
def S2_asl_r_vw : T_S3op_shiftVect < "vaslw", 0b00, 0b10>;
def S2_lsl_r_vw : T_S3op_shiftVect < "vlslw", 0b00, 0b11>;
// Vector shift halfwords by register
def S2_asr_r_vh : T_S3op_shiftVect < "vasrh", 0b01, 0b00>;
def S2_lsr_r_vh : T_S3op_shiftVect < "vlsrh", 0b01, 0b01>;
def S2_asl_r_vh : T_S3op_shiftVect < "vaslh", 0b01, 0b10>;
def S2_lsl_r_vh : T_S3op_shiftVect < "vlslh", 0b01, 0b11>;
}

View File

@ -163,7 +163,7 @@ let Namespace = "Hexagon" in {
// FIXME: the register order should be defined in terms of the preferred
// allocation order...
//
def IntRegs : RegisterClass<"Hexagon", [i32,f32], 32,
def IntRegs : RegisterClass<"Hexagon", [i32, f32, v4i8, v2i16], 32,
(add (sequence "R%u", 0, 9),
(sequence "R%u", 12, 28),
R10, R11, R29, R30, R31)> {
@ -174,7 +174,9 @@ def DoubleRegs : RegisterClass<"Hexagon", [i64, f64, v8i8, v4i16, v2i32], 64,
(sequence "D%u", 6, 13), D5, D14, D15)>;
def PredRegs : RegisterClass<"Hexagon", [i1, i32], 32, (add (sequence "P%u", 0, 3))>
def PredRegs : RegisterClass<"Hexagon",
[i1, v2i1, v4i1, v8i1, v4i8, v2i16, i32], 32,
(add (sequence "P%u", 0, 3))>
{
let Size = 32;
}

View File

@ -1,5 +1,7 @@
# RUN: llvm-mc --triple hexagon -disassemble < %s | FileCheck %s
# RUN: llvm-mc -triple=hexagon -disassemble < %s | FileCheck %s
# Hexagon Programmer's Reference Manual 11.10.8 XTYPE/SHIFT
# Shift by immediate
0x10 0xdf 0x14 0x80
# CHECK: r17:16 = asr(r21:20, #31)
0x30 0xdf 0x14 0x80
@ -12,6 +14,8 @@
# CHECK: r17 = lsr(r21, #31)
0x51 0xdf 0x15 0x8c
# CHECK: r17 = asl(r21, #31)
# Shift by immediate and accumulate
0x10 0xdf 0x14 0x82
# CHECK: r17:16 -= asr(r21:20, #31)
0x30 0xdf 0x14 0x82
@ -44,8 +48,12 @@
# CHECK: r17 = add(#21, lsr(r17, #23))
0x5e 0xf7 0x11 0xde
# CHECK: r17 = sub(#21, lsr(r17, #23))
# Shift by immediate and add
0xf1 0xd5 0x1f 0xc4
# CHECK: r17 = addasl(r21, r31, #7)
# Shift by immediate and logical
0x10 0xdf 0x54 0x82
# CHECK: r17:16 &= asr(r21:20, #31)
0x30 0xdf 0x54 0x82
@ -62,18 +70,6 @@
# CHECK: r17:16 ^= lsr(r21:20, #31)
0x50 0xdf 0x94 0x82
# CHECK: r17:16 ^= asl(r21:20, #31)
0x48 0xff 0x11 0xde
# CHECK: r17 = and(#21, asl(r17, #31))
0x4a 0xff 0x11 0xde
# CHECK: r17 = or(#21, asl(r17, #31))
0x58 0xff 0x11 0xde
# CHECK: r17 = and(#21, lsr(r17, #31))
0x5a 0xff 0x11 0xde
# CHECK: r17 = or(#21, lsr(r17, #31))
0xf0 0xdf 0xd4 0x80
# CHECK: r17:16 = asr(r21:20, #31):rnd
0x11 0xdf 0x55 0x8c
# CHECK: r17 = asr(r21, #31):rnd
0x11 0xdf 0x55 0x8e
# CHECK: r17 &= asr(r21, #31)
0x31 0xdf 0x55 0x8e
@ -90,12 +86,26 @@
# CHECK: r17 ^= lsr(r21, #31)
0x51 0xdf 0x95 0x8e
# CHECK: r17 ^= asl(r21, #31)
0x48 0xff 0x11 0xde
# CHECK: r17 = and(#21, asl(r17, #31))
0x4a 0xff 0x11 0xde
# CHECK: r17 = or(#21, asl(r17, #31))
0x58 0xff 0x11 0xde
# CHECK: r17 = and(#21, lsr(r17, #31))
0x5a 0xff 0x11 0xde
# CHECK: r17 = or(#21, lsr(r17, #31))
# Shift right by immediate with rounding
0xf0 0xdf 0xd4 0x80
# CHECK: r17:16 = asr(r21:20, #31):rnd
0x11 0xdf 0x55 0x8c
# CHECK: r17 = asr(r21, #31):rnd
# Shift left by immediate with saturation
0x51 0xdf 0x55 0x8c
# CHECK: r17 = asl(r21, #31):sat
# Shift by register
0x10 0xdf 0x94 0xc3
# CHECK: r17:16 = asr(r21:20, r31)
0x50 0xdf 0x94 0xc3
@ -114,6 +124,8 @@
# CHECK: r17 = lsl(r21, r31)
0xf1 0xdf 0x8a 0xc6
# CHECK: r17 = lsl(#21, r31)
# Shift by register and accumulate
0x10 0xdf 0x94 0xcb
# CHECK: r17:16 -= asr(r21:20, r31)
0x50 0xdf 0x94 0xcb
@ -146,6 +158,8 @@
# CHECK: r17 += asl(r21, r31)
0xd1 0xdf 0xd5 0xcc
# CHECK: r17 += lsl(r21, r31)
# Shift by register and logical
0x10 0xdf 0x14 0xcb
# CHECK: r17:16 |= asr(r21:20, r31)
0x50 0xdf 0x14 0xcb
@ -186,7 +200,61 @@
# CHECK: r17 &= asl(r21, r31)
0xd1 0xdf 0x55 0xcc
# CHECK: r17 &= lsl(r21, r31)
# Shift by register with saturation
0x11 0xdf 0x15 0xc6
# CHECK: r17 = asr(r21, r31):sat
0x91 0xdf 0x15 0xc6
# CHECK: r17 = asl(r21, r31):sat
# Vector shift halfwords by immediate
0x10 0xc5 0x94 0x80
# CHECK: r17:16 = vasrh(r21:20, #5)
0x30 0xc5 0x94 0x80
# CHECK: r17:16 = vlsrh(r21:20, #5)
0x50 0xc5 0x94 0x80
# CHECK: r17:16 = vaslh(r21:20, #5)
# Vector arithmetic shift halfwords with round
0x10 0xc5 0x34 0x80
# CHECK: r17:16 = vasrh(r21:20, #5):raw
# Vector arithmetic shift halfwords with saturate and pack
0x91 0xc5 0x74 0x88
# CHECK: r17 = vasrhub(r21:20, #5):raw
0xb1 0xc5 0x74 0x88
# CHECK: r17 = vasrhub(r21:20, #5):sat
# Vector shift halfwords by register
0x10 0xdf 0x54 0xc3
# CHECK: r17:16 = vasrh(r21:20, r31)
0x50 0xdf 0x54 0xc3
# CHECK: r17:16 = vlsrh(r21:20, r31)
0x90 0xdf 0x54 0xc3
# CHECK: r17:16 = vaslh(r21:20, r31)
0xd0 0xdf 0x54 0xc3
# CHECK: r17:16 = vlslh(r21:20, r31)
# Vector shift words by immediate
0x10 0xdf 0x54 0x80
# CHECK: r17:16 = vasrw(r21:20, #31)
0x30 0xdf 0x54 0x80
# CHECK: r17:16 = vlsrw(r21:20, #31)
0x50 0xdf 0x54 0x80
# CHECK: r17:16 = vaslw(r21:20, #31)
# Vector shift words by register
0x10 0xdf 0x14 0xc3
# CHECK: r17:16 = vasrw(r21:20, r31)
0x50 0xdf 0x14 0xc3
# CHECK: r17:16 = vlsrw(r21:20, r31)
0x90 0xdf 0x14 0xc3
# CHECK: r17:16 = vaslw(r21:20, r31)
0xd0 0xdf 0x14 0xc3
# CHECK: r17:16 = vlslw(r21:20, r31)
# Vector shift words with truncate and pack
0x51 0xdf 0xd4 0x88
# CHECK: r17 = vasrw(r21:20, #31)
0x51 0xdf 0x14 0xc5
# CHECK: r17 = vasrw(r21:20, r31)