diff --git a/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp index f99a3aa6634..ae24c8a88e6 100644 --- a/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp +++ b/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp @@ -432,9 +432,23 @@ public: bool isS17Imm() const { return Kind == Expression || (Kind == Immediate && isInt<17>(getImm())); } bool isTLSReg() const { return Kind == TLSRegister; } - bool isDirectBr() const { return Kind == Expression || - (Kind == Immediate && isInt<26>(getImm()) && - (getImm() & 3) == 0); } + bool isDirectBr() const { + if (Kind == Expression) + return true; + if (Kind != Immediate) + return false; + // Operand must be 64-bit aligned, signed 27-bit immediate. + if ((getImm() & 3) != 0) + return false; + if (isInt<26>(getImm())) + return true; + if (!IsPPC64) { + // In 32-bit mode, large 32-bit quantities wrap around. + if (isUInt<32>(getImm()) && isInt<26>(static_cast(getImm()))) + return true; + } + return false; + } bool isCondBr() const { return Kind == Expression || (Kind == Immediate && isInt<16>(getImm()) && (getImm() & 3) == 0); } diff --git a/test/MC/PowerPC/ppc32-ba.s b/test/MC/PowerPC/ppc32-ba.s new file mode 100644 index 00000000000..133423b4e8c --- /dev/null +++ b/test/MC/PowerPC/ppc32-ba.s @@ -0,0 +1,6 @@ +# RUN: llvm-mc -triple powerpc-unknown-unknown --show-encoding %s | FileCheck %s + +# Check that large immediates in 32bit mode are accepted. + +# CHECK: ba -33554432 # encoding: [0x4a,0x00,0x00,0x02] + ba 0xfe000000