disassembler fixes. The ARM disassembler is now crash-free on all opcodes. llvm-svn: 155149
362 lines
15 KiB
Diff
362 lines
15 KiB
Diff
Index: lib/Target/ARM/ARMJITInfo.cpp
|
|
===================================================================
|
|
--- lib/Target/ARM/ARMJITInfo.cpp (revision 152265)
|
|
+++ lib/Target/ARM/ARMJITInfo.cpp (working copy)
|
|
@@ -61,7 +61,7 @@
|
|
// concerned, so we can't just preserve the callee saved regs.
|
|
"stmdb sp!, {r0, r1, r2, r3, lr}\n"
|
|
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
|
- "fstmfdd sp!, {d0, d1, d2, d3, d4, d5, d6, d7}\n"
|
|
+ "vstmdb sp!, {d0, d1, d2, d3, d4, d5, d6, d7}\n"
|
|
#endif
|
|
// The LR contains the address of the stub function on entry.
|
|
// pass it as the argument to the C part of the callback
|
|
@@ -85,7 +85,7 @@
|
|
//
|
|
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
|
// Restore VFP caller-saved registers.
|
|
- "fldmfdd sp!, {d0, d1, d2, d3, d4, d5, d6, d7}\n"
|
|
+ "vldmia sp!, {d0, d1, d2, d3, d4, d5, d6, d7}\n"
|
|
#endif
|
|
//
|
|
// We need to exchange the values in slots 0 and 1 so we can
|
|
Index: lib/Target/ARM/ARMInstrNEON.td
|
|
===================================================================
|
|
--- lib/Target/ARM/ARMInstrNEON.td (revision 152265)
|
|
+++ lib/Target/ARM/ARMInstrNEON.td (working copy)
|
|
@@ -4795,12 +4795,12 @@
|
|
|
|
// Vector Swap
|
|
def VSWPd : N2VX<0b11, 0b11, 0b00, 0b10, 0b00000, 0, 0,
|
|
- (outs DPR:$Vd, DPR:$Vd1), (ins DPR:$Vm, DPR:$Vm1),
|
|
- NoItinerary, "vswp", "$Vd, $Vd1", "$Vm = $Vd, $Vm1 = $Vd1",
|
|
+ (outs DPR:$Vd, DPR:$Vm), (ins DPR:$in1, DPR:$in2),
|
|
+ NoItinerary, "vswp", "$Vd, $Vm", "$in1 = $Vd, $in2 = $Vm",
|
|
[]>;
|
|
def VSWPq : N2VX<0b11, 0b11, 0b00, 0b10, 0b00000, 1, 0,
|
|
- (outs QPR:$Vd, QPR:$Vd1), (ins QPR:$Vm, QPR:$Vm1),
|
|
- NoItinerary, "vswp", "$Vd, $Vd1", "$Vm = $Vd, $Vm1 = $Vd1",
|
|
+ (outs QPR:$Vd, QPR:$Vm), (ins QPR:$in1, QPR:$in2),
|
|
+ NoItinerary, "vswp", "$Vd, $Vm", "$in1 = $Vd, $in2 = $Vm",
|
|
[]>;
|
|
|
|
// Vector Move Operations.
|
|
Index: lib/Target/ARM/ARMInstrVFP.td
|
|
===================================================================
|
|
--- lib/Target/ARM/ARMInstrVFP.td (revision 152265)
|
|
+++ lib/Target/ARM/ARMInstrVFP.td (working copy)
|
|
@@ -818,7 +818,29 @@
|
|
|
|
// FP to Fixed-Point:
|
|
|
|
-def VTOSHS : AVConv1XI<0b11101, 0b11, 0b1110, 0b1010, 0,
|
|
+// Single Precision register
|
|
+class AVConv1XInsS_Encode<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, bit op5,
|
|
+ dag oops, dag iops, InstrItinClass itin, string opc, string asm,
|
|
+ list<dag> pattern>
|
|
+ : AVConv1XI<op1, op2, op3, op4, op5, oops, iops, itin, opc, asm, pattern> {
|
|
+ bits<5> dst;
|
|
+ // if dp_operation then UInt(D:Vd) else UInt(Vd:D);
|
|
+ let Inst{22} = dst{0};
|
|
+ let Inst{15-12} = dst{4-1};
|
|
+}
|
|
+
|
|
+// Double Precision register
|
|
+class AVConv1XInsD_Encode<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, bit op5,
|
|
+ dag oops, dag iops, InstrItinClass itin, string opc, string asm,
|
|
+ list<dag> pattern>
|
|
+ : AVConv1XI<op1, op2, op3, op4, op5, oops, iops, itin, opc, asm, pattern> {
|
|
+ bits<5> dst;
|
|
+ // if dp_operation then UInt(D:Vd) else UInt(Vd:D);
|
|
+ let Inst{22} = dst{4};
|
|
+ let Inst{15-12} = dst{3-0};
|
|
+}
|
|
+
|
|
+def VTOSHS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1010, 0,
|
|
(outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
|
|
IIC_fpCVTSI, "vcvt", ".s16.f32\t$dst, $a, $fbits", []> {
|
|
// Some single precision VFP instructions may be executed on both NEON and
|
|
@@ -826,7 +848,7 @@
|
|
let D = VFPNeonA8Domain;
|
|
}
|
|
|
|
-def VTOUHS : AVConv1XI<0b11101, 0b11, 0b1111, 0b1010, 0,
|
|
+def VTOUHS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1010, 0,
|
|
(outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
|
|
IIC_fpCVTSI, "vcvt", ".u16.f32\t$dst, $a, $fbits", []> {
|
|
// Some single precision VFP instructions may be executed on both NEON and
|
|
@@ -834,7 +856,7 @@
|
|
let D = VFPNeonA8Domain;
|
|
}
|
|
|
|
-def VTOSLS : AVConv1XI<0b11101, 0b11, 0b1110, 0b1010, 1,
|
|
+def VTOSLS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1010, 1,
|
|
(outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
|
|
IIC_fpCVTSI, "vcvt", ".s32.f32\t$dst, $a, $fbits", []> {
|
|
// Some single precision VFP instructions may be executed on both NEON and
|
|
@@ -842,7 +864,7 @@
|
|
let D = VFPNeonA8Domain;
|
|
}
|
|
|
|
-def VTOULS : AVConv1XI<0b11101, 0b11, 0b1111, 0b1010, 1,
|
|
+def VTOULS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1010, 1,
|
|
(outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
|
|
IIC_fpCVTSI, "vcvt", ".u32.f32\t$dst, $a, $fbits", []> {
|
|
// Some single precision VFP instructions may be executed on both NEON and
|
|
@@ -850,25 +872,25 @@
|
|
let D = VFPNeonA8Domain;
|
|
}
|
|
|
|
-def VTOSHD : AVConv1XI<0b11101, 0b11, 0b1110, 0b1011, 0,
|
|
+def VTOSHD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1110, 0b1011, 0,
|
|
(outs DPR:$dst), (ins DPR:$a, fbits16:$fbits),
|
|
IIC_fpCVTDI, "vcvt", ".s16.f64\t$dst, $a, $fbits", []>;
|
|
|
|
-def VTOUHD : AVConv1XI<0b11101, 0b11, 0b1111, 0b1011, 0,
|
|
+def VTOUHD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1111, 0b1011, 0,
|
|
(outs DPR:$dst), (ins DPR:$a, fbits16:$fbits),
|
|
IIC_fpCVTDI, "vcvt", ".u16.f64\t$dst, $a, $fbits", []>;
|
|
|
|
-def VTOSLD : AVConv1XI<0b11101, 0b11, 0b1110, 0b1011, 1,
|
|
+def VTOSLD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1110, 0b1011, 1,
|
|
(outs DPR:$dst), (ins DPR:$a, fbits32:$fbits),
|
|
IIC_fpCVTDI, "vcvt", ".s32.f64\t$dst, $a, $fbits", []>;
|
|
|
|
-def VTOULD : AVConv1XI<0b11101, 0b11, 0b1111, 0b1011, 1,
|
|
+def VTOULD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1111, 0b1011, 1,
|
|
(outs DPR:$dst), (ins DPR:$a, fbits32:$fbits),
|
|
IIC_fpCVTDI, "vcvt", ".u32.f64\t$dst, $a, $fbits", []>;
|
|
|
|
// Fixed-Point to FP:
|
|
|
|
-def VSHTOS : AVConv1XI<0b11101, 0b11, 0b1010, 0b1010, 0,
|
|
+def VSHTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1010, 0,
|
|
(outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
|
|
IIC_fpCVTIS, "vcvt", ".f32.s16\t$dst, $a, $fbits", []> {
|
|
// Some single precision VFP instructions may be executed on both NEON and
|
|
@@ -876,7 +898,7 @@
|
|
let D = VFPNeonA8Domain;
|
|
}
|
|
|
|
-def VUHTOS : AVConv1XI<0b11101, 0b11, 0b1011, 0b1010, 0,
|
|
+def VUHTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1010, 0,
|
|
(outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
|
|
IIC_fpCVTIS, "vcvt", ".f32.u16\t$dst, $a, $fbits", []> {
|
|
// Some single precision VFP instructions may be executed on both NEON and
|
|
@@ -884,7 +906,7 @@
|
|
let D = VFPNeonA8Domain;
|
|
}
|
|
|
|
-def VSLTOS : AVConv1XI<0b11101, 0b11, 0b1010, 0b1010, 1,
|
|
+def VSLTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1010, 1,
|
|
(outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
|
|
IIC_fpCVTIS, "vcvt", ".f32.s32\t$dst, $a, $fbits", []> {
|
|
// Some single precision VFP instructions may be executed on both NEON and
|
|
@@ -892,7 +914,7 @@
|
|
let D = VFPNeonA8Domain;
|
|
}
|
|
|
|
-def VULTOS : AVConv1XI<0b11101, 0b11, 0b1011, 0b1010, 1,
|
|
+def VULTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1010, 1,
|
|
(outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
|
|
IIC_fpCVTIS, "vcvt", ".f32.u32\t$dst, $a, $fbits", []> {
|
|
// Some single precision VFP instructions may be executed on both NEON and
|
|
@@ -900,19 +922,19 @@
|
|
let D = VFPNeonA8Domain;
|
|
}
|
|
|
|
-def VSHTOD : AVConv1XI<0b11101, 0b11, 0b1010, 0b1011, 0,
|
|
+def VSHTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1010, 0b1011, 0,
|
|
(outs DPR:$dst), (ins DPR:$a, fbits16:$fbits),
|
|
IIC_fpCVTID, "vcvt", ".f64.s16\t$dst, $a, $fbits", []>;
|
|
|
|
-def VUHTOD : AVConv1XI<0b11101, 0b11, 0b1011, 0b1011, 0,
|
|
+def VUHTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1011, 0b1011, 0,
|
|
(outs DPR:$dst), (ins DPR:$a, fbits16:$fbits),
|
|
IIC_fpCVTID, "vcvt", ".f64.u16\t$dst, $a, $fbits", []>;
|
|
|
|
-def VSLTOD : AVConv1XI<0b11101, 0b11, 0b1010, 0b1011, 1,
|
|
+def VSLTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1010, 0b1011, 1,
|
|
(outs DPR:$dst), (ins DPR:$a, fbits32:$fbits),
|
|
IIC_fpCVTID, "vcvt", ".f64.s32\t$dst, $a, $fbits", []>;
|
|
|
|
-def VULTOD : AVConv1XI<0b11101, 0b11, 0b1011, 0b1011, 1,
|
|
+def VULTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1011, 0b1011, 1,
|
|
(outs DPR:$dst), (ins DPR:$a, fbits32:$fbits),
|
|
IIC_fpCVTID, "vcvt", ".f64.u32\t$dst, $a, $fbits", []>;
|
|
|
|
Index: lib/Target/ARM/ARMInstrThumb2.td
|
|
===================================================================
|
|
--- lib/Target/ARM/ARMInstrThumb2.td (revision 152265)
|
|
+++ lib/Target/ARM/ARMInstrThumb2.td (working copy)
|
|
@@ -3198,6 +3198,7 @@
|
|
let Inst{13} = target{17};
|
|
let Inst{21-16} = target{16-11};
|
|
let Inst{10-0} = target{10-0};
|
|
+ let DecoderMethod = "DecodeT2BInstruction";
|
|
}
|
|
|
|
let isNotDuplicable = 1, isIndirectBranch = 1 in {
|
|
Index: lib/Target/ARM/Disassembler/ARMDisassembler.cpp
|
|
===================================================================
|
|
--- lib/Target/ARM/Disassembler/ARMDisassembler.cpp (revision 152265)
|
|
+++ lib/Target/ARM/Disassembler/ARMDisassembler.cpp (working copy)
|
|
@@ -182,6 +182,8 @@
|
|
uint64_t Address, const void *Decoder);
|
|
static DecodeStatus DecodeAddrMode7Operand(llvm::MCInst &Inst, unsigned Val,
|
|
uint64_t Address, const void *Decoder);
|
|
+static DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
|
|
+ uint64_t Address, const void *Decoder);
|
|
static DecodeStatus DecodeBranchImmInstruction(llvm::MCInst &Inst,unsigned Insn,
|
|
uint64_t Address, const void *Decoder);
|
|
static DecodeStatus DecodeAddrMode6Operand(llvm::MCInst &Inst, unsigned Val,
|
|
@@ -1945,6 +1947,21 @@
|
|
}
|
|
|
|
static DecodeStatus
|
|
+DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
|
|
+ uint64_t Address, const void *Decoder) {
|
|
+ DecodeStatus S = MCDisassembler::Success;
|
|
+ unsigned imm = (fieldFromInstruction32(Insn, 0, 11) << 0) |
|
|
+ (fieldFromInstruction32(Insn, 11, 1) << 18) |
|
|
+ (fieldFromInstruction32(Insn, 13, 1) << 17) |
|
|
+ (fieldFromInstruction32(Insn, 16, 6) << 11) |
|
|
+ (fieldFromInstruction32(Insn, 26, 1) << 19);
|
|
+ if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<20>(imm<<1) + 4,
|
|
+ true, 4, Inst, Decoder))
|
|
+ Inst.addOperand(MCOperand::CreateImm(SignExtend32<20>(imm << 1)));
|
|
+ return S;
|
|
+}
|
|
+
|
|
+static DecodeStatus
|
|
DecodeBranchImmInstruction(llvm::MCInst &Inst, unsigned Insn,
|
|
uint64_t Address, const void *Decoder) {
|
|
DecodeStatus S = MCDisassembler::Success;
|
|
@@ -2177,6 +2194,8 @@
|
|
case ARM::VLD2b8wb_register:
|
|
case ARM::VLD2b16wb_register:
|
|
case ARM::VLD2b32wb_register:
|
|
+ Inst.addOperand(MCOperand::CreateImm(0));
|
|
+ break;
|
|
case ARM::VLD3d8_UPD:
|
|
case ARM::VLD3d16_UPD:
|
|
case ARM::VLD3d32_UPD:
|
|
@@ -2245,6 +2264,16 @@
|
|
!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
|
|
return MCDisassembler::Fail;
|
|
break;
|
|
+ case ARM::VLD2d8wb_fixed:
|
|
+ case ARM::VLD2d16wb_fixed:
|
|
+ case ARM::VLD2d32wb_fixed:
|
|
+ case ARM::VLD2b8wb_fixed:
|
|
+ case ARM::VLD2b16wb_fixed:
|
|
+ case ARM::VLD2b32wb_fixed:
|
|
+ case ARM::VLD2q8wb_fixed:
|
|
+ case ARM::VLD2q16wb_fixed:
|
|
+ case ARM::VLD2q32wb_fixed:
|
|
+ break;
|
|
}
|
|
|
|
return S;
|
|
@@ -2313,6 +2342,10 @@
|
|
case ARM::VST2b8wb_register:
|
|
case ARM::VST2b16wb_register:
|
|
case ARM::VST2b32wb_register:
|
|
+ if (Rm == 0xF)
|
|
+ return MCDisassembler::Fail;
|
|
+ Inst.addOperand(MCOperand::CreateImm(0));
|
|
+ break;
|
|
case ARM::VST3d8_UPD:
|
|
case ARM::VST3d16_UPD:
|
|
case ARM::VST3d32_UPD:
|
|
@@ -2354,6 +2387,23 @@
|
|
case ARM::VST1q16wb_fixed:
|
|
case ARM::VST1q32wb_fixed:
|
|
case ARM::VST1q64wb_fixed:
|
|
+ case ARM::VST1d8Twb_fixed:
|
|
+ case ARM::VST1d16Twb_fixed:
|
|
+ case ARM::VST1d32Twb_fixed:
|
|
+ case ARM::VST1d64Twb_fixed:
|
|
+ case ARM::VST1d8Qwb_fixed:
|
|
+ case ARM::VST1d16Qwb_fixed:
|
|
+ case ARM::VST1d32Qwb_fixed:
|
|
+ case ARM::VST1d64Qwb_fixed:
|
|
+ case ARM::VST2d8wb_fixed:
|
|
+ case ARM::VST2d16wb_fixed:
|
|
+ case ARM::VST2d32wb_fixed:
|
|
+ case ARM::VST2q8wb_fixed:
|
|
+ case ARM::VST2q16wb_fixed:
|
|
+ case ARM::VST2q32wb_fixed:
|
|
+ case ARM::VST2b8wb_fixed:
|
|
+ case ARM::VST2b16wb_fixed:
|
|
+ case ARM::VST2b32wb_fixed:
|
|
break;
|
|
}
|
|
|
|
@@ -2555,7 +2605,6 @@
|
|
unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
|
|
unsigned align = fieldFromInstruction32(Insn, 4, 1);
|
|
unsigned size = 1 << fieldFromInstruction32(Insn, 6, 2);
|
|
- unsigned pred = fieldFromInstruction32(Insn, 22, 4);
|
|
align *= 2*size;
|
|
|
|
switch (Inst.getOpcode()) {
|
|
@@ -2586,16 +2635,11 @@
|
|
return MCDisassembler::Fail;
|
|
Inst.addOperand(MCOperand::CreateImm(align));
|
|
|
|
- if (Rm == 0xD)
|
|
- Inst.addOperand(MCOperand::CreateReg(0));
|
|
- else if (Rm != 0xF) {
|
|
+ if (Rm != 0xD && Rm != 0xF) {
|
|
if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
|
|
return MCDisassembler::Fail;
|
|
}
|
|
|
|
- if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
|
|
- return MCDisassembler::Fail;
|
|
-
|
|
return S;
|
|
}
|
|
|
|
@@ -2837,19 +2881,25 @@
|
|
|
|
static DecodeStatus DecodeThumbBROperand(llvm::MCInst &Inst, unsigned Val,
|
|
uint64_t Address, const void *Decoder) {
|
|
- Inst.addOperand(MCOperand::CreateImm(SignExtend32<12>(Val << 1)));
|
|
+ if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<12>(Val<<1) + 4,
|
|
+ true, 2, Inst, Decoder))
|
|
+ Inst.addOperand(MCOperand::CreateImm(SignExtend32<12>(Val << 1)));
|
|
return MCDisassembler::Success;
|
|
}
|
|
|
|
static DecodeStatus DecodeT2BROperand(llvm::MCInst &Inst, unsigned Val,
|
|
uint64_t Address, const void *Decoder) {
|
|
- Inst.addOperand(MCOperand::CreateImm(SignExtend32<21>(Val)));
|
|
+ if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<22>(Val<<1) + 4,
|
|
+ true, 4, Inst, Decoder))
|
|
+ Inst.addOperand(MCOperand::CreateImm(SignExtend32<21>(Val)));
|
|
return MCDisassembler::Success;
|
|
}
|
|
|
|
static DecodeStatus DecodeThumbCmpBROperand(llvm::MCInst &Inst, unsigned Val,
|
|
uint64_t Address, const void *Decoder) {
|
|
- Inst.addOperand(MCOperand::CreateImm(SignExtend32<7>(Val << 1)));
|
|
+ if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<7>(Val<<1) + 4,
|
|
+ true, 2, Inst, Decoder))
|
|
+ Inst.addOperand(MCOperand::CreateImm(SignExtend32<7>(Val << 1)));
|
|
return MCDisassembler::Success;
|
|
}
|
|
|
|
@@ -3271,7 +3321,9 @@
|
|
static DecodeStatus
|
|
DecodeThumbBCCTargetOperand(llvm::MCInst &Inst, unsigned Val,
|
|
uint64_t Address, const void *Decoder){
|
|
- Inst.addOperand(MCOperand::CreateImm(Val << 1));
|
|
+ if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<8>(Val<<1) + 4,
|
|
+ true, 2, Inst, Decoder))
|
|
+ Inst.addOperand(MCOperand::CreateImm(SignExtend32<8>(Val << 1)));
|
|
return MCDisassembler::Success;
|
|
}
|
|
|