mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-24 08:33:39 +00:00
All that just to lower div and rem
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25008 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
57030e36e4
commit
53d8970625
@ -206,16 +206,20 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) {
|
||||
case AlphaISD::GlobalBaseReg:
|
||||
return getGlobalBaseReg();
|
||||
|
||||
case ISD::TargetConstantPool: {
|
||||
Constant *C = cast<ConstantPoolSDNode>(N)->get();
|
||||
SDOperand Tmp, CPI = CurDAG->getTargetConstantPool(C, MVT::i64);
|
||||
Tmp = CurDAG->getTargetNode(Alpha::LDAHr, MVT::i64, CPI, getGlobalBaseReg());
|
||||
return CurDAG->SelectNodeTo(N, Alpha::LDAr, MVT::i64, CPI, Tmp);
|
||||
case AlphaISD::DivCall: {
|
||||
SDOperand Chain = CurDAG->getEntryNode();
|
||||
Chain = CurDAG->getCopyToReg(Chain, Alpha::R24, Select(Op.getOperand(1)),
|
||||
SDOperand(0,0));
|
||||
Chain = CurDAG->getCopyToReg(Chain, Alpha::R25, Select(Op.getOperand(2)),
|
||||
Chain.getValue(1));
|
||||
Chain = CurDAG->getCopyToReg(Chain, Alpha::R27, Select(Op.getOperand(0)),
|
||||
Chain.getValue(1));
|
||||
Chain = CurDAG->getTargetNode(Alpha::JSRsDAG, MVT::Other, MVT::Flag,
|
||||
Chain, Chain.getValue(1));
|
||||
Chain = CurDAG->getCopyFromReg(Chain, Alpha::R27, MVT::i64,
|
||||
Chain.getValue(1));
|
||||
return CurDAG->SelectNodeTo(N, Alpha::BIS, MVT::i64, Chain, Chain);
|
||||
}
|
||||
case ISD::ExternalSymbol:
|
||||
return CurDAG->SelectNodeTo(N, Alpha::LDQl, MVT::i64,
|
||||
CurDAG->getTargetExternalSymbol(cast<ExternalSymbolSDNode>(N)->getSymbol(), MVT::i64),
|
||||
getGlobalBaseReg());
|
||||
|
||||
case ISD::RET: {
|
||||
SDOperand Chain = Select(N->getOperand(0)); // Token chain.
|
||||
@ -268,33 +272,6 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ISD::SDIV:
|
||||
case ISD::UDIV:
|
||||
case ISD::UREM:
|
||||
case ISD::SREM:
|
||||
if (MVT::isInteger(N->getValueType(0))) {
|
||||
const char* opstr = 0;
|
||||
switch(N->getOpcode()) {
|
||||
case ISD::UREM: opstr = "__remqu"; break;
|
||||
case ISD::SREM: opstr = "__remq"; break;
|
||||
case ISD::UDIV: opstr = "__divqu"; break;
|
||||
case ISD::SDIV: opstr = "__divq"; break;
|
||||
}
|
||||
SDOperand Tmp1 = Select(N->getOperand(0)),
|
||||
Tmp2 = Select(N->getOperand(1)),
|
||||
Addr = Select(CurDAG->getExternalSymbol(opstr,
|
||||
AlphaLowering.getPointerTy()));
|
||||
SDOperand Chain;
|
||||
Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), Alpha::R24, Tmp1,
|
||||
SDOperand(0,0));
|
||||
Chain = CurDAG->getCopyToReg(Chain, Alpha::R25, Tmp2, Chain.getValue(1));
|
||||
Chain = CurDAG->getCopyToReg(Chain, Alpha::R27, Addr, Chain.getValue(1));
|
||||
Chain = CurDAG->getTargetNode(Alpha::JSRsDAG, MVT::Other, MVT::Flag,
|
||||
Chain, Chain.getValue(1));
|
||||
return CurDAG->getCopyFromReg(Chain, Alpha::R27, MVT::i64,
|
||||
Chain.getValue(1));
|
||||
}
|
||||
break;
|
||||
|
||||
case ISD::SETCC:
|
||||
if (MVT::isFloatingPoint(N->getOperand(0).Val->getValueType(0))) {
|
||||
|
@ -82,9 +82,10 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
|
||||
setOperationAction(ISD::CTLZ , MVT::i64 , Expand);
|
||||
}
|
||||
|
||||
//If this didn't legalize into a div....
|
||||
// setOperationAction(ISD::SREM , MVT::i64, Expand);
|
||||
// setOperationAction(ISD::UREM , MVT::i64, Expand);
|
||||
setOperationAction(ISD::SREM , MVT::i64, Custom);
|
||||
setOperationAction(ISD::UREM , MVT::i64, Custom);
|
||||
setOperationAction(ISD::SDIV , MVT::i64, Custom);
|
||||
setOperationAction(ISD::UDIV , MVT::i64, Custom);
|
||||
|
||||
setOperationAction(ISD::MEMMOVE , MVT::Other, Expand);
|
||||
setOperationAction(ISD::MEMSET , MVT::Other, Expand);
|
||||
@ -104,10 +105,12 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
|
||||
setOperationAction(ISD::LOCATION, MVT::Other, Expand);
|
||||
setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
|
||||
|
||||
// We want to legalize GlobalAddress and ConstantPool nodes into the
|
||||
// appropriate instructions to materialize the address.
|
||||
setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);
|
||||
setOperationAction(ISD::ConstantPool, MVT::i64, Custom);
|
||||
// We want to legalize GlobalAddress and ConstantPool and
|
||||
// ExternalSymbols nodes into the appropriate instructions to
|
||||
// materialize the address.
|
||||
setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);
|
||||
setOperationAction(ISD::ConstantPool, MVT::i64, Custom);
|
||||
setOperationAction(ISD::ExternalSymbol, MVT::i64, Custom);
|
||||
|
||||
addLegalFPImmediate(+0.0); //F31
|
||||
addLegalFPImmediate(-0.0); //-F31
|
||||
@ -461,6 +464,30 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
} else
|
||||
return DAG.getNode(AlphaISD::RelLit, MVT::i64, GA, DAG.getNode(AlphaISD::GlobalBaseReg, MVT::i64));
|
||||
}
|
||||
case ISD::ExternalSymbol: {
|
||||
return DAG.getNode(AlphaISD::RelLit, MVT::i64,
|
||||
DAG.getTargetExternalSymbol(cast<ExternalSymbolSDNode>(Op)->getSymbol(), MVT::i64),
|
||||
DAG.getNode(AlphaISD::GlobalBaseReg, MVT::i64));
|
||||
}
|
||||
|
||||
case ISD::SDIV:
|
||||
case ISD::UDIV:
|
||||
case ISD::UREM:
|
||||
case ISD::SREM:
|
||||
if (MVT::isInteger(Op.getValueType())) {
|
||||
const char* opstr = 0;
|
||||
switch(Op.getOpcode()) {
|
||||
case ISD::UREM: opstr = "__remqu"; break;
|
||||
case ISD::SREM: opstr = "__remq"; break;
|
||||
case ISD::UDIV: opstr = "__divqu"; break;
|
||||
case ISD::SDIV: opstr = "__divq"; break;
|
||||
}
|
||||
SDOperand Tmp1 = Op.getOperand(0),
|
||||
Tmp2 = Op.getOperand(1),
|
||||
Addr = DAG.getExternalSymbol(opstr, MVT::i64);
|
||||
return DAG.getNode(AlphaISD::DivCall, MVT::i64, Addr, Tmp1, Tmp2);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
@ -35,9 +35,12 @@ namespace llvm {
|
||||
/// RetLit - Literal Relocation of a Global
|
||||
RelLit,
|
||||
|
||||
/// GlobalBaseReg, used to restore the GOT ptr
|
||||
/// GlobalBaseReg - used to restore the GOT ptr
|
||||
GlobalBaseReg,
|
||||
|
||||
/// DIVCALL - used for special library calls for div and rem
|
||||
DivCall,
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,6 @@ class AlphaISel : public SelectionDAGISel {
|
||||
|
||||
int count_ins;
|
||||
int count_outs;
|
||||
bool has_sym;
|
||||
int max_depth;
|
||||
|
||||
public:
|
||||
@ -93,15 +92,12 @@ public:
|
||||
count_ins = 0;
|
||||
count_outs = 0;
|
||||
max_depth = 0;
|
||||
has_sym = false;
|
||||
|
||||
// Codegen the basic block.
|
||||
ISelDAG = &DAG;
|
||||
max_depth = DAG.getRoot().getNodeDepth();
|
||||
Select(DAG.getRoot());
|
||||
|
||||
if(has_sym)
|
||||
++count_ins;
|
||||
if(EnableAlphaCount)
|
||||
std::cerr << "COUNT: "
|
||||
<< BB->getParent()->getFunction ()->getName() << " "
|
||||
@ -689,12 +685,11 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
|
||||
dyn_cast<ConstantPoolSDNode>(Address)) {
|
||||
unsigned CPIdx = BB->getParent()->getConstantPool()->
|
||||
getConstantPoolIndex(CP->get());
|
||||
has_sym = true;
|
||||
if (EnableAlphaLSMark)
|
||||
BuildMI(BB, Alpha::MEMLABEL, 4).addImm(i).addImm(j).addImm(k)
|
||||
.addImm(getUID());
|
||||
BuildMI(BB, GetRelVersion(Opc), 2, Result)
|
||||
.addConstantPoolIndex(CPIdx).addReg(Tmp1);
|
||||
.addConstantPoolIndex(CPIdx).addReg(Hi);
|
||||
} else assert(0 && "Unknown Lo part");
|
||||
} else if(Address.getOpcode() == ISD::FrameIndex) {
|
||||
if (EnableAlphaLSMark)
|
||||
@ -717,56 +712,43 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
|
||||
AlphaLowering.restoreGP(BB);
|
||||
BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R29).addReg(Alpha::R29);
|
||||
return Result;
|
||||
case AlphaISD::GPRelHi:
|
||||
case AlphaISD::GPRelHi: {
|
||||
unsigned hi = SelectExpr(N.getOperand(1));
|
||||
if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N.getOperand(0)))
|
||||
BuildMI(BB, Alpha::LDAHr, 2, Result)
|
||||
.addConstantPoolIndex(BB->getParent()->getConstantPool()->
|
||||
getConstantPoolIndex(CP->get()))
|
||||
.addReg(SelectExpr(N.getOperand(1)));
|
||||
getConstantPoolIndex(CP->get())).addReg(hi);
|
||||
else if (GlobalAddressSDNode *GASD =
|
||||
dyn_cast<GlobalAddressSDNode>(N.getOperand(0)))
|
||||
BuildMI(BB, Alpha::LDAHr, 2, Result)
|
||||
.addGlobalAddress(GASD->getGlobal())
|
||||
.addReg(SelectExpr(N.getOperand(1)));
|
||||
.addGlobalAddress(GASD->getGlobal()).addReg(hi);
|
||||
else assert(0 && "unknown Hi part");
|
||||
return Result;
|
||||
case AlphaISD::GPRelLo:
|
||||
}
|
||||
case AlphaISD::GPRelLo: {
|
||||
unsigned hi = SelectExpr(N.getOperand(1));
|
||||
if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N.getOperand(0)))
|
||||
BuildMI(BB, Alpha::LDAr, 2, Result)
|
||||
.addConstantPoolIndex(BB->getParent()->getConstantPool()->
|
||||
getConstantPoolIndex(CP->get()))
|
||||
.addReg(SelectExpr(N.getOperand(1)));
|
||||
getConstantPoolIndex(CP->get())).addReg(hi);
|
||||
else if (GlobalAddressSDNode *GASD =
|
||||
dyn_cast<GlobalAddressSDNode>(N.getOperand(0)))
|
||||
BuildMI(BB, Alpha::LDAr, 2, Result)
|
||||
.addGlobalAddress(GASD->getGlobal())
|
||||
.addReg(SelectExpr(N.getOperand(1)));
|
||||
.addGlobalAddress(GASD->getGlobal()).addReg(hi);
|
||||
else assert(0 && "unknown Lo part");
|
||||
return Result;
|
||||
|
||||
}
|
||||
case AlphaISD::RelLit: {
|
||||
GlobalAddressSDNode *GASD = cast<GlobalAddressSDNode>(N.getOperand(0));
|
||||
BuildMI(BB, Alpha::LDQl, 2, Result)
|
||||
.addGlobalAddress(GASD->getGlobal())
|
||||
.addReg(SelectExpr(N.getOperand(1)));
|
||||
unsigned hi = SelectExpr(N.getOperand(1));
|
||||
if (GlobalAddressSDNode *GASD = dyn_cast<GlobalAddressSDNode>(N.getOperand(0)))
|
||||
BuildMI(BB, Alpha::LDQl, 2, Result)
|
||||
.addGlobalAddress(GASD->getGlobal()).addReg(hi);
|
||||
else if (ExternalSymbolSDNode *ESSD = dyn_cast<ExternalSymbolSDNode>(N.getOperand(0)))
|
||||
BuildMI(BB, Alpha::LDQl, 2, Result)
|
||||
.addExternalSymbol(ESSD->getSymbol()).addReg(hi);
|
||||
return Result;
|
||||
}
|
||||
|
||||
case ISD::ExternalSymbol:
|
||||
AlphaLowering.restoreGP(BB);
|
||||
has_sym = true;
|
||||
|
||||
Reg = Result = MakeReg(MVT::i64);
|
||||
|
||||
if (EnableAlphaLSMark)
|
||||
BuildMI(BB, Alpha::MEMLABEL, 4).addImm(5).addImm(0).addImm(0)
|
||||
.addImm(getUID());
|
||||
|
||||
BuildMI(BB, Alpha::LDQl, 2, Result)
|
||||
.addExternalSymbol(cast<ExternalSymbolSDNode>(N)->getSymbol())
|
||||
.addReg(Alpha::R29);
|
||||
return Result;
|
||||
|
||||
case ISD::TAILCALL:
|
||||
case ISD::CALL:
|
||||
{
|
||||
@ -1248,60 +1230,16 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
|
||||
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
|
||||
return Result;
|
||||
}
|
||||
case ISD::SDIV:
|
||||
{
|
||||
//check if we can convert into a shift!
|
||||
if (isSIntImmediate(N.getOperand(1), SImm) &&
|
||||
SImm != 0 && isPowerOf2_64(llabs(SImm))) {
|
||||
unsigned k = Log2_64(llabs(SImm));
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
if (k == 1)
|
||||
Tmp2 = Tmp1;
|
||||
else
|
||||
{
|
||||
Tmp2 = MakeReg(MVT::i64);
|
||||
BuildMI(BB, Alpha::SRAi, 2, Tmp2).addReg(Tmp1).addImm(k - 1);
|
||||
}
|
||||
Tmp3 = MakeReg(MVT::i64);
|
||||
BuildMI(BB, Alpha::SRLi, 2, Tmp3).addReg(Tmp2).addImm(64-k);
|
||||
unsigned Tmp4 = MakeReg(MVT::i64);
|
||||
BuildMI(BB, Alpha::ADDQ, 2, Tmp4).addReg(Tmp3).addReg(Tmp1);
|
||||
if (SImm > 0)
|
||||
BuildMI(BB, Alpha::SRAi, 2, Result).addReg(Tmp4).addImm(k);
|
||||
else
|
||||
{
|
||||
unsigned Tmp5 = MakeReg(MVT::i64);
|
||||
BuildMI(BB, Alpha::SRAi, 2, Tmp5).addReg(Tmp4).addImm(k);
|
||||
BuildMI(BB, Alpha::SUBQ, 2, Result).addReg(Alpha::R31).addReg(Tmp5);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
//Else fall through
|
||||
case ISD::UDIV:
|
||||
//else fall though
|
||||
case ISD::UREM:
|
||||
case ISD::SREM: {
|
||||
const char* opstr = 0;
|
||||
switch(opcode) {
|
||||
case ISD::UREM: opstr = "__remqu"; break;
|
||||
case ISD::SREM: opstr = "__remq"; break;
|
||||
case ISD::UDIV: opstr = "__divqu"; break;
|
||||
case ISD::SDIV: opstr = "__divq"; break;
|
||||
}
|
||||
case AlphaISD::DivCall:
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
Tmp2 = SelectExpr(N.getOperand(1));
|
||||
SDOperand Addr =
|
||||
ISelDAG->getExternalSymbol(opstr, AlphaLowering.getPointerTy());
|
||||
Tmp3 = SelectExpr(Addr);
|
||||
//set up regs explicitly (helps Reg alloc)
|
||||
BuildMI(BB, Alpha::BIS, 2, Alpha::R24).addReg(Tmp1).addReg(Tmp1);
|
||||
BuildMI(BB, Alpha::BIS, 2, Alpha::R25).addReg(Tmp2).addReg(Tmp2);
|
||||
BuildMI(BB, Alpha::BIS, 2, Alpha::R27).addReg(Tmp3).addReg(Tmp3);
|
||||
Tmp3 = SelectExpr(N.getOperand(2));
|
||||
BuildMI(BB, Alpha::BIS, 2, Alpha::R24).addReg(Tmp2).addReg(Tmp2);
|
||||
BuildMI(BB, Alpha::BIS, 2, Alpha::R25).addReg(Tmp3).addReg(Tmp3);
|
||||
BuildMI(BB, Alpha::BIS, 2, Alpha::R27).addReg(Tmp1).addReg(Tmp1);
|
||||
BuildMI(BB, Alpha::JSRs, 2, Alpha::R23).addReg(Alpha::R27).addImm(0);
|
||||
BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R27).addReg(Alpha::R27);
|
||||
return Result;
|
||||
}
|
||||
|
||||
case ISD::SELECT:
|
||||
if (isFP) {
|
||||
@ -1492,7 +1430,6 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
|
||||
ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val);
|
||||
unsigned CPI = CP->getConstantPoolIndex(C);
|
||||
AlphaLowering.restoreGP(BB);
|
||||
has_sym = true;
|
||||
Tmp1 = MakeReg(MVT::i64);
|
||||
BuildMI(BB, Alpha::LDAHr, 2, Tmp1).addConstantPoolIndex(CPI)
|
||||
.addReg(Alpha::R29);
|
||||
|
@ -434,6 +434,7 @@ let isCall = 1, Defs = [R24, R25, R27, R28], Uses = [R24, R25] in
|
||||
let isCall = 1, Defs = [R23, R24, R25, R27, R28], Uses = [R24, R25, R27] in
|
||||
def JSRsDAG : MbrForm< 0x1A, 0x01, (ops ), "jsr $$23,($$27),0">; //Jump to div or rem
|
||||
|
||||
|
||||
def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP">; //Jump to subroutine return
|
||||
def BR : BForm<0x30, "br $RA,$DISP">; //Branch
|
||||
|
||||
@ -575,9 +576,11 @@ def LDAHg : MFormAlt<0x09, "ldah $RA,0($RB)\t\t!gpdisp!$NUM">; //Load address
|
||||
}
|
||||
|
||||
//Load quad, rellocated literal form
|
||||
let OperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in
|
||||
let OperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in
|
||||
def LDQl : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)\t\t!literal",
|
||||
[(set GPRC:$RA, (Alpha_rellit tglobaladdr:$DISP, GPRC:$RB))]>;
|
||||
def : Pat<(Alpha_rellit texternalsym:$ext, GPRC:$RB),
|
||||
(LDQl texternalsym:$ext, GPRC:$RB)>;
|
||||
|
||||
//Branches, int
|
||||
def BEQ : BForm<0x39, "beq $RA,$DISP">; //Branch if = zero
|
||||
|
Loading…
x
Reference in New Issue
Block a user