Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -508,6 +508,10 @@ /// Coerce the register to GPR32 and return the real register for the current /// target. unsigned getGPR32Reg() const { + // As a special case, immediate zero is also register zero. + if (isConstantImm() && getConstantImm() == 0) + return Mips::ZERO; + assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc); unsigned ClassID = Mips::GPR32RegClassID; @@ -517,6 +521,10 @@ /// Coerce the register to GPR32 and return the real register for the current /// target. unsigned getGPRMM16Reg() const { + // As a special case, immediate zero is also register zero. + if (isConstantImm() && getConstantImm() == 0) + return Mips::ZERO; + assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); unsigned ClassID = Mips::GPR32RegClassID; return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); @@ -525,6 +533,10 @@ /// Coerce the register to GPR64 and return the real register for the current /// target. unsigned getGPR64Reg() const { + // As a special case, immediate zero is also register zero. + if (isConstantImm() && getConstantImm() == 0) + return Mips::ZERO_64; + assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); unsigned ClassID = Mips::GPR64RegClassID; return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); @@ -806,6 +818,10 @@ if (isGPRAsmReg() && RegIdx.Index == 0) return true; + // As another special case, immediate zero is also register zero. + if (isConstantImm() && getConstantImm() == 0) + return true; + return Kind == k_PhysRegister; } bool isRegIdx() const { return Kind == k_RegisterIndex; } @@ -878,6 +894,13 @@ RegIdx.Kind & RegKind_GPR) return getGPR32Reg(); // FIXME: GPR64 too + // As another special case, immediate zero is also register zero. + // FIXME: We ought to handle the GPR64 case properly but MipsOperand + // doesn't know the subtarget and the assembler doesn't need + // that much precision anyway. + if (isConstantImm() && getConstantImm() == 0) + return Mips::ZERO; + assert(Kind == k_PhysRegister && "Invalid access!"); return PhysReg.Num; } @@ -1035,6 +1058,10 @@ } bool isGPRAsmReg() const { + // As a special case, immediate zero is also register zero. + if (isConstantImm() && getConstantImm() == 0) + return true; + return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31; } bool isMM16AsmReg() const { Index: test/MC/Mips/zero.s =================================================================== --- /dev/null +++ test/MC/Mips/zero.s @@ -0,0 +1,7 @@ +// RUN: llvm-mc -arch=mips -show-encoding %s -o - | FileCheck %s + + .text + bne $2, $0, foo # CHECK: bnez $2, foo # encoding: [0x14,0x40,A,A] + bne $2, $zero, foo # CHECK: bnez $2, foo # encoding: [0x14,0x40,A,A] + bne $2, 0, foo # CHECK: bnez $2, foo # encoding: [0x14,0x40,A,A] +foo: