Index: lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64InstrInfo.td +++ lib/Target/Mips/Mips64InstrInfo.td @@ -245,16 +245,12 @@ "sll\t$rd, $rt, 0", [], II_SLL>; } -// We need the following two pseudo instructions to avoid offset calculation for +// We need the following pseudo instruction to avoid offset calculation for // long branches. See the comment in file MipsLongBranch.cpp for detailed // explanation. -// Expands to: lui $dst, %highest($tgt - $baltgt) -def LONG_BRANCH_LUi64 : PseudoSE<(outs GPR64Opnd:$dst), - (ins brtarget:$tgt, brtarget:$baltgt), []>; - // Expands to: daddiu $dst, $src, %PART($tgt - $baltgt) -// where %PART may be %higher, %hi or %lo, depending on the relocation kind +// where %PART may be %hi or %lo, depending on the relocation kind // that $tgt is annotated with. def LONG_BRANCH_DADDiu : PseudoSE<(outs GPR64Opnd:$dst), (ins GPR64Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>; Index: lib/Target/Mips/MipsAsmPrinter.cpp =================================================================== --- lib/Target/Mips/MipsAsmPrinter.cpp +++ lib/Target/Mips/MipsAsmPrinter.cpp @@ -958,7 +958,6 @@ bool MipsAsmPrinter::isLongBranchPseudo(int Opcode) const { return (Opcode == Mips::LONG_BRANCH_LUi || Opcode == Mips::LONG_BRANCH_ADDiu - || Opcode == Mips::LONG_BRANCH_LUi64 || Opcode == Mips::LONG_BRANCH_DADDiu); } Index: lib/Target/Mips/MipsLongBranch.cpp =================================================================== --- lib/Target/Mips/MipsLongBranch.cpp +++ lib/Target/Mips/MipsLongBranch.cpp @@ -64,7 +64,7 @@ : MachineFunctionPass(ID), TM(tm), IsPIC(TM.getRelocationModel() == Reloc::PIC_), ABI(TM.getSubtarget().getTargetABI()), - LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 13 : 9)) {} + LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 10 : 9)) {} const char *getPassName() const override { return "Mips Long Branch"; @@ -324,10 +324,7 @@ // $longbr: // daddiu $sp, $sp, -16 // sd $ra, 0($sp) - // lui64 $at, %highest($tgt - $baltgt) - // daddiu $at, $at, %higher($tgt - $baltgt) - // dsll $at, $at, 16 - // daddiu $at, $at, %hi($tgt - $baltgt) + // daddiu $at, $zero, %hi($tgt - $baltgt) // dsll $at, $at, 16 // bal $baltgt // daddiu $at, $at, %lo($tgt - $baltgt) @@ -339,10 +336,20 @@ // $fallthrough: // - // TODO: %highest and %higher can have non-zero values only when the - // offset is greater than 4GB, which is highly unlikely. Replace - // them (and the following instructon that shifts $at by 16) with the - // instruction that sets $at to zero. + // We assume the branch is within-function, and that offset is within + // +/- 2GB. High 32 bits will therefore always be zero. + + // Note that this will work even if the offset is negative, because + // of the +1 modification that's added in that case. For example, if the + // offset is -1MB (0xFFFFFFFFFFF00000), the computation for %higher is + // + // 0xFFFFFFFFFFF00000 + 0x80008000 = 0x000000007FF08000 + // + // and the bits [47:32] are zero. For %highest + // + // 0xFFFFFFFFFFF00000 + 0x800080008000 = 0x000080007FF08000 + // + // and the bits [63:48] are zero. Pos = LongBrMBB->begin(); @@ -350,16 +357,9 @@ .addReg(Mips::SP_64).addImm(-16); BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SD)).addReg(Mips::RA_64) .addReg(Mips::SP_64).addImm(0); - BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi64), - Mips::AT_64).addMBB(TgtMBB).addMBB(BalTgtMBB); - BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu), - Mips::AT_64).addReg(Mips::AT_64).addMBB(TgtMBB, MipsII::MO_HIGHER) - .addMBB(BalTgtMBB); - BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64) - .addReg(Mips::AT_64).addImm(16); BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu), - Mips::AT_64).addReg(Mips::AT_64).addMBB(TgtMBB, MipsII::MO_ABS_HI) - .addMBB(BalTgtMBB); + Mips::AT_64).addReg(Mips::ZERO_64) + .addMBB(TgtMBB, MipsII::MO_ABS_HI).addMBB(BalTgtMBB); BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64) .addReg(Mips::AT_64).addImm(16); Index: lib/Target/Mips/MipsMCInstLower.h =================================================================== --- lib/Target/Mips/MipsMCInstLower.h +++ lib/Target/Mips/MipsMCInstLower.h @@ -39,8 +39,7 @@ MachineOperandType MOTy, unsigned Offset) const; MCOperand createSub(MachineBasicBlock *BB1, MachineBasicBlock *BB2, MCSymbolRefExpr::VariantKind Kind) const; - void lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI, - int Opcode, MCSymbolRefExpr::VariantKind Kind) const; + void lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const; void lowerLongBranchADDiu(const MachineInstr *MI, MCInst &OutMI, int Opcode, MCSymbolRefExpr::VariantKind Kind) const; Index: lib/Target/Mips/MipsMCInstLower.cpp =================================================================== --- lib/Target/Mips/MipsMCInstLower.cpp +++ lib/Target/Mips/MipsMCInstLower.cpp @@ -162,16 +162,16 @@ } void MipsMCInstLower:: -lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI, int Opcode, - MCSymbolRefExpr::VariantKind Kind) const { - OutMI.setOpcode(Opcode); +lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const { + OutMI.setOpcode(Mips::LUi); // Lower register operand. OutMI.addOperand(LowerOperand(MI->getOperand(0))); - // Create %hi($tgt-$baltgt) or %highest($tgt-$baltgt). + // Create %hi($tgt-$baltgt). OutMI.addOperand(createSub(MI->getOperand(1).getMBB(), - MI->getOperand(2).getMBB(), Kind)); + MI->getOperand(2).getMBB(), + MCSymbolRefExpr::VK_Mips_ABS_HI)); } void MipsMCInstLower:: @@ -185,7 +185,7 @@ OutMI.addOperand(LowerOperand(MO)); } - // Create %lo($tgt-$baltgt), %hi($tgt-$baltgt) or %higher($tgt-$baltgt). + // Create %lo($tgt-$baltgt) or %hi($tgt-$baltgt). OutMI.addOperand(createSub(MI->getOperand(2).getMBB(), MI->getOperand(3).getMBB(), Kind)); } @@ -196,11 +196,7 @@ default: return false; case Mips::LONG_BRANCH_LUi: - lowerLongBranchLUi(MI, OutMI, Mips::LUi, MCSymbolRefExpr::VK_Mips_ABS_HI); - return true; - case Mips::LONG_BRANCH_LUi64: - lowerLongBranchLUi(MI, OutMI, Mips::LUi64, - MCSymbolRefExpr::VK_Mips_HIGHEST); + lowerLongBranchLUi(MI, OutMI); return true; case Mips::LONG_BRANCH_ADDiu: lowerLongBranchADDiu(MI, OutMI, Mips::ADDiu, @@ -208,10 +204,7 @@ return true; case Mips::LONG_BRANCH_DADDiu: unsigned TargetFlags = MI->getOperand(2).getTargetFlags(); - if (TargetFlags == MipsII::MO_HIGHER) - lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu, - MCSymbolRefExpr::VK_Mips_HIGHER); - else if (TargetFlags == MipsII::MO_ABS_HI) + if (TargetFlags == MipsII::MO_ABS_HI) lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu, MCSymbolRefExpr::VK_Mips_ABS_HI); else if (TargetFlags == MipsII::MO_ABS_LO) Index: test/CodeGen/Mips/longbranch.ll =================================================================== --- test/CodeGen/Mips/longbranch.ll +++ test/CodeGen/Mips/longbranch.ll @@ -80,10 +80,7 @@ ; Check for long branch expansion: ; N64: daddiu $sp, $sp, -16 ; N64-NEXT: sd $ra, 0($sp) -; N64-NEXT: lui $1, %highest(($[[BB2:BB[0-9_]+]])-($[[BB1:BB[0-9_]+]])) -; N64-NEXT: daddiu $1, $1, %higher(($[[BB2]])-($[[BB1]])) -; N64-NEXT: dsll $1, $1, 16 -; N64-NEXT: daddiu $1, $1, %hi(($[[BB2]])-($[[BB1]])) +; N64-NEXT: daddiu $1, $zero, %hi(($[[BB2:BB[0-9_]+]])-($[[BB1:BB[0-9_]+]])) ; N64-NEXT: dsll $1, $1, 16 ; N64-NEXT: bal $[[BB1]] ; N64-NEXT: daddiu $1, $1, %lo(($[[BB2]])-($[[BB1]]))