diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp | 22 | 
1 files changed, 19 insertions, 3 deletions
diff --git a/llvm/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp b/llvm/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp index 6a8310e8f28..ee9c61e5285 100644 --- a/llvm/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp +++ b/llvm/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp @@ -4196,9 +4196,8 @@ bool ARM64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,        delete Op;      }    } -  // FIXME: Likewise for [su]xt[bh] with a Xd dst operand -  else if (NumOperands == 3 && -           (Tok == "sxtb" || Tok == "uxtb" || Tok == "sxth" || Tok == "uxth")) { +  // FIXME: Likewise for sxt[bh] with a Xd dst operand +  else if (NumOperands == 3 && (Tok == "sxtb" || Tok == "sxth")) {      ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[1]);      if (Op->isReg() &&          ARM64MCRegisterClasses[ARM64::GPR64allRegClassID].contains( @@ -4214,6 +4213,23 @@ bool ARM64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,        }      }    } +  // FIXME: Likewise for uxt[bh] with a Xd dst operand +  else if (NumOperands == 3 && (Tok == "uxtb" || Tok == "uxth")) { +    ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[1]); +    if (Op->isReg() && +        ARM64MCRegisterClasses[ARM64::GPR64allRegClassID].contains( +            Op->getReg())) { +      // The source register can be Wn here, but the matcher expects a +      // GPR32. Twiddle it here if necessary. +      ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[1]); +      if (Op->isReg()) { +        unsigned Reg = getWRegFromXReg(Op->getReg()); +        Operands[1] = ARM64Operand::CreateReg(Reg, false, Op->getStartLoc(), +                                              Op->getEndLoc(), getContext()); +        delete Op; +      } +    } +  }    // Yet another horrible hack to handle FMOV Rd, #0.0 using [WX]ZR.    if (NumOperands == 3 && Tok == "fmov") {  | 

