Update LLVM to r100285.
This commit is contained in:
parent
104bd8179f
commit
b5efedaf2a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/llvm/dist/; revision=206124
@ -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)
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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; }
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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; }
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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.
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
|
||||
|
@ -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]>;
|
||||
}
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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();
|
||||
|
@ -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 */
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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()) {
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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';
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -27,6 +27,7 @@ add_llvm_library(LLVMCodeGen
|
||||
MachineFunction.cpp
|
||||
MachineFunctionAnalysis.cpp
|
||||
MachineFunctionPass.cpp
|
||||
MachineFunctionPrinterPass.cpp
|
||||
MachineInstr.cpp
|
||||
MachineLICM.cpp
|
||||
MachineLoopInfo.cpp
|
||||
|
@ -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))
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
60
lib/CodeGen/MachineFunctionPrinterPass.cpp
Normal file
60
lib/CodeGen/MachineFunctionPrinterPass.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
@ -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";
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/DebugLoc.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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: {
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
532
lib/Target/ARM/Disassembler/ARMDisassembler.cpp
Normal file
532
lib/Target/ARM/Disassembler/ARMDisassembler.cpp
Normal 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
|
91
lib/Target/ARM/Disassembler/ARMDisassembler.h
Normal file
91
lib/Target/ARM/Disassembler/ARMDisassembler.h
Normal 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 ®ion,
|
||||
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 ®ion,
|
||||
uint64_t address,
|
||||
raw_ostream &vStream) const;
|
||||
private:
|
||||
Session SO;
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
3252
lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
Normal file
3252
lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
Normal file
File diff suppressed because it is too large
Load Diff
248
lib/Target/ARM/Disassembler/ARMDisassemblerCore.h
Normal file
248
lib/Target/ARM/Disassembler/ARMDisassemblerCore.h
Normal 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
|
16
lib/Target/ARM/Disassembler/Makefile
Normal file
16
lib/Target/ARM/Disassembler/Makefile
Normal 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
|
2187
lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
Normal file
2187
lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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) &&
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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) &&
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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 ||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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]>;
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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...
|
||||
//
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user