mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
CellSPU:
- 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:
parent
210de72cd7
commit
9de57a9ed2
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user