- Update DWARF debugging support.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63059 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Scott Michel 2009-01-26 22:33:37 +00:00
parent 210de72cd7
commit 9de57a9ed2
6 changed files with 75 additions and 70 deletions

View File

@ -90,13 +90,13 @@ namespace {
printOp(MO);
}
}
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode);
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode);
void
printS7ImmOperand(const MachineInstr *MI, unsigned OpNo)
{
@ -115,7 +115,7 @@ namespace {
assert(value < (1 << 8) && "Invalid u7 argument");
O << value;
}
void
printShufAddr(const MachineInstr *MI, unsigned OpNo)
{
@ -143,7 +143,7 @@ namespace {
{
O << (unsigned)MI->getOperand(OpNo).getImm();
}
void
printMemRegReg(const MachineInstr *MI, unsigned OpNo) {
// When used as the base register, r0 reads constant zero rather than
@ -286,7 +286,7 @@ namespace {
/// LinuxAsmPrinter - SPU assembly printer, customized for Linux
struct VISIBILITY_HIDDEN LinuxAsmPrinter : public SPUAsmPrinter {
DwarfWriter *DW;
MachineModuleInfo *MMI;
@ -300,12 +300,12 @@ namespace {
virtual const char *getPassName() const {
return "STI CBEA SPU Assembly Printer";
}
bool runOnMachineFunction(MachineFunction &F);
bool doInitialization(Module &M);
//! Dump globals, perform cleanup after function emission
bool doFinalization(Module &M);
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<MachineModuleInfo>();
@ -365,7 +365,7 @@ void SPUAsmPrinter::printOp(const MachineOperand &MO) {
}
}
O << Name;
if (GV->hasExternalWeakLinkage())
ExtWeakSymbols.insert(GV);
return;
@ -380,15 +380,15 @@ void SPUAsmPrinter::printOp(const MachineOperand &MO) {
/// PrintAsmOperand - Print out an operand for an inline asm expression.
///
bool SPUAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant,
unsigned AsmVariant,
const char *ExtraCode) {
// Does this asm operand have a single letter operand modifier?
if (ExtraCode && ExtraCode[0]) {
if (ExtraCode[1] != 0) return true; // Unknown modifier.
switch (ExtraCode[0]) {
default: return true; // Unknown modifier.
case 'L': // Write second word of DImode reference.
case 'L': // Write second word of DImode reference.
// Verify that this operand has two consecutive registers.
if (!MI->getOperand(OpNo).isReg() ||
OpNo+1 == MI->getNumOperands() ||
@ -398,14 +398,14 @@ bool SPUAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
break;
}
}
printOperand(MI, OpNo);
return false;
}
bool SPUAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
unsigned OpNo,
unsigned AsmVariant,
unsigned AsmVariant,
const char *ExtraCode) {
if (ExtraCode && ExtraCode[0])
return true; // Unknown modifier.
@ -429,7 +429,7 @@ LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF)
{
SetupMachineFunction(MF);
O << "\n\n";
// Print out constants referenced by the function
EmitConstantPool(MF.getConstantPool());
@ -478,10 +478,10 @@ LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF)
// Print out jump tables referenced by the function.
EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
// Emit post-function debug information.
DW->EndFunction(&MF);
// We didn't modify anything.
return false;
}
@ -509,7 +509,7 @@ static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) {
/*!
Emit a global variable according to its section, alignment, etc.
\note This code was shamelessly copied from the PowerPC's assembly printer,
which sort of screams for some kind of refactorization of common code.
*/
@ -602,8 +602,6 @@ bool LinuxAsmPrinter::doFinalization(Module &M) {
I != E; ++I)
printModuleLevelGV(I);
// TODO
// Emit initial debug information.
DW->EndModule();

View File

@ -51,16 +51,6 @@ namespace {
return isS10Constant(CN->getSExtValue());
}
#if 0
//! SDNode predicate for sign-extended, 10-bit immediate values
bool
isI32IntS10Immediate(SDNode *N)
{
return (N->getOpcode() == ISD::Constant
&& isI32IntS10Immediate(cast<ConstantSDNode>(N)));
}
#endif
//! ConstantSDNode predicate for i32 unsigned 10-bit immediate values
bool
isI32IntU10Immediate(ConstantSDNode *CN)
@ -79,8 +69,8 @@ namespace {
bool
isI16IntS10Immediate(SDNode *N)
{
return (N->getOpcode() == ISD::Constant
&& isI16IntS10Immediate(cast<ConstantSDNode>(N)));
ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N);
return (CN != 0 && isI16IntS10Immediate(CN));
}
//! ConstantSDNode predicate for i16 unsigned 10-bit immediate values
@ -230,7 +220,7 @@ public:
SelectionDAGISel(tm),
TM(tm),
SPUtli(*tm.getTargetLowering())
{}
{ }
virtual bool runOnFunction(Function &Fn) {
// Make sure we re-emit a set of the global base reg if necessary
@ -259,32 +249,21 @@ public:
SDNode *emitBuildVector(SDValue build_vec) {
MVT vecVT = build_vec.getValueType();
SDNode *bvNode = build_vec.getNode();
bool canBeSelected = false;
// Check to see if this vector can be represented as a CellSPU immediate
// constant.
if (vecVT == MVT::v8i16) {
if (SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0) {
canBeSelected = true;
}
} else if (vecVT == MVT::v4i32) {
if ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0)
|| (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0)
|| (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0)
|| (SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0)) {
canBeSelected = true;
}
} else if (vecVT == MVT::v2i64) {
if ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)
|| (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)
|| (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)) {
canBeSelected = true;
}
}
if (canBeSelected) {
// constant by invoking all of the instruction selection predicates:
if (((vecVT == MVT::v8i16) &&
(SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0)) ||
((vecVT == MVT::v4i32) &&
((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
(SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
(SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) ||
(SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0))) ||
((vecVT == MVT::v2i64) &&
((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) ||
(SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) ||
(SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0))))
return Select(build_vec);
}
// No, need to emit a constant pool spill:
std::vector<Constant*> CV;
@ -411,7 +390,7 @@ SPUDAGToDAGISel::InstructionSelect()
}
/*!
\arg Op The ISD instructio operand
\arg Op The ISD instruction operand
\arg N The address to be tested
\arg Base The base address
\arg Index The base address index
@ -790,9 +769,10 @@ SPUDAGToDAGISel::Select(SDValue Op) {
if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL)
&& OpVT == MVT::i32
&& Op0.getValueType() == MVT::i64) {
// Catch the (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32 to
// take advantage of the fact that the upper 32 bits are in the
// i32 preferred slot and avoid all kinds of other shuffle gymnastics:
// Catch (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32
//
// Take advantage of the fact that the upper 32 bits are in the
// i32 preferred slot and avoid shuffle gymnastics:
ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0.getOperand(1));
if (CN != 0) {
unsigned shift_amt = unsigned(CN->getZExtValue());
@ -806,7 +786,7 @@ SPUDAGToDAGISel::Select(SDValue Op) {
// Take care of the additional shift, if present:
SDValue shift = CurDAG->getTargetConstant(shift_amt, MVT::i32);
unsigned Opc = SPU::ROTMAIr32_i32;
if (Op0.getOpcode() == ISD::SRL)
Opc = SPU::ROTMr32;
@ -1113,8 +1093,8 @@ SDNode *SPUDAGToDAGISel::SelectI64Constant(SDValue& Op, MVT OpVT) {
// The degenerate case where the upper and lower bits in the splat are
// identical:
SDValue Op0 = i64vec.getOperand(0);
ReplaceUses(i64vec, Op0);
ReplaceUses(i64vec, Op0);
return CurDAG->getTargetNode(SPU::ORi64_v2i64, OpVT,
SDValue(emitBuildVector(Op0), 0));
} else if (i64vec.getOpcode() == SPUISD::SHUFB) {
@ -1139,7 +1119,7 @@ SDNode *SPUDAGToDAGISel::SelectI64Constant(SDValue& Op, MVT OpVT) {
SDNode *rhsNode = (rhs.getNode()->isMachineOpcode()
? rhs.getNode()
: emitBuildVector(rhs));
if (shufmask.getOpcode() == ISD::BIT_CONVERT) {
ReplaceUses(shufmask, shufmask.getOperand(0));
shufmask = shufmask.getOperand(0);

View File

@ -293,7 +293,7 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
// FDIV on SPU requires custom lowering
setOperationAction(ISD::FDIV, MVT::f64, Expand); // to libcall
// SPU has [U|S]INT_TO_FP
// SPU has [U|S]INT_TO_FP for f32->i32, but not for f64->i32, f64->i64:
setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);
@ -2281,6 +2281,7 @@ LowerByteImmed(SDValue Op, SelectionDAG &DAG) {
DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize));
}
}
// These operations (AND, OR, XOR) are legal, they just couldn't be custom
// lowered. Return the operation, rather than a null SDValue.
return Op;
@ -2417,7 +2418,7 @@ static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI);
}
return SDValue();
return Op; // return unmolested, legalized op
}
//! Lower ISD::SINT_TO_FP, ISD::UINT_TO_FP for i32
@ -2443,7 +2444,7 @@ static SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG,
return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI);
}
return SDValue();
return Op; // return unmolested, legalized
}
//! Lower ISD::SETCC

View File

@ -290,6 +290,9 @@ class RR_Int_v4i32<bits<11> opcode, string opc, InstrItinClass itin,
class Pseudo<dag OOL, dag IOL, string asmstr, list<dag> pattern>
: SPUInstr<OOL, IOL, asmstr, NoItinerary> {
let OutOperandList = OOL;
let InOperandList = IOL;
let AsmString = asmstr;
let Pattern = pattern;
let Inst{31-0} = 0;
}

View File

@ -34,10 +34,9 @@ let hasCtrlDep = 1, Defs = [R1], Uses = [R1] in {
// DWARF debugging Pseudo Instructions
//===----------------------------------------------------------------------===//
def DWARF_LOC : Pseudo<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file),
"${:comment} .loc $file, $line, $col",
[(dwarf_loc (i32 imm:$line), (i32 imm:$col),
(i32 imm:$file))]>;
def DWARF_LOC : Pseudo<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file),
".loc $file, $line, $col",
[(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>;
//===----------------------------------------------------------------------===//
// Loads:

View File

@ -15,8 +15,10 @@
#include "SPUTargetMachine.h"
#include "llvm/Function.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Dwarf.h"
using namespace llvm;
using namespace llvm::dwarf;
SPULinuxTargetAsmInfo::SPULinuxTargetAsmInfo(const SPUTargetMachine &TM) :
SPUTargetAsmInfo<ELFTargetAsmInfo>(TM) {
@ -27,12 +29,34 @@ SPULinuxTargetAsmInfo::SPULinuxTargetAsmInfo(const SPUTargetMachine &TM) :
// This corresponds to what the gcc SPU compiler emits, for consistency.
CStringSection = ".rodata.str";
// Has leb128, .loc and .file
HasLEB128 = true;
HasDotLocAndDotFile = true;
// BSS section needs to be emitted as ".section"
BSSSection = "\t.section\t.bss";
BSSSection_ = getUnnamedSection("\t.section\t.bss",
SectionFlags::Writeable | SectionFlags::BSS,
true);
SupportsDebugInformation = true;
NeedsSet = true;
SupportsMacInfoSection = false;
DwarfAbbrevSection = "\t.section .debug_abbrev,\"\",@progbits";
DwarfInfoSection = "\t.section .debug_info,\"\",@progbits";
DwarfLineSection = "\t.section .debug_line,\"\",@progbits";
DwarfFrameSection = "\t.section .debug_frame,\"\",@progbits";
DwarfPubNamesSection = "\t.section .debug_pubnames,\"\",@progbits";
DwarfPubTypesSection = "\t.section .debug_pubtypes,\"\",progbits";
DwarfStrSection = "\t.section .debug_str,\"MS\",@progbits,1";
DwarfLocSection = "\t.section .debug_loc,\"\",@progbits";
DwarfARangesSection = "\t.section .debug_aranges,\"\",@progbits";
DwarfRangesSection = "\t.section .debug_ranges,\"\",@progbits";
DwarfMacInfoSection = "\t.section .debug_macinfo,\"\",progbits";
// Exception handling is not supported on CellSPU (think about it: you only
// have 256K for code+data. Would you support exception handling?)
SupportsExceptionHandling = false;
}
/// PreferredEHDataFormat - This hook allows the target to select data