Index: llvm/trunk/lib/Target/Mips/MipsLongBranch.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MipsLongBranch.cpp +++ llvm/trunk/lib/Target/Mips/MipsLongBranch.cpp @@ -279,12 +279,16 @@ LongBrMBB->addSuccessor(BalTgtMBB); BalTgtMBB->addSuccessor(TgtMBB); - // We must select between the MIPS32r6/MIPS64r6 BAL (which is a normal + // We must select between the MIPS32r6/MIPS64r6 BALC (which is a normal // instruction) and the pre-MIPS32r6/MIPS64r6 definition (which is an // pseudo-instruction wrapping BGEZAL). - unsigned BalOp = Subtarget.hasMips32r6() ? Mips::BAL : Mips::BAL_BR; + const unsigned BalOp = + Subtarget.hasMips32r6() + ? Subtarget.inMicroMipsMode() ? Mips::BALC_MMR6 : Mips::BALC + : Mips::BAL_BR; if (!ABI.IsN64()) { + // Pre R6: // $longbr: // addiu $sp, $sp, -8 // sw $ra, 0($sp) @@ -299,6 +303,20 @@ // $fallthrough: // + // R6: + // $longbr: + // addiu $sp, $sp, -8 + // sw $ra, 0($sp) + // lui $at, %hi($tgt - $baltgt) + // addiu $at, $at, %lo($tgt - $baltgt) + // balc $baltgt + // $baltgt: + // addu $at, $ra, $at + // lw $ra, 0($sp) + // addiu $sp, $sp, 8 + // jic $at, 0 + // $fallthrough: + Pos = LongBrMBB->begin(); BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) @@ -307,7 +325,7 @@ .addReg(Mips::SP).addImm(0); // LUi and ADDiu instructions create 32-bit offset of the target basic - // block from the target of BAL instruction. We cannot use immediate + // block from the target of BAL(C) instruction. We cannot use immediate // value for this offset because it cannot be determined accurately when // the program has inline assembly statements. We therefore use the // relocation expressions %hi($tgt-$baltgt) and %lo($tgt-$baltgt) which @@ -324,12 +342,22 @@ BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi), Mips::AT) .addMBB(TgtMBB).addMBB(BalTgtMBB); - MIBundleBuilder(*LongBrMBB, Pos) - .append(BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB)) - .append(BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_ADDiu), Mips::AT) - .addReg(Mips::AT) - .addMBB(TgtMBB) - .addMBB(BalTgtMBB)); + + MachineInstrBuilder BalInstr = + BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB); + MachineInstrBuilder ADDiuInstr = + BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_ADDiu), Mips::AT) + .addReg(Mips::AT) + .addMBB(TgtMBB) + .addMBB(BalTgtMBB); + if (Subtarget.hasMips32r6()) { + LongBrMBB->insert(Pos, ADDiuInstr); + LongBrMBB->insert(Pos, BalInstr); + } else { + LongBrMBB->insert(Pos, BalInstr); + LongBrMBB->insert(Pos, ADDiuInstr); + LongBrMBB->rbegin()->bundleWithPred(); + } Pos = BalTgtMBB->begin(); @@ -337,28 +365,37 @@ .addReg(Mips::RA).addReg(Mips::AT); BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) .addReg(Mips::SP).addImm(0); + if (Subtarget.isTargetNaCl()) + // Bundle-align the target of indirect branch JR. + TgtMBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN); // In NaCl, modifying the sp is not allowed in branch delay slot. - if (Subtarget.isTargetNaCl()) + // For MIPS32R6, we can skip using a delay slot branch. + if (Subtarget.isTargetNaCl() || Subtarget.hasMips32r6()) BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) .addReg(Mips::SP).addImm(8); - if (Subtarget.hasMips32r6()) - BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JALR)) - .addReg(Mips::ZERO).addReg(Mips::AT); - else + if (Subtarget.hasMips32r6()) { + const unsigned JICOp = + Subtarget.inMicroMipsMode() ? Mips::JIC_MMR6 : Mips::JIC; + BuildMI(*BalTgtMBB, Pos, DL, TII->get(JICOp)) + .addReg(Mips::AT) + .addImm(0); + + } else { BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JR)).addReg(Mips::AT); - if (Subtarget.isTargetNaCl()) { - BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::NOP)); - // Bundle-align the target of indirect branch JR. - TgtMBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN); - } else - BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) - .addReg(Mips::SP).addImm(8); + if (Subtarget.isTargetNaCl()) { + BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::NOP)); + } else + BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) + .addReg(Mips::SP) + .addImm(8); - BalTgtMBB->rbegin()->bundleWithPred(); + BalTgtMBB->rbegin()->bundleWithPred(); + } } else { + // Pre R6: // $longbr: // daddiu $sp, $sp, -16 // sd $ra, 0($sp) @@ -372,7 +409,21 @@ // jr64 $at // daddiu $sp, $sp, 16 // $fallthrough: - // + + // R6: + // $longbr: + // daddiu $sp, $sp, -16 + // sd $ra, 0($sp) + // daddiu $at, $zero, %hi($tgt - $baltgt) + // dsll $at, $at, 16 + // daddiu $at, $at, %lo($tgt - $baltgt) + // balc $baltgt + // $baltgt: + // daddu $at, $ra, $at + // ld $ra, 0($sp) + // daddiu $sp, $sp, 16 + // jic $at, 0 + // $fallthrough: // We assume the branch is within-function, and that offset is within // +/- 2GB. High 32 bits will therefore always be zero. @@ -401,13 +452,21 @@ BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64) .addReg(Mips::AT_64).addImm(16); - MIBundleBuilder(*LongBrMBB, Pos) - .append(BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB)) - .append( - BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64) - .addReg(Mips::AT_64) - .addMBB(TgtMBB, MipsII::MO_ABS_LO) - .addMBB(BalTgtMBB)); + MachineInstrBuilder BalInstr = + BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB); + MachineInstrBuilder DADDiuInstr = + BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64) + .addReg(Mips::AT_64) + .addMBB(TgtMBB, MipsII::MO_ABS_LO) + .addMBB(BalTgtMBB); + if (Subtarget.hasMips32r6()) { + LongBrMBB->insert(Pos, DADDiuInstr); + LongBrMBB->insert(Pos, BalInstr); + } else { + LongBrMBB->insert(Pos, BalInstr); + LongBrMBB->insert(Pos, DADDiuInstr); + LongBrMBB->rbegin()->bundleWithPred(); + } Pos = BalTgtMBB->begin(); @@ -416,29 +475,40 @@ BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LD), Mips::RA_64) .addReg(Mips::SP_64).addImm(0); - if (Subtarget.hasMips64r6()) - BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JALR64)) - .addReg(Mips::ZERO_64).addReg(Mips::AT_64); - else + if (Subtarget.hasMips64r6()) { + BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64) + .addReg(Mips::SP_64) + .addImm(16); + BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JIC64)) + .addReg(Mips::AT_64) + .addImm(0); + } else { BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JR64)).addReg(Mips::AT_64); - - BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64) - .addReg(Mips::SP_64).addImm(16); - BalTgtMBB->rbegin()->bundleWithPred(); + BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64) + .addReg(Mips::SP_64) + .addImm(16); + BalTgtMBB->rbegin()->bundleWithPred(); + } } assert(LongBrMBB->size() + BalTgtMBB->size() == LongBranchSeqSize); } else { - // $longbr: - // j $tgt - // nop + // Pre R6: R6: + // $longbr: $longbr: + // j $tgt bc $tgt + // nop $fallthrough // $fallthrough: // Pos = LongBrMBB->begin(); LongBrMBB->addSuccessor(TgtMBB); - MIBundleBuilder(*LongBrMBB, Pos) - .append(BuildMI(*MF, DL, TII->get(Mips::J)).addMBB(TgtMBB)) - .append(BuildMI(*MF, DL, TII->get(Mips::NOP))); + if (Subtarget.hasMips32r6()) + BuildMI(*LongBrMBB, Pos, DL, + TII->get(Subtarget.inMicroMipsMode() ? Mips::BC_MMR6 : Mips::BC)) + .addMBB(TgtMBB); + else + MIBundleBuilder(*LongBrMBB, Pos) + .append(BuildMI(*MF, DL, TII->get(Mips::J)).addMBB(TgtMBB)) + .append(BuildMI(*MF, DL, TII->get(Mips::NOP))); assert(LongBrMBB->size() == LongBranchSeqSize); } @@ -474,8 +544,8 @@ IsPIC = TM.isPositionIndependent(); ABI = static_cast(TM).getABI(); - LongBranchSeqSize = - !IsPIC ? 2 : (ABI.IsN64() ? 10 : (!STI.isTargetNaCl() ? 9 : 10)); + LongBranchSeqSize = IsPIC ? ((ABI.IsN64() || STI.isTargetNaCl()) ? 10 : 9) + : (STI.hasMips32r6() ? 1 : 2); if (STI.inMips16Mode() || !STI.enableLongBranchPass()) return false; Index: llvm/trunk/test/CodeGen/Mips/longbranch.ll =================================================================== --- llvm/trunk/test/CodeGen/Mips/longbranch.ll +++ llvm/trunk/test/CodeGen/Mips/longbranch.ll @@ -1,16 +1,35 @@ -; RUN: llc -march=mipsel -relocation-model=pic < %s | FileCheck %s -; RUN: llc -march=mipsel -force-mips-long-branch -O3 -relocation-model=pic < %s \ -; RUN: | FileCheck %s -check-prefix=O32 -; RUN: llc -march=mipsel -mcpu=mips32r6 -force-mips-long-branch -O3 \ -; RUN: -relocation-model=pic -asm-show-inst < %s | FileCheck %s -check-prefix=O32-R6 -; RUN: llc -march=mips64el -mcpu=mips4 -target-abi=n64 -force-mips-long-branch -O3 -relocation-model=pic \ -; RUN: < %s | FileCheck %s -check-prefix=N64 -; RUN: llc -march=mips64el -mcpu=mips64 -target-abi=n64 -force-mips-long-branch -O3 -relocation-model=pic \ -; RUN: < %s | FileCheck %s -check-prefix=N64 -; RUN: llc -march=mips64el -mcpu=mips64r6 -target-abi=n64 -force-mips-long-branch -O3 \ -; RUN: -relocation-model=pic -asm-show-inst < %s | FileCheck %s -check-prefix=N64-R6 -; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=micromips \ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; Except for the NACL version which isn't parsed by update_llc_test_checks.py +; RUN: llc -mtriple=mipsel-unknown-linux-gnu -O3 -relocation-model=pic < %s \ +; RUN: | FileCheck %s -check-prefix=NOLONGBRANCH + +; RUN: llc -mtriple=mipsel-unknown-linux-gnu -force-mips-long-branch -O3 -relocation-model=pic < %s \ +; RUN: | FileCheck %s -check-prefix=O32-PIC +; RUN: llc -mtriple=mipsel-unknown-linux-gnu -force-mips-long-branch -O3 -relocation-model=static < %s \ +; RUN: | FileCheck %s -check-prefix=O32-STATIC +; RUN: llc -mtriple=mipsel-unknown-linux-gnu -mcpu=mips32r6 -force-mips-long-branch -O3 \ +; RUN: -relocation-model=pic < %s | FileCheck %s -check-prefix=O32-R6-PIC +; RUN: llc -mtriple=mipsel-unknown-linux-gnu -mcpu=mips32r6 -force-mips-long-branch -O3 \ +; RUN: -relocation-model=static < %s | FileCheck %s -check-prefix=O32-R6-STATIC + +; RUN: llc -mtriple=mips64el-unknown-linux-gnu -mcpu=mips4 -target-abi=n64 -force-mips-long-branch -O3 -relocation-model=pic \ +; RUN: < %s | FileCheck %s -check-prefix=MIPS4 +; RUN: llc -mtriple=mips64el-unknown-linux-gnu -mcpu=mips64 -target-abi=n64 -force-mips-long-branch -O3 -relocation-model=pic \ +; RUN: < %s | FileCheck %s -check-prefix=MIPS64 +; RUN: llc -mtriple=mips64el-unknown-linux-gnu -mcpu=mips64r6 -target-abi=n64 -force-mips-long-branch -O3 \ +; RUN: -relocation-model=pic < %s | FileCheck %s -check-prefix=N64-R6 + +; RUN: llc -mtriple=mipsel-unknown-linux-gnu -mcpu=mips32r2 -mattr=micromips \ ; RUN: -force-mips-long-branch -O3 -relocation-model=pic < %s | FileCheck %s -check-prefix=MICROMIPS +; RUN: llc -mtriple=mipsel-unknown-linux-gnu -mcpu=mips32r2 -mattr=micromips \ +; RUN: -force-mips-long-branch -O3 -relocation-model=static < %s | FileCheck %s -check-prefix=MICROMIPSSTATIC + +; RUN: llc -mtriple=mipsel-unknown-linux-gnu -mcpu=mips32r6 -mattr=micromips \ +; RUN: -force-mips-long-branch -O3 -relocation-model=static < %s | FileCheck %s -check-prefix=MICROMIPSR6STATIC +; RUN: llc -mtriple=mipsel-unknown-linux-gnu -mcpu=mips32r6 -mattr=micromips \ +; RUN: -force-mips-long-branch -O3 -relocation-model=pic < %s | FileCheck %s -check-prefix=MICROMIPSR6PIC + + ; RUN: llc -mtriple=mipsel-none-nacl -force-mips-long-branch -O3 -relocation-model=pic < %s \ ; RUN: | FileCheck %s -check-prefix=NACL @@ -18,6 +37,284 @@ @x = external global i32 define void @test1(i32 signext %s) { +; NOLONGBRANCH-LABEL: test1: +; NOLONGBRANCH: # %bb.0: # %entry +; NOLONGBRANCH-NEXT: lui $2, %hi(_gp_disp) +; NOLONGBRANCH-NEXT: addiu $2, $2, %lo(_gp_disp) +; NOLONGBRANCH-NEXT: beqz $4, $BB0_2 +; NOLONGBRANCH-NEXT: addu $2, $2, $25 +; NOLONGBRANCH-NEXT: # %bb.1: # %then +; NOLONGBRANCH-NEXT: lw $1, %got(x)($2) +; NOLONGBRANCH-NEXT: addiu $2, $zero, 1 +; NOLONGBRANCH-NEXT: sw $2, 0($1) +; NOLONGBRANCH-NEXT: $BB0_2: # %end +; NOLONGBRANCH-NEXT: jr $ra +; NOLONGBRANCH-NEXT: nop +; +; O32-PIC-LABEL: test1: +; O32-PIC: # %bb.0: # %entry +; O32-PIC-NEXT: lui $2, %hi(_gp_disp) +; O32-PIC-NEXT: addiu $2, $2, %lo(_gp_disp) +; O32-PIC-NEXT: bnez $4, $BB0_3 +; O32-PIC-NEXT: addu $2, $2, $25 +; O32-PIC-NEXT: # %bb.1: # %entry +; O32-PIC-NEXT: addiu $sp, $sp, -8 +; O32-PIC-NEXT: sw $ra, 0($sp) +; O32-PIC-NEXT: lui $1, %hi(($BB0_4)-($BB0_2)) +; O32-PIC-NEXT: bal $BB0_2 +; O32-PIC-NEXT: addiu $1, $1, %lo(($BB0_4)-($BB0_2)) +; O32-PIC-NEXT: $BB0_2: # %entry +; O32-PIC-NEXT: addu $1, $ra, $1 +; O32-PIC-NEXT: lw $ra, 0($sp) +; O32-PIC-NEXT: jr $1 +; O32-PIC-NEXT: addiu $sp, $sp, 8 +; O32-PIC-NEXT: $BB0_3: # %then +; O32-PIC-NEXT: lw $1, %got(x)($2) +; O32-PIC-NEXT: addiu $2, $zero, 1 +; O32-PIC-NEXT: sw $2, 0($1) +; O32-PIC-NEXT: $BB0_4: # %end +; O32-PIC-NEXT: jr $ra +; O32-PIC-NEXT: nop +; +; O32-STATIC-LABEL: test1: +; O32-STATIC: # %bb.0: # %entry +; O32-STATIC-NEXT: bnez $4, $BB0_2 +; O32-STATIC-NEXT: nop +; O32-STATIC-NEXT: # %bb.1: # %entry +; O32-STATIC-NEXT: j $BB0_3 +; O32-STATIC-NEXT: nop +; O32-STATIC-NEXT: $BB0_2: # %then +; O32-STATIC-NEXT: lui $1, %hi(x) +; O32-STATIC-NEXT: addiu $2, $zero, 1 +; O32-STATIC-NEXT: sw $2, %lo(x)($1) +; O32-STATIC-NEXT: $BB0_3: # %end +; O32-STATIC-NEXT: jr $ra +; O32-STATIC-NEXT: nop +; +; O32-R6-PIC-LABEL: test1: +; O32-R6-PIC: # %bb.0: # %entry +; O32-R6-PIC-NEXT: lui $2, %hi(_gp_disp) +; O32-R6-PIC-NEXT: addiu $2, $2, %lo(_gp_disp) +; O32-R6-PIC-NEXT: bnez $4, $BB0_3 +; O32-R6-PIC-NEXT: addu $2, $2, $25 +; O32-R6-PIC-NEXT: # %bb.1: # %entry +; O32-R6-PIC-NEXT: addiu $sp, $sp, -8 +; O32-R6-PIC-NEXT: sw $ra, 0($sp) +; O32-R6-PIC-NEXT: lui $1, %hi(($BB0_4)-($BB0_2)) +; O32-R6-PIC-NEXT: addiu $1, $1, %lo(($BB0_4)-($BB0_2)) +; O32-R6-PIC-NEXT: balc $BB0_2 +; O32-R6-PIC-NEXT: $BB0_2: # %entry +; O32-R6-PIC-NEXT: addu $1, $ra, $1 +; O32-R6-PIC-NEXT: lw $ra, 0($sp) +; O32-R6-PIC-NEXT: addiu $sp, $sp, 8 +; O32-R6-PIC-NEXT: jrc $1 +; O32-R6-PIC-NEXT: $BB0_3: # %then +; O32-R6-PIC-NEXT: lw $1, %got(x)($2) +; O32-R6-PIC-NEXT: addiu $2, $zero, 1 +; O32-R6-PIC-NEXT: sw $2, 0($1) +; O32-R6-PIC-NEXT: $BB0_4: # %end +; O32-R6-PIC-NEXT: jrc $ra +; +; O32-R6-STATIC-LABEL: test1: +; O32-R6-STATIC: # %bb.0: # %entry +; O32-R6-STATIC-NEXT: bnezc $4, $BB0_2 +; O32-R6-STATIC-NEXT: nop +; O32-R6-STATIC-NEXT: # %bb.1: # %entry +; O32-R6-STATIC-NEXT: bc $BB0_3 +; O32-R6-STATIC-NEXT: $BB0_2: # %then +; O32-R6-STATIC-NEXT: lui $1, %hi(x) +; O32-R6-STATIC-NEXT: addiu $2, $zero, 1 +; O32-R6-STATIC-NEXT: sw $2, %lo(x)($1) +; O32-R6-STATIC-NEXT: $BB0_3: # %end +; O32-R6-STATIC-NEXT: jrc $ra +; +; MIPS4-LABEL: test1: +; MIPS4: # %bb.0: # %entry +; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(test1))) +; MIPS4-NEXT: bnez $4, .LBB0_3 +; MIPS4-NEXT: daddu $2, $1, $25 +; MIPS4-NEXT: # %bb.1: # %entry +; MIPS4-NEXT: daddiu $sp, $sp, -16 +; MIPS4-NEXT: sd $ra, 0($sp) +; MIPS4-NEXT: daddiu $1, $zero, %hi(.LBB0_4-.LBB0_2) +; MIPS4-NEXT: dsll $1, $1, 16 +; MIPS4-NEXT: bal .LBB0_2 +; MIPS4-NEXT: daddiu $1, $1, %lo(.LBB0_4-.LBB0_2) +; MIPS4-NEXT: .LBB0_2: # %entry +; MIPS4-NEXT: daddu $1, $ra, $1 +; MIPS4-NEXT: ld $ra, 0($sp) +; MIPS4-NEXT: jr $1 +; MIPS4-NEXT: daddiu $sp, $sp, 16 +; MIPS4-NEXT: .LBB0_3: # %then +; MIPS4-NEXT: daddiu $1, $2, %lo(%neg(%gp_rel(test1))) +; MIPS4-NEXT: addiu $2, $zero, 1 +; MIPS4-NEXT: ld $1, %got_disp(x)($1) +; MIPS4-NEXT: sw $2, 0($1) +; MIPS4-NEXT: .LBB0_4: # %end +; MIPS4-NEXT: jr $ra +; MIPS4-NEXT: nop +; +; MIPS64-LABEL: test1: +; MIPS64: # %bb.0: # %entry +; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(test1))) +; MIPS64-NEXT: bnez $4, .LBB0_3 +; MIPS64-NEXT: daddu $2, $1, $25 +; MIPS64-NEXT: # %bb.1: # %entry +; MIPS64-NEXT: daddiu $sp, $sp, -16 +; MIPS64-NEXT: sd $ra, 0($sp) +; MIPS64-NEXT: daddiu $1, $zero, %hi(.LBB0_4-.LBB0_2) +; MIPS64-NEXT: dsll $1, $1, 16 +; MIPS64-NEXT: bal .LBB0_2 +; MIPS64-NEXT: daddiu $1, $1, %lo(.LBB0_4-.LBB0_2) +; MIPS64-NEXT: .LBB0_2: # %entry +; MIPS64-NEXT: daddu $1, $ra, $1 +; MIPS64-NEXT: ld $ra, 0($sp) +; MIPS64-NEXT: jr $1 +; MIPS64-NEXT: daddiu $sp, $sp, 16 +; MIPS64-NEXT: .LBB0_3: # %then +; MIPS64-NEXT: daddiu $1, $2, %lo(%neg(%gp_rel(test1))) +; MIPS64-NEXT: addiu $2, $zero, 1 +; MIPS64-NEXT: ld $1, %got_disp(x)($1) +; MIPS64-NEXT: sw $2, 0($1) +; MIPS64-NEXT: .LBB0_4: # %end +; MIPS64-NEXT: jr $ra +; MIPS64-NEXT: nop +; +; N64-R6-LABEL: test1: +; N64-R6: # %bb.0: # %entry +; N64-R6-NEXT: lui $1, %hi(%neg(%gp_rel(test1))) +; N64-R6-NEXT: bnez $4, .LBB0_3 +; N64-R6-NEXT: daddu $2, $1, $25 +; N64-R6-NEXT: # %bb.1: # %entry +; N64-R6-NEXT: daddiu $sp, $sp, -16 +; N64-R6-NEXT: sd $ra, 0($sp) +; N64-R6-NEXT: daddiu $1, $zero, %hi(.LBB0_4-.LBB0_2) +; N64-R6-NEXT: dsll $1, $1, 16 +; N64-R6-NEXT: daddiu $1, $1, %lo(.LBB0_4-.LBB0_2) +; N64-R6-NEXT: balc .LBB0_2 +; N64-R6-NEXT: .LBB0_2: # %entry +; N64-R6-NEXT: daddu $1, $ra, $1 +; N64-R6-NEXT: ld $ra, 0($sp) +; N64-R6-NEXT: daddiu $sp, $sp, 16 +; N64-R6-NEXT: jrc $1 +; N64-R6-NEXT: .LBB0_3: # %then +; N64-R6-NEXT: daddiu $1, $2, %lo(%neg(%gp_rel(test1))) +; N64-R6-NEXT: addiu $2, $zero, 1 +; N64-R6-NEXT: ld $1, %got_disp(x)($1) +; N64-R6-NEXT: sw $2, 0($1) +; N64-R6-NEXT: .LBB0_4: # %end +; N64-R6-NEXT: jrc $ra +; +; MICROMIPS-LABEL: test1: +; MICROMIPS: # %bb.0: # %entry +; MICROMIPS-NEXT: lui $2, %hi(_gp_disp) +; MICROMIPS-NEXT: addiu $2, $2, %lo(_gp_disp) +; MICROMIPS-NEXT: bnez $4, $BB0_3 +; MICROMIPS-NEXT: addu $2, $2, $25 +; MICROMIPS-NEXT: # %bb.1: # %entry +; MICROMIPS-NEXT: addiu $sp, $sp, -8 +; MICROMIPS-NEXT: sw $ra, 0($sp) +; MICROMIPS-NEXT: lui $1, %hi(($BB0_4)-($BB0_2)) +; MICROMIPS-NEXT: bal $BB0_2 +; MICROMIPS-NEXT: addiu $1, $1, %lo(($BB0_4)-($BB0_2)) +; MICROMIPS-NEXT: $BB0_2: # %entry +; MICROMIPS-NEXT: addu $1, $ra, $1 +; MICROMIPS-NEXT: lw $ra, 0($sp) +; MICROMIPS-NEXT: jr $1 +; MICROMIPS-NEXT: addiu $sp, $sp, 8 +; MICROMIPS-NEXT: $BB0_3: # %then +; MICROMIPS-NEXT: lw $2, %got(x)($2) +; MICROMIPS-NEXT: li16 $3, 1 +; MICROMIPS-NEXT: sw16 $3, 0($2) +; MICROMIPS-NEXT: $BB0_4: # %end +; MICROMIPS-NEXT: jrc $ra +; +; MICROMIPSSTATIC-LABEL: test1: +; MICROMIPSSTATIC: # %bb.0: # %entry +; MICROMIPSSTATIC-NEXT: bnezc $4, $BB0_2 +; MICROMIPSSTATIC-NEXT: # %bb.1: # %entry +; MICROMIPSSTATIC-NEXT: j $BB0_4 +; MICROMIPSSTATIC-NEXT: nop +; MICROMIPSSTATIC-NEXT: $BB0_2: # %entry +; MICROMIPSSTATIC-NEXT: j $BB0_3 +; MICROMIPSSTATIC-NEXT: nop +; MICROMIPSSTATIC-NEXT: $BB0_3: # %then +; MICROMIPSSTATIC-NEXT: lui $1, %hi(x) +; MICROMIPSSTATIC-NEXT: li16 $2, 1 +; MICROMIPSSTATIC-NEXT: sw $2, %lo(x)($1) +; MICROMIPSSTATIC-NEXT: $BB0_4: # %end +; MICROMIPSSTATIC-NEXT: jrc $ra +; +; MICROMIPSR6STATIC-LABEL: test1: +; MICROMIPSR6STATIC: # %bb.0: # %entry +; MICROMIPSR6STATIC-NEXT: bnezc $4, $BB0_2 +; MICROMIPSR6STATIC-NEXT: # %bb.1: # %entry +; MICROMIPSR6STATIC-NEXT: bc $BB0_4 +; MICROMIPSR6STATIC-NEXT: $BB0_2: # %entry +; MICROMIPSR6STATIC-NEXT: bc $BB0_3 +; MICROMIPSR6STATIC-NEXT: $BB0_3: # %then +; MICROMIPSR6STATIC-NEXT: lui $1, %hi(x) +; MICROMIPSR6STATIC-NEXT: li16 $2, 1 +; MICROMIPSR6STATIC-NEXT: sw $2, %lo(x)($1) +; MICROMIPSR6STATIC-NEXT: $BB0_4: # %end +; MICROMIPSR6STATIC-NEXT: jrc $ra +; +; MICROMIPSR6PIC-LABEL: test1: +; MICROMIPSR6PIC: # %bb.0: # %entry +; MICROMIPSR6PIC-NEXT: lui $2, %hi(_gp_disp) +; MICROMIPSR6PIC-NEXT: addiu $2, $2, %lo(_gp_disp) +; MICROMIPSR6PIC-NEXT: addu $2, $2, $25 +; MICROMIPSR6PIC-NEXT: bnezc $4, $BB0_3 +; MICROMIPSR6PIC-NEXT: # %bb.1: # %entry +; MICROMIPSR6PIC-NEXT: addiu $sp, $sp, -8 +; MICROMIPSR6PIC-NEXT: sw $ra, 0($sp) +; MICROMIPSR6PIC-NEXT: lui $1, %hi(($BB0_4)-($BB0_2)) +; MICROMIPSR6PIC-NEXT: addiu $1, $1, %lo(($BB0_4)-($BB0_2)) +; MICROMIPSR6PIC-NEXT: balc $BB0_2 +; MICROMIPSR6PIC-NEXT: $BB0_2: # %entry +; MICROMIPSR6PIC-NEXT: addu $1, $ra, $1 +; MICROMIPSR6PIC-NEXT: lw $ra, 0($sp) +; MICROMIPSR6PIC-NEXT: addiu $sp, $sp, 8 +; MICROMIPSR6PIC-NEXT: jic $1, 0 +; MICROMIPSR6PIC-NEXT: $BB0_3: # %then +; MICROMIPSR6PIC-NEXT: lw $2, %got(x)($2) +; MICROMIPSR6PIC-NEXT: li16 $3, 1 +; MICROMIPSR6PIC-NEXT: sw16 $3, 0($2) +; MICROMIPSR6PIC-NEXT: $BB0_4: # %end +; MICROMIPSR6PIC-NEXT: jrc $ra + +; NACL-LABEL: test1: +; NACL: # %bb.0: +; NACL-NEXT: lui $2, %hi(_gp_disp) +; NACL-NEXT: addiu $2, $2, %lo(_gp_disp) +; NACL-NEXT: bnez $4, $BB0_3 +; NACL-NEXT: addu $2, $2, $25 +; NACL-NEXT: # %bb.1: +; NACL-NEXT: addiu $sp, $sp, -8 +; NACL-NEXT: sw $ra, 0($sp) +; NACL-NEXT: lui $1, %hi(($BB0_4)-($BB0_2)) +; NACL-NEXT: bal $BB0_2 +; NACL-NEXT: addiu $1, $1, %lo(($BB0_4)-($BB0_2)) +; NACL-NEXT: $BB0_2: +; NACL-NEXT: addu $1, $ra, $1 +; NACL-NEXT: lw $ra, 0($sp) +; NACL-NEXT: addiu $sp, $sp, 8 +; NACL-NEXT: jr $1 +; NACL-NEXT: nop +; NACL-NEXT: $BB0_3: +; NACL-NEXT: lw $1, %got(x)($2) +; NACL-NEXT: addiu $2, $zero, 1 +; NACL-NEXT: sw $2, 0($1) +; NACL-NEXT: .p2align 4 +; NACL-NEXT: $BB0_4: +; NACL-NEXT: jr $ra +; NACL-NEXT: nop + + +; Check the NaCl version. Check that sp change is not in the branch delay slot +; of "jr $1" instruction. Check that target of indirect branch "jr $1" is +; bundle aligned. + entry: %cmp = icmp eq i32 %s, 0 br i1 %cmp, label %end, label %then @@ -29,147 +326,4 @@ end: ret void - -; First check the normal version (without long branch). beqz jumps to return, -; and fallthrough block stores 1 to global variable. - -; CHECK: lui $[[R0:[0-9]+]], %hi(_gp_disp) -; CHECK: addiu $[[R0]], $[[R0]], %lo(_gp_disp) -; CHECK: beqz $4, $[[BB0:BB[0-9_]+]] -; CHECK: addu $[[GP:[0-9]+]], $[[R0]], $25 -; CHECK: lw $[[R1:[0-9]+]], %got(x)($[[GP]]) -; CHECK: addiu $[[R2:[0-9]+]], $zero, 1 -; CHECK: sw $[[R2]], 0($[[R1]]) -; CHECK: $[[BB0]]: -; CHECK: jr $ra -; CHECK: nop - - -; Check the MIPS32 version. Check that branch logic is inverted, so that the -; target of the new branch (bnez) is the fallthrough block of the original -; branch. Check that fallthrough block of the new branch contains long branch -; expansion which at the end indirectly jumps to the target of the original -; branch. - -; O32: lui $[[R0:[0-9]+]], %hi(_gp_disp) -; O32: addiu $[[R0]], $[[R0]], %lo(_gp_disp) -; O32: bnez $4, $[[BB0:BB[0-9_]+]] -; O32: addu $[[GP:[0-9]+]], $[[R0]], $25 - -; Check for long branch expansion: -; O32: addiu $sp, $sp, -8 -; O32-NEXT: sw $ra, 0($sp) -; O32-NEXT: lui $1, %hi(($[[BB2:BB[0-9_]+]])-($[[BB1:BB[0-9_]+]])) -; O32-NEXT: bal $[[BB1]] -; O32-NEXT: addiu $1, $1, %lo(($[[BB2]])-($[[BB1]])) -; O32-NEXT: $[[BB1]]: -; O32-NEXT: addu $1, $ra, $1 -; O32-NEXT: lw $ra, 0($sp) -; O32-NEXT: jr $1 -; O32-NEXT: addiu $sp, $sp, 8 - -; O32: $[[BB0]]: -; O32: lw $[[R1:[0-9]+]], %got(x)($[[GP]]) -; O32: addiu $[[R2:[0-9]+]], $zero, 1 -; O32: sw $[[R2]], 0($[[R1]]) -; O32: $[[BB2]]: -; O32: jr $ra -; O32: nop - -; In MIPS32R6 JR is an alias to JALR with $rd=0. As everything else remains the -; same with the O32 prefix, we use -asm-show-inst in order to make sure that -; the opcode of the MachineInst is a JALR. -; O32-R6: JALR - -; Check the MIPS64 version. - -; N64: lui $[[R0:[0-9]+]], %hi(%neg(%gp_rel(test1))) -; N64: bnez $4, [[BB0:\.LBB[0-9_]+]] -; N64: daddu $[[R1:[0-9]+]], $[[R0]], $25 - -; Check for long branch expansion: -; N64: daddiu $sp, $sp, -16 -; N64-NEXT: sd $ra, 0($sp) -; N64-NEXT: daddiu $1, $zero, %hi([[BB2:\.LBB[0-9_]+]]-[[BB1:\.LBB[0-9_]+]]) -; N64-NEXT: dsll $1, $1, 16 -; N64-NEXT: bal [[BB1]] -; N64-NEXT: daddiu $1, $1, %lo([[BB2]]-[[BB1]]) -; N64-NEXT: [[BB1]]: -; N64-NEXT: daddu $1, $ra, $1 -; N64-NEXT: ld $ra, 0($sp) -; N64-NEXT: jr $1 -; N64-NEXT: daddiu $sp, $sp, 16 - -; N64: [[BB0]]: -; N64: daddiu $[[GP:[0-9]+]], $[[R1]], %lo(%neg(%gp_rel(test1))) -; N64: addiu $[[R3:[0-9]+]], $zero, 1 -; N64: ld $[[R2:[0-9]+]], %got_disp(x)($[[GP]]) -; N64: sw $[[R3]], 0($[[R2]]) -; N64: [[BB2]]: -; N64: jr $ra -; N64: nop - -; In MIPS64R6 JR is an alias to JALR with $rd=0. As everything else remains the -; same with the N64 prefix, we use -asm-show-inst in order to make sure that -; the opcode of the MachineInst is a JALR. -; N64-R6: JALR64 - - -; Check the microMIPS version. - -; MICROMIPS: lui $[[R0:[0-9]+]], %hi(_gp_disp) -; MICROMIPS: addiu $[[R0]], $[[R0]], %lo(_gp_disp) -; MICROMIPS: bnez $4, $[[BB0:BB[0-9_]+]] -; MICROMIPS: addu $[[GP:[0-9]+]], $[[R0]], $25 - -; Check for long branch expansion: -; MICROMIPS: addiu $sp, $sp, -8 -; MICROMIPS-NEXT: sw $ra, 0($sp) -; MICROMIPS-NEXT: lui $1, %hi(($[[BB2:BB[0-9_]+]])-($[[BB1:BB[0-9_]+]])) -; MICROMIPS-NEXT: bal $[[BB1]] -; MICROMIPS-NEXT: addiu $1, $1, %lo(($[[BB2]])-($[[BB1]])) -; MICROMIPS-NEXT: $[[BB1]]: -; MICROMIPS-NEXT: addu $1, $ra, $1 -; MICROMIPS-NEXT: lw $ra, 0($sp) -; MICROMIPS-NEXT: jr $1 -; MICROMIPS-NEXT: addiu $sp, $sp, 8 - -; MICROMIPS: $[[BB0]]: -; MICROMIPS: lw $[[R1:[0-9]+]], %got(x)($[[GP]]) -; MICROMIPS: li16 $[[R2:[0-9]+]], 1 -; MICROMIPS: sw16 $[[R2]], 0($[[R1]]) -; MICROMIPS: $[[BB2]]: -; MICROMIPS: jrc $ra - - -; Check the NaCl version. Check that sp change is not in the branch delay slot -; of "jr $1" instruction. Check that target of indirect branch "jr $1" is -; bundle aligned. - -; NACL: lui $[[R0:[0-9]+]], %hi(_gp_disp) -; NACL: addiu $[[R0]], $[[R0]], %lo(_gp_disp) -; NACL: bnez $4, $[[BB0:BB[0-9_]+]] -; NACL: addu $[[GP:[0-9]+]], $[[R0]], $25 - -; Check for long branch expansion: -; NACL: addiu $sp, $sp, -8 -; NACL-NEXT: sw $ra, 0($sp) -; NACL-NEXT: lui $1, %hi(($[[BB2:BB[0-9_]+]])-($[[BB1:BB[0-9_]+]])) -; NACL-NEXT: bal $[[BB1]] -; NACL-NEXT: addiu $1, $1, %lo(($[[BB2]])-($[[BB1]])) -; NACL-NEXT: $[[BB1]]: -; NACL-NEXT: addu $1, $ra, $1 -; NACL-NEXT: lw $ra, 0($sp) -; NACL-NEXT: addiu $sp, $sp, 8 -; NACL-NEXT: jr $1 -; NACL-NEXT: nop - -; NACL: $[[BB0]]: -; NACL: lw $[[R1:[0-9]+]], %got(x)($[[GP]]) -; NACL: addiu $[[R2:[0-9]+]], $zero, 1 -; NACL: sw $[[R2]], 0($[[R1]]) -; NACL: .p2align 4 -; NACL-NEXT: $[[BB2]]: -; NACL: jr $ra -; NACL: nop }