From ea46110f57b293844a314aec3b8092adf21ff63f Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Mon, 17 Oct 2011 23:09:09 +0000 Subject: [PATCH] ARM assembly parsing and encoding for VMOV/VMVN/VORR/VBIC.i16. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142303 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrNEON.td | 21 ++++++++++++-------- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 23 ++++++++++++++++++++++ test/MC/ARM/neont2-mov-encoding.s | 24 +++++++++++------------ utils/TableGen/EDEmitter.cpp | 1 + 4 files changed, 49 insertions(+), 20 deletions(-) diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index d5f5772cf04..7ceedd68c2a 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -24,6 +24,11 @@ def nImmSplatI8 : Operand { let PrintMethod = "printNEONModImmOperand"; let ParserMatchClass = nImmSplatI8AsmOperand; } +def nImmSplatI16AsmOperand : AsmOperandClass { let Name = "NEONi16splat"; } +def nImmSplatI16 : Operand { + let PrintMethod = "printNEONModImmOperand"; + let ParserMatchClass = nImmSplatI16AsmOperand; +} def VectorIndex8Operand : AsmOperandClass { let Name = "VectorIndex8"; } def VectorIndex16Operand : AsmOperandClass { let Name = "VectorIndex16"; } @@ -3743,7 +3748,7 @@ def VORRq : N3VQX<0, 0, 0b10, 0b0001, 1, IIC_VBINiQ, "vorr", v4i32, v4i32, or, 1>; def VORRiv4i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 0, 0, 1, - (outs DPR:$Vd), (ins nModImm:$SIMM, DPR:$src), + (outs DPR:$Vd), (ins nImmSplatI16:$SIMM, DPR:$src), IIC_VMOVImm, "vorr", "i16", "$Vd, $SIMM", "$src = $Vd", [(set DPR:$Vd, @@ -3761,7 +3766,7 @@ def VORRiv2i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 0, 0, 1, } def VORRiv8i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 1, 0, 1, - (outs QPR:$Vd), (ins nModImm:$SIMM, QPR:$src), + (outs QPR:$Vd), (ins nImmSplatI16:$SIMM, QPR:$src), IIC_VMOVImm, "vorr", "i16", "$Vd, $SIMM", "$src = $Vd", [(set QPR:$Vd, @@ -3792,7 +3797,7 @@ def VBICq : N3VX<0, 0, 0b01, 0b0001, 1, 1, (outs QPR:$Vd), (vnotq QPR:$Vm))))]>; def VBICiv4i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 0, 1, 1, - (outs DPR:$Vd), (ins nModImm:$SIMM, DPR:$src), + (outs DPR:$Vd), (ins nImmSplatI16:$SIMM, DPR:$src), IIC_VMOVImm, "vbic", "i16", "$Vd, $SIMM", "$src = $Vd", [(set DPR:$Vd, @@ -3810,7 +3815,7 @@ def VBICiv2i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 0, 1, 1, } def VBICiv8i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 1, 1, 1, - (outs QPR:$Vd), (ins nModImm:$SIMM, QPR:$src), + (outs QPR:$Vd), (ins nImmSplatI16:$SIMM, QPR:$src), IIC_VMOVImm, "vbic", "i16", "$Vd, $SIMM", "$src = $Vd", [(set QPR:$Vd, @@ -3844,14 +3849,14 @@ def VORNq : N3VX<0, 0, 0b11, 0b0001, 1, 1, (outs QPR:$Vd), let isReMaterializable = 1 in { def VMVNv4i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 0, 1, 1, (outs DPR:$Vd), - (ins nModImm:$SIMM), IIC_VMOVImm, + (ins nImmSplatI16:$SIMM), IIC_VMOVImm, "vmvn", "i16", "$Vd, $SIMM", "", [(set DPR:$Vd, (v4i16 (NEONvmvnImm timm:$SIMM)))]> { let Inst{9} = SIMM{9}; } def VMVNv8i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 1, 1, 1, (outs QPR:$Vd), - (ins nModImm:$SIMM), IIC_VMOVImm, + (ins nImmSplatI16:$SIMM), IIC_VMOVImm, "vmvn", "i16", "$Vd, $SIMM", "", [(set QPR:$Vd, (v8i16 (NEONvmvnImm timm:$SIMM)))]> { let Inst{9} = SIMM{9}; @@ -4329,14 +4334,14 @@ def VMOVv16i8 : N1ModImm<1, 0b000, 0b1110, 0, 1, 0, 1, (outs QPR:$Vd), [(set QPR:$Vd, (v16i8 (NEONvmovImm timm:$SIMM)))]>; def VMOVv4i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 0, 0, 1, (outs DPR:$Vd), - (ins nModImm:$SIMM), IIC_VMOVImm, + (ins nImmSplatI16:$SIMM), IIC_VMOVImm, "vmov", "i16", "$Vd, $SIMM", "", [(set DPR:$Vd, (v4i16 (NEONvmovImm timm:$SIMM)))]> { let Inst{9} = SIMM{9}; } def VMOVv8i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 1, 0, 1, (outs QPR:$Vd), - (ins nModImm:$SIMM), IIC_VMOVImm, + (ins nImmSplatI16:$SIMM), IIC_VMOVImm, "vmov", "i16", "$Vd, $SIMM", "", [(set QPR:$Vd, (v8i16 (NEONvmovImm timm:$SIMM)))]> { let Inst{9} = SIMM{9}; diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index c887179fc33..11b6574c286 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -924,6 +924,17 @@ public: return Value >= 0 && Value < 256; } + bool isNEONi16splat() const { + if (Kind != k_Immediate) + return false; + const MCConstantExpr *CE = dyn_cast(getImm()); + // Must be a constant. + if (!CE) return false; + int64_t Value = CE->getValue(); + // i16 value in the range [0,255] or [0x0100, 0xff00] + return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00); + } + void addExpr(MCInst &Inst, const MCExpr *Expr) const { // Add as immediates when possible. Null MCExpr = 0. if (Expr == 0) @@ -1454,6 +1465,18 @@ public: Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00)); } + void addNEONi16splatOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + // The immediate encodes the type of constant as well as the value. + const MCConstantExpr *CE = dyn_cast(getImm()); + unsigned Value = CE->getValue(); + if (Value >= 256) + Value = (Value >> 8) | 0xa00; + else + Value |= 0x800; + Inst.addOperand(MCOperand::CreateImm(Value)); + } + virtual void print(raw_ostream &OS) const; static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) { diff --git a/test/MC/ARM/neont2-mov-encoding.s b/test/MC/ARM/neont2-mov-encoding.s index 89fe82cf711..9b5e8016d8d 100644 --- a/test/MC/ARM/neont2-mov-encoding.s +++ b/test/MC/ARM/neont2-mov-encoding.s @@ -3,8 +3,8 @@ .code 16 vmov.i8 d16, #0x8 -@ vmov.i16 d16, #0x10 -@ vmov.i16 d16, #0x1000 + vmov.i16 d16, #0x10 + vmov.i16 d16, #0x1000 @ vmov.i32 d16, #0x20 @ vmov.i32 d16, #0x2000 @ vmov.i32 d16, #0x200000 @@ -14,8 +14,8 @@ @ vmov.i64 d16, #0xFF0000FF0000FFFF @ CHECK: vmov.i8 d16, #0x8 @ encoding: [0xc0,0xef,0x18,0x0e] -@ FIXME: vmov.i16 d16, #0x10 @ encoding: [0xc1,0xef,0x10,0x08] -@ FIXME: vmov.i16 d16, #0x1000 @ encoding: [0xc1,0xef,0x10,0x0a] +@ CHECK: vmov.i16 d16, #0x10 @ encoding: [0xc1,0xef,0x10,0x08] +@ CHECK: vmov.i16 d16, #0x1000 @ encoding: [0xc1,0xef,0x10,0x0a] @ FIXME: vmov.i32 d16, #0x20 @ encoding: [0xc2,0xef,0x10,0x00] @ FIXME: vmov.i32 d16, #0x2000 @ encoding: [0xc2,0xef,0x10,0x02] @ FIXME: vmov.i32 d16, #0x200000 @ encoding: [0xc2,0xef,0x10,0x04] @@ -26,8 +26,8 @@ vmov.i8 q8, #0x8 -@ vmov.i16 q8, #0x10 -@ vmov.i16 q8, #0x1000 + vmov.i16 q8, #0x10 + vmov.i16 q8, #0x1000 @ vmov.i32 q8, #0x20 @ vmov.i32 q8, #0x2000 @ vmov.i32 q8, #0x200000 @@ -37,8 +37,8 @@ @ vmov.i64 q8, #0xFF0000FF0000FFFF @ CHECK: vmov.i8 q8, #0x8 @ encoding: [0xc0,0xef,0x58,0x0e] -@ FIXME: vmov.i16 q8, #0x10 @ encoding: [0xc1,0xef,0x50,0x08] -@ FIXME: vmov.i16 q8, #0x1000 @ encoding: [0xc1,0xef,0x50,0x0a] +@ CHECK: vmov.i16 q8, #0x10 @ encoding: [0xc1,0xef,0x50,0x08] +@ CHECK: vmov.i16 q8, #0x1000 @ encoding: [0xc1,0xef,0x50,0x0a] @ FIXME: vmov.i32 q8, #0x20 @ encoding: [0xc2,0xef,0x50,0x00] @ FIXME: vmov.i32 q8, #0x2000 @ encoding: [0xc2,0xef,0x50,0x02] @ FIXME: vmov.i32 q8, #0x200000 @ encoding: [0xc2,0xef,0x50,0x04] @@ -48,8 +48,8 @@ @ FIXME: vmov.i64 q8, #0xFF0000FF0000FFFF @ encoding: [0xc1,0xff,0x73,0x0e] -@ vmvn.i16 d16, #0x10 -@ vmvn.i16 d16, #0x1000 + vmvn.i16 d16, #0x10 + vmvn.i16 d16, #0x1000 @ vmvn.i32 d16, #0x20 @ vmvn.i32 d16, #0x2000 @ vmvn.i32 d16, #0x200000 @@ -57,8 +57,8 @@ @ vmvn.i32 d16, #0x20FF @ vmvn.i32 d16, #0x20FFFF -@ FIXME: vmvn.i16 d16, #0x10 @ encoding: [0xc1,0xef,0x30,0x08] -@ FIXME: vmvn.i16 d16, #0x1000 @ encoding: [0xc1,0xef,0x30,0x0a] +@ CHECK: vmvn.i16 d16, #0x10 @ encoding: [0xc1,0xef,0x30,0x08] +@ CHECK: vmvn.i16 d16, #0x1000 @ encoding: [0xc1,0xef,0x30,0x0a] @ FIXME: vmvn.i32 d16, #0x20 @ encoding: [0xc2,0xef,0x30,0x00] @ FIXME: vmvn.i32 d16, #0x2000 @ encoding: [0xc2,0xef,0x30,0x02] @ FIXME: vmvn.i32 d16, #0x200000 @ encoding: [0xc2,0xef,0x30,0x04] diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index 9e9384f6c62..90346b77be1 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -598,6 +598,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, IMM("imm1_32"); IMM("nModImm"); IMM("nImmSplatI8"); + IMM("nImmSplatI16"); IMM("imm0_7"); IMM("imm0_15"); IMM("imm0_255");