From dad2f8e7fb2df5fb080a38fa4c33a01f19729f15 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Fri, 2 Dec 2011 18:52:30 +0000 Subject: [PATCH] Clean up aliases for ARM VLD1 single-lane assembly parsing a bit. Add the 16-bit lane variants while I'm at it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145693 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrFormats.td | 107 +++++++++++++++++++--- lib/Target/ARM/ARMInstrNEON.td | 16 ++-- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 36 +++++++- test/MC/ARM/neon-vld-encoding.s | 4 +- 4 files changed, 135 insertions(+), 28 deletions(-) diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index 6940156c7b8..84b4319b76b 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -1999,23 +1999,23 @@ multiclass VFPDT8ReqInstAlias { def I8 : VFPDataTypeInstAlias; def S8 : VFPDataTypeInstAlias; def U8 : VFPDataTypeInstAlias; - def F8 : VFPDataTypeInstAlias; + def P8 : VFPDataTypeInstAlias; } // VFPDT8ReqInstAlias plus plain ".8" multiclass VFPDT8InstAlias { def _8 : VFPDataTypeInstAlias; - defm : VFPDT8ReqInstAlias; + defm _ : VFPDT8ReqInstAlias; } multiclass VFPDT16ReqInstAlias { def I16 : VFPDataTypeInstAlias; def S16 : VFPDataTypeInstAlias; def U16 : VFPDataTypeInstAlias; - def F16 : VFPDataTypeInstAlias; + def P16 : VFPDataTypeInstAlias; } // VFPDT16ReqInstAlias plus plain ".16" multiclass VFPDT16InstAlias { def _16 : VFPDataTypeInstAlias; - defm : VFPDT16ReqInstAlias; + defm _ : VFPDT16ReqInstAlias; } multiclass VFPDT32ReqInstAlias { def I32 : VFPDataTypeInstAlias; @@ -2027,7 +2027,7 @@ multiclass VFPDT32ReqInstAlias { // VFPDT32ReqInstAlias plus plain ".32" multiclass VFPDT32InstAlias { def _32 : VFPDataTypeInstAlias; - defm : VFPDT32ReqInstAlias; + defm _ : VFPDT32ReqInstAlias; } multiclass VFPDT64ReqInstAlias { def I64 : VFPDataTypeInstAlias; @@ -2039,7 +2039,7 @@ multiclass VFPDT64ReqInstAlias { // VFPDT64ReqInstAlias plus plain ".64" multiclass VFPDT64InstAlias { def _64 : VFPDataTypeInstAlias; - defm : VFPDT64ReqInstAlias; + defm _ : VFPDT64ReqInstAlias; } multiclass VFPDT64NoF64ReqInstAlias { def I64 : VFPDataTypeInstAlias; @@ -2050,17 +2050,94 @@ multiclass VFPDT64NoF64ReqInstAlias { // VFPDT64ReqInstAlias plus plain ".64" multiclass VFPDT64NoF64InstAlias { def _64 : VFPDataTypeInstAlias; - defm : VFPDT64ReqInstAlias; + defm _ : VFPDT64ReqInstAlias; } multiclass VFPDTAnyInstAlias { - defm : VFPDT8InstAlias; - defm : VFPDT16InstAlias; - defm : VFPDT32InstAlias; - defm : VFPDT64InstAlias; + defm _ : VFPDT8InstAlias; + defm _ : VFPDT16InstAlias; + defm _ : VFPDT32InstAlias; + defm _ : VFPDT64InstAlias; } multiclass VFPDTAnyNoF64InstAlias { - defm : VFPDT8InstAlias; - defm : VFPDT16InstAlias; - defm : VFPDT32InstAlias; - defm : VFPDT64NoF64InstAlias; + defm _ : VFPDT8InstAlias; + defm _ : VFPDT16InstAlias; + defm _ : VFPDT32InstAlias; + defm _ : VFPDT64NoF64InstAlias; +} + +// The same alias classes using AsmPseudo instead, for the more complex +// stuff in NEON that InstAlias can't quite handle. +// Note that we can't use anonymous defm references here like we can +// above, as we care about the ultimate instruction enum names generated, unlike +// for instalias defs. +class NEONDataTypeAsmPseudoInst : + AsmPseudoInst, Requires<[HasNEON]>; +multiclass NEONDT8ReqAsmPseudoInst { + def I8 : NEONDataTypeAsmPseudoInst; + def S8 : NEONDataTypeAsmPseudoInst; + def U8 : NEONDataTypeAsmPseudoInst; + def P8 : NEONDataTypeAsmPseudoInst; +} +// NEONDT8ReqAsmPseudoInst plus plain ".8" +multiclass NEONDT8AsmPseudoInst { + def _8 : NEONDataTypeAsmPseudoInst; + defm _ : NEONDT8ReqAsmPseudoInst; +} +multiclass NEONDT16ReqAsmPseudoInst { + def I16 : NEONDataTypeAsmPseudoInst; + def S16 : NEONDataTypeAsmPseudoInst; + def U16 : NEONDataTypeAsmPseudoInst; + def P16 : NEONDataTypeAsmPseudoInst; +} +// NEONDT16ReqAsmPseudoInst plus plain ".16" +multiclass NEONDT16AsmPseudoInst { + def _16 : NEONDataTypeAsmPseudoInst; + defm _ : NEONDT16ReqAsmPseudoInst; +} +multiclass NEONDT32ReqAsmPseudoInst { + def I32 : NEONDataTypeAsmPseudoInst; + def S32 : NEONDataTypeAsmPseudoInst; + def U32 : NEONDataTypeAsmPseudoInst; + def F32 : NEONDataTypeAsmPseudoInst; + def F : NEONDataTypeAsmPseudoInst; +} +// NEONDT32ReqAsmPseudoInst plus plain ".32" +multiclass NEONDT32AsmPseudoInst { + def _32 : NEONDataTypeAsmPseudoInst; + defm _ : NEONDT32ReqAsmPseudoInst; +} +multiclass NEONDT64ReqAsmPseudoInst { + def I64 : NEONDataTypeAsmPseudoInst; + def S64 : NEONDataTypeAsmPseudoInst; + def U64 : NEONDataTypeAsmPseudoInst; + def F64 : NEONDataTypeAsmPseudoInst; + def D : NEONDataTypeAsmPseudoInst; +} +// NEONDT64ReqAsmPseudoInst plus plain ".64" +multiclass NEONDT64AsmPseudoInst { + def _64 : NEONDataTypeAsmPseudoInst; + defm _ : NEONDT64ReqAsmPseudoInst; +} +multiclass NEONDT64NoF64ReqAsmPseudoInst { + def I64 : NEONDataTypeAsmPseudoInst; + def S64 : NEONDataTypeAsmPseudoInst; + def U64 : NEONDataTypeAsmPseudoInst; + def D : NEONDataTypeAsmPseudoInst; +} +// NEONDT64ReqAsmPseudoInst plus plain ".64" +multiclass NEONDT64NoF64AsmPseudoInst { + def _64 : NEONDataTypeAsmPseudoInst; + defm _ : NEONDT64ReqAsmPseudoInst; +} +multiclass NEONDTAnyAsmPseudoInst { + defm _ : NEONDT8AsmPseudoInst; + defm _ : NEONDT16AsmPseudoInst; + defm _ : NEONDT32AsmPseudoInst; + defm _ : NEONDT64AsmPseudoInst; +} +multiclass NEONDTAnyNoF64AsmPseudoInst { + defm _ : NEONDT8AsmPseudoInst; + defm _ : NEONDT16AsmPseudoInst; + defm _ : NEONDT32AsmPseudoInst; + defm _ : NEONDT64NoF64AsmPseudoInst; } diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index 12efea242ba..a395db8868d 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -765,13 +765,6 @@ def VLD1LNd32 : VLD1LN32<0b1000, {?,0,?,?}, "32", v2i32, load> { let Inst{4} = Rn{4}; } -// FIXME: Proof of concept pseudos. We want to parameterize these for all -// the suffices we have to support. -def VLD1LNd8asm : NEONAsmPseudo<"vld1${p}.8 $list, $addr", - (ins VecListOneDByteIndexed:$list, addrmode6:$addr, pred:$p)>; -def VLD1LNdf32asm : NEONAsmPseudo<"vld1${p}.f32 $list, $addr", - (ins VecListOneDByteIndexed:$list, addrmode6:$addr, pred:$p)>; - def VLD1LNq8Pseudo : VLD1QLNPseudo; def VLD1LNq16Pseudo : VLD1QLNPseudo; def VLD1LNq32Pseudo : VLD1QLNPseudo; @@ -5599,3 +5592,12 @@ defm : VFPDT16ReqInstAlias<"vtrn${p}", "$Qd, $Qm", (VTRNq16 QPR:$Qd, QPR:$Qm, pred:$p)>; defm : VFPDT32ReqInstAlias<"vtrn${p}", "$Qd, $Qm", (VTRNq32 QPR:$Qd, QPR:$Qm, pred:$p)>; + +// FIXME: Proof of concept pseudos. We want to parameterize these for all +// the suffices we have to support. +defm VLD1LNdAsm : NEONDT8AsmPseudoInst<"vld1${p}", "$list, $addr", + (ins VecListOneDByteIndexed:$list, addrmode6:$addr, pred:$p)>; +defm VLD1LNdAsm : NEONDT16AsmPseudoInst<"vld1${p}", "$list, $addr", + (ins VecListOneDByteIndexed:$list, addrmode6:$addr, pred:$p)>; +defm VLD1LNdAsm : NEONDT32AsmPseudoInst<"vld1${p}", "$list, $addr", + (ins VecListOneDByteIndexed:$list, addrmode6:$addr, pred:$p)>; diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 59dec0edfa6..33b7eef67c6 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -4754,8 +4754,22 @@ validateInstruction(MCInst &Inst, static unsigned getRealVLDNOpcode(unsigned Opc) { switch(Opc) { default: assert(0 && "unexpected opcode!"); - case ARM::VLD1LNd8asm: return ARM::VLD1LNd8; - case ARM::VLD1LNdf32asm: return ARM::VLD1LNd32; + case ARM::VLD1LNdAsm_8: return ARM::VLD1LNd8; + case ARM::VLD1LNdAsm_P8: return ARM::VLD1LNd8; + case ARM::VLD1LNdAsm_I8: return ARM::VLD1LNd8; + case ARM::VLD1LNdAsm_S8: return ARM::VLD1LNd8; + case ARM::VLD1LNdAsm_U8: return ARM::VLD1LNd8; + case ARM::VLD1LNdAsm_16: return ARM::VLD1LNd16; + case ARM::VLD1LNdAsm_P16: return ARM::VLD1LNd16; + case ARM::VLD1LNdAsm_I16: return ARM::VLD1LNd16; + case ARM::VLD1LNdAsm_S16: return ARM::VLD1LNd16; + case ARM::VLD1LNdAsm_U16: return ARM::VLD1LNd16; + case ARM::VLD1LNdAsm_32: return ARM::VLD1LNd32; + case ARM::VLD1LNdAsm_F: return ARM::VLD1LNd32; + case ARM::VLD1LNdAsm_F32: return ARM::VLD1LNd32; + case ARM::VLD1LNdAsm_I32: return ARM::VLD1LNd32; + case ARM::VLD1LNdAsm_S32: return ARM::VLD1LNd32; + case ARM::VLD1LNdAsm_U32: return ARM::VLD1LNd32; } } @@ -4764,8 +4778,22 @@ processInstruction(MCInst &Inst, const SmallVectorImpl &Operands) { switch (Inst.getOpcode()) { // Handle NEON VLD1 complex aliases. - case ARM::VLD1LNd8asm: - case ARM::VLD1LNdf32asm: { + case ARM::VLD1LNdAsm_8: + case ARM::VLD1LNdAsm_P8: + case ARM::VLD1LNdAsm_I8: + case ARM::VLD1LNdAsm_S8: + case ARM::VLD1LNdAsm_U8: + case ARM::VLD1LNdAsm_16: + case ARM::VLD1LNdAsm_P16: + case ARM::VLD1LNdAsm_I16: + case ARM::VLD1LNdAsm_S16: + case ARM::VLD1LNdAsm_U16: + case ARM::VLD1LNdAsm_32: + case ARM::VLD1LNdAsm_F: + case ARM::VLD1LNdAsm_F32: + case ARM::VLD1LNdAsm_I32: + case ARM::VLD1LNdAsm_S32: + case ARM::VLD1LNdAsm_U32: { MCInst TmpInst; // Shuffle the operands around so the lane index operand is in the // right place. diff --git a/test/MC/ARM/neon-vld-encoding.s b/test/MC/ARM/neon-vld-encoding.s index 9b831bbe9b3..a6c1b6eff98 100644 --- a/test/MC/ARM/neon-vld-encoding.s +++ b/test/MC/ARM/neon-vld-encoding.s @@ -182,11 +182,11 @@ @ CHECK: vld1.8 {d4[], d5[]}, [r1]! @ encoding: [0x2d,0x4c,0xa1,0xf4] @ CHECK: vld1.8 {d4[], d5[]}, [r1], r3 @ encoding: [0x23,0x4c,0xa1,0xf4] -@ vld1.8 {d16[3]}, [r0] + vld1.8 {d16[3]}, [r0] @ vld1.16 {d16[2]}, [r0, :16] @ vld1.32 {d16[1]}, [r0, :32] -@ FIXME: vld1.8 {d16[3]}, [r0] @ encoding: [0x6f,0x00,0xe0,0xf4] +@ CHECK: vld1.8 {d16[3]}, [r0] @ encoding: [0x6f,0x00,0xe0,0xf4] @ FIXME: vld1.16 {d16[2]}, [r0, :16] @ encoding: [0x9f,0x04,0xe0,0xf4] @ FIXME: vld1.32 {d16[1]}, [r0, :32] @ encoding: [0xbf,0x08,0xe0,0xf4]