diff options
| author | Tim Northover <tnorthover@apple.com> | 2019-04-23 13:50:13 +0000 | 
|---|---|---|
| committer | Tim Northover <tnorthover@apple.com> | 2019-04-23 13:50:13 +0000 | 
| commit | 6af366be8ad3199f715c54e84c779e02bb8c18b8 (patch) | |
| tree | cac009ac0d69d139c87e571135751e2ded6aeb92 /llvm/lib/Target/ARM | |
| parent | a6be919c9298c3a62e415bd9fac1ad32229be526 (diff) | |
| download | bcm5719-llvm-6af366be8ad3199f715c54e84c779e02bb8c18b8.tar.gz bcm5719-llvm-6af366be8ad3199f715c54e84c779e02bb8c18b8.zip | |
ARM: disallow add/sub to sp unless Rn is also sp.
The manual says that Thumb2 add/sub instructions are only allowed to modify sp
if the first source is also sp. This is slightly different from the usual rGPR
restriction since it's context-sensitive, so implement it in C++.
llvm-svn: 358987
Diffstat (limited to 'llvm/lib/Target/ARM')
| -rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 14 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 14 | 
2 files changed, 27 insertions, 1 deletions
| diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 65c6a566c04..9bc232a09ae 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -6792,6 +6792,20 @@ bool ARMAsmParser::validateInstruction(MCInst &Inst,      }      break; +  case ARM::t2ADDri: +  case ARM::t2ADDri12: +  case ARM::t2ADDrr: +  case ARM::t2ADDrs: +  case ARM::t2SUBri: +  case ARM::t2SUBri12: +  case ARM::t2SUBrr: +  case ARM::t2SUBrs: +    if (Inst.getOperand(0).getReg() == ARM::SP && +        Inst.getOperand(1).getReg() != ARM::SP) +      return Error(Operands[4]->getStartLoc(), +                   "source register must be sp if destination is sp"); +    break; +    // Final range checking for Thumb unconditional branch instructions.    case ARM::tB:      if (!(static_cast<ARMOperand &>(*Operands[2])).isSignedOffset<11, 1>()) diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index e92bcc5ba51..7a8d9b05c8c 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -441,6 +441,18 @@ static DecodeStatus checkDecodedInstruction(MCInst &MI, uint64_t &Size,          return MCDisassembler::SoftFail;        return Result;      } +    case ARM::t2ADDri: +    case ARM::t2ADDri12: +    case ARM::t2ADDrr: +    case ARM::t2ADDrs: +    case ARM::t2SUBri: +    case ARM::t2SUBri12: +    case ARM::t2SUBrr: +    case ARM::t2SUBrs: +      if (MI.getOperand(0).getReg() == ARM::SP && +          MI.getOperand(1).getReg() != ARM::SP) +        return MCDisassembler::SoftFail; +      return Result;      default: return Result;    }  } @@ -772,7 +784,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,    if (Result != MCDisassembler::Fail) {      Size = 4;      Check(Result, AddThumbPredicate(MI)); -    return Result; +    return checkDecodedInstruction(MI, Size, Address, OS, CS, Insn32, Result);    }    if (fieldFromInstruction(Insn32, 28, 4) == 0xE) { | 

