mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-18 12:29:21 +00:00
so, if you beat on it, you too can talk emacs into having a sane indenting policy... Also, optimize many function calls with pc-relative calls (partial prologue skipping for that case coming soon), try to fix the random jumps to strange places problem by pesimizing div et. al. register usage and fixing up GP before using, some calling convention tweaks, and make frame pointer unallocatable (not strickly necessary, but let's go for correctness first)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@20106 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3d261f5ae3
commit
63f2ab2d1b
@ -56,7 +56,8 @@ namespace {
|
||||
setOperationAction(ISD::SEXTLOAD , MVT::i8 , Expand);
|
||||
setOperationAction(ISD::SEXTLOAD , MVT::i16 , Expand);
|
||||
|
||||
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); //what is the sign expansion of 1? 1 or -1?
|
||||
//what is the sign expansion of 1? 1 or -1?
|
||||
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
|
||||
|
||||
setOperationAction(ISD::SREM , MVT::f32 , Expand);
|
||||
setOperationAction(ISD::SREM , MVT::f64 , Expand);
|
||||
@ -148,14 +149,20 @@ AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
|
||||
SDOperand newroot, argt;
|
||||
if (count < 6) {
|
||||
switch (getValueType(I->getType())) {
|
||||
default: std::cerr << "Unknown Type " << getValueType(I->getType()) << "\n"; abort();
|
||||
default:
|
||||
std::cerr << "Unknown Type " << getValueType(I->getType()) << "\n";
|
||||
abort();
|
||||
case MVT::f64:
|
||||
case MVT::f32:
|
||||
BuildMI(&BB, Alpha::IDEF, 0, args_float[count]);
|
||||
argVreg[count] = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(getValueType(I->getType())));
|
||||
argVreg[count] =
|
||||
MF.getSSARegMap()->createVirtualRegister(
|
||||
getRegClassFor(getValueType(I->getType())));
|
||||
argPreg[count] = args_float[count];
|
||||
argOpc[count] = Alpha::CPYS;
|
||||
argt = newroot = DAG.getCopyFromReg(argVreg[count], getValueType(I->getType()), DAG.getRoot());
|
||||
argt = newroot = DAG.getCopyFromReg(argVreg[count],
|
||||
getValueType(I->getType()),
|
||||
DAG.getRoot());
|
||||
break;
|
||||
case MVT::i1:
|
||||
case MVT::i8:
|
||||
@ -163,12 +170,15 @@ AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
|
||||
case MVT::i32:
|
||||
case MVT::i64:
|
||||
BuildMI(&BB, Alpha::IDEF, 0, args_int[count]);
|
||||
argVreg[count] =MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64));
|
||||
argVreg[count] =
|
||||
MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64));
|
||||
argPreg[count] = args_int[count];
|
||||
argOpc[count] = Alpha::BIS;
|
||||
argt = newroot = DAG.getCopyFromReg(argVreg[count], MVT::i64, DAG.getRoot());
|
||||
argt = newroot =
|
||||
DAG.getCopyFromReg(argVreg[count], MVT::i64, DAG.getRoot());
|
||||
if (getValueType(I->getType()) != MVT::i64)
|
||||
argt = DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()), newroot);
|
||||
argt =
|
||||
DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()), newroot);
|
||||
break;
|
||||
}
|
||||
++count;
|
||||
@ -176,9 +186,11 @@ AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
|
||||
// Create the frame index object for this incoming parameter...
|
||||
int FI = MFI->CreateFixedObject(8, 8 * (count - 6));
|
||||
|
||||
// Create the SelectionDAG nodes corresponding to a load from this parameter
|
||||
// Create the SelectionDAG nodes corresponding to a load
|
||||
//from this parameter
|
||||
SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64);
|
||||
argt = newroot = DAG.getLoad(getValueType(I->getType()), DAG.getEntryNode(), FIN);
|
||||
argt = newroot = DAG.getLoad(getValueType(I->getType()),
|
||||
DAG.getEntryNode(), FIN);
|
||||
}
|
||||
DAG.setRoot(newroot.getValue(1));
|
||||
ArgValues.push_back(argt);
|
||||
@ -186,14 +198,15 @@ AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
|
||||
|
||||
BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29);
|
||||
BuildMI(&BB, Alpha::BIS, 2, GP).addReg(Alpha::R29).addReg(Alpha::R29);
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
if (argPreg[i] == Alpha::F16 || argPreg[i] == Alpha::F17 || argPreg[i] == Alpha::F18 ||
|
||||
argPreg[i] == Alpha::F19 || argPreg[i] == Alpha::F20 || argPreg[i] == Alpha::F21)
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (argPreg[i] == Alpha::F16 || argPreg[i] == Alpha::F17 ||
|
||||
argPreg[i] == Alpha::F18 || argPreg[i] == Alpha::F19 ||
|
||||
argPreg[i] == Alpha::F20 || argPreg[i] == Alpha::F21)
|
||||
{
|
||||
assert(argOpc[i] == Alpha::CPYS && "Using BIS for a float??");
|
||||
}
|
||||
BuildMI(&BB, argOpc[i], 2, argVreg[i]).addReg(argPreg[i]).addReg(argPreg[i]);
|
||||
BuildMI(&BB, argOpc[i], 2,
|
||||
argVreg[i]).addReg(argPreg[i]).addReg(argPreg[i]);
|
||||
}
|
||||
|
||||
return ArgValues;
|
||||
@ -239,7 +252,8 @@ AlphaTargetLowering::LowerCallTo(SDOperand Chain,
|
||||
RetVals.push_back(RetTyVT);
|
||||
RetVals.push_back(MVT::Other);
|
||||
|
||||
SDOperand TheCall = SDOperand(DAG.getCall(RetVals, Chain, Callee, args_to_use), 0);
|
||||
SDOperand TheCall = SDOperand(DAG.getCall(RetVals,
|
||||
Chain, Callee, args_to_use), 0);
|
||||
Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
|
||||
Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain,
|
||||
DAG.getConstant(NumBytes, getPointerTy()));
|
||||
@ -271,11 +285,11 @@ LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
|
||||
|
||||
namespace {
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// ISel - Alpha specific code to select Alpha machine instructions for
|
||||
/// SelectionDAG operations.
|
||||
///
|
||||
class ISel : public SelectionDAGISel {
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// ISel - Alpha specific code to select Alpha machine instructions for
|
||||
/// SelectionDAG operations.
|
||||
//===--------------------------------------------------------------------===//
|
||||
class ISel : public SelectionDAGISel {
|
||||
|
||||
/// AlphaLowering - This object fully describes how to lower LLVM code to an
|
||||
/// Alpha-specific SelectionDAG.
|
||||
@ -291,9 +305,9 @@ namespace {
|
||||
//CCInvMap sometimes (SetNE) we have the inverse CC code for free
|
||||
std::map<SDOperand, unsigned> CCInvMap;
|
||||
|
||||
public:
|
||||
ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {
|
||||
}
|
||||
public:
|
||||
ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM)
|
||||
{}
|
||||
|
||||
/// InstructionSelectBasicBlock - This callback is invoked by
|
||||
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
||||
@ -312,7 +326,7 @@ namespace {
|
||||
|
||||
void SelectAddr(SDOperand N, unsigned& Reg, long& offset);
|
||||
void SelectBranchCC(SDOperand N);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
static unsigned GetSymVersion(unsigned opcode)
|
||||
@ -341,13 +355,15 @@ void ISel::SelectAddr(SDOperand N, unsigned& Reg, long& offset)
|
||||
{
|
||||
unsigned opcode = N.getOpcode();
|
||||
if (opcode == ISD::ADD) {
|
||||
if(N.getOperand(1).getOpcode() == ISD::Constant && cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 32767)
|
||||
if(N.getOperand(1).getOpcode() == ISD::Constant &&
|
||||
cast<ConstantSDNode>(N.getOperand(1))->getValue() <= 32767)
|
||||
{ //Normal imm add
|
||||
Reg = SelectExpr(N.getOperand(0));
|
||||
offset = cast<ConstantSDNode>(N.getOperand(1))->getValue();
|
||||
return;
|
||||
}
|
||||
else if(N.getOperand(0).getOpcode() == ISD::Constant && cast<ConstantSDNode>(N.getOperand(0))->getValue() <= 32767)
|
||||
else if(N.getOperand(0).getOpcode() == ISD::Constant &&
|
||||
cast<ConstantSDNode>(N.getOperand(0))->getValue() <= 32767)
|
||||
{
|
||||
Reg = SelectExpr(N.getOperand(1));
|
||||
offset = cast<ConstantSDNode>(N.getOperand(0))->getValue();
|
||||
@ -362,8 +378,9 @@ void ISel::SelectAddr(SDOperand N, unsigned& Reg, long& offset)
|
||||
void ISel::SelectBranchCC(SDOperand N)
|
||||
{
|
||||
assert(N.getOpcode() == ISD::BRCOND && "Not a BranchCC???");
|
||||
MachineBasicBlock *Dest = cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
|
||||
unsigned Opc;
|
||||
MachineBasicBlock *Dest =
|
||||
cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
|
||||
unsigned Opc = Alpha::WTF;
|
||||
|
||||
Select(N.getOperand(0)); //chain
|
||||
SDOperand CC = N.getOperand(1);
|
||||
@ -386,8 +403,7 @@ void ISel::SelectBranchCC(SDOperand N)
|
||||
if(SetCC->getCondition() == ISD::SETNE)
|
||||
isNE = true;
|
||||
|
||||
if (isZero0)
|
||||
{
|
||||
if (isZero0) {
|
||||
switch (SetCC->getCondition()) {
|
||||
default: CC.Val->dump(); assert(0 && "Unknown integer comparison!");
|
||||
case ISD::SETEQ: Opc = Alpha::BEQ; break;
|
||||
@ -404,9 +420,7 @@ void ISel::SelectBranchCC(SDOperand N)
|
||||
unsigned Tmp1 = SelectExpr(SetCC->getOperand(1));
|
||||
BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest);
|
||||
return;
|
||||
}
|
||||
else if (isZero1)
|
||||
{
|
||||
} else if (isZero1) {
|
||||
switch (SetCC->getCondition()) {
|
||||
default: CC.Val->dump(); assert(0 && "Unknown integer comparison!");
|
||||
case ISD::SETEQ: Opc = Alpha::BEQ; break;
|
||||
@ -423,9 +437,7 @@ void ISel::SelectBranchCC(SDOperand N)
|
||||
unsigned Tmp1 = SelectExpr(SetCC->getOperand(0));
|
||||
BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
unsigned Tmp1 = SelectExpr(CC);
|
||||
if (isNE)
|
||||
BuildMI(BB, Alpha::BEQ, 2).addReg(CCInvMap[CC]).addMBB(Dest);
|
||||
@ -458,9 +470,8 @@ void ISel::SelectBranchCC(SDOperand N)
|
||||
return;
|
||||
}
|
||||
abort(); //Should never be reached
|
||||
}
|
||||
else
|
||||
{ //Giveup and do the stupid thing
|
||||
} else {
|
||||
//Giveup and do the stupid thing
|
||||
unsigned Tmp1 = SelectExpr(CC);
|
||||
BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
|
||||
return;
|
||||
@ -502,13 +513,17 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
|
||||
}
|
||||
|
||||
case ISD::FP_ROUND:
|
||||
assert (DestType == MVT::f32 && N.getOperand(0).getValueType() == MVT::f64 && "only f64 to f32 conversion supported here");
|
||||
assert (DestType == MVT::f32 &&
|
||||
N.getOperand(0).getValueType() == MVT::f64 &&
|
||||
"only f64 to f32 conversion supported here");
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
BuildMI(BB, Alpha::CVTTS, 1, Result).addReg(Tmp1);
|
||||
return Result;
|
||||
|
||||
case ISD::FP_EXTEND:
|
||||
assert (DestType == MVT::f64 && N.getOperand(0).getValueType() == MVT::f32 && "only f32 to f64 conversion supported here");
|
||||
assert (DestType == MVT::f64 &&
|
||||
N.getOperand(0).getValueType() == MVT::f32 &&
|
||||
"only f32 to f64 conversion supported here");
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp1);
|
||||
return Result;
|
||||
@ -545,8 +560,7 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
|
||||
Select(Chain);
|
||||
Opc = DestType == MVT::f64 ? Alpha::LDT : Alpha::LDS;
|
||||
|
||||
if (Address.getOpcode() == ISD::GlobalAddress)
|
||||
{
|
||||
if (Address.getOpcode() == ISD::GlobalAddress) {
|
||||
AlphaLowering.restoreGP(BB);
|
||||
Opc = GetSymVersion(Opc);
|
||||
BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
|
||||
@ -556,13 +570,10 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
|
||||
Opc = GetSymVersion(Opc);
|
||||
BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex());
|
||||
}
|
||||
else if(Address.getOpcode() == ISD::FrameIndex)
|
||||
{
|
||||
else if(Address.getOpcode() == ISD::FrameIndex) {
|
||||
Tmp1 = cast<FrameIndexSDNode>(Address)->getIndex();
|
||||
BuildMI(BB, Opc, 2, Result).addFrameIndex(Tmp1).addReg(Alpha::F31);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
long offset;
|
||||
SelectAddr(Address, Tmp1, offset);
|
||||
BuildMI(BB, Opc, 2, Result).addImm(offset).addReg(Tmp1);
|
||||
@ -606,30 +617,28 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
|
||||
|
||||
Tmp1 = MakeReg(MVT::f32);
|
||||
|
||||
assert(cast<MVTSDNode>(Node)->getExtraValueType() == MVT::f32 && "EXTLOAD not from f32");
|
||||
assert(cast<MVTSDNode>(Node)->getExtraValueType() == MVT::f32 &&
|
||||
"EXTLOAD not from f32");
|
||||
assert(Node->getValueType(0) == MVT::f64 && "EXTLOAD not to f64");
|
||||
|
||||
SDOperand Chain = N.getOperand(0);
|
||||
SDOperand Address = N.getOperand(1);
|
||||
Select(Chain);
|
||||
|
||||
if (Address.getOpcode() == ISD::GlobalAddress)
|
||||
{
|
||||
if (Address.getOpcode() == ISD::GlobalAddress) {
|
||||
AlphaLowering.restoreGP(BB);
|
||||
BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
|
||||
}
|
||||
else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N.getOperand(1)))
|
||||
else if (ConstantPoolSDNode *CP =
|
||||
dyn_cast<ConstantPoolSDNode>(N.getOperand(1)))
|
||||
{
|
||||
AlphaLowering.restoreGP(BB);
|
||||
BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addConstantPoolIndex(CP->getIndex());
|
||||
}
|
||||
else if(Address.getOpcode() == ISD::FrameIndex)
|
||||
{
|
||||
else if(Address.getOpcode() == ISD::FrameIndex) {
|
||||
Tmp2 = cast<FrameIndexSDNode>(Address)->getIndex();
|
||||
BuildMI(BB, Alpha::LDS, 2, Tmp1).addFrameIndex(Tmp2).addReg(Alpha::F31);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
long offset;
|
||||
SelectAddr(Address, Tmp2, offset);
|
||||
BuildMI(BB, Alpha::LDS, 1, Tmp1).addImm(offset).addReg(Tmp2);
|
||||
@ -641,7 +650,8 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
|
||||
case ISD::UINT_TO_FP:
|
||||
case ISD::SINT_TO_FP:
|
||||
{
|
||||
assert (N.getOperand(0).getValueType() == MVT::i64 && "only quads can be loaded from");
|
||||
assert (N.getOperand(0).getValueType() == MVT::i64
|
||||
&& "only quads can be loaded from");
|
||||
Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
|
||||
Tmp2 = MakeReg(MVT::f64);
|
||||
|
||||
@ -657,11 +667,11 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
|
||||
BuildMI(BB, Opc, 1, Result).addReg(Tmp2);
|
||||
|
||||
//The easy way: doesn't work
|
||||
// //so these instructions are not supported on ev56
|
||||
// Opc = DestType == MVT::f64 ? Alpha::ITOFT : Alpha::ITOFS;
|
||||
// BuildMI(BB, Opc, 1, Tmp2).addReg(Tmp1);
|
||||
// Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
|
||||
// BuildMI(BB, Opc, 1, Result).addReg(Tmp1);
|
||||
// //so these instructions are not supported on ev56
|
||||
// Opc = DestType == MVT::f64 ? Alpha::ITOFT : Alpha::ITOFS;
|
||||
// BuildMI(BB, Opc, 1, Tmp2).addReg(Tmp1);
|
||||
// Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
|
||||
// BuildMI(BB, Opc, 1, Result).addReg(Tmp1);
|
||||
|
||||
return Result;
|
||||
}
|
||||
@ -701,8 +711,10 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
||||
|
||||
if (DestType == MVT::f64 || DestType == MVT::f32 ||
|
||||
(
|
||||
(opcode == ISD::LOAD || opcode == ISD::CopyFromReg || opcode == ISD::EXTLOAD) &&
|
||||
(N.getValue(0).getValueType() == MVT::f32 || N.getValue(0).getValueType() == MVT::f64)
|
||||
(opcode == ISD::LOAD || opcode == ISD::CopyFromReg ||
|
||||
opcode == ISD::EXTLOAD) &&
|
||||
(N.getValue(0).getValueType() == MVT::f32 ||
|
||||
N.getValue(0).getValueType() == MVT::f64)
|
||||
)
|
||||
)
|
||||
return SelectExprFP(N, Result);
|
||||
@ -738,20 +750,23 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
||||
SDOperand Address = N.getOperand(1);
|
||||
Select(Chain);
|
||||
|
||||
assert(Node->getValueType(0) == MVT::i64 && "Unknown type to sign extend to.");
|
||||
assert(Node->getValueType(0) == MVT::i64 &&
|
||||
"Unknown type to sign extend to.");
|
||||
if (opcode == ISD::LOAD)
|
||||
Opc = Alpha::LDQ;
|
||||
else
|
||||
switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
|
||||
default: Node->dump(); assert(0 && "Bad sign extend!");
|
||||
case MVT::i32: Opc = Alpha::LDL; assert(opcode != ISD::ZEXTLOAD && "Not sext"); break;
|
||||
case MVT::i16: Opc = Alpha::LDWU; assert(opcode != ISD::SEXTLOAD && "Not zext"); break;
|
||||
case MVT::i32: Opc = Alpha::LDL;
|
||||
assert(opcode != ISD::ZEXTLOAD && "Not sext"); break;
|
||||
case MVT::i16: Opc = Alpha::LDWU;
|
||||
assert(opcode != ISD::SEXTLOAD && "Not zext"); break;
|
||||
case MVT::i1: //FIXME: Treat i1 as i8 since there are problems otherwise
|
||||
case MVT::i8: Opc = Alpha::LDBU; assert(opcode != ISD::SEXTLOAD && "Not zext"); break;
|
||||
case MVT::i8: Opc = Alpha::LDBU;
|
||||
assert(opcode != ISD::SEXTLOAD && "Not zext"); break;
|
||||
}
|
||||
|
||||
if (Address.getOpcode() == ISD::GlobalAddress)
|
||||
{
|
||||
if (Address.getOpcode() == ISD::GlobalAddress) {
|
||||
AlphaLowering.restoreGP(BB);
|
||||
Opc = GetSymVersion(Opc);
|
||||
BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
|
||||
@ -761,13 +776,10 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
||||
Opc = GetSymVersion(Opc);
|
||||
BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex());
|
||||
}
|
||||
else if(Address.getOpcode() == ISD::FrameIndex)
|
||||
{
|
||||
else if(Address.getOpcode() == ISD::FrameIndex) {
|
||||
Tmp1 = cast<FrameIndexSDNode>(Address)->getIndex();
|
||||
BuildMI(BB, Opc, 2, Result).addFrameIndex(Tmp1).addReg(Alpha::F31);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
long offset;
|
||||
SelectAddr(Address, Tmp1, offset);
|
||||
BuildMI(BB, Opc, 2, Result).addImm(offset).addReg(Tmp1);
|
||||
@ -805,7 +817,8 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
||||
default:
|
||||
Node->dump();
|
||||
N.getOperand(i).Val->dump();
|
||||
std::cerr << "Type for " << i << " is: " << N.getOperand(i+2).getValueType() << "\n";
|
||||
std::cerr << "Type for " << i << " is: " <<
|
||||
N.getOperand(i+2).getValueType() << "\n";
|
||||
assert(0 && "Unknown value type for call");
|
||||
case MVT::i1:
|
||||
case MVT::i8:
|
||||
@ -827,7 +840,8 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
||||
default:
|
||||
Node->dump();
|
||||
N.getOperand(i).Val->dump();
|
||||
std::cerr << "Type for " << i << " is: " << N.getOperand(i+2).getValueType() << "\n";
|
||||
std::cerr << "Type for " << i << " is: " <<
|
||||
N.getOperand(i+2).getValueType() << "\n";
|
||||
assert(0 && "Unknown value type for call");
|
||||
case MVT::i1:
|
||||
case MVT::i8:
|
||||
@ -848,17 +862,21 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
||||
if (GlobalAddressSDNode *GASD =
|
||||
dyn_cast<GlobalAddressSDNode>(N.getOperand(1)))
|
||||
{
|
||||
if (GASD->getGlobal()->isExternal()) {
|
||||
//use safe calling convention
|
||||
AlphaLowering.restoreGP(BB);
|
||||
BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true);
|
||||
} else {
|
||||
//use PC relative branch call
|
||||
BuildMI(BB, Alpha::BSR, 1, Alpha::R26).addGlobalAddress(GASD->getGlobal(),true);
|
||||
}
|
||||
}
|
||||
else if (ExternalSymbolSDNode *ESSDN =
|
||||
dyn_cast<ExternalSymbolSDNode>(N.getOperand(1)))
|
||||
{
|
||||
AlphaLowering.restoreGP(BB);
|
||||
BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
//no need to restore GP as we are doing an indirect call
|
||||
Tmp1 = SelectExpr(N.getOperand(1));
|
||||
BuildMI(BB, Alpha::BIS, 2, Alpha::R27).addReg(Tmp1).addReg(Tmp1);
|
||||
@ -985,14 +1003,22 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
||||
switch (SetCC->getCondition()) {
|
||||
default: Node->dump(); assert(0 && "Unknown integer comparison!");
|
||||
case ISD::SETEQ: Opc = Alpha::CMPEQ; dir=0; break;
|
||||
case ISD::SETLT: Opc = isConst2 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break;
|
||||
case ISD::SETLE: Opc = isConst2 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 1; break;
|
||||
case ISD::SETGT: Opc = isConst1 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 2; break;
|
||||
case ISD::SETGE: Opc = isConst1 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 2; break;
|
||||
case ISD::SETULT: Opc = isConst2 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 1; break;
|
||||
case ISD::SETUGT: Opc = isConst1 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 2; break;
|
||||
case ISD::SETULE: Opc = isConst2 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 1; break;
|
||||
case ISD::SETUGE: Opc = isConst1 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 2; break;
|
||||
case ISD::SETLT:
|
||||
Opc = isConst2 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break;
|
||||
case ISD::SETLE:
|
||||
Opc = isConst2 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 1; break;
|
||||
case ISD::SETGT:
|
||||
Opc = isConst1 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 2; break;
|
||||
case ISD::SETGE:
|
||||
Opc = isConst1 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 2; break;
|
||||
case ISD::SETULT:
|
||||
Opc = isConst2 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 1; break;
|
||||
case ISD::SETUGT:
|
||||
Opc = isConst1 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 2; break;
|
||||
case ISD::SETULE:
|
||||
Opc = isConst2 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 1; break;
|
||||
case ISD::SETUGE:
|
||||
Opc = isConst1 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 2; break;
|
||||
case ISD::SETNE: {//Handle this one special
|
||||
//std::cerr << "Alpha does not have a setne.\n";
|
||||
//abort();
|
||||
@ -1147,9 +1173,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
|
||||
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
switch(opcode) {
|
||||
case ISD::AND: Opc = Alpha::AND; break;
|
||||
case ISD::OR: Opc = Alpha::BIS; break;
|
||||
@ -1187,9 +1211,8 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
||||
if (!isAdd)
|
||||
Tmp2 = -Tmp2;
|
||||
BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp2).addReg(Tmp1);
|
||||
}
|
||||
else
|
||||
{ //Normal add/sub
|
||||
} else {
|
||||
//Normal add/sub
|
||||
Opc = isAdd ? Alpha::ADDQ : Alpha::SUBQ;
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
Tmp2 = SelectExpr(N.getOperand(1));
|
||||
@ -1205,11 +1228,12 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
||||
//FIXME: alpha really doesn't support any of these operations,
|
||||
// the ops are expanded into special library calls with
|
||||
// special calling conventions
|
||||
//Restore GP because it is a call after all...
|
||||
switch(opcode) {
|
||||
case ISD::UREM: Opc = Alpha::REMQU; break;
|
||||
case ISD::SREM: Opc = Alpha::REMQ; break;
|
||||
case ISD::UDIV: Opc = Alpha::DIVQU; break;
|
||||
case ISD::SDIV: Opc = Alpha::DIVQ; break;
|
||||
case ISD::UREM: AlphaLowering.restoreGP(BB); Opc = Alpha::REMQU; break;
|
||||
case ISD::SREM: AlphaLowering.restoreGP(BB); Opc = Alpha::REMQ; break;
|
||||
case ISD::UDIV: AlphaLowering.restoreGP(BB); Opc = Alpha::DIVQU; break;
|
||||
case ISD::SDIV: AlphaLowering.restoreGP(BB); Opc = Alpha::DIVQ; break;
|
||||
}
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
Tmp2 = SelectExpr(N.getOperand(1));
|
||||
@ -1246,7 +1270,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
// // case ISD::FP_TO_UINT:
|
||||
// // case ISD::FP_TO_UINT:
|
||||
|
||||
case ISD::SELECT:
|
||||
{
|
||||
@ -1263,8 +1287,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
||||
unsigned long val = cast<ConstantSDNode>(N)->getValue();
|
||||
if (val < 32000 && (long)val > -32000)
|
||||
BuildMI(BB, Alpha::LOAD_IMM, 1, Result).addImm(val);
|
||||
else
|
||||
{
|
||||
else {
|
||||
MachineConstantPool *CP = BB->getParent()->getConstantPool();
|
||||
ConstantUInt *C = ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val);
|
||||
unsigned CPI = CP->getConstantPoolIndex(C);
|
||||
@ -1331,7 +1354,8 @@ void ISel::Select(SDOperand N) {
|
||||
Tmp2 = cast<RegSDNode>(N)->getReg();
|
||||
|
||||
if (Tmp1 != Tmp2) {
|
||||
if (N.getOperand(1).getValueType() == MVT::f64 || N.getOperand(1).getValueType() == MVT::f32)
|
||||
if (N.getOperand(1).getValueType() == MVT::f64 ||
|
||||
N.getOperand(1).getValueType() == MVT::f32)
|
||||
BuildMI(BB, Alpha::CPYS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
|
||||
else
|
||||
BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
|
||||
@ -1350,7 +1374,8 @@ void ISel::Select(SDOperand N) {
|
||||
Select(N.getOperand(0));
|
||||
Tmp1 = SelectExpr(N.getOperand(1));
|
||||
switch (N.getOperand(1).getValueType()) {
|
||||
default: Node->dump(); assert(0 && "All other types should have been promoted!!");
|
||||
default: Node->dump();
|
||||
assert(0 && "All other types should have been promoted!!");
|
||||
case MVT::f64:
|
||||
case MVT::f32:
|
||||
BuildMI(BB, Alpha::CPYS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1);
|
||||
@ -1423,7 +1448,7 @@ void ISel::Select(SDOperand N) {
|
||||
case ISD::LOAD:
|
||||
case ISD::CopyFromReg:
|
||||
case ISD::CALL:
|
||||
// case ISD::DYNAMIC_STACKALLOC:
|
||||
// case ISD::DYNAMIC_STACKALLOC:
|
||||
ExprMap.erase(N);
|
||||
SelectExpr(N);
|
||||
return;
|
||||
|
@ -53,7 +53,7 @@ let isCall = 1,
|
||||
let isReturn = 1, isTerminator = 1 in
|
||||
def RETURN : PseudoInstAlpha<(ops ), "ret $$31,($$26),1">; //Return from subroutine
|
||||
|
||||
let Uses = [R28] in
|
||||
let Uses = [R28, R29] in
|
||||
def LOAD_IMM : PseudoInstAlpha<(ops GPRC:$RC, s64imm:$IMM), "ldiq $RC,$IMM">; //Load Immediate Quadword
|
||||
|
||||
let Uses = [R29, R28] in {
|
||||
@ -79,7 +79,8 @@ let Uses = [R29, R28] in {
|
||||
def STT_SYM : PseudoInstAlpha<(ops GPRC:$RA, s64imm:$DISP), "stt $RA,$DISP">; //store double
|
||||
}
|
||||
|
||||
let Uses = [R28, R23, R24, R25, R26] in
|
||||
let Uses = [R28, R23, R24, R25, R26, R29],
|
||||
Defs = [R29] in
|
||||
{
|
||||
def REMQU : PseudoInstAlpha<(ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "remqu $RA,$RB,$RC">; //unsigned remander
|
||||
def REMQ : PseudoInstAlpha<(ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "remq $RA,$RB,$RC">; //unsigned remander
|
||||
@ -274,11 +275,10 @@ let isReturn = 1, isTerminator = 1 in
|
||||
def JMP : MForm< 0x1A, (ops GPRC:$RD, GPRC:$RS), "jmp $RD,($RS),0">; //Jump
|
||||
let isCall = 1,
|
||||
Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
|
||||
R20, R21, R22, R23, R24, R25, R27, R29,
|
||||
R20, R21, R22, R23, R24, R25, R27, R28, R29,
|
||||
F0, F1,
|
||||
F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
|
||||
F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30],
|
||||
Uses = [R29] in {
|
||||
F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30] in {
|
||||
def JSR : MForm< 0x1A, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr $RD,($RS),$DISP">; //Jump to subroutine
|
||||
def BSR : BForm<0x34, (ops GPRC:$RD, s21imm:$DISP), "bsr $RD,$DISP">; //Branch to subroutine
|
||||
}
|
||||
@ -286,7 +286,7 @@ let isCall = 1,
|
||||
def JSR_COROUTINE : MForm< 0x1A, (ops GPRC:$RD, GPRC:$RS), "jsr_coroutine $RD,($RS),1">; //Jump to subroutine return
|
||||
def BR : BForm<0x30, (ops GPRC:$RD, s21imm:$DISP), "br $RD,$DISP">; //Branch
|
||||
|
||||
let Uses = [R29, R28] in {
|
||||
let Uses = [R28] in {
|
||||
//Stores, int
|
||||
def STB : MForm<0x0E, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "stb $RA,$DISP($RB)">; // Store byte
|
||||
def STW : MForm<0x0D, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "stw $RA,$DISP($RB)">; // Store word
|
||||
|
@ -83,8 +83,9 @@ def GPRC : RegisterClass<i64, 64,
|
||||
[R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22,
|
||||
R23, R24, R25, R27,
|
||||
// Non-volatile
|
||||
R9, R10, R11, R12, R13, R14, R15, R26, /* R28, */ R29 /* R30, R31*/ ]>;
|
||||
R9, R10, R11, R12, R13, R14, /*R15,*/ R26, /* R28, */ R29 /* R30, R31*/ ]>;
|
||||
// Note: R28 is reserved for the assembler
|
||||
//leave FP alone
|
||||
|
||||
// Don't allocate 15, 29, 30, 31
|
||||
// Allocation volatiles only for now
|
||||
|
Loading…
Reference in New Issue
Block a user