Changes to work towards compatability with IBM's version of dyninst.
[dyninst.git] / dyninstAPI / src / inst-power.C
1 /*
2  * Copyright (c) 1996 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  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 /*
43  * inst-power.C - Identify instrumentation points for a RS6000/PowerPCs
44  * $Id: inst-power.C,v 1.112 2001/08/29 23:25:27 hollings Exp $
45  */
46
47 #include "common/h/headers.h"
48
49 #ifndef BPATCH_LIBRARY
50 #include "rtinst/h/rtinst.h"
51 #endif
52 #include "dyninstAPI/src/symtab.h"
53 #include "dyninstAPI/src/process.h"
54 #include "dyninstAPI/src/inst.h"
55 #include "dyninstAPI/src/instP.h"
56 #include "dyninstAPI/src/inst-power.h"
57 #include "dyninstAPI/src/arch-power.h"
58 #include "dyninstAPI/src/aix.h"
59 #include "dyninstAPI/src/ast.h"
60 #include "dyninstAPI/src/util.h"
61 #include "dyninstAPI/src/stats.h"
62 #include "dyninstAPI/src/os.h"
63 #include "dyninstAPI/src/instPoint.h" // class instPoint
64 #include "dyninstAPI/src/showerror.h"
65 #include "common/h/debugOstream.h"
66
67 // The following vrbles were defined in process.C:
68 extern debug_ostream attach_cerr;
69 extern debug_ostream inferiorrpc_cerr;
70 extern debug_ostream shmsample_cerr;
71 extern debug_ostream forkexec_cerr;
72
73 //#define perror(a) P_abort();
74
75 extern bool isPowerOf2(int value, int &result);
76
77 #define ABS(x)          ((x) > 0 ? x : -x)
78 //#define MAX_BRANCH    0x1<<23
79 #define MAX_BRANCH      0x01fffffc
80 #define MAX_CBRANCH     0x1<<13
81
82 #define MAX_IMM         0x1<<15         /* 15 plus sign == 16 bits */
83
84 #define SPR_XER 1
85 #define SPR_LR  8
86 #define SPR_CTR 9
87 #define DISTANCE(x,y)   ((x<y) ? (y-x) : (x-y))
88
89 Address getMaxBranch() {
90   return MAX_BRANCH;
91 }
92
93 const char *registerNames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
94                         "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
95                         "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
96                         "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"};
97
98 dictionary_hash<string, unsigned> funcFrequencyTable(string::hash);
99
100 inline void generateBranchInsn(instruction *insn, int offset)
101 {
102     if (ABS(offset) > MAX_BRANCH) {
103         logLine("a branch too far\n");
104         showErrorCallback(52, "Internal error: branch too far");
105         fprintf(stderr, "Attempted to make a branch of offset %x\n", offset);
106         return;
107     }
108
109     insn->raw = 0;
110     insn->iform.op = Bop;
111     insn->iform.aa = 0;
112     insn->iform.lk = 0;
113     insn->iform.li = offset >> 2;
114
115     // logLine("ba,a %x\n", offset);
116 }
117
118 inline void genImmInsn(instruction *insn, int op, Register rt, Register ra, int immd)
119 {
120   // something should be here to make sure immd is within bounds
121   // bound check really depends on op since we have both signed and unsigned
122   //   opcodes.
123   // We basically check if the top bits are 0 (unsigned, or positive signed)
124   // or 0xffff (negative signed)
125   // This is because we don't enforce calling us with LOW(immd), and
126   // signed ints come in with 0xffff set. C'est la vie.
127   // TODO: This should be a check that the high 16 bits are equal to bit 15,
128   // really.
129   assert (((immd & 0xffff0000) == (0xffff0000)) ||
130           ((immd & 0xffff0000) == (0x00000000)));
131
132   insn->raw = 0;
133   insn->dform.op = op;
134   insn->dform.rt = rt;
135   insn->dform.ra = ra;
136   if (op==SIop) immd = -immd;
137   insn->dform.d_or_si = immd;
138 }
139
140 // rlwinm ra,rs,n,0,31-n
141 inline void generateLShift(instruction *insn, int rs, int offset, int ra)
142 {
143     assert(offset<32);
144     insn->raw = 0;
145     insn->mform.op = RLINMxop;
146     insn->mform.rs = rs;
147     insn->mform.ra = ra;
148     insn->mform.sh = offset;
149     insn->mform.mb = 0;
150     insn->mform.me = 31-offset;
151     insn->mform.rc = 0;
152 }
153
154 // rlwinm ra,rs,32-n,n,31
155 inline void generateRShift(instruction *insn, int rs, int offset, int ra)
156 {
157     assert(offset<32);
158     insn->raw = 0;
159     insn->mform.op = RLINMxop;
160     insn->mform.rs = rs;
161     insn->mform.ra = ra;
162     insn->mform.sh = 32-offset;
163     insn->mform.mb = offset;
164     insn->mform.me = 31;
165     insn->mform.rc = 0;
166 }
167
168 //
169 // generate an instruction that does nothing and has to side affect except to
170 //   advance the program counter.
171 //
172 inline void generateNOOP(instruction *insn)
173 {
174   insn->raw = NOOPraw;
175 }
176
177 inline void genSimpleInsn(instruction *insn, int op, 
178                 Register src1, Register src2, Register dest, Address &base)
179 {
180     int xop=-1;
181     insn->raw = 0;
182     insn->xform.op = op;
183     insn->xform.rt = src1;
184     insn->xform.ra = dest;
185     insn->xform.rb = src2;
186     if (op==ANDop) {
187       xop=ANDxop;
188     } else if (op==ORop) {
189       xop=ORxop;
190     } else {
191       // only AND and OR are currently designed to use genSimpleInsn
192       assert(0);
193     }
194     insn->xform.xo = xop;
195     base += sizeof(instruction);
196 }
197
198 inline void genRelOp(instruction *insn, int cond, int mode, Register rs1,
199                      Register rs2, Register rd, Address &base)
200 {
201     // cmp rs1, rs2
202     insn->raw = 0;
203     insn->xform.op = CMPop;
204     insn->xform.rt = 0;    // really bf & l sub fields of rt we care about
205     insn->xform.ra = rs1;
206     insn->xform.rb = rs2;
207     insn->xform.xo = CMPxop;
208     insn++;
209
210     // li rd, 1
211     genImmInsn(insn, CALop, rd, 0, 1);
212     insn++;
213
214     // b??,a +2
215     insn->bform.op = BCop;
216     insn->bform.bi = cond;
217     insn->bform.bo = mode;
218     insn->bform.bd = 2;         // + two instructions */
219     insn->bform.aa = 0;
220     insn->bform.lk = 0;
221     insn++;
222
223     // clr rd
224     genImmInsn(insn, CALop, rd, 0, 0);
225     base += 4 * sizeof(instruction);
226 }
227
228 // Given a value, load it into a register (two operations, CAU and ORIL)
229
230 inline void loadImmIntoReg(instruction *&insn, Register rt, unsigned value)
231 {
232   unsigned high16 = (value & 0xffff0000) >> 16;
233   unsigned low16 = (value & 0x0000ffff);
234   assert((high16+low16)==value);
235
236   if (high16 == 0x0) { // We can save an instruction by not using CAU
237     genImmInsn(insn, CALop, rt, 0, low16);
238     insn++;
239     return;
240   }
241   else if (low16 == 0x0) { // we don't have to ORIL the low bits
242     genImmInsn(insn, CAUop, rt, 0, high16);
243     insn++;
244     return;
245   }
246   else {
247     genImmInsn(insn, CAUop, rt, 0, high16);
248     insn++;
249     genImmInsn(insn, ORILop, rt, rt, low16);
250     insn++;
251     return;
252   }
253 }
254
255 instPoint::instPoint(pd_Function *f, const instruction &instr, 
256                      const image *, Address adr, bool, ipFuncLoc fLoc) 
257                       : addr(adr), originalInstruction(instr), 
258                         callIndirect(false), callee(NULL), func(f), ipLoc(fLoc)
259 {
260    // inDelaySlot = false;
261    // isDelayed = false;
262    // callAggregate = false;
263 }
264
265 // Determine if the called function is a "library" function or a "user" function
266 // This cannot be done until all of the functions have been seen, verified, and
267 // classified
268 //
269 void pd_Function::checkCallPoints() {
270   unsigned int i;
271   instPoint *p;
272   Address loc_addr;
273   image *owner = file_->exec();
274
275   vector<instPoint*> non_lib;
276
277   for (i=0; i<calls.size(); ++i) {
278     /* check to see where we are calling */
279     p = calls[i];
280     assert(p);
281
282     if(isCallInsn(p->originalInstruction)) {
283       loc_addr = p->addr + (p->originalInstruction.iform.li << 2);
284       pd_Function *pdf = owner->findFuncByAddr(loc_addr);
285       if (pdf) {
286         p->callee = pdf;
287         non_lib.push_back(p);
288       } else {
289         p->callIndirect = true;
290         p->callee = NULL;
291         non_lib.push_back(p);
292       }
293     } else 
294       {
295         if ((this->prettyName()).suffixed_by("_linkage"))
296           {
297             // Inter-module call. See note below.
298             // Assert the call is a bctr. Otherwise this code is FUBARed.
299             p->callIndirect = true;
300             p->callee = NULL;
301             non_lib.push_back(p);
302           }
303         else 
304           {
305             // Indirect call -- be conservative, assume it is a call to
306             // an unnamed user function
307             assert(!p->callee); assert(p->callIndirect);
308             p->callee = NULL;
309             non_lib.push_back(p);
310           }
311       }
312   }
313
314
315   calls = non_lib;
316
317 }
318
319 // TODO we cannot find the called function by address at this point in time
320 // because the called function may not have been seen.
321 //
322 Address pd_Function::newCallPoint(const Address adr, const instruction instr,
323                                  const image *owner, bool &err)
324 {
325     Address ret=adr;
326     instPoint *point;
327     err = true;
328
329     point = new instPoint(this, instr, owner, adr, false, ipFuncCallPoint);
330
331     if (!isCallInsn(instr)) {
332       point->callIndirect = true;
333       point->callee = NULL;
334     } else
335       point->callIndirect = false;
336
337     // point->callAggregate = false;
338
339     calls.push_back(point);
340     err = false;
341     return ret;
342 }
343
344 void initDefaultPointFrequencyTable()
345 {
346 #ifdef notdef
347     funcFrequencyTable[EXIT_NAME] = 1;
348
349     FILE *fp;
350     float value;
351     char name[512];
352
353     funcFrequencyTable["main"] = 1;
354     funcFrequencyTable["DYNINSTsampleValues"] = 1;
355     // try to read file.
356     fp = fopen("freq.input", "r");
357     if (!fp) {
358         printf("no freq.input file\n");
359         return;
360     }
361     while (!feof(fp)) {
362         fscanf(fp, "%s %f\n", name, &value);
363         funcFrequencyTable[name] = (int) value;
364         printf("adding %s %f\n", name, value);
365     }
366     fclose(fp);
367 #endif
368 }
369
370 /*
371  * Get an etimate of the frequency for the passed instPoint.  
372  *    This is not (always) the same as the function that contains the point.
373  * 
374  *  The function is selected as follows:
375  *
376  *  If the point is an entry or an exit return the function name.
377  *  If the point is a call and the callee can be determined, return the called
378  *     function.
379  *  else return the funcation containing the point.
380  *
381  *  WARNING: This code contins arbitray values for func frequency (both user 
382  *     and system).  This should be refined over time.
383  *
384  * Using 1000 calls sec to be one SD from the mean for most FPSPEC apps.
385  *      -- jkh 6/24/94
386  *
387  */
388 float getPointFrequency(instPoint *point)
389 {
390
391     pd_Function *func;
392
393     if (point->callee)
394         func = point->callee;
395     else
396         func = point->func;
397
398     if (!funcFrequencyTable.defines(func->prettyName())) {
399       // Changing this value from 250 to 100 because predictedCost was
400       // too high - naim 07/18/96
401       return(100);
402     } else {
403       return (funcFrequencyTable[func->prettyName()]);
404     }
405 }
406
407 //
408 // return cost in cycles of executing at this point.  This is the cost
409 //   of the base tramp if it is the first at this point or 0 otherwise.
410 //
411 int getPointCost(process *proc, const instPoint *point)
412 {
413     if (proc->baseMap.defines(point)) {
414         return(0);
415     } else {
416         // 35 cycles for base tramp
417         // + 70 cyles for MT version (assuming 1 cycle per instruction)
418         return(105);
419     }
420 }
421
422 /*
423  * Given and instruction, relocate it to a new address, patching up
424  *   any relative addressing that is present.
425  *
426  */
427 #ifdef BPATCH_LIBRARY
428 void relocateInstruction(instruction *insn, Address origAddr, Address targetAddr)
429 {
430     int newOffset;
431
432     if (isInsnType(*insn, Bmask, Bmatch)) {
433       // unconditional pc relative branch.
434       newOffset = origAddr  - targetAddr + (insn->iform.li << 2);
435       if (ABS(newOffset) >= MAX_BRANCH) {
436         logLine("a branch too far\n");
437         assert(0);
438       } else {
439         insn->iform.li = newOffset >> 2;
440       }
441     } else if (isInsnType(*insn, Bmask, BCmatch)) {
442       // conditional pc relative branch.
443       newOffset = origAddr - targetAddr + (insn->bform.bd << 2);
444       if (ABS(newOffset) >= MAX_CBRANCH) {
445         unsigned lk = insn->bform.lk;
446         insn->bform.lk = 0;
447
448         if ((insn->bform.bo & BALWAYSmask) == BALWAYScond) {
449             assert(insn->bform.bo == BALWAYScond);
450             generateBranchInsn(insn, newOffset);
451             if (lk) insn->iform.lk = 1;
452         } else {
453             // Figure out if the original branch was predicted as taken or not
454             // taken.  We'll set up our new branch to be predicted the same way
455             // the old one was.
456             bool predict_taken;
457             if (insn->bform.bd < 0)
458                 predict_taken = true;
459             else
460                 predict_taken = false;
461             if (insn->bform.bo & BPREDICTbit)
462                 predict_taken = !predict_taken;
463             insn->bform.bo &= ~BPREDICTbit;
464
465             // Change the branch to move one instruction ahead
466             insn->bform.bd = 2;
467             if (predict_taken) insn->bform.bo |= BPREDICTbit;
468             insn++;
469             assert(insn->raw == NOOPraw);
470             generateBranchInsn(insn, (origAddr + sizeof(instruction)) -
471                                      (targetAddr + sizeof(instruction)));
472             insn++;
473             assert(insn->raw == NOOPraw);
474             generateBranchInsn(insn, newOffset - 2*sizeof(instruction));
475             if (lk) insn->iform.lk = 1;
476         }
477       } else {
478         insn->bform.bd = newOffset >> 2;
479       }
480     } else if (insn->iform.op == SVCop) {
481       logLine("attempt to relocate a system call\n");
482       assert(0);
483     } 
484     /* The rest of the instructions should be fine as is */
485 }
486 #else
487 void relocateInstruction(instruction *insn, Address origAddr, Address targetAddr)
488 {
489     int newOffset;
490
491     if (isInsnType(*insn, Bmask, Bmatch)) {
492       // unconditional pc relative branch.
493       newOffset = origAddr  - targetAddr + (insn->iform.li << 2);
494       if (ABS(newOffset) > MAX_BRANCH) {
495         logLine("a branch too far\n");
496         assert(0);
497       } else {
498         insn->iform.li = newOffset >> 2;
499       }
500     } else if (isInsnType(*insn, Bmask, BCmatch)) {
501       // conditional pc relative branch.
502       newOffset = origAddr - targetAddr + (insn->bform.bd << 2);
503       if (ABS(newOffset) > MAX_CBRANCH) {
504         logLine("a branch too far\n");
505         assert(0);
506       } else {
507         insn->bform.bd = newOffset >> 2;
508       }
509     } else if (insn->iform.op == SVCop) {
510       logLine("attempt to relocate a system call\n");
511       assert(0);
512     } 
513     /* The rest of the instructions should be fine as is */
514 }
515 #endif
516
517 trampTemplate baseTemplate;
518
519 // New version of the base tramp -- will not enter instrumentation recursively
520 trampTemplate baseTemplateNonRecursive;
521
522 #ifdef BPATCH_LIBRARY
523 trampTemplate conservativeTemplate;
524 #endif
525
526 extern "C" void baseTramp();
527 #ifdef BPATCH_LIBRARY
528 extern "C" void conservativeTramp();
529 #endif
530
531 void initATramp(trampTemplate *thisTemp, instruction *tramp, bool guardDesired = true)
532 {
533     instruction *temp;
534
535     // TODO - are these offsets always positive?
536     thisTemp->trampTemp = (void *) tramp;
537     for (temp = tramp; temp->raw != END_TRAMP; temp++) {
538         switch (temp->raw) {
539             case LOCAL_PRE_BRANCH:
540                 thisTemp->localPreOffset = ((char*)temp - (char*)tramp);
541                 thisTemp->localPreReturnOffset = thisTemp->localPreOffset
542                                                  + 4 * sizeof(temp->raw);
543                 break;
544             case GLOBAL_PRE_BRANCH:
545                 thisTemp->globalPreOffset = ((char*)temp - (char*)tramp);
546                 break;
547             case LOCAL_POST_BRANCH:
548                 thisTemp->localPostOffset = ((char*)temp - (char*)tramp);
549                 thisTemp->localPostReturnOffset = thisTemp->localPostOffset
550                                                   + 4 * sizeof(temp->raw);
551                 break;
552             case GLOBAL_POST_BRANCH:
553                 thisTemp->globalPostOffset = ((char*)temp - (char*)tramp);
554                 break;
555             case SKIP_PRE_INSN:
556                 thisTemp->skipPreInsOffset = ((char*)temp - (char*)tramp);
557                 break;
558             case UPDATE_COST_INSN:
559                 thisTemp->updateCostOffset = ((char*)temp - (char*)tramp);
560                 break;
561             case SKIP_POST_INSN:
562                 thisTemp->skipPostInsOffset = ((char*)temp - (char*)tramp);
563                 break;
564             case RETURN_INSN:
565                 thisTemp->returnInsOffset = ((char*)temp - (char*)tramp);
566                 break;
567             case EMULATE_INSN:
568                 thisTemp->emulateInsOffset = ((char*)temp - (char*)tramp);
569                 break;
570             case SAVE_PRE_INSN:
571                 thisTemp->savePreInsOffset = ((char*)temp - (char*)tramp);
572                 break;
573             case RESTORE_PRE_INSN:
574                 thisTemp->restorePreInsOffset = ((char*)temp - (char*)tramp);
575                 break;
576             case SAVE_POST_INSN:
577                 thisTemp->savePostInsOffset = ((char*)temp - (char*)tramp);
578                 break;
579             case RESTORE_POST_INSN:
580                 thisTemp->restorePostInsOffset = ((char*)temp - (char*)tramp);
581                 break;
582             case REENTRANT_PRE_INSN_JUMP:
583                 thisTemp->recursiveGuardPreJumpOffset = ((char*)temp - (char*)tramp);
584                 break;
585             case REENTRANT_POST_INSN_JUMP:
586                 thisTemp->recursiveGuardPostJumpOffset = ((char*)temp - (char*)tramp);
587                 break;
588             default:
589                 break;
590         }       
591     }
592     thisTemp->cost = 8;
593     thisTemp->prevBaseCost = 20;
594     thisTemp->postBaseCost = 30;
595     if (!guardDesired)
596       {
597         thisTemp->recursiveGuardPreJumpOffset = 0;
598         thisTemp->recursiveGuardPostJumpOffset = 0;
599       }
600     else // Update the costs
601       {
602         thisTemp->prevBaseCost += 11;  
603         thisTemp->postBaseCost += 11;
604       }
605     thisTemp->prevInstru = thisTemp->postInstru = false;
606     thisTemp->size = (int) temp - (int) tramp;
607 }
608
609 registerSpace *regSpace;
610 #ifdef BPATCH_LIBRARY
611 // This register space should be used with the conservative base trampoline.
612 // Right now it's only used for purposes of determining which registers must
613 // be saved and restored in the base trampoline.
614 registerSpace *conservativeRegSpace;
615 #endif
616
617 // 11-12 are defined not to have live values at procedure call points.
618 // reg 3-10 are used to pass arguments to functions.
619 //   We must save them before we can use them.
620 #if defined(SHM_SAMPLING) && defined(MT_THREAD)
621 Register deadRegList[] = { 11 };
622 #else
623 Register deadRegList[] = { 11, 12 };
624 #endif
625
626 // allocate in reverse order since we use them to build arguments.
627 Register liveRegList[] = { 10, 9, 8, 7, 6, 5, 4, 3 };
628 int liveRegListSize = 8;
629
630 #ifdef BPATCH_LIBRARY
631 // If we're being conservative, we don't assume that any registers are dead.
632 Register conservativeDeadRegList[] = { };
633 // The registers that aren't preserved by called functions are considered live.
634 Register conservativeLiveRegList[] = { 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 0 };
635 #endif
636
637 void initTramps()
638 {
639     static bool inited=false;
640
641     if (inited) return;
642     inited = true;
643
644     initATramp(&baseTemplateNonRecursive, (instruction *) baseTramp);
645     initATramp(&baseTemplate, (instruction *) baseTramp, false);
646 #ifdef BPATCH_LIBRARY
647     initATramp(&conservativeTemplate, (instruction *) conservativeTramp);
648 #endif
649
650     regSpace = new registerSpace(sizeof(deadRegList)/sizeof(Register), deadRegList, 
651                                  sizeof(liveRegList)/sizeof(Register), liveRegList);
652
653 #ifdef BPATCH_LIBRARY
654     // Note that we don't always use this with the conservative base tramp --
655     // see the message where we declare conservativeRegSpace.
656     conservativeRegSpace =
657       new registerSpace(sizeof(conservativeDeadRegList)/sizeof(Register),
658                         conservativeDeadRegList, 
659                         sizeof(conservativeLiveRegList)/sizeof(Register),
660                         conservativeLiveRegList);
661 #endif
662 }
663
664 /*
665  * Saving and restoring registers
666  *
667  * The base trampoline needs somewhere to save registers to. We currently
668  * save registers based on a negative offset from the stack pointer (on
669  * AIX, the stack grows down). This avoids having to construct a "dummy" stack
670  * frame when building the base tramp. To avoid overwriting program data, 
671  * we shift our save down by an arbitrary "stack pad" value. This is currently 24K.
672  * Basically, we're fine unless we instrument a function with a 24K array. 
673  * I've unified the Dyninst/Paradyn register saving behavior. When paradyn is used,
674  * we "allocate" some extra space. This really isn't a problem, and if we don't emit
675  * a function call, the stack pointer is never even shifted.
676  *
677  *       Stack:    ________________________
678  *             SP  |                      |
679  *                 |                      |
680  *    SP-STKPAD (0)| Begin saving here    |
681  *              -4 |      GPR 0           | actually, I'm not sure if GPRs are
682  *             ... |      GPRs            | saved high first or low first.
683  *  -(13+1)*4  -56 |      Last GPR        |
684  *             -64 |      LR              | LR and CTR are the two registers used
685  *             -68 |      CTR             | in indirect branches.
686  *             -72 |      CR              |
687  *             -76 |      XER             |
688  *             -80 |      SPR0            |
689  *             -88 |      FPSCR           | We allocate 8 bytes for this one.
690  *             -96 | FPR save space       | Allow a little extra room 
691  *            -104 |      FPR             |
692  *             ... |                      |
693  */
694
695 /* PROBLEM WITH MT_THREAD -- stacks are only 8K!!! */
696 #define STKPAD ( 24 * 1024 )
697 #define STKLR    ( -(8 + (13+1)*4) )
698 #define STKCR    (STKLR - 4)
699 #define STKXER   (STKLR - 8)
700 #define STKCTR   (STKLR - 12)
701 #define STKSPR0  (STKLR - 16)
702 #define STKFPSCR (STKLR - 24)
703 #define STKFP    (- STKFPSCR)
704 #define STKFCALLREGS (STKFP+(14*8))
705 #define STKKEEP (STKFCALLREGS+((13+1)*4)+STKPAD)
706
707     ////////////////////////////////////////////////////////////////////
708     //Generates instructions to save a special purpose register onto
709     //the stack.
710     //  Returns the number of bytes needed to store the generated
711     //    instructions.
712     //  The instruction storage pointer is advanced the number of 
713     //    instructions generated.
714     //
715 // NOTE: the bit layout of the mfspr instruction is as follows:
716 // opcode:6 ; RT: 5 ; SPR: 10 ; const 339:10 ; Rc: 1
717 // However, the two 5-bit halves of the SPR field are reversed
718 // so just using the xfxform will not work
719
720 static int saveSPR(instruction *&insn,     //Instruction storage pointer
721                    Register    scratchReg, //Scratch register
722                    int         sprnum,     //SPR number
723                    int         stkOffset)  //Offset from stack pointer
724 {
725   insn->raw = 0;                    //mfspr:  mflr scratchReg
726   insn->xform.op = 31;
727   insn->xform.rt = scratchReg;
728   insn->xform.ra = sprnum & 0x1f;
729   insn->xform.rb = (sprnum >> 5) & 0x1f;
730   insn->xform.xo = 339;
731   insn++;
732
733   insn->raw = 0;                    //st:     st scratchReg, stkOffset(r1)
734   insn->dform.op      = 36;
735   insn->dform.rt      = scratchReg;
736   insn->dform.ra      = 1;
737   insn->dform.d_or_si = stkOffset - STKPAD;
738   insn++;
739
740   return 2 * sizeof(instruction);
741 }
742
743     ////////////////////////////////////////////////////////////////////
744     //Generates instructions to restore a special purpose register from
745     //the stack.
746     //  Returns the number of bytes needed to store the generated
747     //    instructions.
748     //  The instruction storage pointer is advanced the number of 
749     //    instructions generated.
750     //
751 static int restoreSPR(instruction *&insn,       //Instruction storage pointer
752                       Register      scratchReg, //Scratch register
753                       int           sprnum,     //SPR number
754                       int           stkOffset)  //Offset from stack pointer
755 {
756   insn->raw = 0;                    //l:      l scratchReg, stkOffset(r1)
757   insn->dform.op      = 32;
758   insn->dform.rt      = scratchReg;
759   insn->dform.ra      = 1;
760   insn->dform.d_or_si = stkOffset - STKPAD;
761   insn++;
762
763   insn->raw = 0;                    //mtspr:  mtlr scratchReg
764   insn->xform.op = 31;
765   insn->xform.rt = scratchReg;
766   insn->xform.ra = sprnum & 0x1f;
767   insn->xform.rb = (sprnum >> 5) & 0x1f;
768   insn->xform.xo = 467;
769   insn++;
770
771   return 2 * sizeof(instruction);
772 }
773
774            ////////////////////////////////////////////////////////////////////
775            //Generates instructions to save link register onto stack.
776            //  Returns the number of bytes needed to store the generated
777            //    instructions.
778            //  The instruction storage pointer is advanced the number of 
779            //    instructions generated.
780 static int saveLR(instruction *&insn,       //Instruction storage pointer
781                   Register      scratchReg, //Scratch register
782                   int           stkOffset)  //Offset from stack pointer
783 {
784   insn->raw = 0;                    //mfspr:  mflr scratchReg
785   insn->xform.op = 31;
786   insn->xform.rt = scratchReg;
787   insn->xform.ra = 8;
788   insn->xform.xo = 339;
789   insn++;
790
791   insn->raw = 0;                    //st:     st scratchReg, stkOffset(r1)
792   insn->dform.op      = 36;
793   insn->dform.rt      = scratchReg;
794   insn->dform.ra      = 1;
795   insn->dform.d_or_si = stkOffset - STKPAD;
796   insn++;
797
798   return 2 * sizeof(instruction);
799 }
800
801            ////////////////////////////////////////////////////////////////////
802            //Generates instructions to restore link register from stack.
803            //  Returns the number of bytes needed to store the generated
804            //    instructions.
805            //  The instruction storage pointer is advanced the number of 
806            //    instructions generated.
807            //
808 static int restoreLR(instruction *&insn,       //Instruction storage pointer
809                      Register      scratchReg, //Scratch register
810                      int           stkOffset)  //Offset from stack pointer
811 {
812   insn->raw = 0;                    //l:      l scratchReg, stkOffset(r1)
813   insn->dform.op      = 32;
814   insn->dform.rt      = scratchReg;
815   insn->dform.ra      = 1;
816   insn->dform.d_or_si = stkOffset - STKPAD;
817   insn++;
818
819   insn->raw = 0;                    //mtspr:  mtlr scratchReg
820   insn->xform.op = 31;
821   insn->xform.rt = scratchReg;
822   insn->xform.ra = 8;
823   insn->xform.xo = 467;
824   insn++;
825
826   return 2 * sizeof(instruction);
827 }
828
829
830            ////////////////////////////////////////////////////////////////////
831            //Generates instructions to place a given value into link register.
832            //  The entire instruction sequence consists of the generated
833            //    instructions followed by a given (tail) instruction.
834            //  Returns the number of bytes needed to store the entire
835            //    instruction sequence.
836            //  The instruction storage pointer is advanced the number of 
837            //    instructions in the sequence.
838            //
839 static int setBRL(instruction *&insn,        //Instruction storage pointer
840                   Register      scratchReg,  //Scratch register
841                   unsigned      val,         //Value to set link register to
842                   unsigned      ti)          //Tail instruction
843 {
844   insn->raw =0;                  //cau:  cau scratchReg, 0, HIGH(val)
845   insn->dform.op      = 15;
846   insn->dform.rt      = scratchReg;
847   insn->dform.ra      = 0;
848   insn->dform.d_or_si = ((val >> 16) & 0x0000ffff);
849   insn++;
850
851   insn->raw = 0;                 //oril:  oril scratchReg, scratchReg, LOW(val)
852   insn->dform.op      = 24;
853   insn->dform.rt      = scratchReg;
854   insn->dform.ra      = scratchReg;
855   insn->dform.d_or_si = (val & 0x0000ffff);
856   insn++;
857  
858   insn->raw = 0;                 //mtspr:  mtlr scratchReg
859   insn->xform.op = 31;
860   insn->xform.rt = scratchReg;
861   insn->xform.ra = 8;
862   insn->xform.xo = 467;
863   insn++;
864
865   insn->raw = ti;
866   insn++;
867
868   return 4 * sizeof(instruction);
869 }
870
871
872      //////////////////////////////////////////////////////////////////////////
873      //Writes out instructions to place a value into the link register.
874      //  If val == 0, then the instruction sequence is followed by a `nop'.
875      //  If val != 0, then the instruction sequence is followed by a `brl'.
876      //
877 void resetBRL(process  *p,   //Process to write instructions into
878               Address   loc, //Address in process to write into
879               unsigned  val) //Value to set link register
880 {
881   instruction  i[8];                          //8 just to be safe
882   instruction *t        = i;                  //To avoid side-effects on i
883   int          numBytes = val ? setBRL(t, 10, val, BRLraw)
884                               : setBRL(t, 10, val, NOOPraw);
885
886   p->writeTextSpace((void *)loc, numBytes, i);
887 }
888
889     /////////////////////////////////////////////////////////////////////////
890     //Generates instructions to save the condition codes register onto stack.
891     //  Returns the number of bytes needed to store the generated
892     //    instructions.
893     //  The instruction storage pointer is advanced the number of 
894     //    instructions generated.
895     //
896 static int saveCR(instruction *&insn,       //Instruction storage pointer
897                   Register      scratchReg, //Scratch register
898                   int           stkOffset)  //Offset from stack pointer
899 {
900   insn->raw = 0;                    //mfcr:  mflr scratchReg
901   insn->xform.op = 31;
902   insn->xform.rt = scratchReg;
903   insn->xform.xo = 19;
904   insn++;
905
906   insn->raw = 0;                    //st:     st scratchReg, stkOffset(r1)
907   insn->dform.op      = 36;
908   insn->dform.rt      = scratchReg;
909   insn->dform.ra      = 1;
910   insn->dform.d_or_si = stkOffset - STKPAD;
911   insn++;
912
913   return 2 * sizeof(instruction);
914 }
915
916
917     ///////////////////////////////////////////////////////////////////////////
918     //Generates instructions to restore the condition codes register from stack.
919     //  Returns the number of bytes needed to store the generated
920     //    instructions.
921     //  The instruction storage pointer is advanced the number of 
922     //    instructions generated.
923     //
924 static int restoreCR(instruction *&insn,       //Instruction storage pointer
925                      Register      scratchReg, //Scratch register
926                      int           stkOffset)  //Offset from stack pointer
927 {
928   insn->raw = 0;                    //l:      l scratchReg, stkOffset(r1)
929   insn->dform.op      = 32;
930   insn->dform.rt      = scratchReg;
931   insn->dform.ra      = 1;
932   insn->dform.d_or_si = stkOffset - STKPAD;
933   insn++;
934
935   insn->raw = 0;                    //mtcrf:  scratchReg
936   insn->xfxform.op  = 31;
937   insn->xfxform.rt  = scratchReg;
938   insn->xfxform.spr = 0xff << 1;
939   insn->xfxform.xo  = 144;
940   insn++;
941
942   return 2 * sizeof(instruction);
943 }
944
945
946     /////////////////////////////////////////////////////////////////////////
947     //Generates instructions to save the floating point status and control
948     //register on the stack.
949     //  Returns the number of bytes needed to store the generated
950     //    instructions.
951     //  The instruction storage pointer is advanced the number of 
952     //    instructions generated.
953     //
954 static int saveFPSCR(instruction *&insn,       //Instruction storage pointer
955                      Register      scratchReg, //Scratch fp register
956                      int           stkOffset)  //Offset from stack pointer
957 {
958   insn->raw = 0;                    //mffs scratchReg
959   insn->xform.op = 63;
960   insn->xform.rt = scratchReg;
961   insn->xform.xo = 583;
962   insn++;
963
964   //st:     st scratchReg, stkOffset(r1)
965   genImmInsn(insn, STFDop, scratchReg, 1, stkOffset - STKPAD);
966   insn++;
967
968   return 2 * sizeof(instruction);
969 }
970
971
972     ///////////////////////////////////////////////////////////////////////////
973     //Generates instructions to restore the floating point status and control
974     //register from the stack.
975     //  Returns the number of bytes needed to store the generated
976     //    instructions.
977     //  The instruction storage pointer is advanced the number of 
978     //    instructions generated.
979     //
980 static int restoreFPSCR(instruction *&insn,       //Instruction storage pointer
981                         Register      scratchReg, //Scratch fp register
982                         int           stkOffset)  //Offset from stack pointer
983 {
984   genImmInsn(insn, LFDop, scratchReg, 1, stkOffset - STKPAD);
985   insn++;
986
987   insn->raw = 0;                    //mtfsf:  scratchReg
988   insn->xflform.op  = 63;
989   insn->xflform.flm = 0xff;
990   insn->xflform.frb = scratchReg;
991   insn->xflform.xo  = 711;
992   insn++;
993
994   return 2 * sizeof(instruction);
995 }
996
997      //////////////////////////////////////////////////////////////////////////
998      //Writes out a `br' instruction
999      //
1000 void resetBR(process  *p,    //Process to write instruction into
1001              Address   loc)  //Address in process to write into
1002 {
1003   instruction i;
1004
1005   i.raw = BRraw;
1006
1007   p->writeDataSpace((void *)loc, sizeof(instruction), &i);
1008 }
1009
1010 static void saveRegister(instruction *&insn, Address &base, Register reg,
1011                   int offset)
1012 {
1013   genImmInsn(insn, STop, reg, 1, -1*((reg+1)*4 + offset + STKPAD));
1014   insn++;
1015   base += sizeof(instruction);
1016 }
1017
1018 static void restoreRegister(instruction *&insn, Address &base, Register reg,
1019                       int dest, int offset)
1020 {
1021   genImmInsn(insn, Lop, dest, 1, -1*((reg+1)*4 + offset + STKPAD));
1022   insn++;
1023   base += sizeof(instruction);
1024 }
1025
1026 static void restoreRegister(instruction *&insn, Address &base, Register reg,
1027                      int offset)
1028 {
1029   restoreRegister(insn, base, reg, reg, offset);
1030 }       
1031
1032 static void saveFPRegister(instruction *&insn, Address &base, Register reg,
1033                     int offset)
1034 {
1035   genImmInsn(insn, STFDop, reg, 1, -1*((reg+1)*8 + offset + STKPAD));
1036   insn++;
1037   base += sizeof(instruction);
1038 }
1039
1040 static void restoreFPRegister(instruction *&insn, Address &base, Register reg,
1041                         int dest, int offset)
1042 {
1043   genImmInsn(insn, LFDop, dest, 1, -1*((reg+1)*8 + offset + STKPAD));
1044   insn++;
1045   base += sizeof(instruction);
1046 }
1047
1048 static void restoreFPRegister(instruction *&insn, Address &base, Register reg,
1049                        int offset)
1050 {
1051   restoreFPRegister(insn, base, reg, reg, offset);
1052 }       
1053
1054 void saveAllRegistersThatNeedsSaving(instruction *insn, Address &base)
1055 {
1056    unsigned long numInsn=0;
1057    for (u_int i = 0; i < regSpace->getRegisterCount(); i++) {
1058      registerSlot *reg = regSpace->getRegSlot(i);
1059      if (reg->startsLive) {
1060        saveRegister(insn,numInsn,reg->number,8);
1061      }
1062    }
1063    base += numInsn/sizeof(instruction);
1064 }
1065
1066 void restoreAllRegistersThatNeededSaving(instruction *insn, Address &base)
1067 {
1068    unsigned long numInsn=0;
1069    for (u_int i = 0; i < regSpace->getRegisterCount(); i++) {
1070      registerSlot *reg = regSpace->getRegSlot(i);
1071      if (reg->startsLive) {
1072        restoreRegister(insn,numInsn,reg->number,8);
1073      }
1074    }
1075    base += numInsn/sizeof(instruction);
1076 }
1077
1078 #if defined(MT_THREAD)
1079 void generateMTpreamble(char *insn, Address &base, process *proc)
1080 {
1081   AstNode *t1,*t2,*t3,*t4,*t5;
1082   vector<AstNode *> dummy;
1083   Address tableAddr;
1084   int value; 
1085   bool err;
1086   Register src = Null_Register;
1087
1088   // registers cleanup
1089   regSpace->resetSpace();
1090
1091   /* t3=DYNINSTthreadTable[thr_self()] */
1092   /* threadPos returns -2 if the thread_id reported by the OS is 0,
1093      and  */
1094   t1 = new AstNode("DYNINSTthreadPos", dummy);
1095   value = sizeof(unsigned);
1096   t4 = new AstNode(AstNode::Constant,(void *)value);
1097   t2 = new AstNode(timesOp, t1, t4);
1098   removeAst(t1);
1099    removeAst(t4);
1100
1101   tableAddr = proc->findInternalAddress("DYNINSTthreadTable",true,err);
1102   assert(!err);
1103   t5 = new AstNode(AstNode::Constant, (void *)tableAddr);
1104   t3 = new AstNode(plusOp, t2, t5);
1105   removeAst(t2);
1106   removeAst(t5);
1107   src = t3->generateCode(proc, regSpace, insn, base, false, true);
1108   removeAst(t3);
1109   instruction *tmp_insn = (instruction *) ((void*)&insn[base]);
1110   genImmInsn(tmp_insn, ORILop, src, REG_MT, 0);  
1111   base += sizeof(instruction);
1112   regSpace->freeRegister(src);
1113 }
1114 #endif
1115
1116
1117 /*
1118  * Install a base tramp -- fill calls with nop's for now.
1119  *
1120  * This can be called for two different reasons. First, and most often (I 
1121  * believe) is to write in a new base tramp. We decide which one to use
1122  * (conservative/regular, guarded/unguarded) and write it in. The template
1123  * used is then returned, and assumedly stored. 
1124  *
1125  * Option 2: rewriting an existing tramp. The tramp has been scrambled
1126  * for some reason, but the allocated storage still exists. This rewrites
1127  * the existing tramp. 
1128  *
1129  */
1130 trampTemplate *installBaseTramp(const instPoint *location, process *proc,
1131                                 bool trampRecursiveDesired = false,
1132                                 trampTemplate *templateType = NULL,
1133                                 Address exitTrampAddr = 0,
1134                                 Address baseAddr = 0)
1135 {
1136     unsigned long trampGuardFlagAddr = proc->getTrampGuardFlagAddr();
1137     Address currAddr;
1138     instruction *code;
1139     instruction *temp;
1140     unsigned offset;
1141     unsigned long numInsn;
1142     trampTemplate *theTemplate = NULL;
1143     bool isReinstall = (baseAddr != 0);
1144 #ifdef BPATCH_LIBRARY
1145     registerSpace *theRegSpace = NULL;
1146     if (location->ipLoc == ipOther)
1147       theRegSpace = conservativeRegSpace;
1148     else theRegSpace = regSpace;
1149 #endif
1150
1151     if (templateType) // Already have a preferred template type
1152       {
1153         theTemplate = templateType;
1154       }
1155     else
1156       {
1157 #ifdef BPATCH_LIBRARY
1158         if (location->ipLoc == ipOther) {
1159           theTemplate = &conservativeTemplate;
1160         }
1161         else
1162 #endif
1163         {
1164           if (trampRecursiveDesired)
1165             theTemplate = &baseTemplate;
1166           else
1167             theTemplate = &baseTemplateNonRecursive;
1168         }
1169       }
1170
1171     // Have we allocated space for the flag yet?
1172     if (trampGuardFlagAddr == 0)
1173       {
1174         int zeroval = 0;
1175         trampGuardFlagAddr = inferiorMalloc(proc, sizeof(int), dataHeap);
1176         // Zero out the new value
1177         proc->writeDataSpace((void *)trampGuardFlagAddr, sizeof(int), &zeroval);
1178         // Keep track in the process space
1179         proc->setTrampGuardFlagAddr(trampGuardFlagAddr);
1180       }
1181     if (! isReinstall) 
1182       baseAddr = inferiorMalloc(proc, theTemplate->size, anyHeap, location->addr);
1183     // InferiorMalloc can ignore our "hints" when necessary, but that's 
1184     // bad here because we don't have a fallback position
1185 #ifdef DEBUG
1186     fprintf(stderr, "Installing a base tramp at %x, jumping from %s(%x)\n",
1187             baseAddr, location->func->prettyName().string_of(), location->addr);
1188 #endif
1189     
1190     if (DISTANCE(location->addr, baseAddr) > MAX_BRANCH)
1191       {
1192         fprintf(stderr, "Instrumentation point %x too far from tramp location %x, trying to instrument function %s\n",
1193                 (unsigned) location->addr, (unsigned) baseAddr,
1194                 location->func->prettyName().string_of());
1195         assert(0);
1196       }
1197     code = new instruction[theTemplate->size / sizeof(instruction)];
1198     memcpy((char *) code, (char*) theTemplate->trampTemp, theTemplate->size);
1199     // bcopy(theTemplate->trampTemp, code, theTemplate->size);
1200
1201     for (temp = code, currAddr = baseAddr; 
1202         (int) (currAddr - baseAddr) < theTemplate->size;
1203         temp++, currAddr += sizeof(instruction)) {
1204       switch (temp->raw) {
1205         
1206       case UPDATE_LR:
1207         if(location->ipLoc == ipFuncReturn) {
1208           // loading the old LR from the 4th word from the stack, 
1209           // in the link-area
1210           genImmInsn(&code[0], Lop, 0, 1, 12);
1211           code[1].raw = MTLR0raw;
1212           // the rest of the instrs are already NOOPs
1213         } else if((location->ipLoc == ipFuncEntry) && (exitTrampAddr != 0)) {
1214           code[0].raw = MFLR0raw;
1215           // storing the old LR in the 4th word from the stack, 
1216           // in the link-area
1217           genImmInsn(&code[1], STop, 0, 1, 12); 
1218           genImmInsn(&code[2], CAUop, 0, 0, HIGH(exitTrampAddr));
1219           genImmInsn(&code[3], ORILop, 0, 0, LOW(exitTrampAddr));
1220           code[4].raw = MTLR0raw;
1221         } else {
1222           generateNOOP(temp);
1223             // the rest of the instrs are already NOOPs
1224         }
1225         break;
1226       case EMULATE_INSN:
1227         if(location->ipLoc == ipFuncReturn) {
1228           generateNOOP(temp);
1229         } else {
1230           *temp = location->originalInstruction;
1231           relocateInstruction(temp, location->addr, currAddr);
1232         }
1233         break;
1234       case RETURN_INSN:
1235         if(location->ipLoc == ipFuncReturn) {
1236           temp->raw = BRraw;
1237         } else {
1238           generateBranchInsn(temp, (location->addr + 
1239                                     sizeof(instruction) - currAddr));
1240         }
1241         break;
1242       case SKIP_PRE_INSN:
1243         //offset = baseAddr+theTemplate->updateCostOffset-currAddr;
1244         offset = baseAddr+theTemplate->emulateInsOffset-currAddr;
1245         generateBranchInsn(temp,offset);
1246         break;
1247       case SKIP_POST_INSN:
1248         offset = baseAddr+theTemplate->returnInsOffset-currAddr;
1249         generateBranchInsn(temp,offset);
1250         break;
1251       case UPDATE_COST_INSN:
1252         theTemplate->costAddr = currAddr;
1253         generateNOOP(temp);
1254         break;
1255       case SAVE_PRE_INSN:
1256       case SAVE_POST_INSN:
1257         // Note: we're saving the registers 24K down the stack.
1258         // This is necessary since the near area around the stack pointer
1259         // can contain useful data, and we can't tell when this is.
1260         // So we can't shift the SP down a little ways, and in most
1261         // cases we don't care about shifting it down a long way here.
1262         // If we make a function call (emitFuncCall), it handles
1263         // shifting the SP down. See comment at the STKPAD definition.
1264
1265 #ifdef BPATCH_LIBRARY
1266       for(u_int i = 0; i < theRegSpace->getRegisterCount(); i++) {
1267         registerSlot *reg = theRegSpace->getRegSlot(i);
1268 #else
1269         for(u_int i = 0; i < regSpace->getRegisterCount(); i++) {
1270           registerSlot *reg = regSpace->getRegSlot(i);
1271 #endif
1272           if (reg->startsLive) {
1273             numInsn = 0;
1274             saveRegister(temp,numInsn,reg->number,8);
1275             assert(numInsn > 0);
1276             currAddr += numInsn;
1277           }
1278         }
1279         currAddr += saveLR(temp, 10, STKLR);   //Save link register on stack
1280         
1281 #ifdef BPATCH_LIBRARY
1282         // If this is a point where we're using a conservative base tramp,
1283         // we need to save some more registers.
1284         if (location->ipLoc == ipOther) {
1285           currAddr += saveSPR(temp, 10, SPR_CTR, STKCTR); // & count reg
1286           currAddr += saveCR(temp, 10, STKCR); // Save the condition codes
1287           currAddr += saveSPR(temp, 10, SPR_XER, STKXER); // & XER
1288           currAddr += saveSPR(temp, 10, 0, STKSPR0);      // & SPR0
1289         }
1290 #endif
1291           
1292           // Also save the floating point registers which could
1293           // be modified, f0-r13
1294           for(unsigned i=0; i <= 13; i++) {
1295             numInsn = 0;
1296             saveFPRegister(temp,numInsn,i,STKFP);
1297             currAddr += numInsn;
1298           }
1299           
1300 #ifdef BPATCH_LIBRARY
1301           if (location->ipLoc == ipOther) {
1302             // Save the floating point status and control register
1303             // (we have to do it after saving the floating point registers,
1304             // because we need to use one as a temporary)
1305             currAddr += saveFPSCR(temp, 13, STKFPSCR);
1306           }
1307 #endif
1308           
1309           temp--;
1310           currAddr -= sizeof(instruction);
1311           
1312           break;
1313         case RESTORE_PRE_INSN:
1314         case RESTORE_POST_INSN:
1315           // See comment above for why we don't shift SP.
1316           // However, the LR is stored in its normal place (at SP+8)
1317           currAddr += restoreLR(temp, 10, STKLR); //Restore link register from
1318           
1319 #ifdef BPATCH_LIBRARY
1320           // If this is a point where we're using a conservative base tramp,
1321           // we need to restore some more registers.
1322           if (location->ipLoc == ipOther) {
1323           currAddr += restoreSPR(temp, 10, SPR_CTR, STKCTR); // & count reg
1324             currAddr += restoreCR(temp, 10, STKCR); // Restore condition codes
1325             currAddr += restoreSPR(temp, 10, SPR_XER, STKXER); // & XER
1326             currAddr += restoreSPR(temp, 10, 0, STKSPR0); // & SPR0
1327             currAddr += restoreFPSCR(temp, 13, STKFPSCR); // & FPSCR
1328           }
1329 #endif
1330           
1331 #ifdef BPATCH_LIBRARY
1332           for (u_int i = 0; i < theRegSpace->getRegisterCount(); i++) {
1333             registerSlot *reg = theRegSpace->getRegSlot(i);
1334 #else
1335           for (u_int i = 0; i < regSpace->getRegisterCount(); i++) {
1336             registerSlot *reg = regSpace->getRegSlot(i);
1337 #endif
1338             if (reg->startsLive) {
1339               numInsn = 0;
1340               restoreRegister(temp,numInsn,reg->number,8);
1341               assert(numInsn > 0);
1342               currAddr += numInsn;
1343             }
1344           }
1345           // A commented-out closing brace to satisfy the auto-indentation
1346           // programs -- uncomment if they get picky
1347           //}
1348         
1349           // Also load the floating point registers which were saved
1350           // since they could have been modified, f0-r13
1351           for(u_int i=0; i <= 13; i++) {
1352             numInsn = 0;
1353             restoreFPRegister(temp,numInsn,i,STKFP);
1354             currAddr += numInsn;
1355           }
1356           
1357           // "Undo" the for loop step, since we've advanced the FP also.
1358           temp--;
1359           currAddr -= sizeof(instruction);
1360           break;
1361         case LOCAL_PRE_BRANCH:
1362         case GLOBAL_PRE_BRANCH:
1363         case LOCAL_POST_BRANCH:
1364         case GLOBAL_POST_BRANCH:
1365 #if defined(SHM_SAMPLING) && defined(MT_THREAD)
1366           if ((temp->raw == LOCAL_PRE_BRANCH) ||
1367               (temp->raw == LOCAL_POST_BRANCH)) {
1368             temp -= NUM_INSN_MT_PREAMBLE;
1369             unsigned numIns=0;
1370             generateMTpreamble((char *)temp, numIns, proc);
1371             numIns = numIns/sizeof(instruction);
1372             if(numIns != NUM_INSN_MT_PREAMBLE) {
1373               cerr << "numIns = " << numIns << endl;
1374               assert(numIns==NUM_INSN_MT_PREAMBLE);
1375             }
1376             // if numIns!=NUM_INSN_MT_PREAMBLE then we should update the
1377             // space reserved for generateMTpreamble in the base-tramp
1378             // template file (tramp-power.S) - naim
1379             temp += NUM_INSN_MT_PREAMBLE;
1380           }
1381 #endif
1382           currAddr += setBRL(temp, 10, 0, NOOPraw); //Basically `nop'
1383           
1384           temp--;                                   //`for' loop compensate
1385           currAddr -= sizeof(instruction);          //`for' loop compensate
1386           break;
1387         case REENTRANT_GUARD_ADDR:
1388           if (theTemplate->recursiveGuardPreJumpOffset)
1389             {
1390               // Need to write the following instructions:
1391               // cau 7,0,HIGH(baseAddr)
1392               genImmInsn(temp,
1393                          CAUop,   // Add immediate and shift
1394                          6,       // Destination
1395                          0,       // Source
1396                          HIGH((int)trampGuardFlagAddr));
1397               temp++; currAddr += sizeof(instruction); // Step for loop
1398               // oril 6,7,LOW(baseAddr)
1399               genImmInsn(temp,
1400                          ORILop,  // OR immediate
1401                          6,       // Destination
1402                          6,       // Source
1403                          LOW((int)trampGuardFlagAddr));
1404             }
1405           else // No guard wanted, so overwrite with noop
1406             temp->raw = NOOPraw;
1407           break;
1408         case REENTRANT_GUARD_LOAD:
1409           if (theTemplate->recursiveGuardPreJumpOffset)
1410             {
1411               // load (addr: 6, dest: 5)
1412               genImmInsn(temp,   // instruction
1413                          Lop,    // Load
1414                          5,      // Into register 5
1415                          6,      // Addr in register 6
1416                          0);     // No offset
1417             }
1418           else
1419             temp->raw = NOOPraw;
1420           break;
1421         case REENTRANT_PRE_INSN_JUMP:
1422           if (theTemplate->recursiveGuardPreJumpOffset)
1423             {
1424               // Need to write the following instruction:
1425               // cmp (addr: 5 != 0)
1426               genImmInsn(temp,   // Instruction
1427                          CMPIop, // Compare immediate
1428                          0,      // CR 0, L=0
1429                          5,      // Source,
1430                          0);     // Compare to 0
1431               temp++; currAddr += sizeof(instruction);
1432               // bcxxx (4, 2, reentrant(Pre|Post)GuardJump);
1433               temp->raw = 0;
1434               temp->bform.op = BCop; // Branch conditional
1435               temp->bform.bo = BFALSEcond; // Branch if false
1436               temp->bform.bi = EQcond;
1437               temp->bform.bd = ( theTemplate->restorePreInsOffset - 
1438                                  theTemplate->recursiveGuardPreJumpOffset) / 4;
1439               temp->bform.aa = 0; // Relative branch
1440               temp->bform.lk = 0; // No link req'd
1441             }
1442           else
1443             temp->raw = NOOPraw;
1444           break;
1445         case REENTRANT_POST_INSN_JUMP:
1446           if (theTemplate->recursiveGuardPostJumpOffset)
1447             {
1448               // Need to write the following instruction:
1449               // cmp (addr: 5 != 0)
1450               genImmInsn(temp,   // Instruction
1451                          CMPIop, // Compare immediate
1452                          0,      // CR 0, L=0
1453                          5,      // Source,
1454                          0);     // Compare to 0
1455               temp++; currAddr += sizeof(instruction);
1456               // bcxxx (4, 2, reentrant(Pre|Post)GuardJump);
1457               temp->raw = 0;
1458               temp->bform.op = BCop; // Branch conditional
1459               temp->bform.bo = BFALSEcond; // Branch if false
1460               temp->bform.bi = EQcond;
1461               temp->bform.bd = ( theTemplate->restorePostInsOffset - 
1462                                  theTemplate->recursiveGuardPostJumpOffset) / 4;
1463               temp->bform.aa = 0; // Relative branch
1464               temp->bform.lk = 0; // No link req'd
1465             }
1466           else
1467             temp->raw = NOOPraw;
1468           break;
1469         case REENTRANT_GUARD_INC:
1470           if (theTemplate->recursiveGuardPreJumpOffset)
1471             {
1472               // Need to write:
1473               // cal 5,1(0) -- set register 5 to value 1
1474               genImmInsn(temp,  // instruction 
1475                          CALop, // add immediate
1476                          5,     // Destination
1477                          0,     // Source
1478                          1);    // Value of 1
1479             }
1480           else
1481             temp->raw = NOOPraw;
1482           break;
1483         case REENTRANT_GUARD_DEC:
1484           if (theTemplate->recursiveGuardPreJumpOffset)
1485             {
1486               // Need to write:
1487               // cal 5,0(0)
1488               genImmInsn(temp,  // instruction,
1489                          CALop, // Add immediate
1490                          5,     // Destination 
1491                          0,     // Source
1492                          0);    // Set to 0
1493             }
1494           else
1495             temp->raw = NOOPraw;
1496           break;
1497         case REENTRANT_GUARD_STORE: 
1498           if (theTemplate->recursiveGuardPreJumpOffset)
1499             {
1500               // stw 5,0(6)
1501               genImmInsn(temp,
1502                          STop,
1503                          5,         // Register 5 
1504                          6,         // Dest addr in reg 6
1505                          0);        // 0 offset
1506             }
1507           else
1508             temp->raw = NOOPraw;
1509           break;
1510         default:
1511           break;
1512       }
1513     }
1514         /*
1515     for (temp = code, currAddr = baseAddr; 
1516         (int) (currAddr - baseAddr) < theTemplate->size;
1517         temp++, currAddr += sizeof(instruction))
1518       fprintf(stderr, "Op: %u; RT: %u; RA: %u; D: %u\n", temp->dform.op,
1519               temp->dform.rt, temp->dform.ra, temp->dform.d_or_si);
1520         */
1521     // TODO cast
1522     proc->writeDataSpace((caddr_t)baseAddr, theTemplate->size, (caddr_t) code);
1523
1524     free(code);
1525
1526     if (isReinstall) return NULL;
1527
1528     trampTemplate *baseInst = new trampTemplate;
1529     *baseInst = *theTemplate;
1530     baseInst->baseAddr = baseAddr;
1531     return baseInst;
1532 }
1533
1534 void generateNoOp(process *proc, Address addr)
1535 {
1536     instruction insn;
1537
1538     /* fill with no-op */
1539     /* ori 0,0,0 */
1540     insn.raw = 0;
1541     insn.dform.op = ORILop;
1542
1543     proc->writeTextWord((caddr_t)addr, insn.raw);
1544 }
1545
1546
1547
1548      //////////////////////////////////////////////////////////////////////////
1549      //Returns `true' if a correct base trampoline exists; `false' otherwise
1550      //
1551 bool baseTrampExists(process  *p,         //Process to check into
1552                      Address   baseAddr)  //Address at which to start checking
1553 {
1554   if ((! p) || (! baseAddr)) return false;
1555
1556   int data = ptrace(PT_READ_I, p->getPid(), (int *)baseAddr, 0, 0);
1557   if ((data == 0) || (data == -1))        //Bad instruction or ptrace error
1558     return false;
1559   else
1560     return true;
1561 }
1562
1563      //////////////////////////////////////////////////////////////////////////
1564      //Given a process and a vector of instPoint's, reinstall all the 
1565      //  base trampolines that have been damaged by an AIX load.
1566      //
1567 void findAndReinstallBaseTramps(process                  *p,
1568                                 vector<const instPoint*> &allInstPoints)
1569 {
1570   if (! p) return;
1571
1572   for (unsigned u = 0; u < allInstPoints.size(); u++) {
1573     const instPoint *ip = allInstPoints[u];
1574     trampTemplate   *bt = p->baseMap[ip];                       //Base tramp
1575     if (baseTrampExists(p, bt->baseAddr)) continue;
1576
1577     if ((ip->ipLoc == ipFuncEntry) || (ip->ipLoc == ipFuncReturn)) {
1578       const instPoint *rp = ip->iPgetFunction()->funcExits(p)[0]; //Return point
1579       trampTemplate *rt = p->baseMap[rp];                       //Return tramp
1580       // Note: we can safely ignore the return value of installBaseTramp
1581       // since it is NULL for the reinstallation case. 
1582       installBaseTramp(rp, p, true, rt, 0, rt->baseAddr);
1583       rt->updateTrampCost(p, 0);
1584                                                               
1585       const instPoint *ep = ip->iPgetFunction()->funcEntry(p);  //Entry point
1586       trampTemplate *et = p->baseMap[ep];                       //Entry tramp
1587       installBaseTramp(ep, p, true, et, rt->baseAddr, et->baseAddr);
1588       et->updateTrampCost(p, 0);
1589       generateBranch(p, ep->iPgetAddress(), et->baseAddr);
1590     }
1591     else {
1592       installBaseTramp(ip, p, true, bt, 0, bt->baseAddr);
1593       bt->updateTrampCost(p, 0);
1594       generateBranch(p, ip->iPgetAddress(), bt->baseAddr);
1595     }
1596   }
1597 }
1598
1599
1600
1601 trampTemplate *findAndInstallBaseTramp(process *proc, 
1602                                        instPoint *&location,
1603                                        returnInstance *&retInstance,
1604                                        bool trampRecursiveDesired,
1605                                        bool /*noCost*/,
1606                                        bool& /*deferred*/)
1607 {
1608     trampTemplate *ret = NULL;
1609     process *globalProc;
1610     retInstance = NULL;
1611
1612     globalProc = proc;
1613     if (!globalProc->baseMap.defines(location)) {      
1614         if((location->ipLoc == ipFuncEntry) ||
1615            (location->ipLoc == ipFuncReturn)) {
1616           trampTemplate* exTramp;
1617           //instruction    code[5];
1618           
1619           const instPoint* newLoc1 = location->func->funcExits(globalProc)[0];
1620           exTramp = installBaseTramp(newLoc1, globalProc, trampRecursiveDesired);
1621           globalProc->baseMap[newLoc1] = exTramp;
1622
1623           const instPoint* newLoc2 = location->func->funcEntry(globalProc);
1624           assert(newLoc2->ipLoc == ipFuncEntry);
1625           assert(exTramp->baseAddr != 0);
1626           ret = installBaseTramp(newLoc2, globalProc, trampRecursiveDesired,
1627                                  NULL, // Don't have a previous trampType to pass in
1628                                  exTramp->baseAddr);
1629
1630           instruction *insn = new instruction;
1631           generateBranchInsn(insn, ret->baseAddr - newLoc2->addr);
1632           globalProc->baseMap[newLoc2] = ret;
1633           retInstance = new returnInstance(1, (instruction *)insn, 
1634                                            sizeof(instruction), newLoc2->addr,
1635                                            sizeof(instruction));
1636           
1637           if(location->ipLoc == ipFuncReturn) {
1638             ret = exTramp;
1639           }
1640         } else {
1641           ret = installBaseTramp(location, globalProc, trampRecursiveDesired);
1642           instruction *insn = new instruction;
1643           generateBranchInsn(insn, ret->baseAddr - location->addr);
1644           globalProc->baseMap[location] = ret;
1645           retInstance = new returnInstance(1, (instruction *)insn, 
1646                                            sizeof(instruction), location->addr,
1647                                            sizeof(instruction));
1648         }
1649     } else {
1650         ret = globalProc->baseMap[location];
1651     }
1652       
1653     return(ret);
1654 }
1655
1656
1657      //////////////////////////////////////////////////////////////////////////
1658      //Given a process and a vector of instInstance's, reconstruct branches 
1659      //  from base trampolines to their mini trampolines
1660      //
1661 void reattachMiniTramps(process               *p,
1662                         vector<instInstance*> &allInstInstances)
1663 {
1664   if (! p) return;
1665
1666   for (unsigned u = 0; u < allInstInstances.size(); u++) {
1667     instInstance *ii = allInstInstances[u];
1668     if (ii->prevAtPoint) continue;              //Not first at inst point
1669
1670     trampTemplate *bt       = ii->baseInstance; //Base trampoline
1671     Address        skipAddr = bt->baseAddr;
1672     if (ii->when == callPreInsn)
1673       skipAddr += bt->skipPreInsOffset;
1674     else
1675       skipAddr += bt->skipPostInsOffset;
1676     generateNoOp(p, skipAddr);                  //Clear "skip" branch
1677                                                 //Restore branch from base tramp
1678     extern int getBaseBranchAddr(process *, instInstance *);
1679     resetBRL(p, getBaseBranchAddr(p, ii), ii->trampBase);
1680   }
1681 }
1682
1683
1684
1685 /*
1686  * Install a single tramp.
1687  *
1688  */
1689 void installTramp(instInstance *inst, char *code, int codeSize) 
1690 {
1691     totalMiniTramps++;
1692     insnGenerated += codeSize/sizeof(int);
1693     
1694     // TODO cast
1695     (inst->proc)->writeDataSpace((caddr_t)inst->trampBase, codeSize, code);
1696
1697 #ifdef BPATCH_LIBRARY
1698     trampTemplate *theTemplate;
1699
1700     if (inst->location->ipLoc == ipOther)
1701         theTemplate = &conservativeTemplate;
1702     else
1703         theTemplate = &baseTemplate;
1704 #else
1705     const trampTemplate *theTemplate = &baseTemplate;
1706 #endif
1707
1708     Address atAddr;
1709     if (inst->when == callPreInsn) {
1710         if (inst->baseInstance->prevInstru == false) {
1711             atAddr = inst->baseInstance->baseAddr+theTemplate->skipPreInsOffset;
1712             inst->baseInstance->cost += inst->baseInstance->prevBaseCost;
1713             inst->baseInstance->prevInstru = true;
1714             generateNoOp(inst->proc, atAddr);
1715         }
1716     }
1717     else {
1718         if (inst->baseInstance->postInstru == false) {
1719             atAddr = inst->baseInstance->baseAddr+theTemplate->skipPostInsOffset; 
1720             inst->baseInstance->cost += inst->baseInstance->postBaseCost;
1721             inst->baseInstance->postInstru = true;
1722             generateNoOp(inst->proc, atAddr);
1723         }
1724     }
1725 }
1726
1727 /*
1728  * change the insn at addr to be a branch to newAddr.
1729  *   Used to add multiple tramps to a point.
1730  */
1731 void generateBranch(process *proc, Address fromAddr, Address newAddr)
1732 {
1733     int disp;
1734     instruction insn;
1735
1736     disp = newAddr-fromAddr;
1737     generateBranchInsn(&insn, disp);
1738
1739     // TODO cast
1740     proc->writeTextWord((caddr_t)fromAddr, insn.raw);
1741 }
1742
1743 int callsTrackedFuncP(instPoint *point)
1744 {
1745     if (point->callIndirect) {
1746 #ifdef notdef
1747         // TODO this won't compile now
1748         // it's rare to call a library function as a parameter.
1749         sprintf(errorLine, "*** Warning call indirect\n from %s %s (addr %d)\n",
1750             point->func->file->fullName, point->func->prettyName, point->addr);
1751         logLine(errorLine);
1752 #endif
1753         return(true);
1754     } else {
1755         if (point->callee) {
1756             return(true);
1757         } else {
1758             return(false);
1759         }
1760     }
1761 }
1762
1763 /*
1764  * return the function asociated with a point.
1765  *
1766  *     If the point is a funcation call, and we know the function being called,
1767  *          then we use that.  Otherwise it is the function that contains the
1768  *          point.
1769  *  
1770  *   This is done to return a better idea of which function we are using.
1771  */
1772 pd_Function *getFunction(instPoint *point)
1773 {
1774     return(point->callee ? point->callee : point->func);
1775 }
1776
1777
1778 void emitImm(opCode op, Register src1, RegValue src2imm, Register dest, 
1779                  char *i, Address &base, bool noCost)
1780 {
1781         //fprintf(stderr,"emitImm(op=%d,src=%d,src2imm=%d,dest=%d)\n",
1782         //        op, src1, src2imm, dest);
1783         instruction *insn = (instruction *) ((void*)&i[base]);
1784         int iop=-1;
1785         int result=-1;
1786         switch (op) {
1787             // integer ops
1788             case plusOp:
1789                 iop = CALop;
1790                 genImmInsn(insn, iop, dest, src1, src2imm);
1791                 base += sizeof(instruction);
1792                 return;
1793                 break;
1794
1795             case minusOp:
1796                 iop = SIop;
1797                 genImmInsn(insn, iop, dest, src1, src2imm);
1798                 base += sizeof(instruction);
1799                 return;
1800                 break;
1801
1802             case timesOp:
1803                if (isPowerOf2(src2imm,result) && (result<32)) {
1804                   generateLShift(insn, src1, result, dest);           
1805                   base += sizeof(instruction);
1806                   return;
1807                 }
1808                 else {
1809                   Register dest2 = regSpace->allocateRegister(i, base, noCost);
1810                   emitVload(loadConstOp, src2imm, dest2, dest2, i, base, noCost);
1811                   emitV(op, src1, dest2, dest, i, base, noCost);
1812                   regSpace->freeRegister(dest2);
1813                   return;
1814                 }
1815                 break;
1816
1817             case divOp:
1818                 if (isPowerOf2(src2imm,result) && (result<32)) {
1819                   generateRShift(insn, src1, result, dest);           
1820                   base += sizeof(instruction);
1821                   return;
1822                 }
1823                 else {
1824                   Register dest2 = regSpace->allocateRegister(i, base, noCost);
1825                   emitVload(loadConstOp, src2imm, dest2, dest2, i, base, noCost);
1826                   emitV(op, src1, dest2, dest, i, base, noCost);
1827                   regSpace->freeRegister(dest2);
1828                   return;
1829                 }
1830                 break;
1831
1832             // Bool ops
1833             case orOp:
1834                 iop = ORILop;
1835                 // For some reason, the destField is 2nd for ORILop and ANDILop
1836                 genImmInsn(insn, iop, src1, dest, src2imm);
1837                 base += sizeof(instruction);
1838                 return;
1839                 break;
1840
1841             case andOp:
1842                 iop = ANDILop;
1843                 // For some reason, the destField is 2nd for ORILop and ANDILop
1844                 genImmInsn(insn, iop, src1, dest, src2imm);
1845                 base += sizeof(instruction);
1846                 return;
1847                 break;
1848         
1849             default:
1850                 Register dest2 = regSpace->allocateRegister(i, base, noCost);
1851                 emitVload(loadConstOp, src2imm, dest2, dest2, i, base, noCost);
1852                 emitV(op, src1, dest2, dest, i, base, noCost);
1853                 regSpace->freeRegister(dest2);
1854                 return;
1855                 break;
1856         }
1857 }
1858
1859
1860 //static int dummy[3];
1861 //
1862 //void
1863 //initTocOffset(int toc_offset) {
1864 //    //  st r2,20(r1)  ; 0x90410014 save toc register  
1865 //    dummy[0] = 0x90410014; 
1866 //
1867 //    //  liu r2, 0x0000     ;0x3c40abcd reset the toc value to 0xabcdefgh
1868 //    dummy[1] = (0x3c400000 | (toc_offset >> 16));
1869 //
1870 //    //  oril    r2, r2,0x0000   ;0x6042efgh
1871 //    dummy[2] = (0x60420000 | (toc_offset & 0x0000ffff));
1872 //}
1873
1874
1875 void cleanUpAndExit(int status);
1876
1877 //
1878 // Author: Jeff Hollingsworth (3/26/96)
1879 //
1880 // Emit a function call.
1881 //   It saves registers as needed.
1882 //   copy the passed arguments into the canonical argument registers (r3-r10)
1883 //   Locate the TOC entry of the callee module and copy it into R2
1884 //   generate a branch and link the destination
1885 //   Restore the original TOC into R2
1886 //   restore the saved registers.
1887 //
1888 // Parameters:
1889 //   op - unused parameter (to be compatible with sparc)
1890 //   srcs - vector of ints indicating the registers that contain the parameters
1891 //   dest - the destination address (should be Address not reg). 
1892 //   insn - pointer to the code we are generating
1893 //   based - offset into the code generated.
1894 //
1895
1896
1897 Register emitFuncCall(opCode /* ocode */, 
1898                       registerSpace *rs,
1899                       char *iPtr, Address &base, 
1900                       const vector<AstNode *> &operands, 
1901                       const string &callee, process *proc, bool noCost,
1902                       const function_base *calleefunc)
1903 {
1904   Address dest;
1905   Address toc_anchor;
1906   bool err;
1907   vector <Register> srcs;
1908   
1909   if (calleefunc)
1910     {
1911       dest = calleefunc->getEffectiveAddress(proc);
1912     }
1913   else {
1914        dest = proc->findInternalAddress(callee, false, err);
1915        if (err) {
1916             function_base *func = proc->findOneFunction(callee);
1917             if (!func) {
1918                  ostrstream os(errorLine, 1024, ios::out);
1919                  os << "Internal error: unable to find addr of " << callee << endl;
1920                  logLine(errorLine);
1921                  showErrorCallback(80, (const char *) errorLine);
1922                  P_abort();
1923             }
1924             dest = func->getAddress(0);
1925        }
1926   }
1927
1928
1929   // Now that we have the destination address (unique, hopefully) 
1930   // get the TOC anchor value for that function
1931   toc_anchor = proc->getTOCoffsetInfo(dest);
1932
1933   // Generate the code for all function parameters, and keep a list
1934   // of what registers they're in.
1935   for (unsigned u = 0; u < operands.size(); u++) {
1936     if (operands[u]->getSize() == 8) {
1937         Register dummyReg = rs->allocateRegister(iPtr, base, noCost);
1938         srcs.push_back(dummyReg);
1939         instruction *insn = (instruction *) ((void*)&iPtr[base]);
1940         genImmInsn(insn, CALop, dummyReg, 0, 0);
1941         base += sizeof(instruction);
1942     }
1943     srcs.push_back(operands[u]->generateCode(proc, rs, iPtr, base, false, false));
1944   }
1945   
1946   // generateCode can shift the instruction pointer, so reset insn
1947   instruction *insn = (instruction *) ((void*)&iPtr[base]);
1948   vector<int> savedRegs;
1949   
1950   //     Save the link register.
1951   // mflr r0
1952   insn->raw = MFLR0raw;
1953   insn++;
1954   base += sizeof(instruction);
1955
1956   // Register 0 is actually the link register, now. However, since we
1957   // don't want to overwrite the LR slot, save it as "register 0"
1958   saveRegister(insn, base, 0, STKFCALLREGS);
1959   // Add 0 to the list of saved registers
1960   savedRegs.push_back(0);
1961   
1962   // Save register 2 (TOC)
1963   saveRegister(insn, base, 2, STKFCALLREGS);
1964   savedRegs.push_back(2);
1965
1966 #if defined(SHM_SAMPLING) && defined(MT_THREAD)
1967   // save REG_MT
1968   saveRegister(insn,base,REG_MT,STKFCALLREGS);
1969   savedRegs += REG_MT;
1970 #endif
1971
1972   // see what others we need to save.
1973   for (u_int i = 0; i < regSpace->getRegisterCount(); i++) {
1974     registerSlot *reg = regSpace->getRegSlot(i);
1975     if (reg->needsSaving) {
1976       // needsSaving -> caller saves register
1977       // we MUST save restore this and the end of the function call
1978       //     rather than delay it to the end of the tramp due to:
1979       //        (1) we could be in a conditional & the restores would
1980       //            be unconditional (i.e. restore bad data)
1981       //        (2) $arg[n] code depends on paramters being in registers
1982       //
1983       // MT_AIX: we are not saving registers on demand on the power
1984       // architecture anymore - naim
1985       // saveRegister(insn,base,reg->number,8+(46*4));
1986       // savedRegs += reg->number;
1987     } else if (reg->inUse && !reg->mustRestore) {
1988       // inUse && !mustRestore -> in use scratch register 
1989       //                (i.e. part of an expression being evaluated).
1990
1991       // no reason to save the register if we are going to free it in a bit
1992       // we should keep it free, otherwise we might overwrite the register
1993       // we allocate for the return value -- we can't request that register
1994       // before, since we then might run out of registers
1995       unsigned u;
1996       for(u=0; u < srcs.size(); u++) {
1997         if(reg->number == srcs[u]) break;
1998       }
1999       // since the register should be free
2000       // assert((u == srcs.size()) || (srcs[u] != (int) (u+3)));
2001       if(u == srcs.size()) {
2002         saveRegister(insn, base, reg->number, STKFCALLREGS);
2003         savedRegs.push_back(reg->number);
2004       }
2005     } else if (reg->inUse) {
2006       // only inuse registers permitted here are the parameters.
2007       unsigned u;
2008       for (u=0; u<srcs.size(); u++){
2009         if (reg->number == srcs[u]) break;
2010       }
2011       if (u == srcs.size()) {
2012         // XXXX - caller saves register that is in use.  We have no
2013         //    place to save this, but we must save it!!!.  Should
2014         //    find a place to push this on the stack - jkh 7/31/95
2015         string msg = "Too many registers required for MDL expression\n";
2016         fprintf(stderr, msg.string_of());
2017         showErrorCallback(94,msg);
2018         cleanUpAndExit(-1);
2019       }
2020     }
2021   }
2022   
2023   if(srcs.size() > 8) {
2024     // This is not necessarily true; more then 8 arguments could be passed,
2025     // the first 8 need to be in registers while the others need to be on
2026     // the stack, -- sec 3/1/97
2027     string msg = "Too many arguments to function call in instrumentation code:"
2028                 " only 8 arguments can (currently) be passed on the POWER architecture.\n";
2029     fprintf(stderr, msg.string_of());
2030     showErrorCallback(94,msg);
2031     cleanUpAndExit(-1);
2032   }
2033   
2034   // Now load the parameters into registers.
2035   for (unsigned u=0; u<srcs.size(); u++){
2036     // check that is is not already in the register
2037     if (srcs[u] == (unsigned int) u+3) {
2038       regSpace->freeRegister(srcs[u]);
2039       continue;
2040     }
2041
2042     assert(regSpace->isFreeRegister(u+3));
2043
2044     // internal error we expect this register to be free here
2045     // if (!regSpace->isFreeRegister(u+3)) abort();
2046     
2047     genImmInsn(insn, ORILop, srcs[u], u+3, 0);
2048     insn++;
2049     base += sizeof(instruction);
2050     
2051     // source register is now free.
2052     regSpace->freeRegister(srcs[u]);
2053   }
2054   // 
2055   // Update the stack pointer
2056   //   argarea  =  8 words  (8 registers)
2057   //   linkarea =  6 words  (6 registers)
2058   //   nfuncrs  =  32 words (area we use when saving the registers above 
2059   //                         ngprs at the beginning of this function call; 
2060   //                         this area saves the registers already being
2061   //                         used in the mini trampoline, registers which
2062   //                         need to be accessed after this function call;
2063   //                         this area is used in emitFuncCall--not all the
2064   //                         registers are being saved, only the necessary
2065   //                         ones)
2066   //   nfprs    =  14 words (area we use to save the floatpoing registers,
2067   //                         not all the fprs, only the volatile ones 0-13)
2068   //   ngprs    =  32 words (area we use when saving the registers above the
2069   //                         stack pointer, at the beginning of the base
2070   //                         trampoline--not all the gprs are saved, only the
2071   //   ???      =  2  words  (two extra word was added on for extra space, 
2072   //                          and to make sure the floatpings are aligned)
2073   // OLD STACK POINTER
2074   //   szdsa    =  4*(argarea+linkarea+nfuncrs+nfprs+ngprs) = 368 + 8 = 376
2075   // TODO: move this to arch-power. Here for compiling speed reasons.
2076 #define emitFuncCallStackSpace 376
2077
2078   // So as of now, we have a big chunk of space at SP-24K (approx) which
2079   // is used. This is not a good situation, as we have _no clue_ what 
2080   // our instrumentation is going to do. Simple answer: shift the stack
2081   // pointer past our saved area. Not efficient in terms of space (at 24K
2082   // a pop), but safe.
2083   // Take current SP, decrease by frame amount, and store (both) in
2084   // register 1 and in memory. Back chain to "caller"
2085   genImmInsn(insn, STUop, REG_SP, REG_SP, -emitFuncCallStackSpace - STKKEEP);
2086   insn++;
2087   base += sizeof(instruction);
2088
2089   // save the TOC 
2090   // Done above, right after we save the LR
2091   // Push in the value of the TOC anchor to register 2
2092
2093   genImmInsn(insn, CAUop, 2, 0, HIGH(toc_anchor));
2094   insn++;
2095   base += sizeof(instruction);
2096   genImmInsn(insn, ORILop, 2, 2, LOW(toc_anchor));
2097   insn++;
2098   base += sizeof(instruction);
2099
2100   // cout << "Dummy" << dummy[0] << "\t" << dummy[1]<< "\t" << dummy[2]<<endl;
2101
2102   // generate a to the subroutine to be called.
2103   // load r0 with address, then move to link reg and branch and link.
2104   
2105   // TODO: can we do this with a branch to fixed, instead of a
2106   // branch-to-link-register?
2107   // Yes, but we then have to put all of the minitramps in
2108   // the text heap (which is limited), not the data heap (which isn't).
2109   // We can't guarantee that we can reach a function from the data
2110   // heap, and odds are against us. 
2111   // Set the upper half of the link register
2112   genImmInsn(insn, CAUop, 0, 0, HIGH(dest));
2113   insn++;
2114   base += sizeof(instruction);
2115   
2116   // Set lower half
2117   genImmInsn(insn, ORILop, 0, 0, LOW(dest));
2118   insn++;
2119   base += sizeof(instruction);
2120   
2121   // Move to link register
2122   insn->raw = MTLR0raw;
2123   insn++;
2124   base += sizeof(instruction);
2125   
2126   // brl - branch and link through the link reg.
2127
2128   insn->raw = BRLraw;
2129   insn++;
2130   base += sizeof(instruction);
2131
2132   // should there be a nop of some sort here?, sec
2133   // No: AFAIK, the nop is an artifact of the linker, which we bypass.
2134   // ld replaces the nop with a instr to reload the TOC anchor, below.
2135   // -- bernat
2136   //insn->raw = 0x4ffffb82;  // nop
2137   //insn++;
2138   //base += sizeof(instruction);
2139
2140   // restore TOC
2141   // Implicitly done by restoreRegs below (it was saved above)
2142
2143   // now cleanup.
2144   genImmInsn(insn, CALop, REG_SP, REG_SP, emitFuncCallStackSpace + STKKEEP);
2145   insn++;
2146   base += sizeof(instruction);
2147   
2148   // get a register to keep the return value in.
2149   Register retReg = rs->allocateRegister(iPtr, base, noCost);
2150
2151   // allocateRegister can generate code. Reset insn
2152   insn = (instruction *) ((void*)&iPtr[base]);
2153
2154   // put the return value from register 3 to the newly allocated register.
2155   genImmInsn(insn, ORILop, 3, retReg, 0);
2156   insn++;
2157   base += sizeof(instruction);
2158   
2159   // restore saved registers.
2160   for (u_int ui = 0; ui < savedRegs.size(); ui++) {
2161     restoreRegister(insn,base,savedRegs[ui],STKFCALLREGS);
2162   }
2163   
2164   // mtlr       0 (aka mtspr 8, rs) = 0x7c0803a6
2165   insn->raw = MTLR0raw;
2166   insn++;
2167   base += sizeof(instruction);
2168   
2169   // return value is the register with the return value from the called function
2170   return(retReg);
2171 }
2172
2173  
2174 Address emitA(opCode op, Register src1, Register /*src2*/, Register dest,
2175               char *baseInsn, Address &base, bool /*noCost*/)
2176 {
2177     //fprintf(stderr,"emitA(op=%d,src1=%d,src2=XX,dest=%d)\n",op,src1,dest);
2178
2179     // TODO cast
2180     instruction *insn = (instruction *) ((void*)&baseInsn[base]);
2181
2182     switch (op) {
2183       case ifOp: {
2184         // cmpi 0,0,src1,0
2185         insn->raw = 0;
2186         insn->dform.op = CMPIop;
2187         insn->dform.ra = src1;
2188         insn->dform.d_or_si = 0;
2189         insn++;
2190
2191         // be 0, dest
2192         insn->bform.op = BCop;
2193         insn->bform.bo = BTRUEcond;
2194         insn->bform.bi = EQcond;
2195         insn->bform.bd = dest/4;
2196         insn->bform.aa = 0;
2197         insn->bform.lk = 0;
2198         insn++;
2199
2200         generateNOOP(insn);
2201         base += sizeof(instruction)*3;
2202         return(base - 2*sizeof(instruction));
2203         }
2204       case branchOp: {
2205         generateBranchInsn(insn, dest);
2206         insn++;
2207
2208         generateNOOP(insn);
2209         base += sizeof(instruction)*2;
2210         return(base - 2*sizeof(instruction));
2211         }
2212       case trampPreamble: {
2213         // nothing to do in this platform
2214         return(0);              // let's hope this is expected!
2215         }        
2216       case trampTrailer: {
2217 /*
2218         // restore the registers we have saved
2219         for (unsigned i = 0; i < regSpace->getRegisterCount(); i++) {
2220             registerSlot *reg = regSpace->getRegSlot(i);
2221             if (reg->mustRestore) {
2222                 // cleanup register space for next trampoline.
2223                 reg->needsSaving = true;
2224                 reg->mustRestore = false;
2225                 // actually restore the register.
2226                 restoreRegister(insn,base,reg->number,8);
2227             }
2228         }
2229 */
2230         generateBranchInsn(insn, dest);
2231         insn++;
2232         base += sizeof(instruction);
2233
2234         generateNOOP(insn);
2235         insn++;
2236         base += sizeof(instruction);
2237
2238         // return the relative address of the return statement.
2239         return(base - 2*sizeof(instruction));
2240       }
2241     default:
2242         assert(0);        // unexpected op for this emit!
2243   }
2244 }
2245
2246 Register emitR(opCode op, Register src1, Register /*src2*/, Register dest,
2247               char *baseInsn, Address &base, bool /*noCost*/)
2248 {
2249     //fprintf(stderr,"emitR(op=%d,src1=%d,src2=XX,dest=%d)\n",op,src1,dest);
2250
2251     // TODO cast
2252     instruction *insn = (instruction *) ((void*)&baseInsn[base]);
2253
2254     switch (op) {
2255     case getRetValOp: {
2256         // return value is in register 3
2257         Register reg = 3;
2258         registerSlot *regSlot = NULL;
2259
2260         // find the registerSlot for this register.
2261         for (unsigned i = 0; i < regSpace->getRegisterCount(); i++) {
2262             regSlot = regSpace->getRegSlot(i);
2263             if (regSlot->number == reg) {
2264                 break;
2265             }
2266         }
2267
2268         if (regSlot->mustRestore) {
2269           // its on the stack so load it.
2270           restoreRegister(insn, base, reg, dest, 8);
2271           return(dest);
2272         } else {
2273             // its still in a register so return the register it is in.
2274             return(reg);
2275         }
2276       }
2277     case getParamOp: {
2278       // the first 8 parameters (0-7) are stored in registers (r3-r10) upon entering
2279       // the function and then saved above the stack upon entering the trampoline;
2280       // in emit functional call the stack pointer is moved so the saved registers
2281       // are not over-written
2282       // the other parameters > 8 are stored on the caller's stack at an offset.
2283       // 
2284       // src1 is the argument number 0..X, the first 8 are stored in registers
2285       // r3 and 
2286       if(src1 < 8) {
2287         restoreRegister(insn, base, src1+3, dest, 8);
2288         return(dest);
2289       } else {
2290         genImmInsn(insn, Lop, dest, 1, (src1+6)*4);
2291         insn++; 
2292         base += sizeof(instruction);
2293         return(dest);
2294       }
2295     }
2296     default:
2297         assert(0);        // unexpected op for this emit!
2298   }
2299 }
2300
2301 void emitVload(opCode op, Address src1, Register /*src2*/, Register dest,
2302               char *baseInsn, Address &base, bool /*noCost*/, int size)
2303 {
2304     instruction *insn = (instruction *) ((void*)&baseInsn[base]);
2305
2306     if (op == loadConstOp) {
2307         unsigned int constValue = (int) src1;
2308         unsigned int top_half = ((constValue & 0xffff0000) >> 16);
2309         unsigned int bottom_half = (constValue & 0x0000ffff);
2310         assert (constValue == ((top_half << 16) + bottom_half));
2311         // AIX sign-extends. So if top_half is 0, and the top bit of
2312         // bottom_half is 0, then we can use a single instruction. Otherwise
2313         // do it the hard way.
2314         if (!top_half && !(bottom_half & 0x8000)) {
2315           // single instruction (CALop)
2316           genImmInsn(insn, CALop, dest, 0, bottom_half);
2317           base += sizeof(instruction);
2318         }
2319         else {
2320           genImmInsn(insn, CAUop, dest, 0, top_half);
2321           insn++;
2322           // ori dest,dest,LOW(src1)
2323           genImmInsn(insn, ORILop, dest, dest, bottom_half);
2324           base += 2*sizeof(instruction);
2325         }
2326     } else if (op ==  loadOp) {
2327         int high;
2328
2329         // load high half word of address into dest.
2330         // really addis 0,dest,HIGH(src1) aka lis dest, HIGH(src1)
2331         if (LOW(src1) & 0x8000) {
2332             // high bit of low is set so the sign extension of the load
2333             // will cause the wrong effective addr to be computed.
2334             // so we subtract the sign ext value from HIGH.
2335             // sounds odd, but works and saves an instruction - jkh 5/25/95
2336             high = HIGH(src1) - 0xffff;
2337         } else {
2338             high = HIGH(src1);
2339         }
2340         genImmInsn(insn, CAUop, dest, 0, high);
2341         insn++;
2342
2343         // really load dest, (dest)imm
2344         genImmInsn(insn, Lop, dest, dest, LOW(src1));
2345
2346         base += sizeof(instruction)*2;
2347     } else if (op == loadFrameRelativeOp) {
2348         // return the value that is FP offset from the original fp
2349         int offset = (int) src1;
2350
2351         if ((offset < MIN_IMM16) || (offset > MAX_IMM16)) {
2352             assert(0);
2353         } else {
2354             genImmInsn(insn, Lop, dest, REG_SP, offset);
2355             insn++;
2356             base += sizeof(instruction)*2;
2357         }
2358     } else if (op == loadFrameAddr) {
2359         // offsets are signed!
2360         int offset = (int) src1;
2361
2362         if ((offset < MIN_IMM16) || (offset > MAX_IMM16)) {
2363           assert(0);
2364         } else {
2365             genImmInsn(insn, CALop, dest, REG_SP, offset);
2366             insn++;
2367             base += sizeof(instruction);
2368         }
2369     } else {
2370       assert(0);
2371     }
2372 }
2373
2374 void emitVstore(opCode op, Register src1, Register /*src2*/, Address dest,
2375               char *baseInsn, Address &base, bool noCost, int /* size */)
2376 {
2377     instruction *insn = (instruction *) ((void*)&baseInsn[base]);
2378
2379     if (op == storeOp) {
2380         int high;
2381
2382         // load high half word of address into dest.
2383         // really addis 0,dest,HIGH(src1) aka lis dest, HIGH(src1)
2384         if (LOW(dest) & 0x8000) {
2385             // high bit of low is set so the sign extension of the load
2386             // will cause the wrong effective addr to be computed.
2387             // so we subtract the sign ext value from HIGH.
2388             // sounds odd, but works and saves an instruction - jkh 5/25/95
2389             high = HIGH(dest) - 0xffff;
2390         } else {
2391             high = HIGH(dest);
2392         }
2393
2394         // temp register to hold base address for store (added 6/26/96 jkh)
2395         Register temp = regSpace->allocateRegister(baseInsn, base, noCost);
2396
2397         // This next line is a hack! - jkh 6/27/96
2398         //   It is required since allocateRegister can generate code.
2399         insn = (instruction *) ((void*)&baseInsn[base]);
2400
2401         // set upper 16 bits of  temp to be the top high.
2402         genImmInsn(insn, CAUop, temp, 0, high);
2403         base += sizeof(instruction);
2404         insn++;
2405
2406         // low == LOW(dest)
2407         // generate -- st src1, low(temp)
2408 #ifdef notdef
2409         insn->dform.op = STop;
2410         insn->dform.rt = src1;
2411         insn->dform.ra = temp;
2412         insn->dform.d_or_si = LOW(dest);
2413 #endif
2414         genImmInsn(insn, STop, src1, temp, LOW(dest));
2415         base += sizeof(instruction);
2416         insn++;
2417
2418         regSpace->freeRegister(temp);
2419         return;
2420     } else if (op == storeFrameRelativeOp) {
2421         // offsets are signed!
2422         int offset = (int) dest;
2423         if ((offset < MIN_IMM16) || (offset > MAX_IMM16)) {
2424           assert(0);
2425         } else {
2426             genImmInsn(insn, STop, src1, REG_SP, offset);
2427             base += sizeof(instruction);
2428             insn++;
2429         }
2430     } else {
2431         assert(0);       // unexpected op for this emit!
2432     }
2433 }
2434
2435 void emitVupdate(opCode op, RegValue src1, Register /*src2*/, Address dest,
2436               char *baseInsn, Address &base, bool noCost)
2437 {
2438     instruction *insn = (instruction *) ((void*)&baseInsn[base]);
2439
2440     if (op == updateCostOp) {
2441         if (!noCost) {
2442
2443            regSpace->resetSpace();
2444
2445            // add in the cost to the passed pointer variable.
2446
2447            // high order bits of the address of the cummulative cost.
2448            Register obsCostAddr = regSpace->allocateRegister(baseInsn, base, noCost);
2449
2450            // actual cost.
2451            Register obsCostValue = regSpace->allocateRegister(baseInsn, base, noCost);
2452
2453            // This next line is a hack! - jkh 6/27/96
2454            //   It is required since allocateRegister can generate code.
2455            insn = (instruction *) ((void*)&baseInsn[base]);
2456
2457            int high;
2458
2459            // load high half word of address into dest.
2460            // really addis 0,dest,HIGH(dest) aka lis dest, HIGH(dest)
2461            if (LOW(dest) & 0x8000) {
2462               // high bit of low is set so the sign extension of the load
2463               // will cause the wrong effective addr to be computed.
2464               // so we subtract the sign ext value from HIGH.
2465               // sounds odd, but works and saves an instruction - jkh 5/25/95
2466               high = HIGH(dest) - 0xffff;
2467            } else {
2468               high = HIGH(dest);
2469            }
2470            genImmInsn(insn, CAUop, obsCostAddr, 0, high);
2471            insn++;
2472
2473            // really load obsCostValue, (obsCostAddr)imm
2474            genImmInsn(insn, Lop, obsCostValue, obsCostAddr, LOW(dest));
2475            insn++;
2476
2477            base += 2 * sizeof(instruction);
2478
2479            //assert(src1 <= MAX_IMM);
2480            if (src1 <= MAX_IMM) {
2481              genImmInsn(insn, CALop, obsCostValue, obsCostValue, LOW(src1));
2482              insn++;
2483              base += sizeof(instruction);
2484            } else {
2485              // If src1>MAX_IMM, we can't generate an instruction using an
2486              // an immediate operator. Therefore, we need to load the 
2487              // value first, which will cost 2 instructions - naim
2488              Register reg = regSpace->allocateRegister(baseInsn, base, noCost);
2489              genImmInsn(insn, CAUop, reg, 0, HIGH(src1));
2490              insn++;
2491              genImmInsn(insn, ORILop, reg, reg, LOW(src1));
2492              insn++;
2493              base += 2 * sizeof(instruction);
2494              emitV(plusOp, reg, obsCostValue, obsCostValue, baseInsn, 
2495                          base, noCost);        
2496              regSpace->freeRegister(reg);     
2497              insn++;
2498            }
2499
2500            // now store it back.
2501            // low == LOW(dest)
2502            // generate -- st obsCostValue, obsCostAddr+low(dest)
2503            insn->dform.op = STop;
2504            insn->dform.rt = obsCostValue;
2505            insn->dform.ra = obsCostAddr;
2506            insn->dform.d_or_si = LOW(dest);
2507            insn++;
2508            base += sizeof(instruction);
2509
2510            regSpace->freeRegister(obsCostValue);
2511            regSpace->freeRegister(obsCostAddr);
2512        } // if !noCost
2513     } else {
2514         assert(0);       // unexpected op for this emit!
2515     }
2516 }
2517
2518 void emitV(opCode op, Register src1, Register src2, Register dest,
2519               char *baseInsn, Address &base, bool /*noCost*/, int /* size */)
2520 {
2521     //fprintf(stderr,"emitV(op=%d,src1=%d,src2=%d,dest=%d)\n",op,src1,src2,dest)
2522 ;
2523
2524     assert ((op!=branchOp) && (op!=ifOp) && 
2525             (op!=trampTrailer) && (op!=trampPreamble));         // !emitA
2526     assert ((op!=getRetValOp) && (op!=getParamOp));             // !emitR
2527     assert ((op!=loadOp) && (op!=loadConstOp));                 // !emitVload
2528     assert ((op!=storeOp));                                     // !emitVstore
2529     assert ((op!=updateCostOp));                                // !emitVupdate
2530
2531     // TODO cast
2532     instruction *insn = (instruction *) ((void*)&baseInsn[base]);
2533
2534     if (op == loadIndirOp) {
2535         // really load dest, (dest)imm
2536         genImmInsn(insn, Lop, dest, src1, 0);
2537
2538         base += sizeof(instruction);
2539
2540     } else if (op == storeIndirOp) {
2541
2542         // generate -- st src1, dest
2543         insn->dform.op = STop;
2544         insn->dform.rt = src1;
2545         insn->dform.ra = dest;
2546         insn->dform.d_or_si = 0;
2547         base += sizeof(instruction);
2548
2549     } else if (op == noOp) {
2550         generateNOOP(insn);
2551         base += sizeof(instruction);
2552     } else if (op == saveRegOp) {
2553         saveRegister(insn,base,src1,8);
2554     } else {
2555         int instXop=-1;
2556         int instOp=-1;
2557         switch (op) {
2558             // integer ops
2559             case plusOp:
2560                 instOp = CAXop;
2561                 instXop = CAXxop;
2562                 break;
2563
2564             case minusOp:
2565                 Register temp;
2566                 // need to flip operands since this computes ra-rb not rb-ra
2567                 temp = src1;
2568                 src1 = src2;
2569                 src2 = temp;
2570                 instOp = SFop;
2571                 instXop = SFxop;
2572                 break;
2573
2574             case timesOp:
2575                 instOp = MULSop;
2576                 instXop = MULSxop;
2577                 break;
2578
2579             case divOp:
2580                 //#if defined(_POWER_PC)
2581                 // xop = DIVWxop; // PowerPC 32 bit divide instruction
2582                 //#else 
2583                 instOp = DIVSop;   // Power divide instruction
2584                 instXop = DIVSxop;
2585                 break;
2586
2587             // Bool ops
2588             case orOp:
2589                 //genSimpleInsn(insn, ORop, src1, src2, dest, base);
2590                 insn->raw = 0;
2591                 insn->xoform.op = ORop;
2592                 // operation is ra <- rs | rb (or rs,ra,rb)
2593                 insn->xoform.ra = dest;
2594                 insn->xoform.rt = src1;
2595                 insn->xoform.rb = src2;
2596                 insn->xoform.xo = ORxop;
2597                 base += sizeof(instruction);
2598                 return;
2599                 break;
2600
2601             case andOp:
2602                 //genSimpleInsn(insn, ANDop, src1, src2, dest, base);
2603                 // This is a Boolean and with true == 1 so bitwise is OK
2604                 insn->raw = 0;
2605                 insn->xoform.op = ANDop;
2606                 // operation is ra <- rs & rb (and rs,ra,rb)
2607                 insn->xoform.ra = dest;
2608                 insn->xoform.rt = src1;
2609                 insn->xoform.rb = src2;
2610                 insn->xoform.xo = ANDxop;
2611                 base += sizeof(instruction);
2612                 return;
2613                 break;
2614
2615             // rel ops
2616             case eqOp:
2617                 genRelOp(insn, EQcond, BTRUEcond, src1, src2, dest, base);
2618                 return;
2619                 break;
2620
2621             case neOp:
2622                 genRelOp(insn, EQcond, BFALSEcond, src1, src2, dest, base);
2623                 return;
2624                 break;
2625
2626             case lessOp:
2627                 genRelOp(insn, LTcond, BTRUEcond, src1, src2, dest, base);
2628                 return;
2629                 break;
2630
2631             case greaterOp:
2632                 genRelOp(insn, GTcond, BTRUEcond, src1, src2, dest, base);
2633                 return;
2634                 break;
2635
2636             case leOp:
2637                 genRelOp(insn, GTcond, BFALSEcond, src1, src2, dest, base);
2638                 return;
2639                 break;
2640
2641             case geOp:
2642                 genRelOp(insn, LTcond, BFALSEcond, src1, src2, dest, base);
2643                 return;
2644                 break;
2645
2646             default:
2647                 // internal error, invalid op.
2648                 fprintf(stderr, "Invalid op passed to emit, instOp = %d\n", 
2649                         instOp);
2650                 assert(0 && "Invalid op passed to emit");
2651                 break;
2652         }
2653         assert((instOp != -1) && (instXop != -1));
2654         insn->raw = 0;
2655         insn->xoform.op = instOp;
2656         insn->xoform.rt = dest;
2657         insn->xoform.ra = src1;
2658         insn->xoform.rb = src2;
2659         insn->xoform.xo = instXop;
2660
2661         base += sizeof(instruction);
2662     }
2663   return;
2664 }
2665
2666
2667 //
2668 // I don't know how to compute cycles for POWER instructions due to 
2669 //   multiple functional units.  However, we can compute the number of
2670 //   instructions and hope that is fairly close. - jkh 1/30/96
2671 //
2672 int getInsnCost(opCode op)
2673   {
2674     int cost = 0;
2675
2676     /* XXX Need to add branchOp */
2677     switch (op) {
2678       
2679     case noOp:
2680     case loadIndirOp:
2681     case saveRegOp:
2682
2683       // worse case is it is on the stack and takes one instruction.
2684     case getParamOp:
2685
2686       // integer ops
2687     case plusOp:
2688     case minusOp:
2689     case timesOp:
2690     case divOp:
2691       cost = 1;
2692       break;
2693
2694     case loadConstOp:
2695       // worse case is addi followed by ori
2696
2697     case loadOp:
2698       // addis, l
2699       
2700     case storeOp:
2701     case storeIndirOp:
2702       cost = 2;
2703       break;
2704
2705     case ifOp:
2706       // cmpi 0,0,src1,0
2707       // be 0, dest
2708       // nop
2709       cost = 3;
2710       break;
2711
2712       // rel ops
2713     case eqOp:
2714     case neOp:
2715     case lessOp:
2716     case greaterOp:
2717     case leOp:
2718     case geOp:
2719       cost = 4;
2720       break;
2721       
2722     case callOp:
2723       // mflr r0
2724       // st r0, (r1)
2725       cost += 2;
2726       
2727       // Should compute the cost to save registers here.  However, we lack 
2728       //   sufficient information to compute this value. We need to be 
2729       //   inside the code generator to know this amount.
2730       //
2731       // We know it is at *least* every live register (i.e. parameter reg)
2732       cost += sizeof(liveRegList)/sizeof(int);
2733       
2734       // clr r5
2735       // clr r6
2736       // decrement stack pointer -- STUop
2737       // load r0 with address, then move to link reg and branch and link.
2738       // ori dest,dest,LOW(src1)
2739       // mtlr   0 (aka mtspr 8, rs) = 0x7c0803a6
2740       // brl - branch and link through the link reg.
2741       cost += 7;
2742       
2743       // now cleanup.
2744       
2745       // increment stack pointer -- CALop
2746       // restore the saved register 0.
2747       cost += 2;
2748       
2749       // Should compute the cost to restore registers here.  However, we lack 
2750       //   sufficient information to compute this value. We need to be 
2751       //   inside the code generator to know this amount.
2752       //
2753       // We know it is at *least* every live register (i.e. parameter reg)
2754       cost += sizeof(liveRegList)/sizeof(int);
2755       
2756       // mtlr   0 
2757       cost++;
2758       break;
2759
2760     case updateCostOp:
2761       // In most cases this cost is 4, but if we can't use CALop because
2762       // the value is to large, then we'll need 2 additional operations to
2763       // load that value - naim
2764       // Why the +=? Isn't it equivalent to an = here? -- bernat
2765       cost += 4;
2766       break;
2767       
2768     case trampPreamble:
2769       // Generate code to update the observed cost.
2770       // generated code moved to the base trampoline.
2771       cost += 0;
2772       break;
2773
2774     case trampTrailer:
2775       // Should compute the cost to restore registers here.  However, we lack 
2776       //   sufficient information to compute this value. We need to be 
2777       //   inside the code generator to know this amount.
2778       //
2779       
2780       // branch
2781       // nop
2782       cost += 2;
2783       break;
2784
2785     default:
2786       cost = 0;
2787       break;
2788     }
2789     return (cost);
2790 }
2791
2792
2793 bool isCallInsn(const instruction i)
2794 {
2795   #define CALLmatch 0x48000001 /* bl */
2796
2797   // Only look for 'bl' instructions for now, although a branch
2798   // could be a call function, and it doesn't need to set the link
2799   // register if it is the last function call
2800   return(isInsnType(i, OPmask | AALKmask, CALLmatch));
2801 }
2802
2803 /*
2804  * We need to also find calls that don't go to a known location.
2805  * AFAIK, POWER has no "branch to register" calls. It does, however,
2806  * have branch to link register and branch to count register calls.
2807  */
2808
2809 bool isDynamicCall(const instruction i)
2810 {
2811   // I'm going to break this up a little so that I can comment
2812   // it better. 
2813
2814   if (i.xlform.op == BCLRop && i.xlform.xo == BCLRxop)
2815     {
2816       if (i.xlform.lk)
2817         // Type one: Branch-to-LR, save PC in LR
2818         // Standard function pointer call
2819         return true;
2820       else
2821         // Type two: Branch-to-LR, don't save PC
2822         // Haven't seen one of these around
2823         // It would be a return instruction, probably
2824         {
2825           return false;
2826         }
2827     }
2828   if (i.xlform.op == BCLRop && i.xlform.xo == BCCTRxop)
2829     {
2830       if (i.xlform.lk)
2831         // Type three: Branch-to-CR, save PC
2832         {
2833           return true;
2834         }
2835       else
2836         // Type four: Branch-to-CR, don't save PC
2837         // Used for global linkage code.
2838         // We handle those elsewhere.
2839         {
2840           return true;
2841         }
2842     }
2843   return false;
2844 }
2845
2846 /* ************************************************************************
2847    --  This function, isReturnInsn, is no longer needed.  -- sec
2848
2849 // Check for a real return instruction.  Unfortunatly, on RS6000 there are
2850 //    several factors that make this difficult:
2851 //
2852 //    br - is the "normal" return instruction
2853 //    b <cleanupRoutine> is sometimes used to restore fp state.
2854 //    bctr - can be used, but it is also the instruction used for jump tables.
2855 //  
2856 //    However, due to the traceback table convention the instruction after 
2857 //    a real return is always all zeros (i.e. the flag for the start of a
2858 //    tracback record).
2859 //    Also, jump tables never seem to have a 0 offset so the sequence:
2860 //              bctr
2861 //              .long 0
2862 //    doesn't ever appear in a case statement.
2863 //
2864 //    We use the following heuristics.  
2865 //        1.) Any br is a return from function
2866 //        2.) bctr or b insn followed by zero insn is a return from a function.
2867 //
2868 // WARNING:  We use the heuristic that any return insns followed by a 0
2869 //   is the last return in the current function.
2870 //
2871 bool isReturnInsn(const image *owner, Address adr)
2872 {
2873   bool        ret;
2874   instruction instr;
2875   instruction nextInstr;
2876
2877 #ifdef ndef
2878   // Currently there is a problem with finding the return insn on AIX,
2879   // which was found once we started using xlc to compile programs
2880   // xlc uses a br branch to branch inside the function, in addition with
2881   // optmize flags, xlc using conditional branch returns; a conditional branch
2882   // which could branch to somewhere inside of the function or leave the
2883   // function we are working on a new way to handle this, but for it has not
2884   // been implemented, tested, etc. as of now, so it is not here.
2885   // if you have any questins, contact sec@cs.wisc.edu
2886
2887   // Finding a return instruction is becomming harder then predicted,
2888   // right now be safe and allow a bctr or br followed by a 
2889   // 0, raw, instruction--won't always work, but will never fail
2890   // this will be fixed soon, being worked on now...  -- sec
2891   instr.raw = owner->get_instruction(adr);
2892   nextInstr.raw = owner->get_instruction(adr+4);
2893   if(isInsnType(instr, FULLmask, BRraw) ||
2894      isInsnType(instr, FULLmask, BCTRraw)) {     // bctr, br, or b
2895     if(nextInstr.raw == 0) {
2896       ret = true;
2897     } else {
2898       ret = false;
2899     }
2900   } else {
2901     ret = false;
2902   }
2903 #else
2904   instr.raw = owner->get_instruction(adr);
2905   nextInstr.raw = owner->get_instruction(adr+4);
2906   
2907   if(isInsnType(instr, FULLmask, BRraw)) {      // br instruction
2908     ret = true;
2909   } else if (isInsnType(instr, FULLmask, BCTRraw) ||
2910              isInsnType(instr, Bmask, Bmatch)) {  // bctr or b 
2911     if (nextInstr.raw == 0) {
2912       ret = true;
2913     } else {
2914       ret = false;
2915     }
2916   } else {
2917     ret = false;
2918   }
2919 #endif
2920
2921   return ret;
2922 }
2923  * ************************************************************************ */
2924
2925 bool pd_Function::findInstPoints(const image *owner) 
2926 {  
2927   Address adr = getAddress(0);
2928   instruction instr;
2929   bool err;
2930
2931   instr.raw = owner->get_instruction(adr);
2932   if (!IS_VALID_INSN(instr)) {
2933     return false;
2934   }
2935
2936   funcEntry_ = new instPoint(this, instr, owner, adr, true, ipFuncEntry);
2937   assert(funcEntry_);
2938
2939   // instead of finding the return instruction, we are creating a 
2940   // return base trampoline which will be called when the function really
2941   // exits.  what will happen is that the link register, which holds the
2942   // pc for the return branch, will be changed to point ot this trampoline,
2943   //
2944   // !!! Note that because there is no specific instruction that corresponds
2945   //     to this point, we don't have an address to pass to the instPoint
2946   //     constructor.  Because Dyninst maintains a mapping from addresses to
2947   //     instrumentation points, it requires that each point has a unique
2948   //     address.  In order to provide this, we pass the address of the
2949   //     entry point + 1 as the address of the exit point.  Since an
2950   //     instruction must be on a word boundary, this address is guaranteed
2951   //     not to be used by any other point in the function.
2952   instruction retInsn;
2953   retInsn.raw = 0;
2954   funcReturns.push_back(new instPoint(this, retInsn, owner, adr+1, false, ipFuncReturn));
2955
2956   // Define call sites in the function
2957   instr.raw = owner->get_instruction(adr);
2958   while(instr.raw != 0x0) {
2959     if (isCallInsn(instr)) {
2960       // Define the call point
2961       adr = newCallPoint(adr, instr, owner, err);
2962       if (err) return false;
2963     }
2964     else if (isDynamicCall(instr)) {
2965       // Define the call point
2966       adr = newCallPoint(adr, instr, owner, err);
2967       if (err) return false;
2968     }
2969
2970     // now do the next instruction
2971     adr += sizeof(instruction);
2972     instr.raw = owner->get_instruction(adr);
2973   }
2974
2975   // Check for linkage code, and if so enter the call site as 
2976   // a static call.
2977   // Linkage template:
2978   // l      r12,<offset>(r2) // address of call into R12
2979   // st     r2,20(r1)        // Store old TOC on the stack
2980   // l      r0,0(r12)        // Address of callee func
2981   // l      r2,4(r12)        // callee TOC
2982   // mtctr  0                // We keep the LR static, use the CTR
2983   // bctr                    // non-saving branch to CTR
2984   // All linkage code will be in module glink.s, and have _linkage
2985   // appended to the function name by the parser. Woohoo.
2986
2987
2988   return(true);
2989 }
2990
2991
2992
2993 //
2994 // Each processor may have a different heap layout.
2995 //   So we make this processor specific.
2996 //
2997 // find all DYNINST symbols that are data symbols
2998 bool process::heapIsOk(const vector<sym_data> &find_us) {
2999   Address baseAddr;
3000   Symbol sym;
3001   string str;
3002
3003   // find the main function
3004   // first look for main or _main
3005   if (!((mainFunction = findOneFunction("main")) 
3006         || (mainFunction = findOneFunction("_main")))) {
3007      string msg = "Cannot find main. Exiting.";
3008      statusLine(msg.string_of());
3009      showErrorCallback(50, msg);
3010      return false;
3011   }
3012
3013   for (unsigned i=0; i<find_us.size(); i++) {
3014     const string &str = find_us[i].name;
3015     if (!getSymbolInfo(str, sym, baseAddr)) {
3016       string str1 = string("_") + str.string_of();
3017       if (!getSymbolInfo(str1, sym, baseAddr) && find_us[i].must_find) {
3018         string msg;
3019         msg = string("Cannot find ") + str + string(". Exiting");
3020         statusLine(msg.string_of());
3021         showErrorCallback(50, msg);
3022         return false;
3023       }
3024     }
3025   }
3026 #if 0
3027   //string ghb = "_DYNINSTtext";
3028   //aix.C does not change the leading "." of function names to "_" anymore.
3029   //  Instead, the "." is simply skipped.
3030   string ghb = "DYNINSTtext";
3031   if (!symbols->symbol_info(ghb, sym)) {
3032       string msg;
3033       msg = string("Cannot find ") + ghb + string(". Exiting");
3034       statusLine(msg.string_of());
3035       showErrorCallback(50, msg);
3036       return false;
3037   }
3038   instHeapStart = sym.addr();
3039
3040   // check that we can get to our heap.
3041   if (instHeapStart > getMaxBranch() + symbols->codeOffset()) {
3042     logLine("*** FATAL ERROR: Program text + data too big for dyninst\n");
3043     sprintf(errorLine, "    heap starts at 0x%lx\n", instHeapStart);
3044     logLine(errorLine);
3045     sprintf(errorLine, "    max reachable at 0x%lx\n", 
3046         getMaxBranch() + symbols->codeOffset());
3047     logLine(errorLine);
3048     showErrorCallback(53,(const char *) errorLine);
3049     return false;
3050   } else if (instHeapStart + SYN_INST_BUF_SIZE > 
3051              getMaxBranch() + symbols->codeOffset()) {
3052     logLine("WARNING: Program text + data could be too big for dyninst\n");
3053     showErrorCallback(54,(const char *) errorLine);
3054     return false;
3055   }
3056   string hd = "DYNINSTdata";
3057   if (!symbols->symbol_info(hd, sym)) {
3058       string msg;
3059       msg = string("Cannot find ") + hd + string(". Exiting");
3060       statusLine(msg.string_of());
3061       showErrorCallback(50, msg);
3062       return false;
3063   }
3064 #endif
3065   return true;
3066 }
3067
3068
3069
3070 //
3071 // This is specific to some processors that have info in registers that we
3072 //   can read, but should not write.
3073 //   On power, registers r3-r11 are parameters that must be read only.
3074 //     However, sometimes we have spilled to paramter registers back to the
3075 //     stack to use them as scratch registers.  In this case they are writeable.
3076 //
3077 bool registerSpace::readOnlyRegister(Register reg_number) 
3078 {
3079     registerSlot *regSlot = NULL;
3080
3081     // it's not a parameter registers so it is read/write
3082     if ((reg_number > 11) || (reg_number < 3)) return false;
3083
3084     // find the registerSlot for this register.
3085     for (u_int i = 0; i < regSpace->getRegisterCount(); i++) {
3086         regSlot = regSpace->getRegSlot(i);
3087         if (regSlot->number == reg_number) {
3088             break;
3089         }
3090     }
3091
3092     if (regSlot->mustRestore) {
3093         // we have already wrriten this to the stack so its OK to clobber it.
3094         return(false);
3095     } else {
3096         // its a live parameter register.
3097         return true;
3098     }
3099 }
3100
3101
3102 bool returnInstance::checkReturnInstance(const vector<Address> &/*adr*/,
3103                                          u_int &/*index*/)
3104 {
3105 #ifdef ndef  
3106 // TODO: implement this.  This stuff is not implemented for this platform 
3107     for(u_int i=0; i < adr.size(); i++){
3108         index = i;
3109         if ((adr[i] > addr_) && ( adr[i] <= addr_+size_)){
3110              return false;
3111         }
3112     }
3113 #endif
3114     return true;
3115 }
3116  
3117 void returnInstance::installReturnInstance(process *proc) {
3118     proc->writeTextSpace((caddr_t)addr_, instSeqSize, (caddr_t) instructionSeq); 
3119         installed = true;
3120 }
3121
3122 void returnInstance::addToReturnWaitingList(Address , process * ) {
3123     int blah = 0;
3124     assert(blah);
3125     P_abort();
3126 }
3127
3128 void generateBreakPoint(instruction &insn) { // instP.h
3129     insn.raw = BREAK_POINT_INSN;
3130 }
3131
3132 void generateIllegalInsn(instruction &insn) { // instP.h
3133    insn.raw = 0; // I think that on power, this is an illegal instruction (someone check this please) --ari
3134 }
3135
3136 bool doNotOverflow(int value)
3137 {
3138   // we are assuming that we have 15 bits to store the immediate operand.
3139   if ( (value <= 32767) && (value >= -32768) ) return(true);
3140   else return(false);
3141 }
3142
3143 void instWaitingList::cleanUp(process * , Address ) {
3144     P_abort();
3145 }
3146
3147 bool completeTheFork(process *parentProc, int childpid) {
3148    // no "process" structure yet exists for the child.
3149    // a fork syscall has just happened.  On AIX, this means that
3150    // the text segment of the child has been reset instead of copied
3151    // from the parent process.  This routine "completes" the fork so that
3152    // it behaves like a normal UNIX fork.
3153
3154    // First, we copy everything from the parent's inferior text heap
3155    // to the child.  To do this, we loop thru every allocated item in
3156
3157    forkexec_cerr << "WELCOME to completeTheFork parent pid is " << parentProc->getPid()
3158                  << ", child pid is " << childpid << endl;
3159
3160    vector<heapItem*> srcAllocatedBlocks = parentProc->heap.heapActive.values();
3161
3162    char buffer[2048];
3163    const unsigned max_read = 1024;
3164
3165    for (unsigned lcv=0; lcv < srcAllocatedBlocks.size(); lcv++) {
3166       const heapItem &srcItem = *srcAllocatedBlocks[lcv];
3167
3168       assert(srcItem.status == HEAPallocated);
3169       unsigned addr = srcItem.addr;
3170       int      len  = srcItem.length;
3171       const unsigned last_addr = addr + len - 1;
3172
3173       unsigned start_addr = addr;
3174       while (start_addr <= last_addr) {
3175          unsigned this_time_len = len;
3176          if (this_time_len > max_read)
3177             this_time_len = max_read;
3178
3179          if (!parentProc->readDataSpace((const void*)addr, this_time_len, buffer, true))
3180             assert(0);
3181
3182          // now write "this_time_len" bytes from "buffer" into the inferior process,
3183          // starting at "addr".
3184          // Will this have problems with the 1024-byte-at-a-time limit?
3185          if (-1 == ptrace(PT_WRITE_BLOCK, childpid, (int*)addr, this_time_len,
3186                           (int*)buffer))
3187             assert(0);
3188
3189          start_addr += this_time_len;
3190       }
3191    }
3192
3193    // Okay that completes the first part; the inferior text heap contents have
3194    // been copied.  In other words, the base and mini tramps have been copied.
3195    // But now we need to update parts where the code that jumped to the base
3196    // tramps.
3197
3198    // How do we do this?  We loop thru all instInstance's of the parent process.
3199    // Fields of interest are:
3200    // 1) location (type instPoint*) -- where the code was put
3201    // 2) trampBase (type unsigned)  -- base of code.
3202    // 3) baseInstance (type trampTemplate*) -- base trampoline instance
3203
3204    // We can use "location" as the index into dictionary "baseMap"
3205    // of the parent process to get a "trampTemplate".
3206
3207    vector<instInstance*> allParentInstInstances;
3208    getAllInstInstancesForProcess(parentProc, allParentInstInstances);
3209
3210    for (unsigned lcv=0; lcv < allParentInstInstances.size(); lcv++) {
3211       instInstance *inst = allParentInstInstances[lcv];
3212       assert(inst);
3213
3214       instPoint *theLocation = inst->location;
3215       unsigned addr = theLocation->addr;
3216
3217       // I don't think we need these - naim
3218       //unsigned   theTrampBase = inst->trampBase;
3219       //trampTemplate *theBaseInstance = inst->baseInstance;
3220
3221       // I had to comment out the following line because it was causing 
3222       // problems. Also, I don't understand why do we want to overwrite the
3223       // content of the baseAddr field in the parent - naim
3224       //if (theBaseInstance) theBaseInstance->baseAddr = theTrampBase;
3225
3226       if (theLocation->addr==0) {
3227         // This happens when we are only instrumenting the return point of
3228         // a function, so we need to find the address where to insert the
3229         // jump to the base trampoline somewhere else. Actually, if we have
3230         // instrumentation at the entry point, this is not necessary, but
3231         // it looks easier this way - naim
3232         const function_base *base_f = theLocation->iPgetFunction();
3233         assert(base_f);
3234         const instPoint *ip = base_f->funcEntry(parentProc);
3235         assert(ip);
3236         addr = ip->addr;
3237       }
3238       assert(addr);
3239
3240       // Now all we need is a "returnInstance", which contains
3241       // "instructionSeq", a sequence of instructions to be installed,
3242       // and "addr_", an address to write to.
3243
3244       // But for now, since we always relocate exactly ONE
3245       // instruction on AIX, we can hack our way around without
3246       // the returnInstance.
3247
3248       // So, we need to copy one word.  The word to copy can be found
3249       // at address "theLocation->addr" for AIX.  The original instruction
3250       // can be found at "theLocation->originalInstruction", but we don't
3251       // need it.  So, we ptrace-read 1 word @ theLocation->addr from
3252       // the parent process, and then ptrace-write it to the same location
3253       // in the child process.
3254
3255       if (theLocation->ipLoc != ipFuncReturn) {
3256         // 64-bit problem
3257         int data; // big enough to hold 1 instr
3258         
3259         errno = 0;
3260         data = ptrace(PT_READ_I, parentProc->getPid(), 
3261                       (int*)addr, 0, 0);
3262         if (data == -1 && errno != 0) {
3263           fprintf(stderr, "Error in fork handler, parent proc %d, reading instr at %x\n", parentProc->getPid(), addr);
3264           perror("fork handler");
3265           assert(0);
3266         }
3267       errno = 0;
3268       if (-1 == ptrace(PT_WRITE_I, childpid, (int*)addr, data, 0) &&
3269           errno != 0)
3270          assert(0);
3271       }
3272    }
3273    return true;
3274 }
3275
3276
3277 // hasBeenBound: returns false
3278 // On AIX (at least what we handle so far), all symbols are bound
3279 // at load time. This kind of obviates the need for a hasBeenBound
3280 // function: of _course_ the symbol has been bound. 
3281 // So the idea of having a relocation entry for the function doesn't
3282 // quite make sense. Given the target address, we can scan the function
3283 // lists until we find the desired function.
3284
3285 bool process::hasBeenBound(const relocationEntry ,pd_Function *&, Address ) {
3286   // What needs doing:
3287   // Locate call instruction
3288   // Decipher call instruction (static/dynamic call, global linkage code)
3289   // Locate target
3290   // Lookup target
3291   return false; // Haven't patched this up yet
3292 }
3293
3294 // findCallee
3295 bool process::findCallee(instPoint &instr, function_base *&target){
3296   if((target = const_cast<function_base *>(instr.iPgetCallee()))) {
3297     return true; // callee already set
3298   }
3299   // Other possibilities: call through a function pointer,
3300   // or a inter-module call. We handle inter-module calls as
3301   // a static function call.
3302   const image *owner = instr.iPgetOwner();
3303   const function_base *caller = instr.iPgetFunction();
3304   // Or module == glink.s == "Global_Linkage"
3305   if (caller->prettyName().suffixed_by("_linkage"))
3306     {
3307       // Make sure we're not mistaking a function named
3308       // *_linkage for global linkage code. 
3309       if (instr.originalInstruction.raw != 0x4e800420) // BCTR
3310         return false;
3311       Address TOC_addr = (owner->getObject()).getTOCoffset();
3312       instruction offset_instr;
3313       offset_instr.raw = owner->get_instruction(instr.addr - 20); // Five instructions up.
3314       if ((offset_instr.dform.op != Lop) ||
3315           (offset_instr.dform.rt != 12) ||
3316           (offset_instr.dform.ra != 2))
3317         // Not a l r12, <offset>(r2), so not actually linkage code.
3318         return false;
3319       // This should be the contents of R12 in the linkage function
3320       Address callee_TOC_entry = owner->get_instruction(TOC_addr + offset_instr.dform.d_or_si);
3321       // We need to find what object the callee TOC entry is defined in. This will be the
3322       // same place we find the function, later.
3323       Address callee_addr = 0;
3324       const image *callee_img = NULL;
3325       if ( (callee_addr = symbols->get_instruction(callee_TOC_entry) ))
3326         callee_img = symbols;
3327       else
3328         if (shared_objects) {
3329           for(u_int i=0; i < shared_objects->size(); i++){
3330             const image *img_tmp = ((*shared_objects)[i])->getImage();
3331             if ( (callee_addr = img_tmp->get_instruction(callee_TOC_entry)))
3332               {
3333                 callee_img = img_tmp;
3334                 break;
3335               }
3336           }
3337         }
3338       if (!callee_img) return false;
3339       // callee_addr: address of function called, contained in image callee_img
3340       // Sanity check on callee_addr
3341       if (
3342           ((callee_addr < 0x20000000) ||
3343            (callee_addr > 0xdfffffff)))
3344         {
3345           if (callee_addr != 0) { // unexpected -- where is this function call? Print it out.
3346             fprintf(stderr, "Skipping illegal address 0x%x in function %s\n",
3347                     (unsigned) callee_addr, caller->prettyName().string_of());
3348           }
3349           return false;
3350         }
3351
3352       // Again, by definition, the function is not in owner. Loop through all 
3353       // images to find it.
3354       // It needs the process pointer (this) to determine absolute address
3355       pd_Function *pdf = 0;
3356       if ( (pdf = callee_img->findFuncByAddr(callee_addr, this) ))
3357         {
3358           target = pdf;
3359           instr.set_callee(pdf);
3360           return true;
3361         }
3362       else
3363         fprintf(stderr, "Couldn't find target function for address 0x%x\n",
3364                 (unsigned) callee_addr);
3365     }
3366   // Todo
3367   target = 0;
3368   return false;
3369   
3370 }
3371
3372
3373 // process::replaceFunctionCall
3374 //
3375 // Replace the function call at the given instrumentation point with a call to
3376 // a different function, or with a NOOP.  In order to replace the call with a
3377 // NOOP, pass NULL as the parameter "func."
3378 // Returns true if sucessful, false if not.  Fails if the site is not a call
3379 // site, or if the site has already been instrumented using a base tramp.
3380 bool process::replaceFunctionCall(const instPoint *point,
3381                                   const function_base *newFunc) {
3382
3383     // Must be a call site
3384     if (point->ipLoc != ipFuncCallPoint)
3385         return false;
3386
3387     // Cannot already be instrumented with a base tramp
3388     if (baseMap.defines(point))
3389         return false;
3390
3391     instruction newInsn;
3392     if (newFunc == NULL) {      // Replace with a NOOP
3393         generateNOOP(&newInsn);
3394     } else {                    // Replace with a new call instruction
3395         generateBranchInsn(&newInsn, newFunc->addr()-point->addr);
3396         newInsn.iform.lk = 1;
3397     }
3398
3399     writeTextSpace((caddr_t)point->addr, sizeof(instruction), &newInsn);
3400
3401     return true;
3402 }
3403
3404 // Emit code to jump to function CALLEE without linking.  (I.e., when
3405 // CALLEE returns, it returns to the current caller.)
3406
3407 // 18FEB00 -- I removed the parameter names to get rid of compiler
3408 // warnings. They are copied below.
3409 // opCode op, char *i, Address &base, const function_base *callee, process *proc
3410
3411 void emitFuncJump(opCode, 
3412                   char *, Address &, 
3413                   const function_base *unused, process *)
3414 {
3415   // Get rid of a warning about the unused parameter
3416      if (unused) ;
3417      /* Unimplemented on this platform! */
3418      assert(0);
3419 }
3420
3421 // Match AIX register numbering (sys/reg.h)
3422 #define REG_LR  131
3423 #define REG_CTR 132
3424
3425 void emitLoadPreviousStackFrameRegister(Address register_num, 
3426                                         Register dest,
3427                                         char *insn,
3428                                         Address &base,
3429                                         int size,
3430                                         bool noCost)
3431 {
3432   // Offset if needed
3433   int offset;
3434   instruction *insn_ptr = (instruction *)insn;
3435   // We need values to define special registers.
3436   switch ( (int) register_num)
3437     {
3438     case REG_LR:
3439       // LR is saved down the stack
3440       offset = STKLR - STKPAD; 
3441       // Get address (SP + offset) and stick in register dest.
3442       emitImm(plusOp ,(Register) REG_SP, (RegValue) offset, dest, insn, 
3443               base, noCost);
3444       // Load LR into register dest
3445       emitV(loadIndirOp, dest, 0, dest, insn, base, noCost, size);
3446       break;
3447     case REG_CTR:
3448       // CTR is saved down the stack
3449       /*
3450       offset = STKCTR - STKPAD; 
3451       // Get address (SP + offset) and stick in register dest.
3452       emitImm(plusOp ,(Register) REG_SP, (RegValue) offset, dest, insn, 
3453               base, noCost);
3454       // Load LR into register dest
3455       emitV(loadIndirOp, dest, 0, dest, insn, base, noCost, size);
3456       */
3457       // Actually, for non-dyninst we don't touch the CTR. So move
3458       // it from SPR 9 (the CTR) to the appropriate register (dest)
3459       insn_ptr->raw = 0;          // zero the instruction
3460       insn_ptr->xform.op = 31;    // mfspr
3461       insn_ptr->xform.rt = dest ; // target register
3462       insn_ptr->xform.ra = 9;     // SPR number (see comment above saveSPR())
3463       insn_ptr->xform.rb = 0; 
3464       insn_ptr->xform.xo = 339;   // extended opcode
3465       base += sizeof(instruction);
3466       break;
3467     default:
3468       cerr << "Fallthrough in emitLoadPreviousStackFrameRegister" << endl;
3469       cerr << "Unexpected register " << register_num << endl;
3470       abort();
3471       break;
3472     }
3473 }
3474
3475 #ifndef BPATCH_LIBRARY
3476 bool process::isDynamicCallSite(instPoint *callSite){
3477   function_base *temp;
3478   if(!findCallee(*(callSite),temp)){
3479     return true;
3480   }
3481   return false;
3482 }
3483
3484 bool process::MonitorCallSite(instPoint *callSite){
3485   instruction i = callSite->originalInstruction;
3486   vector<AstNode *> the_args(2);
3487   Register branch_target;
3488
3489   // Is this a branch conditional link register (BCLR)
3490   // BCLR uses the xlform (6,5,5,5,10,1)
3491   if(i.xlform.op == BCLRop) // BLR/BCR, or bcctr/bcc. Same opcode.
3492     {
3493       if (i.xlform.xo == BCLRxop) // BLR (bclr)
3494         {
3495           branch_target = REG_LR;
3496         }
3497       else if (i.xlform.xo == BCCTRxop)
3498         {
3499           // We handle global linkage branches (BCTR) as static call
3500           // sites. They're currently registered when the static call
3501           // graph is built (Paradyn), after all objects have been read
3502           // and parsed.
3503           branch_target = REG_CTR;
3504         }
3505       else
3506         {
3507           // Used to print an error, but the opcode (19) is also used
3508           // for other instructions, and errors could confuse people.
3509           // So just return false instead.
3510           return false;
3511         }
3512       // Where we're jumping to (link register, count register)