Fixed MC encoding for index_align for VLD1/VST1 (single element from one lane) for size 32

llvm-svn: 131085
This commit is contained in:
Mon P Wang 2011-05-09 17:47:27 +00:00
parent eb86b04595
commit 92ff16b7bb
5 changed files with 61 additions and 2 deletions

View File

@ -221,6 +221,9 @@ namespace {
const { return 0; } const { return 0; }
unsigned getAddrMode6AddressOpValue(const MachineInstr &MI, unsigned Op) unsigned getAddrMode6AddressOpValue(const MachineInstr &MI, unsigned Op)
const { return 0; } const { return 0; }
unsigned getAddrMode6OneLane32AddressOpValue(const MachineInstr &MI,
unsigned Op)
const { return 0; }
unsigned getAddrMode6DupAddressOpValue(const MachineInstr &MI, unsigned Op) unsigned getAddrMode6DupAddressOpValue(const MachineInstr &MI, unsigned Op)
const { return 0; } const { return 0; }
unsigned getAddrMode6OffsetOpValue(const MachineInstr &MI, unsigned Op) unsigned getAddrMode6OffsetOpValue(const MachineInstr &MI, unsigned Op)

View File

@ -588,6 +588,15 @@ def am6offset : Operand<i32>,
let EncoderMethod = "getAddrMode6OffsetOpValue"; 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<i32>,
ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{
let PrintMethod = "printAddrMode6Operand";
let MIOperandInfo = (ops GPR:$addr, i32imm);
let EncoderMethod = "getAddrMode6OneLane32AddressOpValue";
}
// Special version of addrmode6 to handle alignment encoding for VLD-dup // Special version of addrmode6 to handle alignment encoding for VLD-dup
// instructions, specifically VLD4-dup. // instructions, specifically VLD4-dup.
def addrmode6dup : Operand<i32>, def addrmode6dup : Operand<i32>,

View File

@ -531,6 +531,17 @@ class VLD1LN<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty,
imm:$lane))]> { imm:$lane))]> {
let Rm = 0b1111; let Rm = 0b1111;
} }
class VLD1LN32<bits<4> 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<ValueType Ty, PatFrag LoadOp> : VLDQLNPseudo<IIC_VLD1ln> { class VLD1QLNPseudo<ValueType Ty, PatFrag LoadOp> : VLDQLNPseudo<IIC_VLD1ln> {
let Pattern = [(set QPR:$dst, (vector_insert (Ty QPR:$src), let Pattern = [(set QPR:$dst, (vector_insert (Ty QPR:$src),
(i32 (LoadOp addrmode6:$addr)), (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{7-6} = lane{1-0};
let Inst{4} = Rn{4}; 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{7} = lane{0};
let Inst{5} = Rn{4}; let Inst{5} = Rn{4};
let Inst{4} = Rn{4}; let Inst{4} = Rn{4};
@ -1371,6 +1382,14 @@ class VST1LN<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty,
[(StoreOp (ExtractOp (Ty DPR:$Vd), imm:$lane), addrmode6:$Rn)]> { [(StoreOp (ExtractOp (Ty DPR:$Vd), imm:$lane), addrmode6:$Rn)]> {
let Rm = 0b1111; let Rm = 0b1111;
} }
class VST1LN32<bits<4> 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<ValueType Ty, PatFrag StoreOp, SDNode ExtractOp> class VST1QLNPseudo<ValueType Ty, PatFrag StoreOp, SDNode ExtractOp>
: VSTQLNPseudo<IIC_VST1ln> { : VSTQLNPseudo<IIC_VST1ln> {
let Pattern = [(StoreOp (ExtractOp (Ty QPR:$src), imm:$lane), 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{7-6} = lane{1-0};
let Inst{4} = Rn{5}; 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{7} = lane{0};
let Inst{5-4} = Rn{5-4}; let Inst{5-4} = Rn{5-4};
} }

View File

@ -273,6 +273,8 @@ public:
SmallVectorImpl<MCFixup> &Fixups) const; SmallVectorImpl<MCFixup> &Fixups) const;
unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups) const; SmallVectorImpl<MCFixup> &Fixups) const;
unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups) const;
unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op, unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups) const; SmallVectorImpl<MCFixup> &Fixups) const;
unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op, unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
@ -1178,6 +1180,30 @@ getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
return RegNo | (Align << 4); 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<MCFixup> &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 /// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and
/// alignment operand for use in VLD-dup instructions. This is the same as /// alignment operand for use in VLD-dup instructions. This is the same as
/// getAddrMode6AddressOpValue except for the alignment encoding, which is /// getAddrMode6AddressOpValue except for the alignment encoding, which is

View File

@ -635,6 +635,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
MISC("addrmode6", "kOperandTypeARMAddrMode6"); // R, R, I, I MISC("addrmode6", "kOperandTypeARMAddrMode6"); // R, R, I, I
MISC("am6offset", "kOperandTypeARMAddrMode6Offset"); // R, I, I MISC("am6offset", "kOperandTypeARMAddrMode6Offset"); // R, I, I
MISC("addrmode6dup", "kOperandTypeARMAddrMode6"); // R, R, I, I MISC("addrmode6dup", "kOperandTypeARMAddrMode6"); // R, R, I, I
MISC("addrmode6oneL32", "kOperandTypeARMAddrMode6"); // R, R, I, I
MISC("addrmodepc", "kOperandTypeARMAddrModePC"); // R, I MISC("addrmodepc", "kOperandTypeARMAddrModePC"); // R, I
MISC("addrmode7", "kOperandTypeARMAddrMode7"); // R MISC("addrmode7", "kOperandTypeARMAddrMode7"); // R
MISC("reglist", "kOperandTypeARMRegisterList"); // I, R, ... MISC("reglist", "kOperandTypeARMRegisterList"); // I, R, ...