Add frameindex support

Add support for copying (e.g. returning) doubles
Add support for F<->I instructions


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24818 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2005-12-18 06:59:57 +00:00
parent abfc2a7363
commit 8fa54dc702
4 changed files with 202 additions and 62 deletions

View File

@ -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.
};
}
@ -85,6 +89,14 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM)
// Sparc has no REM operation.
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);
@ -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,8 +348,48 @@ void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
ScheduleAndEmitDAG(DAG);
}
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 (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);
return true;
}
if (Addr.getOperand(1).getOpcode() == V8ISD::Lo) {
Base = Select(Addr.getOperand(0));
Offset = Addr.getOperand(1).getOperand(0);
return true;
}
}
Base = Select(Addr);
Offset = CurDAG->getTargetConstant(0, MVT::i32);
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))
@ -330,32 +407,6 @@ bool SparcV8DAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1,
return true;
}
bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base,
SDOperand &Offset) {
if (Addr.getOpcode() == ISD::ADD) {
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
if (Predicate_simm13(CN)) {
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);
return true;
}
if (Addr.getOperand(1).getOpcode() == V8ISD::Lo) {
Base = Select(Addr.getOperand(0));
Offset = Addr.getOperand(1).getOperand(0);
return true;
}
}
Base = Select(Addr);
Offset = CurDAG->getTargetConstant(0, MVT::i32);
return true;
}
SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
SDNode *N = Op.Val;
if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
@ -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));

View File

@ -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,

View File

@ -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.
};
}
@ -85,6 +89,14 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM)
// Sparc has no REM operation.
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);
@ -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,8 +348,48 @@ void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
ScheduleAndEmitDAG(DAG);
}
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 (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);
return true;
}
if (Addr.getOperand(1).getOpcode() == V8ISD::Lo) {
Base = Select(Addr.getOperand(0));
Offset = Addr.getOperand(1).getOperand(0);
return true;
}
}
Base = Select(Addr);
Offset = CurDAG->getTargetConstant(0, MVT::i32);
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))
@ -330,32 +407,6 @@ bool SparcV8DAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1,
return true;
}
bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base,
SDOperand &Offset) {
if (Addr.getOpcode() == ISD::ADD) {
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
if (Predicate_simm13(CN)) {
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);
return true;
}
if (Addr.getOperand(1).getOpcode() == V8ISD::Lo) {
Base = Select(Addr.getOperand(0));
Offset = Addr.getOperand(1).getOperand(0);
return true;
}
}
Base = Select(Addr);
Offset = CurDAG->getTargetConstant(0, MVT::i32);
return true;
}
SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
SDNode *N = Op.Val;
if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
@ -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));

View File

@ -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,