some drc integration work
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / assem_x64.c
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   Mupen64plus - assem_x64.c                                             *
3  *   Copyright (C) 2009-2010 Ari64                                         *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
19  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
20
21 int cycle_count;
22 int last_count;
23 int pcaddr;
24 int pending_exception;
25 int branch_target;
26 uint64_t readmem_dword;
27 precomp_instr fake_pc;
28 u_int memory_map[1048576];
29 u_int mini_ht[32][2]  __attribute__((aligned(8)));
30 u_char restore_candidate[512]  __attribute__((aligned(4)));
31
32 void do_interrupt();
33 void jump_vaddr_eax();
34 void jump_vaddr_ecx();
35 void jump_vaddr_edx();
36 void jump_vaddr_ebx();
37 void jump_vaddr_ebp();
38 void jump_vaddr_edi();
39
40 const void * jump_vaddr_reg[8] = {
41   jump_vaddr_eax,
42   jump_vaddr_ecx,
43   jump_vaddr_edx,
44   jump_vaddr_ebx,
45   0,
46   jump_vaddr_ebp,
47   0,
48   jump_vaddr_edi };
49
50 const u_short rounding_modes[4] = {
51   0x33F, // round
52   0xF3F, // trunc
53   0xB3F, // ceil
54   0x73F};// floor
55
56 #include "fpu.h"
57
58 // We need these for cmovcc instructions on x86
59 u_int const_zero=0;
60 u_int const_one=1;
61
62 /* Linker */
63
64 void set_jump_target(int addr,int target)
65 {
66   u_char *ptr=(u_char *)addr;
67   if(*ptr==0x0f)
68   {
69     assert(ptr[1]>=0x80&&ptr[1]<=0x8f);
70     u_int *ptr2=(u_int *)(ptr+2);
71     *ptr2=target-(int)ptr2-4;
72   }
73   else if(*ptr==0xe8||*ptr==0xe9) {
74     u_int *ptr2=(u_int *)(ptr+1);
75     *ptr2=target-(int)ptr2-4;
76   }
77   else
78   {
79     assert(*ptr==0xc7); /* mov immediate (store address) */
80     u_int *ptr2=(u_int *)(ptr+6);
81     *ptr2=target;
82   }
83 }
84
85 void kill_pointer(void *stub)
86 {
87   int i_ptr=*((int *)(stub+6));
88   *((int *)i_ptr)=(int)stub-(int)i_ptr-4;
89 }
90 int get_pointer(void *stub)
91 {
92   int i_ptr=*((int *)(stub+6));
93   return *((int *)i_ptr)+(int)i_ptr+4;
94 }
95
96 // Find the "clean" entry point from a "dirty" entry point
97 // by skipping past the call to verify_code
98 u_int get_clean_addr(int addr)
99 {
100   u_char *ptr=(u_char *)addr;
101   assert(ptr[21]==0xE8); // call instruction
102   if(ptr[26]==0xE9) return *(u_int *)(ptr+27)+addr+31; // follow jmp
103   else return(addr+26);
104 }
105
106 int verify_dirty(int addr)
107 {
108   u_char *ptr=(u_char *)addr;
109   assert(ptr[0]==0xB8);
110   u_int source=*(u_int *)(ptr+1);
111   u_int copy=*(u_int *)(ptr+6);
112   u_int len=*(u_int *)(ptr+11);
113   //printf("source=%x source-rdram=%x\n",source,source-(int)rdram);
114   assert(ptr[21]==0xE8); // call instruction
115   u_int verifier=*(u_int *)(ptr+22)+(u_int)ptr+26;
116   if(verifier==(u_int)verify_code_vm||verifier==(u_int)verify_code_ds) {
117     unsigned int page=source>>12;
118     unsigned int map_value=memory_map[page];
119     if(map_value>=0x80000000) return 0;
120     while(page<((source+len-1)>>12)) {
121       if((memory_map[++page]<<2)!=(map_value<<2)) return 0;
122     }
123     source = source+(map_value<<2);
124   }
125   //printf("verify_dirty: %x %x %x\n",source,copy,len);
126   return !memcmp((void *)source,(void *)copy,len);
127 }
128
129 // This doesn't necessarily find all clean entry points, just
130 // guarantees that it's not dirty
131 int isclean(int addr)
132 {
133   u_char *ptr=(u_char *)addr;
134   if(ptr[0]!=0xB8) return 1; // mov imm,%eax
135   if(ptr[5]!=0xBB) return 1; // mov imm,%ebx
136   if(ptr[10]!=0xB9) return 1; // mov imm,%ecx
137   if(ptr[15]!=0x41) return 1; // rex prefix
138   if(ptr[16]!=0xBC) return 1; // mov imm,%r12d
139   if(ptr[21]!=0xE8) return 1; // call instruction
140   return 0;
141 }
142
143 void get_bounds(int addr,u_int *start,u_int *end)
144 {
145   u_char *ptr=(u_char *)addr;
146   assert(ptr[0]==0xB8);
147   u_int source=*(u_int *)(ptr+1);
148   //u_int copy=*(u_int *)(ptr+6);
149   u_int len=*(u_int *)(ptr+11);
150   assert(ptr[21]==0xE8); // call instruction
151   u_int verifier=*(u_int *)(ptr+22)+(u_int)ptr+26;
152   if(verifier==(u_int)verify_code_vm||verifier==(u_int)verify_code_ds) {
153     if(memory_map[source>>12]>=0x80000000) source = 0;
154     else source = source+(memory_map[source>>12]<<2);
155   }
156   *start=source;
157   *end=source+len;
158 }
159
160 /* Register allocation */
161
162 // Note: registers are allocated clean (unmodified state)
163 // if you intend to modify the register, you must call dirty_reg().
164 void alloc_reg(struct regstat *cur,int i,signed char reg)
165 {
166   int r,hr;
167   int preferred_reg = (reg&3)+(reg>28)*4-(reg==32)+2*(reg==36)-(reg==40);
168   
169   // Don't allocate unused registers
170   if((cur->u>>reg)&1) return;
171   
172   // see if it's already allocated
173   for(hr=0;hr<HOST_REGS;hr++)
174   {
175     if(cur->regmap[hr]==reg) return;
176   }
177   
178   // Keep the same mapping if the register was already allocated in a loop
179   preferred_reg = loop_reg(i,reg,preferred_reg);
180   
181   // Try to allocate the preferred register
182   if(cur->regmap[preferred_reg]==-1) {
183     cur->regmap[preferred_reg]=reg;
184     cur->dirty&=~(1<<preferred_reg);
185     cur->isconst&=~(1<<preferred_reg);
186     return;
187   }
188   r=cur->regmap[preferred_reg];
189   if(r<64&&((cur->u>>r)&1)) {
190     cur->regmap[preferred_reg]=reg;
191     cur->dirty&=~(1<<preferred_reg);
192     cur->isconst&=~(1<<preferred_reg);
193     return;
194   }
195   if(r>=64&&((cur->uu>>(r&63))&1)) {
196     cur->regmap[preferred_reg]=reg;
197     cur->dirty&=~(1<<preferred_reg);
198     cur->isconst&=~(1<<preferred_reg);
199     return;
200   }
201   
202   // Try to allocate EAX, EBX, ECX, or EDX
203   // We prefer these because they can do byte and halfword loads
204   for(hr=0;hr<4;hr++) {
205     if(cur->regmap[hr]==-1) {
206       cur->regmap[hr]=reg;
207       cur->dirty&=~(1<<hr);
208       cur->isconst&=~(1<<hr);
209       return;
210     }
211   }
212   
213   // Clear any unneeded registers
214   // We try to keep the mapping consistent, if possible, because it
215   // makes branches easier (especially loops).  So we try to allocate
216   // first (see above) before removing old mappings.  If this is not
217   // possible then go ahead and clear out the registers that are no
218   // longer needed.
219   for(hr=0;hr<HOST_REGS;hr++)
220   {
221     r=cur->regmap[hr];
222     if(r>=0) {
223       if(r<64) {
224         if((cur->u>>r)&1)
225           if(i==0||(unneeded_reg[i-1]>>r)&1) {cur->regmap[hr]=-1;break;}
226       }
227       else
228       {
229         if((cur->uu>>(r&63))&1)
230           if(i==0||(unneeded_reg_upper[i-1]>>(r&63))&1) {cur->regmap[hr]=-1;break;}
231       }
232     }
233   }
234   // Try to allocate any available register, but prefer
235   // registers that have not been used recently.
236   if(i>0) {
237     for(hr=0;hr<HOST_REGS;hr++) {
238       if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) {
239         if(regs[i-1].regmap[hr]!=rs1[i-1]&&regs[i-1].regmap[hr]!=rs2[i-1]&&regs[i-1].regmap[hr]!=rt1[i-1]&&regs[i-1].regmap[hr]!=rt2[i-1]) {
240           cur->regmap[hr]=reg;
241           cur->dirty&=~(1<<hr);
242           cur->isconst&=~(1<<hr);
243           return;
244         }
245       }
246     }
247   }
248   // Try to allocate any available register
249   for(hr=0;hr<HOST_REGS;hr++) {
250     if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) {
251       cur->regmap[hr]=reg;
252       cur->dirty&=~(1<<hr);
253       cur->isconst&=~(1<<hr);
254       return;
255     }
256   }
257   
258   // Ok, now we have to evict someone
259   // Pick a register we hopefully won't need soon
260   u_char hsn[MAXREG+1];
261   memset(hsn,10,sizeof(hsn));
262   int j;
263   lsn(hsn,i,&preferred_reg);
264   //printf("hsn(%x): %d %d %d %d %d %d %d\n",start+i*4,hsn[cur->regmap[0]&63],hsn[cur->regmap[1]&63],hsn[cur->regmap[2]&63],hsn[cur->regmap[3]&63],hsn[cur->regmap[5]&63],hsn[cur->regmap[6]&63],hsn[cur->regmap[7]&63]);
265   if(i>0) {
266     // Don't evict the cycle count at entry points, otherwise the entry
267     // stub will have to write it.
268     if(bt[i]&&hsn[CCREG]>2) hsn[CCREG]=2;
269     if(i>1&&hsn[CCREG]>2&&(itype[i-2]==RJUMP||itype[i-2]==UJUMP||itype[i-2]==CJUMP||itype[i-2]==SJUMP||itype[i-2]==FJUMP)) hsn[CCREG]=2;
270     for(j=10;j>=3;j--)
271     {
272       // Alloc preferred register if available
273       if(hsn[r=cur->regmap[preferred_reg]&63]==j) {
274         for(hr=0;hr<HOST_REGS;hr++) {
275           // Evict both parts of a 64-bit register
276           if((cur->regmap[hr]&63)==r) {
277             cur->regmap[hr]=-1;
278             cur->dirty&=~(1<<hr);
279             cur->isconst&=~(1<<hr);
280           }
281         }
282         cur->regmap[preferred_reg]=reg;
283         return;
284       }
285       for(r=1;r<=MAXREG;r++)
286       {
287         if(hsn[r]==j&&r!=rs1[i-1]&&r!=rs2[i-1]&&r!=rt1[i-1]&&r!=rt2[i-1]) {
288           for(hr=0;hr<HOST_REGS;hr++) {
289             if(hr!=HOST_CCREG||j<hsn[CCREG]) {
290               if(cur->regmap[hr]==r+64) {
291                 cur->regmap[hr]=reg;
292                 cur->dirty&=~(1<<hr);
293                 cur->isconst&=~(1<<hr);
294                 return;
295               }
296             }
297           }
298           for(hr=0;hr<HOST_REGS;hr++) {
299             if(hr!=HOST_CCREG||j<hsn[CCREG]) {
300               if(cur->regmap[hr]==r) {
301                 cur->regmap[hr]=reg;
302                 cur->dirty&=~(1<<hr);
303                 cur->isconst&=~(1<<hr);
304                 return;
305               }
306             }
307           }
308         }
309       }
310     }
311   }
312   for(j=10;j>=0;j--)
313   {
314     for(r=1;r<=MAXREG;r++)
315     {
316       if(hsn[r]==j) {
317         for(hr=0;hr<HOST_REGS;hr++) {
318           if(cur->regmap[hr]==r+64) {
319             cur->regmap[hr]=reg;
320             cur->dirty&=~(1<<hr);
321             cur->isconst&=~(1<<hr);
322             return;
323           }
324         }
325         for(hr=0;hr<HOST_REGS;hr++) {
326           if(cur->regmap[hr]==r) {
327             cur->regmap[hr]=reg;
328             cur->dirty&=~(1<<hr);
329             cur->isconst&=~(1<<hr);
330             return;
331           }
332         }
333       }
334     }
335   }
336   printf("This shouldn't happen (alloc_reg)");exit(1);
337 }
338
339 void alloc_reg64(struct regstat *cur,int i,signed char reg)
340 {
341   int preferred_reg = 5+reg%3;
342   int r,hr;
343   
344   // allocate the lower 32 bits
345   alloc_reg(cur,i,reg);
346   
347   // Don't allocate unused registers
348   if((cur->uu>>reg)&1) return;
349   
350   // see if the upper half is already allocated
351   for(hr=0;hr<HOST_REGS;hr++)
352   {
353     if(cur->regmap[hr]==reg+64) return;
354   }
355   
356   // Keep the same mapping if the register was already allocated in a loop
357   preferred_reg = loop_reg(i,reg,preferred_reg);
358   
359   // Try to allocate the preferred register
360   if(cur->regmap[preferred_reg]==-1) {
361     cur->regmap[preferred_reg]=reg|64;
362     cur->dirty&=~(1<<preferred_reg);
363     cur->isconst&=~(1<<preferred_reg);
364     return;
365   }
366   r=cur->regmap[preferred_reg];
367   if(r<64&&((cur->u>>r)&1)) {
368     cur->regmap[preferred_reg]=reg|64;
369     cur->dirty&=~(1<<preferred_reg);
370     cur->isconst&=~(1<<preferred_reg);
371     return;
372   }
373   if(r>=64&&((cur->uu>>(r&63))&1)) {
374     cur->regmap[preferred_reg]=reg|64;
375     cur->dirty&=~(1<<preferred_reg);
376     cur->isconst&=~(1<<preferred_reg);
377     return;
378   }
379   
380   // Try to allocate EBP, ESI or EDI
381   for(hr=5;hr<8;hr++) {
382     if(cur->regmap[hr]==-1) {
383       cur->regmap[hr]=reg|64;
384       cur->dirty&=~(1<<hr);
385       cur->isconst&=~(1<<hr);
386       return;
387     }
388   }
389   
390   // Clear any unneeded registers
391   // We try to keep the mapping consistent, if possible, because it
392   // makes branches easier (especially loops).  So we try to allocate
393   // first (see above) before removing old mappings.  If this is not
394   // possible then go ahead and clear out the registers that are no
395   // longer needed.
396   for(hr=HOST_REGS-1;hr>=0;hr--)
397   {
398     r=cur->regmap[hr];
399     if(r>=0) {
400       if(r<64) {
401         if((cur->u>>r)&1) {cur->regmap[hr]=-1;break;}
402       }
403       else
404       {
405         if((cur->uu>>(r&63))&1) {cur->regmap[hr]=-1;break;}
406       }
407     }
408   }
409   // Try to allocate any available register, but prefer
410   // registers that have not been used recently.
411   if(i>0) {
412     for(hr=0;hr<HOST_REGS;hr++) {
413       if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) {
414         if(regs[i-1].regmap[hr]!=rs1[i-1]&&regs[i-1].regmap[hr]!=rs2[i-1]&&regs[i-1].regmap[hr]!=rt1[i-1]&&regs[i-1].regmap[hr]!=rt2[i-1]) {
415           cur->regmap[hr]=reg|64;
416           cur->dirty&=~(1<<hr);
417           cur->isconst&=~(1<<hr);
418           return;
419         }
420       }
421     }
422   }
423   // Try to allocate any available register
424   for(hr=0;hr<HOST_REGS;hr++) {
425     if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) {
426       cur->regmap[hr]=reg|64;
427       cur->dirty&=~(1<<hr);
428       cur->isconst&=~(1<<hr);
429       return;
430     }
431   }
432   
433   // Ok, now we have to evict someone
434   // Pick a register we hopefully won't need soon
435   u_char hsn[MAXREG+1];
436   memset(hsn,10,sizeof(hsn));
437   int j;
438   lsn(hsn,i,&preferred_reg);
439   //printf("eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d\n",cur->regmap[0],cur->regmap[1],cur->regmap[2],cur->regmap[3],cur->regmap[5],cur->regmap[6],cur->regmap[7]);
440   //printf("hsn(%x): %d %d %d %d %d %d %d\n",start+i*4,hsn[cur->regmap[0]&63],hsn[cur->regmap[1]&63],hsn[cur->regmap[2]&63],hsn[cur->regmap[3]&63],hsn[cur->regmap[5]&63],hsn[cur->regmap[6]&63],hsn[cur->regmap[7]&63]);
441   if(i>0) {
442     // Don't evict the cycle count at entry points, otherwise the entry
443     // stub will have to write it.
444     if(bt[i]&&hsn[CCREG]>2) hsn[CCREG]=2;
445     if(i>1&&hsn[CCREG]>2&&(itype[i-2]==RJUMP||itype[i-2]==UJUMP||itype[i-2]==CJUMP||itype[i-2]==SJUMP||itype[i-2]==FJUMP)) hsn[CCREG]=2;
446     for(j=10;j>=3;j--)
447     {
448       // Alloc preferred register if available
449       if(hsn[r=cur->regmap[preferred_reg]&63]==j) {
450         for(hr=0;hr<HOST_REGS;hr++) {
451           // Evict both parts of a 64-bit register
452           if((cur->regmap[hr]&63)==r) {
453             cur->regmap[hr]=-1;
454             cur->dirty&=~(1<<hr);
455             cur->isconst&=~(1<<hr);
456           }
457         }
458         cur->regmap[preferred_reg]=reg|64;
459         return;
460       }
461       for(r=1;r<=MAXREG;r++)
462       {
463         if(hsn[r]==j&&r!=rs1[i-1]&&r!=rs2[i-1]&&r!=rt1[i-1]&&r!=rt2[i-1]) {
464           for(hr=0;hr<HOST_REGS;hr++) {
465             if(hr!=HOST_CCREG||j<hsn[CCREG]) {
466               if(cur->regmap[hr]==r+64) {
467                 cur->regmap[hr]=reg|64;
468                 cur->dirty&=~(1<<hr);
469                 cur->isconst&=~(1<<hr);
470                 return;
471               }
472             }
473           }
474           for(hr=0;hr<HOST_REGS;hr++) {
475             if(hr!=HOST_CCREG||j<hsn[CCREG]) {
476               if(cur->regmap[hr]==r) {
477                 cur->regmap[hr]=reg|64;
478                 cur->dirty&=~(1<<hr);
479                 cur->isconst&=~(1<<hr);
480                 return;
481               }
482             }
483           }
484         }
485       }
486     }
487   }
488   for(j=10;j>=0;j--)
489   {
490     for(r=1;r<=MAXREG;r++)
491     {
492       if(hsn[r]==j) {
493         for(hr=0;hr<HOST_REGS;hr++) {
494           if(cur->regmap[hr]==r+64) {
495             cur->regmap[hr]=reg|64;
496             cur->dirty&=~(1<<hr);
497             cur->isconst&=~(1<<hr);
498             return;
499           }
500         }
501         for(hr=0;hr<HOST_REGS;hr++) {
502           if(cur->regmap[hr]==r) {
503             cur->regmap[hr]=reg|64;
504             cur->dirty&=~(1<<hr);
505             cur->isconst&=~(1<<hr);
506             return;
507           }
508         }
509       }
510     }
511   }
512   printf("This shouldn't happen");exit(1);
513 }
514
515 // Allocate a temporary register.  This is done without regard to
516 // dirty status or whether the register we request is on the unneeded list
517 // Note: This will only allocate one register, even if called multiple times
518 void alloc_reg_temp(struct regstat *cur,int i,signed char reg)
519 {
520   int r,hr;
521   int preferred_reg = -1;
522   
523   // see if it's already allocated
524   for(hr=0;hr<HOST_REGS;hr++)
525   {
526     if(hr!=EXCLUDE_REG&&cur->regmap[hr]==reg) return;
527   }
528   
529   // Try to allocate any available register, starting with EDI, ESI, EBP...
530   // We prefer EDI, ESI, EBP since the others are used for byte/halfword stores
531   for(hr=HOST_REGS-1;hr>=0;hr--) {
532     if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) {
533       cur->regmap[hr]=reg;
534       cur->dirty&=~(1<<hr);
535       cur->isconst&=~(1<<hr);
536       return;
537     }
538   }
539   
540   // Find an unneeded register
541   for(hr=HOST_REGS-1;hr>=0;hr--)
542   {
543     r=cur->regmap[hr];
544     if(r>=0) {
545       if(r<64) {
546         if((cur->u>>r)&1) {
547           if(i==0||((unneeded_reg[i-1]>>r)&1)) {
548             cur->regmap[hr]=reg;
549             cur->dirty&=~(1<<hr);
550             cur->isconst&=~(1<<hr);
551             return;
552           }
553         }
554       }
555       else
556       {
557         if((cur->uu>>(r&63))&1) {
558           if(i==0||((unneeded_reg_upper[i-1]>>(r&63))&1)) {
559             cur->regmap[hr]=reg;
560             cur->dirty&=~(1<<hr);
561             cur->isconst&=~(1<<hr);
562             return;
563           }
564         }
565       }
566     }
567   }
568   
569   // Ok, now we have to evict someone
570   // Pick a register we hopefully won't need soon
571   // TODO: we might want to follow unconditional jumps here
572   // TODO: get rid of dupe code and make this into a function
573   u_char hsn[MAXREG+1];
574   memset(hsn,10,sizeof(hsn));
575   int j;
576   lsn(hsn,i,&preferred_reg);
577   //printf("hsn: %d %d %d %d %d %d %d\n",hsn[cur->regmap[0]&63],hsn[cur->regmap[1]&63],hsn[cur->regmap[2]&63],hsn[cur->regmap[3]&63],hsn[cur->regmap[5]&63],hsn[cur->regmap[6]&63],hsn[cur->regmap[7]&63]);
578   if(i>0) {
579     // Don't evict the cycle count at entry points, otherwise the entry
580     // stub will have to write it.
581     if(bt[i]&&hsn[CCREG]>2) hsn[CCREG]=2;
582     if(i>1&&hsn[CCREG]>2&&(itype[i-2]==RJUMP||itype[i-2]==UJUMP||itype[i-2]==CJUMP||itype[i-2]==SJUMP||itype[i-2]==FJUMP)) hsn[CCREG]=2;
583     for(j=10;j>=3;j--)
584     {
585       for(r=1;r<=MAXREG;r++)
586       {
587         if(hsn[r]==j&&r!=rs1[i-1]&&r!=rs2[i-1]&&r!=rt1[i-1]&&r!=rt2[i-1]) {
588           for(hr=0;hr<HOST_REGS;hr++) {
589             if(hr!=HOST_CCREG||hsn[CCREG]>2) {
590               if(cur->regmap[hr]==r+64) {
591                 cur->regmap[hr]=reg;
592                 cur->dirty&=~(1<<hr);
593                 cur->isconst&=~(1<<hr);
594                 return;
595               }
596             }
597           }
598           for(hr=0;hr<HOST_REGS;hr++) {
599             if(hr!=HOST_CCREG||hsn[CCREG]>2) {
600               if(cur->regmap[hr]==r) {
601                 cur->regmap[hr]=reg;
602                 cur->dirty&=~(1<<hr);
603                 cur->isconst&=~(1<<hr);
604                 return;
605               }
606             }
607           }
608         }
609       }
610     }
611   }
612   for(j=10;j>=0;j--)
613   {
614     for(r=1;r<=MAXREG;r++)
615     {
616       if(hsn[r]==j) {
617         for(hr=0;hr<HOST_REGS;hr++) {
618           if(cur->regmap[hr]==r+64) {
619             cur->regmap[hr]=reg;
620             cur->dirty&=~(1<<hr);
621             cur->isconst&=~(1<<hr);
622             return;
623           }
624         }
625         for(hr=0;hr<HOST_REGS;hr++) {
626           if(cur->regmap[hr]==r) {
627             cur->regmap[hr]=reg;
628             cur->dirty&=~(1<<hr);
629             cur->isconst&=~(1<<hr);
630             return;
631           }
632         }
633       }
634     }
635   }
636   printf("This shouldn't happen");exit(1);
637 }
638 // Allocate a specific x86 register.
639 void alloc_x86_reg(struct regstat *cur,int i,signed char reg,char hr)
640 {
641   int n;
642   
643   // see if it's already allocated (and dealloc it)
644   for(n=0;n<HOST_REGS;n++)
645   {
646     if(n!=ESP&&cur->regmap[n]==reg) {cur->regmap[n]=-1;}
647   }
648   
649   cur->regmap[hr]=reg;
650   cur->dirty&=~(1<<hr);
651   cur->isconst&=~(1<<hr);
652 }
653
654 // Alloc cycle count into dedicated register
655 alloc_cc(struct regstat *cur,int i)
656 {
657   alloc_x86_reg(cur,i,CCREG,ESI);
658 }
659
660 /* Special alloc */
661
662 void multdiv_alloc_x86(struct regstat *current,int i)
663 {
664   //  case 0x18: MULT
665   //  case 0x19: MULTU
666   //  case 0x1A: DIV
667   //  case 0x1B: DIVU
668   //  case 0x1C: DMULT
669   //  case 0x1D: DMULTU
670   //  case 0x1E: DDIV
671   //  case 0x1F: DDIVU
672   clear_const(current,rs1[i]);
673   clear_const(current,rs2[i]);
674   if(rs1[i]&&rs2[i])
675   {
676     if((opcode2[i]&4)==0) // 32-bit
677     {
678       current->u&=~(1LL<<HIREG);
679       current->u&=~(1LL<<LOREG);
680       alloc_x86_reg(current,i,HIREG,EDX);
681       alloc_x86_reg(current,i,LOREG,EAX);
682       alloc_reg(current,i,rs1[i]);
683       alloc_reg(current,i,rs2[i]);
684       current->is32|=1LL<<HIREG;
685       current->is32|=1LL<<LOREG;
686       dirty_reg(current,HIREG);
687       dirty_reg(current,LOREG);
688     }
689     else // 64-bit
690     {
691       alloc_x86_reg(current,i,HIREG|64,EDX);
692       alloc_x86_reg(current,i,HIREG,EAX);
693       alloc_reg64(current,i,rs1[i]);
694       alloc_reg64(current,i,rs2[i]);
695       alloc_all(current,i);
696       current->is32&=~(1LL<<HIREG);
697       current->is32&=~(1LL<<LOREG);
698       dirty_reg(current,HIREG);
699       dirty_reg(current,LOREG);
700     }
701   }
702   else
703   {
704     // Multiply by zero is zero.
705     // MIPS does not have a divide by zero exception.
706     // The result is undefined, we return zero.
707     alloc_reg(current,i,HIREG);
708     alloc_reg(current,i,LOREG);
709     current->is32|=1LL<<HIREG;
710     current->is32|=1LL<<LOREG;
711     dirty_reg(current,HIREG);
712     dirty_reg(current,LOREG);
713   }
714 }
715 #define multdiv_alloc multdiv_alloc_x86
716
717 /* Assembler */
718
719 char regname[16][4] = {
720  "eax",
721  "ecx",
722  "edx",
723  "ebx",
724  "esp",
725  "ebp",
726  "esi",
727  "edi",
728  "r8",
729  "r9",
730  "r10",
731  "r11",
732  "r12",
733  "r13",
734  "r14",
735  "r15"};
736
737 void output_byte(u_char byte)
738 {
739   *(out++)=byte;
740 }
741 void output_modrm(u_char mod,u_char rm,u_char ext)
742 {
743   assert(mod<4);
744   assert(rm<8);
745   assert(ext<8);
746   u_char byte=(mod<<6)|(ext<<3)|rm;
747   *(out++)=byte;
748 }
749 void output_sib(u_char scale,u_char index,u_char base)
750 {
751   assert(scale<4);
752   assert(index<8);
753   assert(base<8);
754   u_char byte=(scale<<6)|(index<<3)|base;
755   *(out++)=byte;
756 }
757 void output_rex(u_char w,u_char r,u_char x,u_char b)
758 {
759   assert(w<2);
760   assert(r<2);
761   assert(x<2);
762   assert(b<2);
763   u_char byte=0x40|(w<<3)|(r<<2)|(x<<1)|b;
764   *(out++)=byte;
765 }
766 void output_w32(u_int word)
767 {
768   *((u_int *)out)=word;
769   out+=4;
770 }
771
772 void emit_mov(int rs,int rt)
773 {
774   assem_debug("mov %%%s,%%%s\n",regname[rs],regname[rt]);
775   output_byte(0x89);
776   output_modrm(3,rt,rs);
777 }
778
779 void emit_mov64(int rs,int rt)
780 {
781   assem_debug("mov %%%s,%%%s\n",regname[rs],regname[rt]);
782   output_rex(1,0,0,rt>>3);
783   output_byte(0x89);
784   output_modrm(3,rt,rs);
785 }
786
787 void emit_add(int rs1,int rs2,int rt)
788 {
789   if(rs1==rt) {
790     assem_debug("add %%%s,%%%s\n",regname[rs2],regname[rs1]);
791     output_byte(0x01);
792     output_modrm(3,rs1,rs2);
793   }else if(rs2==rt) {
794     assem_debug("add %%%s,%%%s\n",regname[rs1],regname[rs2]);
795     output_byte(0x01);
796     output_modrm(3,rs2,rs1);
797   }else {
798     assem_debug("lea (%%%s,%%%s),%%%s\n",regname[rs1],regname[rs2],regname[rt]);
799     output_byte(0x8D);
800     if(rs1!=EBP) {
801       output_modrm(0,4,rt);
802       output_sib(0,rs2,rs1);
803     }else if(rs2!=EBP) {
804       output_modrm(0,4,rt);
805       output_sib(0,rs1,rs2);
806     }else /* lea 0(,%ebp,2) */{
807       output_modrm(0,4,rt);
808       output_sib(1,EBP,5);
809       output_w32(0);
810     }
811   }
812 }
813
814 void emit_adds(int rs1,int rs2,int rt)
815 {
816   emit_add(rs1,rs2,rt);
817 }
818
819 void emit_lea8(int rs1,int rt)
820 {
821   assem_debug("lea 0(%%%s,8),%%%s\n",regname[rs1],regname[rt]);
822   output_byte(0x8D);
823   output_modrm(0,4,rt);
824   output_sib(3,rs1,5);
825   output_w32(0);
826 }
827 void emit_leairrx1(int imm,int rs1,int rs2,int rt)
828 {
829   assem_debug("lea %x(%%%s,%%%s,1),%%%s\n",imm,regname[rs1],regname[rs2],regname[rt]);
830   output_byte(0x8D);
831   if(imm!=0||rs1==EBP) {
832     output_modrm(2,4,rt);
833     output_sib(0,rs2,rs1);
834     output_w32(imm);
835   }else{
836     output_modrm(0,4,rt);
837     output_sib(0,rs2,rs1);
838   }
839 }
840 void emit_leairrx4(int imm,int rs1,int rs2,int rt)
841 {
842   assem_debug("lea %x(%%%s,%%%s,4),%%%s\n",imm,regname[rs1],regname[rs2],regname[rt]);
843   output_byte(0x8D);
844   if(imm!=0||rs1==EBP) {
845     output_modrm(2,4,rt);
846     output_sib(2,rs2,rs1);
847     output_w32(imm);
848   }else{
849     output_modrm(0,4,rt);
850     output_sib(2,rs2,rs1);
851   }
852 }
853
854 void emit_neg(int rs, int rt)
855 {
856   if(rs!=rt) emit_mov(rs,rt);
857   assem_debug("neg %%%s\n",regname[rt]);
858   output_byte(0xF7);
859   output_modrm(3,rt,3);
860 }
861
862 void emit_negs(int rs, int rt)
863 {
864   emit_neg(rs,rt);
865 }
866
867 void emit_sub(int rs1,int rs2,int rt)
868 {
869   if(rs1==rt) {
870     assem_debug("sub %%%s,%%%s\n",regname[rs2],regname[rs1]);
871     output_byte(0x29);
872     output_modrm(3,rs1,rs2);
873   } else if(rs2==rt) {
874     emit_neg(rs2,rs2);
875     emit_add(rs2,rs1,rs2);
876   } else {
877     emit_mov(rs1,rt);
878     emit_sub(rt,rs2,rt);
879   }
880 }
881
882 void emit_subs(int rs1,int rs2,int rt)
883 {
884   emit_sub(rs1,rs2,rt);
885 }
886
887 void emit_zeroreg(int rt)
888 {
889   output_byte(0x31);
890   output_modrm(3,rt,rt);
891   assem_debug("xor %%%s,%%%s\n",regname[rt],regname[rt]);
892 }
893
894 void emit_loadreg(int r, int hr)
895 {
896   if((r&63)==0)
897     emit_zeroreg(hr);
898   else {
899     int addr=((int)reg)+((r&63)<<3)+((r&64)>>4);
900     if((r&63)==HIREG) addr=(int)&hi+((r&64)>>4);
901     if((r&63)==LOREG) addr=(int)&lo+((r&64)>>4);
902     if(r==CCREG) addr=(int)&cycle_count;
903     if(r==CSREG) addr=(int)&Status;
904     if(r==FSREG) addr=(int)&FCR31;
905     assem_debug("mov %x+%d,%%%s\n",addr,r,regname[hr]);
906     output_byte(0x8B);
907     output_modrm(0,5,hr);
908     output_w32(addr-(int)out-4); // Note: rip-relative in 64-bit mode
909   }
910 }
911 void emit_storereg(int r, int hr)
912 {
913   int addr=((int)reg)+((r&63)<<3)+((r&64)>>4);
914   if((r&63)==HIREG) addr=(int)&hi+((r&64)>>4);
915   if((r&63)==LOREG) addr=(int)&lo+((r&64)>>4);
916   if(r==CCREG) addr=(int)&cycle_count;
917   if(r==FSREG) addr=(int)&FCR31;
918   assem_debug("mov %%%s,%x+%d\n",regname[hr],addr,r);
919   output_byte(0x89);
920   output_modrm(0,5,hr);
921   output_w32(addr-(int)out-4); // Note: rip-relative in 64-bit mode
922 }
923
924 void emit_test(int rs, int rt)
925 {
926   assem_debug("test %%%s,%%%s\n",regname[rs],regname[rt]);
927   output_byte(0x85);
928   output_modrm(3,rs,rt);
929 }
930
931 void emit_testimm(int rs,int imm)
932 {
933   assem_debug("test $0x%x,%%%s\n",imm,regname[rs]);
934   if(imm<128&&imm>=-128&&rs<4) {
935     output_byte(0xF6);
936     output_modrm(3,rs,0);
937     output_byte(imm);
938   }
939   else
940   {
941     output_byte(0xF7);
942     output_modrm(3,rs,0);
943     output_w32(imm);
944   }
945 }
946
947 void emit_not(int rs,int rt)
948 {
949   if(rs!=rt) emit_mov(rs,rt);
950   assem_debug("not %%%s\n",regname[rt]);
951   output_byte(0xF7);
952   output_modrm(3,rt,2);
953 }
954
955 void emit_and(u_int rs1,u_int rs2,u_int rt)
956 {
957   assert(rs1<8);
958   assert(rs2<8);
959   assert(rt<8);
960   if(rs1==rt) {
961     assem_debug("and %%%s,%%%s\n",regname[rs2],regname[rt]);
962     output_byte(0x21);
963     output_modrm(3,rs1,rs2);
964   }
965   else
966   if(rs2==rt) {
967     assem_debug("and %%%s,%%%s\n",regname[rs1],regname[rt]);
968     output_byte(0x21);
969     output_modrm(3,rs2,rs1);
970   }
971   else {
972     emit_mov(rs1,rt);
973     emit_and(rt,rs2,rt);
974   }
975 }
976
977 void emit_or(u_int rs1,u_int rs2,u_int rt)
978 {
979   assert(rs1<8);
980   assert(rs2<8);
981   assert(rt<8);
982   if(rs1==rt) {
983     assem_debug("or %%%s,%%%s\n",regname[rs2],regname[rt]);
984     output_byte(0x09);
985     output_modrm(3,rs1,rs2);
986   }
987   else
988   if(rs2==rt) {
989     assem_debug("or %%%s,%%%s\n",regname[rs1],regname[rt]);
990     output_byte(0x09);
991     output_modrm(3,rs2,rs1);
992   }
993   else {
994     emit_mov(rs1,rt);
995     emit_or(rt,rs2,rt);
996   }
997 }
998 void emit_or_and_set_flags(int rs1,int rs2,int rt)
999 {
1000   emit_or(rs1,rs2,rt);
1001 }
1002
1003 void emit_xor(u_int rs1,u_int rs2,u_int rt)
1004 {
1005   assert(rs1<8);
1006   assert(rs2<8);
1007   assert(rt<8);
1008   if(rs1==rt) {
1009     assem_debug("xor %%%s,%%%s\n",regname[rs2],regname[rt]);
1010     output_byte(0x31);
1011     output_modrm(3,rs1,rs2);
1012   }
1013   else
1014   if(rs2==rt) {
1015     assem_debug("xor %%%s,%%%s\n",regname[rs1],regname[rt]);
1016     output_byte(0x31);
1017     output_modrm(3,rs2,rs1);
1018   }
1019   else {
1020     emit_mov(rs1,rt);
1021     emit_xor(rt,rs2,rt);
1022   }
1023 }
1024
1025 void emit_movimm(int imm,u_int rt)
1026 {
1027   assem_debug("mov $%d,%%%s\n",imm,regname[rt]);
1028   assert(rt<16);
1029   if(rt>=8) output_rex(0,0,0,1);
1030   output_byte(0xB8+(rt&7));
1031   output_w32(imm);
1032 }
1033
1034 void emit_addimm(int rs,int imm,int rt)
1035 {
1036   if(rs==rt) {
1037     if(imm!=0) {
1038       assem_debug("add $%d,%%%s\n",imm,regname[rt]);
1039       if(imm<128&&imm>=-128) {
1040         output_byte(0x83);
1041         output_modrm(3,rt,0);
1042         output_byte(imm);
1043       }
1044       else
1045       {
1046         output_byte(0x81);
1047         output_modrm(3,rt,0);
1048         output_w32(imm);
1049       }
1050     }
1051   }
1052   else {
1053     if(imm!=0) {
1054       assem_debug("lea %d(%%%s),%%%s\n",imm,regname[rs],regname[rt]);
1055       output_byte(0x8D);
1056       if(imm<128&&imm>=-128) {
1057         output_modrm(1,rs,rt);
1058         output_byte(imm);
1059       }else{
1060         output_modrm(2,rs,rt);
1061         output_w32(imm);
1062       }
1063     }else{
1064       emit_mov(rs,rt);
1065     }
1066   }
1067 }
1068
1069 void emit_addimm64(int rs,int imm,int rt)
1070 {
1071   if(rs==rt) {
1072     if(imm!=0) {
1073       assem_debug("add $%d,%%%s\n",imm,regname[rt]);
1074       if(imm<128&&imm>=-128) {
1075         output_rex(1,0,0,rt>>3);
1076         output_byte(0x83);
1077         output_modrm(3,rt&7,0);
1078         output_byte(imm);
1079       }
1080       else
1081       {
1082         output_rex(1,0,0,rt>>3);
1083         output_byte(0x81);
1084         output_modrm(3,rt&7,0);
1085         output_w32(imm);
1086       }
1087     }
1088   }
1089   else {
1090     if(imm!=0) {
1091       assem_debug("lea %d(%%%s),%%%s\n",imm,regname[rs],regname[rt]);
1092       output_rex(1,rt>>3,0,rs>>3);
1093       output_byte(0x8D);
1094       if(imm<128&&imm>=-128) {
1095         output_modrm(1,rs&7,rt&7);
1096         output_byte(imm);
1097       }else{
1098         output_modrm(2,rs&7,rt&7);
1099         output_w32(imm);
1100       }
1101     }else{
1102       emit_mov(rs,rt);
1103     }
1104   }
1105 }
1106
1107 void emit_addimm_and_set_flags(int imm,int rt)
1108 {
1109   assem_debug("add $%d,%%%s\n",imm,regname[rt]);
1110   if(imm<128&&imm>=-128) {
1111     output_byte(0x83);
1112     output_modrm(3,rt,0);
1113     output_byte(imm);
1114   }
1115   else
1116   {
1117     output_byte(0x81);
1118     output_modrm(3,rt,0);
1119     output_w32(imm);
1120   }
1121 }
1122 void emit_addimm_no_flags(int imm,int rt)
1123 {
1124   if(imm!=0) {
1125     assem_debug("lea %d(%%%s),%%%s\n",imm,regname[rt],regname[rt]);
1126     output_byte(0x8D);
1127     if(imm<128&&imm>=-128) {
1128       output_modrm(1,rt,rt);
1129       output_byte(imm);
1130     }else{
1131       output_modrm(2,rt,rt);
1132       output_w32(imm);
1133     }
1134   }
1135 }
1136
1137 void emit_adcimm(int imm,u_int rt)
1138 {
1139   assem_debug("adc $%d,%%%s\n",imm,regname[rt]);
1140   assert(rt<8);
1141   if(imm<128&&imm>=-128) {
1142     output_byte(0x83);
1143     output_modrm(3,rt,2);
1144     output_byte(imm);
1145   }
1146   else
1147   {
1148     output_byte(0x81);
1149     output_modrm(3,rt,2);
1150     output_w32(imm);
1151   }
1152 }
1153 void emit_sbbimm(int imm,u_int rt)
1154 {
1155   assem_debug("sbb $%d,%%%s\n",imm,regname[rt]);
1156   assert(rt<8);
1157   if(imm<128&&imm>=-128) {
1158     output_byte(0x83);
1159     output_modrm(3,rt,3);
1160     output_byte(imm);
1161   }
1162   else
1163   {
1164     output_byte(0x81);
1165     output_modrm(3,rt,3);
1166     output_w32(imm);
1167   }
1168 }
1169
1170 void emit_addimm64_32(int rsh,int rsl,int imm,int rth,int rtl)
1171 {
1172   if(rsh==rth&&rsl==rtl) {
1173     assem_debug("add $%d,%%%s\n",imm,regname[rtl]);
1174     if(imm<128&&imm>=-128) {
1175       output_byte(0x83);
1176       output_modrm(3,rtl,0);
1177       output_byte(imm);
1178     }
1179     else
1180     {
1181       output_byte(0x81);
1182       output_modrm(3,rtl,0);
1183       output_w32(imm);
1184     }
1185     assem_debug("adc $%d,%%%s\n",imm>>31,regname[rth]);
1186     output_byte(0x83);
1187     output_modrm(3,rth,2);
1188     output_byte(imm>>31);
1189   }
1190   else {
1191     emit_mov(rsh,rth);
1192     emit_mov(rsl,rtl);
1193     emit_addimm64_32(rth,rtl,imm,rth,rtl);
1194   }
1195 }
1196
1197 void emit_sbb(int rs1,int rs2)
1198 {
1199   assem_debug("sbb %%%s,%%%s\n",regname[rs2],regname[rs1]);
1200   output_byte(0x19);
1201   output_modrm(3,rs1,rs2);
1202 }
1203
1204 void emit_andimm(int rs,int imm,int rt)
1205 {
1206   if(rs==rt) {
1207     assem_debug("and $%d,%%%s\n",imm,regname[rt]);
1208     if(imm<128&&imm>=-128) {
1209       output_byte(0x83);
1210       output_modrm(3,rt,4);
1211       output_byte(imm);
1212     }
1213     else
1214     {
1215       output_byte(0x81);
1216       output_modrm(3,rt,4);
1217       output_w32(imm);
1218     }
1219   }
1220   else {
1221     emit_mov(rs,rt);
1222     emit_andimm(rt,imm,rt);
1223   }
1224 }
1225
1226 void emit_orimm(int rs,int imm,int rt)
1227 {
1228   if(rs==rt) {
1229     assem_debug("or $%d,%%%s\n",imm,regname[rt]);
1230     if(imm<128&&imm>=-128) {
1231       output_byte(0x83);
1232       output_modrm(3,rt,1);
1233       output_byte(imm);
1234     }
1235     else
1236     {
1237       output_byte(0x81);
1238       output_modrm(3,rt,1);
1239       output_w32(imm);
1240     }
1241   }
1242   else {
1243     emit_mov(rs,rt);
1244     emit_orimm(rt,imm,rt);
1245   }
1246 }
1247
1248 void emit_xorimm(int rs,int imm,int rt)
1249 {
1250   if(rs==rt) {
1251     assem_debug("xor $%d,%%%s\n",imm,regname[rt]);
1252     if(imm<128&&imm>=-128) {
1253       output_byte(0x83);
1254       output_modrm(3,rt,6);
1255       output_byte(imm);
1256     }
1257     else
1258     {
1259       output_byte(0x81);
1260       output_modrm(3,rt,6);
1261       output_w32(imm);
1262     }
1263   }
1264   else {
1265     emit_mov(rs,rt);
1266     emit_xorimm(rt,imm,rt);
1267   }
1268 }
1269
1270 void emit_shlimm(int rs,u_int imm,int rt)
1271 {
1272   if(rs==rt) {
1273     assem_debug("shl %%%s,%d\n",regname[rt],imm);
1274     assert(imm>0);
1275     if(imm==1) output_byte(0xD1);
1276     else output_byte(0xC1);
1277     output_modrm(3,rt,4);
1278     if(imm>1) output_byte(imm);
1279   }
1280   else {
1281     emit_mov(rs,rt);
1282     emit_shlimm(rt,imm,rt);
1283   }
1284 }
1285
1286 void emit_shrimm(int rs,u_int imm,int rt)
1287 {
1288   if(rs==rt) {
1289     assem_debug("shr %%%s,%d\n",regname[rt],imm);
1290     assert(imm>0);
1291     if(imm==1) output_byte(0xD1);
1292     else output_byte(0xC1);
1293     output_modrm(3,rt,5);
1294     if(imm>1) output_byte(imm);
1295   }
1296   else {
1297     emit_mov(rs,rt);
1298     emit_shrimm(rt,imm,rt);
1299   }
1300 }
1301
1302 void emit_shrimm64(int rs,u_int imm,int rt)
1303 {
1304   assert(rs==rt);
1305   if(rs==rt) {
1306     assem_debug("shr %%%s,%d\n",regname[rt],imm);
1307     assert(imm>0);
1308     output_rex(1,0,0,rt>>3);
1309     if(imm==1) output_byte(0xD1);
1310     else output_byte(0xC1);
1311     output_modrm(3,rt,5);
1312     if(imm>1) output_byte(imm);
1313   }
1314   else {
1315     emit_mov(rs,rt);
1316     emit_shrimm(rt,imm,rt);
1317   }
1318 }
1319
1320 void emit_sarimm(int rs,u_int imm,int rt)
1321 {
1322   if(rs==rt) {
1323     assem_debug("sar %%%s,%d\n",regname[rt],imm);
1324     assert(imm>0);
1325     if(imm==1) output_byte(0xD1);
1326     else output_byte(0xC1);
1327     output_modrm(3,rt,7);
1328     if(imm>1) output_byte(imm);
1329   }
1330   else {
1331     emit_mov(rs,rt);
1332     emit_sarimm(rt,imm,rt);
1333   }
1334 }
1335
1336 void emit_rorimm(int rs,u_int imm,int rt)
1337 {
1338   if(rs==rt) {
1339     assem_debug("ror %%%s,%d\n",regname[rt],imm);
1340     assert(imm>0);
1341     if(imm==1) output_byte(0xD1);
1342     else output_byte(0xC1);
1343     output_modrm(3,rt,1);
1344     if(imm>1) output_byte(imm);
1345   }
1346   else {
1347     emit_mov(rs,rt);
1348     emit_sarimm(rt,imm,rt);
1349   }
1350 }
1351
1352 void emit_shldimm(int rs,int rs2,u_int imm,int rt)
1353 {
1354   if(rs==rt) {
1355     assem_debug("shld %%%s,%%%s,%d\n",regname[rt],regname[rs2],imm);
1356     assert(imm>0);
1357     output_byte(0x0F);
1358     output_byte(0xA4);
1359     output_modrm(3,rt,rs2);
1360     output_byte(imm);
1361   }
1362   else {
1363     emit_mov(rs,rt);
1364     emit_shldimm(rt,rs2,imm,rt);
1365   }
1366 }
1367
1368 void emit_shrdimm(int rs,int rs2,u_int imm,int rt)
1369 {
1370   if(rs==rt) {
1371     assem_debug("shrd %%%s,%%%s,%d\n",regname[rt],regname[rs2],imm);
1372     assert(imm>0);
1373     output_byte(0x0F);
1374     output_byte(0xAC);
1375     output_modrm(3,rt,rs2);
1376     output_byte(imm);
1377   }
1378   else {
1379     emit_mov(rs,rt);
1380     emit_shrdimm(rt,rs2,imm,rt);
1381   }
1382 }
1383
1384 void emit_shlcl(int r)
1385 {
1386   assem_debug("shl %%%s,%%cl\n",regname[r]);
1387   output_byte(0xD3);
1388   output_modrm(3,r,4);
1389 }
1390 void emit_shrcl(int r)
1391 {
1392   assem_debug("shr %%%s,%%cl\n",regname[r]);
1393   output_byte(0xD3);
1394   output_modrm(3,r,5);
1395 }
1396 void emit_sarcl(int r)
1397 {
1398   assem_debug("sar %%%s,%%cl\n",regname[r]);
1399   output_byte(0xD3);
1400   output_modrm(3,r,7);
1401 }
1402
1403 void emit_shldcl(int r1,int r2)
1404 {
1405   assem_debug("shld %%%s,%%%s,%%cl\n",regname[r1],regname[r2]);
1406   output_byte(0x0F);
1407   output_byte(0xA5);
1408   output_modrm(3,r1,r2);
1409 }
1410 void emit_shrdcl(int r1,int r2)
1411 {
1412   assem_debug("shrd %%%s,%%%s,%%cl\n",regname[r1],regname[r2]);
1413   output_byte(0x0F);
1414   output_byte(0xAD);
1415   output_modrm(3,r1,r2);
1416 }
1417
1418 void emit_cmpimm(int rs,int imm)
1419 {
1420   assem_debug("cmp $%d,%%%s\n",imm,regname[rs]);
1421   if(imm<128&&imm>=-128) {
1422     output_byte(0x83);
1423     output_modrm(3,rs,7);
1424     output_byte(imm);
1425   }
1426   else
1427   {
1428     output_byte(0x81);
1429     output_modrm(3,rs,7);
1430     output_w32(imm);
1431   }
1432 }
1433
1434 void emit_cmovne(u_int *addr,int rt)
1435 {
1436   assem_debug("cmovne %x,%%%s",(int)addr,regname[rt]);
1437   if(addr==&const_zero) assem_debug(" [zero]\n");
1438   else if(addr==&const_one) assem_debug(" [one]\n");
1439   else assem_debug("\n");
1440   output_byte(0x0F);
1441   output_byte(0x45);
1442   output_modrm(0,5,rt);
1443   output_w32((int)addr-(int)out-4); // Note: rip-relative in 64-bit mode
1444 }
1445 void emit_cmovl(u_int *addr,int rt)
1446 {
1447   assem_debug("cmovl %x,%%%s",(int)addr,regname[rt]);
1448   if(addr==&const_zero) assem_debug(" [zero]\n");
1449   else if(addr==&const_one) assem_debug(" [one]\n");
1450   else assem_debug("\n");
1451   output_byte(0x0F);
1452   output_byte(0x4C);
1453   output_modrm(0,5,rt);
1454   output_w32((int)addr-(int)out-4); // Note: rip-relative in 64-bit mode
1455 }
1456 void emit_cmovs(u_int *addr,int rt)
1457 {
1458   assem_debug("cmovs %x,%%%s",(int)addr,regname[rt]);
1459   if(addr==&const_zero) assem_debug(" [zero]\n");
1460   else if(addr==&const_one) assem_debug(" [one]\n");
1461   else assem_debug("\n");
1462   output_byte(0x0F);
1463   output_byte(0x48);
1464   output_modrm(0,5,rt);
1465   output_w32((int)addr-(int)out-4); // Note: rip-relative in 64-bit mode
1466 }
1467 void emit_cmovne_reg(int rs,int rt)
1468 {
1469   assem_debug("cmovne %%%s,%%%s\n",regname[rs],regname[rt]);
1470   output_byte(0x0F);
1471   output_byte(0x45);
1472   output_modrm(3,rs,rt);
1473 }
1474 void emit_cmovl_reg(int rs,int rt)
1475 {
1476   assem_debug("cmovl %%%s,%%%s\n",regname[rs],regname[rt]);
1477   output_byte(0x0F);
1478   output_byte(0x4C);
1479   output_modrm(3,rs,rt);
1480 }
1481 void emit_cmovs_reg(int rs,int rt)
1482 {
1483   assem_debug("cmovs %%%s,%%%s\n",regname[rs],regname[rt]);
1484   output_byte(0x0F);
1485   output_byte(0x48);
1486   output_modrm(3,rs,rt);
1487 }
1488 void emit_cmovnc_reg(int rs,int rt)
1489 {
1490   assem_debug("cmovae %%%s,%%%s\n",regname[rs],regname[rt]);
1491   output_byte(0x0F);
1492   output_byte(0x43);
1493   output_modrm(3,rs,rt);
1494 }
1495 void emit_cmova_reg(int rs,int rt)
1496 {
1497   assem_debug("cmova %%%s,%%%s\n",regname[rs],regname[rt]);
1498   output_byte(0x0F);
1499   output_byte(0x47);
1500   output_modrm(3,rs,rt);
1501 }
1502 void emit_cmovp_reg(int rs,int rt)
1503 {
1504   assem_debug("cmovp %%%s,%%%s\n",regname[rs],regname[rt]);
1505   output_byte(0x0F);
1506   output_byte(0x4A);
1507   output_modrm(3,rs,rt);
1508 }
1509 void emit_cmovnp_reg(int rs,int rt)
1510 {
1511   assem_debug("cmovnp %%%s,%%%s\n",regname[rs],regname[rt]);
1512   output_byte(0x0F);
1513   output_byte(0x4B);
1514   output_modrm(3,rs,rt);
1515 }
1516 void emit_setl(int rt)
1517 {
1518   assem_debug("setl %%%s\n",regname[rt]);
1519   output_byte(0x0F);
1520   output_byte(0x9C);
1521   output_modrm(3,rt,2);
1522 }
1523 void emit_movzbl_reg(int rs, int rt)
1524 {
1525   assem_debug("movzbl %%%s,%%%s\n",regname[rs]+1,regname[rt]);
1526   output_byte(0x0F);
1527   output_byte(0xB6);
1528   output_modrm(3,rs,rt);
1529 }
1530
1531 void emit_slti32(int rs,int imm,int rt)
1532 {
1533   if(rs!=rt) emit_zeroreg(rt);
1534   emit_cmpimm(rs,imm);
1535   if(rt<4) {
1536     emit_setl(rt);
1537     if(rs==rt) emit_movzbl_reg(rt,rt);
1538   }
1539   else
1540   {
1541     if(rs==rt) emit_movimm(0,rt);
1542     emit_cmovl(&const_one,rt);
1543   }
1544 }
1545 void emit_sltiu32(int rs,int imm,int rt)
1546 {
1547   if(rs!=rt) emit_zeroreg(rt);
1548   emit_cmpimm(rs,imm);
1549   if(rs==rt) emit_movimm(0,rt);
1550   emit_adcimm(0,rt);
1551 }
1552 void emit_slti64_32(int rsh,int rsl,int imm,int rt)
1553 {
1554   assert(rsh!=rt);
1555   emit_slti32(rsl,imm,rt);
1556   if(imm>=0)
1557   {
1558     emit_test(rsh,rsh);
1559     emit_cmovne(&const_zero,rt);
1560     emit_cmovs(&const_one,rt);
1561   }
1562   else
1563   {
1564     emit_cmpimm(rsh,-1);
1565     emit_cmovne(&const_zero,rt);
1566     emit_cmovl(&const_one,rt);
1567   }
1568 }
1569 void emit_sltiu64_32(int rsh,int rsl,int imm,int rt)
1570 {
1571   assert(rsh!=rt);
1572   emit_sltiu32(rsl,imm,rt);
1573   if(imm>=0)
1574   {
1575     emit_test(rsh,rsh);
1576     emit_cmovne(&const_zero,rt);
1577   }
1578   else
1579   {
1580     emit_cmpimm(rsh,-1);
1581     emit_cmovne(&const_one,rt);
1582   }
1583 }
1584
1585 void emit_cmp(int rs,int rt)
1586 {
1587   assem_debug("cmp %%%s,%%%s\n",regname[rt],regname[rs]);
1588   output_byte(0x39);
1589   output_modrm(3,rs,rt);
1590 }
1591 void emit_set_gz32(int rs, int rt)
1592 {
1593   //assem_debug("set_gz32\n");
1594   emit_cmpimm(rs,1);
1595   emit_movimm(1,rt);
1596   emit_cmovl(&const_zero,rt);
1597 }
1598 void emit_set_nz32(int rs, int rt)
1599 {
1600   //assem_debug("set_nz32\n");
1601   emit_cmpimm(rs,1);
1602   emit_movimm(1,rt);
1603   emit_sbbimm(0,rt);
1604 }
1605 void emit_set_gz64_32(int rsh, int rsl, int rt)
1606 {
1607   //assem_debug("set_gz64\n");
1608   emit_set_gz32(rsl,rt);
1609   emit_test(rsh,rsh);
1610   emit_cmovne(&const_one,rt);
1611   emit_cmovs(&const_zero,rt);
1612 }
1613 void emit_set_nz64_32(int rsh, int rsl, int rt)
1614 {
1615   //assem_debug("set_nz64\n");
1616   emit_or_and_set_flags(rsh,rsl,rt);
1617   emit_cmovne(&const_one,rt);
1618 }
1619 void emit_set_if_less32(int rs1, int rs2, int rt)
1620 {
1621   //assem_debug("set if less (%%%s,%%%s),%%%s\n",regname[rs1],regname[rs2],regname[rt]);
1622   if(rs1!=rt&&rs2!=rt) emit_zeroreg(rt);
1623   emit_cmp(rs1,rs2);
1624   if(rs1==rt||rs2==rt) emit_movimm(0,rt);
1625   emit_cmovl(&const_one,rt);
1626 }
1627 void emit_set_if_carry32(int rs1, int rs2, int rt)
1628 {
1629   //assem_debug("set if carry (%%%s,%%%s),%%%s\n",regname[rs1],regname[rs2],regname[rt]);
1630   if(rs1!=rt&&rs2!=rt) emit_zeroreg(rt);
1631   emit_cmp(rs1,rs2);
1632   if(rs1==rt||rs2==rt) emit_movimm(0,rt);
1633   emit_adcimm(0,rt);
1634 }
1635 void emit_set_if_less64_32(int u1, int l1, int u2, int l2, int rt)
1636 {
1637   //assem_debug("set if less64 (%%%s,%%%s,%%%s,%%%s),%%%s\n",regname[u1],regname[l1],regname[u2],regname[l2],regname[rt]);
1638   assert(u1!=rt);
1639   assert(u2!=rt);
1640   emit_cmp(l1,l2);
1641   emit_mov(u1,rt);
1642   emit_sbb(rt,u2);
1643   emit_movimm(0,rt);
1644   emit_cmovl(&const_one,rt);
1645 }
1646 void emit_set_if_carry64_32(int u1, int l1, int u2, int l2, int rt)
1647 {
1648   //assem_debug("set if carry64 (%%%s,%%%s,%%%s,%%%s),%%%s\n",regname[u1],regname[l1],regname[u2],regname[l2],regname[rt]);
1649   assert(u1!=rt);
1650   assert(u2!=rt);
1651   emit_cmp(l1,l2);
1652   emit_mov(u1,rt);
1653   emit_sbb(rt,u2);
1654   emit_movimm(0,rt);
1655   emit_adcimm(0,rt);
1656 }
1657
1658 void emit_call(int a)
1659 {
1660   assem_debug("call %x (%x+%x)\n",a,(int)out+5,a-(int)out-5);
1661   output_byte(0xe8);
1662   output_w32(a-(int)out-4);
1663 }
1664 void emit_jmp(int a)
1665 {
1666   assem_debug("jmp %x (%x+%x)\n",a,(int)out+5,a-(int)out-5);
1667   output_byte(0xe9);
1668   output_w32(a-(int)out-4);
1669 }
1670 void emit_jne(int a)
1671 {
1672   assem_debug("jne %x\n",a);
1673   output_byte(0x0f);
1674   output_byte(0x85);
1675   output_w32(a-(int)out-4);
1676 }
1677 void emit_jeq(int a)
1678 {
1679   assem_debug("jeq %x\n",a);
1680   output_byte(0x0f);
1681   output_byte(0x84);
1682   output_w32(a-(int)out-4);
1683 }
1684 void emit_js(int a)
1685 {
1686   assem_debug("js %x\n",a);
1687   output_byte(0x0f);
1688   output_byte(0x88);
1689   output_w32(a-(int)out-4);
1690 }
1691 void emit_jns(int a)
1692 {
1693   assem_debug("jns %x\n",a);
1694   output_byte(0x0f);
1695   output_byte(0x89);
1696   output_w32(a-(int)out-4);
1697 }
1698 void emit_jl(int a)
1699 {
1700   assem_debug("jl %x\n",a);
1701   output_byte(0x0f);
1702   output_byte(0x8c);
1703   output_w32(a-(int)out-4);
1704 }
1705 void emit_jge(int a)
1706 {
1707   assem_debug("jge %x\n",a);
1708   output_byte(0x0f);
1709   output_byte(0x8d);
1710   output_w32(a-(int)out-4);
1711 }
1712 void emit_jno(int a)
1713 {
1714   assem_debug("jno %x\n",a);
1715   output_byte(0x0f);
1716   output_byte(0x81);
1717   output_w32(a-(int)out-4);
1718 }
1719 void emit_jc(int a)
1720 {
1721   assem_debug("jc %x\n",a);
1722   output_byte(0x0f);
1723   output_byte(0x82);
1724   output_w32(a-(int)out-4);
1725 }
1726
1727 void emit_pushimm(int imm)
1728 {
1729   assem_debug("push $%x\n",imm);
1730   output_byte(0x68);
1731   output_w32(imm);
1732 }
1733 //void emit_pusha()
1734 //{
1735 //  assem_debug("pusha\n");
1736 //  output_byte(0x60);
1737 //}
1738 //void emit_popa()
1739 //{
1740 //  assem_debug("popa\n");
1741 //  output_byte(0x61);
1742 //}
1743 void emit_pushreg(u_int r)
1744 {
1745   assem_debug("push %%%s\n",regname[r]);
1746   assert(r<8);
1747   output_byte(0x50+r);
1748 }
1749 void emit_popreg(u_int r)
1750 {
1751   assem_debug("pop %%%s\n",regname[r]);
1752   assert(r<8);
1753   output_byte(0x58+r);
1754 }
1755 void emit_callreg(u_int r)
1756 {
1757   assem_debug("call *%%%s\n",regname[r]);
1758   assert(r<8);
1759   output_byte(0xFF);
1760   output_modrm(3,r,2);
1761 }
1762 void emit_jmpreg(u_int r)
1763 {
1764   assem_debug("jmp *%%%s\n",regname[r]);
1765   assert(r<8);
1766   output_byte(0xFF);
1767   output_modrm(3,r,4);
1768 }
1769 void emit_jmpmem_indexed(u_int addr,u_int r)
1770 {
1771   assem_debug("jmp *%x(%%%s)\n",addr,regname[r]);
1772   assert(r<8);
1773   output_byte(0xFF);
1774   output_modrm(2,r,4);
1775   output_w32(addr);
1776 }
1777
1778 void emit_readword(int addr, int rt)
1779 {
1780   assem_debug("mov %x,%%%s\n",addr,regname[rt]);
1781   output_byte(0x8B);
1782   output_modrm(0,5,rt);
1783   output_w32(addr-(int)out-4); // Note: rip-relative in 64-bit mode
1784 }
1785 void emit_readword_indexed(int addr, int rs, int rt)
1786 {
1787   assem_debug("mov %x+%%%s,%%%s\n",addr,regname[rs],regname[rt]);
1788   output_byte(0x8B);
1789   if(addr<128&&addr>=-128) {
1790     output_modrm(1,rs,rt);
1791     if(rs==ESP) output_sib(0,4,4);
1792     output_byte(addr);
1793   }
1794   else
1795   {
1796     output_modrm(2,rs,rt);
1797     if(rs==ESP) output_sib(0,4,4);
1798     output_w32(addr);
1799   }
1800 }
1801 void emit_readword_tlb(int addr, int map, int rt)
1802 {
1803   if(map<0) emit_readword(addr+(int)rdram-0x80000000, rt);
1804   else
1805   {
1806     assem_debug("addr32 mov %x(,%%%s,4),%%%s\n",addr,regname[map],regname[rt]);
1807     output_byte(0x67);
1808     output_byte(0x8B);
1809     output_modrm(0,4,rt);
1810     output_sib(2,map,5);
1811     output_w32(addr);
1812   }
1813 }
1814 void emit_readword_indexed_tlb(int addr, int rs, int map, int rt)
1815 {
1816   if(map<0) emit_readword_indexed(addr+(int)rdram-0x80000000, rs, rt);
1817   else {
1818     assem_debug("addr32 mov %x(%%%s,%%%s,4),%%%s\n",addr,regname[rs],regname[map],regname[rt]);
1819     assert(rs!=ESP);
1820     output_byte(0x67);
1821     output_byte(0x8B);
1822     if(addr==0&&rs!=EBP) {
1823       output_modrm(0,4,rt);
1824       output_sib(2,map,rs);
1825     }
1826     else if(addr<128&&addr>=-128) {
1827       output_modrm(1,4,rt);
1828       output_sib(2,map,rs);
1829       output_byte(addr);
1830     }
1831     else
1832     {
1833       output_modrm(2,4,rt);
1834       output_sib(2,map,rs);
1835       output_w32(addr);
1836     }
1837   }
1838 }
1839 void emit_movmem_indexedx4(int addr, int rs, int rt)
1840 {
1841   assem_debug("mov (%x,%%%s,4),%%%s\n",addr,regname[rs],regname[rt]);
1842   output_byte(0x8B);
1843   output_modrm(0,4,rt);
1844   output_sib(2,rs,5);
1845   output_w32(addr);
1846 }
1847 void emit_movmem_indexedx4_addr32(int addr, int rs, int rt)
1848 {
1849   assem_debug("addr32 mov (%x,%%%s,4),%%%s\n",addr,regname[rs],regname[rt]);
1850   output_byte(0x67);
1851   output_byte(0x8B);
1852   output_modrm(0,4,rt);
1853   output_sib(2,rs,5);
1854   output_w32(addr);
1855 }
1856 void emit_movmem_indexedx8(int addr, int rs, int rt)
1857 {
1858   assem_debug("mov (%x,%%%s,8),%%%s\n",addr,regname[rs],regname[rt]);
1859   output_byte(0x8B);
1860   output_modrm(0,4,rt);
1861   output_sib(3,rs,5);
1862   output_w32(addr);
1863 }
1864 void emit_readdword_tlb(int addr, int map, int rh, int rl)
1865 {
1866   if(map<0) {
1867     if(rh>=0) emit_readword(addr+(int)rdram-0x80000000, rh);
1868     emit_readword(addr+(int)rdram-0x7FFFFFFC, rl);
1869   }
1870   else {
1871     if(rh>=0) emit_movmem_indexedx4_addr32(addr, map, rh);
1872     emit_movmem_indexedx4_addr32(addr+4, map, rl);
1873   }
1874 }
1875 void emit_readdword_indexed(int addr, int rs, int rt)
1876 {
1877   assem_debug("mov %x+%%%s,%%%s\n",addr,regname[rs],regname[rt]);
1878   output_rex(1,rt>>3,0,rs>>3);
1879   output_byte(0x8B);
1880   if(addr<128&&addr>=-128) {
1881     output_modrm(1,rs&7,rt&7);
1882     if(rs==ESP) output_sib(0,4,4);
1883     output_byte(addr);
1884   }
1885   else
1886   {
1887     output_modrm(2,rs&7,rt&7);
1888     if(rs==ESP) output_sib(0,4,4);
1889     output_w32(addr);
1890   }
1891 }
1892 void emit_readdword_indexed_tlb(int addr, int rs, int map, int rh, int rl)
1893 {
1894   assert(rh!=rs);
1895   if(rh>=0) emit_readword_indexed_tlb(addr, rs, map, rh);
1896   emit_readword_indexed_tlb(addr+4, rs, map, rl);
1897 }
1898 void emit_movsbl(int addr, int rt)
1899 {
1900   assem_debug("movsbl %x,%%%s\n",addr,regname[rt]);
1901   output_byte(0x0F);
1902   output_byte(0xBE);
1903   output_modrm(0,5,rt);
1904   output_w32(addr-(int)out-4); // Note: rip-relative in 64-bit mode
1905 }
1906 void emit_movsbl_indexed(int addr, int rs, int rt)
1907 {
1908   assem_debug("movsbl %x+%%%s,%%%s\n",addr,regname[rs],regname[rt]);
1909   output_byte(0x0F);
1910   output_byte(0xBE);
1911   output_modrm(2,rs,rt);
1912   output_w32(addr);
1913 }
1914 void emit_movsbl_tlb(int addr, int map, int rt)
1915 {
1916   if(map<0) emit_movsbl(addr+(int)rdram-0x80000000, rt);
1917   else
1918   {
1919     assem_debug("addr32 movsbl %x(,%%%s,4),%%%s\n",addr,regname[map],regname[rt]);
1920     output_byte(0x67);
1921     output_byte(0x0F);
1922     output_byte(0xBE);
1923     output_modrm(0,4,rt);
1924     output_sib(2,map,5);
1925     output_w32(addr);
1926   }
1927 }
1928 void emit_movsbl_indexed_tlb(int addr, int rs, int map, int rt)
1929 {
1930   if(map<0) emit_movsbl_indexed(addr+(int)rdram-0x80000000, rs, rt);
1931   else {
1932     assem_debug("addr32 movsbl %x(%%%s,%%%s,4),%%%s\n",addr,regname[rs],regname[map],regname[rt]);
1933     assert(rs!=ESP);
1934     output_byte(0x67);
1935     output_byte(0x0F);
1936     output_byte(0xBE);
1937     if(addr==0&&rs!=EBP) {
1938       output_modrm(0,4,rt);
1939       output_sib(2,map,rs);
1940     }
1941     else if(addr<128&&addr>=-128) {
1942       output_modrm(1,4,rt);
1943       output_sib(2,map,rs);
1944       output_byte(addr);
1945     }
1946     else
1947     {
1948       output_modrm(2,4,rt);
1949       output_sib(2,map,rs);
1950       output_w32(addr);
1951     }
1952   }
1953 }
1954 void emit_movswl(int addr, int rt)
1955 {
1956   assem_debug("movswl %x,%%%s\n",addr,regname[rt]);
1957   output_byte(0x0F);
1958   output_byte(0xBF);
1959   output_modrm(0,5,rt);
1960   output_w32(addr-(int)out-4); // Note: rip-relative in 64-bit mode
1961 }
1962 void emit_movswl_indexed(int addr, int rs, int rt)
1963 {
1964   assem_debug("movswl %x+%%%s,%%%s\n",addr,regname[rs],regname[rt]);
1965   output_byte(0x0F);
1966   output_byte(0xBF);
1967   output_modrm(2,rs,rt);
1968   output_w32(addr);
1969 }
1970 void emit_movswl_tlb(int addr, int map, int rt)
1971 {
1972   if(map<0) emit_movswl(addr+(int)rdram-0x80000000, rt);
1973   else
1974   {
1975     assem_debug("addr32 movswl %x(,%%%s,4),%%%s\n",addr,regname[map],regname[rt]);
1976     output_byte(0x67);
1977     output_byte(0x0F);
1978     output_byte(0xBF);
1979     output_modrm(0,4,rt);
1980     output_sib(2,map,5);
1981     output_w32(addr);
1982   }
1983 }
1984 void emit_movzbl(int addr, int rt)
1985 {
1986   assem_debug("movzbl %x,%%%s\n",addr,regname[rt]);
1987   output_byte(0x0F);
1988   output_byte(0xB6);
1989   output_modrm(0,5,rt);
1990   output_w32(addr-(int)out-4); // Note: rip-relative in 64-bit mode
1991 }
1992 void emit_movzbl_indexed(int addr, int rs, int rt)
1993 {
1994   assem_debug("movzbl %x+%%%s,%%%s\n",addr,regname[rs],regname[rt]);
1995   output_byte(0x0F);
1996   output_byte(0xB6);
1997   output_modrm(2,rs,rt);
1998   output_w32(addr);
1999 }
2000 void emit_movzbl_tlb(int addr, int map, int rt)
2001 {
2002   if(map<0) emit_movzbl(addr+(int)rdram-0x80000000, rt);
2003   else
2004   {
2005     assem_debug("addr32 movzbl %x(,%%%s,4),%%%s\n",addr,regname[map],regname[rt]);
2006     output_byte(0x67);
2007     output_byte(0x0F);
2008     output_byte(0xB6);
2009     output_modrm(0,4,rt);
2010     output_sib(2,map,5);
2011     output_w32(addr);
2012   }
2013 }
2014 void emit_movzbl_indexed_tlb(int addr, int rs, int map, int rt)
2015 {
2016   if(map<0) emit_movzbl_indexed(addr+(int)rdram-0x80000000, rs, rt);
2017   else {
2018     assem_debug("addr32 movzbl %x(%%%s,%%%s,4),%%%s\n",addr,regname[rs],regname[map],regname[rt]);
2019     assert(rs!=ESP);
2020     output_byte(0x67);
2021     output_byte(0x0F);
2022     output_byte(0xB6);
2023     if(addr==0&&rs!=EBP) {
2024       output_modrm(0,4,rt);
2025       output_sib(2,map,rs);
2026     }
2027     else if(addr<128&&addr>=-128) {
2028       output_modrm(1,4,rt);
2029       output_sib(2,map,rs);
2030       output_byte(addr);
2031     }
2032     else
2033     {
2034       output_modrm(2,4,rt);
2035       output_sib(2,map,rs);
2036       output_w32(addr);
2037     }
2038   }
2039 }
2040 void emit_movzwl(int addr, int rt)
2041 {
2042   assem_debug("movzwl %x,%%%s\n",addr,regname[rt]);
2043   output_byte(0x0F);
2044   output_byte(0xB7);
2045   output_modrm(0,5,rt);
2046   output_w32(addr-(int)out-4); // Note: rip-relative in 64-bit mode
2047 }
2048 void emit_movzwl_indexed(int addr, int rs, int rt)
2049 {
2050   assem_debug("movzwl %x+%%%s,%%%s\n",addr,regname[rs],regname[rt]);
2051   output_byte(0x0F);
2052   output_byte(0xB7);
2053   output_modrm(2,rs,rt);
2054   output_w32(addr);
2055 }
2056 void emit_movzwl_tlb(int addr, int map, int rt)
2057 {
2058   if(map<0) emit_movzwl(addr+(int)rdram-0x80000000, rt);
2059   else
2060   {
2061     assem_debug("addr32 movzwl %x(,%%%s,4),%%%s\n",addr,regname[map],regname[rt]);
2062     output_byte(0x67);
2063     output_byte(0x0F);
2064     output_byte(0xB7);
2065     output_modrm(0,4,rt);
2066     output_sib(2,map,5);
2067     output_w32(addr);
2068   }
2069 }
2070 void emit_movzwl_reg(int rs, int rt)
2071 {
2072   assem_debug("movzwl %%%s,%%%s\n",regname[rs]+1,regname[rt]);
2073   output_byte(0x0F);
2074   output_byte(0xB7);
2075   output_modrm(3,rs,rt);
2076 }
2077
2078 void emit_xchg(int rs, int rt)
2079 {
2080   assem_debug("xchg %%%s,%%%s\n",regname[rs],regname[rt]);
2081   if(rs==EAX) {
2082     output_byte(0x90+rt);
2083   }
2084   else
2085   {
2086     output_byte(0x87);
2087     output_modrm(3,rs,rt);
2088   }
2089 }
2090 void emit_writeword(int rt, int addr)
2091 {
2092   assem_debug("movl %%%s,%x\n",regname[rt],addr);
2093   output_byte(0x89);
2094   output_modrm(0,5,rt);
2095   output_w32(addr-(int)out-4); // Note: rip-relative in 64-bit mode
2096 }
2097 void emit_writeword_indexed(int rt, int addr, int rs)
2098 {
2099   assem_debug("mov %%%s,%x+%%%s\n",regname[rt],addr,regname[rs]);
2100   output_byte(0x89);
2101   if(addr<128&&addr>=-128) {
2102     output_modrm(1,rs,rt);
2103     if(rs==ESP) output_sib(0,4,4);
2104     output_byte(addr);
2105   }
2106   else
2107   {
2108     output_modrm(2,rs,rt);
2109     if(rs==ESP) output_sib(0,4,4);
2110     output_w32(addr);
2111   }
2112 }
2113 void emit_writeword_tlb(int rt, int addr, int map)
2114 {
2115   if(map<0) {
2116     emit_writeword(rt, addr+(int)rdram-0x80000000);
2117   } else {
2118     emit_writeword_indexed(rt, addr, map);
2119   }
2120 }
2121 void emit_writeword_indexed_tlb(int rt, int addr, int rs, int map, int temp)
2122 {
2123   if(map<0) emit_writeword_indexed(rt, addr+(int)rdram-0x80000000, rs);
2124   else {
2125     assem_debug("addr32 mov %%%s,%x(%%%s,%%%s,1)\n",regname[rt],addr,regname[rs],regname[map]);
2126     assert(rs!=ESP);
2127     output_byte(0x67);
2128     output_byte(0x89);
2129     if(addr==0&&rs!=EBP) {
2130       output_modrm(0,4,rt);
2131       output_sib(0,map,rs);
2132     }
2133     else if(addr<128&&addr>=-128) {
2134       output_modrm(1,4,rt);
2135       output_sib(0,map,rs);
2136       output_byte(addr);
2137     }
2138     else
2139     {
2140       output_modrm(2,4,rt);
2141       output_sib(0,map,rs);
2142       output_w32(addr);
2143     }
2144   }
2145 }
2146 void emit_writedword_tlb(int rh, int rl, int addr, int map)
2147 {
2148   assert(rh>=0);
2149   if(map<0) {
2150     emit_writeword(rh, addr+(int)rdram-0x80000000);
2151     emit_writeword(rl, addr+(int)rdram-0x7FFFFFFC);
2152   }
2153   else {
2154     emit_writeword_indexed(rh, addr, map);
2155     emit_writeword_indexed(rl, addr+4, map);
2156   }
2157 }
2158 void emit_writedword_indexed_tlb(int rh, int rl, int addr, int rs, int map, int temp)
2159 {
2160   assert(rh>=0);
2161   emit_writeword_indexed_tlb(rh, addr, rs, map, temp);
2162   emit_writeword_indexed_tlb(rl, addr+4, rs, map, temp);
2163 }
2164 void emit_writehword(int rt, int addr)
2165 {
2166   assem_debug("movw %%%s,%x\n",regname[rt]+1,addr);
2167   output_byte(0x66);
2168   output_byte(0x89);
2169   output_modrm(0,5,rt);
2170   output_w32(addr-(int)out-4); // Note: rip-relative in 64-bit mode
2171 }
2172 void emit_writehword_indexed(int rt, int addr, int rs)
2173 {
2174   assem_debug("movw %%%s,%x+%%%s\n",regname[rt]+1,addr,regname[rs]);
2175   output_byte(0x66);
2176   output_byte(0x89);
2177   if(addr<128&&addr>=-128) {
2178     output_modrm(1,rs,rt);
2179     output_byte(addr);
2180   }
2181   else
2182   {
2183     output_modrm(2,rs,rt);
2184     output_w32(addr);
2185   }
2186 }
2187 void emit_writehword_tlb(int rt, int addr, int map)
2188 {
2189   if(map<0) {
2190     emit_writehword(rt, addr+(int)rdram-0x80000000);
2191   } else {
2192     emit_writehword_indexed(rt, addr, map);
2193   }
2194 }
2195 void emit_writebyte(int rt, int addr)
2196 {
2197   if(rt<4) {
2198     assem_debug("movb %%%cl,%x\n",regname[rt][1],addr);
2199     output_byte(0x88);
2200     output_modrm(0,5,rt);
2201     output_w32(addr-(int)out-4); // Note: rip-relative in 64-bit mode
2202   }
2203   else
2204   {
2205     emit_xchg(EAX,rt);
2206     emit_writebyte(EAX,addr);
2207     emit_xchg(EAX,rt);
2208   }
2209 }
2210 void emit_writebyte_indexed(int rt, int addr, int rs)
2211 {
2212   if(rt<4) {
2213     assem_debug("movb %%%cl,%x+%%%s\n",regname[rt][1],addr,regname[rs]);
2214     output_byte(0x88);
2215     if(addr<128&&addr>=-128) {
2216       output_modrm(1,rs,rt);
2217       output_byte(addr);
2218     }
2219     else
2220     {
2221       output_modrm(2,rs,rt);
2222       output_w32(addr);
2223     }
2224   }
2225   else
2226   {
2227     emit_xchg(EAX,rt);
2228     emit_writebyte_indexed(EAX,addr,rs==EAX?rt:rs);
2229     emit_xchg(EAX,rt);
2230   }
2231 }
2232 void emit_writebyte_tlb(int rt, int addr, int map)
2233 {
2234   if(map<0) {
2235     emit_writebyte(rt, addr+(int)rdram-0x80000000);
2236   } else {
2237     emit_writebyte_indexed(rt, addr, map);
2238   }
2239 }
2240 void emit_writebyte_indexed_tlb(int rt, int addr, int rs, int map, int temp)
2241 {
2242   if(map<0) emit_writebyte_indexed(rt, addr+(int)rdram-0x80000000, rs);
2243   else
2244   if(rt<4) {
2245     assem_debug("addr32 movb %%%cl,%x(%%%s,%%%s,1)\n",regname[rt][1],addr,regname[rs],regname[map]);
2246     assert(rs!=ESP);
2247     output_byte(0x67);
2248     output_byte(0x88);
2249     if(addr==0&&rs!=EBP) {
2250       output_modrm(0,4,rt);
2251       output_sib(0,map,rs);
2252     }
2253     else if(addr<128&&addr>=-128) {
2254       output_modrm(1,4,rt);
2255       output_sib(0,map,rs);
2256       output_byte(addr);
2257     }
2258     else
2259     {
2260       output_modrm(2,4,rt);
2261       output_sib(0,map,rs);
2262       output_w32(addr);
2263     }
2264   }
2265   else
2266   {
2267     emit_xchg(EAX,rt);
2268     emit_writebyte_indexed_tlb(EAX,addr,rs==EAX?rt:rs,map==EAX?rt:map,temp);
2269     emit_xchg(EAX,rt);
2270   }
2271 }
2272 void emit_writeword_imm(int imm, int addr)
2273 {
2274   assem_debug("movl $%x,%x\n",imm,addr);
2275   output_byte(0xC7);
2276   output_modrm(0,5,0);
2277   output_w32(addr-(int)out-8); // Note: rip-relative in 64-bit mode
2278   output_w32(imm);
2279 }
2280 void emit_writeword_imm_esp(int imm, int addr)
2281 {
2282   assem_debug("mov $%x,%x(%%esp)\n",imm,addr);
2283   assert(addr>=-128&&addr<128);
2284   output_byte(0xC7);
2285   output_modrm(!!addr,4,0);
2286   output_sib(0,4,4);
2287   if(addr) output_byte(addr);
2288   output_w32(imm);
2289 }
2290 void emit_writedword_imm32(int imm, int addr)
2291 {
2292   assem_debug("movq $%x,%x\n",imm,addr);
2293   output_rex(1,0,0,0);
2294   output_byte(0xC7);
2295   output_modrm(0,5,0);
2296   output_w32(addr-(int)out-8); // Note: rip-relative in 64-bit mode
2297   output_w32(imm); // Note: This 32-bit value will be sign extended
2298 }
2299 void emit_writebyte_imm(int imm, int addr)
2300 {
2301   assem_debug("movb $%x,%x\n",imm,addr);
2302   assert(imm>=-128&&imm<128);
2303   output_byte(0xC6);
2304   output_modrm(0,5,0);
2305   output_w32(addr-(int)out-5); // Note: rip-relative in 64-bit mode
2306   output_byte(imm);
2307 }
2308
2309 void emit_mul(int rs)
2310 {
2311   assem_debug("mul %%%s\n",regname[rs]);
2312   output_byte(0xF7);
2313   output_modrm(3,rs,4);
2314 }
2315 void emit_imul(int rs)
2316 {
2317   assem_debug("imul %%%s\n",regname[rs]);
2318   output_byte(0xF7);
2319   output_modrm(3,rs,5);
2320 }
2321 void emit_div(int rs)
2322 {
2323   assem_debug("div %%%s\n",regname[rs]);
2324   output_byte(0xF7);
2325   output_modrm(3,rs,6);
2326 }
2327 void emit_idiv(int rs)
2328 {
2329   assem_debug("idiv %%%s\n",regname[rs]);
2330   output_byte(0xF7);
2331   output_modrm(3,rs,7);
2332 }
2333 void emit_cdq()
2334 {
2335   assem_debug("cdq\n");
2336   output_byte(0x99);
2337 }
2338
2339 // Load 2 immediates optimizing for small code size
2340 void emit_mov2imm_compact(int imm1,u_int rt1,int imm2,u_int rt2)
2341 {
2342   emit_movimm(imm1,rt1);
2343   if(imm2-imm1<128&&imm2-imm1>=-128) emit_addimm(rt1,imm2-imm1,rt2);
2344   else emit_movimm(imm2,rt2);
2345 }
2346
2347 // special case for checking pending_exception
2348 void emit_cmpmem_imm_byte(int addr,int imm)
2349 {
2350   assert(imm<128&&imm>=-127);
2351   assem_debug("cmpb $%d,%x\n",imm,addr);
2352   output_byte(0x80);
2353   output_modrm(0,5,7);
2354   output_w32(addr-(int)out-5); // Note: rip-relative in 64-bit mode
2355   output_byte(imm);
2356 }
2357
2358 // special case for checking invalid_code
2359 void emit_cmpmem_indexedsr12_imm(int addr,int r,int imm)
2360 {
2361   assert(imm<128&&imm>=-127);
2362   assert(r>=0&&r<8);
2363   emit_shrimm(r,12,r);
2364   assem_debug("cmp $%d,%x+%%%s\n",imm,addr,regname[r]);
2365   output_byte(0x80);
2366   output_modrm(2,r,7);
2367   output_w32(addr);
2368   output_byte(imm);
2369 }
2370
2371 // special case for checking hash_table
2372 void emit_cmpmem_indexed(int addr,int rs,int rt)
2373 {
2374   assert(rs>=0&&rs<8);
2375   assert(rt>=0&&rt<8);
2376   assem_debug("cmp %x+%%%s,%%%s\n",addr,regname[rs],regname[rt]);
2377   output_byte(0x39);
2378   output_modrm(2,rs,rt);
2379   output_w32(addr);
2380 }
2381
2382 // special case for checking memory_map in verify_mapping
2383 void emit_cmpmem(int addr,int rt)
2384 {
2385   assert(rt>=0&&rt<8);
2386   assem_debug("cmp %x,%%%s\n",addr,regname[rt]);
2387   output_byte(0x39);
2388   output_modrm(0,5,rt);
2389   output_w32((int)addr-(int)out-4); // Note: rip-relative in 64-bit mode
2390 }
2391
2392 // Used to preload hash table entries
2393 void emit_prefetch(void *addr)
2394 {
2395   assem_debug("prefetch %x\n",(int)addr);
2396   output_byte(0x0F);
2397   output_byte(0x18);
2398   output_modrm(0,5,1);
2399   output_w32((int)addr-(int)out-4); // Note: rip-relative in 64-bit mode
2400 }
2401
2402 /*void emit_submem(int r,int addr)
2403 {
2404   assert(r>=0&&r<8);
2405   assem_debug("sub %x,%%%s\n",addr,regname[r]);
2406   output_byte(0x2B);
2407   output_modrm(0,5,r);
2408   output_w32((int)addr);
2409 }*/
2410
2411 void emit_flds(int r)
2412 {
2413   assem_debug("flds (%%%s)\n",regname[r]);
2414   output_byte(0xd9);
2415   if(r!=EBP) output_modrm(0,r,0);
2416   else {output_modrm(1,EBP,0);output_byte(0);}
2417 }
2418 void emit_fldl(int r)
2419 {
2420   assem_debug("fldl (%%%s)\n",regname[r]);
2421   output_byte(0xdd);
2422   if(r!=EBP) output_modrm(0,r,0);
2423   else {output_modrm(1,EBP,0);output_byte(0);}
2424 }
2425 void emit_fucomip(u_int r)
2426 {
2427   assem_debug("fucomip %d\n",r);
2428   assert(r<8);
2429   output_byte(0xdf);
2430   output_byte(0xe8+r);
2431 }
2432 void emit_fchs()
2433 {
2434   assem_debug("fchs\n");
2435   output_byte(0xd9);
2436   output_byte(0xe0);
2437 }
2438 void emit_fabs()
2439 {
2440   assem_debug("fabs\n");
2441   output_byte(0xd9);
2442   output_byte(0xe1);
2443 }
2444 void emit_fsqrt()
2445 {
2446   assem_debug("fsqrt\n");
2447   output_byte(0xd9);
2448   output_byte(0xfa);
2449 }
2450 void emit_fadds(int r)
2451 {
2452   assem_debug("fadds (%%%s)\n",regname[r]);
2453   output_byte(0xd8);
2454   if(r!=EBP) output_modrm(0,r,0);
2455   else {output_modrm(1,EBP,0);output_byte(0);}
2456 }
2457 void emit_faddl(int r)
2458 {
2459   assem_debug("faddl (%%%s)\n",regname[r]);
2460   output_byte(0xdc);
2461   if(r!=EBP) output_modrm(0,r,0);
2462   else {output_modrm(1,EBP,0);output_byte(0);}
2463 }
2464 void emit_fadd(int r)
2465 {
2466   assem_debug("fadd st%d\n",r);
2467   output_byte(0xd8);
2468   output_byte(0xc0+r);
2469 }
2470 void emit_fsubs(int r)
2471 {
2472   assem_debug("fsubs (%%%s)\n",regname[r]);
2473   output_byte(0xd8);
2474   if(r!=EBP) output_modrm(0,r,4);
2475   else {output_modrm(1,EBP,4);output_byte(0);}
2476 }
2477 void emit_fsubl(int r)
2478 {
2479   assem_debug("fsubl (%%%s)\n",regname[r]);
2480   output_byte(0xdc);
2481   if(r!=EBP) output_modrm(0,r,4);
2482   else {output_modrm(1,EBP,4);output_byte(0);}
2483 }
2484 void emit_fsub(int r)
2485 {
2486   assem_debug("fsub st%d\n",r);
2487   output_byte(0xd8);
2488   output_byte(0xe0+r);
2489 }
2490 void emit_fmuls(int r)
2491 {
2492   assem_debug("fmuls (%%%s)\n",regname[r]);
2493   output_byte(0xd8);
2494   if(r!=EBP) output_modrm(0,r,1);
2495   else {output_modrm(1,EBP,1);output_byte(0);}
2496 }
2497 void emit_fmull(int r)
2498 {
2499   assem_debug("fmull (%%%s)\n",regname[r]);
2500   output_byte(0xdc);
2501   if(r!=EBP) output_modrm(0,r,1);
2502   else {output_modrm(1,EBP,1);output_byte(0);}
2503 }
2504 void emit_fmul(int r)
2505 {
2506   assem_debug("fmul st%d\n",r);
2507   output_byte(0xd8);
2508   output_byte(0xc8+r);
2509 }
2510 void emit_fdivs(int r)
2511 {
2512   assem_debug("fdivs (%%%s)\n",regname[r]);
2513   output_byte(0xd8);
2514   if(r!=EBP) output_modrm(0,r,6);
2515   else {output_modrm(1,EBP,6);output_byte(0);}
2516 }
2517 void emit_fdivl(int r)
2518 {
2519   assem_debug("fdivl (%%%s)\n",regname[r]);
2520   output_byte(0xdc);
2521   if(r!=EBP) output_modrm(0,r,6);
2522   else {output_modrm(1,EBP,6);output_byte(0);}
2523 }
2524 void emit_fdiv(int r)
2525 {
2526   assem_debug("fdiv st%d\n",r);
2527   output_byte(0xd8);
2528   output_byte(0xf0+r);
2529 }
2530 void emit_fpop()
2531 {
2532   // fstp st(0)
2533   assem_debug("fpop\n");
2534   output_byte(0xdd);
2535   output_byte(0xd8);
2536 }
2537 void emit_fildl(int r)
2538 {
2539   assem_debug("fildl (%%%s)\n",regname[r]);
2540   output_byte(0xdb);
2541   if(r!=EBP) output_modrm(0,r,0);
2542   else {output_modrm(1,EBP,0);output_byte(0);}
2543 }
2544 void emit_fildll(int r)
2545 {
2546   assem_debug("fildll (%%%s)\n",regname[r]);
2547   output_byte(0xdf);
2548   if(r!=EBP) output_modrm(0,r,5);
2549   else {output_modrm(1,EBP,5);output_byte(0);}
2550 }
2551 void emit_fistpl(int r)
2552 {
2553   assem_debug("fistpl (%%%s)\n",regname[r]);
2554   output_byte(0xdb);
2555   if(r!=EBP) output_modrm(0,r,3);
2556   else {output_modrm(1,EBP,3);output_byte(0);}
2557 }
2558 void emit_fistpll(int r)
2559 {
2560   assem_debug("fistpll (%%%s)\n",regname[r]);
2561   output_byte(0xdf);
2562   if(r!=EBP) output_modrm(0,r,7);
2563   else {output_modrm(1,EBP,7);output_byte(0);}
2564 }
2565 void emit_fstps(int r)
2566 {
2567   assem_debug("fstps (%%%s)\n",regname[r]);
2568   output_byte(0xd9);
2569   if(r!=EBP) output_modrm(0,r,3);
2570   else {output_modrm(1,EBP,3);output_byte(0);}
2571 }
2572 void emit_fstpl(int r)
2573 {
2574   assem_debug("fstpl (%%%s)\n",regname[r]);
2575   output_byte(0xdd);
2576   if(r!=EBP) output_modrm(0,r,3);
2577   else {output_modrm(1,EBP,3);output_byte(0);}
2578 }
2579 void emit_fnstcw_stack()
2580 {
2581   assem_debug("fnstcw (%%esp)\n");
2582   output_byte(0xd9);
2583   output_modrm(0,4,7);
2584   output_sib(0,4,4);
2585 }
2586 void emit_fldcw_stack()
2587 {
2588   assem_debug("fldcw (%%esp)\n");
2589   output_byte(0xd9);
2590   output_modrm(0,4,5);
2591   output_sib(0,4,4);
2592 }
2593 void emit_fldcw_indexed(int addr,int r)
2594 {
2595   assem_debug("fldcw %x(%%%s)\n",addr,regname[r]);
2596   output_byte(0xd9);
2597   output_modrm(0,4,5);
2598   output_sib(1,r,5);
2599   output_w32(addr);
2600 }
2601 void emit_fldcw(int addr)
2602 {
2603   assem_debug("fldcw %x\n",addr);
2604   output_byte(0xd9);
2605   output_modrm(0,5,5);
2606   output_w32(addr-(int)out-4); // Note: rip-relative in 64-bit mode
2607 }
2608 void emit_movss_load(u_int addr,u_int ssereg)
2609 {
2610   assem_debug("movss (%%%s),xmm%d\n",regname[addr],ssereg);
2611   assert(ssereg<8);
2612   output_byte(0xf3);
2613   output_byte(0x0f);
2614   output_byte(0x10);
2615   if(addr!=EBP) output_modrm(0,addr,ssereg);
2616   else {output_modrm(1,EBP,ssereg);output_byte(0);}
2617 }
2618 void emit_movsd_load(u_int addr,u_int ssereg)
2619 {
2620   assem_debug("movsd (%%%s),xmm%d\n",regname[addr],ssereg);
2621   assert(ssereg<8);
2622   output_byte(0xf2);
2623   output_byte(0x0f);
2624   output_byte(0x10);
2625   if(addr!=EBP) output_modrm(0,addr,ssereg);
2626   else {output_modrm(1,EBP,ssereg);output_byte(0);}
2627 }
2628 void emit_movd_store(u_int ssereg,u_int addr)
2629 {
2630   assem_debug("movd xmm%d,(%%%s)\n",ssereg,regname[addr]);
2631   assert(ssereg<8);
2632   output_byte(0x66);
2633   output_byte(0x0f);
2634   output_byte(0x7e);
2635   if(addr!=EBP) output_modrm(0,addr,ssereg);
2636   else {output_modrm(1,EBP,ssereg);output_byte(0);}
2637 }
2638 void emit_cvttps2dq(u_int ssereg1,u_int ssereg2)
2639 {
2640   assem_debug("cvttps2dq xmm%d,xmm%d\n",ssereg1,ssereg2);
2641   assert(ssereg1<8);
2642   assert(ssereg2<8);
2643   output_byte(0xf3);
2644   output_byte(0x0f);
2645   output_byte(0x5b);
2646   output_modrm(3,ssereg1,ssereg2);
2647 }
2648 void emit_cvttpd2dq(u_int ssereg1,u_int ssereg2)
2649 {
2650   assem_debug("cvttpd2dq xmm%d,xmm%d\n",ssereg1,ssereg2);
2651   assert(ssereg1<8);
2652   assert(ssereg2<8);
2653   output_byte(0x66);
2654   output_byte(0x0f);
2655   output_byte(0xe6);
2656   output_modrm(3,ssereg1,ssereg2);
2657 }
2658
2659 unsigned int count_bits(u_int reglist)
2660 {
2661   int count=0;
2662   while(reglist)
2663   {
2664     count+=reglist&1;
2665     reglist>>=1;
2666   }
2667   return count;
2668 }
2669
2670 // Save registers before function call
2671 // This code is executed infrequently so we try to minimize code size
2672 // by pushing registers onto the stack instead of writing them to their
2673 // usual locations
2674 void save_regs(u_int reglist)
2675 {
2676   int hr;
2677   int count=count_bits(reglist);
2678   if(count) {
2679     for(hr=0;hr<HOST_REGS;hr++) {
2680       if(hr!=EXCLUDE_REG) {
2681         if((reglist>>hr)&1) {
2682           emit_pushreg(hr);
2683         }
2684       }
2685     }
2686   }
2687   emit_addimm(ESP,-(8-count)*8,ESP);
2688 }
2689 // Restore registers after function call
2690 void restore_regs(u_int reglist)
2691 {
2692   int hr;
2693   int count=count_bits(reglist);
2694   emit_addimm(ESP,(8-count)*8,ESP);
2695   if(count) {
2696     for(hr=HOST_REGS-1;hr>=0;hr--) {
2697       if(hr!=EXCLUDE_REG) {
2698         if((reglist>>hr)&1) {
2699           emit_popreg(hr);
2700         }
2701       }
2702     }
2703   }
2704 }
2705
2706 /* Stubs/epilogue */
2707
2708 emit_extjump2(int addr, int target, int linker)
2709 {
2710   u_char *ptr=(u_char *)addr;
2711   if(*ptr==0x0f)
2712   {
2713     assert(ptr[1]>=0x80&&ptr[1]<=0x8f);
2714     addr+=2;
2715   }
2716   else
2717   {
2718     assert(*ptr==0xe8||*ptr==0xe9);
2719     addr++;
2720   }
2721   emit_movimm(target,EAX);
2722   emit_movimm(addr,EBX);
2723   //assert(addr>=0x7000000&&addr<0x7FFFFFF);
2724   //assert((target>=0x80000000&&target<0x80800000)||(target>0xA4000000&&target<0xA4001000));
2725 //DEBUG >
2726 #ifdef DEBUG_CYCLE_COUNT
2727   emit_readword((int)&last_count,ECX);
2728   emit_add(HOST_CCREG,ECX,HOST_CCREG);
2729   emit_readword((int)&next_interupt,ECX);
2730   emit_writeword(HOST_CCREG,(int)&Count);
2731   emit_sub(HOST_CCREG,ECX,HOST_CCREG);
2732   emit_writeword(ECX,(int)&last_count);
2733 #endif
2734 //DEBUG <
2735   emit_jmp(linker);
2736 }
2737
2738 emit_extjump(int addr, int target)
2739 {
2740   emit_extjump2(addr, target, (int)dyna_linker);
2741 }
2742 emit_extjump_ds(int addr, int target)
2743 {
2744   emit_extjump2(addr, target, (int)dyna_linker_ds);
2745 }
2746
2747 do_readstub(int n)
2748 {
2749   assem_debug("do_readstub %x\n",start+stubs[n][3]*4);
2750   set_jump_target(stubs[n][1],(int)out);
2751   int type=stubs[n][0];
2752   int i=stubs[n][3];
2753   int rs=stubs[n][4];
2754   struct regstat *i_regs=(struct regstat *)stubs[n][5];
2755   u_int reglist=stubs[n][7];
2756   signed char *i_regmap=i_regs->regmap;
2757   int addr=get_reg(i_regmap,AGEN1+(i&1));
2758   int rth,rt;
2759   int ds;
2760   if(itype[i]==C1LS||itype[i]==LOADLR) {
2761     rth=get_reg(i_regmap,FTEMP|64);
2762     rt=get_reg(i_regmap,FTEMP);
2763   }else{
2764     rth=get_reg(i_regmap,rt1[i]|64);
2765     rt=get_reg(i_regmap,rt1[i]);
2766   }
2767   assert(rs>=0);
2768   assert(rt>=0);
2769   if(addr<0) addr=rt;
2770   assert(addr>=0);
2771   int ftable=0;
2772   if(type==LOADB_STUB||type==LOADBU_STUB)
2773     ftable=(int)readmemb;
2774   if(type==LOADH_STUB||type==LOADHU_STUB)
2775     ftable=(int)readmemh;
2776   if(type==LOADW_STUB)
2777     ftable=(int)readmem;
2778   if(type==LOADD_STUB)
2779     ftable=(int)readmemd;
2780   emit_writeword(rs,(int)&address);
2781   emit_shrimm(rs,16,addr);
2782   emit_movmem_indexedx8(ftable,addr,addr);
2783   save_regs(reglist);
2784   ds=i_regs!=&regs[i];
2785   int real_rs=(itype[i]==LOADLR)?-1:get_reg(i_regmap,rs1[i]);
2786   if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs)),i);
2787   wb_dirtys(i_regs->regmap_entry,i_regs->was32,i_regs->wasdirty&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs)));
2788   
2789   int temp;
2790   int cc=get_reg(i_regmap,CCREG);
2791   if(cc<0) {
2792     if(addr==HOST_CCREG)
2793     {
2794       cc=0;temp=1;
2795       assert(cc!=HOST_CCREG);
2796       assert(temp!=HOST_CCREG);
2797       emit_loadreg(CCREG,cc);
2798     }
2799     else
2800     {
2801       cc=HOST_CCREG;
2802       emit_loadreg(CCREG,cc);
2803       temp=!addr;
2804     }
2805   }
2806   else
2807   {
2808     temp=!addr;
2809   }
2810   emit_readword((int)&last_count,temp);
2811   emit_addimm(cc,CLOCK_DIVIDER*(stubs[n][6]+1),cc);
2812   emit_writeword_imm_esp(start+i*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,0);
2813   emit_add(cc,temp,cc);
2814   emit_writeword(cc,(int)&Count);
2815   emit_callreg(addr);
2816   // We really shouldn't need to update the count here,
2817   // but not doing so causes random crashes...
2818   emit_readword((int)&Count,HOST_CCREG);
2819   emit_readword((int)&next_interupt,ECX);
2820   emit_addimm(HOST_CCREG,-CLOCK_DIVIDER*(stubs[n][6]+1),HOST_CCREG);
2821   emit_sub(HOST_CCREG,ECX,HOST_CCREG);
2822   emit_writeword(ECX,(int)&last_count);
2823   emit_storereg(CCREG,HOST_CCREG);
2824   restore_regs(reglist);
2825   if((cc=get_reg(i_regmap,CCREG))>=0) {
2826     emit_loadreg(CCREG,cc);
2827   }
2828   if(type==LOADB_STUB)
2829     emit_movsbl((int)&readmem_dword,rt);
2830   if(type==LOADBU_STUB)
2831     emit_movzbl((int)&readmem_dword,rt);
2832   if(type==LOADH_STUB)
2833     emit_movswl((int)&readmem_dword,rt);
2834   if(type==LOADHU_STUB)
2835     emit_movzwl((int)&readmem_dword,rt);
2836   if(type==LOADW_STUB)
2837     emit_readword((int)&readmem_dword,rt);
2838   if(type==LOADD_STUB) {
2839     emit_readword((int)&readmem_dword,rt);
2840     if(rth>=0) emit_readword(((int)&readmem_dword)+4,rth);
2841   }
2842   emit_jmp(stubs[n][2]); // return address
2843 }
2844
2845 inline_readstub(int type, int i, u_int addr, signed char regmap[], int target, int adj, u_int reglist)
2846 {
2847   assem_debug("inline_readstub\n");
2848   int rs=get_reg(regmap,target);
2849   int rth=get_reg(regmap,target|64);
2850   int rt=get_reg(regmap,target);
2851   assert(rs>=0);
2852   assert(rt>=0);
2853   int ftable=0;
2854   if(type==LOADB_STUB||type==LOADBU_STUB)
2855     ftable=(int)readmemb;
2856   if(type==LOADH_STUB||type==LOADHU_STUB)
2857     ftable=(int)readmemh;
2858   if(type==LOADW_STUB)
2859     ftable=(int)readmem;
2860   if(type==LOADD_STUB)
2861     ftable=(int)readmemd;
2862   #ifdef HOST_IMM_ADDR32
2863   emit_writeword_imm(addr,(int)&address);
2864   #else
2865   emit_writeword(rs,(int)&address);
2866   #endif
2867   save_regs(reglist);
2868   int cc=get_reg(regmap,CCREG);
2869   int temp;
2870   if(cc<0) {
2871     if(rs==HOST_CCREG)
2872     {
2873       cc=0;temp=1;
2874       assert(cc!=HOST_CCREG);
2875       assert(temp!=HOST_CCREG);
2876       emit_loadreg(CCREG,cc);
2877     }
2878     else
2879     {
2880       cc=HOST_CCREG;
2881       emit_loadreg(CCREG,cc);
2882       temp=!rs;
2883     }
2884   }
2885   else
2886   {
2887     temp=!rs;
2888   }
2889   emit_readword((int)&last_count,temp);
2890   emit_addimm(cc,CLOCK_DIVIDER*(adj+1),cc);
2891   emit_add(cc,temp,cc);
2892   emit_writeword(cc,(int)&Count);
2893   if((signed int)addr>=(signed int)0xC0000000) {
2894     // Pagefault address
2895     int ds=regmap!=regs[i].regmap;
2896     emit_writeword_imm_esp(start+i*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,0);
2897   }
2898   emit_call(((uint64_t *)ftable)[addr>>16]);
2899   // We really shouldn't need to update the count here,
2900   // but not doing so causes random crashes...
2901   emit_readword((int)&Count,HOST_CCREG);
2902   emit_readword((int)&next_interupt,ECX);
2903   emit_addimm(HOST_CCREG,-CLOCK_DIVIDER*(adj+1),HOST_CCREG);
2904   emit_sub(HOST_CCREG,ECX,HOST_CCREG);
2905   emit_writeword(ECX,(int)&last_count);
2906   emit_storereg(CCREG,HOST_CCREG);
2907   restore_regs(reglist);
2908   if((cc=get_reg(regmap,CCREG))>=0) {
2909     emit_loadreg(CCREG,cc);
2910   }
2911   if(type==LOADB_STUB)
2912     emit_movsbl((int)&readmem_dword,rt);
2913   if(type==LOADBU_STUB)
2914     emit_movzbl((int)&readmem_dword,rt);
2915   if(type==LOADH_STUB)
2916     emit_movswl((int)&readmem_dword,rt);
2917   if(type==LOADHU_STUB)
2918     emit_movzwl((int)&readmem_dword,rt);
2919   if(type==LOADW_STUB)
2920     emit_readword((int)&readmem_dword,rt);
2921   if(type==LOADD_STUB) {
2922     emit_readword((int)&readmem_dword,rt);
2923     if(rth>=0) emit_readword(((int)&readmem_dword)+4,rth);
2924   }
2925 }
2926
2927 do_writestub(int n)
2928 {
2929   assem_debug("do_writestub %x\n",start+stubs[n][3]*4);
2930   set_jump_target(stubs[n][1],(int)out);
2931   int type=stubs[n][0];
2932   int i=stubs[n][3];
2933   int rs=stubs[n][4];
2934   struct regstat *i_regs=(struct regstat *)stubs[n][5];
2935   u_int reglist=stubs[n][7];
2936   signed char *i_regmap=i_regs->regmap;
2937   int addr=get_reg(i_regmap,AGEN1+(i&1));
2938   int rth,rt,r;
2939   int ds;
2940   if(itype[i]==C1LS) {
2941     rth=get_reg(i_regmap,FTEMP|64);
2942     rt=get_reg(i_regmap,r=FTEMP);
2943   }else{
2944     rth=get_reg(i_regmap,rs2[i]|64);
2945     rt=get_reg(i_regmap,r=rs2[i]);
2946   }
2947   assert(rs>=0);
2948   assert(rt>=0);
2949   if(addr<0) addr=get_reg(i_regmap,-1);
2950   assert(addr>=0);
2951   int ftable=0;
2952   if(type==STOREB_STUB)
2953     ftable=(int)writememb;
2954   if(type==STOREH_STUB)
2955     ftable=(int)writememh;
2956   if(type==STOREW_STUB)
2957     ftable=(int)writemem;
2958   if(type==STORED_STUB)
2959     ftable=(int)writememd;
2960   emit_writeword(rs,(int)&address);
2961   emit_shrimm(rs,16,addr);
2962   emit_movmem_indexedx8(ftable,addr,addr);
2963   if(type==STOREB_STUB)
2964     emit_writebyte(rt,(int)&byte);
2965   if(type==STOREH_STUB)
2966     emit_writehword(rt,(int)&hword);
2967   if(type==STOREW_STUB)
2968     emit_writeword(rt,(int)&word);
2969   if(type==STORED_STUB) {
2970     emit_writeword(rt,(int)&dword);
2971     emit_writeword(r?rth:rt,(int)&dword+4);
2972   }
2973   save_regs(reglist);
2974   ds=i_regs!=&regs[i];
2975   int real_rs=get_reg(i_regmap,rs1[i]);
2976   if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs)),i);
2977   wb_dirtys(i_regs->regmap_entry,i_regs->was32,i_regs->wasdirty&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs)));
2978   
2979   int temp;
2980   int cc=get_reg(i_regmap,CCREG);
2981   if(cc<0) {
2982     if(addr==HOST_CCREG)
2983     {
2984       cc=0;temp=1;
2985       assert(cc!=HOST_CCREG);
2986       assert(temp!=HOST_CCREG);
2987       emit_loadreg(CCREG,cc);
2988     }
2989     else
2990     {
2991       cc=HOST_CCREG;
2992       emit_loadreg(CCREG,cc);
2993       temp=!addr;
2994     }
2995   }
2996   else
2997   {
2998     temp=!addr;
2999   }
3000   emit_readword((int)&last_count,temp);
3001   emit_addimm(cc,CLOCK_DIVIDER*(stubs[n][6]+1),cc);
3002   emit_writeword_imm_esp(start+i*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,0);
3003   emit_add(cc,temp,cc);
3004   emit_writeword(cc,(int)&Count);
3005   emit_callreg(addr);
3006   emit_readword((int)&Count,HOST_CCREG);
3007   emit_readword((int)&next_interupt,ECX);
3008   emit_addimm(HOST_CCREG,-CLOCK_DIVIDER*(stubs[n][6]+1),HOST_CCREG);
3009   emit_sub(HOST_CCREG,ECX,HOST_CCREG);
3010   emit_writeword(ECX,(int)&last_count);
3011   emit_storereg(CCREG,HOST_CCREG);
3012   restore_regs(reglist);
3013   if((cc=get_reg(i_regmap,CCREG))>=0) {
3014     emit_loadreg(CCREG,cc);
3015   }
3016   emit_jmp(stubs[n][2]); // return address
3017 }
3018
3019 inline_writestub(int type, int i, u_int addr, signed char regmap[], int target, int adj, u_int reglist)
3020 {
3021   assem_debug("inline_writestub\n");
3022   int rs=get_reg(regmap,-1);
3023   int rth=get_reg(regmap,target|64);
3024   int rt=get_reg(regmap,target);
3025   assert(rs>=0);
3026   assert(rt>=0);
3027   int ftable=0;
3028   if(type==STOREB_STUB)
3029     ftable=(int)writememb;
3030   if(type==STOREH_STUB)
3031     ftable=(int)writememh;
3032   if(type==STOREW_STUB)
3033     ftable=(int)writemem;
3034   if(type==STORED_STUB)
3035     ftable=(int)writememd;
3036   emit_writeword(rs,(int)&address);
3037   if(type==STOREB_STUB)
3038     emit_writebyte(rt,(int)&byte);
3039   if(type==STOREH_STUB)
3040     emit_writehword(rt,(int)&hword);
3041   if(type==STOREW_STUB)
3042     emit_writeword(rt,(int)&word);
3043   if(type==STORED_STUB) {
3044     emit_writeword(rt,(int)&dword);
3045     emit_writeword(target?rth:rt,(int)&dword+4);
3046   }
3047   save_regs(reglist);
3048   int cc=get_reg(regmap,CCREG);
3049   int temp;
3050   if(cc<0) {
3051     if(rs==HOST_CCREG)
3052     {
3053       cc=0;temp=1;
3054       assert(cc!=HOST_CCREG);
3055       assert(temp!=HOST_CCREG);
3056       emit_loadreg(CCREG,cc);
3057     }
3058     else
3059     {
3060       cc=HOST_CCREG;
3061       emit_loadreg(CCREG,cc);
3062       temp=!rs;
3063     }
3064   }
3065   else
3066   {
3067     temp=!rs;
3068   }
3069   emit_readword((int)&last_count,temp);
3070   emit_addimm(cc,CLOCK_DIVIDER*(adj+1),cc);
3071   emit_add(cc,temp,cc);
3072   emit_writeword(cc,(int)&Count);
3073   if((signed int)addr>=(signed int)0xC0000000) {
3074     // Pagefault address
3075     int ds=regmap!=regs[i].regmap;
3076     emit_writeword_imm_esp(start+i*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,0);
3077   }
3078   emit_call(((uint64_t *)ftable)[addr>>16]);
3079   emit_readword((int)&Count,HOST_CCREG);
3080   emit_readword((int)&next_interupt,ECX);
3081   emit_addimm(HOST_CCREG,-CLOCK_DIVIDER*(adj+1),HOST_CCREG);
3082   emit_sub(HOST_CCREG,ECX,HOST_CCREG);
3083   emit_writeword(ECX,(int)&last_count);
3084   emit_storereg(CCREG,HOST_CCREG);
3085   restore_regs(reglist);
3086   if((cc=get_reg(regmap,CCREG))>=0) {
3087     emit_loadreg(CCREG,cc);
3088   }
3089 }
3090
3091 do_unalignedwritestub(int n)
3092 {
3093   set_jump_target(stubs[n][1],(int)out);
3094   output_byte(0xCC);
3095   emit_jmp(stubs[n][2]); // return address
3096 }
3097
3098 void printregs(int edi,int esi,int ebp,int esp,int b,int d,int c,int a)
3099 {
3100   printf("regs: %x %x %x %x %x %x %x (%x)\n",a,b,c,d,ebp,esi,edi,(&edi)[-1]);
3101 }
3102
3103 do_invstub(int n)
3104 {
3105   u_int reglist=stubs[n][3];
3106   set_jump_target(stubs[n][1],(int)out);
3107   save_regs(reglist);
3108   if(stubs[n][4]!=EDI) emit_mov(stubs[n][4],EDI);
3109   emit_call((int)&invalidate_block);
3110   restore_regs(reglist);
3111   emit_jmp(stubs[n][2]); // return address
3112 }
3113
3114 int do_dirty_stub(int i)
3115 {
3116   assem_debug("do_dirty_stub %x\n",start+i*4);
3117   emit_movimm((int)start<(int)0xC0000000?(int)source:(int)start,EAX);
3118   emit_movimm((int)copy,EBX);
3119   emit_movimm(slen*4,ECX);
3120   emit_movimm(start+i*4,12);
3121   emit_call((int)start<(int)0xC0000000?(int)&verify_code:(int)&verify_code_vm);
3122   int entry=(int)out;
3123   load_regs_entry(i);
3124   if(entry==(int)out) entry=instr_addr[i];
3125   emit_jmp(instr_addr[i]);
3126   return entry;
3127 }
3128
3129 void do_dirty_stub_ds()
3130 {
3131   emit_movimm((int)start<(int)0xC0000000?(int)source:(int)start,EAX);
3132   emit_movimm((int)copy,EBX);
3133   emit_movimm(slen*4,ECX);
3134   emit_movimm(start+1,12);
3135   emit_call((int)&verify_code_ds);
3136 }
3137
3138 do_cop1stub(int n)
3139 {
3140   assem_debug("do_cop1stub %x\n",start+stubs[n][3]*4);
3141   set_jump_target(stubs[n][1],(int)out);
3142   int i=stubs[n][3];
3143   int rs=stubs[n][4];
3144   struct regstat *i_regs=(struct regstat *)stubs[n][5];
3145   int ds=stubs[n][6];
3146   if(!ds) {
3147     load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty,i);
3148     //if(i_regs!=&regs[i]) printf("oops: regs[i]=%x i_regs=%x",(int)&regs[i],(int)i_regs);
3149   }
3150   //else {printf("fp exception in delay slot\n");}
3151   wb_dirtys(i_regs->regmap_entry,i_regs->was32,i_regs->wasdirty);
3152   if(regs[i].regmap_entry[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG);
3153   emit_movimm(start+(i-ds)*4,EAX); // Get PC
3154   emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG); // CHECK: is this right?  There should probably be an extra cycle...
3155   emit_jmp(ds?(int)fp_exception_ds:(int)fp_exception);
3156 }
3157
3158 /* TLB */
3159
3160 int do_tlb_r(int s,int ar,int map,int x,int a,int shift,int c,u_int addr)
3161 {
3162   if(c) {
3163     if((signed int)addr>=(signed int)0xC0000000) {
3164       emit_readword((int)(memory_map+(addr>>12)),map);
3165     }
3166     else
3167       return -1; // No mapping
3168   }
3169   else {
3170     if(s!=map) emit_mov(s,map);
3171     emit_shrimm(map,12,map);
3172     // Schedule this while we wait on the load
3173     //if(x) emit_xorimm(addr,x,addr);
3174     if(shift>=0) emit_lea8(s,shift);
3175     if(~a) emit_andimm(s,a,ar);
3176     emit_movmem_indexedx4((int)memory_map,map,map);
3177   }
3178   return map;
3179 }
3180 int do_tlb_r_branch(int map, int c, u_int addr, int *jaddr)
3181 {
3182   if(!c||(signed int)addr>=(signed int)0xC0000000) {
3183     emit_test(map,map);
3184     *jaddr=(int)out;
3185     emit_js(0);
3186   }
3187   return map;
3188 }
3189
3190 int gen_tlb_addr_r(int ar, int map) {
3191   if(map>=0) {
3192     emit_leairrx4(0,ar,map,ar);
3193   }
3194 }
3195
3196 int do_tlb_w(int s,int ar,int map,int x,int c,u_int addr)
3197 {
3198   if(c) {
3199     if(addr<0x80800000||addr>=0xC0000000) {
3200       emit_readword((int)(memory_map+(addr>>12)),map);
3201     }
3202     else
3203       return -1; // No mapping
3204   }
3205   else {
3206     if(s!=map) emit_mov(s,map);
3207     //if(s!=ar) emit_mov(s,ar);
3208     emit_shrimm(map,12,map);
3209     // Schedule this while we wait on the load
3210     //if(x) emit_xorimm(s,x,addr);
3211     emit_movmem_indexedx4((int)memory_map,map,map);
3212   }
3213   emit_shlimm(map,2,map);
3214   return map;
3215 }
3216 int do_tlb_w_branch(int map, int c, u_int addr, int *jaddr)
3217 {
3218   if(!c||addr<0x80800000||addr>=0xC0000000) {
3219     *jaddr=(int)out;
3220     emit_jc(0);
3221   }
3222 }
3223
3224 int gen_tlb_addr_w(int ar, int map) {
3225   if(map>=0) {
3226     emit_leairrx1(0,ar,map,ar);
3227   }
3228 }
3229
3230 // We don't need this for x86
3231 generate_map_const(u_int addr,int reg) {
3232   // void *mapaddr=memory_map+(addr>>12);
3233 }
3234
3235 /* Special assem */
3236
3237 void shift_assemble_x86(int i,struct regstat *i_regs)
3238 {
3239   if(rt1[i]) {
3240     if(opcode2[i]<=0x07) // SLLV/SRLV/SRAV
3241     {
3242       char s,t,shift;
3243       t=get_reg(i_regs->regmap,rt1[i]);
3244       s=get_reg(i_regs->regmap,rs1[i]);
3245       shift=get_reg(i_regs->regmap,rs2[i]);
3246       if(t>=0){
3247         if(rs1[i]==0)
3248         {
3249           emit_zeroreg(t);
3250         }
3251         else if(rs2[i]==0)
3252         {
3253           assert(s>=0);
3254           if(s!=t) emit_mov(s,t);
3255         }
3256         else
3257         {
3258           char temp=get_reg(i_regs->regmap,-1);
3259           assert(s>=0);
3260           if(t==ECX&&s!=ECX) {
3261             if(shift!=ECX) emit_mov(shift,ECX);
3262             if(rt1[i]==rs2[i]) {shift=temp;}
3263             if(s!=shift) emit_mov(s,shift);
3264           }
3265           else
3266           {
3267             if(rt1[i]==rs2[i]) {emit_mov(shift,temp);shift=temp;}
3268             if(s!=t) emit_mov(s,t);
3269             if(shift!=ECX) {
3270               if(i_regs->regmap[ECX]<0)
3271                 emit_mov(shift,ECX);
3272               else
3273                 emit_xchg(shift,ECX);
3274             }
3275           }
3276           if(opcode2[i]==4) // SLLV
3277           {
3278             emit_shlcl(t==ECX?shift:t);
3279           }
3280           if(opcode2[i]==6) // SRLV
3281           {
3282             emit_shrcl(t==ECX?shift:t);
3283           }
3284           if(opcode2[i]==7) // SRAV
3285           {
3286             emit_sarcl(t==ECX?shift:t);
3287           }
3288           if(shift!=ECX&&i_regs->regmap[ECX]>=0) emit_xchg(shift,ECX);
3289         }
3290       }
3291     } else { // DSLLV/DSRLV/DSRAV
3292       char sh,sl,th,tl,shift;
3293       th=get_reg(i_regs->regmap,rt1[i]|64);
3294       tl=get_reg(i_regs->regmap,rt1[i]);
3295       sh=get_reg(i_regs->regmap,rs1[i]|64);
3296       sl=get_reg(i_regs->regmap,rs1[i]);
3297       shift=get_reg(i_regs->regmap,rs2[i]);
3298       if(tl>=0){
3299         if(rs1[i]==0)
3300         {
3301           emit_zeroreg(tl);
3302           if(th>=0) emit_zeroreg(th);
3303         }
3304         else if(rs2[i]==0)
3305         {
3306           assert(sl>=0);
3307           if(sl!=tl) emit_mov(sl,tl);
3308           if(th>=0&&sh!=th) emit_mov(sh,th);
3309         }
3310         else
3311         {
3312           // FIXME: What if shift==tl ?
3313           assert(shift!=tl);
3314           int temp=get_reg(i_regs->regmap,-1);
3315           int real_th=th;
3316           if(th<0&&opcode2[i]!=0x14) {th=temp;} // DSLLV doesn't need a temporary register
3317           assert(sl>=0);
3318           assert(sh>=0);
3319           if(tl==ECX&&sl!=ECX) {
3320             if(shift!=ECX) emit_mov(shift,ECX);
3321             if(sl!=shift) emit_mov(sl,shift);
3322             if(th>=0 && sh!=th) emit_mov(sh,th);
3323           }
3324           else if(th==ECX&&sh!=ECX) {
3325             if(shift!=ECX) emit_mov(shift,ECX);
3326             if(sh!=shift) emit_mov(sh,shift);
3327             if(sl!=tl) emit_mov(sl,tl);
3328           }
3329           else
3330           {
3331             if(sl!=tl) emit_mov(sl,tl);
3332             if(th>=0 && sh!=th) emit_mov(sh,th);
3333             if(shift!=ECX) {
3334               if(i_regs->regmap[ECX]<0)
3335                 emit_mov(shift,ECX);
3336               else
3337                 emit_xchg(shift,ECX);
3338             }
3339           }
3340           if(opcode2[i]==0x14) // DSLLV
3341           {
3342             if(th>=0) emit_shldcl(th==ECX?shift:th,tl==ECX?shift:tl);
3343             emit_shlcl(tl==ECX?shift:tl);
3344             emit_testimm(ECX,32);
3345             if(th>=0) emit_cmovne_reg(tl==ECX?shift:tl,th==ECX?shift:th);
3346             emit_cmovne(&const_zero,tl==ECX?shift:tl);
3347           }
3348           if(opcode2[i]==0x16) // DSRLV
3349           {
3350             assert(th>=0);
3351             emit_shrdcl(tl==ECX?shift:tl,th==ECX?shift:th);
3352             emit_shrcl(th==ECX?shift:th);
3353             emit_testimm(ECX,32);
3354             emit_cmovne_reg(th==ECX?shift:th,tl==ECX?shift:tl);
3355             if(real_th>=0) emit_cmovne(&const_zero,th==ECX?shift:th);
3356           }
3357           if(opcode2[i]==0x17) // DSRAV
3358           {
3359             assert(th>=0);
3360             emit_shrdcl(tl==ECX?shift:tl,th==ECX?shift:th);
3361             if(real_th>=0) {
3362               assert(temp>=0);
3363               emit_mov(th==ECX?shift:th,temp==ECX?shift:temp);
3364             }
3365             emit_sarcl(th==ECX?shift:th);
3366             if(real_th>=0) emit_sarimm(temp==ECX?shift:temp,31,temp==ECX?shift:temp);
3367             emit_testimm(ECX,32);
3368             emit_cmovne_reg(th==ECX?shift:th,tl==ECX?shift:tl);
3369             if(real_th>=0) emit_cmovne_reg(temp==ECX?shift:temp,th==ECX?shift:th);
3370           }
3371           if(shift!=ECX&&(i_regs->regmap[ECX]>=0||temp==ECX)) emit_xchg(shift,ECX);
3372         }
3373       }
3374     }
3375   }
3376 }
3377 #define shift_assemble shift_assemble_x86
3378
3379 void loadlr_assemble_x86(int i,struct regstat *i_regs)
3380 {
3381   int s,th,tl,temp,temp2,addr,map=-1;
3382   int offset;
3383   int jaddr=0;
3384   int memtarget,c=0;
3385   u_int hr,reglist=0;
3386   th=get_reg(i_regs->regmap,rt1[i]|64);
3387   tl=get_reg(i_regs->regmap,rt1[i]);
3388   s=get_reg(i_regs->regmap,rs1[i]);
3389   temp=get_reg(i_regs->regmap,-1);
3390   temp2=get_reg(i_regs->regmap,FTEMP);
3391   addr=get_reg(i_regs->regmap,AGEN1+(i&1));
3392   assert(addr<0);
3393   offset=imm[i];
3394   for(hr=0;hr<HOST_REGS;hr++) {
3395     if(i_regs->regmap[hr]>=0) reglist|=1<<hr;
3396   }
3397   reglist|=1<<temp;
3398   if(offset||s<0||c) addr=temp2;
3399   else addr=s;
3400   if(s>=0) {
3401     c=(i_regs->wasconst>>s)&1;
3402     memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80800000;
3403     if(using_tlb&&((signed int)(constmap[i][s]+offset))>=(signed int)0xC0000000) memtarget=1;
3404   }
3405   if(tl>=0) {
3406     //assert(tl>=0);
3407     //assert(rt1[i]);
3408     if(!using_tlb) {
3409       if(!c) {
3410         emit_lea8(addr,temp);
3411         if (opcode[i]==0x22||opcode[i]==0x26) {
3412           emit_andimm(addr,0xFFFFFFFC,temp2); // LWL/LWR
3413         }else{
3414           emit_andimm(addr,0xFFFFFFF8,temp2); // LDL/LDR
3415         }
3416         emit_cmpimm(addr,0x800000);
3417         jaddr=(int)out;
3418         emit_jno(0);
3419       }
3420       else {
3421         if (opcode[i]==0x22||opcode[i]==0x26) {
3422           emit_movimm(((constmap[i][s]+offset)<<3)&24,temp); // LWL/LWR
3423         }else{
3424           emit_movimm(((constmap[i][s]+offset)<<3)&56,temp); // LDL/LDR
3425         }
3426       }
3427     }else{ // using tlb
3428       int a;
3429       if(c) {
3430         a=-1;
3431       }else if (opcode[i]==0x22||opcode[i]==0x26) {
3432         a=0xFFFFFFFC; // LWL/LWR
3433       }else{
3434         a=0xFFFFFFF8; // LDL/LDR
3435       }
3436       map=get_reg(i_regs->regmap,TLREG);
3437       assert(map>=0);
3438       map=do_tlb_r(addr,temp2,map,0,a,c?-1:temp,c,constmap[i][s]+offset);
3439       if(c) {
3440         if (opcode[i]==0x22||opcode[i]==0x26) {
3441           emit_movimm(((constmap[i][s]+offset)<<3)&24,temp); // LWL/LWR
3442         }else{
3443           emit_movimm(((constmap[i][s]+offset)<<3)&56,temp); // LDL/LDR
3444         }
3445       }
3446       do_tlb_r_branch(map,c,constmap[i][s]+offset,&jaddr);
3447     }
3448     if (opcode[i]==0x22||opcode[i]==0x26) { // LWL/LWR
3449       if(!c||memtarget) {
3450         //emit_readword_indexed((int)rdram-0x80000000,temp2,temp2);
3451         emit_readword_indexed_tlb(0,temp2,map,temp2);
3452         if(jaddr) add_stub(LOADW_STUB,jaddr,(int)out,i,temp2,(int)i_regs,ccadj[i],reglist);
3453       }
3454       else
3455         inline_readstub(LOADW_STUB,i,(constmap[i][s]+offset)&0xFFFFFFFC,i_regs->regmap,FTEMP,ccadj[i],reglist);
3456       emit_andimm(temp,24,temp);
3457       if (opcode[i]==0x26) emit_xorimm(temp,24,temp); // LWR
3458       if(temp==ECX)
3459       {
3460         int temp3=EDX;
3461         if(temp3==temp2) temp3++;
3462         emit_pushreg(temp3);
3463         emit_movimm(-1,temp3);
3464         if (opcode[i]==0x26) {
3465           emit_shrcl(temp3);
3466           emit_shrcl(temp2);
3467         }else{
3468           emit_shlcl(temp3);
3469           emit_shlcl(temp2);
3470         }
3471         emit_mov(temp3,ECX);
3472         emit_not(ECX,ECX);
3473         emit_popreg(temp3);
3474       }
3475       else
3476       {
3477         int temp3=EBP;
3478         if(temp3==temp) temp3++;
3479         if(temp3==temp2) temp3++;
3480         if(temp3==temp) temp3++;
3481         emit_xchg(ECX,temp);
3482         emit_pushreg(temp3);
3483         emit_movimm(-1,temp3);
3484         if (opcode[i]==0x26) {
3485           emit_shrcl(temp3);
3486           emit_shrcl(temp2==ECX?temp:temp2);
3487         }else{
3488           emit_shlcl(temp3);
3489           emit_shlcl(temp2==ECX?temp:temp2);
3490         }
3491         emit_not(temp3,temp3);
3492         emit_mov(temp,ECX);
3493         emit_mov(temp3,temp);
3494         emit_popreg(temp3);
3495       }
3496       emit_and(temp,tl,tl);
3497       emit_or(temp2,tl,tl);
3498       //emit_storereg(rt1[i],tl); // DEBUG
3499     }
3500     if (opcode[i]==0x1A||opcode[i]==0x1B) { // LDL/LDR
3501       if(s>=0) 
3502         if((i_regs->wasdirty>>s)&1)
3503           emit_storereg(rs1[i],s);
3504       if(get_reg(i_regs->regmap,rs1[i]|64)>=0) 
3505         if((i_regs->wasdirty>>get_reg(i_regs->regmap,rs1[i]|64))&1)
3506           emit_storereg(rs1[i]|64,get_reg(i_regs->regmap,rs1[i]|64));
3507       int temp2h=get_reg(i_regs->regmap,FTEMP|64);
3508       if(!c||memtarget) {
3509         //if(th>=0) emit_readword_indexed((int)rdram-0x80000000,temp2,temp2h);
3510         //emit_readword_indexed((int)rdram-0x7FFFFFFC,temp2,temp2);
3511         emit_readdword_indexed_tlb(0,temp2,map,temp2h,temp2);
3512         if(jaddr) add_stub(LOADD_STUB,jaddr,(int)out,i,temp2,(int)i_regs,ccadj[i],reglist);
3513       }
3514       else
3515         inline_readstub(LOADD_STUB,i,(constmap[i][s]+offset)&0xFFFFFFF8,i_regs->regmap,FTEMP,ccadj[i],reglist);
3516       emit_andimm(temp,56,temp);
3517       //output_byte(0xCC);
3518       //emit_pushreg(temp);
3519       //emit_pushreg(temp2h);
3520       //emit_pushreg(temp2);
3521       //emit_pushreg(th);
3522       //emit_pushreg(tl);
3523       emit_addimm64(ESP,-20,ESP);
3524       emit_writeword_indexed(temp,16,ESP);
3525       emit_writeword_indexed(temp2h,12,ESP);
3526       emit_writeword_indexed(temp2,8,ESP);
3527       emit_writeword_indexed(th,4,ESP);
3528       emit_writeword_indexed(tl,0,ESP);
3529       emit_mov(temp,EDX);
3530       emit_readdword_indexed(0,ESP,ARG1_REG);
3531       emit_readdword_indexed(8,ESP,ARG2_REG);
3532       if(opcode[i]==0x1A) emit_call((int)ldl_merge);
3533       if(opcode[i]==0x1B) emit_call((int)ldr_merge);
3534       emit_addimm64(ESP,20,ESP);
3535       if(th!=EAX) {
3536         emit_mov64(EAX,th);
3537       }
3538       emit_mov(EAX,tl);
3539       emit_shrimm64(th,32,th);
3540       if(s>=0) emit_loadreg(rs1[i],s);
3541       if(get_reg(i_regs->regmap,rs1[i]|64)>=0)
3542         emit_loadreg(rs1[i]|64,get_reg(i_regs->regmap,rs1[i]|64));
3543     }
3544   }
3545 }
3546 #define loadlr_assemble loadlr_assemble_x86
3547
3548 void cop0_assemble(int i,struct regstat *i_regs)
3549 {
3550   if(opcode2[i]==0) // MFC0
3551   {
3552     signed char t=get_reg(i_regs->regmap,rt1[i]);
3553     char copr=(source[i]>>11)&0x1f;
3554     //assert(t>=0); // Why does this happen?  OOT is weird
3555     if(t>=0) {
3556       emit_writedword_imm32((int)&fake_pc,(int)&PC);
3557       emit_writebyte_imm((source[i]>>11)&0x1f,(int)&(fake_pc.f.r.nrd));
3558       if(copr==9) {
3559         emit_readword((int)&last_count,ECX);
3560         emit_loadreg(CCREG,HOST_CCREG); // TODO: do proper reg alloc
3561         emit_add(HOST_CCREG,ECX,HOST_CCREG);
3562         emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG);
3563         emit_writeword(HOST_CCREG,(int)&Count);
3564       }
3565       emit_call((int)MFC0);
3566       emit_readword((int)&readmem_dword,t);
3567     }
3568   }
3569   else if(opcode2[i]==4) // MTC0
3570   {
3571     signed char s=get_reg(i_regs->regmap,rs1[i]);
3572     char copr=(source[i]>>11)&0x1f;
3573     assert(s>=0);
3574     emit_writeword(s,(int)&readmem_dword);
3575     wb_register(rs1[i],i_regs->regmap,i_regs->dirty,i_regs->was32); // FIXME
3576     emit_writedword_imm32((int)&fake_pc,(int)&PC);
3577     emit_writebyte_imm((source[i]>>11)&0x1f,(int)&(fake_pc.f.r.nrd));
3578     if(copr==9||copr==11||copr==12) {
3579       emit_readword((int)&last_count,ECX);
3580       emit_loadreg(CCREG,HOST_CCREG); // TODO: do proper reg alloc
3581       emit_add(HOST_CCREG,ECX,HOST_CCREG);
3582       emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG);
3583       emit_writeword(HOST_CCREG,(int)&Count);
3584     }
3585     // What a mess.  The status register (12) can enable interrupts,
3586     // so needs a special case to handle a pending interrupt.
3587     // The interrupt must be taken immediately, because a subsequent
3588     // instruction might disable interrupts again.
3589     if(copr==12&&!is_delayslot) {
3590       emit_writeword_imm(start+i*4+4,(int)&pcaddr);
3591       emit_writebyte_imm(0,(int)&pending_exception);
3592     }
3593     //else if(copr==12&&is_delayslot) emit_call((int)MTC0_R12);
3594     //else
3595     emit_call((int)MTC0);
3596     if(copr==9||copr==11||copr==12) {
3597       emit_readword((int)&Count,HOST_CCREG);
3598       emit_readword((int)&next_interupt,ECX);
3599       emit_addimm(HOST_CCREG,-CLOCK_DIVIDER*ccadj[i],HOST_CCREG);
3600       emit_sub(HOST_CCREG,ECX,HOST_CCREG);
3601       emit_writeword(ECX,(int)&last_count);
3602       emit_storereg(CCREG,HOST_CCREG);
3603     }
3604     emit_loadreg(rs1[i],s);
3605     if(copr==12) {
3606       assert(!is_delayslot);
3607       //if(is_delayslot) output_byte(0xcc);
3608       emit_cmpmem_imm_byte((int)&pending_exception,0);
3609       emit_jne((int)&do_interrupt);
3610     }
3611     cop1_usable=0;
3612   }
3613   else
3614   {
3615     assert(opcode2[i]==0x10);
3616     if((source[i]&0x3f)==0x01) // TLBR
3617       emit_call((int)TLBR);
3618     if((source[i]&0x3f)==0x02) // TLBWI
3619       emit_call((int)TLBWI_new);
3620     if((source[i]&0x3f)==0x06) { // TLBWR
3621       // The TLB entry written by TLBWR is dependent on the count,
3622       // so update the cycle count
3623       emit_readword((int)&last_count,ECX);
3624       if(i_regs->regmap[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG);
3625       emit_add(HOST_CCREG,ECX,HOST_CCREG);
3626       emit_addimm(HOST_CCREG,CLOCK_DIVIDER*ccadj[i],HOST_CCREG);
3627       emit_writeword(HOST_CCREG,(int)&Count);
3628       emit_call((int)TLBWR_new);
3629     }
3630     if((source[i]&0x3f)==0x08) // TLBP
3631       emit_call((int)TLBP);
3632     if((source[i]&0x3f)==0x18) // ERET
3633     {
3634       int count=ccadj[i];
3635       if(i_regs->regmap[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG);
3636       emit_addimm_and_set_flags(CLOCK_DIVIDER*count,HOST_CCREG); // TODO: Should there be an extra cycle here?
3637       emit_jmp((int)jump_eret);
3638     }
3639   }
3640 }
3641
3642 void cop1_assemble(int i,struct regstat *i_regs)
3643 {
3644   // Check cop1 unusable
3645   if(!cop1_usable) {
3646     signed char rs=get_reg(i_regs->regmap,CSREG);
3647     assert(rs>=0);
3648     emit_testimm(rs,0x20000000);
3649     int jaddr=(int)out;
3650     emit_jeq(0);
3651     add_stub(FP_STUB,jaddr,(int)out,i,rs,(int)i_regs,is_delayslot,0);
3652     cop1_usable=1;
3653   }
3654   if (opcode2[i]==0) { // MFC1
3655     signed char tl=get_reg(i_regs->regmap,rt1[i]);
3656     if(tl>=0) {
3657       emit_readword((int)&reg_cop1_simple[(source[i]>>11)&0x1f],tl);
3658       emit_readword_indexed(0,tl,tl);
3659     }
3660   }
3661   else if (opcode2[i]==1) { // DMFC1
3662     signed char tl=get_reg(i_regs->regmap,rt1[i]);
3663     signed char th=get_reg(i_regs->regmap,rt1[i]|64);
3664     if(tl>=0) {
3665       emit_readword((int)&reg_cop1_double[(source[i]>>11)&0x1f],tl);
3666       if(th>=0) emit_readword_indexed(4,tl,th);
3667       emit_readword_indexed(0,tl,tl);
3668     }
3669   }
3670   else if (opcode2[i]==4) { // MTC1
3671     signed char sl=get_reg(i_regs->regmap,rs1[i]);
3672     signed char temp=get_reg(i_regs->regmap,-1);
3673     emit_readword((int)&reg_cop1_simple[(source[i]>>11)&0x1f],temp);
3674     emit_writeword_indexed(sl,0,temp);
3675   }
3676   else if (opcode2[i]==5) { // DMTC1
3677     signed char sl=get_reg(i_regs->regmap,rs1[i]);
3678     signed char sh=rs1[i]>0?get_reg(i_regs->regmap,rs1[i]|64):sl;
3679     signed char temp=get_reg(i_regs->regmap,-1);
3680     emit_readword((int)&reg_cop1_double[(source[i]>>11)&0x1f],temp);
3681     emit_writeword_indexed(sh,4,temp);
3682     emit_writeword_indexed(sl,0,temp);
3683   }
3684   else if (opcode2[i]==2) // CFC1
3685   {
3686     signed char tl=get_reg(i_regs->regmap,rt1[i]);
3687     if(tl>=0) {
3688       u_int copr=(source[i]>>11)&0x1f;
3689       if(copr==0) emit_readword((int)&FCR0,tl);
3690       if(copr==31) emit_readword((int)&FCR31,tl);
3691     }
3692   }
3693   else if (opcode2[i]==6) // CTC1
3694   {
3695     signed char sl=get_reg(i_regs->regmap,rs1[i]);
3696     u_int copr=(source[i]>>11)&0x1f;
3697     assert(sl>=0);
3698     if(copr==31)
3699     {
3700       emit_writeword(sl,(int)&FCR31);
3701       // Set the rounding mode
3702       char temp=get_reg(i_regs->regmap,-1);
3703       emit_movimm(3,temp);
3704       emit_and(sl,temp,temp);
3705       emit_fldcw_indexed((int)&rounding_modes,temp);
3706     }
3707   }
3708 }
3709
3710 void fconv_assemble_x86(int i,struct regstat *i_regs)
3711 {
3712   signed char temp=get_reg(i_regs->regmap,-1);
3713   assert(temp>=0);
3714   // Check cop1 unusable
3715   if(!cop1_usable) {
3716     signed char rs=get_reg(i_regs->regmap,CSREG);
3717     assert(rs>=0);
3718     emit_testimm(rs,0x20000000);
3719     int jaddr=(int)out;
3720     emit_jeq(0);
3721     add_stub(FP_STUB,jaddr,(int)out,i,rs,(int)i_regs,is_delayslot,0);
3722     cop1_usable=1;
3723   }
3724   if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0d) { // trunc_w_s
3725     emit_readword((int)&reg_cop1_simple[(source[i]>>11)&0x1f],temp);
3726     emit_movss_load(temp,0);
3727     emit_cvttps2dq(0,0); // float->int, truncate
3728     if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f))
3729       emit_readword((int)&reg_cop1_simple[(source[i]>>6)&0x1f],temp);
3730     emit_movd_store(0,temp);
3731     return;
3732   }
3733   if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0d) { // trunc_w_d
3734     emit_readword((int)&reg_cop1_double[(source[i]>>11)&0x1f],temp);
3735     emit_movsd_load(temp,0);
3736     emit_cvttpd2dq(0,0); // double->int, truncate
3737     emit_readword((int)&reg_cop1_simple[(source[i]>>6)&0x1f],temp);
3738     emit_movd_store(0,temp);
3739     return;
3740   }
3741   
3742   if(opcode2[i]==0x14&&(source[i]&0x3f)==0x20) { // cvt_s_w
3743     emit_readword((int)&reg_cop1_simple[(source[i]>>11)&0x1f],temp);
3744     emit_fildl(temp);
3745     if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f))
3746       emit_readword((int)&reg_cop1_simple[(source[i]>>6)&0x1f],temp);
3747     emit_fstps(temp);
3748     return;
3749   }
3750   if(opcode2[i]==0x14&&(source[i]&0x3f)==0x21) { // cvt_d_w
3751     emit_readword((int)&reg_cop1_simple[(source[i]>>11)&0x1f],temp);
3752     emit_fildl(temp);
3753     emit_readword((int)&reg_cop1_double[(source[i]>>6)&0x1f],temp);
3754     emit_fstpl(temp);
3755     return;
3756   }
3757   if(opcode2[i]==0x15&&(source[i]&0x3f)==0x20) { // cvt_s_l
3758     emit_readword((int)&reg_cop1_double[(source[i]>>11)&0x1f],temp);
3759     emit_fildll(temp);
3760     emit_readword((int)&reg_cop1_simple[(source[i]>>6)&0x1f],temp);
3761     emit_fstps(temp);
3762     return;
3763   }
3764   if(opcode2[i]==0x15&&(source[i]&0x3f)==0x21) { // cvt_d_l
3765     emit_readword((int)&reg_cop1_double[(source[i]>>11)&0x1f],temp);
3766     emit_fildll(temp);
3767     if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f))
3768       emit_readword((int)&reg_cop1_double[(source[i]>>6)&0x1f],temp);
3769     emit_fstpl(temp);
3770     return;
3771   }
3772   
3773   if(opcode2[i]==0x10&&(source[i]&0x3f)==0x21) { // cvt_d_s
3774     emit_readword((int)&reg_cop1_simple[(source[i]>>11)&0x1f],temp);
3775     emit_flds(temp);
3776     emit_readword((int)&reg_cop1_double[(source[i]>>6)&0x1f],temp);
3777     emit_fstpl(temp);
3778     return;
3779   }
3780   if(opcode2[i]==0x11&&(source[i]&0x3f)==0x20) { // cvt_s_d
3781     emit_readword((int)&reg_cop1_double[(source[i]>>11)&0x1f],temp);
3782     emit_fldl(temp);
3783     emit_readword((int)&reg_cop1_simple[(source[i]>>6)&0x1f],temp);
3784     emit_fstps(temp);
3785     return;
3786   }
3787   
3788   if(opcode2[i]==0x10) { // cvt_*_s
3789     emit_readword((int)&reg_cop1_simple[(source[i]>>11)&0x1f],temp);
3790     emit_flds(temp);
3791   }
3792   if(opcode2[i]==0x11) { // cvt_*_d
3793     emit_readword((int)&reg_cop1_double[(source[i]>>11)&0x1f],temp);
3794     emit_fldl(temp);
3795   }
3796   if((source[i]&0x3f)<0x10) {
3797     emit_fnstcw_stack();
3798     if((source[i]&3)==0) emit_fldcw((int)&round_mode); //printf("round\n");
3799     if((source[i]&3)==1) emit_fldcw((int)&trunc_mode); //printf("trunc\n");
3800     if((source[i]&3)==2) emit_fldcw((int)&ceil_mode); //printf("ceil\n");
3801     if((source[i]&3)==3) emit_fldcw((int)&floor_mode); //printf("floor\n");
3802   }
3803   if((source[i]&0x3f)==0x24||(source[i]&0x3c)==0x0c) { // cvt_w_*
3804     if(opcode2[i]!=0x10||((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f))
3805       emit_readword((int)&reg_cop1_simple[(source[i]>>6)&0x1f],temp);
3806     emit_fistpl(temp);
3807   }
3808   if((source[i]&0x3f)==0x25||(source[i]&0x3c)==0x08) { // cvt_l_*
3809     if(opcode2[i]!=0x11||((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f))
3810       emit_readword((int)&reg_cop1_double[(source[i]>>6)&0x1f],temp);
3811     emit_fistpll(temp);
3812   }
3813   if((source[i]&0x3f)<0x10) {
3814     emit_fldcw_stack();
3815   }
3816   return;
3817 }
3818 #define fconv_assemble fconv_assemble_x86
3819
3820 void fcomp_assemble(int i,struct regstat *i_regs)
3821 {
3822   signed char fs=get_reg(i_regs->regmap,FSREG);
3823   signed char temp=get_reg(i_regs->regmap,-1);
3824   assert(temp>=0);
3825   // Check cop1 unusable
3826   if(!cop1_usable) {
3827     signed char cs=get_reg(i_regs->regmap,CSREG);
3828     assert(cs>=0);
3829     emit_testimm(cs,0x20000000);
3830     int jaddr=(int)out;
3831     emit_jeq(0);
3832     add_stub(FP_STUB,jaddr,(int)out,i,cs,(int)i_regs,is_delayslot,0);
3833     cop1_usable=1;
3834   }
3835   
3836   if((source[i]&0x3f)==0x30) {
3837     emit_andimm(fs,~0x800000,fs);
3838     return;
3839   }
3840   
3841   if((source[i]&0x3e)==0x38) {
3842     // sf/ngle - these should throw exceptions for NaNs
3843     emit_andimm(fs,~0x800000,fs);
3844     return;
3845   }
3846   
3847   if(opcode2[i]==0x10) {
3848     emit_readword((int)&reg_cop1_simple[(source[i]>>16)&0x1f],temp);
3849     emit_flds(temp);
3850     emit_readword((int)&reg_cop1_simple[(source[i]>>11)&0x1f],temp);
3851     emit_flds(temp);
3852     emit_movimm(0x800000,temp);
3853     emit_or(fs,temp,fs);
3854     emit_xor(temp,fs,temp);
3855     emit_fucomip(1);
3856     emit_fpop();
3857     if((source[i]&0x3f)==0x31) emit_cmovnp_reg(temp,fs); // c_un_s
3858     if((source[i]&0x3f)==0x32) {emit_cmovne_reg(temp,fs);emit_cmovp_reg(temp,fs);} // c_eq_s
3859     if((source[i]&0x3f)==0x33) emit_cmovne_reg(temp,fs); // c_ueq_s
3860     if((source[i]&0x3f)==0x34) {emit_cmovnc_reg(temp,fs);emit_cmovp_reg(temp,fs);} // c_olt_s
3861     if((source[i]&0x3f)==0x35) emit_cmovnc_reg(temp,fs); // c_ult_s
3862     if((source[i]&0x3f)==0x36) {emit_cmova_reg(temp,fs);emit_cmovp_reg(temp,fs);} // c_ole_s
3863     if((source[i]&0x3f)==0x37) emit_cmova_reg(temp,fs); // c_ule_s
3864     if((source[i]&0x3f)==0x3a) emit_cmovne_reg(temp,fs); // c_seq_s
3865     if((source[i]&0x3f)==0x3b) emit_cmovne_reg(temp,fs); // c_ngl_s
3866     if((source[i]&0x3f)==0x3c) emit_cmovnc_reg(temp,fs); // c_lt_s
3867     if((source[i]&0x3f)==0x3d) emit_cmovnc_reg(temp,fs); // c_nge_s
3868     if((source[i]&0x3f)==0x3e) emit_cmova_reg(temp,fs); // c_le_s
3869     if((source[i]&0x3f)==0x3f) emit_cmova_reg(temp,fs); // c_ngt_s
3870     return;
3871   }
3872   if(opcode2[i]==0x11) {
3873     emit_readword((int)&reg_cop1_double[(source[i]>>16)&0x1f],temp);
3874     emit_fldl(temp);
3875     emit_readword((int)&reg_cop1_double[(source[i]>>11)&0x1f],temp);
3876     emit_fldl(temp);
3877     emit_movimm(0x800000,temp);
3878     emit_or(fs,temp,fs);
3879     emit_xor(temp,fs,temp);
3880     emit_fucomip(1);
3881     emit_fpop();
3882     if((source[i]&0x3f)==0x31) emit_cmovnp_reg(temp,fs); // c_un_d
3883     if((source[i]&0x3f)==0x32) {emit_cmovne_reg(temp,fs);emit_cmovp_reg(temp,fs);} // c_eq_d
3884     if((source[i]&0x3f)==0x33) emit_cmovne_reg(temp,fs); // c_ueq_d
3885     if((source[i]&0x3f)==0x34) {emit_cmovnc_reg(temp,fs);emit_cmovp_reg(temp,fs);} // c_olt_d
3886     if((source[i]&0x3f)==0x35) emit_cmovnc_reg(temp,fs); // c_ult_d
3887     if((source[i]&0x3f)==0x36) {emit_cmova_reg(temp,fs);emit_cmovp_reg(temp,fs);} // c_ole_d
3888     if((source[i]&0x3f)==0x37) emit_cmova_reg(temp,fs); // c_ule_d
3889     if((source[i]&0x3f)==0x3a) emit_cmovne_reg(temp,fs); // c_seq_d
3890     if((source[i]&0x3f)==0x3b) emit_cmovne_reg(temp,fs); // c_ngl_d
3891     if((source[i]&0x3f)==0x3c) emit_cmovnc_reg(temp,fs); // c_lt_d
3892     if((source[i]&0x3f)==0x3d) emit_cmovnc_reg(temp,fs); // c_nge_d
3893     if((source[i]&0x3f)==0x3e) emit_cmova_reg(temp,fs); // c_le_d
3894     if((source[i]&0x3f)==0x3f) emit_cmova_reg(temp,fs); // c_ngt_d
3895     return;
3896   }
3897 }
3898
3899 void float_assemble(int i,struct regstat *i_regs)
3900 {
3901   signed char temp=get_reg(i_regs->regmap,-1);
3902   assert(temp>=0);
3903   // Check cop1 unusable
3904   if(!cop1_usable) {
3905     signed char cs=get_reg(i_regs->regmap,CSREG);
3906     assert(cs>=0);
3907     emit_testimm(cs,0x20000000);
3908     int jaddr=(int)out;
3909     emit_jeq(0);
3910     add_stub(FP_STUB,jaddr,(int)out,i,cs,(int)i_regs,is_delayslot,0);
3911     cop1_usable=1;
3912   }
3913   
3914   if((source[i]&0x3f)==6) // mov
3915   {
3916     if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) {
3917       if(opcode2[i]==0x10) {
3918         emit_readword((int)&reg_cop1_simple[(source[i]>>11)&0x1f],temp);
3919         emit_flds(temp);
3920         emit_readword((int)&reg_cop1_simple[(source[i]>>6)&0x1f],temp);
3921         emit_fstps(temp);
3922       }
3923       if(opcode2[i]==0x11) {
3924         emit_readword((int)&reg_cop1_double[(source[i]>>11)&0x1f],temp);
3925         emit_fldl(temp);
3926         emit_readword((int)&reg_cop1_double[(source[i]>>6)&0x1f],temp);
3927         emit_fstpl(temp);
3928       }
3929     }
3930     return;
3931   }
3932   
3933   if((source[i]&0x3f)>3)
3934   {
3935     if(opcode2[i]==0x10) {
3936       emit_readword((int)&reg_cop1_simple[(source[i]>>11)&0x1f],temp);
3937       emit_flds(temp);
3938       if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) {
3939         emit_readword((int)&reg_cop1_simple[(source[i]>>6)&0x1f],temp);
3940       }
3941     }
3942     if(opcode2[i]==0x11) {
3943       emit_readword((int)&reg_cop1_double[(source[i]>>11)&0x1f],temp);
3944       emit_fldl(temp);
3945       if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f)) {
3946         emit_readword((int)&reg_cop1_double[(source[i]>>6)&0x1f],temp);
3947       }
3948     }
3949     if((source[i]&0x3f)==4) // sqrt
3950       emit_fsqrt();
3951     if((source[i]&0x3f)==5) // abs
3952       emit_fabs();
3953     if((source[i]&0x3f)==7) // neg
3954       emit_fchs();
3955     if(opcode2[i]==0x10) {
3956       emit_fstps(temp);
3957     }
3958     if(opcode2[i]==0x11) {
3959       emit_fstpl(temp);
3960     }
3961     return;
3962   }
3963   if((source[i]&0x3f)<4)
3964   {
3965     if(opcode2[i]==0x10) {
3966       emit_readword((int)&reg_cop1_simple[(source[i]>>11)&0x1f],temp);
3967       emit_flds(temp);
3968     }
3969     if(opcode2[i]==0x11) {
3970       emit_readword((int)&reg_cop1_double[(source[i]>>11)&0x1f],temp);
3971       emit_fldl(temp);
3972     }
3973     if(((source[i]>>11)&0x1f)!=((source[i]>>16)&0x1f)) {
3974       if(opcode2[i]==0x10) {
3975         emit_readword((int)&reg_cop1_simple[(source[i]>>16)&0x1f],temp);
3976         if((source[i]&0x3f)==0) emit_fadds(temp);
3977         if((source[i]&0x3f)==1) emit_fsubs(temp);
3978         if((source[i]&0x3f)==2) emit_fmuls(temp);
3979         if((source[i]&0x3f)==3) emit_fdivs(temp);
3980       }
3981       else if(opcode2[i]==0x11) {
3982         emit_readword((int)&reg_cop1_double[(source[i]>>16)&0x1f],temp);
3983         if((source[i]&0x3f)==0) emit_faddl(temp);
3984         if((source[i]&0x3f)==1) emit_fsubl(temp);
3985         if((source[i]&0x3f)==2) emit_fmull(temp);
3986         if((source[i]&0x3f)==3) emit_fdivl(temp);
3987       }
3988     }
3989     else {
3990       if((source[i]&0x3f)==0) emit_fadd(0);
3991       if((source[i]&0x3f)==1) emit_fsub(0);
3992       if((source[i]&0x3f)==2) emit_fmul(0);
3993       if((source[i]&0x3f)==3) emit_fdiv(0);
3994     }
3995     if(opcode2[i]==0x10) {
3996       if(((source[i]>>16)&0x1f)!=((source[i]>>6)&0x1f)) {
3997         emit_readword((int)&reg_cop1_simple[(source[i]>>6)&0x1f],temp);
3998       }
3999       emit_fstps(temp);
4000     }
4001     if(opcode2[i]==0x11) {
4002       if(((source[i]>>16)&0x1f)!=((source[i]>>6)&0x1f)) {
4003         emit_readword((int)&reg_cop1_double[(source[i]>>6)&0x1f],temp);
4004       }
4005       emit_fstpl(temp);
4006     }
4007     return;
4008   }
4009 }
4010
4011 void multdiv_assemble_x86(int i,struct regstat *i_regs)
4012 {
4013   //  case 0x18: MULT
4014   //  case 0x19: MULTU
4015   //  case 0x1A: DIV
4016   //  case 0x1B: DIVU
4017   //  case 0x1C: DMULT
4018   //  case 0x1D: DMULTU
4019   //  case 0x1E: DDIV
4020   //  case 0x1F: DDIVU
4021   if(rs1[i]&&rs2[i])
4022   {
4023     if((opcode2[i]&4)==0) // 32-bit
4024     {
4025       if(opcode2[i]==0x18) // MULT
4026       {
4027         char m1=get_reg(i_regs->regmap,rs1[i]);
4028         char m2=get_reg(i_regs->regmap,rs2[i]);
4029         assert(m1>=0);
4030         assert(m2>=0);
4031         emit_mov(m1,EAX);
4032         emit_imul(m2);
4033       }
4034       if(opcode2[i]==0x19) // MULTU
4035       {
4036         char m1=get_reg(i_regs->regmap,rs1[i]);
4037         char m2=get_reg(i_regs->regmap,rs2[i]);
4038         assert(m1>=0);
4039         assert(m2>=0);
4040         emit_mov(m1,EAX);
4041         emit_mul(m2);
4042       }
4043       if(opcode2[i]==0x1A) // DIV
4044       {
4045         char d1=get_reg(i_regs->regmap,rs1[i]);
4046         char d2=get_reg(i_regs->regmap,rs2[i]);
4047         assert(d1>=0);
4048         assert(d2>=0);
4049         emit_mov(d1,EAX);
4050         emit_cdq();
4051         emit_test(d2,d2);
4052         emit_jeq((int)out+8);
4053         emit_idiv(d2);
4054       }
4055       if(opcode2[i]==0x1B) // DIVU
4056       {
4057         char d1=get_reg(i_regs->regmap,rs1[i]);
4058         char d2=get_reg(i_regs->regmap,rs2[i]);
4059         assert(d1>=0);
4060         assert(d2>=0);
4061         emit_mov(d1,EAX);
4062         emit_zeroreg(EDX);
4063         emit_test(d2,d2);
4064         emit_jeq((int)out+8);
4065         emit_div(d2);
4066       }
4067     }
4068     else // 64-bit
4069     {
4070       if(opcode2[i]==0x1C) // DMULT
4071       {
4072         char m1h=get_reg(i_regs->regmap,rs1[i]|64);
4073         char m1l=get_reg(i_regs->regmap,rs1[i]);
4074         char m2h=get_reg(i_regs->regmap,rs2[i]|64);
4075         char m2l=get_reg(i_regs->regmap,rs2[i]);
4076         assert(m1h>=0);
4077         assert(m2h>=0);
4078         assert(m1l>=0);
4079         assert(m2l>=0);
4080         output_byte(0xCC);
4081         emit_pushreg(m2h);
4082         emit_pushreg(m2l);
4083         emit_pushreg(m1h);
4084         emit_pushreg(m1l);
4085         emit_call((int)&mult64);
4086         emit_popreg(m1l);
4087         emit_popreg(m1h);
4088         emit_popreg(m2l);
4089         emit_popreg(m2h);
4090         char hih=get_reg(i_regs->regmap,HIREG|64);
4091         char hil=get_reg(i_regs->regmap,HIREG);
4092         if(hih>=0) emit_loadreg(HIREG|64,hih);
4093         if(hil>=0) emit_loadreg(HIREG,hil);
4094         char loh=get_reg(i_regs->regmap,LOREG|64);
4095         char lol=get_reg(i_regs->regmap,LOREG);
4096         if(loh>=0) emit_loadreg(LOREG|64,loh);
4097         if(lol>=0) emit_loadreg(LOREG,lol);
4098       }
4099       if(opcode2[i]==0x1D) // DMULTU
4100       {
4101         char m1h=get_reg(i_regs->regmap,rs1[i]|64);
4102         char m1l=get_reg(i_regs->regmap,rs1[i]);
4103         char m2h=get_reg(i_regs->regmap,rs2[i]|64);
4104         char m2l=get_reg(i_regs->regmap,rs2[i]);
4105         char temp=get_reg(i_regs->regmap,-1);
4106         assert(m1h>=0);
4107         assert(m2h>=0);
4108         assert(m1l>=0);
4109         assert(m2l>=0);
4110         assert(temp>=0);
4111         emit_mov(m1l,EAX);
4112         emit_mul(m2l);
4113         emit_storereg(LOREG,EAX);
4114         emit_mov(EDX,temp);
4115         emit_mov(m1h,EAX);
4116         emit_mul(m2l);
4117         emit_add(EAX,temp,temp);
4118         emit_adcimm(0,EDX);
4119         emit_storereg(HIREG,EDX);
4120         emit_mov(m2h,EAX);
4121         emit_mul(m1l);
4122         emit_add(EAX,temp,temp);
4123         emit_adcimm(0,EDX);
4124         emit_storereg(LOREG|64,temp);
4125         emit_mov(EDX,temp);
4126         emit_mov(m2h,EAX);
4127         emit_mul(m1h);
4128         emit_add(EAX,temp,EAX);
4129         emit_loadreg(HIREG,temp);
4130         emit_adcimm(0,EDX);
4131         emit_add(EAX,temp,EAX);
4132         emit_adcimm(0,EDX);
4133         // DEBUG
4134         /*
4135         emit_pushreg(m2h);
4136         emit_pushreg(m2l);
4137         emit_pushreg(m1h);
4138         emit_pushreg(m1l);
4139         emit_call((int)&multu64);
4140         emit_popreg(m1l);
4141         emit_popreg(m1h);
4142         emit_popreg(m2l);
4143         emit_popreg(m2h);
4144         char hih=get_reg(i_regs->regmap,HIREG|64);
4145         char hil=get_reg(i_regs->regmap,HIREG);
4146         if(hih>=0) emit_loadreg(HIREG|64,hih);  // DEBUG
4147         if(hil>=0) emit_loadreg(HIREG,hil);  // DEBUG
4148         */
4149         // Shouldn't be necessary
4150         //char loh=get_reg(i_regs->regmap,LOREG|64);
4151         //char lol=get_reg(i_regs->regmap,LOREG);
4152         //if(loh>=0) emit_loadreg(LOREG|64,loh);
4153         //if(lol>=0) emit_loadreg(LOREG,lol);
4154       }
4155       if(opcode2[i]==0x1E) // DDIV
4156       {
4157         char d1h=get_reg(i_regs->regmap,rs1[i]|64);
4158         char d1l=get_reg(i_regs->regmap,rs1[i]);
4159         char d2h=get_reg(i_regs->regmap,rs2[i]|64);
4160         char d2l=get_reg(i_regs->regmap,rs2[i]);
4161         assert(d1h>=0);
4162         assert(d2h>=0);
4163         assert(d1l>=0);
4164         assert(d2l>=0);
4165         //emit_pushreg(d2h);
4166         //emit_pushreg(d2l);
4167         //emit_pushreg(d1h);
4168         //emit_pushreg(d1l);
4169         emit_addimm64(ESP,-16,ESP);
4170         emit_writeword_indexed(d2h,12,ESP);
4171         emit_writeword_indexed(d2l,8,ESP);
4172         emit_writeword_indexed(d1h,4,ESP);
4173         emit_writeword_indexed(d1l,0,ESP);
4174         emit_readdword_indexed(0,ESP,ARG1_REG);
4175         emit_readdword_indexed(8,ESP,ARG2_REG);
4176         emit_call((int)&div64);
4177         //emit_popreg(d1l);
4178         //emit_popreg(d1h);
4179         //emit_popreg(d2l);
4180         //emit_popreg(d2h);
4181         emit_readword_indexed(0,ESP,d1l);
4182         emit_readword_indexed(4,ESP,d1h);
4183         emit_readword_indexed(8,ESP,d2l);
4184         emit_readword_indexed(12,ESP,d2h);
4185         emit_addimm64(ESP,16,ESP);
4186         char hih=get_reg(i_regs->regmap,HIREG|64);
4187         char hil=get_reg(i_regs->regmap,HIREG);
4188         char loh=get_reg(i_regs->regmap,LOREG|64);
4189         char lol=get_reg(i_regs->regmap,LOREG);
4190         if(hih>=0) emit_loadreg(HIREG|64,hih);
4191         if(hil>=0) emit_loadreg(HIREG,hil);
4192         if(loh>=0) emit_loadreg(LOREG|64,loh);
4193         if(lol>=0) emit_loadreg(LOREG,lol);
4194       }
4195       if(opcode2[i]==0x1F) // DDIVU
4196       {
4197         char d1h=get_reg(i_regs->regmap,rs1[i]|64);
4198         char d1l=get_reg(i_regs->regmap,rs1[i]);
4199         char d2h=get_reg(i_regs->regmap,rs2[i]|64);
4200         char d2l=get_reg(i_regs->regmap,rs2[i]);
4201         assert(d1h>=0);
4202         assert(d2h>=0);
4203         assert(d1l>=0);
4204         assert(d2l>=0);
4205         //emit_pushreg(d2h);
4206         //emit_pushreg(d2l);
4207         //emit_pushreg(d1h);
4208         //emit_pushreg(d1l);
4209         emit_addimm64(ESP,-16,ESP);
4210         emit_writeword_indexed(d2h,12,ESP);
4211         emit_writeword_indexed(d2l,8,ESP);
4212         emit_writeword_indexed(d1h,4,ESP);
4213         emit_writeword_indexed(d1l,0,ESP);
4214         emit_readdword_indexed(0,ESP,ARG1_REG);
4215         emit_readdword_indexed(8,ESP,ARG2_REG);
4216         emit_call((int)&divu64);
4217         //emit_popreg(d1l);
4218         //emit_popreg(d1h);
4219         //emit_popreg(d2l);
4220         //emit_popreg(d2h);
4221         emit_readword_indexed(0,ESP,d1l);
4222         emit_readword_indexed(4,ESP,d1h);
4223         emit_readword_indexed(8,ESP,d2l);
4224         emit_readword_indexed(12,ESP,d2h);
4225         emit_addimm64(ESP,16,ESP);
4226         char hih=get_reg(i_regs->regmap,HIREG|64);
4227         char hil=get_reg(i_regs->regmap,HIREG);
4228         char loh=get_reg(i_regs->regmap,LOREG|64);
4229         char lol=get_reg(i_regs->regmap,LOREG);
4230         if(hih>=0) emit_loadreg(HIREG|64,hih);
4231         if(hil>=0) emit_loadreg(HIREG,hil);
4232         if(loh>=0) emit_loadreg(LOREG|64,loh);
4233         if(lol>=0) emit_loadreg(LOREG,lol);
4234       }
4235     }
4236   }
4237   else
4238   {
4239     // Multiply by zero is zero.
4240     // MIPS does not have a divide by zero exception.
4241     // The result is undefined, we return zero.
4242     char hr=get_reg(i_regs->regmap,HIREG);
4243     char lr=get_reg(i_regs->regmap,LOREG);
4244     if(hr>=0) emit_zeroreg(hr);
4245     if(lr>=0) emit_zeroreg(lr);
4246   }
4247 }
4248 #define multdiv_assemble multdiv_assemble_x86
4249
4250 void do_preload_rhash(int r) {
4251   emit_movimm(0xf8,r);
4252 }
4253
4254 void do_preload_rhtbl(int r) {
4255   // Don't need this for x86
4256 }
4257
4258 void do_rhash(int rs,int rh) {
4259   emit_and(rs,rh,rh);
4260 }
4261
4262 void do_miniht_load(int ht,int rh) {
4263   // Don't need this for x86.  The load and compare can be combined into
4264   // a single instruction (below)
4265 }
4266
4267 void do_miniht_jump(int rs,int rh,int ht) {
4268   emit_cmpmem_indexed((int)mini_ht,rh,rs);
4269   emit_jne(jump_vaddr_reg[rs]);
4270   emit_readword_indexed((int)mini_ht+4,rh,rh);
4271   emit_jmpreg(rh);
4272 }
4273
4274 void do_miniht_insert(int return_address,int rt,int temp) {
4275   emit_movimm(return_address,rt); // PC into link register
4276   //emit_writeword_imm(return_address,(int)&mini_ht[(return_address&0xFF)>>8][0]);
4277   emit_writeword(rt,(int)&mini_ht[(return_address&0xFF)>>3][0]);
4278   add_to_linker((int)out,return_address,1);
4279   emit_writeword_imm(0,(int)&mini_ht[(return_address&0xFF)>>3][1]);
4280 }
4281
4282 // We don't need this for x86
4283 void literal_pool(int n) {}
4284 void literal_pool_jumpover(int n) {}
4285
4286 // CPU-architecture-specific initialization, not needed for x86
4287 void arch_init() {}