diff options
| -rw-r--r-- | llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp | 32 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp | 42 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrNEON.td | 91 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 34 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 28 | 
5 files changed, 168 insertions, 59 deletions
diff --git a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp index 0c1b0477db9..5f7b8b21823 100644 --- a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/llvm/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/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp index 7c67e0a1e35..bc8588f948c 100644 --- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/llvm/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<ConstantSDNode>(Inc.getNode()))          Opc = getVLDSTRegisterUpdateOpcode(Opc); -      if (NumVecs != 1 || !isa<ConstantSDNode>(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<ConstantSDNode>(Inc.getNode()))          Ops.push_back(isa<ConstantSDNode>(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<ConstantSDNode>(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<ConstantSDNode>(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<ConstantSDNode>(Inc.getNode())) +        Ops.push_back(isa<ConstantSDNode>(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/llvm/lib/Target/ARM/ARMInstrNEON.td b/llvm/lib/Target/ARM/ARMInstrNEON.td index 3023a3419dd..d3c4486b3db 100644 --- a/llvm/lib/Target/ARM/ARMInstrNEON.td +++ b/llvm/lib/Target/ARM/ARMInstrNEON.td @@ -1208,6 +1208,14 @@ class VSTQWBPseudo<InstrItinClass itin>    : PseudoNLdSt<(outs GPR:$wb),                  (ins addrmode6:$addr, am6offset:$offset, QPR:$src), itin,                  "$addr.addr = $wb">; +class VSTQWBfixedPseudo<InstrItinClass itin> +  : PseudoNLdSt<(outs GPR:$wb), +                (ins addrmode6:$addr, QPR:$src), itin, +                "$addr.addr = $wb">; +class VSTQWBregisterPseudo<InstrItinClass itin> +  : PseudoNLdSt<(outs GPR:$wb), +                (ins addrmode6:$addr, rGPR:$offset, QPR:$src), itin, +                "$addr.addr = $wb">;  class VSTQQPseudo<InstrItinClass itin>    : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQPR:$src), itin, "">;  class VSTQQWBPseudo<InstrItinClass itin> @@ -1254,36 +1262,65 @@ def  VST1q32Pseudo : VSTQPseudo<IIC_VST1x2>;  def  VST1q64Pseudo : VSTQPseudo<IIC_VST1x2>;  // ...with address register writeback: -class VST1DWB<bits<4> 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<bits<4> 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<bits<4> 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<bits<4> 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<IIC_VST1x2u>; -def VST1q16Pseudo_UPD : VSTQWBPseudo<IIC_VST1x2u>; -def VST1q32Pseudo_UPD : VSTQWBPseudo<IIC_VST1x2u>; -def VST1q64Pseudo_UPD : VSTQWBPseudo<IIC_VST1x2u>; +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<IIC_VST1x2u>; +def VST1q16PseudoWB_fixed : VSTQWBfixedPseudo<IIC_VST1x2u>; +def VST1q32PseudoWB_fixed : VSTQWBfixedPseudo<IIC_VST1x2u>; +def VST1q64PseudoWB_fixed : VSTQWBfixedPseudo<IIC_VST1x2u>; +def VST1q8PseudoWB_register  : VSTQWBregisterPseudo<IIC_VST1x2u>; +def VST1q16PseudoWB_register : VSTQWBregisterPseudo<IIC_VST1x2u>; +def VST1q32PseudoWB_register : VSTQWBregisterPseudo<IIC_VST1x2u>; +def VST1q64PseudoWB_register : VSTQWBregisterPseudo<IIC_VST1x2u>;  // ...with 3 registers  class VST1D3<bits<4> op7_4, string Dt> diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 03fba5aee98..0732060c883 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -202,6 +202,10 @@ class ARMAsmParser : public MCTargetAsmParser {                       const SmallVectorImpl<MCParsedAsmOperand*> &);    bool cvtVLDwbRegister(MCInst &Inst, unsigned Opcode,                          const SmallVectorImpl<MCParsedAsmOperand*> &); +  bool cvtVSTwbFixed(MCInst &Inst, unsigned Opcode, +                     const SmallVectorImpl<MCParsedAsmOperand*> &); +  bool cvtVSTwbRegister(MCInst &Inst, unsigned Opcode, +                        const SmallVectorImpl<MCParsedAsmOperand*> &);    bool validateInstruction(MCInst &Inst,                             const SmallVectorImpl<MCParsedAsmOperand*> &Ops); @@ -3429,6 +3433,36 @@ cvtVLDwbRegister(MCInst &Inst, unsigned Opcode,    return true;  } +bool ARMAsmParser:: +cvtVSTwbFixed(MCInst &Inst, unsigned Opcode, +              const SmallVectorImpl<MCParsedAsmOperand*> &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<MCParsedAsmOperand*> &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/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 88700244fe6..e81cc76c9fb 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/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:  | 

