* Bugfix: InstrucIter no longer used for int_function iteration.
[dyninst.git] / dyninstAPI / src / inst-ia64.C
1 /* -*- Mode: C; indent-tabs-mode: true; tab-width: 4 -*- */
2
3 /*
4  * Copyright (c) 1996-2004 Barton P. Miller
5  * 
6  * We provide the Paradyn Parallel Performance Tools (below
7  * described as "Paradyn") on an AS IS basis, and do not warrant its
8  * validity or performance.  We reserve the right to update, modify,
9  * or discontinue this software at any time.  We shall have no
10  * obligation to supply such updates or modifications or any other
11  * form of support to you.
12  * 
13  * This license is for research uses.  For such uses, there is no
14  * charge. We define "research use" to mean you may freely use it
15  * inside your organization for whatever purposes you see fit. But you
16  * may not re-distribute Paradyn or parts of Paradyn, in any form
17  * source or binary (including derivatives), electronic or otherwise,
18  * to any other organization or entity without our permission.
19  * 
20  * (for other uses, please contact us at paradyn@cs.wisc.edu)
21  * 
22  * All warranties, including without limitation, any warranty of
23  * merchantability or fitness for a particular purpose, are hereby
24  * excluded.
25  * 
26  * By your use of Paradyn, you understand and agree that we (or any
27  * other person or entity with proprietary rights in Paradyn) are
28  * under no obligation to provide either maintenance services,
29  * update services, notices of latent defects, or correction of
30  * defects for Paradyn.
31  * 
32  * Even if advised of the possibility of such damages, under no
33  * circumstances shall we (or any other person or entity with
34  * proprietary rights in the software licensed hereunder) be liable
35  * to you or any third party for direct, indirect, or consequential
36  * damages of any character regardless of type of action, including,
37  * without limitation, loss of profits, loss of use, loss of good
38  * will, or computer failure or malfunction.  You agree to indemnify
39  * us (and any other person or entity with proprietary rights in the
40  * software licensed hereunder) for any and all liability it may
41  * incur to third parties resulting from your use of Paradyn.
42  */
43
44 /*
45  * inst-ia64.C - ia64 dependent functions and code generator
46  */
47
48 /* Note that these should all be checked for (linux) platform
49    independence and the possibility of refactoring their originals
50    into in- and de-pendent parts. */
51
52 #include <iomanip>
53 #include <limits.h>
54
55 #include "common/h/headers.h"
56 #include "common/h/Dictionary.h"
57 #include "dyninstAPI/src/symtab.h"
58 #include "dyninstAPI/src/process.h"
59 #include "dyninstAPI/src/inst.h"
60 #include "dyninstAPI/src/instP.h"
61 #include "dyninstAPI/src/ast.h"
62 #include "dyninstAPI/src/util.h"
63 #include "dyninstAPI/src/stats.h"
64 #include "dyninstAPI/src/os.h"
65 #include "dyninstAPI/src/debug.h"
66 #include "dyninstAPI/src/registerSpace.h"
67
68 #include "dyninstAPI/src/dyn_thread.h" // get_index
69 #include "dyninstAPI/src/arch-ia64.h"
70 #include "dyninstAPI/src/inst-ia64.h"
71 #include "dyninstAPI/src/instPoint.h"   // includes instPoint-ia64.h
72 #include "dyninstAPI/src/instP.h"               // class returnInstance
73 #include "dyninstAPI/src/InstrucIter-Function.h"
74 #include "dyninstAPI/src/multiTramp.h"
75 #include "dyninstAPI/src/baseTramp.h"
76 #include "dyninstAPI/src/miniTramp.h"
77
78 #include "dyninstAPI/src/rpcMgr.h"
79
80 #include "debuggerinterface.h"
81
82 #include <sys/ptrace.h>
83 #include <asm/ptrace_offsets.h>
84
85 #include "BPatch.h"
86 #include "BPatch_memoryAccess_NP.h"
87
88 /* For unwinding through instrumentation. */
89 #include <libunwind.h>
90 #define PRESERVATION_UNWIND_OPERATION_COUNT     32
91
92 #define CALCULATE_KTI_REGISTER (rs->GPRs()[0]->number - 1)
93
94 /* Assembler-level labels for the dynamic basetramp. */
95 extern "C" {
96   void fetch_ar_pfs();
97   void address_of_instrumentation();
98   void address_of_call_alloc();
99   void address_of_return_alloc();
100   void address_of_address_of_call_alloc();
101   void address_of_address_of_return_alloc();    
102   void address_of_jump_to_emulation();
103         
104   /* For FP work. */
105   void address_of_jump_to_spills();
106   void address_of_jump_to_fills();
107 } /* end template symbols */
108
109 /* Private refactoring function.  Copies and rewrites
110    the basetramp template so it'll function in its new home. */
111 Address relocateBaseTrampTemplateTo( Address buffer, Address target ) {
112   /* These offset won't change, so only calculate them once. */
113   static Address addressOfTemplate = (Address)&fetch_ar_pfs;
114   static Address offsetOfJumpToInstrumentation = 0;
115   static Address offsetOfJumpToEmulation = 0;
116   static Address offsetOfCallAlloc = 0;
117   static Address offsetOfCallAllocMove = 0;
118   static Address offsetOfReturnAlloc = 0;
119   static Address offsetOfReturnAllocMove = 0;
120
121   static Address offsetOfJumpToSpills = 0;
122   static Address offsetOfJumpToFills = 0;
123
124   if( offsetOfJumpToInstrumentation == 0 ) {
125         offsetOfJumpToInstrumentation = (Address)&address_of_instrumentation - addressOfTemplate;
126         offsetOfJumpToEmulation = (Address)&address_of_jump_to_emulation - addressOfTemplate;
127         offsetOfCallAlloc = (Address)&address_of_call_alloc - addressOfTemplate;
128         offsetOfCallAllocMove = (Address)&address_of_address_of_call_alloc - addressOfTemplate;
129         offsetOfReturnAlloc = (Address)&address_of_return_alloc - addressOfTemplate;
130         offsetOfReturnAllocMove = (Address)&address_of_address_of_return_alloc - addressOfTemplate;
131
132         offsetOfJumpToSpills = (Address)&address_of_jump_to_spills - addressOfTemplate;
133         offsetOfJumpToFills = (Address)&address_of_jump_to_fills - addressOfTemplate;
134   } /* end offset initialization */
135
136         /* Our base tramp (the code block 'ia64_tramp_half')
137            needs two helper functions (get_ar_pfs() and
138            preservation_function()).  Since the latter needs
139            to be rewritten, we may as well copy the whole block
140            and avoid rewriting their calls.  (get_ar_pfs() is small.) */
141   memmove( (void *)buffer, (void *)addressOfTemplate, offsetOfJumpToEmulation + 8 );
142
143   /* Twiddle the appropriate bits. */
144   alterLongMoveAtTo( target + offsetOfCallAllocMove, target + offsetOfCallAlloc );
145   alterLongMoveAtTo( target + offsetOfReturnAllocMove, target + offsetOfReturnAlloc );
146
147   /* Always overwrite the jump to instrumentation bundle with a jump
148          to the bundle past the jump to emulation.  This handles the
149          inferior RPC case cleanly. */
150   instruction memoryNOP( NOP_M );
151   instruction_x longJumpInsn = generateLongBranchTo( target + offsetOfJumpToEmulation + 16 );
152   IA64_bundle jumpBundle = IA64_bundle( MLXstop, memoryNOP, longJumpInsn );
153   ia64_bundle_t rawJumpBundle = jumpBundle.getMachineCode();
154   memmove( (void *)(buffer + offsetOfJumpToInstrumentation), & rawJumpBundle, sizeof( ia64_bundle_t ) );
155
156   /* FIXME: jumpToSpills and jumpToFills need to be over-written to actually jump to the
157          appropriate code blocks, whose mutatee addresses the caller will supply (and populate).
158          Also take the addresses to the jumps back as parameters and rewrite those as well. */
159
160   /* Where do we stick the instrumentation code if we don't rewrite the jump again? */
161   return offsetOfJumpToEmulation + 16;
162 } /* end relocateTrampTemplate() */
163
164
165 /* Required by ast.C; used for memory instrumentation. */
166 void emitCSload( const BPatch_addrSpec_NP *as, Register dest, codeGen &gen, bool noCost ) {
167   // /* DEBUG */ fprintf( stderr, "emitCSload: as.imm = %d, as.r1 = %d, as.r2 = %d\n", as.getImm(), as.getReg( 0 ), as.getReg( 1 ) );
168         
169   /* emitCSload()'s first argument should be a BPatch_countSpec_NP.  It's supposed
170          to set dest to the number calculated by the countSpec, which means that it'll
171          be filled with bogus numnbers.  Don't complicate emitASload() with the bogosity. */
172   assert( as->getReg( 0 ) == -1 && as->getReg( 1 ) == -1 );
173   emitVload( loadConstOp, as->getImm(), dest, dest, gen, noCost );      
174 } /* end emitCSload() */
175
176 #define SHORT_IMMEDIATE_MIN     -8191
177 #define SHORT_IMMEDIATE_MAX             8191
178
179 /* Required by ast.C */
180 void emitVload( opCode op, Address src1, Register src2, Register dest,
181                                 codeGen &gen, bool noCost, registerSpace *rs, 
182                                 int size, const instPoint * location, 
183                                 AddressSpace * proc) {
184   switch( op ) {
185   case loadOp: {
186         /* Stick the address src1 in the temporary register src2. */
187         emitVload( loadConstOp, src1, 0, src2, gen, noCost, NULL, size);
188
189         /* Load into destination register dest from [src2]. */
190         instruction loadInsn = generateRegisterLoad( dest, src2, size );
191         IA64_bundle loadBundle( MIIstop, loadInsn, NOP_I, NOP_I );
192         loadBundle.generate( gen );
193   } break;
194
195   case loadConstOp: {
196         // Optimization: if |immediate| <= 22 bits, use generateShortImmediateAdd(), instead.
197         instruction_x lCO = generateLongConstantInRegister( dest, src1 );
198         generateBundleFromLongInstruction( lCO ).generate( gen );
199   } break;
200
201   case loadFrameRelativeOp: {
202         /* Load size bytes from the address fp + src1 into the register dest. */
203         assert( location->func()->getFramePointerCalculator() != NULL );                        
204                         
205         /* framePointerCalculator will leave the frame pointer in framePointer. */
206
207         Register framePointer = REG_NULL;
208         location->func()->getFramePointerCalculator()->generateCode(gen, false, framePointer);
209
210         instruction_x longConstant = generateLongConstantInRegister( src2, src1 );
211         instruction calculateAddress = generateArithmetic( plusOp, framePointer, src2, framePointer ); 
212         instruction loadFromAddress = generateRegisterLoad( dest, framePointer, size );
213         IA64_bundle prepareOffsetBundle( MLXstop, NOP_M, longConstant );
214         IA64_bundle calculateAndLoadBundle( MstopMIstop, calculateAddress, loadFromAddress, NOP_I );
215         prepareOffsetBundle.generate( gen );
216         calculateAndLoadBundle.generate( gen );
217
218         rs->freeRegister( framePointer );
219   } break;
220
221   case loadRegRelativeOp: {
222         /* Similar to loadFrameRelativeOp, except any general register may be used.
223          *
224          * src1 = offset
225          * src2 = base register
226          */
227         Register trueBase = rs->allocateRegister( gen, noCost );
228
229         emitLoadPreviousStackFrameRegister( BP_GR0 + src2, trueBase, gen, size, noCost );
230         instruction_x longConstant = generateLongConstantInRegister( dest, src1 );
231         instruction calculateAddress = generateArithmetic( plusOp, dest, dest, trueBase );
232         instruction loadFromAddress = generateRegisterLoad( dest, dest, size );
233
234         IA64_bundle prepareOffset( MLXstop, NOP_M, longConstant );
235         IA64_bundle calculateAndLoadBundle( MstopMIstop, calculateAddress, loadFromAddress, NOP_I );
236
237         prepareOffset.generate(gen);
238         calculateAndLoadBundle.generate(gen);
239
240         rs->freeRegister( trueBase );
241   } break;
242
243   case loadRegRelativeAddr: {
244         /* Similar to loadFrameAddr, except any general register may be used.
245          *
246          * src1 = offset
247          * src2 = base register
248          */
249         Register trueBase = rs->allocateRegister( gen, noCost );
250
251         emitLoadPreviousStackFrameRegister( BP_GR0 + src2, trueBase, gen, size, noCost );
252
253         instruction_x longConstant = generateLongConstantInRegister( dest, src1 );
254         instruction calculateAddress = generateArithmetic( plusOp, dest, dest, trueBase );
255         IA64_bundle prepareOffset( MLXstop, NOP_M, longConstant );
256         IA64_bundle calculateBundle( MIIstop, calculateAddress, NOP_I, NOP_I );
257
258         prepareOffset.generate( gen );
259         calculateBundle.generate( gen );
260
261         rs->freeRegister( trueBase );
262   } break;
263
264   case loadFrameAddr: {
265         /* Write the value of the fp + the immediate src1 into the register dest. */
266         assert( location->func()->getFramePointerCalculator() != NULL );
267
268         /* framePointerCalculator will leave the frame pointer in framePointer. */
269         Register framePointer = REG_NULL;
270         location->func()->getFramePointerCalculator()->generateCode( gen, false, framePointer);
271
272         instruction memoryNop( NOP_M );
273         instruction integerNop( NOP_I );
274
275         if( SHORT_IMMEDIATE_MIN < ((int)src1) && ((int)src1) < SHORT_IMMEDIATE_MAX ) {
276           instruction sumFrameAndOffset = generateShortImmediateAdd( dest, src1, framePointer );
277           IA64_bundle resultBundle( MIIstop, memoryNop, integerNop, sumFrameAndOffset );
278           resultBundle.generate( gen );
279         }
280         else {
281           instruction_x longConstant = generateLongConstantInRegister( dest, src1 );
282           IA64_bundle setLCBundle( MLXstop, memoryNop, longConstant );
283
284           instruction addLongConstantToFP = generateArithmetic( plusOp, dest, dest, framePointer );
285           IA64_bundle resultBundle( MIIstop, memoryNop, integerNop, addLongConstantToFP );
286
287           setLCBundle.generate( gen );
288           resultBundle.generate( gen );
289         }
290
291         rs->freeRegister( framePointer );                                               
292   } break;
293
294   default:
295         fprintf( stderr, "emitVload(): op not a load, aborting.\n" );
296         abort();
297         break;
298   } /* end switch */
299 } /* end emitVload() */
300
301 /* private function, used by emitFuncCall() */
302 void emitRegisterToRegisterCopy( Register source, Register destination, codeGen & gen, registerSpace * ) {
303   instruction moveInsn( generateRegisterToRegisterMove( source, destination ) );
304   instruction memoryNOP( NOP_M );
305   IA64_bundle r2rBundle( MMIstop, memoryNOP, memoryNOP, moveInsn );
306         
307   r2rBundle.generate(gen);
308 } /* end emitRegisterToRegisterCopy() */
309
310 /* private refactoring function */
311 Register findFreeLocal( registerSpace * rs, char * failure ) {
312   Register freeLocalRegister = 0;
313   unsigned int localZero = rs->GPRs()[0]->number;
314   for( unsigned int i = 0; i < NUM_LOCALS; i++ ) {
315         if( rs->isFreeRegister( localZero + i ) ) { freeLocalRegister = localZero + i; break; }
316   } /* end freeLocalRegister search */
317   if( freeLocalRegister == 0 ) {
318         fprintf(stderr, "Failed to find free local (0 - %d)\n", NUM_LOCALS);
319         rs->debugPrint();
320         fprintf( stderr, "%s", failure );
321         abort();
322   } /* end if failed to find a free local register */
323   return freeLocalRegister;
324 } /* end findFreeLocal() */
325
326 /* Obsolete addr-based version */
327 Register emitFuncCall(opCode, codeGen &, pdvector<AstNodePtr> &, bool, Address) {
328         assert(0);
329 }
330
331 /* Required by ast.C */
332 Register emitFuncCall( opCode op, codeGen & gen,
333                                            pdvector< AstNodePtr > & operands,
334                                            bool /* noCost */,
335                                            int_function *callee) { 
336   /* Consistency check. */
337   assert( op == callOp );
338
339   /* Sanity check for non-NULL address argument */
340   if( ! callee ) {
341         char msg[256];
342         snprintf( msg, 255, "%s[%d]: internal error:  emitFuncCall called without callee argument", __FILE__, __LINE__ );
343         showErrorCallback( 80, msg );
344         assert(0);
345   }
346  
347   Address calleeGP = gen.addrSpace()->proc()->getTOCoffsetInfo( callee );
348
349   /* Generate the code for the arguments. */
350   pdvector< Register > sourceRegisters;
351   for( unsigned int i = 0; i < operands.size(); i++ ) {
352           Register src = REG_NULL;
353           Address unused = ADDR_NULL;
354           if (!operands[i]->generateCode_phase2( gen, false, unused, src)) assert(0);
355           assert(src != REG_NULL);
356           sourceRegisters.push_back(src);
357   }
358
359   /* source-to-output register copy */
360   unsigned int outputZero = gen.rs()->GPRs()[NUM_LOCALS]->number;
361   for( unsigned int i = 0; i < sourceRegisters.size(); i++ ) {
362         // fprintf( stderr, "Copying argument in local register %d to output register %d\n", sourceRegisters[i], outputZero + i );
363         emitRegisterToRegisterCopy( sourceRegisters[i], outputZero + i, gen, gen.rs() );
364         gen.rs()->freeRegister( sourceRegisters[i] );
365         gen.rs()->incRefCount( outputZero + i );
366   } /* end source-to-output register copy */
367
368         /* Since the BT was kind enough to save the GP, return value,
369            return pointer, ar.pfs, and both scratch registers for us,
370            we don't bother.  Just set the callee's GP, copy the call
371            target into a scratch branch register, and indirect to it. */
372   emitVload( loadConstOp, calleeGP, 0, REGISTER_GP, gen, false /* ? */, 0 );
373
374   /* Grab a register -- temporary for transfer to branch register,
375          and a registerSpace register for the return value. */
376   Register rsRegister = findFreeLocal( gen.rs(), "Unable to find local register in which to store callee address, aborting.\n" );
377   gen.rs()->incRefCount( rsRegister );
378
379   instruction integerNOP( NOP_I );
380   instruction memoryNOP( NOP_M );
381
382   // fprintf( stderr, "Loading function address into register %d\n", rsRegister );
383   instruction_x loadCalleeInsn = generateLongConstantInRegister( rsRegister, callee->getAddress() );
384   IA64_bundle loadCalleeBundle( MLXstop, memoryNOP, loadCalleeInsn );
385         
386   loadCalleeBundle.generate(gen);
387
388   // fprintf( stderr, "Copying computed branch in general register %d to branch register %d.\n", rsRegister, BRANCH_SCRATCH );
389   instruction setBranchInsn = generateRegisterToBranchMove( rsRegister, BRANCH_SCRATCH );
390   IA64_bundle setBranchBundle( MIIstop, memoryNOP, integerNOP, setBranchInsn );
391
392   setBranchBundle.generate(gen);
393
394   // fprintf( stderr, "Calling function with offset in branch register %d, return pointer in %d\n", BRANCH_SCRATCH, BRANCH_RETURN );
395   instruction indirectBranchInsn = generateIndirectCallTo( BRANCH_SCRATCH, BRANCH_RETURN );
396   IA64_bundle indirectBranchBundle( MMBstop, memoryNOP, memoryNOP, indirectBranchInsn );
397
398   indirectBranchBundle.generate(gen);
399
400   /* According to the software conventions, the stack pointer must have sixteen bytes
401          of scratch space available directly above it.  Give it sixteen bytes nobody's using
402          to make sure we don't smash the stack.  This, however, is done in the preservation header. */
403   
404   for( unsigned int i = 0; i < sourceRegisters.size(); i++ ) {
405         /* Free all the output registers. */
406         gen.rs()->freeRegister( outputZero + i );
407   }
408
409   /* copy the result (r8) to a registerSpace register */
410   emitRegisterToRegisterCopy( REGISTER_RV, rsRegister, gen, gen.rs() );
411
412   /* return that register (still allocated) */
413   return rsRegister;
414 } /* end emitFuncCall() */
415
416 /* Required by ast.C; used for memory instrumentation. */
417 void emitASload( const BPatch_addrSpec_NP *as, Register dest, codeGen &gen,  bool /*noCost*/ ) {
418   /* Convert an addrSpec into a value in the destination register. */
419   // /* DEBUG */ fprintf( stderr, "emitASload: as.imm = %d, as.r1 = %d, as.r2 = %d\n", as.getImm(), as.getReg( 0 ), as.getReg( 1 ) );
420   emitLoadPreviousStackFrameRegister( as->getReg( 0 ), dest, gen, 0, 0 );
421 } /* end emitASload() */
422
423 // Used to have deadRegisterList. We now just keep the first and last registers,
424 // and interpolate the middle
425 Register firstDeadRegister = 0;
426 Register lastDeadRegister = 0xf;
427
428 void registerSpace::initialize32() {
429 }
430
431 void registerSpace::initialize64() {
432         static bool done = false;
433         if (done) return;
434         done = true;
435
436   /* Initialize the registerSpace pointer gen.rs() to the state of the
437          registers that will exist at the end of the first part of the base
438          tramp's code.  (That is, for the minitramps.)
439
440          The difficulty here is that the register numbers are expected to be
441          physical registers, but we can't determine those until we know which
442          function we're instrumenting...
443
444          For now, we'll just say 0x1 - 0xF. */
445
446         // There are no live registers - we rotate the window.
447
448         pdvector<registerSlot *> registers;
449         for (unsigned i = firstDeadRegister; i <= lastDeadRegister; i++) {
450                 registers.push_back(new registerSlot(i, 
451                                                                                          false, 
452                                                                                          registerSlot::deadAlways,
453                                                                                          registerSlot::GPR));
454         }
455
456         registerSpace::createRegisterSpace64(registers);
457     
458 } /* end initTramps() */
459
460 void registerSpace::initialize() {
461         initialize64();
462 }
463
464 /* Required by ast.C */
465 void emitV( opCode op, Register src1, Register src2, Register dest,
466                         codeGen &gen,  bool noCost, registerSpace *rs, int size, 
467                         const instPoint * location, AddressSpace * proc) {
468   switch( op ) { 
469   case eqOp:
470   case leOp:
471   case greaterOp:
472   case lessOp:
473   case geOp: 
474   case neOp: {
475         /* Unless we can verify that a comparison result is never used
476            as an operand, we can't do the right thing and treat the
477            destination as a predicate register.  *Sigh*. */
478
479         /* What's worse, since there is no way to allocate predicate
480            registers, the variable dest must represent a general register.
481            To deal with a the range difference between to two types of
482            registers (General: 0-127, Predicate: 0-63), we simply use
483            dest % 64.
484
485            That method is a hack at best, and creates a number of potential
486            bugs.  But, a correct solution would involve a complete overhaul
487            of our gen.rs() class, moving it into architecture specific files.
488            Perhaps for the next release.
489         */
490         instruction comparisonInsn = generateComparison( op, dest % 64, src1, src2 );
491         instruction setTrue = predicateInstruction( dest % 64, generateShortImmediateAdd( dest, 1, REGISTER_ZERO ) );
492         instruction setFalse = predicateInstruction( (dest + 1) % 64, generateShortImmediateAdd( dest, 0, REGISTER_ZERO ));
493         IA64_bundle comparisonBundle( MstopMIstop, comparisonInsn, setTrue, setFalse );
494         comparisonBundle.generate(gen);
495         break; }
496
497   case plusOp:
498   case minusOp:
499   case andOp:
500   case orOp: {
501         instruction arithmeticInsn = generateArithmetic( op, dest, src1, src2 );
502         instruction integerNOP( NOP_I );
503         IA64_bundle arithmeticBundle( MIIstop, arithmeticInsn, integerNOP, integerNOP );
504         arithmeticBundle.generate(gen);
505         break; }
506
507   case timesOp: {
508         /* Only the floating-point unit has a fixed-point multiplier. */
509         /* The stack already has the extra space that we need, thanks to the preservation
510            header, so use (arbitrarily) r3 to generate the pointers. */
511         instruction spillFP2 = generateFPSpillTo( REGISTER_SP, 2 );
512         instruction secondSpillAddr = generateShortImmediateAdd( 3, +16, REGISTER_SP );
513         instruction integerNOP( NOP_I );
514         instruction spillFP3 = generateFPSpillTo( 3, 3 );
515         IA64_bundle spillFP2Bundle( MMIstop, spillFP2, secondSpillAddr, integerNOP );
516         IA64_bundle spillFP3Bundle( MIIstop, spillFP3, integerNOP, integerNOP );
517         spillFP2Bundle.generate(gen);
518         spillFP3Bundle.generate(gen);
519         
520         /* Do the multiplication. */
521         instruction copySrc1 = generateRegisterToFloatMove( src1, 2 );
522         instruction copySrc2 = generateRegisterToFloatMove( src2, 3 );
523         instruction fixedMultiply = generateFixedPointMultiply( 2, 2, 3 );
524         instruction copyDest = generateFloatToRegisterMove( 2, dest );
525         IA64_bundle copySources( MMIstop, copySrc1, copySrc2, integerNOP );
526         instruction memoryNOP( NOP_M );
527         IA64_bundle doMultiplication( MFIstop, memoryNOP, fixedMultiply, integerNOP );
528         IA64_bundle copyToDestination( MMIstop, copyDest, memoryNOP, integerNOP );
529         copySources.generate(gen);
530         doMultiplication.generate(gen);
531         copyToDestination.generate(gen);
532
533         /* Restore the FP registers, SP. */
534         instruction fillFP2 = generateFPFillFrom( REGISTER_SP, 2 );
535         instruction fillFP3 = generateFPFillFrom( 3, 3 );
536         IA64_bundle fillF2Bundle( MIIstop, fillFP2, integerNOP, integerNOP );
537         IA64_bundle fillF3Bundle( MIIstop, fillFP3, integerNOP, integerNOP );
538         fillF2Bundle.generate(gen);
539         fillF3Bundle.generate(gen);
540                         
541         break; }
542
543   case divOp: { /* Call libc's __divsi3(). */
544
545         /* Make sure we've got everything we need to work with. */
546         assert( location );
547         assert( proc );
548         assert( rs );
549         opCode op( callOp );
550
551         /* Generate the operand ASTs. */
552         pdvector< AstNodePtr > operands;
553         operands.push_back(AstNode::operandNode( AstNode::DataReg, (void *)(long long int)src1 ) );
554         operands.push_back(AstNode::operandNode( AstNode::DataReg, (void *)(long long int)src2 ) );
555
556
557         /* Callers of emitV() expect the register space to be unchanged
558            afterward, so make sure eFC() doesn't use the source registers
559            after copying them to the output. */
560
561         /* Find address for functions __divsi3 */
562         pdstring callee = pdstring("__divsi3");
563         int_function *calleefunc = proc->findOnlyOneFunction(callee.c_str());
564         if (!calleefunc) {
565           char msg[256];
566           sprintf(msg, "%s[%d]:  internal error:  unable to find %s",
567                           __FILE__, __LINE__, callee.c_str());
568           showErrorCallback(100, msg);
569           assert(0);  // can probably be more graceful
570         }
571         /* Might want to use funcCall AstNode here */
572
573         /* Call emitFuncCall(). */
574         rs->incRefCount( src1 ); rs->incRefCount( src2 );
575         Register returnRegister = emitFuncCall( op, gen, operands, noCost, calleefunc);
576         /* A function call does not require any conditional branches, so ensure
577            that we're not screwing up the current AST by not telling it about stuff. */
578                         
579         if( returnRegister != dest ) {
580           emitRegisterToRegisterCopy( returnRegister, dest, gen, rs );
581           rs->freeRegister( returnRegister );
582         }
583         break; }
584
585   case noOp: {
586         IA64_bundle nopBundle( MIIstop, NOP_M, NOP_I, NOP_I );
587         nopBundle.generate(gen);
588         break; }
589
590   case storeIndirOp: {
591         /* Store 'size' bytes out of register src1 into the address in dest. */
592         instruction storeInstruction = generateRegisterStore( dest, src1, size );
593         IA64_bundle storeBundle( MMIstop, storeInstruction, NOP_M, NOP_I );
594         storeBundle.generate(gen);
595         break; }
596                         
597   case loadIndirOp: {
598         /* Load 'size' bytes from the address in register src1 to the register dest. */
599         instruction loadInstruction = generateRegisterLoad( dest, src1, size );
600         IA64_bundle loadBundle( MMIstop, loadInstruction, NOP_M, NOP_I );
601         loadBundle.generate(gen);
602         break; }
603
604   default:
605         fprintf( stderr, "emitV(): unrecognized op code %d\n", op );
606         assert( 0 );
607         break;
608   } /* end op switch */
609 } /* end emitV() */
610
611
612 /* Required by ast.C */
613 void emitImm( opCode op, Register src1, RegValue src2imm, Register dest,
614                           codeGen & gen,  bool /* noCost */, registerSpace * ) {
615   switch( op ) {
616   case orOp: {
617         /* Apparently, the bit-wise operation. */
618         if( src2imm == 0 ) {
619           emitRegisterToRegisterCopy( src1, dest, gen, NULL );
620         } else {
621           abort();
622         }
623   } break;
624                 
625   default:
626         assert( 0 );
627         break;
628   } /* end op switch */
629 } /* end emitImm() */
630
631 #define STATE_SAVE_COST     48
632 #define STATE_RESTORE_COST  48
633
634 /* Required by ast.C */
635 int getInsnCost( opCode op ) {
636   /* We'll measure cost mostly in instructions. */
637   int cost = 3;
638
639   switch( op ) {
640   case saveRegOp:
641         /* DEBUG */ fprintf( stderr, "%s[%d]: do I /implement/ saveRegOp?\n", __FILE__, __LINE__ );
642         cost = 3;
643         break;
644
645   case getSysRetValOp:
646         /* DEBUG */ fprintf( stderr, "%s[%d]: do I /implement/ getSysRetValOp?\n", __FILE__, __LINE__ );
647         cost = 3;
648         break;
649
650   case whileOp:
651         /* DEBUG */ fprintf( stderr, "%s[%d]: do I /implement/ whileOp?\n", __FILE__, __LINE__ );
652         cost = 3;
653         break;
654
655   case doOp:
656         /* DEBUG */ fprintf( stderr, "%s[%d]: do I /implement/ doOp?\n", __FILE__, __LINE__ );
657         cost = 3;
658         break;
659
660   case getSysParamOp:
661         /* DEBUG */ fprintf( stderr, "%s[%d]: do I /implement/ getSysParamOp?\n", __FILE__, __LINE__ );
662         cost = 3;
663         break;
664
665   case getAddrOp:
666         /* Turns into loadConstOp, loadFrameAddr, or loadRegRelativeAddr. */
667         cost = 6;
668         break;
669
670   case noOp:
671
672   case plusOp:
673   case minusOp:
674
675   case andOp:
676   case orOp:
677
678   case eqOp:
679   case neOp:
680   case lessOp:
681   case greaterOp:
682   case leOp:
683   case geOp:
684
685   case getParamOp:
686   case getRetValOp:
687
688   case loadOp:
689   case loadIndirOp:
690   case loadConstOp:
691   case storeIndirOp:
692         cost = 3;
693         break;
694
695   case storeOp:
696   case storeFrameRelativeOp:
697   case loadFrameAddr:
698   case loadFrameRelativeOp:
699
700   case ifOp:
701   case branchOp:
702         cost = 6;
703         break;
704
705   case timesOp:
706         cost = 21;
707         break;
708
709   case divOp:
710         /* Incurs the cost of a function call. */
711         cost = 30;
712   case callOp:
713         /* Assuming this doesn't include cost of argument construction
714            or actual delay time, we use (about) thirteen bundles. */
715         cost += 39;
716         break;
717
718   case updateCostOp:
719         cost = 6;
720         break;
721
722   case trampPreamble:
723         cost = STATE_SAVE_COST;
724         break;
725
726   case funcJumpOp:
727         /* Mostly the cost of the trampTrailer. */
728         cost = 6;
729   case trampTrailer:
730         cost += STATE_RESTORE_COST;
731         break;
732
733   case ifMCOp:
734         /* for emitJmpMC(), which isn't implemented. */
735         break;
736
737   default:
738         fprintf( stderr, "%s[%d]: unrecognized opCode %d\n", __FILE__, __LINE__, op );
739         break;
740   } /* end op switch */
741
742   return cost;  
743 } /* end getInsnCost() */
744
745 /* private refactoring function */
746 IA64_bundle generateUnknownRegisterTypeMoveBundle( Address src, Register dest ) {
747   if( /* (BP_GR0 <= src) && */ (src <= BP_GR127) ) {
748         instruction moveInsn = generateRegisterToRegisterMove( src, dest );
749         return IA64_bundle( MIIstop, NOP_M, NOP_I, moveInsn );
750   }
751   else if( (BP_BR0 <= src) && (src <= BP_BR7) ) {
752         instruction moveInsn = generateBranchToRegisterMove( src, dest );
753         return IA64_bundle( MIIstop, NOP_M, NOP_I, moveInsn );
754   }
755   else if( (BP_AR0 <= src) && (src <= BP_AR63) ) {
756         /* M-unit */
757         instruction moveInsn = generateApplicationToRegisterMove( src, dest );
758         return IA64_bundle( MIIstop, moveInsn, NOP_I, NOP_I );
759   }
760   else if( (BP_AR64 <= src) && (src <= BP_AR127) ) {
761         /* I-unit */
762         instruction moveInsn = generateApplicationToRegisterMove( src, dest );
763         return IA64_bundle( MIIstop, NOP_M, NOP_I, moveInsn );
764   }             
765   else if( BP_PR == src ) {
766         instruction moveInsn = generatePredicatesToRegisterMove( dest );
767         return IA64_bundle( MIIstop, NOP_M, NOP_I, moveInsn );
768   }
769   else {
770         fprintf( stderr, "[%s][%d]: illegal register number.\n", __FILE__, __LINE__ );
771         assert( 0 );
772   }
773 } /* end generateUnknownRegisterTypeMoveBundle() */
774
775 /* Required by ast.C */
776 void emitLoadPreviousStackFrameRegister( Address register_num, Register dest, 
777                                                                                  codeGen &gen,
778                                                                                  int /*size*/, bool /*noCost*/ )
779 {
780   /* Ray: why adjust 'base' instead of 'size' (as before)? */
781   IA64_bundle bundle;
782
783   if( gen.rs()->storageMap[ register_num ] == 0 ) {
784         if( register_num == dest ) return;
785         bundle = generateUnknownRegisterTypeMoveBundle( register_num, dest );
786   } else if( gen.rs()->storageMap[ register_num ] > 0 ) {
787         bundle = generateUnknownRegisterTypeMoveBundle( gen.rs()->storageMap[ register_num ], dest );
788   } else {
789         // Register was stored on the memory stack.
790                 
791         int stackOffset = 32 + ( (-gen.rs()->storageMap[ register_num ] - 1) * 8 );
792                 
793         bundle = IA64_bundle( MstopMIstop,
794                                                   generateShortImmediateAdd( dest, stackOffset, REGISTER_SP ),
795                                                   generateFillFrom( dest, dest, 0 ),
796                                                   NOP_I );
797   }
798
799   /* Insert bundle. */
800   bundle.generate(gen);
801 }
802
803 /* in arch-ia64.C */
804 extern instruction::unitType INSTRUCTION_TYPE_ARRAY[(0x20 + 1) * 3];
805
806 /* private refactoring function */
807 IA64_bundle generateBundleFor( instruction insnToBundle ) {
808   /* The instruction to bundle is always short; the long instruction bundling is trivial. */
809   instruction::unitType iUnitType = INSTRUCTION_TYPE_ARRAY[ (insnToBundle.getTemplateID() * 3) + insnToBundle.getSlotNumber() ];
810
811   instruction integerNOP( NOP_I );
812   instruction memoryNOP( NOP_M );
813         
814   switch( iUnitType ) {
815   case instruction::M:
816         return IA64_bundle( MIIstop, insnToBundle, integerNOP, integerNOP );
817         break;
818   case instruction::I:
819         return IA64_bundle( MIIstop, memoryNOP, insnToBundle, integerNOP );
820         break;
821   case instruction::B:
822         return IA64_bundle( MMBstop, memoryNOP, memoryNOP, insnToBundle );
823         break;
824   case instruction::F:
825         return IA64_bundle( MFIstop, memoryNOP, insnToBundle, integerNOP );
826         break;
827
828   case instruction::L:
829   case instruction::X:
830   case instruction::RESERVED:
831   default:
832         fprintf( stderr, "Invalid instruction type in generateBundleFor(), aborting.\n" );
833         abort();
834         break;
835   } /* end iUnitType switch */
836 } /* end generateBundleFor() */
837
838 /* private refactoring function */
839 bool instruction_x::generate(   codeGen &gen, 
840                                                                 AddressSpace *,
841                                                                 Address originalLocation,
842                                                                 Address allocatedAddress,
843                                                                 Address fallthroughTarget,
844                                                                 Address branchTarget ) {
845         // /* DEBUG */ fprintf( stderr, "%s[%d]: fallthroughTarget 0x%lx, branchTarget 0x%lx\n", __FILE__, __LINE__, fallthroughTarget, branchTarget );
846                                                                 
847         instruction::insnType instructionType = getType();
848         insn_tmpl tmpl = { getMachineCode().high };
849         insn_tmpl imm  = { getMachineCode().low };
850         int64_t immediate;
851         
852         /* originalLocation is NOT an encoded address */
853         switch( instructionType ) {
854                 case instruction::DIRECT_BRANCH: immediate = GET_X3_TARGET( &tmpl, &imm ); break;
855                 case instruction::DIRECT_CALL:   immediate = GET_X4_TARGET( &tmpl, &imm ); break;
856                 default: {
857                         instruction memoryNOP( NOP_M );
858                         IA64_bundle( MLXstop, memoryNOP,  *this ).generate(gen);
859                         return true;
860                         }
861                 }
862         
863         /* Correct the immediate by the difference between originalLocation and (insnPtr + size). */
864         /* originalLocation is NOT an encoded address */
865         Address target = immediate + originalLocation;
866         Address source = allocatedAddress + gen.used();
867         int64_t displacement = target - source;
868         
869         /* Handle edge instrumentation. */
870         if( branchTarget != 0x0 ) {
871                 /* DEBUG */ fprintf( stderr, "%s[%d]: given branchTarget 0x%lx, changing displacement from 0x%lx to 0x%lx\n",
872                         __FILE__, __LINE__, branchTarget, displacement, branchTarget - source );
873                 displacement = branchTarget - source;
874                 }
875         
876         switch( instructionType ) {
877                 case instruction::DIRECT_BRANCH: SET_X3_TARGET( &tmpl, &imm, displacement ); break;
878                 case instruction::DIRECT_CALL:   SET_X4_TARGET( &tmpl, &imm, displacement ); break;
879                 default: break;
880                 }
881         
882         instruction_x alteredLong( imm.raw, tmpl.raw, getTemplateID() );
883         IA64_bundle( MLXstop, instruction( NOP_M ), alteredLong ).generate( gen );
884         
885         if( fallthroughTarget != 0x0 ) {
886                 /* DEBUG */ fprintf( stderr, "%s[%d]: given fallthroughTarget 0x%lx, generating second branch with displacement of 0x%lx\n",
887                         __FILE__, __LINE__, fallthroughTarget, fallthroughTarget - source );
888                 IA64_bundle( MLXstop, instruction( NOP_M ), generateLongBranchTo( fallthroughTarget - source ) ).generate( gen );
889                 }
890
891         return true;
892         } /* end emulateLongInstruction */
893
894 /* private refactoring function */
895 void rewriteShortOffset(        instruction insnToRewrite, Address originalLocation,
896                                                         codeGen &gen, Address allocatedAddress, Address fallthroughTarget, Address branchTarget ) {
897         /* We insert a short jump past a long jump to the original target, followed
898            by the instruction rewritten to branch one bundle backwards.
899            It's not very elegant, but it's very straightfoward to implement. :) */
900         // /* DEBUG */ fprintf( stderr, "%s[%d]: rewriteShortOffset(): fallthroughTarget 0x%lx, branchTarget 0x%lx\n", __FILE__, __LINE__, fallthroughTarget, branchTarget );
901            
902         int forwardOffset = 0x20;
903         int backwardOffset = -0x10;
904         if( fallthroughTarget != 0x0 ) {
905                 /* DEBUG */ fprintf( stderr, "%s[%d]: fallthroughTarget 0x%lx generating extra bundle.\n", __FILE__, __LINE__, fallthroughTarget );
906                 forwardOffset = 0x30;
907                 backwardOffset = -0x20;
908                 }
909
910         /* CHECKME: do we need to worry about (dynamic) unwind information for any
911            of the instruction we'll rewrite here?  We special-cased direct calls below. */
912
913         /* Skip the long branch. */
914         instruction memoryNOP( NOP_M );
915         instruction_x skipInsn = generateLongBranchTo( forwardOffset );
916         IA64_bundle skipInsnBundle( MLXstop, memoryNOP, skipInsn );
917         skipInsnBundle.generate( gen ); 
918
919         /* Extract the original target. */
920         insn_tmpl tmpl = { insnToRewrite.getMachineCode() };
921         bool isSpecCheck = ( insnToRewrite.getType() == instruction::SPEC_CHECK );
922         Address originalTarget;
923         
924         if( isSpecCheck ) {
925                 originalTarget = GET_M20_TARGET( &tmpl ) + originalLocation;
926                 }
927         else {
928                 // This is cheating a bit, but all non-SPEC_CHECK instructions
929                 // that flow through this function share the same immediate
930                 // encoding, so using the M22 template should work.
931                 originalTarget = GET_M22_TARGET( &tmpl ) + originalLocation;
932                 }
933
934         /* The long branch. */
935         // /* DEBUG */ fprintf( stderr, "originalTarget 0x%lx = 0x%lx + 0x%lx\n", originalTarget, ( signExtend( signBit, immediate ) << 4 ), originalLocation );
936         // Align originalTarget
937         originalTarget -= originalTarget % 16;
938         // TODO: handle this better. AllocatedAddress is as of the start
939         // of our code generation, but we're a bundle farther. We should
940         // be flexible so that if someone adds in another random bundle we
941         // don't break.
942
943         if( branchTarget != 0x0 ) {
944                 originalTarget = branchTarget;
945                 }
946
947         // 0x10: sizeof(bundle)
948         instruction_x longBranch = generateLongBranchTo( originalTarget - ( allocatedAddress + 0x10 ) );
949         IA64_bundle longBranchBundle( MLXstop, memoryNOP, longBranch );
950         longBranchBundle.generate( gen );
951
952         if( fallthroughTarget != 0x0 ) {
953                 instruction_x fallBranch = generateLongBranchTo( fallthroughTarget - ( allocatedAddress + 0x20 ) );
954                 IA64_bundle fallBranchBundle( MLXstop, memoryNOP, fallBranch );
955                 fallBranchBundle.generate( gen );
956                 }
957
958         /* Rewrite the short immediate. */
959         if( isSpecCheck ) {
960                 SET_M20_TARGET( &tmpl, backwardOffset );
961                 }
962         else {
963                 SET_M22_TARGET( &tmpl, backwardOffset );
964                 }
965
966         /* Emit the rewritten immediate. */
967         instruction rewrittenInsn( tmpl.raw, insnToRewrite.getTemplateID(), insnToRewrite.getSlotNumber() );
968         generateBundleFor( rewrittenInsn ).generate(gen);
969         } /* end rewriteShortOffset() */
970
971 /* private refactoring function */
972 bool instruction::generate(     codeGen &gen,
973                                                         AddressSpace *,
974                                                         Address originalLocation,
975                                                         Address allocatedAddress,
976                                                         Address fallthroughTarget,
977                                                         Address branchTarget ) {
978         insn_tmpl tmpl = { getMachineCode() };
979
980         switch( getType() ) {
981                 case instruction::DIRECT_BRANCH:
982                         rewriteShortOffset( *this, originalLocation, gen,  allocatedAddress, fallthroughTarget, branchTarget );
983                         break; /* end direct jump handling */
984                 
985                 case instruction::DIRECT_CALL: {
986                         /* Direct calls have to be rewritten as long calls in order to make sure the assertions
987                            installBaseTramp() makes about the frame state in the dynamic unwind information
988                            are true.  (If we call backwards one instruction, the frame there is not the same as
989                            it was at the instruction we're emulating.)  */
990                         insn_tmpl tmpl = { getMachineCode() };
991                         Address originalTarget = GET_M22_TARGET( &tmpl ) + originalLocation - (originalLocation % 16);
992                         instruction_x longCall = generateLongCallTo( originalTarget - allocatedAddress, tmpl.B3.b1, tmpl.B3.qp );
993                         instruction memoryNOP( NOP_M );
994                         IA64_bundle longCallBundle( MLXstop, memoryNOP, longCall );
995                         longCallBundle.generate( gen );
996                         } break; /* end direct call handling */         
997         
998                 case instruction::BRANCH_PREDICT:
999                         /* We can suffer the performance loss. :) */
1000                         IA64_bundle( MIIstop, NOP_M, NOP_I, NOP_I ).generate(gen);
1001                         break; /* end branch predict handling */
1002                 
1003                 case instruction::ALAT_CHECK:
1004                 case instruction::SPEC_CHECK:
1005                         /* The advanced load checks can be handled exactly as we 
1006                            handle direct branches and calls.  The other three checks
1007                            (I&M unit integer speculation, fp speculation) are handled
1008                            identically to each other, but their immediates are laid
1009                            out a little different, so we can't handle them as we do
1010                            the advanced loads. */
1011                         rewriteShortOffset( *this, originalLocation, gen, allocatedAddress, fallthroughTarget, branchTarget );
1012                 
1013                         /* FIXME: the jump back needs to be fixed.  Implies we need to leave the emulated code in-place. */
1014                         break; /* end speculation check handling */
1015                 
1016                 case instruction::BRANCH_IA:
1017                         assert( 0 );
1018                         break; /* end branch to x86 handling */
1019                 
1020                 case instruction::MOVE_FROM_IP: {
1021                         /* Replace with a movl of the original IP. */
1022                         unsigned int originalRegister = tmpl.I25.r1;
1023                         instruction memoryNOP( NOP_M );
1024                         instruction_x emulatedIPMove = generateLongConstantInRegister( originalRegister, originalLocation );
1025                         IA64_bundle ipMoveBundle( MLXstop, memoryNOP, emulatedIPMove );
1026                         ipMoveBundle.generate(gen);
1027                         break; } /* end ip move handling */
1028                 
1029                 case instruction::INVALID:
1030                         fprintf( stderr, "Not emulating INVALID instruction.\n" );
1031                         break;
1032                 
1033                 case instruction::ALLOC:
1034                         // When emulating an alloc instruction, we must insure that it is the
1035                         // first instruction of an instruction group.
1036                         IA64_bundle( MstopMIstop, NOP_M, *this, NOP_I ).generate(gen);
1037                         break;
1038                 
1039                 case instruction::RETURN:
1040                 case instruction::INDIRECT_CALL:
1041                 case instruction::INDIRECT_BRANCH:
1042                         /* Branch registers hold absolute addresses. */
1043                 default:
1044                         generateBundleFor( *this ).generate(gen);
1045                         break; /* end default case */
1046                 } /* end type switch */
1047
1048         return true;
1049         } /* end instruction emulation */
1050
1051 /* Required by BPatch_thread.C */
1052 #define NEAR_ADDRESS 0x2000000000000000               /* The lower end of the shared memory segment. */
1053
1054 bool AddressSpace::replaceFunctionCall(instPoint * point, 
1055                                                                            const int_function * func ) {
1056   /* We'll assume that point is a call site, primarily because we don't actually care.
1057          However, the semantics seem to be that we can't replace function calls if we've already
1058          instrumented them (which is, of course, garbage), so we _will_ check that. */
1059   // Must be a call site
1060   if (point->getPointType() != callSite)
1061         return false;
1062
1063   /* We'll need this later. */
1064   instruction memoryNOP( NOP_M );
1065         
1066   /* Further implicit semantics indicate that a NULL function should be replace by NOPs. */
1067   IA64_bundle toInsert;
1068   if( func == NULL ) {
1069         toInsert = IA64_bundle( MIIstop, NOP_M, NOP_I, NOP_I );
1070   } /* end if we're inserting NOPs. */
1071         
1072   instPointIter ipIter(point);
1073   instPointInstance *ipInst;
1074   while ((ipInst = ipIter++)) {  
1075         // Multiple replacements. Wheee...
1076         Address pointAddr = ipInst->addr();
1077                 
1078         codeRange *range;
1079         if (modifiedRanges_.find(pointAddr, range)) {
1080           multiTramp *multi = range->is_multitramp();
1081           if (multi) {
1082                 // We pre-create these guys... so check to see if
1083                 // there's anything there
1084                 if (!multi->generated()) {
1085                   removeMultiTramp(multi);
1086                 }
1087                 else {
1088                   // TODO: modify the callsite in the multitramp.
1089                   assert(0);
1090                 }
1091           }
1092           else if (dynamic_cast<functionReplacement *>(range)) {
1093                 // We overwrote this in a function replacement...
1094                 continue; 
1095           }
1096         }
1097
1098         /* We'd like to generate the call here, but we need to know the IP it'll be
1099            at in order to generate the correct offset.  Grr. */
1100                 
1101         /* Since we need a full bundle to guarantee we can make the jump, we'll
1102            need to insert a minitramp to the emulated instructions.  Gather some
1103            of the necessary data. */
1104         uint8_t slotNo = pointAddr % 16;
1105         Address alignedAddress = pointAddr - slotNo;
1106                 
1107         /* We'll construct the minitramp in the mutator's address space and then copy
1108            it over once we're done. */
1109         codeGen codeBuffer(7*instruction::size());
1110                 
1111         /* However, we need to know the IP we'll be jumping to/from, so allocate
1112            the minitramp now. */
1113         bool allocErr; Address allocatedAddress = inferiorMalloc( 7 * sizeof( ia64_bundle_t ), anyHeap, NEAR_ADDRESS, & allocErr );
1114         assert( ! allocErr );
1115         assert( allocatedAddress % 16 == 0 );
1116                 
1117         /* Acquire the bundle we'll be emulating before we overwrite it. */
1118         ia64_bundle_t originalBundle;
1119         assert( readTextSpace( (void *)alignedAddress, 16, & originalBundle ) );
1120         IA64_bundle bundleToEmulate( originalBundle );
1121                 
1122         /* Overwrite the original instrumentation point with a jump to the minitramp. */
1123         Address offsetToMiniTramp = allocatedAddress /* target */ - alignedAddress /* ip */;
1124         instruction_x lbtMT = generateLongBranchTo( offsetToMiniTramp );
1125         IA64_bundle jumpBundle( MLXstop, memoryNOP, lbtMT );
1126         ia64_bundle_t rawJumpBundle = jumpBundle.getMachineCode();
1127         assert( writeTextSpace( (void *)alignedAddress, 16, & rawJumpBundle ) );
1128
1129
1130         // We keep track of these so that we can disable mutations later.
1131
1132         // In this case we leave the minitramp around, just
1133         // overwriting whatever was in the bundle the first time.
1134
1135         replacedFunctionCall *newRFC = new replacedFunctionCall();
1136         newRFC->callAddr = alignedAddress;
1137         newRFC->callSize = 16;
1138         if (func)
1139           newRFC->newTargetAddr = func->getAddress();
1140         else
1141           newRFC->newTargetAddr = 0;
1142
1143         newRFC->oldCall.allocate(16);
1144         newRFC->oldCall.copy(&originalBundle, sizeof(originalBundle));
1145
1146         newRFC->newCall.allocate(16);
1147         newRFC->newCall.copy(&rawJumpBundle, sizeof(rawJumpBundle));
1148         addReplacedCall(newRFC);
1149
1150         /* We don't want to emulate the call instruction itself. */
1151         if( slotNo != 0 ) {
1152           bundleToEmulate.getInstruction0().generate(codeBuffer, this, alignedAddress, allocatedAddress);
1153         }
1154         else {
1155           if( func != NULL ) {
1156                 /* The SCRAG says that b0 is the return register, but there's no gaurantee of this.
1157                    If we have problems, we can decode the call instruction. */
1158                 uint8_t branchRegister = 0;
1159                 int64_t callOffset = func->getAddress()- (allocatedAddress + codeBuffer.used());
1160                                 
1161                 instruction_x callToFunction = generateLongCallTo( callOffset, branchRegister );
1162                 toInsert = IA64_bundle( MLXstop, memoryNOP, callToFunction );
1163           } /* end if we have a function call to insert. */
1164                         
1165           toInsert.generate(codeBuffer);
1166         }
1167                 
1168         if( bundleToEmulate.hasLongInstruction() ) {
1169           if( slotNo == 0 ) {
1170                 bundleToEmulate.getLongInstruction().generate(codeBuffer,
1171                                                                                                           this,
1172                                                                                                           alignedAddress,
1173                                                                                                           allocatedAddress);
1174           }
1175           else {
1176                 if( func != NULL ) {
1177                   /* The SCRAG says that b0 is the return register, but there's no gaurantee of this.
1178                          If we have problems, we can decode the call instruction. */
1179                   uint8_t branchRegister = 0;
1180                   int64_t callOffset = func->getAddress() - (allocatedAddress + codeBuffer.used());
1181                                         
1182                   instruction_x callToFunction = generateLongCallTo( callOffset, branchRegister );
1183                   toInsert = IA64_bundle( MLXstop, memoryNOP, callToFunction );
1184                 } /* end if we have a function call to insert. */
1185                                 
1186                 toInsert.generate(codeBuffer);
1187           }
1188         } /* end if we have a long instruction */
1189         else {
1190           /* Handle the instruction in slot 1. */
1191           if( slotNo != 1 ) {
1192                 bundleToEmulate.getInstruction1().generate(codeBuffer,
1193                                                                                                    this,
1194                                                                                                    alignedAddress,
1195                                                                                                    allocatedAddress);
1196           }
1197           else {
1198                 if( func != NULL ) {
1199                   /* The SCRAG says that b0 is the return register, but there's no gaurantee of this.
1200                          If we have problems, we can decode the call instruction. */
1201                   uint8_t branchRegister = 0;
1202                   int64_t callOffset = func->getAddress() - (allocatedAddress + codeBuffer.used());
1203                                         
1204                   instruction_x callToFunction = generateLongCallTo( callOffset, branchRegister );
1205                   toInsert = IA64_bundle( MLXstop, memoryNOP, callToFunction );
1206                 } /* end if we have a function call to insert. */
1207                                 
1208                 toInsert.generate(codeBuffer);
1209           }
1210                         
1211           /* Handle the instruction in slot 2. */
1212           if( slotNo != 2 ) {
1213                 bundleToEmulate.getInstruction2().generate(codeBuffer,
1214                                                                                                    this,
1215                                                                                                    alignedAddress,
1216                                                                                                    allocatedAddress);
1217           }
1218           else {
1219                 if( func != NULL ) {
1220                   /* The SCRAG says that b0 is the return register, but there's no gaurantee of this.
1221                          If we have problems, we can decode the call instruction. */
1222                   uint8_t branchRegister = 0;
1223                   int64_t callOffset = func->getAddress() - (allocatedAddress + codeBuffer.used());
1224                                         
1225                   instruction_x callToFunction = generateLongCallTo( callOffset, branchRegister );
1226                   toInsert = IA64_bundle( MLXstop, memoryNOP, callToFunction );
1227                 } /* end if we have a function call to insert. */
1228                                 
1229                 toInsert.generate(codeBuffer);
1230           }
1231         } /* end if all three are short instructions. */
1232                 
1233         /* Append the return jump to the minitramp. */
1234         Address returnOffset = ( alignedAddress + 16 ) /* target */ - 
1235           (allocatedAddress + codeBuffer.used()) /* IP */;
1236         instruction_x lbtOriginal = generateLongBranchTo( returnOffset );
1237         IA64_bundle jumpBackBundle( MLXstop, memoryNOP, lbtOriginal );
1238         jumpBackBundle.generate(codeBuffer);
1239                 
1240         /* Write the minitramp into the mutatee's address space. */
1241         // /* DEBUG */ fprintf( stderr, "* Wrote minitramp at 0x%lx for %d bytes, from 0x%lx\n", allocatedAddress, size + 16, codeBuffer );
1242         assert( writeTextSpace( (void *)allocatedAddress, 
1243                                                         codeBuffer.used(), codeBuffer.start_ptr() ) );
1244                 
1245         // /* DEBUG */ fprintf( stderr, "* Emitted minitramp at local 0x%lx, for instPoint at 0x%lx and remote 0x%lx\n", (Address) & codeBuffer, alignedAddress, allocatedAddress );
1246   }
1247         
1248   return true;
1249         
1250 } /* end replaceFunctionCall() */
1251
1252 /* Private Refactoring Function
1253
1254 Moves preserved unstacked registers to register stack for basetramp.
1255 FIXME: handling for ar.fpsr (status field 1), ar.rsc (mode), and User Mask.
1256 */
1257 void generateRegisterStackSave( codeGen &gen, unw_dyn_region_info_t * unwindRegion )
1258 {
1259   instruction insn[ 3 ];
1260   IA64_bundle bundle;
1261   int slot;
1262
1263   int extraStackSize = 0;
1264   for( int i = 0; i < BP_R_MAX; ++i )
1265         if( gen.rs()->storageMap[ i ] < 0 ) {
1266           // If the memory stack was needed, ar.unat was stashed,
1267           // and the memory stack will be shifted down by 16 bytes.
1268           extraStackSize += 16;
1269           break;
1270         }
1271   int originalFrameSize = gen.rs()->originalLocals + gen.rs()->originalOutputs;
1272   if( originalFrameSize == 96 ) {
1273         // If the original register frame was full, an fp register will be spilled,
1274         // and the memory stack will be shifted down by another 16 bytes.
1275         extraStackSize += 16;
1276   }
1277         
1278   // Save the general registers.
1279   slot = 0;
1280   for( Register i = BP_GR0; i < BP_GR0 + 128; ++i ) {
1281         if( gen.rs()->storageMap[ i ] > 0 ) {
1282           if( i == BP_GR0 + 12 ) {
1283                 // SP is a special case.
1284                 insn[ slot++ ] = generateShortImmediateAdd( gen.rs()->storageMap[ i ],
1285                                                                                                         gen.rs()->sizeOfStack + extraStackSize,
1286                                                                                                         REGISTER_SP );
1287           } else {
1288                 // Default case.
1289                 insn[ slot++ ] = generateRegisterToRegisterMove( i - BP_GR0, gen.rs()->storageMap[ i ] );
1290           }
1291         }
1292         if( slot == 3 || (i == BP_GR0 + 127 && slot) ) {
1293           if( slot < 2 ) insn[ 1 ] = instruction( NOP_I );
1294           if( slot < 3 ) insn[ 2 ] = instruction( NOP_I );
1295                         
1296           bundle = IA64_bundle( MII, insn[ 0 ], insn[ 1 ], insn[ 2 ] );
1297           bundle.generate(gen);
1298           unwindRegion->insn_count += 3;
1299
1300           slot = 0;
1301         }
1302   }
1303
1304   // Save the branch registers
1305   slot = 1;
1306   for( Register i = BP_BR0; i < BP_BR0 + 8; ++i ) {
1307         if( gen.rs()->storageMap[ i ] > 0 ) {
1308           insn[ slot++ ] = generateBranchToRegisterMove( i - BP_BR0, gen.rs()->storageMap[ i ] );
1309
1310           // Register unwind information for RP.
1311           if( i == BP_BR0 )
1312                 _U_dyn_op_save_reg( & unwindRegion->op[ unwindRegion->op_count++ ], _U_QP_TRUE,
1313                                                         unwindRegion->insn_count + (slot-1), UNW_IA64_RP,
1314                                                         gen.rs()->storageMap[ i ] );
1315         }
1316
1317         if( slot == 3 || (i == BP_BR0 + 7 && slot != 1) ) {
1318           if( slot < 3 ) insn[ 2 ] = instruction( NOP_I );
1319
1320           bundle = IA64_bundle( MII, NOP_I, insn[ 1 ], insn[ 2 ] );
1321           bundle.generate(gen);
1322           unwindRegion->insn_count += 3;
1323
1324           slot = 1;
1325         }
1326   }
1327
1328   // Save the application registers.
1329   slot = 0;
1330   bool isPFS = false;
1331   for( Register i = BP_AR0; i < BP_AR0 + 128; ++i ) {
1332         if( gen.rs()->storageMap[ i ] > 0 ) {
1333           if( i == BP_AR_PFS ) {
1334                 // Special case for ar.pfs:  Account for I-type move instruction.
1335                 // ASSUMPTION:  ar.pfs does not change between instrumentation point
1336                 //              and basetramp state preservation.
1337                 insn[ 2 ] = generateApplicationToRegisterMove( i - BP_AR0, gen.rs()->storageMap[ i ] );
1338                 insn[ slot++ ] = instruction( NOP_M );
1339                 isPFS = true;
1340
1341           } else {
1342                 // Default case.
1343                 insn[ slot++ ] = generateApplicationToRegisterMove( i - BP_AR0, gen.rs()->storageMap[ i ] );
1344           }
1345         }
1346
1347         if( slot == 2 || (i == BP_AR0 + 127 && slot) ) {
1348           if( slot < 2 ) insn[ 1 ] = instruction( NOP_M );
1349
1350           bundle = IA64_bundle( MMI, insn[ 0 ], insn[ 1 ], ( isPFS ? insn[ 2 ] : NOP_I ) );
1351           bundle.generate(gen);
1352           unwindRegion->insn_count += 3;
1353
1354           slot = 0;
1355           isPFS = false;
1356         }
1357   }
1358
1359   // Save the predicate registers
1360   insn[ 0 ] = instruction( NOP_M );
1361   if( gen.rs()->storageMap[ BP_PR ] > 0 ) {
1362         insn[ 1 ] = generatePredicatesToRegisterMove( gen.rs()->storageMap[ BP_PR ] );
1363         _U_dyn_op_save_reg( & unwindRegion->op[ unwindRegion->op_count++ ], _U_QP_TRUE,
1364                                                 unwindRegion->insn_count + (slot-1), UNW_IA64_PR,
1365                                                 gen.rs()->storageMap[ BP_PR ] );
1366
1367   } else {
1368         // This bundle is needed to end the instruction group, regardless.
1369         insn[ 1 ] = instruction( NOP_I );
1370   }
1371   insn[ 2 ] = instruction( NOP_I );
1372
1373   bundle = IA64_bundle( MIIstop, insn[ 0 ], insn[ 1 ], insn[ 2 ] );
1374   bundle.generate(gen);
1375   unwindRegion->insn_count += 3;
1376 }
1377
1378 /* Private Refactoring Function
1379
1380 Moves preserved registers back to original location for basetramp trailer.
1381 FIXME: handling for ar.fpsr (status field 1), ar.rsc (mode), and User Mask.
1382 */
1383 void generateRegisterStackRestore( codeGen &gen, unw_dyn_region_info_t * unwindRegion )
1384 {
1385   instruction insn[ 3 ];
1386   IA64_bundle bundle;
1387   int slot;
1388
1389   // Restore the general registers.
1390   slot = 0;
1391   for( Register i = BP_GR0; i < BP_GR0 + 128; ++i ) {
1392         if( i != BP_GR0 + 12 && gen.rs()->storageMap[ i ] > 0 )
1393           insn[ slot++ ] = generateRegisterToRegisterMove( gen.rs()->storageMap[ i ], i - BP_GR0 );
1394
1395         if( slot == 3 || (i == BP_GR0 + 127 && slot) ) {
1396           if( slot < 2 ) insn[ 1 ] = instruction( NOP_I );
1397           if( slot < 3 ) insn[ 2 ] = instruction( NOP_I );
1398
1399           bundle = IA64_bundle( MII, insn[ 0 ], insn[ 1 ], insn[ 2 ] );
1400           bundle.generate(gen);
1401           unwindRegion->insn_count += 3;
1402
1403           slot = 0;
1404         }
1405   }
1406
1407   // Restore the branch registers
1408   slot = 1;
1409   for( Register i = BP_BR0; i < BP_BR0 + 8; ++i ) {
1410         if( gen.rs()->storageMap[ i ] > 0 )
1411           insn[ slot++ ] = generateRegisterToBranchMove( gen.rs()->storageMap[ i ], i - BP_BR0 );
1412
1413         if( slot == 3 || (i == BP_BR0 + 7 && slot != 1) ) {
1414           if( slot < 3 ) insn[ 2 ] = instruction( NOP_I );
1415
1416           bundle = IA64_bundle( MII, NOP_I, insn[ 1 ], insn[ 2 ] );
1417           bundle.generate(gen);
1418           unwindRegion->insn_count += 3;
1419
1420           slot = 1;
1421         }
1422   }
1423
1424   // Restore the application registers.
1425   slot = 0;
1426   bool isPFS = false;
1427   for( Register i = BP_AR0; i < BP_AR0 + 128; ++i ) {
1428         if( gen.rs()->storageMap[ i ] > 0 ) {
1429           if( i == BP_AR_PFS ) {
1430                 // Special case for ar.pfs:  Account for I-type move instruction.
1431                 insn[ 2 ] = generateRegisterToApplicationMove( gen.rs()->storageMap[ i ], i - BP_AR0 );
1432                 insn[ slot++ ] = instruction( NOP_M );
1433                 isPFS = true;
1434
1435           } else {
1436                 // Default case.
1437                 insn[ slot++ ] = generateRegisterToApplicationMove( gen.rs()->storageMap[ i ], i - BP_AR0 );
1438           }
1439         }
1440
1441         if( slot == 2 || (i == BP_AR0 + 127 && slot) ) {
1442           if( slot < 2 ) insn[ 1 ] = instruction( NOP_M );
1443
1444           bundle = IA64_bundle( MMI, insn[ 0 ], insn[ 1 ], ( isPFS ? insn[ 2 ] : NOP_I ) );
1445           bundle.generate(gen);
1446           unwindRegion->insn_count += 3;
1447
1448           slot = 0;
1449           isPFS = false;
1450         }
1451   }
1452
1453   // Restore the predicate registers
1454   insn[ 0 ] = instruction( NOP_M );
1455   if( gen.rs()->storageMap[ BP_PR ] > 0 ) {
1456         insn[ 1 ] = generateRegisterToPredicatesMove( gen.rs()->storageMap[ BP_PR ], ~0x1 );
1457   } else {
1458         // This bundle is needed to end the instruction group, regardless.
1459         insn[ 1 ] = instruction( NOP_I );
1460   }
1461   insn[ 2 ] = instruction( NOP_I );
1462
1463   bundle = IA64_bundle( MIIstop, insn[ 0 ], insn[ 1 ], insn[ 2 ] );
1464   bundle.generate(gen);
1465   unwindRegion->insn_count += 3;
1466 }
1467
1468 /* Private Refactoring Function
1469
1470 Spills stacked registers to memory stack, if needed.
1471 */
1472 void generateMemoryStackSave( codeGen &gen, bool * usedFPregs, unw_dyn_region_info_t * unwindRegion )
1473 {
1474   Register temp_gr[ 2 ] = { 6 };
1475   Register temp_fr = 6;
1476
1477   instruction insn[ 2 ];
1478   IA64_bundle bundle;
1479   int grStackOffset = 0;
1480   int frStackOffset = 0;
1481
1482   bool grSpillNeeded = false;
1483   for( int i = 0; i < BP_R_MAX; ++i )
1484         if( gen.rs()->storageMap[ i ] < frStackOffset ) {
1485           grSpillNeeded = true;
1486           frStackOffset = gen.rs()->storageMap[ i ];
1487         }
1488   frStackOffset  = 32 + (-frStackOffset * 8);
1489   frStackOffset += frStackOffset % 16;
1490
1491   int originalFrameSize = gen.rs()->originalLocals + gen.rs()->originalOutputs;
1492   if( grSpillNeeded ) {
1493         if( originalFrameSize == 96 ) {
1494           // Free a general register when all 96 stacked registers are in use.
1495           // We also do this when 95 registers are in use because our new alloc
1496           // instruction uses the only free register.
1497           //
1498           // Algorithm taken from:
1499           // V. Ramasamy, R. Hundt, "Dynamic Binary Instrumentation for Intel Itanium
1500           // Processor Family," EPIC1 Workshop, MICRO34, Dec 1-5, 2001
1501
1502           bundle = IA64_bundle( MstopMI,
1503                                                         generateShortImmediateAdd( REGISTER_SP, -16, REGISTER_SP ),
1504                                                         generateFPSpillTo( REGISTER_SP, temp_fr, -16 ),
1505                                                         NOP_I );
1506           _U_dyn_op_add( & unwindRegion->op[ unwindRegion->op_count++ ], _U_QP_TRUE,
1507                                          unwindRegion->insn_count + 0, UNW_IA64_SP, (unw_word_t)-16 );
1508           _U_dyn_op_add( & unwindRegion->op[ unwindRegion->op_count++ ], _U_QP_TRUE,
1509                                          unwindRegion->insn_count + 1, UNW_IA64_SP, (unw_word_t)-16 );
1510           bundle.generate(gen);
1511           unwindRegion->insn_count += 3;
1512
1513           bundle = IA64_bundle( MMIstop,
1514                                                         generateRegisterToFloatMove( temp_gr[ 0 ], temp_fr ),
1515                                                         generateApplicationToRegisterMove( AR_UNAT, temp_gr[ 0 ] ),
1516                                                         NOP_I );
1517           bundle.generate(gen);
1518           unwindRegion->insn_count += 3;
1519
1520         } else {
1521           // Since at least one stacked register is unused, the highest
1522           // register allocated for basetramp must be free.
1523                 temp_gr[0] = gen.rs()->GPRs().back()->number;
1524
1525           bundle = IA64_bundle( MMIstop,
1526                                                         generateShortImmediateAdd( REGISTER_SP, -16, REGISTER_SP ),
1527                                                         generateApplicationToRegisterMove( AR_UNAT, temp_gr[ 0 ] ),
1528                                                         NOP_I );
1529           _U_dyn_op_add( & unwindRegion->op[ unwindRegion->op_count++ ], _U_QP_TRUE,
1530                                          unwindRegion->insn_count + 0, UNW_IA64_SP, (unw_word_t)-16 );
1531           bundle.generate(gen);
1532           unwindRegion->insn_count += 3;
1533         }
1534
1535         // Store ar.unat
1536         bundle = IA64_bundle( MIIstop,
1537                                                   generateSpillTo( REGISTER_SP, temp_gr[ 0 ], 0 ),
1538                                                   NOP_I,
1539                                                   NOP_I );
1540         bundle.generate(gen);
1541         unwindRegion->insn_count += 3;
1542   }
1543   /* This is always necessary, because of function calls and the floating-point spills for multiplication. */
1544   bundle = IA64_bundle( MIIstop,
1545                                                 generateShortImmediateAdd( REGISTER_SP, -gen.rs()->sizeOfStack, REGISTER_SP ),
1546                                                 NOP_I,
1547                                                 NOP_I );
1548   _U_dyn_op_add( & unwindRegion->op[ unwindRegion->op_count++ ], _U_QP_TRUE,
1549                                  unwindRegion->insn_count, UNW_IA64_SP, -gen.rs()->sizeOfStack );
1550   bundle.generate(gen);
1551   unwindRegion->insn_count += 3;
1552
1553   // Save the general registers, if needed.
1554   // FIXME: This could be optimized to use more free registers, if they exist.
1555   for( Register i = BP_GR0; i < BP_GR0 + 128; ++i ) {
1556         if( gen.rs()->storageMap[ i ] < 0 ) {
1557           grStackOffset = 32 + ( ( -gen.rs()->storageMap[ i ] - 1 ) * 8 );
1558
1559           bundle = IA64_bundle( MstopMIstop,
1560                                                         generateShortImmediateAdd( temp_gr[ 0 ], grStackOffset, REGISTER_SP ),
1561                                                         generateSpillTo( temp_gr[ 0 ], i, 0 ),
1562                                                         NOP_I );
1563           bundle.generate(gen);
1564           unwindRegion->insn_count += 3;
1565         }
1566   }
1567
1568   //
1569   // At this point, we have NUM_LOCALS + NUM_OUTPUT + NUM_PRESERVED
1570   // general registers free.
1571   //
1572   if( grSpillNeeded ) {
1573         if( originalFrameSize == 96 ) {
1574           temp_gr[ 1 ] = gen.rs()->GPRs()[1]->number;
1575           // Undo register swapping to maintain uniform register state.
1576           bundle = IA64_bundle( MMIstop,
1577                                                         generateFloatToRegisterMove( temp_fr, temp_gr[ 0 ] ),
1578                                                         generateShortImmediateAdd( temp_gr[ 1 ], gen.rs()->sizeOfStack + 16, REGISTER_SP ),
1579                                                         NOP_I );
1580           bundle.generate(gen);
1581           unwindRegion->insn_count += 3;
1582
1583           bundle = IA64_bundle( MIIstop,
1584                                                         generateFPFillFrom( temp_gr[ 1 ], temp_fr, 0 ),
1585                                                         NOP_I,
1586                                                         NOP_I );
1587           bundle.generate(gen);
1588           unwindRegion->insn_count += 3;
1589         }
1590   }
1591
1592   // Save the FP regs
1593   temp_gr[ 0 ] = gen.rs()->GPRs()[0]->number;
1594   temp_gr[ 1 ] = gen.rs()->GPRs()[1]->number;
1595
1596   /* This should only be necessary if an FP register is used; not sure
1597          that two more/fewer GP registers really matter. */
1598   bundle = IA64_bundle( MIIstop,
1599                                                 generateShortImmediateAdd( temp_gr[ 0 ], frStackOffset +  0, REGISTER_SP ),
1600                                                 generateShortImmediateAdd( temp_gr[ 1 ], frStackOffset + 16, REGISTER_SP ),
1601                                                 NOP_I );
1602   bundle.generate(gen);
1603   unwindRegion->insn_count += 3;
1604
1605   // Save the floating point registers
1606   int slot = 0;
1607   for( int i = 0; i < 128; i++ ) {
1608         if( usedFPregs[i] ) {
1609           insn[ slot ] = generateFPSpillTo( temp_gr[ slot ], i, 32 );
1610           ++slot;
1611         }
1612
1613         if( slot == 2 || (i == 127 && slot) ) {
1614           if( slot < 2 ) insn[ 1 ] = instruction( NOP_M );
1615
1616           bundle = IA64_bundle( MMIstop, insn[ 0 ], insn[ 1 ], NOP_I );
1617           bundle.generate(gen);
1618           unwindRegion->insn_count += 3;
1619
1620           slot = 0;
1621         }
1622   }
1623 }
1624
1625 /* Private Refactoring Function
1626    Fills stacked registers from memory stack, if needed.
1627 */
1628 void generateMemoryStackRestore( codeGen &gen, bool * usedFPregs, unw_dyn_region_info_t * unwindRegion )
1629 {
1630   Register temp_gr[ 2 ] = { 6 };
1631   Register temp_fr = 6;
1632
1633   instruction insn[ 2 ];
1634   IA64_bundle bundle;
1635   int grStackOffset = 0;
1636   int frStackOffset = 0;
1637
1638   bool grSpillNeeded = false;
1639   for( int i = 0; i < BP_R_MAX; ++i )
1640         if( gen.rs()->storageMap[ i ] < frStackOffset ) {
1641           grSpillNeeded = true;
1642           frStackOffset = gen.rs()->storageMap[ i ];
1643         }
1644   frStackOffset  = 32 + (-frStackOffset * 8);
1645   frStackOffset += frStackOffset % 16;
1646
1647   int originalFrameSize = gen.rs()->originalLocals + gen.rs()->originalOutputs;
1648
1649   // Prepare offsets for the FP regs
1650   temp_gr[ 0 ] = gen.rs()->GPRs()[0]->number;
1651   temp_gr[ 1 ] = gen.rs()->GPRs()[1]->number;
1652
1653   bundle = IA64_bundle( MIIstop,
1654                                                 generateShortImmediateAdd( temp_gr[ 0 ], frStackOffset +  0, REGISTER_SP ),
1655                                                 generateShortImmediateAdd( temp_gr[ 1 ], frStackOffset + 16, REGISTER_SP ),
1656                                                 NOP_I );
1657   bundle.generate(gen);
1658   unwindRegion->insn_count += 3;
1659
1660   // Restore the FP registers
1661   int slot = 0;
1662   for( int i = 0; i < 128; i++ ) {
1663         if( usedFPregs[i] ) {
1664           insn[ slot ] = generateFPFillFrom( temp_gr[ slot ], i, 32 );
1665           ++slot;
1666         }
1667
1668         if( slot == 2 || (i == 127 && slot) ) {
1669           if( slot < 2 ) insn[ 1 ] = instruction( NOP_M );
1670
1671           bundle = IA64_bundle( MMIstop, insn[ 0 ], insn[ 1 ], NOP_I );
1672           bundle.generate(gen);
1673           unwindRegion->insn_count += 3;
1674
1675           slot = 0;
1676         }
1677   }
1678
1679   // Now we need to find the one guaranteed free register.
1680   if( grSpillNeeded ) {
1681         if( originalFrameSize == 96 ) {
1682           temp_gr[ 0 ] = 6;
1683           temp_gr[ 1 ] = gen.rs()->GPRs()[1]->number;
1684           // Redo register swapping to free up one extra general register..
1685           bundle = IA64_bundle( MstopMI,
1686                                                         generateShortImmediateAdd( temp_gr[ 1 ], gen.rs()->sizeOfStack + 16, REGISTER_SP ),
1687                                                         generateFPSpillTo( temp_gr[ 1 ], temp_fr, 0 ),
1688                                                         NOP_I );
1689           bundle.generate(gen);
1690           unwindRegion->insn_count += 3;
1691
1692           bundle = IA64_bundle( MIIstop,
1693                                                         generateRegisterToFloatMove( temp_gr[ 0 ], temp_fr ),
1694                                                         NOP_I,
1695                                                         NOP_I );
1696           bundle.generate(gen);
1697           unwindRegion->insn_count += 3;
1698
1699         } else {
1700                 temp_gr[0] = gen.rs()->GPRs().back()->number;
1701         }
1702
1703         if( originalFrameSize != 96 && gen.rs()->storageMap[ BP_AR_PFS ] != 32 + originalFrameSize ) {
1704           // Move ar.pfs to the expected location.
1705           bundle = IA64_bundle( MIIstop,
1706                                                         generateRegisterToRegisterMove( gen.rs()->storageMap[ BP_AR_PFS ], 32 + originalFrameSize ),
1707                                                         NOP_I,
1708                                                         NOP_I );
1709           bundle.generate(gen);
1710           unwindRegion->insn_count += 3;
1711         }
1712   }
1713
1714   // Restore the general registers, if needed.
1715   // FIXME: This could be optimized to use more free registers, if they exist.
1716   for( Register i = BP_GR0; i < BP_GR0 + 128; ++i ) {
1717         if( gen.rs()->storageMap[ i ] < 0 ) {
1718           grStackOffset = 32 + ( ( -gen.rs()->storageMap[ i ] - 1 ) * 8 );
1719
1720           bundle = IA64_bundle( MstopMIstop,
1721                                                         generateShortImmediateAdd( temp_gr[ 0 ], grStackOffset, REGISTER_SP ),
1722                                                         generateFillFrom( temp_gr[ 0 ], i, 0 ),
1723                                                         NOP_I );
1724           bundle.generate(gen);
1725           unwindRegion->insn_count += 3;
1726         }
1727   }
1728
1729   //
1730   // At this point, temp_gr[ 0 ] is the only safe register to use.
1731   //
1732   bundle = IA64_bundle( MIIstop,
1733                                                 generateShortImmediateAdd( REGISTER_SP, gen.rs()->sizeOfStack, REGISTER_SP ),
1734                                                 NOP_I,
1735                                                 NOP_I );
1736   _U_dyn_op_pop_frames( & unwindRegion->op[ unwindRegion->op_count++ ], _U_QP_TRUE, unwindRegion->insn_count, 1 );
1737   bundle.generate(gen);
1738   unwindRegion->insn_count += 3;
1739
1740   if( grSpillNeeded ) {
1741         // Restore ar.unat
1742         bundle = IA64_bundle( MstopMIstop,
1743                                                   generateFillFrom( REGISTER_SP, temp_gr[ 0 ], 0 ),
1744                                                   generateRegisterToApplicationMove( temp_gr[ 0 ], AR_UNAT ),
1745                                                   NOP_I );
1746         bundle.generate(gen);
1747         unwindRegion->insn_count += 3;
1748
1749         bundle = IA64_bundle( MIIstop,
1750                                                   generateShortImmediateAdd( REGISTER_SP, 16, REGISTER_SP ),
1751                                                   NOP_I,
1752                                                   NOP_I );
1753         _U_dyn_op_pop_frames( & unwindRegion->op[ unwindRegion->op_count++ ], _U_QP_TRUE, unwindRegion->insn_count, 1 );
1754         bundle.generate(gen);
1755         unwindRegion->insn_count += 3;
1756
1757         if( originalFrameSize == 96 ) {
1758           bundle = IA64_bundle( MMIstop,
1759                                                         generateFloatToRegisterMove( temp_fr, temp_gr[ 0 ] ),
1760                                                         generateFPFillFrom( REGISTER_SP, temp_fr, 16 ),
1761                                                         NOP_I );
1762           _U_dyn_op_pop_frames( & unwindRegion->op[ unwindRegion->op_count++ ], _U_QP_TRUE, unwindRegion->insn_count + 1, 1 );
1763           bundle.generate(gen);
1764           unwindRegion->insn_count += 3;
1765         }
1766   }
1767 }
1768
1769 /* private refactoring function */
1770 bool generatePreservationHeader(codeGen &gen, bool * whichToPreserve, unw_dyn_region_info_t * unwindRegion ) {
1771   /* For clarity (in the callers, too), handle NULL unwindRegions here. */
1772   bool freeUnwindRegion = false;
1773   if( unwindRegion == NULL ) {
1774         unwindRegion = (unw_dyn_region_info_t *)malloc( _U_dyn_region_info_size( PRESERVATION_UNWIND_OPERATION_COUNT ) );
1775         assert( unwindRegion != NULL );
1776         unwindRegion->op_count = 0;
1777         unwindRegion->insn_count = 0;
1778                 
1779         freeUnwindRegion = true;
1780   } /* end if unwindRegion was NULL */
1781
1782   instruction integerNOP( NOP_I );
1783   instruction memoryNOP( NOP_M );
1784   IA64_bundle bundle;
1785
1786   /* Assume, in the absence of information, that we wanted to preserve everything. */
1787   if( whichToPreserve == NULL ) {
1788         whichToPreserve = (bool *)malloc( 128 * sizeof( bool ) );
1789         for( int i = 0; i < 128; i++ ) {
1790           whichToPreserve[i] = true;
1791         } /* end initialization loop */
1792
1793         /* Never try to preserve fp 0, 1, 2 - 5, or 16 - 31, because we don't use
1794            them and the function we're calling will preserve them if it uses them. */
1795         whichToPreserve[ 0 ] = false;
1796         whichToPreserve[ 1 ] = false;
1797
1798         whichToPreserve[ 2 ] = false;
1799         whichToPreserve[ 3 ] = false;
1800         whichToPreserve[ 4 ] = false;
1801         whichToPreserve[ 5 ] = false;
1802
1803         whichToPreserve[ 16 ] = false;
1804         whichToPreserve[ 17 ] = false;
1805         whichToPreserve[ 18 ] = false;
1806         whichToPreserve[ 19 ] = false;
1807         whichToPreserve[ 20 ] = false;
1808         whichToPreserve[ 21 ] = false;
1809         whichToPreserve[ 22 ] = false;
1810         whichToPreserve[ 23 ] = false;
1811         whichToPreserve[ 24 ] = false;
1812         whichToPreserve[ 25 ] = false;
1813         whichToPreserve[ 26 ] = false;
1814         whichToPreserve[ 27 ] = false;
1815         whichToPreserve[ 28 ] = false;
1816         whichToPreserve[ 29 ] = false;
1817         whichToPreserve[ 30 ] = false;
1818         whichToPreserve[ 31 ] = false;          
1819   } /* end if whichToPreserve is NULL */
1820
1821         /* The alloc instruction here generated both preserves the stacked registers
1822            and provides us enough dead stacked registers to preserve the unstacked
1823            general registers, several application registers, and branch registers
1824            we need in order to ensure that we can make arbitrary function calls from
1825            the minitramps without (further) altering the mutatee's semantics.
1826
1827            If the original alloc already uses all 96 registers, don't generate
1828            a new alloc.
1829         */
1830   int originalFrameSize = gen.rs()->originalLocals + gen.rs()->originalOutputs;
1831   if( originalFrameSize < 96 ) {
1832         bundle = IA64_bundle( MIIstop,
1833                                                   generateAllocInstructionFor( gen.rs(), NUM_LOCALS, NUM_OUTPUT, gen.rs()->originalRotates ),
1834                                                   integerNOP,
1835                                                   integerNOP );
1836         bundle.generate(gen);
1837                 
1838         _U_dyn_op_save_reg( & unwindRegion->op[ unwindRegion->op_count++ ], _U_QP_TRUE,
1839                                                 unwindRegion->insn_count, UNW_IA64_AR_PFS, 32 + originalFrameSize );
1840         unwindRegion->insn_count += 3;
1841   }
1842         else if( originalFrameSize == 96 ) {
1843                 /* We can't generate our default alloc because it needs a free register.  However,
1844                    we still need an alloc in order to write to the registers we're preserving.  So
1845                    we use the technique we use for the restore allocs: spill and fill r1 around it. */
1846                    
1847                 IA64_bundle saveBundle = IA64_bundle( MstopMIstop, 
1848                         generateShortImmediateAdd( REGISTER_SP, -16, REGISTER_SP ),
1849                         generateRegisterStoreImmediate( REGISTER_SP, REGISTER_GP, 0 ),
1850                         integerNOP );
1851                 saveBundle.generate(gen);
1852
1853                 /* Generate our custom alloc. */        
1854                 insn_tmpl alloc = { 0x0 };
1855
1856                 alloc.M34.opcode    = 0x1;
1857                 alloc.M34.x3        = 0x6;
1858                 alloc.M34.r1        = 1;
1859
1860                 SET_M34_FIELDS( & alloc, 88, 8, gen.rs()->originalRotates );
1861
1862                 instruction allocInsn( alloc.raw );
1863                 IA64_bundle allocBundle( MIIstop, allocInsn, NOP_I, NOP_I );
1864                 allocBundle.generate(gen);
1865                 
1866                 IA64_bundle restoreBundle = IA64_bundle( MIIstop,
1867                         generateRegisterLoadImmediate( REGISTER_GP, REGISTER_SP, +16 ),
1868                         integerNOP,
1869                         integerNOP );
1870                 restoreBundle.generate(gen);
1871                 
1872                 /* FIXME: Update for save-and-restore around alloc. */
1873                 unwindRegion->insn_count += 9;
1874                 } /* end if the frame has 96 registers */
1875
1876   // generateMemoryStackSave() *MUST* be called before generateRegisterStackSave()
1877   generateMemoryStackSave( gen, whichToPreserve, unwindRegion );
1878   generateRegisterStackSave( gen, unwindRegion );
1879
1880   // /* DEBUG */ fprintf( stderr, "Emitted %d-bundle preservation header at 0x%lx\n", bundleCount, (Address)insnPtr ); 
1881
1882   /* Update the offset. */
1883   assert( unwindRegion->op_count < PRESERVATION_UNWIND_OPERATION_COUNT );
1884   if( freeUnwindRegion ) { free( unwindRegion ); }
1885   return true;
1886 } /* end generatePreservationHeader() */
1887
1888 /* private refactoring function; assumes that gen.rs() and
1889    deadRegisterList are as they were in the corresponding call
1890    to generatePreservationHeader(). */
1891 bool generatePreservationTrailer( codeGen &gen, bool * whichToPreserve, unw_dyn_region_info_t * unwindRegion ) {
1892   /* For clarity (in the callers, too), handle NULL unwindRegions here. */
1893   bool freeUnwindRegion = false;
1894   if( unwindRegion == NULL ) {
1895         unwindRegion = (unw_dyn_region_info_t *)malloc( _U_dyn_region_info_size( PRESERVATION_UNWIND_OPERATION_COUNT ) );
1896         assert( unwindRegion != NULL );
1897         unwindRegion->op_count = 0;
1898         unwindRegion->insn_count = 0;
1899                 
1900         freeUnwindRegion = true;
1901   } /* end if unwindRegion was NULL */
1902
1903         /* How many bundles did we use?  Update the (byte)'count' at the end. */
1904   int originalFrameSize = gen.rs()->originalLocals + gen.rs()->originalOutputs;
1905
1906   instruction memoryNOP( NOP_M );
1907   instruction integerNOP( NOP_I );
1908
1909   /* Assume, in the absence of information, that we wanted to preserve everything. */
1910   if( whichToPreserve == NULL ) {
1911         whichToPreserve = (bool *)malloc( 128 * sizeof( bool ) );
1912         for( int i = 0; i < 128; i++ ) {
1913           whichToPreserve[i] = true;
1914         } /* end initialization loop */
1915
1916         /* Never try to preserve fp 0, 1, 2 - 5, or 16 - 31, because we don't use
1917            them and the function we're calling will preserve them if it uses them. */
1918         whichToPreserve[ 0 ] = false;
1919         whichToPreserve[ 1 ] = false;
1920
1921         whichToPreserve[ 2 ] = false;
1922         whichToPreserve[ 3 ] = false;
1923         whichToPreserve[ 4 ] = false;
1924         whichToPreserve[ 5 ] = false;
1925
1926         whichToPreserve[ 16 ] = false;
1927         whichToPreserve[ 17 ] = false;
1928         whichToPreserve[ 18 ] = false;
1929         whichToPreserve[ 19 ] = false;
1930         whichToPreserve[ 20 ] = false;
1931         whichToPreserve[ 21 ] = false;
1932         whichToPreserve[ 22 ] = false;
1933         whichToPreserve[ 23 ] = false;
1934         whichToPreserve[ 24 ] = false;
1935         whichToPreserve[ 25 ] = false;
1936         whichToPreserve[ 26 ] = false;
1937         whichToPreserve[ 27 ] = false;
1938         whichToPreserve[ 28 ] = false;
1939         whichToPreserve[ 29 ] = false;
1940         whichToPreserve[ 30 ] = false;
1941         whichToPreserve[ 31 ] = false;          
1942   } /* end if whichToPreserve is NULL */
1943
1944         /* generateRegisterStackRestore() *MUST* be called before generateMemoryStackRestore() */
1945   generateRegisterStackRestore( gen, unwindRegion );
1946   generateMemoryStackRestore( gen, whichToPreserve, unwindRegion );
1947
1948   /* Restore the original frame. */
1949   if( originalFrameSize < 96 ) {
1950         /* Restore ar.pfs; preserved by the header's alloc instruction. */
1951         instruction movePFS = generateRegisterToApplicationMove( 32 + originalFrameSize, AR_PFS );
1952         IA64_bundle fifthMoveBundle( MIIstop, memoryNOP, movePFS, integerNOP );
1953         fifthMoveBundle.generate(gen);
1954         unwindRegion->insn_count += 3;
1955                 
1956         /* FIXME: Update for save-and-restore around alloc. */
1957         _U_dyn_op_stop( & unwindRegion->op[ unwindRegion->op_count++ ] );
1958
1959         IA64_bundle saveBundle = IA64_bundle( MstopMIstop, 
1960                                                                                   generateShortImmediateAdd( REGISTER_SP, -16, REGISTER_SP ),
1961                                                                                   generateRegisterStoreImmediate( REGISTER_SP, REGISTER_GP, 0 ),
1962                                                                                   integerNOP );
1963         saveBundle.generate(gen);
1964         
1965         instruction allocInsn = generateOriginalAllocFor( gen.rs() );
1966         IA64_bundle allocBundle( MIIstop, allocInsn, NOP_I, NOP_I );
1967         allocBundle.generate(gen);
1968                 
1969         IA64_bundle restoreBundle = IA64_bundle( MIIstop,
1970                                                                                          generateRegisterLoadImmediate( REGISTER_GP, REGISTER_SP, +16 ),
1971                                                                                          integerNOP,
1972                                                                                          integerNOP );
1973         restoreBundle.generate(gen);
1974
1975         unwindRegion->insn_count += 9;
1976   } else {
1977         _U_dyn_op_stop( & unwindRegion->op[ unwindRegion->op_count++ ] );
1978   }
1979   /* FIXME: It's only after the above alloc executes that anything changes from the
1980          POV of the unwinder, because the preserved values stay where they were
1981          preserved until then. */
1982         
1983   // /* DEBUG */ fprintf( stderr, "Emitted %d-bundle preservation trailer at 0x%lx\n", bundleCount, (Address)insnPtr ); 
1984
1985   /* Update the offset. */
1986   assert( unwindRegion->op_count < PRESERVATION_UNWIND_OPERATION_COUNT );
1987   if( freeUnwindRegion ) { free( unwindRegion ); }
1988   return true;
1989 } /* end generatePreservationTrailer() */
1990
1991 /* Originally from linux-ia64.C's executingSystemCall(). */
1992 bool needToHandleSyscall( dyn_lwp * lwp, bool * pcMayHaveRewound ) {
1993   ia64_bundle_t rawBundle;
1994   uint64_t iip, ri;
1995   int64_t pr;
1996
1997   // Bad things happen if you use ptrace on a running process.
1998   assert( lwp->status() != running );
1999         
2000   // Find the correct bundle.
2001   errno = 0;
2002   iip = lwp->getActiveFrame().getPC();
2003   reg_tmpl reg = { getDBI()->ptrace( PTRACE_PEEKUSER, lwp->get_lwp_id(), PT_CR_IPSR, 0, -1, &errno ) };
2004   if( errno && (reg.raw == ((unsigned long)-1)) ) {
2005         // Error reading process information.  Should we assert here?
2006         assert(0);
2007   }
2008   ri = reg.PSR.ri;
2009   if (ri == 0) iip -= 16;  // Get previous bundle, if necessary.
2010
2011   /* As above; if the syscall rewinds the PC, we must as well. */
2012   if( pcMayHaveRewound != NULL ) {
2013         if( ri == 0 ) {
2014           // /* DEBUG */ fprintf( stderr, "%s[%d]: pcMayHaveRewound.\n", FILE__, __LINE__ );
2015           * pcMayHaveRewound = true;
2016         } 
2017         else {
2018           * pcMayHaveRewound = false;
2019         }
2020   }
2021
2022         // Read bundle data
2023         if( ! lwp->proc()->readDataSpace( (void *)iip, 16, (void *)&rawBundle, true ) ) {
2024                 // Could have gotten here because the mutatee stopped right
2025                 // after a jump to the beginning of a memory segment (aka,
2026                 // no previous bundle).  But, that can't happen from a syscall.
2027                 return false;
2028                 }
2029
2030   // Isolate previous instruction.
2031   ri = (ri + 2) % 3;
2032   IA64_bundle origBundle( rawBundle );
2033   instruction *insn = origBundle.getInstruction(ri);
2034
2035   // Determine predicate register and remove it from instruction.
2036         pr = getDBI()->ptrace( PTRACE_PEEKUSER, lwp->get_lwp_id(), PT_PR, 0 );
2037   if (errno && pr == -1) assert(0);
2038   pr = ( pr >> insn->getPredicate() ) & 0x1;
2039   
2040   return (insn->getType() == instruction::SYSCALL && pr);
2041 } /* end needToHandleSyscall() */
2042
2043 #include "dlfcn.h"
2044
2045 /* From ia64-template.s. */
2046 extern void (* syscallPrefix)();
2047 extern void (* prefixNotInSyscall)();
2048 extern void (* prefixInSyscall)();
2049 extern void (* prefixCommon)();
2050 extern void (* jumpFromNotInSyscallToPrefixCommon)();
2051
2052 bool emitSyscallHeader( dyn_lwp * lwp, codeGen & gen ) {
2053   /* Be polite. */
2054   int firstHeaderIndex = gen.getIndex();
2055
2056   /* Extract the current slotNo. */
2057   errno = 0;
2058   reg_tmpl reg = { getDBI()->ptrace( PTRACE_PEEKUSER, lwp->get_lwp_id(), PT_CR_IPSR, 0 ) };
2059   assert( ! errno );
2060   uint64_t slotNo = reg.PSR.ri;
2061   assert( slotNo <= 2 );
2062
2063   // /* DEBUG */ fprintf( stderr, "emitSyscallHeader() thinks slotNo = %ld\n", slotNo );
2064
2065   /* When the kernel continues execution of the now-stopped process,
2066          it may or may not decrement the slot counter to restart the
2067          interrupted system call.  Since we need to resume after the iRPC
2068          where the kernel thinks we should, we need to change the slot of 
2069          the iRPC's terminal break, since we can't alter ipsr.ri otherwise.
2070            
2071          The header code is templated; we just replace the first bundle(s) with
2072          the one appropriate for the known slotNo.  Copy from 'syscallPrefix'
2073          to 'syscallPrefixCommon', exclusive.  (The last bundle is an spacing-
2074          only NOP bundle.  The iRPC header proper should start there.) */
2075
2076   /* The linker is doing Something Funky, but what we want is the address of
2077          what we're claiming are a bunch of function pointers. */
2078   Address syscallPrefixAddress = (Address)(& syscallPrefix);
2079   Address prefixNotInSyscallAddress = (Address)(& prefixNotInSyscall);
2080   Address prefixInSyscallAddress = (Address)(& prefixInSyscall);
2081   Address prefixCommonAddress = (Address)(& prefixCommon);
2082   Address jumpAddress = (Address)(& jumpFromNotInSyscallToPrefixCommon);
2083         
2084   Address lengthWithoutTrailingNOPs = prefixCommonAddress - syscallPrefixAddress;
2085   gen.copy( (void *)syscallPrefixAddress, lengthWithoutTrailingNOPs );
2086   int endOfTemplateIndex = gen.getIndex();
2087
2088   /* Likewise, we need to rewrite the nop.b bundle at jumpFromNotInSyscallToPrefixCommon
2089          because the assembler jumps are indirected.  (Why can't I force a relative jump?!) */
2090   instruction memoryNOP( NOP_M );
2091   instruction_x branchPastInSyscall = generateLongBranchTo( prefixCommonAddress - jumpAddress );
2092   IA64_bundle branchPastInSyscallBundle( MLXstop, memoryNOP, branchPastInSyscall );
2093
2094   gen.setIndex( (jumpAddress - syscallPrefixAddress) / 16 );
2095   branchPastInSyscallBundle.generate(gen);
2096
2097   /* Construct the slot-specific jump bundle. */
2098   IA64_bundle firstJumpBundle;
2099   IA64_bundle secondJumpBundle;
2100   instruction branchNOP( NOP_B );
2101         
2102   /* Probably wouldn't hurt to assert that the immediates here are small enough. */
2103   instruction jumpToInSyscall = generateShortImmediateBranch( prefixInSyscallAddress - (syscallPrefixAddress + 0x10 ) );
2104   instruction jumpToNotInSyscall = generateShortImmediateBranch( prefixNotInSyscallAddress - (syscallPrefixAddress + 0x10) );
2105   switch( slotNo ) {
2106   case 0:
2107         jumpToInSyscall = generateShortImmediateBranch( prefixInSyscallAddress - syscallPrefixAddress );
2108         firstJumpBundle = IA64_bundle( BBBstop, branchNOP, branchNOP, jumpToInSyscall );
2109         secondJumpBundle = IA64_bundle( BBBstop, jumpToNotInSyscall, branchNOP, branchNOP );
2110         break;
2111   case 1:
2112         firstJumpBundle = IA64_bundle( BBBstop, branchNOP, branchNOP, branchNOP );
2113         secondJumpBundle = IA64_bundle( BBBstop, jumpToInSyscall, jumpToNotInSyscall, branchNOP );
2114         break;
2115   case 2:
2116         firstJumpBundle = IA64_bundle( BBBstop, branchNOP, branchNOP, branchNOP );
2117         secondJumpBundle = IA64_bundle( BBBstop, branchNOP, jumpToInSyscall, jumpToNotInSyscall );
2118         break;
2119   default:
2120         assert( 0 );
2121         break;
2122   }
2123                 
2124   gen.setIndex( firstHeaderIndex );
2125   firstJumpBundle.generate( gen );
2126   secondJumpBundle.generate( gen );
2127   gen.setIndex( endOfTemplateIndex );
2128
2129   // /* DEBUG */ fprintf( stderr, "* iRPC system call handler (prefix) generated at 0x%lx\n", (Address) bundlePtr );
2130   return true;
2131 } /* end emitSystemCallHeader() */
2132
2133 /* private refactoring function */
2134 bool * doFloatingPointStaticAnalysis( const instPoint * location ) {
2135   /* Cast away const-ness rather than fix broken int_function::getAddress(). */
2136   int_function * functionBase = location->func();
2137
2138   InstrucIterFunction iAddr(functionBase);
2139
2140   // /* DEBUG */ fprintf( stderr, "Mutator claims to have mutatee machine code from 0x%lx to 0x%lx\n", mutatorAddress, lastI );
2141   // /* DEBUG */ fprintf( stderr, "(claims to be function '%s')\n", functionBase->symTabName().c_str() );
2142
2143   bool fpUsed = false;
2144   bool registersRotated = false;
2145   bool * whichToPreserve = (bool *)calloc( 128, sizeof( bool ) );
2146         
2147   while (iAddr.hasMore()) {
2148         instruction currInsn = iAddr.getInstruction();
2149         int slotNo = currInsn.getSlotNumber();
2150         iAddr++;
2151
2152         insn_tmpl tmpl = { currInsn.getMachineCode() };
2153                 
2154         bool instructionIsFP = false;
2155         bool instructionIsMem = false;
2156         uint8_t templateID = currInsn.getTemplateID();
2157         switch( templateID ) {
2158         case 0x00:
2159         case 0x01:
2160         case 0x02:
2161         case 0x03:
2162           /* MII */
2163         case 0x04:
2164         case 0x05:
2165           /* MLX */
2166           instructionIsMem = (slotNo == 0);
2167           break;
2168
2169         case 0x08:
2170         case 0x09:
2171         case 0x0A:
2172         case 0x0B:
2173           /* MMI */
2174           instructionIsMem = (slotNo == 0 || slotNo == 1);
2175           break;
2176
2177         case 0x10:
2178         case 0x11:
2179           /* MIB */
2180         case 0x12:
2181         case 0x13:
2182           /* MBB */
2183           instructionIsMem = (slotNo == 0);
2184           break;
2185
2186         case 0x18:
2187         case 0x19:
2188           /* MMB */
2189           instructionIsMem = (slotNo == 0 || slotNo == 1);
2190           break;
2191
2192         case 0x0C:
2193         case 0x0D:
2194           /* MFI */
2195         case 0x1C:
2196         case 0x1D:
2197           /* MFB */
2198           instructionIsFP = (slotNo == 1);
2199           instructionIsMem = (slotNo == 0);
2200           break;
2201
2202         case 0x0E:
2203         case 0x0F:
2204           /* MMF */
2205           instructionIsFP = (slotNo == 2);
2206           instructionIsMem = (slotNo == 0 || slotNo == 1);
2207           break;
2208
2209         default:
2210           break;
2211         } /* end switch */
2212
2213         if( instructionIsMem ) {
2214           /* Decide which fields in the instruction actually contain register numbers. */
2215           switch( GET_OPCODE( &tmpl ) ) {
2216           case 0x0: {
2217                 int8_t x2 = tmpl.M_SYS.x2;
2218                 int8_t x3 = tmpl.M_SYS.x3;
2219                 int8_t x4 = tmpl.M_SYS.x4;
2220
2221                 /* M23 */ if( x3 == 0x6 || x3 == 0x7 )
2222                   whichToPreserve[ tmpl.M23.f1 ] = true;
2223
2224                 /* M27 */ if( x3 == 0x0 && x4 == 0x3 && x2 == 0x1 )
2225                   whichToPreserve[ tmpl.M27.f1 ] = true;
2226           } break;
2227
2228           case 0x1: {
2229                 int8_t x3 = tmpl.M_SYS.x3;
2230
2231                 /* M21 */ if( x3 == 0x3 )
2232                   whichToPreserve[ tmpl.M21.f2 ] = true;
2233           } break;
2234
2235           case 0x4: {
2236                 int8_t m = tmpl.M_LD_ST.m;
2237                 int8_t x = tmpl.M_LD_ST.x;
2238                 int8_t x6 = tmpl.M_LD_ST.x6;
2239
2240                 /* M19 */ if( m == 0x0 && x == 0x1 && 0x1C <= x6 && x6 <= 0x1F )
2241                   whichToPreserve[ tmpl.M19.f2 ] = true;
2242           } break;
2243
2244           case 0x6: {
2245                 int8_t m = tmpl.M_LD_ST.m;
2246                 int8_t x = tmpl.M_LD_ST.x;
2247                 int8_t x6 = tmpl.M_LD_ST.x6;
2248
2249                 if( x == 0x0 && m == 0x0 ) {
2250                   /* M6  */ if( (0x00 <= x6 && x6 <= 0x0F) || (0x20 <= x6 && x6 <= 0x27) || x6 == 0x1B )
2251                         whichToPreserve[ tmpl.M6.f1 ] = true;
2252
2253                   /* M9  */ if( (0x30 <= x6 && x6 <= 0x32) || x6 == 0x3B )
2254                         whichToPreserve[ tmpl.M9.f2 ] = true;
2255                 }
2256                 if( x == 0x0 && m == 0x1 ) {
2257                   /* M7  */ if( (0x00 <= x6 && x6 <= 0x0F) || (0x20 <= x6 && x6 <= 0x27) || x6 == 0x1B )
2258                         whichToPreserve[ tmpl.M7.f1 ] = true;
2259
2260                   /* M10 */ if( (0x30 <= x6 && x6 <= 0x33) || (x6 == 0x3B) )
2261                         whichToPreserve[ tmpl.M10.f2 ] = true;
2262                 }
2263                 if( x == 0x1 && m == 0x0 ) {
2264                   /* M11 */ if( (0x01 <= x6 && x6 <= 0x0F && x6 != 0x04 && x6 != 0x08 && x6 != 0x0C && x6 != 0x24) ||
2265                                                 (0x21 <= x6 && x6 <= 0x27 && x6 != 0x24) ) {
2266                         whichToPreserve[ tmpl.M11.f1 ] = true;
2267                         whichToPreserve[ tmpl.M11.f2 ] = true;
2268                   }
2269                   /* M18 */ if( 0x1C <= x6 && x6 <= 0x1F )
2270                         whichToPreserve[ tmpl.M18.f1 ] = true;
2271                 }
2272                 if( x == 0x1 && m == 0x1 ) {
2273                   /* M12 */ if( (0x01 <= x6 && x6 <= 0x0F && x6 != 0x04 && x6 != 0x08 && x6 != 0x0C && x6 != 0x24) ||
2274                                                 (0x21 <= x6 && x6 <= 0x27 && x6 != 0x24) ) {
2275                         whichToPreserve[ tmpl.M12.f1 ] = true;
2276                         whichToPreserve[ tmpl.M12.f2 ] = true;
2277                   }
2278                 }
2279           } break;
2280
2281           case 0x7: {
2282                 int8_t x6 = tmpl.M_LD_ST.x6;
2283
2284                 /* M8  */ if( (0x00 <= x6 && x6 <= 0x0F) || (0x20 <= x6 && x6 <= 0x27) || x6 == 0x1B )
2285                   whichToPreserve[ tmpl.M8.f1 ] = true;
2286
2287                 /* M10 */ if( (0x30 <= x6 && x6 <= 0x32) || x6 == 0x3B )
2288                   whichToPreserve[ tmpl.M10.f2 ] = true;
2289           } break;
2290           }
2291         }
2292
2293         if( instructionIsFP ) {
2294           // /* DEBUG */ fprintf( stderr, "Instruction at mutator address 0x%lx uses an FPU.\n", iAddr.getEncodedAddress() );
2295
2296           /* Decide which fields in the instruction actually contain register numbers. */
2297           switch( GET_OPCODE( &tmpl ) ) {
2298           case 0x8:
2299           case 0x9:
2300           case 0xA:
2301           case 0xB:
2302           case 0xC:
2303           case 0xD:
2304           case 0xE:
2305                 /* F1, F2, F3 */
2306                 whichToPreserve[ tmpl.F1.f1 ] = true;
2307                 whichToPreserve[ tmpl.F1.f2 ] = true;
2308                 whichToPreserve[ tmpl.F1.f3 ] = true;
2309                 whichToPreserve[ tmpl.F1.f4 ] = true;
2310                 fpUsed = true;
2311                 break;
2312                                         
2313           case 0x4:
2314                 /* F4 */
2315                 whichToPreserve[ tmpl.F4.f2 ] = true;
2316                 whichToPreserve[ tmpl.F4.f3 ] = true;
2317                 fpUsed = true;
2318                 break;                          
2319                                         
2320           case 0x5:
2321                 /* F5 */
2322                 whichToPreserve[ tmpl.F5.f2 ] = true;
2323                 fpUsed = true;
2324                 break;
2325                                         
2326           case 0x0:
2327           case 0x1: {
2328                 /* F6, F7, F8, F9, F10, F11 */
2329                 uint64_t bitX = tmpl.F6.x;
2330                 uint64_t bitQ = tmpl.F6.q;
2331
2332                 if( bitX == 0x1 && bitQ == 0x0 ) {
2333                   /* F6 */
2334                   whichToPreserve[ tmpl.F6.f2 ] = true;
2335                   whichToPreserve[ tmpl.F6.f3 ] = true;
2336                   fpUsed = true;
2337                 }
2338                 if( bitX == 0x1 && bitQ == 0x1 ) {
2339                   /* F7 */
2340                   whichToPreserve[ tmpl.F7.f3 ] = true;
2341                   fpUsed = true;
2342                 }
2343                 if( bitX == 0x0 ) {
2344                   uint64_t x6 = tmpl.F8.x6;
2345
2346                   if( ( 0x14 <= x6 && x6 <= 0x17 ) || ( 0x30 <= x6 && x6 <= 0x37 ) ) {
2347                         /* F8 */
2348                         whichToPreserve[ tmpl.F8.f1 ] = true;
2349                         whichToPreserve[ tmpl.F8.f2 ] = true;
2350                         whichToPreserve[ tmpl.F8.f3 ] = true;
2351                         fpUsed = true;
2352                   }
2353                   if( ( 0x10 <= x6 && x6 <= 0x12 ) || ( 0x2C <= x6 && x6 <= 0x2F ) || 
2354                           ( 0x34 <= x6 && x6 <= 0x36 ) || ( 0x39 <= x6 && x6 <= 0x3D ) || x6 == 0x28 ) {
2355                         /* F9 */
2356                         whichToPreserve[ tmpl.F9.f1 ] = true;
2357                         whichToPreserve[ tmpl.F9.f2 ] = true;
2358                         whichToPreserve[ tmpl.F9.f3 ] = true;
2359                         fpUsed = true;
2360                   }
2361                   if( 0x18 <= x6 && x6 <= 0x1B ) {
2362                         /* F10 */
2363                         whichToPreserve[ tmpl.F10.f1 ] = true;
2364                         whichToPreserve[ tmpl.F10.f2 ] = true;
2365                         fpUsed = true;
2366                   }
2367                   if( 0x1C == x6 ) {
2368                         /* F11 */
2369                         whichToPreserve[ tmpl.F11.f1 ] = true;
2370                         whichToPreserve[ tmpl.F11.f2 ] = true;
2371                         fpUsed = true;
2372                   }
2373                 } /* end if bitX is 0 .*/
2374           } break;
2375
2376           default:
2377                 /* F12, F13, F14, and F15 are actually in case 0, but they don't use FP registers. */
2378                 break;
2379           } /* end opcode switch */
2380         } /* end if instructionIsFP */
2381
2382         /* For simplicity's sake, look for the register-rotating loops separately. */
2383         switch( templateID ) {
2384         case 0x10:
2385         case 0x11:
2386           /* MIB */
2387         case 0x12:
2388         case 0x13:
2389           /* MBB */
2390         case 0x16:
2391         case 0x17:
2392           /* BBB */
2393         case 0x18:
2394         case 0x19:
2395           /* MMB */
2396         case 0x1C:
2397         case 0x1D: {
2398           /* MFB */
2399           if( slotNo == 2 ) {
2400                 if( GET_OPCODE( &tmpl ) == 0x4 ) {
2401                   uint64_t btype = tmpl.B1.btype;
2402                   if( btype == 0x02 || btype == 0x03 || btype == 0x06 || btype == 0x07 ) {
2403                         // /* DEBUG */ fprintf( stderr, "Instruction at mutator address 0x%lx rotates registers.\n", iAddr.getEncodedAddress() );
2404                         registersRotated = true;
2405                   } /* end if it's the right btype */
2406                 } /* end if it's the right opcode */
2407           } /* end if it could be ctop, cexit, wtop, wexit */
2408         } break;
2409                                 
2410         default:
2411           break;
2412         } /* end templateID switch for rotating loops */
2413
2414         /* Increment the slotNo. */
2415         slotNo = (slotNo + 1) % 3;
2416   } /* end instruction iteration */
2417
2418   if( registersRotated && fpUsed ) {
2419         for( int i = 32; i < 128; i++ ) { whichToPreserve[i] = true; }
2420   } /* end if we have to preserve all the stacked registers. */
2421
2422         /* Never try to preserve fp 0, 1, 2 - 5, or 16 - 31, because we don't use
2423            them and the function we're calling will preserve them if it uses them. */
2424   whichToPreserve[ 0 ] = false;
2425   whichToPreserve[ 1 ] = false;
2426
2427   whichToPreserve[ 2 ] = false;
2428   whichToPreserve[ 3 ] = false;
2429   whichToPreserve[ 4 ] = false;
2430   whichToPreserve[ 5 ] = false;
2431
2432   whichToPreserve[ 16 ] = false;
2433   whichToPreserve[ 17 ] = false;
2434   whichToPreserve[ 18 ] = false;
2435   whichToPreserve[ 19 ] = false;
2436   whichToPreserve[ 20 ] = false;
2437   whichToPreserve[ 21 ] = false;
2438   whichToPreserve[ 22 ] = false;
2439   whichToPreserve[ 23 ] = false;
2440   whichToPreserve[ 24 ] = false;
2441   whichToPreserve[ 25 ] = false;
2442   whichToPreserve[ 26 ] = false;
2443   whichToPreserve[ 27 ] = false;
2444   whichToPreserve[ 28 ] = false;
2445   whichToPreserve[ 29 ] = false;
2446   whichToPreserve[ 30 ] = false;
2447   whichToPreserve[ 31 ] = false;
2448                                                                                                                                         
2449   functionBase->ifunc()->usedFPregs = whichToPreserve;
2450   return whichToPreserve;
2451 } /* end doFloatingPointStaticAnalysis() */ 
2452
2453 #define INVALID_CFM 0x10000000000
2454 extern void initBaseTrampStorageMap( registerSpace *, int, bool * );
2455
2456 /* Required by process.C */
2457 bool rpcMgr::emitInferiorRPCheader( codeGen &gen ) {
2458         dyn_lwp * lwpToUse = gen.lwp() != NULL ? gen.lwp() : proc_->getRepresentativeLWP();
2459         assert( lwpToUse->status() != running );
2460         
2461         /* Extract the CFM. */
2462         errno = 0;
2463         reg_tmpl reg = { getDBI()->ptrace( PTRACE_PEEKUSER, lwpToUse->get_lwp_id(), PT_CFM, 0, -1, & errno ) };
2464         if( errno != 0 || reg.raw == INVALID_CFM ) {
2465                 /* Not sure that this helps, but what else can we do? */
2466                 return false;
2467                 }
2468
2469         /* Set gen.rs() for the code generator. */
2470         int baseReg = 32 + reg.CFM.sof + NUM_PRESERVED;
2471         if( baseReg > 128 - (NUM_LOCALS + NUM_OUTPUT) ) {
2472                 baseReg = 128 - (NUM_LOCALS + NUM_OUTPUT); // Never allocate over 128 registers.
2473                 }
2474
2475         registerSpace::overwriteRegisterSpace64(baseReg, (baseReg + NUM_LOCALS + NUM_OUTPUT - 1));
2476         registerSpace *rs = registerSpace::savedRegSpace(proc());
2477
2478         // Whack the global "which registers are we", just in case there's obsolete
2479         // code looking at that instead of the registerSpace.
2480         firstDeadRegister = baseReg;
2481         lastDeadRegister = baseReg + NUM_LOCALS + NUM_OUTPUT - 1;
2482
2483
2484         initBaseTrampStorageMap( rs, reg.CFM.sof, NULL );
2485         rs->originalLocals = reg.CFM.sol;
2486         rs->originalOutputs = reg.CFM.sof - reg.CFM.sol;
2487         rs->originalRotates = reg.CFM.sor << 3;  // the SOR is stored in multiples of eight
2488
2489         /* The code generator needs to know about the register space
2490            as well, so just take advantage of the existing globals. */
2491         gen.setRegisterSpace(rs);
2492
2493         if( needToHandleSyscall( lwpToUse ) ) {
2494                 if( ! emitSyscallHeader( lwpToUse, gen ) ) { return false; }
2495                 }
2496         else {
2497                 /* We'll be adjusting the PC to the start of the preservation code,
2498                    but we can't change the slot number ([i]psr.ri), so we need to soak
2499                    up the extra slots with nops.  (Because the syscall header may require
2500                    a bundle _before_ the jump target, add two NOPs; the installation routine(s)
2501                    will compensate.) */
2502                 IA64_bundle( MIIstop, NOP_M, NOP_I, NOP_I ).generate(gen);
2503                 IA64_bundle( MIIstop, NOP_M, NOP_I, NOP_I ).generate(gen);              
2504                 }
2505
2506         /* It'll probably be faster just to spill all the FP registers,
2507            given that this code'll only be running once. */
2508         bool * whichToPreserve = NULL;
2509
2510         /* Generate the preservation header; don't bother with unwind information
2511            for an inferior RPC.  (It must be the top of the stack.) */
2512         if( ! generatePreservationHeader( gen, whichToPreserve, NULL ) ) { return false; }
2513         
2514         /* We also need to initialize the KTI register. */
2515         assert( irpcTramp );
2516         if( ! irpcTramp->generateMTCode( gen, gen.rs() ) ) { return false; }
2517         
2518         return true;
2519         } /* end emitInferiorRPCheader() */
2520
2521 /* From ia64-template.s. */
2522 extern void (* syscallSuffix)();
2523 extern void (* suffixExitPoint)();
2524 bool emitSyscallTrailer( codeGen & gen, uint64_t slotNo ) {
2525   /* Copy the template from 'syscallSuffix' to 'suffixExitPoint' (inclusive),
2526          and replace the bundle at 'suffixExitPoint' with one which has 
2527          predicated SIGILLs in the right places. */
2528
2529   /* Copy the code template. */
2530   Address syscallSuffixAddress = (Address)(& syscallSuffix );
2531   Address suffixExitPointAddress = (Address)(& suffixExitPoint );
2532         
2533   /* Trailing NOPs are replaced by the constructed SIGILLs. */
2534   Address lengthWithTrailingNOPs = ( suffixExitPointAddress + 0x10 ) - syscallSuffixAddress;
2535   gen.copy( (void *)syscallSuffixAddress, lengthWithTrailingNOPs );
2536   int predicatedBreakBundleIndex = gen.getIndex() - 1;
2537         
2538   /* Construct the predicated SIGILLs for the bundle at suffixExitPointAddress. */
2539   IA64_bundle predicatedBreakBundle;
2540   switch( slotNo ) {
2541   case 0: {
2542         /* slot 0 NOT, slot 2 IS;; p1 and p2 from assembler */
2543         instruction notInSyscallBreak( TRAP_M );
2544         instruction inSyscallBreak( TRAP_I );
2545         notInSyscallBreak = predicateInstruction( 1, notInSyscallBreak );
2546         inSyscallBreak = predicateInstruction( 2, inSyscallBreak );
2547         
2548         /* We checked if iip.ri is zero in needToHandleSyscall(), and will rewind the PC in
2549            restoreRegisters() if pcMayHaveRewound (in the saved registers), set by needToHandleSyscall() is
2550            true and we hit the break in slot 2. */
2551         predicatedBreakBundle = IA64_bundle( MMIstop, notInSyscallBreak, NOP_M, inSyscallBreak );
2552         
2553         // /* DEBUG */ fprintf( stderr, "%s[%d]: pcMayHaveRewound.\n", FILE__, __LINE__ );
2554   } break;
2555                         
2556   case 1: {
2557         /* slot 1 NOT, slot 0 IS */
2558         instruction notInSyscallBreak( TRAP_M );
2559         instruction inSyscallBreak( TRAP_M );
2560         notInSyscallBreak = predicateInstruction( 1, notInSyscallBreak );
2561         inSyscallBreak = predicateInstruction( 2, inSyscallBreak );
2562         predicatedBreakBundle = IA64_bundle( MMIstop, inSyscallBreak, notInSyscallBreak, NOP_I );
2563   } break;
2564                         
2565   case 2: {
2566         /* slot 2 NOT, slot 1 IS */
2567         instruction memoryNOP( NOP_M );
2568         instruction notInSyscallBreak( TRAP_I );
2569         instruction inSyscallBreak( TRAP_M );
2570         notInSyscallBreak = predicateInstruction( 1, notInSyscallBreak );
2571         inSyscallBreak = predicateInstruction( 2, inSyscallBreak );
2572         predicatedBreakBundle = IA64_bundle( MMIstop, memoryNOP, inSyscallBreak, notInSyscallBreak );
2573   } break;
2574                         
2575   default:
2576         assert( 0 );
2577   } /* end slotNo switch */
2578                 
2579   codeBufIndex_t index = gen.getIndex();
2580   gen.setIndex( predicatedBreakBundleIndex );
2581   predicatedBreakBundle.generate( gen );
2582   gen.setIndex( index );
2583
2584   // /* DEBUG */ fprintf( stderr, "* iRPC system call handler (suffix) generated at 0x%lx\n", (Address) bundlePtr );
2585   return true;
2586 } /* end emitSyscallTrailer() */
2587
2588 /* Required by process.C */
2589 bool rpcMgr::emitInferiorRPCtrailer( codeGen &gen,
2590                                                                          unsigned & breakOffset, bool shouldStopForResult,
2591                                                                          unsigned & stopForResultOffset,
2592                                                                          unsigned & justAfter_stopForResultOffset ) {
2593         dyn_lwp * lwpToUse = gen.lwp() != NULL ? gen.lwp() : proc_->getRepresentativeLWP();
2594         assert( lwpToUse->status() != running );
2595         
2596   /* We'll need two of these. */
2597   IA64_bundle trapBundle = generateTrapBundle();
2598
2599   /* Get a real instruction pointer. */
2600   if( shouldStopForResult ) {
2601         // * DEBUG */ fprintf( stderr, "* iRPC will stop for result.\n" );
2602         stopForResultOffset = gen.used();
2603         trapBundle.generate(gen);
2604         justAfter_stopForResultOffset = gen.used();
2605         /* Make sure that we eat the ipsr.ri with a nop. */
2606         IA64_bundle( MIIstop, NOP_M, NOP_I, NOP_I ).generate(gen);
2607   } /* end if we're interested in the result. */
2608
2609         /* Determine which of the scratch (f6 - f15, f32 - f127) floating-point
2610            registers need to be preserved.  See comment in emitInferiorRPCHeader()
2611            for why we don't actually do this. */
2612   bool * whichToPreserve = NULL;
2613
2614   /* Generate the restoration code. */
2615   
2616   generatePreservationTrailer( gen, whichToPreserve, NULL );
2617
2618   /* The SIGILL for the demon needs to happen in the instruction slot
2619          corresponding to ipsr.ri so that the mutatee resumes in the correct
2620          location after the daemon adjusts its PC. */
2621   errno = 0;
2622         reg_tmpl reg = { getDBI()->ptrace( PTRACE_PEEKUSER, lwpToUse->get_lwp_id(), PT_CR_IPSR, 0 ) };
2623   assert( ! errno );
2624   uint64_t slotNo = reg.PSR.ri;
2625   assert( slotNo <= 2 );
2626
2627   if( needToHandleSyscall( lwpToUse ) ) {
2628         if( ! emitSyscallTrailer( gen, slotNo ) ) { return false; }
2629         breakOffset = gen.used() - 16;
2630   }
2631   else {
2632         IA64_bundle slottedTrapBundle;
2633         switch( slotNo ) {
2634         case 0:
2635           slottedTrapBundle = IA64_bundle( MIIstop, TRAP_M, NOP_I, NOP_I );
2636           break;
2637         case 1:
2638           slottedTrapBundle = IA64_bundle( MIIstop, NOP_M, TRAP_I, NOP_I );
2639           break;
2640         case 2:
2641           slottedTrapBundle = IA64_bundle( MIIstop, NOP_M, NOP_I, TRAP_I );
2642           break;
2643         } /* end slotNo switch */
2644
2645         breakOffset = gen.used();
2646         slottedTrapBundle.generate(gen);
2647   } /* end if we don't need to handle a syscall */
2648
2649         /* If the demon drops the ball, make sure the mutatee suicides. */
2650   trapBundle.generate(gen);
2651   return true;
2652 } /* end emitInferiorRPCtrailer() */
2653
2654 void baseTrampInstance::updateTrampCost( unsigned cost ) {
2655   if( baseT->costSize == 0 ) {
2656         return;
2657   }
2658   assert( baseT->costSize != 0 );               
2659   assert( baseT->valueRegister != 0 );
2660   assert( baseT->addressRegister != 0 );
2661     
2662   codeGen gen( baseT->costSize );
2663         
2664   instruction_x setCost = generateLongConstantInRegister( baseT->addressRegister, cost );
2665   generateBundleFromLongInstruction( setCost ).generate( gen );
2666
2667   instruction addInstruction = generateArithmetic( plusOp, baseT->valueRegister, baseT->addressRegister, baseT->valueRegister );
2668   IA64_bundle addBundle( MIIstop, addInstruction, NOP_I, NOP_I );
2669   addBundle.generate( gen );
2670
2671   Address trampCostAddr = trampPreAddr() + baseT->costValueOffset;
2672   proc()->writeDataSpace( (void *) trampCostAddr, gen.used(), (void *) gen.start_ptr() );
2673 } /* end updateTrampCost() */
2674
2675 #define GUARD_PREDICATE_TRUE    6
2676 #define GUARD_PREDICATE_FALSE   7
2677 bool baseTramp::generateGuardPreCode(codeGen &gen,
2678                                                                          codeBufIndex_t &guardJumpIndex,
2679                                                                          registerSpace *rs) {
2680
2681   // Assumptions: No need to "allocate" registers from registerSpace.  They are
2682   //                            scratch registers which just came into existence.
2683   //
2684   //                            The branch in guardOnBundle3 must jump past 3 bundles (Offset +4).
2685   //                                    1 for the miniTramp
2686   //                                    2 for the guardOff bundles
2687
2688   assert(rs);
2689
2690   Address trampGuardBase = proc()->trampGuardBase();
2691   if (!trampGuardBase) return false;
2692
2693   int maxRegister = rs->numGPRs();
2694   trampGuardFlagAddr = rs->GPRs()[maxRegister - 1]->number;
2695   trampGuardFlagValue = rs->GPRs()[maxRegister - 2]->number;
2696         
2697   IA64_bundle guardOnBundle0( MLXstop,
2698                                                           instruction( NOP_M ),
2699                                                           generateLongConstantInRegister( trampGuardFlagAddr, trampGuardBase ));
2700
2701   IA64_bundle guardOnBundle05(  MstopMIstop,
2702                                                                 generateShiftLeftAndAdd( trampGuardFlagAddr, CALCULATE_KTI_REGISTER, 3, trampGuardFlagAddr ),
2703                                                                 instruction( NOP_M ),
2704                                                                 instruction( NOP_I ) );
2705                         
2706   IA64_bundle guardOnBundle1( MstopMIstop,
2707                                                           generateRegisterLoad( trampGuardFlagValue, trampGuardFlagAddr, 4 ),
2708                                                           generateComparison( eqOp, GUARD_PREDICATE_TRUE, trampGuardFlagValue, REGISTER_ZERO ),
2709                                                           instruction( NOP_I ));
2710
2711   IA64_bundle guardOnBundle2( MIIstop,
2712                                                           generateRegisterStore( trampGuardFlagAddr, REGISTER_ZERO, 4, GUARD_PREDICATE_FALSE ),
2713                                                           instruction( NOP_I ),
2714                                                           instruction( NOP_I ));
2715
2716   /* This displacement is fixed up in finalizeGuardBranch(). */
2717   IA64_bundle guardOnBundle3( MLXstop,
2718                                                           instruction( NOP_M ),
2719                                                           generateLongBranchTo( 0 << 4, GUARD_PREDICATE_TRUE ));
2720
2721   guardOnBundle0.generate(gen);
2722   guardOnBundle05.generate(gen);
2723   guardOnBundle1.generate(gen);
2724   guardOnBundle2.generate(gen);
2725   guardJumpIndex = gen.getIndex();
2726   guardOnBundle3.generate(gen); 
2727
2728   return true; 
2729 }
2730
2731 bool baseTramp::generateGuardPostCode(codeGen &gen, codeBufIndex_t &postIndex,
2732                                                                           registerSpace *rs) 
2733 {
2734   Address trampGuardBase = proc()->trampGuardBase();
2735   if (!trampGuardBase) return false;
2736
2737   int maxRegister = rs->numGPRs();
2738   Register trampGuardFlagAddr = rs->GPRs()[maxRegister-1]->number;
2739   Register trampGuardFlagValue = rs->GPRs()[maxRegister-2]->number;
2740
2741   IA64_bundle guardOffBundle0( MLXstop,
2742                                                            generateShortConstantInRegister( trampGuardFlagValue, 1 ),
2743                                                            generateLongConstantInRegister( trampGuardFlagAddr, proc()->trampGuardBase() ));
2744                                                                  
2745   IA64_bundle guardOffBundle05( MstopMIstop,
2746                                                                 generateShiftLeftAndAdd( trampGuardFlagAddr, CALCULATE_KTI_REGISTER, 3, trampGuardFlagAddr ),
2747                                                                 instruction( NOP_M ),
2748                                                                 instruction( NOP_I ) );
2749
2750   IA64_bundle guardOffBundle1( MMIstop,
2751                                                            generateRegisterStore( trampGuardFlagAddr, trampGuardFlagValue, 4 ),
2752                                                            instruction( NOP_M ),
2753                                                            instruction( NOP_I ));
2754
2755   guardOffBundle0.generate(gen);
2756   guardOffBundle05.generate(gen);
2757   guardOffBundle1.generate(gen);
2758   postIndex = gen.getIndex();
2759   return true;
2760 }
2761
2762 bool baseTramp::generateCostCode( codeGen & gen, unsigned & costUpdateOffset, registerSpace * rSpace ) {
2763   Address costAddr = proc()->getObservedCostAddr();
2764   if( ! costAddr ) {
2765         return false;
2766   }
2767     
2768   assert( rSpace != NULL );    
2769   addressRegister = rSpace->allocateRegister( gen, false );
2770   valueRegister = rSpace->allocateRegister( gen, false );
2771     
2772     
2773   emitVload( loadOp, costAddr, addressRegister, valueRegister, gen, false, rSpace );
2774     
2775   /* In the general case, we need a bundle to set addressRegister to the cost,
2776          and another to add it to valueRegister. */    
2777   costUpdateOffset = gen.used();
2778   IA64_bundle nopBundle( MIIstop, NOP_M, NOP_I, NOP_I );
2779   nopBundle.generate( gen );
2780   nopBundle.generate( gen );
2781     
2782   emitVstore( storeOp, valueRegister, addressRegister, costAddr, gen, false, rSpace );
2783     
2784     
2785   rSpace->freeRegister( valueRegister );
2786   rSpace->freeRegister( addressRegister );
2787     
2788   return true;
2789 } /* end generateCostCode() */
2790
2791
2792 bool baseTramp::generateMTCode( codeGen & gen, registerSpace * rs ) {
2793   pdvector< AstNodePtr > dummy;
2794
2795   dyn_thread *thr = gen.thread();
2796   if( !this->threaded() ) {
2797           /* Stick a zero in the Known Thread Index register. */
2798           emitRegisterToRegisterCopy( BP_GR0, CALCULATE_KTI_REGISTER, gen, rs );                
2799   }
2800   else if( thr ) {
2801           // For some reason we're overriding the normal index calculation
2802           unsigned index = thr->get_index();
2803           IA64_bundle setIndexBundle( MIIstop, generateShortConstantInRegister( CALCULATE_KTI_REGISTER, index ), NOP_I, NOP_I );
2804           setIndexBundle.generate( gen );
2805   }
2806   else {
2807           AstNodePtr threadPos = AstNode::funcCallNode( "DYNINSTthreadIndex", dummy );
2808           assert( threadPos != NULL );
2809           
2810           Register src = REG_NULL;
2811           if (!threadPos->generateCode(gen, 
2812                                                                    false /* no cost */, src )) return false;
2813           
2814           /* Ray: I'm asserting that we don't use the 35th preserved register for anything. */
2815           emitRegisterToRegisterCopy( src, CALCULATE_KTI_REGISTER, gen, rs );
2816   }
2817   
2818   return true;
2819 } /* end generateMTCode() */
2820
2821 void registerRemoteUnwindInformation( unw_word_t di, unw_word_t udil, pid_t pid ) {
2822   unw_dyn_info_list_t dummy_dil;
2823   unw_word_t generationOffset = ((unw_word_t)(& dummy_dil.generation)) - ((unw_word_t)(& dummy_dil));
2824   unw_word_t firstOffset = ((unw_word_t)(& dummy_dil.first)) - ((unw_word_t)(& dummy_dil));
2825   
2826   unw_dyn_info_t dummy_di;
2827   unw_word_t nextOffset = ((unw_word_t)(& dummy_di.next)) - ((unw_word_t)(& dummy_di));
2828   unw_word_t prevOffset = ((unw_word_t)(& dummy_di.prev)) - ((unw_word_t)(& dummy_di));
2829   
2830   errno = 0;
2831   
2832   /* Notionally, we should lock from here to the last POKETEXT.  However,
2833          locking in the local process will not suffice if the remote process
2834          is also using libunwind.  In that case, the right thing to do is use
2835          the remote process's lock.  Since the remote process is stopped, if
2836          the lock isn't held, we don't have to do anything; if it is, we need
2837          to single-step out of dyn_register().  However, this may do Very Strange
2838          Things to our process control model, so I'm ignoring it for now. */
2839   unw_word_t generation, first;
2840         
2841         generation = getDBI()->ptrace( PTRACE_PEEKTEXT, pid, (udil + generationOffset), (Address)NULL );
2842   assert( errno == 0 );
2843     
2844   ++generation;
2845     
2846         getDBI()->ptrace( PTRACE_POKETEXT, pid, (udil + generationOffset), generation );
2847   assert( errno == 0 );
2848     
2849     
2850         first = getDBI()->ptrace( PTRACE_PEEKTEXT, pid, (udil + firstOffset), (Address)NULL );
2851   assert( errno == 0 );
2852     
2853         getDBI()->ptrace( PTRACE_POKETEXT, pid, (di + nextOffset), first );
2854   assert( errno == 0 );
2855         getDBI()->ptrace( PTRACE_POKETEXT, pid, (di + prevOffset), (Address)NULL );
2856   assert( errno == 0 );
2857     
2858   if ( first ) {
2859                 getDBI()->ptrace( PTRACE_POKETEXT, pid, (first + prevOffset), di );
2860         assert( errno == 0 );
2861   }
2862     
2863         getDBI()->ptrace( PTRACE_POKETEXT, pid, (udil + firstOffset), di );
2864   assert( errno == 0 );  
2865 } /* end registerRemoteUnwindInformation() */
2866
2867 char * unwindOpTagToString( int8_t op ) {
2868   switch( op ) {
2869   case UNW_DYN_STOP: return "UNW_DYN_STOP";
2870   case UNW_DYN_SAVE_REG: return "UNW_DYN_SAVE_REG";
2871   case UNW_DYN_SPILL_FP_REL: return "UNW_DYN_SPILL_FP_REL";
2872   case UNW_DYN_SPILL_SP_REL: return "UNW_DYN_SPILL_SP_REL";
2873   case UNW_DYN_ADD: return "UNW_DYN_ADD";
2874   case UNW_DYN_POP_FRAMES: return "UNW_DYN_POP_FRAMES";
2875   case UNW_DYN_LABEL_STATE: return "UNW_DYN_LABEL_STATE";
2876   case UNW_DYN_COPY_STATE: return "UNW_DYN_COPY_STATE";
2877   case UNW_DYN_ALIAS: return "UNW_DYN_ALIAS";
2878                 
2879   default:
2880         return "INVALID";
2881   }
2882 } /* end unwindOpTagToString() */
2883
2884 void dumpDynamicUnwindInformation( unw_dyn_info_t * unwindInformation, AddressSpace * ) {
2885   assert( unwindInformation != NULL );
2886
2887   Address currentIP = unwindInformation->start_ip;
2888   unw_dyn_region_info_t * currentRegion = unwindInformation->u.pi.regions;
2889         
2890   dyn_unw_printf( "unwind covers: [0x%lx - 0x%lx)\n", unwindInformation->start_ip, unwindInformation->end_ip );
2891   for( uint32_t i = 0; currentRegion != NULL; currentRegion = currentRegion->next, ++i ) {
2892         Address nextIP = currentIP + ((currentRegion->insn_count / 3) * 16);
2893         assert( currentRegion->insn_count % 3 == 0 ); // 0, 1, or 2 is legal, but we only generate bundles.
2894         dyn_unw_printf( "region %d: [0x%lx - 0x%lx), %d ops", i, currentIP, nextIP, currentRegion->op_count );
2895         for( unsigned int j = 0; j < currentRegion->op_count; ++j ) {
2896           dyn_unw_printf( " %s", unwindOpTagToString( currentRegion->op[j].tag ) );
2897         }
2898         dyn_unw_printf( "\n" );
2899         if( currentRegion->op[currentRegion->op_count - 1].tag != UNW_DYN_STOP ) {
2900           fprintf( stderr, "*** format error!  last operation in region not UNW_DYN_STOP!\n" );
2901         }
2902         currentIP = nextIP;
2903   }
2904
2905                         
2906   if( currentIP != unwindInformation->end_ip ) {
2907          dyn_unw_printf("*** consistency failure!  last instruction not last IP! (0x%lx != 0x%lx)\n", currentIP, unwindInformation->end_ip );
2908   }
2909 } /* end dumpDynamicUnwindInformation() */
2910
2911 /* Copies bTDI and its pointed-to regions into the remote process, adjusting the pointers as it goes.
2912    Assumes that the region's op_count fields are accurate, and only copies over the correct amount. */
2913 bool process::insertAndRegisterDynamicUnwindInformation( unw_dyn_info_t * baseTrampDynamicInfo ) {
2914   /* This also does a simple consistency check. */
2915   dumpDynamicUnwindInformation( baseTrampDynamicInfo, this );
2916         /* DEBUG */ if( baseTrampDynamicInfo->gp == 0 && baseTrampDynamicInfo->start_ip == 0 ) { return false; }
2917         
2918   AddressSpace * proc = this;
2919
2920   /* Note: assumes no 'handler' routine(s) in baseTrampDynamicInfo->u.pi. */
2921   Address addressOfbTDI = proc->inferiorMalloc( sizeof( unw_dyn_info_t ) );
2922   assert( addressOfbTDI != (Address)NULL );
2923   // dyn_unw_printf( "%s[%d]: address of baseTrampDynamicInfo = 0x%lx\n", __FILE__, __LINE__, addressOfbTDI );
2924         
2925   /* Copying the string over every time is wasteful, but simple. */
2926   Address lengthOfName = strlen( (char *) baseTrampDynamicInfo->u.pi.name_ptr );
2927   Address addressOfName = proc->inferiorMalloc( lengthOfName + 1 );
2928   assert( addressOfName != (Address)NULL );
2929   // dyn_unw_printf( "%s[%d]: address of name = 0x%lx\n", __FILE__, __LINE__, addressOfName );
2930         
2931   assert( proc->writeDataSpace( (void *)addressOfName, lengthOfName + 1, (void *)baseTrampDynamicInfo->u.pi.name_ptr ) );
2932   baseTrampDynamicInfo->u.pi.name_ptr = addressOfName;
2933
2934   /* Allocate the first region. */
2935   unw_dyn_region_info_t * nextRegion = baseTrampDynamicInfo->u.pi.regions;
2936   Address sizeOfNextRegion = _U_dyn_region_info_size( nextRegion->op_count );
2937   Address addressOfNextRegion = proc->inferiorMalloc( sizeOfNextRegion );
2938   baseTrampDynamicInfo->u.pi.regions = (unw_dyn_region_info_t *)addressOfNextRegion;
2939   dyn_unw_printf( "%s[%d]: nextRegion = %p, sizeOfNextRegion = 0x%lx, addressOfNextRegion = 0x%lx\n", __FILE__, __LINE__, nextRegion, sizeOfNextRegion, addressOfNextRegion );
2940
2941   unw_dyn_region_info_t * currentRegion = nextRegion;   
2942   Address sizeOfCurrentRegion = sizeOfNextRegion;
2943   Address addressOfCurrentRegion = addressOfNextRegion;
2944   dyn_unw_printf( "%s[%d]: currentRegion = %p, sizeOfCurrentRegion = 0x%lx, addressOfCurrentRegion = 0x%lx\n", __FILE__, __LINE__, currentRegion, sizeOfCurrentRegion, addressOfCurrentRegion );        
2945         
2946   /* Copy baseTrampDynamicInfo itself over, now that we've updated all of its pointers. */
2947   assert( proc->writeDataSpace( (void *)addressOfbTDI, sizeof( unw_dyn_info_t ), baseTrampDynamicInfo ) );
2948         
2949   /* Iteratively allocate region (n + 1), update region n, and then copy it over. */
2950   dyn_unw_printf( "%s[%d]: beginning iterations over region list.\n", __FILE__, __LINE__ );
2951   while( currentRegion->next != NULL ) {
2952         nextRegion = currentRegion->next;
2953         sizeOfNextRegion = _U_dyn_region_info_size( nextRegion->op_count );
2954                 
2955         /* Allocate. */
2956         addressOfNextRegion = proc->inferiorMalloc( sizeOfNextRegion );
2957         assert( addressOfNextRegion != (Address)NULL );
2958                 
2959         /* Update. */
2960         currentRegion->next = (unw_dyn_region_info_t *)addressOfNextRegion;
2961                 
2962         /* Copy. */
2963         dyn_unw_printf( "%s[%d]: (at copy) nextRegion = %p, sizeOfNextRegion = 0x%lx, addressOfNextRegion = 0x%lx\n", __FILE__, __LINE__, nextRegion, sizeOfNextRegion, addressOfNextRegion );
2964         dyn_unw_printf( "%s[%d]: (at copy) currentRegion = %p, sizeOfCurrentRegion = 0x%lx, addressOfCurrentRegion = 0x%lx\n", __FILE__, __LINE__, currentRegion, sizeOfCurrentRegion, addressOfCurrentRegion );        
2965         assert( proc->writeDataSpace( (void *)addressOfCurrentRegion, sizeOfCurrentRegion, currentRegion ) );
2966
2967         /* Iterate. */
2968         currentRegion = nextRegion;
2969         sizeOfCurrentRegion = sizeOfNextRegion;
2970         addressOfCurrentRegion = addressOfNextRegion;
2971   } /* end region iteration */
2972         
2973         /* Copy the n + 1 region. */
2974   dyn_unw_printf( "%s[%d]: (at last copy) currentRegion = %p, sizeOfCurrentRegion = 0x%lx, addressOfCurrentRegion = 0x%lx\n", __FILE__, __LINE__, currentRegion, sizeOfCurrentRegion, addressOfCurrentRegion ); 
2975   assert( proc->writeDataSpace( (void *)addressOfCurrentRegion, sizeOfCurrentRegion, currentRegion ) );
2976         
2977   /* We need the address of the _U_dyn_info_list in the remote process in order
2978          to register the baseTrampDynamicInfo. */
2979   Symbol dyn_info_list;
2980   if (!proc->proc()->getSymbolInfo( "_U_dyn_info_list", dyn_info_list))
2981           return ! proc->proc()->isBootstrappedYet();
2982   
2983   Address addressOfuDIL = dyn_info_list.getAddr();
2984         
2985   /* Register baseTrampDynamicInfo in remote process. */
2986   dyn_unw_printf( "%s[%d]: registering remote address range [0x%lx - 0x%lx) with gp = 0x%lx with uDIL at 0x%lx\n", __FILE__, __LINE__, baseTrampDynamicInfo->start_ip, baseTrampDynamicInfo->end_ip, baseTrampDynamicInfo->gp, addressOfuDIL );
2987   registerRemoteUnwindInformation( addressOfbTDI, addressOfuDIL, proc->proc()->getPid() );
2988   return true;
2989 } /* end insertAndRegisterDynamicUnwindInformation() */
2990
2991 /* Required by ast.C */
2992 void emitFuncJump(opCode op, codeGen &gen, const int_function *callee,
2993                                   AddressSpace *proc, const instPoint *location, bool) {
2994
2995   assert(op == funcJumpOp);
2996   IA64_bundle bundle;
2997
2998   // Remove basetramp's frame on memory stack.
2999   /* FIXME: we should make use of the unwind_region information here, but this 
3000          is the only minitramp which alters the frame. */
3001   generatePreservationTrailer( gen, location->func()->getUsedFPregs(), NULL );
3002
3003   int outputRegisters = 8;
3004   int extraOuts = outputRegisters % 3;
3005   int offset = gen.rs()->GPRs()[0]->number + 5;
3006   
3007   // Generate a new register frame with an output size equal to the
3008   // original local size.
3009   // NOTE:      What we really want is the post-call, pre-alloc local size.
3010   //                    Unfortunatly, that is difficult to get, so we'll use the
3011   //                    post-call, post-alloc local instead.  While that may be
3012   //                    larger than is strictly necessary, it should still work
3013   //                    correctly.
3014   bundle = IA64_bundle( MII,
3015                                                 generateAllocInstructionFor( gen.rs(), 5, outputRegisters, 0 ),
3016                                                 (extraOuts >= 1 ? generateRegisterToRegisterMove( 32, offset )
3017                                                  : instruction( NOP_I )),
3018                                                 (extraOuts >= 2 ? generateRegisterToRegisterMove( 33, offset + 1 )
3019                                                  : instruction( NOP_I )));
3020   bundle.generate(gen);
3021
3022   // Move local regs into output area.
3023   for (int i = extraOuts; i < outputRegisters; i += 3) {
3024         bundle = IA64_bundle( MII,
3025                                                   generateRegisterToRegisterMove( 32 + (i+0), offset + (i+0) ),
3026                                                   generateRegisterToRegisterMove( 32 + (i+1), offset + (i+1) ),
3027                                                   generateRegisterToRegisterMove( 32 + (i+2), offset + (i+2) ));
3028         bundle.generate(gen);
3029   }
3030
3031   // Save system state into local registers.  AR.PFS saved earlier by alloc.
3032   bundle = IA64_bundle( MII,
3033                                                 generateRegisterToRegisterMove( REGISTER_GP, offset - 4 ),
3034                                                 generateBranchToRegisterMove( BRANCH_RETURN, offset - 3 ),
3035                                                 generateBranchToRegisterMove( BRANCH_SCRATCH, offset - 2 ));
3036   bundle.generate(gen);
3037
3038   // Ready the callee address.
3039   Address callee_addr = callee->getAddress();
3040   bundle = IA64_bundle( MLXstop,
3041                                                 instruction( NOP_M ),
3042                                                 generateLongConstantInRegister( offset - 1, callee_addr ));
3043   bundle.generate(gen);
3044
3045   // Install GP for callee.
3046   bundle = IA64_bundle( MLX,
3047                                                 instruction( NOP_M ),
3048                                                 generateLongConstantInRegister( REGISTER_GP, proc->proc()->getTOCoffsetInfo( callee_addr )));
3049   bundle.generate(gen);
3050
3051   // Copy the callee address and jump.
3052   bundle = IA64_bundle( MIBstop,
3053                                                 instruction( NOP_M ),
3054                                                 generateRegisterToBranchMove( offset - 1, BRANCH_SCRATCH ),
3055                                                 generateIndirectCallTo( BRANCH_SCRATCH, BRANCH_RETURN ));
3056   bundle.generate(gen);
3057
3058   // Restore system state.
3059   bundle = IA64_bundle( MII,
3060                                                 generateRegisterToRegisterMove( offset - 4, REGISTER_GP ),
3061                                                 generateRegisterToBranchMove( offset - 3, BRANCH_RETURN ),
3062                                                 generateRegisterToApplicationMove( 32 + gen.rs()->originalLocals + gen.rs()->originalOutputs, AR_PFS ));
3063   bundle.generate(gen);
3064
3065   bundle = IA64_bundle( MII,
3066                                                 (extraOuts >= 1 ? generateRegisterToRegisterMove( offset, 32 )
3067                                                  : instruction( NOP_I )),
3068                                                 (extraOuts >= 2 ? generateRegisterToRegisterMove( offset + 1, 33 )
3069                                                  : instruction( NOP_I )),
3070                                                 generateRegisterToBranchMove( offset - 2, BRANCH_SCRATCH ));
3071   bundle.generate(gen);
3072
3073   // Move output regs back into local area.
3074   for (int i = extraOuts; i < outputRegisters; i += 3) {
3075         bundle = IA64_bundle( MII,
3076                                                   generateRegisterToRegisterMove( offset + (i+0), 32 + (i+0) ),
3077                                                   generateRegisterToRegisterMove( offset + (i+1), 32 + (i+1) ),
3078                                                   generateRegisterToRegisterMove( offset + (i+2), 32 + (i+2) ));
3079         bundle.generate(gen);
3080   }
3081
3082   // Restore original register frame.
3083   bundle = IA64_bundle( MstopMIstop,
3084                                                 instruction( NOP_M ),
3085                                                 generateOriginalAllocFor( gen.rs() ),
3086                                                 instruction( NOP_M ));
3087   bundle.generate(gen);
3088
3089   // Ignore rest of tramp, and return directly to original caller.
3090   bundle = IA64_bundle( MMBstop,
3091                                                 instruction( NOP_M ),
3092                                                 instruction( NOP_M ),
3093                                                 generateReturnTo( BRANCH_RETURN ));
3094   bundle.generate(gen);
3095 }
3096
3097
3098 /* Required by ast.C */
3099 Register emitR( opCode op, Register src1, Register /*src2*/, Register dest,
3100                                 codeGen &gen,  bool /*noCost*/,
3101                                 const instPoint *location, bool /*for_multithreaded*/) {
3102   /* FIXME: handle noCost */
3103   switch( op ) {
3104   case getParamOp: {
3105         /* src1 is the (incoming) parameter we want. */
3106         if( src1 >= 8 ) {
3107           /* emitR is only called from within generateTramp, which sets the global
3108                  variable gen.rs() to the correct value.  Use it with reckless abandon.
3109
3110                  Also, REGISTER_SP will always be stored in a register, so we are free
3111                  to use regSpage->storageMap directly (as opposed to going through
3112                  emitLoadPreviousStackFrameRegister).
3113           */
3114           int spReg = gen.rs()->storageMap[ BP_GR0 + REGISTER_SP ];
3115           int memStackOffset = (src1 - 8 + 2) * 8;
3116
3117           IA64_bundle bundle = IA64_bundle( MstopMIstop,
3118                                                                                 generateShortImmediateAdd(dest, memStackOffset, spReg),
3119                                                                                 generateRegisterLoad(dest, dest),
3120                                                                                 instruction(NOP_M) );
3121           bundle.generate(gen);
3122           return dest;
3123
3124         } else {
3125           /* Due to register renaming, the requested parameter location depends
3126                  on the instPoint. */
3127
3128           int regStackOffset = 0;
3129           if (location->getPointType() == callSite)
3130                 regStackOffset = gen.rs()->originalLocals;
3131
3132           emitRegisterToRegisterCopy( 32 + regStackOffset + src1, dest, gen, NULL );
3133           return dest;
3134         } /* end if it's a parameter in a register. */
3135   } break;
3136                 
3137   case getRetValOp: {
3138         /* WARNING: According to the Itanium Software Conventions
3139            Guide, the return value can use multiple registers (r8-11).
3140            However, since Dyninst can't handle anything larger than
3141            64 bits (for now), we'll just return r8.
3142
3143            This should be valid for the general case. */
3144                            
3145           //Register retVal = (Register)8;
3146           assert(gen.rs()->storageMap[REGISTER_RV] > 0);
3147           Register retVal = gen.rs()->storageMap[REGISTER_RV];
3148         emitRegisterToRegisterCopy(retVal, dest, gen, NULL);
3149         return dest;
3150   } break;
3151
3152   default:
3153         assert( 0 );
3154         break;
3155   } /* end switch */
3156 } /* end emitR() */
3157
3158 /* Required by BPatch_init.C */
3159 void initDefaultPointFrequencyTable() {
3160   /* On other platforms, this loads data into a table that's only used
3161          in the function getPointFrequency, which is never called, so we'll do nothing. */
3162 } /* end initDefaultPointFrequencyTable() */
3163
3164 #define DEFAULT_MAGIC_FREQUENCY 100.0
3165 float getPointFrequency( instPoint * point ) {
3166   int_function * func = point->findCallee();
3167         
3168   if( !func ) { func = point->func(); }
3169         
3170 #if defined( USE_DEFAULT_FREQUENCY_TABLE )
3171   if( ! funcFrequencyTable.defines( func->prettyName() ) ) { return DEFAULT_MAGIC_FREQUENCY; }
3172   else{ return (float) funcFrequencyTable[ func->prettyName() ]; }
3173 #else
3174   return DEFAULT_MAGIC_FREQUENCY;
3175 #endif /* defined( USE_DEFAULT_FREQUENCY_TABLE ) */
3176 } /* end getPointFrequency() */
3177
3178 /* Required by inst.C, ast.C */
3179 codeBufIndex_t emitA( opCode op, Register src1, Register /*src2*/, Register dest,
3180                                           codeGen &gen,  bool /*noCost*/ ) {  // FIXME: cost?
3181   /* Emit the given opcode, returning its relative offset.  For
3182          multi-bundle opcodes, return the offset of the branch itself;
3183          the code generator will insert the fall-through case directly
3184          after this address. */
3185         
3186   codeBufIndex_t retval;
3187
3188   switch( op ) {
3189   case trampTrailer: {
3190         retval = gen.getIndex();
3191         IA64_bundle( MIIstop, NOP_M, NOP_I, NOP_I ).generate(gen);
3192         break; }
3193
3194   case ifOp: {
3195         /* Branch by offset dest if src1 is zero. */
3196                         
3197         /* See note in eqOp case of emitV() about predicate registers */
3198         instruction compareInsn = generateComparison( eqOp, src1 % 64, src1, REGISTER_ZERO );
3199         instruction_x branchInsn = predicateLongInstruction( src1 % 64, generateLongBranchTo( dest ) );
3200         IA64_bundle compareBundle( MIIstop, compareInsn, NOP_I, NOP_I );
3201         instruction memoryNOP( NOP_M );
3202         IA64_bundle branchBundle( MLXstop, memoryNOP, branchInsn );
3203         compareBundle.generate(gen);
3204         retval = gen.getIndex();
3205         branchBundle.generate(gen);
3206         break; }
3207                         
3208   case branchOp: {