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 "SparcV8.h"
|
||||||
#include "SparcV8TargetMachine.h"
|
#include "SparcV8TargetMachine.h"
|
||||||
#include "llvm/Function.h"
|
#include "llvm/Function.h"
|
||||||
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
#include "llvm/CodeGen/SelectionDAG.h"
|
#include "llvm/CodeGen/SelectionDAG.h"
|
||||||
#include "llvm/CodeGen/SelectionDAGISel.h"
|
#include "llvm/CodeGen/SelectionDAGISel.h"
|
||||||
|
@ -36,6 +37,9 @@ namespace V8ISD {
|
||||||
BRFCC, // Branch to dest on fcc condition
|
BRFCC, // Branch to dest on fcc condition
|
||||||
|
|
||||||
Hi, Lo, // Hi/Lo operations, typically on a global address.
|
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::UREM, MVT::i32, Expand);
|
||||||
setOperationAction(ISD::SREM, 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.
|
// Sparc has no select or setcc: expand to SELECT_CC.
|
||||||
setOperationAction(ISD::SELECT, MVT::i32, Expand);
|
setOperationAction(ISD::SELECT, MVT::i32, Expand);
|
||||||
setOperationAction(ISD::SELECT, MVT::f32, 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);
|
SDOperand Lo = DAG.getNode(V8ISD::Lo, MVT::i32, CP);
|
||||||
return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi);
|
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);
|
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,
|
bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base,
|
||||||
SDOperand &Offset) {
|
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 (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 (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));
|
Base = Select(Addr.getOperand(0));
|
||||||
|
}
|
||||||
Offset = CurDAG->getTargetConstant(CN->getValue(), MVT::i32);
|
Offset = CurDAG->getTargetConstant(CN->getValue(), MVT::i32);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (Addr.getOperand(0).getOpcode() == V8ISD::Lo) {
|
if (Addr.getOperand(0).getOpcode() == V8ISD::Lo) {
|
||||||
Base = Select(Addr.getOperand(1));
|
Base = Select(Addr.getOperand(1));
|
||||||
Offset = Addr.getOperand(0).getOperand(0);
|
Offset = Addr.getOperand(0).getOperand(0);
|
||||||
|
@ -355,6 +387,25 @@ bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base,
|
||||||
return true;
|
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) {
|
SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
|
||||||
SDNode *N = Op.Val;
|
SDNode *N = Op.Val;
|
||||||
|
@ -368,6 +419,17 @@ SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
|
||||||
switch (N->getOpcode()) {
|
switch (N->getOpcode()) {
|
||||||
default: break;
|
default: break;
|
||||||
case ISD::BasicBlock: return CodeGenMap[Op] = Op;
|
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: {
|
case V8ISD::CMPICC: {
|
||||||
// FIXME: Handle compare with immediate.
|
// FIXME: Handle compare with immediate.
|
||||||
SDOperand LHS = Select(N->getOperand(0));
|
SDOperand LHS = Select(N->getOperand(0));
|
||||||
|
|
|
@ -87,6 +87,9 @@ def V8brfcc : SDNode<"V8ISD::BRFCC", SDTV8brcc, [SDNPHasChain]>;
|
||||||
def V8hi : SDNode<"V8ISD::Hi", SDTIntUnaryOp>;
|
def V8hi : SDNode<"V8ISD::Hi", SDTIntUnaryOp>;
|
||||||
def V8lo : SDNode<"V8ISD::Lo", SDTIntUnaryOp>;
|
def V8lo : SDNode<"V8ISD::Lo", SDTIntUnaryOp>;
|
||||||
|
|
||||||
|
def V8ftoi : SDNode<"V8ISD::FTOI", SDTFPUnaryOp>;
|
||||||
|
def V8itof : SDNode<"V8ISD::ITOF", SDTFPUnaryOp>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Instructions
|
// Instructions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -104,7 +107,8 @@ def ADJCALLSTACKUP : PseudoInstV8<"!ADJCALLSTACKUP $amt",
|
||||||
//def IMPLICIT_USE : PseudoInstV8<"!IMPLICIT_USE",(ops variable_ops)>;
|
//def IMPLICIT_USE : PseudoInstV8<"!IMPLICIT_USE",(ops variable_ops)>;
|
||||||
def IMPLICIT_DEF : PseudoInstV8<"!IMPLICIT_DEF $dst",
|
def IMPLICIT_DEF : PseudoInstV8<"!IMPLICIT_DEF $dst",
|
||||||
(ops IntRegs:$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
|
// Section A.3 - Synthetic Instructions, p. 85
|
||||||
// special cases of JMPL:
|
// special cases of JMPL:
|
||||||
|
@ -544,18 +548,22 @@ def WRYri : F3_2<2, 0b110000,
|
||||||
// Convert Integer to Floating-point Instructions, p. 141
|
// Convert Integer to Floating-point Instructions, p. 141
|
||||||
def FITOS : F3_3<2, 0b110100, 0b011000100,
|
def FITOS : F3_3<2, 0b110100, 0b011000100,
|
||||||
(ops FPRegs:$dst, FPRegs:$src),
|
(ops FPRegs:$dst, FPRegs:$src),
|
||||||
"fitos $src, $dst", []>;
|
"fitos $src, $dst",
|
||||||
|
[(set FPRegs:$dst, (V8itof FPRegs:$src))]>;
|
||||||
def FITOD : F3_3<2, 0b110100, 0b011001000,
|
def FITOD : F3_3<2, 0b110100, 0b011001000,
|
||||||
(ops DFPRegs:$dst, DFPRegs:$src),
|
(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
|
// Convert Floating-point to Integer Instructions, p. 142
|
||||||
def FSTOI : F3_3<2, 0b110100, 0b011010001,
|
def FSTOI : F3_3<2, 0b110100, 0b011010001,
|
||||||
(ops FPRegs:$dst, FPRegs:$src),
|
(ops FPRegs:$dst, FPRegs:$src),
|
||||||
"fstoi $src, $dst", []>;
|
"fstoi $src, $dst",
|
||||||
|
[(set FPRegs:$dst, (V8ftoi FPRegs:$src))]>;
|
||||||
def FDTOI : F3_3<2, 0b110100, 0b011010010,
|
def FDTOI : F3_3<2, 0b110100, 0b011010010,
|
||||||
(ops DFPRegs:$dst, DFPRegs:$src),
|
(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
|
// Convert between Floating-point Formats Instructions, p. 143
|
||||||
def FSTOD : F3_3<2, 0b110100, 0b011001001,
|
def FSTOD : F3_3<2, 0b110100, 0b011001001,
|
||||||
|
|
Loading…
Reference in New Issue