Merge branch 'jistone/coverity'
[dyninst.git] / dyninstAPI / src / emit-x86.C
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 /*
32  * emit-x86.C - x86 & AMD64 code generators
33  * $Id: emit-x86.C,v 1.64 2008/09/11 20:14:14 mlam Exp $
34  */
35
36 #include <assert.h>
37 #include <stdio.h>
38 #include "common/src/Types.h"
39 #include "dyninstAPI/src/codegen.h"
40 #include "dyninstAPI/src/function.h"
41 #include "dyninstAPI/src/emit-x86.h"
42 #include "dyninstAPI/src/inst-x86.h"
43 #include "dyninstAPI/src/debug.h"
44 #include "dyninstAPI/src/ast.h"
45 #include "dyninstAPI/h/BPatch.h"
46 #include "dyninstAPI/h/BPatch_memoryAccess_NP.h"
47 #include "dyninstAPI/src/registerSpace.h"
48
49 #include "dyninstAPI/src/dynProcess.h"
50
51 #include "dyninstAPI/src/binaryEdit.h"
52 #include "dyninstAPI/src/image.h"
53 // get_index...
54 #include "dyninstAPI/src/dynThread.h"
55 #include "ABI.h"
56 #include "liveness.h"
57 #include "RegisterConversion.h"
58
59 const int EmitterIA32::mt_offset = -4;
60 #if defined(arch_x86_64)
61 const int EmitterAMD64::mt_offset = -8;
62 #endif
63
64 static void emitXMMRegsSaveRestore(codeGen& gen, bool isRestore)
65 {
66    GET_PTR(insn, gen);
67    for(int reg = 0; reg <= 7; ++reg)
68    {
69      registerSlot* r = (*gen.rs())[(REGNUM_XMM0 + reg)];
70      if( r && r->liveState == registerSlot::dead) 
71      {
72        continue;
73      }
74      unsigned char offset = reg * 16;
75      *insn++ = 0x66; *insn++ = 0x0f; 
76      // 6f to save, 7f to restore
77      if(isRestore) 
78      {
79        *insn++ = 0x6f;
80      }
81      else
82      {
83        *insn++ = 0x7f;
84      }
85      
86      if (reg == 0) {
87        *insn++ = 0x00;
88      }
89      else {
90        unsigned char modrm = 0x40 + (0x8 * reg);
91        *insn++ = modrm;
92        *insn++ = offset;
93      }
94    }
95    SET_PTR(insn, gen);
96 }
97
98
99 bool EmitterIA32::emitMoveRegToReg(Register src, Register dest, codeGen &gen) {
100    RealRegister src_r = gen.rs()->loadVirtual(src, gen);
101    RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
102    emitMovRegToReg(dest_r, src_r, gen);
103    return true;
104 }
105
106 codeBufIndex_t EmitterIA32::emitIf(Register expr_reg, Register target, RegControl rc, codeGen &gen)
107 {
108    RealRegister r = gen.rs()->loadVirtual(expr_reg, gen);
109    emitOpRegReg(TEST_EV_GV, r, r, gen);
110    
111    // Retval: where the jump is in this sequence
112    codeBufIndex_t retval = gen.getIndex();
113    
114    // Jump displacements are from the end of the insn, not start. The
115    // one we're emitting has a size of 6.
116    int disp = 0;
117    if (target)
118       disp = target - 6;
119    
120    if (rc == rc_before_jump)
121       gen.rs()->pushNewRegState();
122    GET_PTR(insn, gen);
123    // je dest
124    *insn++ = 0x0F;
125    *insn++ = 0x84;
126    *((int *)insn) = disp;
127    if (disp == 0) {
128      SET_PTR(insn, gen);
129      gen.addPatch(gen.getIndex(), NULL, sizeof(int), relocPatch::pcrel, 
130                   gen.used() + sizeof(int));
131      REGET_PTR(insn, gen);
132    }
133    insn += sizeof(int);
134    SET_PTR(insn, gen);
135    
136    return retval;
137 }
138
139 void EmitterIA32::emitOp(unsigned opcode, Register dest, Register src1, Register src2, codeGen &gen)
140 {
141    RealRegister src1_r = gen.rs()->loadVirtual(src1, gen);
142    RealRegister src2_r = gen.rs()->loadVirtual(src2, gen);
143    RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
144    emitMovRegToReg(dest_r, src1_r, gen);
145    emitOpRegReg(opcode, dest_r, src2_r, gen);
146 }
147
148 void EmitterIA32::emitRelOp(unsigned op, Register dest, Register src1, Register src2, codeGen &gen)
149 {
150    RealRegister src1_r = gen.rs()->loadVirtual(src1, gen);
151    RealRegister src2_r = gen.rs()->loadVirtual(src2, gen);
152    RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);   
153    Register scratch = gen.rs()->allocateRegister(gen, true);
154    RealRegister scratch_r = gen.rs()->loadVirtualForWrite(scratch, gen);
155
156    emitOpRegReg(XOR_R32_RM32, dest_r, dest_r, gen); //XOR dest,dest
157    emitMovImmToReg(scratch_r, 0x1, gen);            //MOV $1,scratch
158    emitOpRegReg(CMP_GV_EV, src1_r, src2_r, gen);    //CMP src1, src2
159    
160    unsigned char opcode = cmovOpcodeFromRelOp(op); 
161    GET_PTR(insn, gen);
162    *insn++ = 0x0f;
163    SET_PTR(insn, gen);
164    emitOpRegReg(opcode, dest_r, scratch_r, gen);               //CMOVcc scratch,dest
165    gen.rs()->freeRegister(scratch);
166 }
167
168 void EmitterIA32::emitDiv(Register dest, Register src1, Register src2, codeGen &gen)
169 {
170    Register scratch = gen.rs()->allocateRegister(gen, true);
171    gen.rs()->loadVirtualToSpecific(src1, RealRegister(REGNUM_EAX), gen);
172    gen.rs()->makeRegisterAvail(RealRegister(REGNUM_EDX), gen);
173    gen.rs()->noteVirtualInReal(scratch, RealRegister(REGNUM_EDX));
174    RealRegister src2_r = gen.rs()->loadVirtual(src2, gen);                          
175    gen.rs()->makeRegisterAvail(RealRegister(REGNUM_EAX), gen);
176    emitSimpleInsn(0x99, gen);            //cdq (src1 -> eax:edx)
177    emitOpExtReg(0xF7, 0x7, src2_r, gen); //idiv eax:edx,src2 -> eax
178    gen.rs()->noteVirtualInReal(dest, RealRegister(REGNUM_EAX));
179    gen.rs()->freeRegister(scratch);
180 }
181
182 void EmitterIA32::emitOpImm(unsigned opcode1, unsigned opcode2, Register dest, Register src1, 
183                             RegValue src2imm, codeGen &gen)
184 {
185    RealRegister src1_r = gen.rs()->loadVirtual(src1, gen);
186    RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
187    if (src1 != dest) {
188       emitMovRegToReg(dest_r, src1_r, gen);
189    }
190    emitOpExtRegImm(opcode1, (char) opcode2, dest_r, src2imm, gen);
191 }
192
193 void EmitterIA32::emitRelOpImm(unsigned op, Register dest, Register src1, RegValue src2imm, codeGen &gen)
194 {
195
196    Register src2 = gen.rs()->allocateRegister(gen, true);
197    emitLoadConst(src2, src2imm, gen);
198    emitRelOp(op, dest, src1, src2, gen);
199    gen.rs()->freeRegister(src2);
200 }
201
202 // where is this defined?
203 extern bool isPowerOf2(int value, int &result);
204
205 void EmitterIA32::emitTimesImm(Register dest, Register src1, RegValue src2imm, codeGen &gen)
206 {
207    int result;
208    
209    RealRegister src1_r = gen.rs()->loadVirtual(src1, gen);
210    RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
211
212    if (src2imm == 1) {
213       emitMovRegToReg(dest_r, src1_r, gen);
214       return;
215    }
216
217
218    if (isPowerOf2(src2imm, result) && result <= MAX_IMM8) {
219       // sal dest, result
220       if (src1 != dest)
221          emitMovRegToReg(dest_r, src1_r, gen);
222       emitOpExtRegImm8(0xC1, 4, dest_r, static_cast<char>(result), gen);
223    }
224    else {
225       // imul src1 * src2imm -> dest_r
226       emitOpRegRegImm(0x69, dest_r, src1_r, src2imm, gen);
227    } 
228 }
229
230 void EmitterIA32::emitDivImm(Register dest, Register src1, RegValue src2imm, codeGen &gen)
231 {
232    int result;
233    if (src2imm == 1)
234       return;
235
236    if (isPowerOf2(src2imm, result) && result <= MAX_IMM8) {
237       // sar dest, result
238       RealRegister src1_r = gen.rs()->loadVirtual(src1, gen);
239       RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
240
241       if (src1 != dest)
242          emitMovRegToReg(src1_r, dest_r, gen);
243       emitOpExtRegImm8(0xC1, 4, dest_r, static_cast<unsigned char>(result), gen);
244    }
245    else {
246       Register src2 = gen.rs()->allocateRegister(gen, true);
247       emitLoadConst(src2, src2imm, gen);
248       emitDiv(dest, src1, src2, gen);
249       gen.rs()->freeRegister(src2);
250    }
251 }
252
253 void EmitterIA32::emitLoad(Register dest, Address addr, int size, codeGen &gen)
254 {
255    RealRegister r = gen.rs()->loadVirtualForWrite(dest, gen);
256    if (size == 1) {
257       emitMovMBToReg(r, addr, gen);               // movsbl eax, addr
258    } else if (size == 2) {
259       emitMovMWToReg(r, addr, gen);               // movswl eax, addr
260    } else {
261       emitMovMToReg(r, addr, gen);               // mov eax, addr
262    }
263 }
264
265 void EmitterIA32::emitLoadConst(Register dest, Address imm, codeGen &gen)
266 {
267    RealRegister r = gen.rs()->loadVirtualForWrite(dest, gen);
268    emitMovImmToReg(r, imm, gen);
269 }
270
271 void EmitterIA32::emitLoadIndir(Register dest, Register addr_reg, int /*size*/, codeGen &gen)
272 {
273    RealRegister dest_r(-1);
274    RealRegister src_r = gen.rs()->loadVirtual(addr_reg, gen);
275    if (dest != addr_reg)
276       dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
277    else
278       dest_r = src_r;
279    emitMovRMToReg(dest_r, src_r, 0, gen);
280 }
281
282 void EmitterIA32::emitLoadOrigFrameRelative(Register dest, Address offset, codeGen &gen)
283 {
284    if (gen.bt()->createdFrame) {
285       Register scratch = gen.rs()->allocateRegister(gen, true);
286       RealRegister scratch_r = gen.rs()->loadVirtualForWrite(scratch, gen);
287       RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
288       emitMovRMToReg(scratch_r, RealRegister(REGNUM_EBP), 0, gen);
289       emitMovRMToReg(dest_r, scratch_r, offset, gen);
290       gen.rs()->freeRegister(scratch);
291       return;
292    }
293
294    RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
295    emitMovRMToReg(dest_r, RealRegister(REGNUM_EBP), offset, gen);
296 }
297
298 bool EmitterIA32::emitLoadRelative(Register /*dest*/, Address /*offset*/, Register /*base*/, int /*size*/,
299                                    codeGen &/*gen*/)
300 {
301     assert(0);
302     return false;
303 }
304
305 void EmitterIA32::emitStoreRelative(Register /*src*/, Address /*offset*/, 
306                                     Register /*base*/, int /*size*/, codeGen &/*gen*/)
307 {
308     assert(0);
309     return;
310 }
311
312 void EmitterIA32::emitLoadOrigRegRelative(Register dest, Address offset,
313                                           Register base, codeGen &gen,
314                                           bool store)
315 {
316
317    RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
318    restoreGPRtoGPR(RealRegister(base), dest_r, gen);
319    // either load the address or the contents at that address
320    if(store) 
321    {
322       // dest = [reg](offset)
323       emitMovRMToReg(dest_r, dest_r, offset, gen);
324    }
325    else //calc address
326    {
327       //add offset,eax
328       emitAddRegImm32(dest_r, offset, gen);
329    }
330
331
332 void EmitterIA32::emitLoadFrameAddr(Register dest, Address offset, codeGen &gen)
333 {
334    RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
335    restoreGPRtoReg(RealRegister(REGNUM_EBP), gen, &dest_r);
336    emitAddRegImm32(dest_r, offset, gen);
337 }
338
339
340
341 void EmitterIA32::emitLoadOrigRegister(Address register_num, Register dest, codeGen &gen)
342 {
343    RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
344    restoreGPRtoGPR(RealRegister(register_num), dest_r, gen);
345
346 }
347
348 void EmitterIA32::emitStoreOrigRegister(Address register_num, Register src, codeGen &gen) {
349
350    assert(0); //MATT TODO
351    //Previous stack frame register is stored on the stack,
352     //it was stored there at the begining of the base tramp.
353     
354     //Calculate the register's offset from the frame pointer in REGNUM_EBP
355     unsigned offset = SAVED_EAX_OFFSET - (register_num * 4);
356
357     emitMovRMToReg(RealRegister(REGNUM_EAX), RealRegister(REGNUM_EBP), -1*(src*4), gen);
358     gen.markRegDefined(REGNUM_EAX);
359     emitMovRegToRM(RealRegister(REGNUM_EBP), offset, RealRegister(REGNUM_EAX), gen);
360 }
361
362 void EmitterIA32::emitStore(Address addr, Register src, int size, codeGen &gen)
363 {
364    RealRegister r = gen.rs()->loadVirtual(src, gen);
365    if (size == 1) {
366       emitMovRegToMB(addr, r, gen);
367    } else if (size == 2) {
368       emitMovRegToMW(addr, r, gen);
369    } else {
370       emitMovRegToM(addr, r, gen);
371    }
372 }
373
374 void EmitterIA32::emitStoreIndir(Register addr_reg, Register src, int /*size*/, codeGen &gen)
375 {
376    RealRegister src_r = gen.rs()->loadVirtual(src, gen);
377    RealRegister addr_r = gen.rs()->loadVirtual(addr_reg, gen);
378    emitMovRegToRM(addr_r, 0, src_r, gen);
379 }
380
381 void EmitterIA32::emitStoreFrameRelative(Address offset, Register src, Register scratch, int /*size*/, codeGen &gen)
382 {
383    if (gen.bt()->createdFrame) 
384    {
385       RealRegister src_r = gen.rs()->loadVirtual(src, gen);
386       RealRegister scratch_r = gen.rs()->loadVirtual(scratch, gen);
387       emitMovRMToReg(scratch_r, RealRegister(REGNUM_EBP), 0, gen);
388       emitMovRegToRM(scratch_r, offset, src_r, gen);
389       return;
390    }
391    RealRegister src_r = gen.rs()->loadVirtual(src, gen);
392    emitMovRegToRM(RealRegister(REGNUM_EBP), offset, src_r, gen);
393 }
394
395 void EmitterIA32::emitGetRetVal(Register dest, bool addr_of, codeGen &gen)
396 {
397    RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
398    if (!addr_of) {
399       restoreGPRtoGPR(RealRegister(REGNUM_EAX), dest_r, gen);
400       return;
401    }
402   
403    //EAX isn't really defined here, but this will make the code generator
404    //put it onto the stack and thus guarentee that we'll have an
405    //address to access it at.
406    gen.markRegDefined(REGNUM_EAX);
407    stackItemLocation loc = getHeightOf(stackItem::framebase, gen);
408
409    pdvector<registerSlot *> &regs = gen.rs()->trampRegs();
410    registerSlot *eax = NULL;
411    for (unsigned i=0; i<regs.size(); i++) {
412       if (regs[i]->encoding() == REGNUM_EAX) {
413          eax = regs[i];
414          break;
415       }
416    }
417    assert(eax);
418
419    loc.offset += (eax->saveOffset * 4);
420    emitLEA(loc.reg, RealRegister(Null_Register), 0, loc.offset, dest_r, gen);
421 }
422
423 void EmitterIA32::emitGetRetAddr(Register dest, codeGen &gen)
424 {
425    // Parameters are addressed by a positive offset from ebp,
426    // the first is PARAM_OFFSET[ebp]
427    stackItemLocation loc = getHeightOf(stackItem::stacktop, gen);
428    RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
429    if (!gen.bt() || gen.bt()->alignedStack) {
430        // Load the original %esp value into dest_r
431        emitMovRMToReg(dest_r, loc.reg, loc.offset, gen);
432        loc.offset = 0;
433        loc.reg = dest_r;
434    }
435    emitMovRMToReg(dest_r, loc.reg, loc.offset, gen);
436 }
437
438 void EmitterIA32::emitGetParam(Register dest, Register param_num,
439                                instPoint::Type pt_type, opCode op, 
440                                bool addr_of, codeGen &gen)
441 {
442    // Parameters are addressed by a positive offset from ebp,
443    // the first is PARAM_OFFSET[ebp]
444    stackItemLocation loc = getHeightOf(stackItem::stacktop, gen);
445    RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
446    if (!gen.bt() || gen.bt()->alignedStack) {
447        // Load the original %esp value into dest_r
448        emitMovRMToReg(dest_r, loc.reg, loc.offset, gen);
449        loc.offset = 0;
450        loc.reg = dest_r;
451    }
452    
453    switch (op) {
454        case getParamOp: 
455            // guess whether we're at the call or the function entry point,
456            // in which case we need to skip the return value
457           if (pt_type == instPoint::FuncEntry) {
458              loc.offset += 4;
459           }
460           break;
461        case getParamAtCallOp:
462            break;
463        case getParamAtEntryOp:
464            loc.offset += 4;
465            break;
466        default:
467            assert(0);
468            break;
469    }
470
471    loc.offset += param_num*4;
472
473    // Prepare a real destination register.
474
475    if (!addr_of)
476       emitMovRMToReg(dest_r, loc.reg, loc.offset, gen);
477    else
478       emitLEA(loc.reg, RealRegister(Null_Register),
479               0, loc.offset, dest_r, gen);
480 }
481
482 // Moves stack pointer by offset and aligns it to IA32_STACK_ALIGNMENT
483 // with the following sequence:
484 //
485 //     lea    -off(%esp) => %esp           # move %esp down
486 //     mov    %eax => saveSlot1(%esp)      # save %eax onto stack
487 //     lahf                                # save %eflags byte into %ah
488 //     seto   %al                          # save overflow flag into %al
489 //     mov    %eax => saveSlot2(%esp)      # save flags %eax onto stack
490 //     lea    off(%esp) => %eax            # store original %esp in %eax
491 //     and    -$IA32_STACK_ALIGNMENT,%esp  # align %esp
492 //     mov    %eax => (%esp)               # store original %esp on stack
493 //     mov    -off+saveSlot2(%eax) => %eax # restore flags %eax from stack
494 //     add    $0x7f,%al                    # restore overflow flag from %al
495 //     sahf                                # restore %eflags byte from %ah
496 //     mov    (%esp) => %eax               # re-load old %esp into %eax to ...
497 //     mov    -off+saveSlot1(%eax) => %eax # ... restore %eax from stack
498 //
499 // This sequence has three important properties:
500 //     1) It never *directly* writes to memory below %esp.  It always begins
501 //        by moving %esp down, then writing to locations above it.  This way,
502 //        if the kernel decides to interrupt, it won't stomp all over our
503 //        values before we get a chance to use them.
504 //     2) It is designed to support easy de-allocation of this space by
505 //        ending with %esp pointing to where we stored the original %esp.
506 //     3) Care has been taken to properly restore both %eax and %eflags
507 //        by using "lea" instead of "add" or "sub," and saving the necessary
508 //        flags around the "and" instruction.
509 //
510 // Saving of the flags register can be skipped if the register is not live.
511
512 void EmitterIA32::emitStackAlign(int offset, codeGen &gen)
513 {
514     int off = offset + 4 + IA32_STACK_ALIGNMENT;
515     int saveSlot1 =    0 + IA32_STACK_ALIGNMENT;
516     int saveSlot2 =    4 + IA32_STACK_ALIGNMENT;
517     RealRegister esp = RealRegister(REGNUM_ESP);
518     RealRegister eax = RealRegister(REGNUM_EAX);
519     RealRegister enull = RealRegister(Null_Register);
520
521     bool saveFlags = false;
522     if (gen.rs()->checkVolatileRegisters(gen, registerSlot::live)) {
523         saveFlags = true;   // We need to save the flags register
524         off += 4;           // Allocate stack space to store the flags
525     }
526
527     emitLEA(esp, enull, 0, -off, esp, gen);
528     emitMovRegToRM(esp, saveSlot1, eax, gen);
529     if (saveFlags) {
530         emitSimpleInsn(0x9f, gen);
531         emitSaveO(gen);
532         emitMovRegToRM(esp, saveSlot2, eax, gen);
533     }
534     emitLEA(esp, enull, 0, off, eax, gen);
535     emitOpExtRegImm8(0x83, EXTENDED_0x83_AND, esp, -IA32_STACK_ALIGNMENT, gen);
536     emitMovRegToRM(esp, 0, eax, gen);
537     if (saveFlags) {
538         emitMovRMToReg(eax, eax, -off + saveSlot2, gen);
539         emitRestoreO(gen);
540         emitSimpleInsn(0x9e, gen);
541         emitMovRMToReg(eax, esp, 0, gen);
542     }
543     emitMovRMToReg(eax, eax, -off + saveSlot1, gen);
544 }
545
546 static int extra_space_check;
547 bool EmitterIA32::emitBTSaves(baseTramp* bt, codeGen &gen)
548 {
549     // x86 linux platforms do not allow for writing to memory
550     // below the stack pointer.  No need to skip a "red zone."
551
552    gen.setInInstrumentation(true);
553
554
555     int instFrameSize = 0; // Tracks how much we are moving %rsp
556     int funcJumpSlotSize = 0;
557     if (bt) {
558         funcJumpSlotSize = bt->funcJumpSlotSize() * 4;
559     }
560
561     // Align the stack now to avoid having a padding hole in the middle of
562     // our instrumentation stack.  Referring to anything on the stack above
563     // this point will require an indirect reference.
564     //
565     // There are two cases that require a 16-byte aligned stack pointer:
566     //
567     //    - Any time we need to save the FP registers
568     //    - Any time we may execute SSE/SSE2 instructions
569     //
570     // The second case is only possible if we generate a function call
571     // so search the ASTs for function call generation.
572     //
573     bool useFPRs =  BPatch::bpatch->isForceSaveFPROn() ||
574                   ( BPatch::bpatch->isSaveFPROn()      &&
575                     gen.rs()->anyLiveFPRsAtEntry()     &&
576                     bt->saveFPRs() &&
577                     bt->makesCall() );
578     bool alignStack = useFPRs || !bt || bt->checkForFuncCalls();
579
580     if (alignStack) {
581         emitStackAlign(funcJumpSlotSize, gen);
582
583     } else if (funcJumpSlotSize > 0) {
584         // Just move %esp to make room for the funcJump.
585         // Use LEA to avoid flag modification.
586         emitLEA(RealRegister(REGNUM_ESP), RealRegister(Null_Register), 0,
587                 -funcJumpSlotSize, RealRegister(REGNUM_ESP), gen);
588         instFrameSize += funcJumpSlotSize;
589     }
590
591
592     bool flags_saved = gen.rs()->saveVolatileRegisters(gen);
593     // makesCall was added because our code spills registers around function
594     // calls, and needs somewhere for those spills to go
595     bool createFrame = !bt || bt->needsFrame() || useFPRs || bt->makesCall();
596     bool saveOrigAddr = createFrame && bt->instP();
597     bool localSpace = createFrame || useFPRs || 
598        (bt && bt->validOptimizationInfo() && bt->spilledRegisters);
599
600     if (bt) {
601        bt->savedFPRs = useFPRs;
602        bt->createdFrame = createFrame;
603        bt->savedOrigAddr = saveOrigAddr;
604        bt->createdLocalSpace = localSpace;
605        bt->alignedStack = alignStack;
606        bt->savedFlags = flags_saved;
607     }
608
609     int flags_saved_i = flags_saved ? 1 : 0;
610     int base_i = (saveOrigAddr ? 1 : 0) + (createFrame ? 1 : 0);
611
612     int num_saved = 0;
613     int numRegsUsed = bt ? bt->numDefinedRegs() : -1;
614     if (numRegsUsed == -1 || 
615         numRegsUsed > X86_REGS_SAVE_LIMIT)
616     {
617        emitSimpleInsn(PUSHAD, gen);
618        gen.rs()->incStack(8 * 4);
619        num_saved = 8;
620
621        gen.rs()->markSavedRegister(RealRegister(REGNUM_EAX), 7 + flags_saved_i + base_i);
622        if(flags_saved)
623        {
624            gen.rs()->markSavedRegister(IA32_FLAG_VIRTUAL_REGISTER, 7 + base_i);
625        }
626        gen.rs()->markSavedRegister(RealRegister(REGNUM_ECX), 6 + base_i);
627        gen.rs()->markSavedRegister(RealRegister(REGNUM_EDX), 5 + base_i);
628        gen.rs()->markSavedRegister(RealRegister(REGNUM_EBX), 4 + base_i);
629        gen.rs()->markSavedRegister(RealRegister(REGNUM_ESP), 3 + base_i);
630        if (!createFrame)
631           gen.rs()->markSavedRegister(RealRegister(REGNUM_EBP), 2 + base_i);
632        gen.rs()->markSavedRegister(RealRegister(REGNUM_ESI), 1 + base_i);
633        gen.rs()->markSavedRegister(RealRegister(REGNUM_EDI), 0 + base_i);
634     }
635     else
636     {
637        pdvector<registerSlot *> &regs = gen.rs()->trampRegs();
638        for (unsigned i=0; i<regs.size(); i++) {
639           registerSlot *reg = regs[i];
640           if (bt->definedRegs[reg->encoding()]) {
641              ::emitPush(RealRegister(reg->encoding()), gen);
642              int eax_flags = (reg->encoding() == REGNUM_EAX) ? flags_saved_i : 0;
643              gen.rs()->markSavedRegister(RealRegister(reg->encoding()),
644                                          numRegsUsed - num_saved +
645                                          base_i - 1 + eax_flags);
646              if(eax_flags)
647              {
648                  gen.rs()->markSavedRegister(IA32_FLAG_VIRTUAL_REGISTER,
649                     numRegsUsed - num_saved + base_i - 1);
650              }
651              num_saved++;
652           }
653        }
654        assert(num_saved == numRegsUsed);
655     }
656
657     if (saveOrigAddr) {
658        emitPushImm(bt->instP()->addr_compat(), gen);
659     }
660     if (createFrame)
661     {
662        // For now, we'll do all saves then do the guard. Could inline
663        // Return addr for stack frame walking; for lack of a better idea,
664        // we grab the original instPoint address
665        emitSimpleInsn(PUSH_EBP, gen);
666        gen.rs()->incStack(4);
667        emitMovRegToReg(RealRegister(REGNUM_EBP), RealRegister(REGNUM_ESP), gen);
668        gen.rs()->markSavedRegister(RealRegister(REGNUM_EBP), 0);
669     }
670
671     // Not sure liveness touches this yet, so not using
672     //bool liveFPRs = (gen.rs()->FPRs()[0]->liveState == registerSlot:live);
673
674     // Prepare our stack bookkeeping data structures.
675     instFrameSize += (flags_saved_i + num_saved + base_i) * 4;
676     if (bt) {
677        bt->stackHeight = instFrameSize;
678     }
679     gen.rs()->setInstFrameSize(instFrameSize);
680     gen.rs()->setStackHeight(0);
681
682     // Pre-calculate space for temporaries and floating-point state.
683     int extra_space = 0;
684     if (useFPRs) {
685         if (gen.rs()->hasXMM) {
686             extra_space += TRAMP_FRAME_SIZE + 512;
687         } else {
688             extra_space += TRAMP_FRAME_SIZE + FSAVE_STATE_SIZE;
689         }
690
691     } else if (localSpace) {
692         extra_space += TRAMP_FRAME_SIZE;
693     }
694
695     // Make sure that we're still aligned when we add extra_space to the stack.
696     if (alignStack) {
697         if ((instFrameSize + extra_space) % IA32_STACK_ALIGNMENT)
698             extra_space += IA32_STACK_ALIGNMENT -
699                 ((instFrameSize + extra_space) % IA32_STACK_ALIGNMENT);
700     }
701
702     if (extra_space) {
703         emitLEA(RealRegister(REGNUM_ESP), RealRegister(Null_Register), 0,
704                 -extra_space, RealRegister(REGNUM_ESP), gen);
705         gen.rs()->incStack(extra_space);
706     }
707     extra_space_check = extra_space;
708
709     if (useFPRs) {
710         if (gen.rs()->hasXMM) {
711            // need to save the floating point state (x87, MMX, SSE)
712            // We're guaranteed to be 16-byte aligned now, so just
713            // emit the fxsave.
714
715            // fxsave (%esp) ; 0x0f 0xae 0x04 0x24
716            GET_PTR(insn, gen);
717            *insn++ = 0x0f;
718            *insn++ = 0xae;
719            *insn++ = 0x04;
720            *insn++ = 0x24;
721            SET_PTR(insn, gen);
722         }
723         else {
724            emitOpRegRM(FSAVE, RealRegister(FSAVE_OP),
725                        RealRegister(REGNUM_ESP), 0, gen);
726         }
727     }
728
729     return true;
730 }
731
732 bool EmitterIA32::emitBTRestores(baseTramp* bt,codeGen &gen)
733 {
734     bool useFPRs;
735     bool createFrame;
736     bool saveOrigAddr;
737     bool alignStack;
738     if (bt) {
739        useFPRs = bt->savedFPRs;
740        createFrame = bt->createdFrame;
741        saveOrigAddr = bt->savedOrigAddr;
742        alignStack = bt->alignedStack;
743     }
744     else {
745        useFPRs =  BPatch::bpatch->isForceSaveFPROn() ||
746                 ( BPatch::bpatch->isSaveFPROn()      &&
747                   gen.rs()->anyLiveFPRsAtEntry()     &&
748                   bt->saveFPRs()               &&
749                   !bt->makesCall() );
750        createFrame = true;
751        saveOrigAddr = bt->instP();
752        alignStack = true;
753     }
754
755     if (useFPRs) {
756         if (gen.rs()->hasXMM) {
757             // restore saved FP state
758             // fxrstor (%rsp) ; 0x0f 0xae 0x04 0x24
759             GET_PTR(insn, gen);
760             *insn++ = 0x0f;
761             *insn++ = 0xae;
762             *insn++ = 0x0c;
763             *insn++ = 0x24;
764             SET_PTR(insn, gen);
765
766         } else
767            emitOpRegRM(FRSTOR, RealRegister(FRSTOR_OP),
768                        RealRegister(REGNUM_ESP), 0, gen);
769     }
770
771     // Remove extra space allocated for temporaries and floating-point state
772     int extra_space = gen.rs()->getStackHeight();
773     assert(extra_space == extra_space_check);
774     if (!createFrame && extra_space) {
775         emitLEA(RealRegister(REGNUM_ESP), RealRegister(Null_Register), 0,
776                 extra_space, RealRegister(REGNUM_ESP), gen);
777     }
778
779     if (createFrame) {
780        emitSimpleInsn(LEAVE, gen);
781     }
782     if (saveOrigAddr) {
783         emitLEA(RealRegister(REGNUM_ESP), RealRegister(Null_Register), 0, 4,
784                 RealRegister(REGNUM_ESP), gen);
785     }
786
787     //popa or pop each register, plus optional popf
788     emitBTRegRestores32(bt, gen);
789
790     // Restore the (possibly unaligned) stack pointer.
791     if (alignStack) {
792         emitMovRMToReg(RealRegister(REGNUM_ESP),
793                        RealRegister(REGNUM_ESP), 0, gen);
794     } else {
795        int funcJumpSlotSize = 0;
796        if (bt && bt->funcJumpSlotSize()) {
797           funcJumpSlotSize = bt->funcJumpSlotSize() * 4;
798        }
799        if (funcJumpSlotSize) {
800           emitLEA(RealRegister(REGNUM_ESP),
801                   RealRegister(Null_Register), 0, funcJumpSlotSize,
802                   RealRegister(REGNUM_ESP), gen);
803        }
804     }
805
806    gen.setInInstrumentation(false);
807     return true;
808 }
809
810 //
811 // 64-bit code generation helper functions
812 //
813
814 static void emitRex(bool is_64, Register* r, Register* x, Register* b, codeGen &gen)
815 {
816     unsigned char rex = 0x40;
817
818     // need rex for 64-bit ops in most cases
819     if (is_64)
820        rex |= 0x08;
821
822     // need rex for use of new registers
823     // if a new register is used, we mask off the high bit before
824     // returning since we account for it in the rex prefix
825     
826     // "R" register - extension to ModRM reg field
827     if (r && *r & 0x08) {
828        rex |= 0x04;
829        *r &= 0x07;
830     }
831     
832     // "X" register - extension to SIB index field
833     if (x && *x & 0x08) {
834        rex |= 0x02;
835        *x &= 0x07;
836     }
837
838     // "B" register - extension to ModRM r/m field, SIB base field,
839     // or opcode reg field
840     if (b && *b & 0x08) {
841        rex |= 0x01;
842        *b &= 0x07;
843     }
844     
845     // emit the rex, if needed
846     // (note that some other weird cases not covered here
847     //  need a "blank" rex, like using %sil or %dil)
848     if (rex & 0x0f)
849        emitSimpleInsn(rex, gen);
850 }
851
852 #if 0
853 /* build the MOD/RM byte of an instruction */
854 static unsigned char makeModRMbyte(unsigned Mod, unsigned Reg, unsigned RM)
855 {
856    return static_cast<unsigned char>(((Mod & 0x3) << 6) + ((Reg & 0x7) << 3) + (RM & 0x7));
857 }
858 #endif
859
860 void EmitterIA32::emitStoreImm(Address addr, int imm, codeGen &gen, bool /*noCost*/) 
861 {
862    emitMovImmToMem(addr, imm, gen);
863 }
864
865 void emitAddMem(Address addr, int imm, codeGen &gen) {
866    //This add needs to encode "special" due to an exception
867    // to the normal encoding rules and issues caused by AMD64's
868    // pc-relative data addressing mode.  Our helper functions will
869    // not correctly emit what we want, and we want this very specific
870    // mode for the add instruction.  So I'm just writing raw bytes.
871
872    GET_PTR(insn, gen);
873    if (imm < 128 && imm > -127) {
874       if (gen.rs()->getAddressWidth() == 8)
875          *insn++ = 0x48; // REX byte for a quad-add
876       *insn++ = 0x83;
877       *insn++ = 0x04;
878       *insn++ = 0x25;
879
880       *((int *)insn) = addr; //Write address
881       insn += sizeof(int);
882
883       *insn++ = (char) imm;
884       SET_PTR(insn, gen);
885       return;
886    }
887
888    if (imm == 1) {
889       if (gen.rs()->getAddressWidth() == 4)
890       {
891          *insn++ = 0xFF; //incl 
892          *insn++ = 0x05;
893       }
894       else {
895          assert(gen.rs()->getAddressWidth() == 8);
896          *insn++ = 0xFF; //inlc with SIB
897          *insn++ = 0x04;
898          *insn++ = 0x25;
899       }
900    }
901    else {
902       *insn++ = 0x81; //addl
903       *insn++ = 0x4;
904       *insn++ = 0x25;
905    }
906
907    *((int *)insn) = addr; //Write address
908    insn += sizeof(int);
909
910    if (imm != 1) {
911       *((int*)insn) = imm; //Write immediate value to add
912       insn += sizeof(int);
913    }
914
915    SET_PTR(insn, gen);
916 }
917
918 void EmitterIA32::emitAddSignedImm(Address addr, int imm, codeGen &gen,
919                                  bool /*noCost*/)
920 {
921    emitAddMem(addr, imm, gen);
922 }
923
924
925 void emitMovImmToReg64(Register dest, long imm, bool is_64, codeGen &gen)
926 {
927    Register tmp_dest = dest;
928    gen.markRegDefined(dest);
929    emitRex(is_64, NULL, NULL, &tmp_dest, gen);
930    if (is_64) {
931       GET_PTR(insn, gen);
932       *insn++ = static_cast<unsigned char>(0xB8 + tmp_dest);
933       *((long *)insn) = imm;
934       insn += sizeof(long);
935       SET_PTR(insn, gen);
936    }
937    else
938       emitMovImmToReg(RealRegister(tmp_dest), imm, gen);
939 }
940
941 // on 64-bit x86_64 targets, the DWARF register number does not
942 // correspond to the machine encoding. See the AMD-64 ABI.
943
944 // We can only safely map the general purpose registers (0-7 on ia-32,
945 // 0-15 on amd-64)
946 #define IA32_MAX_MAP 7
947 #define AMD64_MAX_MAP 15
948 static int const amd64_register_map[] =
949
950     0,  // RAX
951     2,  // RDX
952     1,  // RCX
953     3,  // RBX
954     6,  // RSI
955     7,  // RDI
956     5,  // RBP
957     4,  // RSP
958     8, 9, 10, 11, 12, 13, 14, 15    // gp 8 - 15
959     
960     /* This is incomplete. The x86_64 ABI specifies a mapping from
961        dwarf numbers (0-66) to ("architecture number"). Without a
962        corresponding mapping for the SVR4 dwarf-machine encoding for
963        IA-32, however, it is not meaningful to provide this mapping. */
964 };
965
966 int Register_DWARFtoMachineEnc32(int n)
967 {
968     if(n > IA32_MAX_MAP) {
969                 assert(0);
970         }
971     
972     return n;
973 }
974
975 #if defined(arch_x86_64)
976
977 bool isImm64bit(Address imm) {
978    return (imm >> 32);
979 }
980
981 void emitMovRegToReg64(Register dest, Register src, bool is_64, codeGen &gen)
982 {
983     if (dest == src) return;
984
985     Register tmp_dest = dest;
986     Register tmp_src = src;
987     emitRex(is_64, &tmp_dest, NULL, &tmp_src, gen);
988     emitMovRegToReg(RealRegister(tmp_dest), RealRegister(tmp_src), gen);
989     gen.markRegDefined(dest);
990 }
991
992 void emitMovPCRMToReg64(Register dest, int offset, int size, codeGen &gen, bool deref_result)
993 {
994    GET_PTR(insn, gen);
995    if (size == 8)
996       *insn++ = static_cast<unsigned char>((dest & 0x8)>>1 | 0x48);    // REX prefix
997    else {
998       *insn++ = static_cast<unsigned char>((dest & 0x8)>>1 | 0x40);    // REX prefix
999    }
1000    if (deref_result)
1001       *insn++ = 0x8B;                                                  // MOV instruction
1002    else
1003       *insn++ = 0x8D;                                                  // LEA instruction
1004    *insn++ = static_cast<unsigned char>(((dest & 0x7) << 3) | 0x5); // ModRM byte
1005    *((int *)insn) = offset-7;                                       // offset
1006    insn += sizeof(int);
1007    gen.markRegDefined(dest);
1008    SET_PTR(insn, gen);
1009 }
1010
1011 void emitLEA64(Register base, Register index, unsigned int scale, int disp,
1012                Register dest, bool is_64, codeGen &gen)
1013 {
1014     Register tmp_base = base;
1015     Register tmp_index = index;
1016     Register tmp_dest = dest;
1017     emitRex(is_64, &tmp_dest,
1018             tmp_index == Null_Register ? NULL : &tmp_index,
1019             tmp_base == Null_Register ? NULL : &tmp_base,
1020             gen);
1021     emitLEA(RealRegister(tmp_base), RealRegister(tmp_index), scale, disp, 
1022             RealRegister(tmp_dest), gen);
1023     gen.markRegDefined(dest);
1024 }
1025
1026 static void emitMovRMToReg64(Register dest, Register base, int disp, int size, codeGen &gen)
1027 {
1028     Register tmp_dest = dest;
1029     Register tmp_base = base;
1030
1031     gen.markRegDefined(dest);
1032     if (size == 1 || size == 2)
1033     {
1034        emitRex(true, &tmp_dest, NULL, &tmp_base, gen);
1035        GET_PTR(insn, gen);
1036        *insn++ = 0x0f;
1037        if (size == 1)
1038           *insn++ = 0xb6;
1039        else if (size == 2)
1040           *insn++ = 0xb7;
1041        SET_PTR(insn, gen);
1042        emitAddressingMode(tmp_base, 0, tmp_dest, gen);
1043     }
1044     if (size == 4 || size == 8)
1045     {
1046        emitRex((size == 8), &tmp_dest, NULL, &tmp_base, gen);
1047        emitMovRMToReg(RealRegister(tmp_dest), RealRegister(tmp_base), disp, gen);
1048     }
1049 }
1050
1051 static void emitMovRegToRM64(Register base, int disp, Register src, int size, codeGen &gen)
1052 {
1053     Register tmp_base = base;
1054     Register tmp_src = src;
1055     Register rax = REGNUM_RAX;
1056     if (size == 1 || size == 2) {
1057        //mov src, rax
1058        //mov a[l/x], (dest)
1059        gen.markRegDefined(REGNUM_RAX);
1060        if (tmp_src != REGNUM_RAX) {
1061           emitRex(true, &tmp_src, NULL, &rax, gen);
1062           emitMovRegToReg(RealRegister(rax), RealRegister(tmp_src), gen);
1063        }
1064
1065        emitRex(false, NULL, NULL, &tmp_base, gen);
1066        GET_PTR(insn, gen);       
1067        if (size == 1) 
1068           *insn++ = 0x88;
1069        else if (size == 2)
1070           *insn++ = 0x89;
1071        SET_PTR(insn, gen);
1072        emitAddressingMode(tmp_base, 0, REGNUM_RAX, gen);
1073     }
1074
1075     if (size == 4 || size == 8)
1076     {
1077       emitRex((size == 8), &tmp_src, NULL, &tmp_base, gen);
1078       emitMovRegToRM(RealRegister(tmp_base), disp, RealRegister(tmp_src), gen);
1079     }
1080 }
1081
1082 static void emitOpRegReg64(unsigned opcode, Register dest, Register src, bool is_64, codeGen &gen)
1083 {
1084     Register tmp_dest = dest;
1085     Register tmp_src = src;
1086     emitRex(is_64, &tmp_dest, NULL, &tmp_src, gen);
1087     emitOpRegReg(opcode, RealRegister(tmp_dest), RealRegister(tmp_src), gen);
1088     gen.markRegDefined(dest);
1089 }
1090
1091 static void emitOpRegRM64(unsigned opcode, Register dest, Register base, int disp, bool is_64, codeGen &gen)
1092 {
1093     Register tmp_dest = dest;
1094     Register tmp_base = base;
1095     emitRex(is_64, &tmp_dest, NULL, &tmp_base, gen);
1096     emitOpRegRM(opcode, RealRegister(tmp_dest), RealRegister(tmp_base), disp, gen);
1097     gen.markRegDefined(dest);
1098 }
1099
1100 void emitOpRegImm64(unsigned opcode, unsigned opcode_ext, Register rm_reg, int imm,
1101                            bool is_64, codeGen &gen)
1102 {
1103     Register tmp_rm_reg = rm_reg;
1104     emitRex(is_64, NULL, NULL, &tmp_rm_reg, gen);
1105
1106     GET_PTR(insn, gen);
1107     *insn++ = opcode;
1108     *insn++ = 0xC0 | ((opcode_ext & 0x7) << 3) | tmp_rm_reg;
1109     *((int *)insn) = imm;
1110     insn+= sizeof(int);
1111     SET_PTR(insn, gen);
1112     gen.markRegDefined(rm_reg);
1113 }
1114
1115 // operation on memory location specified with a base register
1116 // (does not work for RSP, RBP, R12, R13)
1117 static void emitOpMemImm64(unsigned opcode, unsigned opcode_ext, Register base,
1118                           int imm, bool is_64, codeGen &gen)
1119 {
1120     Register tmp_base = base;
1121     emitRex(is_64, NULL, NULL, &tmp_base, gen);
1122
1123     GET_PTR(insn, gen);
1124     *insn++ = opcode;
1125     *insn++ = ((opcode_ext & 0x7) << 3) | tmp_base;
1126     *((int *)insn) = imm;
1127     insn+= sizeof(int);
1128     SET_PTR(insn, gen);
1129 }
1130
1131 static void emitOpRegRegImm64(unsigned opcode, Register dest, Register src1, int imm,
1132                               bool is_64, codeGen &gen)
1133 {
1134     emitOpRegReg64(opcode, dest, src1, is_64, gen);
1135     GET_PTR(insn, gen);
1136     *((int *)insn) = imm;
1137     insn+= sizeof(int);
1138     SET_PTR(insn, gen);
1139     gen.markRegDefined(dest);
1140 }
1141
1142 static void emitOpRegImm8_64(unsigned opcode, unsigned opcode_ext, Register dest,
1143                              char imm, bool is_64, codeGen &gen)
1144 {
1145     Register tmp_dest = dest;
1146     emitRex(is_64, NULL, NULL, &tmp_dest, gen);
1147     GET_PTR(insn, gen);
1148     *insn++ = opcode;
1149     *insn++ = 0xC0 | ((opcode_ext & 0x7) << 3) | tmp_dest;
1150     *insn++ = imm;
1151     SET_PTR(insn, gen);
1152     gen.markRegDefined(dest);
1153 }
1154
1155 void emitPushReg64(Register src, codeGen &gen)
1156 {
1157     emitRex(false, NULL, NULL, &src, gen);
1158     emitSimpleInsn(0x50 + src, gen);
1159     if (gen.rs()) gen.rs()->incStack(8);
1160 }
1161
1162 void emitPopReg64(Register dest, codeGen &gen)
1163 {
1164     emitRex(false, NULL, NULL, &dest, gen);    
1165     emitSimpleInsn(0x58 + dest, gen);
1166     if (gen.rs()) gen.rs()->incStack(-8);
1167 }
1168
1169 void emitMovImmToRM64(Register base, int disp, int imm, bool is_64, 
1170                       codeGen &gen) 
1171 {
1172    GET_PTR(insn, gen);
1173    if (base == Null_Register) {
1174       *insn++ = 0xC7;
1175       *insn++ = 0x84;
1176       *insn++ = 0x25;
1177       *((int*)insn) = disp;
1178       insn += sizeof(int);
1179    }
1180    else {
1181       emitRex(is_64, &base, NULL, NULL, gen);
1182       *insn++ = 0xC7;
1183       SET_PTR(insn, gen);
1184       emitAddressingMode(base, disp, 0, gen);
1185       REGET_PTR(insn, gen);
1186    }
1187    *((int*)insn) = imm;
1188    insn += sizeof(int);
1189    SET_PTR(insn, gen);
1190 }
1191
1192 void emitAddRM64(Register dest, int imm, bool is_64, codeGen &gen)
1193 {
1194    if (imm == 1) {
1195       emitRex(is_64, &dest, NULL, NULL, gen);
1196       GET_PTR(insn, gen);
1197       *insn++ = 0xFF;
1198       *insn++ = dest & 0x7; 
1199       SET_PTR(insn, gen);   
1200       return;
1201    }
1202    emitRex(is_64, &dest, NULL, NULL, gen);
1203    emitOpMemImm64(0x81, 0x0, dest, imm, true, gen);
1204    gen.markRegDefined(dest);
1205    //   *((int*)insn) = imm;
1206    //insn += sizeof(int);
1207 }
1208
1209
1210 bool EmitterAMD64::emitMoveRegToReg(Register src, Register dest, codeGen &gen) {
1211     emitMovRegToReg64(dest, src, true, gen);
1212     gen.markRegDefined(dest);
1213     return true;
1214 }
1215
1216 bool EmitterAMD64::emitMoveRegToReg(registerSlot *source, registerSlot *dest, codeGen &gen) {
1217     // TODO: make this work for getting the flag register too.
1218
1219     return emitMoveRegToReg(source->encoding(), dest->encoding(), gen);
1220 }
1221
1222 codeBufIndex_t EmitterAMD64::emitIf(Register expr_reg, Register target, RegControl, codeGen &gen)
1223 {
1224     // test %expr, %expr
1225     emitOpRegReg64(0x85, expr_reg, expr_reg, true, gen);
1226
1227     // Retval: where the jump is in this sequence
1228     codeBufIndex_t retval = gen.getIndex();
1229
1230     // Jump displacements are from the end of the insn, not start. The
1231     // one we're emitting has a size of 6.
1232     int disp = target - 6;
1233
1234     // je target
1235     GET_PTR(insn, gen);
1236     *insn++ = 0x0F;
1237     *insn++ = 0x84;
1238     *((int *)insn) = disp;
1239     insn += sizeof(int);
1240     SET_PTR(insn, gen);
1241
1242     return retval;
1243 }
1244
1245 void EmitterAMD64::emitOp(unsigned opcode, Register dest, Register src1, Register src2, codeGen &gen)
1246 {
1247     // TODO: optimize this further for ops where order doesn't matter
1248     if (src1 != dest)
1249        emitMovRegToReg64(dest, src1, true, gen);
1250     emitOpRegReg64(opcode, dest, src2, true, gen);
1251     gen.markRegDefined(dest);
1252 }
1253
1254 void EmitterAMD64::emitOpImm(unsigned opcode1, unsigned opcode2, Register dest, Register src1, RegValue src2imm,
1255                           codeGen &gen)
1256 {
1257    if (src1 != dest) {
1258       emitMovRegToReg64(dest, src1, true, gen);
1259    }
1260    emitOpRegImm64(opcode1, opcode2, dest, src2imm, true, gen);
1261    gen.markRegDefined(dest);
1262 }
1263
1264 void EmitterAMD64::emitRelOp(unsigned op, Register dest, Register src1, Register src2, codeGen &gen)
1265 {
1266     // cmp %src2, %src1
1267     emitOpRegReg64(0x39, src2, src1, true, gen);
1268
1269     // mov $0, $dest ; done now in case src1 == dest or src2 == dest
1270     // (we can do this since mov doesn't mess w/ flags)
1271     emitMovImmToReg64(dest, 0, false, gen);
1272     gen.markRegDefined(dest);
1273
1274     // jcc by two or three, depdending on size of mov
1275     unsigned char jcc_opcode = jccOpcodeFromRelOp(op);
1276     GET_PTR(insn, gen);
1277     *insn++ = jcc_opcode;
1278     SET_PTR(insn, gen);
1279
1280     codeBufIndex_t jcc_disp = gen.used();
1281     gen.fill(1, codeGen::cgNOP);
1282     codeBufIndex_t after_jcc = gen.used();
1283     // mov $1,  %dest
1284
1285     emitMovImmToReg64(dest, 1, false, gen);
1286     codeBufIndex_t after_mov = gen.used();
1287
1288     gen.setIndex(jcc_disp);
1289     REGET_PTR(insn, gen);
1290     *insn = (char) codeGen::getDisplacement(after_jcc, after_mov);
1291     SET_PTR(insn, gen);
1292
1293     gen.setIndex(after_mov);
1294 }
1295
1296 void EmitterAMD64::emitRelOpImm(unsigned op, Register dest, Register src1, RegValue src2imm,
1297                                 codeGen &gen)
1298 {
1299 /* disabling hack
1300    // HACKITY - remove before doing anything else
1301    // 
1302    // If the input is a character, then mask off the value in the register so that we're
1303    // only comparing the low bytes. 
1304    if (src2imm < 0xff) {
1305       // Use a 32-bit mask instead of an 8-bit since it sign-extends...
1306       emitOpRegImm64(0x81, EXTENDED_0x81_AND, src1, 0xff, true, gen); 
1307   }
1308 */
1309
1310    // cmp $src2imm, %src1
1311    emitOpRegImm64(0x81, 7, src1, src2imm, true, gen);
1312
1313    // mov $0, $dest ; done now in case src1 == dest
1314    // (we can do this since mov doesn't mess w/ flags)
1315    emitMovImmToReg64(dest, 0, false, gen);
1316    gen.markRegDefined(dest);
1317
1318    // jcc by two or three, depdending on size of mov
1319    unsigned char opcode = jccOpcodeFromRelOp(op);
1320    GET_PTR(insn, gen);
1321    *insn++ = opcode;
1322    SET_PTR(insn, gen);
1323    codeBufIndex_t jcc_disp = gen.used();
1324    gen.fill(1, codeGen::cgNOP);
1325    codeBufIndex_t after_jcc = gen.used();
1326
1327    // mov $1,  %dest
1328    emitMovImmToReg64(dest, 1, false, gen);
1329    codeBufIndex_t after_mov = gen.used();
1330
1331    gen.setIndex(jcc_disp);
1332    REGET_PTR(insn, gen);
1333    *insn = (char) codeGen::getDisplacement(after_jcc, after_mov);
1334
1335    SET_PTR(insn, gen);
1336    gen.setIndex(after_mov);
1337 }
1338
1339 void EmitterAMD64::emitDiv(Register dest, Register src1, Register src2, codeGen &gen)
1340 {
1341    // TODO: fix so that we don't always use RAX
1342
1343    // push RDX if it's in use, since we will need it
1344    bool save_rdx = false;
1345    if (!gen.rs()->isFreeRegister(REGNUM_RDX) && (dest != REGNUM_RDX)) {
1346       save_rdx = true;
1347       emitPushReg64(REGNUM_RDX, gen);
1348    }
1349    else {
1350       gen.markRegDefined(REGNUM_RDX);
1351    }
1352    
1353    // If src2 is RDX we need to move it into a scratch register, as the sign extend
1354    // will overwrite RDX.
1355    // Note that this does not imply RDX is not free; both inputs are free if they
1356    // are not used after this call.
1357    Register scratchReg = src2;
1358    if (scratchReg == REGNUM_RDX) {
1359       pdvector<Register> dontUse;
1360       dontUse.push_back(REGNUM_RAX);
1361       dontUse.push_back(src2);
1362       dontUse.push_back(dest);
1363       dontUse.push_back(src1);
1364       scratchReg = gen.rs()->getScratchRegister(gen, dontUse);
1365       emitMovRegToReg64(scratchReg, src2, true, gen);
1366    }
1367    gen.markRegDefined(scratchReg);
1368    
1369    // mov %src1, %rax
1370    emitMovRegToReg64(REGNUM_RAX, src1, true, gen);
1371    gen.markRegDefined(REGNUM_RAX);
1372    
1373    // cqo (sign extend RAX into RDX)
1374    emitSimpleInsn(0x48, gen); // REX.W
1375    emitSimpleInsn(0x99, gen);
1376    
1377    // idiv %src2
1378    emitOpRegReg64(0xF7, 0x7, scratchReg, true, gen);
1379    
1380    // mov %rax, %dest
1381    emitMovRegToReg64(dest, REGNUM_RAX, true, gen);
1382    gen.markRegDefined(dest);
1383    
1384    // pop rdx if it needed to be saved
1385    if (save_rdx)
1386       emitPopReg64(REGNUM_RDX, gen);
1387 }
1388
1389 void EmitterAMD64::emitTimesImm(Register dest, Register src1, RegValue src2imm, codeGen &gen)
1390 {
1391    int result = -1;
1392
1393    gen.markRegDefined(dest);
1394    if (isPowerOf2(src2imm, result) && result <= MAX_IMM8) {
1395       // immediate is a power of two - use a shift
1396       // mov %src1, %dest (if needed)
1397       if (src1 != dest) {
1398          emitMovRegToReg64(dest, src1, true, gen);
1399       }
1400       // sal dest, result
1401       emitOpRegImm8_64(0xC1, 4, dest, result, true, gen);
1402    }
1403    else {
1404       // imul %dest, %src1, $src2imm
1405       emitOpRegRegImm64(0x69, dest, src1, src2imm, true, gen);
1406    } 
1407 }
1408
1409 void EmitterAMD64::emitDivImm(Register dest, Register src1, RegValue src2imm, codeGen &gen)
1410 {
1411    int result = -1;
1412    gen.markRegDefined(dest);
1413    if (isPowerOf2(src2imm, result) && result <= MAX_IMM8) {
1414       // divisor is a power of two - use a shift instruction
1415       // mov %src1, %dest (if needed)
1416       if (src1 != dest) {
1417          emitMovRegToReg64(dest, src1, true, gen);
1418       }
1419       
1420       // sar $result, %dest
1421       emitOpRegImm8_64(0xC1, 7, dest, result, true, gen);
1422    }
1423    else {
1424       
1425       // push RDX if it's in use, since we will need it
1426       bool save_rdx = false;
1427       if (!gen.rs()->isFreeRegister(REGNUM_RDX) && (dest != REGNUM_RDX)) {
1428          save_rdx = true;
1429          emitPushReg64(REGNUM_RDX, gen);
1430       }
1431       else {
1432          gen.markRegDefined(REGNUM_RDX);
1433       }
1434
1435       // need to put dividend in RDX:RAX
1436       // mov %src1, %rax
1437       // cqo
1438       emitMovRegToReg64(REGNUM_EAX, src1, true, gen);
1439       gen.markRegDefined(REGNUM_RAX);
1440       emitSimpleInsn(0x48, gen); // REX.W
1441       emitSimpleInsn(0x99, gen);
1442       
1443       // push immediate operand on the stack (no IDIV $imm)
1444       emitPushImm(src2imm, gen);
1445       
1446       // idiv (%rsp)
1447       emitOpRegRM64(0xF7, 0x7 /* opcode extension */, REGNUM_RSP, 0, true, gen);
1448       
1449       // mov %rax, %dest ; set the result
1450       emitMovRegToReg64(dest, REGNUM_RAX, true, gen);
1451       
1452       // pop the immediate off the stack
1453       // add $8, %rsp
1454       emitOpRegImm8_64(0x83, 0x0, REGNUM_RSP, 8, true, gen);
1455       gen.rs()->incStack(-8);
1456       
1457       // pop rdx if it needed to be saved
1458       if (save_rdx)
1459          emitPopReg64(REGNUM_RDX, gen);
1460    }
1461 }
1462
1463 void EmitterAMD64::emitLoad(Register dest, Address addr, int size, codeGen &gen)
1464 {
1465
1466    Register scratch = gen.rs()->getScratchRegister(gen);
1467    
1468    // mov $addr, %rax
1469    emitMovImmToReg64(scratch, addr, true, gen);
1470         
1471    // mov (%rax), %dest
1472    emitMovRMToReg64(dest, scratch, 0, size, gen);
1473    gen.rs()->freeRegister(scratch);
1474    gen.markRegDefined(dest);
1475 }
1476
1477 void EmitterAMD64::emitLoadConst(Register dest, Address imm, codeGen &gen)
1478 {
1479    emitMovImmToReg64(dest, imm, true, gen);
1480    gen.markRegDefined(dest);
1481 }
1482
1483 void EmitterAMD64::emitLoadIndir(Register dest, Register addr_src, int size, codeGen &gen)
1484 {
1485    emitMovRMToReg64(dest, addr_src, 0, size, gen);
1486    gen.markRegDefined(dest);
1487 }
1488
1489 void EmitterAMD64::emitLoadOrigFrameRelative(Register dest, Address offset, codeGen &gen)
1490 {
1491    if (gen.bt()->createdFrame) {
1492       Register scratch = gen.rs()->getScratchRegister(gen);
1493       // mov (%rbp), %rax
1494       emitMovRMToReg64(scratch, REGNUM_RBP, 0, 8, gen);
1495       
1496       // mov offset(%rax), %dest
1497       emitMovRMToReg64(dest, scratch, offset, 4, gen);
1498       return;
1499    }
1500    emitMovRMToReg64(dest, REGNUM_RBP, offset, 4, gen);
1501 }
1502
1503 bool EmitterAMD64::emitLoadRelative(Register dest, Address offset, Register base, int /* size */, codeGen &gen)
1504 {
1505    // mov offset(%base), %dest
1506    emitMovRMToReg64(dest, base, offset,
1507                     gen.addrSpace()->getAddressWidth(), gen);
1508    gen.markRegDefined(dest);
1509    return true;
1510 }
1511
1512 void EmitterAMD64::emitLoadFrameAddr(Register dest, Address offset, codeGen &gen)
1513 {
1514    // mov (%rbp), %dest
1515    if (gen.bt()->createdFrame) {
1516       emitMovRMToReg64(dest, REGNUM_RBP, 0, 8, gen);
1517       
1518       // add $offset, %dest
1519       emitOpRegImm64(0x81, 0x0, dest, offset, 8, gen);
1520       gen.markRegDefined(dest);
1521       return;
1522    }
1523    emitLEA64(REGNUM_RBP, Null_Register, 0, offset, dest, true, gen);
1524 }
1525
1526 void EmitterAMD64::emitLoadOrigRegRelative(Register dest, Address offset,
1527                                            Register base, codeGen &gen,
1528                                            bool store)
1529 {
1530    Register scratch = gen.rs()->getScratchRegister(gen);
1531    gen.markRegDefined(scratch);
1532    gen.markRegDefined(dest);
1533    // either load the address or the contents at that address
1534    if(store) 
1535    {
1536       // load the stored register 'base' into RAX
1537       emitLoadOrigRegister(base, scratch, gen);
1538       // move offset(%rax), %dest
1539       emitMovRMToReg64(dest, scratch, offset, 4, gen);
1540    }
1541    else
1542    {
1543       // load the stored register 'base' into dest
1544       emitLoadOrigRegister(base, dest, gen);
1545       // add $offset, %dest
1546       emitOpRegImm64(0x81, 0x0, dest, offset, true, gen);
1547    }
1548
1549
1550 // this is the distance on the basetramp stack frame from the
1551 // start of the GPR save region to where the base pointer is,
1552 // in 8-byte quadwords
1553 #define GPR_SAVE_REGION_OFFSET 18
1554
1555 void EmitterAMD64::emitLoadOrigRegister(Address register_num, Register destination, codeGen &gen)
1556 {
1557    registerSlot *src = (*gen.rs())[register_num];
1558    assert(src);
1559    registerSlot *dest = (*gen.rs())[destination];
1560    assert(dest);
1561
1562    if (register_num == REGNUM_ESP) {
1563       stackItemLocation loc = getHeightOf(stackItem::stacktop, gen);
1564       if (!gen.bt() || gen.bt()->alignedStack)
1565          emitMovRMToReg64(destination, loc.reg.reg(), loc.offset, 8, gen);
1566       else
1567          emitLEA64(loc.reg.reg(), Null_Register, 0, loc.offset,
1568                    destination, true, gen);
1569       return;
1570    }
1571
1572    if (src->spilledState == registerSlot::unspilled)
1573    {
1574       assert(register_num != REGNUM_EFLAGS);
1575       emitMoveRegToReg((Register) register_num, destination, gen);
1576       return;
1577    }
1578
1579    stackItemLocation loc = getHeightOf(stackItem(RealRegister(register_num)), gen);
1580    registerSlot *stack = (*gen.rs())[loc.reg.reg()];
1581    emitLoadRelative(dest->encoding(), loc.offset, stack->encoding(), gen.addrSpace()->getAddressWidth(), gen);
1582    gen.markRegDefined(destination);
1583    return;
1584 }
1585
1586 void EmitterAMD64::emitStoreOrigRegister(Address register_num, Register src, codeGen &gen) {
1587    assert(gen.addrSpace());
1588    unsigned size = (gen.addrSpace()->getAddressWidth());
1589    gen.rs()->writeProgramRegister(gen, register_num, src, size);
1590 }
1591
1592 void EmitterAMD64::emitStore(Address addr, Register src, int size, codeGen &gen)
1593 {
1594    Register scratch = gen.rs()->getScratchRegister(gen);
1595    gen.markRegDefined(scratch);
1596
1597    // mov $addr, %rax
1598    emitMovImmToReg64(scratch, addr, true, gen);
1599
1600    // mov %src, (%rax)
1601    emitMovRegToRM64(scratch, 0, src, size, gen);
1602 }
1603
1604 void EmitterAMD64::emitStoreIndir(Register addr_reg, Register src, int size, codeGen &gen)
1605 {
1606    emitMovRegToRM64(addr_reg, 0, src, size, gen);
1607 }
1608
1609 void EmitterAMD64::emitStoreFrameRelative(Address offset, Register src, Register /*scratch*/, int size, codeGen &gen)
1610 {
1611    if (gen.bt()->createdFrame) {
1612       Register scratch = gen.rs()->getScratchRegister(gen);
1613       gen.markRegDefined(scratch);
1614       // mov (%rbp), %rax
1615       emitMovRMToReg64(scratch, REGNUM_RBP, 0, 8, gen);
1616       // mov %src, offset(%rax)
1617       emitMovRegToRM64(scratch, offset, src, size, gen);
1618       gen.rs()->freeRegister(scratch);
1619       return;
1620    }
1621    emitMovRegToRM64(REGNUM_RBP, offset, src, size, gen);
1622 }
1623
1624 void EmitterAMD64::emitStoreRelative(Register src, Address offset, Register base, int /* size */, codeGen &gen) {
1625    emitMovRegToRM64(base, 
1626                     offset,
1627                     src, 
1628                     gen.addrSpace()->getAddressWidth(),
1629                     gen);
1630 }
1631
1632 void EmitterAMD64::setFPSaveOrNot(const int * liveFPReg,bool saveOrNot)
1633 {
1634    if (liveFPReg != NULL)
1635    {
1636       if (liveFPReg[0] == 0 && saveOrNot)
1637       {
1638          int * temp = const_cast<int *>(liveFPReg);
1639          temp[0] = 1;
1640       }
1641    }
1642 }
1643
1644
1645
1646 /* Recursive function that goes to where our instrumentation is calling
1647    to figure out what registers are clobbered there, and in any function
1648    that it calls, to a certain depth ... at which point we clobber everything
1649
1650    Update-12/06, njr, since we're going to a cached system we are just going to 
1651    look at the first level and not do recursive, since we would have to also
1652    store and reexamine every call out instead of doing it on the fly like before*/
1653 bool EmitterAMD64::clobberAllFuncCall( registerSpace *rs,
1654                                        func_instance *callee)
1655                    
1656 {
1657    if (callee == NULL) return false;
1658    
1659    /* This will calculate the values if the first time around, otherwise
1660       will check preparsed, stored values.
1661       True - FP Writes are present
1662       False - No FP Writes
1663    */
1664
1665    stats_codegen.startTimer(CODEGEN_LIVENESS_TIMER);  
1666    if (callee->ifunc()->writesFPRs()) {
1667       for (unsigned i = 0; i < rs->FPRs().size(); i++) {
1668          // We might want this to be another flag, actually
1669          rs->FPRs()[i]->beenUsed = true;
1670       }
1671    }
1672
1673    // Since we are making a call, mark all caller-saved registers
1674    // as used (therefore we will save them if they are live)
1675    for (int i = 0; i < rs->numGPRs(); i++) {
1676       rs->GPRs()[i]->beenUsed = true;
1677    }
1678    
1679    stats_codegen.stopTimer(CODEGEN_LIVENESS_TIMER);
1680    return true;
1681 }
1682
1683
1684
1685 static Register amd64_arg_regs[] = {REGNUM_RDI, REGNUM_RSI, REGNUM_RDX, REGNUM_RCX, REGNUM_R8, REGNUM_R9};
1686 #define AMD64_ARG_REGS (sizeof(amd64_arg_regs) / sizeof(Register))
1687 Register EmitterAMD64::emitCall(opCode op, codeGen &gen, const pdvector<AstNodePtr> &operands,
1688                                 bool noCost, func_instance *callee)
1689 {
1690    assert(op == callOp);
1691    pdvector <Register> srcs;
1692
1693    bool inInstrumentation = true;
1694
1695    //  Sanity check for NULL address arg
1696    if (!callee) {
1697       char msg[256];
1698       sprintf(msg, "%s[%d]:  internal error:  emitFuncCall called w/out"
1699               "callee argument", __FILE__, __LINE__);
1700       showErrorCallback(80, msg);
1701       assert(0);
1702    }
1703
1704    // Before we generate argument code, save any register that's live across
1705    // the call. 
1706    pdvector<pair<unsigned,int> > savedRegsToRestore;
1707    if (inInstrumentation) {
1708       bitArray regsClobberedByCall = ABI::getABI(8)->getCallWrittenRegisters();
1709       for (int i = 0; i < gen.rs()->numGPRs(); i++) {
1710          registerSlot *reg = gen.rs()->GPRs()[i];
1711          Register r = reg->encoding();
1712          static LivenessAnalyzer live(8);
1713          bool callerSave = 
1714             regsClobberedByCall.test(live.getIndex(regToMachReg64.equal_range(r).first->second));
1715          if (!callerSave) {
1716             // We don't care!
1717             regalloc_printf("%s[%d]: pre-call, skipping callee-saved register %d\n", FILE__, __LINE__,
1718                      reg->number);
1719             continue;
1720          }
1721
1722          regalloc_printf("%s[%d]: pre-call, register %d has refcount %d, keptValue %d, liveState %s\n",
1723                          FILE__, __LINE__, reg->number,
1724                          reg->refCount,
1725                          reg->keptValue,
1726                          (reg->liveState == registerSlot::live) ? "live" : ((reg->liveState == registerSlot::spilled) ? "spilled" : "dead"));
1727
1728          if (reg->refCount > 0 ||  // Currently active
1729              reg->keptValue || // Has a kept value
1730              (reg->liveState == registerSlot::live)) { // needs to be saved pre-call
1731             regalloc_printf("%s[%d]: \tsaving reg\n", FILE__, __LINE__);
1732             pair<unsigned, unsigned> regToSave;
1733             regToSave.first = reg->number;
1734             
1735             regToSave.second = reg->refCount;
1736             // We can have both a keptValue and a refCount - so I invert
1737             // the refCount if there's a keptValue
1738             if (reg->keptValue)
1739                regToSave.second *= -1;
1740             
1741             savedRegsToRestore.push_back(regToSave);
1742             
1743             // The register is live; save it. 
1744             emitPushReg64(reg->encoding(), gen);
1745             // And now that it's saved, nuke it
1746             reg->refCount = 0;
1747             reg->keptValue = false;
1748          }
1749          else {
1750             // mapping from Register to MachRegister, then to index in liveness bitArray
1751             if (regsClobberedByCall.test(live.getIndex(regToMachReg64.equal_range(r).first->second))){    
1752                gen.markRegDefined(r);
1753             }
1754          }
1755       }
1756    }
1757
1758    // Make sure we'll be adding exactly enough to the stack to maintain
1759    // alignment required by the AMD64 ABI.
1760    //
1761    // We must make sure this matches the number of push operations
1762    // in the operands.size() loop below.
1763    int stack_operands = operands.size() - AMD64_ARG_REGS;
1764    if (stack_operands < 0)
1765       stack_operands = 0;
1766
1767    int alignment = (savedRegsToRestore.size() + stack_operands) * 8;
1768    if (alignment % AMD64_STACK_ALIGNMENT)
1769       alignment = AMD64_STACK_ALIGNMENT - (alignment % AMD64_STACK_ALIGNMENT);
1770
1771    if (alignment) {
1772       emitLEA64(REGNUM_RSP, Null_Register, 0, -alignment,
1773                 REGNUM_RSP, true, gen);
1774       gen.rs()->incStack(alignment);
1775    }
1776
1777    // generate code for arguments
1778    // Now, it would be _really_ nice to emit into 
1779    // the correct register so we don't need to move it. 
1780    // So try and allocate the correct one. 
1781    // We should be able to - we saved them all up above.
1782    int frame_size = 0;
1783    for (int u = operands.size() - 1; u >= 0; u--) {
1784       Address unused = ADDR_NULL;
1785       unsigned reg = REG_NULL;
1786       if(u >= (int)AMD64_ARG_REGS)
1787       {
1788          if (!operands[u]->generateCode_phase2(gen,
1789                                                noCost,
1790                                                unused,
1791                                                reg)) assert(0);
1792          assert(reg != REG_NULL);
1793          emitPushReg64(reg, gen);
1794          gen.rs()->freeRegister(reg);
1795          frame_size++;
1796       }
1797       else
1798       {
1799           if (gen.rs()->allocateSpecificRegister(gen, (unsigned) amd64_arg_regs[u], true))
1800             reg = amd64_arg_regs[u];
1801          else {
1802             cerr << "Error: tried to allocate register " << amd64_arg_regs[u] << " and failed!" << endl;
1803             assert(0);
1804          }
1805          gen.markRegDefined(reg);
1806          if (!operands[u]->generateCode_phase2(gen,
1807                                                noCost,
1808                                                unused,
1809                                                reg)) assert(0);
1810          if (reg != amd64_arg_regs[u]) {
1811            // Code generator said "we've already got this one in a different
1812            // register, so just reuse it"
1813            emitMovRegToReg64(amd64_arg_regs[u], reg, true, gen);
1814          }      
1815       }
1816    }
1817
1818    // RAX = number of FP regs used by varargs on AMD64 (also specified as caller-saved).
1819    //Clobber it to 0.
1820    emitMovImmToReg64(REGNUM_RAX, 0, true, gen);
1821    gen.markRegDefined(REGNUM_RAX);
1822
1823    emitCallInstruction(gen, callee, REG_NULL);
1824
1825    // Now clear whichever registers were "allocated" for a return value
1826    // Don't do that for stack-pushed operands; they've already been freed.
1827    for (unsigned i = 0; i < operands.size(); i++) {
1828       if (i == AMD64_ARG_REGS) break;
1829
1830       if (operands[i]->decRefCount())
1831          gen.rs()->freeRegister(amd64_arg_regs[i]);
1832    }
1833    if(frame_size)
1834    {
1835       emitAdjustStackPointer(frame_size, gen);
1836       //emitOpRegImm64(0x81, EXTENDED_0x81_ADD, REGNUM_RSP, frame_size * 8, gen); // add esp, frame_size
1837    }
1838
1839    if (alignment) {
1840       // Skip past the stack alignment.
1841       emitLEA64(REGNUM_RSP, Null_Register, 0, alignment,
1842                 REGNUM_RSP, true, gen);
1843       gen.rs()->incStack(-alignment);
1844    }
1845
1846    if (!inInstrumentation) return REG_NULL;
1847
1848    // We now have a bit of an ordering problem.
1849    // The RS thinks all registers are free; this is not the case
1850    // We've saved the incoming registers, and it's likely that
1851    // the return value is co-occupying one. 
1852    // We need to restore the registers, but _first_ we need to 
1853    // restore the RS state and allocate a keeper register.
1854    // Now restore any registers live over the call
1855
1856    for (int i = savedRegsToRestore.size() - 1; i >= 0; i--) {
1857       registerSlot *reg = (*gen.rs())[savedRegsToRestore[i].first];
1858         
1859       if (savedRegsToRestore[i].second < 1) {
1860          reg->refCount = -1*(savedRegsToRestore[i].second);
1861          reg->keptValue = true;
1862       }
1863       else
1864          reg->refCount = savedRegsToRestore[i].second;
1865    }
1866
1867    // allocate a (virtual) register to store the return value
1868    // We do this now because the state is correct again in the RS.
1869
1870    Register ret = gen.rs()->allocateRegister(gen, noCost);
1871    gen.markRegDefined(ret);
1872    emitMovRegToReg64(ret, REGNUM_EAX, true, gen);
1873
1874     
1875    // Now restore any registers live over the call
1876    for (int i = savedRegsToRestore.size() - 1; i >= 0; i--) {
1877       registerSlot *reg = (*gen.rs())[savedRegsToRestore[i].first];
1878
1879       emitPopReg64(reg->encoding(), gen);
1880    }
1881
1882    return ret;
1883 }
1884
1885 bool EmitterAMD64Dyn::emitCallInstruction(codeGen &gen, func_instance *callee, Register) {
1886    // make the call (using an indirect call)
1887    //emitMovImmToReg64(REGNUM_EAX, callee->addr(), true, gen);
1888    //emitSimpleInsn(0xff, gen); // group 5
1889    //emitSimpleInsn(0xd0, gen); // mod = 11, reg = 2 (call Ev), r/m = 0 (RAX)
1890
1891    
1892    if (gen.startAddr() != (Address) -1) {
1893       signed long disp = callee->addr() - (gen.currAddr() + 5);
1894       int disp_i = (int) disp;
1895       if (disp == (signed long) disp_i) {
1896          emitCallRel32(disp_i, gen);
1897          return true;
1898       }
1899    }
1900    
1901    pdvector<Register> excluded;
1902    excluded.push_back(REGNUM_RAX);
1903    
1904    Register ptr = gen.rs()->getScratchRegister(gen, excluded);
1905    gen.markRegDefined(ptr);
1906    Register effective = ptr;
1907    emitMovImmToReg64(ptr, callee->addr(), true, gen);
1908    if(ptr >= REGNUM_R8) {
1909       emitRex(false, NULL, NULL, &effective, gen);
1910    }
1911    GET_PTR(insn, gen);
1912    *insn++ = 0xFF;
1913    *insn++ = static_cast<unsigned char>(0xD0 | effective);
1914    SET_PTR(insn, gen);
1915
1916    return true;
1917 }
1918
1919
1920 bool EmitterAMD64Stat::emitCallInstruction(codeGen &gen, func_instance *callee, Register) {
1921    //fprintf(stdout, "at emitCallInstruction: callee=%s\n", callee->prettyName().c_str());
1922
1923    AddressSpace *addrSpace = gen.addrSpace();
1924    Address dest;
1925
1926    // find func_instance reference in address space
1927    // (refresh func_map)
1928    pdvector<func_instance *> funcs;
1929    addrSpace->findFuncsByAll(callee->prettyName(), funcs);
1930
1931    // test to see if callee is in a shared module
1932    assert(gen.func());
1933    if (gen.func()->obj() != callee->obj()) {
1934       emitPLTCall(callee, gen);
1935    } else {
1936       dest = callee->addr();
1937       signed long disp = dest - (gen.currAddr() + 5);
1938       int disp_i = (int) disp;
1939       assert(disp == (signed long) disp_i);
1940       emitCallRel32(disp_i, gen);
1941       return true;
1942    }
1943    return true;
1944 }
1945
1946 bool EmitterAMD64Stat::emitPLTJump(func_instance *callee, codeGen &gen) {
1947    // create or retrieve jump slot
1948    Address dest = getInterModuleFuncAddr(callee, gen);
1949    GET_PTR(insn, gen);
1950    *insn++ = 0xFF;
1951    // Note: this is a combination of 00 (MOD), 100 (opcode extension), and 101
1952    // (disp32)
1953    *insn++ = 0x25;
1954    *(unsigned int*)insn = dest - (gen.currAddr() + sizeof(unsigned int) + 2);
1955    insn += sizeof(unsigned int);
1956    SET_PTR(insn, gen);
1957    return true;
1958 }
1959
1960 bool EmitterAMD64Stat::emitPLTCall(func_instance *callee, codeGen &gen) {
1961    // create or retrieve jump slot
1962    Address dest = getInterModuleFuncAddr(callee, gen);
1963    GET_PTR(insn, gen);
1964    *insn++ = 0xFF;
1965    *insn++ = 0x15;
1966    *(unsigned int*)insn = dest - (gen.currAddr() + sizeof(unsigned int) + 2);
1967    insn += sizeof(unsigned int);
1968    SET_PTR(insn, gen);
1969    return true;
1970 }
1971
1972
1973 // FIXME: comment here on the stack layout
1974 void EmitterAMD64::emitGetRetVal(Register dest, bool addr_of, codeGen &gen)
1975 {
1976    if (!addr_of) {
1977       emitLoadOrigRegister(REGNUM_RAX, dest, gen);
1978       gen.markRegDefined(dest);
1979       return;
1980    }
1981
1982    //RAX isn't defined here.  See comment in EmitterIA32::emitGetRetVal
1983    gen.markRegDefined(REGNUM_RAX);
1984    stackItemLocation loc = getHeightOf(stackItem::framebase, gen);
1985    registerSlot *rax = (*gen.rs())[REGNUM_RAX];
1986    assert(rax);
1987    loc.offset += (rax->saveOffset * 8);
1988    emitLEA64(loc.reg.reg(), REG_NULL, 0, loc.offset, dest, true, gen);
1989 }
1990
1991
1992 void EmitterAMD64::emitGetRetAddr(Register dest, codeGen &gen)
1993 {
1994    stackItemLocation loc = getHeightOf(stackItem::stacktop, gen);
1995    emitLEA64(loc.reg.reg(), REG_NULL, 0, loc.offset, dest, true, gen);
1996 }
1997
1998
1999 void EmitterAMD64::emitGetParam(Register dest, Register param_num, instPoint::Type pt_type, opCode op, bool addr_of, codeGen &gen)
2000 {
2001    if (!addr_of && param_num < 6) {
2002       emitLoadOrigRegister(amd64_arg_regs[param_num], dest, gen);
2003       gen.markRegDefined(dest);
2004       return;
2005    }
2006    else if (addr_of && param_num < 6) {
2007       Register reg = amd64_arg_regs[param_num];
2008       gen.markRegDefined(reg);
2009       stackItemLocation loc = getHeightOf(stackItem::framebase, gen);
2010       registerSlot *regSlot = (*gen.rs())[reg];
2011       assert(regSlot);
2012       loc.offset += (regSlot->saveOffset * 8);
2013       emitLEA64(loc.reg.reg(), REG_NULL, 0, loc.offset, dest, true, gen);
2014       return;
2015    }
2016    assert(param_num >= 6);
2017    stackItemLocation loc = getHeightOf(stackItem::stacktop, gen);
2018    if (!gen.bt() || gen.bt()->alignedStack) {
2019       // Load the original %rsp value into dest
2020       emitMovRMToReg64(dest, loc.reg.reg(), loc.offset, 8, gen);
2021       loc.reg = RealRegister(dest);
2022       loc.offset = 0;
2023    }
2024
2025    switch (op) {
2026       case getParamOp:
2027          if (pt_type == instPoint::FuncEntry) {
2028             //Return value before any parameters
2029             loc.offset += 8;
2030          }
2031          break;
2032       case getParamAtCallOp:
2033          break;
2034       case getParamAtEntryOp:
2035          loc.offset += 8;
2036          break;
2037       default:
2038          assert(0);
2039          break;
2040    }
2041
2042    loc.offset += (param_num-6)*8;
2043    if (!addr_of)
2044       emitMovRMToReg64(dest, loc.reg.reg(), loc.offset, 8, gen);
2045    else 
2046       emitLEA64(loc.reg.reg(), Null_Register, 0, loc.offset, dest, true, gen);
2047 }
2048
2049 // Commented out until we need it to avoid warnings
2050 #if 0
2051 static void emitPushImm16_64(unsigned short imm, codeGen &gen)
2052 {
2053    GET_PTR(insn, gen);
2054
2055    // operand-size prefix
2056    *insn++ = 0x66;
2057
2058    // PUSH imm opcode
2059    *insn++ = 0x68;
2060
2061    // and the immediate
2062    *(unsigned short*)insn = imm;
2063    insn += 2;
2064
2065    SET_PTR(insn, gen);
2066 }
2067 #endif
2068
2069 void EmitterAMD64::emitASload(int ra, int rb, int sc, long imm, Register dest, int stackShift, codeGen &gen)
2070 {
2071    // Support for using ESP that has been moved is unimplemented.
2072
2073    assert(stackShift == 0);
2074    Register use_a = Null_Register;
2075    Register use_b = Null_Register;
2076
2077    bool havera = ra > -1, haverb = rb > -1;
2078
2079
2080    // if ra is specified, move its inst-point value into our
2081    // destination register
2082    gen.markRegDefined(dest);
2083    if(havera) {
2084       if (ra == mRIP) {
2085          // special case: rip-relative data addressing
2086          // the correct address has been stuffed in imm
2087          emitMovImmToReg64(dest, imm, true, gen);
2088          return;
2089       }
2090       if (gen.inInstrumentation()) {
2091          use_a = dest;
2092          emitLoadOrigRegister(ra, dest, gen);
2093       }
2094       else {
2095          use_a = ra;
2096       }
2097    }
2098   
2099    // if rb is specified, move its inst-point value into RAX
2100    if(haverb) {
2101       if (gen.inInstrumentation()) {
2102          use_b = gen.rs()->getScratchRegister(gen);
2103          gen.markRegDefined(use_b);
2104          emitLoadOrigRegister(rb, use_b, gen);
2105       }
2106       else {
2107          use_b = rb;
2108       }
2109    }
2110    // emitLEA64 will not handle the [disp32] case properly, so
2111    // we special case that
2112    if (!havera && !haverb)
2113       emitMovImmToReg64(dest, imm, false, gen);
2114    else {
2115       emitLEA64(use_a, use_b,
2116                 sc, (int)imm, 
2117                 dest, true, gen);
2118    }
2119 }
2120
2121 void EmitterAMD64::emitCSload(int ra, int rb, int sc, long imm, Register dest, codeGen &gen)
2122 {
2123    // count is at most 1 register or constant or hack (aka pseudoregister)
2124    assert((ra == -1) &&
2125           ((rb == -1) ||
2126            ((imm == 0) && (rb == 1 /*REGNUM_ECX */ || rb >= IA32_EMULATE))));
2127    
2128    gen.markRegDefined(dest);
2129    if(rb >= IA32_EMULATE) {      
2130       // need to emulate repeated SCAS or CMPS to figure out byte count
2131       
2132       // TODO: firewall code to ensure that direction is up
2133       
2134       bool neg = false;
2135       unsigned char opcode_small, opcode_large;
2136       bool restore_rax = false;
2137       bool restore_rsi = false;
2138       
2139       bool rax_wasUsed = false;
2140       bool rsi_wasUsed = false;
2141       bool rdi_wasUsed = false;
2142       bool rcx_wasUsed = false;
2143       
2144       switch(rb) {
2145          case IA32_NESCAS:
2146             neg = true;
2147          case IA32_ESCAS:
2148             opcode_small = 0xAE;
2149             opcode_large = 0xAF;
2150             restore_rax = true;
2151             break;
2152          case IA32_NECMPS:
2153             neg = true;
2154          case IA32_ECMPS:
2155             opcode_small = 0xA6;
2156             opcode_large = 0xA7;
2157             restore_rsi = true;
2158             break;
2159          default:
2160             assert(!"Wrong emulation!");
2161       }
2162       
2163       // restore flags (needed for direction flag)
2164       gen.codeEmitter()->emitRestoreFlagsFromStackSlot(gen);
2165
2166       // restore needed registers to values at the inst point
2167       // (push current values on the stack in case they're in use)
2168       if (restore_rax) {
2169          // We often use RAX as a destination register - in this case,
2170          // it's allocated but by us. And we really don't want to save 
2171          // it and then restore...
2172          if (!gen.rs()->isFreeRegister(REGNUM_RAX) && (dest != REGNUM_RAX)) {
2173             rax_wasUsed = true;
2174             emitPushReg64(REGNUM_RAX, gen);
2175          }
2176          emitLoadOrigRegister(REGNUM_RAX, REGNUM_RAX, gen);
2177       }
2178       if (restore_rsi) {
2179          if (!gen.rs()->isFreeRegister(REGNUM_RSI) && (dest != REGNUM_RSI)) {
2180             rsi_wasUsed = true;
2181             emitPushReg64(REGNUM_RSI, gen);
2182          }
2183          emitLoadOrigRegister(REGNUM_RSI, REGNUM_RSI, gen);
2184       }
2185       if (!gen.rs()->isFreeRegister(REGNUM_RDI) && (dest != REGNUM_RDI)) {
2186          rdi_wasUsed = true;
2187          emitPushReg64(REGNUM_RDI, gen);
2188       }
2189       emitLoadOrigRegister(REGNUM_RDI, REGNUM_RDI, gen);
2190       if (!gen.rs()->isFreeRegister(REGNUM_RCX) && (dest != REGNUM_RCX)) {
2191          rcx_wasUsed = true;
2192          emitPushReg64(REGNUM_RCX, gen);
2193       }
2194       emitLoadOrigRegister(REGNUM_RCX, REGNUM_RCX, gen);
2195
2196       // emulate the string instruction
2197       emitSimpleInsn(neg ? 0xF2 : 0xF3, gen); // rep(n)e
2198       if (sc == 0)
2199          emitSimpleInsn(opcode_small, gen);
2200       else {
2201          if (sc == 1)
2202             emitSimpleInsn(0x66, gen); // operand size prefix
2203          else if (sc == 3)
2204             emitSimpleInsn(0x48, gen); // REX.W
2205          emitSimpleInsn(opcode_large, gen);
2206       }
2207
2208       // RCX has now been decremented by the number of repititions
2209       // load old RCX into RAX and compute difference
2210       emitLoadOrigRegister(REGNUM_RCX, dest, gen);
2211       emitOp(0x2B, dest, dest, REGNUM_RCX, gen);
2212
2213       // restore registers we stomped on
2214       if (rcx_wasUsed)
2215          emitPopReg64(REGNUM_RCX, gen);
2216       if (rdi_wasUsed)
2217          emitPopReg64(REGNUM_RDI, gen);
2218       if (rsi_wasUsed)
2219          emitPopReg64(REGNUM_RSI, gen);       
2220       if (rax_wasUsed)
2221          emitPopReg64(REGNUM_RAX, gen);
2222    }
2223    else if(rb > -1) {
2224
2225       // count spec is simple register with scale
2226       // TODO: 16-bit pseudoregisters
2227       assert(rb < 16);
2228
2229       // store the register into RAX
2230       Register scratch = gen.rs()->getScratchRegister(gen);
2231       gen.markRegDefined(scratch);
2232       emitLoadOrigRegister(rb, scratch, gen);
2233
2234       // shift left by the given scale
2235       // emitTimesImm will do the right thing
2236       if(sc > 0)
2237          emitTimesImm(dest, scratch, 1 << sc, gen);
2238    }
2239    else
2240       emitMovImmToReg64(dest, (int)imm, true, gen);       
2241 }
2242
2243 // this is the distance in 8-byte quadwords from the frame pointer
2244 // in our basetramp's stack frame to the saved value of RFLAGS
2245 // (1 qword for our false return address, 16 for the saved registers, 1 more for the flags)
2246 #define SAVED_RFLAGS_OFFSET 18
2247
2248 void EmitterAMD64::emitRestoreFlags(codeGen &gen, unsigned offset)
2249 {
2250    if (offset)
2251       emitOpRMReg(PUSH_RM_OPC1, RealRegister(REGNUM_EBP), offset*8, RealRegister(PUSH_RM_OPC2), gen);
2252    emitSimpleInsn(0x9D, gen);
2253 }
2254
2255 void EmitterAMD64::emitPushFlags(codeGen &gen) {
2256    // save flags (PUSHFQ)
2257    emitSimpleInsn(0x9C, gen);
2258 }
2259
2260 void EmitterAMD64::emitRestoreFlagsFromStackSlot(codeGen &gen)
2261 {
2262    stackItemLocation loc = getHeightOf(stackItem(RealRegister(REGNUM_OF)), gen);
2263    emitOpRMReg(PUSH_RM_OPC1, RealRegister(loc.reg.reg()), loc.offset, RealRegister(PUSH_RM_OPC2), gen);
2264    emitSimpleInsn(0x9D, gen);
2265 }
2266
2267 bool shouldSaveReg(registerSlot *reg, baseTramp *inst, bool saveFlags)
2268
2269   if (reg->encoding() == REGNUM_RSP) {
2270     return false;
2271   }
2272   
2273    if (inst->point()) {
2274       regalloc_printf("\t shouldSaveReg for BT %p, from 0x%lx\n", inst, inst->point()->insnAddr() );
2275    }
2276    else {
2277       regalloc_printf("\t shouldSaveReg for iRPC\n");
2278    }
2279    if (reg->liveState != registerSlot::live) {
2280       regalloc_printf("\t Reg %d not live, concluding don't save\n", reg->number);
2281       return false;
2282    }
2283    if (saveFlags) {
2284       // Saving flags takes up EAX/RAX, and so if they're live they must
2285       // be saved even if we don't explicitly use them
2286       if (reg->number == REGNUM_EAX ||
2287           reg->number == REGNUM_RAX) return true;
2288    }
2289    if (inst && inst->validOptimizationInfo() && !inst->definedRegs[reg->encoding()]) {
2290       regalloc_printf("\t Base tramp instance doesn't have reg %d (num %d) defined; concluding don't save\n",
2291                       reg->encoding(), reg->number);
2292       return false;
2293    }
2294    return true;
2295 }
2296
2297 // Moves stack pointer by offset and aligns it to AMD64_STACK_ALIGNMENT
2298 // with the following sequence:
2299 //
2300 //     lea    -off(%rsp) => %rsp           # move %rsp down
2301 //     mov    %rax => saveSlot1(%rsp)      # save %rax onto stack
2302 //     lahf                                # save %rflags byte into %ah
2303 //     seto   %al                          # save overflow flag into %al
2304 //     mov    %rax => saveSlot2(%rsp)      # save flags %rax onto stack
2305 //     lea    off(%rsp) => %rax            # store original %rsp in %rax
2306 //     and    -$AMD64_STACK_ALIGNMENT,%rsp # align %rsp
2307 //     mov    %rax => (%rsp)               # store original %rsp on stack
2308 //     mov    -off+saveSlot2(%rax) => %rax # restore flags %rax from stack
2309 //     add    $0x7f,%al                    # restore overflow flag from %al
2310 //     sahf                                # restore %rflags byte from %ah
2311 //     mov    (%rsp) => %rax               # re-load old %rsp into %rax to ...
2312 //     mov    -off+saveSlot1(%rax) => %rax # ... restore %rax from stack
2313 //
2314 // This sequence has four important properties:
2315 //     1) It never writes to memory within offset bytes below the original
2316 //        %rsp.  This is to make it compatible with red zone skips.
2317 //     2) It never *directly* writes to memory below %rsp.  It always begins
2318 //        by moving %rsp down, then writing to locations above it.  This way,
2319 //        if the kernel decides to interrupt, it won't stomp all over our
2320 //        values before we get a chance to use them.
2321 //     3) It is designed to support easy de-allocation of this space by
2322 //        ending with %rsp pointing to where we stored the original %rsp.
2323 //     4) Care has been taken to properly restore both %eax and %eflags
2324 //        by using "lea" instead of "add" or "sub," and saving the necessary
2325 //        flags around the "and" instruction.
2326 //
2327 // Saving of the flags register can be skipped if the register is not live.
2328
2329 void EmitterAMD64::emitStackAlign(int offset, codeGen &gen)
2330 {
2331    int off = offset + 8 + AMD64_STACK_ALIGNMENT;
2332    int saveSlot1 =    0 + AMD64_STACK_ALIGNMENT;
2333    int saveSlot2 =    8 + AMD64_STACK_ALIGNMENT;
2334
2335    bool saveFlags = false;
2336    if (gen.rs()->checkVolatileRegisters(gen, registerSlot::live)) {
2337       saveFlags = true;   // We need to save the flags register
2338       off += 8;           // Allocate stack space to store the flags
2339    }
2340
2341    emitLEA64(REGNUM_RSP, Null_Register, 0, -off, REGNUM_RSP, true, gen);
2342    emitStoreRelative(REGNUM_RAX, saveSlot1, REGNUM_RSP, 8, gen);
2343    if (saveFlags) {
2344       emitSimpleInsn(0x9f, gen);
2345       emitSaveO(gen);
2346       emitStoreRelative(REGNUM_RAX, saveSlot2, REGNUM_RSP, 8, gen);
2347    }
2348    emitLEA64(REGNUM_RSP, Null_Register, 0, off, REGNUM_RAX, true, gen);
2349    emitOpRegImm8_64(0x83, EXTENDED_0x83_AND, REGNUM_RSP,
2350                     -AMD64_STACK_ALIGNMENT, true, gen);
2351    emitStoreRelative(REGNUM_RAX, 0, REGNUM_RSP, 8, gen);
2352    if (saveFlags) {
2353       emitLoadRelative(REGNUM_RAX, -off+saveSlot2, REGNUM_RAX, 8, gen);
2354       emitRestoreO(gen);
2355       emitSimpleInsn(0x9e, gen);
2356       emitLoadRelative(REGNUM_RAX, 0, REGNUM_RSP, 8, gen);
2357    }
2358    emitLoadRelative(REGNUM_RAX, -off+saveSlot1, REGNUM_RAX, 8, gen);
2359 }
2360
2361 bool EmitterAMD64::emitBTSaves(baseTramp* bt,  codeGen &gen)
2362 {
2363    gen.setInInstrumentation(true);
2364
2365    int instFrameSize = 0; // Tracks how much we are moving %rsp
2366
2367    // Align the stack now to avoid having a padding hole in the middle of
2368    // our instrumentation stack.  Referring to anything on the stack above
2369    // this point will require an indirect reference.
2370    //
2371    // There are four cases that require a AMD64_STACK_ALIGNMENT aligned
2372    // stack pointer:
2373    //
2374    //    - Any time we need to save the FP registers
2375    //    - Any time we call a function (Required by the AMD64 ABI)
2376    //    - Any time we may execute SSE/SSE2 instructions
2377    //
2378    // The third case is equivalent to the second case, so search the
2379    // ASTs for function call generation.
2380    //
2381    bool useFPRs =  BPatch::bpatch->isForceSaveFPROn() ||
2382       ( BPatch::bpatch->isSaveFPROn()      &&
2383         gen.rs()->anyLiveFPRsAtEntry()     &&
2384         bt->saveFPRs()               &&
2385         bt->makesCall() );
2386    bool alignStack = useFPRs || !bt || bt->checkForFuncCalls();
2387    bool saveFlags = gen.rs()->checkVolatileRegisters(gen, registerSlot::live);
2388    bool createFrame = !bt || bt->needsFrame() || useFPRs;
2389    bool saveOrigAddr = createFrame && bt->instP();
2390
2391    //   printf("Saving registers ...\n");
2392    int num_saved = 0;
2393    int num_to_save = 0;
2394    //Calculate the number of registers we'll save
2395    for (int i = 0; i < gen.rs()->numGPRs(); i++) {
2396       registerSlot *reg = gen.rs()->GPRs()[i];
2397       if (!shouldSaveReg(reg, bt, saveFlags))
2398          continue;
2399       if (createFrame && reg->encoding() == REGNUM_RBP)
2400          continue;
2401       num_to_save++;
2402    }
2403    if (createFrame) {
2404       num_to_save++; //will save rbp
2405    }
2406    if (saveOrigAddr) {
2407       num_to_save++; //Stack slot for return value, no actual save though
2408    }
2409    if (saveFlags) {
2410       num_to_save++;
2411    }
2412          
2413    bool skipRedZone = (num_to_save > 0) || alignStack || saveOrigAddr || createFrame;
2414
2415
2416    if (alignStack) {
2417       emitStackAlign(AMD64_RED_ZONE, gen);
2418    } else if (skipRedZone) {
2419       // Just move %rsp past the red zone 
2420       // Use LEA to avoid flag modification.
2421       emitLEA64(REGNUM_RSP, Null_Register, 0,
2422                 -AMD64_RED_ZONE, REGNUM_RSP, true, gen);
2423       instFrameSize += AMD64_RED_ZONE;
2424    }
2425
2426    
2427
2428    // Save the live ones
2429    for (int i = 0; i < gen.rs()->numGPRs(); i++) {
2430       registerSlot *reg = gen.rs()->GPRs()[i];
2431
2432       if (!shouldSaveReg(reg, bt, saveFlags))
2433            continue; 
2434       if (createFrame && reg->encoding() == REGNUM_RBP)
2435            continue;
2436       emitPushReg64(reg->encoding(),gen);
2437       // We move the FP down to just under here, so we're actually
2438       // measuring _up_ from the FP. 
2439       assert((18-num_saved) > 0);
2440       num_saved++;
2441       gen.rs()->markSavedRegister(reg->encoding(), num_to_save-num_saved);
2442    }
2443
2444    // Save flags if we need to
2445    if (saveFlags) {
2446       gen.rs()->saveVolatileRegisters(gen);
2447       emitPushReg64(REGNUM_RAX, gen); 
2448
2449       num_saved++;
2450       gen.rs()->markSavedRegister(REGNUM_EFLAGS, num_to_save-num_saved);
2451       // Need a "defined, but not by us silly"
2452       gen.markRegDefined(REGNUM_RAX);
2453    }
2454
2455    // push a return address for stack walking
2456    if (saveOrigAddr) {
2457       // FIXME use a scratch register!
2458       emitMovImmToReg64(REGNUM_RAX, bt->instP()->addr_compat(), true, gen);
2459       emitPushReg64(REGNUM_RAX, gen);
2460       gen.markRegDefined(REGNUM_RAX);
2461       num_saved++;
2462    }
2463
2464    // Push RBP...
2465    if (createFrame)
2466    {
2467       // set up a fresh stack frame
2468       // pushl %rbp        (0x55)
2469       // movl  %rsp, %rbp  (0x48 0x89 0xe5)
2470       emitSimpleInsn(0x55, gen);
2471       gen.rs()->markSavedRegister(REGNUM_RBP, 0);
2472       num_saved++;
2473
2474       // And track where it went
2475       (*gen.rs())[REGNUM_RBP]->liveState = registerSlot::spilled;
2476       (*gen.rs())[REGNUM_RBP]->spilledState = registerSlot::framePointer;
2477       (*gen.rs())[REGNUM_RBP]->saveOffset = 0;
2478
2479       emitMovRegToReg64(REGNUM_RBP, REGNUM_RSP, true, gen);
2480
2481    }
2482
2483    assert(num_saved == num_to_save);
2484
2485    // Prepare our stack bookkeeping data structures.
2486    instFrameSize += num_saved * 8;
2487    if (bt) {
2488       bt->stackHeight = instFrameSize;
2489    }
2490    gen.rs()->setInstFrameSize(instFrameSize);
2491    gen.rs()->setStackHeight(0);
2492
2493    // Pre-calculate space for re-alignment and floating-point state.
2494    int extra_space = 0;
2495    if (useFPRs) {
2496       extra_space += 512;
2497    }
2498
2499    // Make sure that we're still 32-byte aligned when we add extra_space
2500    // to the stack.
2501    if (alignStack) {
2502       if ((instFrameSize + extra_space) % 32)
2503          extra_space += 32 - ((instFrameSize + extra_space) % 32);
2504    }
2505
2506    if (extra_space) {
2507       emitLEA64(REGNUM_RSP, Null_Register, 0, -extra_space,
2508                 REGNUM_RSP, true, gen);
2509       gen.rs()->incStack(extra_space);
2510    }
2511    extra_space_check = extra_space;
2512
2513
2514    bool needFXsave = false;
2515    if (useFPRs) {
2516       // need to save the floating point state (x87, MMX, SSE)
2517       // Since we're guarenteed to be at least 16-byte aligned
2518       // now, the following sequence does the job:
2519       //
2520       //   fxsave (%rsp)           ; 0x0f 0xae 0x04 0x24
2521
2522       // Change to REGET if we go back to magic LEA emission
2523      
2524      for(auto curReg = gen.rs()->FPRs().begin();
2525          curReg != gen.rs()->FPRs().end();
2526          ++curReg)
2527      {
2528        if((*curReg)->liveState != registerSlot::dead)
2529        {
2530          switch ((*curReg)->number) 
2531          {
2532          case REGNUM_XMM0:
2533          case REGNUM_XMM1:
2534          case REGNUM_XMM2:
2535          case REGNUM_XMM3:
2536          case REGNUM_XMM4:
2537          case REGNUM_XMM5:
2538          case REGNUM_XMM6:
2539          case REGNUM_XMM7:
2540            continue;
2541          default:
2542            needFXsave = true;
2543            break;
2544          }
2545        }
2546      }
2547      
2548      if(needFXsave)
2549      {
2550        GET_PTR(buffer, gen);
2551        *buffer++ = 0x0f;
2552        *buffer++ = 0xae;
2553        *buffer++ = 0x04;
2554        *buffer++ = 0x24;
2555        SET_PTR(buffer, gen);
2556      } else 
2557      {
2558        emitMovRegToReg64(REGNUM_RAX, REGNUM_RSP, true, gen);
2559        emitXMMRegsSaveRestore(gen, false);
2560      }
2561    }
2562
2563    if (bt) {
2564       bt->savedFPRs = useFPRs;
2565       bt->wasFullFPRSave = needFXsave;
2566       
2567       bt->createdFrame = createFrame;
2568       bt->savedOrigAddr = saveOrigAddr;
2569       bt->createdLocalSpace = false;
2570       bt->alignedStack = alignStack;
2571       bt->savedFlags = saveFlags;
2572       bt->skippedRedZone = skipRedZone; 
2573    }
2574
2575    return true;
2576 }
2577
2578 bool EmitterAMD64::emitBTRestores(baseTramp* bt, codeGen &gen)
2579 {
2580    bool useFPRs = false;
2581    bool createFrame = false;
2582    bool saveOrigAddr = false;
2583    bool alignStack = false;
2584    bool skippedRedZone = false;
2585    bool restoreFlags = false;
2586
2587
2588    if (bt) {
2589       useFPRs = bt->savedFPRs;
2590       createFrame = bt->createdFrame;
2591       saveOrigAddr = bt->savedOrigAddr;
2592       alignStack = bt->alignedStack;
2593       skippedRedZone = bt->skippedRedZone;
2594       restoreFlags = bt->savedFlags;
2595    }
2596    else {
2597       useFPRs =  BPatch::bpatch->isForceSaveFPROn() ||
2598          ( BPatch::bpatch->isSaveFPROn()      &&
2599            gen.rs()->anyLiveFPRsAtEntry()     &&
2600            bt->saveFPRs()               &&
2601            !bt->makesCall() );
2602       createFrame = true;
2603       saveOrigAddr = false;
2604       alignStack = true;
2605       skippedRedZone = true; // Obviated by alignStack, but hey
2606       restoreFlags = true;
2607    }
2608
2609    if (useFPRs) {
2610       // restore saved FP state
2611       // fxrstor (%rsp) ; 0x0f 0xae 0x04 0x24
2612      if(bt && bt->wasFullFPRSave)
2613      {
2614        GET_PTR(buffer, gen);
2615        *buffer++ = 0x0f;
2616        *buffer++ = 0xae;
2617        *buffer++ = 0x0c;
2618        *buffer++ = 0x24;
2619        SET_PTR(buffer, gen);
2620      }
2621      else
2622      {
2623        emitMovRegToReg64(REGNUM_RAX, REGNUM_RSP, true, gen);
2624        emitXMMRegsSaveRestore(gen, true);
2625      }
2626      
2627    }
2628
2629    int extra_space = gen.rs()->getStackHeight();
2630    assert(extra_space == extra_space_check);
2631    if (!createFrame && extra_space) {
2632       emitLEA64(REGNUM_RSP, Null_Register, 0, extra_space,
2633                 REGNUM_RSP, true, gen);
2634    }
2635
2636    if (createFrame) {
2637       // tear down the stack frame (LEAVE)
2638       emitSimpleInsn(0xC9, gen);
2639    }
2640
2641    // pop "fake" return address
2642    if (saveOrigAddr)
2643       emitPopReg64(REGNUM_RAX, gen);
2644
2645    // Restore flags
2646    if (restoreFlags) {
2647       emitPopReg64(REGNUM_RAX, gen);
2648       gen.rs()->restoreVolatileRegisters(gen);
2649    }
2650
2651    // restore saved registers
2652    for (int i = gen.rs()->numGPRs() - 1; i >= 0; i--) {
2653       registerSlot *reg = gen.rs()->GPRs()[i];
2654       if (reg->encoding() == REGNUM_RBP && createFrame) {
2655         // Although we marked it saved, we already restored it
2656         // above. 
2657         continue;
2658       }
2659
2660       if (reg->liveState == registerSlot::spilled) {
2661          emitPopReg64(reg->encoding(),gen);
2662       }
2663    }
2664
2665    // Restore the (possibly unaligned) stack pointer.
2666    if (alignStack) {
2667       emitLoadRelative(REGNUM_RSP, 0, REGNUM_RSP, 0, gen);
2668    } else if (skippedRedZone) {
2669       emitLEA64(REGNUM_ESP, Null_Register, 0,
2670                   AMD64_RED_ZONE, REGNUM_ESP, true, gen);
2671     }
2672
2673    gen.setInInstrumentation(false);
2674     return true;
2675 }
2676
2677 void EmitterAMD64::emitStoreImm(Address addr, int imm, codeGen &gen, bool noCost) 
2678 {
2679    if (!isImm64bit(addr) && !isImm64bit(imm)) {
2680       emitMovImmToMem(addr, imm, gen);
2681    }
2682    else {
2683       Register r = gen.rs()->allocateRegister(gen, noCost);
2684       gen.markRegDefined(r);
2685       emitMovImmToReg64(r, addr, true, gen);
2686       emitMovImmToRM64(r, 0, imm, true, gen);
2687       gen.rs()->freeRegister(r);
2688    }
2689 }
2690
2691 void EmitterAMD64::emitAddSignedImm(Address addr, int imm, codeGen &gen,bool noCost)
2692 {
2693    if (!isImm64bit(addr) && !isImm64bit(imm)) {
2694       emitAddMem(addr, imm, gen);
2695    }
2696    else {
2697       Register r = gen.rs()->allocateRegister(gen, noCost);      
2698       gen.markRegDefined(r);
2699       emitMovImmToReg64(r, addr, true, gen);
2700       emitAddRM64(r, imm, true, gen);
2701       gen.rs()->freeRegister(r);
2702    }
2703 }
2704
2705       
2706 int Register_DWARFtoMachineEnc64(int n)
2707 {
2708     if(n <= AMD64_MAX_MAP)
2709         return amd64_register_map[n];
2710     else {
2711                 assert(0);
2712                 return n;
2713
2714     }
2715 }
2716
2717 bool EmitterAMD64::emitPush(codeGen &gen, Register reg) {
2718     emitPushReg64(reg, gen);
2719     return true;
2720 }
2721    
2722 bool EmitterAMD64::emitPop(codeGen &gen, Register reg) {
2723     emitPopReg64(reg, gen);
2724     return true;
2725 }
2726
2727 bool EmitterAMD64::emitAdjustStackPointer(int index, codeGen &gen) {
2728         // The index will be positive for "needs popped" and negative
2729         // for "needs pushed". However, positive + SP works, so don't
2730         // invert.
2731         int popVal = index * gen.addrSpace()->getAddressWidth();
2732         emitOpRegImm64(0x81, EXTENDED_0x81_ADD, REGNUM_ESP, popVal, true, gen);
2733    gen.rs()->incStack(-1 * popVal);
2734         return true;
2735 }
2736
2737 #endif /* end of AMD64-specific functions */
2738
2739 Address Emitter::getInterModuleFuncAddr(func_instance *func, codeGen& gen)
2740 {
2741     AddressSpace *addrSpace = gen.addrSpace();
2742     BinaryEdit *binEdit = addrSpace->edit();
2743     Address relocation_address;
2744     unsigned int jump_slot_size = 4;
2745 #if defined(arch_x86_64)
2746     jump_slot_size = 8;
2747 #endif
2748
2749     if (!binEdit || !func) {
2750         assert(!"Invalid function call (function info is missing)");
2751     }
2752
2753     SymtabAPI::Symbol *referring = func->getRelocSymbol();
2754
2755     // have we added this relocation already?
2756     relocation_address = binEdit->getDependentRelocationAddr(referring);
2757
2758     if (!relocation_address) {
2759         // inferiorMalloc addr location and initialize to zero
2760         relocation_address = binEdit->inferiorMalloc(jump_slot_size);
2761         unsigned char* dat = (unsigned char*) malloc(jump_slot_size);
2762         memset(dat,0,jump_slot_size);
2763         binEdit->writeDataSpace((void*)relocation_address, jump_slot_size, dat);
2764         free(dat);
2765
2766         // add write new relocation symbol/entry
2767         binEdit->addDependentRelocation(relocation_address, referring);
2768     }
2769
2770     return relocation_address;
2771 }
2772
2773 Address Emitter::getInterModuleVarAddr(const image_variable *var, codeGen& gen)
2774 {
2775     AddressSpace *addrSpace = gen.addrSpace();
2776     BinaryEdit *binEdit = addrSpace->edit();
2777     Address relocation_address;
2778     unsigned int jump_slot_size = 4;
2779 #if defined(arch_x86_64)
2780     jump_slot_size = 8;
2781 #endif
2782
2783     if (!binEdit || !var) {
2784         assert(!"Invalid variable load (variable info is missing)");
2785     }
2786
2787     // find the Symbol corresponding to the int_variable
2788     std::vector<SymtabAPI::Symbol *> syms;
2789     var->svar()->getSymbols(syms);
2790
2791     if (syms.size() == 0) {
2792         char msg[256];
2793         sprintf(msg, "%s[%d]:  internal error:  cannot find symbol %s"
2794                 , __FILE__, __LINE__, var->symTabName().c_str());
2795         showErrorCallback(80, msg);
2796         assert(0);
2797     }
2798
2799     // try to find a dynamic symbol
2800     // (take first static symbol if none are found)
2801     SymtabAPI::Symbol *referring = syms[0];
2802     for (unsigned k=0; k<syms.size(); k++) {
2803         if (syms[k]->isInDynSymtab()) {
2804             referring = syms[k];
2805             break;
2806         }
2807     }
2808
2809     // have we added this relocation already?
2810     relocation_address = binEdit->getDependentRelocationAddr(referring);
2811
2812     if (!relocation_address) {
2813         // inferiorMalloc addr location and initialize to zero
2814         relocation_address = binEdit->inferiorMalloc(jump_slot_size);
2815         unsigned int dat = 0;
2816         binEdit->writeDataSpace((void*)relocation_address, jump_slot_size, &dat);
2817
2818         // add write new relocation symbol/entry
2819         binEdit->addDependentRelocation(relocation_address, referring);
2820     }
2821
2822     return relocation_address;
2823 }
2824
2825 bool EmitterIA32Dyn::emitCallInstruction(codeGen &gen, func_instance *callee, Register ret) 
2826 {
2827    // make the call
2828    // we are using an indirect call here because we don't know the
2829    // address of this instruction, so we can't use a relative call.
2830         // The only direct, absolute calls available on x86 are far calls,
2831         // which require the callee to be aware that they're being far-called.
2832         // So we grit our teeth and deal with the indirect call.
2833         // Physical register
2834    //Same regs on Win/x86 and linux/x86
2835    gen.rs()->makeRegisterAvail(RealRegister(REGNUM_EAX), gen); //caller saved regs
2836    gen.rs()->makeRegisterAvail(RealRegister(REGNUM_ECX), gen);
2837    gen.rs()->makeRegisterAvail(RealRegister(REGNUM_EDX), gen);
2838
2839    Register placeholder1 = gen.rs()->allocateRegister(gen, true);
2840    Register placeholder2 = gen.rs()->allocateRegister(gen, true);
2841    gen.rs()->noteVirtualInReal(ret, RealRegister(REGNUM_EAX));
2842    gen.rs()->noteVirtualInReal(placeholder1, RealRegister(REGNUM_ECX));
2843    gen.rs()->noteVirtualInReal(placeholder2, RealRegister(REGNUM_EDX));
2844
2845    if (gen.startAddr() == (Address) -1) {
2846       emitMovImmToReg(RealRegister(REGNUM_EAX), callee->addr(), gen);
2847       emitOpExtReg(CALL_RM_OPC1, CALL_RM_OPC2, RealRegister(REGNUM_EAX), gen);
2848    }
2849    else {
2850       Address dest = callee->addr();
2851       Address src = gen.currAddr() + 5;
2852       emitCallRel32(dest - src, gen);
2853    }
2854
2855    gen.rs()->freeRegister(placeholder1);
2856    gen.rs()->freeRegister(placeholder2);
2857    return true;
2858 }
2859
2860 bool EmitterIA32Stat::emitCallInstruction(codeGen &gen, func_instance *callee, Register ret) {
2861    AddressSpace *addrSpace = gen.addrSpace();
2862    Address dest;
2863
2864    gen.rs()->makeRegisterAvail(RealRegister(REGNUM_EAX), gen); //caller saved regs
2865    gen.rs()->makeRegisterAvail(RealRegister(REGNUM_ECX), gen);
2866    gen.rs()->makeRegisterAvail(RealRegister(REGNUM_EDX), gen);
2867
2868    //Put some dummy virtual registers in ECX and EDX so that the
2869    // emitMovPCRMToReg below doesn't try to allocate them.  
2870    // Associate the return value into EAX now for the same reason.
2871    // These shouldn't generate to any acutal code.  
2872    Register placeholder1 = gen.rs()->allocateRegister(gen, true);
2873    Register placeholder2 = gen.rs()->allocateRegister(gen, true);
2874    gen.rs()->noteVirtualInReal(ret, RealRegister(REGNUM_EAX));
2875    gen.rs()->noteVirtualInReal(placeholder1, RealRegister(REGNUM_ECX));
2876    gen.rs()->noteVirtualInReal(placeholder2, RealRegister(REGNUM_EDX));
2877
2878    // find func_instance reference in address space
2879    // (refresh func_map)
2880    pdvector<func_instance *> funcs;
2881    addrSpace->findFuncsByAll(callee->prettyName(), funcs);
2882    
2883    // test to see if callee is in a shared module
2884    if (gen.func()->obj() != callee->obj()) {
2885       emitPLTCall(callee, gen);
2886    } else {
2887       dest = callee->addr();
2888       Address src = gen.currAddr() + 5;
2889       emitCallRel32(dest - src, gen);
2890    }
2891
2892    gen.rs()->freeRegister(placeholder1);
2893    gen.rs()->freeRegister(placeholder2);
2894    return true;
2895 }
2896
2897 bool EmitterIA32Stat::emitPLTCall(func_instance *callee, codeGen &gen) {
2898    // create or retrieve jump slot
2899    Address dest = getInterModuleFuncAddr(callee, gen);
2900    // load register with address from jump slot
2901    emitMovPCRMToReg(RealRegister(REGNUM_EAX), dest-gen.currAddr(), gen);
2902    // emit call *(e_x)
2903    emitOpRegReg(CALL_RM_OPC1, RealRegister(CALL_RM_OPC2), 
2904                 RealRegister(REGNUM_EAX), gen);
2905    return true;
2906 }
2907
2908 bool EmitterIA32Stat::emitPLTJump(func_instance *callee, codeGen &gen) {
2909   // create or retrieve jump slot
2910    Address dest = getInterModuleFuncAddr(callee, gen);
2911    // load register with address from jump slot
2912    emitMovPCRMToReg(RealRegister(REGNUM_EAX), dest-gen.currAddr(), gen);
2913    // emit jump *(e_x)
2914    emitOpRegReg(JUMP_RM_OPC1, RealRegister(JUMP_RM_OPC2), 
2915                 RealRegister(REGNUM_EAX), gen);
2916    return true;
2917 }
2918
2919 void EmitterIA32::emitLoadShared(opCode op, Register dest, const image_variable *var, bool is_local, int /*size*/, codeGen &gen, Address offset)
2920 {
2921    RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
2922
2923    // create or retrieve jump slot
2924    Address addr;
2925    if(var == NULL) {
2926       addr = offset;
2927    }
2928    else if(!is_local) {
2929       addr = getInterModuleVarAddr(var, gen);
2930    }  
2931    else {
2932       addr = (Address)var->getOffset();
2933    }
2934   
2935    emitMovPCRMToReg(dest_r, addr - gen.currAddr(), gen, (!is_local && var != NULL));
2936    if (op == loadOp) {
2937       emitLoadIndir(dest, dest, 4, gen);
2938    }
2939 }
2940
2941 void EmitterIA32::emitStoreShared(Register source, const image_variable *var, bool is_local, 
2942                                   int /*size*/, codeGen &gen)
2943 {
2944    // create or retrieve jump slot
2945    //Address addr = getInterModuleVarAddr(var, gen);
2946    Address addr;
2947    if(!is_local)
2948       addr = getInterModuleVarAddr(var, gen);
2949    else
2950       addr = (Address)var->getOffset();
2951    
2952    // temporary virtual register for storing destination address
2953    Register dest = gen.rs()->allocateRegister(gen, false);
2954    RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
2955    emitMovPCRMToReg(dest_r, addr-gen.currAddr(), gen, !is_local);
2956    emitStoreIndir(dest, source, 4, gen);
2957    gen.rs()->freeRegister(dest);
2958 }
2959
2960 #if defined(arch_x86_64)
2961 void EmitterAMD64::emitLoadShared(opCode op, Register dest, const image_variable *var, bool is_local, int size, codeGen &gen, Address offset)
2962 {
2963   Address addr;
2964   gen.markRegDefined(dest);
2965   if(!var)
2966   {
2967     addr = offset;
2968   }
2969   else if(is_local)
2970   {
2971       addr = (Address)var ->getOffset();
2972   }
2973   else
2974   {
2975     // create or retrieve jump slot
2976     addr = getInterModuleVarAddr(var, gen);
2977   }
2978   
2979   if(op == loadConstOp) {
2980     int offset = addr - gen.currAddr();
2981     // Brutal hack for IP-relative: displacement operand on 32-bit = IP-relative on 64-bit.
2982     if(is_local || !var)
2983       emitLEA64(Null_Register, Null_Register, 0, offset - 7, dest, true, gen);
2984     else
2985        emitMovPCRMToReg64(dest, addr - gen.currAddr(), 8, gen, true);
2986     
2987     return;
2988   }
2989   
2990   // load register with address from jump slot
2991   if(!is_local) {
2992      emitMovPCRMToReg64(dest, addr - gen.currAddr(), 8, gen, true);
2993      emitLoadIndir(dest, dest, size, gen);
2994   }
2995   else {
2996      emitMovPCRMToReg64(dest, addr - gen.currAddr(), size, gen, true);
2997   }
2998 }
2999
3000 void EmitterAMD64::emitStoreShared(Register source, const image_variable *var, bool is_local, int size, codeGen &gen)
3001 {
3002   Address addr;
3003   
3004   if(is_local) {
3005      addr = (Address)var->getOffset();
3006   }
3007   else {
3008      addr = getInterModuleVarAddr(var, gen);
3009   }
3010   
3011   // temporary virtual register for storing destination address
3012   Register dest = gen.rs()->allocateRegister(gen, false); 
3013   gen.markRegDefined(dest);
3014  
3015   // load register with address from jump slot
3016   emitLEA64(Null_Register, Null_Register, 0, addr-gen.currAddr() - 7, dest, true, gen);
3017   //emitMovPCRMToReg64(dest, addr-gen.currAddr(), gen, true);
3018   if(!is_local)
3019      emitLoadIndir(dest, dest, 8, gen);
3020     
3021   // get the variable with an indirect load
3022   emitStoreIndir(dest, source, size, gen);
3023   
3024   gen.rs()->freeRegister(dest);
3025 }
3026
3027 #endif