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:
Andrew Lenharth 2005-02-10 06:25:22 +00:00
parent 3d261f5ae3
commit 63f2ab2d1b
3 changed files with 573 additions and 547 deletions

View File

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

View File

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

View File

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