From: Jim Grosbach Date: Mon, 31 Oct 2011 21:50:31 +0000 (+0000) Subject: ARM VST1 w/ writeback assembly parsing and encoding. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=4334e032525d6c9038605f3871b945e8cbe6fab7;p=oota-llvm.git ARM VST1 w/ writeback assembly parsing and encoding. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143369 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/lib/Target/ARM/ARMExpandPseudoInsts.cpp index 0c1b0477db9..5f7b8b21823 100644 --- a/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -273,13 +273,17 @@ static const NEONLdStTableEntry NEONLdStTable[] = { { ARM::VST1d64TPseudo_UPD, ARM::VST1d64T_UPD, false, true, true, SingleSpc, 3, 1 ,true}, { ARM::VST1q16Pseudo, ARM::VST1q16, false, false, false, SingleSpc, 2, 4 ,true}, -{ ARM::VST1q16Pseudo_UPD, ARM::VST1q16_UPD, false, true, true, SingleSpc, 2, 4 ,true}, +{ ARM::VST1q16PseudoWB_fixed, ARM::VST1q16wb_fixed, false, true, false, SingleSpc, 2, 4 ,false}, +{ ARM::VST1q16PseudoWB_register, ARM::VST1q16wb_register, false, true, true, SingleSpc, 2, 4 ,false}, { ARM::VST1q32Pseudo, ARM::VST1q32, false, false, false, SingleSpc, 2, 2 ,true}, -{ ARM::VST1q32Pseudo_UPD, ARM::VST1q32_UPD, false, true, true, SingleSpc, 2, 2 ,true}, +{ ARM::VST1q32PseudoWB_fixed, ARM::VST1q32wb_fixed, false, true, false, SingleSpc, 2, 2 ,false}, +{ ARM::VST1q32PseudoWB_register, ARM::VST1q32wb_register, false, true, true, SingleSpc, 2, 2 ,false}, { ARM::VST1q64Pseudo, ARM::VST1q64, false, false, false, SingleSpc, 2, 1 ,true}, -{ ARM::VST1q64Pseudo_UPD, ARM::VST1q64_UPD, false, true, true, SingleSpc, 2, 1 ,true}, +{ ARM::VST1q64PseudoWB_fixed, ARM::VST1q64wb_fixed, false, true, false, SingleSpc, 2, 1 ,false}, +{ ARM::VST1q64PseudoWB_register, ARM::VST1q64wb_register, false, true, true, SingleSpc, 2, 1 ,false}, { ARM::VST1q8Pseudo, ARM::VST1q8, false, false, false, SingleSpc, 2, 8 ,true}, -{ ARM::VST1q8Pseudo_UPD, ARM::VST1q8_UPD, false, true, true, SingleSpc, 2, 8 ,true}, +{ ARM::VST1q8PseudoWB_fixed, ARM::VST1q8wb_fixed, false, true, false, SingleSpc, 2, 8 ,false}, +{ ARM::VST1q8PseudoWB_register, ARM::VST1q8wb_register, false, true, true, SingleSpc, 2, 8 ,false}, { ARM::VST2LNd16Pseudo, ARM::VST2LNd16, false, false, false, SingleSpc, 2, 4 ,true}, { ARM::VST2LNd16Pseudo_UPD, ARM::VST2LNd16_UPD, false, true, true, SingleSpc, 2, 4 ,true}, @@ -504,10 +508,12 @@ void ARMExpandPseudo::ExpandVST(MachineBasicBlock::iterator &MBBI) { unsigned SrcReg = MI.getOperand(OpIdx++).getReg(); unsigned D0, D1, D2, D3; GetDSubRegs(SrcReg, RegSpc, TRI, D0, D1, D2, D3); - MIB.addReg(D0).addReg(D1); - if (NumRegs > 2) + MIB.addReg(D0); + if (NumRegs > 1 && TableEntry->copyAllListRegs) + MIB.addReg(D1); + if (NumRegs > 2 && TableEntry->copyAllListRegs) MIB.addReg(D2); - if (NumRegs > 3) + if (NumRegs > 3 && TableEntry->copyAllListRegs) MIB.addReg(D3); // Copy the predicate operands. @@ -1153,10 +1159,14 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB, case ARM::VST1q16Pseudo: case ARM::VST1q32Pseudo: case ARM::VST1q64Pseudo: - case ARM::VST1q8Pseudo_UPD: - case ARM::VST1q16Pseudo_UPD: - case ARM::VST1q32Pseudo_UPD: - case ARM::VST1q64Pseudo_UPD: + case ARM::VST1q8PseudoWB_fixed: + case ARM::VST1q16PseudoWB_fixed: + case ARM::VST1q32PseudoWB_fixed: + case ARM::VST1q64PseudoWB_fixed: + case ARM::VST1q8PseudoWB_register: + case ARM::VST1q16PseudoWB_register: + case ARM::VST1q32PseudoWB_register: + case ARM::VST1q64PseudoWB_register: case ARM::VST2d8Pseudo: case ARM::VST2d16Pseudo: case ARM::VST2d32Pseudo: diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index 7c67e0a1e35..bc8588f948c 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -1566,6 +1566,19 @@ static unsigned getVLDSTRegisterUpdateOpcode(unsigned Opc) { case ARM::VLD1q16PseudoWB_fixed: return ARM::VLD1q16PseudoWB_register; case ARM::VLD1q32PseudoWB_fixed: return ARM::VLD1q32PseudoWB_register; case ARM::VLD1q64PseudoWB_fixed: return ARM::VLD1q64PseudoWB_register; + + case ARM::VST1d8wb_fixed: return ARM::VST1d8wb_register; + case ARM::VST1d16wb_fixed: return ARM::VST1d16wb_register; + case ARM::VST1d32wb_fixed: return ARM::VST1d32wb_register; + case ARM::VST1d64wb_fixed: return ARM::VST1d64wb_register; + case ARM::VST1q8wb_fixed: return ARM::VST1q8wb_register; + case ARM::VST1q16wb_fixed: return ARM::VST1q16wb_register; + case ARM::VST1q32wb_fixed: return ARM::VST1q32wb_register; + case ARM::VST1q64wb_fixed: return ARM::VST1q64wb_register; + case ARM::VST1q8PseudoWB_fixed: return ARM::VST1q8PseudoWB_register; + case ARM::VST1q16PseudoWB_fixed: return ARM::VST1q16PseudoWB_register; + case ARM::VST1q32PseudoWB_fixed: return ARM::VST1q32PseudoWB_register; + case ARM::VST1q64PseudoWB_fixed: return ARM::VST1q64PseudoWB_register; } return Opc; // If not one we handle, return it unchanged. } @@ -1635,11 +1648,12 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, bool isUpdating, unsigned NumVecs, SDValue Inc = N->getOperand(AddrOpIdx + 1); // FIXME: VLD1 fixed increment doesn't need Reg0. Remove the reg0 // case entirely when the rest are updated to that form, too. - // Do that before committing this change. Likewise, the opcode - // update call will become unconditional. if (NumVecs == 1 && !isa(Inc.getNode())) Opc = getVLDSTRegisterUpdateOpcode(Opc); - if (NumVecs != 1 || !isa(Inc.getNode())) + // We use a VST1 for v1i64 even if the pseudo says vld2/3/4, so + // check for that explicitly too. Horribly hacky, but temporary. + if ((NumVecs != 1 && Opc != ARM::VLD1q64PseudoWB_fixed) || + !isa(Inc.getNode())) Ops.push_back(isa(Inc.getNode()) ? Reg0 : Inc); } Ops.push_back(Pred); @@ -1782,7 +1796,15 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, bool isUpdating, unsigned NumVecs, Ops.push_back(Align); if (isUpdating) { SDValue Inc = N->getOperand(AddrOpIdx + 1); - Ops.push_back(isa(Inc.getNode()) ? Reg0 : Inc); + // FIXME: VST1 fixed increment doesn't need Reg0. Remove the reg0 + // case entirely when the rest are updated to that form, too. + if (NumVecs == 1 && !isa(Inc.getNode())) + Opc = getVLDSTRegisterUpdateOpcode(Opc); + // We use a VST1 for v1i64 even if the pseudo says vld2/3/4, so + // check for that explicitly too. Horribly hacky, but temporary. + if ((NumVecs != 1 && Opc != ARM::VST1q64PseudoWB_fixed) || + !isa(Inc.getNode())) + Ops.push_back(isa(Inc.getNode()) ? Reg0 : Inc); } Ops.push_back(SrcReg); Ops.push_back(Pred); @@ -2844,16 +2866,18 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) { } case ARMISD::VST1_UPD: { - unsigned DOpcodes[] = { ARM::VST1d8_UPD, ARM::VST1d16_UPD, - ARM::VST1d32_UPD, ARM::VST1d64_UPD }; - unsigned QOpcodes[] = { ARM::VST1q8Pseudo_UPD, ARM::VST1q16Pseudo_UPD, - ARM::VST1q32Pseudo_UPD, ARM::VST1q64Pseudo_UPD }; + unsigned DOpcodes[] = { ARM::VST1d8wb_fixed, ARM::VST1d16wb_fixed, + ARM::VST1d32wb_fixed, ARM::VST1d64wb_fixed }; + unsigned QOpcodes[] = { ARM::VST1q8PseudoWB_fixed, + ARM::VST1q16PseudoWB_fixed, + ARM::VST1q32PseudoWB_fixed, + ARM::VST1q64PseudoWB_fixed }; return SelectVST(N, true, 1, DOpcodes, QOpcodes, 0); } case ARMISD::VST2_UPD: { unsigned DOpcodes[] = { ARM::VST2d8Pseudo_UPD, ARM::VST2d16Pseudo_UPD, - ARM::VST2d32Pseudo_UPD, ARM::VST1q64Pseudo_UPD }; + ARM::VST2d32Pseudo_UPD, ARM::VST1q64PseudoWB_fixed}; unsigned QOpcodes[] = { ARM::VST2q8Pseudo_UPD, ARM::VST2q16Pseudo_UPD, ARM::VST2q32Pseudo_UPD }; return SelectVST(N, true, 2, DOpcodes, QOpcodes, 0); diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index 3023a3419dd..d3c4486b3db 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -1208,6 +1208,14 @@ class VSTQWBPseudo : PseudoNLdSt<(outs GPR:$wb), (ins addrmode6:$addr, am6offset:$offset, QPR:$src), itin, "$addr.addr = $wb">; +class VSTQWBfixedPseudo + : PseudoNLdSt<(outs GPR:$wb), + (ins addrmode6:$addr, QPR:$src), itin, + "$addr.addr = $wb">; +class VSTQWBregisterPseudo + : PseudoNLdSt<(outs GPR:$wb), + (ins addrmode6:$addr, rGPR:$offset, QPR:$src), itin, + "$addr.addr = $wb">; class VSTQQPseudo : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQPR:$src), itin, "">; class VSTQQWBPseudo @@ -1254,36 +1262,65 @@ def VST1q32Pseudo : VSTQPseudo; def VST1q64Pseudo : VSTQPseudo; // ...with address register writeback: -class VST1DWB op7_4, string Dt> - : NLdSt<0, 0b00, 0b0111, op7_4, (outs GPR:$wb), - (ins addrmode6:$Rn, am6offset:$Rm, DPR:$Vd), IIC_VST1u, - "vst1", Dt, "\\{$Vd\\}, $Rn$Rm", "$Rn.addr = $wb", []> { - let Inst{4} = Rn{4}; - let DecoderMethod = "DecodeVSTInstruction"; +multiclass VST1DWB op7_4, string Dt> { + def _fixed : NLdSt<0,0b00, 0b0111,op7_4, (outs GPR:$wb), + (ins addrmode6:$Rn, VecListOneD:$Vd), IIC_VLD1u, + "vst1", Dt, "$Vd, $Rn!", + "$Rn.addr = $wb", []> { + let Rm = 0b1101; // NLdSt will assign to the right encoding bits. + let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVSTInstruction"; + let AsmMatchConverter = "cvtVSTwbFixed"; + } + def _register : NLdSt<0,0b00,0b0111,op7_4, (outs GPR:$wb), + (ins addrmode6:$Rn, rGPR:$Rm, VecListOneD:$Vd), + IIC_VLD1u, + "vst1", Dt, "$Vd, $Rn, $Rm", + "$Rn.addr = $wb", []> { + let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVSTInstruction"; + let AsmMatchConverter = "cvtVSTwbRegister"; + } } -class VST1QWB op7_4, string Dt> - : NLdSt<0, 0b00, 0b1010, op7_4, (outs GPR:$wb), - (ins addrmode6:$Rn, am6offset:$Rm, DPR:$Vd, DPR:$src2), - IIC_VST1x2u, "vst1", Dt, "\\{$Vd, $src2\\}, $Rn$Rm", - "$Rn.addr = $wb", []> { - let Inst{5-4} = Rn{5-4}; - let DecoderMethod = "DecodeVSTInstruction"; +multiclass VST1QWB op7_4, string Dt> { + def _fixed : NLdSt<0,0b00,0b1010,op7_4, (outs GPR:$wb), + (ins addrmode6:$Rn, VecListTwoD:$Vd), IIC_VLD1x2u, + "vst1", Dt, "$Vd, $Rn!", + "$Rn.addr = $wb", []> { + let Rm = 0b1101; // NLdSt will assign to the right encoding bits. + let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVSTInstruction"; + let AsmMatchConverter = "cvtVSTwbFixed"; + } + def _register : NLdSt<0,0b00,0b1010,op7_4, (outs GPR:$wb), + (ins addrmode6:$Rn, rGPR:$Rm, VecListTwoD:$Vd), + IIC_VLD1x2u, + "vst1", Dt, "$Vd, $Rn, $Rm", + "$Rn.addr = $wb", []> { + let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVSTInstruction"; + let AsmMatchConverter = "cvtVSTwbRegister"; + } } -def VST1d8_UPD : VST1DWB<{0,0,0,?}, "8">; -def VST1d16_UPD : VST1DWB<{0,1,0,?}, "16">; -def VST1d32_UPD : VST1DWB<{1,0,0,?}, "32">; -def VST1d64_UPD : VST1DWB<{1,1,0,?}, "64">; - -def VST1q8_UPD : VST1QWB<{0,0,?,?}, "8">; -def VST1q16_UPD : VST1QWB<{0,1,?,?}, "16">; -def VST1q32_UPD : VST1QWB<{1,0,?,?}, "32">; -def VST1q64_UPD : VST1QWB<{1,1,?,?}, "64">; - -def VST1q8Pseudo_UPD : VSTQWBPseudo; -def VST1q16Pseudo_UPD : VSTQWBPseudo; -def VST1q32Pseudo_UPD : VSTQWBPseudo; -def VST1q64Pseudo_UPD : VSTQWBPseudo; +defm VST1d8wb : VST1DWB<{0,0,0,?}, "8">; +defm VST1d16wb : VST1DWB<{0,1,0,?}, "16">; +defm VST1d32wb : VST1DWB<{1,0,0,?}, "32">; +defm VST1d64wb : VST1DWB<{1,1,0,?}, "64">; + +defm VST1q8wb : VST1QWB<{0,0,?,?}, "8">; +defm VST1q16wb : VST1QWB<{0,1,?,?}, "16">; +defm VST1q32wb : VST1QWB<{1,0,?,?}, "32">; +defm VST1q64wb : VST1QWB<{1,1,?,?}, "64">; + +def VST1q8PseudoWB_fixed : VSTQWBfixedPseudo; +def VST1q16PseudoWB_fixed : VSTQWBfixedPseudo; +def VST1q32PseudoWB_fixed : VSTQWBfixedPseudo; +def VST1q64PseudoWB_fixed : VSTQWBfixedPseudo; +def VST1q8PseudoWB_register : VSTQWBregisterPseudo; +def VST1q16PseudoWB_register : VSTQWBregisterPseudo; +def VST1q32PseudoWB_register : VSTQWBregisterPseudo; +def VST1q64PseudoWB_register : VSTQWBregisterPseudo; // ...with 3 registers class VST1D3 op7_4, string Dt> diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 03fba5aee98..0732060c883 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -202,6 +202,10 @@ class ARMAsmParser : public MCTargetAsmParser { const SmallVectorImpl &); bool cvtVLDwbRegister(MCInst &Inst, unsigned Opcode, const SmallVectorImpl &); + bool cvtVSTwbFixed(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl &); + bool cvtVSTwbRegister(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl &); bool validateInstruction(MCInst &Inst, const SmallVectorImpl &Ops); @@ -3429,6 +3433,36 @@ cvtVLDwbRegister(MCInst &Inst, unsigned Opcode, return true; } +bool ARMAsmParser:: +cvtVSTwbFixed(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl &Operands) { + // Create a writeback register dummy placeholder. + Inst.addOperand(MCOperand::CreateImm(0)); + // Vn + ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); + // Vt + ((ARMOperand*)Operands[3])->addVecListTwoDOperands(Inst, 1); + // pred + ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); + return true; +} + +bool ARMAsmParser:: +cvtVSTwbRegister(MCInst &Inst, unsigned Opcode, + const SmallVectorImpl &Operands) { + // Create a writeback register dummy placeholder. + Inst.addOperand(MCOperand::CreateImm(0)); + // Vn + ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2); + // Vm + ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); + // Vt + ((ARMOperand*)Operands[3])->addVecListTwoDOperands(Inst, 1); + // pred + ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); + return true; +} + /// Parse an ARM memory expression, return false if successful else return true /// or an error. The first token must be a '[' when called. bool ARMAsmParser:: diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 88700244fe6..e81cc76c9fb 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -2183,14 +2183,22 @@ static DecodeStatus DecodeVSTInstruction(llvm::MCInst &Inst, unsigned Insn, // Writeback Operand switch (Inst.getOpcode()) { - case ARM::VST1d8_UPD: - case ARM::VST1d16_UPD: - case ARM::VST1d32_UPD: - case ARM::VST1d64_UPD: - case ARM::VST1q8_UPD: - case ARM::VST1q16_UPD: - case ARM::VST1q32_UPD: - case ARM::VST1q64_UPD: + case ARM::VST1d8wb_fixed: + case ARM::VST1d16wb_fixed: + case ARM::VST1d32wb_fixed: + case ARM::VST1d64wb_fixed: + case ARM::VST1d8wb_register: + case ARM::VST1d16wb_register: + case ARM::VST1d32wb_register: + case ARM::VST1d64wb_register: + case ARM::VST1q8wb_fixed: + case ARM::VST1q16wb_fixed: + case ARM::VST1q32wb_fixed: + case ARM::VST1q64wb_fixed: + case ARM::VST1q8wb_register: + case ARM::VST1q16wb_register: + case ARM::VST1q32wb_register: + case ARM::VST1q64wb_register: case ARM::VST1d8T_UPD: case ARM::VST1d16T_UPD: case ARM::VST1d32T_UPD: @@ -2249,10 +2257,6 @@ static DecodeStatus DecodeVSTInstruction(llvm::MCInst &Inst, unsigned Insn, case ARM::VST1q16: case ARM::VST1q32: case ARM::VST1q64: - case ARM::VST1q8_UPD: - case ARM::VST1q16_UPD: - case ARM::VST1q32_UPD: - case ARM::VST1q64_UPD: case ARM::VST1d8T: case ARM::VST1d16T: case ARM::VST1d32T: