From vadve at cs.uiuc.edu Mon Nov 25 12:22:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Mon Nov 25 12:22:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200211251821.MAA01426@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.68 -> 1.69 --- Log message: Keep global nodes in each DS Graph (by forcing them to be marked live). --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.68 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.69 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.68 Mon Nov 18 15:44:46 2002 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Mon Nov 25 12:21:25 2002 @@ -997,10 +997,10 @@ // Mark all nodes reachable by (non-global) scalar nodes as alive... for (std::map::iterator I = ScalarMap.begin(), E = ScalarMap.end(); I != E; ++I) - if (!isa(I->first)) // Don't mark globals! + // if (!isa(I->first)) // Don't mark globals! markAlive(I->second.getNode(), Alive); - else // Keep track of global nodes - GlobalNodes.push_back(std::make_pair(I->first, I->second.getNode())); + // else // Keep track of global nodes + // GlobalNodes.push_back(std::make_pair(I->first, I->second.getNode())); // The return value is alive as well... markAlive(RetNode.getNode(), Alive); From lattner at cs.uiuc.edu Tue Nov 26 04:44:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 26 04:44:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200211261043.EAA05322@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.37 -> 1.38 --- Log message: brg InstSelectSimple.cpp: Add some comments that say what I'm going to do for calls and casts. --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.37 llvm/lib/Target/X86/InstSelectSimple.cpp:1.38 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.37 Fri Nov 22 05:07:01 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Tue Nov 26 04:43:30 2002 @@ -363,9 +363,9 @@ } } -void -ISel::visitCallInst (CallInst &CI) -{ +/// visitCallInst - Have to push args and do a procedure call +/// instruction, if the target address is known. +void ISel::visitCallInst (CallInst &CI) { visitInstruction (CI); } @@ -581,9 +581,39 @@ } } +/// visitCastInst - Here we have various kinds of copying with or without +/// sign extension going on. void ISel::visitCastInst (CastInst &CI) { +//> cast larger int to smaller int --> copy least significant byte/word w/ mov? +// +//I'm not really sure what to do with this. We could insert a pseudo-op +//that says take the low X bits of a Y bit register, but for now we can just +//force the value into, say, EAX, then rip out AL or AX. The advantage of +//the former is that the register allocator could use any register it wants, +//but for now this obviously doesn't matter. :) + +// if target type is bool +// Emit Compare +// Emit Set-if-not-zero + +// if size of target type == size of source type +// Emit Mov reg(target) <- reg(source) + +// if size of target type > size of source type +// if both types are integer types +// if source type is signed +// sbyte to short, ushort: Emit movsx 8->16 +// sbyte to int, uint: Emit movsx 8->32 +// short to int, uint: Emit movsx 16->32 +// else if source type is unsigned +// ubyte to short, ushort: Emit movzx 8->16 +// ubyte to int, uint: Emit movzx 8->32 +// ushort to int, uint: Emit movzx 16->32 +// if both types are fp types +// float to double: Emit fstp, fld (???) + visitInstruction (CI); } From vadve at cs.uiuc.edu Wed Nov 27 11:38:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Nov 27 11:38:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/IPModRef.cpp Message-ID: <200211271737.LAA11051@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: IPModRef.cpp updated: 1.10 -> 1.11 --- Log message: (1) Bug fix that was causing nodes with dangling references to be freed. We run removeDeadNodes() on the TD graph up front before using it. (2) Major enhancement to printing of results: now we list the actual objects that are mod/ref instead of just printing the bit vectors. Also an important bug fix in TDDataStructures pass (no change here): clear Mod/Ref bits of callers before inlining into a function. --- Diffs of the changes: Index: llvm/lib/Analysis/IPA/IPModRef.cpp diff -u llvm/lib/Analysis/IPA/IPModRef.cpp:1.10 llvm/lib/Analysis/IPA/IPModRef.cpp:1.11 --- llvm/lib/Analysis/IPA/IPModRef.cpp:1.10 Mon Nov 11 16:23:56 2002 +++ llvm/lib/Analysis/IPA/IPModRef.cpp Wed Nov 27 11:37:46 2002 @@ -8,10 +8,13 @@ #include "llvm/Analysis/DataStructure.h" #include "llvm/Analysis/DSGraph.h" #include "llvm/Module.h" +#include "llvm/Function.h" +#include "llvm/iMemory.h" #include "llvm/iOther.h" #include "Support/Statistic.h" #include "Support/STLExtras.h" #include "Support/StringExtras.h" +#include //---------------------------------------------------------------------------- // Private constants and data @@ -25,10 +28,11 @@ // class ModRefInfo //---------------------------------------------------------------------------- -void ModRefInfo::print(std::ostream &O) const +void ModRefInfo::print(std::ostream &O, + const std::string& sprefix) const { - O << std::endl << "Modified nodes = " << modNodeSet; - O << "Referenced nodes = " << refNodeSet << std::endl; + O << sprefix << "Modified nodes = " << modNodeSet; + O << sprefix << "Referenced nodes = " << refNodeSet; } void ModRefInfo::dump() const @@ -45,15 +49,13 @@ // FunctionModRefInfo::FunctionModRefInfo(const Function& func, IPModRef& ipmro, - const DSGraph& tdg, - const DSGraph& ldg) + DSGraph* tdgClone) : F(func), IPModRefObj(ipmro), - funcTDGraph(tdg), - funcLocalGraph(ldg), - funcModRefInfo(tdg.getGraphSize()) + funcTDGraph(tdgClone), + funcModRefInfo(tdgClone->getGraphSize()) { - for (unsigned i=0, N = funcTDGraph.getGraphSize(); i < N; ++i) - NodeIds[funcTDGraph.getNodes()[i]] = i; + for (unsigned i=0, N = funcTDGraph->getGraphSize(); i < N; ++i) + NodeIds[funcTDGraph->getNodes()[i]] = i; } @@ -65,10 +67,12 @@ // Empty map just to make problems easier to track down callSiteModRefInfo.clear(); + + delete funcTDGraph; } unsigned FunctionModRefInfo::getNodeId(const Value* value) const { - return getNodeId(funcTDGraph.getNodeForValue(const_cast(value)) + return getNodeId(funcTDGraph->getNodeForValue(const_cast(value)) .getNode()); } @@ -82,22 +86,22 @@ { // Mark all nodes in the graph that are marked MOD as being mod // and all those marked REF as being ref. - for (unsigned i = 0, N = funcTDGraph.getGraphSize(); i < N; ++i) + for (unsigned i = 0, N = funcTDGraph->getGraphSize(); i < N; ++i) { - if (funcTDGraph.getNodes()[i]->isModified()) + if (funcTDGraph->getNodes()[i]->isModified()) funcModRefInfo.setNodeIsMod(i); - if (funcTDGraph.getNodes()[i]->isRead()) + if (funcTDGraph->getNodes()[i]->isRead()) funcModRefInfo.setNodeIsRef(i); } - // Compute the Mod/Ref info for all call sites within the function - // Use the Local DSgraph, which includes all the call sites in the - // original program. - const std::vector& callSites = funcLocalGraph.getFunctionCalls(); + // Compute the Mod/Ref info for all call sites within the function. + // The call sites are recorded in the TD graph. + const std::vector& callSites = funcTDGraph->getFunctionCalls(); for (unsigned i = 0, N = callSites.size(); i < N; ++i) computeModRef(callSites[i].getCallInst()); } + // ResolveCallSiteModRefInfo - This method performs the following actions: // // 1. It clones the top-down graph for the current function @@ -113,52 +117,64 @@ // requested information (because the call site calls an external // function or we cannot determine the complete set of functions invoked). // -DSGraph *FunctionModRefInfo::ResolveCallSiteModRefInfo(CallInst &CI, - std::map &NodeMap) { +DSGraph* FunctionModRefInfo::ResolveCallSiteModRefInfo(CallInst &CI, + std::map &NodeMap) +{ + // Step #0: Quick check if we are going to fail anyway: avoid + // all the graph cloning and map copying in steps #1 and #2. + // + if (const Function *F = CI.getCalledFunction()) + { + if (F->isExternal()) + return 0; // We cannot compute Mod/Ref info for this callsite... + } + else + { + // Eventually, should check here if any callee is external. + // For now we are not handling this case anyway. + std::cerr << "IP Mod/Ref indirect call not implemented yet: " + << "Being conservative\n"; + return 0; // We cannot compute Mod/Ref info for this callsite... + } // Step #1: Clone the top-down graph... - DSGraph *Result = new DSGraph(funcTDGraph, NodeMap); + DSGraph *Result = new DSGraph(*funcTDGraph, NodeMap); // Step #2: Clear Mod/Ref information... Result->maskNodeTypes(~(DSNode::Modified | DSNode::Read)); // Step #3: clone the bottom up graphs for the callees into the caller graph - if (const Function *F = CI.getCalledFunction()) { - if (F->isExternal()) { - delete Result; - return 0; // We cannot compute Mod/Ref info for this callsite... - } - - // Build up a DSCallSite for our invocation point here... + if (const Function *F = CI.getCalledFunction()) + { + assert(!F->isExternal()); - // If the call returns a value, make sure to merge the nodes... - DSNodeHandle RetVal; - if (DS::isPointerType(CI.getType())) - RetVal = Result->getNodeForValue(&CI); - - // Populate the arguments list... - std::vector Args; - for (unsigned i = 1, e = CI.getNumOperands(); i != e; ++i) - if (DS::isPointerType(CI.getOperand(i)->getType())) - Args.push_back(Result->getNodeForValue(CI.getOperand(i))); - - // Build the call site... - DSCallSite CS(CI, RetVal, 0, Args); - - // Perform the merging now of the graph for the callee, which will come with - // mod/ref bits set... - Result->mergeInGraph(CS, IPModRefObj.getBUDSGraph(*F), - DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes | - DSGraph::DontCloneAuxCallNodes); + // Build up a DSCallSite for our invocation point here... - } else { - std::cerr << "IP Mod/Ref indirect call not implemented yet: " - << "Being conservative\n"; - delete Result; - return 0; - } + // If the call returns a value, make sure to merge the nodes... + DSNodeHandle RetVal; + if (DS::isPointerType(CI.getType())) + RetVal = Result->getNodeForValue(&CI); + + // Populate the arguments list... + std::vector Args; + for (unsigned i = 1, e = CI.getNumOperands(); i != e; ++i) + if (DS::isPointerType(CI.getOperand(i)->getType())) + Args.push_back(Result->getNodeForValue(CI.getOperand(i))); + + // Build the call site... + DSCallSite CS(CI, RetVal, 0, Args); + + // Perform the merging now of the graph for the callee, which will + // come with mod/ref bits set... + Result->mergeInGraph(CS, IPModRefObj.getBUDSGraph(*F), + DSGraph::StripAllocaBit + | DSGraph::DontCloneCallNodes + | DSGraph::DontCloneAuxCallNodes); + } + else + assert(0 && "See error message"); - // Remove dead nodes... + // Remove dead nodes aggressively to match the caller's original graph. Result->removeDeadNodes(); // Step #4: Return the clone + the mapping (by ref) @@ -174,26 +190,34 @@ FunctionModRefInfo::computeModRef(const CallInst& callInst) { // Allocate the mod/ref info for the call site. Bits automatically cleared. - ModRefInfo* callModRefInfo = new ModRefInfo(funcTDGraph.getGraphSize()); + ModRefInfo* callModRefInfo = new ModRefInfo(funcTDGraph->getGraphSize()); callSiteModRefInfo[&callInst] = callModRefInfo; // Get a copy of the graph for the callee with the callee inlined std::map NodeMap; - DSGraph* csgp = - ResolveCallSiteModRefInfo(const_cast(callInst), NodeMap); - - assert(csgp && "FIXME: Cannot handle case where call site mod/ref info" - " is not available yet!"); + DSGraph* csgp = ResolveCallSiteModRefInfo(const_cast(callInst), + NodeMap); + if (!csgp) + { // Callee's side effects are unknown: mark all nodes Mod and Ref. + // Eventually this should only mark nodes visible to the callee, i.e., + // exclude stack variables not reachable from any outgoing argument + // or any global. + callModRefInfo->getModSet().set(); + callModRefInfo->getRefSet().set(); + return; + } // For all nodes in the graph, extract the mod/ref information const std::vector& csgNodes = csgp->getNodes(); - const std::vector& origNodes = funcTDGraph.getNodes(); + const std::vector& origNodes = funcTDGraph->getNodes(); assert(csgNodes.size() == origNodes.size()); - for (unsigned i=0, N = csgNodes.size(); i < N; ++i) + for (unsigned i=0, N = origNodes.size(); i < N; ++i) { - if (csgNodes[i]->isModified()) + DSNode* csgNode = NodeMap[origNodes[i]].getNode(); + assert(csgNode && "Inlined and original graphs do not correspond!"); + if (csgNode->isModified()) callModRefInfo->setNodeIsMod(getNodeId(origNodes[i])); - if (csgNodes[i]->isRead()) + if (csgNode->isRead()) callModRefInfo->setNodeIsRef(getNodeId(origNodes[i])); } @@ -203,23 +227,118 @@ } +class DSGraphPrintHelper { + const DSGraph& tdGraph; + std::vector > knownValues; // identifiable objects + +public: + /*ctor*/ DSGraphPrintHelper(const FunctionModRefInfo& fmrInfo) + : tdGraph(fmrInfo.getFuncGraph()) + { + knownValues.resize(tdGraph.getGraphSize()); + + // For every identifiable value, save Value pointer in knownValues[i] + for (std::map::const_iterator + I = tdGraph.getScalarMap().begin(), + E = tdGraph.getScalarMap().end(); I != E; ++I) + if (isa(I->first) || + isa(I->first) || + isa(I->first) || + isa(I->first) || + isa(I->first)) + { + unsigned nodeId = fmrInfo.getNodeId(I->second.getNode()); + knownValues[nodeId].push_back(I->first); + } + } + + void printValuesInBitVec(std::ostream &O, const BitSetVector& bv) const + { + assert(bv.size() == knownValues.size()); + + if (bv.none()) + { // No bits are set: just say so and return + O << "\tNONE.\n"; + return; + } + + if (bv.all()) + { // All bits are set: just say so and return + O << "\tALL GRAPH NODES.\n"; + return; + } + + for (unsigned i=0, N=bv.size(); i < N; ++i) + if (bv.test(i)) + { + O << "\tNode# " << i << " : "; + if (! knownValues[i].empty()) + for (unsigned j=0, NV=knownValues[i].size(); j < NV; j++) + { + const Value* V = knownValues[i][j]; + + if (isa(V)) O << "(Global) "; + else if (isa(V)) O << "(Target of FormalParm) "; + else if (isa(V)) O << "(Target of LoadInst ) "; + else if (isa(V)) O << "(Target of AllocaInst) "; + else if (isa(V)) O << "(Target of MallocInst) "; + + if (V->hasName()) O << V->getName(); + else if (isa(V)) O << *V; + else O << "(Value*) 0x" << (void*) V; + + O << std::string((j < NV-1)? "; " : "\n"); + } + else + tdGraph.getNodes()[i]->print(O, /*graph*/ NULL); + } + } +}; + + // Print the results of the pass. // Currently this just prints bit-vectors and is not very readable. // void FunctionModRefInfo::print(std::ostream &O) const { - O << "---------- Mod/ref information for function " - << F.getName() << "---------- \n\n"; + DSGraphPrintHelper DPH(*this); + + O << "========== Mod/ref information for function " + << F.getName() << "========== \n\n"; + + // First: Print Globals and Locals modified anywhere in the function. + // + O << " -----Mod/Ref in the body of function " << F.getName()<< ":\n"; + + O << " --Objects modified in the function body:\n"; + DPH.printValuesInBitVec(O, funcModRefInfo.getModSet()); - O << "Mod/ref info for function body:\n"; - funcModRefInfo.print(O); + O << " --Objects referenced in the function body:\n"; + DPH.printValuesInBitVec(O, funcModRefInfo.getRefSet()); + O << " --Mod and Ref vectors for the nodes listed above:\n"; + funcModRefInfo.print(O, "\t"); + + O << "\n"; + + // Second: Print Globals and Locals modified at each call site in function + // for (std::map::const_iterator CI = callSiteModRefInfo.begin(), CE = callSiteModRefInfo.end(); CI != CE; ++CI) { - O << "Mod/ref info for call site " << CI->first << ":\n"; - CI->second->print(O); + O << " ----Mod/Ref information for call site\n" << CI->first; + + O << " --Objects modified at call site:\n"; + DPH.printValuesInBitVec(O, CI->second->getModSet()); + + O << " --Objects referenced at call site:\n"; + DPH.printValuesInBitVec(O, CI->second->getRefSet()); + + O << " --Mod and Ref vectors for the nodes listed above:\n"; + CI->second->print(O, "\t"); + + O << "\n"; } O << "\n"; @@ -268,11 +387,16 @@ FunctionModRefInfo*& funcInfo = funcToModRefInfoMap[&func]; assert (funcInfo != NULL || computeIfMissing); if (funcInfo == NULL) - { // Create a new FunctionModRefInfo object - funcInfo = new FunctionModRefInfo(func, *this, // inserts into map - getAnalysis().getDSGraph(func), - getAnalysis().getDSGraph(func)); - funcInfo->computeModRef(func); // computes the mod/ref info + { // Create a new FunctionModRefInfo object. + // Clone the top-down graph and remove any dead nodes first, because + // otherwise original and merged graphs will not match. + // The memory for this graph clone will be freed by FunctionModRefInfo. + DSGraph* funcTDGraph = + new DSGraph(getAnalysis().getDSGraph(func)); + funcTDGraph->removeDeadNodes(); + + funcInfo = new FunctionModRefInfo(func, *this, funcTDGraph); //auto-insert + funcInfo->computeModRef(func); // computes the mod/ref info } return *funcInfo; } @@ -298,7 +422,7 @@ void IPModRef::print(std::ostream &O) const { - O << "\n========== Results of Interprocedural Mod/Ref Analysis ==========\n"; + O << "\nRESULTS OF INTERPROCEDURAL MOD/REF ANALYSIS:\n\n"; for (std::map::const_iterator mapI = funcToModRefInfoMap.begin(), mapE = funcToModRefInfoMap.end(); From vadve at cs.uiuc.edu Wed Nov 27 11:40:00 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Nov 27 11:40:00 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/IPModRef.h Message-ID: <200211271739.LAA11065@psmith.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: IPModRef.h updated: 1.6 -> 1.7 --- Log message: No longer need local graph to find call sites. Also some major fixes within IPModRef.cpp. --- Diffs of the changes: Index: llvm/include/llvm/Analysis/IPModRef.h diff -u llvm/include/llvm/Analysis/IPModRef.h:1.6 llvm/include/llvm/Analysis/IPModRef.h:1.7 --- llvm/include/llvm/Analysis/IPModRef.h:1.6 Thu Nov 7 01:11:49 2002 +++ llvm/include/llvm/Analysis/IPModRef.h Wed Nov 27 11:38:56 2002 @@ -96,7 +96,7 @@ BitSetVector& getRefSet() { return refNodeSet; } // Debugging support methods - void print(std::ostream &O) const; + void print(std::ostream &O, const std::string& prefix=std::string("")) const; void dump() const; }; @@ -114,8 +114,7 @@ class FunctionModRefInfo { const Function& F; // The function IPModRef& IPModRefObj; // The IPModRef Object owning this - const DSGraph& funcTDGraph; // Top-down DS graph for function - const DSGraph& funcLocalGraph; // Local DS graph for function + DSGraph* funcTDGraph; // Top-down DS graph for function ModRefInfo funcModRefInfo; // ModRefInfo for the function body std::map callSiteModRefInfo; // ModRefInfo for each callsite @@ -130,15 +129,14 @@ public: /* ctor */ FunctionModRefInfo (const Function& func, - IPModRef& IPModRefObj, - const DSGraph& tdg, - const DSGraph& ldg); + IPModRef& IPModRefObj, + DSGraph* tdgClone); /* dtor */ ~FunctionModRefInfo (); // Identify the function and its relevant DS graph // const Function& getFunction() const { return F; } - const DSGraph& getFuncGraph() const { return funcTDGraph; } + const DSGraph& getFuncGraph() const { return *funcTDGraph; } // Retrieve Mod/Ref results for a single call site and for the function body // From vadve at cs.uiuc.edu Wed Nov 27 11:40:02 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Nov 27 11:40:02 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DSGraph.h Message-ID: <200211271739.LAA11079@psmith.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: DSGraph.h updated: 1.38 -> 1.39 --- Log message: Added flags to CloneFlags to strip/keep Mod/Ref bits when cloning a graph. --- Diffs of the changes: Index: llvm/include/llvm/Analysis/DSGraph.h diff -u llvm/include/llvm/Analysis/DSGraph.h:1.38 llvm/include/llvm/Analysis/DSGraph.h:1.39 --- llvm/include/llvm/Analysis/DSGraph.h:1.38 Sun Nov 10 00:47:35 2002 +++ llvm/include/llvm/Analysis/DSGraph.h Wed Nov 27 11:39:37 2002 @@ -153,6 +153,7 @@ StripAllocaBit = 1 << 0, KeepAllocaBit = 0 << 0, DontCloneCallNodes = 1 << 1, CloneCallNodes = 0 << 0, DontCloneAuxCallNodes = 1 << 2, CloneAuxCallNodes = 0 << 0, + StripModRefBits = 1 << 3, KeepModRefBits = 0 << 0, }; // cloneInto - Clone the specified DSGraph into the current graph, returning From vadve at cs.uiuc.edu Wed Nov 27 11:42:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Nov 27 11:42:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp DataStructure.cpp TopDownClosure.cpp Message-ID: <200211271741.LAA11103@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: BottomUpClosure.cpp updated: 1.45 -> 1.46 DataStructure.cpp updated: 1.69 -> 1.70 TopDownClosure.cpp updated: 1.30 -> 1.31 --- Log message: Fix logical error in TD pass: we should clear Mod/Ref bits of each caller before inlining their graphs into a function. To support this, added flags to CloneFlags to strip/keep Mod/Ref bits. --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.45 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.46 --- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.45 Sun Nov 17 16:16:28 2002 +++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Wed Nov 27 11:41:13 2002 @@ -344,8 +344,9 @@ #endif // Handle self recursion by resolving the arguments and return value - Graph.mergeInGraph(CS, GI, DSGraph::StripAllocaBit | - DSGraph::DontCloneCallNodes); + Graph.mergeInGraph(CS, GI, + DSGraph::KeepModRefBits | + DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes); #if 0 Graph.writeGraphToFile(std::cerr, "bu_" + F.getName() + "_after_" + @@ -424,7 +425,8 @@ << GI.getAuxFunctionCalls().size() << "]\n"); // Handle self recursion by resolving the arguments and return value - Graph.mergeInGraph(CS, GI, DSGraph::StripAllocaBit | + Graph.mergeInGraph(CS, GI, + DSGraph::KeepModRefBits | DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes); } } @@ -508,7 +510,8 @@ << GI.getAuxFunctionCalls().size() << "]\n"); // Handle self recursion by resolving the arguments and return value - Graph.mergeInGraph(CS, GI, DSGraph::StripAllocaBit | + Graph.mergeInGraph(CS, GI, + DSGraph::KeepModRefBits | DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes); if (SCCFunctions.count(Callee)) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.69 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.70 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.69 Mon Nov 25 12:21:25 2002 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Wed Nov 27 11:41:13 2002 @@ -598,9 +598,14 @@ Nodes[i]->remapLinks(OldNodeMap); // Remove alloca markers as specified - if (CloneFlags & StripAllocaBit) + if (CloneFlags & (StripAllocaBit | StripModRefBits)) { + unsigned short clearBits = (CloneFlags & StripAllocaBit + ? DSNode::AllocaNode : 0) + | (CloneFlags & StripModRefBits + ? (DSNode::Modified | DSNode::Read) : 0); for (unsigned i = FN, e = Nodes.size(); i != e; ++i) - Nodes[i]->NodeType &= ~DSNode::AllocaNode; + Nodes[i]->NodeType &= ~clearBits; + } // Copy the value map... and merge all of the global nodes... for (std::map::const_iterator I = G.ScalarMap.begin(), Index: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp diff -u llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.30 llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.31 --- llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.30 Mon Nov 11 15:36:05 2002 +++ llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Wed Nov 27 11:41:13 2002 @@ -100,7 +100,7 @@ const std::vector &CallSites = Graph.getFunctionCalls(); if (CallSites.empty()) { DEBUG(std::cerr << " [TD] No callees for: " << F.getName() << "\n"); - return; // If no call sites, the graph is the same as the BU graph! + return; // If no call sites, there is nothing more to do here } // Loop over all of the call sites, building a multi-map from Callees to @@ -143,9 +143,10 @@ std::map OldValMap; std::map OldNodeMap; CG.cloneInto(Graph, OldValMap, OldNodeMap, + DSGraph::StripModRefBits | DSGraph::KeepAllocaBit | DSGraph::DontCloneCallNodes); OldValMap.clear(); // We don't care about the ValMap - + // Loop over all of the invocation sites of the callee, resolving // arguments to our graph. This loop may iterate multiple times if the // current function calls this callee multiple times with different From vadve at cs.uiuc.edu Wed Nov 27 11:47:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Nov 27 11:47:01 2002 Subject: [llvm-commits] CVS: llvm/include/Support/BitSetVector.h Message-ID: <200211271746.LAA11124@psmith.cs.uiuc.edu> Changes in directory llvm/include/Support: BitSetVector.h updated: 1.2 -> 1.3 --- Log message: Several fixes: (1) Applied patch from Casey to implement iterator::operator= correctly: it should use a pointer, not a reference. (2) Added operators == and !=, and method all(). (3) Important bug fix: excess bits need to be ignored in operations like ==, count(), and all(). We do this by ensuring excess bits in the last bitset are always 0. --- Diffs of the changes: Index: llvm/include/Support/BitSetVector.h diff -u llvm/include/Support/BitSetVector.h:1.2 llvm/include/Support/BitSetVector.h:1.3 --- llvm/include/Support/BitSetVector.h:1.2 Wed Nov 6 12:34:40 2002 +++ llvm/include/Support/BitSetVector.h Wed Nov 27 11:46:38 2002 @@ -36,14 +36,26 @@ class BitSetVector { + // Types used internal to the representation typedef std::bitset bitword; typedef bitword::reference reference; class iterator; + // Data used in the representation std::vector bitsetVec; unsigned maxSize; +private: + // Utility functions for the representation static unsigned NumWords(unsigned Size) { return (Size+WORDSIZE-1)/WORDSIZE;} + static unsigned LastWordSize(unsigned Size) { return Size % WORDSIZE; } + + // Clear the unused bits in the last word. + // The unused bits are the high (WORDSIZE - LastWordSize()) bits + void ClearUnusedBits() { + unsigned long usedBits = (1U << LastWordSize(size())) - 1; + bitsetVec.back() &= bitword(usedBits); + } const bitword& getWord(unsigned i) const { return bitsetVec[i]; } bitword& getWord(unsigned i) { return bitsetVec[i]; } @@ -68,29 +80,42 @@ /// Modifier methods: reset, set for entire set, operator[] for one element. /// void reset() { - for(std::vector::iterator I=bitsetVec.begin(), E=bitsetVec.end(); - I != E; ++I) - I->reset(); + for (unsigned i=0, N = bitsetVec.size(); i < N; ++i) + bitsetVec[i].reset(); } void set() { - for(std::vector::iterator I=bitsetVec.begin(), E=bitsetVec.end(); - I != E; ++I) - I->set(); + for (unsigned i=0, N = bitsetVec.size(); i < N; ++i) // skip last word + bitsetVec[i].set(); + ClearUnusedBits(); } - std::bitset<32>::reference operator[](unsigned n) { + reference operator[](unsigned n) { + assert(n < size() && "BitSetVector: Bit number out of range"); unsigned ndiv = n / WORDSIZE, nmod = n % WORDSIZE; - assert(ndiv < bitsetVec.size() && "BitSetVector: Bit number out of range"); return bitsetVec[ndiv][nmod]; } iterator begin() { return iterator::begin(*this); } iterator end() { return iterator::end(*this); } /// + /// Comparison operations: equal, not equal + /// + bool operator == (const BitSetVector& set2) const { + assert(maxSize == set2.maxSize && "Illegal == comparison"); + for (unsigned i = 0; i < bitsetVec.size(); ++i) + if (getWord(i) != set2.getWord(i)) + return false; + return true; + } + bool operator != (const BitSetVector& set2) const { + return ! (*this == set2); + } + + /// /// Set membership operations: single element, any, none, count /// bool test(unsigned n) const { + assert(n < size() && "BitSetVector: Bit number out of range"); unsigned ndiv = n / WORDSIZE, nmod = n % WORDSIZE; - assert(ndiv < bitsetVec.size() && "BitSetVector: Bit number out of range"); return bitsetVec[ndiv].test(nmod); } bool any() const { @@ -108,6 +133,9 @@ n += bitsetVec[i].count(); return n; } + bool all() const { + return (count() == size()); + } /// /// Set operations: intersection, union, disjoint union, complement. @@ -137,6 +165,7 @@ BitSetVector result(maxSize); for (unsigned i = 0; i < bitsetVec.size(); ++i) (result.getWord(i) = getWord(i)).flip(); + result.ClearUnusedBits(); return result; } @@ -156,12 +185,12 @@ class iterator { unsigned currentBit; unsigned currentWord; - BitSetVector& bitvec; - iterator(unsigned B, unsigned W, BitSetVector _bitvec) - : currentBit(B), currentWord(W), bitvec(_bitvec) { } + BitSetVector* bitvec; + iterator(unsigned B, unsigned W, BitSetVector& _bitvec) + : currentBit(B), currentWord(W), bitvec(&_bitvec) { } public: iterator(BitSetVector& _bitvec) - : currentBit(0), currentWord(0), bitvec(_bitvec) { } + : currentBit(0), currentWord(0), bitvec(&_bitvec) { } iterator(const iterator& I) : currentBit(I.currentBit),currentWord(I.currentWord),bitvec(I.bitvec) { } iterator& operator=(const iterator& I) { @@ -174,13 +203,13 @@ // Increment and decrement operators (pre and post) iterator& operator++() { if (++currentBit == WORDSIZE) - { currentBit = 0; if (currentWord < bitvec.maxSize) ++currentWord; } + { currentBit = 0; if (currentWord < bitvec->maxSize) ++currentWord; } return *this; } iterator& operator--() { if (currentBit == 0) { currentBit = WORDSIZE-1; - currentWord = (currentWord == 0)? bitvec.maxSize : --currentWord; + currentWord = (currentWord == 0)? bitvec->maxSize : --currentWord; } else --currentBit; @@ -191,14 +220,14 @@ // Dereferencing operators reference operator*() { - assert(currentWord < bitvec.maxSize && + assert(currentWord < bitvec->maxSize && "Dereferencing iterator past the end of a BitSetVector"); - return bitvec.getWord(currentWord)[currentBit]; + return bitvec->getWord(currentWord)[currentBit]; } // Comparison operator bool operator==(const iterator& I) { - return (&I.bitvec == &bitvec && + return (I.bitvec == bitvec && I.currentWord == currentWord && I.currentBit == currentBit); } From buschard at cs.uiuc.edu Wed Nov 27 21:12:00 2002 From: buschard at cs.uiuc.edu (Cameron Buschardt) Date: Wed Nov 27 21:12:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/BinInterface/main.cpp salloc.cpp salloc.h sparc9.hp sparcbin.cpp sparcbin.h analyze.cpp analyze.h bitmath.h fvector.h machine.h sparcdis.cpp sparcdis.h BinInterface.cpp BinInterface.h sparc.cpp sparc9.h test1.cpp Message-ID: <200211280311.VAA27649@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/BinInterface: main.cpp added (r1.1) salloc.cpp added (r1.1) salloc.h added (r1.1) sparc9.hp added (r1.1) sparcbin.cpp added (r1.1) sparcbin.h added (r1.1) analyze.cpp updated: 1.3 -> 1.4 analyze.h updated: 1.2 -> 1.3 bitmath.h updated: 1.2 -> 1.3 fvector.h updated: 1.2 -> 1.3 machine.h updated: 1.2 -> 1.3 sparcdis.cpp updated: 1.3 -> 1.4 sparcdis.h updated: 1.2 -> 1.3 BinInterface.cpp (r1.2) removed BinInterface.h (r1.2) removed sparc.cpp (r1.3) removed sparc9.h (r1.5) removed test1.cpp (r1.2) removed --- Log message: --- Diffs of the changes: Index: llvm/lib/Reoptimizer/BinInterface/analyze.cpp diff -u llvm/lib/Reoptimizer/BinInterface/analyze.cpp:1.3 llvm/lib/Reoptimizer/BinInterface/analyze.cpp:1.4 --- llvm/lib/Reoptimizer/BinInterface/analyze.cpp:1.3 Mon Nov 18 16:39:11 2002 +++ llvm/lib/Reoptimizer/BinInterface/analyze.cpp Wed Nov 27 20:19:49 2002 @@ -1,201 +1,324 @@ -//===-----------------------------------------------------------*- C++ -*--===// -// SPARC Instruction Analyzer +//***************************************************************************** +// SPARC Instruction Analysis // -// Implementation of Analysis API +// Analysis API Implementation // -// * Need to add support for register conditional branches +// * Initial implementation +// * Fixed API to handle the special case where RD can be read from +// * Extended API to handle register read/write to G0 differently +// +// TODO: +// * Floating point support is lacking +// * Verify all instructions are supported (double check disasm tool too) // // 2002 Cameron Buschardt -//===----------------------------------------------------------------------===// +//***************************************************************************** #include #include + +#include "sparc9.hp" // SPARC 9 opcode and field definitions +#include "bitmath.h" +#include "analyze.h" // API library #include -#include "sparc9.h" -#include "analyze.h" +// +// Analyze instructions with OP field set to OP_BRANCH +// (note not all of these instructions are branches!) +// unsigned sparc_analyzebr(unsigned instr) { - // look at the OP2 field - if (RD_FLD(instr, INSTR_OP2)==OP2_SETHI) - { - if (RD_FLD(instr, INSTR_RD) == 0) - return 0; // This is the special encoding for NOP - else - return IF_RD; - } - else if (RD_FLD(instr, INSTR_OP2)==OP2_BICC) - { - return IF_RCC | IF_BR; - } - else if (RD_FLD(instr, INSTR_OP2)==OP2_BPR) - return IF_RCC; - else{ - printf("Unknown:OP=0b00 OP2 = 0x%04X\n", RD_FLD(instr, INSTR_OP2)); - assert(0); - return 0; - } + // look at the OP2 field + if (RD_FLD(instr, INSTR_OP2)==OP2_SETHI) + { + // The sethi instruction zeroes the register + // and loads the immediate into bits 10->31 + if (RD_FLD(instr, INSTR_RD) == 0) + return 0; // This is the special encoding for NOP + else + return IF_RD | IF_W_RD; + } + else if (RD_FLD(instr, INSTR_OP2)==OP2_BICC) + { + // Branch on integer condition code + return IF_RCC | IF_BR; + } + else if (RD_FLD(instr, INSTR_OP2)==OP2_BPR) + { + // Branch on integer register with prediction + return IF_RCC | IF_RS1 | IF_R_RS1; + } + else{ + // There are a few opcodes missing from this field, + // if we run into any of them we can add support + // most appear to be systems level instructions + + printf("Unknown:OP=0b00 OP2 = 0x%04X\n", RD_FLD(instr, INSTR_OP2)); + assert(0); + return 0; + } } + +// +// Analyze instructions with OP field set to 2 +// unsigned sparc_analyze_c2(unsigned instr) { - switch(RD_FLD(instr, INSTR_OP3)) - { - case OP3_DONERETRY: - return 0; - - case OP3_FCMP: - case OP3_FPU: - assert(0); - return 0; - - case OP3_FLUSHW: //OP=OP_2 I = 0 - return 0; - - case OP3_FLUSH: //OP=OP_2 RS1 {I=0 -> IF_RS2, I=1->simm13} - if (RD_FLD(instr, INSTR_I) == 0) - return IF_RS1 | IF_RS2; - else - return IF_RS1; - - case OP3_JMPL: //OP=OP_2 RD, IF_RS1 {I=0-> IF_RS2, I=1->SIMM13} - case OP3_ADD: - case OP3_AND: - case OP3_OR: - case OP3_XOR: - case OP3_SUB: - case OP3_ANDN: - case OP3_ORN: - case OP3_XNOR: - case OP3_MULX: - case OP3_SDIVX: - case OP3_UDIVX: - case OP3_SLL: - case OP3_SRL: - case OP3_SRA: - case OP3_SAVE: - case OP3_RETURN: - case OP3_RESTORE: - if (RD_FLD(instr, INSTR_I) == 0) - return IF_RD | IF_RS1 | IF_RS2; - else - return IF_RD | IF_RS1; - - case OP3_ADDC: - case OP3_SUBC: - if (RD_FLD(instr, INSTR_I) == 0) - return IF_RD| IF_RS1 | IF_RS2 | IF_RCC; - else - return IF_RD| IF_RS1 | IF_RCC; - - - - case OP3_XNORcc: - case OP3_ANDNcc: - case OP3_ANDcc: - case OP3_ADDcc: - case OP3_ORcc: - case OP3_ORNcc: - case OP3_SUBcc: - case OP3_XORcc: - if (RD_FLD(instr, INSTR_I) == 0) - return IF_RD | IF_RS1 | IF_RS2 | IF_WCC; - else - return IF_RD | IF_RS1 | IF_WCC; - - case OP3_ADDCcc: - case OP3_SUBCcc: - if (RD_FLD(instr, INSTR_I) == 0) - return IF_RD | IF_RS1 | IF_RS2 | IF_WCC | IF_RCC; - else - return IF_RD | IF_RS1 | IF_WCC | IF_RCC; - - default: - printf("Unknown:OP=0b10 OP3 = 0x%04X\n", RD_FLD(instr, INSTR_OP3)); - assert(0); - - } + switch(RD_FLD(instr, INSTR_OP3)) + { + case OP3_DONERETRY: + assert(0); // This appears to be a system instruction + // either way though it acts like a branch + // and should NOT appear in an trace + return 0; + + case OP3_FCMP: + case OP3_FPU: + assert(0); // TODO: Add support when we do floating point + // support! + return 0; + + case OP3_FLUSHW: //OP=OP_2 I = 0 + return 0; // Flush has no negative side effects + + case OP3_FLUSH: //OP=OP_2 RS1 {I=0 -> IF_RS2, I=1->simm13} + if (RD_FLD(instr, INSTR_I) == 0) + return IF_RS1 | IF_RS2 | IF_R_RS1 | IF_R_RS2; + else + return IF_RS1 | IF_R_RS1; + + case OP3_JMPL: //OP=OP_2 RD, IF_RS1 {I=0-> IF_RS2, I=1->SIMM13} + case OP3_ADD: + case OP3_AND: + case OP3_OR: + case OP3_XOR: + case OP3_SUB: + case OP3_ANDN: + case OP3_ORN: + case OP3_XNOR: + case OP3_MULX: + case OP3_SDIVX: + case OP3_UDIVX: + case OP3_SLL: + case OP3_SRL: + case OP3_SRA: + case OP3_SAVE: + case OP3_RETURN: + case OP3_RESTORE: + if (RD_FLD(instr, INSTR_I) == 0) + return IF_RD | IF_RS1 | IF_RS2 | IF_R_RS1 | IF_R_RS2 | IF_W_RD; + else + return IF_RD | IF_RS1 | IF_W_RD | IF_R_RS1; + + case OP3_ADDC: + case OP3_SUBC: + if (RD_FLD(instr, INSTR_I) == 0) + return IF_RD| IF_RS1 | IF_RS2 | IF_RCC | IF_W_RD | IF_R_RS1 | IF_R_RS2; + else + return IF_RD| IF_RS1 | IF_RCC | IF_W_RD | IF_R_RS1; + + + + case OP3_XNORcc: + case OP3_ANDNcc: + case OP3_ANDcc: + case OP3_ADDcc: + case OP3_ORcc: + case OP3_ORNcc: + case OP3_SUBcc: + case OP3_XORcc: + if (RD_FLD(instr, INSTR_I) == 0) + return IF_RD | IF_RS1 | IF_RS2 | IF_WCC | IF_W_RD | IF_R_RS1 | IF_R_RS2; + else + return IF_RD | IF_RS1 | IF_WCC | IF_W_RD | IF_R_RS1; + + case OP3_ADDCcc: + case OP3_SUBCcc: + if (RD_FLD(instr, INSTR_I) == 0) + return IF_RD | IF_RS1 | IF_RS2 | IF_WCC | IF_RCC | IF_W_RD | IF_R_RS1 | IF_R_RS2; + else + return IF_RD | IF_RS1 | IF_WCC | IF_RCC | IF_W_RD | IF_R_RS1; + + default: + printf("Unknown:OP=0b10 OP3 = 0x%04X\n", RD_FLD(instr, INSTR_OP3)); + assert(0); + + } } unsigned sparc_analyze3(unsigned instr) { - switch(RD_FLD(instr, INSTR_OP3)) - { - //OP=OP_3 RD, IF_RS1 {I=0->IF_RS2, I=1->SIMM13} - case OP3_STB: - case OP3_STH: - case OP3_STW: - case OP3_STX: - case OP3_LDSB: - case OP3_LDSH: - case OP3_LDSW: - case OP3_LDUB: - case OP3_LDUH: - case OP3_LDUW: - case OP3_LDX: - case OP3_LDSTUB: - case OP3_STFA: - case OP3_STDFA: - case OP3_STQFA: - if (RD_FLD(instr, INSTR_I) == 0) - return IF_RD | IF_RS1 | IF_RS2; - else - return IF_RD | IF_RS1; - - case OP3_CASXA: - case OP3_CASA: - return IF_RD | IF_RS1 | IF_RS2; - - case OP3_PREFETCHA: - case OP3_PREFETCH: - if (RD_FLD(instr, INSTR_I) == 0) - return IF_RS1 | IF_RS2; - else - return IF_RS1; + switch(RD_FLD(instr, INSTR_OP3)) + { + //OP=OP_3 RD, IF_RS1 {I=0->IF_RS2, I=1->SIMM13} + // BUG FIX! ST* does not write to RD, rather it reads!! + case OP3_STB: + case OP3_STH: + case OP3_STW: + case OP3_STX: + + if (RD_FLD(instr, INSTR_I) == 0) + return IF_RD | IF_RS1 | IF_RS2 | IF_R_RS1 | IF_R_RS2 | IF_R_RD; + else + return IF_RD | IF_RS1 | IF_R_RS1 | IF_R_RS2 | IF_R_RD; + + case OP3_STFA: + case OP3_STDFA: + case OP3_STQFA: + assert(0); + return 0; + + case OP3_LDSB: + case OP3_LDSH: + case OP3_LDSW: + case OP3_LDUB: + case OP3_LDUH: + case OP3_LDUW: + case OP3_LDX: + case OP3_LDSTUB: + if (RD_FLD(instr, INSTR_I) == 0) + return IF_RD | IF_RS1 | IF_RS2 | IF_W_RD | IF_R_RS1 | IF_R_RS2; + else + return IF_RD | IF_RS1 | IF_W_RD | IF_R_RS1; + + + // compare and exchange r[rd] with value at r[rs1] depending on + // comparison between r[rs1] and r[rs2] + case OP3_CASXA: + case OP3_CASA: + return IF_RD | IF_RS1 | IF_RS2 | IF_W_RD | IF_R_RD | IF_RS1 | IF_RS2; + + // Cache line prefetch instructions + case OP3_PREFETCHA: + case OP3_PREFETCH: + if (RD_FLD(instr, INSTR_I) == 0) + return IF_RS1 | IF_RS2 | IF_R_RS1 | IF_R_RS2; + else + return IF_RS1 | IF_R_RS1; + + default: + printf("Unknown OP_3: OP3 = %08X\n", RD_FLD(instr, INSTR_OP3)); + assert(0); + } +} - default: - printf("Unknown OP_3: OP3 = %08X\n", RD_FLD(instr, INSTR_OP3)); - assert(0); - } +unsigned sparc_analyze_full(unsigned instr) +{ + if (RD_FLD(instr,INSTR_OP)==OP_2) + return sparc_analyze_c2(instr); + else if (RD_FLD(instr,INSTR_OP)==OP_3) + return sparc_analyze3(instr); + else if (RD_FLD(instr,INSTR_OP)==OP_BRANCH) + return sparc_analyzebr(instr); + else + return IF_CALL; // Call instruction not seen as branch + // in that control flow change is transparent + // to trace } unsigned sparc_analyze(unsigned instr) { - if (RD_FLD(instr,INSTR_OP)==OP_2) - return sparc_analyze_c2(instr); - else if (RD_FLD(instr,INSTR_OP)==OP_3) - return sparc_analyze3(instr); - else if (RD_FLD(instr,INSTR_OP)==OP_BRANCH) - return sparc_analyzebr(instr); - else - return 0; + unsigned flags = sparc_analyze_full(instr); + + // validate that none of these registers are R0 if + // they are cancel read or write flags on that field + + if (flags & IF_RS1) + if (!RD_FLD(instr, INSTR_RS1)) + flags &= ~IF_R_RS1; + if (flags & IF_RS2) + if (!RD_FLD(instr, INSTR_RS2)) + flags &= ~IF_R_RS2; + + if (flags & IF_RD) + if (!RD_FLD(instr, INSTR_RD)) + flags &= ~(IF_R_RD | IF_W_RD); + + return flags; } -// returns which register is written to unsigned sparc_getwrites(unsigned mask, unsigned instr) { - if (mask & IF_RD) - return (1 << RD_FLD(instr, INSTR_RD)); - else - return 0; + if (mask & IF_RD) + return (1 << RD_FLD(instr, INSTR_RD)); + else + return 0; } -// returns which registers are read unsigned sparc_getreads (unsigned mask, unsigned instr) { - unsigned m = 0; - - if (mask & IF_RS1) - m |= (1 << RD_FLD(instr, INSTR_RS1)); + unsigned m = 0; + + if (mask & IF_RS1) + m |= (1 << RD_FLD(instr, INSTR_RS1)); - if (mask & IF_RS2) - m |= (1 << RD_FLD(instr, INSTR_RS2)); + if (mask & IF_RS2) + m |= (1 << RD_FLD(instr, INSTR_RS2)); - return m; + return m; } -// bit 0 -> CC READ , bit 1 -> CC write -unsigned sparc_getcc (unsigned mask, unsigned instr) +unsigned sparc_getcc (unsigned mask, unsigned instr) // bit 0 -> CC READ , bit 1 -> CC write { - return (mask & (IF_WCC | IF_RCC)); + return (mask & (IF_WCC | IF_RCC)); +} + +// +// Complete list of instructions that require relocation: +// BPr -> D16LO/D16HI field +// FBfcc -> DISP22 field (deprecated) +// FBPfcc-> DISP19 field +// Bicc -> DISP22 field (deprecated) +// BPcc -> DISP19 field +// CALL -> DISP30 field + +// returns relative branch destination (in instruction words) +signed sparc_getbrdest(unsigned instr) +{ + if (RD_FLD(instr, INSTR_OP)==OP_CALL) + return SIGN_EXTEND(RD_FLD(instr, INSTR_DISP30),30); + else + { + assert(RD_FLD(instr,INSTR_OP)==OP_BRANCH); + switch(RD_FLD(instr, INSTR_OP2)) + { + case OP2_BPR: // D16LO/D16HI + return SIGN_EXTEND(RD_D16(instr), 16); + case OP2_BICC: // DISP22 field + case OP2_FB: // DISP22 field + return SIGN_EXTEND(RD_FLD(instr, INSTR_DISP22), 22); + case OP2_FBP: // DISP19 field + case OP2_BPICC: // DISP19 field + return SIGN_EXTEND(RD_FLD(instr, INSTR_DISP19), 19); + default: + assert(0); + } + + } +} + +unsigned sparc_setbrdest(unsigned instr, signed reladdr) +{ + + if (RD_FLD(instr,INSTR_OP)==OP_CALL) + return MK_FLD(INSTR_OP, OP_CALL) | MK_FLD(INSTR_DISP30, unsigned(reladdr) & 0x3FFFFFFF); + else + { + assert(RD_FLD(instr,INSTR_OP)==OP_BRANCH); + switch(RD_FLD(instr, INSTR_OP2)) + { + case OP2_BPR: // D16LO/D16HI + return RM_FLD(INSTR_D16LO, RM_FLD(INSTR_D16HI, instr)) | MK_FLD(INSTR_D16LO, unsigned(reladdr) & 0x3FFF) | MK_FLD(INSTR_D16HI, (unsigned(reladdr) >> 14) & 3); + + case OP2_BICC: // DISP22 field + case OP2_FB: // DISP22 field + return RM_FLD(INSTR_DISP22, instr) | MK_FLD(INSTR_DISP22, unsigned(reladdr) & 0x003FFFFF); + case OP2_FBP: // DISP19 field + case OP2_BPICC: // DISP19 field + return RM_FLD(INSTR_DISP19, instr) | MK_FLD(INSTR_DISP19, unsigned(reladdr) & 0x0007FFFF); + default: + assert(0); + } + } } Index: llvm/lib/Reoptimizer/BinInterface/analyze.h diff -u llvm/lib/Reoptimizer/BinInterface/analyze.h:1.2 llvm/lib/Reoptimizer/BinInterface/analyze.h:1.3 --- llvm/lib/Reoptimizer/BinInterface/analyze.h:1.2 Tue Nov 12 20:44:48 2002 +++ llvm/lib/Reoptimizer/BinInterface/analyze.h Wed Nov 27 20:19:50 2002 @@ -1,29 +1,53 @@ -//===-----------------------------------------------------------*- C++ -*--===// -// SPARC Instruction Analyzer +//***************************************************************************** +// SPARC Instruction Analysis // -// Definitions of Analysis API +// Analysis API Header +// +// * Initial implementation +// * Fixed API to handle the special case where RD can be read from +// * Extended API to handle register read/write to G0 differently // // 2002 Cameron Buschardt -//===----------------------------------------------------------------------===// +//***************************************************************************** #ifndef __ANALYZE__ #define __ANALYZE__ -#define IF_RS1 1 // READ from RS1 -#define IF_RS2 2 // READ from RS2 -#define IF_RD 4 // WRITE to RC -#define IF_BR 8 // BRANCH -#define IF_WCC 16 // write to condition code -#define IF_RCC 32 // read from condition code -#define IF_USR 64 // first user IF instr -// parse instruction +#define IF_RS1 0x001 // Presence of RS1 field in instruction +#define IF_RS2 0x002 // Presence of RS2 field in instruction +#define IF_RD 0x004 // Presence of RD field in instruction +#define IF_BR 0x008 // BRANCH +#define IF_WCC 0x010 // write to condition code +#define IF_RCC 0x020 // read from condition code +#define IF_W_RD 0x040 // instruction writes rd +#define IF_R_RD 0x080 // instruction reads rd (not exclusive with above) +#define IF_R_RS1 0x100 // reads from RS1 +#define IF_R_RS2 0x200 // reads from RS2 +#define IF_CALL 0x400 // Is call instruction? (affects live registers) +#define IF_USR 0x800 // Later in the code we wish to be able to pack other + // flags along side these when we store them in the + // SSA form. This is the first 'user' flag available + +/* + Important NOTE! + + Since sparc treats register 0 specially - in such a way that + we wish to ignore writes or reads from this register for dataflow + analysis. IF_RS1, IF_RS2, and IF_RD are set independantly of whether + their respective register is 0 HOWEVER the read/write flags before are + turned off if their respective register is 0. + +*/ + +// parse instruction and return IF flags unsigned sparc_analyze(unsigned instr); // use these command to expand the information return by analyze unsigned sparc_getwrites(unsigned mask, unsigned instr); unsigned sparc_getreads (unsigned mask, unsigned instr); -// returns a bitmask containing RCC or WCC -unsigned sparc_getcc (unsigned mask, unsigned instr); +unsigned sparc_getcc (unsigned mask, unsigned instr); // returns a bitmask containing RCC or WCC +unsigned sparc_setbrdest(unsigned instr, signed reladdr); +signed sparc_getbrdest(unsigned instr); -#endif +#endif \ No newline at end of file Index: llvm/lib/Reoptimizer/BinInterface/bitmath.h diff -u llvm/lib/Reoptimizer/BinInterface/bitmath.h:1.2 llvm/lib/Reoptimizer/BinInterface/bitmath.h:1.3 --- llvm/lib/Reoptimizer/BinInterface/bitmath.h:1.2 Wed Nov 13 14:17:52 2002 +++ llvm/lib/Reoptimizer/BinInterface/bitmath.h Wed Nov 27 20:19:51 2002 @@ -1,94 +1,115 @@ -//===-----------------------------------------------------------*- C++ -*--===// -// High Performance Bit Utility Functions +//***************************************************************************** +// +// High Performance Bit Utility Functions // // // 2002 Cameron Buschardt -//===----------------------------------------------------------------------===// +//***************************************************************************** #ifndef __BITMATH_H__ #define __BITMATH_H__ +//********************************* +// Bitfield manipulation Macros +//********************************* +#define FLD_UPPER(FLD_DEF) (1 ? FLD_DEF) +#define FLD_LOWER(FLD_DEF) (0 ? FLD_DEF) +#define MASKBELOW(V) ((1 << V) - 1) +#define MASKEQBELOW(V) ((1 << V) | MASKBELOW(V)) //masks off everything ABOVE +#define RD_FLD(x, FLD) ((x & MASKEQBELOW(FLD_UPPER(FLD))) >> FLD_LOWER(FLD)) +#define MK_FLD(FLD, val) ((val << FLD_LOWER(FLD)) & MASKEQBELOW(FLD_UPPER(FLD))) +#define MASK_FLD(FLD) (MASKEQBELOW(FLD_UPPER(FLD)) & ~MASKBELOW(FLD_LOWER(FLD))) +#define RM_FLD(FLD, val) (val & ~(MASK_FLD(FLD))) + +//********************************** +// Portable sign extend macros +//********************************** +#define SIGN_EXTEND13(x) (x & 0x1000 ? -(-x & 0x1FFF): x) +#define SIGN_EXTEND(x, bits) (x & (1 << (bits-1)) ? -(-x & ((1 << bits)-1)):x) + #define IS_POWER_2(x) !(x & (x-1)) #define LOWEST_BIT(x) x & ~(x & (x-1)) #define UPPER_BITS(x) (x & (x-1)) // Good if expected number of bits set < 4 -inline static int countbits_sparse(unsigned m) //VALIDATED +static int countbits_sparse(unsigned m) //VALIDATED { - int c = 0; - while (m) - { - c++; - m = UPPER_BITS(m); - } - return c; + int c = 0; + while (m) + { + c++; + m = UPPER_BITS(m); + } + return c; } -// base 2 sum of digits -inline static int countbits_dense(unsigned w) //VALIDATED +// base 2 sum of digits (hardwired for 32-bit) +static int countbits_dense(unsigned w) //VALIDATED { - w = (0x55555555 & w) + (0x55555555 & (w >> 1)); - w = (0x33333333 & w) + (0x33333333 & (w >> 2)); - w = (w + (w>>4)) & 0x0f0f0f0f; - w = w + (w>>16); - w = w + (w>>8); - return w&0xFF; + w = (0x55555555 & w) + (0x55555555 & (w >> 1)); + w = (0x33333333 & w) + (0x33333333 & (w >> 2)); + w = (w + (w>>4)) & 0x0f0f0f0f; + w = w + (w>>16); + w = w + (w>>8); + return w&0xFF; } -inline static bool ismod3(unsigned w) //VALIDATED +static bool ismod3(unsigned w) //VALIDATED { - w = (w >> 16) + (w&0xFFFF); - w = (w >> 8) + (w&0xFF); - w = (w >> 4) + (w&0xF); - w = (w >> 2) + (w&0x3); - return (0xB6DB6DB6 >> w) & 1; + w = (w >> 16) + (w&0xFFFF); + w = (w >> 8) + (w&0xFF); + w = (w >> 4) + (w&0xF); + w = (w >> 2) + (w&0x3); + return (0xB6DB6DB6 >> w) & 1; } -inline static int mod3(unsigned w) //VALIDATED +static int mod3(unsigned w) //VALIDATED { - w = (w >> 16) + (w&0xFFFF); - w = (w >> 8) + (w&0xFF); - w = (w >> 4) + (w&0xF); - w = (w >> 2) + (w&0x3); - //use lookuptable - return (0x24924924 >> (w<<1)) & 3; + w = (w >> 16) + (w&0xFFFF); + w = (w >> 8) + (w&0xFF); + w = (w >> 4) + (w&0xF); + w = (w >> 2) + (w&0x3); + //use lookuptable + return (0x24924924 >> (w<<1)) & 3; } -inline static int parity(unsigned w) //VALIDATED +static int parity(unsigned w) //VALIDATED { - w = w >> 16; - w = w >> 8; - w = w >> 4; - w = w >> 2; - w = w >> 1; - return w & 1; + w ^= w >> 16; + w ^= w >> 8; + w ^= w >> 4; + w ^= w >> 2; + w ^= w >> 1; + return w & 1; } -inline static int log2(unsigned w) //VALIDATED +static int log2(unsigned w) //VALIDATED { - int n = 0; + int n = 0; - if (w >> 16) - { - w >>= 16; - n+=16; - } - if (w >> 8) - { - w >>= 8; - n+=8; - } - if (w >> 4) - { - w >>= 4; - n+=4; - } + if (w >> 16) + { + w >>= 16; + n+=16; + } + if (w >> 8) + { + w >>= 8; + n+=8; + } + if (w >> 4) + { + w >>= 4; + n+=4; + } - w <<= 1; - return ((0xFFFFAA50 >> w) & 3)+n; + w <<= 1; + return ((0xFFFFAA50 >> w) & 3)+n; } + + #endif Index: llvm/lib/Reoptimizer/BinInterface/fvector.h diff -u llvm/lib/Reoptimizer/BinInterface/fvector.h:1.2 llvm/lib/Reoptimizer/BinInterface/fvector.h:1.3 --- llvm/lib/Reoptimizer/BinInterface/fvector.h:1.2 Mon Nov 18 16:39:11 2002 +++ llvm/lib/Reoptimizer/BinInterface/fvector.h Wed Nov 27 20:19:51 2002 @@ -4,7 +4,7 @@ // * Implementation of a vector class around // the stack allocator. Couldn't use STL // because I need to support stored the -// pointer to the allocator +// pointer to the allocator stack. // // 2002 Cameron Buschardt //***************************************************************************** @@ -13,16 +13,19 @@ #define __FVECTOR_H__ #include "salloc.h" +#include + template class fvector { T * v_begin; T * v_end; T * v_capacity; - Allocator * alloc; + StackAllocator * alloc; void validate(T * pos) { + assert(alloc); if (pos < v_capacity) return; @@ -31,7 +34,7 @@ if (!ns) ns = 64; else - while (ns < ms) + while (ns < ms) ns *= 2; T * n = (T *)alloc->resize(v_begin, sizeof(T) * ns); @@ -40,9 +43,13 @@ v_begin = n; } + fvector(const fvector &) {} - operator = (const fvector &) {} public: + typedef T * iterator; + + iterator begin() { return v_begin; } + iterator end() { return v_end; } void clear() { if (v_begin) @@ -51,36 +58,57 @@ } unsigned size() { return v_end - v_begin; } - fvector(Allocator * a) + + fvector(StackAllocator * a) { v_begin = v_end = v_capacity = NULL; alloc = a; } + + fvector() + { + v_begin = v_end = v_capacity = NULL; + alloc = NULL; + + } + + void setallocator(StackAllocator * a) + { + assert(!alloc); + alloc = a; + } void sizehint(unsigned v) { if (v_begin) return; - v_begin = (T*)alloc->alloc(sizeof(T) * v); + v_begin = (T*)alloc->alloc(sizeof(T) * v); v_end = v_begin; v_capacity = v_begin + v; } - void push_back(const T & e) { - validate(v_end+1); - *v_end++ = e; + void push_back(const T & e) { + validate(v_end+1); + *v_end++ = e; } - void inc(unsigned amt) + void inc(unsigned amt) // increase size by this amt { validate(v_end + amt); v_end += amt; } + + void resize(unsigned amt) + { + validate(v_begin + amt); + v_end = v_begin + amt; + } - T& operator[] (unsigned n) { return v_begin[n]; } - const T & operator[] (unsigned n) const { return v_begin[n]; } + T& operator[] (unsigned n) { return v_begin[n]; } + const T & operator[] (unsigned n) const { return v_begin[n]; } }; + #endif Index: llvm/lib/Reoptimizer/BinInterface/machine.h diff -u llvm/lib/Reoptimizer/BinInterface/machine.h:1.2 llvm/lib/Reoptimizer/BinInterface/machine.h:1.3 --- llvm/lib/Reoptimizer/BinInterface/machine.h:1.2 Tue Nov 12 20:41:04 2002 +++ llvm/lib/Reoptimizer/BinInterface/machine.h Wed Nov 27 20:19:52 2002 @@ -9,9 +9,7 @@ #define __MACHINE_H__ #define MACHINE_CACHELINE 16 -#define FLIP_ENDIAN32(x) (((x & 255) << 24) \ - | (((x >> 8) & 255) << 16) \ - | (((x >> 16) & 255) << 8) \ - | ((x >> 24) & 255)) +#define FLIP_ENDIAN32(x) (((x & 255) << 24) | (((x >> 8) & 255) << 16) | (((x >> 16) & 255) << 8) | ((x >> 24) & 255)) -#endif + +#endif \ No newline at end of file Index: llvm/lib/Reoptimizer/BinInterface/sparcdis.cpp diff -u llvm/lib/Reoptimizer/BinInterface/sparcdis.cpp:1.3 llvm/lib/Reoptimizer/BinInterface/sparcdis.cpp:1.4 --- llvm/lib/Reoptimizer/BinInterface/sparcdis.cpp:1.3 Wed Nov 13 14:17:52 2002 +++ llvm/lib/Reoptimizer/BinInterface/sparcdis.cpp Wed Nov 27 20:20:37 2002 @@ -1,479 +1,590 @@ -//===-----------------------------------------------------------*- C++ -*--===// -// SPARC Disassembler +//***************************************************************************** +// SPARC Instruction Disassembler // +// Disassembler API Header +// +// * Initial implementation +// * Added support for MOVcc (somehow I missed it?!) +// * Added support for pseudo-disassembly +// ( In the print routine for bin-interface we want +// to be able to print the internal SSA form with +// labels instead of registers. And we wish to +// ommit RD from the view when we are not explicitly +// reading from it) +// +// Todo: +// * On the instructions that don't read from RD +// do not print the label field (we get l-1 when we print) // // 2002 Cameron Buschardt -//===----------------------------------------------------------------------===// +//***************************************************************************** #include #include -#include "sparc9.h" -void sparc_printbr(unsigned instr) +#include "sparc9.hp" // SPARC 9 definitions +#include "bitmath.h" +#include + +void sparc_printbr(unsigned instr, bool labels, int labelrs1, int labelrs2, int labelrd, int labelccf) { - // look at the OP2 field - if (RD_FLD(instr,INSTR_OP2)==OP2_ILLTRAP) { - printf("ILLTRAP .. "); - } else if (RD_FLD(instr, INSTR_OP2)==OP2_SETHI) { - if (RD_FLD(instr, INSTR_RD) == 0) - printf("NOP"); - else - printf("SETHI %%hi(%08X), r%d", - RD_FLD(instr, INSTR_IMM22) << 10, RD_FLD(instr, INSTR_RD)); - } else if (RD_FLD(instr, INSTR_OP2) == OP2_BICC) { - printf("%s disp:%08X",icond_names[RD_FLD(instr, INSTR_COND_H)], - SIGN_EXTEND(RD_FLD(instr,INSTR_DISP22),22)); - } else if (RD_FLD(instr, INSTR_OP2)==OP2_BPR) { - //A, RCOND_H, D16HI, P, RS1, D16LO - printf("P%s%s%s r%d, %06X " , rcond_names[RD_FLD(instr, INSTR_RCOND_H)], - RD_FLD(instr, INSTR_A) ? ",a" : "", - RD_FLD(instr, INSTR_P) ? ",pt" : ",pn", - RD_FLD(instr, INSTR_RS1), - RD_D16(instr) - ); - } else if (RD_FLD(instr, INSTR_OP2)==OP2_FB) { - // cond, A, disp22 - printf("%s%s %08X", fcond_names[RD_FLD(instr, INSTR_COND_H)], - RD_FLD(instr, INSTR_A) ? ",a" : "", - RD_FLD(instr, INSTR_DISP22)); - } else if (RD_FLD(instr, INSTR_OP2)==OP2_FBP) { - // - } else{ - printf("Unknown:OP=0b00 OP2 = 0x%04X", RD_FLD(instr, INSTR_OP2)); - } + // look at the OP2 field + if (RD_FLD(instr,INSTR_OP2)==OP2_ILLTRAP) + printf("ILLTRAP .. "); + else if (RD_FLD(instr, INSTR_OP2)==OP2_SETHI) + { + if (RD_FLD(instr, INSTR_RD) == 0) + printf("NOP"); + else + { + if (!labels) + printf("SETHI %%hi(%08X), r%d", RD_FLD(instr, INSTR_IMM22) << 10, RD_FLD(instr, INSTR_RD)); + else + printf("SETHI %%hi(%08X), l%d", RD_FLD(instr, INSTR_IMM22) << 10, labelrd); + } + } + else if (RD_FLD(instr, INSTR_OP2)==OP2_BICC) + { + printf("%s disp:%08X",icond_names[RD_FLD(instr, INSTR_COND_H)], SIGN_EXTEND(RD_FLD(instr,INSTR_DISP22),22)); + } + else if (RD_FLD(instr, INSTR_OP2)==OP2_BPR) + { + //A, RCOND_H, D16HI, P, RS1, D16LO + if (!labels) + { + printf("P%s%s%s r%d, %06X " , rcond_names[RD_FLD(instr, INSTR_RCOND_H)], + RD_FLD(instr, INSTR_A) ? ",a" : "", + RD_FLD(instr, INSTR_P) ? ",pt" : ",pn", + RD_FLD(instr, INSTR_RS1), + RD_D16(instr) + ); + } + else + { + printf("P%s%s%s l%d, %06X " , rcond_names[RD_FLD(instr, INSTR_RCOND_H)], + RD_FLD(instr, INSTR_A) ? ",a" : "", + RD_FLD(instr, INSTR_P) ? ",pt" : ",pn", + labelrs1, + RD_D16(instr) + ); + } + } + else if (RD_FLD(instr, INSTR_OP2)==OP2_FB) + { + // cond, A, disp22 + printf("%s%s %08X", fcond_names[RD_FLD(instr, INSTR_COND_H)], + RD_FLD(instr, INSTR_A) ? ",a" : "", + RD_FLD(instr, INSTR_DISP22)); + } + else{ + printf("Unknown:OP=0b00 OP2 = 0x%04X", RD_FLD(instr, INSTR_OP2)); + assert(0); + } } -void sparc_printalu(char * basename , unsigned instr) +void sparc_printalu(char * basename , unsigned instr, bool labels, int labelrs1, int labelrs2, int labelrd, int labelccf) { - // OP=OP_2 : RD, OP3, RS1: {I=0 -> RS2 I=1->SIMM13} - if (RD_FLD(instr, INSTR_I)==0) { - printf("%s r%d <- r%d ,r%d",basename, RD_FLD(instr, INSTR_RD), - RD_FLD(instr, INSTR_RS1), RD_FLD(instr, INSTR_RS2)); - } else { - printf("%s r%d <- r%d ,%d",basename, RD_FLD(instr, INSTR_RD), - RD_FLD(instr, INSTR_RS1), - SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13))); - } + // OP=OP_2 : RD, OP3, RS1: {I=0 -> RS2 I=1->SIMM13} + if (RD_FLD(instr, INSTR_I)==0) + { + if (!labels) + printf("%s r%d <- r%d ,r%d",basename, RD_FLD(instr, INSTR_RD),RD_FLD(instr, INSTR_RS1), RD_FLD(instr, INSTR_RS2)); + else + printf("%s l%d <- l%d ,l%d",basename, labelrd,labelrs1, labelrs2); + } + else + { + if (!labels) + printf("%s r%d <- r%d ,%d",basename, RD_FLD(instr, INSTR_RD),RD_FLD(instr, INSTR_RS1), SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13))); + else + printf("%s l%d <- l%d ,%d",basename, labelrd,labelrs1, SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13))); + } } -void sparc_printshf(char * basename, unsigned instr) +void sparc_printshf(char * basename, unsigned instr, bool labels, int labelrs1, int labelrs2, int labelrd, int labelccf) { - // OP=OP_2: RD, OP_3 RS1: - // {I=0 -> X & RS2 ,I=1 -> {X=0 -> SHCNT32 X=1->SHCNT64 }} - if (RD_FLD(instr, INSTR_I)==0) { - printf("%s%d r%d <- r%d, by r%d ", (RD_FLD(instr, INSTR_X)==0 ? 32 : 64), - basename, RD_FLD(instr, INSTR_RD), RD_FLD(instr, INSTR_RS1), - RD_FLD(instr, INSTR_RS2)); - } else { - printf("%s%d r%d <- r%d, by 0x%04X ", basename, - (RD_FLD(instr, INSTR_X)==0 ? 32 : 64), - RD_FLD(instr, INSTR_RD), RD_FLD(instr, INSTR_RS1), - (RD_FLD(instr, INSTR_X)==0 ? RD_FLD(instr, INSTR_SHCNT32) - : RD_FLD(instr, INSTR_SHCNT64)) ); - } + //OP=OP_2: RD, OP_3 RS1: {I=0 -> X & RS2 ,I=1 -> {X=0 -> SHCNT32 X=1->SHCNT64 }} + if (RD_FLD(instr, INSTR_I)==0) + { + if (!labels) + printf("%s%d r%d <- r%d, by r%d ",(RD_FLD(instr, INSTR_X)==0 ? 32 : 64), basename, RD_FLD(instr, INSTR_RD), RD_FLD(instr, INSTR_RS1), RD_FLD(instr, INSTR_RS2)); + else + printf("%s%d l%d <- l%d, by l%d ",(RD_FLD(instr, INSTR_X)==0 ? 32 : 64), basename, labelrd, labelrs1, labelrs2); + } + else + { + if (!labels) + printf("%s%d r%d <- r%d, by 0x%04X ", basename,(RD_FLD(instr, INSTR_X)==0 ? 32 : 64), RD_FLD(instr, INSTR_RD), RD_FLD(instr, INSTR_RS1), (RD_FLD(instr, INSTR_X)==0 ? RD_FLD(instr, INSTR_SHCNT32) : RD_FLD(instr, INSTR_SHCNT64)) ); + else + printf("%s%d l%d <- l%d, by 0x%04X ", basename,(RD_FLD(instr, INSTR_X)==0 ? 32 : 64), labelrd, labelrs1, (RD_FLD(instr, INSTR_X)==0 ? RD_FLD(instr, INSTR_SHCNT32) : RD_FLD(instr, INSTR_SHCNT64)) ); + } + } // Op2 class instructions -void sparc_printfpu(unsigned instr) +void sparc_printfpu(unsigned instr, bool labels, int labelrs1, int labelrs2, int labelrd, int labelccf) { - switch(RD_FLD(instr, INSTR_OPF) &~ OPF_MASK_ON) - { - case OPF_FADDn: - printf("FADDn"); - return; - case OPF_FSUBn: - printf("FSUBn"); - return; - case OPF_FMOVn: - printf("FMOVn"); - return; - case OPF_FNEGn: - printf("FNEGn"); - return; - case OPF_FABSn: - printf("FABSn"); - return; - case OPF_FMULn: - printf("FMULn"); - return; - case OPF_FDIVn: - printf("FDIVn"); - return; - case OPF_FSQRTn: - printf("FSQRTn"); - return; - } - switch (RD_FLD(instr, INSTR_OPF) &~OPF_MASK_TO) - { - case OPF_FxTOt: - printf("FxTOt"); - return; - case OPF_FiTOt: - printf("FiTOt"); - return; - } - - switch(RD_FLD(instr, INSTR_OPF)) - { - case OPF_FsTOx: - printf("OPF_FsTOx"); - return; - case OPF_FsTOi: - printf("OPF_FsTOi"); - return; - case OPF_FsTOd: - printf("OPF_FsTOd"); - return; - case OPF_FsTOq: - printf("OPF_FsTOq"); - return; - case OPF_FdTOx: - printf("OPF_FdTOx"); - return; - case OPF_FdTOi: - printf("OPF_FdTOi"); - return; - case OPF_FqTOx: - printf("OPF_FqTOx"); - return; - case OPF_FdTOs: - printf("OPF_FdTOs"); - return; - case OPF_FdTOq: - printf("OPF_FdTOq"); - return; - case OPF_FqTOi: - printf("OPF_FqTOi"); - return; - case OPF_FqTOs: - printf("OPF_FqTOs"); - return; - case OPF_FqTOd: - printf("OPF_FqTOd"); - return; - case OPF_FsMULd: - printf("OPF_FsMULd"); - return; - case OPF_FdMULq: - printf("OPF_FdMULq"); - return; - } + switch(RD_FLD(instr, INSTR_OPF) &~ OPF_MASK_ON) + { + case OPF_FADDn: + printf("FADDn"); + return; + case OPF_FSUBn: + printf("FSUBn"); + return; + case OPF_FMOVn: + printf("FMOVn"); + return; + case OPF_FNEGn: + printf("FNEGn"); + return; + case OPF_FABSn: + printf("FABSn"); + return; + case OPF_FMULn: + printf("FMULn"); + return; + case OPF_FDIVn: + printf("FDIVn"); + return; + case OPF_FSQRTn: + printf("FSQRTn"); + return; + } + switch (RD_FLD(instr, INSTR_OPF) &~OPF_MASK_TO) + { + case OPF_FxTOt: + printf("FxTOt"); + return; + case OPF_FiTOt: + printf("FiTOt"); + return; + } + + switch(RD_FLD(instr, INSTR_OPF)) + { + case OPF_FsTOx: + printf("OPF_FsTOx"); + return; + case OPF_FsTOi: + printf("OPF_FsTOi"); + return; + case OPF_FsTOd: + printf("OPF_FsTOd"); + return; + case OPF_FsTOq: + printf("OPF_FsTOq"); + return; + case OPF_FdTOx: + printf("OPF_FdTOx"); + return; + case OPF_FdTOi: + printf("OPF_FdTOi"); + return; + case OPF_FqTOx: + printf("OPF_FqTOx"); + return; + case OPF_FdTOs: + printf("OPF_FdTOs"); + return; + case OPF_FdTOq: + printf("OPF_FdTOq"); + return; + case OPF_FqTOi: + printf("OPF_FqTOi"); + return; + case OPF_FqTOs: + printf("OPF_FqTOs"); + return; + case OPF_FqTOd: + printf("OPF_FqTOd"); + return; + case OPF_FsMULd: + printf("OPF_FsMULd"); + return; + case OPF_FdMULq: + printf("OPF_FdMULq"); + return; + } + + assert(0); // we don't know the FPU instruction yet } -void sparc_print2(unsigned instr) +void sparc_print2(unsigned instr, bool labels, int labelrs1, int labelrs2, int labelrd, int labelccf) { - switch(RD_FLD(instr, INSTR_OP3)) - { - case OP3_ADD: - sparc_printalu("ADD", instr); - return; - - case OP3_ADDcc: - sparc_printalu("ADDcc", instr); - return; - - case OP3_ADDC: - sparc_printalu("ADDC", instr); - return; - - case OP3_ADDCcc: - sparc_printalu("ADDCcc", instr); - return; - - case OP3_AND: - sparc_printalu("AND", instr); - return; - - case OP3_ANDcc: - sparc_printalu("ANDcc", instr); - return; - - case OP3_OR: - sparc_printalu("OR", instr); - return; - - case OP3_ORcc: - sparc_printalu("ORcc", instr); - return; - - case OP3_XOR: - sparc_printalu("XOR", instr); - return; - - case OP3_XORcc: - sparc_printalu("XORcc", instr); - return; - - case OP3_SUB: - sparc_printalu("SUB", instr); - return; - - case OP3_SUBcc: - sparc_printalu("SUBcc", instr); - return; - - case OP3_ANDN: - sparc_printalu("ANDN", instr); - return; - - case OP3_ANDNcc: - sparc_printalu("ANDNcc", instr); - return; - - case OP3_ORN: - sparc_printalu("ORN", instr); - return; - - case OP3_ORNcc: - sparc_printalu("ORNcc", instr); - return; - - case OP3_XNOR: - sparc_printalu("XNOR", instr); - return; - - case OP3_XNORcc: - sparc_printalu("XNORcc", instr); - return; - - case OP3_SUBC: - sparc_printalu("SUBC", instr); - return; - - case OP3_SUBCcc: - sparc_printalu("SUBCcc", instr); - return; - - case OP3_MULX: - sparc_printalu("MULX", instr); - return; - - case OP3_SDIVX: - sparc_printalu("SDIVX", instr); - return; - - case OP3_UDIVX: - sparc_printalu("UDIVX", instr); - return; - - case OP3_SLL: - sparc_printshf("SLL",instr); - return; - case OP3_SRL: - sparc_printshf("SRL",instr); - return; - case OP3_SRA: - sparc_printshf("SRA",instr); - return; - - case OP3_DONERETRY: + switch(RD_FLD(instr, INSTR_OP3)) + { + + case OP3_MOVcc: { - if (RD_FLD(instr, INSTR_FCN)==FCN_DONE) - printf("DONE"); - else if (RD_FLD(instr, INSTR_FCN)==FCN_RETRY) - printf("RETRY"); - else - printf("DOH!"); - return; - } + if (RD_FLD(instr, INSTR_I)==0) + printf("mov%s(%s) r%d <- r%d", icond_names[RD_FLD(instr, INSTR_COND_L)], + cc_names[(RD_FLD(instr, INSTR_CC2) << 2) | (RD_FLD(instr, INSTR_MOV_CC1) << 1) | RD_FLD(instr, INSTR_MOV_CC0)], + RD_FLD(instr, INSTR_RD), + RD_FLD(instr, INSTR_RS2)); + else + printf("mov%s(%s) r%d <- %d", icond_names[RD_FLD(instr, INSTR_COND_L)], + cc_names[(RD_FLD(instr, INSTR_CC2) << 2) | (RD_FLD(instr, INSTR_MOV_CC1) << 1) | RD_FLD(instr, INSTR_MOV_CC0)], + RD_FLD(instr, INSTR_RD), + SIGN_EXTEND(RD_FLD(instr, INSTR_SIMM11),11)); + return; + } + + + case OP3_ADD: + sparc_printalu("ADD", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_ADDcc: + sparc_printalu("ADDcc", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_ADDC: + sparc_printalu("ADDC", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_ADDCcc: + sparc_printalu("ADDCcc", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_AND: + sparc_printalu("AND", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_ANDcc: + sparc_printalu("ANDcc", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_OR: + sparc_printalu("OR", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_ORcc: + sparc_printalu("ORcc", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_XOR: + sparc_printalu("XOR", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_XORcc: + sparc_printalu("XORcc", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_SUB: + sparc_printalu("SUB", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_SUBcc: + sparc_printalu("SUBcc", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_ANDN: + sparc_printalu("ANDN", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_ANDNcc: + sparc_printalu("ANDNcc", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_ORN: + sparc_printalu("ORN", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_ORNcc: + sparc_printalu("ORNcc", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_XNOR: + sparc_printalu("XNOR", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_XNORcc: + sparc_printalu("XNORcc", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_SUBC: + sparc_printalu("SUBC", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_SUBCcc: + sparc_printalu("SUBCcc", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_MULX: + sparc_printalu("MULX", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_SDIVX: + sparc_printalu("SDIVX", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_UDIVX: + sparc_printalu("UDIVX", instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_SLL: + sparc_printshf("SLL",instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + case OP3_SRL: + sparc_printshf("SRL",instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + case OP3_SRA: + sparc_printshf("SRA",instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_DONERETRY: + { + if (RD_FLD(instr, INSTR_FCN)==FCN_DONE) + printf("DONE"); + else if (RD_FLD(instr, INSTR_FCN)==FCN_RETRY) + printf("RETRY"); + return; + } + + case OP3_FCMP: + { + unsigned fop_n =RD_FLD(instr, INSTR_OPF) &~ OPF_MASK_ON; + if (fop_n==OPF_FCMPn) + printf("FCMP"); + else if (fop_n==OPF_FCMPEn) + printf("FCMPE"); + return; + } + + case OP3_FPU: + sparc_printfpu(instr, labels, labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_FLUSH: //OP=OP_2 RS1 {I=0 -> rs2, I=1->simm13} + printf("OP3_FLUSH"); + return; + case OP3_FLUSHW: //OP=OP_2 I = 0 + printf("OP3_FLUSHW"); + return; + case OP3_JMPL: //OP=OP_2 RD, RS1 {I=0-> RS2, I=1->SIMM13} + if (RD_FLD(instr, INSTR_I)==0) + { + if (!labels) + printf("JMPL link:r%d, to: r%d+r%d", RD_FLD(instr, INSTR_RD),RD_FLD(instr, INSTR_RS1),RD_FLD(instr, INSTR_RS2) ); + else + printf("JMPL link:l%d, to: l%d+l%d", labelrd,labelrs1,labelrs2 ); + } + else + { + if (!labels) + printf("JMPL link:r%d, to: r%d+%d", RD_FLD(instr, INSTR_RD),RD_FLD(instr, INSTR_RS1),SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)) ); + else + printf("JMPL link:l%d, to: l%d+%d", labelrd,labelrs1,SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)) ); + } + return; + + case OP3_POPC: + printf("POPC ????"); + return; + + case OP3_RETURN: + if (RD_FLD(instr, INSTR_I) == 0) + { + if (!labels) + printf("RETURN r%d + r%d", RD_FLD(instr, INSTR_RS1), RD_FLD(instr, INSTR_RS2)); + else + printf("RETURN l%d + l%d", labelrs1, labelrs2); + } + else + { + if (!labels) + printf("RETURN r%d + %d", RD_FLD(instr, INSTR_RS1), SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13))); + else + printf("RETURN l%d + %d", labelrs1, SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13))); + } + return; + + case OP3_SAVE: + if (RD_FLD(instr, INSTR_I) == 0) + { + if (!labels) + printf("save r%d , r%d, r%d", RD_FLD(instr, INSTR_RS1), RD_FLD(instr, INSTR_RS2), RD_FLD(instr, INSTR_RD)); + else + printf("save l%d , l%d, l%d", labelrs1, labelrs2, labelrd); + } + else + { + if (!labels) + printf("save r%d , %d, r%d", RD_FLD(instr, INSTR_RS1), SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)), RD_FLD(instr, INSTR_RD)); + else + printf("save l%d , %d, l%d", labelrs1, SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)), labelrd); + } + return; + + case OP3_RESTORE: + if (RD_FLD(instr, INSTR_I) == 0) + { + if (!labels) + printf("RESTORE r%d , r%d, r%d", RD_FLD(instr, INSTR_RS1), RD_FLD(instr, INSTR_RS2), RD_FLD(instr, INSTR_RD)); + else + printf("RESTORE l%d , l%d, l%d", labelrs1, labelrs2, labelrd); + } + else + { + if (!labels) + printf("RESTORE r%d , %d, r%d", RD_FLD(instr, INSTR_RS1), SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)), RD_FLD(instr, INSTR_RD)); + else + printf("RESTORE l04%d , %d, l04%d",labelrs1, SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)), labelrd); + + } + return; - case OP3_FCMP: - { - unsigned fop_n =RD_FLD(instr, INSTR_OPF) &~ OPF_MASK_ON; - if (fop_n==OPF_FCMPn) - printf("FCMP"); - else if (fop_n==OPF_FCMPEn) - printf("FCMPE"); - else - printf("DOH!"); - return; - } - case OP3_FPU: - sparc_printfpu(instr); - return; - - case OP3_FLUSH: //OP=OP_2 RS1 {I=0 -> rs2, I=1->simm13} - printf("OP3_FLUSH"); - return; - case OP3_FLUSHW: //OP=OP_2 I = 0 - printf("OP3_FLUSHW"); - return; - case OP3_JMPL: //OP=OP_2 RD, RS1 {I=0-> RS2, I=1->SIMM13} - if (RD_FLD(instr, INSTR_I)==0) - printf("JMPL link:r%d, to: r%d+r%d", RD_FLD(instr, INSTR_RD), - RD_FLD(instr, INSTR_RS1),RD_FLD(instr, INSTR_RS2) ); - else - printf("JMPL link:r%d, to: r%d+%d", RD_FLD(instr, INSTR_RD), - RD_FLD(instr, INSTR_RS1), - SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)) ); - return; - - case OP3_POPC: - printf("POPC ????"); - return; - - case OP3_RETURN: - if (RD_FLD(instr, INSTR_I) == 0) - printf("RETURN r%d + r%d", RD_FLD(instr, INSTR_RS1), - RD_FLD(instr, INSTR_RS2)); - else - printf("RETURN r%d + %d", RD_FLD(instr, INSTR_RS1), - SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13))); - return; - - case OP3_SAVE: - if (RD_FLD(instr, INSTR_I) == 0) - printf("save r%d , r%d, r%d", RD_FLD(instr, INSTR_RS1), - RD_FLD(instr, INSTR_RS2), RD_FLD(instr, INSTR_RD)); - else - printf("save r%d , %d, r%d", RD_FLD(instr, INSTR_RS1), - SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)), - RD_FLD(instr, INSTR_RD)); - return; - - case OP3_RESTORE: - if (RD_FLD(instr, INSTR_I) == 0) - printf("RESTORE r%d , r%d, r%d", RD_FLD(instr, INSTR_RS1), - RD_FLD(instr, INSTR_RS2), RD_FLD(instr, INSTR_RD)); - else - printf("RESTORE r%d , %d, r%d", RD_FLD(instr, INSTR_RS1), - SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13)), - RD_FLD(instr, INSTR_RD)); - return; + } + printf("Unknown:OP=0b10 OP3 = 0x%04X", RD_FLD(instr, INSTR_OP3)); + assert(0); +} - } +void sparc_printldst(char * basename, unsigned instr, bool labels, int labelrs1, int labelrs2, int labelrd , int labelccf) +{ + if (RD_FLD(instr, INSTR_I)==0) + { + if (!labels) + printf("%s r%d <- r%d , r%d", basename,RD_FLD(instr, INSTR_RD), RD_FLD(instr, INSTR_RS1), RD_FLD(instr, INSTR_RS2)); + else + printf("%s l04%d <- l%d , l%d", basename, labelrd, labelrs1, labelrs2); + } + else + { + if (!labels) + printf("%s r%d <- r%d , %d",basename, RD_FLD(instr, INSTR_RD), RD_FLD(instr, INSTR_RS1), SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13))); + else + printf("%s l%d <- l%d, l%d", basename, labelrd, labelrs1,SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13))); + } +} +void sparc_print3(unsigned instr, bool labels, int labelrs1, int labelrs2, int labelrd, int labelccf) +{ +//#define OP3_LDFA 0b110000 //OP=OP_3 RD, Rs1, {I=0->IMM_ASI, RS2 I=1->SIMM13} +//#define OP3_LDDFA 0b110011 //OP=OP_3 RD, Rs1, {I=0->IMM_ASI, RS2 I=1->SIMM13} +//#define OP3_LDQFA 0b110010 //OP=OP_3 RD, Rs1, {I=0->IMM_ASI, RS2 I=1->SIMM13} +//#define OP3_LDSTUB 0b001101 //OP=OP_3 RD, Rs1 {I=0->RS2, I=1->SIMM13} +//#define OP3_LDSTUBA 0b011101 //OP=OP_3 RD, RS1 {I=0->RS2, IMM_ASI, I=1->SIMM13} + switch(RD_FLD(instr, INSTR_OP3)) + { + //OP=OP_3 RD, Rs1 {I=0->RS2, I=1->SIMM13} + case OP3_LDSTUB: + sparc_printldst("LDSTUB", instr,labels,labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_STB: + sparc_printldst("STB", instr,labels,labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_STH: + sparc_printldst("STH", instr,labels,labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_STW: + sparc_printldst("STW", instr,labels,labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_STX: + sparc_printldst("STX", instr,labels,labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_LDSB: + sparc_printldst("LDSB", instr,labels,labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_LDSH: + sparc_printldst("LDSH", instr,labels,labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_LDSW: + sparc_printldst("LDSW", instr,labels,labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_LDUB: + sparc_printldst("LDUB", instr,labels,labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_LDUH: + sparc_printldst("LDUH", instr,labels,labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_LDUW: + sparc_printldst("LDUW", instr,labels,labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_LDX: + sparc_printldst("LDX", instr,labels,labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_CASA: + if (RD_FLD(instr, INSTR_I)==0) + { + if (!labels) + printf("CASA [r%d] %%%d, r%d, r%d", RD_FLD(instr, INSTR_RS1),RD_FLD(instr, INSTR_IMMASI), RD_FLD(instr, INSTR_RS2), RD_FLD(instr, INSTR_RD)); + else + printf("CASA [l%d] %%%d, l%d, l%d", labelrs1,RD_FLD(instr, INSTR_IMMASI), labelrs2, labelrd); + } + else + { + if (!labels) + printf("CASA [r%d] , r%d, r%d", RD_FLD(instr, INSTR_RS1), RD_FLD(instr, INSTR_RS2), RD_FLD(instr, INSTR_RD)); + else + printf("CASA [l%d] , l%d, l%d", labelrs1, labelrs2, labelrd); + } + + sparc_printalu("CASA", instr,labels,labelrs1, labelrs2, labelrd, labelccf); + + return; + + case OP3_CASXA: + sparc_printalu("CASXA", instr,labels,labelrs1, labelrs2, labelrd, labelccf); + return; + case OP3_STFA: + sparc_printalu("STFA",instr,labels,labelrs1, labelrs2, labelrd, labelccf); + return; + case OP3_STDFA: + sparc_printalu("STDFA",instr,labels,labelrs1, labelrs2, labelrd, labelccf); + return; + case OP3_STQFA: + sparc_printalu("STQFA",instr,labels,labelrs1, labelrs2, labelrd, labelccf); + return; + + case OP3_PREFETCH: + printf("PREFETCH ??? "); + return; + + case OP3_PREFETCHA: + printf("PREFETCHA ??? "); + return; + } - printf("Unknown:OP=0b10 OP3 = 0x%04X", RD_FLD(instr, INSTR_OP3)); + printf("Unknown OP_3: OP3 = %08X", RD_FLD(instr, INSTR_OP3)); + assert(0); } -void sparc_printldst(char * basename, unsigned instr) -{ - if (RD_FLD(instr, INSTR_I)==0) - printf("%s r%d <- r%d , r%d", basename, RD_FLD(instr, INSTR_RD), - RD_FLD(instr, INSTR_RS1), RD_FLD(instr, INSTR_RS2)); - else - printf("%s r%d <- r%d , %d",basename, RD_FLD(instr, INSTR_RD), - RD_FLD(instr, INSTR_RS1), - SIGN_EXTEND13(RD_FLD(instr, INSTR_SIMM13))); -} -void sparc_print3(unsigned instr) -{ - //#define OP3_LDFA 0b110000 - //OP=OP_3 RD, Rs1, {I=0->IMM_ASI, RS2 I=1->SIMM13} - - //#define OP3_LDDFA 0b110011 - //OP=OP_3 RD, Rs1, {I=0->IMM_ASI, RS2 I=1->SIMM13} - - //#define OP3_LDQFA 0b110010 - //OP=OP_3 RD, Rs1, {I=0->IMM_ASI, RS2 I=1->SIMM13} - - //#define OP3_LDSTUB 0b001101 - //OP=OP_3 RD, Rs1 {I=0->RS2, I=1->SIMM13} - - //#define OP3_LDSTUBA 0b011101 - //OP=OP_3 RD, RS1 {I=0->RS2, IMM_ASI, I=1->SIMM13} - - switch(RD_FLD(instr, INSTR_OP3)) - { - //OP=OP_3 RD, Rs1 {I=0->RS2, I=1->SIMM13} - case OP3_LDSTUB: - sparc_printldst("LDSTUB", instr); - return; - - case OP3_STB: - sparc_printldst("STB", instr); - return; - - case OP3_STH: - sparc_printldst("STH", instr); - return; - - case OP3_STW: - sparc_printldst("STW", instr); - return; - - case OP3_STX: - sparc_printldst("STX", instr); - return; - - case OP3_LDSB: - sparc_printldst("LDSB", instr); - return; - - case OP3_LDSH: - sparc_printldst("LDSH", instr); - return; - - case OP3_LDSW: - sparc_printldst("LDSW", instr); - return; - - case OP3_LDUB: - sparc_printldst("LDUB", instr); - return; - - case OP3_LDUH: - sparc_printldst("LDUH", instr); - return; - - case OP3_LDUW: - sparc_printldst("LDUW", instr); - return; - - case OP3_LDX: - sparc_printldst("LDX", instr); - return; - - case OP3_CASA: - if (RD_FLD(instr, INSTR_I)==0) - printf("CASA [r%d] %%%d, r%d, r%d", RD_FLD(instr, INSTR_RS1), - RD_FLD(instr, INSTR_IMMASI), RD_FLD(instr, INSTR_RS2), - RD_FLD(instr, INSTR_RD)); - else - printf("CASA [r%d] , r%d, r%d", RD_FLD(instr, INSTR_RS1), - RD_FLD(instr, INSTR_RS2), RD_FLD(instr, INSTR_RD)); - - sparc_printalu("CASA", instr); - - return; - - case OP3_CASXA: - sparc_printalu("CASXA", instr); - return; - case OP3_STFA: - sparc_printalu("STFA",instr); - return; - case OP3_STDFA: - sparc_printalu("STDFA",instr); - return; - case OP3_STQFA: - sparc_printalu("STQFA",instr); - return; - - case OP3_PREFETCH: - printf("PREFETCH ??? "); - return; - - case OP3_PREFETCHA: - printf("PREFETCHA ??? "); - return; - } - printf("Unknown OP_3: OP3 = %08X", RD_FLD(instr, INSTR_OP3)); +void sparc_print_pseudo(unsigned instr, int labelrs1, int labelrs2, int labelrd, int labelccf) +{ + if (RD_FLD(instr,INSTR_OP)==OP_CALL) + printf("CALL disp:+%08X", instr & 0x3FFFFFFF); + else if (RD_FLD(instr,INSTR_OP)==OP_BRANCH) + sparc_printbr(instr,true,labelrs1, labelrs2, labelrd, labelccf); + else if (RD_FLD(instr,INSTR_OP)==OP_2) + sparc_print2(instr,true,labelrs1, labelrs2, labelrd, labelccf); + else if (RD_FLD(instr,INSTR_OP)==OP_3) + sparc_print3(instr,true,labelrs1, labelrs2, labelrd, labelccf); } void sparc_print(unsigned instr) { - printf("(%08X) ", instr); - if (RD_FLD(instr,INSTR_OP)==OP_CALL) - printf("CALL disp:+%08X", instr & 0x3FFFFFFF); - else if (RD_FLD(instr,INSTR_OP)==OP_BRANCH) - sparc_printbr(instr); - else if (RD_FLD(instr,INSTR_OP)==OP_2) - sparc_print2(instr); - else if (RD_FLD(instr,INSTR_OP)==OP_3) - sparc_print3(instr); + if (RD_FLD(instr,INSTR_OP)==OP_CALL) + printf("CALL disp:+%08X", instr & 0x3FFFFFFF); + else if (RD_FLD(instr,INSTR_OP)==OP_BRANCH) + sparc_printbr(instr,false,0, 0, 0, 0); + else if (RD_FLD(instr,INSTR_OP)==OP_2) + sparc_print2(instr,false,0, 0, 0, 0); + else if (RD_FLD(instr,INSTR_OP)==OP_3) + sparc_print3(instr,false,0, 0, 0, 0 ); } Index: llvm/lib/Reoptimizer/BinInterface/sparcdis.h diff -u llvm/lib/Reoptimizer/BinInterface/sparcdis.h:1.2 llvm/lib/Reoptimizer/BinInterface/sparcdis.h:1.3 --- llvm/lib/Reoptimizer/BinInterface/sparcdis.h:1.2 Wed Nov 13 14:17:52 2002 +++ llvm/lib/Reoptimizer/BinInterface/sparcdis.h Wed Nov 27 20:20:42 2002 @@ -1 +1,34 @@ -void sparc_print(unsigned instr); +//***************************************************************************** +// SPARC Instruction Disassembler +// +// Disassembler API Header +// +// * Initial implementation +// * Added support for MOVcc (somehow I missed it?!) +// * Added support for pseudo-disassembly +// ( In the print routine for bin-interface we want +// to be able to print the internal SSA form with +// labels instead of registers. And we wish to +// ommit RD from the view when we are not explicitly +// reading from it) +// +// Todo: +// * On the instructions that don't read from RD +// do not print the label field (we get l-1 when we print) +// +// 2002 Cameron Buschardt +//***************************************************************************** + +#ifndef __SPARCDIS__ +#define __SPARCDIS__ +// Conventional Disassembly. Prints instruction (no newline) +void sparc_print(unsigned instr); + +// Pseudo disasm +// uses the integers in labelrs1, labelrs2, labelrd, and labelccf as +// gen labels for the parameter sources +// instead of printing rxx for rs1, it will print l__labelrs1__ +void sparc_print_pseudo(unsigned instr, int labelrs1, int labelrs2, int labelrd, int labelccf); + + +#endif \ No newline at end of file From brukman at cs.uiuc.edu Wed Nov 27 23:39:00 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Nov 27 23:39:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/BinInterface/Makefile Message-ID: <200211280538.XAA02353@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/BinInterface: Makefile added (r1.1) --- Log message: It's about time BinInterface got a Makefile. Maybe it'll compile one of these days. --- Diffs of the changes: From lattner at cs.uiuc.edu Fri Nov 29 06:03:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Nov 29 06:03:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp X86InstrInfo.def Message-ID: <200211291202.GAA15021@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.38 -> 1.39 X86InstrInfo.def updated: 1.27 -> 1.28 --- Log message: brg InstSelectSimple.cpp: First draft of visitCallInst method, handling int/float args. X86InstrInfo.def: Add entries for CALL with 32-bit pc relative arg, and PUSH with 32-bit reg arg. --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.38 llvm/lib/Target/X86/InstSelectSimple.cpp:1.39 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.38 Tue Nov 26 04:43:30 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Fri Nov 29 06:01:58 2002 @@ -363,10 +363,30 @@ } } -/// visitCallInst - Have to push args and do a procedure call -/// instruction, if the target address is known. -void ISel::visitCallInst (CallInst &CI) { - visitInstruction (CI); +/// visitCallInst - Push args on stack and do a procedure call instruction. +void +ISel::visitCallInst (CallInst & CI) +{ + // Push the arguments on the stack in reverse order, as specified by + // the ABI. + for (unsigned i = CI.getNumOperands (); i >= 1; --i) + { + Value *v = CI.getOperand (i); + unsigned argReg = getReg (v); + switch (getClass (v->getType ())) + { + case cInt: + case cFloat: + BuildMI (BB, X86::PUSHr32, 1).addReg (argReg); + break; + default: + // FIXME + visitInstruction (CI); + break; + } + } + // Emit a CALL instruction with PC-relative displacement. + BuildMI (BB, X86::CALLpcrel32, 1).addPCDisp (CI.getCalledValue ()); } /// visitSimpleBinary - Implement simple binary operators for integral types... Index: llvm/lib/Target/X86/X86InstrInfo.def diff -u llvm/lib/Target/X86/X86InstrInfo.def:1.27 llvm/lib/Target/X86/X86InstrInfo.def:1.28 --- llvm/lib/Target/X86/X86InstrInfo.def:1.27 Thu Nov 21 16:49:46 2002 +++ llvm/lib/Target/X86/X86InstrInfo.def Fri Nov 29 06:01:58 2002 @@ -39,6 +39,7 @@ I(JMP , "jmp", 0xE9, M_BRANCH_FLAG, X86II::Void) // jmp foo I(JNE , "jne", 0x85, M_BRANCH_FLAG, X86II::TB | X86II::Void) I(JE , "je", 0x84, M_BRANCH_FLAG, X86II::TB | X86II::Void) +I(CALLpcrel32 , "call", 0xE8, M_BRANCH_FLAG, X86II::Void) // Misc instructions I(LEAVE , "leave", 0xC9, 0, X86II::RawFrm) // leave @@ -57,6 +58,8 @@ I(MOVrm16 , "movw", 0x89, 0, X86II::MRMDestMem | X86II::Void | // [mem] = R16 89/r X86II::OpSize) I(MOVrm32 , "movl", 0x89, 0, X86II::MRMDestMem | X86II::Void) // [mem] = R32 89/r + +I(PUSHr32 , "pushl", 0x50, 0, X86II::AddRegFrm | X86II::Void) // Arithmetic instructions I(ADDrr8 , "addb", 0x00, 0, X86II::MRMDestReg) // R8 += R8 From lattner at cs.uiuc.edu Sat Nov 30 05:58:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Nov 30 05:58:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200211301157.FAA16846@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.39 -> 1.40 --- Log message: brg InstSelectSimple.cpp: Refactor out conversion of byte, short -> int from visitReturnInst() to new method, promote32(). Use it in both visitReturnInst() and visitCallInst(). --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.39 llvm/lib/Target/X86/InstSelectSimple.cpp:1.40 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.39 Fri Nov 29 06:01:58 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Sat Nov 30 05:57:28 2002 @@ -107,6 +107,7 @@ abort(); } + void promote32 (const unsigned targetReg, Value *v); /// copyConstantToRegister - Output the instructions required to put the /// specified constant into the specified register. @@ -272,6 +273,38 @@ BuildMI (BB, X86::MOVrr8, 1, getReg(I)).addReg(X86::AL); } +/// promote32 - Emit instructions to turn a narrow operand into a 32-bit-wide +/// operand, in the specified target register. +void +ISel::promote32 (const unsigned targetReg, Value *v) +{ + unsigned vReg = getReg (v); + unsigned Class = getClass (v->getType ()); + bool isUnsigned = v->getType ()->isUnsigned (); + assert (((Class == cByte) || (Class == cShort) || (Class == cInt)) + && "Unpromotable operand class in promote32"); + switch (Class) + { + case cByte: + // Extend value into target register (8->32) + if (isUnsigned) + BuildMI (BB, X86::MOVZXr32r8, 1, targetReg).addReg (vReg); + else + BuildMI (BB, X86::MOVSXr32r8, 1, targetReg).addReg (vReg); + break; + case cShort: + // Extend value into target register (16->32) + if (isUnsigned) + BuildMI (BB, X86::MOVZXr32r16, 1, targetReg).addReg (vReg); + else + BuildMI (BB, X86::MOVSXr32r16, 1, targetReg).addReg (vReg); + break; + case cInt: + // Move value into target register (32->32) + BuildMI (BB, X86::MOVrr32, 1, targetReg).addReg (vReg); + break; + } +} /// 'ret' instruction - Here we are interested in meeting the x86 ABI. As such, /// we have the following possibilities: @@ -284,56 +317,43 @@ /// ret long, ulong : Move value into EAX/EDX and return /// ret float/double : Top of FP stack /// -void ISel::visitReturnInst (ReturnInst &I) { - if (I.getNumOperands() == 0) { - // Emit a 'ret' instruction - BuildMI(BB, X86::RET, 0); - return; - } - - unsigned val = getReg(I.getOperand(0)); - unsigned Class = getClass(I.getOperand(0)->getType()); - bool isUnsigned = I.getOperand(0)->getType()->isUnsigned(); - switch (Class) { - case cByte: - // ret sbyte, ubyte: Extend value into EAX and return - if (isUnsigned) - BuildMI (BB, X86::MOVZXr32r8, 1, X86::EAX).addReg (val); - else - BuildMI (BB, X86::MOVSXr32r8, 1, X86::EAX).addReg (val); - break; - case cShort: - // ret short, ushort: Extend value into EAX and return - if (isUnsigned) - BuildMI (BB, X86::MOVZXr32r16, 1, X86::EAX).addReg (val); - else - BuildMI (BB, X86::MOVSXr32r16, 1, X86::EAX).addReg (val); - break; - case cInt: - // ret int, uint, ptr: Move value into EAX and return - // MOV EAX, - BuildMI(BB, X86::MOVrr32, 1, X86::EAX).addReg(val); - break; - - // ret float/double: top of FP stack - // FLD - case cFloat: // Floats - BuildMI(BB, X86::FLDr4, 1).addReg(val); - break; - case cDouble: // Doubles - BuildMI(BB, X86::FLDr8, 1).addReg(val); - break; - case cLong: - // ret long: use EAX(least significant 32 bits)/EDX (most - // significant 32)...uh, I think so Brain, but how do i call - // up the two parts of the value from inside this mouse - // cage? *zort* - default: - visitInstruction(I); - } - +void +ISel::visitReturnInst (ReturnInst &I) +{ + if (I.getNumOperands () == 0) + { + // Emit a 'ret' instruction + BuildMI (BB, X86::RET, 0); + return; + } + Value *rv = I.getOperand (0); + unsigned Class = getClass (rv->getType ()); + switch (Class) + { + // integral return values: extend or move into EAX and return. + case cByte: + case cShort: + case cInt: + promote32 (X86::EAX, rv); + break; + // ret float/double: top of FP stack + // FLD + case cFloat: // Floats + BuildMI (BB, X86::FLDr4, 1).addReg (getReg (rv)); + break; + case cDouble: // Doubles + BuildMI (BB, X86::FLDr8, 1).addReg (getReg (rv)); + break; + case cLong: + // ret long: use EAX(least significant 32 bits)/EDX (most + // significant 32)...uh, I think so Brain, but how do i call + // up the two parts of the value from inside this mouse + // cage? *zort* + default: + visitInstruction (I); + } // Emit a 'ret' instruction - BuildMI(BB, X86::RET, 0); + BuildMI (BB, X86::RET, 0); } /// visitBranchInst - Handle conditional and unconditional branches here. Note @@ -375,6 +395,11 @@ unsigned argReg = getReg (v); switch (getClass (v->getType ())) { + case cByte: + case cShort: + promote32 (X86::EAX, v); + BuildMI (BB, X86::PUSHr32, 1).addReg (X86::EAX); + break; case cInt: case cFloat: BuildMI (BB, X86::PUSHr32, 1).addReg (argReg); From lattner at cs.uiuc.edu Sun Dec 1 17:26:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 1 17:26:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200212012325.RAA24899@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.40 -> 1.41 --- Log message: Don't add implicit regs --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.40 llvm/lib/Target/X86/InstSelectSimple.cpp:1.41 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.40 Sat Nov 30 05:57:28 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Sun Dec 1 17:24:58 2002 @@ -502,7 +502,7 @@ if (isSigned) { // Emit a sign extension instruction... - BuildMI(BB, ExtOpcode[Class], 1, ExtReg).addReg(Reg); + BuildMI(BB, ExtOpcode[Class], 0); } else { // If unsigned, emit a zeroing instruction... (reg = xor reg, reg) BuildMI(BB, ClrOpcode[Class], 2, ExtReg).addReg(ExtReg).addReg(ExtReg); From lattner at cs.uiuc.edu Sun Dec 1 17:27:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 1 17:27:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp X86InstrInfo.def Message-ID: <200212012326.RAA24918@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.17 -> 1.18 X86InstrInfo.def updated: 1.28 -> 1.29 --- Log message: Add rawfrm flags --- Diffs of the changes: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.17 llvm/lib/Target/X86/Printer.cpp:1.18 --- llvm/lib/Target/X86/Printer.cpp:1.17 Thu Nov 21 17:30:00 2002 +++ llvm/lib/Target/X86/Printer.cpp Sun Dec 1 17:25:59 2002 @@ -78,6 +78,10 @@ MO.getType() == MachineOperand::MO_UnextendedImmed; } +static bool isPCRelativeDisp(const MachineOperand &MO) { + return MO.getType() == MachineOperand::MO_PCRelativeDisp; +} + static bool isScale(const MachineOperand &MO) { return isImmediate(MO) && (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 || @@ -105,6 +109,9 @@ case MachineOperand::MO_UnextendedImmed: O << (int)MO.getImmedValue(); return; + case MachineOperand::MO_PCRelativeDisp: + O << "< " << MO.getVRegValue()->getName() << ">"; + return; default: O << ""; return; } @@ -305,13 +312,25 @@ break; case X86II::RawFrm: - toHex(O, getBaseOpcodeFor(Opcode)); + // The accepted forms of Raw instructions are: + // 1. nop - No operand required + // 2. jmp foo - PC relative displacement operand + // + assert(MI->getNumOperands() == 0 || + (MI->getNumOperands() == 1 && isPCRelativeDisp(MI->getOperand(0))) && + "Illegal raw instruction!"); + toHex(O, getBaseOpcodeFor(Opcode)) << " "; + + if (MI->getNumOperands() == 1) { + Value *V = MI->getOperand(0).getVRegValue(); + emitConstant(O, 0, 4); + } + O << "\n\t\t\t\t"; O << getName(MI->getOpCode()) << " "; - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - if (i) O << ", "; - printOp(O, MI->getOperand(i), RI); + if (MI->getNumOperands() == 1) { + printOp(O, MI->getOperand(0), RI); } O << "\n"; return; Index: llvm/lib/Target/X86/X86InstrInfo.def diff -u llvm/lib/Target/X86/X86InstrInfo.def:1.28 llvm/lib/Target/X86/X86InstrInfo.def:1.29 --- llvm/lib/Target/X86/X86InstrInfo.def:1.28 Fri Nov 29 06:01:58 2002 +++ llvm/lib/Target/X86/X86InstrInfo.def Sun Dec 1 17:25:59 2002 @@ -36,9 +36,9 @@ // Flow control instructions I(RET , "ret", 0xCB, M_RET_FLAG, X86II::RawFrm | X86II::Void) // ret -I(JMP , "jmp", 0xE9, M_BRANCH_FLAG, X86II::Void) // jmp foo -I(JNE , "jne", 0x85, M_BRANCH_FLAG, X86II::TB | X86II::Void) -I(JE , "je", 0x84, M_BRANCH_FLAG, X86II::TB | X86II::Void) +I(JMP , "jmp", 0xE9, M_BRANCH_FLAG, X86II::RawFrm | X86II::Void) // jmp foo +I(JNE , "jne", 0x85, M_BRANCH_FLAG, X86II::RawFrm | X86II::TB | X86II::Void) +I(JE , "je", 0x84, M_BRANCH_FLAG, X86II::RawFrm | X86II::TB | X86II::Void) I(CALLpcrel32 , "call", 0xE8, M_BRANCH_FLAG, X86II::Void) // Misc instructions From lattner at cs.uiuc.edu Sun Dec 1 19:20:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 1 19:20:01 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/ Message-ID: <200212020119.TAA25865@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/utils/TableGen added to the repository --- Diffs of the changes: From lattner at cs.uiuc.edu Sun Dec 1 19:22:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 1 19:22:00 2002 Subject: [llvm-commits] CVS: llvm/utils/Makefile Message-ID: <200212020121.TAA26037@apoc.cs.uiuc.edu> Changes in directory llvm/utils: Makefile added (r1.1) --- Log message: Add makefile to build subdirs --- Diffs of the changes: From lattner at cs.uiuc.edu Sun Dec 1 19:24:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 1 19:24:01 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileLexer.l FileParser.y Makefile Record.cpp Record.h TableGen.cpp Message-ID: <200212020123.TAA26179@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileLexer.l added (r1.1) FileParser.y added (r1.1) Makefile added (r1.1) Record.cpp added (r1.1) Record.h added (r1.1) TableGen.cpp added (r1.1) --- Log message: Initial checkin of TableGen utility --- Diffs of the changes: From lattner at cs.uiuc.edu Sun Dec 1 19:24:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 1 19:24:03 2002 Subject: [llvm-commits] CVS: llvm/Makefile Message-ID: <200212020123.TAA26188@apoc.cs.uiuc.edu> Changes in directory llvm: Makefile updated: 1.2 -> 1.3 --- Log message: Make sure to build lib/Support before the utilities, then use the new makefile in utils to build the utilities --- Diffs of the changes: Index: llvm/Makefile diff -u llvm/Makefile:1.2 llvm/Makefile:1.3 --- llvm/Makefile:1.2 Tue Sep 17 18:23:52 2002 +++ llvm/Makefile Sun Dec 1 19:23:26 2002 @@ -1,5 +1,5 @@ LEVEL = . -DIRS = utils/Burg lib tools +DIRS = lib/Support utils lib tools include $(LEVEL)/Makefile.common