ARM NEON VST2 assembly parsing and encoding.

Work in progress. Parsing for non-writeback, single spaced register lists
works now. The rest have the representations better factored, but still
need more to be able to parse properly.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146579 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Grosbach 2011-12-14 19:35:22 +00:00
parent ac12ef4ad2
commit e90ac9bce9
7 changed files with 64 additions and 88 deletions

View File

@ -307,19 +307,19 @@ static const NEONLdStTableEntry NEONLdStTable[] = {
{ ARM::VST2LNq32Pseudo, ARM::VST2LNq32, false, false, false, EvenDblSpc, 2, 2,true},
{ ARM::VST2LNq32Pseudo_UPD, ARM::VST2LNq32_UPD, false, true, true, EvenDblSpc, 2, 2,true},
{ ARM::VST2d16Pseudo, ARM::VST2d16, false, false, false, SingleSpc, 2, 4 ,true},
{ ARM::VST2d16Pseudo_UPD, ARM::VST2d16_UPD, false, true, true, SingleSpc, 2, 4 ,true},
{ ARM::VST2d32Pseudo, ARM::VST2d32, false, false, false, SingleSpc, 2, 2 ,true},
{ ARM::VST2d32Pseudo_UPD, ARM::VST2d32_UPD, false, true, true, SingleSpc, 2, 2 ,true},
{ ARM::VST2d8Pseudo, ARM::VST2d8, false, false, false, SingleSpc, 2, 8 ,true},
{ ARM::VST2d8Pseudo_UPD, ARM::VST2d8_UPD, false, true, true, SingleSpc, 2, 8 ,true},
{ ARM::VST2d16Pseudo, ARM::VST2d16, false, false, false, SingleSpc, 2, 4 ,false},
{ ARM::VST2d16Pseudo_UPD, ARM::VST2d16_UPD, false, true, true, SingleSpc, 2, 4 ,false},
{ ARM::VST2d32Pseudo, ARM::VST2d32, false, false, false, SingleSpc, 2, 2 ,false},
{ ARM::VST2d32Pseudo_UPD, ARM::VST2d32_UPD, false, true, true, SingleSpc, 2, 2 ,false},
{ ARM::VST2d8Pseudo, ARM::VST2d8, false, false, false, SingleSpc, 2, 8 ,false},
{ ARM::VST2d8Pseudo_UPD, ARM::VST2d8_UPD, false, true, true, SingleSpc, 2, 8 ,false},
{ ARM::VST2q16Pseudo, ARM::VST2q16, false, false, false, SingleSpc, 4, 4 ,true},
{ ARM::VST2q16Pseudo_UPD, ARM::VST2q16_UPD, false, true, true, SingleSpc, 4, 4 ,true},
{ ARM::VST2q32Pseudo, ARM::VST2q32, false, false, false, SingleSpc, 4, 2 ,true},
{ ARM::VST2q32Pseudo_UPD, ARM::VST2q32_UPD, false, true, true, SingleSpc, 4, 2 ,true},
{ ARM::VST2q8Pseudo, ARM::VST2q8, false, false, false, SingleSpc, 4, 8 ,true},
{ ARM::VST2q8Pseudo_UPD, ARM::VST2q8_UPD, false, true, true, SingleSpc, 4, 8 ,true},
{ ARM::VST2q16Pseudo, ARM::VST2q16, false, false, false, SingleSpc, 4, 4 ,false},
{ ARM::VST2q16Pseudo_UPD, ARM::VST2q16_UPD, false, true, true, SingleSpc, 4, 4 ,false},
{ ARM::VST2q32Pseudo, ARM::VST2q32, false, false, false, SingleSpc, 4, 2 ,false},
{ ARM::VST2q32Pseudo_UPD, ARM::VST2q32_UPD, false, true, true, SingleSpc, 4, 2 ,false},
{ ARM::VST2q8Pseudo, ARM::VST2q8, false, false, false, SingleSpc, 4, 8 ,false},
{ ARM::VST2q8Pseudo_UPD, ARM::VST2q8_UPD, false, true, true, SingleSpc, 4, 8 ,false},
{ ARM::VST3LNd16Pseudo, ARM::VST3LNd16, false, false, false, SingleSpc, 3, 4 ,true},
{ ARM::VST3LNd16Pseudo_UPD, ARM::VST3LNd16_UPD, false, true, true, SingleSpc, 3, 4 ,true},

View File

@ -116,7 +116,7 @@ def VecListTwoQAsmOperand : AsmOperandClass {
let ParserMethod = "parseVectorList";
let RenderMethod = "addVecListOperands";
}
def VecListTwoQ : RegisterOperand<DPR, "printVectorListTwo"> {
def VecListTwoQ : RegisterOperand<DPR, "printVectorListTwoSpaced"> {
let ParserMatchClass = VecListTwoQAsmOperand;
}
@ -1497,31 +1497,28 @@ def VST1d64QPseudoWB_fixed : VSTQQWBPseudo<IIC_VST1x4u>;
def VST1d64QPseudoWB_register : VSTQQWBPseudo<IIC_VST1x4u>;
// VST2 : Vector Store (multiple 2-element structures)
class VST2D<bits<4> op11_8, bits<4> op7_4, string Dt>
: NLdSt<0, 0b00, op11_8, op7_4, (outs),
(ins addrmode6:$Rn, DPR:$Vd, DPR:$src2),
IIC_VST2, "vst2", Dt, "\\{$Vd, $src2\\}, $Rn", "", []> {
class VST2D<bits<4> op11_8, bits<4> op7_4, string Dt, RegisterOperand VdTy>
: NLdSt<0, 0b00, op11_8, op7_4, (outs), (ins addrmode6:$Rn, VdTy:$Vd),
IIC_VST2, "vst2", Dt, "$Vd, $Rn", "", []> {
let Rm = 0b1111;
let Inst{5-4} = Rn{5-4};
let DecoderMethod = "DecodeVSTInstruction";
}
class VST2Q<bits<4> op7_4, string Dt>
: NLdSt<0, 0b00, 0b0011, op7_4, (outs),
(ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4),
IIC_VST2x2, "vst2", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn",
"", []> {
class VST2Q<bits<4> op7_4, string Dt, RegisterOperand VdTy>
: NLdSt<0, 0b00, 0b0011, op7_4, (outs), (ins addrmode6:$Rn, VdTy:$Vd),
IIC_VST2x2, "vst2", Dt, "$Vd, $Rn", "", []> {
let Rm = 0b1111;
let Inst{5-4} = Rn{5-4};
let DecoderMethod = "DecodeVSTInstruction";
}
def VST2d8 : VST2D<0b1000, {0,0,?,?}, "8">;
def VST2d16 : VST2D<0b1000, {0,1,?,?}, "16">;
def VST2d32 : VST2D<0b1000, {1,0,?,?}, "32">;
def VST2d8 : VST2D<0b1000, {0,0,?,?}, "8", VecListTwoD>;
def VST2d16 : VST2D<0b1000, {0,1,?,?}, "16", VecListTwoD>;
def VST2d32 : VST2D<0b1000, {1,0,?,?}, "32", VecListTwoD>;
def VST2q8 : VST2Q<{0,0,?,?}, "8">;
def VST2q16 : VST2Q<{0,1,?,?}, "16">;
def VST2q32 : VST2Q<{1,0,?,?}, "32">;
def VST2q8 : VST2Q<{0,0,?,?}, "8", VecListFourD>;
def VST2q16 : VST2Q<{0,1,?,?}, "16", VecListFourD>;
def VST2q32 : VST2Q<{1,0,?,?}, "32", VecListFourD>;
def VST2d8Pseudo : VSTQPseudo<IIC_VST2>;
def VST2d16Pseudo : VSTQPseudo<IIC_VST2>;
@ -1532,27 +1529,24 @@ def VST2q16Pseudo : VSTQQPseudo<IIC_VST2x2>;
def VST2q32Pseudo : VSTQQPseudo<IIC_VST2x2>;
// ...with address register writeback:
class VST2DWB<bits<4> op11_8, bits<4> op7_4, string Dt>
class VST2DWB<bits<4> op11_8, bits<4> op7_4, string Dt, RegisterOperand VdTy>
: NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb),
(ins addrmode6:$Rn, am6offset:$Rm, DPR:$Vd, DPR:$src2),
IIC_VST2u, "vst2", Dt, "\\{$Vd, $src2\\}, $Rn$Rm",
"$Rn.addr = $wb", []> {
(ins addrmode6:$Rn, am6offset:$Rm, VdTy:$Vd),
IIC_VST2u, "vst2", Dt, "$Vd, $Rn$Rm", "$Rn.addr = $wb", []> {
let Inst{5-4} = Rn{5-4};
let DecoderMethod = "DecodeVSTInstruction";
}
class VST2QWB<bits<4> op7_4, string Dt>
: NLdSt<0, 0b00, 0b0011, op7_4, (outs GPR:$wb),
(ins addrmode6:$Rn, am6offset:$Rm,
DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4), IIC_VST2x2u,
"vst2", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn$Rm",
"$Rn.addr = $wb", []> {
(ins addrmode6:$Rn, am6offset:$Rm, VecListFourD:$Vd), IIC_VST2x2u,
"vst2", Dt, "$Vd, $Rn$Rm", "$Rn.addr = $wb", []> {
let Inst{5-4} = Rn{5-4};
let DecoderMethod = "DecodeVSTInstruction";
}
def VST2d8_UPD : VST2DWB<0b1000, {0,0,?,?}, "8">;
def VST2d16_UPD : VST2DWB<0b1000, {0,1,?,?}, "16">;
def VST2d32_UPD : VST2DWB<0b1000, {1,0,?,?}, "32">;
def VST2d8_UPD : VST2DWB<0b1000, {0,0,?,?}, "8", VecListTwoD>;
def VST2d16_UPD : VST2DWB<0b1000, {0,1,?,?}, "16", VecListTwoD>;
def VST2d32_UPD : VST2DWB<0b1000, {1,0,?,?}, "32", VecListTwoD>;
def VST2q8_UPD : VST2QWB<{0,0,?,?}, "8">;
def VST2q16_UPD : VST2QWB<{0,1,?,?}, "16">;
@ -1567,12 +1561,12 @@ def VST2q16Pseudo_UPD : VSTQQWBPseudo<IIC_VST2x2u>;
def VST2q32Pseudo_UPD : VSTQQWBPseudo<IIC_VST2x2u>;
// ...with double-spaced registers
def VST2b8 : VST2D<0b1001, {0,0,?,?}, "8">;
def VST2b16 : VST2D<0b1001, {0,1,?,?}, "16">;
def VST2b32 : VST2D<0b1001, {1,0,?,?}, "32">;
def VST2b8_UPD : VST2DWB<0b1001, {0,0,?,?}, "8">;
def VST2b16_UPD : VST2DWB<0b1001, {0,1,?,?}, "16">;
def VST2b32_UPD : VST2DWB<0b1001, {1,0,?,?}, "32">;
def VST2b8 : VST2D<0b1001, {0,0,?,?}, "8", VecListTwoQ>;
def VST2b16 : VST2D<0b1001, {0,1,?,?}, "16", VecListTwoQ>;
def VST2b32 : VST2D<0b1001, {1,0,?,?}, "32", VecListTwoQ>;
def VST2b8_UPD : VST2DWB<0b1001, {0,0,?,?}, "8", VecListTwoQ>;
def VST2b16_UPD : VST2DWB<0b1001, {0,1,?,?}, "16", VecListTwoQ>;
def VST2b32_UPD : VST2DWB<0b1001, {1,0,?,?}, "32", VecListTwoQ>;
// VST3 : Vector Store (multiple 3-element structures)
class VST3D<bits<4> op11_8, bits<4> op7_4, string Dt>

View File

@ -2281,18 +2281,6 @@ static DecodeStatus DecodeVSTInstruction(llvm::MCInst &Inst, unsigned Insn,
// Second input register
switch (Inst.getOpcode()) {
case ARM::VST2d8:
case ARM::VST2d16:
case ARM::VST2d32:
case ARM::VST2d8_UPD:
case ARM::VST2d16_UPD:
case ARM::VST2d32_UPD:
case ARM::VST2q8:
case ARM::VST2q16:
case ARM::VST2q32:
case ARM::VST2q8_UPD:
case ARM::VST2q16_UPD:
case ARM::VST2q32_UPD:
case ARM::VST3d8:
case ARM::VST3d16:
case ARM::VST3d32:
@ -2308,12 +2296,6 @@ static DecodeStatus DecodeVSTInstruction(llvm::MCInst &Inst, unsigned Insn,
if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
return MCDisassembler::Fail;
break;
case ARM::VST2b8:
case ARM::VST2b16:
case ARM::VST2b32:
case ARM::VST2b8_UPD:
case ARM::VST2b16_UPD:
case ARM::VST2b32_UPD:
case ARM::VST3q8:
case ARM::VST3q16:
case ARM::VST3q32:
@ -2335,12 +2317,6 @@ static DecodeStatus DecodeVSTInstruction(llvm::MCInst &Inst, unsigned Insn,
// Third input register
switch (Inst.getOpcode()) {
case ARM::VST2q8:
case ARM::VST2q16:
case ARM::VST2q32:
case ARM::VST2q8_UPD:
case ARM::VST2q16_UPD:
case ARM::VST2q32_UPD:
case ARM::VST3d8:
case ARM::VST3d16:
case ARM::VST3d32:
@ -2377,12 +2353,6 @@ static DecodeStatus DecodeVSTInstruction(llvm::MCInst &Inst, unsigned Insn,
// Fourth input register
switch (Inst.getOpcode()) {
case ARM::VST2q8:
case ARM::VST2q16:
case ARM::VST2q32:
case ARM::VST2q8_UPD:
case ARM::VST2q16_UPD:
case ARM::VST2q32_UPD:
case ARM::VST4d8:
case ARM::VST4d16:
case ARM::VST4d32:

View File

@ -1045,3 +1045,13 @@ void ARMInstPrinter::printVectorListTwoAllLanes(const MCInst *MI,
O << "{" << getRegisterName(MI->getOperand(OpNum).getReg()) << "[], "
<< getRegisterName(MI->getOperand(OpNum).getReg() + 1) << "[]}";
}
void ARMInstPrinter::printVectorListTwoSpaced(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) << "}";
}

View File

@ -137,6 +137,8 @@ public:
raw_ostream &O);
void printVectorListTwoAllLanes(const MCInst *MI, unsigned OpNum,
raw_ostream &O);
void printVectorListTwoSpaced(const MCInst *MI, unsigned OpNum,
raw_ostream &O);
};
} // end namespace llvm

View File

@ -31,19 +31,19 @@
@ CHECK: vst1.64 {d16, d17, d18, d19}, [r3], r2 @ encoding: [0xc2,0x02,0x43,0xf4]
@ vst2.8 {d16, d17}, [r0, :64]
@ vst2.16 {d16, d17}, [r0, :128]
@ vst2.32 {d16, d17}, [r0]
@ vst2.8 {d16, d17, d18, d19}, [r0, :64]
@ vst2.16 {d16, d17, d18, d19}, [r0, :128]
@ vst2.32 {d16, d17, d18, d19}, [r0, :256]
vst2.8 {d16, d17}, [r0, :64]
vst2.16 {d16, d17}, [r0, :128]
vst2.32 {d16, d17}, [r0]
vst2.8 {d16, d17, d18, d19}, [r0, :64]
vst2.16 {d16, d17, d18, d19}, [r0, :128]
vst2.32 {d16, d17, d18, d19}, [r0, :256]
@ FIXME: vst2.8 {d16, d17}, [r0, :64] @ encoding: [0x1f,0x08,0x40,0xf4]
@ FIXME: vst2.16 {d16, d17}, [r0, :128] @ encoding: [0x6f,0x08,0x40,0xf4]
@ FIXME: vst2.32 {d16, d17}, [r0] @ encoding: [0x8f,0x08,0x40,0xf4]
@ FIXME: vst2.8 {d16, d17, d18, d19}, [r0, :64] @ encoding: [0x1f,0x03,0x40,0xf4]
@ FIXME: vst2.16 {d16, d17, d18, d19}, [r0, :128] @ encoding: [0x6f,0x03,0x40,0xf4]
@ FIXME: vst2.32 {d16, d17, d18, d19}, [r0, :256] @ encoding: [0xbf,0x03,0x40,0xf4]
@ CHECK: vst2.8 {d16, d17}, [r0, :64] @ encoding: [0x1f,0x08,0x40,0xf4]
@ CHECK: vst2.16 {d16, d17}, [r0, :128] @ encoding: [0x6f,0x08,0x40,0xf4]
@ CHECK: vst2.32 {d16, d17}, [r0] @ encoding: [0x8f,0x08,0x40,0xf4]
@ CHECK: vst2.8 {d16, d17, d18, d19}, [r0, :64] @ encoding: [0x1f,0x03,0x40,0xf4]
@ CHECK: vst2.16 {d16, d17, d18, d19}, [r0, :128] @ encoding: [0x6f,0x03,0x40,0xf4]
@ CHECK: vst2.32 {d16, d17, d18, d19}, [r0, :256] @ encoding: [0xbf,0x03,0x40,0xf4]
@ vst3.8 {d16, d17, d18}, [r0, :64]

View File

@ -1586,5 +1586,5 @@
# CHECK: vst4.32 {d17[0], d19[0], d21[0], d23[0]}, [r0]
0x63 0xf9 0x37 0xc9
# CHECK: vld2.8 {d28, d29}, [r3, :256], r7
# CHECK: vld2.8 {d28, d30}, [r3, :256], r7