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::i8 , Expand);
setOperationAction(ISD::SEXTLOAD , MVT::i16 , 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::f32 , Expand);
setOperationAction(ISD::SREM , MVT::f64 , Expand); setOperationAction(ISD::SREM , MVT::f64 , Expand);
@ -148,14 +149,20 @@ AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
SDOperand newroot, argt; SDOperand newroot, argt;
if (count < 6) { if (count < 6) {
switch (getValueType(I->getType())) { 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::f64:
case MVT::f32: case MVT::f32:
BuildMI(&BB, Alpha::IDEF, 0, args_float[count]); 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]; argPreg[count] = args_float[count];
argOpc[count] = Alpha::CPYS; 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; break;
case MVT::i1: case MVT::i1:
case MVT::i8: case MVT::i8:
@ -163,12 +170,15 @@ AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
case MVT::i32: case MVT::i32:
case MVT::i64: case MVT::i64:
BuildMI(&BB, Alpha::IDEF, 0, args_int[count]); 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]; argPreg[count] = args_int[count];
argOpc[count] = Alpha::BIS; 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) 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; break;
} }
++count; ++count;
@ -176,9 +186,11 @@ AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
// Create the frame index object for this incoming parameter... // Create the frame index object for this incoming parameter...
int FI = MFI->CreateFixedObject(8, 8 * (count - 6)); 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); 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)); DAG.setRoot(newroot.getValue(1));
ArgValues.push_back(argt); ArgValues.push_back(argt);
@ -186,14 +198,15 @@ AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29); BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29);
BuildMI(&BB, Alpha::BIS, 2, GP).addReg(Alpha::R29).addReg(Alpha::R29); BuildMI(&BB, Alpha::BIS, 2, GP).addReg(Alpha::R29).addReg(Alpha::R29);
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i) {
{ if (argPreg[i] == Alpha::F16 || argPreg[i] == Alpha::F17 ||
if (argPreg[i] == Alpha::F16 || argPreg[i] == Alpha::F17 || argPreg[i] == Alpha::F18 || argPreg[i] == Alpha::F18 || argPreg[i] == Alpha::F19 ||
argPreg[i] == Alpha::F19 || argPreg[i] == Alpha::F20 || argPreg[i] == Alpha::F21) argPreg[i] == Alpha::F20 || argPreg[i] == Alpha::F21)
{ {
assert(argOpc[i] == Alpha::CPYS && "Using BIS for a float??"); 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; return ArgValues;
@ -239,7 +252,8 @@ AlphaTargetLowering::LowerCallTo(SDOperand Chain,
RetVals.push_back(RetTyVT); RetVals.push_back(RetTyVT);
RetVals.push_back(MVT::Other); 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 = TheCall.getValue(RetTyVT != MVT::isVoid);
Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain, Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain,
DAG.getConstant(NumBytes, getPointerTy())); DAG.getConstant(NumBytes, getPointerTy()));
@ -274,7 +288,7 @@ namespace {
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
/// ISel - Alpha specific code to select Alpha machine instructions for /// ISel - Alpha specific code to select Alpha machine instructions for
/// SelectionDAG operations. /// SelectionDAG operations.
/// //===--------------------------------------------------------------------===//
class ISel : public SelectionDAGISel { class ISel : public SelectionDAGISel {
/// AlphaLowering - This object fully describes how to lower LLVM code to an /// AlphaLowering - This object fully describes how to lower LLVM code to an
@ -292,8 +306,8 @@ namespace {
std::map<SDOperand, unsigned> CCInvMap; std::map<SDOperand, unsigned> CCInvMap;
public: public:
ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) { ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM)
} {}
/// InstructionSelectBasicBlock - This callback is invoked by /// InstructionSelectBasicBlock - This callback is invoked by
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
@ -341,13 +355,15 @@ void ISel::SelectAddr(SDOperand N, unsigned& Reg, long& offset)
{ {
unsigned opcode = N.getOpcode(); unsigned opcode = N.getOpcode();
if (opcode == ISD::ADD) { 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 { //Normal imm add
Reg = SelectExpr(N.getOperand(0)); Reg = SelectExpr(N.getOperand(0));
offset = cast<ConstantSDNode>(N.getOperand(1))->getValue(); offset = cast<ConstantSDNode>(N.getOperand(1))->getValue();
return; 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)); Reg = SelectExpr(N.getOperand(1));
offset = cast<ConstantSDNode>(N.getOperand(0))->getValue(); 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) void ISel::SelectBranchCC(SDOperand N)
{ {
assert(N.getOpcode() == ISD::BRCOND && "Not a BranchCC???"); assert(N.getOpcode() == ISD::BRCOND && "Not a BranchCC???");
MachineBasicBlock *Dest = cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock(); MachineBasicBlock *Dest =
unsigned Opc; cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
unsigned Opc = Alpha::WTF;
Select(N.getOperand(0)); //chain Select(N.getOperand(0)); //chain
SDOperand CC = N.getOperand(1); SDOperand CC = N.getOperand(1);
@ -386,8 +403,7 @@ void ISel::SelectBranchCC(SDOperand N)
if(SetCC->getCondition() == ISD::SETNE) if(SetCC->getCondition() == ISD::SETNE)
isNE = true; isNE = true;
if (isZero0) if (isZero0) {
{
switch (SetCC->getCondition()) { switch (SetCC->getCondition()) {
default: CC.Val->dump(); assert(0 && "Unknown integer comparison!"); default: CC.Val->dump(); assert(0 && "Unknown integer comparison!");
case ISD::SETEQ: Opc = Alpha::BEQ; break; case ISD::SETEQ: Opc = Alpha::BEQ; break;
@ -404,9 +420,7 @@ void ISel::SelectBranchCC(SDOperand N)
unsigned Tmp1 = SelectExpr(SetCC->getOperand(1)); unsigned Tmp1 = SelectExpr(SetCC->getOperand(1));
BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest); BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest);
return; return;
} } else if (isZero1) {
else if (isZero1)
{
switch (SetCC->getCondition()) { switch (SetCC->getCondition()) {
default: CC.Val->dump(); assert(0 && "Unknown integer comparison!"); default: CC.Val->dump(); assert(0 && "Unknown integer comparison!");
case ISD::SETEQ: Opc = Alpha::BEQ; break; case ISD::SETEQ: Opc = Alpha::BEQ; break;
@ -423,9 +437,7 @@ void ISel::SelectBranchCC(SDOperand N)
unsigned Tmp1 = SelectExpr(SetCC->getOperand(0)); unsigned Tmp1 = SelectExpr(SetCC->getOperand(0));
BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest); BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest);
return; return;
} } else {
else
{
unsigned Tmp1 = SelectExpr(CC); unsigned Tmp1 = SelectExpr(CC);
if (isNE) if (isNE)
BuildMI(BB, Alpha::BEQ, 2).addReg(CCInvMap[CC]).addMBB(Dest); BuildMI(BB, Alpha::BEQ, 2).addReg(CCInvMap[CC]).addMBB(Dest);
@ -458,9 +470,8 @@ void ISel::SelectBranchCC(SDOperand N)
return; return;
} }
abort(); //Should never be reached abort(); //Should never be reached
} } else {
else //Giveup and do the stupid thing
{ //Giveup and do the stupid thing
unsigned Tmp1 = SelectExpr(CC); unsigned Tmp1 = SelectExpr(CC);
BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest); BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
return; return;
@ -502,13 +513,17 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
} }
case ISD::FP_ROUND: 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)); Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, Alpha::CVTTS, 1, Result).addReg(Tmp1); BuildMI(BB, Alpha::CVTTS, 1, Result).addReg(Tmp1);
return Result; return Result;
case ISD::FP_EXTEND: 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)); Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp1); BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp1);
return Result; return Result;
@ -545,8 +560,7 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
Select(Chain); Select(Chain);
Opc = DestType == MVT::f64 ? Alpha::LDT : Alpha::LDS; Opc = DestType == MVT::f64 ? Alpha::LDT : Alpha::LDS;
if (Address.getOpcode() == ISD::GlobalAddress) if (Address.getOpcode() == ISD::GlobalAddress) {
{
AlphaLowering.restoreGP(BB); AlphaLowering.restoreGP(BB);
Opc = GetSymVersion(Opc); Opc = GetSymVersion(Opc);
BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal()); BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
@ -556,13 +570,10 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
Opc = GetSymVersion(Opc); Opc = GetSymVersion(Opc);
BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex()); 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(); Tmp1 = cast<FrameIndexSDNode>(Address)->getIndex();
BuildMI(BB, Opc, 2, Result).addFrameIndex(Tmp1).addReg(Alpha::F31); BuildMI(BB, Opc, 2, Result).addFrameIndex(Tmp1).addReg(Alpha::F31);
} } else {
else
{
long offset; long offset;
SelectAddr(Address, Tmp1, offset); SelectAddr(Address, Tmp1, offset);
BuildMI(BB, Opc, 2, Result).addImm(offset).addReg(Tmp1); BuildMI(BB, Opc, 2, Result).addImm(offset).addReg(Tmp1);
@ -606,30 +617,28 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
Tmp1 = MakeReg(MVT::f32); 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"); assert(Node->getValueType(0) == MVT::f64 && "EXTLOAD not to f64");
SDOperand Chain = N.getOperand(0); SDOperand Chain = N.getOperand(0);
SDOperand Address = N.getOperand(1); SDOperand Address = N.getOperand(1);
Select(Chain); Select(Chain);
if (Address.getOpcode() == ISD::GlobalAddress) if (Address.getOpcode() == ISD::GlobalAddress) {
{
AlphaLowering.restoreGP(BB); AlphaLowering.restoreGP(BB);
BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal()); 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); AlphaLowering.restoreGP(BB);
BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addConstantPoolIndex(CP->getIndex()); 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(); Tmp2 = cast<FrameIndexSDNode>(Address)->getIndex();
BuildMI(BB, Alpha::LDS, 2, Tmp1).addFrameIndex(Tmp2).addReg(Alpha::F31); BuildMI(BB, Alpha::LDS, 2, Tmp1).addFrameIndex(Tmp2).addReg(Alpha::F31);
} } else {
else
{
long offset; long offset;
SelectAddr(Address, Tmp2, offset); SelectAddr(Address, Tmp2, offset);
BuildMI(BB, Alpha::LDS, 1, Tmp1).addImm(offset).addReg(Tmp2); 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::UINT_TO_FP:
case ISD::SINT_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 Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
Tmp2 = MakeReg(MVT::f64); Tmp2 = MakeReg(MVT::f64);
@ -701,8 +711,10 @@ unsigned ISel::SelectExpr(SDOperand N) {
if (DestType == MVT::f64 || DestType == MVT::f32 || if (DestType == MVT::f64 || DestType == MVT::f32 ||
( (
(opcode == ISD::LOAD || opcode == ISD::CopyFromReg || opcode == ISD::EXTLOAD) && (opcode == ISD::LOAD || opcode == ISD::CopyFromReg ||
(N.getValue(0).getValueType() == MVT::f32 || N.getValue(0).getValueType() == MVT::f64) opcode == ISD::EXTLOAD) &&
(N.getValue(0).getValueType() == MVT::f32 ||
N.getValue(0).getValueType() == MVT::f64)
) )
) )
return SelectExprFP(N, Result); return SelectExprFP(N, Result);
@ -738,20 +750,23 @@ unsigned ISel::SelectExpr(SDOperand N) {
SDOperand Address = N.getOperand(1); SDOperand Address = N.getOperand(1);
Select(Chain); 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) if (opcode == ISD::LOAD)
Opc = Alpha::LDQ; Opc = Alpha::LDQ;
else else
switch (cast<MVTSDNode>(Node)->getExtraValueType()) { switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
default: Node->dump(); assert(0 && "Bad sign extend!"); default: Node->dump(); assert(0 && "Bad sign extend!");
case MVT::i32: Opc = Alpha::LDL; assert(opcode != ISD::ZEXTLOAD && "Not sext"); break; case MVT::i32: Opc = Alpha::LDL;
case MVT::i16: Opc = Alpha::LDWU; assert(opcode != ISD::SEXTLOAD && "Not zext"); break; 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::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); AlphaLowering.restoreGP(BB);
Opc = GetSymVersion(Opc); Opc = GetSymVersion(Opc);
BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal()); BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
@ -761,13 +776,10 @@ unsigned ISel::SelectExpr(SDOperand N) {
Opc = GetSymVersion(Opc); Opc = GetSymVersion(Opc);
BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex()); 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(); Tmp1 = cast<FrameIndexSDNode>(Address)->getIndex();
BuildMI(BB, Opc, 2, Result).addFrameIndex(Tmp1).addReg(Alpha::F31); BuildMI(BB, Opc, 2, Result).addFrameIndex(Tmp1).addReg(Alpha::F31);
} } else {
else
{
long offset; long offset;
SelectAddr(Address, Tmp1, offset); SelectAddr(Address, Tmp1, offset);
BuildMI(BB, Opc, 2, Result).addImm(offset).addReg(Tmp1); BuildMI(BB, Opc, 2, Result).addImm(offset).addReg(Tmp1);
@ -805,7 +817,8 @@ unsigned ISel::SelectExpr(SDOperand N) {
default: default:
Node->dump(); Node->dump();
N.getOperand(i).Val->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"); assert(0 && "Unknown value type for call");
case MVT::i1: case MVT::i1:
case MVT::i8: case MVT::i8:
@ -827,7 +840,8 @@ unsigned ISel::SelectExpr(SDOperand N) {
default: default:
Node->dump(); Node->dump();
N.getOperand(i).Val->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"); assert(0 && "Unknown value type for call");
case MVT::i1: case MVT::i1:
case MVT::i8: case MVT::i8:
@ -848,17 +862,21 @@ unsigned ISel::SelectExpr(SDOperand N) {
if (GlobalAddressSDNode *GASD = if (GlobalAddressSDNode *GASD =
dyn_cast<GlobalAddressSDNode>(N.getOperand(1))) dyn_cast<GlobalAddressSDNode>(N.getOperand(1)))
{ {
if (GASD->getGlobal()->isExternal()) {
//use safe calling convention
AlphaLowering.restoreGP(BB); AlphaLowering.restoreGP(BB);
BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true); 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 = else if (ExternalSymbolSDNode *ESSDN =
dyn_cast<ExternalSymbolSDNode>(N.getOperand(1))) dyn_cast<ExternalSymbolSDNode>(N.getOperand(1)))
{ {
AlphaLowering.restoreGP(BB); AlphaLowering.restoreGP(BB);
BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true); BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true);
} } else {
else
{
//no need to restore GP as we are doing an indirect call //no need to restore GP as we are doing an indirect call
Tmp1 = SelectExpr(N.getOperand(1)); Tmp1 = SelectExpr(N.getOperand(1));
BuildMI(BB, Alpha::BIS, 2, Alpha::R27).addReg(Tmp1).addReg(Tmp1); BuildMI(BB, Alpha::BIS, 2, Alpha::R27).addReg(Tmp1).addReg(Tmp1);
@ -985,14 +1003,22 @@ unsigned ISel::SelectExpr(SDOperand N) {
switch (SetCC->getCondition()) { switch (SetCC->getCondition()) {
default: Node->dump(); assert(0 && "Unknown integer comparison!"); default: Node->dump(); assert(0 && "Unknown integer comparison!");
case ISD::SETEQ: Opc = Alpha::CMPEQ; dir=0; break; case ISD::SETEQ: Opc = Alpha::CMPEQ; dir=0; break;
case ISD::SETLT: Opc = isConst2 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break; case ISD::SETLT:
case ISD::SETLE: Opc = isConst2 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 1; break; Opc = isConst2 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break;
case ISD::SETGT: Opc = isConst1 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 2; break; case ISD::SETLE:
case ISD::SETGE: Opc = isConst1 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 2; break; Opc = isConst2 ? Alpha::CMPLEi : Alpha::CMPLE; dir = 1; break;
case ISD::SETULT: Opc = isConst2 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 1; break; case ISD::SETGT:
case ISD::SETUGT: Opc = isConst1 ? Alpha::CMPULTi : Alpha::CMPULT; dir = 2; break; Opc = isConst1 ? Alpha::CMPLTi : Alpha::CMPLT; dir = 2; break;
case ISD::SETULE: Opc = isConst2 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 1; break; case ISD::SETGE:
case ISD::SETUGE: Opc = isConst1 ? Alpha::CMPULEi : Alpha::CMPULE; dir = 2; break; 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 case ISD::SETNE: {//Handle this one special
//std::cerr << "Alpha does not have a setne.\n"; //std::cerr << "Alpha does not have a setne.\n";
//abort(); //abort();
@ -1147,9 +1173,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
Tmp1 = SelectExpr(N.getOperand(0)); Tmp1 = SelectExpr(N.getOperand(0));
Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue(); Tmp2 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2); BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
} } else {
else
{
switch(opcode) { switch(opcode) {
case ISD::AND: Opc = Alpha::AND; break; case ISD::AND: Opc = Alpha::AND; break;
case ISD::OR: Opc = Alpha::BIS; break; case ISD::OR: Opc = Alpha::BIS; break;
@ -1187,9 +1211,8 @@ unsigned ISel::SelectExpr(SDOperand N) {
if (!isAdd) if (!isAdd)
Tmp2 = -Tmp2; Tmp2 = -Tmp2;
BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp2).addReg(Tmp1); BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp2).addReg(Tmp1);
} } else {
else //Normal add/sub
{ //Normal add/sub
Opc = isAdd ? Alpha::ADDQ : Alpha::SUBQ; Opc = isAdd ? Alpha::ADDQ : Alpha::SUBQ;
Tmp1 = SelectExpr(N.getOperand(0)); Tmp1 = SelectExpr(N.getOperand(0));
Tmp2 = SelectExpr(N.getOperand(1)); Tmp2 = SelectExpr(N.getOperand(1));
@ -1205,11 +1228,12 @@ unsigned ISel::SelectExpr(SDOperand N) {
//FIXME: alpha really doesn't support any of these operations, //FIXME: alpha really doesn't support any of these operations,
// the ops are expanded into special library calls with // the ops are expanded into special library calls with
// special calling conventions // special calling conventions
//Restore GP because it is a call after all...
switch(opcode) { switch(opcode) {
case ISD::UREM: Opc = Alpha::REMQU; break; case ISD::UREM: AlphaLowering.restoreGP(BB); Opc = Alpha::REMQU; break;
case ISD::SREM: Opc = Alpha::REMQ; break; case ISD::SREM: AlphaLowering.restoreGP(BB); Opc = Alpha::REMQ; break;
case ISD::UDIV: Opc = Alpha::DIVQU; break; case ISD::UDIV: AlphaLowering.restoreGP(BB); Opc = Alpha::DIVQU; break;
case ISD::SDIV: Opc = Alpha::DIVQ; break; case ISD::SDIV: AlphaLowering.restoreGP(BB); Opc = Alpha::DIVQ; break;
} }
Tmp1 = SelectExpr(N.getOperand(0)); Tmp1 = SelectExpr(N.getOperand(0));
Tmp2 = SelectExpr(N.getOperand(1)); Tmp2 = SelectExpr(N.getOperand(1));
@ -1263,8 +1287,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
unsigned long val = cast<ConstantSDNode>(N)->getValue(); unsigned long val = cast<ConstantSDNode>(N)->getValue();
if (val < 32000 && (long)val > -32000) if (val < 32000 && (long)val > -32000)
BuildMI(BB, Alpha::LOAD_IMM, 1, Result).addImm(val); BuildMI(BB, Alpha::LOAD_IMM, 1, Result).addImm(val);
else else {
{
MachineConstantPool *CP = BB->getParent()->getConstantPool(); MachineConstantPool *CP = BB->getParent()->getConstantPool();
ConstantUInt *C = ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val); ConstantUInt *C = ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val);
unsigned CPI = CP->getConstantPoolIndex(C); unsigned CPI = CP->getConstantPoolIndex(C);
@ -1331,7 +1354,8 @@ void ISel::Select(SDOperand N) {
Tmp2 = cast<RegSDNode>(N)->getReg(); Tmp2 = cast<RegSDNode>(N)->getReg();
if (Tmp1 != Tmp2) { 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); BuildMI(BB, Alpha::CPYS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
else else
BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1); BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
@ -1350,7 +1374,8 @@ void ISel::Select(SDOperand N) {
Select(N.getOperand(0)); Select(N.getOperand(0));
Tmp1 = SelectExpr(N.getOperand(1)); Tmp1 = SelectExpr(N.getOperand(1));
switch (N.getOperand(1).getValueType()) { 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::f64:
case MVT::f32: case MVT::f32:
BuildMI(BB, Alpha::CPYS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1); BuildMI(BB, Alpha::CPYS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1);

View File

@ -53,7 +53,7 @@ let isCall = 1,
let isReturn = 1, isTerminator = 1 in let isReturn = 1, isTerminator = 1 in
def RETURN : PseudoInstAlpha<(ops ), "ret $$31,($$26),1">; //Return from subroutine 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 def LOAD_IMM : PseudoInstAlpha<(ops GPRC:$RC, s64imm:$IMM), "ldiq $RC,$IMM">; //Load Immediate Quadword
let Uses = [R29, R28] in { 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 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 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 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 def JMP : MForm< 0x1A, (ops GPRC:$RD, GPRC:$RS), "jmp $RD,($RS),0">; //Jump
let isCall = 1, let isCall = 1,
Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, 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, F0, F1,
F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30] in {
Uses = [R29] in {
def JSR : MForm< 0x1A, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr $RD,($RS),$DISP">; //Jump to subroutine 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 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 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 def BR : BForm<0x30, (ops GPRC:$RD, s21imm:$DISP), "br $RD,$DISP">; //Branch
let Uses = [R29, R28] in { let Uses = [R28] in {
//Stores, int //Stores, int
def STB : MForm<0x0E, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "stb $RA,$DISP($RB)">; // Store byte 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 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, [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22,
R23, R24, R25, R27, R23, R24, R25, R27,
// Non-volatile // 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 // Note: R28 is reserved for the assembler
//leave FP alone
// Don't allocate 15, 29, 30, 31 // Don't allocate 15, 29, 30, 31
// Allocation volatiles only for now // Allocation volatiles only for now