- New file to extract type info from executables in Coff format
[dyninst.git] / dyninstAPI / src / inst-alpha.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 // $Id: inst-alpha.C,v 1.20 2000/01/11 21:55:34 altinel Exp $
43
44 #include "util/h/headers.h"
45
46 #ifdef BPATCH_LIBRARY
47 #include "dyninstAPI_RT/h/dyninstAPI_RT.h"
48 #else
49 #include "rtinst/h/rtinst.h"
50 #endif
51 #include "dyninstAPI/src/symtab.h"
52 #include "dyninstAPI/src/process.h"
53 #include "dyninstAPI/src/inst.h"
54 #include "dyninstAPI/src/instP.h"
55 #include "dyninstAPI/src/arch-alpha.h"
56 #include "dyninstAPI/src/ast.h"
57 #include "dyninstAPI/src/util.h"
58 #include "dyninstAPI/src/instPoint.h"
59 #include <sys/procfs.h>
60 #ifndef BPATCH_LIBRARY
61 #include "dyninstAPI/src/internalMetrics.h"
62 #endif
63 #include "dyninstAPI/src/stats.h"
64 #include "dyninstAPI/src/os.h"
65
66 /*
67    This has not been fully tested.
68    The Alpha likes to use jsrs much more than the sparc. 
69    Paradyn assumes jsrs are jumps to library functions -- this is incorrect.
70    It causes timers to be left on for many functions.  These timers are not 
71    supposed to overlap.
72
73    gcc compiles code in an interesting manner for the Alpha.  It creates an 
74    alternate entry point for most functions.  If gcc -S is run, the alternate
75    entry point has ..NG appended to the function name.  The alternate entry 
76    point does not show up in the symbol table.  I don't know the rules for 
77    choosing which entry point to use.  The alternate entry point is usually
78    two instructions after the advertised entry point.  This code will not work
79    with gcc compiled applications.  The runtime must also not be compiled with
80    gcc.
81
82    I have seen generated code that uses a register other than 'ra' for the return
83    address (a temporary register had been used).  I find this disturbing and played
84    it mostly safe when it came to saving registers.  At the base tramp, all registers
85    that a callee can clobber are saved.  This is done before and after the relocated
86    instruction.  One simple optimization is to avoid doing the save and restore
87    unless a slot is used on that side of the relocated instruction.
88
89    I have had to split the DYNINSTdata field into DYNINSTcode and DYNINSTdata.
90    The branch displacement is not large enough to reach DYNINSTdata from text space.
91    Programs compiled using cc should specify '-taso -non_shared -N'
92
93    The 'pv' register must contain the address of the callee when the callee is called.
94    I have not seen any documentation on this.  The API does not mention this.
95
96    'TODO' is used to mark loose ends -- this file does not have too many.
97    
98    Optimizing branch behavior (not implemented)
99    * branch to quadword or octaword aligned addresses
100    * forward conditional branches are predicted not taken, take advantage of this
101
102    Optimizing branch behavior (implemented)
103    * use least significant 16 bits of JSR for branch prediction
104
105  */
106
107
108 // HACK: This allows the bootstrap code for loading the dyninst library to
109 //    skip calling save/restore register code.
110 bool skipSaveCalls = false;
111
112 // The API for Alphas does not appear to be followed in all cases
113 // rather than spend much time and effort disassembling and cursing
114 // registers will be saved and restored in the base trampoline
115 // A save/restore pair will be executed before and after the relocated
116 // instruction.  An obvious optimization is to not do the save/restore
117 // when no code is inserted before or after the relocated instruction.
118 // 
119
120 // static inline Address generate_integer_op(instruction *insn, Address, Address,
121 //                                        Address, unsigned&, opCode);
122 // static inline Address generate_call_code(instruction*, Address, Address,
123 //                                       Address, unsigned&, process *proc);
124 // static inline Address generate_tramp_preamble(instruction*, Address,
125 //                                            Address, unsigned&);
126 static inline void generate_integer_op(instruction *insn, Address, Address,
127                                           Address, unsigned long&, opCode,bool Imm = false);
128 static inline Address generate_call_code(instruction*, Address, Address,
129                                          Address, unsigned long&, process *proc);
130 static inline void generate_tramp_preamble(instruction*, Address,
131                                               Address, unsigned long&);
132
133 // Register usage conventions:
134 //   a0-a5 are saved in the base trampoline
135 //   t0-t10 are scratch and do not have to be saved as long as instrumentation
136 //      is restricted to function entry/exit, and call points
137 //      these will be allocated by paradynd
138 //
139 //   t0-t7 : allocated by paradynd
140 //   t8: stores compare results, scratch for paradynd
141 //   t9,t10 : used as scratch registers by paradynd
142
143 // Return value register
144 #define REG_V0           0
145 // scratch registers -- not saved across procedure calls
146 #define REG_T0           1
147 #define REG_T1           2
148 #define REG_T2           3
149 #define REG_T3           4
150 #define REG_T4           5
151 #define REG_T5           6
152 #define REG_T6           7
153 #define REG_T7           8
154
155 // caller save registers
156 #define REG_S0           9
157 #define REG_S1          10
158 #define REG_S2          11
159 #define REG_S3          12
160 #define REG_S4          13
161 #define REG_S5          14
162
163 // argument registers
164 #define REG_A0          16
165 #define REG_A1          17
166 #define REG_A2          18
167 #define REG_A3          19
168 #define REG_A4          20
169 #define REG_A5          21
170
171 // more scratch registers
172 #define REG_T8          22
173 #define REG_T9          23
174 #define REG_T10         24
175 #define REG_T11         25
176
177 // return address register
178 #define REG_RA          26
179
180 // undocumented pv/t12
181 #define REG_PV          27
182 #define REG_T12         27
183
184 #define REG_GP          29
185 #define REG_SP          30
186 #define REG_ZERO        31
187
188 const unsigned Num_Registers=32;
189
190 typedef enum { dw_long, dw_quad } data_width;
191
192 #define MASK_4(x)     (x & 0xffffffff)
193 #define MASK_2(x)     (x & 0xffff)
194
195 const Address shifted_16 = (Address(1)) << 16;
196 const Address shifted_32 = (Address(1)) << 32;
197 const Address shifted_48 = (Address(1)) << 48;
198 const Address bit_15 =     (Address(1)) << 15;
199 const Address bit_31 =     (Address(1)) << 31;
200 const Address bit_47 =     (Address(1)) << 47;
201
202 const char *registerNames[] = { "ren", "stimpy" };
203 registerSpace *regSpace;
204 Register regList[] = {1, 2, 3, 4, 5, 6, 7, 8};
205
206 trampTemplate baseTemplate;
207
208 string getStrOp(int /* op */) {
209   assert(0);
210 }
211
212 // BIS (or)  R31, R31, R31
213 // unsigned generate_nop(instruction* insn) {
214 unsigned long generate_nop(instruction* insn) {
215   insn->raw = 0;
216   // insn.oper.zero = 0; insn.oper.sbz = 0;
217   insn->oper.opcode = OP_BIS;
218   insn->oper.function = FC_BIS;
219   insn->oper.ra = 31;
220   insn->oper.rb = 31;
221   insn->oper.rc = 31;
222   return 1;
223 }
224
225 inline void generateNOOP(instruction *insn)
226 {
227   insn->raw = 0;
228   // insn.oper.zero = 0; insn.oper.sbz = 0;
229   insn->oper.opcode = OP_BIS;
230   insn->oper.function = FC_BIS;
231   insn->oper.ra = 31;
232   insn->oper.rb = 31;
233   insn->oper.rc = 31;
234 }
235
236 #define FIRST_16(x)       ((x) & 0xffff)
237 #define SECOND_16(x)      ((x) >> 16)
238 #define THIRD_16(x)       ((x) >> 32)
239
240 #define ABS(x)          ((x) > 0 ? (x) : -(x))
241
242 // TODO -- the max branch is (0x1 << 22)
243 // if we limited branches to this distance, dyn. inst. would not work
244 // on a 64 bit architecture
245 #define MAX_BRANCH      (0x1<<22)
246
247 #define MAX_IMM 0x1<<8  // 8 bits
248
249 Address getMaxBranch() { 
250   return ((Address)(1 << 22));
251 }
252
253 bool doNotOverflow(int value)
254 {
255   // we are assuming that we have 8 bits to store the immediate operand.
256   if ( (value >= 0) && (value <= 255) ) return(true);
257   else return(false);
258 }
259
260 void instWaitingList::cleanUp(process * , Address ) {
261     P_abort();
262 }
263
264 // 
265 //
266 // unsigned
267 // generate_operate(instruction *insn, unsigned reg_a, unsigned reg_b, 
268 //               unsigned reg_c, unsigned opcode, unsigned func_code) {
269 unsigned long
270 generate_operate(instruction *insn, Register reg_a, Register reg_b, 
271          Register reg_c, unsigned int opcode, unsigned int func_code) {
272   assert(reg_a < Num_Registers);
273   assert(reg_b < Num_Registers);
274   assert(reg_c < Num_Registers);
275   insn->raw = 0;
276   // insn->oper.zero = 0; insn->oper.sbz = 0;
277   insn->oper.ra = reg_a; insn->oper.rb = reg_b; insn->oper.rc = reg_c;
278   insn->oper.opcode = opcode;
279   insn->oper.function = func_code;
280   return 1;
281 }
282
283 // 
284 //
285 // unsigned
286 // generate_lit_operate(instruction *insn, unsigned reg_a, int literal,
287 //                   unsigned reg_c, unsigned opcode, unsigned func_code) {
288 unsigned long
289 generate_lit_operate(instruction *insn, Register reg_a, int literal,
290              Register reg_c, unsigned int opcode, unsigned int func_code) {
291   assert(reg_a < Num_Registers);
292   // literal is 0 to 255
293   assert((literal >= 0) && (literal < MAX_IMM));
294   assert(reg_c < Num_Registers);
295   insn->raw = 0;
296   insn->oper_lit.one = 1;
297   insn->oper_lit.ra = reg_a;
298   insn->oper_lit.lit = literal;
299   insn->oper_lit.rc = reg_c;
300   insn->oper_lit.opcode = opcode;
301   insn->oper_lit.function = func_code;
302   return 1;
303 }
304
305 // j?? ra, (rb), hint
306 // jump to rb, ra gets return address, displacement field provides 
307 // instruction fetch hint
308 // TODO -- provide a decent hint
309 // unsigned
310 // generate_jump(instruction *insn, unsigned dest_reg, unsigned ext_code,
311 //            unsigned ret_reg, int hint) {
312 unsigned long
313 generate_jump(instruction *insn, Register dest_reg, unsigned long ext_code,
314               Register ret_reg, int hint) {
315   assert(dest_reg < Num_Registers); 
316   assert(ret_reg < Num_Registers); 
317   assert((ext_code == MD_JSR) || (ext_code == MD_JMP));
318
319   // If you want to use this for other ext_code values, then modify the branch
320   // prediction
321
322   insn->raw = 0;
323   insn->mem_jmp.opcode = OP_MEM_BRANCH;
324   insn->mem_jmp.ext = ext_code;
325   insn->mem_jmp.ra = ret_reg;
326   insn->mem_jmp.rb = dest_reg;
327   insn->mem_jmp.disp = hint;
328   return 1;
329 }
330
331
332 // src_reg --> for unconditional branch, gets return address
333 // src_reg --> for conditional branch, is register to test
334 // b??  r31, offset   <-- return address written to r31, which is ignored
335 //
336 // unsigned
337 // generate_branch(instruction *insn, unsigned src_reg, int offset, unsigned opcode) {
338 unsigned long
339 generate_branch(instruction *insn, Register src_reg, int offset,
340                 unsigned int opcode) {
341   if (ABS(offset >> 2) > MAX_BRANCH) 
342         { logLine("a branch too far\n"); assert(0); }
343   assert(src_reg < Num_Registers);
344   insn->raw = 0;
345   insn->branch.opcode = opcode;
346   insn->branch.ra = src_reg;
347   insn->branch.disp = offset >> 2;
348   return 1;
349 }
350
351 void generateBSR(instruction *insn,int offset)
352 {
353   generate_branch(insn,REG_RA,offset,OP_BSR);
354
355 }
356 void generateBranchInsn(instruction *insn, int offset) {
357   generate_branch(insn, REG_ZERO, offset, OP_BR);
358 }
359
360 // 
361 // Set condition flag (a register)
362 // unsigned
363 // genRelOp(instruction *insn, unsigned opcode, unsigned fcode,
364 //       unsigned src1, unsigned src2, unsigned dest, bool do_not=false) {
365 unsigned long
366 genRelOp(instruction *insn, unsigned opcode, unsigned fcode, Register src1,
367          Register src2, Register dest, bool Imm=false, bool do_not=false) {
368   // cmp?? src1, src2, t8      : leave result in t8
369 //  unsigned words = generate_operate(insn, src1, src2, dest, opcode, fcode);
370   unsigned long words;
371   if (Imm)
372     words = generate_lit_operate(insn, src1, src2, dest, opcode, fcode);
373   else
374     words = generate_operate(insn, src1, src2, dest, opcode, fcode);
375
376   if (do_not) {
377     // since there is no cmpne -- cmpeq is used and the result must be inverted
378     // 0 -->  1,  1 ---> 0
379     // negate t8, and add 1  (1 --> -1 + 1 = 0,  0 --> -0 +1 = 1 )
380     words += generate_operate(insn+words, REG_ZERO, dest, dest, OP_SUBL, FC_SUBL);
381     words += generate_lit_operate(insn+words, dest, 1, dest, OP_ADDL, FC_ADDL);
382     // dest now contains a 0 or a 1 
383   }
384   return words;
385 }
386
387 instPoint::instPoint(pd_Function *f, const instruction &instr, 
388                      const image *img, Address &adr,
389                      const bool,instPointType pointType)
390 : addr(adr), originalInstruction(instr), inDelaySlot(false), isDelayed(false),
391   callIndirect(false), callAggregate(false), callee(NULL), func(f),
392   ipType(pointType), image_ptr(img)
393 {
394 }
395
396
397
398 // lda(h) rdest, literal:16(rstart)
399 // put a literal in a register
400 // offset is the value before the shift
401 // unsigned 
402 // generate_lda(instruction *insn, unsigned rdest, unsigned rstart,
403 //           int offset, bool do_low) {
404 unsigned long
405 generate_lda(instruction *insn, Register rdest, Register rstart,
406              long offset, bool do_low) {
407
408   // this is not wuite the correct check, but some calls supply the actual
409   //   signed displacement and others supply the raw 16 bits (i.e. not sign
410   //   extended.  - jkh
411   assert(ABS(offset) < (int) shifted_16);
412   // assert(offset >= (- (long) 0xffffffff));
413   assert(rdest < Num_Registers);
414   assert(rstart < Num_Registers);
415
416   insn->raw = 0;
417   insn->mem.opcode = do_low ? OP_LDA : OP_LDAH;
418   insn->mem.ra = rdest;
419   insn->mem.rb = rstart;
420   insn->mem.disp = offset;
421   return 1;
422 }
423
424 // left == true, shift left
425 // left == false, shift right
426 // unsigned
427 // amount is a literal
428 // generate_sxl(instruction *insn, unsigned rdest, unsigned amount,
429 //           bool left, unsigned rsrc) {
430 unsigned long
431 generate_sxl(instruction *insn, Register rdest, unsigned long amount,
432              bool left, Register rsrc) {
433   assert(rdest < Num_Registers);
434   assert(amount < Num_Registers);
435   assert(rsrc < Num_Registers);
436   insn->raw = 0;
437   // insn->oper.sbz = 0;
438   // insn->oper.zero = 0;
439
440   insn->oper_lit.opcode = left ? OP_SLL : OP_SRL;
441   insn->oper_lit.function = left ? FC_SLL : FC_SRL;
442   insn->oper_lit.one = 1;
443   insn->oper_lit.ra = rsrc;
444   insn->oper_lit.lit = amount;
445   insn->oper_lit.rc = rdest;
446   return 1;
447 }
448
449 #define SEXT_16(x) (((x) & bit_15) ? ((x) | 0xffffffffffff0000) : (x))
450
451 typedef unsigned long int Offset;
452
453 // remainder returns 15 bit offset to be included in load or store
454 // returns number of instruction words
455 // unsigned generate_address(instruction *insn, 
456 //                       unsigned rdest,
457 //                       const Address &addr,
458 //                       int& remainder) {
459 unsigned long generate_address(instruction *insn, 
460                          unsigned long rdest,
461                          const Address &addr,
462                          int& remainder) {
463 //  unsigned words = 0;
464   unsigned long words = 0;
465
466   Offset tempAddr = addr;
467   Offset low = tempAddr & 0xffff;
468   tempAddr -= SEXT_16(low);
469   Offset high = (tempAddr >> 16) & 0xffff;
470   tempAddr -= (SEXT_16(high) << 16);
471   Offset third = (tempAddr >> 32) & 0xffff;
472
473   assert((Address)SEXT_16(low) +
474          ((Address)SEXT_16(high)<<16) +
475          ((Address)SEXT_16(third)<<32) == addr);
476
477   bool primed = false;
478   if (third) {
479     primed = true;
480     assert(third < shifted_16);
481     generate_lda(insn+words, rdest, REG_ZERO, third, false);
482     words++;
483     generate_sxl(insn+words, rdest, 16, true, rdest);  // move (31:15) to (47:32)
484     words++;
485   }
486
487   if (high) {
488     if (primed)
489       generate_lda(insn+words, rdest, rdest, high, false);
490     else
491       generate_lda(insn+words, rdest, REG_ZERO, high, false);
492     words++; 
493     primed = true;
494   }
495   // a better solution is to use register zero as the base
496   // clear the base register
497   if (!primed) 
498     words += generate_operate(insn+words, REG_ZERO, REG_ZERO, rdest, 
499                               OP_BIS, FC_BIS);
500
501   remainder = low;
502   return words;
503 }
504
505 // stx rsrc, [rbase + sign_extend(offset:16)]
506 // unsigned
507 // generate_store(instruction* insn, unsigned rsrc, unsigned rbase, int disp,
508 //             data_width width) {
509 unsigned long
510 generate_store(instruction* insn, Register rsrc, Register rbase, 
511         int disp, data_width width) {
512   assert(ABS(disp) < (int) shifted_16); 
513   assert(rsrc < Num_Registers); 
514   assert(rbase < Num_Registers);
515   insn->raw = 0;
516   insn->mem.disp = FIRST_16(disp);
517   insn->mem.ra = rsrc;
518   insn->mem.rb = rbase;
519   switch (width) {
520   case dw_long: insn->mem.opcode = OP_STL; break;
521   case dw_quad: insn->mem.opcode = OP_STQ; break;
522   default: assert(0);
523   }
524   return 1;
525 }
526
527 // ldx rdest, [rbase + sign_extend(offset:16)]
528 // unsigned
529 // generate_load(instruction *insn, unsigned rdest, unsigned rbase, int disp,
530 //            data_width width) {
531 unsigned long
532 generate_load(instruction *insn, Register rdest, Register rbase, 
533         int disp, data_width width,bool aligned = true) {
534   assert(ABS(disp) < (int) shifted_16); 
535   assert(rdest < Num_Registers);
536   assert(rbase < Num_Registers);
537   insn->raw = 0;
538   insn->mem.disp = disp;
539   insn->mem.ra = rdest;
540   insn->mem.rb = rbase;
541   switch (width) {
542   case dw_long: insn->mem.opcode = OP_LDL; break;
543   case dw_quad: insn->mem.opcode = OP_LDQ; break;
544   default: assert(0);
545   }
546   if (aligned == false)
547     insn->mem.opcode = OP_LDQ_U;
548   return 1;
549 }
550
551
552 // Restore argument registers (a0-a4) or v0
553 void restoreRegister(instruction *&insn, Address &base, int reg, int dest)
554 {
555   assert(reg >= 0);
556   generate_load(insn,dest,REG_SP,(reg<<3),dw_quad);
557   insn++;
558   base += sizeof(instruction);
559 }
560
561 // Determine if the called function is a "library" function or a "user" function
562 // This cannot be done until all of the functions have been seen, verified, and
563 // classified
564 //
565 void pd_Function::checkCallPoints() {
566 //  unsigned i;
567   unsigned long i;
568   instPoint *p;
569   Address loc_addr;
570
571   vector<instPoint*> non_lib;
572
573   for (i=0; i<calls.size(); ++i) {
574     /* check to see where we are calling */
575     p = calls[i];
576     assert(p);
577
578     if (isJsr(p->originalInstruction)) {
579       // assume this is a library function
580       // since it is a jump through a register
581       // TODO -- should this be deleted here ?
582       p->callIndirect = true;
583       non_lib += p;
584       //      delete p;
585     } else if (isBsr(p->originalInstruction)) {
586       loc_addr = p->addr + (p->originalInstruction.branch.disp << 2)+4;
587       non_lib += p;
588       pd_Function *pdf = (file_->exec())->findFunction(loc_addr);
589
590       if (pdf == NULL)
591         {
592           /* Try alternate entry point in the symbol table */
593           loc_addr = loc_addr - 8;
594           pdf = (file_->exec())->findFunction(loc_addr);
595         }
596
597       if (pdf && !pdf->isLibTag())
598           p->callee = pdf;
599     } else {
600       assert(0);
601     }
602   }
603   calls = non_lib;
604 }
605
606 // TODO we cannot find the called function by address at this point in time
607 // because the called function may not have been seen.
608 //
609 Address pd_Function::newCallPoint(Address, const instruction,
610                                   const image *, bool &) {
611     abort();
612     // This is not used on Alpha
613 }
614
615 //
616 // Given and instruction, relocate it to a new address, patching up
617 // any relative addressing that is present.
618 //
619 // Note - currently - only 
620 //
621 void relocateInstruction(instruction* insn, Address origAddr,
622                          Address targetAddr) {
623   Address newOffset;
624
625   if (isBranchType(*insn)) {
626     newOffset = origAddr - targetAddr + (Address) (insn->branch.disp << 2);
627     insn->branch.disp = newOffset >> 2;
628
629     if (ABS(insn->branch.disp) > MAX_BRANCH) {
630       logLine("a branch too far\n");
631       assert(0);
632     }
633   }
634   // The rest of the instructions should be fine as is 
635 }
636
637 registerSpace *createRegisterSpace()
638 {
639   return new registerSpace(sizeof(regList)/sizeof(Register), regList,
640                                 0, NULL);
641 }
642
643 //
644 // We now generate tramps on demand, so all we do is init the reg space.
645 //
646 void initTramps() {
647   static bool init_done=false;
648
649   if (init_done) return;
650   init_done = true;
651
652   regSpace = new registerSpace(sizeof(regList)/sizeof(Register), regList,
653                                 0, NULL);
654 }
655
656 // Emit a func 64bit address for the call
657 inline void callAbsolute(instruction *code, 
658                          unsigned long &words, 
659                          Address funcAddr)
660 {
661   int remainder;
662   words += generate_address(code+(words), REG_GP, funcAddr, remainder);
663   if (remainder)
664     words += generate_lda(code+(words), REG_GP, REG_GP, remainder, true);
665   words += generate_jump(code+(words), REG_GP, MD_JSR, REG_RA, remainder);
666 }
667
668 /*
669  * Install a base tramp -- fill calls with nop's for now.
670  * An obvious optimization is to turn off the save-restore calls when they 
671  * are not needed.
672  */
673 void installBaseTramp(instPoint *location,
674                       process *proc,
675                       trampTemplate &tramp
676                       ) {
677 //  unsigned words = 0;
678   unsigned long words = 0;
679   const int MAX_BASE_TRAMP = 128;
680
681   // XXX - for now assume base tramp is less than 1K
682   instruction *code = new instruction[MAX_BASE_TRAMP]; assert(code);
683
684   function_base *fun_save;
685   function_base *fun_restore;
686
687   Symbol info;
688   Address baseAddr;
689
690   if (location->ipType == otherPoint) {
691       fun_save = proc->findOneFunction("DYNINSTsave_conservative");
692       fun_restore = proc->findOneFunction("DYNINSTrestore_conservative");
693       proc->getSymbolInfo("DYNINSTsave_conservative", info, baseAddr);
694   } else {
695       fun_save = proc->findOneFunction("DYNINSTsave_temp");
696       fun_restore = proc->findOneFunction("DYNINSTrestore_temp");
697       proc->getSymbolInfo("DYNINSTsave_temp", info, baseAddr);
698   }
699
700   assert(fun_save && fun_restore);
701   Address dyn_save = fun_save->addr() + baseAddr;
702   Address dyn_restore = fun_restore->addr() + baseAddr;
703
704   // Pre branch
705   tramp.skipPreInsOffset = words*4;
706   words += generate_nop(code+words);
707
708   // decrement stack by 16
709   tramp.savePreInsOffset = words*4;
710   words += generate_lda(code+words, REG_SP, REG_SP, -16, true);
711
712   // push ra onto the stack
713   words += generate_store(code+words, REG_RA, REG_SP, 0, dw_quad);
714
715   // push GP onto the stack
716   words += generate_store(code+words, REG_GP, REG_SP, 8, dw_quad);
717
718   // Call to DYNINSTsave_temp
719   callAbsolute(code, words, dyn_save);
720
721   // global_pre
722   tramp.globalPreOffset = words * 4;
723   words += generate_nop(code+words);
724
725   // local_pre
726   tramp.localPreOffset = words * 4;
727   words += generate_nop(code+words);
728
729   words += generate_nop(code+words);
730
731   // **** When you change these code also look at emitFuncJump ****
732   // Call to DYNINSTrestore_temp
733   tramp.localPreReturnOffset = words * 4;
734   callAbsolute(code, words, dyn_restore);
735
736   // load ra from the stack
737   words += generate_load(code+words, REG_RA, REG_SP, 0, dw_quad);
738
739   // load GP from the stack
740   words += generate_load(code+words, REG_GP, REG_SP, 8, dw_quad);
741
742   // increment stack by 16
743   tramp.restorePreInsOffset = words*4;
744   words += generate_lda(code+words, REG_SP, REG_SP, 16, true);
745
746   // *** end code cloned in emitFuncJump ****
747
748   // slot for emulate instruction
749   tramp.emulateInsOffset = words*4;
750   instruction *reloc = &code[words]; 
751   *reloc = location->originalInstruction;
752   words += 1;
753   // Do actual relocation once we know the base address of the tramp
754
755   // compute effective address of this location
756   Address pointAddr = location->addr;
757   Address baseAddress;
758   if(proc->getBaseAddress(location->image_ptr, baseAddress)){
759       pointAddr += baseAddress;
760   }
761
762   // decrement stack by 16
763   tramp.savePostInsOffset = words*4;
764   words += generate_lda(code+words, REG_SP, REG_SP, -16, true);
765
766   // push ra onto the stack
767   words += generate_store(code+words, REG_RA, REG_SP, 0, dw_quad);
768
769   // push GP onto the stack
770   words += generate_store(code+words, REG_GP, REG_SP, 8, dw_quad);
771
772   // Call to DYNINSTsave_temp
773   callAbsolute(code, words, dyn_save);
774
775   // global_post
776   tramp.globalPostOffset = words * 4;
777   words += generate_nop(code+words);
778
779   // local_post
780   tramp.localPostOffset = words * 4;
781   words += generate_nop(code+words);
782
783   // Call to DYNINSTrestore_temp
784   tramp.localPostReturnOffset = words * 4;
785   callAbsolute(code, words, dyn_restore);
786
787   // load ra from the stack
788   words += generate_load(code+words, REG_RA, REG_SP, 0, dw_quad);
789
790   // load GP from the stack
791   words += generate_load(code+words, REG_GP, REG_SP, 8, dw_quad);
792
793   // increment stack by 16
794   tramp.restorePostInsOffset = words*4;
795   words += generate_lda(code+words, REG_SP, REG_SP, 16, true);
796
797   // If the relocated insn is a Jsr or Bsr then 
798   // appropriately set Register Ra
799   if (isCallInsn(location->originalInstruction)) {
800       int remainder;
801       words += generate_address(code+words, REG_RA, pointAddr+4,remainder);
802       if (remainder)
803         words += generate_lda(code+words, REG_RA, REG_RA, remainder, true);
804   }
805
806   // slot for return (branch) instruction
807   // actual code after we know its locations
808   // branchFromAddr offset from base until we know base of tramp 
809   Address branchFromAddr = (words * 4);         
810   instruction *branchBack = &code[words];
811   words += 1;
812
813   words += generate_nop(code+words);
814
815   assert(words < MAX_BASE_TRAMP);
816
817   tramp.size = words * sizeof(instruction);
818   tramp.baseAddr = inferiorMalloc(proc, tramp.size, textHeap, pointAddr);
819   assert(tramp.baseAddr);
820
821   // pointAddr + 4 is address of instruction after relocated instr
822   // branchFromAddr = address of the branch insn that returns to user code
823   // branchFromAddr + 4 is updated pc when branch instruction executes
824   // we assumed this one was instruction long before
825   branchFromAddr += tramp.baseAddr;     // update now that we know base
826
827   int count = generate_branch(branchBack, REG_ZERO,
828                            (pointAddr+4) - (branchFromAddr+4), OP_BR);
829   assert(count == 1);
830
831   // Do actual relocation once we know the base address of the tramp
832   relocateInstruction(reloc, pointAddr, 
833        tramp.baseAddr + tramp.emulateInsOffset);
834
835   proc->writeDataSpace((caddr_t)tramp.baseAddr, tramp.size, (caddr_t) code);
836   delete (code);
837 }
838
839 /*
840  * emitSaveConservative - generate code to save all registers
841  *      used as part of inferrior RPC
842  *      We don't know where this will be located, so generate absolute addr
843  *          for the function call.
844  *
845  */
846 void emitSaveConservative(process *proc, char *code, Address &offset)
847 {
848   unsigned count = 0;
849   function_base *fun_save;
850   instruction *insn = (instruction *) ((void*)&code[offset]);
851
852   Symbol info;
853   Address baseAddr;
854   fun_save = proc->findOneFunction("DYNINSTsave_conservative");
855   proc->getSymbolInfo("DYNINSTsave_temp", info, baseAddr);
856   assert(fun_save);
857
858   Address dyn_save = fun_save->addr() + baseAddr;
859
860   // decrement stack by 16
861   count += generate_lda(&insn[count], REG_SP, REG_SP, -16, true);
862
863   // push T10 onto the stack
864   count += generate_store(&insn[count], REG_T10, REG_SP, 0, dw_quad);
865
866   // push ra onto the stack
867   count += generate_store(&insn[count], REG_RA, REG_SP, 8, dw_quad);
868
869   // Call to DYNINSTsave_conservative
870   int remainder;
871   count += generate_address(&insn[count], REG_T10, dyn_save, remainder);
872   if (remainder)
873     count += generate_lda(&insn[count], REG_T10, REG_T10, remainder, true);
874   count += generate_jump(&insn[count], REG_T10, MD_JSR, REG_RA, remainder);
875
876   offset += count * sizeof(instruction);
877 }
878
879 /*
880  * emitSaveConservative - generate code to restore all registers
881  *      used as part of inferrior RPC
882  *      We don't know where this will be located, so generate absolute addr
883  *          for the function call.
884  *
885  */
886 void emitRestoreConservative(process *proc, char *code, Address &offset)
887 {
888   unsigned count = 0;
889   function_base *fun_restore;
890   instruction *insn = (instruction *) ((void*)&code[offset]);
891
892   Symbol info;
893   Address baseAddr;
894   fun_restore = proc->findOneFunction("DYNINSTrestore_conservative");
895   proc->getSymbolInfo("DYNINSTsave_temp", info, baseAddr);
896   assert(fun_restore);
897
898   Address dyn_restore = fun_restore->addr() + baseAddr;
899
900   // Call to DYNINSTrestore_temp
901   int remainder;
902   count += generate_address(&insn[count], REG_T10, dyn_restore, remainder);
903   if (remainder)
904     count += generate_lda(&insn[count], REG_T10, REG_T10, remainder, true);
905   count += generate_jump(&insn[count], REG_T10, MD_JSR, REG_RA, remainder);
906
907   // load t10 from the stack
908   count += generate_load(&insn[count], REG_T10, REG_SP, 0, dw_quad);
909
910   // load ra from the stack
911   count += generate_load(&insn[count], REG_RA, REG_SP, 8, dw_quad);
912
913   // increment stack by 16
914   count += generate_lda(&insn[count], REG_SP, REG_SP, 16, true);
915
916   offset += count * sizeof(instruction);
917 }
918
919 //
920 // move the passed parameter into the passed register, or if it is already
921 //    in a register return the register number.
922 //
923 Register getParameter(Register, int param) {
924   if (param <= 5) {
925     return(16+param);
926   }
927   assert(0); 
928   return(Null_Register);
929 }
930
931 int getInsnCost(opCode op) {
932
933   if (op == loadConstOp) {
934     return(1);
935   } else if (op ==  loadOp) {
936     // assume two cycles to generate address, one to issue load
937     return(1+2);
938   } else if (op ==  storeOp) {
939     // assume two cycles to generate address, one to issue store
940     return(1+2);
941   } else if (op ==  ifOp) {
942     // beq
943     return(1);
944   } else if (op ==  callOp) {
945     //  3  : load address for jsr to DYNINSTsave_misc
946     // 12  : cost of DYNINSTsave_misc           
947     //  3  : jsr to DYNINSTsave_misc (1 + 2 cycle branch penalty)
948     //  3  : load address into register for jsr to called function
949     //  1  : move argument to argument register (assume 1 arg on average)
950     //  3  : issue jsr to called function (1 + 2 cycle branch penalty)
951     //  3  : load address for jsr to DYNINSTrestore_misc
952     // 12  : cost of DYNINSTrestore_misc           
953     //  3  : jsr to DYNINSTrestore_misc (1 + 2 cycle branch penalty)
954     //
955     // TODO -- what about the cost of the called code ?
956     return 43;
957   } else if (op ==  trampPreamble) {
958     //  2  : load address of observed_cost
959     //  1  : load value of observed_cost
960     //  1  : add to observed cost
961     //  1  : store updated observed_cost
962     return(2+1+1+1);
963   } else if (op ==  trampTrailer) {
964     // ret
965     return(1);
966   } else if (op == noOp) {
967     // noop
968     return(1);
969   } else {
970     switch (op) {
971     case eqOp:
972       return 1;                 // 1  : cmpeq
973     case neOp:
974       return 3;                 // cmpeq, negate result, add 1 to result
975     case lessOp:          
976     case greaterOp:
977     case leOp:
978     case geOp:
979       return 1;                 // cmpXX, arguments may be reversed
980     default:                    // other integer operators
981       return(1);
982       break;
983     }
984   }
985 }
986
987 // void generateNoOp(process *proc, int addr) {
988 void generateNoOp(process *proc, unsigned long addr) {
989   instruction insn;
990   generate_nop(&insn);
991   proc->writeTextWord((caddr_t)addr, insn.raw);
992 }
993
994 /*
995  * change the insn at fromAddr to be a branch to newAddr.
996  *   Used to add multiple tramps to a point.
997  */
998 void generateBranch(process *proc, Address fromAddr, Address newAddr) {
999   int disp;
1000   instruction insn;
1001
1002   Address a = ABS((long)((fromAddr+4) - newAddr));
1003   Address b = (Address) MAX_BRANCH;
1004 //  if ((ABS((fromAddr+4) - newAddr)) > (Address) MAX_BRANCH) { 
1005 if (a > b) {
1006     logLine("a branch too far\n"); assert(0);
1007   }
1008
1009   // Note the explicit cast
1010   // +4 to use updated pc
1011   disp = newAddr - (fromAddr+4);
1012   generateBranchInsn(&insn, disp);
1013
1014   proc->writeTextWord((caddr_t)fromAddr, insn.raw);
1015 }
1016
1017 // The Alpha does not have a divide instruction
1018 // The divide is performed in software by calling __divl
1019 int software_divide(int src1,int src2,int dest,char *i,Address &base,bool,Address divl_addr,bool Imm = false)
1020 {
1021   int words;
1022   int remainder;
1023   instruction *insn = (instruction *) ((void*)&i[base]);
1024
1025   assert(!((unsigned long)insn & (unsigned long)3));  
1026   // or src1,src1,a0
1027   generate_operate(insn,src1,src1,REG_A0,OP_BIS,FC_BIS);
1028   insn++;
1029   base+= sizeof(instruction);
1030   if (Imm)
1031     // load constant into register a1
1032     generate_lit_operate(insn,REG_ZERO,src2,REG_A1, OP_ADDL, FC_ADDL);    
1033     else
1034       // or src2,src2,a1
1035       generate_operate(insn,src2,src2,REG_A1,OP_BIS,FC_BIS);
1036   insn++;
1037   base+= sizeof(instruction);
1038
1039   // jsr __divl
1040   words = generate_address(insn, REG_PV,divl_addr, remainder);
1041   if (remainder)
1042       words += generate_lda(insn+words, REG_PV, REG_PV, remainder, true);
1043   words += generate_jump(insn+words, REG_PV, MD_JSR, REG_RA, remainder);
1044   insn += words; base += (words*4);
1045
1046   // or v0,v0,dest
1047   generate_operate(insn,REG_V0,REG_V0,dest,OP_BIS,FC_BIS);
1048   insn++;
1049   base+= sizeof(instruction);  
1050   return 0;
1051 }
1052
1053 static inline void
1054 generate_integer_op(instruction *insn, Address src1, Address src2, 
1055                     Address dest, unsigned long& base, opCode op, bool Imm = FALSE) {
1056 //                  Address dest, unsigned & base, opCode op) {
1057   // integer ops
1058 //  unsigned op_code=0, func_code=0, words = 0;
1059   unsigned op_code=0, func_code=0;
1060   unsigned long words = 0;
1061
1062   switch (op) {
1063
1064   case plusOp:        op_code = OP_ADDQ; func_code = FC_ADDQ; break;
1065   case minusOp:       op_code = OP_SUBQ; func_code = FC_SUBQ; break;
1066   case timesOp:       op_code = OP_MULQ; func_code = FC_MULQ; break;
1067   case divOp:         assert(0); // shouldn't get here. Call software_divide from the ast
1068   case orOp:          op_code = OP_BIS;  func_code = FC_BIS; break;
1069   case andOp:         op_code = OP_AND;  func_code = FC_AND; break;
1070
1071   // The compare instruction leave a one in dest if the compare is true
1072   // beq branch when dest is 0 --> and the compare is false
1073
1074   case eqOp:
1075     words += genRelOp(insn, OP_CMPEQ, FC_CMPEQ, src1, src2, dest,Imm);
1076     base += words * 4; return;
1077
1078   case neOp:
1079     // last arg == true --> inverts value of comparison               
1080     words += genRelOp(insn, OP_CMPEQ, FC_CMPEQ, src1, src2, dest,Imm,true);
1081     base += words * 4; return;
1082
1083   case lessOp:
1084     words += genRelOp(insn, OP_CMPLT, FC_CMPLT, src1, src2, dest,Imm);
1085     base += words * 4; return;
1086                       
1087   case greaterOp:                          
1088     words += genRelOp(insn, OP_CMPLE, FC_CMPLE, src1, src2, dest,Imm,true);
1089     base += words * 4; return;
1090
1091   case leOp:
1092     words += genRelOp(insn, OP_CMPLE, FC_CMPLE, src1, src2, dest,Imm);
1093     base += words * 4; return;
1094
1095   case geOp:                               
1096     words += genRelOp(insn, OP_CMPLE, FC_CMPLT, src1, src2, dest,Imm,true);
1097     base += words * 4; return;
1098
1099   default:
1100     assert(0);
1101     break;
1102   }
1103
1104   if (Imm) {
1105       if ((src2 >= 0) && (src2 < MAX_IMM)) {
1106         words += generate_lit_operate(insn+words, src1, src2, dest, op_code, 
1107             func_code);
1108       } else {
1109         words += generate_operate(insn+words, src1, src2, dest, op_code, func_code);
1110       }
1111   } else {
1112     words += generate_operate(insn+words, src1, src2, dest, op_code, func_code);
1113   }
1114   base += words * 4; return;
1115 }
1116
1117 /*
1118     ra only has to be saved when a procedure call is added using
1119     instrumentation.
1120     the Alpha API.
1121     ra must be saved because it will be clobbered by a procedure call since 
1122     it will get the return address. 
1123  */
1124
1125 /*
1126    It would be nice to be able to do relative branches to DYNINST funcs from
1127    here.  Unfortunately, I do not have the base address of the trampoline.
1128  */
1129 static inline Address
1130 generate_call_code(instruction *insn, Address src1, Address src2, Address dest,
1131                    unsigned long& base, process *proc) {
1132 //                 unsigned& base, process *proc) {
1133   // put parameters in argument registers
1134   // register move is "bis src, src, dest"  (bis is logical or)
1135   // save and restore the values currently in the argument registers
1136 //  unsigned words = 0;
1137   unsigned long words = 0;
1138 //  int decrement = -8;
1139
1140   Symbol info;
1141   Address baseAddr;
1142
1143   proc->getSymbolInfo("DYNINSTsave_misc", info, baseAddr);
1144   function_base *fun_save = proc->findOneFunction("DYNINSTsave_misc");
1145   function_base *fun_restore = proc->findOneFunction("DYNINSTrestore_misc");
1146   assert(fun_save && fun_restore);
1147   Address dyn_save = fun_save->addr() + baseAddr;
1148   Address dyn_restore = fun_restore->addr() + baseAddr;
1149
1150   // save the current values in v0, a0..a5, pv, at, gp
1151   // Call to DYNINSTsave_misc
1152   int remainder;
1153   words += generate_address(insn+words, REG_T10, dyn_save, remainder);
1154   if (remainder)
1155     words += generate_lda(insn+words, REG_T10, REG_T10, remainder, true);
1156   words += generate_jump(insn+words, REG_T10, MD_JSR, REG_RA, remainder);
1157
1158   // move args to argument registers
1159   if (src1 > 0)
1160     words += generate_operate(insn+words, src1, src1, REG_A0, OP_BIS, FC_BIS);
1161   if (src2 > 0) 
1162     words += generate_operate(insn+words, src2, src2, REG_A1, OP_BIS, FC_BIS);
1163
1164   // Set the value of  pv/t12/r27
1165   // I have not found any documentation on this
1166   // But the alpha appears to put the callee's address in this register
1167   // this register must be saved and restored
1168
1169   // Jump to the function
1170   words += generate_address(insn+words, REG_PV, dest, remainder);
1171   if (remainder)
1172     words += generate_lda(insn+words, REG_PV, REG_PV, remainder, true);
1173
1174   // TODO -- clear other argument registers ?
1175   words += generate_jump(insn+words, REG_PV, MD_JSR, REG_RA, remainder);
1176   
1177   // Call to DYNINSTrestore_misc
1178   words += generate_address(insn+words, REG_T10, dyn_restore, remainder);
1179   if (remainder)
1180     words += generate_lda(insn+words, REG_T10, REG_T10, remainder, true);
1181   words += generate_jump(insn+words, REG_T10, MD_JSR, REG_RA, remainder);
1182
1183   base += words * 4; return 0;
1184 }
1185
1186 static inline void
1187 generate_tramp_preamble(instruction *insn, Address src1,
1188                         Address dest, unsigned long& base) {
1189 //                      Address dest, unsigned& base) {
1190   // generate code to update the observed cost
1191   // a4 holds address, a3 gets loaded
1192
1193 //  unsigned words = 0; int obs_rem;
1194   unsigned long words = 0; int obs_rem;
1195   // load the current observed cost
1196   words += generate_address(insn+words, REG_T11, dest, obs_rem);
1197   words += generate_load(insn+words, REG_T10, REG_T11, obs_rem, dw_long);
1198
1199   // update the observed cost
1200   if ((src1 >= 0) && (src1 < MAX_IMM)) {
1201     // addl literal, REG_T10, REG_T10       (t10 += literal)
1202     words += generate_lit_operate(insn+words, REG_T10, src1, REG_T10,
1203                                   OP_ADDL, FC_ADDL);
1204   } else {
1205     // load literal into REG_T9
1206     int remainder;
1207     words += generate_address(insn+words, REG_T9, src1, remainder);
1208     if (remainder)
1209       words += generate_lda(insn+words, REG_T9, REG_T9, remainder, true);
1210
1211     // addl REG_T9, REG_T10, REG_T10       (t10 += t9)
1212     words += generate_operate(insn+words, REG_T10, REG_T9, REG_T10, OP_ADDL, FC_ADDL);
1213   }
1214
1215   // store new observed cost  
1216   // st REG_T10, obs_rem[REG_T11]
1217   words += generate_store(insn+words, REG_T10, REG_T11, obs_rem, dw_long);
1218   base += words * 4; 
1219   return;
1220 }
1221
1222
1223 // The value returned by emitA can be
1224 // 
1225 // ifOp: address to calculate branch
1226 // 
1227 // TODO -- if an offset is returned, it is the offset to the instruction
1228 //         where the branch occurs.  This offset cannot be used to
1229 //         calculate branches, the offset of the next instruction should
1230 //         be used.  The alpha uses the UPDATED pc for branches.
1231 // 
1232
1233 Address emitA(opCode op, Register src1, Register /*src2*/, Register dest,
1234              char *i, Address &base, bool /*noCost*/) {
1235
1236   //fprintf(stderr,"emitA(op=%d,src1=%d,src2=XX,dest=%d)\n",op,src1,dest);
1237
1238   instruction *insn = (instruction *) ((void*)&i[base]);
1239   assert(!((unsigned long)insn & (unsigned long)3));
1240
1241   switch (op) {
1242   case ifOp: {
1243     // beq src1
1244     // return address used to calculate branch offset
1245     assert(src1 < Num_Registers);
1246     // branch calculations use the updated pc
1247     unsigned long words = generate_branch(insn, src1, dest-4, OP_BEQ);
1248     // return offset of branch instruction
1249     base += words * 4; 
1250     return (base-4);
1251     }
1252   case branchOp: {
1253     generateBranchInsn(insn, dest-4);
1254     base += sizeof(instruction);
1255     return(base - sizeof(instruction));
1256     }
1257   case trampTrailer: {
1258     // dest is in words of offset and generateBranchInsn is bytes offset
1259     assert(!dest);
1260 //    unsigned words = generate_branch(insn, REG_ZERO, dest << 2, OP_BR);
1261     unsigned long words = generate_branch(insn, REG_ZERO, dest << 2, OP_BR);
1262     // return the offset of the branch instruction -- not the updated pc
1263     base += words * 4; 
1264     return (base-4);
1265     }
1266   case trampPreamble: {
1267     generate_tramp_preamble(insn, src1, dest, base);
1268     return(0);          // let's hope this is expected!
1269     }
1270   default:
1271     abort();            // unexpected op for this emit!
1272   }
1273 }
1274
1275 Register emitR(opCode op, Register src1, Register /*src2*/, Register dest,
1276              char *i, Address &base, bool /*noCost*/) {
1277
1278   //fprintf(stderr,"emitR(op=%d,src1=%d,src2=XX,dest=%d)\n",op,src1,dest);
1279
1280   instruction *insn = (instruction *) ((void*)&i[base]);
1281   assert(!((unsigned long)insn & (unsigned long)3));
1282
1283   switch (op) {
1284   case getRetValOp:
1285     {
1286       // Return value register v0 is the 12th register saved in the base tramp
1287       restoreRegister(insn,base,12,dest);
1288       return(dest);
1289     }
1290   case getParamOp:
1291     {
1292       if (src1 >5) assert(0);
1293       /*
1294        * We don't save the parameter registers unless we make a function call,
1295        * so we can read the values directly out of the registers.
1296        */
1297       unsigned long words =
1298           generate_operate(insn,REG_A0+src1,REG_A0+src1,dest,OP_BIS, FC_BIS);
1299       base += words * sizeof(instruction);
1300       return(dest);
1301     }
1302   default:
1303     abort();                    // unexpected op for this emit!
1304   }
1305   return(Null_Register);        // should never get here!
1306 }
1307
1308 void emitVload(opCode op, Address src1, Register, Register dest,
1309              char *i, Address &base, bool, int size=4)
1310 {
1311   instruction *insn = (instruction *) ((void*)&i[base]);
1312   assert(!((unsigned long)insn & (unsigned long)3));
1313
1314   if (op == loadConstOp) {
1315     // lda dest, src1 (LITERAL)     --> put the literal value of src1 into dest
1316     // it may take several instructions to do this
1317     assert(dest < Num_Registers);
1318     int remainder;
1319     unsigned long words = 0;
1320     // if the constant is a zero -- or it into place
1321     if (!src1) { 
1322       words = generate_operate(insn+words, REG_ZERO, REG_ZERO, 
1323                                (unsigned long) dest, OP_BIS, FC_BIS);
1324 //                             (unsigned) dest, OP_BIS, FC_BIS);
1325     } else {
1326 //      words = generate_address(insn, (unsigned) dest, src1, remainder);
1327       words = generate_address(insn, (unsigned long) dest, src1, remainder);
1328       if (remainder)
1329         words +=
1330 //        generate_lda(insn+words, (unsigned) dest, (unsigned) dest,
1331           generate_lda(insn+words, (unsigned long) dest, (unsigned long) dest,
1332                        remainder, true);
1333     }
1334     base += words * 4; return;
1335
1336   } else if (op ==  loadOp) {
1337         // ld? dest, [src1]             --> src1 is a literal
1338         // src1 = address to load
1339         // src2 = 
1340         // dest = register to load
1341         int remainder;
1342         unsigned long words = generate_address(insn, (unsigned long) dest, src1, remainder);
1343         if (size == 4) {
1344             words += generate_load(insn+words, (unsigned long) dest, 
1345                  (unsigned long) dest, remainder, dw_long);
1346         } else if (size == 8) {
1347             words += generate_load(insn+words, (unsigned long) dest, 
1348                  (unsigned long) dest, remainder, dw_quad);
1349         } else {
1350             abort();
1351         }
1352         base += words * 4; return;
1353     } else if (op ==  loadFrameRelativeOp) {
1354         unsigned long words = 0;
1355         // frame offset is negative of actual offset.
1356         long offset = (long) src1;
1357         assert(ABS(offset) < 32767);
1358         words += generate_load(insn+words, (unsigned long) dest,  REG_SP,
1359                                104, dw_quad);
1360         assert(ABS(offset) < (1<<30));
1361         if (ABS(offset) > 32767) {
1362             Offset low = offset & 0xffff;
1363             offset -= SEXT_16(low);
1364             Offset high = (offset >> 16) & 0xffff;
1365             assert((Address)SEXT_16(low) +
1366              ((Address)SEXT_16(high)<<16) == src1);
1367
1368             words += generate_lda(insn+words, dest, dest, high, false);
1369             words += generate_load(insn+words, (unsigned long) dest,  dest,
1370                                low, dw_long);
1371         } else {
1372             words += generate_load(insn+words, (unsigned long) dest,  dest,
1373                                offset, dw_long);
1374         }
1375         base += words * 4; 
1376     } else if (op == loadFrameAddr) {
1377         unsigned long words = 0;
1378         // frame offset is signed.
1379         long offset = (long) src1;
1380
1381         // load fp into dest
1382         words += generate_load(insn+words, (unsigned long) dest,  REG_SP,
1383                                104, dw_quad);
1384
1385         assert(ABS(offset) < (1<<30));
1386         if (ABS(offset) > 32767) {
1387             Offset low = offset & 0xffff;
1388             offset -= SEXT_16(low);
1389             Offset high = (offset >> 16) & 0xffff;
1390             assert((Address)SEXT_16(low) +
1391              ((Address)SEXT_16(high)<<16) == src1);
1392
1393             // add high bits of offset
1394             words += generate_lda(insn+words, dest, dest, high, false);
1395             // now addd the low bits of the offset
1396             words += generate_lda(insn+words, dest, dest, low, true);
1397         } else {
1398             // addd the offset
1399             words += generate_lda(insn+words, dest, dest, offset, true);
1400         }
1401         base += words * 4; 
1402     } else {
1403         abort();       // unexpected op for this emit!
1404     }
1405 }
1406
1407 void emitVstore(opCode op, Register src1, Register src2, Address dest,
1408              char *i, Address &base, bool /* noCost */, int size=4)
1409 {
1410   instruction *insn = (instruction *) ((void*)&i[base]);
1411   assert(!((unsigned long)insn & (unsigned long)3));
1412
1413   if (op ==  storeOp) {
1414     // st? dest, [src1]
1415     // src1 = value to store
1416     // src2 = register to hold address
1417     // dest = address
1418     int remainder;
1419 //    unsigned words = generate_address(insn, (unsigned) src2, dest, remainder);
1420     unsigned long words = generate_address(insn, (unsigned long) src2, dest, remainder);
1421 //    words += generate_store(insn+words, (unsigned) src1, (unsigned) src2,
1422     if (size == 8) {
1423         words += generate_store(insn+words, (unsigned long) src1, 
1424             (unsigned long) src2, remainder, dw_quad);
1425     } else if (size == 4) {
1426         words += generate_store(insn+words, (unsigned long) src1, 
1427             (unsigned long) src2, remainder, dw_long);
1428     } else {
1429         abort();
1430     }
1431     base += words * 4; return;
1432   } else if (op ==  storeFrameRelativeOp) {
1433     // frame offset is signed.
1434     long offset = (long) dest;
1435     assert(ABS(offset) < 32767);
1436     unsigned long words = 0;
1437     words += generate_load(insn+words, (unsigned long) src2,  REG_SP,
1438                                104, dw_quad);
1439     if (size == 8) {
1440         words += generate_store(insn+words, (unsigned long) src1, 
1441             (unsigned long) src2, offset, dw_quad);
1442     } else if (size == 4) {
1443         words += generate_store(insn+words, (unsigned long) src1, 
1444             (unsigned long) src2, offset, dw_long);
1445     } else {
1446         abort();
1447     }
1448     base += words * 4; return;
1449   } else {
1450       abort();       // unexpected op for this emit!
1451   }
1452 }
1453
1454 void emitVupdate(opCode op, RegValue /* src1 */, 
1455                             Register /*src2*/, Address /* dest */,
1456                             char *i, Address &base, bool /* noCost */)
1457 {
1458   instruction *insn = (instruction *) ((void*)&i[base]);
1459   assert(!((unsigned long)insn & (unsigned long)3));
1460
1461   if (op == updateCostOp) {
1462       return;
1463   } else {
1464       abort();       // unexpected op for this emit!
1465   }
1466 }
1467
1468 void emitV(opCode op, Register src1, Register src2, Register dest,
1469              char *i, Address &base, bool /*noCost*/, int size = 4)
1470 {
1471   //fprintf(stderr,"emitV(op=%d,src1=%d,src2=%d,dest=%d)\n",op,src1,src2,dest);
1472
1473     assert ((op!=branchOp) && (op!=ifOp) && 
1474             (op!=trampTrailer) && (op!=trampPreamble));         // !emitA
1475     assert ((op!=getRetValOp) && (op!=getParamOp));             // !emitR
1476     assert ((op!=loadOp) && (op!=loadConstOp));                 // !emitVload
1477     assert ((op!=storeOp));                                     // !emitVstore
1478     assert ((op!=updateCostOp));                                // !emitVupdate
1479
1480   instruction *insn = (instruction *) ((void*)&i[base]);
1481   assert(!((unsigned long)insn & (unsigned long)3));
1482
1483   data_width width;
1484   if (size == 4) {
1485       width = dw_long;
1486   } else if (size == 8) {
1487       width = dw_quad;
1488   } else {
1489       // should not happen
1490       abort();
1491   }
1492
1493   if (op == noOp) {
1494     unsigned long words = generate_nop(insn);
1495     base += words * 4; 
1496     return;
1497   } else if (op == loadIndirOp) {
1498     unsigned long words = generate_load(insn, dest, src1, 0, width);
1499     base += words * 4;
1500     return;
1501   } else if (op == storeIndirOp) {
1502     unsigned long words = generate_store(insn, src1, dest, 0, width);
1503     base += words * 4;
1504     return;
1505   } else {
1506     generate_integer_op(insn, src1, src2, dest, base, op);
1507     return;
1508   }
1509 }
1510
1511
1512 /************************************************************************
1513  * void restore_original_instructions(process* p, instPoint* ip)
1514 ************************************************************************/
1515
1516 void
1517 restore_original_instructions(process* p, instPoint* ip) {
1518   Address addr = ip->addr;
1519   p->writeTextWord((caddr_t)addr, ip->originalInstruction.raw);
1520   addr += sizeof(instruction);
1521 }
1522
1523 // The only non read only registers are those that are allocated - t0...t7
1524
1525 bool registerSpace::readOnlyRegister(Register reg_number) {
1526   if ((reg_number >= REG_T0) && (reg_number <= REG_T7))
1527     return false;
1528   else 
1529     return true;
1530 }
1531
1532 //
1533 // return cost in cycles of executing at this point.  This is the cost
1534 //   of the base tramp if it is the first at this point or 0 otherwise.
1535 //
1536 // This was in inst.C, but the base tramp cost is machine dependent
1537 // 
1538 int getPointCost(process *proc, instPoint *point)
1539 {
1540   if (proc->baseMap.defines(point)) {
1541     return(0);
1542   } else {
1543     //  1 : decrement stack
1544     //  1 : push ra onto the stack
1545     //  3 : bsr to DYNINSTsave_temp (1 for call, 2 cycle branch penalty)
1546     // 14 : cost of DYNINSTsave_temp
1547     //  2 : empty nop slots
1548     //  3 : bsr to DYNINSTrestore_temp (1 for call, 2 cycle branch penalty)
1549     // 14 : cost of DYNINSTrestore_temp
1550     //  1 : load ra from stack
1551     //  1 : increment stack
1552     //  1 : slot for relocated instruction
1553     //  1 : decrement stack
1554     //  1 : push ra onto the stack
1555     //  3 : bsr to DYNINSTsave_temp (1 for call, 2 cycle branch penalty)
1556     // 14 : cost of DYNINSTsave_temp
1557     //  2 : empty nop slots
1558     //  3 : bsr to DYNINSTrestore_temp (1 for call, 2 cycle branch penalty)
1559     // 14 : cost of DYNINSTrestore_temp
1560     //  1 : load ra from stack
1561     //  1 : increment stack
1562     //  1 : return
1563     return(81);
1564   }
1565 }
1566
1567 dictionary_hash<string, unsigned> funcFrequencyTable(string::hash);
1568
1569 void initDefaultPointFrequencyTable()
1570 {
1571     FILE *fp;
1572     float value;
1573     char name[512];
1574
1575     funcFrequencyTable["main"] = 1;
1576     funcFrequencyTable["DYNINSTsampleValues"] = 1;
1577     funcFrequencyTable[EXIT_NAME] = 1;
1578
1579     // try to read file.
1580     fp = fopen("freq.input", "r");
1581     if (!fp) {
1582         return;
1583     } else {
1584         printf("found freq.input file\n");
1585     }
1586     while (!feof(fp)) {
1587         fscanf(fp, "%s %f\n", name, &value);
1588         funcFrequencyTable[name] = (int) value;
1589         printf("adding %s %f\n", name, value);
1590     }
1591     fclose(fp);
1592 }
1593
1594
1595
1596 // unsigned findAndInstallBaseTramp(process *proc, 
1597 trampTemplate *findAndInstallBaseTramp(process *proc, 
1598                                        instPoint *&location,
1599                                        returnInstance *&retInstance, 
1600                                        bool /* noCost */)
1601 {
1602   trampTemplate *ret;
1603   process *globalProc;
1604   retInstance = NULL;
1605
1606 #ifdef notdef
1607     if (nodePseudoProcess && (proc->symbols == nodePseudoProcess->symbols)){
1608         globalProc = nodePseudoProcess;
1609         // logLine("findAndInstallBaseTramp global\n");
1610     } else {
1611         globalProc = proc;
1612     }
1613 #endif
1614     globalProc = proc;
1615
1616     if (!globalProc->baseMap.defines(location)) {
1617         ret = new trampTemplate;
1618         installBaseTramp(location, globalProc, *ret);
1619         instruction *insn = new instruction;
1620
1621         Address pointAddr = location->addr;
1622         Address baseAddress;
1623         if (proc->getBaseAddress(location->image_ptr, baseAddress)) {
1624             pointAddr += baseAddress;
1625         }
1626         generateBranchInsn(insn, ret->baseAddr - (pointAddr+4));
1627         globalProc->baseMap[location] = ret;
1628         retInstance = new returnInstance((instruction *)insn,sizeof(instruction), 
1629             pointAddr, sizeof(instruction)); 
1630     } else {
1631         ret = globalProc->baseMap[location];
1632     }
1633       
1634     return(ret);
1635 }
1636
1637 /*
1638  * Install a single tramp.
1639  *
1640  */
1641 void installTramp(instInstance *inst, char *code, int codeSize)
1642 {
1643     totalMiniTramps++;
1644     insnGenerated += codeSize/sizeof(int);
1645
1646     // TODO cast
1647     (inst->proc)->writeDataSpace((caddr_t)inst->trampBase, codeSize, code);
1648 }
1649
1650
1651 float getPointFrequency(instPoint *point)
1652 {
1653
1654     pd_Function *func;
1655
1656     if (point->callee)
1657         func = point->callee;
1658     else
1659         func = point->func;
1660
1661     if (!funcFrequencyTable.defines(func->prettyName())) {
1662       if (func->isLibTag()) {
1663         return(100);
1664       } else {
1665         return(250);
1666       }
1667     } else {
1668       return (funcFrequencyTable[func->prettyName()]);
1669     }
1670 }
1671
1672 bool isReturn(const instruction insn) {
1673     return ((insn.mem_jmp.opcode == OP_MEM_BRANCH) &&
1674             (insn.mem_jmp.ext == MD_RET));
1675 }
1676
1677 // Borrowed from the POWER version
1678 bool isReturnInsn(const image *owner, Address adr, bool &lastOne)
1679 {
1680   instruction insn;
1681
1682   insn.raw = owner->get_instruction(adr);
1683   // need to know if this is really the last return.
1684   //    for now assume one return per function - jkh 4/12/96
1685   lastOne = true;
1686   return isReturn(insn);
1687 }
1688
1689 bool isCallInsn(const instruction i) {
1690   return (isBsr(i) || isJsr(i));
1691 }
1692
1693 bool pd_Function::findInstPoints(const image *owner) 
1694 {  
1695   bool err;
1696   Address adr = addr();
1697   instruction instr;
1698   instruction instr2;
1699   long gpValue; // gp needs signed operations
1700   bool gpKnown = false;
1701
1702   // normal linkage on alphas is that the first two instructions load gp.
1703   //   In this case, many functions jump past these two instructions, so
1704   //   we put the inst point at the third instruction.
1705   //   However, system call libs don't always follow this rule, so we
1706   //   look for a load of gp in the first two instructions.
1707   instr.raw = owner->get_instruction(adr);
1708   instr2.raw = owner->get_instruction(adr+4);
1709   if ((instr.mem.opcode == OP_LDAH) && (instr.mem.ra == REG_GP) &&
1710       (instr2.mem.opcode == OP_LDA) && (instr2.mem.ra == REG_GP)) {
1711       // compute the value of the gp
1712       gpKnown = true;
1713       gpValue = ((long) adr) + (SEXT_16(instr.mem.disp)<<16) + instr2.mem.disp;
1714       adr += 8;
1715   }
1716
1717   instr.raw = owner->get_instruction(adr);
1718   if (!IS_VALID_INSN(instr)) {
1719     return false;
1720   }
1721
1722   funcEntry_ = new instPoint(this, instr, owner, adr, true,functionEntry);
1723   assert(funcEntry_);
1724
1725   // perform simple data flow tracking on t12 within a basic block.
1726   Address t12Value;
1727   bool t12Known = false;
1728   while (true) {
1729     instr.raw = owner->get_instruction(adr);
1730
1731     bool done;
1732
1733     // check for return insn and as a side affect decide if we are at the
1734     //   end of the function.
1735     if (isReturnInsn(owner, adr, done)) {
1736       // define the return point
1737       // check to see if adr-8 is ldq fp, xx(sp), if so use it as the
1738       // address since it will ensure the activation record is still active.
1739       // Only gcc seems to use a frame pointer
1740       instruction frameRestInsn;
1741       frameRestInsn.raw = owner->get_instruction(adr-8);
1742       if ((frameRestInsn.raw & 0xffff0000) == 0xa5fe0000) {
1743           Address tempAddr = adr - 8;
1744           funcReturns += new instPoint(this,frameRestInsn,owner,tempAddr,false, 
1745               functionExit);
1746       } else {
1747           funcReturns += new instPoint(this,instr,owner,adr,false,functionExit);
1748       }
1749
1750       // see if this return is the last one 
1751       if (done) return true;
1752     } else if (isCallInsn(instr)) {
1753       // define a call point
1754       instPoint *point = new instPoint(this, instr, owner, adr, false,callSite);
1755
1756       if (isJsr(instr)) {
1757           Address destAddr = 0;
1758           if ((instr.mem_jmp.rb == REG_T12) && t12Known) {
1759               destAddr = t12Value;
1760           }
1761           point->callIndirect = true;
1762           point->callee = destAddr;             // this is the indirect address
1763       } else {
1764           point->callIndirect = false;
1765           point->callee = NULL;
1766       }
1767       calls += point;
1768       t12Known = false;
1769     } else if (isJmpType(instr) || isBranchType(instr)) {
1770       // end basic block, kill t12
1771       t12Known = false;
1772     } else if ((instr.mem.opcode == OP_LDQ) && (instr.mem.ra == REG_T12) &&
1773                (instr.mem.rb = REG_GP)) {
1774       // intruction is:  ldq t12, disp(gp)
1775       if (gpKnown) {
1776           t12Value = gpValue + instr.mem.disp;
1777           t12Known = true;
1778       }
1779     }
1780
1781     // now do the next instruction
1782     adr += 4;
1783
1784    }
1785 }
1786
1787 //
1788 // Each processor may have a different heap layout.
1789 //   So we make this processor specific.
1790 //
1791 // find all DYNINST symbols that are data symbols
1792 bool process::heapIsOk(const vector<sym_data> &find_us) {
1793   bool err;
1794   Symbol sym;
1795   string str;
1796   Address addr;
1797   Address instHeapStart;
1798
1799   // find the main function
1800   // first look for main or _main
1801   if (!((mainFunction = findOneFunction("main")) 
1802         || (mainFunction = findOneFunction("_main")))) {
1803      string msg = "Cannot find main. Exiting.";
1804      statusLine(msg.string_of());
1805      showErrorCallback(50, msg);
1806      return false;
1807   }
1808   
1809   for (unsigned long i=0; i<find_us.size(); i++) {
1810     addr = findInternalAddress(find_us[i].name, false, err);
1811     printf("looking for %s\n", find_us[i].name.string_of());
1812     if (err) {
1813         string msg;
1814         msg = string("Cannot find ") + str + string(". Exiting");
1815         statusLine(msg.string_of());
1816         showErrorCallback(50, msg);
1817         return false;
1818     }
1819   }
1820
1821   string ghb = "_DYNINSTtext";
1822   addr = findInternalAddress(ghb, false, err);
1823   if (err) {
1824       string msg;
1825       msg = string("Cannot find _DYNINSTtext") + string(". Exiting");
1826       statusLine(msg.string_of());
1827       showErrorCallback(50, msg);
1828   }
1829   instHeapStart = addr;
1830
1831   string hd = "DYNINSTdata";
1832   addr = findInternalAddress(hd, true, err);
1833   if (err) {
1834       string msg;
1835       msg = string("Cannot find DYNINSTdata") + string(". Exiting");
1836       statusLine(msg.string_of());
1837       showErrorCallback(50, msg);
1838       return false;
1839   }
1840   instHeapStart = addr;
1841
1842   return true;
1843 }
1844
1845 void emitImm(opCode op, Register src1, RegValue src2imm, Register dest, 
1846              char *i, Address &base, bool /* noCost */)
1847 {
1848   instruction *insn = (instruction *) ((void*)&i[base]);
1849   assert(!((unsigned long)insn & (unsigned long)3));
1850   generate_integer_op(insn, src1, src2imm, dest, base, op, true);
1851   return;
1852 }
1853
1854 Register
1855 emitFuncCall(opCode /* op */, 
1856              registerSpace *rs,
1857              char *i, Address &base, 
1858              const vector<AstNode *> &operands,
1859              const string &callee, process *proc, bool noCost,
1860              const function_base *calleebase)
1861 {
1862   vector <Register> srcs;
1863
1864   // First, generate the parameters
1865   for (unsigned u = 0; u < operands.size(); u++)
1866     srcs += operands[u]->generateCode(proc, rs, i , base, false, false);
1867
1868   // put parameters in argument registers
1869   // register move is "bis src, src, dest"  (bis is logical or)
1870   // save and restore the values currently in the argument registers
1871   //  unsigned long words = 0;
1872   Address addr;
1873   bool err;
1874   void cleanUpAndExit(int status);
1875
1876   if (calleebase)
1877        addr = calleebase->getEffectiveAddress(proc);
1878   else {
1879        addr = proc->findInternalAddress(callee, false, err);
1880        if (err) {
1881             function_base *func_b = proc->findOneFunction(callee);
1882             if (!func_b) {
1883                  ostrstream os(errorLine, 1024, ios::out);
1884                  os << "Internal error: unable to find addr of " << callee << endl;
1885                  logLine(errorLine);
1886                  showErrorCallback(80, (const char *) errorLine);
1887                  P_abort();
1888             }
1889             addr = func_b->addr();
1890        }
1891   }
1892
1893   int remainder;
1894   instruction *insn = (instruction *) ((void*)&i[base]);
1895   Address dyn_save;
1896   Address dyn_restore;
1897
1898   if (!skipSaveCalls) {
1899       function_base *fun_save = proc->findOneFunction("DYNINSTsave_misc");
1900       function_base *fun_restore = proc->findOneFunction("DYNINSTrestore_misc");
1901       assert(fun_save && fun_restore);
1902       dyn_save = fun_save->addr();
1903       dyn_restore = fun_restore->addr();
1904
1905       Symbol info;
1906       Address baseAddr;
1907       proc->getSymbolInfo("DYNINSTsave_misc", info, baseAddr);
1908
1909       dyn_save += baseAddr;
1910       dyn_restore += baseAddr;
1911
1912       // save the current values in v0, a0..a5, pv, at, gp
1913       // Call to DYNINSTsave_misc
1914       base += (4* generate_address(insn, REG_T10, dyn_save, remainder));
1915       if (remainder) {
1916           insn = (instruction *) ((void*)&i[base]);
1917           base += (4 * generate_lda(insn, REG_T10, REG_T10, remainder, true));
1918       }
1919       insn = (instruction *) ((void*)&i[base]);
1920       base += (4 * generate_jump(insn, REG_T10, MD_JSR, REG_RA, remainder));
1921
1922       //  words += (base - temp_base) / sizeof(insn);
1923       //  base = temp_base;
1924   }
1925
1926   for (unsigned u=0; u<srcs.size(); u++){
1927     if (u >= 5) {
1928          string msg = "Too many arguments to function call in instrumentation code: only 5 arguments can be passed on the sparc architecture.\n";
1929          fprintf(stderr, msg.string_of());
1930          showErrorCallback(94,msg);
1931          cleanUpAndExit(-1);
1932     }
1933     insn = (instruction *) ((void*)&i[base]);
1934     base += (4 * generate_operate(insn, srcs[u], srcs[u], u+REG_A0, 
1935                 OP_BIS, FC_BIS));
1936   }
1937
1938   // Set the value of  pv/t12/r27
1939   // I have not found any documentation on this
1940   // But the alpha appears to put the callee's address in this register
1941   // this register must be saved and restored
1942
1943   // Jump to the function
1944   insn = (instruction *) ((void*)&i[base]);
1945   base += (4 *generate_address(insn, REG_PV, addr, remainder));
1946   if (remainder)
1947     {
1948       insn = (instruction *) ((void*)&i[base]);
1949       base += (4 * generate_lda(insn, REG_PV, REG_PV, remainder, true));
1950     }
1951
1952   // TODO -- clear other argument registers ?
1953   insn = (instruction *) ((void*)&i[base]);
1954   base += (4 * generate_jump(insn, REG_PV, MD_JSR, REG_RA, remainder));
1955   
1956   if (!skipSaveCalls) {
1957       // Call to DYNINSTrestore_misc
1958       insn = (instruction *) ((void*)&i[base]);
1959       base += (4 * generate_address(insn, REG_T10, dyn_restore, remainder));
1960       if (remainder) {
1961           insn = (instruction *) ((void*)&i[base]);
1962           base += (4 * generate_lda(insn, REG_T10, REG_T10, remainder, true));
1963       }
1964       insn = (instruction *) ((void*)&i[base]);
1965       base += ( 4 * generate_jump(insn, REG_T10, MD_JSR, REG_RA, remainder));
1966   }
1967
1968   Register dest = rs->allocateRegister(i, base, noCost);
1969
1970   insn = (instruction *) ((void*)&i[base]);
1971
1972   // or v0,v0,dest
1973   generate_operate(insn,REG_V0,REG_V0,dest,OP_BIS,FC_BIS);
1974   base+= sizeof(instruction);
1975
1976   for (unsigned u=0; u<srcs.size(); u++){
1977     rs->freeRegister(srcs[u]);
1978   }
1979
1980   return dest;
1981 }
1982
1983 bool returnInstance::checkReturnInstance(const vector<Address> & /* adr */, 
1984                                          u_int & /* index */) {
1985     return true;
1986 }
1987  
1988 void returnInstance::installReturnInstance(process *proc) {
1989     proc->writeTextSpace((caddr_t)addr_, instSeqSize, (caddr_t) instructionSeq); 
1990         installed = true;
1991 }
1992
1993 void returnInstance::addToReturnWaitingList(Address /* pc */, 
1994                                             process*  /* proc */) 
1995 {
1996     P_abort();
1997 }
1998
1999 void generateBreakPoint(instruction &insn)
2000 {
2001   insn.raw = BREAK_POINT_INSN;
2002 }
2003
2004 void generateIllegalInsn(instruction &insn) { // instP.h
2005    insn.raw = 0;
2006 }
2007
2008 // findCallee: returns false unless callee is already set in instPoint
2009 // dynamic linking not implemented on this platform
2010 bool process::findCallee(instPoint &instr, function_base *&target){
2011
2012     if((target = (function_base *)instr.iPgetCallee())) {
2013        return true;
2014     }
2015     if (instr.callIndirect && instr.callee) {
2016         // callee contains the address in the mutatee
2017         // read the contents of the address
2018         Address dest;
2019         if (!readDataSpace((caddr_t)(instr.callee), sizeof(Address),
2020             (caddr_t)&(dest),true)) {
2021             return false;
2022         }
2023         // now lookup the funcation
2024         target = findFunctionIn(dest);
2025         if (target) return true;
2026     }
2027     return false;
2028 }
2029
2030 bool process::replaceFunctionCall(const instPoint *point,
2031                                   const function_base *newFunc) {
2032   // Must be a call site
2033     if (point->ipType != callSite)
2034       return false;
2035     
2036     // Cannot already be instrumented with a base tramp
2037     if (baseMap.defines(point))
2038         return false;
2039     instruction newInsn;
2040     if (newFunc == NULL) {      // Replace with a NOOP
2041       generateNOOP(&newInsn);
2042     } else {                    // Replace with a new call instruction
2043       generateBSR(&newInsn,
2044                            newFunc->addr()+sizeof(instruction)-point->addr);
2045     }
2046     
2047     writeTextSpace((caddr_t)point->addr, sizeof(instruction), &newInsn);
2048     
2049     return true;
2050 }
2051
2052 static const Address lowest_addr = 0x00400000;
2053 void inferiorMallocConstraints(Address near, Address &lo, Address &hi)
2054 {
2055   lo = near - MAX_BRANCH;
2056   hi = near + MAX_BRANCH;
2057   // avoid mapping the zero page
2058   if (lo < lowest_addr) lo = lowest_addr;
2059 }
2060
2061 void inferiorMallocAlign(unsigned &size)
2062 {
2063   // quadword-aligned (stack alignment)
2064   unsigned align = 16;
2065   if (size % align) size = ((size/align)+1)*align;
2066 }
2067
2068 // Emit code to jump to function CALLEE without linking.  (I.e., when
2069 // CALLEE returns, it returns to the current caller.)
2070 void emitFuncJump(opCode op, 
2071                   char *i, Address &base, 
2072                   const function_base *callee, process *proc)
2073 {
2074
2075     Address addr;
2076     int remainder;
2077     unsigned long count;
2078
2079     assert(op == funcJumpOp);
2080
2081     addr = callee->getEffectiveAddress(proc);
2082     Address addr2 = ((function_base *)callee)->getAddress(0);
2083     instruction *insn = (instruction *) ((void*)&i[base]);
2084     count = 0;
2085
2086     // Cleanup stack state from tramp preamble
2087
2088     // call DYNINSTrestore_temp
2089     Symbol info;
2090     Address baseAddr;
2091     function_base *fun_restore = proc->findOneFunction("DYNINSTrestore_temp");
2092     proc->getSymbolInfo("DYNINSTrestore_temp", info, baseAddr);
2093     assert(fun_restore);
2094     Address dyn_restore = fun_restore->addr() + baseAddr;
2095
2096     callAbsolute(insn, count, dyn_restore);
2097
2098     // load ra from the stack
2099     count += generate_load(&insn[count], REG_RA, REG_SP, 0, dw_quad);
2100
2101     // load GP from the stack
2102     count += generate_load(&insn[count], REG_GP, REG_SP, 8, dw_quad);
2103
2104     // increment stack by 16
2105     count += generate_lda(&insn[count], REG_SP, REG_SP, 16, true);
2106
2107     // save gp and ra in special location
2108     // **** Warning this fails in the case of replacing a mutually recursive
2109     //    function
2110     Address saveArea = inferiorMalloc(proc, 2*sizeof(long), dataHeap, 0);
2111
2112     count += generate_address(&insn[count], REG_T12, saveArea, remainder);
2113     count += generate_store(&insn[count], REG_GP, REG_T12, remainder, 
2114         dw_quad); 
2115
2116     count += generate_store(&insn[count], REG_RA, REG_T12, 
2117         remainder+sizeof(long), dw_quad);
2118
2119     // calling convention seems to expect t12 to contain the address of the
2120     //    suboutine being called, so we use t12 to build the address
2121     count += generate_address(&insn[count], REG_T12, addr, remainder);
2122     if (remainder)
2123         count += generate_lda(&insn[count], REG_T12, REG_T12, remainder, true);
2124     count += generate_jump(&insn[count], REG_T12, MD_JSR, REG_RA, remainder);
2125
2126     count += generate_nop(&insn[count]);
2127
2128     // back after function, restore everything
2129     count += generate_address(&insn[count], REG_RA, saveArea, remainder);
2130     count += generate_load(&insn[count], REG_GP, REG_RA, remainder, 
2131         dw_quad); 
2132
2133     count += generate_load(&insn[count], REG_RA, REG_RA, 
2134         remainder+sizeof(long), dw_quad);
2135     count += generate_jump(&insn[count], REG_RA, MD_JMP, REG_ZERO, remainder);
2136     count += generate_nop(&insn[count]);
2137
2138     base += count * sizeof(instruction);
2139 }
2140
2141 #ifdef BPATCH_LIBRARY
2142 /*
2143    terminate execution of a process
2144  */
2145 bool process::terminateProc_()
2146 {
2147     long flags = PRFS_KOLC;
2148     if (ioctl (proc_fd, PIOCSSPCACT, &flags) < 0)
2149         return false;
2150
2151     Exited();
2152
2153     // just to make sure it is dead
2154     kill(getPid(), 9);
2155
2156     return true;
2157 }
2158 #endif
2159
2160 void emitLoadPreviousStackFrameRegister(Address, Register,
2161                                         char *, Address &, int, bool){
2162   assert(0);
2163 }
2164  
2165 #ifndef BPATCH_LIBRARY
2166 bool process::isDynamicCallSite(instPoint *callSite){
2167   function_base *temp;
2168   if(!findCallee(*(callSite),temp)){
2169     return true;
2170   }
2171   return false;
2172 }
2173  
2174 bool process::MonitorCallSite(instPoint *callSite){
2175   return false;
2176 }
2177 #endif