diff options
Diffstat (limited to 'lib/Target/ARM/AsmParser/ARMAsmParser.cpp')
| -rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 51 | 
1 files changed, 31 insertions, 20 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 807d625473377..a5fbbbf26be98 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -969,7 +969,7 @@ public:    // checks whether this operand is a memory operand computed as an offset    // applied to PC. the offset may have 8 bits of magnitude and is represented -  // with two bits of shift. textually it may be either [pc, #imm], #imm or  +  // with two bits of shift. textually it may be either [pc, #imm], #imm or    // relocable expression...    bool isThumbMemPC() const {      int64_t Val = 0; @@ -2284,7 +2284,7 @@ public:        }        const MCSymbolRefExpr *SR = dyn_cast<MCSymbolRefExpr>(Imm.Val); -  +        assert(SR && "Unknown value type!");        Inst.addOperand(MCOperand::createExpr(SR));        return; @@ -2326,7 +2326,7 @@ public:      assert(isImm() && "Not an immediate!");      // If we have an immediate that's not a constant, treat it as a label -    // reference needing a fixup.  +    // reference needing a fixup.      if (!isa<MCConstantExpr>(getImm())) {        Inst.addOperand(MCOperand::createExpr(getImm()));        return; @@ -3419,7 +3419,7 @@ int ARMAsmParser::tryParseShiftRegister(OperandVector &Operands) {    SMLoc S = Parser.getTok().getLoc();    const AsmToken &Tok = Parser.getTok();    if (Tok.isNot(AsmToken::Identifier)) -    return -1;  +    return -1;    std::string lowerCase = Tok.getString().lower();    ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) @@ -4311,7 +4311,7 @@ ARMAsmParser::parseProcIFlagsOperand(OperandVector &Operands) {    MCAsmParser &Parser = getParser();    SMLoc S = Parser.getTok().getLoc();    const AsmToken &Tok = Parser.getTok(); -  if (!Tok.is(AsmToken::Identifier))  +  if (!Tok.is(AsmToken::Identifier))      return MatchOperand_NoMatch;    StringRef IFlagsStr = Tok.getString(); @@ -4353,7 +4353,7 @@ ARMAsmParser::parseMSRMaskOperand(OperandVector &Operands) {        return MatchOperand_NoMatch;      }      unsigned SYSmvalue = Val & 0xFF; -    Parser.Lex();  +    Parser.Lex();      Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S));      return MatchOperand_Success;    } @@ -4996,7 +4996,7 @@ void ARMAsmParser::cvtThumbBranches(MCInst &Inst,    // first decide whether or not the branch should be conditional    // by looking at it's location relative to an IT block    if(inITBlock()) { -    // inside an IT block we cannot have any conditional branches. any  +    // inside an IT block we cannot have any conditional branches. any      // such instructions needs to be converted to unconditional form      switch(Inst.getOpcode()) {        case ARM::tBcc: Inst.setOpcode(ARM::tB); break; @@ -5008,11 +5008,11 @@ void ARMAsmParser::cvtThumbBranches(MCInst &Inst,      unsigned Cond = static_cast<ARMOperand &>(*Operands[CondOp]).getCondCode();      switch(Inst.getOpcode()) {        case ARM::tB: -      case ARM::tBcc:  -        Inst.setOpcode(Cond == ARMCC::AL ? ARM::tB : ARM::tBcc);  +      case ARM::tBcc: +        Inst.setOpcode(Cond == ARMCC::AL ? ARM::tB : ARM::tBcc);          break;        case ARM::t2B: -      case ARM::t2Bcc:  +      case ARM::t2Bcc:          Inst.setOpcode(Cond == ARMCC::AL ? ARM::t2B : ARM::t2Bcc);          break;      } @@ -8882,7 +8882,7 @@ bool ARMAsmParser::processInstruction(MCInst &Inst,    case ARM::MOVsi: {      ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm());      // rrx shifts and asr/lsr of #32 is encoded as 0 -    if (SOpc == ARM_AM::rrx || SOpc == ARM_AM::asr || SOpc == ARM_AM::lsr)  +    if (SOpc == ARM_AM::rrx || SOpc == ARM_AM::asr || SOpc == ARM_AM::lsr)        return false;      if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) {        // Shifting by zero is accepted as a vanilla 'MOVr' @@ -9371,6 +9371,12 @@ bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {      return parseDirectiveAlign(DirectiveID.getLoc()); // Use Generic on failure.    else if (IDVal == ".thumb_set")      parseDirectiveThumbSet(DirectiveID.getLoc()); +  else if (IDVal == ".inst") +    parseDirectiveInst(DirectiveID.getLoc()); +  else if (IDVal == ".inst.n") +    parseDirectiveInst(DirectiveID.getLoc(), 'n'); +  else if (IDVal == ".inst.w") +    parseDirectiveInst(DirectiveID.getLoc(), 'w');    else if (!IsMachO && !IsCOFF) {      if (IDVal == ".arch")        parseDirectiveArch(DirectiveID.getLoc()); @@ -9382,12 +9388,6 @@ bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {        parseDirectiveFPU(DirectiveID.getLoc());      else if (IDVal == ".fnstart")        parseDirectiveFnStart(DirectiveID.getLoc()); -    else if (IDVal == ".inst") -      parseDirectiveInst(DirectiveID.getLoc()); -    else if (IDVal == ".inst.n") -      parseDirectiveInst(DirectiveID.getLoc(), 'n'); -    else if (IDVal == ".inst.w") -      parseDirectiveInst(DirectiveID.getLoc(), 'w');      else if (IDVal == ".object_arch")        parseDirectiveObjectArch(DirectiveID.getLoc());      else if (IDVal == ".tlsdescseq") @@ -10012,8 +10012,8 @@ bool ARMAsmParser::parseDirectiveInst(SMLoc Loc, char Suffix) {      case 'w':        break;      default: -      return Error(Loc, "cannot determine Thumb instruction size, " -                        "use inst.n/inst.w instead"); +      Width = 0; +      break;      }    } else {      if (Suffix) @@ -10029,6 +10029,7 @@ bool ARMAsmParser::parseDirectiveInst(SMLoc Loc, char Suffix) {        return Error(Loc, "expected constant expression");      } +    char CurSuffix = Suffix;      switch (Width) {      case 2:        if (Value->getValue() > 0xffff) @@ -10039,11 +10040,21 @@ bool ARMAsmParser::parseDirectiveInst(SMLoc Loc, char Suffix) {          return Error(Loc, StringRef(Suffix ? "inst.w" : "inst") +                                " operand is too big");        break; +    case 0: +      // Thumb mode, no width indicated. Guess from the opcode, if possible. +      if (Value->getValue() < 0xe800) +        CurSuffix = 'n'; +      else if (Value->getValue() >= 0xe8000000) +        CurSuffix = 'w'; +      else +        return Error(Loc, "cannot determine Thumb instruction size, " +                          "use inst.n/inst.w instead"); +      break;      default:        llvm_unreachable("only supported widths are 2 and 4");      } -    getTargetStreamer().emitInst(Value->getValue(), Suffix); +    getTargetStreamer().emitInst(Value->getValue(), CurSuffix);      return false;    };  | 
