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