diff options
Diffstat (limited to 'llvm/lib/Target/ARM')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrVFP.td | 76 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 6 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 24 |
3 files changed, 71 insertions, 35 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrVFP.td b/llvm/lib/Target/ARM/ARMInstrVFP.td index b43216fb5c5..0549a198b5b 100644 --- a/llvm/lib/Target/ARM/ARMInstrVFP.td +++ b/llvm/lib/Target/ARM/ARMInstrVFP.td @@ -2164,28 +2164,32 @@ let Defs = [CPSR], Uses = [FPSCR_NZCV], Rt = 0b1111 /* apsr_nzcv */ in def FMSTAT : MovFromVFP<0b0001 /* fpscr */, (outs), (ins), "vmrs", "\tAPSR_nzcv, fpscr", [(arm_fmstat)]>; -// Application level FPSCR -> GPR -let hasSideEffects = 1, Uses = [FPSCR] in -def VMRS : MovFromVFP<0b0001 /* fpscr */, (outs GPR:$Rt), (ins), - "vmrs", "\t$Rt, fpscr", - [(set GPR:$Rt, (int_arm_get_fpscr))]>; - -// System level FPEXC, FPSID -> GPR -let Uses = [FPSCR] in { - def VMRS_FPEXC : MovFromVFP<0b1000 /* fpexc */, (outs GPR:$Rt), (ins), - "vmrs", "\t$Rt, fpexc", []>; - def VMRS_FPSID : MovFromVFP<0b0000 /* fpsid */, (outs GPR:$Rt), (ins), - "vmrs", "\t$Rt, fpsid", []>; - def VMRS_MVFR0 : MovFromVFP<0b0111 /* mvfr0 */, (outs GPR:$Rt), (ins), +let DecoderMethod = "DecodeForVMRSandVMSR" in { + // Application level FPSCR -> GPR + let hasSideEffects = 1, Uses = [FPSCR] in + def VMRS : MovFromVFP<0b0001 /* fpscr */, (outs GPRnopc:$Rt), (ins), + "vmrs", "\t$Rt, fpscr", + [(set GPRnopc:$Rt, (int_arm_get_fpscr))]>; + + // System level FPEXC, FPSID -> GPR + let Uses = [FPSCR] in { + def VMRS_FPEXC : MovFromVFP<0b1000 /* fpexc */, (outs GPRnopc:$Rt), (ins), + "vmrs", "\t$Rt, fpexc", []>; + def VMRS_FPSID : MovFromVFP<0b0000 /* fpsid */, (outs GPRnopc:$Rt), (ins), + "vmrs", "\t$Rt, fpsid", []>; + def VMRS_MVFR0 : MovFromVFP<0b0111 /* mvfr0 */, (outs GPRnopc:$Rt), (ins), "vmrs", "\t$Rt, mvfr0", []>; - def VMRS_MVFR1 : MovFromVFP<0b0110 /* mvfr1 */, (outs GPR:$Rt), (ins), - "vmrs", "\t$Rt, mvfr1", []>; - def VMRS_MVFR2 : MovFromVFP<0b0101 /* mvfr2 */, (outs GPR:$Rt), (ins), - "vmrs", "\t$Rt, mvfr2", []>, Requires<[HasFPARMv8]>; - def VMRS_FPINST : MovFromVFP<0b1001 /* fpinst */, (outs GPR:$Rt), (ins), - "vmrs", "\t$Rt, fpinst", []>; - def VMRS_FPINST2 : MovFromVFP<0b1010 /* fpinst2 */, (outs GPR:$Rt), (ins), - "vmrs", "\t$Rt, fpinst2", []>; + def VMRS_MVFR1 : MovFromVFP<0b0110 /* mvfr1 */, (outs GPRnopc:$Rt), (ins), + "vmrs", "\t$Rt, mvfr1", []>; + let Predicates = [HasFPARMv8] in { + def VMRS_MVFR2 : MovFromVFP<0b0101 /* mvfr2 */, (outs GPRnopc:$Rt), (ins), + "vmrs", "\t$Rt, mvfr2", []>; + } + def VMRS_FPINST : MovFromVFP<0b1001 /* fpinst */, (outs GPRnopc:$Rt), (ins), + "vmrs", "\t$Rt, fpinst", []>; + def VMRS_FPINST2 : MovFromVFP<0b1010 /* fpinst2 */, (outs GPRnopc:$Rt), + (ins), "vmrs", "\t$Rt, fpinst2", []>; + } } //===----------------------------------------------------------------------===// @@ -2209,21 +2213,23 @@ class MovToVFP<bits<4> opc19_16, dag oops, dag iops, string opc, string asm, let Inst{4} = 1; } -let Defs = [FPSCR] in { - // Application level GPR -> FPSCR - def VMSR : MovToVFP<0b0001 /* fpscr */, (outs), (ins GPR:$src), - "vmsr", "\tfpscr, $src", [(int_arm_set_fpscr GPR:$src)]>; - // System level GPR -> FPEXC - def VMSR_FPEXC : MovToVFP<0b1000 /* fpexc */, (outs), (ins GPR:$src), - "vmsr", "\tfpexc, $src", []>; - // System level GPR -> FPSID - def VMSR_FPSID : MovToVFP<0b0000 /* fpsid */, (outs), (ins GPR:$src), - "vmsr", "\tfpsid, $src", []>; - - def VMSR_FPINST : MovToVFP<0b1001 /* fpinst */, (outs), (ins GPR:$src), +let DecoderMethod = "DecodeForVMRSandVMSR" in { + let Defs = [FPSCR] in { + // Application level GPR -> FPSCR + def VMSR : MovToVFP<0b0001 /* fpscr */, (outs), (ins GPRnopc:$src), + "vmsr", "\tfpscr, $src", + [(int_arm_set_fpscr GPRnopc:$src)]>; + // System level GPR -> FPEXC + def VMSR_FPEXC : MovToVFP<0b1000 /* fpexc */, (outs), (ins GPRnopc:$src), + "vmsr", "\tfpexc, $src", []>; + // System level GPR -> FPSID + def VMSR_FPSID : MovToVFP<0b0000 /* fpsid */, (outs), (ins GPRnopc:$src), + "vmsr", "\tfpsid, $src", []>; + def VMSR_FPINST : MovToVFP<0b1001 /* fpinst */, (outs), (ins GPRnopc:$src), "vmsr", "\tfpinst, $src", []>; - def VMSR_FPINST2 : MovToVFP<0b1010 /* fpinst2 */, (outs), (ins GPR:$src), - "vmsr", "\tfpinst2, $src", []>; + def VMSR_FPINST2 : MovToVFP<0b1010 /* fpinst2 */, (outs), (ins GPRnopc:$src), + "vmsr", "\tfpinst2, $src", []>; + } } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 4b10874481d..287ed20988f 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -8805,6 +8805,12 @@ unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { return Match_RequiresV8; } + // Use of SP for VMRS/VMSR is only allowed in ARM mode with the exception of + // ARMv8-A. + if ((Inst.getOpcode() == ARM::VMRS || Inst.getOpcode() == ARM::VMSR) && + Inst.getOperand(0).getReg() == ARM::SP && (isThumb() && !hasV8Ops())) + return Match_InvalidOperand; + for (unsigned I = 0; I < MCID.NumOperands; ++I) if (MCID.OpInfo[I].RegClass == ARM::rGPRRegClassID) { // rGPRRegClass excludes PC, and also excluded SP before ARMv8 diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index e8bfa6b2a8c..e3854989c4f 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -400,6 +400,8 @@ static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); static DecodeStatus DecoderForMRRC2AndMCRR2(MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeForVMRSandVMSR(MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder); #include "ARMGenDisassemblerTables.inc" @@ -5284,3 +5286,25 @@ static DecodeStatus DecoderForMRRC2AndMCRR2(MCInst &Inst, unsigned Val, return S; } + +static DecodeStatus DecodeForVMRSandVMSR(MCInst &Inst, unsigned Val, + uint64_t Address, + const void *Decoder) { + const FeatureBitset &featureBits = + ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits(); + DecodeStatus S = MCDisassembler::Success; + + unsigned Rt = fieldFromInstruction(Val, 12, 4); + + if (featureBits[ARM::ModeThumb] && !featureBits[ARM::HasV8Ops]) { + if (Rt == 13 || Rt == 15) + S = MCDisassembler::SoftFail; + Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)); + } else + Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)); + + Inst.addOperand(MCOperand::createImm(ARMCC::AL)); + Inst.addOperand(MCOperand::createReg(0)); + + return S; +} |

