From a032778dcf9072df6aca23909241ddd28997aa69 Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Fri, 30 Jan 2015 21:58:46 +0000 Subject: [PATCH] [Hexagon] Adding vector shift instructions and tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227619 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Hexagon/HexagonInstrInfo.td | 13 +++ lib/Target/Hexagon/HexagonInstrInfoV5.td | 23 +++++ lib/Target/Hexagon/HexagonInstrInfoVector.td | 67 ++++++++++++++ lib/Target/Hexagon/HexagonRegisterInfo.td | 6 +- test/MC/Disassembler/Hexagon/xtype_shift.txt | 94 +++++++++++++++++--- 5 files changed, 188 insertions(+), 15 deletions(-) create mode 100644 lib/Target/Hexagon/HexagonInstrInfoVector.td diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td index e1e7c02d624..b415bf88627 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/lib/Target/Hexagon/HexagonInstrInfo.td @@ -3995,6 +3995,10 @@ class T_S2op_shift 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 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" \ No newline at end of file diff --git a/lib/Target/Hexagon/HexagonInstrInfoV5.td b/lib/Target/Hexagon/HexagonInstrInfoV5.td index 8fde71042f2..9b8d9d6c2a8 100644 --- a/lib/Target/Hexagon/HexagonInstrInfoV5.td +++ b/lib/Target/Hexagon/HexagonInstrInfoV5.td @@ -779,12 +779,35 @@ class T_ASRHUB 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, diff --git a/lib/Target/Hexagon/HexagonInstrInfoVector.td b/lib/Target/Hexagon/HexagonInstrInfoVector.td new file mode 100644 index 00000000000..26de697ba23 --- /dev/null +++ b/lib/Target/Hexagon/HexagonInstrInfoVector.td @@ -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 +// = SHL/SRA/SRL by +// while Hexagon has the following format: +// = SHL/SRA/SRL by +// As a result, special care is needed to guarantee correctness and +// performance. +class vshift_v4i16MajOp, bits<3>MinOp> + : S_2OpInstImm { + bits<4> src2; + let Inst{11-8} = src2; +} + +class vshift_v2i32MajOp, bits<3>MinOp> + : S_2OpInstImm { + bits<5> src2; + let Inst{12-8} = src2; +} + +let isCodeGenOnly = 0 in { +def S2_asr_i_vw : vshift_v2i32; +def S2_lsr_i_vw : vshift_v2i32; +def S2_asl_i_vw : vshift_v2i32; + +def S2_asr_i_vh : vshift_v4i16; +def S2_lsr_i_vh : vshift_v4i16; +def S2_asl_i_vh : vshift_v4i16; + +// 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>; +} diff --git a/lib/Target/Hexagon/HexagonRegisterInfo.td b/lib/Target/Hexagon/HexagonRegisterInfo.td index fc4e7158455..edf1c251ac7 100644 --- a/lib/Target/Hexagon/HexagonRegisterInfo.td +++ b/lib/Target/Hexagon/HexagonRegisterInfo.td @@ -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; } diff --git a/test/MC/Disassembler/Hexagon/xtype_shift.txt b/test/MC/Disassembler/Hexagon/xtype_shift.txt index a0577383d80..e2d6816c1ca 100644 --- a/test/MC/Disassembler/Hexagon/xtype_shift.txt +++ b/test/MC/Disassembler/Hexagon/xtype_shift.txt @@ -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) -- 2.34.1