From 587f5062b9e4532c4f464942e593cb87c58ac153 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Fri, 2 Dec 2011 23:34:39 +0000 Subject: [PATCH] ARM NEON VEXT aliases for data type suffices. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145726 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrInfo.td | 8 +++++ lib/Target/ARM/ARMInstrNEON.td | 43 +++++++++++++++++------ lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 16 +++++++++ utils/TableGen/EDEmitter.cpp | 2 ++ 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index f0077e5b10c..0b135981284 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -512,6 +512,14 @@ def arm_i32imm : PatLeaf<(imm), [{ return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue()); }]>; +/// imm0_1 predicate - Immediate in the range [0,1]. +def Imm0_1AsmOperand: ImmAsmOperand { let Name = "Imm0_1"; } +def imm0_1 : Operand { let ParserMatchClass = Imm0_1AsmOperand; } + +/// imm0_3 predicate - Immediate in the range [0,3]. +def Imm0_3AsmOperand: ImmAsmOperand { let Name = "Imm0_3"; } +def imm0_3 : Operand { let ParserMatchClass = Imm0_3AsmOperand; } + /// imm0_7 predicate - Immediate in the range [0,7]. def Imm0_7AsmOperand: ImmAsmOperand { let Name = "Imm0_7"; } def imm0_7 : Operand, ImmLeaf; // VEXT : Vector Extract -class VEXTd +class VEXTd : N3V<0,1,0b11,{?,?,?,?},0,0, (outs DPR:$Vd), - (ins DPR:$Vn, DPR:$Vm, imm0_7:$index), NVExtFrm, + (ins DPR:$Vn, DPR:$Vm, immTy:$index), NVExtFrm, IIC_VEXTD, OpcodeStr, Dt, "$Vd, $Vn, $Vm, $index", "", [(set DPR:$Vd, (Ty (NEONvext (Ty DPR:$Vn), - (Ty DPR:$Vm), imm:$index)))]> { + (Ty DPR:$Vm), imm:$index)))]> { bits<4> index; let Inst{11-8} = index{3-0}; } -class VEXTq +class VEXTq : N3V<0,1,0b11,{?,?,?,?},1,0, (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm, imm0_15:$index), NVExtFrm, IIC_VEXTQ, OpcodeStr, Dt, "$Vd, $Vn, $Vm, $index", "", [(set QPR:$Vd, (Ty (NEONvext (Ty QPR:$Vn), - (Ty QPR:$Vm), imm:$index)))]> { + (Ty QPR:$Vm), imm:$index)))]> { bits<4> index; let Inst{11-8} = index{3-0}; } -def VEXTd8 : VEXTd<"vext", "8", v8i8> { +def VEXTd8 : VEXTd<"vext", "8", v8i8, imm0_7> { let Inst{11-8} = index{3-0}; } -def VEXTd16 : VEXTd<"vext", "16", v4i16> { +def VEXTd16 : VEXTd<"vext", "16", v4i16, imm0_3> { let Inst{11-9} = index{2-0}; let Inst{8} = 0b0; } -def VEXTd32 : VEXTd<"vext", "32", v2i32> { +def VEXTd32 : VEXTd<"vext", "32", v2i32, imm0_1> { let Inst{11-10} = index{1-0}; let Inst{9-8} = 0b00; } @@ -5061,17 +5061,21 @@ def : Pat<(v2f32 (NEONvext (v2f32 DPR:$Vn), (i32 imm:$index))), (VEXTd32 DPR:$Vn, DPR:$Vm, imm:$index)>; -def VEXTq8 : VEXTq<"vext", "8", v16i8> { +def VEXTq8 : VEXTq<"vext", "8", v16i8, imm0_15> { let Inst{11-8} = index{3-0}; } -def VEXTq16 : VEXTq<"vext", "16", v8i16> { +def VEXTq16 : VEXTq<"vext", "16", v8i16, imm0_7> { let Inst{11-9} = index{2-0}; let Inst{8} = 0b0; } -def VEXTq32 : VEXTq<"vext", "32", v4i32> { +def VEXTq32 : VEXTq<"vext", "32", v4i32, imm0_3> { let Inst{11-10} = index{1-0}; let Inst{9-8} = 0b00; } +def VEXTq64 : VEXTq<"vext", "32", v2i64, imm0_1> { + let Inst{11} = index{0}; + let Inst{10-8} = 0b000; +} def : Pat<(v4f32 (NEONvext (v4f32 QPR:$Vn), (v4f32 QPR:$Vm), (i32 imm:$index))), @@ -5593,6 +5597,23 @@ defm : VFPDT16ReqInstAlias<"vtrn${p}", "$Qd, $Qm", defm : VFPDT32ReqInstAlias<"vtrn${p}", "$Qd, $Qm", (VTRNq32 QPR:$Qd, QPR:$Qm, pred:$p)>; +// VEXT instructions data type suffix aliases for more-specific types. +defm VEXTd : VFPDT8ReqInstAlias <"vext${p}", "$Vd, $Vn, $Vm, $index", + (VEXTd8 DPR:$Vd, DPR:$Vn, DPR:$Vm, imm0_7:$index, pred:$p)>; +defm VEXTd : VFPDT16ReqInstAlias<"vext${p}", "$Vd, $Vn, $Vm, $index", + (VEXTd16 DPR:$Vd, DPR:$Vn, DPR:$Vm, imm0_3:$index, pred:$p)>; +defm VEXTd : VFPDT32ReqInstAlias<"vext${p}", "$Vd, $Vn, $Vm, $index", + (VEXTd32 DPR:$Vd, DPR:$Vn, DPR:$Vm, imm0_1:$index, pred:$p)>; + +defm VEXTq : VFPDT8ReqInstAlias <"vext${p}", "$Vd, $Vn, $Vm, $index", + (VEXTq8 QPR:$Vd, QPR:$Vn, QPR:$Vm, imm0_15:$index, pred:$p)>; +defm VEXTq : VFPDT16ReqInstAlias<"vext${p}", "$Vd, $Vn, $Vm, $index", + (VEXTq16 QPR:$Vd, QPR:$Vn, QPR:$Vm, imm0_7:$index, pred:$p)>; +defm VEXTq : VFPDT32ReqInstAlias<"vext${p}", "$Vd, $Vn, $Vm, $index", + (VEXTq32 QPR:$Vd, QPR:$Vn, QPR:$Vm, imm0_3:$index, pred:$p)>; +defm VEXTq : VFPDT64ReqInstAlias<"vext${p}", "$Vd, $Vn, $Vm, $index", + (VEXTq64 QPR:$Vd, QPR:$Vn, QPR:$Vm, imm0_1:$index, pred:$p)>; + // VLD1 single-lane pseudo-instructions. These need special handling for // the lane index that an InstAlias can't handle, so we use these instead. defm VLD1LNdAsm : NEONDT8AsmPseudoInst<"vld1${p}", "$list, $addr", diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 8219069bcef..5b1fe36d4a0 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -570,6 +570,22 @@ public: int64_t Value = CE->getValue(); return Value >= 0 && Value < 256; } + bool isImm0_1() const { + if (Kind != k_Immediate) + return false; + const MCConstantExpr *CE = dyn_cast(getImm()); + if (!CE) return false; + int64_t Value = CE->getValue(); + return Value >= 0 && Value < 2; + } + bool isImm0_3() const { + if (Kind != k_Immediate) + return false; + const MCConstantExpr *CE = dyn_cast(getImm()); + if (!CE) return false; + int64_t Value = CE->getValue(); + return Value >= 0 && Value < 4; + } bool isImm0_7() const { if (Kind != k_Immediate) return false; diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index 22de37788c2..7402a83d70f 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -610,6 +610,8 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, IMM("nImmSplatI64"); IMM("nImmVMOVI32"); IMM("nImmVMOVF32"); + IMM("imm0_1"); + IMM("imm0_3"); IMM("imm0_7"); IMM("imm0_15"); IMM("imm0_255");