diff options
| author | Jim Grosbach <grosbach@apple.com> | 2012-01-24 00:43:17 +0000 | 
|---|---|---|
| committer | Jim Grosbach <grosbach@apple.com> | 2012-01-24 00:43:17 +0000 | 
| commit | ed561fc85032b26e0785e828be8e595f7820785c (patch) | |
| tree | 8804695f0619f7e8dd18fdbef9d409eac32adda5 /llvm/lib | |
| parent | 1e946a4f912054efaa8a5f90fb2c390b1287c5c7 (diff) | |
| download | bcm5719-llvm-ed561fc85032b26e0785e828be8e595f7820785c.tar.gz bcm5719-llvm-ed561fc85032b26e0785e828be8e595f7820785c.zip  | |
NEON VLD4(multiple 4 element structures) assembly parsing.
llvm-svn: 148762
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrNEON.td | 68 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 97 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp | 12 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h | 2 | 
4 files changed, 179 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrNEON.td b/llvm/lib/Target/ARM/ARMInstrNEON.td index e369fc1e7d4..4ec3bc82e0f 100644 --- a/llvm/lib/Target/ARM/ARMInstrNEON.td +++ b/llvm/lib/Target/ARM/ARMInstrNEON.td @@ -133,6 +133,15 @@ def VecListThreeQAsmOperand : AsmOperandClass {  def VecListThreeQ : RegisterOperand<DPR, "printVectorListThreeSpaced"> {    let ParserMatchClass = VecListThreeQAsmOperand;  } +// Register list of three D registers spaced by 2 (three Q registers). +def VecListFourQAsmOperand : AsmOperandClass { +  let Name = "VecListFourQ"; +  let ParserMethod = "parseVectorList"; +  let RenderMethod = "addVecListOperands"; +} +def VecListFourQ : RegisterOperand<DPR, "printVectorListFourSpaced"> { +  let ParserMatchClass = VecListFourQAsmOperand; +}  // Register list of one D register, with "all lanes" subscripting.  def VecListOneDAllLanesAsmOperand : AsmOperandClass { @@ -6196,6 +6205,65 @@ def VST3qWB_register_Asm_32 : +// VLD4 multiple structure pseudo-instructions. These need special handling for +// the vector operands that the normal instructions don't yet model. +// FIXME: Remove these when the register classes and instructions are updated. +def VLD4dAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr", +               (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>; +def VLD4dAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr", +               (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>; +def VLD4dAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr", +               (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>; +def VLD4qAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr", +               (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>; +def VLD4qAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr", +               (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>; +def VLD4qAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr", +               (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>; + +def VLD4dWB_fixed_Asm_8 : +        NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!", +               (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>; +def VLD4dWB_fixed_Asm_16 : +        NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!", +               (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>; +def VLD4dWB_fixed_Asm_32 : +        NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!", +               (ins VecListFourD:$list, addrmode6:$addr, pred:$p)>; +def VLD4qWB_fixed_Asm_8 : +        NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!", +               (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>; +def VLD4qWB_fixed_Asm_16 : +        NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!", +               (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>; +def VLD4qWB_fixed_Asm_32 : +        NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!", +               (ins VecListFourQ:$list, addrmode6:$addr, pred:$p)>; +def VLD4dWB_register_Asm_8 : +        NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm", +                  (ins VecListFourD:$list, addrmode6:$addr, +                       rGPR:$Rm, pred:$p)>; +def VLD4dWB_register_Asm_16 : +        NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm", +                  (ins VecListFourD:$list, addrmode6:$addr, +                       rGPR:$Rm, pred:$p)>; +def VLD4dWB_register_Asm_32 : +        NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm", +                  (ins VecListFourD:$list, addrmode6:$addr, +                       rGPR:$Rm, pred:$p)>; +def VLD4qWB_register_Asm_8 : +        NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm", +                  (ins VecListFourQ:$list, addrmode6:$addr, +                       rGPR:$Rm, pred:$p)>; +def VLD4qWB_register_Asm_16 : +        NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm", +                  (ins VecListFourQ:$list, addrmode6:$addr, +                       rGPR:$Rm, pred:$p)>; +def VLD4qWB_register_Asm_32 : +        NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm", +                  (ins VecListFourQ:$list, addrmode6:$addr, +                       rGPR:$Rm, pred:$p)>; +  // VMOV takes an optional datatype suffix  defm : VFPDTAnyInstAlias<"vmov${p}", "$Vd, $Vm",                           (VORRd DPR:$Vd, DPR:$Vm, DPR:$Vm, pred:$p)>; diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index db3cf1deb1c..81c060f616f 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -5317,6 +5317,26 @@ static unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing) {    case ARM::VLD3qAsm_8:  Spacing = 2; return ARM::VLD3q8;    case ARM::VLD3qAsm_16: Spacing = 2; return ARM::VLD3q16;    case ARM::VLD3qAsm_32: Spacing = 2; return ARM::VLD3q32; + +  // VLD4 +  case ARM::VLD4dWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4d8_UPD; +  case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD; +  case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD; +  case ARM::VLD4qWB_fixed_Asm_8:  Spacing = 2; return ARM::VLD4q8_UPD; +  case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD; +  case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD; +  case ARM::VLD4dWB_register_Asm_8:  Spacing = 1; return ARM::VLD4d8_UPD; +  case ARM::VLD4dWB_register_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD; +  case ARM::VLD4dWB_register_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD; +  case ARM::VLD4qWB_register_Asm_8:  Spacing = 2; return ARM::VLD4q8_UPD; +  case ARM::VLD4qWB_register_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD; +  case ARM::VLD4qWB_register_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD; +  case ARM::VLD4dAsm_8:  Spacing = 1; return ARM::VLD4d8; +  case ARM::VLD4dAsm_16: Spacing = 1; return ARM::VLD4d16; +  case ARM::VLD4dAsm_32: Spacing = 1; return ARM::VLD4d32; +  case ARM::VLD4qAsm_8:  Spacing = 2; return ARM::VLD4q8; +  case ARM::VLD4qAsm_16: Spacing = 2; return ARM::VLD4q16; +  case ARM::VLD4qAsm_32: Spacing = 2; return ARM::VLD4q32;    }  } @@ -5848,6 +5868,83 @@ processInstruction(MCInst &Inst,      return true;    } +  // VLD4 multiple 3-element structure instructions. +  case ARM::VLD4dAsm_8: +  case ARM::VLD4dAsm_16: +  case ARM::VLD4dAsm_32: +  case ARM::VLD4qAsm_8: +  case ARM::VLD4qAsm_16: +  case ARM::VLD4qAsm_32: { +    MCInst TmpInst; +    unsigned Spacing; +    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); +    TmpInst.addOperand(Inst.getOperand(0)); // Vd +    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + +                                            Spacing)); +    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + +                                            Spacing * 2)); +    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + +                                            Spacing * 3)); +    TmpInst.addOperand(Inst.getOperand(1)); // Rn +    TmpInst.addOperand(Inst.getOperand(2)); // alignment +    TmpInst.addOperand(Inst.getOperand(3)); // CondCode +    TmpInst.addOperand(Inst.getOperand(4)); +    Inst = TmpInst; +    return true; +  } + +  case ARM::VLD4dWB_fixed_Asm_8: +  case ARM::VLD4dWB_fixed_Asm_16: +  case ARM::VLD4dWB_fixed_Asm_32: +  case ARM::VLD4qWB_fixed_Asm_8: +  case ARM::VLD4qWB_fixed_Asm_16: +  case ARM::VLD4qWB_fixed_Asm_32: { +    MCInst TmpInst; +    unsigned Spacing; +    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); +    TmpInst.addOperand(Inst.getOperand(0)); // Vd +    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + +                                            Spacing)); +    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + +                                            Spacing * 2)); +    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + +                                            Spacing * 3)); +    TmpInst.addOperand(Inst.getOperand(1)); // Rn +    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn +    TmpInst.addOperand(Inst.getOperand(2)); // alignment +    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm +    TmpInst.addOperand(Inst.getOperand(3)); // CondCode +    TmpInst.addOperand(Inst.getOperand(4)); +    Inst = TmpInst; +    return true; +  } + +  case ARM::VLD4dWB_register_Asm_8: +  case ARM::VLD4dWB_register_Asm_16: +  case ARM::VLD4dWB_register_Asm_32: +  case ARM::VLD4qWB_register_Asm_8: +  case ARM::VLD4qWB_register_Asm_16: +  case ARM::VLD4qWB_register_Asm_32: { +    MCInst TmpInst; +    unsigned Spacing; +    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); +    TmpInst.addOperand(Inst.getOperand(0)); // Vd +    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + +                                            Spacing)); +    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + +                                            Spacing * 2)); +    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + +                                            Spacing * 3)); +    TmpInst.addOperand(Inst.getOperand(1)); // Rn +    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn +    TmpInst.addOperand(Inst.getOperand(2)); // alignment +    TmpInst.addOperand(Inst.getOperand(3)); // Rm +    TmpInst.addOperand(Inst.getOperand(4)); // CondCode +    TmpInst.addOperand(Inst.getOperand(5)); +    Inst = TmpInst; +    return true; +  } +    // VST3 multiple 3-element structure instructions.    case ARM::VST3dAsm_8:    case ARM::VST3dAsm_16: diff --git a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index 734654e3449..27d5de81e9a 100644 --- a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -1096,3 +1096,15 @@ void ARMInstPrinter::printVectorListThreeSpaced(const MCInst *MI,      << getRegisterName(MI->getOperand(OpNum).getReg() + 2) << ", "      << getRegisterName(MI->getOperand(OpNum).getReg() + 4) << "}";  } + +void ARMInstPrinter::printVectorListFourSpaced(const MCInst *MI, +                                                unsigned OpNum, +                                                raw_ostream &O) { +  // Normally, it's not safe to use register enum values directly with +  // addition to get the next register, but for VFP registers, the +  // sort order is guaranteed because they're all of the form D<n>. +  O << "{" << getRegisterName(MI->getOperand(OpNum).getReg()) << ", " +    << getRegisterName(MI->getOperand(OpNum).getReg() + 2) << ", " +    << getRegisterName(MI->getOperand(OpNum).getReg() + 4) << ", " +    << getRegisterName(MI->getOperand(OpNum).getReg() + 6) << "}"; +} diff --git a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h index e189477c237..4af116c8324 100644 --- a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h +++ b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h @@ -145,6 +145,8 @@ public:                                          raw_ostream &O);    void printVectorListThreeSpaced(const MCInst *MI, unsigned OpNum,                                    raw_ostream &O); +  void printVectorListFourSpaced(const MCInst *MI, unsigned OpNum, +                                  raw_ostream &O);  };  } // end namespace llvm  | 

