From 183c627d89be5d0e8f3255ab7f6d1204c2fabedf Mon Sep 17 00:00:00 2001 From: Mon P Wang Date: Mon, 9 May 2011 17:47:27 +0000 Subject: [PATCH] Fixed MC encoding for index_align for VLD1/VST1 (single element from one lane) for size 32 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131085 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMCodeEmitter.cpp | 3 +++ lib/Target/ARM/ARMInstrInfo.td | 9 +++++++++ lib/Target/ARM/ARMInstrNEON.td | 24 ++++++++++++++++++++++-- lib/Target/ARM/ARMMCCodeEmitter.cpp | 26 ++++++++++++++++++++++++++ utils/TableGen/EDEmitter.cpp | 1 + 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index d0c0e952512..8397e3bf1d7 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -221,6 +221,9 @@ namespace { const { return 0; } unsigned getAddrMode6AddressOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + unsigned getAddrMode6OneLane32AddressOpValue(const MachineInstr &MI, + unsigned Op) + const { return 0; } unsigned getAddrMode6DupAddressOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getAddrMode6OffsetOpValue(const MachineInstr &MI, unsigned Op) diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 2bfd76bfc5b..4e81401eb7e 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -588,6 +588,15 @@ def am6offset : Operand, let EncoderMethod = "getAddrMode6OffsetOpValue"; } +// Special version of addrmode6 to handle alignment encoding for VST1/VLD1 +// (single element from one lane) for size 32. +def addrmode6oneL32 : Operand, + ComplexPattern{ + let PrintMethod = "printAddrMode6Operand"; + let MIOperandInfo = (ops GPR:$addr, i32imm); + let EncoderMethod = "getAddrMode6OneLane32AddressOpValue"; +} + // Special version of addrmode6 to handle alignment encoding for VLD-dup // instructions, specifically VLD4-dup. def addrmode6dup : Operand, diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index e34d69a44d9..2f8912f1ec5 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -531,6 +531,17 @@ class VLD1LN op11_8, bits<4> op7_4, string Dt, ValueType Ty, imm:$lane))]> { let Rm = 0b1111; } +class VLD1LN32 op11_8, bits<4> op7_4, string Dt, ValueType Ty, + PatFrag LoadOp> + : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd), + (ins addrmode6oneL32:$Rn, DPR:$src, nohash_imm:$lane), + IIC_VLD1ln, "vld1", Dt, "\\{$Vd[$lane]\\}, $Rn", + "$src = $Vd", + [(set DPR:$Vd, (vector_insert (Ty DPR:$src), + (i32 (LoadOp addrmode6oneL32:$Rn)), + imm:$lane))]> { + let Rm = 0b1111; +} class VLD1QLNPseudo : VLDQLNPseudo { let Pattern = [(set QPR:$dst, (vector_insert (Ty QPR:$src), (i32 (LoadOp addrmode6:$addr)), @@ -544,7 +555,7 @@ def VLD1LNd16 : VLD1LN<0b0100, {?,?,0,?}, "16", v4i16, extloadi16> { let Inst{7-6} = lane{1-0}; let Inst{4} = Rn{4}; } -def VLD1LNd32 : VLD1LN<0b1000, {?,0,?,?}, "32", v2i32, load> { +def VLD1LNd32 : VLD1LN32<0b1000, {?,0,?,?}, "32", v2i32, load> { let Inst{7} = lane{0}; let Inst{5} = Rn{4}; let Inst{4} = Rn{4}; @@ -1371,6 +1382,14 @@ class VST1LN op11_8, bits<4> op7_4, string Dt, ValueType Ty, [(StoreOp (ExtractOp (Ty DPR:$Vd), imm:$lane), addrmode6:$Rn)]> { let Rm = 0b1111; } +class VST1LN32 op11_8, bits<4> op7_4, string Dt, ValueType Ty, + PatFrag StoreOp, SDNode ExtractOp> + : NLdStLn<1, 0b00, op11_8, op7_4, (outs), + (ins addrmode6oneL32:$Rn, DPR:$Vd, nohash_imm:$lane), + IIC_VST1ln, "vst1", Dt, "\\{$Vd[$lane]\\}, $Rn", "", + [(StoreOp (ExtractOp (Ty DPR:$Vd), imm:$lane), addrmode6oneL32:$Rn)]> { + let Rm = 0b1111; +} class VST1QLNPseudo : VSTQLNPseudo { let Pattern = [(StoreOp (ExtractOp (Ty QPR:$src), imm:$lane), @@ -1386,7 +1405,8 @@ def VST1LNd16 : VST1LN<0b0100, {?,?,0,?}, "16", v4i16, truncstorei16, let Inst{7-6} = lane{1-0}; let Inst{4} = Rn{5}; } -def VST1LNd32 : VST1LN<0b1000, {?,0,?,?}, "32", v2i32, store, extractelt> { + +def VST1LNd32 : VST1LN32<0b1000, {?,0,?,?}, "32", v2i32, store, extractelt> { let Inst{7} = lane{0}; let Inst{5-4} = Rn{5-4}; } diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index 10607b17c53..2b6d9fcfb33 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -273,6 +273,8 @@ public: SmallVectorImpl &Fixups) const; unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, SmallVectorImpl &Fixups) const; + unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups) const; unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op, SmallVectorImpl &Fixups) const; unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, @@ -1178,6 +1180,30 @@ getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, return RegNo | (Align << 4); } +/// getAddrMode6OneLane32AddressOpValue - Encode an addrmode6 register number +/// along with the alignment operand for use in VST1 and VLD1 with size 32. +unsigned ARMMCCodeEmitter:: +getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups) const { + const MCOperand &Reg = MI.getOperand(Op); + const MCOperand &Imm = MI.getOperand(Op + 1); + + unsigned RegNo = getARMRegisterNumbering(Reg.getReg()); + unsigned Align = 0; + + switch (Imm.getImm()) { + default: break; + case 2: + case 4: + case 8: + case 16: Align = 0x00; break; + case 32: Align = 0x03; break; + } + + return RegNo | (Align << 4); +} + + /// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and /// alignment operand for use in VLD-dup instructions. This is the same as /// getAddrMode6AddressOpValue except for the alignment encoding, which is diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index 5358c0c3616..cb0e5126a0f 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -635,6 +635,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, MISC("addrmode6", "kOperandTypeARMAddrMode6"); // R, R, I, I MISC("am6offset", "kOperandTypeARMAddrMode6Offset"); // R, I, I MISC("addrmode6dup", "kOperandTypeARMAddrMode6"); // R, R, I, I + MISC("addrmode6oneL32", "kOperandTypeARMAddrMode6"); // R, R, I, I MISC("addrmodepc", "kOperandTypeARMAddrModePC"); // R, I MISC("addrmode7", "kOperandTypeARMAddrMode7"); // R MISC("reglist", "kOperandTypeARMRegisterList"); // I, R, ...