diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index f1c54b9e173..3fa9a9c7247 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -101,7 +101,8 @@ namespace { unsigned OpIdx); unsigned getMachineSoImmOpValue(unsigned SoImm); - + unsigned getAddrMode6RegisterOperand(const MachineInstr &MI); + unsigned getAddrModeSBit(const MachineInstr &MI, const TargetInstrDesc &TID) const; @@ -172,6 +173,8 @@ namespace { const { return 0; } unsigned getImmMinusOneOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + unsigned getAddrMode6RegisterOperand(const MachineInstr &MI, unsigned Op) + const { return 0; } unsigned getBitfieldInvertedMaskOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getAddrModeImm12OpValue(const MachineInstr &MI, unsigned Op) diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index e3a547fadf0..99bfba99e68 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -1771,6 +1771,15 @@ class NLdSt op21_20, bits<4> op11_8, bits<4> op7_4, let Inst{21-20} = op21_20; let Inst{11-8} = op11_8; let Inst{7-4} = op7_4; + + bits<5> Vd; + bits<6> Rn; + bits<4> Rm; + + let Inst{22} = Vd{4}; + let Inst{15-12} = Vd{3-0}; + let Inst{19-16} = Rn{3-0}; + let Inst{3-0} = Rm{3-0}; } class PseudoNLdSt diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 6384d3c39ce..649c83bbd1f 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -472,6 +472,7 @@ def addrmode6 : Operand, ComplexPattern{ let PrintMethod = "printAddrMode6Operand"; let MIOperandInfo = (ops GPR:$addr, i32imm); + string EncoderMethod = "getAddrMode6RegisterOperand"; } def am6offset : Operand { diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index ed14814dde8..5af5579b0d8 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -164,23 +164,29 @@ class VLDQQQQWBPseudo // VLD1 : Vector Load (multiple single elements) class VLD1D op7_4, string Dt> - : NLdSt<0,0b10,0b0111,op7_4, (outs DPR:$dst), - (ins addrmode6:$addr), IIC_VLD1, - "vld1", Dt, "\\{$dst\\}, $addr", "", []>; + : NLdSt<0,0b10,0b0111,op7_4, (outs DPR:$Vd), + (ins addrmode6:$Rn), IIC_VLD1, + "vld1", Dt, "\\{$Vd\\}, $Rn", "", []> { + let Rm = 0b1111; + let Inst{4} = Rn{4}; +} class VLD1Q op7_4, string Dt> - : NLdSt<0,0b10,0b1010,op7_4, (outs DPR:$dst1, DPR:$dst2), - (ins addrmode6:$addr), IIC_VLD1x2, - "vld1", Dt, "\\{$dst1, $dst2\\}, $addr", "", []>; + : NLdSt<0,0b10,0b1010,op7_4, (outs DPR:$Vd, DPR:$dst2), + (ins addrmode6:$Rn), IIC_VLD1x2, + "vld1", Dt, "\\{$Vd, $dst2\\}, $Rn", "", []> { + let Rm = 0b1111; + let Inst{5-4} = Rn{5-4}; +} -def VLD1d8 : VLD1D<0b0000, "8">; -def VLD1d16 : VLD1D<0b0100, "16">; -def VLD1d32 : VLD1D<0b1000, "32">; -def VLD1d64 : VLD1D<0b1100, "64">; +def VLD1d8 : VLD1D<{0,0,0,?}, "8">; +def VLD1d16 : VLD1D<{0,1,0,?}, "16">; +def VLD1d32 : VLD1D<{1,0,0,?}, "32">; +def VLD1d64 : VLD1D<{1,1,0,?}, "64">; -def VLD1q8 : VLD1Q<0b0000, "8">; -def VLD1q16 : VLD1Q<0b0100, "16">; -def VLD1q32 : VLD1Q<0b1000, "32">; -def VLD1q64 : VLD1Q<0b1100, "64">; +def VLD1q8 : VLD1Q<{0,0,?,?}, "8">; +def VLD1q16 : VLD1Q<{0,1,?,?}, "16">; +def VLD1q32 : VLD1Q<{1,0,?,?}, "32">; +def VLD1q64 : VLD1Q<{1,1,?,?}, "64">; def VLD1q8Pseudo : VLDQPseudo; def VLD1q16Pseudo : VLDQPseudo; diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index 5757046e993..b2763013675 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -99,7 +99,7 @@ public: unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op) const; unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op) const; - + unsigned getAddrMode6RegisterOperand(const MCInst &MI, unsigned Op) const; unsigned getNumFixupKinds() const { assert(0 && "ARMMCCodeEmitter::getNumFixupKinds() not yet implemented."); @@ -296,6 +296,22 @@ unsigned ARMMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, return Binary; } +unsigned ARMMCCodeEmitter::getAddrMode6RegisterOperand(const MCInst &MI, + unsigned Op) const { + const MCOperand &Reg = MI.getOperand(Op); + const MCOperand &Imm = MI.getOperand(Op+1); + + unsigned RegNo = getARMRegisterNumbering(Reg.getReg()); + unsigned Align = Imm.getImm(); + switch(Align) { + case 8: Align = 0x01; break; + case 16: Align = 0x02; break; + case 32: Align = 0x03; break; + default: Align = 0x00; + } + return RegNo | (Align << 4); +} + void ARMMCCodeEmitter:: EncodeInstruction(const MCInst &MI, raw_ostream &OS, SmallVectorImpl &Fixups) const { diff --git a/test/MC/ARM/neon-vld-encoding.s b/test/MC/ARM/neon-vld-encoding.s new file mode 100644 index 00000000000..93919c82392 --- /dev/null +++ b/test/MC/ARM/neon-vld-encoding.s @@ -0,0 +1,19 @@ +@ RUN: llvm-mc -mcpu=cortex-a8 -triple armv7-apple-darwin -show-encoding < %s | FileCheck %s +@ XFAIL: * + +@ CHECK: vld1.8 {d16}, [r0, :64] @ encoding: [0x1f,0x07,0x60,0xf4] + vld1.8 {d16}, [r0, :64] +@ CHECK: vld1.16 {d16}, [r0] @ encoding: [0x4f,0x07,0x60,0xf4] + vld1.16 {d16}, [r0] +@ CHECK: vld1.32 {d16}, [r0] @ encoding: [0x8f,0x07,0x60,0xf4] + vld1.32 {d16}, [r0] +@ CHECK: vld1.64 {d16}, [r0] @ encoding: [0xcf,0x07,0x60,0xf4] + vld1.64 {d16}, [r0] +@ CHECK: vld1.8 {d16, d17}, [r0, :64] @ encoding: [0x1f,0x0a,0x60,0xf4] + vld1.8 {d16, d17}, [r0, :64] +@ CHECK: vld1.16 {d16, d17}, [r0, :128] @ encoding: [0x6f,0x0a,0x60,0xf4] + vld1.16 {d16, d17}, [r0, :128] +@ CHECK: vld1.32 {d16, d17}, [r0] @ encoding: [0x8f,0x0a,0x60,0xf4] + vld1.32 {d16, d17}, [r0] +@ CHECK: vld1.64 {d16, d17}, [r0] @ encoding: [0xcf,0x0a,0x60,0xf4] + vld1.64 {d16, d17}, [r0]