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