Update LLVM to r100285.

This commit is contained in:
Roman Divacky 2010-04-03 07:51:10 +00:00
parent 104bd8179f
commit b5efedaf2a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/llvm/dist/; revision=206124
134 changed files with 10293 additions and 1430 deletions

View File

@ -1612,6 +1612,11 @@ $(ObjDir)/%GenIntrinsics.inc.tmp : %.td $(ObjDir)/.dir
$(Echo) "Building $(<F) intrinsics information with tblgen"
$(Verb) $(TableGen) -gen-tgt-intrinsic -o $(call SYSPATH, $@) $<
$(ObjDir)/ARMGenDecoderTables.inc.tmp : ARM.td $(ObjDir)/.dir
$(Echo) "Building $(<F) decoder tables with tblgen"
$(Verb) $(TableGen) -gen-arm-decoder -o $(call SYSPATH, $@) $<
clean-local::
-$(Verb) $(RM) -f $(INCFiles)

View File

@ -221,15 +221,35 @@ License, a "BSD-style" license.</p>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="dragonegg">DragonEgg: GCC-4.5 as an LLVM frontend</a>
<a name="dragonegg">DragonEgg: llvm-gcc ported to gcc-4.5</a>
</div>
<div class="doc_text">
<p>
The goal of <a href="http://dragonegg.llvm.org/">DragonEgg</a> is to make
gcc-4.5 act like llvm-gcc without requiring any gcc modifications whatsoever.
<a href="http://dragonegg.llvm.org/">DragonEgg</a> is a shared library (dragonegg.so)
that is loaded by gcc at runtime. It ...
<a href="http://dragonegg.llvm.org/">DragonEgg</a> is a port of llvm-gcc to
gcc-4.5. Unlike llvm-gcc, which makes many intrusive changes to the underlying
gcc-4.2 code, dragonegg in theory does not require any gcc-4.5 modifications
whatsoever (currently one small patch is needed). This is thanks to the new
<a href="http://gcc.gnu.org/wiki/plugins">gcc plugin architecture</a>, which
makes it possible to modify the behaviour of gcc at runtime by loading a plugin,
which is nothing more than a dynamic library which conforms to the gcc plugin
interface. DragonEgg is a gcc plugin that causes the LLVM optimizers to be run
instead of the gcc optimizers, and the LLVM code generators instead of the gcc
code generators, just like llvm-gcc. To use it, you add
"-fplugin=path/dragonegg.so" to the gcc-4.5 command line, and gcc-4.5 magically
becomes llvm-gcc-4.5!
</p>
<p>
DragonEgg is still a work in progress. Currently C works very well, while C++,
Ada and Fortran work fairly well. All other languages either don't work at all,
or only work poorly. For the moment only the x86-32 and x86-64 targets are
supported, and only on linux.
</p>
<p>
DragonEgg has not yet been released. Once gcc-4.5 has been released, dragonegg
will probably be released as part of the following LLVM release.
</p>
</div>
@ -1058,7 +1078,7 @@ lists</a>.</p>
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2010-04-01 03:53:24 +0200 (Thu, 01 Apr 2010) $
Last modified: $Date: 2010-04-02 11:23:15 +0200 (Fri, 02 Apr 2010) $
</address>
</body>

View File

@ -31,8 +31,6 @@ namespace llvm {
class Type;
class Value;
class DbgDeclareInst;
class DebugLoc;
struct DebugLocTracker;
class Instruction;
class MDNode;
class LLVMContext;
@ -710,11 +708,6 @@ namespace llvm {
std::string &Type, unsigned &LineNo, std::string &File,
std::string &Dir);
/// ExtractDebugLocation - Extract debug location information
/// from DILocation.
DebugLoc ExtractDebugLocation(DILocation &Loc,
DebugLocTracker &DebugLocInfo);
/// getDISubprogram - Find subprogram that is enclosing this scope.
DISubprogram getDISubprogram(MDNode *Scope);

View File

@ -31,6 +31,10 @@ class LoopPass : public Pass {
explicit LoopPass(intptr_t pid) : Pass(PT_Loop, pid) {}
explicit LoopPass(void *pid) : Pass(PT_Loop, pid) {}
/// getPrinterPass - Get a pass to print the function corresponding
/// to a Loop.
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
// runOnLoop - This method should be implemented by the subclass to perform
// whatever action is necessary for the specified Loop.
virtual bool runOnLoop(Loop *L, LPPassManager &LPM) = 0;

View File

@ -27,7 +27,9 @@ namespace llvm {
/// createPrintModulePass - Create and return a pass that writes the
/// module to the specified raw_ostream.
ModulePass *createPrintModulePass(raw_ostream *OS, bool DeleteStream=false);
ModulePass *createPrintModulePass(raw_ostream *OS,
bool DeleteStream=false,
const std::string &Banner = "");
/// createPrintFunctionPass - Create and return a pass that prints
/// functions to the specified raw_ostream as they are processed.

View File

@ -131,6 +131,12 @@ class BasicBlock : public Value, // Basic blocks are data objects also
const Instruction* getFirstNonPHI() const {
return const_cast<BasicBlock*>(this)->getFirstNonPHI();
}
// Same as above, but also skip debug intrinsics.
Instruction* getFirstNonPHIOrDbg();
const Instruction* getFirstNonPHIOrDbg() const {
return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbg();
}
/// removeFromParent - This method unlinks 'this' from the containing
/// function, but does not delete it.

View File

@ -240,7 +240,10 @@ namespace bitc {
// new select on i1 or [N x i1]
FUNC_CODE_INST_VSELECT = 29, // VSELECT: [ty,opval,opval,predty,pred]
FUNC_CODE_INST_INBOUNDS_GEP= 30, // INBOUNDS_GEP: [n x operands]
FUNC_CODE_INST_INDIRECTBR = 31 // INDIRECTBR: [opty, op0, op1, ...]
FUNC_CODE_INST_INDIRECTBR = 31, // INDIRECTBR: [opty, op0, op1, ...]
FUNC_CODE_DEBUG_LOC = 32, // DEBUG_LOC: [Line,Col,ScopeVal, IAVal]
FUNC_CODE_DEBUG_LOC_AGAIN = 33 // DEBUG_LOC_AGAIN
};
} // End bitc namespace
} // End llvm namespace

View File

@ -35,6 +35,10 @@ struct CallGraphSCCPass : public Pass {
explicit CallGraphSCCPass(intptr_t pid) : Pass(PT_CallGraphSCC, pid) {}
explicit CallGraphSCCPass(void *pid) : Pass(PT_CallGraphSCC, pid) {}
/// createPrinterPass - Get a pass that prints the Module
/// corresponding to a CallGraph.
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
/// doInitialization - This method is called before the SCC's of the program
/// has been processed, allowing the pass to do initialization as necessary.
virtual bool doInitialization(CallGraph &CG) {

View File

@ -19,6 +19,7 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/Support/DebugLoc.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/DenseMap.h"
namespace llvm {
class BlockAddress;

View File

@ -26,7 +26,6 @@
namespace llvm {
class DILocation;
class Value;
class Function;
class MachineRegisterInfo;
@ -112,9 +111,6 @@ class MachineFunction {
// of a function.
DebugLoc DefaultDebugLoc;
// Tracks debug locations.
DebugLocTracker DebugLocInfo;
/// FunctionNumber - This provides a unique ID for each function emitted in
/// this translation unit.
///
@ -402,9 +398,6 @@ class MachineFunction {
// Debug location.
//
/// getDILocation - Get the DILocation for a given DebugLoc object.
DILocation getDILocation(DebugLoc DL) const;
/// getDefaultDebugLoc - Get the default debug location for the machine
/// function.
DebugLoc getDefaultDebugLoc() const { return DefaultDebugLoc; }
@ -412,9 +405,6 @@ class MachineFunction {
/// setDefaultDebugLoc - Get the default debug location for the machine
/// function.
void setDefaultDebugLoc(DebugLoc DL) { DefaultDebugLoc = DL; }
/// getDebugLocInfo - Get the debug info location tracker.
DebugLocTracker &getDebugLocInfo() { return DebugLocInfo; }
};
//===--------------------------------------------------------------------===//

View File

@ -34,6 +34,9 @@ class MachineFunctionPass : public FunctionPass {
explicit MachineFunctionPass(intptr_t ID) : FunctionPass(ID) {}
explicit MachineFunctionPass(void *ID) : FunctionPass(ID) {}
/// createPrinterPass - Get a machine function printer pass.
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
/// runOnMachineFunction - This method must be overloaded to perform the
/// desired machine code transformation or analysis.
///

View File

@ -16,12 +16,13 @@
#ifndef LLVM_CODEGEN_MACHINEINSTR_H
#define LLVM_CODEGEN_MACHINEINSTR_H
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/Target/TargetInstrDesc.h"
#include "llvm/Target/TargetOpcodes.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/DebugLoc.h"
#include <vector>

View File

@ -37,6 +37,7 @@
#include "llvm/CodeGen/MachineLocation.h"
#include "llvm/MC/MCContext.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/DebugLoc.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/System/DataTypes.h"
#include "llvm/ADT/DenseMap.h"
@ -156,8 +157,8 @@ class MachineModuleInfo : public ImmutablePass {
public:
static char ID; // Pass identification, replacement for typeid
typedef std::pair<unsigned, TrackingVH<MDNode> > UnsignedAndMDNodePair;
typedef SmallVector< std::pair<TrackingVH<MDNode>, UnsignedAndMDNodePair>, 4>
typedef std::pair<unsigned, DebugLoc> UnsignedDebugLocPair;
typedef SmallVector<std::pair<TrackingVH<MDNode>, UnsignedDebugLocPair>, 4>
VariableDbgInfoMapTy;
VariableDbgInfoMapTy VariableDbgInfo;
@ -330,10 +331,10 @@ class MachineModuleInfo : public ImmutablePass {
/// of one is required to emit exception handling info.
Function *getPersonality() const;
/// setVariableDbgInfo - Collect information used to emit debugging information
/// of a variable.
void setVariableDbgInfo(MDNode *N, unsigned Slot, MDNode *Scope) {
VariableDbgInfo.push_back(std::make_pair(N, std::make_pair(Slot, Scope)));
/// setVariableDbgInfo - Collect information used to emit debugging
/// information of a variable.
void setVariableDbgInfo(MDNode *N, unsigned Slot, DebugLoc Loc) {
VariableDbgInfo.push_back(std::make_pair(N, std::make_pair(Slot, Loc)));
}
VariableDbgInfoMapTy &getVariableDbgInfo() { return VariableDbgInfo; }

View File

@ -21,6 +21,7 @@
namespace llvm {
class FunctionPass;
class MachineFunctionPass;
class PassInfo;
class TargetLowering;
class RegisterCoalescer;
@ -36,8 +37,9 @@ namespace llvm {
/// MachineFunctionPrinter pass - This pass prints out the machine function to
/// the given stream, as a debugging tool.
FunctionPass *createMachineFunctionPrinterPass(raw_ostream &OS,
const std::string &Banner ="");
MachineFunctionPass *
createMachineFunctionPrinterPass(raw_ostream &OS,
const std::string &Banner ="");
/// MachineLoopInfo pass - This pass is a loop analysis pass.
///

View File

@ -461,8 +461,7 @@ class SelectionDAG {
SDValue getCALLSEQ_START(SDValue Chain, SDValue Op) {
SDVTList VTs = getVTList(MVT::Other, MVT::Flag);
SDValue Ops[] = { Chain, Op };
return getNode(ISD::CALLSEQ_START, DebugLoc::getUnknownLoc(),
VTs, Ops, 2);
return getNode(ISD::CALLSEQ_START, DebugLoc(), VTs, Ops, 2);
}
/// getCALLSEQ_END - Return a new CALLSEQ_END node, which always must have a
@ -476,20 +475,19 @@ class SelectionDAG {
Ops.push_back(Op1);
Ops.push_back(Op2);
Ops.push_back(InFlag);
return getNode(ISD::CALLSEQ_END, DebugLoc::getUnknownLoc(), NodeTys,
&Ops[0],
return getNode(ISD::CALLSEQ_END, DebugLoc(), NodeTys, &Ops[0],
(unsigned)Ops.size() - (InFlag.getNode() == 0 ? 1 : 0));
}
/// getUNDEF - Return an UNDEF node. UNDEF does not have a useful DebugLoc.
SDValue getUNDEF(EVT VT) {
return getNode(ISD::UNDEF, DebugLoc::getUnknownLoc(), VT);
return getNode(ISD::UNDEF, DebugLoc(), VT);
}
/// getGLOBAL_OFFSET_TABLE - Return a GLOBAL_OFFSET_TABLE node. This does
/// not have a useful DebugLoc.
SDValue getGLOBAL_OFFSET_TABLE(EVT VT) {
return getNode(ISD::GLOBAL_OFFSET_TABLE, DebugLoc::getUnknownLoc(), VT);
return getNode(ISD::GLOBAL_OFFSET_TABLE, DebugLoc(), VT);
}
/// getNode - Gets or creates the specified node.

View File

@ -1569,8 +1569,7 @@ class HandleSDNode : public SDNode {
#else
explicit HandleSDNode(SDValue X)
#endif
: SDNode(ISD::HANDLENODE, DebugLoc::getUnknownLoc(),
getSDVTList(MVT::Other)) {
: SDNode(ISD::HANDLENODE, DebugLoc(), getSDVTList(MVT::Other)) {
InitOperands(&Op, X);
}
~HandleSDNode();
@ -1801,7 +1800,7 @@ class ConstantSDNode : public SDNode {
friend class SelectionDAG;
ConstantSDNode(bool isTarget, const ConstantInt *val, EVT VT)
: SDNode(isTarget ? ISD::TargetConstant : ISD::Constant,
DebugLoc::getUnknownLoc(), getSDVTList(VT)), Value(val) {
DebugLoc(), getSDVTList(VT)), Value(val) {
}
public:
@ -1825,7 +1824,7 @@ class ConstantFPSDNode : public SDNode {
friend class SelectionDAG;
ConstantFPSDNode(bool isTarget, const ConstantFP *val, EVT VT)
: SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP,
DebugLoc::getUnknownLoc(), getSDVTList(VT)), Value(val) {
DebugLoc(), getSDVTList(VT)), Value(val) {
}
public:
@ -1896,7 +1895,7 @@ class FrameIndexSDNode : public SDNode {
friend class SelectionDAG;
FrameIndexSDNode(int fi, EVT VT, bool isTarg)
: SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex,
DebugLoc::getUnknownLoc(), getSDVTList(VT)), FI(fi) {
DebugLoc(), getSDVTList(VT)), FI(fi) {
}
public:
@ -1915,7 +1914,7 @@ class JumpTableSDNode : public SDNode {
friend class SelectionDAG;
JumpTableSDNode(int jti, EVT VT, bool isTarg, unsigned char TF)
: SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable,
DebugLoc::getUnknownLoc(), getSDVTList(VT)), JTI(jti), TargetFlags(TF) {
DebugLoc(), getSDVTList(VT)), JTI(jti), TargetFlags(TF) {
}
public:
@ -1941,7 +1940,7 @@ class ConstantPoolSDNode : public SDNode {
ConstantPoolSDNode(bool isTarget, Constant *c, EVT VT, int o, unsigned Align,
unsigned char TF)
: SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
DebugLoc::getUnknownLoc(),
DebugLoc(),
getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) {
assert((int)Offset >= 0 && "Offset is too large");
Val.ConstVal = c;
@ -1949,7 +1948,7 @@ class ConstantPoolSDNode : public SDNode {
ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v,
EVT VT, int o, unsigned Align, unsigned char TF)
: SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
DebugLoc::getUnknownLoc(),
DebugLoc(),
getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) {
assert((int)Offset >= 0 && "Offset is too large");
Val.MachineCPVal = v;
@ -1997,8 +1996,7 @@ class BasicBlockSDNode : public SDNode {
/// blocks out of order when they're jumped to, which makes it a bit
/// harder. Let's see if we need it first.
explicit BasicBlockSDNode(MachineBasicBlock *mbb)
: SDNode(ISD::BasicBlock, DebugLoc::getUnknownLoc(),
getSDVTList(MVT::Other)), MBB(mbb) {
: SDNode(ISD::BasicBlock, DebugLoc(), getSDVTList(MVT::Other)), MBB(mbb) {
}
public:
@ -2044,8 +2042,7 @@ class SrcValueSDNode : public SDNode {
friend class SelectionDAG;
/// Create a SrcValue for a general value.
explicit SrcValueSDNode(const Value *v)
: SDNode(ISD::SRCVALUE, DebugLoc::getUnknownLoc(),
getSDVTList(MVT::Other)), V(v) {}
: SDNode(ISD::SRCVALUE, DebugLoc(), getSDVTList(MVT::Other)), V(v) {}
public:
/// getValue - return the contained Value.
@ -2062,8 +2059,7 @@ class RegisterSDNode : public SDNode {
unsigned Reg;
friend class SelectionDAG;
RegisterSDNode(unsigned reg, EVT VT)
: SDNode(ISD::Register, DebugLoc::getUnknownLoc(),
getSDVTList(VT)), Reg(reg) {
: SDNode(ISD::Register, DebugLoc(), getSDVTList(VT)), Reg(reg) {
}
public:
@ -2081,7 +2077,7 @@ class BlockAddressSDNode : public SDNode {
friend class SelectionDAG;
BlockAddressSDNode(unsigned NodeTy, EVT VT, BlockAddress *ba,
unsigned char Flags)
: SDNode(NodeTy, DebugLoc::getUnknownLoc(), getSDVTList(VT)),
: SDNode(NodeTy, DebugLoc(), getSDVTList(VT)),
BA(ba), TargetFlags(Flags) {
}
public:
@ -2119,8 +2115,7 @@ class ExternalSymbolSDNode : public SDNode {
friend class SelectionDAG;
ExternalSymbolSDNode(bool isTarget, const char *Sym, unsigned char TF, EVT VT)
: SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol,
DebugLoc::getUnknownLoc(),
getSDVTList(VT)), Symbol(Sym), TargetFlags(TF) {
DebugLoc(), getSDVTList(VT)), Symbol(Sym), TargetFlags(TF) {
}
public:
@ -2138,8 +2133,8 @@ class CondCodeSDNode : public SDNode {
ISD::CondCode Condition;
friend class SelectionDAG;
explicit CondCodeSDNode(ISD::CondCode Cond)
: SDNode(ISD::CONDCODE, DebugLoc::getUnknownLoc(),
getSDVTList(MVT::Other)), Condition(Cond) {
: SDNode(ISD::CONDCODE, DebugLoc(), getSDVTList(MVT::Other)),
Condition(Cond) {
}
public:
@ -2296,8 +2291,8 @@ class VTSDNode : public SDNode {
EVT ValueType;
friend class SelectionDAG;
explicit VTSDNode(EVT VT)
: SDNode(ISD::VALUETYPE, DebugLoc::getUnknownLoc(),
getSDVTList(MVT::Other)), ValueType(VT) {
: SDNode(ISD::VALUETYPE, DebugLoc(), getSDVTList(MVT::Other)),
ValueType(VT) {
}
public:

View File

@ -22,11 +22,11 @@
#ifndef LLVM_CODEGEN_SLOTINDEXES_H
#define LLVM_CODEGEN_SLOTINDEXES_H
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ErrorHandling.h"

View File

@ -32,7 +32,7 @@ class Instruction : public User, public ilist_node<Instruction> {
Instruction(const Instruction &); // Do not implement
BasicBlock *Parent;
NewDebugLoc DbgLoc; // 'dbg' Metadata cache.
DebugLoc DbgLoc; // 'dbg' Metadata cache.
enum {
/// HasMetadataBit - This is a bit stored in the SubClassData field which
@ -181,10 +181,10 @@ class Instruction : public User, public ilist_node<Instruction> {
}
/// setDebugLoc - Set the debug location information for this instruction.
void setDebugLoc(const NewDebugLoc &Loc) { DbgLoc = Loc; }
void setDebugLoc(const DebugLoc &Loc) { DbgLoc = Loc; }
/// getDebugLoc - Return the debug location for this node as a DebugLoc.
const NewDebugLoc &getDebugLoc() const { return DbgLoc; }
const DebugLoc &getDebugLoc() const { return DbgLoc; }
private:
/// hasMetadataHashEntry - Return true if we have an entry in the on-the-side

View File

@ -782,7 +782,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
// Advanced Encryption Standard (AES) Instructions
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_aesni_aesimc : GCCBuiltin<"__builtin_ia32_aesimc128">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty],
[IntrNoMem]>;
def int_x86_aesni_aesenc : GCCBuiltin<"__builtin_ia32_aesenc128">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
@ -797,7 +797,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
[IntrNoMem]>;
def int_x86_aesni_aeskeygenassist :
GCCBuiltin<"__builtin_ia32_aeskeygenassist">,
GCCBuiltin<"__builtin_ia32_aeskeygenassist128">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty],
[IntrNoMem]>;
}

View File

@ -30,7 +30,9 @@
#define LLVM_PASS_H
#include "llvm/System/DataTypes.h"
#include <cassert>
#include <string>
#include <utility>
#include <vector>
@ -120,6 +122,11 @@ class Pass {
virtual void print(raw_ostream &O, const Module *M) const;
void dump() const; // dump - Print to stderr.
/// createPrinterPass - Get a Pass appropriate to print the IR this
/// pass operates one (Module, Function or MachineFunction).
virtual Pass *createPrinterPass(raw_ostream &O,
const std::string &Banner) const = 0;
/// Each pass is responsible for assigning a pass manager to itself.
/// PMS is the stack of available pass manager.
virtual void assignPassManager(PMStack &,
@ -233,6 +240,9 @@ class Pass {
///
class ModulePass : public Pass {
public:
/// createPrinterPass - Get a module printer pass.
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
/// runOnModule - Virtual method overriden by subclasses to process the module
/// being operated on.
virtual bool runOnModule(Module &M) = 0;
@ -293,6 +303,9 @@ class FunctionPass : public Pass {
explicit FunctionPass(intptr_t pid) : Pass(PT_Function, pid) {}
explicit FunctionPass(const void *pid) : Pass(PT_Function, pid) {}
/// createPrinterPass - Get a function printer pass.
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
/// doInitialization - Virtual method overridden by subclasses to do
/// any necessary per-module initialization.
///
@ -343,6 +356,9 @@ class BasicBlockPass : public Pass {
explicit BasicBlockPass(intptr_t pid) : Pass(PT_BasicBlock, pid) {}
explicit BasicBlockPass(const void *pid) : Pass(PT_BasicBlock, pid) {}
/// createPrinterPass - Get a function printer pass.
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
/// doInitialization - Virtual method overridden by subclasses to do
/// any necessary per-module initialization.
///

View File

@ -200,7 +200,7 @@ class SpecificBumpPtrAllocator {
while (Slab) {
char *End = Slab == Allocator.CurSlab ? Allocator.CurPtr :
(char *)Slab + Slab->Size;
for (char *Ptr = (char*)Slab+1; Ptr < End; Ptr += sizeof(T)) {
for (char *Ptr = (char*)(Slab+1); Ptr < End; Ptr += sizeof(T)) {
Ptr = Allocator.AlignPtr(Ptr, alignof<T>());
if (Ptr + sizeof(T) <= End)
reinterpret_cast<T*>(Ptr)->~T();

View File

@ -12,11 +12,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGLOC_H
#define LLVM_DEBUGLOC_H
#include "llvm/ADT/DenseMap.h"
#include <vector>
#ifndef LLVM_SUPPORT_DEBUGLOC_H
#define LLVM_SUPPORT_DEBUGLOC_H
namespace llvm {
class MDNode;
@ -25,7 +22,7 @@ namespace llvm {
/// DebugLoc - Debug location id. This is carried by Instruction, SDNode,
/// and MachineInstr to compactly encode file/line/scope information for an
/// operation.
class NewDebugLoc {
class DebugLoc {
/// LineCol - This 32-bit value encodes the line and column number for the
/// location, encoded as 24-bits for line and 8 bits for col. A value of 0
/// for either means unknown.
@ -35,15 +32,15 @@ namespace llvm {
/// decoded by LLVMContext. 0 is unknown.
int ScopeIdx;
public:
NewDebugLoc() : LineCol(0), ScopeIdx(0) {} // Defaults to unknown.
DebugLoc() : LineCol(0), ScopeIdx(0) {} // Defaults to unknown.
/// get - Get a new DebugLoc that corresponds to the specified line/col
/// scope/inline location.
static NewDebugLoc get(unsigned Line, unsigned Col,
MDNode *Scope, MDNode *InlinedAt = 0);
static DebugLoc get(unsigned Line, unsigned Col,
MDNode *Scope, MDNode *InlinedAt = 0);
/// getFromDILocation - Translate the DILocation quad into a NewDebugLoc.
static NewDebugLoc getFromDILocation(MDNode *N);
/// getFromDILocation - Translate the DILocation quad into a DebugLoc.
static DebugLoc getFromDILocation(MDNode *N);
/// isUnknown - Return true if this is an unknown location.
bool isUnknown() const { return ScopeIdx == 0; }
@ -73,48 +70,11 @@ namespace llvm {
/// DILocation compatible MDNode.
MDNode *getAsMDNode(const LLVMContext &Ctx) const;
bool operator==(const NewDebugLoc &DL) const {
bool operator==(const DebugLoc &DL) const {
return LineCol == DL.LineCol && ScopeIdx == DL.ScopeIdx;
}
bool operator!=(const NewDebugLoc &DL) const { return !(*this == DL); }
};
/// DebugLoc - Debug location id. This is carried by SDNode and MachineInstr
/// to index into a vector of unique debug location tuples.
class DebugLoc {
unsigned Idx;
public:
DebugLoc() : Idx(~0U) {} // Defaults to invalid.
static DebugLoc getUnknownLoc() { DebugLoc L; L.Idx = ~0U; return L; }
static DebugLoc get(unsigned idx) { DebugLoc L; L.Idx = idx; return L; }
unsigned getIndex() const { return Idx; }
/// isUnknown - Return true if there is no debug info for the SDNode /
/// MachineInstr.
bool isUnknown() const { return Idx == ~0U; }
bool operator==(const DebugLoc &DL) const { return Idx == DL.Idx; }
bool operator!=(const DebugLoc &DL) const { return !(*this == DL); }
};
/// DebugLocTracker - This class tracks debug location information.
///
struct DebugLocTracker {
/// DebugLocations - A vector of unique DebugLocTuple's.
///
std::vector<MDNode *> DebugLocations;
/// DebugIdMap - This maps DebugLocTuple's to indices into the
/// DebugLocations vector.
DenseMap<MDNode *, unsigned> DebugIdMap;
DebugLocTracker() {}
};
} // end namespace llvm
#endif /* LLVM_DEBUGLOC_H */

View File

@ -40,7 +40,7 @@ class IRBuilderDefaultInserter {
/// IRBuilderBase - Common base class shared among various IRBuilders.
class IRBuilderBase {
NewDebugLoc CurDbgLocation;
DebugLoc CurDbgLocation;
protected:
BasicBlock *BB;
BasicBlock::iterator InsertPt;
@ -82,13 +82,13 @@ class IRBuilderBase {
/// SetCurrentDebugLocation - Set location information used by debugging
/// information.
void SetCurrentDebugLocation(const NewDebugLoc &L) {
void SetCurrentDebugLocation(const DebugLoc &L) {
CurDbgLocation = L;
}
/// getCurrentDebugLocation - Get location information used by debugging
/// information.
const NewDebugLoc &getCurrentDebugLocation() const { return CurDbgLocation; }
const DebugLoc &getCurrentDebugLocation() const { return CurDbgLocation; }
/// SetInstDebugLocation - If this builder has a current debug location, set
/// it on the specified instruction.

View File

@ -457,6 +457,18 @@ inline int64_t abs64(int64_t x) {
return (x < 0) ? -x : x;
}
/// SignExtend32 - Sign extend B-bit number x to 32-bit int.
/// Usage int32_t r = SignExtend32<5>(x);
template <unsigned B> inline int32_t SignExtend32(int32_t x) {
return (x << (32 - B)) >> (32 - B);
}
/// SignExtend64 - Sign extend B-bit number x to 64-bit int.
/// Usage int64_t r = SignExtend64<5>(x);
template <unsigned B> inline int64_t SignExtend64(int32_t x) {
return (x << (64 - B)) >> (64 - B);
}
} // End llvm namespace
#endif

View File

@ -41,7 +41,7 @@ namespace llvm {
SlowOperationInformer(const SlowOperationInformer&); // DO NOT IMPLEMENT
void operator=(const SlowOperationInformer&); // DO NOT IMPLEMENT
public:
SlowOperationInformer(const std::string &Name);
explicit SlowOperationInformer(const std::string &Name);
~SlowOperationInformer();
/// progress - Clients should periodically call this method when they can

View File

@ -633,15 +633,19 @@ class TargetLowering {
}
/// getOptimalMemOpType - Returns the target specific optimal type for load
/// and store operations as a result of memset, memcpy, and memmove lowering.
/// If DstAlign is zero that means it's safe to destination alignment can
/// satisfy any constraint. Similarly if SrcAlign is zero it means there isn't
/// a need to check it against alignment requirement, probably because the
/// source does not need to be loaded. It returns EVT::Other if SelectionDAG
/// should be responsible for determining it.
/// and store operations as a result of memset, memcpy, and memmove
/// lowering. If DstAlign is zero that means it's safe to destination
/// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
/// means there isn't a need to check it against alignment requirement,
/// probably because the source does not need to be loaded. If
/// 'NonScalarIntSafe' is true, that means it's safe to return a
/// non-scalar-integer type, e.g. empty string source, constant, or loaded
/// from memory. It returns EVT::Other if SelectionDAG should be responsible
/// for determining it.
virtual EVT getOptimalMemOpType(uint64_t Size,
unsigned DstAlign, unsigned SrcAlign,
bool SafeToUseFP, SelectionDAG &DAG) const {
bool NonScalarIntSafe,
SelectionDAG &DAG) const {
return MVT::Other;
}

View File

@ -27,28 +27,22 @@ namespace llvm {
/// transformation wants to rewrite a set of uses of one value with uses of a
/// set of values.
class SSAUpdater {
public:
class BBInfo;
private:
/// AvailableVals - This keeps track of which value to use on a per-block
/// basis. When we insert PHI nodes, we keep track of them here.
//typedef DenseMap<BasicBlock*, Value*> AvailableValsTy;
/// basis. When we insert PHI nodes, we keep track of them here. We use
/// TrackingVH's for the value of the map because we RAUW PHI nodes when we
/// eliminate them, and want the TrackingVH's to track this.
//typedef DenseMap<BasicBlock*, TrackingVH<Value> > AvailableValsTy;
void *AV;
/// PrototypeValue is an arbitrary representative value, which we derive names
/// and a type for PHI nodes.
Value *PrototypeValue;
/// BBMap - The GetValueAtEndOfBlock method maintains this mapping from
/// basic blocks to BBInfo structures.
/// typedef DenseMap<BasicBlock*, BBInfo*> BBMapTy;
void *BM;
/// Allocator - The GetValueAtEndOfBlock method uses this BumpPtrAllocator to
/// hold its internal data. The allocator and its storage is created and
/// discarded for each invocation of GetValueAtEndOfBlock.
void *BPA;
/// IncomingPredInfo - We use this as scratch space when doing our recursive
/// walk. This should only be used in GetValueInBlockInternal, normally it
/// should be empty.
//std::vector<std::pair<BasicBlock*, TrackingVH<Value> > > IncomingPredInfo;
void *IPI;
/// InsertedPHIs - If this is non-null, the SSAUpdater adds all PHI nodes that
/// it creates to the vector.
@ -105,14 +99,6 @@ class SSAUpdater {
private:
Value *GetValueAtEndOfBlockInternal(BasicBlock *BB);
void FindPHIPlacement(BasicBlock *BB, BBInfo *Info, bool &Changed,
unsigned Counter);
void FindAvailableVal(BasicBlock *BB, BBInfo *Info, unsigned Counter);
void FindExistingPHI(BasicBlock *BB);
bool CheckIfPHIMatches(PHINode *PHI);
void RecordMatchingPHI(PHINode *PHI);
void ClearPHITags(PHINode *PHI);
void operator=(const SSAUpdater&); // DO NOT IMPLEMENT
SSAUpdater(const SSAUpdater&); // DO NOT IMPLEMENT
};

View File

@ -24,7 +24,6 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/DebugLoc.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace llvm::dwarf;
@ -1147,16 +1146,31 @@ Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, uint64_t Offset,
/// processModule - Process entire module and collect debug info.
void DebugInfoFinder::processModule(Module &M) {
unsigned MDDbgKind = M.getMDKindID("dbg");
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
for (Function::iterator FI = (*I).begin(), FE = (*I).end(); FI != FE; ++FI)
for (BasicBlock::iterator BI = (*FI).begin(), BE = (*FI).end(); BI != BE;
++BI) {
if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI))
if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI)) {
processDeclare(DDI);
else if (MDNode *L = BI->getMetadata(MDDbgKind))
processLocation(DILocation(L));
continue;
}
DebugLoc Loc = BI->getDebugLoc();
if (Loc.isUnknown())
continue;
LLVMContext &Ctx = BI->getContext();
DIDescriptor Scope(Loc.getScope(Ctx));
if (Scope.isCompileUnit())
addCompileUnit(DICompileUnit(Scope.getNode()));
else if (Scope.isSubprogram())
processSubprogram(DISubprogram(Scope.getNode()));
else if (Scope.isLexicalBlock())
processLexicalBlock(DILexicalBlock(Scope.getNode()));
if (MDNode *IA = Loc.getInlinedAt(Ctx))
processLocation(DILocation(IA));
}
NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.gv");
@ -1372,23 +1386,6 @@ bool llvm::getLocationInfo(const Value *V, std::string &DisplayName,
return true;
}
/// ExtractDebugLocation - Extract debug location information
/// from DILocation.
DebugLoc llvm::ExtractDebugLocation(DILocation &Loc,
DebugLocTracker &DebugLocInfo) {
DenseMap<MDNode *, unsigned>::iterator II
= DebugLocInfo.DebugIdMap.find(Loc.getNode());
if (II != DebugLocInfo.DebugIdMap.end())
return DebugLoc::get(II->second);
// Add a new location entry.
unsigned Id = DebugLocInfo.DebugLocations.size();
DebugLocInfo.DebugLocations.push_back(Loc.getNode());
DebugLocInfo.DebugIdMap[Loc.getNode()] = Id;
return DebugLoc::get(Id);
}
/// getDISubprogram - Find subprogram that is enclosing this scope.
DISubprogram llvm::getDISubprogram(MDNode *Scope) {
DIDescriptor D(Scope);

View File

@ -87,10 +87,40 @@ class CGPassManager : public ModulePass, public PMDataManager {
bool IsCheckingMode);
};
/// PrintCallGraphPass - Print a Module corresponding to a call graph.
///
class PrintCallGraphPass : public CallGraphSCCPass {
private:
std::string Banner;
raw_ostream &Out; // raw_ostream to print on.
public:
static char ID;
PrintCallGraphPass() : CallGraphSCCPass(&ID), Out(dbgs()) {}
PrintCallGraphPass(const std::string &B, raw_ostream &o)
: CallGraphSCCPass(&ID), Banner(B), Out(o) {}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}
bool runOnSCC(std::vector<CallGraphNode *> &SCC) {
Out << Banner;
for (std::vector<CallGraphNode *>::iterator n = SCC.begin(), ne = SCC.end();
n != ne;
++n) {
(*n)->getFunction()->print(Out);
}
return false;
}
};
} // end anonymous namespace.
char CGPassManager::ID = 0;
char PrintCallGraphPass::ID = 0;
bool CGPassManager::RunPassOnSCC(Pass *P, std::vector<CallGraphNode*> &CurSCC,
CallGraph &CG, bool &CallGraphUpToDate) {
bool Changed = false;
@ -396,6 +426,11 @@ bool CGPassManager::doFinalization(CallGraph &CG) {
return Changed;
}
Pass *CallGraphSCCPass::createPrinterPass(raw_ostream &O,
const std::string &Banner) const {
return new PrintCallGraphPass(Banner, O);
}
/// Assign pass manager to manage this pass.
void CallGraphSCCPass::assignPassManager(PMStack &PMS,
PassManagerType PreferredType) {

View File

@ -14,9 +14,44 @@
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Timer.h"
using namespace llvm;
namespace {
/// PrintLoopPass - Print a Function corresponding to a Loop.
///
class PrintLoopPass : public LoopPass {
private:
std::string Banner;
raw_ostream &Out; // raw_ostream to print on.
public:
static char ID;
PrintLoopPass() : LoopPass(&ID), Out(dbgs()) {}
PrintLoopPass(const std::string &B, raw_ostream &o)
: LoopPass(&ID), Banner(B), Out(o) {}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}
bool runOnLoop(Loop *L, LPPassManager &) {
Out << Banner;
for (Loop::block_iterator b = L->block_begin(), be = L->block_end();
b != be;
++b) {
(*b)->print(Out);
}
return false;
}
};
char PrintLoopPass::ID = 0;
}
//===----------------------------------------------------------------------===//
// LPPassManager
//
@ -306,6 +341,11 @@ void LPPassManager::dumpPassStructure(unsigned Offset) {
//===----------------------------------------------------------------------===//
// LoopPass
Pass *LoopPass::createPrinterPass(raw_ostream &O,
const std::string &Banner) const {
return new PrintLoopPass(Banner, O);
}
// Check if this pass is suitable for the current LPPassManager, if
// available. This pass P is not suitable for a LPPassManager if P
// is not preserving higher level analysis info used by other

View File

@ -1644,6 +1644,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
BasicBlock *CurBB = 0;
unsigned CurBBNo = 0;
DebugLoc LastLoc;
// Read all the records.
SmallVector<uint64_t, 64> Record;
while (1) {
@ -1699,6 +1701,46 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
CurBB = FunctionBBs[0];
continue;
case bitc::FUNC_CODE_DEBUG_LOC_AGAIN: // DEBUG_LOC_AGAIN
// This record indicates that the last instruction is at the same
// location as the previous instruction with a location.
I = 0;
// Get the last instruction emitted.
if (CurBB && !CurBB->empty())
I = &CurBB->back();
else if (CurBBNo && FunctionBBs[CurBBNo-1] &&
!FunctionBBs[CurBBNo-1]->empty())
I = &FunctionBBs[CurBBNo-1]->back();
if (I == 0) return Error("Invalid DEBUG_LOC_AGAIN record");
I->setDebugLoc(LastLoc);
I = 0;
continue;
case bitc::FUNC_CODE_DEBUG_LOC: { // DEBUG_LOC: [line, col, scope, ia]
I = 0; // Get the last instruction emitted.
if (CurBB && !CurBB->empty())
I = &CurBB->back();
else if (CurBBNo && FunctionBBs[CurBBNo-1] &&
!FunctionBBs[CurBBNo-1]->empty())
I = &FunctionBBs[CurBBNo-1]->back();
if (I == 0 || Record.size() < 4)
return Error("Invalid FUNC_CODE_DEBUG_LOC record");
unsigned Line = Record[0], Col = Record[1];
unsigned ScopeID = Record[2], IAID = Record[3];
MDNode *Scope = 0, *IA = 0;
if (ScopeID) Scope = cast<MDNode>(MDValueList.getValueFwdRef(ScopeID-1));
if (IAID) IA = cast<MDNode>(MDValueList.getValueFwdRef(IAID-1));
LastLoc = DebugLoc::get(Line, Col, Scope, IA);
I->setDebugLoc(LastLoc);
I = 0;
continue;
}
case bitc::FUNC_CODE_INST_BINOP: { // BINOP: [opval, ty, opval, opcode]
unsigned OpNum = 0;
Value *LHS, *RHS;
@ -2285,8 +2327,6 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
// See if anything took the address of blocks in this function. If so,
// resolve them now.
/// BlockAddrFwdRefs - These are blockaddr references to basic blocks. These
/// are resolved lazily when functions are loaded.
DenseMap<Function*, std::vector<BlockAddrRefTy> >::iterator BAFRI =
BlockAddrFwdRefs.find(F);
if (BAFRI != BlockAddrFwdRefs.end()) {

View File

@ -596,7 +596,8 @@ static void WriteFunctionLocalMetadata(const Function &F,
static void WriteMetadataAttachment(const Function &F,
const ValueEnumerator &VE,
BitstreamWriter &Stream) {
bool StartedMetadataBlock = false;
Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3);
SmallVector<uint64_t, 64> Record;
// Write metadata attachments
@ -607,7 +608,7 @@ static void WriteMetadataAttachment(const Function &F,
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
I != E; ++I) {
MDs.clear();
I->getAllMetadata(MDs);
I->getAllMetadataOtherThanDebugLoc(MDs);
// If no metadata, ignore instruction.
if (MDs.empty()) continue;
@ -618,16 +619,11 @@ static void WriteMetadataAttachment(const Function &F,
Record.push_back(MDs[i].first);
Record.push_back(VE.getValueID(MDs[i].second));
}
if (!StartedMetadataBlock) {
Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3);
StartedMetadataBlock = true;
}
Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
Record.clear();
}
if (StartedMetadataBlock)
Stream.ExitBlock();
Stream.ExitBlock();
}
static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) {
@ -1256,19 +1252,49 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE,
// Keep a running idea of what the instruction ID is.
unsigned InstID = CstEnd;
bool NeedsMetadataAttachment = false;
DebugLoc LastDL;
// Finally, emit all the instructions, in order.
for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
I != E; ++I) {
WriteInstruction(*I, InstID, VE, Stream, Vals);
if (!I->getType()->isVoidTy())
++InstID;
// If the instruction has metadata, write a metadata attachment later.
NeedsMetadataAttachment |= I->hasMetadataOtherThanDebugLoc();
// If the instruction has a debug location, emit it.
DebugLoc DL = I->getDebugLoc();
if (DL.isUnknown()) {
// nothing todo.
} else if (DL == LastDL) {
// Just repeat the same debug loc as last time.
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals);
} else {
MDNode *Scope, *IA;
DL.getScopeAndInlinedAt(Scope, IA, I->getContext());
Vals.push_back(DL.getLine());
Vals.push_back(DL.getCol());
Vals.push_back(Scope ? VE.getValueID(Scope)+1 : 0);
Vals.push_back(IA ? VE.getValueID(IA)+1 : 0);
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
Vals.clear();
LastDL = DL;
}
}
// Emit names for all the instructions etc.
WriteValueSymbolTable(F.getValueSymbolTable(), VE, Stream);
WriteMetadataAttachment(F, VE, Stream);
if (NeedsMetadataAttachment)
WriteMetadataAttachment(F, VE, Stream);
VE.purgeFunction();
Stream.ExitBlock();
}

View File

@ -104,9 +104,16 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
// Enumerate metadata attached with this instruction.
MDs.clear();
I->getAllMetadata(MDs);
I->getAllMetadataOtherThanDebugLoc(MDs);
for (unsigned i = 0, e = MDs.size(); i != e; ++i)
EnumerateMetadata(MDs[i].second);
if (!I->getDebugLoc().isUnknown()) {
MDNode *Scope, *IA;
I->getDebugLoc().getScopeAndInlinedAt(Scope, IA, I->getContext());
if (Scope) EnumerateMetadata(Scope);
if (IA) EnumerateMetadata(IA);
}
}
}

View File

@ -340,19 +340,17 @@ static void EmitComments(const MachineInstr &MI, raw_ostream &CommentOS) {
const MachineFunction *MF = MI.getParent()->getParent();
const TargetMachine &TM = MF->getTarget();
if (!MI.getDebugLoc().isUnknown()) {
DILocation DLT = MF->getDILocation(MI.getDebugLoc());
// Print source line info.
DIScope Scope = DLT.getScope();
DebugLoc DL = MI.getDebugLoc();
if (!DL.isUnknown()) { // Print source line info.
DIScope Scope(DL.getScope(MF->getFunction()->getContext()));
// Omit the directory, because it's likely to be long and uninteresting.
if (Scope.Verify())
CommentOS << Scope.getFilename();
else
CommentOS << "<unknown>";
CommentOS << ':' << DLT.getLineNumber();
if (DLT.getColumnNumber() != 0)
CommentOS << ':' << DLT.getColumnNumber();
CommentOS << ':' << DL.getLine();
if (DL.getCol() != 0)
CommentOS << ':' << DL.getCol();
CommentOS << '\n';
}

View File

@ -302,7 +302,7 @@ DwarfDebug::DwarfDebug(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T)
: DwarfPrinter(OS, A, T), ModuleCU(0),
AbbreviationsSet(InitAbbreviationsSetSize), Abbreviations(),
DIEBlocks(), SectionSourceLines(), didInitial(false), shouldEmit(false),
CurrentFnDbgScope(0), PrevDILoc(0), DebugTimer(0) {
CurrentFnDbgScope(0), DebugTimer(0) {
NextStringPoolNumber = 0;
if (TimePassesIsEnabled)
DebugTimer = new Timer("Dwarf Debug Writer");
@ -1932,13 +1932,14 @@ void DwarfDebug::endModule() {
/// findAbstractVariable - Find abstract variable, if any, associated with Var.
DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
unsigned FrameIdx,
DILocation &ScopeLoc) {
DebugLoc ScopeLoc) {
DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var.getNode());
if (AbsDbgVariable)
return AbsDbgVariable;
DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope().getNode());
LLVMContext &Ctx = Var.getNode()->getContext();
DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope(Ctx));
if (!Scope)
return NULL;
@ -1953,13 +1954,14 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
/// FIXME : Refactor findAbstractVariable.
DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
const MachineInstr *MI,
DILocation &ScopeLoc) {
DebugLoc ScopeLoc) {
DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var.getNode());
if (AbsDbgVariable)
return AbsDbgVariable;
DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope().getNode());
LLVMContext &Ctx = Var.getNode()->getContext();
DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope(Ctx));
if (!Scope)
return NULL;
@ -1975,24 +1977,27 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
void DwarfDebug::collectVariableInfo() {
if (!MMI) return;
const LLVMContext &Ctx = MF->getFunction()->getContext();
MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo();
for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(),
VE = VMap.end(); VI != VE; ++VI) {
MDNode *Var = VI->first;
if (!Var) continue;
DIVariable DV (Var);
std::pair< unsigned, MDNode *> VP = VI->second;
DILocation ScopeLoc(VP.second);
DIVariable DV(Var);
const std::pair<unsigned, DebugLoc> &VP = VI->second;
DbgScope *Scope =
ConcreteScopes.lookup(ScopeLoc.getOrigLocation().getNode());
if (!Scope)
Scope = DbgScopeMap.lookup(ScopeLoc.getScope().getNode());
DbgScope *Scope = 0;
if (MDNode *IA = VP.second.getInlinedAt(Ctx))
Scope = ConcreteScopes.lookup(IA);
if (Scope == 0)
Scope = DbgScopeMap.lookup(VP.second.getScope(Ctx));
// If variable scope is not found then skip this variable.
if (!Scope)
if (Scope == 0)
continue;
DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.first, ScopeLoc);
DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.first, VP.second);
DbgVariable *RegVar = new DbgVariable(DV, VP.first, AbsDbgVariable);
Scope->addVariable(RegVar);
}
@ -2021,16 +2026,17 @@ void DwarfDebug::collectVariableInfo() {
DebugLoc DL = MInsn->getDebugLoc();
if (DL.isUnknown()) continue;
DILocation ScopeLoc = MF->getDILocation(DL);
DbgScope *Scope =
ConcreteScopes.lookup(ScopeLoc.getOrigLocation().getNode());
if (!Scope)
Scope = DbgScopeMap.lookup(ScopeLoc.getScope().getNode());
DbgScope *Scope = 0;
if (MDNode *IA = DL.getInlinedAt(Ctx))
Scope = ConcreteScopes.lookup(IA);
if (Scope == 0)
Scope = DbgScopeMap.lookup(DL.getScope(Ctx));
// If variable scope is not found then skip this variable.
if (!Scope)
if (Scope == 0)
continue;
DbgVariable *AbsDbgVariable = findAbstractVariable(DV, MInsn, ScopeLoc);
DbgVariable *AbsDbgVariable = findAbstractVariable(DV, MInsn, DL);
DbgVariable *RegVar = new DbgVariable(DV, MInsn, AbsDbgVariable);
DbgValueStartMap[MInsn] = RegVar;
Scope->addVariable(RegVar);
@ -2044,12 +2050,15 @@ void DwarfDebug::beginScope(const MachineInstr *MI) {
DebugLoc DL = MI->getDebugLoc();
if (DL.isUnknown())
return;
DILocation DILoc = MF->getDILocation(DL);
if (!DILoc.getScope().Verify())
return;
// Check and update last known location info.
if(DILoc.getNode() == PrevDILoc)
if (DL == PrevInstLoc)
return;
MDNode *Scope = DL.getScope(MF->getFunction()->getContext());
// FIXME: Should only verify each scope once!
if (!DIScope(Scope).Verify())
return;
// DBG_VALUE instruction establishes new value.
@ -2057,10 +2066,8 @@ void DwarfDebug::beginScope(const MachineInstr *MI) {
DenseMap<const MachineInstr *, DbgVariable *>::iterator DI
= DbgValueStartMap.find(MI);
if (DI != DbgValueStartMap.end()) {
MCSymbol *Label = recordSourceLine(DILoc.getLineNumber(),
DILoc.getColumnNumber(),
DILoc.getScope().getNode());
PrevDILoc = DILoc.getNode();
MCSymbol *Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
PrevInstLoc = DL;
DI->second->setDbgValueLabel(Label);
}
return;
@ -2068,10 +2075,8 @@ void DwarfDebug::beginScope(const MachineInstr *MI) {
// Emit a label to indicate location change. This is used for line
// table even if this instruction does start a new scope.
MCSymbol *Label = recordSourceLine(DILoc.getLineNumber(),
DILoc.getColumnNumber(),
DILoc.getScope().getNode());
PrevDILoc = DILoc.getNode();
MCSymbol *Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
PrevInstLoc = DL;
// update DbgScope if this instruction starts a new scope.
InsnToDbgScopeMapTy::iterator I = DbgScopeBeginMap.find(MI);
@ -2094,15 +2099,12 @@ void DwarfDebug::endScope(const MachineInstr *MI) {
DebugLoc DL = MI->getDebugLoc();
if (DL.isUnknown())
return;
DILocation DILoc = MF->getDILocation(DL);
if (!DILoc.getScope().Verify())
return;
// Emit a label and update DbgScope if this instruction ends a scope.
InsnToDbgScopeMapTy::iterator I = DbgScopeEndMap.find(MI);
if (I == DbgScopeEndMap.end())
return;
MCSymbol *Label = MMI->getContext().CreateTempSymbol();
Asm->OutStreamer.EmitLabel(Label);
@ -2115,7 +2117,6 @@ void DwarfDebug::endScope(const MachineInstr *MI) {
/// createDbgScope - Create DbgScope for the scope.
void DwarfDebug::createDbgScope(MDNode *Scope, MDNode *InlinedAt) {
if (!InlinedAt) {
DbgScope *WScope = DbgScopeMap.lookup(Scope);
if (WScope)
@ -2147,6 +2148,8 @@ bool DwarfDebug::extractScopeInformation() {
DenseMap<const MachineInstr *, unsigned> MIIndexMap;
unsigned MIIndex = 0;
LLVMContext &Ctx = MF->getFunction()->getContext();
// Scan each instruction and create scopes. First build working set of scopes.
for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
I != E; ++I) {
@ -2156,16 +2159,17 @@ bool DwarfDebug::extractScopeInformation() {
// FIXME : Remove DBG_VALUE check.
if (MInsn->isDebugValue()) continue;
MIIndexMap[MInsn] = MIIndex++;
DebugLoc DL = MInsn->getDebugLoc();
if (DL.isUnknown()) continue;
DILocation DLT = MF->getDILocation(DL);
DIScope DLTScope = DLT.getScope();
if (!DLTScope.getNode()) continue;
MDNode *Scope = DL.getScope(Ctx);
// There is no need to create another DIE for compile unit. For all
// other scopes, create one DbgScope now. This will be translated
// into a scope DIE at the end.
if (DLTScope.isCompileUnit()) continue;
createDbgScope(DLTScope.getNode(), DLT.getOrigLocation().getNode());
if (DIScope(Scope).isCompileUnit()) continue;
createDbgScope(Scope, DL.getInlinedAt(Ctx));
}
}
@ -2179,17 +2183,17 @@ bool DwarfDebug::extractScopeInformation() {
// FIXME : Remove DBG_VALUE check.
if (MInsn->isDebugValue()) continue;
DebugLoc DL = MInsn->getDebugLoc();
if (DL.isUnknown()) continue;
DILocation DLT = MF->getDILocation(DL);
DIScope DLTScope = DLT.getScope();
if (!DLTScope.getNode()) continue;
if (DL.isUnknown()) continue;
MDNode *Scope = DL.getScope(Ctx);
if (Scope == 0) continue;
// There is no need to create another DIE for compile unit. For all
// other scopes, create one DbgScope now. This will be translated
// into a scope DIE at the end.
if (DLTScope.isCompileUnit()) continue;
DbgScope *Scope = getUpdatedDbgScope(DLTScope.getNode(), MInsn,
DLT.getOrigLocation().getNode());
Scope->setLastInsn(MInsn);
if (DIScope(Scope).isCompileUnit()) continue;
DbgScope *DScope = getUpdatedDbgScope(Scope, MInsn, DL.getInlinedAt(Ctx));
DScope->setLastInsn(MInsn);
}
}
@ -2255,20 +2259,21 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
// Emit label for the implicitly defined dbg.stoppoint at the start of the
// function.
DebugLoc FDL = MF->getDefaultDebugLoc();
if (!FDL.isUnknown()) {
DILocation DLT = MF->getDILocation(FDL);
DISubprogram SP = getDISubprogram(DLT.getScope().getNode());
unsigned Line, Col;
if (SP.Verify()) {
Line = SP.getLineNumber();
Col = 0;
} else {
Line = DLT.getLineNumber();
Col = DLT.getColumnNumber();
}
recordSourceLine(Line, Col, DLT.getScope().getNode());
if (FDL.isUnknown()) return;
MDNode *Scope = FDL.getScope(MF->getFunction()->getContext());
DISubprogram SP = getDISubprogram(Scope);
unsigned Line, Col;
if (SP.Verify()) {
Line = SP.getLineNumber();
Col = 0;
} else {
Line = FDL.getLine();
Col = FDL.getCol();
}
recordSourceLine(Line, Col, Scope);
}
/// endFunction - Gather and emit post-function debug information.

View File

@ -195,7 +195,7 @@ class DwarfDebug : public DwarfPrinter {
/// Previous instruction's location information. This is used to determine
/// label location to indicate scope boundries in dwarf debug info.
mutable const MDNode *PrevDILoc;
DebugLoc PrevInstLoc;
/// DebugTimer - Timer for the Dwarf debug writer.
Timer *DebugTimer;
@ -361,7 +361,8 @@ class DwarfDebug : public DwarfPrinter {
/// getUpdatedDbgScope - Find or create DbgScope assicated with
/// the instruction. Initialize scope and update scope hierarchy.
DbgScope *getUpdatedDbgScope(MDNode *N, const MachineInstr *MI, MDNode *InlinedAt);
DbgScope *getUpdatedDbgScope(MDNode *N, const MachineInstr *MI,
MDNode *InlinedAt);
/// createDbgScope - Create DbgScope for the scope.
void createDbgScope(MDNode *Scope, MDNode *InlinedAt);
@ -370,9 +371,9 @@ class DwarfDebug : public DwarfPrinter {
/// findAbstractVariable - Find abstract variable associated with Var.
DbgVariable *findAbstractVariable(DIVariable &Var, unsigned FrameIdx,
DILocation &Loc);
DebugLoc Loc);
DbgVariable *findAbstractVariable(DIVariable &Var, const MachineInstr *MI,
DILocation &Loc);
DebugLoc Loc);
/// updateSubprogramScopeDIE - Find DIE for the given subprogram and
/// attach appropriate DW_AT_low_pc and DW_AT_high_pc attributes.

View File

@ -27,6 +27,7 @@ add_llvm_library(LLVMCodeGen
MachineFunction.cpp
MachineFunctionAnalysis.cpp
MachineFunctionPass.cpp
MachineFunctionPrinterPass.cpp
MachineInstr.cpp
MachineLICM.cpp
MachineLoopInfo.cpp

View File

@ -661,7 +661,7 @@ bool DwarfEHPrepare::PromoteStackTemporaries() {
/// the start of the basic block (unless there already is one, in which case
/// the existing call is returned).
Instruction *DwarfEHPrepare::CreateExceptionValueCall(BasicBlock *BB) {
Instruction *Start = BB->getFirstNonPHI();
Instruction *Start = BB->getFirstNonPHIOrDbg();
// Is this a call to eh.exception?
if (IntrinsicInst *CI = dyn_cast<IntrinsicInst>(Start))
if (CI->getIntrinsicID() == Intrinsic::eh_exception)
@ -681,7 +681,7 @@ Instruction *DwarfEHPrepare::CreateExceptionValueCall(BasicBlock *BB) {
/// (creating it if necessary) at the start of the basic block (unless
/// there already is a load, in which case the existing load is returned).
Instruction *DwarfEHPrepare::CreateValueLoad(BasicBlock *BB) {
Instruction *Start = BB->getFirstNonPHI();
Instruction *Start = BB->getFirstNonPHIOrDbg();
// Is this a load of the exception temporary?
if (ExceptionValueVar)
if (LoadInst* LI = dyn_cast<LoadInst>(Start))

View File

@ -39,40 +39,6 @@
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
struct Printer : public MachineFunctionPass {
static char ID;
raw_ostream &OS;
const std::string Banner;
Printer(raw_ostream &os, const std::string &banner)
: MachineFunctionPass(&ID), OS(os), Banner(banner) {}
const char *getPassName() const { return "MachineFunction Printer"; }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
}
bool runOnMachineFunction(MachineFunction &MF) {
OS << "# " << Banner << ":\n";
MF.print(OS);
return false;
}
};
char Printer::ID = 0;
}
/// Returns a newly-created MachineFunction Printer pass. The default banner is
/// empty.
///
FunctionPass *llvm::createMachineFunctionPrinterPass(raw_ostream &OS,
const std::string &Banner){
return new Printer(OS, Banner);
}
//===----------------------------------------------------------------------===//
// MachineFunction implementation
//===----------------------------------------------------------------------===//
@ -436,15 +402,6 @@ unsigned MachineFunction::addLiveIn(unsigned PReg,
return VReg;
}
/// getDILocation - Get the DILocation for a given DebugLoc object.
DILocation MachineFunction::getDILocation(DebugLoc DL) const {
unsigned Idx = DL.getIndex();
assert(Idx < DebugLocInfo.DebugLocations.size() &&
"Invalid index into debug locations!");
return DILocation(DebugLocInfo.DebugLocations[Idx]);
}
/// getJTISymbol - Return the MCSymbol for the specified non-empty jump table.
/// If isLinkerPrivate is specified, an 'l' label is returned, otherwise a
/// normal 'L' label is returned.

View File

@ -15,8 +15,14 @@
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/Passes.h"
using namespace llvm;
Pass *MachineFunctionPass::createPrinterPass(raw_ostream &O,
const std::string &Banner) const {
return createMachineFunctionPrinterPass(O, Banner);
}
bool MachineFunctionPass::runOnFunction(Function &F) {
// Do not codegen any 'available_externally' functions at all, they have
// definitions outside the translation unit.

View File

@ -0,0 +1,60 @@
//===-- MachineFunctionPrinterPass.cpp ------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// MachineFunctionPrinterPass implementation.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
/// MachineFunctionPrinterPass - This is a pass to dump the IR of a
/// MachineFunction.
///
struct MachineFunctionPrinterPass : public MachineFunctionPass {
static char ID;
raw_ostream &OS;
const std::string Banner;
MachineFunctionPrinterPass(raw_ostream &os, const std::string &banner)
: MachineFunctionPass(&ID), OS(os), Banner(banner) {}
const char *getPassName() const { return "MachineFunction Printer"; }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
}
bool runOnMachineFunction(MachineFunction &MF) {
OS << "# " << Banner << ":\n";
MF.print(OS);
return false;
}
};
char MachineFunctionPrinterPass::ID = 0;
}
namespace llvm {
/// Returns a newly-created MachineFunction Printer pass. The
/// default banner is empty.
///
MachineFunctionPass *createMachineFunctionPrinterPass(raw_ostream &OS,
const std::string &Banner){
return new MachineFunctionPrinterPass(OS, Banner);
}
}

View File

@ -395,7 +395,7 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) {
/// TID NULL and no operands.
MachineInstr::MachineInstr()
: TID(0), NumImplicitOps(0), AsmPrinterFlags(0), MemRefs(0), MemRefsEnd(0),
Parent(0), debugLoc(DebugLoc::getUnknownLoc()) {
Parent(0) {
// Make sure that we get added to a machine basicblock
LeakDetector::addGarbageObject(this);
}
@ -415,8 +415,7 @@ void MachineInstr::addImplicitDefUseOperands() {
/// instructions with variable number of operands).
MachineInstr::MachineInstr(const TargetInstrDesc &tid, bool NoImp)
: TID(&tid), NumImplicitOps(0), AsmPrinterFlags(0),
MemRefs(0), MemRefsEnd(0), Parent(0),
debugLoc(DebugLoc::getUnknownLoc()) {
MemRefs(0), MemRefsEnd(0), Parent(0) {
if (!NoImp && TID->getImplicitDefs())
for (const unsigned *ImpDefs = TID->getImplicitDefs(); *ImpDefs; ++ImpDefs)
NumImplicitOps++;
@ -454,8 +453,7 @@ MachineInstr::MachineInstr(const TargetInstrDesc &tid, const DebugLoc dl,
///
MachineInstr::MachineInstr(MachineBasicBlock *MBB, const TargetInstrDesc &tid)
: TID(&tid), NumImplicitOps(0), AsmPrinterFlags(0),
MemRefs(0), MemRefsEnd(0), Parent(0),
debugLoc(DebugLoc::getUnknownLoc()) {
MemRefs(0), MemRefsEnd(0), Parent(0) {
assert(MBB && "Cannot use inserting ctor with null basic block!");
if (TID->ImplicitDefs)
for (const unsigned *ImpDefs = TID->getImplicitDefs(); *ImpDefs; ++ImpDefs)
@ -1221,17 +1219,16 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const {
// TODO: print InlinedAtLoc information
DILocation DLT = MF->getDILocation(debugLoc);
DIScope Scope = DLT.getScope();
DIScope Scope(debugLoc.getScope(MF->getFunction()->getContext()));
OS << " dbg:";
// Omit the directory, since it's usually long and uninteresting.
if (Scope.Verify())
OS << Scope.getFilename();
else
OS << "<unknown>";
OS << ':' << DLT.getLineNumber();
if (DLT.getColumnNumber() != 0)
OS << ':' << DLT.getColumnNumber();
OS << ':' << debugLoc.getLine();
if (debugLoc.getCol() != 0)
OS << ':' << debugLoc.getCol();
}
OS << "\n";

View File

@ -125,7 +125,7 @@ MachineInstr *InsertNewDef(unsigned Opcode,
const TargetRegisterClass *RC,
MachineRegisterInfo *MRI, const TargetInstrInfo *TII) {
unsigned NewVR = MRI->createVirtualRegister(RC);
return BuildMI(*BB, I, DebugLoc::getUnknownLoc(), TII->get(Opcode), NewVR);
return BuildMI(*BB, I, DebugLoc(), TII->get(Opcode), NewVR);
}
/// GetValueInMiddleOfBlock - Construct SSA form, materializing a value that

View File

@ -340,8 +340,8 @@ bool FastISel::SelectCall(User *I) {
StaticAllocaMap.find(AI);
if (SI == StaticAllocaMap.end()) break; // VLAs.
int FI = SI->second;
if (MDNode *Dbg = DI->getDbgMetadata())
MMI->setVariableDbgInfo(DI->getVariable(), FI, Dbg);
if (!DI->getDebugLoc().isUnknown())
MMI->setVariableDbgInfo(DI->getVariable(), FI, DI->getDebugLoc());
// Building the map above is target independent. Generating DBG_VALUE
// inline is target dependent; do this now.

View File

@ -16,6 +16,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/DebugLoc.h"
#include "llvm/System/DataTypes.h"
namespace llvm {

View File

@ -794,8 +794,7 @@ unsigned SelectionDAG::getEVTAlignment(EVT VT) const {
// EntryNode could meaningfully have debug info if we can find it...
SelectionDAG::SelectionDAG(TargetLowering &tli, FunctionLoweringInfo &fli)
: TLI(tli), FLI(fli), DW(0),
EntryNode(ISD::EntryToken, DebugLoc::getUnknownLoc(),
getVTList(MVT::Other)),
EntryNode(ISD::EntryToken, DebugLoc(), getVTList(MVT::Other)),
Root(getEntryNode()), Ordering(0) {
AllNodes.push_back(&EntryNode);
Ordering = new SDNodeOrdering();
@ -919,8 +918,7 @@ SDValue SelectionDAG::getConstant(const ConstantInt &Val, EVT VT, bool isT) {
if (VT.isVector()) {
SmallVector<SDValue, 8> Ops;
Ops.assign(VT.getVectorNumElements(), Result);
Result = getNode(ISD::BUILD_VECTOR, DebugLoc::getUnknownLoc(),
VT, &Ops[0], Ops.size());
Result = getNode(ISD::BUILD_VECTOR, DebugLoc(), VT, &Ops[0], Ops.size());
}
return Result;
}
@ -963,8 +961,7 @@ SDValue SelectionDAG::getConstantFP(const ConstantFP& V, EVT VT, bool isTarget){
SmallVector<SDValue, 8> Ops;
Ops.assign(VT.getVectorNumElements(), Result);
// FIXME DebugLoc info might be appropriate here
Result = getNode(ISD::BUILD_VECTOR, DebugLoc::getUnknownLoc(),
VT, &Ops[0], Ops.size());
Result = getNode(ISD::BUILD_VECTOR, DebugLoc(), VT, &Ops[0], Ops.size());
}
return Result;
}
@ -3094,6 +3091,8 @@ SDValue SelectionDAG::getStackArgumentTokenFactor(SDValue Chain) {
/// operand.
static SDValue getMemsetValue(SDValue Value, EVT VT, SelectionDAG &DAG,
DebugLoc dl) {
assert(Value.getOpcode() != ISD::UNDEF);
unsigned NumBits = VT.getScalarType().getSizeInBits();
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Value)) {
APInt Val = APInt(NumBits, C->getZExtValue() & 255);
@ -3197,7 +3196,7 @@ static bool isMemSrcFromString(SDValue Src, std::string &Str) {
static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,
unsigned Limit, uint64_t Size,
unsigned DstAlign, unsigned SrcAlign,
bool SafeToUseFP,
bool NonScalarIntSafe,
SelectionDAG &DAG,
const TargetLowering &TLI) {
assert((SrcAlign == 0 || SrcAlign >= DstAlign) &&
@ -3207,7 +3206,8 @@ static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,
// the inferred alignment of the source. 'DstAlign', on the other hand, is the
// specified alignment of the memory operation. If it is zero, that means
// it's possible to change the alignment of the destination.
EVT VT = TLI.getOptimalMemOpType(Size, DstAlign, SrcAlign, SafeToUseFP, DAG);
EVT VT = TLI.getOptimalMemOpType(Size, DstAlign, SrcAlign,
NonScalarIntSafe, DAG);
if (VT == MVT::Other) {
VT = TLI.getPointerTy();
@ -3266,10 +3266,13 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
unsigned Align, bool AlwaysInline,
const Value *DstSV, uint64_t DstSVOff,
const Value *SrcSV, uint64_t SrcSVOff) {
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
// Turn a memcpy of undef to nop.
if (Src.getOpcode() == ISD::UNDEF)
return Chain;
// Expand memcpy to a series of load and store ops if the size operand falls
// below a certain threshold.
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
std::vector<EVT> MemOps;
uint64_t Limit = -1ULL;
if (!AlwaysInline)
@ -3352,10 +3355,13 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
unsigned Align,bool AlwaysInline,
const Value *DstSV, uint64_t DstSVOff,
const Value *SrcSV, uint64_t SrcSVOff) {
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
// Turn a memmove of undef to nop.
if (Src.getOpcode() == ISD::UNDEF)
return Chain;
// Expand memmove to a series of load and store ops if the size operand falls
// below a certain threshold.
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
std::vector<EVT> MemOps;
uint64_t Limit = -1ULL;
if (!AlwaysInline)
@ -3426,21 +3432,24 @@ static SDValue getMemsetStores(SelectionDAG &DAG, DebugLoc dl,
SDValue Src, uint64_t Size,
unsigned Align,
const Value *DstSV, uint64_t DstSVOff) {
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
// Turn a memset of undef to nop.
if (Src.getOpcode() == ISD::UNDEF)
return Chain;
// Expand memset to a series of load/store ops if the size operand
// falls below a certain threshold.
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
std::vector<EVT> MemOps;
bool DstAlignCanChange = false;
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Dst);
if (FI && !MFI->isFixedObjectIndex(FI->getIndex()))
DstAlignCanChange = true;
bool IsZero = isa<ConstantSDNode>(Src) &&
cast<ConstantSDNode>(Src)->isNullValue();
bool NonScalarIntSafe =
isa<ConstantSDNode>(Src) && cast<ConstantSDNode>(Src)->isNullValue();
if (!FindOptimalMemOpLowering(MemOps, TLI.getMaxStoresPerMemset(),
Size, (DstAlignCanChange ? 0 : Align), 0,
IsZero, DAG, TLI))
NonScalarIntSafe, DAG, TLI))
return SDValue();
if (DstAlignCanChange) {
@ -3592,9 +3601,9 @@ SDValue SelectionDAG::getMemset(SDValue Chain, DebugLoc dl, SDValue Dst,
if (ConstantSize->isNullValue())
return Chain;
SDValue Result =
getMemsetStores(*this, dl, Chain, Dst, Src, ConstantSize->getZExtValue(),
Align, DstSV, DstSVOff);
SDValue Result = getMemsetStores(*this, dl, Chain, Dst, Src,
ConstantSize->getZExtValue(),
Align, DstSV, DstSVOff);
if (Result.getNode())
return Result;
}
@ -5323,8 +5332,7 @@ HandleSDNode::~HandleSDNode() {
GlobalAddressSDNode::GlobalAddressSDNode(unsigned Opc, const GlobalValue *GA,
EVT VT, int64_t o, unsigned char TF)
: SDNode(Opc, DebugLoc::getUnknownLoc(), getSDVTList(VT)),
Offset(o), TargetFlags(TF) {
: SDNode(Opc, DebugLoc(), getSDVTList(VT)), Offset(o), TargetFlags(TF) {
TheGlobal = const_cast<GlobalValue*>(GA);
}

View File

@ -546,7 +546,7 @@ void SelectionDAGBuilder::clear() {
PendingExports.clear();
EdgeMapping.clear();
DAG.clear();
CurDebugLoc = DebugLoc::getUnknownLoc();
CurDebugLoc = DebugLoc();
HasTailCall = false;
}
@ -3800,8 +3800,8 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
int FI = SI->second;
if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo())
if (MDNode *Dbg = DI.getDbgMetadata())
MMI->setVariableDbgInfo(Variable, FI, Dbg);
if (!DI.getDebugLoc().isUnknown())
MMI->setVariableDbgInfo(Variable, FI, DI.getDebugLoc());
return 0;
}
case Intrinsic::dbg_value: {
@ -3851,9 +3851,10 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
if (SI == FuncInfo.StaticAllocaMap.end())
return 0; // VLAs.
int FI = SI->second;
if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo())
if (MDNode *Dbg = DI.getDbgMetadata())
MMI->setVariableDbgInfo(Variable, FI, Dbg);
if (!DI.getDebugLoc().isUnknown())
MMI->setVariableDbgInfo(Variable, FI, DI.getDebugLoc());
return 0;
}
case Intrinsic::eh_exception: {

View File

@ -306,10 +306,8 @@ class SelectionDAGBuilder {
SelectionDAGBuilder(SelectionDAG &dag, TargetLowering &tli,
FunctionLoweringInfo &funcinfo,
CodeGenOpt::Level ol)
: CurDebugLoc(DebugLoc::getUnknownLoc()), SDNodeOrder(0),
TLI(tli), DAG(dag), FuncInfo(funcinfo), OptLevel(ol),
HasTailCall(false),
Context(dag.getContext()) {
: SDNodeOrder(0), TLI(tli), DAG(dag), FuncInfo(funcinfo), OptLevel(ol),
HasTailCall(false), Context(dag.getContext()) {
}
void init(GCFunctionInfo *gfi, AliasAnalysis &aa);

View File

@ -368,28 +368,25 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
/// attached with this instruction.
static void SetDebugLoc(Instruction *I, SelectionDAGBuilder *SDB,
FastISel *FastIS, MachineFunction *MF) {
MDNode *Dbg = I->getDbgMetadata();
if (Dbg == 0) return;
DebugLoc DL = I->getDebugLoc();
if (DL.isUnknown()) return;
DILocation DILoc(Dbg);
DebugLoc Loc = ExtractDebugLocation(DILoc, MF->getDebugLocInfo());
SDB->setCurDebugLoc(Loc);
SDB->setCurDebugLoc(DL);
if (FastIS)
FastIS->setCurDebugLoc(Loc);
FastIS->setCurDebugLoc(DL);
// If the function doesn't have a default debug location yet, set
// it. This is kind of a hack.
if (MF->getDefaultDebugLoc().isUnknown())
MF->setDefaultDebugLoc(Loc);
MF->setDefaultDebugLoc(DL);
}
/// ResetDebugLoc - Set MF's and SDB's DebugLocs to Unknown.
static void ResetDebugLoc(SelectionDAGBuilder *SDB, FastISel *FastIS) {
SDB->setCurDebugLoc(DebugLoc::getUnknownLoc());
SDB->setCurDebugLoc(DebugLoc());
if (FastIS)
FastIS->setCurDebugLoc(DebugLoc::getUnknownLoc());
FastIS->setCurDebugLoc(DebugLoc());
}
void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB,

View File

@ -821,21 +821,20 @@ void *JITEmitter::getPointerToGVIndirectSym(GlobalValue *V, void *Reference) {
}
void JITEmitter::processDebugLoc(DebugLoc DL, bool BeforePrintingInsn) {
if (!DL.isUnknown()) {
DILocation CurDLT = EmissionDetails.MF->getDILocation(DL);
if (DL.isUnknown()) return;
if (!BeforePrintingInsn) return;
if (BeforePrintingInsn) {
if (CurDLT.getScope().getNode() != 0
&& PrevDLT.getNode() != CurDLT.getNode()) {
JITEvent_EmittedFunctionDetails::LineStart NextLine;
NextLine.Address = getCurrentPCValue();
NextLine.Loc = DL;
EmissionDetails.LineStarts.push_back(NextLine);
}
PrevDLT = CurDLT;
}
// FIXME: This is horribly inefficient.
DILocation CurDLT(DL.getAsMDNode(CurFn->getContext()));
if (CurDLT.getScope().getNode() != 0 && PrevDLT.getNode() !=CurDLT.getNode()){
JITEvent_EmittedFunctionDetails::LineStart NextLine;
NextLine.Address = getCurrentPCValue();
NextLine.Loc = DL;
EmissionDetails.LineStarts.push_back(NextLine);
}
PrevDLT = CurDLT;
}
static unsigned GetConstantPoolSizeInBytes(MachineConstantPool *MCP,

View File

@ -312,7 +312,7 @@ ARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond) const {
// FIXME this should probably have a DebugLoc argument
DebugLoc dl = DebugLoc::getUnknownLoc();
DebugLoc dl;
ARMFunctionInfo *AFI = MBB.getParent()->getInfo<ARMFunctionInfo>();
int BOpc = !AFI->isThumbFunction()
@ -653,7 +653,7 @@ ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *DestRC,
const TargetRegisterClass *SrcRC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
// tGPR is used sometimes in ARM instructions that need to avoid using
@ -715,7 +715,7 @@ void ARMBaseInstrInfo::
storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned SrcReg, bool isKill, int FI,
const TargetRegisterClass *RC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
MachineFunction &MF = *MBB.getParent();
MachineFrameInfo &MFI = *MF.getFrameInfo();
@ -769,7 +769,7 @@ void ARMBaseInstrInfo::
loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned DestReg, int FI,
const TargetRegisterClass *RC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
MachineFunction &MF = *MBB.getParent();
MachineFrameInfo &MFI = *MF.getFrameInfo();

View File

@ -1277,8 +1277,7 @@ emitPrologue(MachineFunction &MF) const {
unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
unsigned NumBytes = MFI->getStackSize();
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
DebugLoc dl = (MBBI != MBB.end() ?
MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
// Determine the sizes of each callee-save spill areas and record which frame
// belongs to which callee-save spill areas.

View File

@ -399,8 +399,8 @@ void ARMConstantIslands::DoInitialPlacement(MachineFunction &MF,
// aligned.
assert((Size & 3) == 0 && "CP Entry not multiple of 4 bytes!");
MachineInstr *CPEMI =
BuildMI(BB, DebugLoc::getUnknownLoc(), TII->get(ARM::CONSTPOOL_ENTRY))
.addImm(i).addConstantPoolIndex(i).addImm(Size);
BuildMI(BB, DebugLoc(), TII->get(ARM::CONSTPOOL_ENTRY))
.addImm(i).addConstantPoolIndex(i).addImm(Size);
CPEMIs.push_back(CPEMI);
// Add a new CPEntry, but no corresponding CPUser yet.
@ -721,7 +721,7 @@ MachineBasicBlock *ARMConstantIslands::SplitBlockBeforeInstr(MachineInstr *MI) {
// There doesn't seem to be meaningful DebugInfo available; this doesn't
// correspond to anything in the source.
unsigned Opc = isThumb ? (isThumb2 ? ARM::t2B : ARM::tB) : ARM::B;
BuildMI(OrigBB, DebugLoc::getUnknownLoc(), TII->get(Opc)).addMBB(NewBB);
BuildMI(OrigBB, DebugLoc(), TII->get(Opc)).addMBB(NewBB);
NumSplit++;
// Update the CFG. All succs of OrigBB are now succs of NewBB.
@ -1103,8 +1103,7 @@ void ARMConstantIslands::CreateNewWater(unsigned CPUserIndex,
// targets will be exchanged, and the altered branch may be out of
// range, so the machinery has to know about it.
int UncondBr = isThumb ? ((isThumb2) ? ARM::t2B : ARM::tB) : ARM::B;
BuildMI(UserMBB, DebugLoc::getUnknownLoc(),
TII->get(UncondBr)).addMBB(NewMBB);
BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)).addMBB(NewMBB);
unsigned MaxDisp = getUnconditionalBrDisp(UncondBr);
ImmBranches.push_back(ImmBranch(&UserMBB->back(),
MaxDisp, false, UncondBr));
@ -1244,8 +1243,7 @@ bool ARMConstantIslands::HandleConstantPoolUser(MachineFunction &MF,
// Now that we have an island to add the CPE to, clone the original CPE and
// add it to the island.
U.HighWaterMark = NewIsland;
U.CPEMI = BuildMI(NewIsland, DebugLoc::getUnknownLoc(),
TII->get(ARM::CONSTPOOL_ENTRY))
U.CPEMI = BuildMI(NewIsland, DebugLoc(), TII->get(ARM::CONSTPOOL_ENTRY))
.addImm(ID).addConstantPoolIndex(CPI).addImm(Size);
CPEntries[CPI].push_back(CPEntry(U.CPEMI, ID, 1));
NumCPEs++;
@ -1446,12 +1444,11 @@ ARMConstantIslands::FixUpConditionalBr(MachineFunction &MF, ImmBranch &Br) {
// Insert a new conditional branch and a new unconditional branch.
// Also update the ImmBranch as well as adding a new entry for the new branch.
BuildMI(MBB, DebugLoc::getUnknownLoc(),
TII->get(MI->getOpcode()))
BuildMI(MBB, DebugLoc(), TII->get(MI->getOpcode()))
.addMBB(NextBB).addImm(CC).addReg(CCReg);
Br.MI = &MBB->back();
BBSizes[MBB->getNumber()] += TII->GetInstSizeInBytes(&MBB->back());
BuildMI(MBB, DebugLoc::getUnknownLoc(), TII->get(Br.UncondBr)).addMBB(DestBB);
BuildMI(MBB, DebugLoc(), TII->get(Br.UncondBr)).addMBB(DestBB);
BBSizes[MBB->getNumber()] += TII->GetInstSizeInBytes(&MBB->back());
unsigned MaxDisp = getUnconditionalBrDisp(Br.UncondBr);
ImmBranches.push_back(ImmBranch(&MBB->back(), MaxDisp, false, Br.UncondBr));
@ -1809,7 +1806,7 @@ AdjustJTTargetBlockForward(MachineBasicBlock *BB, MachineBasicBlock *JTBB)
// There doesn't seem to be meaningful DebugInfo available; this doesn't
// correspond directly to anything in the source.
assert (isThumb2 && "Adjusting for TB[BH] but not in Thumb2?");
BuildMI(NewBB, DebugLoc::getUnknownLoc(), TII->get(ARM::t2B)).addMBB(BB);
BuildMI(NewBB, DebugLoc(), TII->get(ARM::t2B)).addMBB(BB);
// Update internal data structures to account for the newly inserted MBB.
MF.RenumberBlocks(NewBB);

View File

@ -18,6 +18,7 @@
#include "llvm/Target/TargetAsmParser.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
using namespace llvm;
@ -46,11 +47,11 @@ class ARMAsmParser : public TargetAsmParser {
bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
bool MaybeParseRegister(ARMOperand &Op, bool ParseWriteBack);
bool MaybeParseRegister(OwningPtr<ARMOperand> &Op, bool ParseWriteBack);
bool ParseRegisterList(ARMOperand &Op);
bool ParseRegisterList(OwningPtr<ARMOperand> &Op);
bool ParseMemory(ARMOperand &Op);
bool ParseMemory(OwningPtr<ARMOperand> &Op);
bool ParseMemoryOffsetReg(bool &Negative,
bool &OffsetRegShifted,
@ -58,11 +59,12 @@ class ARMAsmParser : public TargetAsmParser {
const MCExpr *&ShiftAmount,
const MCExpr *&Offset,
bool &OffsetIsReg,
int &OffsetRegNum);
int &OffsetRegNum,
SMLoc &E);
bool ParseShift(enum ShiftType &St, const MCExpr *&ShiftAmount);
bool ParseShift(enum ShiftType &St, const MCExpr *&ShiftAmount, SMLoc &E);
bool ParseOperand(ARMOperand &Op);
bool ParseOperand(OwningPtr<ARMOperand> &Op);
bool ParseDirectiveWord(unsigned Size, SMLoc L);
@ -104,13 +106,17 @@ class ARMAsmParser : public TargetAsmParser {
/// ARMOperand - Instances of this class represent a parsed ARM machine
/// instruction.
struct ARMOperand : public MCParsedAsmOperand {
enum {
private:
ARMOperand() {}
public:
enum KindTy {
Token,
Register,
Immediate,
Memory
} Kind;
SMLoc StartLoc, EndLoc;
union {
struct {
@ -126,7 +132,7 @@ struct ARMOperand : public MCParsedAsmOperand {
struct {
const MCExpr *Val;
} Imm;
// This is for all forms of ARM address expressions
struct {
unsigned BaseRegNum;
@ -144,6 +150,34 @@ struct ARMOperand : public MCParsedAsmOperand {
} Mem;
};
ARMOperand(KindTy K, SMLoc S, SMLoc E)
: Kind(K), StartLoc(S), EndLoc(E) {}
ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
Kind = o.Kind;
StartLoc = o.StartLoc;
EndLoc = o.EndLoc;
switch (Kind) {
case Token:
Tok = o.Tok;
break;
case Register:
Reg = o.Reg;
break;
case Immediate:
Imm = o.Imm;
break;
case Memory:
Mem = o.Mem;
break;
}
}
/// getStartLoc - Get the location of the first token of this operand.
SMLoc getStartLoc() const { return StartLoc; }
/// getEndLoc - Get the location of the last token of this operand.
SMLoc getEndLoc() const { return EndLoc; }
StringRef getToken() const {
assert(Kind == Token && "Invalid access!");
@ -169,48 +203,60 @@ struct ARMOperand : public MCParsedAsmOperand {
Inst.addOperand(MCOperand::CreateReg(getReg()));
}
static ARMOperand CreateToken(StringRef Str) {
ARMOperand Res;
Res.Kind = Token;
Res.Tok.Data = Str.data();
Res.Tok.Length = Str.size();
return Res;
static void CreateToken(OwningPtr<ARMOperand> &Op, StringRef Str,
SMLoc S) {
Op.reset(new ARMOperand);
Op->Kind = Token;
Op->Tok.Data = Str.data();
Op->Tok.Length = Str.size();
Op->StartLoc = S;
Op->EndLoc = S;
}
static ARMOperand CreateReg(unsigned RegNum, bool Writeback) {
ARMOperand Res;
Res.Kind = Register;
Res.Reg.RegNum = RegNum;
Res.Reg.Writeback = Writeback;
return Res;
static void CreateReg(OwningPtr<ARMOperand> &Op, unsigned RegNum,
bool Writeback, SMLoc S, SMLoc E) {
Op.reset(new ARMOperand);
Op->Kind = Register;
Op->Reg.RegNum = RegNum;
Op->Reg.Writeback = Writeback;
Op->StartLoc = S;
Op->EndLoc = E;
}
static ARMOperand CreateImm(const MCExpr *Val) {
ARMOperand Res;
Res.Kind = Immediate;
Res.Imm.Val = Val;
return Res;
static void CreateImm(OwningPtr<ARMOperand> &Op, const MCExpr *Val,
SMLoc S, SMLoc E) {
Op.reset(new ARMOperand);
Op->Kind = Immediate;
Op->Imm.Val = Val;
Op->StartLoc = S;
Op->EndLoc = E;
}
static ARMOperand CreateMem(unsigned BaseRegNum, bool OffsetIsReg,
const MCExpr *Offset, unsigned OffsetRegNum,
bool OffsetRegShifted, enum ShiftType ShiftType,
const MCExpr *ShiftAmount, bool Preindexed,
bool Postindexed, bool Negative, bool Writeback) {
ARMOperand Res;
Res.Kind = Memory;
Res.Mem.BaseRegNum = BaseRegNum;
Res.Mem.OffsetIsReg = OffsetIsReg;
Res.Mem.Offset = Offset;
Res.Mem.OffsetRegNum = OffsetRegNum;
Res.Mem.OffsetRegShifted = OffsetRegShifted;
Res.Mem.ShiftType = ShiftType;
Res.Mem.ShiftAmount = ShiftAmount;
Res.Mem.Preindexed = Preindexed;
Res.Mem.Postindexed = Postindexed;
Res.Mem.Negative = Negative;
Res.Mem.Writeback = Writeback;
return Res;
static void CreateMem(OwningPtr<ARMOperand> &Op,
unsigned BaseRegNum, bool OffsetIsReg,
const MCExpr *Offset, unsigned OffsetRegNum,
bool OffsetRegShifted, enum ShiftType ShiftType,
const MCExpr *ShiftAmount, bool Preindexed,
bool Postindexed, bool Negative, bool Writeback,
SMLoc S, SMLoc E) {
Op.reset(new ARMOperand);
Op->Kind = Memory;
Op->Mem.BaseRegNum = BaseRegNum;
Op->Mem.OffsetIsReg = OffsetIsReg;
Op->Mem.Offset = Offset;
Op->Mem.OffsetRegNum = OffsetRegNum;
Op->Mem.OffsetRegShifted = OffsetRegShifted;
Op->Mem.ShiftType = ShiftType;
Op->Mem.ShiftAmount = ShiftAmount;
Op->Mem.Preindexed = Preindexed;
Op->Mem.Postindexed = Postindexed;
Op->Mem.Negative = Negative;
Op->Mem.Writeback = Writeback;
Op->StartLoc = S;
Op->EndLoc = E;
}
};
@ -221,7 +267,9 @@ struct ARMOperand : public MCParsedAsmOperand {
/// and false is returned. Else true is returned and no token is eaten.
/// TODO this is likely to change to allow different register types and or to
/// parse for a specific register type.
bool ARMAsmParser::MaybeParseRegister(ARMOperand &Op, bool ParseWriteBack) {
bool ARMAsmParser::MaybeParseRegister
(OwningPtr<ARMOperand> &Op, bool ParseWriteBack) {
SMLoc S, E;
const AsmToken &Tok = Parser.getTok();
assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
@ -232,27 +280,35 @@ bool ARMAsmParser::MaybeParseRegister(ARMOperand &Op, bool ParseWriteBack) {
RegNum = MatchRegisterName(Tok.getString());
if (RegNum == -1)
return true;
S = Tok.getLoc();
Parser.Lex(); // Eat identifier token.
E = Parser.getTok().getLoc();
bool Writeback = false;
if (ParseWriteBack) {
const AsmToken &ExclaimTok = Parser.getTok();
if (ExclaimTok.is(AsmToken::Exclaim)) {
E = ExclaimTok.getLoc();
Writeback = true;
Parser.Lex(); // Eat exclaim token
}
}
Op = ARMOperand::CreateReg(RegNum, Writeback);
ARMOperand::CreateReg(Op, RegNum, Writeback, S, E);
return false;
}
/// Parse a register list, return false if successful else return true or an
/// error. The first token must be a '{' when called.
bool ARMAsmParser::ParseRegisterList(ARMOperand &Op) {
bool ARMAsmParser::ParseRegisterList(OwningPtr<ARMOperand> &Op) {
SMLoc S, E;
assert(Parser.getTok().is(AsmToken::LCurly) &&
"Token is not an Left Curly Brace");
S = Parser.getTok().getLoc();
Parser.Lex(); // Eat left curly brace token.
const AsmToken &RegTok = Parser.getTok();
@ -290,6 +346,7 @@ bool ARMAsmParser::ParseRegisterList(ARMOperand &Op) {
const AsmToken &RCurlyTok = Parser.getTok();
if (RCurlyTok.isNot(AsmToken::RCurly))
return Error(RCurlyTok.getLoc(), "'}' expected");
E = RCurlyTok.getLoc();
Parser.Lex(); // Eat left curly brace token.
return false;
@ -299,9 +356,11 @@ bool ARMAsmParser::ParseRegisterList(ARMOperand &Op) {
/// or an error. The first token must be a '[' when called.
/// TODO Only preindexing and postindexing addressing are started, unindexed
/// with option, etc are still to do.
bool ARMAsmParser::ParseMemory(ARMOperand &Op) {
bool ARMAsmParser::ParseMemory(OwningPtr<ARMOperand> &Op) {
SMLoc S, E;
assert(Parser.getTok().is(AsmToken::LBrac) &&
"Token is not an Left Bracket");
S = Parser.getTok().getLoc();
Parser.Lex(); // Eat left bracket token.
const AsmToken &BaseRegTok = Parser.getTok();
@ -309,7 +368,7 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) {
return Error(BaseRegTok.getLoc(), "register expected");
if (MaybeParseRegister(Op, false))
return Error(BaseRegTok.getLoc(), "register expected");
int BaseRegNum = Op.getReg();
int BaseRegNum = Op->getReg();
bool Preindexed = false;
bool Postindexed = false;
@ -329,21 +388,23 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) {
const MCExpr *ShiftAmount;
const MCExpr *Offset;
if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
Offset, OffsetIsReg, OffsetRegNum))
Offset, OffsetIsReg, OffsetRegNum, E))
return true;
const AsmToken &RBracTok = Parser.getTok();
if (RBracTok.isNot(AsmToken::RBrac))
return Error(RBracTok.getLoc(), "']' expected");
E = RBracTok.getLoc();
Parser.Lex(); // Eat right bracket token.
const AsmToken &ExclaimTok = Parser.getTok();
if (ExclaimTok.is(AsmToken::Exclaim)) {
E = ExclaimTok.getLoc();
Writeback = true;
Parser.Lex(); // Eat exclaim token
}
Op = ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum,
OffsetRegShifted, ShiftType, ShiftAmount,
Preindexed, Postindexed, Negative, Writeback);
ARMOperand::CreateMem(Op, BaseRegNum, OffsetIsReg, Offset, OffsetRegNum,
OffsetRegShifted, ShiftType, ShiftAmount,
Preindexed, Postindexed, Negative, Writeback, S, E);
return false;
}
// The "[Rn" we have so far was not followed by a comma.
@ -352,6 +413,7 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) {
// the "[Rn".
Postindexed = true;
Writeback = true;
E = Tok.getLoc();
Parser.Lex(); // Eat right bracket token.
int OffsetRegNum = 0;
@ -366,13 +428,14 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) {
return Error(NextTok.getLoc(), "',' expected");
Parser.Lex(); // Eat comma token.
if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
ShiftAmount, Offset, OffsetIsReg, OffsetRegNum))
ShiftAmount, Offset, OffsetIsReg, OffsetRegNum,
E))
return true;
}
Op = ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum,
OffsetRegShifted, ShiftType, ShiftAmount,
Preindexed, Postindexed, Negative, Writeback);
ARMOperand::CreateMem(Op, BaseRegNum, OffsetIsReg, Offset, OffsetRegNum,
OffsetRegShifted, ShiftType, ShiftAmount,
Preindexed, Postindexed, Negative, Writeback, S, E);
return false;
}
@ -387,18 +450,20 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) {
/// #offset
/// we return false on success or an error otherwise.
bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
bool &OffsetRegShifted,
bool &OffsetRegShifted,
enum ShiftType &ShiftType,
const MCExpr *&ShiftAmount,
const MCExpr *&Offset,
bool &OffsetIsReg,
int &OffsetRegNum) {
ARMOperand Op;
int &OffsetRegNum,
SMLoc &E) {
OwningPtr<ARMOperand> Op;
Negative = false;
OffsetRegShifted = false;
OffsetIsReg = false;
OffsetRegNum = -1;
const AsmToken &NextTok = Parser.getTok();
E = NextTok.getLoc();
if (NextTok.is(AsmToken::Plus))
Parser.Lex(); // Eat plus token.
else if (NextTok.is(AsmToken::Minus)) {
@ -409,8 +474,10 @@ bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
const AsmToken &OffsetRegTok = Parser.getTok();
if (OffsetRegTok.is(AsmToken::Identifier)) {
OffsetIsReg = !MaybeParseRegister(Op, false);
if (OffsetIsReg)
OffsetRegNum = Op.getReg();
if (OffsetIsReg) {
E = Op->getEndLoc();
OffsetRegNum = Op->getReg();
}
}
// If we parsed a register as the offset then their can be a shift after that
if (OffsetRegNum != -1) {
@ -420,7 +487,7 @@ bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
Parser.Lex(); // Eat comma token.
const AsmToken &Tok = Parser.getTok();
if (ParseShift(ShiftType, ShiftAmount))
if (ParseShift(ShiftType, ShiftAmount, E))
return Error(Tok.getLoc(), "shift expected");
OffsetRegShifted = true;
}
@ -430,10 +497,12 @@ bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
const AsmToken &HashTok = Parser.getTok();
if (HashTok.isNot(AsmToken::Hash))
return Error(HashTok.getLoc(), "'#' expected");
Parser.Lex(); // Eat hash token.
if (getParser().ParseExpression(Offset))
return true;
E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
}
return false;
}
@ -442,7 +511,9 @@ bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
/// ( lsl | lsr | asr | ror ) , # shift_amount
/// rrx
/// and returns true if it parses a shift otherwise it returns false.
bool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount) {
bool ARMAsmParser::ParseShift(ShiftType &St,
const MCExpr *&ShiftAmount,
SMLoc &E) {
const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Identifier))
return true;
@ -550,7 +621,9 @@ MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
/// Parse a arm instruction operand. For now this parses the operand regardless
/// of the mnemonic.
bool ARMAsmParser::ParseOperand(ARMOperand &Op) {
bool ARMAsmParser::ParseOperand(OwningPtr<ARMOperand> &Op) {
SMLoc S, E;
switch (getLexer().getKind()) {
case AsmToken::Identifier:
if (!MaybeParseRegister(Op, true))
@ -558,9 +631,11 @@ bool ARMAsmParser::ParseOperand(ARMOperand &Op) {
// This was not a register so parse other operands that start with an
// identifier (like labels) as expressions and create them as immediates.
const MCExpr *IdVal;
S = Parser.getTok().getLoc();
if (getParser().ParseExpression(IdVal))
return true;
Op = ARMOperand::CreateImm(IdVal);
E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
ARMOperand::CreateImm(Op, IdVal, S, E);
return false;
case AsmToken::LBrac:
return ParseMemory(Op);
@ -569,11 +644,13 @@ bool ARMAsmParser::ParseOperand(ARMOperand &Op) {
case AsmToken::Hash:
// #42 -> immediate.
// TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
S = Parser.getTok().getLoc();
Parser.Lex();
const MCExpr *ImmVal;
if (getParser().ParseExpression(ImmVal))
return true;
Op = ARMOperand::CreateImm(ImmVal);
E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
ARMOperand::CreateImm(Op, ImmVal, S, E);
return false;
default:
return Error(Parser.getTok().getLoc(), "unexpected token in operand");
@ -583,22 +660,25 @@ bool ARMAsmParser::ParseOperand(ARMOperand &Op) {
/// Parse an arm instruction mnemonic followed by its operands.
bool ARMAsmParser::ParseInstruction(const StringRef &Name, SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Operands.push_back(new ARMOperand(ARMOperand::CreateToken(Name)));
OwningPtr<ARMOperand> Op;
ARMOperand::CreateToken(Op, Name, NameLoc);
Operands.push_back(Op.take());
SMLoc Loc = Parser.getTok().getLoc();
if (getLexer().isNot(AsmToken::EndOfStatement)) {
// Read the first operand.
ARMOperand Op;
OwningPtr<ARMOperand> Op;
if (ParseOperand(Op)) return true;
Operands.push_back(new ARMOperand(Op));
Operands.push_back(Op.take());
while (getLexer().is(AsmToken::Comma)) {
Parser.Lex(); // Eat the comma.
// Parse and remember the operand.
if (ParseOperand(Op)) return true;
Operands.push_back(new ARMOperand(Op));
Operands.push_back(Op.take());
}
}
return false;

View File

@ -0,0 +1,532 @@
//===- ARMDisassembler.cpp - Disassembler for ARM/Thumb ISA -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is part of the ARM Disassembler.
// It contains code to implement the public interfaces of ARMDisassembler and
// ThumbDisassembler, both of which are instances of MCDisassembler.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "arm-disassembler"
#include "ARMDisassembler.h"
#include "ARMDisassemblerCore.h"
#include "llvm/MC/MCInst.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
/// ARMGenDecoderTables.inc - ARMDecoderTables.inc is tblgen'ed from
/// ARMDecoderEmitter.cpp TableGen backend. It contains:
///
/// o Mappings from opcode to ARM/Thumb instruction format
///
/// o static uint16_t decodeInstruction(uint32_t insn) - the decoding function
/// for an ARM instruction.
///
/// o static uint16_t decodeThumbInstruction(field_t insn) - the decoding
/// function for a Thumb instruction.
///
#include "../ARMGenDecoderTables.inc"
namespace llvm {
/// showBitVector - Use the raw_ostream to log a diagnostic message describing
/// the inidividual bits of the instruction.
///
static inline void showBitVector(raw_ostream &os, const uint32_t &insn) {
// Split the bit position markers into more than one lines to fit 80 columns.
os << " 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11"
<< " 10 9 8 7 6 5 4 3 2 1 0 \n";
os << "---------------------------------------------------------------"
<< "----------------------------------\n";
os << '|';
for (unsigned i = 32; i != 0; --i) {
if (insn >> (i - 1) & 0x01)
os << " 1";
else
os << " 0";
os << (i%4 == 1 ? '|' : ':');
}
os << '\n';
// Split the bit position markers into more than one lines to fit 80 columns.
os << "---------------------------------------------------------------"
<< "----------------------------------\n";
os << '\n';
}
/// decodeARMInstruction is a decorator function which tries special cases of
/// instruction matching before calling the auto-generated decoder function.
static unsigned decodeARMInstruction(uint32_t &insn) {
if (slice(insn, 31, 28) == 15)
goto AutoGenedDecoder;
// Special case processing, if any, goes here....
// LLVM combines the offset mode of A8.6.197 & A8.6.198 into STRB.
// The insufficient encoding information of the combined instruction confuses
// the decoder wrt BFC/BFI. Therefore, we try to recover here.
// For BFC, Inst{27-21} = 0b0111110 & Inst{6-0} = 0b0011111.
// For BFI, Inst{27-21} = 0b0111110 & Inst{6-4} = 0b001 & Inst{3-0} =! 0b1111.
if (slice(insn, 27, 21) == 0x3e && slice(insn, 6, 4) == 1) {
if (slice(insn, 3, 0) == 15)
return ARM::BFC;
else
return ARM::BFI;
}
// Ditto for ADDSrs, which is a super-instruction for A8.6.7 & A8.6.8.
// As a result, the decoder fails to decode UMULL properly.
if (slice(insn, 27, 21) == 0x04 && slice(insn, 7, 4) == 9) {
return ARM::UMULL;
}
// Ditto for STR_PRE, which is a super-instruction for A8.6.194 & A8.6.195.
// As a result, the decoder fails to decode SBFX properly.
if (slice(insn, 27, 21) == 0x3d && slice(insn, 6, 4) == 5)
return ARM::SBFX;
// And STRB_PRE, which is a super-instruction for A8.6.197 & A8.6.198.
// As a result, the decoder fails to decode UBFX properly.
if (slice(insn, 27, 21) == 0x3f && slice(insn, 6, 4) == 5)
return ARM::UBFX;
// Ditto for STRT, which is a super-instruction for A8.6.210 Encoding A1 & A2.
// As a result, the decoder fails to deocode SSAT properly.
if (slice(insn, 27, 21) == 0x35 && slice(insn, 5, 4) == 1)
return slice(insn, 6, 6) == 0 ? ARM::SSATlsl : ARM::SSATasr;
// Ditto for RSCrs, which is a super-instruction for A8.6.146 & A8.6.147.
// As a result, the decoder fails to decode STRHT/LDRHT/LDRSHT/LDRSBT.
if (slice(insn, 27, 24) == 0) {
switch (slice(insn, 21, 20)) {
case 2:
switch (slice(insn, 7, 4)) {
case 11:
return ARM::STRHT;
default:
break; // fallthrough
}
break;
case 3:
switch (slice(insn, 7, 4)) {
case 11:
return ARM::LDRHT;
case 13:
return ARM::LDRSBT;
case 15:
return ARM::LDRSHT;
default:
break; // fallthrough
}
break;
default:
break; // fallthrough
}
}
// Ditto for SBCrs, which is a super-instruction for A8.6.152 & A8.6.153.
// As a result, the decoder fails to decode STRH_Post/LDRD_POST/STRD_POST
// properly.
if (slice(insn, 27, 25) == 0 && slice(insn, 20, 20) == 0) {
unsigned PW = slice(insn, 24, 24) << 1 | slice(insn, 21, 21);
switch (slice(insn, 7, 4)) {
case 11:
switch (PW) {
case 2: // Offset
return ARM::STRH;
case 3: // Pre-indexed
return ARM::STRH_PRE;
case 0: // Post-indexed
return ARM::STRH_POST;
default:
break; // fallthrough
}
break;
case 13:
switch (PW) {
case 2: // Offset
return ARM::LDRD;
case 3: // Pre-indexed
return ARM::LDRD_PRE;
case 0: // Post-indexed
return ARM::LDRD_POST;
default:
break; // fallthrough
}
break;
case 15:
switch (PW) {
case 2: // Offset
return ARM::STRD;
case 3: // Pre-indexed
return ARM::STRD_PRE;
case 0: // Post-indexed
return ARM::STRD_POST;
default:
break; // fallthrough
}
break;
default:
break; // fallthrough
}
}
// Ditto for SBCSSrs, which is a super-instruction for A8.6.152 & A8.6.153.
// As a result, the decoder fails to decode LDRH_POST/LDRSB_POST/LDRSH_POST
// properly.
if (slice(insn, 27, 25) == 0 && slice(insn, 20, 20) == 1) {
unsigned PW = slice(insn, 24, 24) << 1 | slice(insn, 21, 21);
switch (slice(insn, 7, 4)) {
case 11:
switch (PW) {
case 2: // Offset
return ARM::LDRH;
case 3: // Pre-indexed
return ARM::LDRH_PRE;
case 0: // Post-indexed
return ARM::LDRH_POST;
default:
break; // fallthrough
}
break;
case 13:
switch (PW) {
case 2: // Offset
return ARM::LDRSB;
case 3: // Pre-indexed
return ARM::LDRSB_PRE;
case 0: // Post-indexed
return ARM::LDRSB_POST;
default:
break; // fallthrough
}
break;
case 15:
switch (PW) {
case 2: // Offset
return ARM::LDRSH;
case 3: // Pre-indexed
return ARM::LDRSH_PRE;
case 0: // Post-indexed
return ARM::LDRSH_POST;
default:
break; // fallthrough
}
break;
default:
break; // fallthrough
}
}
AutoGenedDecoder:
// Calling the auto-generated decoder function.
return decodeInstruction(insn);
}
// Helper function for special case handling of LDR (literal) and friends.
// See, for example, A6.3.7 Load word: Table A6-18 Load word.
// See A8.6.57 T3, T4 & A8.6.60 T2 and friends for why we morphed the opcode
// before returning it.
static unsigned T2Morph2LoadLiteral(unsigned Opcode) {
switch (Opcode) {
default:
return Opcode; // Return unmorphed opcode.
case ARM::t2LDRDi8:
return ARM::t2LDRDpci;
case ARM::t2LDR_POST: case ARM::t2LDR_PRE:
case ARM::t2LDRi12: case ARM::t2LDRi8:
case ARM::t2LDRs:
return ARM::t2LDRpci;
case ARM::t2LDRB_POST: case ARM::t2LDRB_PRE:
case ARM::t2LDRBi12: case ARM::t2LDRBi8:
case ARM::t2LDRBs:
return ARM::t2LDRBpci;
case ARM::t2LDRH_POST: case ARM::t2LDRH_PRE:
case ARM::t2LDRHi12: case ARM::t2LDRHi8:
case ARM::t2LDRHs:
return ARM::t2LDRHpci;
case ARM::t2LDRSB_POST: case ARM::t2LDRSB_PRE:
case ARM::t2LDRSBi12: case ARM::t2LDRSBi8:
case ARM::t2LDRSBs:
return ARM::t2LDRSBpci;
case ARM::t2LDRSH_POST: case ARM::t2LDRSH_PRE:
case ARM::t2LDRSHi12: case ARM::t2LDRSHi8:
case ARM::t2LDRSHs:
return ARM::t2LDRSHpci;
}
}
/// decodeThumbSideEffect is a decorator function which can potentially twiddle
/// the instruction or morph the returned opcode under Thumb2.
///
/// First it checks whether the insn is a NEON or VFP instr; if true, bit
/// twiddling could be performed on insn to turn it into an ARM NEON/VFP
/// equivalent instruction and decodeInstruction is called with the transformed
/// insn.
///
/// Next, there is special handling for Load byte/halfword/word instruction by
/// checking whether Rn=0b1111 and call T2Morph2LoadLiteral() on the decoded
/// Thumb2 instruction. See comments below for further details.
///
/// Finally, one last check is made to see whether the insn is a NEON/VFP and
/// decodeInstruction(insn) is invoked on the original insn.
///
/// Otherwise, decodeThumbInstruction is called with the original insn.
static unsigned decodeThumbSideEffect(bool IsThumb2, uint32_t &insn) {
if (IsThumb2) {
uint16_t op1 = slice(insn, 28, 27);
uint16_t op2 = slice(insn, 26, 20);
// A6.3 32-bit Thumb instruction encoding
// Table A6-9 32-bit Thumb instruction encoding
// The coprocessor instructions of interest are transformed to their ARM
// equivalents.
// --------- Transform Begin Marker ---------
if ((op1 == 1 || op1 == 3) && slice(op2, 6, 4) == 7) {
// A7.4 Advanced SIMD data-processing instructions
// U bit of Thumb corresponds to Inst{24} of ARM.
uint16_t U = slice(op1, 1, 1);
// Inst{28-24} of ARM = {1,0,0,1,U};
uint16_t bits28_24 = 9 << 1 | U;
DEBUG(showBitVector(errs(), insn));
setSlice(insn, 28, 24, bits28_24);
return decodeInstruction(insn);
}
if (op1 == 3 && slice(op2, 6, 4) == 1 && slice(op2, 0, 0) == 0) {
// A7.7 Advanced SIMD element or structure load/store instructions
// Inst{27-24} of Thumb = 0b1001
// Inst{27-24} of ARM = 0b0100
DEBUG(showBitVector(errs(), insn));
setSlice(insn, 27, 24, 4);
return decodeInstruction(insn);
}
// --------- Transform End Marker ---------
// See, for example, A6.3.7 Load word: Table A6-18 Load word.
// See A8.6.57 T3, T4 & A8.6.60 T2 and friends for why we morphed the opcode
// before returning it to our caller.
if (op1 == 3 && slice(op2, 6, 5) == 0 && slice(op2, 0, 0) == 1
&& slice(insn, 19, 16) == 15)
return T2Morph2LoadLiteral(decodeThumbInstruction(insn));
// One last check for NEON/VFP instructions.
if ((op1 == 1 || op1 == 3) && slice(op2, 6, 6) == 1)
return decodeInstruction(insn);
// Fall through.
}
return decodeThumbInstruction(insn);
}
static inline bool Thumb2PreloadOpcodeNoPCI(unsigned Opcode) {
switch (Opcode) {
default:
return false;
case ARM::t2PLDi12: case ARM::t2PLDi8:
case ARM::t2PLDr: case ARM::t2PLDs:
case ARM::t2PLDWi12: case ARM::t2PLDWi8:
case ARM::t2PLDWr: case ARM::t2PLDWs:
case ARM::t2PLIi12: case ARM::t2PLIi8:
case ARM::t2PLIr: case ARM::t2PLIs:
return true;
}
}
static inline unsigned T2Morph2Preload2PCI(unsigned Opcode) {
switch (Opcode) {
default:
return 0;
case ARM::t2PLDi12: case ARM::t2PLDi8:
case ARM::t2PLDr: case ARM::t2PLDs:
return ARM::t2PLDpci;
case ARM::t2PLDWi12: case ARM::t2PLDWi8:
case ARM::t2PLDWr: case ARM::t2PLDWs:
return ARM::t2PLDWpci;
case ARM::t2PLIi12: case ARM::t2PLIi8:
case ARM::t2PLIr: case ARM::t2PLIs:
return ARM::t2PLIpci;
}
}
//
// Public interface for the disassembler
//
bool ARMDisassembler::getInstruction(MCInst &MI,
uint64_t &Size,
const MemoryObject &Region,
uint64_t Address,
raw_ostream &os) const {
// The machine instruction.
uint32_t insn;
// We want to read exactly 4 bytes of data.
if (Region.readBytes(Address, 4, (uint8_t*)&insn, NULL) == -1)
return false;
unsigned Opcode = decodeARMInstruction(insn);
ARMFormat Format = ARMFormats[Opcode];
Size = 4;
DEBUG({
errs() << "Opcode=" << Opcode << " Name=" << ARMUtils::OpcodeName(Opcode)
<< " Format=" << stringForARMFormat(Format) << '(' << (int)Format
<< ")\n";
showBitVector(errs(), insn);
});
ARMBasicMCBuilder *Builder = CreateMCBuilder(Opcode, Format);
if (!Builder)
return false;
if (!Builder->Build(MI, insn))
return false;
delete Builder;
return true;
}
bool ThumbDisassembler::getInstruction(MCInst &MI,
uint64_t &Size,
const MemoryObject &Region,
uint64_t Address,
raw_ostream &os) const {
// The machine instruction.
uint32_t insn = 0;
uint32_t insn1 = 0;
// A6.1 Thumb instruction set encoding
//
// If bits [15:11] of the halfword being decoded take any of the following
// values, the halfword is the first halfword of a 32-bit instruction:
// o 0b11101
// o 0b11110
// o 0b11111.
//
// Otherwise, the halfword is a 16-bit instruction.
// Read 2 bytes of data first.
if (Region.readBytes(Address, 2, (uint8_t*)&insn, NULL) == -1)
return false;
unsigned bits15_11 = slice(insn, 15, 11);
bool IsThumb2 = false;
// 32-bit instructions if the bits [15:11] of the halfword matches
// { 0b11101 /* 0x1D */, 0b11110 /* 0x1E */, ob11111 /* 0x1F */ }.
if (bits15_11 == 0x1D || bits15_11 == 0x1E || bits15_11 == 0x1F) {
IsThumb2 = true;
if (Region.readBytes(Address + 2, 2, (uint8_t*)&insn1, NULL) == -1)
return false;
insn = (insn << 16 | insn1);
}
// The insn could potentially be bit-twiddled in order to be decoded as an ARM
// NEON/VFP opcode. In such case, the modified insn is later disassembled as
// an ARM NEON/VFP instruction.
//
// This is a short term solution for lack of encoding bits specified for the
// Thumb2 NEON/VFP instructions. The long term solution could be adding some
// infrastructure to have each instruction support more than one encodings.
// Which encoding is used would be based on which subtarget the compiler/
// disassembler is working with at the time. This would allow the sharing of
// the NEON patterns between ARM and Thumb2, as well as potential greater
// sharing between the regular ARM instructions and the 32-bit wide Thumb2
// instructions as well.
unsigned Opcode = decodeThumbSideEffect(IsThumb2, insn);
// A8.6.117/119/120/121.
// PLD/PLDW/PLI instructions with Rn==15 is transformed to the pci variant.
if (Thumb2PreloadOpcodeNoPCI(Opcode) && slice(insn, 19, 16) == 15)
Opcode = T2Morph2Preload2PCI(Opcode);
ARMFormat Format = ARMFormats[Opcode];
Size = IsThumb2 ? 4 : 2;
DEBUG({
errs() << "Opcode=" << Opcode << " Name=" << ARMUtils::OpcodeName(Opcode)
<< " Format=" << stringForARMFormat(Format) << '(' << (int)Format
<< ")\n";
showBitVector(errs(), insn);
});
ARMBasicMCBuilder *Builder = CreateMCBuilder(Opcode, Format);
Builder->setSession(const_cast<Session *>(&SO));
if (!Builder)
return false;
if (!Builder->Build(MI, insn))
return false;
delete Builder;
return true;
}
// A8.6.50
static unsigned short CountITSize(unsigned ITMask) {
// First count the trailing zeros of the IT mask.
unsigned TZ = CountTrailingZeros_32(ITMask);
assert(TZ <= 3 && "Encoding error");
return (4 - TZ);
}
/// Init ITState.
void Session::InitIT(unsigned short bits7_0) {
ITCounter = CountITSize(slice(bits7_0, 3, 0));
ITState = bits7_0;
}
/// Update ITState if necessary.
void Session::UpdateIT() {
assert(ITCounter);
--ITCounter;
if (ITCounter == 0)
ITState = 0;
else {
unsigned short NewITState4_0 = slice(ITState, 4, 0) << 1;
setSlice(ITState, 4, 0, NewITState4_0);
}
}
static MCDisassembler *createARMDisassembler(const Target &T) {
return new ARMDisassembler;
}
static MCDisassembler *createThumbDisassembler(const Target &T) {
return new ThumbDisassembler;
}
extern "C" void LLVMInitializeARMDisassembler() {
// Register the disassembler.
TargetRegistry::RegisterMCDisassembler(TheARMTarget,
createARMDisassembler);
TargetRegistry::RegisterMCDisassembler(TheThumbTarget,
createThumbDisassembler);
}
} // namespace llvm

View File

@ -0,0 +1,91 @@
//===- ARMDisassembler.h - Disassembler for ARM/Thumb ISA -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is part of the ARM Disassembler.
// It contains the header for ARMDisassembler and ThumbDisassembler, both are
// subclasses of MCDisassembler.
//
//===----------------------------------------------------------------------===//
#ifndef ARMDISASSEMBLER_H
#define ARMDISASSEMBLER_H
#include "llvm/MC/MCDisassembler.h"
namespace llvm {
class MCInst;
class MemoryObject;
class raw_ostream;
/// ARMDisassembler - ARM disassembler for all ARM platforms.
class ARMDisassembler : public MCDisassembler {
public:
/// Constructor - Initializes the disassembler.
///
ARMDisassembler() :
MCDisassembler() {
}
~ARMDisassembler() {
}
/// getInstruction - See MCDisassembler.
bool getInstruction(MCInst &instr,
uint64_t &size,
const MemoryObject &region,
uint64_t address,
raw_ostream &vStream) const;
private:
};
// Forward declaration.
class ARMBasicMCBuilder;
/// Session - Keep track of the IT Block progression.
class Session {
friend class ARMBasicMCBuilder;
public:
Session() : ITCounter(0), ITState(0) {}
~Session() {}
/// InitIT - Initializes ITCounter/ITState.
void InitIT(unsigned short bits7_0);
/// UpdateIT - Updates ITCounter/ITState as IT Block progresses.
void UpdateIT();
private:
unsigned ITCounter; // Possible values: 0, 1, 2, 3, 4.
unsigned ITState; // A2.5.2 Consists of IT[7:5] and IT[4:0] initially.
};
/// ThumbDisassembler - Thumb disassembler for all ARM platforms.
class ThumbDisassembler : public MCDisassembler {
public:
/// Constructor - Initializes the disassembler.
///
ThumbDisassembler() :
MCDisassembler(), SO() {
}
~ThumbDisassembler() {
}
/// getInstruction - See MCDisassembler.
bool getInstruction(MCInst &instr,
uint64_t &size,
const MemoryObject &region,
uint64_t address,
raw_ostream &vStream) const;
private:
Session SO;
};
} // namespace llvm
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,248 @@
//===- ARMDisassemblerCore.h - ARM disassembler helpers ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is part of the ARM Disassembler.
//
// The first part defines the enumeration type of ARM instruction format, which
// specifies the encoding used by the instruction, as well as a helper function
// to convert the enums to printable char strings.
//
// It also contains code to represent the concepts of Builder and DisassembleFP
// to solve the problem of disassembling an ARM instr.
//
//===----------------------------------------------------------------------===//
#ifndef ARMDISASSEMBLERCORE_H
#define ARMDISASSEMBLERCORE_H
#include "llvm/MC/MCInst.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "ARMInstrInfo.h"
#include "ARMDisassembler.h"
namespace llvm {
class ARMUtils {
public:
static const char *OpcodeName(unsigned Opcode);
};
/////////////////////////////////////////////////////
// //
// Enums and Utilities for ARM Instruction Format //
// //
/////////////////////////////////////////////////////
#define ARM_FORMATS \
ENTRY(ARM_FORMAT_PSEUDO, 0) \
ENTRY(ARM_FORMAT_MULFRM, 1) \
ENTRY(ARM_FORMAT_BRFRM, 2) \
ENTRY(ARM_FORMAT_BRMISCFRM, 3) \
ENTRY(ARM_FORMAT_DPFRM, 4) \
ENTRY(ARM_FORMAT_DPSOREGFRM, 5) \
ENTRY(ARM_FORMAT_LDFRM, 6) \
ENTRY(ARM_FORMAT_STFRM, 7) \
ENTRY(ARM_FORMAT_LDMISCFRM, 8) \
ENTRY(ARM_FORMAT_STMISCFRM, 9) \
ENTRY(ARM_FORMAT_LDSTMULFRM, 10) \
ENTRY(ARM_FORMAT_LDSTEXFRM, 11) \
ENTRY(ARM_FORMAT_ARITHMISCFRM, 12) \
ENTRY(ARM_FORMAT_EXTFRM, 13) \
ENTRY(ARM_FORMAT_VFPUNARYFRM, 14) \
ENTRY(ARM_FORMAT_VFPBINARYFRM, 15) \
ENTRY(ARM_FORMAT_VFPCONV1FRM, 16) \
ENTRY(ARM_FORMAT_VFPCONV2FRM, 17) \
ENTRY(ARM_FORMAT_VFPCONV3FRM, 18) \
ENTRY(ARM_FORMAT_VFPCONV4FRM, 19) \
ENTRY(ARM_FORMAT_VFPCONV5FRM, 20) \
ENTRY(ARM_FORMAT_VFPLDSTFRM, 21) \
ENTRY(ARM_FORMAT_VFPLDSTMULFRM, 22) \
ENTRY(ARM_FORMAT_VFPMISCFRM, 23) \
ENTRY(ARM_FORMAT_THUMBFRM, 24) \
ENTRY(ARM_FORMAT_NEONFRM, 25) \
ENTRY(ARM_FORMAT_NEONGETLNFRM, 26) \
ENTRY(ARM_FORMAT_NEONSETLNFRM, 27) \
ENTRY(ARM_FORMAT_NEONDUPFRM, 28) \
ENTRY(ARM_FORMAT_MISCFRM, 29) \
ENTRY(ARM_FORMAT_THUMBMISCFRM, 30) \
ENTRY(ARM_FORMAT_NLdSt, 31) \
ENTRY(ARM_FORMAT_N1RegModImm, 32) \
ENTRY(ARM_FORMAT_N2Reg, 33) \
ENTRY(ARM_FORMAT_NVCVT, 34) \
ENTRY(ARM_FORMAT_NVecDupLn, 35) \
ENTRY(ARM_FORMAT_N2RegVecShL, 36) \
ENTRY(ARM_FORMAT_N2RegVecShR, 37) \
ENTRY(ARM_FORMAT_N3Reg, 38) \
ENTRY(ARM_FORMAT_N3RegVecSh, 39) \
ENTRY(ARM_FORMAT_NVecExtract, 40) \
ENTRY(ARM_FORMAT_NVecMulScalar, 41) \
ENTRY(ARM_FORMAT_NVTBL, 42)
// ARM instruction format specifies the encoding used by the instruction.
#define ENTRY(n, v) n = v,
typedef enum {
ARM_FORMATS
ARM_FORMAT_NA
} ARMFormat;
#undef ENTRY
// Converts enum to const char*.
static const inline char *stringForARMFormat(ARMFormat form) {
#define ENTRY(n, v) case n: return #n;
switch(form) {
ARM_FORMATS
case ARM_FORMAT_NA:
default:
return "";
}
#undef ENTRY
}
/// Expands on the enum definitions from ARMBaseInstrInfo.h.
/// They are being used by the disassembler implementation.
namespace ARMII {
enum {
NEONRegMask = 15,
GPRRegMask = 15,
NEON_RegRdShift = 12,
NEON_D_BitShift = 22,
NEON_RegRnShift = 16,
NEON_N_BitShift = 7,
NEON_RegRmShift = 0,
NEON_M_BitShift = 5
};
}
/// Utility function for extracting [From, To] bits from a uint32_t.
static inline unsigned slice(uint32_t Bits, unsigned From, unsigned To) {
assert(From < 32 && To < 32 && From >= To);
return (Bits >> To) & ((1 << (From - To + 1)) - 1);
}
/// Utility function for setting [From, To] bits to Val for a uint32_t.
static inline void setSlice(uint32_t &Bits, unsigned From, unsigned To,
uint32_t Val) {
assert(From < 32 && To < 32 && From >= To);
uint32_t Mask = ((1 << (From - To + 1)) - 1);
Bits &= ~(Mask << To);
Bits |= (Val & Mask) << To;
}
/// Various utilities for checking the target specific flags.
/// A unary data processing instruction doesn't have an Rn operand.
static inline bool isUnaryDP(unsigned TSFlags) {
return (TSFlags & ARMII::UnaryDP);
}
/// This four-bit field describes the addressing mode used.
/// See also ARMBaseInstrInfo.h.
static inline unsigned getAddrMode(unsigned TSFlags) {
return (TSFlags & ARMII::AddrModeMask);
}
/// {IndexModePre, IndexModePost}
/// Only valid for load and store ops.
/// See also ARMBaseInstrInfo.h.
static inline unsigned getIndexMode(unsigned TSFlags) {
return (TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
}
/// Pre-/post-indexed operations define an extra $base_wb in the OutOperandList.
static inline bool isPrePostLdSt(unsigned TSFlags) {
return (TSFlags & ARMII::IndexModeMask) != 0;
}
// Forward declaration.
class ARMBasicMCBuilder;
// Builder Object is mostly ignored except in some Thumb disassemble functions.
typedef ARMBasicMCBuilder *BO;
/// DisassembleFP - DisassembleFP points to a function that disassembles an insn
/// and builds the MCOperand list upon disassembly. It returns false on failure
/// or true on success. The number of operands added is updated upon success.
typedef bool (*DisassembleFP)(MCInst &MI, unsigned Opcode, uint32_t insn,
unsigned short NumOps, unsigned &NumOpsAdded, BO Builder);
/// ARMBasicMCBuilder - ARMBasicMCBuilder represents an ARM MCInst builder that
/// knows how to build up the MCOperand list.
class ARMBasicMCBuilder {
unsigned Opcode;
ARMFormat Format;
unsigned short NumOps;
DisassembleFP Disasm;
Session *SP;
public:
ARMBasicMCBuilder(ARMBasicMCBuilder &B)
: Opcode(B.Opcode), Format(B.Format), NumOps(B.NumOps), Disasm(B.Disasm),
SP(B.SP)
{}
/// Opcode, Format, and NumOperands make up an ARM Basic MCBuilder.
ARMBasicMCBuilder(unsigned opc, ARMFormat format, unsigned short num);
virtual ~ARMBasicMCBuilder() {}
void setSession(Session *sp) {
SP = sp;
}
/// TryPredicateAndSBitModifier - TryPredicateAndSBitModifier tries to process
/// the possible Predicate and SBitModifier, to build the remaining MCOperand
/// constituents.
bool TryPredicateAndSBitModifier(MCInst& MI, unsigned Opcode,
uint32_t insn, unsigned short NumOpsRemaning);
/// InITBlock - InITBlock returns true if we are inside an IT block.
bool InITBlock() {
if (SP)
return SP->ITCounter > 0;
return false;
}
/// Build - Build delegates to BuildIt to perform the heavy liftling. After
/// that, it invokes RunBuildAfterHook where some housekeepings can be done.
virtual bool Build(MCInst &MI, uint32_t insn) {
bool Status = BuildIt(MI, insn);
return RunBuildAfterHook(Status, MI, insn);
}
/// BuildIt - BuildIt performs the build step for this ARM Basic MC Builder.
/// The general idea is to set the Opcode for the MCInst, followed by adding
/// the appropriate MCOperands to the MCInst. ARM Basic MC Builder delegates
/// to the Format-specific disassemble function for disassembly, followed by
/// TryPredicateAndSBitModifier() for PredicateOperand and OptionalDefOperand
/// which follow the Dst/Src Operands.
virtual bool BuildIt(MCInst &MI, uint32_t insn);
/// RunBuildAfterHook - RunBuildAfterHook performs operations deemed necessary
/// after BuildIt is finished.
virtual bool RunBuildAfterHook(bool Status, MCInst &MI, uint32_t insn);
private:
/// Get condition of the current IT instruction.
unsigned GetITCond() {
assert(SP);
return slice(SP->ITState, 7, 4);
}
};
/// CreateMCBuilder - Return an ARMBasicMCBuilder that can build up the MC
/// infrastructure of an MCInst given the Opcode and Format of the instr.
/// Return NULL if it fails to create/return a proper builder. API clients
/// are responsible for freeing up of the allocated memory. Cacheing can be
/// performed by the API clients to improve performance.
extern ARMBasicMCBuilder *CreateMCBuilder(unsigned Opcode, ARMFormat Format);
} // namespace llvm
#endif

View File

@ -0,0 +1,16 @@
##===- lib/Target/ARM/Disassembler/Makefile ----------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMARMDisassembler
# Hack: we need to include 'main' arm target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common

File diff suppressed because it is too large Load Diff

View File

@ -16,8 +16,9 @@ BUILT_SOURCES = ARMGenRegisterInfo.h.inc ARMGenRegisterNames.inc \
ARMGenRegisterInfo.inc ARMGenInstrNames.inc \
ARMGenInstrInfo.inc ARMGenAsmWriter.inc \
ARMGenDAGISel.inc ARMGenSubtarget.inc \
ARMGenCodeEmitter.inc ARMGenCallingConv.inc
ARMGenCodeEmitter.inc ARMGenCallingConv.inc \
ARMGenDecoderTables.inc
DIRS = AsmPrinter AsmParser TargetInfo
DIRS = AsmPrinter AsmParser Disassembler TargetInfo
include $(LEVEL)/Makefile.common

View File

@ -37,7 +37,7 @@ bool Thumb1InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *DestRC,
const TargetRegisterClass *SrcRC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
if (DestRC == ARM::GPRRegisterClass) {
@ -98,7 +98,7 @@ void Thumb1InstrInfo::
storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned SrcReg, bool isKill, int FI,
const TargetRegisterClass *RC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
assert((RC == ARM::tGPRRegisterClass ||
@ -125,7 +125,7 @@ void Thumb1InstrInfo::
loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned DestReg, int FI,
const TargetRegisterClass *RC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
assert((RC == ARM::tGPRRegisterClass ||
@ -154,7 +154,7 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB,
if (CSI.empty())
return false;
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, get(ARM::tPUSH));

View File

@ -398,7 +398,7 @@ Thumb1RegisterInfo::saveScavengerRegister(MachineBasicBlock &MBB,
// off the frame pointer (if, for example, there are alloca() calls in
// the function, the offset will be negative. Use R12 instead since that's
// a call clobbered register that we know won't be used in Thumb1 mode.
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
BuildMI(MBB, I, DL, TII.get(ARM::tMOVtgpr2gpr)).
addReg(ARM::R12, RegState::Define).addReg(Reg, RegState::Kill);
@ -685,8 +685,7 @@ void Thumb1RegisterInfo::emitPrologue(MachineFunction &MF) const {
unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
unsigned NumBytes = MFI->getStackSize();
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
DebugLoc dl = (MBBI != MBB.end() ?
MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
// Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4.
NumBytes = (NumBytes + 3) & ~3;

View File

@ -41,7 +41,7 @@ Thumb2InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *DestRC,
const TargetRegisterClass *SrcRC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
if (DestRC == ARM::GPRRegisterClass &&
@ -66,7 +66,7 @@ void Thumb2InstrInfo::
storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned SrcReg, bool isKill, int FI,
const TargetRegisterClass *RC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
if (RC == ARM::GPRRegisterClass || RC == ARM::tGPRRegisterClass) {
@ -90,7 +90,7 @@ void Thumb2InstrInfo::
loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned DestReg, int FI,
const TargetRegisterClass *RC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
if (RC == ARM::GPRRegisterClass || RC == ARM::tGPRRegisterClass) {

View File

@ -471,8 +471,7 @@ AlphaTargetLowering::LowerReturn(SDValue Chain,
SDValue Copy = DAG.getCopyToReg(Chain, dl, Alpha::R26,
DAG.getNode(AlphaISD::GlobalRetAddr,
DebugLoc::getUnknownLoc(),
MVT::i64),
DebugLoc(), MVT::i64),
SDValue());
switch (Outs.size()) {
default:
@ -740,8 +739,7 @@ SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
SA2, NULL, 0, MVT::i32, false, false, 0);
}
case ISD::RETURNADDR:
return DAG.getNode(AlphaISD::GlobalRetAddr, DebugLoc::getUnknownLoc(),
MVT::i64);
return DAG.getNode(AlphaISD::GlobalRetAddr, DebugLoc(), MVT::i64);
//FIXME: implement
case ISD::FRAMEADDR: break;
}

View File

@ -112,7 +112,7 @@ unsigned AlphaInstrInfo::InsertBranch(MachineBasicBlock &MBB,
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond) const {
// FIXME this should probably have a DebugLoc argument
DebugLoc dl = DebugLoc::getUnknownLoc();
DebugLoc dl;
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
assert((Cond.size() == 2 || Cond.size() == 0) &&
"Alpha branch conditions have two components!");
@ -153,7 +153,7 @@ bool AlphaInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
return false;
}
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
if (DestRC == Alpha::GPRCRegisterClass) {
@ -185,7 +185,7 @@ AlphaInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
// << FrameIdx << "\n";
//BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg);
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
if (RC == Alpha::F4RCRegisterClass)
@ -211,7 +211,7 @@ AlphaInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
const TargetRegisterClass *RC) const {
//cerr << "Trying to load " << getPrettyName(DestReg) << " to "
// << FrameIdx << "\n";
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
if (RC == Alpha::F4RCRegisterClass)
@ -398,7 +398,7 @@ unsigned AlphaInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
void AlphaInstrInfo::insertNoop(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
BuildMI(MBB, MI, DL, get(Alpha::BISr), Alpha::R31)
.addReg(Alpha::R31)

View File

@ -49,7 +49,7 @@ namespace {
const TargetInstrInfo *TII = F.getTarget().getInstrInfo();
bool Changed = false;
MachineInstr* prev[3] = {0,0,0};
DebugLoc dl = DebugLoc::getUnknownLoc();
DebugLoc dl;
unsigned count = 0;
for (MachineFunction::iterator FI = F.begin(), FE = F.end();
FI != FE; ++FI) {

View File

@ -207,8 +207,7 @@ void AlphaRegisterInfo::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
MachineBasicBlock::iterator MBBI = MBB.begin();
MachineFrameInfo *MFI = MF.getFrameInfo();
DebugLoc dl = (MBBI != MBB.end() ?
MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
DebugLoc dl = (MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc());
bool FP = hasFP(MF);
//handle GOP offset

View File

@ -106,7 +106,7 @@ InsertBranch(MachineBasicBlock &MBB,
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond) const {
// FIXME this should probably have a DebugLoc operand
DebugLoc dl = DebugLoc::getUnknownLoc();
DebugLoc DL;
// Shouldn't be a fall through.
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
@ -116,7 +116,7 @@ InsertBranch(MachineBasicBlock &MBB,
if (Cond.empty()) {
// Unconditional branch?
assert(!FBB && "Unconditional branch with multiple successors!");
BuildMI(&MBB, dl, get(BF::JUMPa)).addMBB(TBB);
BuildMI(&MBB, DL, get(BF::JUMPa)).addMBB(TBB);
return 1;
}
@ -139,27 +139,27 @@ bool BlackfinInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
unsigned SrcReg,
const TargetRegisterClass *DestRC,
const TargetRegisterClass *SrcRC) const {
DebugLoc dl = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (inClass(BF::ALLRegClass, DestReg, DestRC) &&
inClass(BF::ALLRegClass, SrcReg, SrcRC)) {
BuildMI(MBB, I, dl, get(BF::MOVE), DestReg).addReg(SrcReg);
BuildMI(MBB, I, DL, get(BF::MOVE), DestReg).addReg(SrcReg);
return true;
}
if (inClass(BF::D16RegClass, DestReg, DestRC) &&
inClass(BF::D16RegClass, SrcReg, SrcRC)) {
BuildMI(MBB, I, dl, get(BF::SLL16i), DestReg).addReg(SrcReg).addImm(0);
BuildMI(MBB, I, DL, get(BF::SLL16i), DestReg).addReg(SrcReg).addImm(0);
return true;
}
if (inClass(BF::AnyCCRegClass, SrcReg, SrcRC) &&
inClass(BF::DRegClass, DestReg, DestRC)) {
if (inClass(BF::NotCCRegClass, SrcReg, SrcRC)) {
BuildMI(MBB, I, dl, get(BF::MOVENCC_z), DestReg).addReg(SrcReg);
BuildMI(MBB, I, dl, get(BF::BITTGL), DestReg).addReg(DestReg).addImm(0);
BuildMI(MBB, I, DL, get(BF::MOVENCC_z), DestReg).addReg(SrcReg);
BuildMI(MBB, I, DL, get(BF::BITTGL), DestReg).addReg(DestReg).addImm(0);
} else {
BuildMI(MBB, I, dl, get(BF::MOVECC_zext), DestReg).addReg(SrcReg);
BuildMI(MBB, I, DL, get(BF::MOVECC_zext), DestReg).addReg(SrcReg);
}
return true;
}
@ -167,21 +167,21 @@ bool BlackfinInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
if (inClass(BF::AnyCCRegClass, DestReg, DestRC) &&
inClass(BF::DRegClass, SrcReg, SrcRC)) {
if (inClass(BF::NotCCRegClass, DestReg, DestRC))
BuildMI(MBB, I, dl, get(BF::SETEQri_not), DestReg).addReg(SrcReg);
BuildMI(MBB, I, DL, get(BF::SETEQri_not), DestReg).addReg(SrcReg);
else
BuildMI(MBB, I, dl, get(BF::MOVECC_nz), DestReg).addReg(SrcReg);
BuildMI(MBB, I, DL, get(BF::MOVECC_nz), DestReg).addReg(SrcReg);
return true;
}
if (inClass(BF::NotCCRegClass, DestReg, DestRC) &&
inClass(BF::JustCCRegClass, SrcReg, SrcRC)) {
BuildMI(MBB, I, dl, get(BF::MOVE_ncccc), DestReg).addReg(SrcReg);
BuildMI(MBB, I, DL, get(BF::MOVE_ncccc), DestReg).addReg(SrcReg);
return true;
}
if (inClass(BF::JustCCRegClass, DestReg, DestRC) &&
inClass(BF::NotCCRegClass, SrcReg, SrcRC)) {
BuildMI(MBB, I, dl, get(BF::MOVE_ccncc), DestReg).addReg(SrcReg);
BuildMI(MBB, I, DL, get(BF::MOVE_ccncc), DestReg).addReg(SrcReg);
return true;
}
@ -197,8 +197,7 @@ BlackfinInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
bool isKill,
int FI,
const TargetRegisterClass *RC) const {
DebugLoc DL = I != MBB.end() ?
I->getDebugLoc() : DebugLoc::getUnknownLoc();
DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
if (inClass(BF::DPRegClass, SrcReg, RC)) {
BuildMI(MBB, I, DL, get(BF::STORE32fi))
@ -244,8 +243,7 @@ BlackfinInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
unsigned DestReg,
int FI,
const TargetRegisterClass *RC) const {
DebugLoc DL = I != MBB.end() ?
I->getDebugLoc() : DebugLoc::getUnknownLoc();
DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
if (inClass(BF::DPRegClass, DestReg, RC)) {
BuildMI(MBB, I, DL, get(BF::LOAD32fi), DestReg)
.addFrameIndex(FI)

View File

@ -384,9 +384,7 @@ void BlackfinRegisterInfo::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
MachineBasicBlock::iterator MBBI = MBB.begin();
MachineFrameInfo *MFI = MF.getFrameInfo();
DebugLoc dl = (MBBI != MBB.end()
? MBBI->getDebugLoc()
: DebugLoc::getUnknownLoc());
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
int FrameSize = MFI->getStackSize();
if (FrameSize%4) {

View File

@ -262,7 +262,7 @@ bool SPUInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
// we instruction select bitconvert i64 -> f64 as a noop for example, so our
// types have no specific meaning.
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
if (DestRC == SPU::R8CRegisterClass) {
@ -317,7 +317,7 @@ SPUInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
llvm_unreachable("Unknown regclass!");
}
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
addFrameReference(BuildMI(MBB, MI, DL, get(opc))
.addReg(SrcReg, getKillRegState(isKill)), FrameIdx);
@ -351,7 +351,7 @@ SPUInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
llvm_unreachable("Unknown regclass in loadRegFromStackSlot!");
}
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
addFrameReference(BuildMI(MBB, MI, DL, get(opc), DestReg), FrameIdx);
}
@ -553,7 +553,7 @@ SPUInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond) const {
// FIXME this should probably have a DebugLoc argument
DebugLoc dl = DebugLoc::getUnknownLoc();
DebugLoc dl;
// Shouldn't be a fall through.
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
assert((Cond.size() == 2 || Cond.size() == 0) &&

View File

@ -452,8 +452,7 @@ void SPURegisterInfo::emitPrologue(MachineFunction &MF) const
MachineBasicBlock::iterator MBBI = MBB.begin();
MachineFrameInfo *MFI = MF.getFrameInfo();
MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
DebugLoc dl = (MBBI != MBB.end() ?
MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
// Prepare for debug frame info.
bool hasDebugInfo = MMI && MMI->hasDebugInfo();

View File

@ -106,7 +106,7 @@ isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const {
/// instruction.
void MBlazeInstrInfo::
insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
BuildMI(MBB, MI, DL, get(MBlaze::NOP));
}
@ -116,8 +116,8 @@ copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *DestRC,
const TargetRegisterClass *SrcRC) const {
DebugLoc dl = DebugLoc::getUnknownLoc();
llvm::BuildMI(MBB, I, dl, get(MBlaze::ADD), DestReg)
DebugLoc DL;
llvm::BuildMI(MBB, I, DL, get(MBlaze::ADD), DestReg)
.addReg(SrcReg).addReg(MBlaze::R0);
return true;
}
@ -126,8 +126,8 @@ void MBlazeInstrInfo::
storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned SrcReg, bool isKill, int FI,
const TargetRegisterClass *RC) const {
DebugLoc dl = DebugLoc::getUnknownLoc();
BuildMI(MBB, I, dl, get(MBlaze::SWI)).addReg(SrcReg,getKillRegState(isKill))
DebugLoc DL;
BuildMI(MBB, I, DL, get(MBlaze::SWI)).addReg(SrcReg,getKillRegState(isKill))
.addImm(0).addFrameIndex(FI);
}
@ -135,8 +135,8 @@ void MBlazeInstrInfo::
loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned DestReg, int FI,
const TargetRegisterClass *RC) const {
DebugLoc dl = DebugLoc::getUnknownLoc();
BuildMI(MBB, I, dl, get(MBlaze::LWI), DestReg)
DebugLoc DL;
BuildMI(MBB, I, DL, get(MBlaze::LWI), DestReg)
.addImm(0).addFrameIndex(FI);
}
@ -185,11 +185,9 @@ unsigned MBlazeInstrInfo::
InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond) const {
DebugLoc dl = DebugLoc::getUnknownLoc();
// Can only insert uncond branches so far.
assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!");
BuildMI(&MBB, dl, get(MBlaze::BRI)).addMBB(TBB);
BuildMI(&MBB, DebugLoc(), get(MBlaze::BRI)).addMBB(TBB);
return 1;
}

View File

@ -302,8 +302,7 @@ emitPrologue(MachineFunction &MF) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc dl = (MBBI != MBB.end() ?
MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
// Get the right frame order for MBlaze.
adjustMBlazeStackFrame(MF);
@ -319,13 +318,13 @@ emitPrologue(MachineFunction &MF) const {
int RAOffset = MBlazeFI->getRAStackOffset();
// Adjust stack : addi R1, R1, -imm
BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADDI), MBlaze::R1)
BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADDI), MBlaze::R1)
.addReg(MBlaze::R1).addImm(-StackSize);
// Save the return address only if the function isnt a leaf one.
// swi R15, R1, stack_loc
if (MFI->hasCalls()) {
BuildMI(MBB, MBBI, dl, TII.get(MBlaze::SWI))
BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI))
.addReg(MBlaze::R15).addImm(RAOffset).addReg(MBlaze::R1);
}
@ -333,11 +332,11 @@ emitPrologue(MachineFunction &MF) const {
// to point to the stack pointer
if (hasFP(MF)) {
// swi R19, R1, stack_loc
BuildMI(MBB, MBBI, dl, TII.get(MBlaze::SWI))
BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI))
.addReg(MBlaze::R19).addImm(FPOffset).addReg(MBlaze::R1);
// add R19, R1, R0
BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADD), MBlaze::R19)
BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADD), MBlaze::R19)
.addReg(MBlaze::R1).addReg(MBlaze::R0);
}
}

View File

@ -33,7 +33,7 @@ void MSP430InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned SrcReg, bool isKill, int FrameIdx,
const TargetRegisterClass *RC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
MachineFunction &MF = *MBB.getParent();
MachineFrameInfo &MFI = *MF.getFrameInfo();
@ -60,7 +60,7 @@ void MSP430InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned DestReg, int FrameIdx,
const TargetRegisterClass *RC) const{
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
MachineFunction &MF = *MBB.getParent();
MachineFrameInfo &MFI = *MF.getFrameInfo();
@ -86,7 +86,7 @@ bool MSP430InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *DestRC,
const TargetRegisterClass *SrcRC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
if (DestRC == SrcRC) {
@ -134,7 +134,7 @@ MSP430InstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
if (CSI.empty())
return false;
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
MachineFunction &MF = *MBB.getParent();
@ -158,7 +158,7 @@ MSP430InstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
if (CSI.empty())
return false;
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
for (unsigned i = 0, e = CSI.size(); i != e; ++i)
@ -323,7 +323,7 @@ MSP430InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond) const {
// FIXME this should probably have a DebugLoc operand
DebugLoc dl = DebugLoc::getUnknownLoc();
DebugLoc DL;
// Shouldn't be a fall through.
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
@ -333,18 +333,18 @@ MSP430InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
if (Cond.empty()) {
// Unconditional branch?
assert(!FBB && "Unconditional branch with multiple successors!");
BuildMI(&MBB, dl, get(MSP430::JMP)).addMBB(TBB);
BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(TBB);
return 1;
}
// Conditional branch.
unsigned Count = 0;
BuildMI(&MBB, dl, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm());
BuildMI(&MBB, DL, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm());
++Count;
if (FBB) {
// Two-way Conditional branch. Insert the second branch.
BuildMI(&MBB, dl, get(MSP430::JMP)).addMBB(FBB);
BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(FBB);
++Count;
}
return Count;

View File

@ -283,8 +283,7 @@ void MSP430RegisterInfo::emitPrologue(MachineFunction &MF) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>();
MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() :
DebugLoc::getUnknownLoc());
DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
// Get the number of bytes to allocate from the FrameInfo.
uint64_t StackSize = MFI->getStackSize();

View File

@ -123,7 +123,7 @@ isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const
void MipsInstrInfo::
insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const
{
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
BuildMI(MBB, MI, DL, get(Mips::NOP));
}
@ -133,7 +133,7 @@ copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *DestRC,
const TargetRegisterClass *SrcRC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
@ -191,7 +191,7 @@ void MipsInstrInfo::
storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned SrcReg, bool isKill, int FI,
const TargetRegisterClass *RC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
if (RC == Mips::CPURegsRegisterClass)
@ -225,7 +225,7 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned DestReg, int FI,
const TargetRegisterClass *RC) const
{
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
if (RC == Mips::CPURegsRegisterClass)
@ -523,7 +523,7 @@ InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond) const {
// FIXME this should probably have a DebugLoc argument
DebugLoc dl = DebugLoc::getUnknownLoc();
DebugLoc dl;
// Shouldn't be a fall through.
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
assert((Cond.size() == 3 || Cond.size() == 2 || Cond.size() == 0) &&

View File

@ -397,8 +397,7 @@ emitPrologue(MachineFunction &MF) const
MachineFrameInfo *MFI = MF.getFrameInfo();
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc dl = (MBBI != MBB.end() ?
MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
bool isPIC = (MF.getTarget().getRelocationModel() == Reloc::PIC_);
// Get the right frame order for Mips.

View File

@ -256,15 +256,11 @@ void PIC16DbgInfo::BeginFunction(const MachineFunction &MF) {
///
void PIC16DbgInfo::ChangeDebugLoc(const MachineFunction &MF,
const DebugLoc &DL, bool IsInBeginFunction) {
if (! EmitDebugDirectives) return;
assert (! DL.isUnknown() && "can't change to invalid debug loc");
if (!EmitDebugDirectives) return;
assert(!DL.isUnknown() && "can't change to invalid debug loc");
DILocation Loc = MF.getDILocation(DL);
MDNode *CU = Loc.getScope().getNode();
unsigned line = Loc.getLineNumber();
SwitchToCU(CU);
SwitchToLine(line, IsInBeginFunction);
SwitchToCU(DL.getScope(MF.getFunction()->getContext()));
SwitchToLine(DL.getLine(), IsInBeginFunction);
}
/// SwitchToLine - Emit line directive for a new line.

View File

@ -72,7 +72,7 @@ void PIC16InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
unsigned SrcReg, bool isKill, int FI,
const TargetRegisterClass *RC) const {
PIC16TargetLowering *PTLI = TM.getTargetLowering();
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
const Function *Func = MBB.getParent()->getFunction();
@ -114,7 +114,7 @@ void PIC16InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
unsigned DestReg, int FI,
const TargetRegisterClass *RC) const {
PIC16TargetLowering *PTLI = TM.getTargetLowering();
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
const Function *Func = MBB.getParent()->getFunction();
@ -154,7 +154,7 @@ bool PIC16InstrInfo::copyRegToReg (MachineBasicBlock &MBB,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *DestRC,
const TargetRegisterClass *SrcRC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
if (DestRC == PIC16::FSR16RegisterClass) {
@ -202,7 +202,7 @@ InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
if (FBB == 0) { // One way branch.
if (Cond.empty()) {
// Unconditional branch?
DebugLoc dl = DebugLoc::getUnknownLoc();
DebugLoc dl;
BuildMI(&MBB, dl, get(PIC16::br_uncond)).addMBB(TBB);
}
return 1;

View File

@ -215,7 +215,7 @@ void PPCDAGToDAGISel::InsertVRSaveCode(MachineFunction &Fn) {
const TargetInstrInfo &TII = *TM.getInstrInfo();
MachineBasicBlock &EntryBB = *Fn.begin();
DebugLoc dl = DebugLoc::getUnknownLoc();
DebugLoc dl;
// Emit the following code into the entry block:
// InVRSAVE = MFVRSAVE
// UpdatedVRSAVE = UPDATE_VRSAVE InVRSAVE
@ -253,7 +253,7 @@ SDNode *PPCDAGToDAGISel::getGlobalBaseReg() {
// Insert the set of GlobalBaseReg into the first MBB of the function
MachineBasicBlock &FirstMBB = MF->front();
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
DebugLoc dl = DebugLoc::getUnknownLoc();
DebugLoc dl;
if (PPCLowering.getPointerTy() == MVT::i32) {
GlobalBaseReg = RegInfo->createVirtualRegister(PPC::GPRCRegisterClass);

View File

@ -1122,7 +1122,7 @@ SDValue PPCTargetLowering::LowerConstantPool(SDValue Op,
// With PIC, the first instruction is actually "GR+hi(&G)".
Hi = DAG.getNode(ISD::ADD, dl, PtrVT,
DAG.getNode(PPCISD::GlobalBaseReg,
DebugLoc::getUnknownLoc(), PtrVT), Hi);
DebugLoc(), PtrVT), Hi);
}
Lo = DAG.getNode(ISD::ADD, dl, PtrVT, Hi, Lo);
@ -1155,7 +1155,7 @@ SDValue PPCTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) {
// With PIC, the first instruction is actually "GR+hi(&G)".
Hi = DAG.getNode(ISD::ADD, dl, PtrVT,
DAG.getNode(PPCISD::GlobalBaseReg,
DebugLoc::getUnknownLoc(), PtrVT), Hi);
DebugLoc(), PtrVT), Hi);
}
Lo = DAG.getNode(ISD::ADD, dl, PtrVT, Hi, Lo);
@ -1192,7 +1192,7 @@ SDValue PPCTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) {
// With PIC, the first instruction is actually "GR+hi(&G)".
Hi = DAG.getNode(ISD::ADD, DL, PtrVT,
DAG.getNode(PPCISD::GlobalBaseReg,
DebugLoc::getUnknownLoc(), PtrVT), Hi);
DebugLoc(), PtrVT), Hi);
}
return DAG.getNode(ISD::ADD, DL, PtrVT, Hi, Lo);
@ -1233,7 +1233,7 @@ SDValue PPCTargetLowering::LowerGlobalAddress(SDValue Op,
// With PIC, the first instruction is actually "GR+hi(&G)".
Hi = DAG.getNode(ISD::ADD, dl, PtrVT,
DAG.getNode(PPCISD::GlobalBaseReg,
DebugLoc::getUnknownLoc(), PtrVT), Hi);
DebugLoc(), PtrVT), Hi);
}
Lo = DAG.getNode(ISD::ADD, dl, PtrVT, Hi, Lo);
@ -5540,15 +5540,18 @@ PPCTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
}
/// getOptimalMemOpType - Returns the target specific optimal type for load
/// and store operations as a result of memset, memcpy, and memmove lowering.
/// If DstAlign is zero that means it's safe to destination alignment can
/// satisfy any constraint. Similarly if SrcAlign is zero it means there
/// isn't a need to check it against alignment requirement, probably because
/// the source does not need to be loaded. It returns EVT::Other if
/// SelectionDAG should be responsible for determining it.
/// and store operations as a result of memset, memcpy, and memmove
/// lowering. If DstAlign is zero that means it's safe to destination
/// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
/// means there isn't a need to check it against alignment requirement,
/// probably because the source does not need to be loaded. If
/// 'NonScalarIntSafe' is true, that means it's safe to return a
/// non-scalar-integer type, e.g. empty string source, constant, or loaded
/// from memory. It returns EVT::Other if SelectionDAG should be responsible
/// for determining it.
EVT PPCTargetLowering::getOptimalMemOpType(uint64_t Size,
unsigned DstAlign, unsigned SrcAlign,
bool SafeToUseFP,
bool NonScalarIntSafe,
SelectionDAG &DAG) const {
if (this->PPCSubTarget.isPPC64()) {
return MVT::i64;

View File

@ -348,15 +348,19 @@ namespace llvm {
virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
/// getOptimalMemOpType - Returns the target specific optimal type for load
/// and store operations as a result of memset, memcpy, and memmove lowering.
/// If DstAlign is zero that means it's safe to destination alignment can
/// satisfy any constraint. Similarly if SrcAlign is zero it means there
/// isn't a need to check it against alignment requirement, probably because
/// the source does not need to be loaded. It returns EVT::Other if
/// SelectionDAG should be responsible for determining it.
virtual EVT getOptimalMemOpType(uint64_t Size,
unsigned DstAlign, unsigned SrcAlign,
bool SafeToUseFP, SelectionDAG &DAG) const;
/// and store operations as a result of memset, memcpy, and memmove
/// lowering. If DstAlign is zero that means it's safe to destination
/// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
/// means there isn't a need to check it against alignment requirement,
/// probably because the source does not need to be loaded. If
/// 'NonScalarIntSafe' is true, that means it's safe to return a
/// non-scalar-integer type, e.g. empty string source, constant, or loaded
/// from memory. It returns EVT::Other if SelectionDAG should be responsible
/// for determining it.
virtual EVT
getOptimalMemOpType(uint64_t Size,
unsigned DstAlign, unsigned SrcAlign,
bool NonScalarIntSafe, SelectionDAG &DAG) const;
/// getFunctionAlignment - Return the Log2 alignment of this function.
virtual unsigned getFunctionAlignment(const Function *F) const;

View File

@ -199,7 +199,7 @@ PPCInstrInfo::commuteInstruction(MachineInstr *MI, bool NewMI) const {
void PPCInstrInfo::insertNoop(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
BuildMI(MBB, MI, DL, get(PPC::NOP));
@ -317,7 +317,7 @@ PPCInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond) const {
// FIXME this should probably have a DebugLoc argument
DebugLoc dl = DebugLoc::getUnknownLoc();
DebugLoc dl;
// Shouldn't be a fall through.
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
assert((Cond.size() == 2 || Cond.size() == 0) &&
@ -350,7 +350,7 @@ bool PPCInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
return false;
}
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
if (DestRC == PPC::GPRCRegisterClass) {
@ -380,7 +380,7 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF,
int FrameIdx,
const TargetRegisterClass *RC,
SmallVectorImpl<MachineInstr*> &NewMIs) const{
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (RC == PPC::GPRCRegisterClass) {
if (SrcReg != PPC::LR) {
NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STW))
@ -635,7 +635,7 @@ PPCInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
const TargetRegisterClass *RC) const {
MachineFunction &MF = *MBB.getParent();
SmallVector<MachineInstr*, 4> NewMIs;
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
LoadRegFromStackSlot(MF, DL, DestReg, FrameIdx, RC, NewMIs);
for (unsigned i = 0, e = NewMIs.size(); i != e; ++i)

View File

@ -1281,7 +1281,7 @@ PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock::iterator MBBI = MBB.begin();
MachineFrameInfo *MFI = MF.getFrameInfo();
MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
DebugLoc dl = DebugLoc::getUnknownLoc();
DebugLoc dl;
bool needsFrameMoves = (MMI && MMI->hasDebugInfo()) ||
!MF.getFunction()->doesNotThrow() ||
UnwindTablesMandatory;
@ -1521,7 +1521,7 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator MBBI = prior(MBB.end());
unsigned RetOpcode = MBBI->getOpcode();
DebugLoc dl = DebugLoc::getUnknownLoc();
DebugLoc dl;
assert( (RetOpcode == PPC::BLR ||
RetOpcode == PPC::TCRETURNri ||

View File

@ -68,7 +68,7 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
if (I->getDesc().hasDelaySlot()) {
MachineBasicBlock::iterator J = I;
++J;
BuildMI(MBB, J, DebugLoc::getUnknownLoc(), TII->get(SP::NOP));
BuildMI(MBB, J, DebugLoc(), TII->get(SP::NOP));
++FilledSlots;
Changed = true;
}

View File

@ -111,7 +111,7 @@ SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond)const{
// FIXME this should probably take a DebugLoc argument
DebugLoc dl = DebugLoc::getUnknownLoc();
DebugLoc dl;
// Can only insert uncond branches so far.
assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!");
BuildMI(&MBB, dl, get(SP::BA)).addMBB(TBB);
@ -128,7 +128,7 @@ bool SparcInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
return false;
}
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
if (DestRC == SP::IntRegsRegisterClass)
@ -149,7 +149,7 @@ void SparcInstrInfo::
storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned SrcReg, bool isKill, int FI,
const TargetRegisterClass *RC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
// On the order of operands here: think "[FrameIdx + 0] = SrcReg".
@ -170,7 +170,7 @@ void SparcInstrInfo::
loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned DestReg, int FI,
const TargetRegisterClass *RC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
if (RC == SP::IntRegsRegisterClass)
@ -253,7 +253,7 @@ unsigned SparcInstrInfo::getGlobalBaseReg(MachineFunction *MF) const
GlobalBaseReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
DebugLoc dl = DebugLoc::getUnknownLoc();
DebugLoc dl;
BuildMI(FirstMBB, MBBI, dl, get(SP::GETPCX), GlobalBaseReg);
SparcFI->setGlobalBaseReg(GlobalBaseReg);

View File

@ -125,8 +125,7 @@ void SparcRegisterInfo::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front();
MachineFrameInfo *MFI = MF.getFrameInfo();
MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc dl = (MBBI != MBB.end() ?
MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
// Get the number of bytes to allocate from the FrameInfo
int NumBytes = (int) MFI->getStackSize();

View File

@ -62,7 +62,7 @@ void SystemZInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned SrcReg, bool isKill, int FrameIdx,
const TargetRegisterClass *RC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
unsigned Opc = 0;
@ -91,7 +91,7 @@ void SystemZInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned DestReg, int FrameIdx,
const TargetRegisterClass *RC) const{
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
unsigned Opc = 0;
@ -120,7 +120,7 @@ bool SystemZInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *DestRC,
const TargetRegisterClass *SrcRC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
// Determine if DstRC and SrcRC have a common superclass.
@ -273,7 +273,7 @@ SystemZInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
if (CSI.empty())
return false;
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
MachineFunction &MF = *MBB.getParent();
@ -347,7 +347,7 @@ SystemZInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
if (CSI.empty())
return false;
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
MachineFunction &MF = *MBB.getParent();
@ -521,7 +521,7 @@ SystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond) const {
// FIXME: this should probably have a DebugLoc operand
DebugLoc dl = DebugLoc::getUnknownLoc();
DebugLoc DL;
// Shouldn't be a fall through.
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
assert((Cond.size() == 1 || Cond.size() == 0) &&
@ -530,19 +530,19 @@ SystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
if (Cond.empty()) {
// Unconditional branch?
assert(!FBB && "Unconditional branch with multiple successors!");
BuildMI(&MBB, dl, get(SystemZ::JMP)).addMBB(TBB);
BuildMI(&MBB, DL, get(SystemZ::JMP)).addMBB(TBB);
return 1;
}
// Conditional branch.
unsigned Count = 0;
SystemZCC::CondCodes CC = (SystemZCC::CondCodes)Cond[0].getImm();
BuildMI(&MBB, dl, getBrCond(CC)).addMBB(TBB);
BuildMI(&MBB, DL, getBrCond(CC)).addMBB(TBB);
++Count;
if (FBB) {
// Two-way Conditional branch. Insert the second branch.
BuildMI(&MBB, dl, get(SystemZ::JMP)).addMBB(FBB);
BuildMI(&MBB, DL, get(SystemZ::JMP)).addMBB(FBB);
++Count;
}
return Count;

View File

@ -194,8 +194,7 @@ void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
Chunk = (1LL << 15) - 1;
}
DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() :
DebugLoc::getUnknownLoc());
DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
while (Offset) {
uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset;
@ -215,8 +214,7 @@ void SystemZRegisterInfo::emitPrologue(MachineFunction &MF) const {
SystemZMachineFunctionInfo *SystemZMFI =
MF.getInfo<SystemZMachineFunctionInfo>();
MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() :
DebugLoc::getUnknownLoc());
DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
// Get the number of bytes to allocate from the FrameInfo.
// Note that area for callee-saved stuff is already allocated, thus we need to

View File

@ -21,8 +21,8 @@
#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "X86GenRegisterNames.inc"
@ -30,6 +30,14 @@
using namespace llvm;
using namespace llvm::X86Disassembler;
void x86DisassemblerDebug(const char *file,
unsigned line,
const char *s) {
dbgs() << file << ":" << line << ": " << s;
}
#define debug(s) DEBUG(x86DisassemblerDebug(__FILE__, __LINE__, s));
namespace llvm {
// Fill-ins to make the compiler happy. These constants are never actually
@ -50,8 +58,8 @@ extern Target TheX86_32Target, TheX86_64Target;
}
static void translateInstruction(MCInst &target,
InternalInstruction &source);
static bool translateInstruction(MCInst &target,
InternalInstruction &source);
X86GenericDisassembler::X86GenericDisassembler(DisassemblerMode mode) :
MCDisassembler(),
@ -106,14 +114,13 @@ bool X86GenericDisassembler::getInstruction(MCInst &instr,
address,
fMode);
if(ret) {
if (ret) {
size = internalInstr.readerCursor - address;
return false;
}
else {
size = internalInstr.length;
translateInstruction(instr, internalInstr);
return true;
return !translateInstruction(instr, internalInstr);
}
}
@ -151,29 +158,35 @@ static void translateImmediate(MCInst &mcInst, uint64_t immediate) {
/// @param mcInst - The MCInst to append to.
/// @param insn - The internal instruction to extract the R/M field
/// from.
static void translateRMRegister(MCInst &mcInst,
/// @return - 0 on success; -1 otherwise
static bool translateRMRegister(MCInst &mcInst,
InternalInstruction &insn) {
assert(insn.eaBase != EA_BASE_sib && insn.eaBase != EA_BASE_sib64 &&
"A R/M register operand may not have a SIB byte");
if (insn.eaBase == EA_BASE_sib || insn.eaBase == EA_BASE_sib64) {
debug("A R/M register operand may not have a SIB byte");
return true;
}
switch (insn.eaBase) {
default:
debug("Unexpected EA base register");
return true;
case EA_BASE_NONE:
llvm_unreachable("EA_BASE_NONE for ModR/M base");
break;
debug("EA_BASE_NONE for ModR/M base");
return true;
#define ENTRY(x) case EA_BASE_##x:
ALL_EA_BASES
#undef ENTRY
llvm_unreachable("A R/M register operand may not have a base; "
"the operand must be a register.");
break;
#define ENTRY(x) \
debug("A R/M register operand may not have a base; "
"the operand must be a register.");
return true;
#define ENTRY(x) \
case EA_REG_##x: \
mcInst.addOperand(MCOperand::CreateReg(X86::x)); break;
ALL_REGS
#undef ENTRY
default:
llvm_unreachable("Unexpected EA base register");
}
return false;
}
/// translateRMMemory - Translates a memory operand stored in the Mod and R/M
@ -186,7 +199,8 @@ static void translateRMRegister(MCInst &mcInst,
/// @param sr - Whether or not to emit the segment register. The
/// LEA instruction does not expect a segment-register
/// operand.
static void translateRMMemory(MCInst &mcInst,
/// @return - 0 on success; nonzero otherwise
static bool translateRMMemory(MCInst &mcInst,
InternalInstruction &insn,
bool sr) {
// Addresses in an MCInst are represented as five operands:
@ -211,7 +225,8 @@ static void translateRMMemory(MCInst &mcInst,
if (insn.sibBase != SIB_BASE_NONE) {
switch (insn.sibBase) {
default:
llvm_unreachable("Unexpected sibBase");
debug("Unexpected sibBase");
return true;
#define ENTRY(x) \
case SIB_BASE_##x: \
baseReg = MCOperand::CreateReg(X86::x); break;
@ -225,7 +240,8 @@ static void translateRMMemory(MCInst &mcInst,
if (insn.sibIndex != SIB_INDEX_NONE) {
switch (insn.sibIndex) {
default:
llvm_unreachable("Unexpected sibIndex");
debug("Unexpected sibIndex");
return true;
#define ENTRY(x) \
case SIB_INDEX_##x: \
indexReg = MCOperand::CreateReg(X86::x); break;
@ -241,9 +257,10 @@ static void translateRMMemory(MCInst &mcInst,
} else {
switch (insn.eaBase) {
case EA_BASE_NONE:
assert(insn.eaDisplacement != EA_DISP_NONE &&
"EA_BASE_NONE and EA_DISP_NONE for ModR/M base");
if (insn.eaDisplacement == EA_DISP_NONE) {
debug("EA_BASE_NONE and EA_DISP_NONE for ModR/M base");
return true;
}
if (insn.mode == MODE_64BIT)
baseReg = MCOperand::CreateReg(X86::RIP); // Section 2.2.1.6
else
@ -271,8 +288,8 @@ static void translateRMMemory(MCInst &mcInst,
indexReg = MCOperand::CreateReg(0);
switch (insn.eaBase) {
default:
llvm_unreachable("Unexpected eaBase");
break;
debug("Unexpected eaBase");
return true;
// Here, we will use the fill-ins defined above. However,
// BX_SI, BX_DI, BP_SI, and BP_DI are all handled above and
// sib and sib64 were handled in the top-level if, so they're only
@ -285,9 +302,9 @@ static void translateRMMemory(MCInst &mcInst,
#define ENTRY(x) case EA_REG_##x:
ALL_REGS
#undef ENTRY
llvm_unreachable("A R/M memory operand may not be a register; "
"the base field must be a base.");
break;
debug("A R/M memory operand may not be a register; "
"the base field must be a base.");
return true;
}
}
@ -315,6 +332,8 @@ static void translateRMMemory(MCInst &mcInst,
if (sr)
mcInst.addOperand(segmentReg);
return false;
}
/// translateRM - Translates an operand stored in the R/M (and possibly SIB)
@ -324,12 +343,14 @@ static void translateRMMemory(MCInst &mcInst,
/// @param operand - The operand, as stored in the descriptor table.
/// @param insn - The instruction to extract Mod, R/M, and SIB fields
/// from.
static void translateRM(MCInst &mcInst,
OperandSpecifier &operand,
InternalInstruction &insn) {
/// @return - 0 on success; nonzero otherwise
static bool translateRM(MCInst &mcInst,
OperandSpecifier &operand,
InternalInstruction &insn) {
switch (operand.type) {
default:
llvm_unreachable("Unexpected type for a R/M operand");
debug("Unexpected type for a R/M operand");
return true;
case TYPE_R8:
case TYPE_R16:
case TYPE_R32:
@ -345,8 +366,7 @@ static void translateRM(MCInst &mcInst,
case TYPE_DEBUGREG:
case TYPE_CR32:
case TYPE_CR64:
translateRMRegister(mcInst, insn);
break;
return translateRMRegister(mcInst, insn);
case TYPE_M:
case TYPE_M8:
case TYPE_M16:
@ -364,11 +384,9 @@ static void translateRM(MCInst &mcInst,
case TYPE_M1616:
case TYPE_M1632:
case TYPE_M1664:
translateRMMemory(mcInst, insn, true);
break;
return translateRMMemory(mcInst, insn, true);
case TYPE_LEA:
translateRMMemory(mcInst, insn, false);
break;
return translateRMMemory(mcInst, insn, false);
}
}
@ -377,11 +395,17 @@ static void translateRM(MCInst &mcInst,
///
/// @param mcInst - The MCInst to append to.
/// @param stackPos - The stack position to translate.
static void translateFPRegister(MCInst &mcInst,
uint8_t stackPos) {
assert(stackPos < 8 && "Invalid FP stack position");
/// @return - 0 on success; nonzero otherwise.
static bool translateFPRegister(MCInst &mcInst,
uint8_t stackPos) {
if (stackPos >= 8) {
debug("Invalid FP stack position");
return true;
}
mcInst.addOperand(MCOperand::CreateReg(X86::ST0 + stackPos));
return false;
}
/// translateOperand - Translates an operand stored in an internal instruction
@ -390,25 +414,27 @@ static void translateFPRegister(MCInst &mcInst,
/// @param mcInst - The MCInst to append to.
/// @param operand - The operand, as stored in the descriptor table.
/// @param insn - The internal instruction.
static void translateOperand(MCInst &mcInst,
OperandSpecifier &operand,
InternalInstruction &insn) {
/// @return - false on success; true otherwise.
static bool translateOperand(MCInst &mcInst,
OperandSpecifier &operand,
InternalInstruction &insn) {
switch (operand.encoding) {
default:
llvm_unreachable("Unhandled operand encoding during translation");
debug("Unhandled operand encoding during translation");
return true;
case ENCODING_REG:
translateRegister(mcInst, insn.reg);
break;
return false;
case ENCODING_RM:
translateRM(mcInst, operand, insn);
break;
return translateRM(mcInst, operand, insn);
case ENCODING_CB:
case ENCODING_CW:
case ENCODING_CD:
case ENCODING_CP:
case ENCODING_CO:
case ENCODING_CT:
llvm_unreachable("Translation of code offsets isn't supported.");
debug("Translation of code offsets isn't supported.");
return true;
case ENCODING_IB:
case ENCODING_IW:
case ENCODING_ID:
@ -417,24 +443,22 @@ static void translateOperand(MCInst &mcInst,
case ENCODING_Ia:
translateImmediate(mcInst,
insn.immediates[insn.numImmediatesTranslated++]);
break;
return false;
case ENCODING_RB:
case ENCODING_RW:
case ENCODING_RD:
case ENCODING_RO:
translateRegister(mcInst, insn.opcodeRegister);
break;
return false;
case ENCODING_I:
translateFPRegister(mcInst, insn.opcodeModifier);
break;
return translateFPRegister(mcInst, insn.opcodeModifier);
case ENCODING_Rv:
translateRegister(mcInst, insn.opcodeRegister);
break;
return false;
case ENCODING_DUP:
translateOperand(mcInst,
insn.spec->operands[operand.type - TYPE_DUP0],
insn);
break;
return translateOperand(mcInst,
insn.spec->operands[operand.type - TYPE_DUP0],
insn);
}
}
@ -443,9 +467,13 @@ static void translateOperand(MCInst &mcInst,
///
/// @param mcInst - The MCInst to populate with the instruction's data.
/// @param insn - The internal instruction.
static void translateInstruction(MCInst &mcInst,
InternalInstruction &insn) {
assert(insn.spec);
/// @return - false on success; true otherwise.
static bool translateInstruction(MCInst &mcInst,
InternalInstruction &insn) {
if (!insn.spec) {
debug("Instruction has no specification");
return true;
}
mcInst.setOpcode(insn.instructionID);
@ -454,9 +482,14 @@ static void translateInstruction(MCInst &mcInst,
insn.numImmediatesTranslated = 0;
for (index = 0; index < X86_MAX_OPERANDS; ++index) {
if (insn.spec->operands[index].encoding != ENCODING_NONE)
translateOperand(mcInst, insn.spec->operands[index], insn);
if (insn.spec->operands[index].encoding != ENCODING_NONE) {
if (translateOperand(mcInst, insn.spec->operands[index], insn)) {
return true;
}
}
}
return false;
}
static MCDisassembler *createX86_32Disassembler(const Target &T) {

View File

@ -13,7 +13,6 @@
*
*===----------------------------------------------------------------------===*/
#include <assert.h> /* for assert() */
#include <stdarg.h> /* for va_*() */
#include <stdio.h> /* for vsnprintf() */
#include <stdlib.h> /* for exit() */
@ -26,17 +25,20 @@
#define TRUE 1
#define FALSE 0
typedef int8_t bool;
#ifdef __GNUC__
#define NORETURN __attribute__((noreturn))
#else
#define NORETURN
#endif
#define unreachable(s) \
do { \
fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, s); \
exit(-1); \
} while (0);
#ifndef NDEBUG
#define debug(s) do { x86DisassemblerDebug(__FILE__, __LINE__, s); } while (0)
#else
#define debug(s) do { } while (0)
#endif
/*
* contextForAttrs - Client for the instruction context table. Takes a set of
@ -84,7 +86,6 @@ static int modRMRequired(OpcodeType type,
return decision->opcodeDecisions[insnContext].modRMDecisions[opcode].
modrm_type != MODRM_ONEENTRY;
unreachable("Unknown opcode type");
return 0;
}
@ -96,16 +97,18 @@ static int modRMRequired(OpcodeType type,
* @param insnContext - See modRMRequired().
* @param opcode - See modRMRequired().
* @param modRM - The ModR/M byte if required, or any value if not.
* @return - The UID of the instruction, or 0 on failure.
*/
static InstrUID decode(OpcodeType type,
InstructionContext insnContext,
uint8_t opcode,
uint8_t modRM) {
InstructionContext insnContext,
uint8_t opcode,
uint8_t modRM) {
struct ModRMDecision* dec;
switch (type) {
default:
unreachable("Unknown opcode type");
debug("Unknown opcode type");
return 0;
case ONEBYTE:
dec = &ONEBYTE_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode];
break;
@ -122,7 +125,8 @@ static InstrUID decode(OpcodeType type,
switch (dec->modrm_type) {
default:
unreachable("Corrupt table! Unknown modrm_type");
debug("Corrupt table! Unknown modrm_type");
return 0;
case MODRM_ONEENTRY:
return dec->instructionIDs[0];
case MODRM_SPLITRM:
@ -133,8 +137,6 @@ static InstrUID decode(OpcodeType type,
case MODRM_FULL:
return dec->instructionIDs[modRM];
}
return 0;
}
/*
@ -342,7 +344,8 @@ static int readPrefixes(struct InternalInstruction* insn) {
insn->segmentOverride = SEG_OVERRIDE_GS;
break;
default:
unreachable("Unhandled override");
debug("Unhandled override");
return -1;
}
if (prefixGroups[1])
dbgprintf(insn, "Redundant Group 2 prefix");
@ -376,7 +379,7 @@ static int readPrefixes(struct InternalInstruction* insn) {
if ((byte & 0xf0) == 0x40) {
uint8_t opcodeByte;
if(lookAtByte(insn, &opcodeByte) || ((opcodeByte & 0xf0) == 0x40)) {
if (lookAtByte(insn, &opcodeByte) || ((opcodeByte & 0xf0) == 0x40)) {
dbgprintf(insn, "Redundant REX prefix");
return -1;
}
@ -540,17 +543,17 @@ static int getIDWithAttrMask(uint16_t* instructionID,
static BOOL is16BitEquvalent(const char* orig, const char* equiv) {
off_t i;
for(i = 0;; i++) {
if(orig[i] == '\0' && equiv[i] == '\0')
for (i = 0;; i++) {
if (orig[i] == '\0' && equiv[i] == '\0')
return TRUE;
if(orig[i] == '\0' || equiv[i] == '\0')
if (orig[i] == '\0' || equiv[i] == '\0')
return FALSE;
if(orig[i] != equiv[i]) {
if((orig[i] == 'Q' || orig[i] == 'L') && equiv[i] == 'W')
if (orig[i] != equiv[i]) {
if ((orig[i] == 'Q' || orig[i] == 'L') && equiv[i] == 'W')
continue;
if((orig[i] == '6' || orig[i] == '3') && equiv[i] == '1')
if ((orig[i] == '6' || orig[i] == '3') && equiv[i] == '1')
continue;
if((orig[i] == '4' || orig[i] == '2') && equiv[i] == '6')
if ((orig[i] == '4' || orig[i] == '2') && equiv[i] == '6')
continue;
return FALSE;
}
@ -567,17 +570,17 @@ static BOOL is16BitEquvalent(const char* orig, const char* equiv) {
static BOOL is64BitEquivalent(const char* orig, const char* equiv) {
off_t i;
for(i = 0;; i++) {
if(orig[i] == '\0' && equiv[i] == '\0')
for (i = 0;; i++) {
if (orig[i] == '\0' && equiv[i] == '\0')
return TRUE;
if(orig[i] == '\0' || equiv[i] == '\0')
if (orig[i] == '\0' || equiv[i] == '\0')
return FALSE;
if(orig[i] != equiv[i]) {
if((orig[i] == 'W' || orig[i] == 'L') && equiv[i] == 'Q')
if (orig[i] != equiv[i]) {
if ((orig[i] == 'W' || orig[i] == 'L') && equiv[i] == 'Q')
continue;
if((orig[i] == '1' || orig[i] == '3') && equiv[i] == '6')
if ((orig[i] == '1' || orig[i] == '3') && equiv[i] == '6')
continue;
if((orig[i] == '6' || orig[i] == '2') && equiv[i] == '4')
if ((orig[i] == '6' || orig[i] == '2') && equiv[i] == '4')
continue;
return FALSE;
}
@ -615,7 +618,7 @@ static int getID(struct InternalInstruction* insn) {
else if (isPrefixAtLocation(insn, 0xf2, insn->necessaryPrefixLocation))
attrMask |= ATTR_XD;
if(getIDWithAttrMask(&instructionID, insn, attrMask))
if (getIDWithAttrMask(&instructionID, insn, attrMask))
return -1;
/* The following clauses compensate for limitations of the tables. */
@ -792,7 +795,8 @@ static int readSIB(struct InternalInstruction* insn) {
SIB_BASE_EBP : SIB_BASE_RBP);
break;
case 0x3:
unreachable("Cannot have Mod = 0b11 and a SIB byte");
debug("Cannot have Mod = 0b11 and a SIB byte");
return -1;
}
break;
default:
@ -903,7 +907,7 @@ static int readModRM(struct InternalInstruction* insn) {
if (rm == 0x6) {
insn->eaBase = EA_BASE_NONE;
insn->eaDisplacement = EA_DISP_16;
if(readDisplacement(insn))
if (readDisplacement(insn))
return -1;
} else {
insn->eaBase = (EABase)(insn->eaBaseBase + rm);
@ -913,18 +917,18 @@ static int readModRM(struct InternalInstruction* insn) {
case 0x1:
insn->eaBase = (EABase)(insn->eaBaseBase + rm);
insn->eaDisplacement = EA_DISP_8;
if(readDisplacement(insn))
if (readDisplacement(insn))
return -1;
break;
case 0x2:
insn->eaBase = (EABase)(insn->eaBaseBase + rm);
insn->eaDisplacement = EA_DISP_16;
if(readDisplacement(insn))
if (readDisplacement(insn))
return -1;
break;
case 0x3:
insn->eaBase = (EABase)(insn->eaRegBase + rm);
if(readDisplacement(insn))
if (readDisplacement(insn))
return -1;
break;
}
@ -942,13 +946,13 @@ static int readModRM(struct InternalInstruction* insn) {
insn->eaBase = (insn->addressSize == 4 ?
EA_BASE_sib : EA_BASE_sib64);
readSIB(insn);
if(readDisplacement(insn))
if (readDisplacement(insn))
return -1;
break;
case 0x5:
insn->eaBase = EA_BASE_NONE;
insn->eaDisplacement = EA_DISP_32;
if(readDisplacement(insn))
if (readDisplacement(insn))
return -1;
break;
default:
@ -964,12 +968,12 @@ static int readModRM(struct InternalInstruction* insn) {
case 0xc: /* in case REXW.b is set */
insn->eaBase = EA_BASE_sib;
readSIB(insn);
if(readDisplacement(insn))
if (readDisplacement(insn))
return -1;
break;
default:
insn->eaBase = (EABase)(insn->eaBaseBase + rm);
if(readDisplacement(insn))
if (readDisplacement(insn))
return -1;
break;
}
@ -993,11 +997,13 @@ static int readModRM(struct InternalInstruction* insn) {
*valid = 1; \
switch (type) { \
default: \
unreachable("Unhandled register type"); \
debug("Unhandled register type"); \
*valid = 0; \
return 0; \
case TYPE_Rv: \
return base + index; \
case TYPE_R8: \
if(insn->rexPrefix && \
if (insn->rexPrefix && \
index >= 4 && index <= 7) { \
return prefix##_SPL + (index - 4); \
} else { \
@ -1017,23 +1023,23 @@ static int readModRM(struct InternalInstruction* insn) {
case TYPE_MM64: \
case TYPE_MM32: \
case TYPE_MM: \
if(index > 7) \
if (index > 7) \
*valid = 0; \
return prefix##_MM0 + index; \
case TYPE_SEGMENTREG: \
if(index > 5) \
if (index > 5) \
*valid = 0; \
return prefix##_ES + index; \
case TYPE_DEBUGREG: \
if(index > 7) \
if (index > 7) \
*valid = 0; \
return prefix##_DR0 + index; \
case TYPE_CR32: \
if(index > 7) \
if (index > 7) \
*valid = 0; \
return prefix##_ECR0 + index; \
case TYPE_CR64: \
if(index > 8) \
if (index > 8) \
*valid = 0; \
return prefix##_RCR0 + index; \
} \
@ -1050,6 +1056,7 @@ static int readModRM(struct InternalInstruction* insn) {
* @param index - The existing value of the field as reported by readModRM().
* @param valid - The address of a uint8_t. The target is set to 1 if the
* field is valid for the register class; 0 if not.
* @return - The proper value.
*/
GENERIC_FIXUP_FUNC(fixupRegValue, insn->regBase, MODRM_REG)
GENERIC_FIXUP_FUNC(fixupRMValue, insn->eaRegBase, EA_REG)
@ -1071,7 +1078,8 @@ static int fixupReg(struct InternalInstruction *insn,
switch ((OperandEncoding)op->encoding) {
default:
unreachable("Expected a REG or R/M encoding in fixupReg");
debug("Expected a REG or R/M encoding in fixupReg");
return -1;
case ENCODING_REG:
insn->reg = (Reg)fixupRegValue(insn,
(OperandType)op->type,
@ -1102,26 +1110,29 @@ static int fixupReg(struct InternalInstruction *insn,
* @param insn - The instruction whose opcode field is to be read.
* @param inModRM - Indicates that the opcode field is to be read from the
* ModR/M extension; useful for escape opcodes
* @return - 0 on success; nonzero otherwise.
*/
static void readOpcodeModifier(struct InternalInstruction* insn) {
static int readOpcodeModifier(struct InternalInstruction* insn) {
dbgprintf(insn, "readOpcodeModifier()");
if (insn->consumedOpcodeModifier)
return;
return 0;
insn->consumedOpcodeModifier = TRUE;
switch(insn->spec->modifierType) {
switch (insn->spec->modifierType) {
default:
unreachable("Unknown modifier type.");
debug("Unknown modifier type.");
return -1;
case MODIFIER_NONE:
unreachable("No modifier but an operand expects one.");
debug("No modifier but an operand expects one.");
return -1;
case MODIFIER_OPCODE:
insn->opcodeModifier = insn->opcode - insn->spec->modifierBase;
break;
return 0;
case MODIFIER_MODRM:
insn->opcodeModifier = insn->modRM - insn->spec->modifierBase;
break;
return 0;
}
}
@ -1134,11 +1145,13 @@ static void readOpcodeModifier(struct InternalInstruction* insn) {
* @param size - The width (in bytes) of the register being specified.
* 1 means AL and friends, 2 means AX, 4 means EAX, and 8 means
* RAX.
* @return - 0 on success; nonzero otherwise.
*/
static void readOpcodeRegister(struct InternalInstruction* insn, uint8_t size) {
static int readOpcodeRegister(struct InternalInstruction* insn, uint8_t size) {
dbgprintf(insn, "readOpcodeRegister()");
readOpcodeModifier(insn);
if (readOpcodeModifier(insn))
return -1;
if (size == 0)
size = insn->registerSize;
@ -1147,9 +1160,9 @@ static void readOpcodeRegister(struct InternalInstruction* insn, uint8_t size) {
case 1:
insn->opcodeRegister = (Reg)(MODRM_REG_AL + ((bFromREX(insn->rexPrefix) << 3)
| insn->opcodeModifier));
if(insn->rexPrefix &&
insn->opcodeRegister >= MODRM_REG_AL + 0x4 &&
insn->opcodeRegister < MODRM_REG_AL + 0x8) {
if (insn->rexPrefix &&
insn->opcodeRegister >= MODRM_REG_AL + 0x4 &&
insn->opcodeRegister < MODRM_REG_AL + 0x8) {
insn->opcodeRegister = (Reg)(MODRM_REG_SPL
+ (insn->opcodeRegister - MODRM_REG_AL - 4));
}
@ -1161,7 +1174,7 @@ static void readOpcodeRegister(struct InternalInstruction* insn, uint8_t size) {
| insn->opcodeModifier));
break;
case 4:
insn->opcodeRegister = (Reg)(MODRM_REG_EAX +
insn->opcodeRegister = (Reg)(MODRM_REG_EAX
+ ((bFromREX(insn->rexPrefix) << 3)
| insn->opcodeModifier));
break;
@ -1171,6 +1184,8 @@ static void readOpcodeRegister(struct InternalInstruction* insn, uint8_t size) {
| insn->opcodeModifier));
break;
}
return 0;
}
/*
@ -1190,8 +1205,10 @@ static int readImmediate(struct InternalInstruction* insn, uint8_t size) {
dbgprintf(insn, "readImmediate()");
if (insn->numImmediatesConsumed == 2)
unreachable("Already consumed two immediates");
if (insn->numImmediatesConsumed == 2) {
debug("Already consumed two immediates");
return -1;
}
if (size == 0)
size = insn->immediateSize;
@ -1274,29 +1291,35 @@ static int readOperands(struct InternalInstruction* insn) {
return -1;
break;
case ENCODING_Iv:
readImmediate(insn, insn->immediateSize);
break;
if (readImmediate(insn, insn->immediateSize))
return -1;
case ENCODING_Ia:
readImmediate(insn, insn->addressSize);
if (readImmediate(insn, insn->addressSize))
return -1;
break;
case ENCODING_RB:
readOpcodeRegister(insn, 1);
if (readOpcodeRegister(insn, 1))
return -1;
break;
case ENCODING_RW:
readOpcodeRegister(insn, 2);
if (readOpcodeRegister(insn, 2))
return -1;
break;
case ENCODING_RD:
readOpcodeRegister(insn, 4);
if (readOpcodeRegister(insn, 4))
return -1;
break;
case ENCODING_RO:
readOpcodeRegister(insn, 8);
if (readOpcodeRegister(insn, 8))
return -1;
break;
case ENCODING_Rv:
readOpcodeRegister(insn, 0);
if (readOpcodeRegister(insn, 0))
return -1;
break;
case ENCODING_I:
readOpcodeModifier(insn);
break;
if (readOpcodeModifier(insn))
return -1;
case ENCODING_DUP:
break;
default:

View File

@ -508,6 +508,17 @@ int decodeInstruction(struct InternalInstruction* insn,
uint64_t startLoc,
DisassemblerMode mode);
/* x86DisassemblerDebug - C-accessible function for printing a message to
* debugs()
* @param file - The name of the file printing the debug message.
* @param line - The line number that printed the debug message.
* @param s - The message to print.
*/
void x86DisassemblerDebug(const char *file,
unsigned line,
const char *s);
#ifdef __cplusplus
}
#endif

View File

@ -74,6 +74,8 @@ def FeatureFMA4 : SubtargetFeature<"fma4", "HasFMA4", "true",
def FeatureVectorUAMem : SubtargetFeature<"vector-unaligned-mem",
"HasVectorUAMem", "true",
"Allow unaligned memory operands on vector/SIMD instructions">;
def FeatureAES : SubtargetFeature<"aes", "HasAES", "true",
"Enable AES instructions">;
//===----------------------------------------------------------------------===//
// X86 processors supported.
@ -101,11 +103,17 @@ def : Proc<"nocona", [FeatureSSE3, Feature64Bit, FeatureSlowBTMem]>;
def : Proc<"core2", [FeatureSSSE3, Feature64Bit, FeatureSlowBTMem]>;
def : Proc<"penryn", [FeatureSSE41, Feature64Bit, FeatureSlowBTMem]>;
def : Proc<"atom", [FeatureSSE3, Feature64Bit, FeatureSlowBTMem]>;
// "Arrandale" along with corei3 and corei5
def : Proc<"corei7", [FeatureSSE42, Feature64Bit, FeatureSlowBTMem,
FeatureFastUAMem]>;
FeatureFastUAMem, FeatureAES]>;
def : Proc<"nehalem", [FeatureSSE42, Feature64Bit, FeatureSlowBTMem,
FeatureFastUAMem]>;
// Westmere is a similar machine to nehalem with some additional features.
// Westmere is the corei3/i5/i7 path from nehalem to sandybridge
def : Proc<"westmere", [FeatureSSE42, Feature64Bit, FeatureSlowBTMem,
FeatureFastUAMem, FeatureAES]>;
// Sandy Bridge does not have FMA
// FIXME: Wikipedia says it does... it should have AES as well.
def : Proc<"sandybridge", [FeatureSSE42, FeatureAVX, Feature64Bit]>;
def : Proc<"k6", [FeatureMMX]>;

View File

@ -129,7 +129,7 @@ bool FPRegKiller::runOnMachineFunction(MachineFunction &MF) {
}
// Finally, if we found any FP code, emit the FP_REG_KILL instruction.
if (ContainsFPCode) {
BuildMI(*MBB, MBBI->getFirstTerminator(), DebugLoc::getUnknownLoc(),
BuildMI(*MBB, MBBI->getFirstTerminator(), DebugLoc(),
MF.getTarget().getInstrInfo()->get(X86::FP_REG_KILL));
++NumFPKill;
Changed = true;

View File

@ -542,7 +542,7 @@ void X86DAGToDAGISel::EmitSpecialCodeForMain(MachineBasicBlock *BB,
MachineFrameInfo *MFI) {
const TargetInstrInfo *TII = TM.getInstrInfo();
if (Subtarget->isTargetCygMing())
BuildMI(BB, DebugLoc::getUnknownLoc(),
BuildMI(BB, DebugLoc(),
TII->get(X86::CALLpcrel32)).addExternalSymbol("__main");
}

View File

@ -1071,18 +1071,21 @@ unsigned X86TargetLowering::getByValTypeAlignment(const Type *Ty) const {
/// If DstAlign is zero that means it's safe to destination alignment can
/// satisfy any constraint. Similarly if SrcAlign is zero it means there
/// isn't a need to check it against alignment requirement, probably because
/// the source does not need to be loaded. It returns EVT::Other if
/// SelectionDAG should be responsible for determining it.
/// the source does not need to be loaded. If 'NonScalarIntSafe' is true, that
/// means it's safe to return a non-scalar-integer type, e.g. constant string
/// source or loaded from memory. It returns EVT::Other if SelectionDAG should
/// be responsible for determining it.
EVT
X86TargetLowering::getOptimalMemOpType(uint64_t Size,
unsigned DstAlign, unsigned SrcAlign,
bool SafeToUseFP,
bool NonScalarIntSafe,
SelectionDAG &DAG) const {
// FIXME: This turns off use of xmm stores for memset/memcpy on targets like
// linux. This is because the stack realignment code can't handle certain
// cases like PR2962. This should be removed when PR2962 is fixed.
const Function *F = DAG.getMachineFunction().getFunction();
if (!F->hasFnAttr(Attribute::NoImplicitFloat)) {
if (NonScalarIntSafe &&
!F->hasFnAttr(Attribute::NoImplicitFloat)) {
if (Size >= 16 &&
(Subtarget->isUnalignedMemAccessFast() ||
((DstAlign == 0 || DstAlign >= 16) &&
@ -1090,10 +1093,9 @@ X86TargetLowering::getOptimalMemOpType(uint64_t Size,
Subtarget->getStackAlignment() >= 16) {
if (Subtarget->hasSSE2())
return MVT::v4i32;
if (SafeToUseFP && Subtarget->hasSSE1())
if (Subtarget->hasSSE1())
return MVT::v4f32;
} else if (SafeToUseFP &&
Size >= 8 &&
} else if (Size >= 8 &&
!Subtarget->is64Bit() &&
Subtarget->getStackAlignment() >= 8 &&
Subtarget->hasSSE2())
@ -1147,8 +1149,7 @@ SDValue X86TargetLowering::getPICJumpTableRelocBase(SDValue Table,
if (!Subtarget->is64Bit())
// This doesn't have DebugLoc associated with it, but is not really the
// same as a Register.
return DAG.getNode(X86ISD::GlobalBaseReg, DebugLoc::getUnknownLoc(),
getPointerTy());
return DAG.getNode(X86ISD::GlobalBaseReg, DebugLoc(), getPointerTy());
return Table;
}
@ -1929,8 +1930,7 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
if (!isTailCall) {
Chain = DAG.getCopyToReg(Chain, dl, X86::EBX,
DAG.getNode(X86ISD::GlobalBaseReg,
DebugLoc::getUnknownLoc(),
getPointerTy()),
DebugLoc(), getPointerTy()),
InFlag);
InFlag = Chain.getValue(1);
} else {
@ -5059,7 +5059,7 @@ X86TargetLowering::LowerConstantPool(SDValue Op, SelectionDAG &DAG) {
if (OpFlag) {
Result = DAG.getNode(ISD::ADD, DL, getPointerTy(),
DAG.getNode(X86ISD::GlobalBaseReg,
DebugLoc::getUnknownLoc(), getPointerTy()),
DebugLoc(), getPointerTy()),
Result);
}
@ -5092,7 +5092,7 @@ SDValue X86TargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) {
if (OpFlag) {
Result = DAG.getNode(ISD::ADD, DL, getPointerTy(),
DAG.getNode(X86ISD::GlobalBaseReg,
DebugLoc::getUnknownLoc(), getPointerTy()),
DebugLoc(), getPointerTy()),
Result);
}
@ -5128,8 +5128,7 @@ X86TargetLowering::LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) {
!Subtarget->is64Bit()) {
Result = DAG.getNode(ISD::ADD, DL, getPointerTy(),
DAG.getNode(X86ISD::GlobalBaseReg,
DebugLoc::getUnknownLoc(),
getPointerTy()),
DebugLoc(), getPointerTy()),
Result);
}
@ -5251,8 +5250,7 @@ LowerToTLSGeneralDynamicModel32(GlobalAddressSDNode *GA, SelectionDAG &DAG,
DebugLoc dl = GA->getDebugLoc(); // ? function entry point might be better
SDValue Chain = DAG.getCopyToReg(DAG.getEntryNode(), dl, X86::EBX,
DAG.getNode(X86ISD::GlobalBaseReg,
DebugLoc::getUnknownLoc(),
PtrVT), InFlag);
DebugLoc(), PtrVT), InFlag);
InFlag = Chain.getValue(1);
return GetTLSADDR(DAG, Chain, GA, &InFlag, PtrVT, X86::EAX, X86II::MO_TLSGD);
@ -5274,7 +5272,7 @@ static SDValue LowerToTLSExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
DebugLoc dl = GA->getDebugLoc();
// Get the Thread Pointer
SDValue Base = DAG.getNode(X86ISD::SegmentBaseAddress,
DebugLoc::getUnknownLoc(), PtrVT,
DebugLoc(), PtrVT,
DAG.getRegister(is64Bit? X86::FS : X86::GS,
MVT::i32));

View File

@ -417,15 +417,19 @@ namespace llvm {
virtual unsigned getByValTypeAlignment(const Type *Ty) const;
/// getOptimalMemOpType - Returns the target specific optimal type for load
/// and store operations as a result of memset, memcpy, and memmove lowering.
/// If DstAlign is zero that means it's safe to destination alignment can
/// satisfy any constraint. Similarly if SrcAlign is zero it means there
/// isn't a need to check it against alignment requirement, probably because
/// the source does not need to be loaded. It returns EVT::Other if
/// SelectionDAG should be responsible for determining it.
virtual EVT getOptimalMemOpType(uint64_t Size,
unsigned DstAlign, unsigned SrcAlign,
bool SafeToUseFP, SelectionDAG &DAG) const;
/// and store operations as a result of memset, memcpy, and memmove
/// lowering. If DstAlign is zero that means it's safe to destination
/// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
/// means there isn't a need to check it against alignment requirement,
/// probably because the source does not need to be loaded. If
/// 'NonScalarIntSafe' is true, that means it's safe to return a
/// non-scalar-integer type, e.g. empty string source, constant, or loaded
/// from memory. It returns EVT::Other if SelectionDAG should be responsible
/// for determining it.
virtual EVT
getOptimalMemOpType(uint64_t Size,
unsigned DstAlign, unsigned SrcAlign,
bool NonScalarIntSafe, SelectionDAG &DAG) const;
/// allowsUnalignedMemoryAccesses - Returns true if the target allows
/// unaligned memory accesses. of the specified type.

View File

@ -311,6 +311,21 @@ class SS42AI<bits<8> o, Format F, dag outs, dag ins, string asm,
: Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, TA,
Requires<[HasSSE42]>;
// AES Instruction Templates:
//
// AES8I
// FIXME: Verify these, they appear to use the same encoding as the SSE4.2 T8
// and TA encodings.
class AES8I<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag>pattern>
: I<o, F, outs, ins, asm, pattern, SSEPackedInt>, T8,
Requires<[HasAES]>;
class AESAI<bits<8> o, Format F, dag outs, dag ins, string asm,
list<dag> pattern>
: Ii8<o, F, outs, ins, asm, pattern, SSEPackedInt>, TA,
Requires<[HasAES]>;
// X86-64 Instruction templates...
//

View File

@ -1803,7 +1803,7 @@ X86InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond) const {
// FIXME this should probably have a DebugLoc operand
DebugLoc dl = DebugLoc::getUnknownLoc();
DebugLoc dl;
// Shouldn't be a fall through.
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
assert((Cond.size() == 1 || Cond.size() == 0) &&
@ -2107,7 +2107,7 @@ void X86InstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
SmallVectorImpl<MachineInstr*> &NewMIs) const {
bool isAligned = (*MMOBegin)->getAlignment() >= 16;
unsigned Opc = getStoreRegOpcode(SrcReg, RC, isAligned, TM);
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc));
for (unsigned i = 0, e = Addr.size(); i != e; ++i)
MIB.addOperand(Addr[i]);
@ -2202,7 +2202,7 @@ void X86InstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
SmallVectorImpl<MachineInstr*> &NewMIs) const {
bool isAligned = (*MMOBegin)->getAlignment() >= 16;
unsigned Opc = getLoadRegOpcode(DestReg, RC, isAligned, TM);
DebugLoc DL = DebugLoc::getUnknownLoc();
DebugLoc DL;
MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg);
for (unsigned i = 0, e = Addr.size(); i != e; ++i)
MIB.addOperand(Addr[i]);

Some files were not shown because too many files have changed in this diff Show More