diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp index a56b90887bf..f75009ca2db 100644 --- a/lib/Target/Alpha/AlphaISelLowering.cpp +++ b/lib/Target/Alpha/AlphaISelLowering.cpp @@ -20,6 +20,7 @@ #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Constants.h" #include "llvm/Function.h" +#include "llvm/Module.h" #include "llvm/Support/CommandLine.h" #include @@ -68,6 +69,12 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) setOperationAction(ISD::TRUNCSTORE, MVT::i1, Promote); + if (EnableAlphaLSMark) { + setOperationAction(ISD::LOAD, MVT::i64, Custom); + setOperationAction(ISD::LOAD, MVT::f64, Custom); + setOperationAction(ISD::LOAD, MVT::f32, Custom); + } + setOperationAction(ISD::FREM, MVT::f32, Expand); setOperationAction(ISD::FREM, MVT::f64, Expand); @@ -145,6 +152,12 @@ const char *AlphaTargetLowering::getTargetNodeName(unsigned Opcode) const { case AlphaISD::RelLit: return "Alpha::RelLit"; case AlphaISD::GlobalBaseReg: return "Alpha::GlobalBaseReg"; case AlphaISD::DivCall: return "Alpha::DivCall"; + case AlphaISD::LDQ_: return "Alpha::LDQ_"; + case AlphaISD::LDT_: return "Alpha::LDT_"; + case AlphaISD::LDS_: return "Alpha::LDS_"; + case AlphaISD::LDL_: return "Alpha::LDL_"; + case AlphaISD::LDWU_: return "Alpha::LDWU_"; + case AlphaISD::LDBU_: return "Alpha::LDBU_"; } } @@ -396,7 +409,6 @@ LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, return std::make_pair(Result, Update); } - SDOperand AlphaTargetLowering:: LowerVACopy(SDOperand Chain, SDOperand SrcP, Value *SrcV, SDOperand DestP, Value *DestV, SelectionDAG &DAG) { @@ -425,6 +437,53 @@ void AlphaTargetLowering::restoreRA(MachineBasicBlock* BB) } + +static void getValueInfo(const Value* v, int& type, int& fun, int& offset) +{ + fun = type = offset = 0; + if (v == NULL) { + type = 0; + } else if (const GlobalValue* GV = dyn_cast(v)) { + type = 1; + const Module* M = GV->getParent(); + for(Module::const_global_iterator ii = M->global_begin(); &*ii != GV; ++ii) + ++offset; + } else if (const Argument* Arg = dyn_cast(v)) { + type = 2; + const Function* F = Arg->getParent(); + const Module* M = F->getParent(); + for(Module::const_iterator ii = M->begin(); &*ii != F; ++ii) + ++fun; + for(Function::const_arg_iterator ii = F->arg_begin(); &*ii != Arg; ++ii) + ++offset; + } else if (const Instruction* I = dyn_cast(v)) { + assert(dyn_cast(I->getType())); + type = 3; + const BasicBlock* bb = I->getParent(); + const Function* F = bb->getParent(); + const Module* M = F->getParent(); + for(Module::const_iterator ii = M->begin(); &*ii != F; ++ii) + ++fun; + for(Function::const_iterator ii = F->begin(); &*ii != bb; ++ii) + offset += ii->size(); + for(BasicBlock::const_iterator ii = bb->begin(); &*ii != I; ++ii) + ++offset; + } else if (const Constant* C = dyn_cast(v)) { + //Don't know how to look these up yet + type = 0; + } else { + assert(0 && "Error in value marking"); + } + //type = 4: register spilling + //type = 5: global address loading or constant loading +} + +static int getUID() +{ + static int id = 0; + return ++id; +} + /// LowerOperation - Provide custom lowering hooks for some operations. /// SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { @@ -516,6 +575,53 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { } break; + case ISD::LOAD: + case ISD::SEXTLOAD: + case ISD::ZEXTLOAD: + { + SDOperand Chain = Op.getOperand(0); + SDOperand Address = Op.getOperand(1); + + unsigned Opc; + unsigned opcode = Op.getOpcode(); + + if (opcode == ISD::LOAD) + switch (Op.Val->getValueType(0)) { + default: Op.Val->dump(); assert(0 && "Bad load!"); + case MVT::i64: Opc = AlphaISD::LDQ_; break; + case MVT::f64: Opc = AlphaISD::LDT_; break; + case MVT::f32: Opc = AlphaISD::LDS_; break; + } + else + switch (cast(Op.getOperand(3))->getVT()) { + default: Op.Val->dump(); assert(0 && "Bad sign extend!"); + case MVT::i32: Opc = AlphaISD::LDL_; + assert(opcode != ISD::ZEXTLOAD && "Not sext"); break; + case MVT::i16: Opc = AlphaISD::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 = AlphaISD::LDBU_; + assert(opcode != ISD::SEXTLOAD && "Not zext"); break; + } + + int i, j, k; + getValueInfo(dyn_cast(Op.getOperand(2))->getValue(), i, j, k); + + SDOperand Zero = DAG.getConstant(0, MVT::i64); + std::vector VTS; + VTS.push_back(Op.Val->getValueType(0)); + VTS.push_back(MVT::Other); + std::vector ARGS; + ARGS.push_back(Zero); + ARGS.push_back(Address); + ARGS.push_back(DAG.getConstant(i, MVT::i64)); + ARGS.push_back(DAG.getConstant(j, MVT::i64)); + ARGS.push_back(DAG.getConstant(k, MVT::i64)); + ARGS.push_back(DAG.getConstant(getUID(), MVT::i64)); + ARGS.push_back(Chain); + return DAG.getNode(Opc, VTS, ARGS); + } + } return SDOperand(); diff --git a/lib/Target/Alpha/AlphaISelLowering.h b/lib/Target/Alpha/AlphaISelLowering.h index e9d9b91dc02..c1ec6565080 100644 --- a/lib/Target/Alpha/AlphaISelLowering.h +++ b/lib/Target/Alpha/AlphaISelLowering.h @@ -41,6 +41,9 @@ namespace llvm { /// DIVCALL - used for special library calls for div and rem DivCall, + ///LD, ST + LDQ_, LDT_, LDS_, LDL_, LDWU_, LDBU_, + }; } diff --git a/lib/Target/Alpha/AlphaInstrInfo.td b/lib/Target/Alpha/AlphaInstrInfo.td index 6a7cc8091c5..9b5f0203f68 100644 --- a/lib/Target/Alpha/AlphaInstrInfo.td +++ b/lib/Target/Alpha/AlphaInstrInfo.td @@ -19,15 +19,24 @@ include "AlphaInstrFormats.td" def SDTFPUnaryOpUnC : SDTypeProfile<1, 1, [ SDTCisFP<1>, SDTCisFP<0> ]>; +def SDTLoadA : SDTypeProfile<1, 6, [ // load + SDTCisInt<1>, SDTCisPtrTy<2>, SDTCisInt<3>, SDTCisInt<4>, SDTCisInt<5>, SDTCisInt<6> +]>; -def Alpha_itoft : SDNode<"AlphaISD::ITOFT_", SDTIntToFPOp, []>; -def Alpha_ftoit : SDNode<"AlphaISD::FTOIT_", SDTFPToIntOp, []>; -def Alpha_cvtqt : SDNode<"AlphaISD::CVTQT_", SDTFPUnaryOpUnC, []>; -def Alpha_cvtqs : SDNode<"AlphaISD::CVTQS_", SDTFPUnaryOpUnC, []>; -def Alpha_cvttq : SDNode<"AlphaISD::CVTTQ_", SDTFPUnaryOp, []>; -def Alpha_gprello : SDNode<"AlphaISD::GPRelLo", SDTIntBinOp, []>; -def Alpha_gprelhi : SDNode<"AlphaISD::GPRelHi", SDTIntBinOp, []>; -def Alpha_rellit : SDNode<"AlphaISD::RelLit", SDTIntBinOp, []>; +def Alpha_itoft : SDNode<"AlphaISD::ITOFT_", SDTIntToFPOp, []>; +def Alpha_ftoit : SDNode<"AlphaISD::FTOIT_", SDTFPToIntOp, []>; +def Alpha_cvtqt : SDNode<"AlphaISD::CVTQT_", SDTFPUnaryOpUnC, []>; +def Alpha_cvtqs : SDNode<"AlphaISD::CVTQS_", SDTFPUnaryOpUnC, []>; +def Alpha_cvttq : SDNode<"AlphaISD::CVTTQ_" , SDTFPUnaryOp, []>; +def Alpha_gprello : SDNode<"AlphaISD::GPRelLo", SDTIntBinOp, []>; +def Alpha_gprelhi : SDNode<"AlphaISD::GPRelHi", SDTIntBinOp, []>; +def Alpha_rellit : SDNode<"AlphaISD::RelLit", SDTIntBinOp, []>; +def Alpha_ldq : SDNode<"AlphaISD::LDQ_", SDTLoadA, [SDNPInFlag]>; +def Alpha_ldt : SDNode<"AlphaISD::LDT_", SDTLoadA, [SDNPInFlag]>; +def Alpha_lds : SDNode<"AlphaISD::LDS_", SDTLoadA, [SDNPInFlag]>; +def Alpha_ldl : SDNode<"AlphaISD::LDL_", SDTLoadA, [SDNPInFlag]>; +def Alpha_ldwu : SDNode<"AlphaISD::LDWU_", SDTLoadA, [SDNPInFlag]>; +def Alpha_ldbu : SDNode<"AlphaISD::LDBU_", SDTLoadA, [SDNPInFlag]>; // These are target-independent nodes, but have target-specific formats. def SDT_AlphaCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i64> ]>; @@ -114,8 +123,9 @@ def ADJUSTSTACKDOWN : PseudoInstAlpha<(ops s64imm:$amt), "; ADJDOWN $amt", } def ALTENT : PseudoInstAlpha<(ops s64imm:$TARGET), "$$$TARGET..ng:\n", []>; def PCLABEL : PseudoInstAlpha<(ops s64imm:$num), "PCMARKER_$num:\n",[]>; +let noResults = 1 in def MEMLABEL : PseudoInstAlpha<(ops s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m), - "LSMARKER$$$i$$$j$$$k$$$m:\n",[]>; + "LSMARKER$$$i$$$j$$$k$$$m:", []>; @@ -569,6 +579,30 @@ def LDQl : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)\t\t!literal", def : Pat<(Alpha_rellit texternalsym:$ext, GPRC:$RB), (LDQl texternalsym:$ext, GPRC:$RB)>; + +let OperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB, + s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m) in { +def LDQlbl : MForm<0x29, 0, 1, "LSMARKER$$$i$$$j$$$k$$$m:\n\t ldq $RA,$DISP($RB)", + [(set GPRC:$RA, (Alpha_ldq imm:$DISP, GPRC:$RB, imm:$i, imm:$j, imm:$k, imm:$m))]>; +} + +let OperandList = (ops F8RC:$RA, s64imm:$DISP, GPRC:$RB, + s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m) in +def LDTlbl : MForm<0x29, 0, 1, "LSMARKER$$$i$$$j$$$k$$$m:\n\t ldt $RA,$DISP($RB)", + [(set F8RC:$RA, (Alpha_ldt imm:$DISP, GPRC:$RB, imm:$i, imm:$j, imm:$k, imm:$m))]>; + +let OperandList = (ops F4RC:$RA, s64imm:$DISP, GPRC:$RB, + s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m) in +def LDSlbl : MForm<0x29, 0, 1, "LSMARKER$$$i$$$j$$$k$$$m:\n\t lds $RA,$DISP($RB)", + [(set F4RC:$RA, (Alpha_lds imm:$DISP, GPRC:$RB, imm:$i, imm:$j, imm:$k, imm:$m))]>; + +//def LDLlbl : MForm<0x29, 0, 1, "ldl $RA,$DISP($RB)", +// [(set GPRC:$RA, (sextload (add GPRC:$RB, immSExt16:$DISP), i32))]>; +//def LDBUlbl : MForm<0x0A, 0, 1, "ldbu $RA,$DISP($RB)", +// [(set GPRC:$RA, (zextload (add GPRC:$RB, immSExt16:$DISP), i8))]>; +//def LDWUlbl : MForm<0x0C, 0, 1, "ldwu $RA,$DISP($RB)", +// [(set GPRC:$RA, (zextload (add GPRC:$RB, immSExt16:$DISP), i16))]>; + def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA">; //Read process cycle counter //Basic Floating point ops