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