From 30a7a7c1fdbd2607345dd1554e3436749fd75c6e Mon Sep 17 00:00:00 2001 From: Mihai Popa Date: Mon, 20 May 2013 14:57:05 +0000 Subject: [PATCH] VSTn instructions have a number of encoding constraints which are not implemented. I have added these using wrapper methods around the original custom decoder (incidentally - this is a huge poorly written method that should be cleaned up. I have left it as is since the changes would be much to hard to review). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182281 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrNEON.td | 42 +++++++-------- .../ARM/Disassembler/ARMDisassembler.cpp | 51 +++++++++++++++++++ test/MC/Disassembler/ARM/invalid-VST-arm.txt | 35 +++++++++++++ .../ARM/invalid-VST2b32_UPD-arm.txt | 14 +++-- 4 files changed, 117 insertions(+), 25 deletions(-) create mode 100644 test/MC/Disassembler/ARM/invalid-VST-arm.txt diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index 896fd0f7850..140056a81b0 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -1580,14 +1580,14 @@ class VST1D op7_4, string Dt> IIC_VST1, "vst1", Dt, "$Vd, $Rn", "", []> { let Rm = 0b1111; let Inst{4} = Rn{4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST1Instruction"; } class VST1Q op7_4, string Dt> : NLdSt<0,0b00,0b1010,op7_4, (outs), (ins addrmode6:$Rn, VecListDPair:$Vd), IIC_VST1x2, "vst1", Dt, "$Vd, $Rn", "", []> { let Rm = 0b1111; let Inst{5-4} = Rn{5-4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST1Instruction"; } def VST1d8 : VST1D<{0,0,0,?}, "8">; @@ -1608,7 +1608,7 @@ multiclass VST1DWB op7_4, string Dt> { "$Rn.addr = $wb", []> { let Rm = 0b1101; // NLdSt will assign to the right encoding bits. let Inst{4} = Rn{4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST1Instruction"; let AsmMatchConverter = "cvtVSTwbFixed"; } def _register : NLdSt<0,0b00,0b0111,op7_4, (outs GPR:$wb), @@ -1617,7 +1617,7 @@ multiclass VST1DWB op7_4, string Dt> { "vst1", Dt, "$Vd, $Rn, $Rm", "$Rn.addr = $wb", []> { let Inst{4} = Rn{4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST1Instruction"; let AsmMatchConverter = "cvtVSTwbRegister"; } } @@ -1628,7 +1628,7 @@ multiclass VST1QWB op7_4, string Dt> { "$Rn.addr = $wb", []> { let Rm = 0b1101; // NLdSt will assign to the right encoding bits. let Inst{5-4} = Rn{5-4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST1Instruction"; let AsmMatchConverter = "cvtVSTwbFixed"; } def _register : NLdSt<0,0b00,0b1010,op7_4, (outs GPR:$wb), @@ -1637,7 +1637,7 @@ multiclass VST1QWB op7_4, string Dt> { "vst1", Dt, "$Vd, $Rn, $Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST1Instruction"; let AsmMatchConverter = "cvtVSTwbRegister"; } } @@ -1659,7 +1659,7 @@ class VST1D3 op7_4, string Dt> IIC_VST1x3, "vst1", Dt, "$Vd, $Rn", "", []> { let Rm = 0b1111; let Inst{4} = Rn{4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST1Instruction"; } multiclass VST1D3WB op7_4, string Dt> { def _fixed : NLdSt<0,0b00,0b0110,op7_4, (outs GPR:$wb), @@ -1668,7 +1668,7 @@ multiclass VST1D3WB op7_4, string Dt> { "$Rn.addr = $wb", []> { let Rm = 0b1101; // NLdSt will assign to the right encoding bits. let Inst{5-4} = Rn{5-4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST1Instruction"; let AsmMatchConverter = "cvtVSTwbFixed"; } def _register : NLdSt<0,0b00,0b0110,op7_4, (outs GPR:$wb), @@ -1677,7 +1677,7 @@ multiclass VST1D3WB op7_4, string Dt> { "vst1", Dt, "$Vd, $Rn, $Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST1Instruction"; let AsmMatchConverter = "cvtVSTwbRegister"; } } @@ -1704,7 +1704,7 @@ class VST1D4 op7_4, string Dt> []> { let Rm = 0b1111; let Inst{5-4} = Rn{5-4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST1Instruction"; } multiclass VST1D4WB op7_4, string Dt> { def _fixed : NLdSt<0,0b00,0b0010,op7_4, (outs GPR:$wb), @@ -1713,7 +1713,7 @@ multiclass VST1D4WB op7_4, string Dt> { "$Rn.addr = $wb", []> { let Rm = 0b1101; // NLdSt will assign to the right encoding bits. let Inst{5-4} = Rn{5-4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST1Instruction"; let AsmMatchConverter = "cvtVSTwbFixed"; } def _register : NLdSt<0,0b00,0b0010,op7_4, (outs GPR:$wb), @@ -1722,7 +1722,7 @@ multiclass VST1D4WB op7_4, string Dt> { "vst1", Dt, "$Vd, $Rn, $Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST1Instruction"; let AsmMatchConverter = "cvtVSTwbRegister"; } } @@ -1748,7 +1748,7 @@ class VST2 op11_8, bits<4> op7_4, string Dt, RegisterOperand VdTy, itin, "vst2", Dt, "$Vd, $Rn", "", []> { let Rm = 0b1111; let Inst{5-4} = Rn{5-4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST2Instruction"; } def VST2d8 : VST2<0b1000, {0,0,?,?}, "8", VecListDPair, IIC_VST2>; @@ -1772,7 +1772,7 @@ multiclass VST2DWB op11_8, bits<4> op7_4, string Dt, "$Rn.addr = $wb", []> { let Rm = 0b1101; // NLdSt will assign to the right encoding bits. let Inst{5-4} = Rn{5-4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST2Instruction"; let AsmMatchConverter = "cvtVSTwbFixed"; } def _register : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb), @@ -1780,7 +1780,7 @@ multiclass VST2DWB op11_8, bits<4> op7_4, string Dt, "vst2", Dt, "$Vd, $Rn, $Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST2Instruction"; let AsmMatchConverter = "cvtVSTwbRegister"; } } @@ -1791,7 +1791,7 @@ multiclass VST2QWB op7_4, string Dt> { "$Rn.addr = $wb", []> { let Rm = 0b1101; // NLdSt will assign to the right encoding bits. let Inst{5-4} = Rn{5-4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST2Instruction"; let AsmMatchConverter = "cvtVSTwbFixed"; } def _register : NLdSt<0, 0b00, 0b0011, op7_4, (outs GPR:$wb), @@ -1800,7 +1800,7 @@ multiclass VST2QWB op7_4, string Dt> { "vst2", Dt, "$Vd, $Rn, $Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST2Instruction"; let AsmMatchConverter = "cvtVSTwbRegister"; } } @@ -1835,7 +1835,7 @@ class VST3D op11_8, bits<4> op7_4, string Dt> "vst3", Dt, "\\{$Vd, $src2, $src3\\}, $Rn", "", []> { let Rm = 0b1111; let Inst{4} = Rn{4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST3Instruction"; } def VST3d8 : VST3D<0b0100, {0,0,0,?}, "8">; @@ -1854,7 +1854,7 @@ class VST3DWB op11_8, bits<4> op7_4, string Dt> "vst3", Dt, "\\{$Vd, $src2, $src3\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{4} = Rn{4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST3Instruction"; } def VST3d8_UPD : VST3DWB<0b0100, {0,0,0,?}, "8">; @@ -1894,7 +1894,7 @@ class VST4D op11_8, bits<4> op7_4, string Dt> "", []> { let Rm = 0b1111; let Inst{5-4} = Rn{5-4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST4Instruction"; } def VST4d8 : VST4D<0b0000, {0,0,?,?}, "8">; @@ -1913,7 +1913,7 @@ class VST4DWB op11_8, bits<4> op7_4, string Dt> "vst4", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; - let DecoderMethod = "DecodeVSTInstruction"; + let DecoderMethod = "DecodeVST4Instruction"; } def VST4d8_UPD : VST4DWB<0b0000, {0,0,?,?}, "8">; diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index aa59c98296c..fb82945356e 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -241,6 +241,14 @@ static DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); static DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeVST1Instruction(MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder); +static DecodeStatus DecodeVST2Instruction(MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder); +static DecodeStatus DecodeVST3Instruction(MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder); +static DecodeStatus DecodeVST4Instruction(MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder); static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); static DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Val, @@ -2450,6 +2458,49 @@ static DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Insn, return S; } +static DecodeStatus DecodeVST1Instruction(MCInst& Inst, unsigned Insn, + uint64_t Addr, const void* Decoder) { + unsigned type = fieldFromInstruction(Insn, 8, 4); + unsigned align = fieldFromInstruction(Insn, 4, 2); + if(type == 7 && (align & 2)) return MCDisassembler::Fail; + if(type == 10 && align == 3) return MCDisassembler::Fail; + if(type == 6 && (align & 2)) return MCDisassembler::Fail; + + return DecodeVSTInstruction(Inst, Insn, Addr, Decoder); +} + +static DecodeStatus DecodeVST2Instruction(MCInst& Inst, unsigned Insn, + uint64_t Addr, const void* Decoder) { + unsigned size = fieldFromInstruction(Insn, 6, 2); + if(size == 3) return MCDisassembler::Fail; + + unsigned type = fieldFromInstruction(Insn, 8, 4); + unsigned align = fieldFromInstruction(Insn, 4, 2); + if(type == 8 && align == 3) return MCDisassembler::Fail; + if(type == 9 && align == 3) return MCDisassembler::Fail; + + return DecodeVSTInstruction(Inst, Insn, Addr, Decoder); +} + +static DecodeStatus DecodeVST3Instruction(MCInst& Inst, unsigned Insn, + uint64_t Addr, const void* Decoder) { + unsigned size = fieldFromInstruction(Insn, 6, 2); + if(size == 3) return MCDisassembler::Fail; + + unsigned align = fieldFromInstruction(Insn, 4, 2); + if(align & 2) return MCDisassembler::Fail; + + return DecodeVSTInstruction(Inst, Insn, Addr, Decoder); +} + +static DecodeStatus DecodeVST4Instruction(MCInst& Inst, unsigned Insn, + uint64_t Addr, const void* Decoder) { + unsigned size = fieldFromInstruction(Insn, 6, 2); + if(size == 3) return MCDisassembler::Fail; + + return DecodeVSTInstruction(Inst, Insn, Addr, Decoder); +} + static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) { DecodeStatus S = MCDisassembler::Success; diff --git a/test/MC/Disassembler/ARM/invalid-VST-arm.txt b/test/MC/Disassembler/ARM/invalid-VST-arm.txt new file mode 100644 index 00000000000..19f3e5b2f22 --- /dev/null +++ b/test/MC/Disassembler/ARM/invalid-VST-arm.txt @@ -0,0 +1,35 @@ +# VST1 multi-element, type == 0b0111, align == 0b10 -> undefined +# RUN: echo "0xaf 0xb7 0x07 0xf4" | llvm-mc -triple=armv7 -show-encoding -disassemble 2>&1 | FileCheck %s + +# VST1 multi-element, type == 0b0111, align == 0b11 -> undefined +# RUN: echo "0xbf 0xb7 0x07 0xf4" | llvm-mc -triple=armv7 -show-encoding -disassemble 2>&1 | FileCheck %s + +# VST1 multi-element, type == 0b1010, align == 0b11 -> undefined +# RUN: echo "0xbf 0x8a 0x03 0xf4" | llvm-mc -triple=armv7 -show-encoding -disassemble 2>&1 | FileCheck %s + +# VST1 multi-element, type == 0b0110, align == 0b10 -> undefined +# RUN: echo "0xaf 0xb6 0x07 0xf4" | llvm-mc -triple=armv7 -show-encoding -disassemble 2>&1 | FileCheck %s + +# VST1 multi-element, type == 0b0110, align == 0b11 -> undefined +# RUN: echo "0xbf 0xb6 0x07 0xf4" | llvm-mc -triple=armv7 -show-encoding -disassemble 2>&1 | FileCheck %s + +# VST2 multi-element, type == 0b0100, align == 0b11 -> undefined +# RUN: echo "0x4f 0xa8 0x07 0xf7" | llvm-mc -triple=armv7 -show-encoding -disassemble 2>&1 | FileCheck %s + +# VST2 multi-element, type == 0b0100, align == 0b11 -> undefined +# RUN: echo "0x4f 0xa9 0x07 0xf7" | llvm-mc -triple=armv7 -show-encoding -disassemble 2>&1 | FileCheck %s + +# VST3 multi-element, size = 0b11 -> undefined +# RUN: echo "0xbf 0xa4 0x0b 0xf4" | llvm-mc -triple=armv7 -show-encoding -disassemble 2>&1 | FileCheck %s + +# VST3 multi-element, align = 0b10 -> undefined +# RUN: echo "0x6f 0xa4 0x0b 0xf4" | llvm-mc -triple=armv7 -show-encoding -disassemble 2>&1 | FileCheck %s + +# VST3 multi-element, align = 0b11 -> undefined +# RUN: echo "0x7f 0xa4 0x0b 0xf4" | llvm-mc -triple=armv7 -show-encoding -disassemble 2>&1 | FileCheck %s + +# VST4 multi-element, size = 0b11 -> undefined +# RUN: echo "0xcf 0x50 0x03 0xf4" | llvm-mc -triple=armv7 -show-encoding -disassemble 2>&1 | FileCheck %s + +# CHECK: invalid instruction encoding + diff --git a/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt b/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt index 07a1c7aac69..497822a6e5d 100644 --- a/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt @@ -1,6 +1,3 @@ -# RUN: llvm-mc --disassemble %s -triple=armv7-unknown-unknwon -mcpu=cortex-a8 2>&1 | grep "invalid instruction encoding" -# XFAIL: * - # Opcode=1641 Name=VST2b32_UPD Format=ARM_FORMAT_NLdSt(30) # 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- @@ -9,4 +6,13 @@ # # A8.6.393 VST2 (multiple 2-element structures) # type == '1001' and align == '11' ==> UNDEFINED -0xb3 0x9 0x3 0xf4 +# RUN: echo "0xb3 0x09 0x03 0xf4" | llvm-mc --disassemble -triple=armv7-unknown-unknwon -mcpu=cortex-a8 2>&1 | FileCheck %s + +# size == '11' ==> UNDEFINED +# RUN: echo "0xc3 0x08 0x03 0xf4" | llvm-mc --disassemble -triple=armv7-unknown-unknwon -mcpu=cortex-a8 2>&1 | FileCheck %s + +# type == '1000' and align == '11' ==> UNDEFINED +# RUN: echo "0xb3 0x08 0x03 0xf4" | llvm-mc --disassemble -triple=armv7-unknown-unknwon -mcpu=cortex-a8 2>&1 | FileCheck %s + +# CHECK: invalid instruction encoding +