From bfc9429c2b814469adf3930dda31539d1c3319d8 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Tue, 15 Nov 2011 01:46:57 +0000 Subject: [PATCH] ARM parsing datatype suffix variants for fixed-writeback VLD1/VST1 instructions. rdar://10435076 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@144606 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrNEON.td | 69 +++++++++++++++++++++++++-- utils/TableGen/AsmWriterEmitter.cpp | 7 +++ utils/TableGen/CodeGenInstruction.cpp | 17 +++++-- 3 files changed, 85 insertions(+), 8 deletions(-) diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index 3ccf992c698..49cc254a11b 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -5209,6 +5209,15 @@ defm : VFPDT32ReqInstAlias<"vld1${p}", "$Vd, $Rn", (VLD1d32 VecListOneD:$Vd, addrmode6:$Rn, pred:$p)>; defm : VFPDT64ReqInstAlias<"vld1${p}", "$Vd, $Rn", (VLD1d64 VecListOneD:$Vd, addrmode6:$Rn, pred:$p)>; +// with writeback, fixed stride +defm : VFPDT8ReqInstAlias<"vld1${p}", "$Vd, $Rn!", + (VLD1d8wb_fixed VecListOneD:$Vd, zero_reg, addrmode6:$Rn, pred:$p)>; +defm : VFPDT16ReqInstAlias<"vld1${p}", "$Vd, $Rn!", + (VLD1d16wb_fixed VecListOneD:$Vd, zero_reg, addrmode6:$Rn, pred:$p)>; +defm : VFPDT32ReqInstAlias<"vld1${p}", "$Vd, $Rn!", + (VLD1d32wb_fixed VecListOneD:$Vd, zero_reg, addrmode6:$Rn, pred:$p)>; +defm : VFPDT64ReqInstAlias<"vld1${p}", "$Vd, $Rn!", + (VLD1d64wb_fixed VecListOneD:$Vd, zero_reg, addrmode6:$Rn, pred:$p)>; // Load two D registers. defm : VFPDT8ReqInstAlias<"vld1${p}", "$Vd, $Rn", @@ -5219,6 +5228,15 @@ defm : VFPDT32ReqInstAlias<"vld1${p}", "$Vd, $Rn", (VLD1q32 VecListTwoD:$Vd, addrmode6:$Rn, pred:$p)>; defm : VFPDT64ReqInstAlias<"vld1${p}", "$Vd, $Rn", (VLD1q64 VecListTwoD:$Vd, addrmode6:$Rn, pred:$p)>; +// with writeback, fixed stride +defm : VFPDT8ReqInstAlias<"vld1${p}", "$Vd, $Rn!", + (VLD1q8wb_fixed VecListTwoD:$Vd, zero_reg, addrmode6:$Rn, pred:$p)>; +defm : VFPDT16ReqInstAlias<"vld1${p}", "$Vd, $Rn!", + (VLD1q16wb_fixed VecListTwoD:$Vd, zero_reg, addrmode6:$Rn, pred:$p)>; +defm : VFPDT32ReqInstAlias<"vld1${p}", "$Vd, $Rn!", + (VLD1q32wb_fixed VecListTwoD:$Vd, zero_reg, addrmode6:$Rn, pred:$p)>; +defm : VFPDT64ReqInstAlias<"vld1${p}", "$Vd, $Rn!", + (VLD1q64wb_fixed VecListTwoD:$Vd, zero_reg, addrmode6:$Rn, pred:$p)>; // Load three D registers. defm : VFPDT8ReqInstAlias<"vld1${p}", "$Vd, $Rn", @@ -5229,6 +5247,20 @@ defm : VFPDT32ReqInstAlias<"vld1${p}", "$Vd, $Rn", (VLD1d32T VecListThreeD:$Vd, addrmode6:$Rn, pred:$p)>; defm : VFPDT64ReqInstAlias<"vld1${p}", "$Vd, $Rn", (VLD1d64T VecListThreeD:$Vd, addrmode6:$Rn, pred:$p)>; +// with writeback, fixed stride +defm : VFPDT8ReqInstAlias<"vld1${p}", "$Vd, $Rn!", + (VLD1d8Twb_fixed VecListThreeD:$Vd, zero_reg, + addrmode6:$Rn, pred:$p)>; +defm : VFPDT16ReqInstAlias<"vld1${p}", "$Vd, $Rn!", + (VLD1d16Twb_fixed VecListThreeD:$Vd, zero_reg, + addrmode6:$Rn, pred:$p)>; +defm : VFPDT32ReqInstAlias<"vld1${p}", "$Vd, $Rn!", + (VLD1d32Twb_fixed VecListThreeD:$Vd, zero_reg, + addrmode6:$Rn, pred:$p)>; +defm : VFPDT64ReqInstAlias<"vld1${p}", "$Vd, $Rn!", + (VLD1d64Twb_fixed VecListThreeD:$Vd, zero_reg, + addrmode6:$Rn, pred:$p)>; + // Load four D registers. defm : VFPDT8ReqInstAlias<"vld1${p}", "$Vd, $Rn", @@ -5239,9 +5271,22 @@ defm : VFPDT32ReqInstAlias<"vld1${p}", "$Vd, $Rn", (VLD1d32Q VecListFourD:$Vd, addrmode6:$Rn, pred:$p)>; defm : VFPDT64ReqInstAlias<"vld1${p}", "$Vd, $Rn", (VLD1d64Q VecListFourD:$Vd, addrmode6:$Rn, pred:$p)>; +// with writeback, fixed stride +defm : VFPDT8ReqInstAlias<"vld1${p}", "$Vd, $Rn!", + (VLD1d8Qwb_fixed VecListFourD:$Vd, zero_reg, + addrmode6:$Rn, pred:$p)>; +defm : VFPDT16ReqInstAlias<"vld1${p}", "$Vd, $Rn!", + (VLD1d16Qwb_fixed VecListFourD:$Vd, zero_reg, + addrmode6:$Rn, pred:$p)>; +defm : VFPDT32ReqInstAlias<"vld1${p}", "$Vd, $Rn!", + (VLD1d32Qwb_fixed VecListFourD:$Vd, zero_reg, + addrmode6:$Rn, pred:$p)>; +defm : VFPDT64ReqInstAlias<"vld1${p}", "$Vd, $Rn!", + (VLD1d64Qwb_fixed VecListFourD:$Vd, zero_reg, + addrmode6:$Rn, pred:$p)>; // VST1 requires a size suffix, but also accepts type specific variants. -// Load one D register. +// Store one D register. defm : VFPDT8ReqInstAlias<"vst1${p}", "$Vd, $Rn", (VST1d8 addrmode6:$Rn, VecListOneD:$Vd, pred:$p)>; defm : VFPDT16ReqInstAlias<"vst1${p}", "$Vd, $Rn", @@ -5250,8 +5295,17 @@ defm : VFPDT32ReqInstAlias<"vst1${p}", "$Vd, $Rn", (VST1d32 addrmode6:$Rn, VecListOneD:$Vd, pred:$p)>; defm : VFPDT64ReqInstAlias<"vst1${p}", "$Vd, $Rn", (VST1d64 addrmode6:$Rn, VecListOneD:$Vd, pred:$p)>; - -// Load two D registers. +// with writeback, fixed stride +defm : VFPDT8ReqInstAlias<"vst1${p}", "$Vd, $Rn!", + (VST1d8wb_fixed zero_reg, addrmode6:$Rn, VecListOneD:$Vd, pred:$p)>; +defm : VFPDT16ReqInstAlias<"vst1${p}", "$Vd, $Rn!", + (VST1d16wb_fixed zero_reg, addrmode6:$Rn, VecListOneD:$Vd, pred:$p)>; +defm : VFPDT32ReqInstAlias<"vst1${p}", "$Vd, $Rn!", + (VST1d32wb_fixed zero_reg, addrmode6:$Rn, VecListOneD:$Vd, pred:$p)>; +defm : VFPDT64ReqInstAlias<"vst1${p}", "$Vd, $Rn!", + (VST1d64wb_fixed zero_reg, addrmode6:$Rn, VecListOneD:$Vd, pred:$p)>; + +// Store two D registers. defm : VFPDT8ReqInstAlias<"vst1${p}", "$Vd, $Rn", (VST1q8 addrmode6:$Rn, VecListTwoD:$Vd, pred:$p)>; defm : VFPDT16ReqInstAlias<"vst1${p}", "$Vd, $Rn", @@ -5260,6 +5314,15 @@ defm : VFPDT32ReqInstAlias<"vst1${p}", "$Vd, $Rn", (VST1q32 addrmode6:$Rn, VecListTwoD:$Vd, pred:$p)>; defm : VFPDT64ReqInstAlias<"vst1${p}", "$Vd, $Rn", (VST1q64 addrmode6:$Rn, VecListTwoD:$Vd, pred:$p)>; +// with writeback, fixed stride +defm : VFPDT8ReqInstAlias<"vst1${p}", "$Vd, $Rn!", + (VST1q8wb_fixed zero_reg, addrmode6:$Rn, VecListTwoD:$Vd, pred:$p)>; +defm : VFPDT16ReqInstAlias<"vst1${p}", "$Vd, $Rn!", + (VST1q16wb_fixed zero_reg, addrmode6:$Rn, VecListTwoD:$Vd, pred:$p)>; +defm : VFPDT32ReqInstAlias<"vst1${p}", "$Vd, $Rn!", + (VST1q32wb_fixed zero_reg, addrmode6:$Rn, VecListTwoD:$Vd, pred:$p)>; +defm : VFPDT64ReqInstAlias<"vst1${p}", "$Vd, $Rn!", + (VST1q64wb_fixed zero_reg, addrmode6:$Rn, VecListTwoD:$Vd, pred:$p)>; // FIXME: The three and four register VST1 instructions haven't been moved // to the VecList* encoding yet, so we can't do assembly parsing support diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index 3123e11f774..bbac59c25cd 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -900,6 +900,13 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { IAP->addCond(Cond); break; case CodeGenInstAlias::ResultOperand::K_Reg: + // If this is zero_reg, something's playing tricks we're not + // equipped to handle. + if (!CGA->ResultOperands[i].getRegister()) { + CantHandle = true; + break; + } + Cond = std::string("MI->getOperand(") + llvm::utostr(i) + ").getReg() == " + Target.getName() + "::" + CGA->ResultOperands[i].getRegister()->getName(); diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index 46e6591fdc9..fb9ad9371be 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -468,9 +468,13 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, if (ADI && ADI->getDef()->getName() == "zero_reg") { // Check if this is an optional def. - if (!InstOpRec->isSubClassOf("OptionalDefOperand")) - throw TGError(Loc, "reg0 used for result that is not an " - "OptionalDefOperand!"); + // Tied operands where the source is a sub-operand of a complex operand + // need to represent both operands in the alias destination instruction. + // Allow zero_reg for the tied portion. This can and should go away once + // the MC representation of things doesn't use tied operands at all. + //if (!InstOpRec->isSubClassOf("OptionalDefOperand")) + // throw TGError(Loc, "reg0 used for result that is not an " + // "OptionalDefOperand!"); ResOp = ResultOperand(static_cast(0)); return true; @@ -537,8 +541,11 @@ CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T) : TheDef(R) { unsigned AliasOpNo = 0; for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) { - // Tied registers don't have an entry in the result dag. - if (ResultInst->Operands[i].getTiedRegister() != -1) + // Tied registers don't have an entry in the result dag unless they're part + // of a complex operand, in which case we include them anyways, as we + // don't have any other way to specify the whole operand. + if (ResultInst->Operands[i].MINumOperands == 1 && + ResultInst->Operands[i].getTiedRegister() != -1) continue; if (AliasOpNo >= Result->getNumArgs()) -- 2.34.1