[PATCH] Optimize long branch for MIPS64 by removing calculation of %higher and %highest

Daniel Sanders daniel.sanders at imgtec.com
Tue Apr 15 09:06:07 PDT 2014



================
Comment at: lib/Target/Mips/MipsLongBranch.cpp:328
@@ -330,2 +327,3 @@
+      //  daddiu $at, $zero, 0
       //  daddiu $at, $at, %hi($tgt - $baltgt)
       //  bal $baltgt
----------------
Sasa Stankovic wrote:
> Mark Seaborn wrote:
> > Does 64-bit MIPS not have an instruction for setting bits 16-31 of a register while zeroing the others (as 32-bit MIPS' "lui" instruction does)?
> > 
> > What does lui64 do?
> > 
> > This part looks OK to me, but I'm not familiar with 64-bit MIPS, so you might want to get someone who is sign off on the change too.
> There is no lui64 (I fixed that comment), there is only a lui instruction (you can see it in .td file lib/Target/Mips/Mips64InstrInfo.td - mnemonic for MIPS64 LUi64 instruction is just "lui"). lui on MIPS64 sets bits 16-31 of a register, zeroes bits 15-0, and sign-extends bit 31 into higher part of the 64-bit register.  MIPS64 supports all (or almost all) MIPS32 instructions, and they all operate like this - they change low 32 bits just like they do on MIPS32, and they sign-extend bit 31 into high 32 bits. MIPS64 also has instructions that operate on all 64 bits (their mnemonics start with d (from double)), but there is no instruction that sets bits 16-31 while clearing the others.
> Does 64-bit MIPS not have an instruction for setting bits 16-31 of a register while 
> zeroing the others (as 32-bit MIPS' "lui" instruction does)?

Not while zeroing the other bits but 32-bit results are generally sign-extended to 64-bit. lui is nearly the right operation but sign-extends instead of zero extending.

> What does lui64 do?

lui64 doesn't exist in the assembler or the ISA spec so we ought to avoid using that term when writing assembly examples. It's the same as the 32-bit lui instruction but sign-extended to 64-bits.

----

It looks like you should be able to remove another insn by replacing:
    daddiu $at, $zero, 0
    daddiu $at, $at, %hi($tgt - $baltgt)
with:
    daddiu $at, $zero, %hi($tgt - $baltgt)

================
Comment at: lib/Target/Mips/MipsLongBranch.cpp:350-364
@@ -346,1 +349,17 @@
+      //
+      // It's safe to do this because %highest and %higher can have non-zero
+      // values only when the offset is greater than 4GB, which is highly
+      // unlikely, if not impossible when compiling a single function.
+      //
+      // 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.
 
----------------
This logic makes sense to me but I didn't notice a guarantee that $tgt and $baltgt are in the same function. Have I missed it?


http://reviews.llvm.org/D3281






More information about the llvm-commits mailing list