mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +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::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);
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user