Fixes compile error and Merge branch 'Defensive' of ssh://coriander.cs.wisc.edu/u...
[dyninst.git] / dyninstAPI / src / ast.C
1 /*
2  * Copyright (c) 1996-2011 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 // $Id: ast.C,v 1.209 2008/09/15 18:37:49 jaw Exp $
33
34 #include "dyninstAPI/src/symtab.h"
35 #include "dyninstAPI/src/function.h"
36 #include "dyninstAPI/src/process.h"
37 #include "dyninstAPI/src/inst.h"
38 #include "dyninstAPI/src/instP.h"
39 #include "dyninstAPI/src/instPoint.h"
40 #include "dyninstAPI/src/ast.h"
41 #include "dyninstAPI/src/util.h"
42 #include "dyninstAPI/src/debug.h"
43
44 extern int dyn_debug_ast;
45
46
47
48 #include "Instruction.h"
49 using namespace Dyninst::InstructionAPI;
50
51 #include "dyninstAPI/h/BPatch.h"
52 #include "dyninstAPI/src/BPatch_collections.h"
53 #include "dyninstAPI/h/BPatch_type.h"
54 #include "dyninstAPI/src/BPatch_libInfo.h" // For instPoint->BPatch_point mapping
55
56 #include "dyninstAPI/h/BPatch_point.h"
57 #include "dyninstAPI/h/BPatch_memoryAccess_NP.h"
58 #include "dyninstAPI/h/BPatch_type.h"
59
60 #include "dyninstAPI/src/addressSpace.h"
61 #include "dyninstAPI/src/binaryEdit.h"
62
63 #if defined(arch_power)
64 #include "dyninstAPI/src/inst-power.h"
65 #elif defined(arch_x86) || defined (arch_x86_64)
66 #include "dyninstAPI/src/inst-x86.h"
67 extern int tramp_pre_frame_size_32;
68 extern int tramp_pre_frame_size_64;
69 #else
70 #error "Unknown architecture in ast.h"
71 #endif
72
73 #include "emitter.h"
74
75 #include "registerSpace.h"
76 #include "mapped_module.h"
77
78 #include "legacy-instruction.h"
79 #include "mapped_object.h"
80
81 using namespace Dyninst;
82
83 extern bool doNotOverflow(int value);
84
85 AstNodePtr AstNode::originalAddrNode_ = AstNodePtr();
86 AstNodePtr AstNode::actualAddrNode_ = AstNodePtr();
87 AstNodePtr AstNode::dynamicTargetNode_ = AstNodePtr();
88
89 AstNode::AstNode() {
90 #if defined(ASTDEBUG)
91    ASTcounter();
92 #endif
93
94 //   dyn_debug_ast = 0;
95    referenceCount = 0;
96    useCount = 0;
97    // "operands" is left as an empty vector
98    size = 4;
99    bptype = NULL;
100    doTypeCheck = true;
101    lineNum = 0;
102    columnNum = 0;
103    lineInfoSet = false;
104    columnInfoSet = false;
105 }
106
107 //The following methods are for error reporting in dynC_API
108
109 // Returns the line number at which the ast was declared
110 int AstNode::getLineNum(){
111    return lineNum;
112 }
113
114 // Sets the line number at which the ast was declared
115 void AstNode::setLineNum(int ln){
116    lineInfoSet = true;
117    lineNum = ln;
118 }
119
120 // Returns the column number at which the ast was declared
121 int AstNode::getColumnNum(){
122    return columnNum;
123 }
124
125 // Sets the column number at which the ast was declared
126 void AstNode::setColumnNum(int cn){
127    columnInfoSet = true;
128    columnNum = cn;
129 }
130
131 char * AstNode::getSnippetName(){
132    return snippetName;
133 }
134
135 void AstNode::setSnippetName(char *n){
136    if(n != NULL){
137 //      printf(":::%s\n", n);
138       snippetName = n;
139       snippetNameSet = true;
140    }
141 }
142
143 bool AstNode::hasLineInfo(){
144    return lineInfoSet;
145 }
146
147
148 bool AstNode::hasColumnInfo(){
149    return columnInfoSet;
150 }
151
152 bool AstNode::hasNameInfo(){
153    return snippetNameSet;
154 }
155
156 //////////////////////////////////////////////////////
157
158 AstNodePtr AstNode::nullNode() {
159     return AstNodePtr(new AstNullNode());
160 }
161
162 AstNodePtr AstNode::labelNode(std::string &label) {
163     return AstNodePtr (new AstLabelNode(label));
164 }
165
166 AstNodePtr AstNode::operandNode(operandType ot, void *arg) {
167     return AstNodePtr(new AstOperandNode(ot, arg));
168 }
169
170 // TODO: this is an indirect load; should be an operator.
171 AstNodePtr AstNode::operandNode(operandType ot, AstNodePtr ast) {
172     return AstNodePtr(new AstOperandNode(ot, ast));
173 }
174
175 AstNodePtr AstNode::operandNode(operandType ot, const image_variable* iv) {
176     return AstNodePtr(new AstOperandNode(ot, iv));
177 }
178
179 AstNodePtr AstNode::sequenceNode(pdvector<AstNodePtr > &sequence) {
180 //    assert(sequence.size());
181     return AstNodePtr(new AstSequenceNode(sequence));
182 }
183
184 AstNodePtr AstNode::variableNode(vector<AstNodePtr> &ast_wrappers, 
185                                  vector<pair<Offset, Offset> >*ranges) {
186     return AstNodePtr(new AstVariableNode(ast_wrappers, ranges));
187 }
188
189 AstNodePtr AstNode::operatorNode(opCode ot, AstNodePtr l, AstNodePtr r, AstNodePtr e) {
190     return AstNodePtr(new AstOperatorNode(ot, l, r, e));
191 }
192
193 AstNodePtr AstNode::funcCallNode(const std::string &func, pdvector<AstNodePtr > &args,
194       AddressSpace *addrSpace) 
195 {
196    if (addrSpace) 
197    {
198       func_instance *ifunc = addrSpace->findOnlyOneFunction(func.c_str());
199
200       if (ifunc == NULL) 
201       {
202          fprintf(stderr, "Bitch whine moan\n"); 
203          fprintf(stderr, "%s[%d]: Can't find function %s\n", FILE__, __LINE__, func.c_str());
204          return AstNodePtr();
205       }
206
207       return AstNodePtr(new AstCallNode(ifunc, args));
208    }
209    else
210       return AstNodePtr(new AstCallNode(func, args));
211 }
212
213 AstNodePtr AstNode::funcCallNode(func_instance *func, pdvector<AstNodePtr > &args) {
214     if (func == NULL) return AstNodePtr();
215     return AstNodePtr(new AstCallNode(func, args));
216 }
217
218 AstNodePtr AstNode::funcCallNode(func_instance *func) {
219     if (func == NULL) return AstNodePtr();
220     return AstNodePtr(new AstCallNode(func));
221 }
222
223 AstNodePtr AstNode::funcCallNode(Address addr, pdvector<AstNodePtr > &args) {
224     return AstNodePtr(new AstCallNode(addr, args));
225 }
226
227 AstNodePtr AstNode::memoryNode(memoryType ma, int which) {
228     return AstNodePtr(new AstMemoryNode(ma, which));
229 }
230
231 AstNodePtr AstNode::miniTrampNode(AstNodePtr tramp) {
232     if (tramp == NULL) return AstNodePtr();
233     return AstNodePtr(new AstMiniTrampNode(tramp));
234 }
235
236 AstNodePtr AstNode::insnNode(BPatch_instruction *insn) {
237     // Figure out what kind of instruction we've got...
238     if (dynamic_cast<BPatch_memoryAccess *>(insn)) {
239         return AstNodePtr(new AstInsnMemoryNode(insn->insn()->insn(), (Address) insn->getAddress()));
240     } 
241     
242     return AstNodePtr(new AstInsnNode(insn->insn()->insn(), (Address) insn->getAddress()));
243 }
244
245 AstNodePtr AstNode::originalAddrNode() {
246     if (originalAddrNode_ == NULL) {
247         originalAddrNode_ = AstNodePtr(new AstOriginalAddrNode());
248     }
249     return originalAddrNode_;
250 }
251
252 AstNodePtr AstNode::actualAddrNode() {
253     if (actualAddrNode_ == NULL) {
254         actualAddrNode_ = AstNodePtr(new AstActualAddrNode());
255     }
256     return actualAddrNode_;
257 }
258
259 AstNodePtr AstNode::dynamicTargetNode() {
260     if (dynamicTargetNode_ == NULL) {
261         dynamicTargetNode_ = AstNodePtr(new AstDynamicTargetNode());
262     }
263     return dynamicTargetNode_;
264 }
265
266
267 bool isPowerOf2(int value, int &result)
268 {
269   if (value<=0) return(false);
270   if (value==1) {
271     result=0;
272     return(true);
273   }
274   if ((value%2)!=0) return(false);
275   if (isPowerOf2(value/2,result)) {
276     result++;
277     return(true);
278   }
279   else return(false);
280 }
281
282 BPatch_type *AstNode::getType() { return bptype; }
283
284 void AstNode::setType(BPatch_type *t) { 
285     bptype = t;
286     if (t != NULL) { 
287         size = t->getSize(); 
288     }
289 }
290
291 AstOperatorNode::AstOperatorNode(opCode opC, AstNodePtr l, AstNodePtr r, AstNodePtr e) :
292     AstNode(),
293     op(opC),
294     loperand(l),
295     roperand(r),
296     eoperand(e)
297 {
298     // Optimization pass...
299     
300     if (op == plusOp) {
301         if (loperand->getoType() == Constant) {
302             // Swap left and right...
303             AstNodePtr temp = loperand;
304             loperand = roperand;
305             roperand = temp;
306         }
307     }
308     if (op == timesOp) {
309         if (roperand->getoType() == undefOperandType) {
310             // ...
311        }
312         else if (roperand->getoType() != Constant) {
313             AstNodePtr temp = roperand;
314             roperand = loperand;
315             loperand = temp;
316         }
317         else {
318             int result;
319             if (!isPowerOf2((Address)roperand->getOValue(),result) &&
320                 isPowerOf2((Address)loperand->getOValue(),result)) {
321                 AstNodePtr temp = roperand;
322                 roperand = loperand;
323                 loperand = temp;
324             }
325         }
326     }
327     if (l != AstNodePtr())
328     {
329        //Unfortunate hack.  storeOp with a loperand of DataIndir
330        // don't actually reference their loperand--they reference
331        // the child of the loperand.  Handle that here to keep
332        // reference counts sane.
333        if (op == storeOp && loperand->getoType() == DataIndir)
334           l->operand()->referenceCount++;
335        else
336           l->referenceCount++;
337     }
338     if (r != AstNodePtr())
339        r->referenceCount++;
340     if (e != AstNodePtr())
341        e->referenceCount++;
342 };
343
344     // Direct operand
345 AstOperandNode::AstOperandNode(operandType ot, void *arg) :
346     AstNode(),
347     oType(ot),
348     oVar(NULL),
349     operand_()
350 {
351     
352     if (ot == ConstantString)
353         oValue = (void *)P_strdup((char *)arg);
354     else
355         oValue = (void *) arg;
356 }
357
358 // And an indirect (say, a load)
359 AstOperandNode::AstOperandNode(operandType ot, AstNodePtr l) :
360     AstNode(),
361     oType(ot),
362     oValue(NULL),
363     oVar(NULL),
364     operand_(l)
365 {
366    l->referenceCount++;
367 }
368
369 AstOperandNode::AstOperandNode(operandType ot, const image_variable* iv) :
370   AstNode(),
371   oType(ot),
372   oValue(NULL),
373   oVar(iv),
374   operand_()
375 {
376   assert(oVar);
377 }
378
379
380 AstCallNode::AstCallNode(func_instance *func,
381                          pdvector<AstNodePtr > &args) :
382     AstNode(),
383     func_addr_(0),
384     func_(func),
385     callReplace_(false),
386     constFunc_(false)
387 {
388     for (unsigned i = 0; i < args.size(); i++) {
389         args[i]->referenceCount++; 
390         args_.push_back(args[i]);
391     }
392 }
393
394 AstCallNode::AstCallNode(func_instance *func) :
395     AstNode(),
396     func_addr_(0),
397     func_(func),
398     callReplace_(true),
399     constFunc_(false)
400 {
401 }
402
403 AstCallNode::AstCallNode(const std::string &func,
404                          pdvector<AstNodePtr > &args) :
405     AstNode(),
406     func_name_(func),
407     func_addr_(0),
408     func_(NULL),
409     callReplace_(false),
410     constFunc_(false)
411 {
412     for (unsigned i = 0; i < args.size(); i++) {
413         args[i]->referenceCount++; 
414         args_.push_back(args[i]);
415     }
416 }
417
418 AstCallNode::AstCallNode(Address addr,
419                          pdvector<AstNodePtr > &args) :
420     AstNode(),
421     func_addr_(addr),
422     func_(NULL),
423     callReplace_(false),
424     constFunc_(false)
425 {
426     for (unsigned i = 0; i < args.size(); i++) {
427         args[i]->referenceCount++; 
428         args_.push_back(args[i]);
429     }
430 }
431  
432 AstSequenceNode::AstSequenceNode(pdvector<AstNodePtr > &sequence) :
433     AstNode()
434 {
435     for (unsigned i = 0; i < sequence.size(); i++) {
436         sequence[i]->referenceCount++;
437         sequence_.push_back(sequence[i]);
438     }
439 }
440
441 AstVariableNode::AstVariableNode(vector<AstNodePtr>&ast_wrappers, vector<pair<Offset, Offset> > *ranges) :
442     ast_wrappers_(ast_wrappers), ranges_(ranges), index(0)
443 {
444    vector<AstNodePtr>::iterator i;
445    for (i = ast_wrappers.begin(); i != ast_wrappers.end(); i++) {
446       (*i)->referenceCount++;
447    }
448 }
449
450 AstInsnNode::AstInsnNode(instruction *insn, Address addr) :
451     AstNode(),
452     insn_(insn),
453     origAddr_(addr) {
454 }
455
456 AstMemoryNode::AstMemoryNode(memoryType mem,
457                              unsigned which) :
458     AstNode(),
459     mem_(mem),
460     which_(which) {
461     
462     assert(BPatch::bpatch != NULL);
463     assert(BPatch::bpatch->stdTypes != NULL);
464
465     
466     switch(mem_) {
467     case EffectiveAddr:
468         bptype = BPatch::bpatch->stdTypes->findType("void *");
469         break;
470     case BytesAccessed:
471         bptype = BPatch::bpatch->stdTypes->findType("int");
472         break;
473     default:
474         assert(!"Naah...");
475     }
476     size = bptype->getSize();
477     doTypeCheck = BPatch::bpatch->isTypeChecked();
478 };
479
480
481 AstNodePtr AstNode::threadIndexNode() {
482     // We use one of these across all platforms, since it
483     // devolves into a process-specific function node. 
484     // However, this lets us delay that until code generation
485     // when we have the process pointer.
486     static AstNodePtr indexNode_;
487
488     // Since we only ever have one, keep a static copy around. If
489     // we get multiples, we'll screw up our pointer-based common subexpression
490     // elimination.
491
492     if (indexNode_ != AstNodePtr()) return indexNode_;
493     pdvector<AstNodePtr > args;
494     // By not including a process we'll specialize at code generation.
495     indexNode_ = AstNode::funcCallNode("DYNINSTthreadIndex", args);
496     assert(indexNode_);
497     indexNode_->setConstFunc(true);
498
499     return indexNode_;
500 }
501
502
503 #if defined(ASTDEBUG)
504 #define AST_PRINT
505 #endif
506
507 #if defined(AST_PRINT)
508 void AstNode::printRC()
509 {
510     sprintf(errorLine,"RC referenceCount=%d\n",referenceCount);
511     logLine(errorLine);
512     if (loperand) {
513       logLine("RC loperand\n");
514       loperand->printRC();
515     }
516     if (roperand) {
517       logLine("RC roperand\n");
518       roperand->printRC();
519     }
520     if (eoperand) {
521       logLine("RC eoperand\n");
522       eoperand->printRC();
523     }
524 }
525 #endif
526
527 AstNode::~AstNode() {
528     //printf("at ~AstNode()  count=%d\n", referenceCount);
529 }
530
531 Address AstMiniTrampNode::generateTramp(codeGen &gen,
532                                         int &trampCost, 
533                                         bool noCost) {
534     static AstNodePtr costAst;
535     static AstNodePtr preamble;
536
537     if (costAst == AstNodePtr())
538         costAst = AstNode::operandNode(AstNode::Constant, (void *)0);
539
540     if (preamble == AstNodePtr())
541         preamble = AstNode::operatorNode(trampPreamble, costAst);
542
543     // private constructor; assumes NULL for right child
544     
545     // we only want to use the cost of the minimum statements that will
546     // be executed.  Statements, such as the body of an if statement,
547     // will have their costs added to the observed cost global variable
548     // only if they are indeed called.  The code to do this in the minitramp
549     // right after the body of the if.
550     trampCost = preamble->maxCost() + minCost();
551
552     costAst->setOValue((void *) (long) trampCost);
553    
554     if (!preamble->generateCode(gen, noCost)) {
555         fprintf(stderr, "[%s:%d] WARNING: failure to generate miniTramp preamble\n", __FILE__, __LINE__);
556     }
557     
558     if (!ast_->generateCode(gen, noCost)) {
559         fprintf(stderr, "[%s:%d] WARNING: failure to generate miniTramp body\n", __FILE__, __LINE__);
560     }
561
562     return 0;
563 }
564
565 // This name is a bit of a misnomer. It's not the strict use count; it's the
566 // use count modified by whether a node can be kept or not. We can treat
567 // un-keepable nodes (AKA those that don't strictly depend on their AST inputs)
568 // as multiple different nodes that happen to have the same children; keepable
569 // nodes are the "same". If that makes any sense. 
570 //
571 // In any case, we use the following algorithm to set use counts:
572 //
573 //DFS through the AST graph. 
574 //If an AST can be kept:
575 //  Increase its use count;
576 //  Return.
577 //If an AST cannot be kept:
578 //  Recurse to each child;
579 //  Return
580 //
581 // The result is all nodes having counts of 0, 1, or >1. These mean:
582 // 0: node cannot be kept, or is only reached via a keepable node.
583 // 1: Node can be kept, but doesn't matter as it's only used once.
584 // >1: keep result in a register.
585
586 void AstNode::setUseCount() 
587 {
588         if (useCount) {
589                 // If the useCount is 1, then it means this node can
590                 // be shared, and there is a copy. In that case, we assume
591                 // that when this particular incarnation is generated, the
592                 // result will already be calculated and sitting in a register.
593                 // Since that's the case, just up the useCount so we know when
594                 // we can free said register.
595                 useCount++;
596                 return; 
597         }
598         if (canBeKept()) {
599                 useCount++;
600                 // We purposefully fall through... if our use count
601                 // is 1, we'll have to calculate this node instead of
602                 // keeping it around. In that case, see if any of the 
603                 // children are shared (because we can reuse them when
604                 // calculating this guy)
605         }
606         // We can't be kept, but maybe our children can.
607         pdvector<AstNodePtr> children;
608         getChildren(children);
609         for (unsigned i=0; i<children.size(); i++) {
610             children[i]->setUseCount();
611     }
612 }
613
614 void AstNode::cleanUseCount(void)
615 {
616     useCount = 0;
617
618     pdvector<AstNodePtr> children;
619     getChildren(children);
620     for (unsigned i=0; i<children.size(); i++) {
621                 children[i]->cleanUseCount();
622     }
623 }
624
625 // Allocate a register and make it available for sharing if our
626 // node is shared
627 Register AstNode::allocateAndKeep(codeGen &gen, bool noCost)
628 {
629     ast_printf("Allocating register for node %p, useCount %d\n", this, useCount);
630     // Allocate a register
631     Register dest = gen.rs()->allocateRegister(gen, noCost);
632
633     ast_printf("Allocator returned %d\n", dest);
634     assert(dest != REG_NULL);
635
636     if (useCount > 1) {
637         ast_printf("Adding kept register %d for node %p: useCount %d\n", dest, this, useCount);
638         // If use count is 0 or 1, we don't want to keep
639         // it around. If it's > 1, then we can keep the node
640         // (by construction) and want to since there's another
641         // use later.
642         gen.tracker()->addKeptRegister(gen, this, dest);
643     }
644     return dest;
645 }
646
647 //
648 // This procedure generates code for an AST DAG. If there is a sub-graph
649 // being shared between more than 1 node, then the code is generated only
650 // once for this sub-graph and the register where the return value of the
651 // sub-graph is stored, is kept allocated until the last node sharing the
652 // sub-graph has used it (freeing it afterwards). A count called "useCount"
653 // is used to determine whether a particular node or sub-graph is being
654 // shared. At the end of the call to generate code, this count must be 0
655 // for every node. Another important issue to notice is that we have to make
656 // sure that if a node is not calling generate code recursively for either
657 // its left or right operands, we then need to make sure that we update the
658 // "useCount" for these nodes (otherwise we might be keeping registers
659 // allocated without reason). 
660 //
661 // This code was modified in order to set the proper "useCount" for every
662 // node in the DAG before calling the original generateCode procedure (now
663 // generateCode_phase2). This means that we are traversing the DAG twice,
664 // but with the advantage of potencially generating more efficient code.
665 //
666 // Note: a complex Ast DAG might require more registers than the ones 
667 // currently available. In order to fix this problem, we will need to 
668 // implement a "virtual" register allocator - naim 11/06/96
669 //
670 bool AstNode::generateCode(codeGen &gen, 
671                            bool noCost, 
672                            Address &retAddr,
673                            Register &retReg) {
674     static bool entered = false;
675
676
677     bool ret = true;
678
679     bool top_level;
680     if (entered) {
681         top_level = false;
682     }
683     else {
684         entered = true;
685         top_level = true;
686         stats_codegen.startTimer(CODEGEN_AST_TIMER);
687         stats_codegen.incrementCounter(CODEGEN_AST_COUNTER);
688     }
689
690     entered = true;
691
692     cleanUseCount();
693     setUseCount();
694     setVariableAST(gen);
695     ast_printf("====== Code Generation Start ===== \n");
696     debugPrint();
697     ast_printf("\n\n\n\n");
698
699     // We can enter this guy recursively... inst-ia64 goes through
700     // emitV and calls generateCode on the frame pointer AST. Now, it
701     // really shouldn't, but them's the breaks. So we only want
702     // to build a regTracker if there isn't one already...
703     if (top_level) {
704         gen.setRegTracker(new regTracker_t);
705     }
706     
707     // note: this could return the value "(Address)(-1)" -- csserra
708     if (!generateCode_phase2(gen, noCost, retAddr, retReg)) {
709         fprintf(stderr, "WARNING: failed in generateCode internals!\n");
710         ret = false;
711     }
712     
713     if (top_level) {
714       delete gen.tracker();
715       gen.setRegTracker(NULL);
716     }
717     
718     ast_printf("====== Code Generation End ===== \n");
719     debugPrint();
720     ast_printf("\n\n\n\n");
721
722     if (top_level) {
723         entered = false;
724         stats_codegen.stopTimer(CODEGEN_AST_TIMER);
725     }
726     return ret;
727 }
728
729 bool AstNode::generateCode(codeGen &gen, 
730                            bool noCost) {
731     Address unused = ADDR_NULL;
732     Register unusedReg = REG_NULL;
733     bool ret = generateCode(gen, noCost, unused, unusedReg);
734     gen.rs()->freeRegister(unusedReg);
735
736     return ret;
737 }
738
739 bool AstNode::previousComputationValid(Register &reg,
740                                        codeGen &gen) {
741         Register keptReg = gen.tracker()->hasKeptRegister(this);
742         if (keptReg != REG_NULL) {
743                 reg = keptReg;
744                 ast_printf("Returning previously used register %d for node %p\n", reg, this);
745                 return true;
746         }
747    return false;
748 }
749
750 // We're going to use this fragment over and over and over...
751 #define RETURN_KEPT_REG(r) { if (previousComputationValid(r, gen)) { decUseCount(gen); gen.rs()->incRefCount(r); return true;} }
752 #define ERROR_RETURN { fprintf(stderr, "[%s:%d] ERROR: failure to generate operand\n", __FILE__, __LINE__); return false; }
753 #define REGISTER_CHECK(r) if (r == REG_NULL) { fprintf(stderr, "[%s: %d] ERROR: returned register invalid\n", __FILE__, __LINE__); return false; }
754
755
756 bool AstNode::initRegisters(codeGen &g) {
757     bool ret = true;
758     pdvector<AstNodePtr> kids;
759     getChildren(kids);
760     for (unsigned i = 0; i < kids.size(); i++) {
761         if (!kids[i]->initRegisters(g))
762             ret = false;
763     }
764     return ret;
765 }
766
767
768 bool AstNode::generateCode_phase2(codeGen &, bool,
769                                   Address &,
770                                   Register &) {
771     fprintf(stderr, "ERROR: call to AstNode generateCode_phase2; should be handled by subclass\n");
772     fprintf(stderr, "Undefined phase2 for:\n");
773     if (dynamic_cast<AstNullNode *>(this)) fprintf(stderr, "nullNode\n");
774     if (dynamic_cast<AstOperatorNode *>(this)) fprintf(stderr, "operatorNode\n");
775     if (dynamic_cast<AstOperandNode *>(this)) fprintf(stderr, "operandNode\n");
776     if (dynamic_cast<AstCallNode *>(this)) fprintf(stderr, "callNode\n");
777     if (dynamic_cast<AstSequenceNode *>(this)) fprintf(stderr, "seqNode\n");
778     if (dynamic_cast<AstVariableNode *>(this)) fprintf(stderr, "varNode\n");
779     if (dynamic_cast<AstInsnNode *>(this)) fprintf(stderr, "insnNode\n");
780     if (dynamic_cast<AstMiniTrampNode *>(this)) fprintf(stderr, "miniTrampNode\n");
781     if (dynamic_cast<AstMemoryNode *>(this)) fprintf(stderr, "memoryNode\n");
782     assert(0);
783         return 0;
784 }
785
786
787 bool AstNullNode::generateCode_phase2(codeGen &gen, bool,
788                                       Address &retAddr,
789                                       Register &retReg) {
790     retAddr = ADDR_NULL;
791     retReg = REG_NULL;
792
793     decUseCount(gen);
794    
795     return true;
796 }
797
798
799 bool AstLabelNode::generateCode_phase2(codeGen &gen, bool,
800                                        Address &retAddr,
801                                        Register &retReg) {
802         assert(generatedAddr_ == 0);
803     // Pick up the address we were added at
804     generatedAddr_ = gen.currAddr();
805
806     retAddr = ADDR_NULL;
807     retReg = REG_NULL;
808
809         decUseCount(gen);
810
811     return true;
812 }
813
814 bool AstOperatorNode::initRegisters(codeGen &g) {
815     bool ret = true;
816     pdvector<AstNodePtr> kids;
817     getChildren(kids);
818     for (unsigned i = 0; i < kids.size(); i++) {
819         if (!kids[i]->initRegisters(g))
820             ret = false;
821     }
822
823 #if !defined(arch_x86)
824     // Override: if we're trying to save to an original
825     // register, make sure it's saved on the stack.
826     if (op == storeOp) {
827         if (loperand->getoType() == origRegister) {
828             Address origReg = (Address) loperand->getOValue();
829             // Mark that register as live so we are sure to save it.
830             registerSlot *r = (*(g.rs()))[origReg];
831             r->liveState = registerSlot::live;
832         }
833     }
834 #endif
835     return ret;
836 }
837
838
839 #if defined(arch_x86) || defined(arch_x86_64)
840 bool AstOperatorNode::generateOptimizedAssignment(codeGen &gen, bool noCost) 
841 {
842    //Recognize the common case of 'a = a op constant' and try to 
843    // generate optimized code for this case.
844    Address laddr;
845   
846    if (loperand->getoType() == DataAddr)
847    {
848       laddr = (Address) loperand->getOValue();
849    }
850    else
851    {
852       if(loperand->getoType() == variableValue)
853       {
854          dyn_detail::boost::shared_ptr<AstOperandNode> lnode = 
855             dyn_detail::boost::dynamic_pointer_cast<AstOperandNode>(loperand);
856        
857          int_variable* var = lnode->lookUpVar(gen.addrSpace());
858          if (!var || gen.addrSpace()->needsPIC(var))
859             return false;
860          laddr = var->getAddress();
861       }
862       else
863       {
864          //Deal with global writes for now.
865          return false;
866       }
867      
868    }
869
870    if (roperand->getoType() == Constant) {
871       //Looks like 'global = constant'
872 #if defined(arch_x86_64)
873       if (laddr >> 32 || ((Address) roperand->getOValue()) >> 32) {
874          // Make sure value and address are 32-bit values.
875          return false;
876       }
877 #endif
878       int imm = (int) (long) roperand->getOValue();
879       emitStoreConst(laddr, (int) imm, gen, noCost);
880       loperand->decUseCount(gen);
881       roperand->decUseCount(gen);
882       return true;
883    }
884
885    AstOperatorNode *roper = dynamic_cast<AstOperatorNode *>(roperand.get());
886    if (!roper)
887       return false;
888    
889    if (roper->op != plusOp && roper->op != minusOp)
890       return false;
891    
892    AstOperandNode *arithl = dynamic_cast<AstOperandNode *>(roper->loperand.get());
893    AstOperandNode *arithr = dynamic_cast<AstOperandNode *>(roper->roperand.get());
894    if (!arithl || !arithr)
895       return false;
896    
897    AstNode *data_oper = NULL, *const_oper = NULL;
898    if (arithl->getoType() == DataAddr && arithr->getoType() == Constant &&
899        laddr == (Address) arithl->getOValue())
900    {
901       data_oper = arithl;
902       const_oper = arithr;
903    }
904    else if (arithl->getoType() == variableValue && arithr->getoType() == Constant)
905    {
906       Address addr = 0;
907       int_variable* var = arithl->lookUpVar(gen.addrSpace());
908       if (!var || gen.addrSpace()->needsPIC(var))
909          return false;
910       addr = var->getAddress();
911       if (addr == laddr) {
912          data_oper = arithl;
913          const_oper = arithr;
914       }
915    }
916    else if (arithr->getoType() == DataAddr && arithl->getoType() == Constant &&
917             laddr == (Address) arithr->getOValue() && roper->op == plusOp)
918    {
919       data_oper = arithr;
920       const_oper = arithl;
921    }
922    else if (arithl->getoType() == variableValue && arithr->getoType() == Constant)
923    {
924       Address addr = 0;
925       int_variable* var = arithl->lookUpVar(gen.addrSpace());
926       if(!var || gen.addrSpace()->needsPIC(var))
927          return false;
928       addr = var->getAddress();
929       if (addr == laddr) {
930          data_oper = arithr;
931          const_oper = arithl;
932       }
933    }
934    else
935    {
936       return false;
937    }
938
939    long int imm = (long int) const_oper->getOValue();
940    if (roper->op == plusOp) {
941       emitAddSignedImm(laddr, imm, gen, noCost);
942    }
943    else {
944       emitSubSignedImm(laddr, imm, gen, noCost);
945    }
946    
947    loperand->decUseCount(gen);
948    roper->roperand->decUseCount(gen);
949    roper->loperand->decUseCount(gen);
950    roper->decUseCount(gen);
951
952    return true;
953 }
954 #else
955 bool AstOperatorNode::generateOptimizedAssignment(codeGen &, bool) 
956 {
957    return false;   
958 }
959 #endif
960
961 bool AstOperatorNode::generateCode_phase2(codeGen &gen, bool noCost,
962                                           Address &retAddr,
963                                           Register &retReg) {
964
965    retAddr = ADDR_NULL; // We won't be setting this...
966    // retReg may have a value or be the (register) equivalent of NULL.
967    // In either case, we don't touch it...
968
969         RETURN_KEPT_REG(retReg);
970
971     
972    Address addr = ADDR_NULL;
973  
974    Register src1 = Null_Register;
975    Register src2 = Null_Register;
976
977    Register right_dest = Null_Register;
978    Register tmp = Null_Register;
979     
980    switch(op) {
981       case branchOp: {
982          assert(loperand->getoType() == Constant);
983          unsigned offset = (Register) (long) loperand->getOValue();
984          // We are not calling loperand->generateCode_phase2,
985          // so we decrement its useCount by hand.
986          // Would be nice to allow register branches...
987          loperand->decUseCount(gen);
988          (void)emitA(branchOp, 0, 0, (Register)offset, gen, rc_no_control, noCost);
989          retReg = REG_NULL; // No return register
990          break;
991       }
992       case ifOp: {
993          // This ast cannot be shared because it doesn't return a register
994          if (!loperand->generateCode_phase2(gen, noCost, addr, src1)) ERROR_RETURN;
995         
996          REGISTER_CHECK(src1);
997          codeBufIndex_t ifIndex= gen.getIndex();
998
999          size_t preif_patches_size = gen.allPatches().size();
1000          codeBufIndex_t thenSkipStart = emitA(op, src1, 0, 0, gen, rc_before_jump, noCost);
1001          size_t postif_patches_size = gen.allPatches().size();
1002          // DO NOT FREE THE REGISTER HERE!!! we use it later to regenerate the
1003          // jump once code has been generated. This is annoying, since we
1004          // don't really need the register... we just want it allocated.
1005         
1006          // I'm ignoring the above; we'll keep the _value_ of src1, but free it
1007          // for internal code.
1008          Register src1_copy = src1;
1009          if (loperand->decRefCount())
1010             gen.rs()->freeRegister(src1);
1011         
1012          // The flow of control forks. We need to add the forked node to 
1013          // the path
1014          gen.tracker()->increaseConditionalLevel();
1015          if (!roperand->generateCode_phase2(gen, noCost, addr, src2)) ERROR_RETURN;
1016          if (roperand->decRefCount())
1017             gen.rs()->freeRegister(src2);
1018          gen.tracker()->decreaseAndClean(gen);
1019          gen.rs()->unifyTopRegStates(gen); //Join the registerState for the if
1020         
1021          // Is there an else clause?  If yes, generate branch over it
1022          codeBufIndex_t elseSkipStart = 0;
1023          codeBufIndex_t elseSkipIndex = gen.getIndex();
1024          size_t preelse_patches_size = 0, postelse_patches_size = 0;
1025          if (eoperand) {
1026             gen.rs()->pushNewRegState(); //Create registerState for else
1027             preelse_patches_size = gen.allPatches().size();
1028             elseSkipStart = emitA(branchOp, 0, 0, 0,
1029                                   gen, rc_no_control, noCost);
1030             postelse_patches_size = gen.allPatches().size();
1031          }
1032
1033          // Now that we've generated the "then" section, rewrite the if
1034          // conditional branch.
1035          codeBufIndex_t elseStartIndex = gen.getIndex();
1036
1037          if (preif_patches_size != postif_patches_size) {
1038             assert(postif_patches_size > preif_patches_size);
1039             ifTargetPatch if_targ(elseStartIndex + gen.startAddr());
1040             for (unsigned i=preif_patches_size; i < postif_patches_size; i++) {
1041                gen.allPatches()[i].setTarget(&if_targ);
1042             }
1043             for (unsigned i=preif_patches_size; i < postif_patches_size; i++) {
1044                gen.allPatches()[i].applyPatch();
1045             }
1046          }
1047          else {
1048             gen.setIndex(ifIndex);
1049             // call emit again now with correct offset.
1050             // This backtracks over current code.
1051             // If/when we vectorize, we can do this in a two-pass arrangement
1052             (void) emitA(op, src1_copy, 0, 
1053                          (Register) codeGen::getDisplacement(thenSkipStart, elseStartIndex),
1054                          gen, rc_no_control, noCost);
1055             // Now we can free the register
1056             // Register has already been freed; we're just re-using it.
1057             //gen.rs()->freeRegister(src1);
1058         
1059             gen.setIndex(elseStartIndex);
1060          }
1061
1062          if (eoperand) {
1063             // If there's an else clause, we need to generate code for it.
1064             gen.tracker()->increaseConditionalLevel();
1065             if (!eoperand->generateCode_phase2(gen,
1066                                                noCost, 
1067                                                addr,
1068                                                src2)) ERROR_RETURN;
1069             if (eoperand->decRefCount())
1070                gen.rs()->freeRegister(src2);
1071             gen.tracker()->decreaseAndClean(gen);
1072             gen.rs()->unifyTopRegStates(gen); //Join the registerState for the else
1073             
1074             // We also need to fix up the branch at the end of the "true"
1075             // clause to jump around the "else" clause.
1076             codeBufIndex_t endIndex = gen.getIndex();
1077             if (preelse_patches_size != postelse_patches_size) {
1078                assert(postif_patches_size > preif_patches_size);
1079                ifTargetPatch else_targ(endIndex + gen.startAddr());
1080                for (unsigned i=preelse_patches_size; i < postelse_patches_size; i++) {
1081                   gen.allPatches()[i].setTarget(&else_targ);
1082                }
1083                for (unsigned i=preelse_patches_size; i < postelse_patches_size; i++) {
1084                   gen.allPatches()[i].applyPatch();
1085                }
1086             }
1087             else {        
1088                gen.setIndex(elseSkipIndex);
1089                emitA(branchOp, 0, 0, 
1090                      (Register) codeGen::getDisplacement(elseSkipStart, endIndex),
1091                      gen, rc_no_control, noCost);
1092                gen.setIndex(endIndex);
1093             }
1094          }
1095          retReg = REG_NULL; 
1096          break;
1097       }
1098       case ifMCOp: {
1099          assert(gen.point());
1100         
1101          // TODO: Right now we get the condition from the memory access info,
1102          // because scanning for memory accesses is the only way to detect these
1103          // conditional instructions. The right way(TM) would be to attach that
1104          // info directly to the point...
1105          // Okay. The info we need is stored in the BPatch_point. We have the instPoint. 
1106          // Yay.
1107         
1108          BPatch_addressSpace *bproc = (BPatch_addressSpace *) gen.addrSpace()->up_ptr();
1109          BPatch_point *bpoint = bproc->findOrCreateBPPoint(NULL, gen.point(), BPatch_point::convertInstPointType_t(gen.point()->type()));
1110         
1111          const BPatch_memoryAccess* ma = bpoint->getMemoryAccess();
1112          assert(ma);
1113          int cond = ma->conditionCode_NP();
1114          if(cond > -1) {
1115             codeBufIndex_t startIndex = gen.getIndex();
1116             emitJmpMC(cond, 0 /* target, changed later */, gen);
1117             codeBufIndex_t fromIndex = gen.getIndex();
1118             // Add the snippet to the tracker, as AM has indicated...
1119             gen.tracker()->increaseConditionalLevel();
1120             // generate code with the right path
1121             if (!loperand->generateCode_phase2(gen,
1122                                                noCost,
1123                                                addr,
1124                                                src1)) ERROR_RETURN;
1125             if (loperand->decRefCount())
1126                gen.rs()->freeRegister(src1);
1127             gen.tracker()->decreaseAndClean(gen);
1128             codeBufIndex_t endIndex = gen.getIndex();
1129             // call emit again now with correct offset.
1130             gen.setIndex(startIndex);
1131             emitJmpMC(cond, codeGen::getDisplacement(fromIndex, endIndex), gen);
1132             gen.setIndex(endIndex);
1133          }
1134          else {
1135             if (!loperand->generateCode_phase2(gen,
1136                                                noCost,
1137                                                addr, 
1138                                                src1)) ERROR_RETURN;
1139             if (loperand->decRefCount())
1140                gen.rs()->freeRegister(src1);
1141          }
1142
1143          break;
1144       }
1145       case whileOp: {
1146          codeBufIndex_t top = gen.getIndex();
1147          if (!loperand->generateCode_phase2(gen, noCost, addr, src1)) ERROR_RETURN;
1148          REGISTER_CHECK(src1);
1149          codeBufIndex_t startIndex = gen.getIndex();
1150          codeBufIndex_t fromIndex = emitA(ifOp, src1, 0, 0, gen, rc_no_control, noCost);
1151          if (loperand->decRefCount())
1152             gen.rs()->freeRegister(src1);
1153          if (roperand) {
1154             gen.tracker()->increaseConditionalLevel();
1155             if (!roperand->generateCode_phase2(gen, noCost,
1156                                                addr,
1157                                                src1)) ERROR_RETURN;
1158             if (roperand->decRefCount())
1159                gen.rs()->freeRegister(src1);
1160             gen.tracker()->decreaseAndClean(gen);
1161          }
1162          //jump back
1163          (void) emitA(branchOp, 0, 0, codeGen::getDisplacement(top, gen.getIndex()),
1164                       gen, rc_no_control, noCost);
1165         
1166          // Rewind and replace the skip jump
1167          codeBufIndex_t endIndex = gen.getIndex();
1168          gen.setIndex(startIndex);
1169          (void) emitA(ifOp, src1, 0, (Register) codeGen::getDisplacement(fromIndex, endIndex), 
1170                       gen, rc_no_control, noCost);
1171          gen.setIndex(endIndex);
1172          // sprintf(errorLine,"branch forward %d\n", base - fromAddr);
1173          break;
1174       }
1175       case doOp: {
1176          fprintf(stderr, "[%s:%d] WARNING: do AST node unimplemented!\n", __FILE__, __LINE__);
1177          return false;
1178       }
1179       case getAddrOp: {
1180          switch(loperand->getoType()) {
1181             case variableAddr:
1182                if (retReg == REG_NULL) {
1183                   retReg = allocateAndKeep(gen, noCost);
1184                }
1185                assert (loperand->getOVar());
1186                loperand->emitVariableLoad(loadConstOp, retReg, retReg, gen, noCost, gen.rs(), size,
1187                                           gen.point(), gen.addrSpace());
1188                break;
1189             case variableValue:
1190                if (retReg == REG_NULL) {
1191                   retReg = allocateAndKeep(gen, noCost);
1192                }
1193                assert (loperand->getOVar());
1194                loperand->emitVariableLoad(loadOp, retReg, retReg, gen, noCost, gen.rs(), size,
1195                                           gen.point(), gen.addrSpace());
1196                break;
1197             case DataAddr:
1198                {
1199                   addr = reinterpret_cast<Address>(loperand->getOValue());
1200                   if (retReg == REG_NULL) {
1201                      retReg = allocateAndKeep(gen, noCost);
1202                   }
1203                   assert(!loperand->getOVar());
1204                   emitVload(loadConstOp, addr, retReg, retReg, gen,
1205                             noCost, gen.rs(), size, gen.point(), gen.addrSpace());
1206                }
1207                break;
1208             case FrameAddr: {
1209                // load the address fp + addr into dest
1210                if (retReg == REG_NULL)
1211                   retReg = allocateAndKeep(gen, noCost);
1212                Register temp = gen.rs()->getScratchRegister(gen, noCost);
1213                addr = (Address) loperand->getOValue();
1214                emitVload(loadFrameAddr, addr, temp, retReg, gen,
1215                          noCost, gen.rs(), size, gen.point(), gen.addrSpace());
1216                break;
1217             }
1218             case RegOffset: {
1219                cerr << "Emitting a regOffset for reg " << loperand->getOValue() << endl;
1220                assert(loperand);
1221                assert(loperand->operand());
1222             
1223                // load the address reg + addr into dest
1224                if (retReg == REG_NULL) {
1225                   retReg = allocateAndKeep(gen, noCost);
1226                }
1227                addr = (Address) loperand->operand()->getOValue();
1228             
1229                emitVload(loadRegRelativeOp, addr, (long)loperand->getOValue(), retReg, gen,
1230                          noCost, gen.rs(), size, gen.point(), gen.addrSpace());
1231                break;
1232             }
1233             case DataIndir:
1234                // taking address of pointer de-ref returns the original
1235                //    expression, so we simple generate the left child's 
1236                //    code to get the address 
1237                if (!loperand->operand()->generateCode_phase2(gen,
1238                                                              noCost, 
1239                                                              addr,
1240                                                              retReg)) ERROR_RETURN;
1241                // Broken refCounts?
1242                break;
1243             case origRegister:
1244                // Added 2NOV11 Bernat - some variables live in original registers,
1245                // and so we need to be able to dereference their contents. 
1246                if (!loperand->generateCode_phase2(gen, noCost, addr, retReg)) ERROR_RETURN;
1247                break;
1248             default:
1249                cerr << "Uh oh, unknown loperand type in getAddrOp: " << loperand->getoType() << endl;
1250                cerr << "\t Generating ast " << hex << this << dec << endl;
1251                assert(0);
1252          }
1253          break;
1254       }
1255       case storeOp: {
1256          bool result = generateOptimizedAssignment(gen, noCost);
1257          if (result)
1258             break;
1259        
1260          // This ast cannot be shared because it doesn't return a register
1261          if (!roperand->generateCode_phase2(gen,
1262                                             noCost,
1263                                             addr,
1264                                             src1))  { 
1265             fprintf(stderr, "ERROR: failure generating roperand\n"); 
1266             ERROR_RETURN; 
1267          }
1268          REGISTER_CHECK(src1);
1269          // We will access loperand's children directly. They do not expect
1270          // it, so we need to bump up their useCounts
1271          loperand->fixChildrenCounts();
1272
1273          src2 = gen.rs()->allocateRegister(gen, noCost);
1274          switch (loperand->getoType()) {
1275             case variableValue:
1276                loperand->emitVariableStore(storeOp, src1, src2, gen,
1277                                            noCost, gen.rs(), size, gen.point(), gen.addrSpace());
1278                loperand->decUseCount(gen);
1279                break;
1280             case DataAddr:
1281                addr = (Address) loperand->getOValue();
1282                assert(loperand->getOVar() == NULL);
1283                emitVstore(storeOp, src1, src2, addr, gen,
1284                           noCost, gen.rs(), size, gen.point(), gen.addrSpace());
1285                // We are not calling generateCode for the left branch,
1286                // so need to decrement the refcount by hand
1287                loperand->decUseCount(gen);
1288                break;
1289             case FrameAddr:
1290                addr = (Address) loperand->getOValue();
1291                emitVstore(storeFrameRelativeOp, src1, src2, addr, gen, 
1292                           noCost, gen.rs(), size, gen.point(), gen.addrSpace());
1293                loperand->decUseCount(gen);
1294                break;
1295             case RegOffset: {
1296                assert(loperand->operand());
1297                addr = (Address) loperand->operand()->getOValue();
1298             
1299                // This is cheating, but I need to pass 4 data values into emitVstore, and
1300                // it only allows for 3.  Prepare the dest address in scratch register src2.
1301             
1302                emitVload(loadRegRelativeAddr, addr, (long)loperand->getOValue(), src2,
1303                          gen, noCost, gen.rs(), size, gen.point(), gen.addrSpace());
1304             
1305                // Same as DataIndir at this point.
1306                emitV(storeIndirOp, src1, 0, src2, gen, noCost, gen.rs(), size, gen.point(), gen.addrSpace());
1307                loperand->decUseCount(gen);
1308                break;
1309             }
1310             case DataIndir: {
1311                // store to a an expression (e.g. an array or field use)
1312                // *(+ base offset) = src1
1313                if (!loperand->operand()->generateCode_phase2(gen,
1314                                                              noCost,
1315                                                              addr,
1316                                                              tmp)) ERROR_RETURN;
1317                REGISTER_CHECK(tmp);
1318
1319                // tmp now contains address to store into
1320                emitV(storeIndirOp, src1, 0, tmp, gen, noCost, gen.rs(), size, gen.point(), gen.addrSpace());
1321                if (loperand->operand()->decRefCount())
1322                   gen.rs()->freeRegister(tmp);
1323                loperand->decUseCount(gen);
1324                break;
1325             }
1326             case origRegister:
1327                gen.rs()->writeProgramRegister(gen, (Register)(long)loperand->getOValue(),
1328                                               src1, getSize());
1329                //emitStorePreviousStackFrameRegister((Address) loperand->getOValue(),
1330                //src1, gen, getSize(), noCost);
1331                loperand->decUseCount(gen);
1332                break;
1333             case Param: 
1334             case ParamAtCall: 
1335             case ParamAtEntry: {
1336                dyn_detail::boost::shared_ptr<AstOperandNode> lnode = 
1337                   dyn_detail::boost::dynamic_pointer_cast<AstOperandNode>(loperand);
1338                emitR(getParamOp, (Address)lnode->oValue,
1339                      src1, src2, gen, noCost, gen.point(),
1340                      gen.addrSpace()->multithread_capable());
1341                loperand->decUseCount(gen);
1342                break;
1343             }
1344             case ReturnVal:
1345                emitR(getRetValOp, Null_Register,
1346                      src1, src2, gen, noCost, gen.point(),
1347                      gen.addrSpace()->multithread_capable());
1348                loperand->decUseCount(gen);
1349                break;
1350             case ReturnAddr:
1351                 emitR(getRetAddrOp, Null_Register,
1352                       src1, src2, gen, noCost, gen.point(), 
1353                       gen.addrSpace()->multithread_capable());
1354             default: {
1355                // Could be an error, could be an attempt to load based on an arithmetic expression
1356                // Generate the left hand side, store the right to that address
1357                if (!loperand->generateCode_phase2(gen, noCost, addr, tmp)) ERROR_RETURN;
1358                REGISTER_CHECK(tmp);
1359
1360                emitV(storeIndirOp, src1, 0, tmp, gen, noCost, gen.rs(), size, gen.point(), gen.addrSpace());
1361                if (loperand->decRefCount())
1362                   gen.rs()->freeRegister(tmp);
1363                break;
1364             }
1365          }
1366          if (roperand->decRefCount())
1367             gen.rs()->freeRegister(src1);
1368          gen.rs()->freeRegister(src2);
1369          retReg = REG_NULL;
1370          break;
1371       }
1372       case storeIndirOp: {
1373         
1374          if (!roperand->generateCode_phase2(gen, noCost, addr, src1)) ERROR_RETURN;
1375          if (!loperand->generateCode_phase2(gen, noCost, addr, src2)) ERROR_RETURN;
1376          REGISTER_CHECK(src1);
1377          REGISTER_CHECK(src2);
1378          emitV(op, src1, 0, src2, gen, noCost, gen.rs(), size, gen.point(), gen.addrSpace());
1379          if (roperand->decRefCount())
1380             gen.rs()->freeRegister(src1);
1381          if (loperand->decRefCount())
1382             gen.rs()->freeRegister(src2);
1383          retReg = REG_NULL;
1384          break;
1385       }
1386       case trampPreamble: {
1387          // This ast cannot be shared because it doesn't return a register
1388          retReg = REG_NULL;
1389          break;
1390       }
1391       case plusOp:
1392       case minusOp:
1393       case timesOp:
1394       case divOp:
1395       case orOp:
1396       case andOp:
1397       case eqOp:
1398       case neOp:
1399       case lessOp:
1400       case leOp:
1401       case greaterOp:
1402       case geOp:
1403       default: 
1404       {
1405          src1 = Null_Register;
1406          right_dest = Null_Register;
1407          if (loperand) {
1408             if (!loperand->generateCode_phase2(gen,
1409                                                noCost, addr, src1)) ERROR_RETURN;
1410             REGISTER_CHECK(src1);
1411          }
1412          
1413          if (roperand &&
1414              (roperand->getoType() == Constant) &&
1415              doNotOverflow((Register) (long) roperand->getOValue())) {
1416             if (retReg == REG_NULL) {
1417                retReg = allocateAndKeep(gen, noCost);
1418                ast_printf("Operator node, const RHS, allocated register %d\n", retReg);
1419             }
1420             else
1421                ast_printf("Operator node, const RHS, keeping register %d\n", retReg);
1422                                 
1423             emitImm(op, src1, (Register) (long) roperand->getOValue(), retReg, gen, noCost, gen.rs());
1424
1425             if (src1 != Null_Register && loperand->decRefCount())
1426                gen.rs()->freeRegister(src1); 
1427
1428             // We do not .generateCode for roperand, so need to update its
1429             // refcounts manually
1430             roperand->decUseCount(gen);
1431          }
1432          else {
1433             if (roperand) {
1434                if (!roperand->generateCode_phase2(gen, noCost, addr, right_dest)) ERROR_RETURN;
1435                REGISTER_CHECK(right_dest);
1436             }
1437             if (retReg == REG_NULL) {
1438                retReg = allocateAndKeep(gen, noCost);
1439             }
1440             emitV(op, src1, right_dest, retReg, gen, noCost, gen.rs(), size, gen.point(), gen.addrSpace());
1441             if (src1 != Null_Register && loperand->decRefCount()) {
1442                // Don't free inputs until afterwards; we have _no_ idea
1443                gen.rs()->freeRegister(src1); 
1444             }
1445             // what the underlying code might do with a temporary register.
1446             if (right_dest != Null_Register && roperand->decRefCount())
1447                gen.rs()->freeRegister(right_dest); 
1448          }
1449       }
1450    }
1451         decUseCount(gen);
1452    return true;
1453 }
1454
1455 bool AstOperandNode::generateCode_phase2(codeGen &gen, bool noCost,
1456                                          Address &,
1457                                          Register &retReg) {
1458         RETURN_KEPT_REG(retReg);
1459     
1460
1461     Address addr = ADDR_NULL;
1462     Register src = Null_Register;
1463
1464 #if defined(ASTDEBUG)
1465    sprintf(errorLine,"### location: %p ###\n", gen.point());
1466    logLine(errorLine);
1467 #endif
1468    // Allocate a register to return
1469    if (oType != DataReg) {
1470        if (retReg == REG_NULL) {
1471            retReg = allocateAndKeep(gen, noCost);
1472        }
1473    }
1474    Register temp;
1475    int tSize;
1476    int len;
1477    BPatch_type *Type;
1478    switch (oType) {
1479    case Constant:
1480      assert(oVar == NULL);
1481      emitVload(loadConstOp, (Address)oValue, retReg, retReg, gen,
1482                  noCost, gen.rs(), size, gen.point(), gen.addrSpace());
1483      break;
1484    case DataIndir:
1485       if (!operand_->generateCode_phase2(gen, noCost, addr, src)) ERROR_RETURN;
1486       REGISTER_CHECK(src);
1487       Type = const_cast<BPatch_type *> (getType());
1488       // Internally generated calls will not have type information set
1489       if(Type)
1490          tSize = Type->getSize();
1491       else
1492          tSize = sizeof(long);
1493       emitV(loadIndirOp, src, 0, retReg, gen, noCost, gen.rs(), tSize, gen.point(), gen.addrSpace()); 
1494       if (operand_->decRefCount())
1495          gen.rs()->freeRegister(src);
1496       break;
1497    case DataReg:
1498        retReg = (Register) (long) oValue;
1499        break;
1500    case origRegister:
1501       gen.rs()->readProgramRegister(gen, (Register)(long)oValue, retReg, size);
1502        //emitLoadPreviousStackFrameRegister((Address) oValue, retReg, gen,
1503        //size, noCost);
1504        break;
1505    case variableAddr:
1506      assert(oVar);
1507      emitVariableLoad(loadConstOp, retReg, retReg, gen,
1508                  noCost, gen.rs(), size, gen.point(), gen.addrSpace());
1509      break;
1510    case variableValue:
1511      assert(oVar);
1512      emitVariableLoad(loadOp, retReg, retReg, gen,
1513         noCost, gen.rs(), size, gen.point(), gen.addrSpace());
1514      break;
1515    case ReturnVal:
1516        src = emitR(getRetValOp, 0, Null_Register, retReg, gen, noCost, gen.point(),
1517                    gen.addrSpace()->multithread_capable());
1518        REGISTER_CHECK(src);
1519        if (src != retReg) {
1520            // Move src to retReg. Can't simply return src, since it was not
1521            // allocated properly
1522            emitImm(orOp, src, 0, retReg, gen, noCost, gen.rs());
1523        }
1524        break;
1525    case ReturnAddr:
1526        src = emitR(getRetAddrOp, 0, Null_Register, retReg, gen, noCost, gen.point(),
1527                    gen.addrSpace()->multithread_capable());
1528        REGISTER_CHECK(src);
1529        if (src != retReg) {
1530            // Move src to retReg. Can't simply return src, since it was not
1531            // allocated properly
1532            emitImm(orOp, src, 0, retReg, gen, noCost, gen.rs());
1533        }
1534        break;
1535    case Param:
1536    case ParamAtCall: 
1537    case ParamAtEntry: {
1538        opCode paramOp = undefOp;
1539        switch(oType) {
1540            case Param: 
1541                paramOp = getParamOp;
1542                break;
1543            case ParamAtCall: 
1544                paramOp = getParamAtCallOp;
1545                break;
1546            case ParamAtEntry: 
1547                paramOp = getParamAtEntryOp;
1548                break;
1549            default:
1550                assert(0);
1551                break;
1552        }
1553        src = emitR(paramOp, (Address)oValue, Null_Register,
1554                    retReg, gen, noCost, gen.point(),
1555                    gen.addrSpace()->multithread_capable());
1556        REGISTER_CHECK(src);
1557        if (src != retReg) {
1558            // Move src to retReg. Can't simply return src, since it was not
1559            // allocated properly
1560            emitImm(orOp, src, 0, retReg, gen, noCost, gen.rs());
1561        }
1562        }
1563        break;
1564    case DataAddr:
1565      {
1566        assert(oVar == NULL);
1567        Address addr = reinterpret_cast<Address>(oValue);
1568        emitVload(loadOp, addr, retReg, retReg, gen, noCost, NULL, size, gen.point(), gen.addrSpace());
1569      }
1570      
1571        break;
1572    case FrameAddr:
1573        addr = (Address) oValue;
1574        temp = gen.rs()->allocateRegister(gen, noCost);
1575        emitVload(loadFrameRelativeOp, addr, temp, retReg, gen, noCost, gen.rs(), size, gen.point(), gen.addrSpace());
1576        gen.rs()->freeRegister(temp);
1577        break;
1578    case RegOffset:
1579        // Prepare offset from value in any general register (not just fp).
1580        // This AstNode holds the register number, and loperand holds offset.
1581        assert(operand_);
1582        addr = (Address) operand_->getOValue();
1583        emitVload(loadRegRelativeOp, addr, (long)oValue, retReg, gen, noCost, gen.rs(), size, gen.point(), gen.addrSpace());
1584        break;
1585    case ConstantString:
1586        // XXX This is for the std::string type.  If/when we fix the std::string type
1587        // to make it less of a hack, we'll need to change this.
1588        len = strlen((char *)oValue) + 1;
1589        
1590        addr = (Address) gen.addrSpace()->inferiorMalloc(len, dataHeap); //dataheap
1591        
1592        if (!gen.addrSpace()->writeDataSpace((char *)addr, len, (char *)oValue))
1593            perror("ast.C(1351): writing string value");
1594        if(!gen.addrSpace()->needsPIC())
1595        {
1596           emitVload(loadConstOp, addr, retReg, retReg, gen, noCost, gen.rs(), size, gen.point(), gen.addrSpace());
1597        }
1598        else
1599        {
1600           gen.codeEmitter()->emitLoadShared(loadConstOp, retReg, NULL, true, size, gen, addr);
1601        }
1602        break;
1603    default:
1604        fprintf(stderr, "[%s:%d] ERROR: Unknown operand type %d in AstOperandNode generation\n",
1605                __FILE__, __LINE__, oType);
1606        return false;
1607        break;
1608    }
1609         decUseCount(gen);
1610    return true;
1611 }
1612
1613 bool AstMemoryNode::generateCode_phase2(codeGen &gen, bool noCost,
1614                                         Address &,
1615                                         Register &retReg) {
1616         RETURN_KEPT_REG(retReg);
1617         
1618     const BPatch_memoryAccess* ma;
1619     const BPatch_addrSpec_NP *start;
1620     const BPatch_countSpec_NP *count;
1621     if (retReg == REG_NULL)
1622         retReg = allocateAndKeep(gen, noCost);    
1623     switch(mem_) {
1624     case EffectiveAddr: {
1625         
1626         // VG(11/05/01): get effective address
1627         // VG(07/31/02): take care which one
1628         // 1. get the point being instrumented & memory access info
1629         assert(gen.point());
1630         
1631         BPatch_addressSpace *bproc = (BPatch_addressSpace *)gen.addrSpace()->up_ptr();
1632         BPatch_point *bpoint = bproc->findOrCreateBPPoint(NULL, gen.point(), BPatch_point::convertInstPointType_t(gen.point()->type()));
1633         if (bpoint == NULL) {
1634             fprintf(stderr, "ERROR: Unable to find BPatch point for internal point %p/0x%lx\n",
1635                     gen.point(), gen.point()->insnAddr());
1636         }
1637         assert(bpoint);
1638         ma = bpoint->getMemoryAccess();
1639         if(!ma) {
1640             bpfatal( "Memory access information not available at this point.\n");
1641             bpfatal( "Make sure you create the point in a way that generates it.\n");
1642             bpfatal( "E.g.: find*Point(const BPatch_Set<BPatch_opCode>& ops).\n");
1643             assert(0);
1644         }
1645         if(which_ >= ma->getNumberOfAccesses()) {
1646             bpfatal( "Attempt to instrument non-existent memory access number.\n");
1647             bpfatal( "Consider using filterPoints()...\n");
1648             assert(0);
1649         }
1650         start = ma->getStartAddr(which_);
1651         emitASload(start, retReg, 0, gen, noCost);
1652         break;
1653     }
1654     case BytesAccessed: {
1655         // 1. get the point being instrumented & memory access info
1656         assert(gen.point());
1657         
1658         BPatch_addressSpace *bproc = (BPatch_addressSpace *)gen.addrSpace()->up_ptr();
1659         BPatch_point *bpoint = bproc->findOrCreateBPPoint(NULL, gen.point(), BPatch_point::convertInstPointType_t(gen.point()->type()));
1660         ma = bpoint->getMemoryAccess();
1661         if(!ma) {
1662             bpfatal( "Memory access information not available at this point.\n");
1663             bpfatal("Make sure you create the point in a way that generates it.\n");
1664             bpfatal( "E.g.: find*Point(const BPatch_Set<BPatch_opCode>& ops).\n");
1665             assert(0);
1666         }
1667         if(which_ >= ma->getNumberOfAccesses()) {
1668             bpfatal( "Attempt to instrument non-existent memory access number.\n");
1669             bpfatal( "Consider using filterPoints()...\n");
1670             assert(0);
1671         }
1672         count = ma->getByteCount(which_);
1673         emitCSload(count, retReg, gen, noCost);
1674         break;
1675     }
1676     default:
1677         assert(0);
1678     }
1679         decUseCount(gen);
1680     return true;
1681 }
1682
1683 bool AstCallNode::initRegisters(codeGen &gen) {
1684     // For now, we only care if we should save everything. "Everything", of course, 
1685     // is platform dependent. This is the new location of the clobberAllFuncCalls
1686     // that had previously been in emitCall.
1687
1688     bool ret = true;
1689
1690     // First, check kids
1691     pdvector<AstNodePtr > kids;
1692     getChildren(kids);
1693     for (unsigned i = 0; i < kids.size(); i++) {
1694         if (!kids[i]->initRegisters(gen))
1695             ret = false;
1696     }
1697
1698     // Platform-specific...
1699 #if defined(arch_x86) || defined(arch_x86_64)
1700     // Our "everything" is "floating point registers".
1701     // We also need a function object.
1702     func_instance *callee = func_;
1703     if (!callee) {
1704         // Painful lookup time
1705         callee = gen.addrSpace()->findOnlyOneFunction(func_name_.c_str());
1706     }
1707     assert(callee);
1708
1709     // Marks registers as used based on the callee's behavior
1710     // This means we'll save them if necessary (also, lets us use
1711     // them in our generated code because we've saved, instead
1712     // of saving others).
1713     assert(gen.codeEmitter());
1714     gen.codeEmitter()->clobberAllFuncCall(gen.rs(), callee);
1715
1716
1717 #endif
1718 #if defined(arch_power)
1719     if (callReplace_) return true;
1720
1721     // This code really doesn't work right now...
1722     func_instance *callee = func_;
1723     if (!callee) {
1724         // Painful lookup time
1725         callee = gen.addrSpace()->findOnlyOneFunction(func_name_.c_str());
1726         assert(callee);
1727     }
1728     gen.codeEmitter()->clobberAllFuncCall(gen.rs(), callee);
1729     // We clobber in clobberAllFuncCall...
1730
1731     // Monotonically increasing...
1732 #endif
1733     return ret;
1734     
1735 }
1736
1737 bool AstCallNode::generateCode_phase2(codeGen &gen, bool noCost,
1738                                       Address &, 
1739                                       Register &retReg) {
1740         // We call this anyway... not that we'll ever be kept.
1741         // Well... if we can somehow know a function is entirely
1742         // dependent on arguments (a flag?) we can keep it around.
1743         RETURN_KEPT_REG(retReg);
1744
1745     // VG(11/06/01): This platform independent fn calls a platfrom
1746     // dependent fn which calls it back for each operand... Have to
1747     // fix those as well to pass location...
1748
1749     func_instance *use_func = func_;
1750
1751     if (!use_func && !func_addr_) {
1752         // We purposefully don't cache the func_instance object; the AST nodes
1753         // are process independent, and functions kinda are.
1754         use_func = gen.addrSpace()->findOnlyOneFunction(func_name_.c_str());
1755         if (!use_func) {
1756             fprintf(stderr, "ERROR: failed to find function %s, unable to create call\n",
1757                     func_name_.c_str());
1758         }
1759         assert(use_func); // Otherwise we've got trouble...
1760     }
1761
1762     Register tmp = 0;
1763
1764     if (use_func && !callReplace_) {
1765         tmp = emitFuncCall(callOp, gen, args_,  
1766                            noCost, use_func);
1767     }
1768     else if (use_func && callReplace_) {
1769         tmp = emitFuncCall(funcJumpOp, gen, args_,
1770                            noCost, use_func);
1771     }
1772     else if (func_addr_) {
1773         tmp = emitFuncCall(callOp, gen, args_,  
1774                            noCost, func_addr_);
1775     }
1776     else {
1777         char msg[256];
1778         sprintf(msg, "%s[%d]:  internal error:  unable to find %s",
1779                 __FILE__, __LINE__, func_name_.c_str());
1780         showErrorCallback(100, msg);
1781         assert(0);  // can probably be more graceful
1782     }
1783     
1784         // TODO: put register allocation here and have emitCall just
1785         // move the return result.
1786     if (tmp == REG_NULL) {
1787         // Happens in function replacement... didn't allocate
1788         // a return register.
1789     }
1790     else if (retReg == REG_NULL) {
1791         //emitFuncCall allocated tmp; we can use it, but let's see
1792         // if we should keep it around.
1793         retReg = tmp;
1794         // from allocateAndKeep:
1795         if (useCount > 1) {
1796             // If use count is 0 or 1, we don't want to keep
1797             // it around. If it's > 1, then we can keep the node
1798             // (by construction) and want to since there's another
1799             // use later.
1800             gen.tracker()->addKeptRegister(gen, this, retReg);
1801         }
1802     }           
1803     else if (retReg != tmp) {
1804         emitImm(orOp, tmp, 0, retReg, gen, noCost, gen.rs());
1805         gen.rs()->freeRegister(tmp);
1806     }
1807     decUseCount(gen);
1808     return true;
1809 }
1810
1811 bool AstSequenceNode::generateCode_phase2(codeGen &gen, bool noCost,
1812                                           Address &,
1813                                           Register &retReg) {
1814     RETURN_KEPT_REG(retReg);
1815     Register tmp = REG_NULL;
1816     Address unused = ADDR_NULL;
1817     
1818     if (sequence_.size() == 0) {
1819       // Howzat???
1820       return true;
1821     }
1822
1823     for (unsigned i = 0; i < sequence_.size() - 1; i++) {
1824       if (!sequence_[i]->generateCode_phase2(gen,
1825                                                noCost, 
1826                                                unused,
1827                                                tmp)) ERROR_RETURN;
1828         if (sequence_[i]->decRefCount())
1829            gen.rs()->freeRegister(tmp);
1830         tmp = REG_NULL;
1831     }
1832
1833     // We keep the last one
1834     if (!sequence_.back()->generateCode_phase2(gen, noCost, unused, retReg)) ERROR_RETURN;
1835
1836         decUseCount(gen);
1837     
1838     return true;
1839 }
1840
1841 bool AstVariableNode::generateCode_phase2(codeGen &gen, bool noCost,
1842                                           Address &addr,
1843                                           Register &retReg) {
1844
1845     return ast_wrappers_[index]->generateCode_phase2(gen, noCost, addr, retReg);
1846 }
1847
1848 bool AstInsnNode::generateCode_phase2(codeGen &gen, bool,
1849                                       Address &, Register &) {
1850     assert(insn_);
1851    
1852     insnCodeGen::generate(gen,*insn_,gen.addrSpace(),origAddr_,gen.currAddr());
1853     decUseCount(gen);
1854     
1855     return true;
1856 }
1857
1858 bool AstInsnBranchNode::generateCode_phase2(codeGen &gen, bool noCost,
1859                                             Address &, Register & ) {
1860     assert(insn_);
1861     
1862     // Generate side 2 and get the result...
1863     Address targetAddr = ADDR_NULL;
1864     Register targetReg = REG_NULL;
1865     if (target_) {
1866         // TODO: address vs. register...
1867         if (!target_->generateCode_phase2(gen, noCost, targetAddr, targetReg)) ERROR_RETURN;
1868     }
1869     // We'd now generate a fixed or register branch. But we don't. So there.
1870     assert(0 && "Unimplemented");
1871     insnCodeGen::generate(gen,*insn_,gen.addrSpace(), origAddr_, gen.currAddr(), 0, 0);
1872         decUseCount(gen);
1873
1874     return true;
1875 }
1876
1877 bool AstInsnMemoryNode::generateCode_phase2(codeGen &gen, bool noCost,
1878                                             Address &, Register &) {
1879     Register loadReg = REG_NULL;
1880     Register storeReg = REG_NULL;
1881     Address loadAddr = ADDR_NULL;
1882     Address storeAddr = ADDR_NULL;
1883     assert(insn_);
1884
1885     // Step 1: save machine-specific state (AKA flags) and mark registers used in
1886     // the instruction itself as off-limits.
1887
1888     gen.rs()->saveVolatileRegisters(gen);
1889     pdvector<int> usedRegisters;
1890     if (insn_->getUsedRegs(usedRegisters)) {
1891         for (unsigned i = 0; i < usedRegisters.size(); i++) {
1892             gen.rs()->markReadOnly(usedRegisters[i]);
1893         }
1894     }
1895     else {
1896         // We don't know who to avoid... return false?
1897         fprintf(stderr, "WARNING: unknown \"off limits\" register set, returning false from memory modification\n");
1898         return false;
1899     }
1900
1901     // Step 2: generate code (this may spill registers)
1902
1903     if (load_)
1904         if (!load_->generateCode_phase2(gen, noCost, loadAddr, loadReg)) ERROR_RETURN;
1905     
1906     if (store_)
1907         if (!store_->generateCode_phase2(gen, noCost, storeAddr, storeReg)) ERROR_RETURN;
1908
1909     // Step 3: restore flags (before the original instruction)
1910
1911     gen.rs()->restoreVolatileRegisters(gen);
1912
1913     // Step 4: generate the memory instruction
1914     if (!insnCodeGen::generateMem(gen,*insn_,origAddr_, gen.currAddr(), loadReg, storeReg)) {
1915         fprintf(stderr, "ERROR: generateMem call failed\n");
1916         return false;
1917     }
1918
1919     // Step 5: restore any registers that were st0mped. 
1920
1921
1922     gen.rs()->restoreAllRegisters(gen, true);
1923
1924     decUseCount(gen);
1925     return true;
1926 }
1927
1928 bool AstOriginalAddrNode::generateCode_phase2(codeGen &gen,
1929                                               bool noCost,
1930                                               Address &,
1931                                               Register &retReg) {
1932     RETURN_KEPT_REG(retReg);
1933     if (retReg == REG_NULL) {
1934         retReg = allocateAndKeep(gen, noCost);
1935     }
1936     if (retReg == REG_NULL) return false;
1937
1938     emitVload(loadConstOp, 
1939               (Address) gen.point()->addr_compat(),
1940               retReg, retReg, gen, noCost);
1941     return true;
1942 }
1943
1944 bool AstActualAddrNode::generateCode_phase2(codeGen &gen,
1945                                             bool noCost,
1946                                             Address &,
1947                                             Register &retReg) {
1948     if (retReg == REG_NULL) {
1949         retReg = allocateAndKeep(gen, noCost);
1950     }
1951     if (retReg == REG_NULL) return false;
1952
1953     emitVload(loadConstOp, 
1954               (Address) gen.currAddr(),
1955               retReg, retReg, 
1956               gen, noCost);
1957
1958     return true;
1959 }
1960
1961 bool AstDynamicTargetNode::generateCode_phase2(codeGen &gen,
1962                                             bool noCost,
1963                                             Address & retAddr,
1964                                             Register &retReg) 
1965 {
1966     if (gen.point()->type() != instPoint::PreCall &&
1967        gen.point()->type() != instPoint::FuncExit &&
1968        gen.point()->type() != instPoint::PreInsn) 
1969        return false;
1970
1971    InstructionAPI::Instruction::Ptr insn = gen.point()->block()->getInsn(gen.point()->block()->last());
1972    if (insn->getCategory() == c_ReturnInsn) {
1973       // if this is a return instruction our AST reads the top stack value
1974       if (retReg == REG_NULL) {
1975          retReg = allocateAndKeep(gen, noCost);
1976       }
1977       if (retReg == REG_NULL) return false;
1978
1979 #if defined (arch_x86)
1980         emitVload(loadRegRelativeOp, 
1981                   (Address) sizeof(Address), 
1982                   REGNUM_ESP, 
1983                   retReg, 
1984                   gen, noCost);
1985 #elif defined (arch_x86_64) // KEVINTODO: untested
1986         emitVload(loadRegRelativeOp, 
1987                   (Address) sizeof(Address), 
1988                   REGNUM_RSP, 
1989                   retReg, 
1990                   gen, noCost);
1991         bpwarn("WARNING: Untested functionality for x86/64 platform");
1992 #elif defined (arch_power) // KEVINTODO: untested
1993         emitVload(loadRegRelativeOp, 
1994                   (Address) sizeof(Address), 
1995                   REG_SP,
1996                   retReg, 
1997                   gen, noCost);
1998 #else
1999         assert(0);
2000 #endif
2001       return true;
2002    }
2003    else {// this is a dynamic ctrl flow instruction, have
2004       // getDynamicCallSiteArgs generate the necessary AST
2005       pdvector<AstNodePtr> args;
2006       if (!gen.addrSpace()->getDynamicCallSiteArgs(insn, gen.point()->block()->last(), args)) {
2007          return false;
2008       }
2009       if (!args[0]->generateCode_phase2(gen, noCost, retAddr, retReg)) {
2010          return false;
2011       }
2012       return true;                      
2013    }
2014 }
2015
2016
2017 #if defined(AST_PRINT)
2018 std::string getOpString(opCode op)
2019 {
2020     switch (op) {
2021         case plusOp: return("+");
2022         case minusOp: return("-");
2023         case timesOp: return("*");
2024         case divOp: return("/");
2025         case lessOp: return("<");
2026         case leOp: return("<=");
2027         case greaterOp: return(">");
2028         case geOp: return(">=");
2029         case eqOp: return("==");
2030         case neOp: return("!=");
2031         case loadOp: return("lda");
2032         case loadConstOp: return("load");
2033         case storeOp: return("=");
2034         case ifOp: return("if");
2035         case ifMCOp: return("ifMC");
2036         case whileOp: return("while") ;
2037         case doOp: return("while") ;
2038         case trampPreamble: return("preTramp");
2039         case branchOp: return("goto");
2040         case noOp: return("nop");
2041         case andOp: return("and");
2042         case orOp: return("or");
2043         case loadIndirOp: return("load&");
2044         case storeIndirOp: return("=&");
2045         case loadFrameRelativeOp: return("load $fp");
2046         case loadRegRelativeOp: return("load $reg");
2047         case loadFrameAddr: return("$fp");
2048         case storeFrameRelativeOp: return("store $fp");
2049         case getAddrOp: return("&");
2050         default: return("ERROR");
2051     }
2052 }
2053 #endif
2054
2055 #undef MIN
2056 #define MIN(x,y) ((x)>(y) ? (y) : (x))
2057 #undef MAX
2058 #define MAX(x,y) ((x)>(y) ? (x) : (y))
2059 #undef AVG
2060 #define AVG(x,y) (((x)+(y))/2)
2061
2062 int AstOperatorNode::costHelper(enum CostStyleType costStyle) const {
2063     int total = 0;
2064     int getInsnCost(opCode t);
2065     
2066     if (op == ifOp) {
2067         // loperand is the conditional expression
2068         if (loperand) total += loperand->costHelper(costStyle);
2069         total += getInsnCost(op);
2070         int rcost = 0, ecost = 0;
2071         if (roperand) {
2072             rcost = roperand->costHelper(costStyle);
2073             if (eoperand)
2074                 rcost += getInsnCost(branchOp);
2075         }
2076         if (eoperand)
2077             ecost = eoperand->costHelper(costStyle);
2078         if(ecost == 0) { // ie. there's only the if body
2079             if(costStyle      == Min)  total += 0;
2080             //guess half time body not executed
2081             else if(costStyle == Avg)  total += rcost / 2;
2082             else if(costStyle == Max)  total += rcost;
2083         } else {  // ie. there's an else block also, for the statements
2084             if(costStyle      == Min)  total += MIN(rcost, ecost);
2085             else if(costStyle == Avg)  total += AVG(rcost, ecost);
2086             else if(costStyle == Max)  total += MAX(rcost, ecost);
2087         }
2088     } else if (op == storeOp) {
2089         if (roperand) total += roperand->costHelper(costStyle);
2090         total += getInsnCost(op);
2091     } else if (op == storeIndirOp) {
2092         if (loperand) total += loperand->costHelper(costStyle);
2093         if (roperand) total += roperand->costHelper(costStyle);
2094         total += getInsnCost(op);
2095     } else if (op == trampPreamble) {
2096         total = getInsnCost(op);
2097     } else {
2098         if (loperand) 
2099             total += loperand->costHelper(costStyle);
2100         if (roperand) 
2101             total += roperand->costHelper(costStyle);
2102         total += getInsnCost(op);
2103     }
2104     return total;
2105 }
2106
2107 int AstOperandNode::costHelper(enum CostStyleType costStyle) const {
2108     int total = 0;
2109     if (oType == Constant) {
2110         total = getInsnCost(loadConstOp);
2111     } else if (oType == DataIndir) {
2112         total = getInsnCost(loadIndirOp);
2113         total += operand()->costHelper(costStyle);
2114     } else if (oType == DataAddr) {
2115         total = getInsnCost(loadOp);
2116     } else if (oType == DataReg) {
2117         total = getInsnCost(loadIndirOp);
2118     } else if (oType == Param || oType == ParamAtCall || oType == ParamAtEntry) {
2119         total = getInsnCost(getParamOp);
2120     }
2121     return total;
2122 }
2123
2124 int AstCallNode::costHelper(enum CostStyleType costStyle) const {
2125     int total = 0;
2126     if (func_) total += getPrimitiveCost(func_->prettyName().c_str());
2127     else total += getPrimitiveCost(func_name_);
2128
2129     for (unsigned u = 0; u < args_.size(); u++)
2130         if (args_[u]) total += args_[u]->costHelper(costStyle);
2131     return total;
2132 }
2133     
2134
2135 int AstSequenceNode::costHelper(enum CostStyleType costStyle) const {
2136     int total = 0;
2137     for (unsigned i = 0; i < sequence_.size(); i++) {
2138         total += sequence_[i]->costHelper(costStyle);
2139     }
2140
2141     return total;
2142 }
2143
2144 int AstVariableNode::costHelper(enum CostStyleType /*costStyle*/) const{
2145     int total = 0;
2146     return total;
2147 }
2148
2149 #if defined(AST_PRINT)
2150 void AstNode::print() const {
2151   if (this) {
2152 #if defined(ASTDEBUG)
2153     bpfatal("{%d}", referenceCount) ;
2154 #endif
2155     if (type == operandNode) {
2156       if (oType == Constant) {
2157         fprintf(stderr,"%d", (int)(Address) oValue);
2158       } else if (oType == ConstantString) {
2159         fprintf(stderr," %s", (char *)oValue);
2160       } else if (oType == DataIndir) {
2161         fprintf(stderr," @[");
2162         loperand->print();
2163         fprintf(stderr,"]");
2164       } else if (oType == DataReg) {
2165         fprintf(stderr," reg%d ",(int)(Address)oValue);
2166         loperand->print();
2167       } else if (oType == Param || oType == ParamAtCall || oType == ParamAtEntry) {
2168         fprintf(stderr," param[%d]", (int)(Address) oValue);
2169       } else if (oType == ReturnVal) {
2170         fprintf(stderr,"retVal");
2171       } else if (oType == ReturnAddr) {
2172         fprintf(stderr, "retAddr");
2173       } else if (oType == DataAddr)  {
2174         if(!oVar)
2175         {
2176           fprintf(stderr," [0x%lx]", (long) oValue);
2177         }
2178         else
2179         {
2180           fprintf(stderr," [%s]", oVar->symTabName().c_str());
2181         }
2182         
2183       } else if (oType == FrameAddr)  {
2184         fprintf(stderr," [$fp + %d]", (int)(Address) oValue);
2185       } else if (oType == RegOffset)  {
2186         fprintf(stderr," [$%d + %d]", (int)(Address) loperand->getOValue(), (int)(Address) oValue);
2187       } else if (oType == EffectiveAddr)  {
2188         fprintf(stderr," <<effective address>>");
2189       } else if (oType == BytesAccessed)  {
2190         fprintf(stderr," <<bytes accessed>>");
2191       } else {
2192         fprintf(stderr," <Unknown Operand>");
2193       }
2194     } else if (type == opCodeNode_t) {
2195       cerr << "(" << getOpString(op);
2196       if (loperand) loperand->print();
2197       if (roperand) roperand->print();
2198       if (eoperand) eoperand->print();
2199       fprintf(stderr,")\n");
2200     } else if (type == callNode) {
2201       cerr << "(" << callee;
2202       for (unsigned u = 0; u < operands.size(); u++)
2203          operands[u]->print();
2204       fprintf(stderr,")\n");
2205     } else if (type == sequenceNode_t) {
2206        if (loperand) loperand->print();
2207        fprintf(stderr,",");
2208        if (roperand) roperand->print();
2209        fprintf(stderr,"\n");
2210     }
2211   }
2212 }
2213 #endif
2214
2215 BPatch_type *AstNode::checkType() {
2216     return BPatch::bpatch->type_Untyped;
2217 }
2218
2219 BPatch_type *AstOperatorNode::checkType() {
2220     BPatch_type *ret = NULL;
2221     BPatch_type *lType = NULL, *rType = NULL, *eType = NULL;
2222     bool errorFlag = false;
2223
2224     assert(BPatch::bpatch != NULL);     /* We'll use this later. */
2225
2226     if ((loperand || roperand) && getType()) {
2227         // something has already set the type for us.
2228         // this is likely an expression for array access
2229        ret = const_cast<BPatch_type *>(getType());
2230        return ret;
2231     }
2232
2233     if (loperand) lType = loperand->checkType();
2234
2235     if (roperand) rType = roperand->checkType();
2236
2237     if (eoperand) eType = eoperand->checkType();
2238
2239     if (lType == BPatch::bpatch->type_Error ||
2240         rType == BPatch::bpatch->type_Error)
2241        errorFlag = true;
2242     
2243     switch (op) {
2244     case ifOp:
2245         // XXX No checking for now.  Should check that loperand
2246         // is boolean.
2247         ret = BPatch::bpatch->type_Untyped;
2248         break;
2249     case noOp:
2250         ret = BPatch::bpatch->type_Untyped;
2251         break;
2252     case funcJumpOp:
2253         ret = BPatch::bpatch->type_Untyped;
2254         break;
2255     case getAddrOp:
2256         // Should set type to the infered type not just void * 
2257         //  - jkh 7/99
2258         ret = BPatch::bpatch->stdTypes->findType("void *");
2259         assert(ret != NULL);
2260         break;
2261     default:
2262         // XXX The following line must change to decide based on the
2263         // types and operation involved what the return type of the
2264         // expression will be.
2265         ret = lType;
2266         if (lType != NULL && rType != NULL) {
2267             if (!lType->isCompatible(rType)) {
2268                 fprintf(stderr, "WARNING: LHS type %s not compatible with RHS type %s\n",
2269                         lType->getName(), rType->getName());
2270                 errorFlag = true;
2271             }
2272         }
2273         break;
2274     }
2275     assert (ret != NULL);
2276
2277     if (errorFlag && doTypeCheck) {
2278        ret = BPatch::bpatch->type_Error;
2279     } else if (errorFlag) {
2280        ret = BPatch::bpatch->type_Untyped;
2281     }
2282
2283 #if defined(ASTDEBUG)
2284     // it would be useful to have some indication of what the type applied to
2285     // (currently it appears to be copious amounts of contextless junk)
2286     if (ret) {
2287        logLine(" type is ");
2288        if (ret->getName()){ 
2289           logLine(ret->getName());
2290        } else {
2291           logLine(" <NULL Name String>");
2292           logLine("\n");
2293        }
2294     }
2295 #endif
2296
2297     // remember what type we are
2298     setType(ret);
2299
2300     return ret;
2301 }
2302
2303 BPatch_type *AstOperandNode::checkType()
2304 {
2305     BPatch_type *ret = NULL;
2306     BPatch_type *type = NULL;
2307     bool errorFlag = false;
2308     
2309     assert(BPatch::bpatch != NULL);     /* We'll use this later. */
2310
2311     if (operand_ && getType()) {
2312        // something has already set the type for us.
2313        // this is likely an expression for array access
2314        ret = const_cast<BPatch_type *>(getType());
2315        return ret;
2316     }
2317     
2318     if (operand_) type = operand_->checkType();
2319
2320     if (type == BPatch::bpatch->type_Error)
2321        errorFlag = true;
2322     
2323     if (oType == DataIndir) {
2324         // XXX Should really be pointer to lType -- jkh 7/23/99
2325         ret = BPatch::bpatch->type_Untyped;
2326     } 
2327     else if ((oType == Param) || (oType == ParamAtCall) || 
2328              (oType == ParamAtEntry) || (oType == ReturnVal) 
2329              || (oType == ReturnAddr)) {
2330             // XXX Params and ReturnVals untyped for now
2331       // ReturnAddr should be void *, probably
2332         ret = BPatch::bpatch->type_Untyped; 
2333     }
2334     else if ((oType == origRegister)) {
2335         ret = BPatch::bpatch->stdTypes->findType("int");
2336     }
2337     else {
2338         ret = const_cast<BPatch_type *>(getType());
2339     }
2340     assert(ret != NULL);
2341
2342     if (errorFlag && doTypeCheck) {
2343        ret = BPatch::bpatch->type_Error;
2344     } else if (errorFlag) {
2345        ret = BPatch::bpatch->type_Untyped;
2346     }
2347
2348 #if defined(ASTDEBUG)
2349     // it would be useful to have some indication of what the type applied to
2350     // (currently it appears to be copious amounts of contextless junk)
2351     if (ret) {
2352         logLine(" type is ");
2353         if (ret->getName()) 
2354              logLine(ret->getName());
2355         else
2356              logLine(" <NULL Name String>");
2357         logLine("\n");
2358     }
2359 #endif
2360
2361     // remember what type we are
2362     setType(ret);
2363
2364     return ret;
2365
2366 }
2367
2368
2369 BPatch_type *AstCallNode::checkType() {
2370     BPatch_type *ret = NULL;
2371     bool errorFlag = false;
2372     
2373     assert(BPatch::bpatch != NULL);     /* We'll use this later. */
2374     
2375     unsigned i;
2376     for (i = 0; i < args_.size(); i++) {
2377         BPatch_type *operandType = args_[i]->checkType();
2378         /* XXX Check operands for compatibility */
2379         if (operandType == BPatch::bpatch->type_Error) {
2380             errorFlag = true;
2381         }
2382     }
2383     /* XXX Should set to return type of function. */
2384     ret = BPatch::bpatch->type_Untyped;
2385
2386     assert(ret != NULL);
2387
2388     if (errorFlag && doTypeCheck) {
2389        ret = BPatch::bpatch->type_Error;
2390     } else if (errorFlag) {
2391        ret = BPatch::bpatch->type_Untyped;
2392     }
2393
2394 #if defined(ASTDEBUG)
2395     // it would be useful to have some indication of what the type applied to
2396     // (currently it appears to be copious amounts of contextless junk)
2397     if (ret) {
2398         logLine(" type is ");
2399         if (ret->getName()) 
2400              logLine(ret->getName());
2401         else
2402              logLine(" <NULL Name String>");
2403         logLine("\n");
2404     }
2405 #endif
2406
2407     // remember what type we are
2408     setType(ret);
2409
2410     return ret;
2411 }
2412
2413 BPatch_type *AstSequenceNode::checkType() {
2414     BPatch_type *ret = NULL;
2415     BPatch_type *sType = NULL;
2416     bool errorFlag = false;
2417     
2418     assert(BPatch::bpatch != NULL);     /* We'll use this later. */
2419
2420     if (getType()) {
2421         // something has already set the type for us.
2422         // this is likely an expression for array access
2423         ret = const_cast<BPatch_type *>(getType());
2424         return ret;
2425     }
2426
2427     for (unsigned i = 0; i < sequence_.size(); i++) {
2428         sType = sequence_[i]->checkType();
2429         if (sType == BPatch::bpatch->type_Error)
2430             errorFlag = true;
2431     }
2432
2433     ret = sType;
2434
2435     assert(ret != NULL);
2436     
2437     if (errorFlag && doTypeCheck) {
2438         ret = BPatch::bpatch->type_Error;
2439     } else if (errorFlag) {
2440         ret = BPatch::bpatch->type_Untyped;
2441     }
2442     
2443 #if defined(ASTDEBUG)
2444     // it would be useful to have some indication of what the type applied to
2445     // (currently it appears to be copious amounts of contextless junk)
2446     if (ret) {
2447         logLine(" type is ");
2448         if (ret->getName()) 
2449              logLine(ret->getName());
2450         else
2451              logLine(" <NULL Name String>");
2452         logLine("\n");
2453     }
2454 #endif
2455
2456     // remember what type we are
2457     setType(ret);
2458
2459     return ret;
2460 }
2461
2462 bool AstNode::accessesParam() {
2463 #if 0
2464     fprintf(stderr, "Undefined call to getChildren for type: ");
2465     if (dynamic_cast<AstNullNode *>(this)) fprintf(stderr, "nullNode\n");
2466     else if (dynamic_cast<AstOperatorNode *>(this)) fprintf(stderr, "operatorNode\n");
2467     else if (dynamic_cast<AstOperandNode *>(this)) fprintf(stderr, "operandNode\n");
2468     else if (dynamic_cast<AstCallNode *>(this)) fprintf(stderr, "callNode\n");
2469     else if (dynamic_cast<AstSequenceNode *>(this)) fprintf(stderr, "seqNode\n");
2470     else if (dynamic_cast<AstVariableNode *>(this)) fprintf(stderr, "varNode\n");
2471     else if (dynamic_cast<AstInsnNode *>(this)) fprintf(stderr, "insnNode\n");
2472     else if (dynamic_cast<AstMiniTrampNode *>(this)) fprintf(stderr, "miniTrampNode\n");
2473     else if (dynamic_cast<AstMemoryNode *>(this)) fprintf(stderr, "memoryNode\n");
2474     else fprintf(stderr, "unknownNode\n");
2475 #endif
2476     return false;
2477 }
2478
2479
2480 // This is not the most efficient way to traverse a DAG
2481 bool AstOperatorNode::accessesParam()
2482 {
2483     bool ret = false;
2484     if (loperand)
2485         ret |= loperand->accessesParam();
2486     if (roperand)
2487         ret |= roperand->accessesParam();
2488     if (eoperand)
2489         ret |= eoperand->accessesParam();
2490     return ret;
2491 }
2492
2493
2494 bool AstCallNode::accessesParam() {
2495     for (unsigned i = 0; i < args_.size(); i++) {
2496         if (args_[i]->accessesParam())
2497             return true;
2498     }
2499     return false;
2500 }
2501
2502 bool AstSequenceNode::accessesParam() {
2503     for (unsigned i = 0; i < sequence_.size(); i++) {
2504         if (sequence_[i]->accessesParam())
2505             return true;
2506     }
2507     return false;
2508 }
2509
2510 bool AstVariableNode::accessesParam() {
2511     return ast_wrappers_[index]->accessesParam();
2512 }
2513
2514 // Our children may have incorrect useCounts (most likely they 
2515 // assume that we will not bother them again, which is wrong)
2516 void AstNode::fixChildrenCounts()
2517 {
2518     pdvector<AstNodePtr> children;
2519     getChildren(children);
2520     for (unsigned i=0; i<children.size(); i++) {
2521                 children[i]->setUseCount();
2522     }
2523 }
2524
2525
2526 // Check if the node can be kept at all. Some nodes (e.g., storeOp)
2527 // can not be cached. In fact, there are fewer nodes that can be cached.
2528 bool AstOperatorNode::canBeKept() const {
2529     switch (op) {
2530     case plusOp:
2531     case minusOp:
2532     case timesOp:
2533     case divOp:
2534     case neOp:
2535     case noOp:
2536     case orOp:
2537     case andOp:
2538                 break;
2539     default:
2540         return false;
2541     }
2542
2543     // The switch statement is a little odd, but hey. 
2544     if (loperand && !loperand->canBeKept()) return false;
2545     if (roperand && !roperand->canBeKept()) return false;
2546     if (eoperand && !eoperand->canBeKept()) return false;
2547     
2548     return true;
2549 }
2550
2551 bool AstOperandNode::canBeKept() const {
2552     
2553     switch (oType) {
2554     case DataReg:
2555     case DataIndir:
2556     case RegOffset:
2557     case origRegister:
2558     case DataAddr:
2559     case variableValue:
2560         return false;
2561     default:
2562                 break;
2563     }
2564     if (operand_ && !operand_->canBeKept()) return false;
2565     return true;
2566 }
2567
2568 bool AstCallNode::canBeKept() const {
2569     if (constFunc_) {
2570         for (unsigned i = 0; i < args_.size(); i++) {
2571             if (!args_[i]->canBeKept()) {
2572                 fprintf(stderr, "AST %p: labelled const func but argument %d cannot be kept!\n",
2573                         this, i);
2574                 return false;
2575             }
2576         }
2577         return true;
2578     }
2579     return false;
2580     
2581 }
2582
2583 bool AstSequenceNode::canBeKept() const {
2584         // Theoretically we could keep the entire thing, but... not sure
2585         // that's a terrific idea. For now, don't keep a sequence node around.
2586     return false;
2587 }
2588
2589 bool AstVariableNode::canBeKept() const {
2590     return ast_wrappers_[index]->canBeKept();
2591 }
2592
2593 bool AstMiniTrampNode::canBeKept() const {
2594         // Well... depends on the actual AST, doesn't it.
2595         assert(ast_);
2596         
2597         return ast_->canBeKept();
2598 }
2599
2600 bool AstMemoryNode::canBeKept() const {
2601         // Despite our memory loads, we can be kept;
2602         // we're loading off process state, which is defined
2603         // to be invariant during the instrumentation phase.
2604         return true;
2605 }
2606
2607 // Occasionally, we do not call .generateCode_phase2 for the referenced node, 
2608 // but generate code by hand. This routine decrements its use count properly
2609 void AstNode::decUseCount(codeGen &gen)
2610 {
2611     if (useCount == 0) return;
2612     
2613     useCount--;
2614     
2615     if (useCount == 0) {
2616         gen.tracker()->removeKeptRegister(gen, this);
2617     }
2618 }
2619
2620 // Return all children of this node ([lre]operand, ..., operands[])
2621
2622 void AstNode::getChildren(pdvector<AstNodePtr > &) {
2623 #if 0
2624     fprintf(stderr, "Undefined call to getChildren for type: ");
2625     if (dynamic_cast<AstNullNode *>(this)) fprintf(stderr, "nullNode\n");
2626     else if (dynamic_cast<AstOperatorNode *>(this)) fprintf(stderr, "operatorNode\n");
2627     else if (dynamic_cast<AstOperandNode *>(this)) fprintf(stderr, "operandNode\n");
2628     else if (dynamic_cast<AstCallNode *>(this)) fprintf(stderr, "callNode\n");
2629     else if (dynamic_cast<AstSequenceNode *>(this)) fprintf(stderr, "seqNode\n");
2630     else if (dynamic_cast<AstInsnNode *>(this)) fprintf(stderr, "insnNode\n");
2631     else if (dynamic_cast<AstMiniTrampNode *>(this)) fprintf(stderr, "miniTrampNode\n");
2632     else if (dynamic_cast<AstMemoryNode *>(this)) fprintf(stderr, "memoryNode\n");
2633     else fprintf(stderr, "unknownNode\n");
2634 #endif
2635 }
2636
2637 void AstNode::setChildren(pdvector<AstNodePtr > &) {
2638 #if 0
2639     fprintf(stderr, "Undefined call to setChildren for type: ");
2640     if (dynamic_cast<AstNullNode *>(this)) fprintf(stderr, "nullNode\n");
2641     else if (dynamic_cast<AstOperatorNode *>(this)) fprintf(stderr, "operatorNode\n");
2642     else if (dynamic_cast<AstOperandNode *>(this)) fprintf(stderr, "operandNode\n");
2643     else if (dynamic_cast<AstCallNode *>(this)) fprintf(stderr, "callNode\n");
2644     else if (dynamic_cast<AstSequenceNode *>(this)) fprintf(stderr, "seqNode\n");
2645     else if (dynamic_cast<AstInsnNode *>(this)) fprintf(stderr, "insnNode\n");
2646     else if (dynamic_cast<AstMiniTrampNode *>(this)) fprintf(stderr, "miniTrampNode\n");
2647     else if (dynamic_cast<AstMemoryNode *>(this)) fprintf(stderr, "memoryNode\n");
2648     else fprintf(stderr, "unknownNode\n");
2649 #endif
2650 }
2651
2652 void AstOperatorNode::getChildren(pdvector<AstNodePtr > &children) {
2653     if (loperand) children.push_back(loperand);
2654     if (roperand) children.push_back(roperand);
2655     if (eoperand) children.push_back(eoperand);
2656 }
2657
2658 void AstOperatorNode::setChildren(pdvector<AstNodePtr > &children){
2659    int count = (loperand ? 1 : 0) + (roperand ? 1 : 0) + (eoperand ? 1 : 0); 
2660    if ((int)children.size() == count){
2661       //memory management?
2662       if (loperand) loperand = children[0];
2663       if (roperand) roperand = children[1];
2664       if (eoperand) eoperand = children[2];
2665    }else{
2666       fprintf(stderr, "OPERATOR setChildren given bad arguments. Wanted:%d , given:%d\n", count, (int)children.size());      
2667    }
2668 }
2669
2670 AstNodePtr AstOperatorNode::deepCopy(){
2671    AstNodePtr copy = operatorNode(op, (loperand ? loperand->deepCopy() : loperand),
2672                                   (roperand ? roperand->deepCopy() : roperand),
2673                                   (eoperand ? eoperand->deepCopy() : eoperand));
2674    copy->setType(bptype);
2675    copy->setTypeChecking(doTypeCheck);
2676
2677    copy->setLineNum(getLineNum());
2678    copy->setColumnNum(getColumnNum());
2679    copy->setSnippetName(snippetName);
2680
2681 /* TODO: Impliment this copy.
2682    copy->columnInfoSet = columnInfoSet
2683    copy->lineInfoSet = lineInfoSet;
2684 */
2685    return copy;
2686 }
2687
2688 void AstOperandNode::getChildren(pdvector<AstNodePtr > &children) {
2689     if (operand_) children.push_back(operand_);
2690 }
2691
2692 void AstOperandNode::setChildren(pdvector<AstNodePtr > &children){
2693    if (children.size() == 1){
2694       //memory management?
2695       operand_ = children[0];
2696    }else{
2697       fprintf(stderr, "OPERAND setChildren given bad arguments. Wanted:%d , given:%d\n", 1,  (int)children.size());      
2698    }
2699 }
2700
2701 AstNodePtr AstOperandNode::deepCopy(){
2702    AstOperandNode * copy = new AstOperandNode();
2703    copy->oType = oType;
2704    copy->oValue = oValue; //this might need to be copied deeper
2705    copy->oVar = oVar;
2706    if(operand_) copy->operand_ = operand_->deepCopy();
2707
2708    copy->setType(bptype);
2709    copy->setTypeChecking(doTypeCheck);
2710
2711    copy->setLineNum(getLineNum());
2712    copy->lineInfoSet = lineInfoSet;
2713    copy->setColumnNum(getColumnNum());
2714    copy->columnInfoSet = columnInfoSet;
2715    copy->setSnippetName(getSnippetName());
2716    return AstNodePtr(copy);
2717 }
2718
2719 void AstCallNode::getChildren(pdvector<AstNodePtr > &children) {
2720     for (unsigned i = 0; i < args_.size(); i++)
2721         children.push_back(args_[i]);
2722 }
2723
2724 void AstCallNode::setChildren(pdvector<AstNodePtr > &children){
2725    if (children.size() == args_.size()){
2726       //memory management?
2727       for (unsigned i = 0; i < args_.size(); i++){
2728          AstNodePtr * newNode = new AstNodePtr(children[i]);
2729          args_.push_back(*newNode);
2730          args_.erase(args_.begin() + i + 1);
2731       }
2732    }else{
2733       fprintf(stderr, "CALL setChildren given bad arguments. Wanted:%d , given:%d\n",  (int)args_.size(),  (int)children.size());      
2734    }
2735 }
2736
2737 AstNodePtr AstCallNode::deepCopy(){
2738    pdvector<AstNodePtr> empty_args;
2739
2740    AstCallNode * copy;
2741
2742    if(func_name_.empty()){
2743       copy = new AstCallNode();
2744    }else{
2745       copy = new AstCallNode(func_name_, empty_args);
2746    }
2747 //   copy->func_name_ = func_name_;
2748    copy->func_addr_ = func_addr_; 
2749    copy->func_ = func_;
2750
2751    for(unsigned int i = 0; i < args_.size(); ++i){
2752       copy->args_.push_back(args_[i]->deepCopy());
2753    }
2754   
2755    copy->callReplace_ = callReplace_;
2756    copy->constFunc_ = constFunc_;
2757
2758    copy->setType(bptype);
2759    copy->setTypeChecking(doTypeCheck);
2760
2761    copy->setLineNum(getLineNum());
2762    copy->lineInfoSet = lineInfoSet;
2763    copy->setColumnNum(getColumnNum());
2764    copy->columnInfoSet = columnInfoSet;
2765    copy->setSnippetName(getSnippetName());
2766    copy->snippetNameSet = snippetNameSet;
2767
2768    return AstNodePtr(copy);
2769 }
2770
2771 void AstSequenceNode::getChildren(pdvector<AstNodePtr > &children) {
2772     for (unsigned i = 0; i < sequence_.size(); i++)
2773         children.push_back(sequence_[i]);
2774 }
2775
2776 void AstSequenceNode::setChildren(pdvector<AstNodePtr > &children){
2777    if (children.size() == sequence_.size()){
2778       //memory management?
2779       for (unsigned i = 0; i < sequence_.size(); i++){
2780          AstNodePtr * newNode = new AstNodePtr(children[i]);
2781          sequence_.push_back(*newNode);
2782          sequence_.erase(sequence_.begin() + i + 1);
2783       }
2784    }else{
2785       fprintf(stderr, "SEQ setChildren given bad arguments. Wanted:%d , given:%d\n", (int)sequence_.size(),  (int)children.size());      
2786    }
2787 }
2788
2789 AstNodePtr AstSequenceNode::deepCopy(){
2790    AstSequenceNode * copy = new AstSequenceNode();
2791    for(unsigned int i = 0; i < sequence_.size(); ++i){
2792       copy->sequence_.push_back(sequence_[i]->deepCopy());
2793    }
2794
2795    copy->setType(bptype);
2796    copy->setTypeChecking(doTypeCheck);
2797
2798    copy->setLineNum(getLineNum());
2799    copy->lineInfoSet = lineInfoSet;
2800    copy->setColumnNum(getColumnNum());
2801    copy->columnInfoSet = columnInfoSet;
2802    copy->setSnippetName(getSnippetName());
2803    copy->snippetNameSet = snippetNameSet;
2804
2805    return AstNodePtr(copy);
2806 }
2807
2808 void AstVariableNode::getChildren(pdvector<AstNodePtr > &children) {
2809     ast_wrappers_[index]->getChildren(children);
2810 }
2811
2812 void AstVariableNode::setChildren(pdvector<AstNodePtr > &children){
2813    ast_wrappers_[index]->setChildren(children);
2814 }
2815
2816 AstNodePtr AstVariableNode::deepCopy(){
2817    AstVariableNode * copy = new AstVariableNode();
2818    copy->index = index;
2819    copy->ranges_ = ranges_; //i'm not sure about this one. (it's a vector)
2820    for(unsigned int i = 0; i < ast_wrappers_.size(); ++i){
2821       copy->ast_wrappers_.push_back(ast_wrappers_[i]->deepCopy());
2822    }
2823
2824    copy->setType(bptype);
2825    copy->setTypeChecking(doTypeCheck);
2826
2827    copy->setLineNum(getLineNum());
2828    copy->lineInfoSet = lineInfoSet;
2829    copy->setColumnNum(getColumnNum());
2830    copy->columnInfoSet = columnInfoSet;
2831    copy->setSnippetName(getSnippetName());
2832    copy->snippetNameSet = snippetNameSet;
2833
2834    return AstNodePtr(copy);
2835 }
2836
2837 void AstMiniTrampNode::getChildren(pdvector<AstNodePtr > &children) {
2838     children.push_back(ast_);
2839 }
2840
2841 void AstMiniTrampNode::setChildren(pdvector<AstNodePtr > &children){
2842    if (children.size() == 1){
2843       //memory management?
2844       ast_ = children[0];
2845    }else{
2846  fprintf(stderr, "MINITRAMP setChildren given bad arguments. Wanted:%d , given:%d\n", 1,  (int)children.size());      
2847    }
2848 }
2849
2850 AstNodePtr AstMiniTrampNode::deepCopy(){
2851    AstMiniTrampNode * copy = new AstMiniTrampNode();
2852    copy->inline_ = inline_;
2853    copy->ast_ = ast_->deepCopy();
2854
2855    copy->setType(bptype);
2856    copy->setTypeChecking(doTypeCheck);
2857
2858    copy->setLineNum(getLineNum());
2859    copy->lineInfoSet = lineInfoSet;
2860    copy->setColumnNum(getColumnNum());
2861    copy->columnInfoSet = columnInfoSet;
2862    copy->setSnippetName(getSnippetName());
2863    copy->snippetNameSet = snippetNameSet;
2864
2865    return AstNodePtr(copy);
2866 }
2867
2868
2869 void AstOperatorNode::setVariableAST(codeGen &g) {
2870     if(loperand) loperand->setVariableAST(g);
2871     if(roperand) roperand->setVariableAST(g);
2872     if(eoperand) eoperand->setVariableAST(g);
2873 }
2874
2875 void AstOperandNode::setVariableAST(codeGen &g){
2876     if(operand_) operand_->setVariableAST(g);
2877 }
2878
2879 void AstCallNode::setVariableAST(codeGen &g){
2880     for (unsigned i = 0; i < args_.size(); i++)
2881         args_[i]->setVariableAST(g);
2882 }
2883
2884 void AstSequenceNode::setVariableAST(codeGen &g) {
2885     for (unsigned i = 0; i < sequence_.size(); i++)
2886         sequence_[i]->setVariableAST(g);
2887 }
2888
2889 void AstVariableNode::setVariableAST(codeGen &gen){
2890     //fprintf(stderr, "Generating code for variable in function %s with start address 0x%lx at address 0x%lx\n",gen.func()->prettyName().c_str(), gen.func()->getAddress(),gen.point()->addr());
2891     if(!ranges_)
2892         return;
2893     if(!gen.point())    //oneTimeCode. Set the AST at the beginning of the function??
2894     {
2895         index = 0;
2896         return;
2897     }
2898     Address addr = gen.point()->addr_compat();     //Offset of inst point from function base address
2899     for(unsigned i=0; i< ranges_->size();i++){
2900         if((*ranges_)[i].first<=addr && addr<(*ranges_)[i].second)
2901             index = i;
2902     }
2903 }
2904
2905 void AstInsnBranchNode::setVariableAST(codeGen &g){
2906     if(target_) target_->setVariableAST(g);
2907 }
2908
2909 void AstInsnMemoryNode::setVariableAST(codeGen &g){
2910     if(load_) load_->setVariableAST(g);
2911     if(store_) store_->setVariableAST(g);
2912 }
2913
2914 void AstMiniTrampNode::setVariableAST(codeGen &g){
2915     if(ast_) ast_->setVariableAST(g);
2916 }
2917
2918 bool AstCallNode::containsFuncCall() const {
2919    return true;
2920 }
2921
2922
2923
2924 bool AstOperatorNode::containsFuncCall() const {
2925         if (loperand && loperand->containsFuncCall()) return true;
2926         if (roperand && roperand->containsFuncCall()) return true;
2927         if (eoperand && eoperand->containsFuncCall()) return true;
2928         return false;
2929 }
2930
2931 bool AstOperandNode::containsFuncCall() const {
2932         if (operand_ && operand_->containsFuncCall()) return true;
2933         return false;
2934 }
2935
2936 bool AstMiniTrampNode::containsFuncCall() const {
2937         if (ast_ && ast_->containsFuncCall()) return true;
2938         return false;
2939 }
2940
2941 bool AstSequenceNode::containsFuncCall() const {
2942         for (unsigned i = 0; i < sequence_.size(); i++) {
2943                 if (sequence_[i]->containsFuncCall()) return true;
2944         }
2945         return false;
2946 }
2947
2948 bool AstVariableNode::containsFuncCall() const 
2949 {
2950     return ast_wrappers_[index]->containsFuncCall();
2951 }
2952
2953 bool AstInsnMemoryNode::containsFuncCall() const {
2954     if (load_ && load_->containsFuncCall()) return true;
2955     if (store_ && store_->containsFuncCall()) return true;
2956     return false;
2957 }
2958
2959 bool AstNullNode::containsFuncCall() const
2960 {
2961    return false;
2962 }
2963
2964 bool AstLabelNode::containsFuncCall() const
2965 {
2966    return false;
2967 }
2968
2969 bool AstMemoryNode::containsFuncCall() const
2970 {
2971    return false;
2972 }
2973
2974 bool AstInsnNode::containsFuncCall() const
2975 {
2976    return false;
2977 }
2978
2979 bool AstOriginalAddrNode::containsFuncCall() const
2980 {
2981    return false;
2982 }
2983
2984 bool AstActualAddrNode::containsFuncCall() const
2985 {
2986    return false;
2987 }
2988
2989 bool AstDynamicTargetNode::containsFuncCall() const
2990 {
2991    return false;
2992 }
2993
2994 static void setCFJRet(cfjRet_t &a, cfjRet_t b) {
2995    //cfj_call takes priority over cfj_jump
2996    int a_i = (int) a;
2997    int b_i = (int) b;
2998    if (b_i > a_i)
2999       a = b;
3000 }
3001
3002 cfjRet_t AstCallNode::containsFuncJump() const {
3003    return cfj_none;
3004 }
3005
3006 cfjRet_t AstOperatorNode::containsFuncJump() const {
3007    cfjRet_t ret = cfj_none;
3008         if (loperand) setCFJRet(ret, loperand->containsFuncJump());
3009         if (roperand) setCFJRet(ret, roperand->containsFuncJump());
3010         if (eoperand) setCFJRet(ret, eoperand->containsFuncJump());
3011         return ret;
3012 }
3013
3014 cfjRet_t AstOperandNode::containsFuncJump() const {
3015    cfjRet_t ret = cfj_none;
3016         if (operand_) setCFJRet(ret, operand_->containsFuncJump());
3017         return ret;
3018 }
3019
3020 cfjRet_t AstMiniTrampNode::containsFuncJump() const {
3021    cfjRet_t ret = cfj_none;
3022    if (ast_) setCFJRet(ret, ast_->containsFuncJump());
3023         return ret;
3024 }
3025
3026 cfjRet_t AstSequenceNode::containsFuncJump() const {
3027    cfjRet_t ret = cfj_none;
3028         for (unsigned i = 0; i < sequence_.size(); i++) {
3029                 setCFJRet(ret, sequence_[i]->containsFuncJump());
3030         }
3031         return ret;
3032 }
3033
3034 cfjRet_t AstVariableNode::containsFuncJump() const 
3035 {
3036     return ast_wrappers_[index]->containsFuncJump();
3037 }
3038
3039 cfjRet_t AstInsnMemoryNode::containsFuncJump() const {
3040    cfjRet_t ret = cfj_none;
3041    if (load_) setCFJRet(ret, load_->containsFuncJump());
3042    if (store_) setCFJRet(ret, store_->containsFuncJump());
3043    return ret;
3044 }
3045
3046 cfjRet_t AstNullNode::containsFuncJump() const
3047 {
3048    return cfj_none;
3049 }
3050
3051 cfjRet_t AstLabelNode::containsFuncJump() const
3052 {
3053    return cfj_none;
3054 }
3055
3056 cfjRet_t AstMemoryNode::containsFuncJump() const
3057 {
3058    return cfj_none;
3059 }
3060
3061 cfjRet_t AstInsnNode::containsFuncJump() const
3062 {
3063    return cfj_none;
3064 }
3065
3066 cfjRet_t AstOriginalAddrNode::containsFuncJump() const
3067 {
3068    return cfj_none;
3069 }
3070
3071 cfjRet_t AstActualAddrNode::containsFuncJump() const
3072 {
3073    return cfj_none;
3074 }
3075
3076 cfjRet_t AstDynamicTargetNode::containsFuncJump() const
3077 {
3078    return cfj_none;
3079 }
3080
3081 bool AstCallNode::usesAppRegister() const {
3082    for (unsigned i=0; i<args_.size(); i++) {
3083       if (args_[i] && args_[i]->usesAppRegister()) return true;
3084    }
3085    return false;
3086 }
3087
3088 bool AstOperatorNode::usesAppRegister() const {
3089         if (loperand && loperand->usesAppRegister()) return true;
3090         if (roperand && roperand->usesAppRegister()) return true;
3091         if (eoperand && eoperand->usesAppRegister()) return true;
3092         return false;
3093 }
3094
3095 bool AstOperandNode::usesAppRegister() const {
3096    if (oType == AstNode::FrameAddr ||
3097        oType == AstNode::RegOffset ||
3098        oType == AstNode::origRegister ||
3099        oType == AstNode::Param ||
3100        oType == AstNode::ParamAtEntry ||
3101        oType == AstNode::ParamAtCall ||
3102        oType == AstNode::ReturnVal)
3103    {
3104       return true;
3105    }
3106
3107    if (operand_ && operand_->usesAppRegister()) return true;
3108    return false;
3109 }
3110
3111 bool AstMiniTrampNode::usesAppRegister() const {
3112         if (ast_ && ast_->usesAppRegister()) return true;
3113         return false;
3114 }
3115
3116 bool AstSequenceNode::usesAppRegister() const {
3117         for (unsigned i = 0; i < sequence_.size(); i++) {
3118                 if (sequence_[i]->usesAppRegister()) return true;
3119         }
3120         return false;
3121 }
3122
3123 bool AstVariableNode::usesAppRegister() const 
3124 {
3125     return ast_wrappers_[index]->usesAppRegister();
3126 }
3127
3128 bool AstInsnMemoryNode::usesAppRegister() const {
3129     if (load_ && load_->usesAppRegister()) return true;
3130     if (store_ && store_->usesAppRegister()) return true;
3131     return false;
3132 }
3133
3134 bool AstNullNode::usesAppRegister() const
3135 {
3136    return false;
3137 }
3138
3139 bool AstLabelNode::usesAppRegister() const
3140 {
3141    return false;
3142 }
3143
3144 bool AstDynamicTargetNode::usesAppRegister() const
3145 {
3146    return false;
3147 }
3148
3149 bool AstActualAddrNode::usesAppRegister() const
3150 {
3151    return false;
3152 }
3153
3154 bool AstOriginalAddrNode::usesAppRegister() const
3155 {
3156    return false;
3157 }
3158
3159 bool AstMemoryNode::usesAppRegister() const
3160 {
3161    return true;
3162 }
3163
3164 bool AstInsnNode::usesAppRegister() const
3165 {
3166    return true;
3167 }
3168
3169 void regTracker_t::addKeptRegister(codeGen &gen, AstNode *n, Register reg) {
3170         assert(n);
3171         if (tracker.find(n)) {
3172                 assert(tracker[n].keptRegister == reg);
3173                 return;
3174         }
3175         commonExpressionTracker t;
3176         t.keptRegister = reg;
3177         t.keptLevel = condLevel;
3178         tracker[n] = t;
3179         gen.rs()->markKeptRegister(reg);
3180 }
3181
3182 void regTracker_t::removeKeptRegister(codeGen &gen, AstNode *n) {
3183         if (!tracker.find(n)) {
3184                 return;
3185         }
3186         gen.rs()->unKeepRegister(tracker[n].keptRegister);
3187         tracker.undef(n);
3188 }
3189
3190 Register regTracker_t::hasKeptRegister(AstNode *n) {
3191         if (tracker.find(n))
3192                 return tracker[n].keptRegister;
3193         return REG_NULL;        
3194 }
3195
3196 // Find if the given register is "owned" by an AST node,
3197 // and if so nuke it.
3198
3199 bool regTracker_t::stealKeptRegister(Register r) {
3200         AstNode *a;
3201         commonExpressionTracker c;
3202         ast_printf("STEALING kept register %d for someone else\n", r);
3203         dictionary_hash_iter<AstNode *, commonExpressionTracker> reg_iter(tracker);
3204         while (reg_iter.next(a, c)) {
3205             if (c.keptRegister == r) {
3206                 tracker.undef(a);
3207                 return true;
3208             }
3209         }
3210         fprintf(stderr, "Odd - couldn't find kept register %d\n", r);
3211         return true;
3212 }
3213
3214 void regTracker_t::reset() {
3215         condLevel = 0;
3216         tracker.clear();
3217 }
3218
3219 void regTracker_t::increaseConditionalLevel() {
3220         condLevel++;
3221         ast_printf("Entering conditional branch, level now %d\n", condLevel);
3222 }
3223
3224 void regTracker_t::decreaseAndClean(codeGen &gen) {
3225     AstNode *a;
3226     commonExpressionTracker c;
3227     assert(condLevel > 0);
3228     
3229     ast_printf("Exiting from conditional branch, level currently %d\n", condLevel);
3230     
3231     dictionary_hash_iter<AstNode *, commonExpressionTracker> reg_iter(tracker);
3232     while (reg_iter.next(a, c)) {
3233         if (c.keptLevel == condLevel) {
3234             tracker.undef(a);
3235             gen.rs()->unKeepRegister(c.keptRegister);
3236             ast_printf("Removing kept register %d, level %d, for AST %p\n", 
3237                        c.keptRegister, c.keptLevel, a);
3238         }
3239     }
3240     
3241     condLevel--;
3242 }
3243
3244 unsigned regTracker_t::astHash(AstNode* const &ast) {
3245         return addrHash4((Address) ast);
3246 }
3247
3248 void AstNode::debugPrint(unsigned level) {
3249    cerr << format("") << endl;
3250 #if 0
3251
3252
3253     if (!dyn_debug_ast) return;
3254     
3255     for (unsigned i = 0; i < level; i++) fprintf(stderr, "%s", " ");
3256    
3257     std::string type;
3258     if (dynamic_cast<AstNullNode *>(this)) type = "nullNode";
3259     else if (dynamic_cast<AstOperatorNode *>(this)) type = "operatorNode";
3260     else if (dynamic_cast<AstOperandNode *>(this)) type = "operandNode";
3261     else if (dynamic_cast<AstCallNode *>(this)) type = "callNode";
3262     else if (dynamic_cast<AstSequenceNode *>(this)) type = "sequenceNode";
3263     else if (dynamic_cast<AstVariableNode *>(this)) type = "variableNode";
3264     else if (dynamic_cast<AstInsnNode *>(this)) type = "insnNode";
3265     else if (dynamic_cast<AstMiniTrampNode *>(this)) type = "miniTrampNode";
3266     else if (dynamic_cast<AstMemoryNode *>(this)) type = "memoryNode";
3267     else type = "unknownNode";
3268
3269     ast_printf("Node %s: ptr %p, useCount is %d, canBeKept %d, type %s\n", type.c_str(), this, useCount, canBeKept(), getType() ? getType()->getName() : "<NULL TYPE>");
3270
3271     pdvector<AstNodePtr> children;
3272     getChildren(children);
3273     for (unsigned i=0; i<children.size(); i++) {
3274         children[i]->debugPrint(level+1);
3275     }
3276 #endif
3277 }
3278
3279 void regTracker_t::debugPrint() {
3280     if (!dyn_debug_ast) return;
3281     
3282     fprintf(stderr, "==== Begin debug dump of register tracker ====\n");
3283     
3284     fprintf(stderr, "Condition level: %d\n", condLevel);
3285     
3286     AstNode *a;
3287     commonExpressionTracker c;
3288     
3289     dictionary_hash_iter<AstNode *, commonExpressionTracker> reg_iter(tracker);
3290     while (reg_iter.next(a, c)) {
3291         fprintf(stderr, "AstNode %p: register %d, condition level %d\n",
3292                 a, c.keptRegister, c.keptLevel);
3293     }   
3294     fprintf(stderr, "==== End debug dump of register tracker ====\n");
3295 }
3296
3297 unsigned AstNode::getTreeSize() {
3298         pdvector<AstNodePtr > children;
3299         getChildren(children);
3300
3301         unsigned size = 1; // Us
3302         for (unsigned i = 0; i < children.size(); i++)
3303                 size += children[i]->getTreeSize();
3304         return size;
3305         
3306 }
3307
3308 int_variable* AstOperandNode::lookUpVar(AddressSpace* as)
3309 {
3310   mapped_module *mod = as->findModule(oVar->pdmod()->fileName());
3311   if(mod && (oVar->pdmod() == mod->pmod()))
3312   {
3313     int_variable* tmp = mod->obj()->findVariable(const_cast<image_variable*>(oVar));
3314     return tmp;
3315   }
3316   return NULL;
3317 }
3318
3319 void AstOperandNode::emitVariableLoad(opCode op, Register src2, Register dest, codeGen& gen, 
3320                                       bool noCost, registerSpace* rs, 
3321                                       int size, const instPoint* point, AddressSpace* as)
3322 {
3323   int_variable* var = lookUpVar(as);
3324   if(var && !as->needsPIC(var))
3325   {
3326     emitVload(op, var->getAddress(), src2, dest, gen, noCost, rs, size, point, as);
3327   }
3328   else
3329   {
3330     gen.codeEmitter()->emitLoadShared(op, dest, oVar, (var!=NULL),size, gen, 0);
3331   }  
3332 }
3333
3334 void AstOperandNode::emitVariableStore(opCode op, Register src1, Register src2, codeGen& gen, 
3335                                       bool noCost, registerSpace* rs, 
3336                                       int size, const instPoint* point, AddressSpace* as)
3337 {
3338   int_variable* var = lookUpVar(as);
3339   if (var && !as->needsPIC(var))
3340   {
3341     emitVstore(op, src1, src2, var->getAddress(), gen, noCost, rs, size, point, as);
3342   }
3343   else
3344   {
3345     gen.codeEmitter()->emitStoreShared(src1, oVar, (var!=NULL), size, gen);
3346   }  
3347 }
3348
3349 bool AstNode::decRefCount()
3350 {
3351    referenceCount--;
3352    //return referenceCount <= 0;
3353    return true;
3354 }
3355
3356 std::string AstNode::format(std::string indent) {
3357    std::stringstream ret;
3358    ret << indent << "Default/" << hex << this << dec << "()" << endl;
3359    return ret.str();
3360 }
3361
3362 std::string AstNullNode::format(std::string indent) {
3363    std::stringstream ret;
3364    ret << indent << "Null/" << hex << this << dec << "()" << endl;
3365    return ret.str();
3366 }
3367
3368 std::string AstOperatorNode::format(std::string indent) {
3369    std::stringstream ret;
3370    ret << indent << "Op/" << hex << this << dec << "(" << convert(op) << ")" << endl;
3371    if (loperand) ret << indent << loperand->format(indent + "  ");
3372    if (roperand) ret << indent << roperand->format(indent + "  ");
3373    if (eoperand) ret << indent << eoperand->format(indent + "  ");
3374
3375    return ret.str();
3376 }
3377
3378 std::string AstOperandNode::format(std::string indent) {
3379    std::stringstream ret;
3380    ret << indent << "Oper/" << hex << this << dec << "(" << convert(oType) << "/" << oValue << ")" << endl;
3381    if (operand_) ret << indent << operand_->format(indent + "  ");
3382
3383    return ret.str();
3384 }
3385
3386
3387 std::string AstCallNode::format(std::string indent) {
3388    std::stringstream ret;
3389    ret << indent << "Call/" << hex << this << dec;
3390    if (func_) ret << "(" << func_->name() << ")";
3391    else ret << "(" << func_name_ << ")"; 
3392    ret << endl;
3393    indent += "  ";
3394    for (unsigned i = 0; i < args_.size(); ++i) {
3395       ret << indent << args_[i]->format(indent + "  ");
3396    }
3397
3398    return ret.str();
3399 }
3400
3401 std::string AstSequenceNode::format(std::string indent) {
3402    std::stringstream ret;
3403    ret << indent << "Seq/" << hex << this << dec << "()" << endl;
3404    for (unsigned i = 0; i < sequence_.size(); ++i) {
3405       ret << indent << sequence_[i]->format(indent + "  ");
3406    }
3407    return ret.str();
3408 }
3409
3410
3411 std::string AstVariableNode::format(std::string indent) {
3412    std::stringstream ret;
3413    ret << indent << "Var/" << hex << this << dec << "(" << ast_wrappers_.size() << ")" << endl;
3414    for (unsigned i = 0; i < ast_wrappers_.size(); ++i) {
3415       ret << indent << ast_wrappers_[i]->format(indent + "  ");
3416    }
3417
3418    return ret.str();
3419 }
3420
3421
3422 std::string AstNode::convert(operandType type) {
3423    switch(type) {
3424       case Constant: return "Constant";
3425       case ConstantString: return "ConstantString";
3426       case DataReg: return "DataReg";
3427       case DataIndir: return "DataIndir";
3428       case Param: return "Param";
3429       case ParamAtCall: return "ParamAtCall";
3430       case ParamAtEntry: return "ParamAtEntry";
3431       case ReturnVal: return "ReturnVal";
3432       case ReturnAddr: return "ReturnAddr";
3433       case DataAddr: return "DataAddr";
3434       case FrameAddr: return "FrameAddr";
3435       case RegOffset: return "RegOffset";
3436       case origRegister: return "OrigRegister";
3437       case variableAddr: return "variableAddr";
3438       case variableValue: return "variableValue";
3439       default: return "UnknownOperand";
3440    }
3441 }
3442
3443 std::string AstNode::convert(opCode op) {
3444    switch(op) {
3445       case invalidOp: return "invalid";
3446       case plusOp: return "plus";
3447       case minusOp: return "minus";
3448       case timesOp: return "times";
3449       case divOp: return "div";
3450       case lessOp: return "less";
3451       case leOp: return "le";
3452       case greaterOp: return "greater";
3453       case geOp: return "ge";
3454       case eqOp: return "equal";
3455       case neOp: return "ne";
3456       case loadOp: return "loadOp";
3457       case loadConstOp: return "loadConstOp";
3458       case loadFrameRelativeOp: return "loadFrameRelativeOp";
3459       case loadFrameAddr: return "loadFrameAddr";
3460       case loadRegRelativeOp: return "loadRegRelativeOp";
3461       case loadRegRelativeAddr: return "loadRegRelativeAddr";
3462       case storeOp: return "storeOp";
3463       case storeFrameRelativeOp: return "storeFrameRelativeOp";
3464       case ifOp: return "if";
3465       case whileOp: return "while";
3466       case doOp: return "do";
3467       case callOp: return "call";
3468       case noOp: return "no";
3469       case orOp: return "or";
3470       case andOp: return "and";
3471       case getRetValOp: return "getRetValOp";
3472       case getRetAddrOp: return "getRetAddrOp";
3473       case getSysRetValOp: return "getSysRetValOp";
3474       case getParamOp: return "getParamOp";
3475       case getParamAtCallOp: return "getParamAtCallOp";
3476       case getParamAtEntryOp: return "getParamAtEntryOp";
3477       case getSysParamOp: return "getSysParamOp";
3478       case getAddrOp: return "getAddrOp";
3479       case loadIndirOp: return "loadIndirOp";
3480       case storeIndirOp: return "storeIndirOp";
3481       case saveRegOp: return "saveRegOp";
3482       case loadRegOp: return "loadRegOp";
3483       case saveStateOp: return "saveStateOp";
3484       case loadStateOp: return "loadStateOp";
3485       case funcJumpOp: return "funcJump";
3486       case funcCallOp: return "funcCall";
3487       case branchOp: return "branch";
3488       case ifMCOp: return "ifMC";
3489       case breakOp: return "break";
3490       default: return "UnknownOp";
3491    }
3492 }
3493
3494 bool AstOperandNode::initRegisters(codeGen &g) {
3495     bool ret = true;
3496     pdvector<AstNodePtr> kids;
3497     getChildren(kids);
3498     for (unsigned i = 0; i < kids.size(); i++) {
3499         if (!kids[i]->initRegisters(g))
3500             ret = false;
3501     }
3502     
3503     // If we're an origRegister, override its state as live. 
3504     if (oType == origRegister) {
3505        Address origReg = (Address) oValue;
3506        cerr << "Override for origRegister use: marking register " << origReg << " off-limits!" << endl;
3507        // Mark that register as live so we are sure to save it.
3508        registerSlot *r = (*(g.rs()))[origReg];
3509        r->offLimits = true;
3510     }       
3511     
3512     return ret;
3513 }