Bug fix for FP liveness in test 1-20 (ICC).
[dyninst.git] / dyninstAPI / src / inst-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  * inst-x86.C - x86 dependent functions and code generator
34  * $Id: inst-x86.C,v 1.289 2008/09/11 20:14:14 mlam Exp $
35  */
36 #include <iomanip>
37
38 #include <limits.h>
39 #include "common/h/headers.h"
40 #include "common/h/Dictionary.h"
41 #include "dyninstAPI/src/symtab.h"
42 #include "dyninstAPI/src/process.h"
43 #include "dyninstAPI/src/dyn_lwp.h"
44 #include "dyninstAPI/src/inst.h"
45 #include "dyninstAPI/src/instP.h"
46 #include "dyninstAPI/src/ast.h"
47 #include "dyninstAPI/src/util.h"
48 #include "common/h/stats.h"
49 #include "dyninstAPI/src/os.h"
50 #include "dyninstAPI/src/debug.h"
51 #include "dyninstAPI/src/function.h"
52 #include "dyninstAPI/src/arch.h"
53 #include "dyninstAPI/src/inst-x86.h"
54 #include "dyninstAPI/src/miniTramp.h"
55 #include "dyninstAPI/src/baseTramp.h"
56 #include "dyninstAPI/src/emit-x86.h"
57 #include "dyninstAPI/src/instPoint.h" // includes instPoint-x86.h
58
59 #include "dyninstAPI/src/addressSpace.h"
60 #include "dyninstAPI/src/binaryEdit.h"
61
62 #include "dyninstAPI/src/registerSpace.h"
63
64 #include "dyninstAPI/src/instP.h" // class returnInstance
65 #include "dyninstAPI/src/rpcMgr.h"
66 #include "dyninstAPI/src/dyn_thread.h"
67 //#include "InstrucIter.h"
68 #include "mapped_module.h"
69 #include "dyninstAPI/h/BPatch_memoryAccess_NP.h"
70 #include "IAPI_to_AST.h"
71 #include "Expression.h"
72 #include "Instruction.h"
73 #include <sstream>
74 #include <assert.h>
75
76 class ExpandInstruction;
77 class InsertNops;
78
79 extern bool relocateFunction(process *proc, instPoint *&location);
80
81 extern "C" int cpuidCall();
82
83 /****************************************************************************/
84 /****************************************************************************/
85 /****************************************************************************/
86
87
88
89 /****************************************************************************/
90 /****************************************************************************/
91 /****************************************************************************/
92
93 /* A quick model for the "we're done, branch back/ILL" tramp end */
94
95
96 /*
97  * Worst-case scenario for how much room it will take to relocate
98  * an instruction -- used for allocating the new area
99  */
100 unsigned relocatedInstruction::maxSizeRequired() {
101     return insn->spaceToRelocate();
102 }
103
104 void registerSpace::initialize32() {
105     static bool done = false;
106     if (done) return;
107     done = true;
108
109     // On 32-bit x86 we use stack slots as "registers"; therefore we can
110     // create an arbitrary number, and use them. However, this can bite us
111     // if we want to use actual registers. Any ideas?
112     
113     pdvector<registerSlot *> registers;
114
115     // When we use 
116     registerSlot *eax = new registerSlot(REGNUM_EAX,
117                                         "eax",
118                                         false, // Off-limits due to our "stack slot" register mechanism
119                                         registerSlot::liveAlways,
120                                         registerSlot::realReg);
121     registerSlot *ecx = new registerSlot(REGNUM_ECX,
122                                         "ecx",
123                                         false,
124                                         registerSlot::liveAlways,
125                                         registerSlot::realReg);
126     registerSlot *edx = new registerSlot(REGNUM_EDX,
127                                         "edx",
128                                         false,
129                                         registerSlot::liveAlways,
130                                         registerSlot::realReg);
131     registerSlot *ebx = new registerSlot(REGNUM_EBX,
132                                         "ebx",
133                                         false,
134                                         registerSlot::liveAlways,
135                                         registerSlot::realReg);
136     registerSlot *esp = new registerSlot(REGNUM_ESP,
137                                         "esp",
138                                         true, // Off-limits...
139                                         registerSlot::liveAlways,
140                                         registerSlot::realReg); // I'd argue the SP is a special-purpose reg
141     registerSlot *ebp = new registerSlot(REGNUM_EBP,
142                                         "ebp",
143                                         true,
144                                         registerSlot::liveAlways,
145                                         registerSlot::realReg);
146     registerSlot *esi = new registerSlot(REGNUM_ESI,
147                                         "esi",
148                                         false,
149                                         registerSlot::liveAlways,
150                                         registerSlot::realReg);
151     registerSlot *edi = new registerSlot(REGNUM_EDI,
152                                         "edi",
153                                         false,
154                                         registerSlot::liveAlways,
155                                         registerSlot::realReg);
156     
157     registers.push_back(eax);
158     registers.push_back(ecx);
159     registers.push_back(edx);
160     registers.push_back(ebx);
161     registers.push_back(esp);
162     registers.push_back(ebp);
163     registers.push_back(esi);
164     registers.push_back(edi);
165
166     // FPRs...
167
168     // SPRs...
169     
170     // "Virtual" registers
171     for (unsigned i = 1; i <= NUM_VIRTUAL_REGISTERS; i++) {
172                 char buf[128];
173         sprintf(buf, "virtGPR%d", i);
174
175         registerSlot *virt = new registerSlot(i,
176                                               buf,
177                                               false,
178                                               registerSlot::deadAlways,
179                                               registerSlot::GPR);
180         registers.push_back(virt);
181     }
182     // Create a single FPR representation to represent
183     // whether any FPR is live
184     registerSlot *fpr = new registerSlot(REGNUM_DUMMYFPR,
185                                          "virtFPR",
186                                          true, // off-limits...
187                                          registerSlot::liveAlways, // because we check this via overapproximation and not the
188                                          // regular liveness algorithm, start out *dead* and set live if written
189                                          registerSlot::FPR);
190     registers.push_back(fpr);
191
192     // And a "do we save the flags" "register"
193     registers.push_back(new registerSlot(IA32_FLAG_VIRTUAL_REGISTER,
194                                          "virtFlags",
195                                          true,
196                                          registerSlot::liveAlways,
197                                          registerSlot::SPR));
198     // Create the global register space
199     registerSpace::createRegisterSpace(registers);
200
201     // Define:
202     // callRead
203     // callWritten
204     // Fortunately, both are basically zero...
205     
206     // callRead: no change
207     // callWritten: write to the flags
208     // TODO FIXME
209
210     // Define:
211     // callRead - argument registers
212     // callWritten - RAX
213
214     // Can't use numRegisters here because we're depending
215     // on the REGNUM_FOO numbering
216 #if defined(cap_liveness)
217     returnRead_ = getBitArray();
218     // Return reads no registers
219
220     callRead_ = getBitArray();
221     // CallRead reads no registers
222     // We wish...
223     callRead_[REGNUM_ECX] = true;
224     callRead_[REGNUM_EDX] = true;
225
226     // PLT entries use ebx
227     callRead_[REGNUM_EBX] = true;
228
229     // TODO: Fix this for platform-specific calling conventions
230
231     // Assume calls write flags
232     callWritten_ = callRead_;
233     for (unsigned i = REGNUM_OF; i <= REGNUM_RF; i++) 
234         callWritten_[i] = true;
235
236
237     // And assume a syscall reads or writes _everything_
238     syscallRead_ = getBitArray().set();
239     syscallWritten_ = syscallRead_;
240
241     allRegs_ = getBitArray().set();
242 #endif
243 }
244
245 #if defined(cap_32_64)
246 void registerSpace::initialize64() {
247     static bool done = false;
248     if (done) return;
249     done = true;
250
251     // Create the 64-bit registers
252     // Well, let's just list them....
253
254     // Calling ABI:
255     // rax, rcx, rdx, r8, r9, r10, r11 are not preserved across a call
256     // However, rcx, rdx, r8, and r9 are used for arguments, and therefore
257     // should be assumed live. 
258     // So rax, r10, r11 are dead at a function call.
259
260     registerSlot * rax = new registerSlot(REGNUM_RAX,
261                                           "rax",
262                                           true, // We use it implicitly _everywhere_
263                                           registerSlot::deadABI,
264                                           registerSlot::GPR);
265     registerSlot * rcx = new registerSlot(REGNUM_RCX,
266                                           "rcx",
267                                           false,
268                                           registerSlot::liveAlways,
269                                           registerSlot::GPR);
270     registerSlot * rdx = new registerSlot(REGNUM_RDX,
271                                           "rdx",
272                                           false,
273                                           registerSlot::liveAlways,
274                                           registerSlot::GPR);
275     registerSlot * rbx = new registerSlot(REGNUM_RBX,
276                                           "rbx",
277                                           false,
278                                           registerSlot::liveAlways,
279                                           registerSlot::GPR);
280     registerSlot * rsp = new registerSlot(REGNUM_RSP,
281                                           "rsp",
282                                           true, // Off-limits...
283                                           registerSlot::liveAlways,
284                                           registerSlot::SPR); 
285     registerSlot * rbp = new registerSlot(REGNUM_RBP,
286                                           "rbp",
287                                           true,
288                                           registerSlot::liveAlways,
289                                           registerSlot::SPR);
290     registerSlot * rsi = new registerSlot(REGNUM_RSI,
291                                           "rsi",
292                                           false,
293                                           registerSlot::liveAlways,
294                                           registerSlot::GPR);
295     registerSlot * rdi = new registerSlot(REGNUM_RDI,
296                                           "rdi",
297                                           false,
298                                           registerSlot::liveAlways,
299                                           registerSlot::GPR);
300     registerSlot * r8 = new registerSlot(REGNUM_R8,
301                                          "r8",
302                                          false,
303                                          registerSlot::liveAlways,
304                                          registerSlot::GPR);
305     registerSlot * r9 = new registerSlot(REGNUM_R9,
306                                          "r9",
307                                          false,
308                                          registerSlot::liveAlways,
309                                          registerSlot::GPR);
310     registerSlot * r10 = new registerSlot(REGNUM_R10,
311                                           "r10",
312                                           false,
313                                           registerSlot::deadABI,
314                                           registerSlot::GPR);
315     registerSlot * r11 = new registerSlot(REGNUM_R11,
316                                           "r11",
317                                           false,
318                                           registerSlot::deadABI,
319                                           registerSlot::GPR);
320     registerSlot * r12 = new registerSlot(REGNUM_R12,
321                                           "r12",
322                                           false,
323                                           registerSlot::liveAlways,
324                                           registerSlot::GPR);
325     registerSlot * r13 = new registerSlot(REGNUM_R13,
326                                           "r13",
327                                           false,
328                                           registerSlot::liveAlways,
329                                           registerSlot::GPR);
330     registerSlot * r14 = new registerSlot(REGNUM_R14,
331                                           "r14",
332                                           false,
333                                           registerSlot::liveAlways,
334                                           registerSlot::GPR);
335     registerSlot * r15 = new registerSlot(REGNUM_R15,
336                                           "r15",
337                                           false,
338                                           registerSlot::liveAlways,
339                                           registerSlot::GPR);
340
341     pdvector<registerSlot *> registers;
342     registers.push_back(rax);
343     registers.push_back(rbx);
344     registers.push_back(rsp);
345     registers.push_back(rbp);
346     registers.push_back(r10);
347     registers.push_back(r11);
348     registers.push_back(r12);
349     registers.push_back(r13);
350     registers.push_back(r14);
351     registers.push_back(r15);
352
353     // Put the call parameter registers last so that we are not
354     // likely to allocate them for general purposes
355     registers.push_back(r8);
356     registers.push_back(r9);
357     registers.push_back(rcx);
358     registers.push_back(rdx);
359     registers.push_back(rsi);
360     registers.push_back(rdi);
361
362
363     registers.push_back(new registerSlot(REGNUM_OF,
364                                          "of",
365                                          true,
366                                          registerSlot::liveAlways,
367                                          registerSlot::SPR));
368     registers.push_back(new registerSlot(REGNUM_SF,
369                                          "sf",
370                                          true,
371                                          registerSlot::liveAlways,
372                                          registerSlot::SPR));
373     registers.push_back(new registerSlot(REGNUM_ZF,
374                                          "zf",
375                                          true,
376                                          registerSlot::liveAlways,
377                                          registerSlot::SPR));
378     registers.push_back(new registerSlot(REGNUM_AF,
379                                          "af",
380                                          true,
381                                          registerSlot::liveAlways,
382                                          registerSlot::SPR));
383     registers.push_back(new registerSlot(REGNUM_PF,
384                                          "pf",
385                                          true,
386                                          registerSlot::liveAlways,
387                                          registerSlot::SPR));
388     registers.push_back(new registerSlot(REGNUM_CF,
389                                          "cf",
390                                          true,
391                                          registerSlot::liveAlways,
392                                          registerSlot::SPR));
393     registers.push_back(new registerSlot(REGNUM_TF,
394                                          "tf",
395                                          true,
396                                          registerSlot::liveAlways,
397                                          registerSlot::SPR));
398     registers.push_back(new registerSlot(REGNUM_IF,
399                                          "if",
400                                          true,
401                                          registerSlot::liveAlways,
402                                          registerSlot::SPR));
403     registers.push_back(new registerSlot(REGNUM_DF,
404                                          "df",
405                                          true,
406                                          registerSlot::liveAlways,
407                                          registerSlot::SPR));
408     registers.push_back(new registerSlot(REGNUM_NT,
409                                          "nt",
410                                          true,
411                                          registerSlot::liveAlways,
412                                          registerSlot::SPR));
413     registers.push_back(new registerSlot(REGNUM_RF,
414                                          "rf",
415                                          true,
416                                          registerSlot::liveAlways,
417                                          registerSlot::SPR));
418
419     registers.push_back(new registerSlot(REGNUM_DUMMYFPR,
420                                          "dummyFPR",
421                                          true,
422                                          registerSlot::liveAlways, // because we check this via overapproximation and not the
423                                          // regular liveness algorithm, start out *dead* and set live if written
424                                          registerSlot::FPR));
425     registers.push_back(new registerSlot(REGNUM_MM0,
426                                          "MM0/ST(0)",
427                                          true,
428                                          registerSlot::liveAlways,
429                                          registerSlot::FPR));
430     registers.push_back(new registerSlot(REGNUM_MM1,
431                                          "MM1/ST(1)",
432                                          true,
433                                          registerSlot::liveAlways,
434                                          registerSlot::FPR));
435     registers.push_back(new registerSlot(REGNUM_MM2,
436                                          "MM2/ST(2)",
437                                          true,
438                                          registerSlot::liveAlways,
439                                          registerSlot::FPR));
440     registers.push_back(new registerSlot(REGNUM_MM3,
441                                          "MM3/ST(3)",
442                                          true,
443                                          registerSlot::liveAlways,
444                                          registerSlot::FPR));
445     registers.push_back(new registerSlot(REGNUM_MM4,
446                                          "MM4/ST(4)",
447                                          true,
448                                          registerSlot::liveAlways,
449                                          registerSlot::FPR));
450     registers.push_back(new registerSlot(REGNUM_MM5,
451                                          "MM5/ST(5)",
452                                          true,
453                                          registerSlot::liveAlways,
454                                          registerSlot::FPR));
455     registers.push_back(new registerSlot(REGNUM_MM6,
456                                          "MM6/ST(6)",
457                                          true,
458                                          registerSlot::liveAlways,
459                                          registerSlot::FPR));
460     registers.push_back(new registerSlot(REGNUM_MM7,
461                                          "MM7/ST(7)",
462                                          true,
463                                          registerSlot::liveAlways,
464                                          registerSlot::FPR));
465     registers.push_back(new registerSlot(REGNUM_XMM0,
466                                          "XMM0",
467                                          true,
468                                          registerSlot::liveAlways,
469                                          registerSlot::FPR));
470     registers.push_back(new registerSlot(REGNUM_XMM1,
471                                          "XMM1)",
472                                          true,
473                                          registerSlot::liveAlways,
474                                          registerSlot::FPR));
475     registers.push_back(new registerSlot(REGNUM_XMM2,
476                                          "XMM2",
477                                          true,
478                                          registerSlot::liveAlways,
479                                          registerSlot::FPR));
480     registers.push_back(new registerSlot(REGNUM_XMM3,
481                                          "XMM3",
482                                          true,
483                                          registerSlot::liveAlways,
484                                          registerSlot::FPR));
485     registers.push_back(new registerSlot(REGNUM_XMM4,
486                                          "XMM4",
487                                          true,
488                                          registerSlot::liveAlways,
489                                          registerSlot::FPR));
490     registers.push_back(new registerSlot(REGNUM_XMM5,
491                                          "XMM5",
492                                          true,
493                                          registerSlot::liveAlways,
494                                          registerSlot::FPR));
495     registers.push_back(new registerSlot(REGNUM_XMM6,
496                                          "XMM6",
497                                          true,
498                                          registerSlot::liveAlways,
499                                          registerSlot::FPR));
500     registers.push_back(new registerSlot(REGNUM_XMM7,
501                                          "XMM7",
502                                          true,
503                                          registerSlot::liveAlways,
504                                          registerSlot::FPR));
505
506
507
508
509     // For registers that we really just don't care about.
510     registers.push_back(new registerSlot(REGNUM_IGNORED,
511                                          "ignored",
512                                          true,
513                                          registerSlot::liveAlways,
514                                          registerSlot::SPR));
515
516     registerSpace::createRegisterSpace64(registers);
517
518     // Define:
519     // callRead - argument registers
520     // callWritten - RAX
521
522 #if defined(cap_liveness)
523     returnRead64_ = getBitArray();
524     returnRead64_[REGNUM_RAX] = true;
525     returnRead64_[REGNUM_RCX] = true; //Not correct, temporary
526     // Returns also "read" any callee-saved registers
527     returnRead64_[REGNUM_RBX] = true;
528     returnRead64_[REGNUM_RDX] = true;
529     returnRead64_[REGNUM_R12] = true;
530     returnRead64_[REGNUM_R13] = true;
531     returnRead64_[REGNUM_R14] = true;
532     returnRead64_[REGNUM_R15] = true;
533
534     //returnRead64_[REGNUM_R10] = true;
535     
536
537     callRead64_ = getBitArray();
538     callRead64_[REGNUM_RCX] = true;
539     callRead64_[REGNUM_RDX] = true;
540     callRead64_[REGNUM_R8] = true;
541     callRead64_[REGNUM_R9] = true;
542     callRead64_[REGNUM_RDI] = true;
543     callRead64_[REGNUM_RSI] = true;
544
545     // Anything in those four is not preserved across a call...
546     // So we copy this as a shorthand then augment it
547     callWritten64_ = callRead64_;
548
549     // As well as RAX, R10, R11
550     callWritten64_[REGNUM_RAX] = true;
551     callWritten64_[REGNUM_R10] = true;
552     callWritten64_[REGNUM_R11] = true;
553     // And flags
554     for (unsigned i = REGNUM_OF; i <= REGNUM_RF; i++) 
555         callWritten64_[i] = true;
556
557     // What about floating point?
558
559     // And assume a syscall reads or writes _everything_
560     syscallRead64_ = getBitArray().set();
561     syscallWritten64_ = syscallRead_;
562
563     allRegs64_ = getBitArray().set();
564 #endif
565
566 }
567 #endif
568
569 void registerSpace::initialize()
570 {
571     static bool inited = false;
572     
573     if (inited) return;
574     inited = true;
575     if(xmmCapable())
576     {
577       hasXMM = true;
578     }
579     
580
581     initialize32();
582 #if defined(cap_32_64)
583     initialize64();
584 #endif
585 }
586
587 /* This makes a call to the cpuid instruction, which returns an int where each bit is 
588    a feature.  Bit 24 contains whether fxsave is possible, meaning that xmm registers
589    are saved. */
590 #if defined(os_windows)
591 int cpuidCall() {
592     DWORD result;
593     _asm {
594         xor eax, eax
595         cpuid
596         mov result, eax
597     }
598     return result;
599 }
600 #endif
601 #if !defined(x86_64_unknown_linux2_4)
602 bool xmmCapable()
603 {
604   int features = cpuidCall();
605   char * ptr = (char *)&features;
606   ptr += 3;
607   if (0x1 & (*ptr))
608     return true;
609   else
610     return false;
611 }
612 #else
613 bool xmmCapable()
614 {
615   return true;
616 }
617 #endif
618
619 bool baseTramp::generateSaves(codeGen& gen, registerSpace*, baseTrampInstance *inst) {
620    return gen.codeEmitter()->emitBTSaves(this, inst, gen);
621 }
622
623 bool baseTramp::generateRestores(codeGen &gen, registerSpace*, baseTrampInstance *inst) {
624
625    return gen.codeEmitter()->emitBTRestores(this, inst, gen);
626 }
627
628 /****************************************************************************/
629 /****************************************************************************/
630 /****************************************************************************/
631
632 void emitJccR8(int condition_code, char jump_offset,
633                codeGen &gen) {
634     GET_PTR(insn, gen);
635     *insn++ = static_cast<unsigned char>(condition_code);
636     *insn++ = jump_offset;
637     SET_PTR(insn, gen);
638 }
639
640 // VG(8/15/02): nicer jcc: condition is the tttn field.
641 // Because we generate jumps twice, once with bogus 0
642 // offset, and then with the right offset, the instruction
643 // may be longer (and overwrite something else) the 2nd time.
644 // So willRegen defaults to true and always generates jcc near
645 // (the longer form)
646
647 // TODO: generate JEXCZ as well
648 void emitJcc(int condition, int offset,
649              codeGen &gen, bool willRegen) /* = true */
650 {
651    unsigned char opcode;
652    GET_PTR(insn, gen);
653    
654    assert(condition >= 0 && condition <= 0x0F);
655    
656    if(!willRegen && (offset >= -128 && offset <= 127)) { // jcc rel8
657       opcode = 0x70 | (unsigned char)condition;
658       *insn++ = opcode;
659       *insn++ = (unsigned char) (offset & 0xFF);
660    }
661    else { // jcc near rel32
662       opcode = 0x80 | (unsigned char)condition;
663       *insn++ = 0x0F;
664       *insn++ = opcode;
665       *((int*)insn) = offset;
666       insn += sizeof(int);
667    }
668    SET_PTR(insn, gen);
669 }
670
671 /****************************************************************************/
672 /****************************************************************************/
673 /****************************************************************************/
674
675
676 /****************************************************************************/
677 /****************************************************************************/
678 /****************************************************************************/
679
680 /**
681  * tramp_pre_frame_size is the amount of space the base trampoline allocates
682  * on the stack before setting up a stack frame.  It's needed to stack
683  * walk out of base tramps.  Should be treated as a constant, but the
684  * C++ scoping rules for const are stupid.
685  **/
686
687 int tramp_pre_frame_size_32 = 36; //Stack space allocated by 'pushf; pusha'
688
689 int tramp_pre_frame_size_64 = 8 + 16 * 8 + STACK_PAD_CONSTANT; // stack space allocated by pushing flags and 16 GPRs
690                                                 // and skipping the 128-byte red zone
691
692 bool can_do_relocation(process *proc,
693                        const pdvector<pdvector<Frame> > &stackWalks,
694                        int_function *instrumented_func)
695 {
696    bool can_do_reloc = true;
697
698    // for every vectors of frame, ie. thread stack walk, make sure can do
699    // relocation
700    Address begAddr = instrumented_func->getAddress();
701    for (unsigned walk_itr = 0; walk_itr < stackWalks.size(); walk_itr++) {
702      pdvector<int_function *> stack_funcs =
703        proc->pcsToFuncs(stackWalks[walk_itr]);
704      
705      // for every frame in thread stack walk
706      for(unsigned i=0; i<stack_funcs.size(); i++) {
707        int_function *stack_func = stack_funcs[i];
708        Address pc = stackWalks[walk_itr][i].getPC();
709        
710        if( stack_func == instrumented_func ) {
711          // Catchup doesn't occur on instPoinst in relocated function when
712          // the original function is on the stack.  This leads to the
713          // timer never being called for timer metrics.  A solution still
714          // needs to be worked out.
715          if(pc >= begAddr && pc <= begAddr+JUMP_REL32_SZ) {
716            // can't relocate since within first five bytes
717            can_do_reloc = false;
718          } else {
719              // Need to check whether each entry point has enough room
720              // to patch in a jump; technically, this is only needed
721              // if we're _in_ the function as control may transfer to
722              // the middle of the jump(s) out.
723
724              assert(0);
725          }
726          break;
727        }
728      }
729    }
730    
731    return can_do_reloc;
732 }
733
734 /**************************************************************
735  *
736  *  code generator for x86
737  *
738  **************************************************************/
739
740
741
742
743 #define MAX_BRANCH      (0x1<<31)
744
745 Address getMaxBranch() {
746   return (Address)MAX_BRANCH;
747 }
748
749
750 bool doNotOverflow(int)
751 {
752    //
753    // this should be changed by the correct code. If there isn't any case to
754    // be checked here, then the function should return TRUE. If there isn't
755    // any immediate code to be generated, then it should return FALSE - naim
756    //
757    // any int value can be an immediate on the pentium
758     return(true);
759 }
760
761
762
763 /* build the MOD/RM byte of an instruction */
764 static inline unsigned char makeModRMbyte(unsigned Mod, unsigned Reg,
765                                           unsigned RM)
766 {
767    return static_cast<unsigned char>(((Mod & 0x3) << 6) + ((Reg & 0x7) << 3) + (RM & 0x7));
768 }
769
770 // VG(7/30/02): Build the SIB byte of an instruction */
771 static inline unsigned char makeSIBbyte(unsigned Scale, unsigned Index,
772                                         unsigned Base)
773 {
774    return static_cast<unsigned char>(((Scale & 0x3) << 6) + ((Index & 0x7) << 3) + (Base & 0x7));
775 }
776
777 /* 
778    Emit the ModRM byte and displacement for addressing modes.
779    base is a register (EAX, ECX, REGNUM_EDX, EBX, EBP, REGNUM_ESI, REGNUM_EDI)
780    disp is a displacement
781    reg_opcode is either a register or an opcode
782 */
783 void emitAddressingMode(unsigned base, RegValue disp,
784                         unsigned reg_opcode, codeGen &gen)
785 {
786    // MT linux uses ESP+4
787    // we need an SIB in that case
788    if (base == REGNUM_ESP) {
789       emitAddressingMode(REGNUM_ESP, Null_Register, 0, disp, reg_opcode, gen);
790       return;
791    }
792    GET_PTR(insn, gen);
793    if (base == Null_Register) {
794       *insn++ = makeModRMbyte(0, reg_opcode, 5);
795       *((int *)insn) = disp;
796       insn += sizeof(int);
797    } else if (disp == 0 && base != REGNUM_EBP) {
798       *insn++ = makeModRMbyte(0, reg_opcode, base);
799    } else if (disp >= -128 && disp <= 127) {
800       *insn++ = makeModRMbyte(1, reg_opcode, base);
801       *((char *)insn++) = (char) disp;
802    } else {
803       *insn++ = makeModRMbyte(2, reg_opcode, base);
804       *((int *)insn) = disp;
805       insn += sizeof(int);
806    }
807    SET_PTR(insn, gen);
808 }
809
810 // VG(7/30/02): emit a fully fledged addressing mode: base+index<<scale+disp
811 void emitAddressingMode(unsigned base, unsigned index,
812                         unsigned int scale, RegValue disp,
813                         int reg_opcode, codeGen &gen)
814 {
815    bool needSIB = (base == REGNUM_ESP) || (index != Null_Register);
816
817    if(!needSIB) {
818       emitAddressingMode(base, disp, reg_opcode, gen);
819       return;
820    }
821    
822    assert(index != REGNUM_ESP);
823    
824    if(index == Null_Register) {
825       assert(base == REGNUM_ESP); // not necessary, but sane
826       index = 4;           // (==REGNUM_ESP) which actually means no index in SIB
827    }
828
829    GET_PTR(insn, gen);
830    
831    if(base == Null_Register) { // we have to emit [index<<scale+disp32]
832       *insn++ = makeModRMbyte(0, reg_opcode, 4);
833       *insn++ = makeSIBbyte(scale, index, 5);
834       *((int *)insn) = disp;
835       insn += sizeof(int);
836    }
837    else if(disp == 0 && base != REGNUM_EBP) { // EBP must have 0 disp8; emit [base+index<<scale]
838        *insn++ = makeModRMbyte(0, reg_opcode, 4);
839        *insn++ = makeSIBbyte(scale, index, base);
840    }
841    else if (disp >= -128 && disp <= 127) { // emit [base+index<<scale+disp8]
842       *insn++ = makeModRMbyte(1, reg_opcode, 4);
843       *insn++ = makeSIBbyte(scale, index, base);
844       *((char *)insn++) = (char) disp;
845    }
846    else { // emit [base+index<<scale+disp32]
847       *insn++ = makeModRMbyte(2, reg_opcode, 4);
848       *insn++ = makeSIBbyte(scale, index, base);
849       *((int *)insn) = disp;
850       insn += sizeof(int);
851    }
852
853    SET_PTR(insn, gen);
854 }
855
856
857 /* emit a simple one-byte instruction */
858 void emitSimpleInsn(unsigned op, codeGen &gen) {
859     GET_PTR(insn, gen);
860     *insn++ = static_cast<unsigned char>(op);
861     SET_PTR(insn, gen);
862 }
863
864 void emitPushImm(unsigned int imm, codeGen &gen)
865 {
866     GET_PTR(insn, gen);
867     *insn++ = 0x68;
868     *((unsigned int *)insn) = imm;
869     insn += sizeof(unsigned int);
870     SET_PTR(insn, gen);
871     if (gen.rs())
872        gen.rs()->incStack(gen.addrSpace()->getAddressWidth());
873 }
874
875 // emit a simple register to register instruction: OP dest, src
876 // opcode is one or two byte
877 void emitOpRegReg(unsigned opcode, RealRegister dest, RealRegister src,
878                   codeGen &gen)
879 {
880     GET_PTR(insn, gen);
881     if (opcode <= 0xFF)
882        *insn++ = static_cast<unsigned char>(opcode);
883     else {
884        *insn++ = static_cast<unsigned char>(opcode >> 8);
885        *insn++ = static_cast<unsigned char>(opcode & 0xFF);
886     }
887     // ModRM byte define the operands: Mod = 3, Reg = dest, RM = src
888     *insn++ = makeModRMbyte(3, dest.reg(), src.reg());
889     SET_PTR(insn, gen);
890 }
891
892 void emitOpRegImm(int opcode, RealRegister dest, int imm,
893                   codeGen &gen) {
894    GET_PTR(insn, gen);
895    *insn++ = 0x81;
896    *insn++ = makeModRMbyte(3, opcode, dest.reg());
897    *((int *)insn) = imm;
898    insn+= sizeof(int);
899    SET_PTR(insn, gen);
900 }
901
902 // emit OP reg, r/m
903 void emitOpRegRM(unsigned opcode, RealRegister dest, RealRegister base,
904                  int disp, codeGen &gen)
905 {
906     GET_PTR(insn, gen);
907     if (opcode <= 0xff) {
908        *insn++ = static_cast<unsigned char>(opcode);
909     } else {
910        *insn++ = static_cast<unsigned char>(opcode >> 8);
911        *insn++ = static_cast<unsigned char>(opcode & 0xff);
912     }
913     SET_PTR(insn, gen);
914     emitAddressingMode(base.reg(), disp, dest.reg(), gen);
915 }
916
917 // emit OP r/m, reg
918 void emitOpRMReg(unsigned opcode, RealRegister base, int disp,
919                  RealRegister src, codeGen &gen) {
920    GET_PTR(insn, gen);
921    *insn++ = static_cast<unsigned char>(opcode);
922    SET_PTR(insn, gen);
923    emitAddressingMode(base.reg(), disp, src.reg(), gen);
924 }
925
926 // emit OP reg, imm32
927 void emitOpExtRegImm(int opcode, int ext, RealRegister dest, int imm,
928                      codeGen &gen) 
929 {
930    GET_PTR(insn, gen);
931    *insn++ = opcode;
932    *insn++ = makeModRMbyte(3, (char) ext, dest.reg());
933    *((int *)insn) = imm;
934    insn+= sizeof(int);
935    SET_PTR(insn, gen);
936 }
937
938 void emitOpExtRegImm8(int opcode, char ext, RealRegister dest, unsigned char imm,
939                      codeGen &gen) 
940 {
941    GET_PTR(insn, gen);
942    *insn++ = opcode;
943    *insn++ = makeModRMbyte(3, ext, dest.reg());
944    *((unsigned char *)insn) = imm;
945    insn+= sizeof(unsigned char);
946    SET_PTR(insn, gen);
947 }
948
949 void emitOpExtReg(unsigned opcode, unsigned char ext, RealRegister reg, codeGen &gen)
950 {
951    GET_PTR(insn, gen);
952    *insn++ = opcode;
953    *insn++ = makeModRMbyte(3, ext, reg.reg());
954    SET_PTR(insn, gen);
955 }
956
957 void emitMovRegToReg(RealRegister dest, RealRegister src, codeGen &gen)
958 {
959    GET_PTR(insn, gen);
960    *insn++ = 0x8B;
961    *insn++ = makeModRMbyte(3, dest.reg(), src.reg());
962    SET_PTR(insn, gen);
963 }
964
965 void emitOpRegRegImm(unsigned opcode, RealRegister dest, RealRegister src, unsigned imm, codeGen &gen)
966 {
967    GET_PTR(insn, gen);
968    *insn++ = opcode;
969    *insn++ = makeModRMbyte(3, dest.reg(), src.reg());
970    *((int *)insn) = imm;
971    insn += sizeof(int);
972    SET_PTR(insn, gen);
973 }
974
975 // emit MOV reg, (reg)
976 void emitMovIRegToReg(RealRegister dest, RealRegister src,
977                       codeGen &gen) {
978     GET_PTR(insn, gen);
979     *insn++ = 0x8B;
980     *insn++ = makeModRMbyte(0, dest.reg(), src.reg());
981     SET_PTR(insn, gen);
982     gen.markRegDefined(dest.reg());
983 }
984
985 // VG(07/30/02): Emit a lea dest, [base + index * scale + disp]; dest is a
986 // real GPR
987 void emitLEA(RealRegister base, RealRegister index, unsigned int scale,
988              RegValue disp, RealRegister dest, codeGen &gen)
989 {
990    if (dest.reg() != REGNUM_ESP)
991       gen.markRegDefined(dest.reg());
992    GET_PTR(insn, gen);
993    *insn++ = 0x8D;
994    SET_PTR(insn, gen);
995    emitAddressingMode(base.reg(), index.reg(), scale, disp, (int)dest.reg(), gen);
996 }
997
998 void emitLEA(RealRegister base, unsigned displacement, RealRegister dest, 
999              codeGen &gen)
1000 {
1001    gen.markRegDefined(dest.reg());
1002    GET_PTR(insn, gen);
1003    *insn++ = 0x8D;
1004    *insn++ = makeModRMbyte(2, dest.reg(), base.reg());
1005    *((unsigned *) insn) = displacement;
1006    insn += sizeof(unsigned);
1007    SET_PTR(insn, gen);
1008 }
1009
1010 // emit MOV reg, (offset(%eip))
1011 void emitMovPCRMToReg(RealRegister dest, int offset, codeGen &gen, bool deref_result)
1012 {
1013     // call next instruction (relative 0x0) and pop PC (EIP) into register
1014    GET_PTR(insn, gen);
1015
1016    if (!gen.addrSpace()->needsPIC())
1017    {
1018       Address target = gen.currAddr() + offset;
1019       if (deref_result) {
1020          emitMovMToReg(dest, target, gen);
1021       }
1022       else {
1023          emitMovImmToReg(dest, target, gen);
1024       }
1025       return;
1026    }
1027
1028    int used = gen.used();
1029    RealRegister pc_reg(0);
1030    if (gen.rs()->pc_rel_offset() == -1) {
1031       //assert(!gen.rs()->pc_rel_use_count);
1032       if (gen.getPCRelUseCount() == 1) {
1033          //We know there's only one getPC instruction.  We won't setup
1034          // a stored register for the PC.  Just use dest since we're
1035          // about to write to it anyways.
1036          pc_reg = dest;
1037       }
1038       else {
1039          gen.rs()->pc_rel_reg = gen.rs()->allocateRegister(gen, true);
1040          pc_reg = gen.rs()->loadVirtualForWrite(gen.rs()->pc_rel_reg, gen);
1041       }
1042       gen.rs()->pc_rel_offset() = used + 5;
1043       *insn++ = 0xE8;
1044       *insn++ = 0x00;
1045       *insn++ = 0x00;
1046       *insn++ = 0x00;
1047       *insn++ = 0x00;
1048       *insn++ = static_cast<unsigned char>(0x58 + pc_reg.reg());
1049       SET_PTR(insn, gen);
1050    }
1051    else {
1052       pc_reg = gen.rs()->loadVirtual(gen.rs()->pc_rel_reg, gen);   
1053    }
1054    gen.rs()->pc_rel_use_count++;
1055
1056    offset += used - gen.rs()->pc_rel_offset();
1057    if (deref_result) {
1058       emitMovRMToReg(dest, pc_reg, offset, gen);
1059    }
1060    else {
1061       emitLEA(pc_reg, offset, dest, gen);
1062    }   
1063
1064    if (gen.getPCRelUseCount() > 1 && 
1065        gen.rs()->pc_rel_use_count == gen.getPCRelUseCount())
1066    {
1067       //We've made the last use of getPC.  Free the register that stores the PC
1068       //Don't do if getPCRelUseCount() is 0, because we don't know how many uses
1069       // there are.
1070       //Don't do if getPCRelUseCount() is 1, because it was special cased above
1071       gen.rs()->freeRegister(gen.rs()->pc_rel_reg);
1072       gen.rs()->pc_rel_reg = Null_Register;
1073       gen.rs()->pc_rel_offset() = -1;
1074    }
1075 }
1076
1077 // emit MOV reg, r/m
1078 void emitMovRMToReg(RealRegister dest, RealRegister base, int disp,
1079                     codeGen &gen) 
1080 {
1081    GET_PTR(insn, gen);
1082    *insn++ = 0x8B;
1083    SET_PTR(insn, gen);
1084    emitAddressingMode(base.reg(), disp, dest.reg(), gen);
1085 }
1086
1087 // emit MOV r/m, reg
1088 void emitMovRegToRM(RealRegister base, int disp, RealRegister src,
1089                     codeGen &gen) 
1090 {
1091    GET_PTR(insn, gen);
1092    *insn++ = 0x89;
1093    SET_PTR(insn, gen);
1094    emitAddressingMode(base.reg(), disp, src.reg(), gen);
1095 }
1096
1097 // emit MOV m, reg
1098 void emitMovRegToM(int disp, RealRegister src, codeGen &gen)
1099 {
1100    GET_PTR(insn, gen);
1101    *insn++ = 0x89;
1102    SET_PTR(insn, gen);
1103    emitAddressingMode(Null_Register, disp, src.reg(), gen);
1104 }
1105
1106 // emit MOV m, reg
1107 void emitMovRegToMB(int disp, RealRegister src, codeGen &gen)
1108 {
1109    GET_PTR(insn, gen);
1110    *insn++ = 0x88;
1111    *insn++ = makeModRMbyte(0, src.reg(), 5);
1112    *((int *) insn) = disp;
1113    insn += sizeof(int);
1114    SET_PTR(insn, gen);
1115 }
1116
1117 // emit MOV m, reg
1118 void emitMovRegToMW(int disp, RealRegister src, codeGen &gen)
1119 {
1120    GET_PTR(insn, gen);
1121    *insn++ = 0x66;
1122    *insn++ = 0x88;
1123    *insn++ = makeModRMbyte(0, src.reg(), 5);
1124    *((int *) insn) = disp;
1125    insn += sizeof(int);
1126    SET_PTR(insn, gen);
1127 }
1128
1129 // emit MOV reg, m
1130 void emitMovMToReg(RealRegister dest, int disp, codeGen &gen)
1131 {
1132    gen.markRegDefined(dest.reg());
1133    GET_PTR(insn, gen);
1134    *insn++ = 0x8B;
1135    SET_PTR(insn, gen);
1136    emitAddressingMode(Null_Register, disp, dest.reg(), gen);
1137 }
1138
1139 // emit MOVSBL reg, m
1140 void emitMovMBToReg(RealRegister dest, int disp, codeGen &gen)
1141 {
1142    gen.markRegDefined(dest.reg());
1143    GET_PTR(insn, gen);
1144    *insn++ = 0x0F;
1145    *insn++ = 0xBE;
1146    SET_PTR(insn, gen);
1147    emitAddressingMode(Null_Register, disp, dest.reg(), gen);
1148 }
1149
1150 // emit MOVSWL reg, m
1151 void emitMovMWToReg(RealRegister dest, int disp, codeGen &gen)
1152 {
1153    gen.markRegDefined(dest.reg());
1154    GET_PTR(insn, gen);
1155    *insn++ = 0x0F;
1156    *insn++ = 0xBF;
1157    SET_PTR(insn, gen);
1158    emitAddressingMode(Null_Register, disp, dest.reg(), gen);
1159 }
1160
1161 // emit MOV reg, imm32
1162 void emitMovImmToReg(RealRegister dest, int imm, codeGen &gen)
1163 {
1164    GET_PTR(insn, gen);
1165    *insn++ = static_cast<unsigned char>(0xB8 + dest.reg());
1166    *((int *)insn) = imm;
1167    insn += sizeof(int);
1168    SET_PTR(insn, gen);
1169 }
1170
1171 // emit MOV r/m32, imm32
1172 void emitMovImmToRM(RealRegister base, int disp, int imm,
1173                     codeGen &gen) {
1174    GET_PTR(insn, gen);
1175    *insn++ = 0xC7;
1176    SET_PTR(insn, gen);
1177    emitAddressingMode(base.reg(), disp, 0, gen);
1178    REGET_PTR(insn, gen);
1179    *((int*)insn) = imm;
1180    insn += sizeof(int);
1181     SET_PTR(insn, gen);
1182 }
1183
1184 // emit MOV mem32, imm32
1185 void emitMovImmToMem(Address maddr, int imm,
1186                                    codeGen &gen) {
1187     // In x86_64, the meaning of the ModRM byte for disp32 has changed.
1188     // Now, it implies an [RIP] + disp32 address.  To get an absolute
1189     // address operand (in both x86 and x86_64), the full ModRM + SIB
1190     // syntax must be used.
1191     GET_PTR(insn, gen);
1192     *insn++ = 0xC7;
1193
1194     // FIXME: To adhere strictly to the x86 and x86_64 ISAs, we specify an
1195     // absolute (32-bit) address by emitting a ModRM and SIB byte of the
1196     // following form:
1197     //     Mod = 00b, Reg = (doesn't matter?), R/M = 100b
1198     //     base = 101b, index = 100b, scale = (doesn't matter?)
1199     // Current forms of emitAddressingMode() do not allow for this, and so
1200     // we do it manually here.  emitAddressingMode() should be made more
1201     // robust.
1202     *insn++ = makeModRMbyte(0, 0, 4);
1203     *insn++ = makeSIBbyte(0, 4, 5);
1204     *((int *)insn) = maddr;
1205     insn += sizeof(unsigned);
1206
1207     *((int*)insn) = imm;
1208     insn += sizeof(int);
1209     SET_PTR(insn, gen);
1210 }
1211
1212 // emit Add dword ptr DS:[addr], imm
1213 void emitAddMemImm32(Address addr, int imm, codeGen &gen)
1214 {
1215     GET_PTR(insn, gen);
1216    *insn++ = 0x81;
1217    *insn++ = 0x05;
1218    *((unsigned *)insn) = addr;
1219    insn += sizeof(unsigned);
1220    *((int *)insn) = imm;
1221    insn += sizeof(int);
1222     SET_PTR(insn, gen);
1223 }
1224
1225 // emit Add reg, imm32
1226 void emitAddRegImm32(RealRegister reg, int imm, codeGen &gen)
1227 {
1228    GET_PTR(insn, gen);
1229    if (imm >= -128 && imm <= 127) {
1230       *insn++ = 0x83;
1231       *insn++ = makeModRMbyte(3, 0, reg.reg());
1232       *((char *)insn) = (char) imm;
1233       insn += sizeof(char);
1234    }
1235    else {
1236       *insn++ = 0x81;
1237       *insn++ = makeModRMbyte(3, 0, reg.reg());
1238       *((int *)insn) = imm;
1239       insn += sizeof(int);
1240    }
1241    SET_PTR(insn, gen);
1242 }
1243
1244 // emit Sub reg, reg
1245 void emitSubRegReg(RealRegister dest, RealRegister src, codeGen &gen)
1246 {
1247    gen.markRegDefined(dest.reg());
1248    GET_PTR(insn, gen);
1249    *insn++ = 0x2B;
1250    *insn++ = makeModRMbyte(3, dest.reg(), src.reg());
1251    SET_PTR(insn, gen);
1252 }
1253
1254 unsigned char cmovOpcodeFromRelOp(unsigned op)
1255 {
1256    switch (op) {
1257       case eqOp: return 0x44; //cmove
1258       case neOp: return 0x45; //cmovne
1259       case lessOp: return 0x4c; //cmovl
1260       case leOp: return 0x4e; //cmovle
1261       case greaterOp: return 0x4f; //cmovg
1262       case geOp: return 0x4d; //cmovge
1263      default: assert(0);
1264    }
1265    return 0x0;
1266 }
1267 // help function to select appropriate jcc opcode for a relOp
1268 unsigned char jccOpcodeFromRelOp(unsigned op)
1269 {
1270    switch (op) {
1271      case eqOp: return JNE_R8;
1272      case neOp: return JE_R8;
1273      case lessOp: return JGE_R8;
1274      case leOp: return JG_R8;
1275      case greaterOp: return JLE_R8;
1276      case geOp: return JL_R8;
1277      default: assert(0);
1278    }
1279    return 0x0;
1280 }
1281
1282 static inline void emitEnter(short imm16, codeGen &gen) {
1283     GET_PTR(insn, gen);
1284    *insn++ = 0xC8;
1285    *((short*)insn) = imm16;
1286    insn += sizeof(short);
1287    *insn++ = 0;
1288     SET_PTR(insn, gen);
1289 }
1290
1291 Register emitFuncCall(opCode, codeGen &, pdvector<AstNodePtr> &, bool, Address) {
1292         assert(0);
1293         return 0;
1294 }
1295
1296 // this function just multiplexes between the 32-bit and 64-bit versions
1297 Register emitFuncCall(opCode op, 
1298                       codeGen &gen,
1299                       pdvector<AstNodePtr> &operands, 
1300                       bool noCost,
1301                       int_function *callee)
1302 {
1303     Register reg = gen.codeEmitter()->emitCall(op, gen, operands, noCost, callee);
1304     return reg;
1305 }
1306
1307
1308
1309 /* Recursive function that goes to where our instrumentation is calling
1310 to figure out what registers are clobbered there, and in any function
1311 that it calls, to a certain depth ... at which point we clobber everything
1312
1313 Update-12/06, njr, since we're going to a cached system we are just going to 
1314 look at the first level and not do recursive, since we would have to also
1315 store and reexamine every call out instead of doing it on the fly like before*/
1316
1317 // Should be a member of the registerSpace class?
1318
1319 bool EmitterIA32::clobberAllFuncCall( registerSpace *rs,
1320                                       int_function *callee)
1321                    
1322 {
1323   if (callee == NULL) return false;
1324
1325   /* This will calculate the values if the first time around, otherwise
1326      will check preparsed, stored values.
1327      True - FP Writes are present
1328      False - No FP Writes
1329   */
1330
1331   stats_codegen.startTimer(CODEGEN_LIVENESS_TIMER);  
1332   if (callee->ifunc()->writesFPRs()) {
1333       for (unsigned i = 0; i < rs->FPRs().size(); i++) {
1334           rs->FPRs()[i]->beenUsed = true;
1335       }
1336   }
1337   stats_codegen.stopTimer(CODEGEN_LIVENESS_TIMER);
1338   return true;
1339 }
1340
1341
1342 void EmitterIA32::setFPSaveOrNot(const int * liveFPReg,bool saveOrNot)
1343 {
1344    if (liveFPReg != NULL)
1345    {
1346       if (liveFPReg[0] == 0 && saveOrNot)
1347       {
1348          int * temp = const_cast<int *>(liveFPReg);
1349          temp[0] = 1;
1350       }
1351    }
1352 }
1353
1354
1355 Register EmitterIA32::emitCall(opCode op, 
1356                                codeGen &gen,
1357                                const pdvector<AstNodePtr> &operands, 
1358                                bool noCost, int_function *callee) {
1359     bool inInstrumentation = true;
1360     if (gen.obj() &&
1361         dynamic_cast<replacedInstruction *>(gen.obj())) {
1362         // We're replacing an instruction - so don't do anything
1363         // that requires a base tramp.
1364         inInstrumentation = false;
1365     }
1366
1367
1368     assert(op == callOp);
1369     pdvector <Register> srcs;
1370     int param_size;
1371     pdvector<Register> saves;
1372     
1373     //  Sanity check for NULL address arg
1374     if (!callee) {
1375         char msg[256];
1376         sprintf(msg, "%s[%d]:  internal error:  emitFuncCall called w/out"
1377                 "callee argument", __FILE__, __LINE__);
1378         showErrorCallback(80, msg);
1379         assert(0);
1380     }
1381
1382    param_size = emitCallParams(gen, operands, callee, saves, noCost);
1383
1384    Register ret = gen.rs()->allocateRegister(gen, noCost);
1385
1386    emitCallInstruction(gen, callee, ret);
1387
1388    emitCallCleanup(gen, callee, param_size, saves);
1389
1390    if (!inInstrumentation) return REG_NULL;
1391
1392    // allocate a (virtual) register to store the return value
1393    // Virtual register
1394
1395    return ret;
1396 }
1397
1398 /*
1399  * emit code for op(src1,src2, dest)
1400  * ibuf is an instruction buffer where instructions are generated
1401  * base is the next free position on ibuf where code is to be generated
1402  */
1403
1404 codeBufIndex_t emitA(opCode op, Register src1, Register /*src2*/, Register dest,
1405                      codeGen &gen, RegControl rc, bool /*noCost*/)
1406 {
1407    //bperr("emitA(op=%d,src1=%d,src2=XX,dest=%d)\n",op,src1,dest);
1408    
1409    // retval is the address of the jump (if one is created). 
1410    // It's always the _start_ of the jump, which means that if we need
1411    // to offset (like x86 (to - (from + insnsize))) we do it later.
1412    codeBufIndex_t retval = 0;
1413    
1414    switch (op) {
1415       case ifOp: {
1416          // if src1 == 0 jump to dest
1417          // src1 is a temporary
1418          // dest is a target address
1419          retval = gen.codeEmitter()->emitIf(src1, dest, rc, gen);
1420          break;
1421       }
1422       case branchOp: {
1423          // dest is the displacement from the current value of insn
1424          // this will need to work for both 32-bits and 64-bits
1425          // (since there is no JMP rel64)
1426          instruction::generateBranch(gen, dest);
1427          retval = gen.getIndex();
1428          break;
1429       }
1430       case trampPreamble: {
1431          break;
1432       }
1433       default:
1434          abort();        // unexpected op for this emit!
1435    }
1436    
1437    return retval;
1438 }
1439
1440 Register emitR(opCode op, Register src1, Register src2, Register dest,
1441                codeGen &gen, bool noCost,
1442                const instPoint *location, bool /*for_multithreaded*/)
1443 {
1444     //bperr("emitR(op=%d,src1=%d,src2=XX,dest=%d)\n",op,src1,dest);
1445
1446    bool get_addr_of = (src2 != Null_Register);
1447    switch (op) {
1448        case getRetValOp:
1449           // dest is a register where we can store the value
1450           // the return value is in the saved EAX
1451           gen.codeEmitter()->emitGetRetVal(dest, get_addr_of, gen);
1452           if (!get_addr_of)
1453              return dest;
1454           break;
1455        case getParamOp:
1456           // src1 is the number of the argument
1457           // dest is a register where we can store the value
1458           gen.codeEmitter()->emitGetParam(dest, src1, location->getPointType(), 
1459                                           get_addr_of, gen);
1460           if (!get_addr_of)
1461              return dest;
1462           break;
1463        case loadRegOp:
1464           assert(src1 == 0);
1465           assert(0);
1466           return dest;
1467        default:
1468           abort();                  // unexpected op for this emit!
1469     }
1470     assert(get_addr_of);
1471     emitV(storeIndirOp, src2, 0, dest, gen, noCost, gen.rs(), 
1472           gen.addrSpace()->getAddressWidth(), gen.point(), gen.addrSpace());
1473     return(dest);
1474 }
1475
1476 void emitSHL(RealRegister dest, unsigned char pos, codeGen &gen)
1477 {
1478   //bperr( "Emiting SHL\n");
1479    gen.markRegDefined(dest.reg());
1480    GET_PTR(insn, gen);
1481    *insn++ = 0xC1;
1482    *insn++ = makeModRMbyte(3 /* rm gives register */,
1483                            4 /* opcode ext. */, dest.reg());
1484    *insn++ = pos;
1485    SET_PTR(insn, gen);
1486 }
1487
1488 void EmitterIA32::emitPushFlags(codeGen &gen) {
1489     // These crank the saves forward
1490     emitSimpleInsn(PUSHFD, gen);
1491 }
1492
1493 void EmitterIA32::emitRestoreFlags(codeGen &gen, unsigned offset)
1494 {
1495    emitOpRMReg(PUSH_RM_OPC1, RealRegister(REGNUM_ESP), offset*4, RealRegister(PUSH_RM_OPC2), gen);
1496     emitSimpleInsn(POPFD, gen); // popfd
1497 }
1498
1499 void EmitterIA32::emitRestoreFlagsFromStackSlot(codeGen &gen)
1500 {
1501     emitRestoreFlags(gen, SAVED_EFLAGS_OFFSET);
1502 }
1503
1504 // VG(8/15/02): Emit the jcc over a conditional snippet
1505 void emitJmpMC(int condition, int offset, codeGen &gen)
1506 {
1507     // What we want: 
1508     //   mov eax, [original EFLAGS]
1509     //   push eax
1510     //   popfd
1511     //   jCC target   ; CC = !condition (we jump on the negated condition)
1512     
1513     assert(condition >= 0 && condition <= 0x0F);
1514     
1515     //bperr("OC: %x, NC: %x\n", condition, condition ^ 0x01);
1516     condition ^= 0x01; // flip last bit to negate the tttn condition
1517     
1518     gen.codeEmitter()->emitRestoreFlagsFromStackSlot(gen);
1519     emitJcc(condition, offset, gen);
1520 }
1521
1522 stackItemLocation getHeightOf(stackItem sitem, codeGen &gen)
1523 {
1524    int offset = 0;
1525    RealRegister reg;
1526
1527    int addr_width = gen.addrSpace()->getAddressWidth();
1528    RealRegister plat_bp(addr_width == 4 ? REGNUM_EBP : REGNUM_RBP);
1529    RealRegister plat_sp(addr_width == 4 ? REGNUM_ESP : REGNUM_RSP); 
1530
1531    if (sitem.item == stackItem::reg_item && sitem.reg.reg() == plat_sp.reg())
1532    {
1533       sitem.item = stackItem::stacktop;
1534    }
1535
1536    switch (sitem.item)
1537    {
1538       case stackItem::reg_item:
1539       {
1540          registerSlot *r = NULL;
1541          pdvector<registerSlot *> &regs = gen.rs()->trampRegs();
1542          for (unsigned i=0; i<regs.size(); i++) {
1543             if (regs[i]->number == (unsigned) sitem.reg.reg()) {
1544                r = regs[i];
1545                break;
1546             }
1547          }
1548          if (!r && addr_width == 8) {
1549             r = (*gen.rs())[sitem.reg.reg()];
1550          }
1551          assert(r);
1552          offset = r->saveOffset * addr_width;
1553          if (gen.bti()->hasStackFrame()) {
1554             reg = plat_bp;
1555             return stackItemLocation(plat_bp, offset);
1556          }
1557          if (gen.bti()->hasLocalSpace()) {
1558             offset += TRAMP_FRAME_SIZE;
1559          }
1560          offset += gen.rs()->getStackHeight();
1561          return stackItemLocation(plat_sp, offset);
1562       }
1563       case stackItem::stacktop:
1564       {
1565          if (addr_width == 8)
1566             offset += STACK_PAD_CONSTANT;
1567          if (!gen.bti() || gen.bti()->flagsSaved())
1568             offset += addr_width;
1569          pdvector<registerSlot *> &regs = gen.rs()->trampRegs();
1570          for (unsigned i=0; i<regs.size(); i++) {
1571             registerSlot *reg = regs[i];
1572             if (reg->spilledState != registerSlot::unspilled)
1573                offset += addr_width;
1574          }
1575          offset += (gen.bti()->funcJumpSlotSize() * addr_width);
1576          if (gen.bti()->hasStackFrame()) {
1577             //Save of EBP adds addr_width--ebp may have been counted once above
1578             // and here again if a pusha and frame were created, but that's
1579             // okay.
1580             offset += addr_width; 
1581             return stackItemLocation(plat_bp, offset);
1582          }
1583          if (gen.bti()->hasLocalSpace()) {
1584             offset += TRAMP_FRAME_SIZE;
1585          }
1586          offset += gen.rs()->getStackHeight();
1587          return stackItemLocation(plat_sp, offset);
1588       }
1589       case stackItem::framebase: {
1590          if (!gen.bti() || gen.bti()->hasStackFrame()) {
1591             return stackItemLocation(plat_bp, 0);
1592          }
1593          offset = gen.rs()->getStackHeight();
1594          if (gen.bti()->hasLocalSpace()) {
1595             offset += TRAMP_FRAME_SIZE;
1596          }
1597          return stackItemLocation(plat_sp, offset);
1598       }
1599    }
1600    assert(0);
1601    return stackItemLocation(RealRegister(REG_NULL), 0);
1602 }
1603
1604 // Restore mutatee value of GPR reg to dest (real) GPR
1605 Register restoreGPRtoReg(RealRegister reg, codeGen &gen, RealRegister *dest_to_use)
1606 {
1607    Register dest = REG_NULL;
1608    RealRegister dest_r(-1);
1609    if (dest_to_use) {
1610       dest_r = *dest_to_use;
1611    }
1612    else {
1613       dest = gen.rs()->getScratchRegister(gen);
1614    }
1615    
1616    if (reg.reg() == REGNUM_EBP) {
1617       //Special handling for EBP with and without instr stack frame
1618       if (dest_r.reg() == -1)
1619          dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
1620       if (gen.bti()->hasStackFrame()) {
1621          emitMovRMToReg(dest_r, RealRegister(REGNUM_EBP), 0, gen);
1622       }
1623       else {
1624          if (reg.reg() != dest_r.reg()) {
1625             //TODO: Future optimization here, allow ebp to be used
1626             // though not allocated
1627             emitMovRegToReg(dest_r, reg, gen);
1628          }
1629       }
1630       return dest;
1631    }
1632
1633    if (reg.reg() == REGNUM_ESP) {
1634       //Special handling for ESP 
1635       if (dest_r.reg() == -1)
1636          dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
1637       stackItemLocation loc = getHeightOf(stackItem(stackItem::stacktop), gen);
1638       if (loc.reg.reg() == REGNUM_EBP) {
1639          emitLEA(RealRegister(REGNUM_EBP), loc.offset, dest_r, gen);
1640       }
1641       else {
1642          emitLEA(RealRegister(REGNUM_ESP), RealRegister(Null_Register), 0, 
1643                  loc.offset, dest_r, gen);
1644       }
1645       return dest;
1646    }
1647
1648    registerSlot *r = gen.rs()->trampRegs()[reg.reg()];
1649    if (r->spilledState == registerSlot::unspilled ||
1650        !gen.isRegDefined(reg.reg())) 
1651    {
1652       //Register is still in its pristine state from app, leave it.
1653       if (dest_r.reg() == -1)
1654          gen.rs()->noteVirtualInReal(dest, reg);
1655       else if (dest_r.reg() != reg.reg())
1656          emitMovRegToReg(dest_r, reg, gen);
1657       return dest;
1658    }
1659
1660    //Load register from its saved location
1661    stackItemLocation loc = getHeightOf(stackItem(reg), gen);
1662    emitMovRMToReg(dest_r, loc.reg, loc.offset, gen);
1663    return dest;
1664 }
1665
1666 void restoreGPRtoGPR(RealRegister src, RealRegister dest, codeGen &gen)
1667 {
1668    restoreGPRtoReg(src, gen, &dest);
1669 }
1670
1671 // VG(11/07/01): Load in destination the effective address given
1672 // by the address descriptor. Used for memory access stuff.
1673 void emitASload(const BPatch_addrSpec_NP *as, Register dest, codeGen &gen, bool /* noCost */)
1674 {
1675     // TODO 16-bit registers, rep hacks
1676     long imm = as->getImm();
1677     int ra  = as->getReg(0);
1678     int rb  = as->getReg(1);
1679     int sc  = as->getScale();
1680
1681     gen.codeEmitter()->emitASload(ra, rb, sc, imm, dest, gen);
1682 }
1683
1684 void EmitterIA32::emitASload(int ra, int rb, int sc, long imm, Register dest, codeGen &gen)
1685 {
1686    bool havera = ra > -1, haverb = rb > -1;
1687    
1688    // assuming 32-bit addressing (for now)
1689    
1690    if (ra == REGNUM_ESP && !haverb && sc == 0 && gen.bti()) {
1691       //Optimization, common for push/pop
1692       RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
1693       stackItemLocation loc = getHeightOf(stackItem(stackItem::stacktop), gen);
1694       if (loc.reg.reg() == REGNUM_EBP) {
1695          emitLEA(RealRegister(REGNUM_EBP), loc.offset + imm, dest_r, gen);
1696       }
1697       else {
1698          emitLEA(RealRegister(REGNUM_ESP), RealRegister(Null_Register), 0, 
1699                  loc.offset + imm, dest_r, gen);
1700       }
1701       return;
1702    }
1703
1704    RealRegister src1_r(-1);
1705    Register src1 = REG_NULL;
1706    if (havera) {
1707       src1 = restoreGPRtoReg(RealRegister(ra), gen);
1708       src1_r = gen.rs()->loadVirtual(src1, gen);
1709    }
1710
1711    RealRegister src2_r(-1);
1712    Register src2 = REG_NULL;
1713    if (haverb) {
1714       if (ra == rb) {
1715          src2_r = src1_r;
1716       }
1717       else {
1718          src2 = restoreGPRtoReg(RealRegister(rb), gen);
1719          src2_r = gen.rs()->loadVirtual(src2, gen);
1720       }
1721    }
1722    
1723    if (havera && !haverb && !sc && !imm) {
1724       //Optimized case, just use the existing src1_r
1725       gen.rs()->freeRegister(src1);
1726       gen.rs()->noteVirtualInReal(dest, src1_r);
1727       return;
1728    }
1729
1730    // Emit the lea to do the math for us:
1731    // e.g. lea eax, [eax + edx * sc + imm] if both ra and rb had to be
1732    // restored
1733    RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);      
1734    emitLEA(src1_r, src2_r, sc, (long) imm, dest_r, gen);   
1735
1736    if (src1 != REG_NULL)
1737       gen.rs()->freeRegister(src1);
1738    if (src2 != REG_NULL)
1739       gen.rs()->freeRegister(src2);
1740 }
1741
1742 void emitCSload(const BPatch_countSpec_NP *as, Register dest,
1743                 codeGen &gen, bool /* noCost */ )
1744 {
1745    // VG(7/30/02): different from ASload on this platform, no LEA business
1746
1747    long imm = as->getImm();
1748    int ra  = as->getReg(0);
1749    int rb  = as->getReg(1);
1750    int sc  = as->getScale();
1751
1752    gen.codeEmitter()->emitCSload(ra, rb, sc, imm, dest, gen);
1753 }
1754
1755 void EmitterIA32::emitCSload(int ra, int rb, int sc, long imm, Register dest, codeGen &gen)
1756 {
1757    // count is at most 1 register or constant or hack (aka pseudoregister)
1758    assert((ra == -1) &&
1759           ((rb == -1) ||
1760             ((imm == 0) && (rb == 1 /*REGNUM_ECX */ || rb >= IA32_EMULATE))));
1761
1762    if(rb >= IA32_EMULATE) {
1763       //Calculate the location of the flags register.  Flags are saved
1764       //one stack slot above the first saved original register.
1765       int max_saved = 0;
1766       pdvector<registerSlot *> &regs = gen.rs()->trampRegs();
1767       for (int i=regs.size()-1; i>=0; i--) {
1768          registerSlot *reg = regs[i];          
1769          if (reg->spilledState != registerSlot::unspilled &&
1770              max_saved < reg->saveOffset)
1771             max_saved = reg->saveOffset;
1772       }
1773       int flags_slot = max_saved + 1;
1774            
1775       bool neg = false;
1776       //bperr( "!!!In case rb >= IA32_EMULATE!!!\n");
1777       switch(rb) {
1778         case IA32_NESCAS:
1779            neg = true;
1780         case IA32_ESCAS: {
1781            // plan: restore flags, edi, eax, ecx; do rep(n)e scas(b/w);
1782            // compute (saved_ecx - ecx) << sc;
1783
1784            gen.rs()->makeRegisterAvail(RealRegister(REGNUM_EAX), gen);
1785            gen.rs()->makeRegisterAvail(RealRegister(REGNUM_ECX), gen);
1786            gen.rs()->makeRegisterAvail(RealRegister(REGNUM_EDI), gen);
1787            
1788            // mov eax<-offset[ebp]
1789            emitMovRMToReg(RealRegister(REGNUM_EAX), RealRegister(REGNUM_EBP), 
1790                           flags_slot, gen);
1791
1792            emitSimpleInsn(0x50, gen);  // push eax
1793            emitSimpleInsn(POPFD, gen); // popfd
1794            restoreGPRtoGPR(RealRegister(REGNUM_EAX), RealRegister(REGNUM_EAX), gen); 
1795            restoreGPRtoGPR(RealRegister(REGNUM_ECX), RealRegister(REGNUM_ECX), gen);
1796            restoreGPRtoGPR(RealRegister(REGNUM_EDI), RealRegister(REGNUM_EDI), gen);
1797            gen.markRegDefined(REGNUM_EAX);
1798            gen.markRegDefined(REGNUM_ECX);
1799            gen.markRegDefined(REGNUM_EDI);
1800            emitSimpleInsn(neg ? 0xF2 : 0xF3, gen); // rep(n)e
1801            switch(sc) {
1802              case 0:
1803                 emitSimpleInsn(0xAE, gen); // scasb
1804                 break;
1805              case 1:
1806                 emitSimpleInsn(0x66, gen); // operand size override for scasw;
1807              case 2:
1808                 emitSimpleInsn(0xAF, gen); // scasw/d
1809                 break;
1810              default:
1811                 assert(!"Wrong scale!");
1812            }
1813            restoreGPRtoGPR(RealRegister(REGNUM_ECX), RealRegister(REGNUM_EAX), gen); // old ecx -> eax
1814            emitSubRegReg(RealRegister(REGNUM_EAX), RealRegister(REGNUM_ECX), gen); // eax = eax - ecx
1815            gen.markRegDefined(REGNUM_EAX);
1816            if(sc > 0)
1817               emitSHL(RealRegister(REGNUM_EAX), static_cast<unsigned char>(sc), gen); // shl eax, scale
1818            RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
1819            emitMovRegToReg(dest_r, RealRegister(REGNUM_EAX), gen);
1820            break;
1821         }
1822         case IA32_NECMPS:
1823            neg = true;
1824         case IA32_ECMPS: {
1825            // plan: restore flags, esi, edi, ecx; do rep(n)e cmps(b/w);
1826            // compute (saved_ecx - ecx) << sc;
1827
1828            gen.rs()->makeRegisterAvail(RealRegister(REGNUM_EAX), gen);
1829            gen.rs()->makeRegisterAvail(RealRegister(REGNUM_ESI), gen);
1830            gen.rs()->makeRegisterAvail(RealRegister(REGNUM_EDI), gen);
1831            gen.rs()->makeRegisterAvail(RealRegister(REGNUM_ECX), gen);
1832            
1833            // mov eax<-offset[ebp]
1834            emitMovRMToReg(RealRegister(REGNUM_EAX), RealRegister(REGNUM_EBP), 
1835                           flags_slot, gen);
1836
1837            emitSimpleInsn(0x50, gen);  // push eax
1838            emitSimpleInsn(POPFD, gen); // popfd
1839            restoreGPRtoGPR(RealRegister(REGNUM_ECX), RealRegister(REGNUM_ECX), gen);
1840            gen.markRegDefined(REGNUM_ECX);
1841            restoreGPRtoGPR(RealRegister(REGNUM_ESI), RealRegister(REGNUM_ESI), gen);
1842            gen.markRegDefined(REGNUM_ESI);
1843            restoreGPRtoGPR(RealRegister(REGNUM_EDI), RealRegister(REGNUM_EDI), gen);
1844            gen.markRegDefined(REGNUM_EDI);
1845            emitSimpleInsn(neg ? 0xF2 : 0xF3, gen); // rep(n)e
1846            switch(sc) {
1847              case 0:
1848                 emitSimpleInsn(0xA6, gen); // cmpsb
1849                 break;
1850              case 1:
1851                 emitSimpleInsn(0x66, gen); // operand size override for cmpsw;
1852              case 2:
1853                 emitSimpleInsn(0xA7, gen); // cmpsw/d
1854                 break;
1855              default:
1856                 assert(!"Wrong scale!");
1857            }
1858            restoreGPRtoGPR(RealRegister(REGNUM_ECX), RealRegister(REGNUM_EAX), gen); // old ecx -> eax
1859            emitSubRegReg(RealRegister(REGNUM_EAX), RealRegister(REGNUM_ECX), gen); // eax = eax - ecx
1860            if(sc > 0)
1861               emitSHL(RealRegister(REGNUM_EAX), static_cast<unsigned char>(sc), gen); // shl eax, scale
1862            RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
1863            emitMovRegToReg(dest_r, RealRegister(REGNUM_EAX), gen);
1864
1865            break;
1866         }
1867         default:
1868            assert(!"Wrong emulation!");
1869       }
1870    }
1871    else if(rb > -1) {
1872       //bperr( "!!!In case rb > -1!!!\n");
1873       // TODO: 16-bit pseudoregisters
1874       assert(rb < 8); 
1875       RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
1876       restoreGPRtoGPR(RealRegister(rb), dest_r, gen); // mov dest, [saved_rb]
1877       if(sc > 0)
1878          emitSHL(dest_r, static_cast<unsigned char>(sc), gen); // shl eax, scale
1879    }
1880    else {
1881       RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
1882       emitMovImmToReg(dest_r, imm, gen);
1883    }
1884 }
1885
1886 void emitVload(opCode op, Address src1, Register src2, Register dest, 
1887                codeGen &gen, bool /*noCost*/, 
1888                registerSpace * /*rs*/, int size,
1889                const instPoint * /* location */, AddressSpace * /* proc */)
1890 {
1891    if (op == loadConstOp) {
1892       // dest is a temporary
1893       // src1 is an immediate value 
1894       // dest = src1:imm32
1895        gen.codeEmitter()->emitLoadConst(dest, src1, gen);
1896       return;
1897    } else if (op ==  loadOp) {
1898       // dest is a temporary
1899       // src1 is the address of the operand
1900       // dest = [src1]
1901        gen.codeEmitter()->emitLoad(dest, src1, size, gen);
1902       return;
1903    } else if (op == loadFrameRelativeOp) {
1904       // dest is a temporary
1905       // src1 is the offset of the from the frame of the variable
1906        gen.codeEmitter()->emitLoadOrigFrameRelative(dest, src1, gen);
1907        return;
1908    } else if (op == loadRegRelativeOp) {
1909       // dest is a temporary
1910       // src2 is the register 
1911       // src1 is the offset from the address in src2
1912       gen.codeEmitter()->emitLoadOrigRegRelative(dest, src1, src2, gen, true);
1913       return;
1914    } else if (op == loadRegRelativeAddr) {
1915       // dest is a temporary
1916       // src2 is the register 
1917       // src1 is the offset from the address in src2
1918       gen.codeEmitter()->emitLoadOrigRegRelative(dest, src1, src2, gen, false);
1919       return;
1920    } else if (op == loadFrameAddr) {
1921        gen.codeEmitter()->emitLoadFrameAddr(dest, src1, gen);
1922        return;
1923    } else {
1924       abort();                // unexpected op for this emit!
1925    }
1926 }
1927
1928 void emitVstore(opCode op, Register src1, Register src2, Address dest,
1929                 codeGen &gen, bool /*noCost*/, registerSpace * /*rs*/, 
1930                 int size,
1931                 const instPoint * /* location */, AddressSpace * /* proc */)
1932 {
1933    if (op ==  storeOp) {
1934       // [dest] = src1
1935       // dest has the address where src1 is to be stored
1936       // src1 is a temporary
1937       // src2 is a "scratch" register, we don't need it in this architecture
1938        gen.codeEmitter()->emitStore(dest, src1, size, gen);
1939       return;
1940    } else if (op == storeFrameRelativeOp) {
1941        // src1 is a temporary
1942        // src2 is a "scratch" register, we don't need it in this architecture
1943        // dest is the frame offset 
1944        gen.codeEmitter()->emitStoreFrameRelative(dest, src1, src2, size, gen);
1945        return;
1946    } else {
1947        abort();                // unexpected op for this emit!
1948    }
1949 }
1950
1951 void emitV(opCode op, Register src1, Register src2, Register dest, 
1952            codeGen &gen, bool /*noCost*/, 
1953            registerSpace * /*rs*/, int size,
1954            const instPoint * /* location */, AddressSpace * /* proc */)
1955 {
1956     //bperr( "emitV(op=%d,src1=%d,src2=%d,dest=%d)\n", op, src1,
1957     //        src2, dest);
1958     
1959     assert ((op!=branchOp) && (op!=ifOp) &&
1960             (op!=trampPreamble));         // !emitA
1961     assert ((op!=getRetValOp) && (op!=getParamOp));             // !emitR
1962     assert ((op!=loadOp) && (op!=loadConstOp));                 // !emitVload
1963     assert ((op!=storeOp));                                     // !emitVstore
1964     assert ((op!=updateCostOp));                                // !emitVupdate
1965     
1966     if (op ==  loadIndirOp) {
1967         // same as loadOp, but the value to load is already in a register
1968        gen.codeEmitter()->emitLoadIndir(dest, src1, size, gen);
1969     } 
1970     else if (op ==  storeIndirOp) {
1971         // same as storeOp, but the address where to store is already in a
1972         // register
1973        gen.codeEmitter()->emitStoreIndir(dest, src1, size, gen);
1974     } else if (op == noOp) {
1975         emitSimpleInsn(NOP, gen); // nop
1976     } else if (op == saveRegOp) {
1977         // Push....
1978         assert(src2 == 0);
1979         assert(dest == 0);
1980         gen.codeEmitter()->emitPush(gen, src1);
1981     } else if (op == loadRegOp) {
1982         assert(src1 == 0);
1983         assert(src2 == 0);
1984         gen.codeEmitter()->emitPop(gen, dest);
1985     } else {
1986         unsigned opcode = 0;//initialize to placate gcc warnings
1987         switch (op) {
1988             // integer ops
1989         case plusOp:
1990             // dest = src1 + src2
1991             // mv eax, src1
1992             // add eax, src2
1993             // mov dest, eax
1994             opcode = 0x03; // ADD
1995             break;
1996             
1997         case minusOp:
1998             opcode = 0x2B; // SUB
1999             break;
2000             
2001         case timesOp:
2002             opcode = 0x0FAF; // IMUL
2003             break;
2004
2005         case divOp: {
2006            // dest = src1 div src2
2007            gen.codeEmitter()->emitDiv(dest, src1, src2, gen);
2008            return;
2009            break;
2010         }
2011            // Bool ops
2012         case orOp:
2013            opcode = 0x0B; // OR 
2014            break;
2015
2016         case andOp:
2017            opcode = 0x23; // AND
2018            break;
2019
2020            // rel ops
2021            // dest = src1 relop src2
2022         case eqOp:
2023         case neOp:
2024         case lessOp:
2025         case leOp:
2026         case greaterOp:
2027         case geOp: {
2028             gen.codeEmitter()->emitRelOp(op, dest, src1, src2, gen);
2029             return;
2030             break;
2031         }
2032         default:
2033             abort();
2034             break;
2035         }
2036         gen.codeEmitter()->emitOp(opcode, dest, src1, src2, gen);
2037     }
2038     return;
2039 }
2040
2041 void emitImm(opCode op, Register src1, RegValue src2imm, Register dest, 
2042              codeGen &gen, bool, registerSpace *)
2043 {
2044    if (op ==  storeOp) {
2045        // this doesn't seem to ever be called from ast.C (or anywhere) - gq
2046
2047       // [dest] = src1
2048       // dest has the address where src1 is to be stored
2049       // src1 is an immediate value
2050       // src2 is a "scratch" register, we don't need it in this architecture
2051       emitMovImmToReg(RealRegister(REGNUM_EAX), dest, gen);
2052       emitMovImmToRM(RealRegister(REGNUM_EAX), 0, src1, gen);
2053    } else {
2054       unsigned opcode1;
2055       unsigned opcode2;
2056       switch (op) {
2057          // integer ops
2058          case plusOp:
2059             opcode1 = 0x81;
2060             opcode2 = 0x0; // ADD
2061             break;            
2062          case minusOp:
2063             opcode1 = 0x81;
2064             opcode2 = 0x5; // SUB
2065             break;            
2066          case timesOp:
2067             gen.codeEmitter()->emitTimesImm(dest, src1, src2imm, gen);
2068             return;
2069          case divOp:
2070             gen.codeEmitter()->emitDivImm(dest, src1, src2imm, gen);
2071             return;
2072          // Bool ops
2073          case orOp:
2074             opcode1 = 0x81;
2075             opcode2 = 0x1; // OR 
2076             break;            
2077          case andOp:
2078            opcode1 = 0x81;
2079            opcode2 = 0x4; // AND
2080            break;
2081          // rel ops
2082          // dest = src1 relop src2
2083          case eqOp:
2084          case neOp:
2085          case lessOp:
2086          case leOp:
2087          case greaterOp:
2088          case geOp:
2089             gen.codeEmitter()->emitRelOpImm(op, dest, src1, src2imm, gen);
2090             return;
2091          default:
2092           abort();
2093           break;
2094       }
2095       gen.codeEmitter()->emitOpImm(opcode1, opcode2, dest, src1, src2imm, gen);
2096    }
2097    return;
2098 }
2099
2100
2101 // TODO: mux this between x86 and AMD64
2102 int getInsnCost(opCode op)
2103 {
2104    if (op == loadConstOp) {
2105       return(1);
2106    } else if (op ==  loadOp) {
2107       return(1+1);
2108    } else if (op ==  loadIndirOp) {
2109       return(3);
2110    } else if (op ==  storeOp) {
2111       return(1+1); 
2112    } else if (op ==  storeIndirOp) {
2113       return(3);
2114    } else if (op ==  ifOp) {
2115       return(1+2+1);
2116    } else if (op ==  ifMCOp) { // VG(8/15/02): No clue if this is right or not
2117       return(1+2+1);
2118    } else if (op ==  whileOp) {
2119       return(1+2+1+1); /* Need to find out about this */
2120    } else if (op == branchOp) {
2121       return(1);        /* XXX Need to find out what value this should be. */
2122    } else if (op ==  callOp) {
2123       // cost of call only
2124       return(1+2+1+1);
2125    } else if (op == funcJumpOp) {
2126       // copy callOp
2127       return(1+2+1+1);
2128    } else if (op == updateCostOp) {
2129       return(3);
2130    } else if (op ==  trampPreamble) {
2131       return(0);
2132    } else if (op == noOp) {
2133       return(1);
2134    } else if (op == getRetValOp) {
2135       return (1+1);
2136    } else if (op == getParamOp) {
2137       return(1+1);
2138    } else {
2139       switch (op) {
2140          // rel ops
2141         case eqOp:
2142         case neOp:
2143         case lessOp:
2144         case leOp:
2145         case greaterOp:
2146         case geOp:
2147                 return(1+1+2+1+1+1);
2148                 break;
2149         case divOp:
2150            return(1+2+46+1);
2151         case timesOp:
2152            return(1+10+1);
2153         case plusOp:
2154         case minusOp:
2155         case orOp:
2156         case andOp:
2157            return(1+2+1);
2158         case getAddrOp:
2159            return(0);   // doesn't add anything to operand
2160         default:
2161            assert(0);
2162            return 0;
2163            break;
2164       }
2165    }
2166    return 0;
2167 }
2168
2169
2170 //
2171 // return cost in cycles of executing at this point.  This is the cost
2172 //   of the base tramp if it is the first at this point or 0 otherwise.
2173 //
2174 // We now have multiple versions of instrumentation... so, how does this work?
2175 // We look for a local maximum.
2176 int instPoint::getPointCost()
2177 {
2178   unsigned worstCost = 0;
2179   for (unsigned i = 0; i < instances.size(); i++) {
2180       if (instances[i]->multi()) {
2181           if (instances[i]->multi()->usesTrap()) {
2182               // Stop right here
2183               // Actually, probably don't want this if the "always
2184               // delivered" instrumentation happens
2185               return 9000; // Estimated trap cost
2186           }
2187           else {
2188               // Base tramp cost if we're first at point, otherwise
2189               // free (someone else paid)
2190               // Which makes no sense, since we're talking an entire instPoint.
2191               // So if there is a multitramp hooked up we use the base tramp cost.
2192               worstCost = 83; // Magic constant from before time
2193           }
2194       }
2195       else {
2196           // No multiTramp, so still free (we're not instrumenting here).
2197       }
2198   }
2199   return worstCost;
2200 }
2201
2202 unsigned baseTramp::getBTCost() {
2203     // Check this...
2204     return 83;
2205 }
2206
2207 // Emit code to jump to function CALLEE without linking.  (I.e., when
2208 // CALLEE returns, it returns to the current caller.)
2209 void emitFuncJump(opCode op, 
2210                   codeGen &gen,
2211                   int_function *callee, AddressSpace *,
2212                   const instPoint *loc, bool)
2213 {
2214    // This must mimic the generateRestores baseTramp method. 
2215     assert(op == funcJumpOp || op == funcCallOp);
2216
2217     instPointType_t ptType = loc->getPointType();
2218     gen.codeEmitter()->emitFuncJump(callee, ptType, (op == funcCallOp), gen);
2219 }
2220
2221 #define MAX_SINT ((signed int) (0x7fffffff))
2222 #define MIN_SINT ((signed int) (0x80000000))
2223 void EmitterIA32::emitFuncJump(int_function *f, instPointType_t /*ptType*/, bool callOp,
2224                                codeGen &gen)
2225 {       
2226     assert(gen.bti());
2227     Address addr = f->getAddress();
2228     signed int disp = addr - (gen.currAddr()+5);
2229
2230     if (callOp) {
2231        //Set up a slot on the stack for the return address
2232
2233        //Get the current PC.
2234        Register dest = gen.rs()->getScratchRegister(gen);
2235        RealRegister dest_r = gen.rs()->loadVirtualForWrite(dest, gen);
2236        GET_PTR(patch_start, gen);
2237        emitMovPCRMToReg(dest_r, 0, gen, false);
2238        
2239        //Add the distance from the current PC to the end if this
2240        // baseTramp (which isn't known yet).
2241        GET_PTR(insn, gen);
2242        *insn++ = 0x81;
2243        *insn++ = makeModRMbyte(3, 0, dest_r.reg());
2244        void *patch_loc = (void *) insn;
2245        *((int *)insn) = 0x0;
2246        insn += sizeof(int);
2247        SET_PTR(insn, gen);
2248
2249        //Store the computed return address into the stack slot.
2250        stackItemLocation loc = getHeightOf(stackItem::stacktop, gen);
2251        emitMovRegToRM(loc.reg, loc.offset-4, dest_r, gen);
2252        gen.rs()->freeRegister(dest);
2253
2254        //Create a patch to fill in the end of the baseTramp to the above
2255        // instruction when it becomes known.
2256        generatedCodeObject *nextobj = gen.bti()->nextObj()->nextObj();
2257        assert(nextobj);
2258        int offset = ((unsigned long) patch_start) - ((unsigned long) gen.start_ptr());
2259        relocPatch newPatch(patch_loc, nextobj, relocPatch::pcrel, &gen, 
2260                            offset, sizeof(int));
2261        gen.addPatch(newPatch);
2262     }
2263
2264     if (f->proc() == gen.addrSpace() &&
2265         gen.startAddr() &&
2266        disp < MAX_SINT &&
2267        disp > MIN_SINT)
2268     {
2269        //Same module or dynamic instrumentation and address and within
2270        // jump distance.
2271        cfjRet_t tmp = gen.bti()->hasFuncJump();
2272        gen.bti()->setHasFuncJump(cfj_jump);
2273        emitBTRestores(gen.bti()->baseT, gen.bti(), gen);
2274        gen.bti()->setHasFuncJump(tmp);
2275
2276        int disp = addr - (gen.currAddr()+5);
2277        emitJump(disp, gen);
2278     }
2279     else if (dynamic_cast<process *>(gen.addrSpace())) {
2280        //Dynamic instrumentation, emit an absolute jump (push/ret combo)
2281        cfjRet_t tmp = gen.bti()->hasFuncJump();
2282        gen.bti()->setHasFuncJump(cfj_jump);
2283        emitBTRestores(gen.bti()->baseT, gen.bti(), gen);
2284        gen.bti()->setHasFuncJump(tmp);
2285
2286        GET_PTR(insn, gen);
2287        *insn++ = 0x68; /* push 32 bit immediate */
2288        *((int *)insn) = addr; /* the immediate */
2289        insn += 4;
2290        *insn++ = 0xc3; /* ret */
2291        SET_PTR(insn, gen);
2292     }
2293     else if (dynamic_cast<BinaryEdit *>(gen.addrSpace())) {
2294        //Static instrumentation, calculate and store the target 
2295        // value to the top of our instrumentation stack and return to it.
2296        assert(gen.bti() && gen.bti()->hasFuncJump());
2297
2298        //Get address of target into realr
2299        Register reg = gen.rs()->getScratchRegister(gen);
2300        RealRegister realr = gen.rs()->loadVirtualForWrite(reg, gen);
2301        Address dest = getInterModuleFuncAddr(f, gen);
2302        emitMovPCRMToReg(realr, dest-gen.currAddr(), gen);
2303        //Mov realr to stack slot
2304        stackItemLocation loc = getHeightOf(stackItem::stacktop, gen);
2305        int top_offset = callOp ? -8 : -4;
2306        emitMovRegToRM(loc.reg, loc.offset+top_offset, realr, gen);
2307
2308        //Temporarily unset the hasFuncJump so that when we restore the BT
2309        // the funcJump slot is not cleaned.
2310        cfjRet_t tmp = gen.bti()->hasFuncJump();
2311        gen.bti()->setHasFuncJump(cfj_none);
2312        emitBTRestores(gen.bti()->baseT, gen.bti(), gen);
2313        gen.bti()->setHasFuncJump(tmp);
2314
2315        //The address should be left on the stack.  Just return now.
2316        GET_PTR(insn, gen);
2317        *insn++ = 0xc3;
2318        SET_PTR(insn, gen);
2319     }
2320
2321     instruction::generateIllegal(gen);
2322 }
2323
2324 bool EmitterIA32::emitPush(codeGen &gen, Register reg) {
2325     RealRegister real_reg = gen.rs()->loadVirtual(reg, gen);
2326     return ::emitPush(real_reg, gen);
2327 }
2328
2329 bool EmitterIA32::emitPop(codeGen &gen, Register reg) {
2330     RealRegister real_reg = gen.rs()->loadVirtual(reg, gen);
2331     return ::emitPop(real_reg, gen);
2332 }
2333
2334 bool emitPush(RealRegister reg, codeGen &gen) {
2335     GET_PTR(insn, gen);
2336     int r = reg.reg();
2337     assert(r < 8);
2338
2339     *insn++ = static_cast<unsigned char>(0x50 + r); // 0x50 is push EAX, and it increases from there.
2340
2341     SET_PTR(insn, gen);
2342     gen.rs()->incStack(4);
2343     return true;
2344 }
2345
2346 bool emitPop(RealRegister reg, codeGen &gen) {
2347     GET_PTR(insn, gen);
2348     int r = reg.reg();
2349     assert(r < 8);
2350     *insn++ = static_cast<unsigned char>(0x58 + r);    
2351     SET_PTR(insn, gen);
2352     gen.rs()->incStack(-4);
2353     return true;
2354 }
2355
2356 bool EmitterIA32::emitAdjustStackPointer(int index, codeGen &gen) {
2357         // The index will be positive for "needs popped" and negative
2358         // for "needs pushed". However, positive + SP works, so don't
2359         // invert.
2360         int popVal = index * gen.addrSpace()->getAddressWidth();
2361         emitOpExtRegImm(0x81, EXTENDED_0x81_ADD, RealRegister(REGNUM_ESP), popVal, gen);
2362    gen.rs()->incStack(-1 * popVal);
2363         return true;
2364 }
2365
2366
2367 void emitLoadPreviousStackFrameRegister(Address register_num,
2368                                         Register dest,
2369                                         codeGen &gen,
2370                                         int,
2371                                         bool){
2372     gen.codeEmitter()->emitLoadOrigRegister(register_num, dest, gen);
2373 }
2374
2375 void emitStorePreviousStackFrameRegister(Address register_num,
2376                                         Register src,
2377                                         codeGen &gen,
2378                                         int,
2379                                         bool) {
2380     gen.codeEmitter()->emitStoreOrigRegister(register_num, src, gen);
2381 }
2382
2383 // First AST node: target of the call
2384 // Second AST node: source of the call
2385 // This can handle indirect control transfers as well 
2386 bool AddressSpace::getDynamicCallSiteArgs(instPoint *callSite,
2387                                           pdvector<AstNodePtr> &args)
2388 {
2389    using namespace Dyninst::InstructionAPI;        
2390    Expression::Ptr cft = callSite->insn()->getControlFlowTarget();
2391    ASTFactory f;
2392    cft->apply(&f);
2393    assert(f.m_stack.size() == 1);
2394    args.push_back(f.m_stack[0]);
2395    args.push_back(AstNode::operandNode(AstNode::Constant,
2396                                        (void *) callSite->addr()));
2397    inst_printf("%s[%d]:  Inserting dynamic call site instrumentation for %s\n",
2398                FILE__, __LINE__, cft->format().c_str());
2399    return true;
2400 }
2401
2402 /****************************************************************************/
2403 /****************************************************************************/
2404
2405 int getMaxJumpSize()
2406 {
2407   return JUMP_REL32_SZ;
2408 }
2409
2410 // TODO: fix this so we don't screw future instrumentation of this
2411 // function. It's a cute little hack, but jeez.
2412 bool int_function::setReturnValue(int val)
2413 {
2414     codeGen gen(16);
2415
2416     Address addr = getAddress();
2417     emitMovImmToReg(RealRegister(REGNUM_EAX), val, gen);
2418     emitSimpleInsn(0xc3, gen); //ret
2419     
2420     return proc()->writeTextSpace((void *) addr, gen.used(), gen.start_ptr());
2421 }
2422
2423 unsigned saveRestoreRegistersInBaseTramp(process * /*proc*/, 
2424                                          baseTramp * /*bt*/,
2425                                          registerSpace * /*rs*/)
2426 {
2427   return 0;
2428 }
2429
2430 /**
2431  * Fills in an indirect function pointer at 'addr' to point to 'f'.
2432  **/
2433 bool writeFunctionPtr(AddressSpace *p, Address addr, int_function *f)
2434 {
2435    Address val_to_write = f->getAddress();
2436    return p->writeDataSpace((void *) addr, sizeof(Address), &val_to_write);   
2437 }
2438
2439 int instPoint::liveRegSize()
2440 {
2441   return maxGPR;
2442 }
2443
2444 bool emitStoreConst(Address addr, int imm, codeGen &gen, bool noCost) {
2445    gen.codeEmitter()->emitStoreImm(addr, imm, gen, noCost);
2446    return true;
2447 }
2448
2449 bool emitAddSignedImm(Address addr, long int imm, codeGen &gen, bool noCost) {
2450    gen.codeEmitter()->emitAddSignedImm(addr, imm, gen, noCost);
2451    return true;
2452 }
2453
2454 bool emitSubSignedImm(Address addr, long int imm, codeGen &gen, bool noCost) {
2455    gen.codeEmitter()->emitAddSignedImm(addr, imm * -1, gen, noCost);
2456    return true;
2457 }
2458
2459 Emitter *AddressSpace::getEmitter() 
2460 {
2461    static EmitterIA32Dyn emitter32Dyn;
2462    static EmitterIA32Stat emitter32Stat;
2463
2464 #if defined(arch_x86_64)
2465    static EmitterAMD64Dyn emitter64Dyn;
2466    static EmitterAMD64Stat emitter64Stat;
2467
2468    if (getAddressWidth() == 8) {
2469        if (proc()) {
2470            return &emitter64Dyn;
2471        }
2472        else {
2473            assert(edit());
2474            return &emitter64Stat;
2475        }
2476    }
2477 #endif
2478    if (proc()) {
2479        return &emitter32Dyn;
2480    }
2481    else {
2482        assert(edit());
2483        return &emitter32Stat;
2484    }
2485 }
2486
2487 bool image::isAligned(const Address/* where*/) const 
2488 {
2489    return true;
2490 }
2491
2492
2493 #if defined(arch_x86_64)
2494 int registerSpace::framePointer() { 
2495    return addr_width == 8 ? REGNUM_RBP : REGNUM_EBP; 
2496 }
2497 #elif defined(arch_x86)
2498 int registerSpace::framePointer() { 
2499    return REGNUM_EBP; 
2500 }
2501 #endif
2502
2503 void registerSpace::initRealRegSpace()
2504 {
2505    for (unsigned i=0; i<regStateStack.size(); i++) {
2506       if (regStateStack[i])
2507          delete regStateStack[i];
2508    }
2509    regStateStack.clear();
2510
2511    regState_t *new_regState = new regState_t();
2512    regStateStack.push_back(new_regState);
2513    regs_been_spilled.clear();
2514    
2515    pc_rel_reg = Null_Register;
2516    pc_rel_use_count = 0;
2517 }
2518
2519 void registerSpace::movRegToReg(RealRegister dest, RealRegister src, codeGen &gen)
2520 {
2521    gen.markRegDefined(dest.reg());
2522    emitMovRegToReg(dest, src, gen);
2523 }
2524
2525 void registerSpace::spillToVReg(RealRegister reg, registerSlot *v_reg, codeGen &gen)
2526 {
2527    stackItemLocation loc = getHeightOf(stackItem::framebase, gen);
2528    loc.offset += -4*v_reg->encoding();
2529    emitMovRegToRM(loc.reg, loc.offset, reg, gen);
2530 }
2531
2532 void registerSpace::movVRegToReal(registerSlot *v_reg, RealRegister r, codeGen &gen)
2533 {
2534    stackItemLocation loc = getHeightOf(stackItem::framebase, gen);
2535    loc.offset += -4*v_reg->encoding();
2536    gen.markRegDefined(r.reg());
2537    emitMovRMToReg(r, loc.reg, loc.offset, gen);
2538 }
2539
2540 void emitBTRegRestores32(baseTrampInstance *bti, codeGen &gen)
2541 {
2542    int numRegsUsed = bti ? bti->numDefinedRegs() : -1;
2543    if (numRegsUsed == -1 || 
2544        numRegsUsed > X86_REGS_SAVE_LIMIT) {
2545       emitSimpleInsn(POPAD, gen);
2546    }
2547    else {
2548       registerSlot *reg;
2549       pdvector<registerSlot *> &regs = gen.rs()->trampRegs();
2550       for (int i=regs.size()-1; i>=0; i--) {
2551          reg = regs[i];          
2552          if (reg->encoding() != REGNUM_ESP && 
2553              reg->encoding() != REGNUM_EBP &&
2554              reg->spilledState != registerSlot::unspilled)
2555          {
2556             emitPop(RealRegister(reg->encoding()), gen);
2557          }
2558       }
2559    }
2560    
2561    gen.rs()->restoreVolatileRegisters(gen);
2562 }
2563
2564 regState_t::regState_t() : 
2565    pc_rel_offset(-1), 
2566    timeline(0), 
2567    stack_height(0) 
2568 {
2569    for (unsigned i=0; i<8; i++) {
2570       RealRegsState r;
2571       r.is_allocatable = (i != REGNUM_ESP && i != REGNUM_EBP);
2572       r.been_used = false;
2573       r.last_used = 0;
2574       r.contains = NULL;
2575       registerStates.push_back(r);
2576    }
2577 }
2578
2579 void emitSaveO(codeGen &gen)
2580 {
2581    GET_PTR(insn, gen);
2582    *insn++ = 0x0f;
2583    *insn++ = 0x90;
2584    *insn++ = 0xC0;
2585    SET_PTR(insn, gen);
2586 }
2587
2588 void emitRestoreO(codeGen &gen)
2589 {
2590    GET_PTR(insn, gen);
2591    *insn++ = 0x80;
2592    *insn++ = 0xC0;
2593    *insn++ = 0x7f;
2594    SET_PTR(insn, gen);
2595 }
2596
2597 void emitCallRel32(unsigned disp32, codeGen &gen)
2598 {
2599    GET_PTR(insn, gen);
2600    *insn++ = 0xE8;
2601    *((int *) insn) = disp32;
2602    insn += sizeof(int);
2603    SET_PTR(insn, gen);
2604 }
2605
2606 void emitJump(unsigned disp32, codeGen &gen)
2607 {
2608    GET_PTR(insn, gen);
2609    *insn++ = 0xE9;
2610    *((int *) insn) = disp32;
2611    insn += sizeof(int);
2612    SET_PTR(insn, gen);
2613 }