forked from OSchip/llvm-project
Add frameindex support
Add support for copying (e.g. returning) doubles Add support for F<->I instructions llvm-svn: 24818
This commit is contained in:
parent
9dcfe37e76
commit
4492b1b7a0
|
@ -14,6 +14,7 @@
|
|||
#include "SparcV8.h"
|
||||
#include "SparcV8TargetMachine.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/SelectionDAG.h"
|
||||
#include "llvm/CodeGen/SelectionDAGISel.h"
|
||||
|
@ -36,6 +37,9 @@ namespace V8ISD {
|
|||
BRFCC, // Branch to dest on fcc condition
|
||||
|
||||
Hi, Lo, // Hi/Lo operations, typically on a global address.
|
||||
|
||||
FTOI, // FP to Int within a FP register.
|
||||
ITOF, // Int to FP within a FP register.
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -86,6 +90,14 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM)
|
|||
setOperationAction(ISD::UREM, MVT::i32, Expand);
|
||||
setOperationAction(ISD::SREM, MVT::i32, Expand);
|
||||
|
||||
// Custom expand fp<->sint
|
||||
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
|
||||
setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
|
||||
|
||||
// Expand fp<->uint
|
||||
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
|
||||
setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
|
||||
|
||||
// Sparc has no select or setcc: expand to SELECT_CC.
|
||||
setOperationAction(ISD::SELECT, MVT::i32, Expand);
|
||||
setOperationAction(ISD::SELECT, MVT::f32, Expand);
|
||||
|
@ -259,6 +271,31 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||
SDOperand Lo = DAG.getNode(V8ISD::Lo, MVT::i32, CP);
|
||||
return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi);
|
||||
}
|
||||
case ISD::FP_TO_SINT: {
|
||||
// Convert the fp value to integer in an FP register.
|
||||
Op = DAG.getNode(V8ISD::FTOI, Op.getOperand(0).getValueType(),
|
||||
Op.getOperand(0));
|
||||
int Size = Op.getOperand(0).getValueType() == MVT::f32 ? 4 : 8;
|
||||
int FrameIdx =
|
||||
DAG.getMachineFunction().getFrameInfo()->CreateStackObject(Size, Size);
|
||||
SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32);
|
||||
SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
|
||||
Op, FI, DAG.getSrcValue(0));
|
||||
return DAG.getLoad(MVT::i32, ST, FI, DAG.getSrcValue(0));
|
||||
}
|
||||
case ISD::SINT_TO_FP: {
|
||||
int Size = Op.getOperand(0).getValueType() == MVT::f32 ? 4 : 8;
|
||||
int FrameIdx =
|
||||
DAG.getMachineFunction().getFrameInfo()->CreateStackObject(Size, Size);
|
||||
SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32);
|
||||
SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
|
||||
Op.getOperand(0), FI, DAG.getSrcValue(0));
|
||||
|
||||
Op = DAG.getLoad(Op.getValueType(), ST, FI, DAG.getSrcValue(0));
|
||||
|
||||
// Convert the int value to FP in an FP register.
|
||||
return DAG.getNode(V8ISD::ITOF, Op.getValueType(), Op);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,34 +348,29 @@ void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
|||
ScheduleAndEmitDAG(DAG);
|
||||
}
|
||||
|
||||
bool SparcV8DAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1,
|
||||
SDOperand &R2) {
|
||||
if (Addr.getOpcode() == ISD::ADD) {
|
||||
if (isa<ConstantSDNode>(Addr.getOperand(1)) &&
|
||||
Predicate_simm13(Addr.getOperand(1).Val))
|
||||
return false; // Let the reg+imm pattern catch this!
|
||||
if (Addr.getOperand(0).getOpcode() == V8ISD::Lo ||
|
||||
Addr.getOperand(1).getOpcode() == V8ISD::Lo)
|
||||
return false; // Let the reg+imm pattern catch this!
|
||||
R1 = Select(Addr.getOperand(0));
|
||||
R2 = Select(Addr.getOperand(1));
|
||||
return true;
|
||||
}
|
||||
|
||||
R1 = Select(Addr);
|
||||
R2 = CurDAG->getRegister(V8::G0, MVT::i32);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base,
|
||||
SDOperand &Offset) {
|
||||
if (Addr.getOpcode() == ISD::FrameIndex) {
|
||||
int FI = cast<FrameIndexSDNode>(Addr)->getIndex();
|
||||
Base = CurDAG->getTargetFrameIndex(FI, MVT::i32);
|
||||
Offset = CurDAG->getTargetConstant(0, MVT::i32);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Addr.getOpcode() == ISD::ADD) {
|
||||
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
|
||||
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
|
||||
if (Predicate_simm13(CN)) {
|
||||
if (Addr.getOperand(0).getOpcode() == ISD::FrameIndex) {
|
||||
// Constant offset from frame ref.
|
||||
int FI = cast<FrameIndexSDNode>(Addr)->getIndex();
|
||||
Base = CurDAG->getTargetFrameIndex(FI, MVT::i32);
|
||||
} else {
|
||||
Base = Select(Addr.getOperand(0));
|
||||
}
|
||||
Offset = CurDAG->getTargetConstant(CN->getValue(), MVT::i32);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (Addr.getOperand(0).getOpcode() == V8ISD::Lo) {
|
||||
Base = Select(Addr.getOperand(1));
|
||||
Offset = Addr.getOperand(0).getOperand(0);
|
||||
|
@ -355,6 +387,25 @@ bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SparcV8DAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1,
|
||||
SDOperand &R2) {
|
||||
if (Addr.getOpcode() == ISD::FrameIndex) return false;
|
||||
if (Addr.getOpcode() == ISD::ADD) {
|
||||
if (isa<ConstantSDNode>(Addr.getOperand(1)) &&
|
||||
Predicate_simm13(Addr.getOperand(1).Val))
|
||||
return false; // Let the reg+imm pattern catch this!
|
||||
if (Addr.getOperand(0).getOpcode() == V8ISD::Lo ||
|
||||
Addr.getOperand(1).getOpcode() == V8ISD::Lo)
|
||||
return false; // Let the reg+imm pattern catch this!
|
||||
R1 = Select(Addr.getOperand(0));
|
||||
R2 = Select(Addr.getOperand(1));
|
||||
return true;
|
||||
}
|
||||
|
||||
R1 = Select(Addr);
|
||||
R2 = CurDAG->getRegister(V8::G0, MVT::i32);
|
||||
return true;
|
||||
}
|
||||
|
||||
SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
|
||||
SDNode *N = Op.Val;
|
||||
|
@ -368,6 +419,17 @@ SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
|
|||
switch (N->getOpcode()) {
|
||||
default: break;
|
||||
case ISD::BasicBlock: return CodeGenMap[Op] = Op;
|
||||
case ISD::FrameIndex: {
|
||||
int FI = cast<FrameIndexSDNode>(N)->getIndex();
|
||||
if (N->hasOneUse())
|
||||
return CurDAG->SelectNodeTo(N, V8::ADDri, MVT::i32,
|
||||
CurDAG->getTargetFrameIndex(FI, MVT::i32),
|
||||
CurDAG->getTargetConstant(0, MVT::i32));
|
||||
return CodeGenMap[Op] =
|
||||
CurDAG->getTargetNode(V8::ADDri, MVT::i32,
|
||||
CurDAG->getTargetFrameIndex(FI, MVT::i32),
|
||||
CurDAG->getTargetConstant(0, MVT::i32));
|
||||
}
|
||||
case V8ISD::CMPICC: {
|
||||
// FIXME: Handle compare with immediate.
|
||||
SDOperand LHS = Select(N->getOperand(0));
|
||||
|
|
|
@ -87,6 +87,9 @@ def V8brfcc : SDNode<"V8ISD::BRFCC", SDTV8brcc, [SDNPHasChain]>;
|
|||
def V8hi : SDNode<"V8ISD::Hi", SDTIntUnaryOp>;
|
||||
def V8lo : SDNode<"V8ISD::Lo", SDTIntUnaryOp>;
|
||||
|
||||
def V8ftoi : SDNode<"V8ISD::FTOI", SDTFPUnaryOp>;
|
||||
def V8itof : SDNode<"V8ISD::ITOF", SDTFPUnaryOp>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -104,7 +107,8 @@ def ADJCALLSTACKUP : PseudoInstV8<"!ADJCALLSTACKUP $amt",
|
|||
//def IMPLICIT_USE : PseudoInstV8<"!IMPLICIT_USE",(ops variable_ops)>;
|
||||
def IMPLICIT_DEF : PseudoInstV8<"!IMPLICIT_DEF $dst",
|
||||
(ops IntRegs:$dst)>;
|
||||
def FpMOVD : PseudoInstV8<"!FpMOVD", (ops)>; // pseudo 64-bit double move
|
||||
def FpMOVD : PseudoInstV8<"!FpMOVD", // pseudo 64-bit double move
|
||||
(ops DFPRegs:$dst, DFPRegs:$src)>;
|
||||
|
||||
// Section A.3 - Synthetic Instructions, p. 85
|
||||
// special cases of JMPL:
|
||||
|
@ -544,18 +548,22 @@ def WRYri : F3_2<2, 0b110000,
|
|||
// Convert Integer to Floating-point Instructions, p. 141
|
||||
def FITOS : F3_3<2, 0b110100, 0b011000100,
|
||||
(ops FPRegs:$dst, FPRegs:$src),
|
||||
"fitos $src, $dst", []>;
|
||||
"fitos $src, $dst",
|
||||
[(set FPRegs:$dst, (V8itof FPRegs:$src))]>;
|
||||
def FITOD : F3_3<2, 0b110100, 0b011001000,
|
||||
(ops DFPRegs:$dst, DFPRegs:$src),
|
||||
"fitod $src, $dst", []>;
|
||||
"fitod $src, $dst",
|
||||
[(set DFPRegs:$dst, (V8itof DFPRegs:$src))]>;
|
||||
|
||||
// Convert Floating-point to Integer Instructions, p. 142
|
||||
def FSTOI : F3_3<2, 0b110100, 0b011010001,
|
||||
(ops FPRegs:$dst, FPRegs:$src),
|
||||
"fstoi $src, $dst", []>;
|
||||
"fstoi $src, $dst",
|
||||
[(set FPRegs:$dst, (V8ftoi FPRegs:$src))]>;
|
||||
def FDTOI : F3_3<2, 0b110100, 0b011010010,
|
||||
(ops DFPRegs:$dst, DFPRegs:$src),
|
||||
"fdtoi $src, $dst", []>;
|
||||
"fdtoi $src, $dst",
|
||||
[(set DFPRegs:$dst, (V8ftoi DFPRegs:$src))]>;
|
||||
|
||||
// Convert between Floating-point Formats Instructions, p. 143
|
||||
def FSTOD : F3_3<2, 0b110100, 0b011001001,
|
||||
|
|
Loading…
Reference in New Issue