mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Lower 64-bit immediates using MipsAnalyzeImmediate that has just been added.
Add a test case to show fewer instructions are needed to load an immediate with the new way of loading immediates. llvm-svn: 148908
This commit is contained in:
parent
c5d8deed3f
commit
6880302ac2
@ -31,19 +31,6 @@ def Subtract32 : SDNodeXForm<imm, [{
|
||||
// shamt must fit in 6 bits.
|
||||
def immZExt6 : ImmLeaf<i32, [{return Imm == (Imm & 0x3f);}]>;
|
||||
|
||||
// Is a 32-bit int.
|
||||
def immSExt32 : ImmLeaf<i64, [{return isInt<32>(Imm);}]>;
|
||||
|
||||
// Transformation Function - get the higher 16 bits.
|
||||
def HIGHER : SDNodeXForm<imm, [{
|
||||
return getImm(N, (N->getZExtValue() >> 32) & 0xFFFF);
|
||||
}]>;
|
||||
|
||||
// Transformation Function - get the highest 16 bits.
|
||||
def HIGHEST : SDNodeXForm<imm, [{
|
||||
return getImm(N, (N->getZExtValue() >> 48) & 0xFFFF);
|
||||
}]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instructions specific format
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -213,24 +200,6 @@ def SLL64_64 : FR<0x0, 0x00, (outs CPU64Regs:$rd), (ins CPU64Regs:$rt),
|
||||
// Arbitrary patterns that map to one or more instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Small immediates
|
||||
def : Pat<(i64 immSExt16:$in),
|
||||
(DADDiu ZERO_64, imm:$in)>;
|
||||
def : Pat<(i64 immZExt16:$in),
|
||||
(ORi64 ZERO_64, imm:$in)>;
|
||||
def : Pat<(i64 immLow16Zero:$in),
|
||||
(LUi64 (HI16 imm:$in))>;
|
||||
|
||||
// 32-bit immediates
|
||||
def : Pat<(i64 immSExt32:$imm),
|
||||
(ORi64 (LUi64 (HI16 imm:$imm)), (LO16 imm:$imm))>;
|
||||
|
||||
// Arbitrary immediates
|
||||
def : Pat<(i64 imm:$imm),
|
||||
(ORi64 (DSLL (ORi64 (DSLL (ORi64 (LUi64 (HIGHEST imm:$imm)),
|
||||
(HIGHER imm:$imm)), 16), (HI16 imm:$imm)), 16),
|
||||
(LO16 imm:$imm))>;
|
||||
|
||||
// extended loads
|
||||
let Predicates = [NotN64] in {
|
||||
def : Pat<(i64 (extloadi1 addr:$src)), (LB64 addr:$src)>;
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#define DEBUG_TYPE "mips-isel"
|
||||
#include "Mips.h"
|
||||
#include "MipsAnalyzeImmediate.h"
|
||||
#include "MipsMachineFunction.h"
|
||||
#include "MipsRegisterInfo.h"
|
||||
#include "MipsSubtarget.h"
|
||||
@ -317,6 +318,47 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
|
||||
break;
|
||||
}
|
||||
|
||||
case ISD::Constant: {
|
||||
const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Node);
|
||||
unsigned Size = CN->getValueSizeInBits(0);
|
||||
|
||||
if (Size == 32)
|
||||
break;
|
||||
|
||||
MipsAnalyzeImmediate AnalyzeImm;
|
||||
int64_t Imm = CN->getSExtValue();
|
||||
|
||||
const MipsAnalyzeImmediate::InstSeq &Seq =
|
||||
AnalyzeImm.Analyze(Imm, Size, false);
|
||||
|
||||
MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin();
|
||||
DebugLoc DL = CN->getDebugLoc();
|
||||
SDNode *RegOpnd;
|
||||
SDValue ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd),
|
||||
MVT::i64);
|
||||
|
||||
// The first instruction can be a LUi which is different from other
|
||||
// instructions (ADDiu, ORI and SLL) in that it does not have a register
|
||||
// operand.
|
||||
if (Inst->Opc == Mips::LUi64)
|
||||
RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, ImmOpnd);
|
||||
else
|
||||
RegOpnd =
|
||||
CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,
|
||||
CurDAG->getRegister(Mips::ZERO_64, MVT::i64),
|
||||
ImmOpnd);
|
||||
|
||||
// The remaining instructions in the sequence are handled here.
|
||||
for (++Inst; Inst != Seq.end(); ++Inst) {
|
||||
ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd),
|
||||
MVT::i64);
|
||||
RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,
|
||||
SDValue(RegOpnd, 0), ImmOpnd);
|
||||
}
|
||||
|
||||
return RegOpnd;
|
||||
}
|
||||
|
||||
case MipsISD::ThreadPointer: {
|
||||
EVT PtrVT = TLI.getPointerTy();
|
||||
unsigned RdhwrOpc, SrcReg, DestReg;
|
||||
|
@ -12,7 +12,7 @@ define i64 @foo3() nounwind readnone {
|
||||
entry:
|
||||
; CHECK: foo3
|
||||
; CHECK: lui $[[R0:[0-9]+]], 4660
|
||||
; CHECK: ori ${{[0-9]+}}, $[[R0]], 22136
|
||||
; CHECK: daddiu ${{[0-9]+}}, $[[R0]], 22136
|
||||
ret i64 305419896
|
||||
}
|
||||
|
||||
@ -33,11 +33,20 @@ entry:
|
||||
define i64 @foo9() nounwind readnone {
|
||||
entry:
|
||||
; CHECK: foo9
|
||||
; CHECK: lui $[[R0:[0-9]+]], 4660
|
||||
; CHECK: ori $[[R1:[0-9]+]], $[[R0]], 22136
|
||||
; CHECK: dsll $[[R2:[0-9]+]], $[[R1]], 16
|
||||
; CHECK: ori $[[R3:[0-9]+]], $[[R2]], 36882
|
||||
; CHECK: dsll $[[R4:[0-9]+]], $[[R3]], 16
|
||||
; CHECK: ori ${{[0-9]+}}, $[[R4]], 13398
|
||||
; CHECK: lui $[[R0:[0-9]+]], 583
|
||||
; CHECK: daddiu $[[R1:[0-9]+]], $[[R0]], -30001
|
||||
; CHECK: dsll $[[R2:[0-9]+]], $[[R1]], 18
|
||||
; CHECK: daddiu $[[R3:[0-9]+]], $[[R2]], 18441
|
||||
; CHECK: dsll $[[R4:[0-9]+]], $[[R3]], 17
|
||||
; CHECK: daddiu ${{[0-9]+}}, $[[R4]], 13398
|
||||
ret i64 1311768467284833366
|
||||
}
|
||||
|
||||
define i64 @foo10() nounwind readnone {
|
||||
entry:
|
||||
; CHECK: foo10
|
||||
; CHECK: lui $[[R0:[0-9]+]], 34661
|
||||
; CHECK: daddiu ${{[0-9]+}}, $[[R0]], 17185
|
||||
ret i64 -8690466096928522240
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user