inline/parametrize rootcounter reads
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / assem_arm.c
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   Mupen64plus/PCSX - assem_arm.c                                        *
3  *   Copyright (C) 2009-2011 Ari64                                         *
4  *   Copyright (C) 2010-2011 GraÅžvydas "notaz" Ignotas                     *
5  *                                                                         *
6  *   This program is free software; you can redistribute it and/or modify  *
7  *   it under the terms of the GNU General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (at your option) any later version.                                   *
10  *                                                                         *
11  *   This program is distributed in the hope that it will be useful,       *
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14  *   GNU General Public License for more details.                          *
15  *                                                                         *
16  *   You should have received a copy of the GNU General Public License     *
17  *   along with this program; if not, write to the                         *
18  *   Free Software Foundation, Inc.,                                       *
19  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
20  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21
22 extern int cycle_count;
23 extern int last_count;
24 extern int pcaddr;
25 extern int pending_exception;
26 extern int branch_target;
27 extern uint64_t readmem_dword;
28 #ifdef MUPEN64
29 extern precomp_instr fake_pc;
30 #endif
31 extern void *dynarec_local;
32 extern u_int memory_map[1048576];
33 extern u_int mini_ht[32][2];
34 extern u_int rounding_modes[4];
35
36 void indirect_jump_indexed();
37 void indirect_jump();
38 void do_interrupt();
39 void jump_vaddr_r0();
40 void jump_vaddr_r1();
41 void jump_vaddr_r2();
42 void jump_vaddr_r3();
43 void jump_vaddr_r4();
44 void jump_vaddr_r5();
45 void jump_vaddr_r6();
46 void jump_vaddr_r7();
47 void jump_vaddr_r8();
48 void jump_vaddr_r9();
49 void jump_vaddr_r10();
50 void jump_vaddr_r12();
51
52 const u_int jump_vaddr_reg[16] = {
53   (int)jump_vaddr_r0,
54   (int)jump_vaddr_r1,
55   (int)jump_vaddr_r2,
56   (int)jump_vaddr_r3,
57   (int)jump_vaddr_r4,
58   (int)jump_vaddr_r5,
59   (int)jump_vaddr_r6,
60   (int)jump_vaddr_r7,
61   (int)jump_vaddr_r8,
62   (int)jump_vaddr_r9,
63   (int)jump_vaddr_r10,
64   0,
65   (int)jump_vaddr_r12,
66   0,
67   0,
68   0};
69
70 void invalidate_addr_r0();
71 void invalidate_addr_r1();
72 void invalidate_addr_r2();
73 void invalidate_addr_r3();
74 void invalidate_addr_r4();
75 void invalidate_addr_r5();
76 void invalidate_addr_r6();
77 void invalidate_addr_r7();
78 void invalidate_addr_r8();
79 void invalidate_addr_r9();
80 void invalidate_addr_r10();
81 void invalidate_addr_r12();
82
83 const u_int invalidate_addr_reg[16] = {
84   (int)invalidate_addr_r0,
85   (int)invalidate_addr_r1,
86   (int)invalidate_addr_r2,
87   (int)invalidate_addr_r3,
88   (int)invalidate_addr_r4,
89   (int)invalidate_addr_r5,
90   (int)invalidate_addr_r6,
91   (int)invalidate_addr_r7,
92   (int)invalidate_addr_r8,
93   (int)invalidate_addr_r9,
94   (int)invalidate_addr_r10,
95   0,
96   (int)invalidate_addr_r12,
97   0,
98   0,
99   0};
100
101 #include "fpu.h"
102
103 unsigned int needs_clear_cache[1<<(TARGET_SIZE_2-17)];
104
105 /* Linker */
106
107 void set_jump_target(int addr,u_int target)
108 {
109   u_char *ptr=(u_char *)addr;
110   u_int *ptr2=(u_int *)ptr;
111   if(ptr[3]==0xe2) {
112     assert((target-(u_int)ptr2-8)<1024);
113     assert((addr&3)==0);
114     assert((target&3)==0);
115     *ptr2=(*ptr2&0xFFFFF000)|((target-(u_int)ptr2-8)>>2)|0xF00;
116     //printf("target=%x addr=%x insn=%x\n",target,addr,*ptr2);
117   }
118   else if(ptr[3]==0x72) {
119     // generated by emit_jno_unlikely
120     if((target-(u_int)ptr2-8)<1024) {
121       assert((addr&3)==0);
122       assert((target&3)==0);
123       *ptr2=(*ptr2&0xFFFFF000)|((target-(u_int)ptr2-8)>>2)|0xF00;
124     }
125     else if((target-(u_int)ptr2-8)<4096&&!((target-(u_int)ptr2-8)&15)) {
126       assert((addr&3)==0);
127       assert((target&3)==0);
128       *ptr2=(*ptr2&0xFFFFF000)|((target-(u_int)ptr2-8)>>4)|0xE00;
129     }
130     else *ptr2=(0x7A000000)|(((target-(u_int)ptr2-8)<<6)>>8);
131   }
132   else {
133     assert((ptr[3]&0x0e)==0xa);
134     *ptr2=(*ptr2&0xFF000000)|(((target-(u_int)ptr2-8)<<6)>>8);
135   }
136 }
137
138 // This optionally copies the instruction from the target of the branch into
139 // the space before the branch.  Works, but the difference in speed is
140 // usually insignificant.
141 void set_jump_target_fillslot(int addr,u_int target,int copy)
142 {
143   u_char *ptr=(u_char *)addr;
144   u_int *ptr2=(u_int *)ptr;
145   assert(!copy||ptr2[-1]==0xe28dd000);
146   if(ptr[3]==0xe2) {
147     assert(!copy);
148     assert((target-(u_int)ptr2-8)<4096);
149     *ptr2=(*ptr2&0xFFFFF000)|(target-(u_int)ptr2-8);
150   }
151   else {
152     assert((ptr[3]&0x0e)==0xa);
153     u_int target_insn=*(u_int *)target;
154     if((target_insn&0x0e100000)==0) { // ALU, no immediate, no flags
155       copy=0;
156     }
157     if((target_insn&0x0c100000)==0x04100000) { // Load
158       copy=0;
159     }
160     if(target_insn&0x08000000) {
161       copy=0;
162     }
163     if(copy) {
164       ptr2[-1]=target_insn;
165       target+=4;
166     }
167     *ptr2=(*ptr2&0xFF000000)|(((target-(u_int)ptr2-8)<<6)>>8);
168   }
169 }
170
171 /* Literal pool */
172 add_literal(int addr,int val)
173 {
174   assert(literalcount<sizeof(literals)/sizeof(literals[0]));
175   literals[literalcount][0]=addr;
176   literals[literalcount][1]=val;
177   literalcount++; 
178
179
180 void *kill_pointer(void *stub)
181 {
182   int *ptr=(int *)(stub+4);
183   assert((*ptr&0x0ff00000)==0x05900000);
184   u_int offset=*ptr&0xfff;
185   int **l_ptr=(void *)ptr+offset+8;
186   int *i_ptr=*l_ptr;
187   set_jump_target((int)i_ptr,(int)stub);
188   return i_ptr;
189 }
190
191 // find where external branch is liked to using addr of it's stub:
192 // get address that insn one after stub loads (dyna_linker arg1),
193 // treat it as a pointer to branch insn,
194 // return addr where that branch jumps to
195 int get_pointer(void *stub)
196 {
197   //printf("get_pointer(%x)\n",(int)stub);
198   int *ptr=(int *)(stub+4);
199   assert((*ptr&0x0fff0000)==0x059f0000);
200   u_int offset=*ptr&0xfff;
201   int **l_ptr=(void *)ptr+offset+8;
202   int *i_ptr=*l_ptr;
203   assert((*i_ptr&0x0f000000)==0x0a000000);
204   return (int)i_ptr+((*i_ptr<<8)>>6)+8;
205 }
206
207 // Find the "clean" entry point from a "dirty" entry point
208 // by skipping past the call to verify_code
209 u_int get_clean_addr(int addr)
210 {
211   int *ptr=(int *)addr;
212   #ifdef ARMv5_ONLY
213   ptr+=4;
214   #else
215   ptr+=6;
216   #endif
217   if((*ptr&0xFF000000)!=0xeb000000) ptr++;
218   assert((*ptr&0xFF000000)==0xeb000000); // bl instruction
219   ptr++;
220   if((*ptr&0xFF000000)==0xea000000) {
221     return (int)ptr+((*ptr<<8)>>6)+8; // follow jump
222   }
223   return (u_int)ptr;
224 }
225
226 int verify_dirty(int addr)
227 {
228   u_int *ptr=(u_int *)addr;
229   #ifdef ARMv5_ONLY
230   // get from literal pool
231   assert((*ptr&0xFFFF0000)==0xe59f0000);
232   u_int offset=*ptr&0xfff;
233   u_int *l_ptr=(void *)ptr+offset+8;
234   u_int source=l_ptr[0];
235   u_int copy=l_ptr[1];
236   u_int len=l_ptr[2];
237   ptr+=4;
238   #else
239   // ARMv7 movw/movt
240   assert((*ptr&0xFFF00000)==0xe3000000);
241   u_int source=(ptr[0]&0xFFF)+((ptr[0]>>4)&0xF000)+((ptr[2]<<16)&0xFFF0000)+((ptr[2]<<12)&0xF0000000);
242   u_int copy=(ptr[1]&0xFFF)+((ptr[1]>>4)&0xF000)+((ptr[3]<<16)&0xFFF0000)+((ptr[3]<<12)&0xF0000000);
243   u_int len=(ptr[4]&0xFFF)+((ptr[4]>>4)&0xF000);
244   ptr+=6;
245   #endif
246   if((*ptr&0xFF000000)!=0xeb000000) ptr++;
247   assert((*ptr&0xFF000000)==0xeb000000); // bl instruction
248 #ifndef DISABLE_TLB
249   u_int verifier=(int)ptr+((signed int)(*ptr<<8)>>6)+8; // get target of bl
250   if(verifier==(u_int)verify_code_vm||verifier==(u_int)verify_code_ds) {
251     unsigned int page=source>>12;
252     unsigned int map_value=memory_map[page];
253     if(map_value>=0x80000000) return 0;
254     while(page<((source+len-1)>>12)) {
255       if((memory_map[++page]<<2)!=(map_value<<2)) return 0;
256     }
257     source = source+(map_value<<2);
258   }
259 #endif
260   //printf("verify_dirty: %x %x %x\n",source,copy,len);
261   return !memcmp((void *)source,(void *)copy,len);
262 }
263
264 // This doesn't necessarily find all clean entry points, just
265 // guarantees that it's not dirty
266 int isclean(int addr)
267 {
268   #ifdef ARMv5_ONLY
269   int *ptr=((u_int *)addr)+4;
270   #else
271   int *ptr=((u_int *)addr)+6;
272   #endif
273   if((*ptr&0xFF000000)!=0xeb000000) ptr++;
274   if((*ptr&0xFF000000)!=0xeb000000) return 1; // bl instruction
275   if((int)ptr+((*ptr<<8)>>6)+8==(int)verify_code) return 0;
276   if((int)ptr+((*ptr<<8)>>6)+8==(int)verify_code_vm) return 0;
277   if((int)ptr+((*ptr<<8)>>6)+8==(int)verify_code_ds) return 0;
278   return 1;
279 }
280
281 void get_bounds(int addr,u_int *start,u_int *end)
282 {
283   u_int *ptr=(u_int *)addr;
284   #ifdef ARMv5_ONLY
285   // get from literal pool
286   assert((*ptr&0xFFFF0000)==0xe59f0000);
287   u_int offset=*ptr&0xfff;
288   u_int *l_ptr=(void *)ptr+offset+8;
289   u_int source=l_ptr[0];
290   //u_int copy=l_ptr[1];
291   u_int len=l_ptr[2];
292   ptr+=4;
293   #else
294   // ARMv7 movw/movt
295   assert((*ptr&0xFFF00000)==0xe3000000);
296   u_int source=(ptr[0]&0xFFF)+((ptr[0]>>4)&0xF000)+((ptr[2]<<16)&0xFFF0000)+((ptr[2]<<12)&0xF0000000);
297   //u_int copy=(ptr[1]&0xFFF)+((ptr[1]>>4)&0xF000)+((ptr[3]<<16)&0xFFF0000)+((ptr[3]<<12)&0xF0000000);
298   u_int len=(ptr[4]&0xFFF)+((ptr[4]>>4)&0xF000);
299   ptr+=6;
300   #endif
301   if((*ptr&0xFF000000)!=0xeb000000) ptr++;
302   assert((*ptr&0xFF000000)==0xeb000000); // bl instruction
303 #ifndef DISABLE_TLB
304   u_int verifier=(int)ptr+((signed int)(*ptr<<8)>>6)+8; // get target of bl
305   if(verifier==(u_int)verify_code_vm||verifier==(u_int)verify_code_ds) {
306     if(memory_map[source>>12]>=0x80000000) source = 0;
307     else source = source+(memory_map[source>>12]<<2);
308   }
309 #endif
310   *start=source;
311   *end=source+len;
312 }
313
314 /* Register allocation */
315
316 // Note: registers are allocated clean (unmodified state)
317 // if you intend to modify the register, you must call dirty_reg().
318 void alloc_reg(struct regstat *cur,int i,signed char reg)
319 {
320   int r,hr;
321   int preferred_reg = (reg&7);
322   if(reg==CCREG) preferred_reg=HOST_CCREG;
323   if(reg==PTEMP||reg==FTEMP) preferred_reg=12;
324   
325   // Don't allocate unused registers
326   if((cur->u>>reg)&1) return;
327   
328   // see if it's already allocated
329   for(hr=0;hr<HOST_REGS;hr++)
330   {
331     if(cur->regmap[hr]==reg) return;
332   }
333   
334   // Keep the same mapping if the register was already allocated in a loop
335   preferred_reg = loop_reg(i,reg,preferred_reg);
336   
337   // Try to allocate the preferred register
338   if(cur->regmap[preferred_reg]==-1) {
339     cur->regmap[preferred_reg]=reg;
340     cur->dirty&=~(1<<preferred_reg);
341     cur->isconst&=~(1<<preferred_reg);
342     return;
343   }
344   r=cur->regmap[preferred_reg];
345   if(r<64&&((cur->u>>r)&1)) {
346     cur->regmap[preferred_reg]=reg;
347     cur->dirty&=~(1<<preferred_reg);
348     cur->isconst&=~(1<<preferred_reg);
349     return;
350   }
351   if(r>=64&&((cur->uu>>(r&63))&1)) {
352     cur->regmap[preferred_reg]=reg;
353     cur->dirty&=~(1<<preferred_reg);
354     cur->isconst&=~(1<<preferred_reg);
355     return;
356   }
357   
358   // Clear any unneeded registers
359   // We try to keep the mapping consistent, if possible, because it
360   // makes branches easier (especially loops).  So we try to allocate
361   // first (see above) before removing old mappings.  If this is not
362   // possible then go ahead and clear out the registers that are no
363   // longer needed.
364   for(hr=0;hr<HOST_REGS;hr++)
365   {
366     r=cur->regmap[hr];
367     if(r>=0) {
368       if(r<64) {
369         if((cur->u>>r)&1) {cur->regmap[hr]=-1;break;}
370       }
371       else
372       {
373         if((cur->uu>>(r&63))&1) {cur->regmap[hr]=-1;break;}
374       }
375     }
376   }
377   // Try to allocate any available register, but prefer
378   // registers that have not been used recently.
379   if(i>0) {
380     for(hr=0;hr<HOST_REGS;hr++) {
381       if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) {
382         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]) {
383           cur->regmap[hr]=reg;
384           cur->dirty&=~(1<<hr);
385           cur->isconst&=~(1<<hr);
386           return;
387         }
388       }
389     }
390   }
391   // Try to allocate any available register
392   for(hr=0;hr<HOST_REGS;hr++) {
393     if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) {
394       cur->regmap[hr]=reg;
395       cur->dirty&=~(1<<hr);
396       cur->isconst&=~(1<<hr);
397       return;
398     }
399   }
400   
401   // Ok, now we have to evict someone
402   // Pick a register we hopefully won't need soon
403   u_char hsn[MAXREG+1];
404   memset(hsn,10,sizeof(hsn));
405   int j;
406   lsn(hsn,i,&preferred_reg);
407   //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]);
408   //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]);
409   if(i>0) {
410     // Don't evict the cycle count at entry points, otherwise the entry
411     // stub will have to write it.
412     if(bt[i]&&hsn[CCREG]>2) hsn[CCREG]=2;
413     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;
414     for(j=10;j>=3;j--)
415     {
416       // Alloc preferred register if available
417       if(hsn[r=cur->regmap[preferred_reg]&63]==j) {
418         for(hr=0;hr<HOST_REGS;hr++) {
419           // Evict both parts of a 64-bit register
420           if((cur->regmap[hr]&63)==r) {
421             cur->regmap[hr]=-1;
422             cur->dirty&=~(1<<hr);
423             cur->isconst&=~(1<<hr);
424           }
425         }
426         cur->regmap[preferred_reg]=reg;
427         return;
428       }
429       for(r=1;r<=MAXREG;r++)
430       {
431         if(hsn[r]==j&&r!=rs1[i-1]&&r!=rs2[i-1]&&r!=rt1[i-1]&&r!=rt2[i-1]) {
432           for(hr=0;hr<HOST_REGS;hr++) {
433             if(hr!=HOST_CCREG||j<hsn[CCREG]) {
434               if(cur->regmap[hr]==r+64) {
435                 cur->regmap[hr]=reg;
436                 cur->dirty&=~(1<<hr);
437                 cur->isconst&=~(1<<hr);
438                 return;
439               }
440             }
441           }
442           for(hr=0;hr<HOST_REGS;hr++) {
443             if(hr!=HOST_CCREG||j<hsn[CCREG]) {
444               if(cur->regmap[hr]==r) {
445                 cur->regmap[hr]=reg;
446                 cur->dirty&=~(1<<hr);
447                 cur->isconst&=~(1<<hr);
448                 return;
449               }
450             }
451           }
452         }
453       }
454     }
455   }
456   for(j=10;j>=0;j--)
457   {
458     for(r=1;r<=MAXREG;r++)
459     {
460       if(hsn[r]==j) {
461         for(hr=0;hr<HOST_REGS;hr++) {
462           if(cur->regmap[hr]==r+64) {
463             cur->regmap[hr]=reg;
464             cur->dirty&=~(1<<hr);
465             cur->isconst&=~(1<<hr);
466             return;
467           }
468         }
469         for(hr=0;hr<HOST_REGS;hr++) {
470           if(cur->regmap[hr]==r) {
471             cur->regmap[hr]=reg;
472             cur->dirty&=~(1<<hr);
473             cur->isconst&=~(1<<hr);
474             return;
475           }
476         }
477       }
478     }
479   }
480   printf("This shouldn't happen (alloc_reg)");exit(1);
481 }
482
483 void alloc_reg64(struct regstat *cur,int i,signed char reg)
484 {
485   int preferred_reg = 8+(reg&1);
486   int r,hr;
487   
488   // allocate the lower 32 bits
489   alloc_reg(cur,i,reg);
490   
491   // Don't allocate unused registers
492   if((cur->uu>>reg)&1) return;
493   
494   // see if the upper half is already allocated
495   for(hr=0;hr<HOST_REGS;hr++)
496   {
497     if(cur->regmap[hr]==reg+64) return;
498   }
499   
500   // Keep the same mapping if the register was already allocated in a loop
501   preferred_reg = loop_reg(i,reg,preferred_reg);
502   
503   // Try to allocate the preferred register
504   if(cur->regmap[preferred_reg]==-1) {
505     cur->regmap[preferred_reg]=reg|64;
506     cur->dirty&=~(1<<preferred_reg);
507     cur->isconst&=~(1<<preferred_reg);
508     return;
509   }
510   r=cur->regmap[preferred_reg];
511   if(r<64&&((cur->u>>r)&1)) {
512     cur->regmap[preferred_reg]=reg|64;
513     cur->dirty&=~(1<<preferred_reg);
514     cur->isconst&=~(1<<preferred_reg);
515     return;
516   }
517   if(r>=64&&((cur->uu>>(r&63))&1)) {
518     cur->regmap[preferred_reg]=reg|64;
519     cur->dirty&=~(1<<preferred_reg);
520     cur->isconst&=~(1<<preferred_reg);
521     return;
522   }
523   
524   // Clear any unneeded registers
525   // We try to keep the mapping consistent, if possible, because it
526   // makes branches easier (especially loops).  So we try to allocate
527   // first (see above) before removing old mappings.  If this is not
528   // possible then go ahead and clear out the registers that are no
529   // longer needed.
530   for(hr=HOST_REGS-1;hr>=0;hr--)
531   {
532     r=cur->regmap[hr];
533     if(r>=0) {
534       if(r<64) {
535         if((cur->u>>r)&1) {cur->regmap[hr]=-1;break;}
536       }
537       else
538       {
539         if((cur->uu>>(r&63))&1) {cur->regmap[hr]=-1;break;}
540       }
541     }
542   }
543   // Try to allocate any available register, but prefer
544   // registers that have not been used recently.
545   if(i>0) {
546     for(hr=0;hr<HOST_REGS;hr++) {
547       if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) {
548         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]) {
549           cur->regmap[hr]=reg|64;
550           cur->dirty&=~(1<<hr);
551           cur->isconst&=~(1<<hr);
552           return;
553         }
554       }
555     }
556   }
557   // Try to allocate any available register
558   for(hr=0;hr<HOST_REGS;hr++) {
559     if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) {
560       cur->regmap[hr]=reg|64;
561       cur->dirty&=~(1<<hr);
562       cur->isconst&=~(1<<hr);
563       return;
564     }
565   }
566   
567   // Ok, now we have to evict someone
568   // Pick a register we hopefully won't need soon
569   u_char hsn[MAXREG+1];
570   memset(hsn,10,sizeof(hsn));
571   int j;
572   lsn(hsn,i,&preferred_reg);
573   //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]);
574   //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]);
575   if(i>0) {
576     // Don't evict the cycle count at entry points, otherwise the entry
577     // stub will have to write it.
578     if(bt[i]&&hsn[CCREG]>2) hsn[CCREG]=2;
579     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;
580     for(j=10;j>=3;j--)
581     {
582       // Alloc preferred register if available
583       if(hsn[r=cur->regmap[preferred_reg]&63]==j) {
584         for(hr=0;hr<HOST_REGS;hr++) {
585           // Evict both parts of a 64-bit register
586           if((cur->regmap[hr]&63)==r) {
587             cur->regmap[hr]=-1;
588             cur->dirty&=~(1<<hr);
589             cur->isconst&=~(1<<hr);
590           }
591         }
592         cur->regmap[preferred_reg]=reg|64;
593         return;
594       }
595       for(r=1;r<=MAXREG;r++)
596       {
597         if(hsn[r]==j&&r!=rs1[i-1]&&r!=rs2[i-1]&&r!=rt1[i-1]&&r!=rt2[i-1]) {
598           for(hr=0;hr<HOST_REGS;hr++) {
599             if(hr!=HOST_CCREG||j<hsn[CCREG]) {
600               if(cur->regmap[hr]==r+64) {
601                 cur->regmap[hr]=reg|64;
602                 cur->dirty&=~(1<<hr);
603                 cur->isconst&=~(1<<hr);
604                 return;
605               }
606             }
607           }
608           for(hr=0;hr<HOST_REGS;hr++) {
609             if(hr!=HOST_CCREG||j<hsn[CCREG]) {
610               if(cur->regmap[hr]==r) {
611                 cur->regmap[hr]=reg|64;
612                 cur->dirty&=~(1<<hr);
613                 cur->isconst&=~(1<<hr);
614                 return;
615               }
616             }
617           }
618         }
619       }
620     }
621   }
622   for(j=10;j>=0;j--)
623   {
624     for(r=1;r<=MAXREG;r++)
625     {
626       if(hsn[r]==j) {
627         for(hr=0;hr<HOST_REGS;hr++) {
628           if(cur->regmap[hr]==r+64) {
629             cur->regmap[hr]=reg|64;
630             cur->dirty&=~(1<<hr);
631             cur->isconst&=~(1<<hr);
632             return;
633           }
634         }
635         for(hr=0;hr<HOST_REGS;hr++) {
636           if(cur->regmap[hr]==r) {
637             cur->regmap[hr]=reg|64;
638             cur->dirty&=~(1<<hr);
639             cur->isconst&=~(1<<hr);
640             return;
641           }
642         }
643       }
644     }
645   }
646   printf("This shouldn't happen");exit(1);
647 }
648
649 // Allocate a temporary register.  This is done without regard to
650 // dirty status or whether the register we request is on the unneeded list
651 // Note: This will only allocate one register, even if called multiple times
652 void alloc_reg_temp(struct regstat *cur,int i,signed char reg)
653 {
654   int r,hr;
655   int preferred_reg = -1;
656   
657   // see if it's already allocated
658   for(hr=0;hr<HOST_REGS;hr++)
659   {
660     if(hr!=EXCLUDE_REG&&cur->regmap[hr]==reg) return;
661   }
662   
663   // Try to allocate any available register
664   for(hr=HOST_REGS-1;hr>=0;hr--) {
665     if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) {
666       cur->regmap[hr]=reg;
667       cur->dirty&=~(1<<hr);
668       cur->isconst&=~(1<<hr);
669       return;
670     }
671   }
672   
673   // Find an unneeded register
674   for(hr=HOST_REGS-1;hr>=0;hr--)
675   {
676     r=cur->regmap[hr];
677     if(r>=0) {
678       if(r<64) {
679         if((cur->u>>r)&1) {
680           if(i==0||((unneeded_reg[i-1]>>r)&1)) {
681             cur->regmap[hr]=reg;
682             cur->dirty&=~(1<<hr);
683             cur->isconst&=~(1<<hr);
684             return;
685           }
686         }
687       }
688       else
689       {
690         if((cur->uu>>(r&63))&1) {
691           if(i==0||((unneeded_reg_upper[i-1]>>(r&63))&1)) {
692             cur->regmap[hr]=reg;
693             cur->dirty&=~(1<<hr);
694             cur->isconst&=~(1<<hr);
695             return;
696           }
697         }
698       }
699     }
700   }
701   
702   // Ok, now we have to evict someone
703   // Pick a register we hopefully won't need soon
704   // TODO: we might want to follow unconditional jumps here
705   // TODO: get rid of dupe code and make this into a function
706   u_char hsn[MAXREG+1];
707   memset(hsn,10,sizeof(hsn));
708   int j;
709   lsn(hsn,i,&preferred_reg);
710   //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]);
711   if(i>0) {
712     // Don't evict the cycle count at entry points, otherwise the entry
713     // stub will have to write it.
714     if(bt[i]&&hsn[CCREG]>2) hsn[CCREG]=2;
715     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;
716     for(j=10;j>=3;j--)
717     {
718       for(r=1;r<=MAXREG;r++)
719       {
720         if(hsn[r]==j&&r!=rs1[i-1]&&r!=rs2[i-1]&&r!=rt1[i-1]&&r!=rt2[i-1]) {
721           for(hr=0;hr<HOST_REGS;hr++) {
722             if(hr!=HOST_CCREG||hsn[CCREG]>2) {
723               if(cur->regmap[hr]==r+64) {
724                 cur->regmap[hr]=reg;
725                 cur->dirty&=~(1<<hr);
726                 cur->isconst&=~(1<<hr);
727                 return;
728               }
729             }
730           }
731           for(hr=0;hr<HOST_REGS;hr++) {
732             if(hr!=HOST_CCREG||hsn[CCREG]>2) {
733               if(cur->regmap[hr]==r) {
734                 cur->regmap[hr]=reg;
735                 cur->dirty&=~(1<<hr);
736                 cur->isconst&=~(1<<hr);
737                 return;
738               }
739             }
740           }
741         }
742       }
743     }
744   }
745   for(j=10;j>=0;j--)
746   {
747     for(r=1;r<=MAXREG;r++)
748     {
749       if(hsn[r]==j) {
750         for(hr=0;hr<HOST_REGS;hr++) {
751           if(cur->regmap[hr]==r+64) {
752             cur->regmap[hr]=reg;
753             cur->dirty&=~(1<<hr);
754             cur->isconst&=~(1<<hr);
755             return;
756           }
757         }
758         for(hr=0;hr<HOST_REGS;hr++) {
759           if(cur->regmap[hr]==r) {
760             cur->regmap[hr]=reg;
761             cur->dirty&=~(1<<hr);
762             cur->isconst&=~(1<<hr);
763             return;
764           }
765         }
766       }
767     }
768   }
769   printf("This shouldn't happen");exit(1);
770 }
771 // Allocate a specific ARM register.
772 void alloc_arm_reg(struct regstat *cur,int i,signed char reg,char hr)
773 {
774   int n;
775   int dirty=0;
776   
777   // see if it's already allocated (and dealloc it)
778   for(n=0;n<HOST_REGS;n++)
779   {
780     if(n!=EXCLUDE_REG&&cur->regmap[n]==reg) {
781       dirty=(cur->dirty>>n)&1;
782       cur->regmap[n]=-1;
783     }
784   }
785   
786   cur->regmap[hr]=reg;
787   cur->dirty&=~(1<<hr);
788   cur->dirty|=dirty<<hr;
789   cur->isconst&=~(1<<hr);
790 }
791
792 // Alloc cycle count into dedicated register
793 alloc_cc(struct regstat *cur,int i)
794 {
795   alloc_arm_reg(cur,i,CCREG,HOST_CCREG);
796 }
797
798 /* Special alloc */
799
800
801 /* Assembler */
802
803 char regname[16][4] = {
804  "r0",
805  "r1",
806  "r2",
807  "r3",
808  "r4",
809  "r5",
810  "r6",
811  "r7",
812  "r8",
813  "r9",
814  "r10",
815  "fp",
816  "r12",
817  "sp",
818  "lr",
819  "pc"};
820
821 void output_byte(u_char byte)
822 {
823   *(out++)=byte;
824 }
825 void output_modrm(u_char mod,u_char rm,u_char ext)
826 {
827   assert(mod<4);
828   assert(rm<8);
829   assert(ext<8);
830   u_char byte=(mod<<6)|(ext<<3)|rm;
831   *(out++)=byte;
832 }
833 void output_sib(u_char scale,u_char index,u_char base)
834 {
835   assert(scale<4);
836   assert(index<8);
837   assert(base<8);
838   u_char byte=(scale<<6)|(index<<3)|base;
839   *(out++)=byte;
840 }
841 void output_w32(u_int word)
842 {
843   *((u_int *)out)=word;
844   out+=4;
845 }
846 u_int rd_rn_rm(u_int rd, u_int rn, u_int rm)
847 {
848   assert(rd<16);
849   assert(rn<16);
850   assert(rm<16);
851   return((rn<<16)|(rd<<12)|rm);
852 }
853 u_int rd_rn_imm_shift(u_int rd, u_int rn, u_int imm, u_int shift)
854 {
855   assert(rd<16);
856   assert(rn<16);
857   assert(imm<256);
858   assert((shift&1)==0);
859   return((rn<<16)|(rd<<12)|(((32-shift)&30)<<7)|imm);
860 }
861 u_int genimm(u_int imm,u_int *encoded)
862 {
863   *encoded=0;
864   if(imm==0) return 1;
865   int i=32;
866   while(i>0)
867   {
868     if(imm<256) {
869       *encoded=((i&30)<<7)|imm;
870       return 1;
871     }
872     imm=(imm>>2)|(imm<<30);i-=2;
873   }
874   return 0;
875 }
876 void genimm_checked(u_int imm,u_int *encoded)
877 {
878   u_int ret=genimm(imm,encoded);
879   assert(ret);
880 }
881 u_int genjmp(u_int addr)
882 {
883   int offset=addr-(int)out-8;
884   if(offset<-33554432||offset>=33554432) {
885     if (addr>2) {
886       printf("genjmp: out of range: %08x\n", offset);
887       exit(1);
888     }
889     return 0;
890   }
891   return ((u_int)offset>>2)&0xffffff;
892 }
893
894 void emit_mov(int rs,int rt)
895 {
896   assem_debug("mov %s,%s\n",regname[rt],regname[rs]);
897   output_w32(0xe1a00000|rd_rn_rm(rt,0,rs));
898 }
899
900 void emit_movs(int rs,int rt)
901 {
902   assem_debug("movs %s,%s\n",regname[rt],regname[rs]);
903   output_w32(0xe1b00000|rd_rn_rm(rt,0,rs));
904 }
905
906 void emit_add(int rs1,int rs2,int rt)
907 {
908   assem_debug("add %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
909   output_w32(0xe0800000|rd_rn_rm(rt,rs1,rs2));
910 }
911
912 void emit_adds(int rs1,int rs2,int rt)
913 {
914   assem_debug("adds %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
915   output_w32(0xe0900000|rd_rn_rm(rt,rs1,rs2));
916 }
917
918 void emit_adcs(int rs1,int rs2,int rt)
919 {
920   assem_debug("adcs %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
921   output_w32(0xe0b00000|rd_rn_rm(rt,rs1,rs2));
922 }
923
924 void emit_sbc(int rs1,int rs2,int rt)
925 {
926   assem_debug("sbc %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
927   output_w32(0xe0c00000|rd_rn_rm(rt,rs1,rs2));
928 }
929
930 void emit_sbcs(int rs1,int rs2,int rt)
931 {
932   assem_debug("sbcs %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
933   output_w32(0xe0d00000|rd_rn_rm(rt,rs1,rs2));
934 }
935
936 void emit_neg(int rs, int rt)
937 {
938   assem_debug("rsb %s,%s,#0\n",regname[rt],regname[rs]);
939   output_w32(0xe2600000|rd_rn_rm(rt,rs,0));
940 }
941
942 void emit_negs(int rs, int rt)
943 {
944   assem_debug("rsbs %s,%s,#0\n",regname[rt],regname[rs]);
945   output_w32(0xe2700000|rd_rn_rm(rt,rs,0));
946 }
947
948 void emit_sub(int rs1,int rs2,int rt)
949 {
950   assem_debug("sub %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
951   output_w32(0xe0400000|rd_rn_rm(rt,rs1,rs2));
952 }
953
954 void emit_subs(int rs1,int rs2,int rt)
955 {
956   assem_debug("subs %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
957   output_w32(0xe0500000|rd_rn_rm(rt,rs1,rs2));
958 }
959
960 void emit_zeroreg(int rt)
961 {
962   assem_debug("mov %s,#0\n",regname[rt]);
963   output_w32(0xe3a00000|rd_rn_rm(rt,0,0));
964 }
965
966 void emit_loadlp(u_int imm,u_int rt)
967 {
968   add_literal((int)out,imm);
969   assem_debug("ldr %s,pc+? [=%x]\n",regname[rt],imm);
970   output_w32(0xe5900000|rd_rn_rm(rt,15,0));
971 }
972 void emit_movw(u_int imm,u_int rt)
973 {
974   assert(imm<65536);
975   assem_debug("movw %s,#%d (0x%x)\n",regname[rt],imm,imm);
976   output_w32(0xe3000000|rd_rn_rm(rt,0,0)|(imm&0xfff)|((imm<<4)&0xf0000));
977 }
978 void emit_movt(u_int imm,u_int rt)
979 {
980   assem_debug("movt %s,#%d (0x%x)\n",regname[rt],imm&0xffff0000,imm&0xffff0000);
981   output_w32(0xe3400000|rd_rn_rm(rt,0,0)|((imm>>16)&0xfff)|((imm>>12)&0xf0000));
982 }
983 void emit_movimm(u_int imm,u_int rt)
984 {
985   u_int armval;
986   if(genimm(imm,&armval)) {
987     assem_debug("mov %s,#%d\n",regname[rt],imm);
988     output_w32(0xe3a00000|rd_rn_rm(rt,0,0)|armval);
989   }else if(genimm(~imm,&armval)) {
990     assem_debug("mvn %s,#%d\n",regname[rt],imm);
991     output_w32(0xe3e00000|rd_rn_rm(rt,0,0)|armval);
992   }else if(imm<65536) {
993     #ifdef ARMv5_ONLY
994     assem_debug("mov %s,#%d\n",regname[rt],imm&0xFF00);
995     output_w32(0xe3a00000|rd_rn_imm_shift(rt,0,imm>>8,8));
996     assem_debug("add %s,%s,#%d\n",regname[rt],regname[rt],imm&0xFF);
997     output_w32(0xe2800000|rd_rn_imm_shift(rt,rt,imm&0xff,0));
998     #else
999     emit_movw(imm,rt);
1000     #endif
1001   }else{
1002     #ifdef ARMv5_ONLY
1003     emit_loadlp(imm,rt);
1004     #else
1005     emit_movw(imm&0x0000FFFF,rt);
1006     emit_movt(imm&0xFFFF0000,rt);
1007     #endif
1008   }
1009 }
1010 void emit_pcreladdr(u_int rt)
1011 {
1012   assem_debug("add %s,pc,#?\n",regname[rt]);
1013   output_w32(0xe2800000|rd_rn_rm(rt,15,0));
1014 }
1015
1016 void emit_loadreg(int r, int hr)
1017 {
1018 #ifdef FORCE32
1019   if(r&64) {
1020     printf("64bit load in 32bit mode!\n");
1021     assert(0);
1022     return;
1023   }
1024 #endif
1025   if((r&63)==0)
1026     emit_zeroreg(hr);
1027   else {
1028     int addr=((int)reg)+((r&63)<<REG_SHIFT)+((r&64)>>4);
1029     if((r&63)==HIREG) addr=(int)&hi+((r&64)>>4);
1030     if((r&63)==LOREG) addr=(int)&lo+((r&64)>>4);
1031     if(r==CCREG) addr=(int)&cycle_count;
1032     if(r==CSREG) addr=(int)&Status;
1033     if(r==FSREG) addr=(int)&FCR31;
1034     if(r==INVCP) addr=(int)&invc_ptr;
1035     u_int offset = addr-(u_int)&dynarec_local;
1036     assert(offset<4096);
1037     assem_debug("ldr %s,fp+%d\n",regname[hr],offset);
1038     output_w32(0xe5900000|rd_rn_rm(hr,FP,0)|offset);
1039   }
1040 }
1041 void emit_storereg(int r, int hr)
1042 {
1043 #ifdef FORCE32
1044   if(r&64) {
1045     printf("64bit store in 32bit mode!\n");
1046     assert(0);
1047     return;
1048   }
1049 #endif
1050   int addr=((int)reg)+((r&63)<<REG_SHIFT)+((r&64)>>4);
1051   if((r&63)==HIREG) addr=(int)&hi+((r&64)>>4);
1052   if((r&63)==LOREG) addr=(int)&lo+((r&64)>>4);
1053   if(r==CCREG) addr=(int)&cycle_count;
1054   if(r==FSREG) addr=(int)&FCR31;
1055   u_int offset = addr-(u_int)&dynarec_local;
1056   assert(offset<4096);
1057   assem_debug("str %s,fp+%d\n",regname[hr],offset);
1058   output_w32(0xe5800000|rd_rn_rm(hr,FP,0)|offset);
1059 }
1060
1061 void emit_test(int rs, int rt)
1062 {
1063   assem_debug("tst %s,%s\n",regname[rs],regname[rt]);
1064   output_w32(0xe1100000|rd_rn_rm(0,rs,rt));
1065 }
1066
1067 void emit_testimm(int rs,int imm)
1068 {
1069   u_int armval;
1070   assem_debug("tst %s,#%d\n",regname[rs],imm);
1071   genimm_checked(imm,&armval);
1072   output_w32(0xe3100000|rd_rn_rm(0,rs,0)|armval);
1073 }
1074
1075 void emit_testeqimm(int rs,int imm)
1076 {
1077   u_int armval;
1078   assem_debug("tsteq %s,$%d\n",regname[rs],imm);
1079   genimm_checked(imm,&armval);
1080   output_w32(0x03100000|rd_rn_rm(0,rs,0)|armval);
1081 }
1082
1083 void emit_not(int rs,int rt)
1084 {
1085   assem_debug("mvn %s,%s\n",regname[rt],regname[rs]);
1086   output_w32(0xe1e00000|rd_rn_rm(rt,0,rs));
1087 }
1088
1089 void emit_mvnmi(int rs,int rt)
1090 {
1091   assem_debug("mvnmi %s,%s\n",regname[rt],regname[rs]);
1092   output_w32(0x41e00000|rd_rn_rm(rt,0,rs));
1093 }
1094
1095 void emit_and(u_int rs1,u_int rs2,u_int rt)
1096 {
1097   assem_debug("and %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
1098   output_w32(0xe0000000|rd_rn_rm(rt,rs1,rs2));
1099 }
1100
1101 void emit_or(u_int rs1,u_int rs2,u_int rt)
1102 {
1103   assem_debug("orr %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
1104   output_w32(0xe1800000|rd_rn_rm(rt,rs1,rs2));
1105 }
1106 void emit_or_and_set_flags(int rs1,int rs2,int rt)
1107 {
1108   assem_debug("orrs %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
1109   output_w32(0xe1900000|rd_rn_rm(rt,rs1,rs2));
1110 }
1111
1112 void emit_orrshl_imm(u_int rs,u_int imm,u_int rt)
1113 {
1114   assert(rs<16);
1115   assert(rt<16);
1116   assert(imm<32);
1117   assem_debug("orr %s,%s,%s,lsl #%d\n",regname[rt],regname[rt],regname[rs],imm);
1118   output_w32(0xe1800000|rd_rn_rm(rt,rt,rs)|(imm<<7));
1119 }
1120
1121 void emit_orrshr_imm(u_int rs,u_int imm,u_int rt)
1122 {
1123   assert(rs<16);
1124   assert(rt<16);
1125   assert(imm<32);
1126   assem_debug("orr %s,%s,%s,lsr #%d\n",regname[rt],regname[rt],regname[rs],imm);
1127   output_w32(0xe1800020|rd_rn_rm(rt,rt,rs)|(imm<<7));
1128 }
1129
1130 void emit_xor(u_int rs1,u_int rs2,u_int rt)
1131 {
1132   assem_debug("eor %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
1133   output_w32(0xe0200000|rd_rn_rm(rt,rs1,rs2));
1134 }
1135
1136 void emit_addimm(u_int rs,int imm,u_int rt)
1137 {
1138   assert(rs<16);
1139   assert(rt<16);
1140   if(imm!=0) {
1141     u_int armval;
1142     if(genimm(imm,&armval)) {
1143       assem_debug("add %s,%s,#%d\n",regname[rt],regname[rs],imm);
1144       output_w32(0xe2800000|rd_rn_rm(rt,rs,0)|armval);
1145     }else if(genimm(-imm,&armval)) {
1146       assem_debug("sub %s,%s,#%d\n",regname[rt],regname[rs],imm);
1147       output_w32(0xe2400000|rd_rn_rm(rt,rs,0)|armval);
1148     }else if(imm<0) {
1149       assert(imm>-65536);
1150       assem_debug("sub %s,%s,#%d\n",regname[rt],regname[rs],(-imm)&0xFF00);
1151       assem_debug("sub %s,%s,#%d\n",regname[rt],regname[rt],(-imm)&0xFF);
1152       output_w32(0xe2400000|rd_rn_imm_shift(rt,rs,(-imm)>>8,8));
1153       output_w32(0xe2400000|rd_rn_imm_shift(rt,rt,(-imm)&0xff,0));
1154     }else{
1155       assert(imm<65536);
1156       assem_debug("add %s,%s,#%d\n",regname[rt],regname[rs],imm&0xFF00);
1157       assem_debug("add %s,%s,#%d\n",regname[rt],regname[rt],imm&0xFF);
1158       output_w32(0xe2800000|rd_rn_imm_shift(rt,rs,imm>>8,8));
1159       output_w32(0xe2800000|rd_rn_imm_shift(rt,rt,imm&0xff,0));
1160     }
1161   }
1162   else if(rs!=rt) emit_mov(rs,rt);
1163 }
1164
1165 void emit_addimm_and_set_flags(int imm,int rt)
1166 {
1167   assert(imm>-65536&&imm<65536);
1168   u_int armval;
1169   if(genimm(imm,&armval)) {
1170     assem_debug("adds %s,%s,#%d\n",regname[rt],regname[rt],imm);
1171     output_w32(0xe2900000|rd_rn_rm(rt,rt,0)|armval);
1172   }else if(genimm(-imm,&armval)) {
1173     assem_debug("subs %s,%s,#%d\n",regname[rt],regname[rt],imm);
1174     output_w32(0xe2500000|rd_rn_rm(rt,rt,0)|armval);
1175   }else if(imm<0) {
1176     assem_debug("sub %s,%s,#%d\n",regname[rt],regname[rt],(-imm)&0xFF00);
1177     assem_debug("subs %s,%s,#%d\n",regname[rt],regname[rt],(-imm)&0xFF);
1178     output_w32(0xe2400000|rd_rn_imm_shift(rt,rt,(-imm)>>8,8));
1179     output_w32(0xe2500000|rd_rn_imm_shift(rt,rt,(-imm)&0xff,0));
1180   }else{
1181     assem_debug("add %s,%s,#%d\n",regname[rt],regname[rt],imm&0xFF00);
1182     assem_debug("adds %s,%s,#%d\n",regname[rt],regname[rt],imm&0xFF);
1183     output_w32(0xe2800000|rd_rn_imm_shift(rt,rt,imm>>8,8));
1184     output_w32(0xe2900000|rd_rn_imm_shift(rt,rt,imm&0xff,0));
1185   }
1186 }
1187 void emit_addimm_no_flags(u_int imm,u_int rt)
1188 {
1189   emit_addimm(rt,imm,rt);
1190 }
1191
1192 void emit_addnop(u_int r)
1193 {
1194   assert(r<16);
1195   assem_debug("add %s,%s,#0 (nop)\n",regname[r],regname[r]);
1196   output_w32(0xe2800000|rd_rn_rm(r,r,0));
1197 }
1198
1199 void emit_adcimm(u_int rs,int imm,u_int rt)
1200 {
1201   u_int armval;
1202   genimm_checked(imm,&armval);
1203   assem_debug("adc %s,%s,#%d\n",regname[rt],regname[rs],imm);
1204   output_w32(0xe2a00000|rd_rn_rm(rt,rs,0)|armval);
1205 }
1206 /*void emit_sbcimm(int imm,u_int rt)
1207 {
1208   u_int armval;
1209   genimm_checked(imm,&armval);
1210   assem_debug("sbc %s,%s,#%d\n",regname[rt],regname[rt],imm);
1211   output_w32(0xe2c00000|rd_rn_rm(rt,rt,0)|armval);
1212 }*/
1213 void emit_sbbimm(int imm,u_int rt)
1214 {
1215   assem_debug("sbb $%d,%%%s\n",imm,regname[rt]);
1216   assert(rt<8);
1217   if(imm<128&&imm>=-128) {
1218     output_byte(0x83);
1219     output_modrm(3,rt,3);
1220     output_byte(imm);
1221   }
1222   else
1223   {
1224     output_byte(0x81);
1225     output_modrm(3,rt,3);
1226     output_w32(imm);
1227   }
1228 }
1229 void emit_rscimm(int rs,int imm,u_int rt)
1230 {
1231   assert(0);
1232   u_int armval;
1233   genimm_checked(imm,&armval);
1234   assem_debug("rsc %s,%s,#%d\n",regname[rt],regname[rs],imm);
1235   output_w32(0xe2e00000|rd_rn_rm(rt,rs,0)|armval);
1236 }
1237
1238 void emit_addimm64_32(int rsh,int rsl,int imm,int rth,int rtl)
1239 {
1240   // TODO: if(genimm(imm,&armval)) ...
1241   // else
1242   emit_movimm(imm,HOST_TEMPREG);
1243   emit_adds(HOST_TEMPREG,rsl,rtl);
1244   emit_adcimm(rsh,0,rth);
1245 }
1246
1247 void emit_sbb(int rs1,int rs2)
1248 {
1249   assem_debug("sbb %%%s,%%%s\n",regname[rs2],regname[rs1]);
1250   output_byte(0x19);
1251   output_modrm(3,rs1,rs2);
1252 }
1253
1254 void emit_andimm(int rs,int imm,int rt)
1255 {
1256   u_int armval;
1257   if(imm==0) {
1258     emit_zeroreg(rt);
1259   }else if(genimm(imm,&armval)) {
1260     assem_debug("and %s,%s,#%d\n",regname[rt],regname[rs],imm);
1261     output_w32(0xe2000000|rd_rn_rm(rt,rs,0)|armval);
1262   }else if(genimm(~imm,&armval)) {
1263     assem_debug("bic %s,%s,#%d\n",regname[rt],regname[rs],imm);
1264     output_w32(0xe3c00000|rd_rn_rm(rt,rs,0)|armval);
1265   }else if(imm==65535) {
1266     #ifdef ARMv5_ONLY
1267     assem_debug("bic %s,%s,#FF000000\n",regname[rt],regname[rs]);
1268     output_w32(0xe3c00000|rd_rn_rm(rt,rs,0)|0x4FF);
1269     assem_debug("bic %s,%s,#00FF0000\n",regname[rt],regname[rt]);
1270     output_w32(0xe3c00000|rd_rn_rm(rt,rt,0)|0x8FF);
1271     #else
1272     assem_debug("uxth %s,%s\n",regname[rt],regname[rs]);
1273     output_w32(0xe6ff0070|rd_rn_rm(rt,0,rs));
1274     #endif
1275   }else{
1276     assert(imm>0&&imm<65535);
1277     #ifdef ARMv5_ONLY
1278     assem_debug("mov r14,#%d\n",imm&0xFF00);
1279     output_w32(0xe3a00000|rd_rn_imm_shift(HOST_TEMPREG,0,imm>>8,8));
1280     assem_debug("add r14,r14,#%d\n",imm&0xFF);
1281     output_w32(0xe2800000|rd_rn_imm_shift(HOST_TEMPREG,HOST_TEMPREG,imm&0xff,0));
1282     #else
1283     emit_movw(imm,HOST_TEMPREG);
1284     #endif
1285     assem_debug("and %s,%s,r14\n",regname[rt],regname[rs]);
1286     output_w32(0xe0000000|rd_rn_rm(rt,rs,HOST_TEMPREG));
1287   }
1288 }
1289
1290 void emit_orimm(int rs,int imm,int rt)
1291 {
1292   u_int armval;
1293   if(imm==0) {
1294     if(rs!=rt) emit_mov(rs,rt);
1295   }else if(genimm(imm,&armval)) {
1296     assem_debug("orr %s,%s,#%d\n",regname[rt],regname[rs],imm);
1297     output_w32(0xe3800000|rd_rn_rm(rt,rs,0)|armval);
1298   }else{
1299     assert(imm>0&&imm<65536);
1300     assem_debug("orr %s,%s,#%d\n",regname[rt],regname[rs],imm&0xFF00);
1301     assem_debug("orr %s,%s,#%d\n",regname[rt],regname[rs],imm&0xFF);
1302     output_w32(0xe3800000|rd_rn_imm_shift(rt,rs,imm>>8,8));
1303     output_w32(0xe3800000|rd_rn_imm_shift(rt,rt,imm&0xff,0));
1304   }
1305 }
1306
1307 void emit_xorimm(int rs,int imm,int rt)
1308 {
1309   u_int armval;
1310   if(imm==0) {
1311     if(rs!=rt) emit_mov(rs,rt);
1312   }else if(genimm(imm,&armval)) {
1313     assem_debug("eor %s,%s,#%d\n",regname[rt],regname[rs],imm);
1314     output_w32(0xe2200000|rd_rn_rm(rt,rs,0)|armval);
1315   }else{
1316     assert(imm>0&&imm<65536);
1317     assem_debug("eor %s,%s,#%d\n",regname[rt],regname[rs],imm&0xFF00);
1318     assem_debug("eor %s,%s,#%d\n",regname[rt],regname[rs],imm&0xFF);
1319     output_w32(0xe2200000|rd_rn_imm_shift(rt,rs,imm>>8,8));
1320     output_w32(0xe2200000|rd_rn_imm_shift(rt,rt,imm&0xff,0));
1321   }
1322 }
1323
1324 void emit_shlimm(int rs,u_int imm,int rt)
1325 {
1326   assert(imm>0);
1327   assert(imm<32);
1328   //if(imm==1) ...
1329   assem_debug("lsl %s,%s,#%d\n",regname[rt],regname[rs],imm);
1330   output_w32(0xe1a00000|rd_rn_rm(rt,0,rs)|(imm<<7));
1331 }
1332
1333 void emit_lsls_imm(int rs,int imm,int rt)
1334 {
1335   assert(imm>0);
1336   assert(imm<32);
1337   assem_debug("lsls %s,%s,#%d\n",regname[rt],regname[rs],imm);
1338   output_w32(0xe1b00000|rd_rn_rm(rt,0,rs)|(imm<<7));
1339 }
1340
1341 void emit_shrimm(int rs,u_int imm,int rt)
1342 {
1343   assert(imm>0);
1344   assert(imm<32);
1345   assem_debug("lsr %s,%s,#%d\n",regname[rt],regname[rs],imm);
1346   output_w32(0xe1a00000|rd_rn_rm(rt,0,rs)|0x20|(imm<<7));
1347 }
1348
1349 void emit_sarimm(int rs,u_int imm,int rt)
1350 {
1351   assert(imm>0);
1352   assert(imm<32);
1353   assem_debug("asr %s,%s,#%d\n",regname[rt],regname[rs],imm);
1354   output_w32(0xe1a00000|rd_rn_rm(rt,0,rs)|0x40|(imm<<7));
1355 }
1356
1357 void emit_rorimm(int rs,u_int imm,int rt)
1358 {
1359   assert(imm>0);
1360   assert(imm<32);
1361   assem_debug("ror %s,%s,#%d\n",regname[rt],regname[rs],imm);
1362   output_w32(0xe1a00000|rd_rn_rm(rt,0,rs)|0x60|(imm<<7));
1363 }
1364
1365 void emit_shldimm(int rs,int rs2,u_int imm,int rt)
1366 {
1367   assem_debug("shld %%%s,%%%s,%d\n",regname[rt],regname[rs2],imm);
1368   assert(imm>0);
1369   assert(imm<32);
1370   //if(imm==1) ...
1371   assem_debug("lsl %s,%s,#%d\n",regname[rt],regname[rs],imm);
1372   output_w32(0xe1a00000|rd_rn_rm(rt,0,rs)|(imm<<7));
1373   assem_debug("orr %s,%s,%s,lsr #%d\n",regname[rt],regname[rt],regname[rs2],32-imm);
1374   output_w32(0xe1800020|rd_rn_rm(rt,rt,rs2)|((32-imm)<<7));
1375 }
1376
1377 void emit_shrdimm(int rs,int rs2,u_int imm,int rt)
1378 {
1379   assem_debug("shrd %%%s,%%%s,%d\n",regname[rt],regname[rs2],imm);
1380   assert(imm>0);
1381   assert(imm<32);
1382   //if(imm==1) ...
1383   assem_debug("lsr %s,%s,#%d\n",regname[rt],regname[rs],imm);
1384   output_w32(0xe1a00020|rd_rn_rm(rt,0,rs)|(imm<<7));
1385   assem_debug("orr %s,%s,%s,lsl #%d\n",regname[rt],regname[rt],regname[rs2],32-imm);
1386   output_w32(0xe1800000|rd_rn_rm(rt,rt,rs2)|((32-imm)<<7));
1387 }
1388
1389 void emit_signextend16(int rs,int rt)
1390 {
1391   #ifdef ARMv5_ONLY
1392   emit_shlimm(rs,16,rt);
1393   emit_sarimm(rt,16,rt);
1394   #else
1395   assem_debug("sxth %s,%s\n",regname[rt],regname[rs]);
1396   output_w32(0xe6bf0070|rd_rn_rm(rt,0,rs));
1397   #endif
1398 }
1399
1400 void emit_signextend8(int rs,int rt)
1401 {
1402   #ifdef ARMv5_ONLY
1403   emit_shlimm(rs,24,rt);
1404   emit_sarimm(rt,24,rt);
1405   #else
1406   assem_debug("sxtb %s,%s\n",regname[rt],regname[rs]);
1407   output_w32(0xe6af0070|rd_rn_rm(rt,0,rs));
1408   #endif
1409 }
1410
1411 void emit_shl(u_int rs,u_int shift,u_int rt)
1412 {
1413   assert(rs<16);
1414   assert(rt<16);
1415   assert(shift<16);
1416   //if(imm==1) ...
1417   assem_debug("lsl %s,%s,%s\n",regname[rt],regname[rs],regname[shift]);
1418   output_w32(0xe1a00000|rd_rn_rm(rt,0,rs)|0x10|(shift<<8));
1419 }
1420 void emit_shr(u_int rs,u_int shift,u_int rt)
1421 {
1422   assert(rs<16);
1423   assert(rt<16);
1424   assert(shift<16);
1425   assem_debug("lsr %s,%s,%s\n",regname[rt],regname[rs],regname[shift]);
1426   output_w32(0xe1a00000|rd_rn_rm(rt,0,rs)|0x30|(shift<<8));
1427 }
1428 void emit_sar(u_int rs,u_int shift,u_int rt)
1429 {
1430   assert(rs<16);
1431   assert(rt<16);
1432   assert(shift<16);
1433   assem_debug("asr %s,%s,%s\n",regname[rt],regname[rs],regname[shift]);
1434   output_w32(0xe1a00000|rd_rn_rm(rt,0,rs)|0x50|(shift<<8));
1435 }
1436 void emit_shlcl(int r)
1437 {
1438   assem_debug("shl %%%s,%%cl\n",regname[r]);
1439   assert(0);
1440 }
1441 void emit_shrcl(int r)
1442 {
1443   assem_debug("shr %%%s,%%cl\n",regname[r]);
1444   assert(0);
1445 }
1446 void emit_sarcl(int r)
1447 {
1448   assem_debug("sar %%%s,%%cl\n",regname[r]);
1449   assert(0);
1450 }
1451
1452 void emit_shldcl(int r1,int r2)
1453 {
1454   assem_debug("shld %%%s,%%%s,%%cl\n",regname[r1],regname[r2]);
1455   assert(0);
1456 }
1457 void emit_shrdcl(int r1,int r2)
1458 {
1459   assem_debug("shrd %%%s,%%%s,%%cl\n",regname[r1],regname[r2]);
1460   assert(0);
1461 }
1462 void emit_orrshl(u_int rs,u_int shift,u_int rt)
1463 {
1464   assert(rs<16);
1465   assert(rt<16);
1466   assert(shift<16);
1467   assem_debug("orr %s,%s,%s,lsl %s\n",regname[rt],regname[rt],regname[rs],regname[shift]);
1468   output_w32(0xe1800000|rd_rn_rm(rt,rt,rs)|0x10|(shift<<8));
1469 }
1470 void emit_orrshr(u_int rs,u_int shift,u_int rt)
1471 {
1472   assert(rs<16);
1473   assert(rt<16);
1474   assert(shift<16);
1475   assem_debug("orr %s,%s,%s,lsr %s\n",regname[rt],regname[rt],regname[rs],regname[shift]);
1476   output_w32(0xe1800000|rd_rn_rm(rt,rt,rs)|0x30|(shift<<8));
1477 }
1478
1479 void emit_cmpimm(int rs,int imm)
1480 {
1481   u_int armval;
1482   if(genimm(imm,&armval)) {
1483     assem_debug("cmp %s,#%d\n",regname[rs],imm);
1484     output_w32(0xe3500000|rd_rn_rm(0,rs,0)|armval);
1485   }else if(genimm(-imm,&armval)) {
1486     assem_debug("cmn %s,#%d\n",regname[rs],imm);
1487     output_w32(0xe3700000|rd_rn_rm(0,rs,0)|armval);
1488   }else if(imm>0) {
1489     assert(imm<65536);
1490     #ifdef ARMv5_ONLY
1491     emit_movimm(imm,HOST_TEMPREG);
1492     #else
1493     emit_movw(imm,HOST_TEMPREG);
1494     #endif
1495     assem_debug("cmp %s,r14\n",regname[rs]);
1496     output_w32(0xe1500000|rd_rn_rm(0,rs,HOST_TEMPREG));
1497   }else{
1498     assert(imm>-65536);
1499     #ifdef ARMv5_ONLY
1500     emit_movimm(-imm,HOST_TEMPREG);
1501     #else
1502     emit_movw(-imm,HOST_TEMPREG);
1503     #endif
1504     assem_debug("cmn %s,r14\n",regname[rs]);
1505     output_w32(0xe1700000|rd_rn_rm(0,rs,HOST_TEMPREG));
1506   }
1507 }
1508
1509 void emit_cmovne(u_int *addr,int rt)
1510 {
1511   assem_debug("cmovne %x,%%%s",(int)addr,regname[rt]);
1512   assert(0);
1513 }
1514 void emit_cmovl(u_int *addr,int rt)
1515 {
1516   assem_debug("cmovl %x,%%%s",(int)addr,regname[rt]);
1517   assert(0);
1518 }
1519 void emit_cmovs(u_int *addr,int rt)
1520 {
1521   assem_debug("cmovs %x,%%%s",(int)addr,regname[rt]);
1522   assert(0);
1523 }
1524 void emit_cmovne_imm(int imm,int rt)
1525 {
1526   assem_debug("movne %s,#%d\n",regname[rt],imm);
1527   u_int armval;
1528   genimm_checked(imm,&armval);
1529   output_w32(0x13a00000|rd_rn_rm(rt,0,0)|armval);
1530 }
1531 void emit_cmovl_imm(int imm,int rt)
1532 {
1533   assem_debug("movlt %s,#%d\n",regname[rt],imm);
1534   u_int armval;
1535   genimm_checked(imm,&armval);
1536   output_w32(0xb3a00000|rd_rn_rm(rt,0,0)|armval);
1537 }
1538 void emit_cmovb_imm(int imm,int rt)
1539 {
1540   assem_debug("movcc %s,#%d\n",regname[rt],imm);
1541   u_int armval;
1542   genimm_checked(imm,&armval);
1543   output_w32(0x33a00000|rd_rn_rm(rt,0,0)|armval);
1544 }
1545 void emit_cmovs_imm(int imm,int rt)
1546 {
1547   assem_debug("movmi %s,#%d\n",regname[rt],imm);
1548   u_int armval;
1549   genimm_checked(imm,&armval);
1550   output_w32(0x43a00000|rd_rn_rm(rt,0,0)|armval);
1551 }
1552 void emit_cmove_reg(int rs,int rt)
1553 {
1554   assem_debug("moveq %s,%s\n",regname[rt],regname[rs]);
1555   output_w32(0x01a00000|rd_rn_rm(rt,0,rs));
1556 }
1557 void emit_cmovne_reg(int rs,int rt)
1558 {
1559   assem_debug("movne %s,%s\n",regname[rt],regname[rs]);
1560   output_w32(0x11a00000|rd_rn_rm(rt,0,rs));
1561 }
1562 void emit_cmovl_reg(int rs,int rt)
1563 {
1564   assem_debug("movlt %s,%s\n",regname[rt],regname[rs]);
1565   output_w32(0xb1a00000|rd_rn_rm(rt,0,rs));
1566 }
1567 void emit_cmovs_reg(int rs,int rt)
1568 {
1569   assem_debug("movmi %s,%s\n",regname[rt],regname[rs]);
1570   output_w32(0x41a00000|rd_rn_rm(rt,0,rs));
1571 }
1572
1573 void emit_slti32(int rs,int imm,int rt)
1574 {
1575   if(rs!=rt) emit_zeroreg(rt);
1576   emit_cmpimm(rs,imm);
1577   if(rs==rt) emit_movimm(0,rt);
1578   emit_cmovl_imm(1,rt);
1579 }
1580 void emit_sltiu32(int rs,int imm,int rt)
1581 {
1582   if(rs!=rt) emit_zeroreg(rt);
1583   emit_cmpimm(rs,imm);
1584   if(rs==rt) emit_movimm(0,rt);
1585   emit_cmovb_imm(1,rt);
1586 }
1587 void emit_slti64_32(int rsh,int rsl,int imm,int rt)
1588 {
1589   assert(rsh!=rt);
1590   emit_slti32(rsl,imm,rt);
1591   if(imm>=0)
1592   {
1593     emit_test(rsh,rsh);
1594     emit_cmovne_imm(0,rt);
1595     emit_cmovs_imm(1,rt);
1596   }
1597   else
1598   {
1599     emit_cmpimm(rsh,-1);
1600     emit_cmovne_imm(0,rt);
1601     emit_cmovl_imm(1,rt);
1602   }
1603 }
1604 void emit_sltiu64_32(int rsh,int rsl,int imm,int rt)
1605 {
1606   assert(rsh!=rt);
1607   emit_sltiu32(rsl,imm,rt);
1608   if(imm>=0)
1609   {
1610     emit_test(rsh,rsh);
1611     emit_cmovne_imm(0,rt);
1612   }
1613   else
1614   {
1615     emit_cmpimm(rsh,-1);
1616     emit_cmovne_imm(1,rt);
1617   }
1618 }
1619
1620 void emit_cmp(int rs,int rt)
1621 {
1622   assem_debug("cmp %s,%s\n",regname[rs],regname[rt]);
1623   output_w32(0xe1500000|rd_rn_rm(0,rs,rt));
1624 }
1625 void emit_set_gz32(int rs, int rt)
1626 {
1627   //assem_debug("set_gz32\n");
1628   emit_cmpimm(rs,1);
1629   emit_movimm(1,rt);
1630   emit_cmovl_imm(0,rt);
1631 }
1632 void emit_set_nz32(int rs, int rt)
1633 {
1634   //assem_debug("set_nz32\n");
1635   if(rs!=rt) emit_movs(rs,rt);
1636   else emit_test(rs,rs);
1637   emit_cmovne_imm(1,rt);
1638 }
1639 void emit_set_gz64_32(int rsh, int rsl, int rt)
1640 {
1641   //assem_debug("set_gz64\n");
1642   emit_set_gz32(rsl,rt);
1643   emit_test(rsh,rsh);
1644   emit_cmovne_imm(1,rt);
1645   emit_cmovs_imm(0,rt);
1646 }
1647 void emit_set_nz64_32(int rsh, int rsl, int rt)
1648 {
1649   //assem_debug("set_nz64\n");
1650   emit_or_and_set_flags(rsh,rsl,rt);
1651   emit_cmovne_imm(1,rt);
1652 }
1653 void emit_set_if_less32(int rs1, int rs2, int rt)
1654 {
1655   //assem_debug("set if less (%%%s,%%%s),%%%s\n",regname[rs1],regname[rs2],regname[rt]);
1656   if(rs1!=rt&&rs2!=rt) emit_zeroreg(rt);
1657   emit_cmp(rs1,rs2);
1658   if(rs1==rt||rs2==rt) emit_movimm(0,rt);
1659   emit_cmovl_imm(1,rt);
1660 }
1661 void emit_set_if_carry32(int rs1, int rs2, int rt)
1662 {
1663   //assem_debug("set if carry (%%%s,%%%s),%%%s\n",regname[rs1],regname[rs2],regname[rt]);
1664   if(rs1!=rt&&rs2!=rt) emit_zeroreg(rt);
1665   emit_cmp(rs1,rs2);
1666   if(rs1==rt||rs2==rt) emit_movimm(0,rt);
1667   emit_cmovb_imm(1,rt);
1668 }
1669 void emit_set_if_less64_32(int u1, int l1, int u2, int l2, int rt)
1670 {
1671   //assem_debug("set if less64 (%%%s,%%%s,%%%s,%%%s),%%%s\n",regname[u1],regname[l1],regname[u2],regname[l2],regname[rt]);
1672   assert(u1!=rt);
1673   assert(u2!=rt);
1674   emit_cmp(l1,l2);
1675   emit_movimm(0,rt);
1676   emit_sbcs(u1,u2,HOST_TEMPREG);
1677   emit_cmovl_imm(1,rt);
1678 }
1679 void emit_set_if_carry64_32(int u1, int l1, int u2, int l2, int rt)
1680 {
1681   //assem_debug("set if carry64 (%%%s,%%%s,%%%s,%%%s),%%%s\n",regname[u1],regname[l1],regname[u2],regname[l2],regname[rt]);
1682   assert(u1!=rt);
1683   assert(u2!=rt);
1684   emit_cmp(l1,l2);
1685   emit_movimm(0,rt);
1686   emit_sbcs(u1,u2,HOST_TEMPREG);
1687   emit_cmovb_imm(1,rt);
1688 }
1689
1690 void emit_call(int a)
1691 {
1692   assem_debug("bl %x (%x+%x)\n",a,(int)out,a-(int)out-8);
1693   u_int offset=genjmp(a);
1694   output_w32(0xeb000000|offset);
1695 }
1696 void emit_jmp(int a)
1697 {
1698   assem_debug("b %x (%x+%x)\n",a,(int)out,a-(int)out-8);
1699   u_int offset=genjmp(a);
1700   output_w32(0xea000000|offset);
1701 }
1702 void emit_jne(int a)
1703 {
1704   assem_debug("bne %x\n",a);
1705   u_int offset=genjmp(a);
1706   output_w32(0x1a000000|offset);
1707 }
1708 void emit_jeq(int a)
1709 {
1710   assem_debug("beq %x\n",a);
1711   u_int offset=genjmp(a);
1712   output_w32(0x0a000000|offset);
1713 }
1714 void emit_js(int a)
1715 {
1716   assem_debug("bmi %x\n",a);
1717   u_int offset=genjmp(a);
1718   output_w32(0x4a000000|offset);
1719 }
1720 void emit_jns(int a)
1721 {
1722   assem_debug("bpl %x\n",a);
1723   u_int offset=genjmp(a);
1724   output_w32(0x5a000000|offset);
1725 }
1726 void emit_jl(int a)
1727 {
1728   assem_debug("blt %x\n",a);
1729   u_int offset=genjmp(a);
1730   output_w32(0xba000000|offset);
1731 }
1732 void emit_jge(int a)
1733 {
1734   assem_debug("bge %x\n",a);
1735   u_int offset=genjmp(a);
1736   output_w32(0xaa000000|offset);
1737 }
1738 void emit_jno(int a)
1739 {
1740   assem_debug("bvc %x\n",a);
1741   u_int offset=genjmp(a);
1742   output_w32(0x7a000000|offset);
1743 }
1744 void emit_jc(int a)
1745 {
1746   assem_debug("bcs %x\n",a);
1747   u_int offset=genjmp(a);
1748   output_w32(0x2a000000|offset);
1749 }
1750 void emit_jcc(int a)
1751 {
1752   assem_debug("bcc %x\n",a);
1753   u_int offset=genjmp(a);
1754   output_w32(0x3a000000|offset);
1755 }
1756
1757 void emit_pushimm(int imm)
1758 {
1759   assem_debug("push $%x\n",imm);
1760   assert(0);
1761 }
1762 void emit_pusha()
1763 {
1764   assem_debug("pusha\n");
1765   assert(0);
1766 }
1767 void emit_popa()
1768 {
1769   assem_debug("popa\n");
1770   assert(0);
1771 }
1772 void emit_pushreg(u_int r)
1773 {
1774   assem_debug("push %%%s\n",regname[r]);
1775   assert(0);
1776 }
1777 void emit_popreg(u_int r)
1778 {
1779   assem_debug("pop %%%s\n",regname[r]);
1780   assert(0);
1781 }
1782 void emit_callreg(u_int r)
1783 {
1784   assert(r<15);
1785   assem_debug("blx %s\n",regname[r]);
1786   output_w32(0xe12fff30|r);
1787 }
1788 void emit_jmpreg(u_int r)
1789 {
1790   assem_debug("mov pc,%s\n",regname[r]);
1791   output_w32(0xe1a00000|rd_rn_rm(15,0,r));
1792 }
1793
1794 void emit_readword_indexed(int offset, int rs, int rt)
1795 {
1796   assert(offset>-4096&&offset<4096);
1797   assem_debug("ldr %s,%s+%d\n",regname[rt],regname[rs],offset);
1798   if(offset>=0) {
1799     output_w32(0xe5900000|rd_rn_rm(rt,rs,0)|offset);
1800   }else{
1801     output_w32(0xe5100000|rd_rn_rm(rt,rs,0)|(-offset));
1802   }
1803 }
1804 void emit_readword_dualindexedx4(int rs1, int rs2, int rt)
1805 {
1806   assem_debug("ldr %s,%s,%s lsl #2\n",regname[rt],regname[rs1],regname[rs2]);
1807   output_w32(0xe7900000|rd_rn_rm(rt,rs1,rs2)|0x100);
1808 }
1809 void emit_ldrcc_dualindexed(int rs1, int rs2, int rt)
1810 {
1811   assem_debug("ldrcc %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
1812   output_w32(0x37900000|rd_rn_rm(rt,rs1,rs2));
1813 }
1814 void emit_ldrccb_dualindexed(int rs1, int rs2, int rt)
1815 {
1816   assem_debug("ldrccb %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
1817   output_w32(0x37d00000|rd_rn_rm(rt,rs1,rs2));
1818 }
1819 void emit_ldrccsb_dualindexed(int rs1, int rs2, int rt)
1820 {
1821   assem_debug("ldrccsb %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
1822   output_w32(0x319000d0|rd_rn_rm(rt,rs1,rs2));
1823 }
1824 void emit_ldrcch_dualindexed(int rs1, int rs2, int rt)
1825 {
1826   assem_debug("ldrcch %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
1827   output_w32(0x319000b0|rd_rn_rm(rt,rs1,rs2));
1828 }
1829 void emit_ldrccsh_dualindexed(int rs1, int rs2, int rt)
1830 {
1831   assem_debug("ldrccsh %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
1832   output_w32(0x319000f0|rd_rn_rm(rt,rs1,rs2));
1833 }
1834 void emit_readword_indexed_tlb(int addr, int rs, int map, int rt)
1835 {
1836   if(map<0) emit_readword_indexed(addr, rs, rt);
1837   else {
1838     assert(addr==0);
1839     emit_readword_dualindexedx4(rs, map, rt);
1840   }
1841 }
1842 void emit_readdword_indexed_tlb(int addr, int rs, int map, int rh, int rl)
1843 {
1844   if(map<0) {
1845     if(rh>=0) emit_readword_indexed(addr, rs, rh);
1846     emit_readword_indexed(addr+4, rs, rl);
1847   }else{
1848     assert(rh!=rs);
1849     if(rh>=0) emit_readword_indexed_tlb(addr, rs, map, rh);
1850     emit_addimm(map,1,map);
1851     emit_readword_indexed_tlb(addr, rs, map, rl);
1852   }
1853 }
1854 void emit_movsbl_indexed(int offset, int rs, int rt)
1855 {
1856   assert(offset>-256&&offset<256);
1857   assem_debug("ldrsb %s,%s+%d\n",regname[rt],regname[rs],offset);
1858   if(offset>=0) {
1859     output_w32(0xe1d000d0|rd_rn_rm(rt,rs,0)|((offset<<4)&0xf00)|(offset&0xf));
1860   }else{
1861     output_w32(0xe15000d0|rd_rn_rm(rt,rs,0)|(((-offset)<<4)&0xf00)|((-offset)&0xf));
1862   }
1863 }
1864 void emit_movsbl_indexed_tlb(int addr, int rs, int map, int rt)
1865 {
1866   if(map<0) emit_movsbl_indexed(addr, rs, rt);
1867   else {
1868     if(addr==0) {
1869       emit_shlimm(map,2,map);
1870       assem_debug("ldrsb %s,%s+%s\n",regname[rt],regname[rs],regname[map]);
1871       output_w32(0xe19000d0|rd_rn_rm(rt,rs,map));
1872     }else{
1873       assert(addr>-256&&addr<256);
1874       assem_debug("add %s,%s,%s,lsl #2\n",regname[rt],regname[rs],regname[map]);
1875       output_w32(0xe0800000|rd_rn_rm(rt,rs,map)|(2<<7));
1876       emit_movsbl_indexed(addr, rt, rt);
1877     }
1878   }
1879 }
1880 void emit_movswl_indexed(int offset, int rs, int rt)
1881 {
1882   assert(offset>-256&&offset<256);
1883   assem_debug("ldrsh %s,%s+%d\n",regname[rt],regname[rs],offset);
1884   if(offset>=0) {
1885     output_w32(0xe1d000f0|rd_rn_rm(rt,rs,0)|((offset<<4)&0xf00)|(offset&0xf));
1886   }else{
1887     output_w32(0xe15000f0|rd_rn_rm(rt,rs,0)|(((-offset)<<4)&0xf00)|((-offset)&0xf));
1888   }
1889 }
1890 void emit_movzbl_indexed(int offset, int rs, int rt)
1891 {
1892   assert(offset>-4096&&offset<4096);
1893   assem_debug("ldrb %s,%s+%d\n",regname[rt],regname[rs],offset);
1894   if(offset>=0) {
1895     output_w32(0xe5d00000|rd_rn_rm(rt,rs,0)|offset);
1896   }else{
1897     output_w32(0xe5500000|rd_rn_rm(rt,rs,0)|(-offset));
1898   }
1899 }
1900 void emit_movzbl_dualindexedx4(int rs1, int rs2, int rt)
1901 {
1902   assem_debug("ldrb %s,%s,%s lsl #2\n",regname[rt],regname[rs1],regname[rs2]);
1903   output_w32(0xe7d00000|rd_rn_rm(rt,rs1,rs2)|0x100);
1904 }
1905 void emit_movzbl_indexed_tlb(int addr, int rs, int map, int rt)
1906 {
1907   if(map<0) emit_movzbl_indexed(addr, rs, rt);
1908   else {
1909     if(addr==0) {
1910       emit_movzbl_dualindexedx4(rs, map, rt);
1911     }else{
1912       emit_addimm(rs,addr,rt);
1913       emit_movzbl_dualindexedx4(rt, map, rt);
1914     }
1915   }
1916 }
1917 void emit_movzwl_indexed(int offset, int rs, int rt)
1918 {
1919   assert(offset>-256&&offset<256);
1920   assem_debug("ldrh %s,%s+%d\n",regname[rt],regname[rs],offset);
1921   if(offset>=0) {
1922     output_w32(0xe1d000b0|rd_rn_rm(rt,rs,0)|((offset<<4)&0xf00)|(offset&0xf));
1923   }else{
1924     output_w32(0xe15000b0|rd_rn_rm(rt,rs,0)|(((-offset)<<4)&0xf00)|((-offset)&0xf));
1925   }
1926 }
1927 void emit_readword(int addr, int rt)
1928 {
1929   u_int offset = addr-(u_int)&dynarec_local;
1930   assert(offset<4096);
1931   assem_debug("ldr %s,fp+%d\n",regname[rt],offset);
1932   output_w32(0xe5900000|rd_rn_rm(rt,FP,0)|offset);
1933 }
1934 void emit_movsbl(int addr, int rt)
1935 {
1936   u_int offset = addr-(u_int)&dynarec_local;
1937   assert(offset<256);
1938   assem_debug("ldrsb %s,fp+%d\n",regname[rt],offset);
1939   output_w32(0xe1d000d0|rd_rn_rm(rt,FP,0)|((offset<<4)&0xf00)|(offset&0xf));
1940 }
1941 void emit_movswl(int addr, int rt)
1942 {
1943   u_int offset = addr-(u_int)&dynarec_local;
1944   assert(offset<256);
1945   assem_debug("ldrsh %s,fp+%d\n",regname[rt],offset);
1946   output_w32(0xe1d000f0|rd_rn_rm(rt,FP,0)|((offset<<4)&0xf00)|(offset&0xf));
1947 }
1948 void emit_movzbl(int addr, int rt)
1949 {
1950   u_int offset = addr-(u_int)&dynarec_local;
1951   assert(offset<4096);
1952   assem_debug("ldrb %s,fp+%d\n",regname[rt],offset);
1953   output_w32(0xe5d00000|rd_rn_rm(rt,FP,0)|offset);
1954 }
1955 void emit_movzwl(int addr, int rt)
1956 {
1957   u_int offset = addr-(u_int)&dynarec_local;
1958   assert(offset<256);
1959   assem_debug("ldrh %s,fp+%d\n",regname[rt],offset);
1960   output_w32(0xe1d000b0|rd_rn_rm(rt,FP,0)|((offset<<4)&0xf00)|(offset&0xf));
1961 }
1962 void emit_movzwl_reg(int rs, int rt)
1963 {
1964   assem_debug("movzwl %%%s,%%%s\n",regname[rs]+1,regname[rt]);
1965   assert(0);
1966 }
1967
1968 void emit_xchg(int rs, int rt)
1969 {
1970   assem_debug("xchg %%%s,%%%s\n",regname[rs],regname[rt]);
1971   assert(0);
1972 }
1973 void emit_writeword_indexed(int rt, int offset, int rs)
1974 {
1975   assert(offset>-4096&&offset<4096);
1976   assem_debug("str %s,%s+%d\n",regname[rt],regname[rs],offset);
1977   if(offset>=0) {
1978     output_w32(0xe5800000|rd_rn_rm(rt,rs,0)|offset);
1979   }else{
1980     output_w32(0xe5000000|rd_rn_rm(rt,rs,0)|(-offset));
1981   }
1982 }
1983 void emit_writeword_dualindexedx4(int rt, int rs1, int rs2)
1984 {
1985   assem_debug("str %s,%s,%s lsl #2\n",regname[rt],regname[rs1],regname[rs2]);
1986   output_w32(0xe7800000|rd_rn_rm(rt,rs1,rs2)|0x100);
1987 }
1988 void emit_writeword_indexed_tlb(int rt, int addr, int rs, int map, int temp)
1989 {
1990   if(map<0) emit_writeword_indexed(rt, addr, rs);
1991   else {
1992     assert(addr==0);
1993     emit_writeword_dualindexedx4(rt, rs, map);
1994   }
1995 }
1996 void emit_writedword_indexed_tlb(int rh, int rl, int addr, int rs, int map, int temp)
1997 {
1998   if(map<0) {
1999     if(rh>=0) emit_writeword_indexed(rh, addr, rs);
2000     emit_writeword_indexed(rl, addr+4, rs);
2001   }else{
2002     assert(rh>=0);
2003     if(temp!=rs) emit_addimm(map,1,temp);
2004     emit_writeword_indexed_tlb(rh, addr, rs, map, temp);
2005     if(temp!=rs) emit_writeword_indexed_tlb(rl, addr, rs, temp, temp);
2006     else {
2007       emit_addimm(rs,4,rs);
2008       emit_writeword_indexed_tlb(rl, addr, rs, map, temp);
2009     }
2010   }
2011 }
2012 void emit_writehword_indexed(int rt, int offset, int rs)
2013 {
2014   assert(offset>-256&&offset<256);
2015   assem_debug("strh %s,%s+%d\n",regname[rt],regname[rs],offset);
2016   if(offset>=0) {
2017     output_w32(0xe1c000b0|rd_rn_rm(rt,rs,0)|((offset<<4)&0xf00)|(offset&0xf));
2018   }else{
2019     output_w32(0xe14000b0|rd_rn_rm(rt,rs,0)|(((-offset)<<4)&0xf00)|((-offset)&0xf));
2020   }
2021 }
2022 void emit_writebyte_indexed(int rt, int offset, int rs)
2023 {
2024   assert(offset>-4096&&offset<4096);
2025   assem_debug("strb %s,%s+%d\n",regname[rt],regname[rs],offset);
2026   if(offset>=0) {
2027     output_w32(0xe5c00000|rd_rn_rm(rt,rs,0)|offset);
2028   }else{
2029     output_w32(0xe5400000|rd_rn_rm(rt,rs,0)|(-offset));
2030   }
2031 }
2032 void emit_writebyte_dualindexedx4(int rt, int rs1, int rs2)
2033 {
2034   assem_debug("strb %s,%s,%s lsl #2\n",regname[rt],regname[rs1],regname[rs2]);
2035   output_w32(0xe7c00000|rd_rn_rm(rt,rs1,rs2)|0x100);
2036 }
2037 void emit_writebyte_indexed_tlb(int rt, int addr, int rs, int map, int temp)
2038 {
2039   if(map<0) emit_writebyte_indexed(rt, addr, rs);
2040   else {
2041     if(addr==0) {
2042       emit_writebyte_dualindexedx4(rt, rs, map);
2043     }else{
2044       emit_addimm(rs,addr,temp);
2045       emit_writebyte_dualindexedx4(rt, temp, map);
2046     }
2047   }
2048 }
2049 void emit_strcc_dualindexed(int rs1, int rs2, int rt)
2050 {
2051   assem_debug("strcc %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
2052   output_w32(0x37800000|rd_rn_rm(rt,rs1,rs2));
2053 }
2054 void emit_strccb_dualindexed(int rs1, int rs2, int rt)
2055 {
2056   assem_debug("strccb %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
2057   output_w32(0x37c00000|rd_rn_rm(rt,rs1,rs2));
2058 }
2059 void emit_strcch_dualindexed(int rs1, int rs2, int rt)
2060 {
2061   assem_debug("strcch %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
2062   output_w32(0x318000b0|rd_rn_rm(rt,rs1,rs2));
2063 }
2064 void emit_writeword(int rt, int addr)
2065 {
2066   u_int offset = addr-(u_int)&dynarec_local;
2067   assert(offset<4096);
2068   assem_debug("str %s,fp+%d\n",regname[rt],offset);
2069   output_w32(0xe5800000|rd_rn_rm(rt,FP,0)|offset);
2070 }
2071 void emit_writehword(int rt, int addr)
2072 {
2073   u_int offset = addr-(u_int)&dynarec_local;
2074   assert(offset<256);
2075   assem_debug("strh %s,fp+%d\n",regname[rt],offset);
2076   output_w32(0xe1c000b0|rd_rn_rm(rt,FP,0)|((offset<<4)&0xf00)|(offset&0xf));
2077 }
2078 void emit_writebyte(int rt, int addr)
2079 {
2080   u_int offset = addr-(u_int)&dynarec_local;
2081   assert(offset<4096);
2082   assem_debug("strb %s,fp+%d\n",regname[rt],offset);
2083   output_w32(0xe5c00000|rd_rn_rm(rt,FP,0)|offset);
2084 }
2085 void emit_writeword_imm(int imm, int addr)
2086 {
2087   assem_debug("movl $%x,%x\n",imm,addr);
2088   assert(0);
2089 }
2090 void emit_writebyte_imm(int imm, int addr)
2091 {
2092   assem_debug("movb $%x,%x\n",imm,addr);
2093   assert(0);
2094 }
2095
2096 void emit_mul(int rs)
2097 {
2098   assem_debug("mul %%%s\n",regname[rs]);
2099   assert(0);
2100 }
2101 void emit_imul(int rs)
2102 {
2103   assem_debug("imul %%%s\n",regname[rs]);
2104   assert(0);
2105 }
2106 void emit_umull(u_int rs1, u_int rs2, u_int hi, u_int lo)
2107 {
2108   assem_debug("umull %s, %s, %s, %s\n",regname[lo],regname[hi],regname[rs1],regname[rs2]);
2109   assert(rs1<16);
2110   assert(rs2<16);
2111   assert(hi<16);
2112   assert(lo<16);
2113   output_w32(0xe0800090|(hi<<16)|(lo<<12)|(rs2<<8)|rs1);
2114 }
2115 void emit_smull(u_int rs1, u_int rs2, u_int hi, u_int lo)
2116 {
2117   assem_debug("smull %s, %s, %s, %s\n",regname[lo],regname[hi],regname[rs1],regname[rs2]);
2118   assert(rs1<16);
2119   assert(rs2<16);
2120   assert(hi<16);
2121   assert(lo<16);
2122   output_w32(0xe0c00090|(hi<<16)|(lo<<12)|(rs2<<8)|rs1);
2123 }
2124
2125 void emit_div(int rs)
2126 {
2127   assem_debug("div %%%s\n",regname[rs]);
2128   assert(0);
2129 }
2130 void emit_idiv(int rs)
2131 {
2132   assem_debug("idiv %%%s\n",regname[rs]);
2133   assert(0);
2134 }
2135 void emit_cdq()
2136 {
2137   assem_debug("cdq\n");
2138   assert(0);
2139 }
2140
2141 void emit_clz(int rs,int rt)
2142 {
2143   assem_debug("clz %s,%s\n",regname[rt],regname[rs]);
2144   output_w32(0xe16f0f10|rd_rn_rm(rt,0,rs));
2145 }
2146
2147 void emit_subcs(int rs1,int rs2,int rt)
2148 {
2149   assem_debug("subcs %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
2150   output_w32(0x20400000|rd_rn_rm(rt,rs1,rs2));
2151 }
2152
2153 void emit_shrcc_imm(int rs,u_int imm,int rt)
2154 {
2155   assert(imm>0);
2156   assert(imm<32);
2157   assem_debug("lsrcc %s,%s,#%d\n",regname[rt],regname[rs],imm);
2158   output_w32(0x31a00000|rd_rn_rm(rt,0,rs)|0x20|(imm<<7));
2159 }
2160
2161 void emit_shrne_imm(int rs,u_int imm,int rt)
2162 {
2163   assert(imm>0);
2164   assert(imm<32);
2165   assem_debug("lsrne %s,%s,#%d\n",regname[rt],regname[rs],imm);
2166   output_w32(0x11a00000|rd_rn_rm(rt,0,rs)|0x20|(imm<<7));
2167 }
2168
2169 void emit_negmi(int rs, int rt)
2170 {
2171   assem_debug("rsbmi %s,%s,#0\n",regname[rt],regname[rs]);
2172   output_w32(0x42600000|rd_rn_rm(rt,rs,0));
2173 }
2174
2175 void emit_negsmi(int rs, int rt)
2176 {
2177   assem_debug("rsbsmi %s,%s,#0\n",regname[rt],regname[rs]);
2178   output_w32(0x42700000|rd_rn_rm(rt,rs,0));
2179 }
2180
2181 void emit_orreq(u_int rs1,u_int rs2,u_int rt)
2182 {
2183   assem_debug("orreq %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
2184   output_w32(0x01800000|rd_rn_rm(rt,rs1,rs2));
2185 }
2186
2187 void emit_orrne(u_int rs1,u_int rs2,u_int rt)
2188 {
2189   assem_debug("orrne %s,%s,%s\n",regname[rt],regname[rs1],regname[rs2]);
2190   output_w32(0x11800000|rd_rn_rm(rt,rs1,rs2));
2191 }
2192
2193 void emit_bic_lsl(u_int rs1,u_int rs2,u_int shift,u_int rt)
2194 {
2195   assem_debug("bic %s,%s,%s lsl %s\n",regname[rt],regname[rs1],regname[rs2],regname[shift]);
2196   output_w32(0xe1C00000|rd_rn_rm(rt,rs1,rs2)|0x10|(shift<<8));
2197 }
2198
2199 void emit_biceq_lsl(u_int rs1,u_int rs2,u_int shift,u_int rt)
2200 {
2201   assem_debug("biceq %s,%s,%s lsl %s\n",regname[rt],regname[rs1],regname[rs2],regname[shift]);
2202   output_w32(0x01C00000|rd_rn_rm(rt,rs1,rs2)|0x10|(shift<<8));
2203 }
2204
2205 void emit_bicne_lsl(u_int rs1,u_int rs2,u_int shift,u_int rt)
2206 {
2207   assem_debug("bicne %s,%s,%s lsl %s\n",regname[rt],regname[rs1],regname[rs2],regname[shift]);
2208   output_w32(0x11C00000|rd_rn_rm(rt,rs1,rs2)|0x10|(shift<<8));
2209 }
2210
2211 void emit_bic_lsr(u_int rs1,u_int rs2,u_int shift,u_int rt)
2212 {
2213   assem_debug("bic %s,%s,%s lsr %s\n",regname[rt],regname[rs1],regname[rs2],regname[shift]);
2214   output_w32(0xe1C00000|rd_rn_rm(rt,rs1,rs2)|0x30|(shift<<8));
2215 }
2216
2217 void emit_biceq_lsr(u_int rs1,u_int rs2,u_int shift,u_int rt)
2218 {
2219   assem_debug("biceq %s,%s,%s lsr %s\n",regname[rt],regname[rs1],regname[rs2],regname[shift]);
2220   output_w32(0x01C00000|rd_rn_rm(rt,rs1,rs2)|0x30|(shift<<8));
2221 }
2222
2223 void emit_bicne_lsr(u_int rs1,u_int rs2,u_int shift,u_int rt)
2224 {
2225   assem_debug("bicne %s,%s,%s lsr %s\n",regname[rt],regname[rs1],regname[rs2],regname[shift]);
2226   output_w32(0x11C00000|rd_rn_rm(rt,rs1,rs2)|0x30|(shift<<8));
2227 }
2228
2229 void emit_teq(int rs, int rt)
2230 {
2231   assem_debug("teq %s,%s\n",regname[rs],regname[rt]);
2232   output_w32(0xe1300000|rd_rn_rm(0,rs,rt));
2233 }
2234
2235 void emit_rsbimm(int rs, int imm, int rt)
2236 {
2237   u_int armval;
2238   genimm_checked(imm,&armval);
2239   assem_debug("rsb %s,%s,#%d\n",regname[rt],regname[rs],imm);
2240   output_w32(0xe2600000|rd_rn_rm(rt,rs,0)|armval);
2241 }
2242
2243 // Load 2 immediates optimizing for small code size
2244 void emit_mov2imm_compact(int imm1,u_int rt1,int imm2,u_int rt2)
2245 {
2246   emit_movimm(imm1,rt1);
2247   u_int armval;
2248   if(genimm(imm2-imm1,&armval)) {
2249     assem_debug("add %s,%s,#%d\n",regname[rt2],regname[rt1],imm2-imm1);
2250     output_w32(0xe2800000|rd_rn_rm(rt2,rt1,0)|armval);
2251   }else if(genimm(imm1-imm2,&armval)) {
2252     assem_debug("sub %s,%s,#%d\n",regname[rt2],regname[rt1],imm1-imm2);
2253     output_w32(0xe2400000|rd_rn_rm(rt2,rt1,0)|armval);
2254   }
2255   else emit_movimm(imm2,rt2);
2256 }
2257
2258 // Conditionally select one of two immediates, optimizing for small code size
2259 // This will only be called if HAVE_CMOV_IMM is defined
2260 void emit_cmov2imm_e_ne_compact(int imm1,int imm2,u_int rt)
2261 {
2262   u_int armval;
2263   if(genimm(imm2-imm1,&armval)) {
2264     emit_movimm(imm1,rt);
2265     assem_debug("addne %s,%s,#%d\n",regname[rt],regname[rt],imm2-imm1);
2266     output_w32(0x12800000|rd_rn_rm(rt,rt,0)|armval);
2267   }else if(genimm(imm1-imm2,&armval)) {
2268     emit_movimm(imm1,rt);
2269     assem_debug("subne %s,%s,#%d\n",regname[rt],regname[rt],imm1-imm2);
2270     output_w32(0x12400000|rd_rn_rm(rt,rt,0)|armval);
2271   }
2272   else {
2273     #ifdef ARMv5_ONLY
2274     emit_movimm(imm1,rt);
2275     add_literal((int)out,imm2);
2276     assem_debug("ldrne %s,pc+? [=%x]\n",regname[rt],imm2);
2277     output_w32(0x15900000|rd_rn_rm(rt,15,0));
2278     #else
2279     emit_movw(imm1&0x0000FFFF,rt);
2280     if((imm1&0xFFFF)!=(imm2&0xFFFF)) {
2281       assem_debug("movwne %s,#%d (0x%x)\n",regname[rt],imm2&0xFFFF,imm2&0xFFFF);
2282       output_w32(0x13000000|rd_rn_rm(rt,0,0)|(imm2&0xfff)|((imm2<<4)&0xf0000));
2283     }
2284     emit_movt(imm1&0xFFFF0000,rt);
2285     if((imm1&0xFFFF0000)!=(imm2&0xFFFF0000)) {
2286       assem_debug("movtne %s,#%d (0x%x)\n",regname[rt],imm2&0xffff0000,imm2&0xffff0000);
2287       output_w32(0x13400000|rd_rn_rm(rt,0,0)|((imm2>>16)&0xfff)|((imm2>>12)&0xf0000));
2288     }
2289     #endif
2290   }
2291 }
2292
2293 // special case for checking invalid_code
2294 void emit_cmpmem_indexedsr12_imm(int addr,int r,int imm)
2295 {
2296   assert(0);
2297 }
2298
2299 // special case for checking invalid_code
2300 void emit_cmpmem_indexedsr12_reg(int base,int r,int imm)
2301 {
2302   assert(imm<128&&imm>=0);
2303   assert(r>=0&&r<16);
2304   assem_debug("ldrb lr,%s,%s lsr #12\n",regname[base],regname[r]);
2305   output_w32(0xe7d00000|rd_rn_rm(HOST_TEMPREG,base,r)|0x620);
2306   emit_cmpimm(HOST_TEMPREG,imm);
2307 }
2308
2309 // special case for tlb mapping
2310 void emit_addsr12(int rs1,int rs2,int rt)
2311 {
2312   assem_debug("add %s,%s,%s lsr #12\n",regname[rt],regname[rs1],regname[rs2]);
2313   output_w32(0xe0800620|rd_rn_rm(rt,rs1,rs2));
2314 }
2315
2316 void emit_callne(int a)
2317 {
2318   assem_debug("blne %x\n",a);
2319   u_int offset=genjmp(a);
2320   output_w32(0x1b000000|offset);
2321 }
2322
2323 // Used to preload hash table entries
2324 void emit_prefetch(void *addr)
2325 {
2326   assem_debug("prefetch %x\n",(int)addr);
2327   output_byte(0x0F);
2328   output_byte(0x18);
2329   output_modrm(0,5,1);
2330   output_w32((int)addr);
2331 }
2332 void emit_prefetchreg(int r)
2333 {
2334   assem_debug("pld %s\n",regname[r]);
2335   output_w32(0xf5d0f000|rd_rn_rm(0,r,0));
2336 }
2337
2338 // Special case for mini_ht
2339 void emit_ldreq_indexed(int rs, u_int offset, int rt)
2340 {
2341   assert(offset<4096);
2342   assem_debug("ldreq %s,[%s, #%d]\n",regname[rt],regname[rs],offset);
2343   output_w32(0x05900000|rd_rn_rm(rt,rs,0)|offset);
2344 }
2345
2346 void emit_flds(int r,int sr)
2347 {
2348   assem_debug("flds s%d,[%s]\n",sr,regname[r]);
2349   output_w32(0xed900a00|((sr&14)<<11)|((sr&1)<<22)|(r<<16));
2350
2351
2352 void emit_vldr(int r,int vr)
2353 {
2354   assem_debug("vldr d%d,[%s]\n",vr,regname[r]);
2355   output_w32(0xed900b00|(vr<<12)|(r<<16));
2356
2357
2358 void emit_fsts(int sr,int r)
2359 {
2360   assem_debug("fsts s%d,[%s]\n",sr,regname[r]);
2361   output_w32(0xed800a00|((sr&14)<<11)|((sr&1)<<22)|(r<<16));
2362
2363
2364 void emit_vstr(int vr,int r)
2365 {
2366   assem_debug("vstr d%d,[%s]\n",vr,regname[r]);
2367   output_w32(0xed800b00|(vr<<12)|(r<<16));
2368
2369
2370 void emit_ftosizs(int s,int d)
2371 {
2372   assem_debug("ftosizs s%d,s%d\n",d,s);
2373   output_w32(0xeebd0ac0|((d&14)<<11)|((d&1)<<22)|((s&14)>>1)|((s&1)<<5));
2374
2375
2376 void emit_ftosizd(int s,int d)
2377 {
2378   assem_debug("ftosizd s%d,d%d\n",d,s);
2379   output_w32(0xeebd0bc0|((d&14)<<11)|((d&1)<<22)|(s&7));
2380
2381
2382 void emit_fsitos(int s,int d)
2383 {
2384   assem_debug("fsitos s%d,s%d\n",d,s);
2385   output_w32(0xeeb80ac0|((d&14)<<11)|((d&1)<<22)|((s&14)>>1)|((s&1)<<5));
2386
2387
2388 void emit_fsitod(int s,int d)
2389 {
2390   assem_debug("fsitod d%d,s%d\n",d,s);
2391   output_w32(0xeeb80bc0|((d&7)<<12)|((s&14)>>1)|((s&1)<<5));
2392
2393
2394 void emit_fcvtds(int s,int d)
2395 {
2396   assem_debug("fcvtds d%d,s%d\n",d,s);
2397   output_w32(0xeeb70ac0|((d&7)<<12)|((s&14)>>1)|((s&1)<<5));
2398
2399
2400 void emit_fcvtsd(int s,int d)
2401 {
2402   assem_debug("fcvtsd s%d,d%d\n",d,s);
2403   output_w32(0xeeb70bc0|((d&14)<<11)|((d&1)<<22)|(s&7));
2404
2405
2406 void emit_fsqrts(int s,int d)
2407 {
2408   assem_debug("fsqrts d%d,s%d\n",d,s);
2409   output_w32(0xeeb10ac0|((d&14)<<11)|((d&1)<<22)|((s&14)>>1)|((s&1)<<5));
2410
2411
2412 void emit_fsqrtd(int s,int d)
2413 {
2414   assem_debug("fsqrtd s%d,d%d\n",d,s);
2415   output_w32(0xeeb10bc0|((d&7)<<12)|(s&7));
2416
2417
2418 void emit_fabss(int s,int d)
2419 {
2420   assem_debug("fabss d%d,s%d\n",d,s);
2421   output_w32(0xeeb00ac0|((d&14)<<11)|((d&1)<<22)|((s&14)>>1)|((s&1)<<5));
2422
2423
2424 void emit_fabsd(int s,int d)
2425 {
2426   assem_debug("fabsd s%d,d%d\n",d,s);
2427   output_w32(0xeeb00bc0|((d&7)<<12)|(s&7));
2428
2429
2430 void emit_fnegs(int s,int d)
2431 {
2432   assem_debug("fnegs d%d,s%d\n",d,s);
2433   output_w32(0xeeb10a40|((d&14)<<11)|((d&1)<<22)|((s&14)>>1)|((s&1)<<5));
2434
2435
2436 void emit_fnegd(int s,int d)
2437 {
2438   assem_debug("fnegd s%d,d%d\n",d,s);
2439   output_w32(0xeeb10b40|((d&7)<<12)|(s&7));
2440
2441
2442 void emit_fadds(int s1,int s2,int d)
2443 {
2444   assem_debug("fadds s%d,s%d,s%d\n",d,s1,s2);
2445   output_w32(0xee300a00|((d&14)<<11)|((d&1)<<22)|((s1&14)<<15)|((s1&1)<<7)|((s2&14)>>1)|((s2&1)<<5));
2446
2447
2448 void emit_faddd(int s1,int s2,int d)
2449 {
2450   assem_debug("faddd d%d,d%d,d%d\n",d,s1,s2);
2451   output_w32(0xee300b00|((d&7)<<12)|((s1&7)<<16)|(s2&7));
2452
2453
2454 void emit_fsubs(int s1,int s2,int d)
2455 {
2456   assem_debug("fsubs s%d,s%d,s%d\n",d,s1,s2);
2457   output_w32(0xee300a40|((d&14)<<11)|((d&1)<<22)|((s1&14)<<15)|((s1&1)<<7)|((s2&14)>>1)|((s2&1)<<5));
2458
2459
2460 void emit_fsubd(int s1,int s2,int d)
2461 {
2462   assem_debug("fsubd d%d,d%d,d%d\n",d,s1,s2);
2463   output_w32(0xee300b40|((d&7)<<12)|((s1&7)<<16)|(s2&7));
2464
2465
2466 void emit_fmuls(int s1,int s2,int d)
2467 {
2468   assem_debug("fmuls s%d,s%d,s%d\n",d,s1,s2);
2469   output_w32(0xee200a00|((d&14)<<11)|((d&1)<<22)|((s1&14)<<15)|((s1&1)<<7)|((s2&14)>>1)|((s2&1)<<5));
2470
2471
2472 void emit_fmuld(int s1,int s2,int d)
2473 {
2474   assem_debug("fmuld d%d,d%d,d%d\n",d,s1,s2);
2475   output_w32(0xee200b00|((d&7)<<12)|((s1&7)<<16)|(s2&7));
2476
2477
2478 void emit_fdivs(int s1,int s2,int d)
2479 {
2480   assem_debug("fdivs s%d,s%d,s%d\n",d,s1,s2);
2481   output_w32(0xee800a00|((d&14)<<11)|((d&1)<<22)|((s1&14)<<15)|((s1&1)<<7)|((s2&14)>>1)|((s2&1)<<5));
2482
2483
2484 void emit_fdivd(int s1,int s2,int d)
2485 {
2486   assem_debug("fdivd d%d,d%d,d%d\n",d,s1,s2);
2487   output_w32(0xee800b00|((d&7)<<12)|((s1&7)<<16)|(s2&7));
2488
2489
2490 void emit_fcmps(int x,int y)
2491 {
2492   assem_debug("fcmps s14, s15\n");
2493   output_w32(0xeeb47a67);
2494
2495
2496 void emit_fcmpd(int x,int y)
2497 {
2498   assem_debug("fcmpd d6, d7\n");
2499   output_w32(0xeeb46b47);
2500
2501
2502 void emit_fmstat()
2503 {
2504   assem_debug("fmstat\n");
2505   output_w32(0xeef1fa10);
2506
2507
2508 void emit_bicne_imm(int rs,int imm,int rt)
2509 {
2510   u_int armval;
2511   genimm_checked(imm,&armval);
2512   assem_debug("bicne %s,%s,#%d\n",regname[rt],regname[rs],imm);
2513   output_w32(0x13c00000|rd_rn_rm(rt,rs,0)|armval);
2514 }
2515
2516 void emit_biccs_imm(int rs,int imm,int rt)
2517 {
2518   u_int armval;
2519   genimm_checked(imm,&armval);
2520   assem_debug("biccs %s,%s,#%d\n",regname[rt],regname[rs],imm);
2521   output_w32(0x23c00000|rd_rn_rm(rt,rs,0)|armval);
2522 }
2523
2524 void emit_bicvc_imm(int rs,int imm,int rt)
2525 {
2526   u_int armval;
2527   genimm_checked(imm,&armval);
2528   assem_debug("bicvc %s,%s,#%d\n",regname[rt],regname[rs],imm);
2529   output_w32(0x73c00000|rd_rn_rm(rt,rs,0)|armval);
2530 }
2531
2532 void emit_bichi_imm(int rs,int imm,int rt)
2533 {
2534   u_int armval;
2535   genimm_checked(imm,&armval);
2536   assem_debug("bichi %s,%s,#%d\n",regname[rt],regname[rs],imm);
2537   output_w32(0x83c00000|rd_rn_rm(rt,rs,0)|armval);
2538 }
2539
2540 void emit_orrvs_imm(int rs,int imm,int rt)
2541 {
2542   u_int armval;
2543   genimm_checked(imm,&armval);
2544   assem_debug("orrvs %s,%s,#%d\n",regname[rt],regname[rs],imm);
2545   output_w32(0x63800000|rd_rn_rm(rt,rs,0)|armval);
2546 }
2547
2548 void emit_orrne_imm(int rs,int imm,int rt)
2549 {
2550   u_int armval;
2551   genimm_checked(imm,&armval);
2552   assem_debug("orrne %s,%s,#%d\n",regname[rt],regname[rs],imm);
2553   output_w32(0x13800000|rd_rn_rm(rt,rs,0)|armval);
2554 }
2555
2556 void emit_andne_imm(int rs,int imm,int rt)
2557 {
2558   u_int armval;
2559   genimm_checked(imm,&armval);
2560   assem_debug("andne %s,%s,#%d\n",regname[rt],regname[rs],imm);
2561   output_w32(0x12000000|rd_rn_rm(rt,rs,0)|armval);
2562 }
2563
2564 void emit_jno_unlikely(int a)
2565 {
2566   //emit_jno(a);
2567   assem_debug("addvc pc,pc,#? (%x)\n",/*a-(int)out-8,*/a);
2568   output_w32(0x72800000|rd_rn_rm(15,15,0));
2569 }
2570
2571 // Save registers before function call
2572 void save_regs(u_int reglist)
2573 {
2574   reglist&=0x100f; // only save the caller-save registers, r0-r3, r12
2575   if(!reglist) return;
2576   assem_debug("stmia fp,{");
2577   if(reglist&1) assem_debug("r0, ");
2578   if(reglist&2) assem_debug("r1, ");
2579   if(reglist&4) assem_debug("r2, ");
2580   if(reglist&8) assem_debug("r3, ");
2581   if(reglist&0x1000) assem_debug("r12");
2582   assem_debug("}\n");
2583   output_w32(0xe88b0000|reglist);
2584 }
2585 // Restore registers after function call
2586 void restore_regs(u_int reglist)
2587 {
2588   reglist&=0x100f; // only restore the caller-save registers, r0-r3, r12
2589   if(!reglist) return;
2590   assem_debug("ldmia fp,{");
2591   if(reglist&1) assem_debug("r0, ");
2592   if(reglist&2) assem_debug("r1, ");
2593   if(reglist&4) assem_debug("r2, ");
2594   if(reglist&8) assem_debug("r3, ");
2595   if(reglist&0x1000) assem_debug("r12");
2596   assem_debug("}\n");
2597   output_w32(0xe89b0000|reglist);
2598 }
2599
2600 // Write back consts using r14 so we don't disturb the other registers
2601 void wb_consts(signed char i_regmap[],uint64_t i_is32,u_int i_dirty,int i)
2602 {
2603   int hr;
2604   for(hr=0;hr<HOST_REGS;hr++) {
2605     if(hr!=EXCLUDE_REG&&i_regmap[hr]>=0&&((i_dirty>>hr)&1)) {
2606       if(((regs[i].isconst>>hr)&1)&&i_regmap[hr]>0) {
2607         if(i_regmap[hr]<64 || !((i_is32>>(i_regmap[hr]&63))&1) ) {
2608           int value=constmap[i][hr];
2609           if(value==0) {
2610             emit_zeroreg(HOST_TEMPREG);
2611           }
2612           else {
2613             emit_movimm(value,HOST_TEMPREG);
2614           }
2615           emit_storereg(i_regmap[hr],HOST_TEMPREG);
2616 #ifndef FORCE32
2617           if((i_is32>>i_regmap[hr])&1) {
2618             if(value!=-1&&value!=0) emit_sarimm(HOST_TEMPREG,31,HOST_TEMPREG);
2619             emit_storereg(i_regmap[hr]|64,HOST_TEMPREG);
2620           }
2621 #endif
2622         }
2623       }
2624     }
2625   }
2626 }
2627
2628 /* Stubs/epilogue */
2629
2630 void literal_pool(int n)
2631 {
2632   if(!literalcount) return;
2633   if(n) {
2634     if((int)out-literals[0][0]<4096-n) return;
2635   }
2636   u_int *ptr;
2637   int i;
2638   for(i=0;i<literalcount;i++)
2639   {
2640     ptr=(u_int *)literals[i][0];
2641     u_int offset=(u_int)out-(u_int)ptr-8;
2642     assert(offset<4096);
2643     assert(!(offset&3));
2644     *ptr|=offset;
2645     output_w32(literals[i][1]);
2646   }
2647   literalcount=0;
2648 }
2649
2650 void literal_pool_jumpover(int n)
2651 {
2652   if(!literalcount) return;
2653   if(n) {
2654     if((int)out-literals[0][0]<4096-n) return;
2655   }
2656   int jaddr=(int)out;
2657   emit_jmp(0);
2658   literal_pool(0);
2659   set_jump_target(jaddr,(int)out);
2660 }
2661
2662 emit_extjump2(int addr, int target, int linker)
2663 {
2664   u_char *ptr=(u_char *)addr;
2665   assert((ptr[3]&0x0e)==0xa);
2666   emit_loadlp(target,0);
2667   emit_loadlp(addr,1);
2668   assert(addr>=BASE_ADDR&&addr<(BASE_ADDR+(1<<TARGET_SIZE_2)));
2669   //assert((target>=0x80000000&&target<0x80800000)||(target>0xA4000000&&target<0xA4001000));
2670 //DEBUG >
2671 #ifdef DEBUG_CYCLE_COUNT
2672   emit_readword((int)&last_count,ECX);
2673   emit_add(HOST_CCREG,ECX,HOST_CCREG);
2674   emit_readword((int)&next_interupt,ECX);
2675   emit_writeword(HOST_CCREG,(int)&Count);
2676   emit_sub(HOST_CCREG,ECX,HOST_CCREG);
2677   emit_writeword(ECX,(int)&last_count);
2678 #endif
2679 //DEBUG <
2680   emit_jmp(linker);
2681 }
2682
2683 emit_extjump(int addr, int target)
2684 {
2685   emit_extjump2(addr, target, (int)dyna_linker);
2686 }
2687 emit_extjump_ds(int addr, int target)
2688 {
2689   emit_extjump2(addr, target, (int)dyna_linker_ds);
2690 }
2691
2692 // put rt_val into rt, potentially making use of rs with value rs_val
2693 static void emit_movimm_from(u_int rs_val,int rs,u_int rt_val,int rt)
2694 {
2695   u_int xor=rs_val^rt_val;
2696   u_int xs;
2697   for(xs=xor;xs!=0&&(xs&3)==0;xs>>=2)
2698     ;
2699   if(xs<0x100)
2700     emit_xorimm(rs,xor,rt);
2701   else
2702     emit_movimm(rt_val,rt);
2703 }
2704
2705 // trashes r2
2706 static void pass_args(int a0, int a1)
2707 {
2708   if(a0==1&&a1==0) {
2709     // must swap
2710     emit_mov(a0,2); emit_mov(a1,1); emit_mov(2,0);
2711   }
2712   else if(a0!=0&&a1==0) {
2713     emit_mov(a1,1);
2714     if (a0>=0) emit_mov(a0,0);
2715   }
2716   else {
2717     if(a0>=0&&a0!=0) emit_mov(a0,0);
2718     if(a1>=0&&a1!=1) emit_mov(a1,1);
2719   }
2720 }
2721
2722 static void mov_loadtype_adj(int type,int rs,int rt)
2723 {
2724   switch(type) {
2725     case LOADB_STUB:  emit_signextend8(rs,rt); break;
2726     case LOADBU_STUB: emit_andimm(rs,0xff,rt); break;
2727     case LOADH_STUB:  emit_signextend16(rs,rt); break;
2728     case LOADHU_STUB: emit_andimm(rs,0xffff,rt); break;
2729     case LOADW_STUB:  if(rs!=rt) emit_mov(rs,rt); break;
2730     default: assert(0);
2731   }
2732 }
2733
2734 #ifdef PCSX
2735 #include "pcsxmem.h"
2736 #include "pcsxmem_inline.c"
2737 #endif
2738
2739 do_readstub(int n)
2740 {
2741   assem_debug("do_readstub %x\n",start+stubs[n][3]*4);
2742   literal_pool(256);
2743   set_jump_target(stubs[n][1],(int)out);
2744   int type=stubs[n][0];
2745   int i=stubs[n][3];
2746   int rs=stubs[n][4];
2747   struct regstat *i_regs=(struct regstat *)stubs[n][5];
2748   u_int reglist=stubs[n][7];
2749   signed char *i_regmap=i_regs->regmap;
2750   int addr=get_reg(i_regmap,AGEN1+(i&1));
2751   int rth,rt;
2752   int ds;
2753   if(itype[i]==C1LS||itype[i]==C2LS||itype[i]==LOADLR) {
2754     rth=get_reg(i_regmap,FTEMP|64);
2755     rt=get_reg(i_regmap,FTEMP);
2756   }else{
2757     rth=get_reg(i_regmap,rt1[i]|64);
2758     rt=get_reg(i_regmap,rt1[i]);
2759   }
2760   assert(rs>=0);
2761 #ifdef PCSX
2762   int r,temp=-1,temp2=HOST_TEMPREG,regs_saved=0,restore_jump=0;
2763   reglist|=(1<<rs);
2764   for(r=0;r<=12;r++) {
2765     if(((1<<r)&0x13ff)&&((1<<r)&reglist)==0) {
2766       temp=r; break;
2767     }
2768   }
2769   if(rt>=0)
2770     reglist&=~(1<<rt);
2771   if(temp==-1) {
2772     save_regs(reglist);
2773     regs_saved=1;
2774     temp=(rs==0)?2:0;
2775   }
2776   if((regs_saved||(reglist&2)==0)&&temp!=1&&rs!=1)
2777     temp2=1;
2778   emit_readword((int)&mem_rtab,temp);
2779   emit_shrimm(rs,12,temp2);
2780   emit_readword_dualindexedx4(temp,temp2,temp2);
2781   emit_lsls_imm(temp2,1,temp2);
2782   if(itype[i]==C1LS||itype[i]==C2LS||(rt>=0&&rt1[i]!=0)) {
2783     switch(type) {
2784       case LOADB_STUB:  emit_ldrccsb_dualindexed(temp2,rs,rt); break;
2785       case LOADBU_STUB: emit_ldrccb_dualindexed(temp2,rs,rt); break;
2786       case LOADH_STUB:  emit_ldrccsh_dualindexed(temp2,rs,rt); break;
2787       case LOADHU_STUB: emit_ldrcch_dualindexed(temp2,rs,rt); break;
2788       case LOADW_STUB:  emit_ldrcc_dualindexed(temp2,rs,rt); break;
2789     }
2790   }
2791   if(regs_saved) {
2792     restore_jump=(int)out;
2793     emit_jcc(0); // jump to reg restore
2794   }
2795   else
2796     emit_jcc(stubs[n][2]); // return address
2797
2798   if(!regs_saved)
2799     save_regs(reglist);
2800   int handler=0;
2801   if(type==LOADB_STUB||type==LOADBU_STUB)
2802     handler=(int)jump_handler_read8;
2803   if(type==LOADH_STUB||type==LOADHU_STUB)
2804     handler=(int)jump_handler_read16;
2805   if(type==LOADW_STUB)
2806     handler=(int)jump_handler_read32;
2807   assert(handler!=0);
2808   pass_args(rs,temp2);
2809   int cc=get_reg(i_regmap,CCREG);
2810   if(cc<0)
2811     emit_loadreg(CCREG,2);
2812   emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n][6]+1),2);
2813   emit_call(handler);
2814   if(itype[i]==C1LS||itype[i]==C2LS||(rt>=0&&rt1[i]!=0)) {
2815     mov_loadtype_adj(type,0,rt);
2816   }
2817   if(restore_jump)
2818     set_jump_target(restore_jump,(int)out);
2819   restore_regs(reglist);
2820   emit_jmp(stubs[n][2]); // return address
2821 #else // !PCSX
2822   if(addr<0) addr=rt;
2823   if(addr<0&&itype[i]!=C1LS&&itype[i]!=C2LS&&itype[i]!=LOADLR) addr=get_reg(i_regmap,-1);
2824   assert(addr>=0);
2825   int ftable=0;
2826   if(type==LOADB_STUB||type==LOADBU_STUB)
2827     ftable=(int)readmemb;
2828   if(type==LOADH_STUB||type==LOADHU_STUB)
2829     ftable=(int)readmemh;
2830   if(type==LOADW_STUB)
2831     ftable=(int)readmem;
2832 #ifndef FORCE32
2833   if(type==LOADD_STUB)
2834     ftable=(int)readmemd;
2835 #endif
2836   assert(ftable!=0);
2837   emit_writeword(rs,(int)&address);
2838   //emit_pusha();
2839   save_regs(reglist);
2840 #ifndef PCSX
2841   ds=i_regs!=&regs[i];
2842   int real_rs=(itype[i]==LOADLR)?-1:get_reg(i_regmap,rs1[i]);
2843   u_int cmask=ds?-1:(0x100f|~i_regs->wasconst);
2844   if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs))&0x100f,i);
2845   wb_dirtys(i_regs->regmap_entry,i_regs->was32,i_regs->wasdirty&cmask&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs)));
2846   if(!ds) wb_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs))&~0x100f,i);
2847 #endif
2848   emit_shrimm(rs,16,1);
2849   int cc=get_reg(i_regmap,CCREG);
2850   if(cc<0) {
2851     emit_loadreg(CCREG,2);
2852   }
2853   emit_movimm(ftable,0);
2854   emit_addimm(cc<0?2:cc,2*stubs[n][6]+2,2);
2855 #ifndef PCSX
2856   emit_movimm(start+stubs[n][3]*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,3);
2857 #endif
2858   //emit_readword((int)&last_count,temp);
2859   //emit_add(cc,temp,cc);
2860   //emit_writeword(cc,(int)&Count);
2861   //emit_mov(15,14);
2862   emit_call((int)&indirect_jump_indexed);
2863   //emit_callreg(rs);
2864   //emit_readword_dualindexedx4(rs,HOST_TEMPREG,15);
2865 #ifndef PCSX
2866   // We really shouldn't need to update the count here,
2867   // but not doing so causes random crashes...
2868   emit_readword((int)&Count,HOST_TEMPREG);
2869   emit_readword((int)&next_interupt,2);
2870   emit_addimm(HOST_TEMPREG,-2*stubs[n][6]-2,HOST_TEMPREG);
2871   emit_writeword(2,(int)&last_count);
2872   emit_sub(HOST_TEMPREG,2,cc<0?HOST_TEMPREG:cc);
2873   if(cc<0) {
2874     emit_storereg(CCREG,HOST_TEMPREG);
2875   }
2876 #endif
2877   //emit_popa();
2878   restore_regs(reglist);
2879   //if((cc=get_reg(regmap,CCREG))>=0) {
2880   //  emit_loadreg(CCREG,cc);
2881   //}
2882   if(itype[i]==C1LS||itype[i]==C2LS||(rt>=0&&rt1[i]!=0)) {
2883     assert(rt>=0);
2884     if(type==LOADB_STUB)
2885       emit_movsbl((int)&readmem_dword,rt);
2886     if(type==LOADBU_STUB)
2887       emit_movzbl((int)&readmem_dword,rt);
2888     if(type==LOADH_STUB)
2889       emit_movswl((int)&readmem_dword,rt);
2890     if(type==LOADHU_STUB)
2891       emit_movzwl((int)&readmem_dword,rt);
2892     if(type==LOADW_STUB)
2893       emit_readword((int)&readmem_dword,rt);
2894     if(type==LOADD_STUB) {
2895       emit_readword((int)&readmem_dword,rt);
2896       if(rth>=0) emit_readword(((int)&readmem_dword)+4,rth);
2897     }
2898   }
2899   emit_jmp(stubs[n][2]); // return address
2900 #endif // !PCSX
2901 }
2902
2903 #ifdef PCSX
2904 // return memhandler, or get directly accessable address and return 0
2905 u_int get_direct_memhandler(void *table,u_int addr,int type,u_int *addr_host)
2906 {
2907   u_int l1,l2=0;
2908   l1=((u_int *)table)[addr>>12];
2909   if((l1&(1<<31))==0) {
2910     u_int v=l1<<1;
2911     *addr_host=v+addr;
2912     return 0;
2913   }
2914   else {
2915     l1<<=1;
2916     if(type==LOADB_STUB||type==LOADBU_STUB||type==STOREB_STUB)
2917       l2=((u_int *)l1)[0x1000/4 + 0x1000/2 + (addr&0xfff)];
2918     else if(type==LOADH_STUB||type==LOADHU_STUB||type==STOREH_STUB)
2919       l2=((u_int *)l1)[0x1000/4 + (addr&0xfff)/2];
2920     else
2921       l2=((u_int *)l1)[(addr&0xfff)/4];
2922     if((l2&(1<<31))==0) {
2923       u_int v=l2<<1;
2924       *addr_host=v+(addr&0xfff);
2925       return 0;
2926     }
2927     return l2<<1;
2928   }
2929 }
2930 #endif
2931
2932 inline_readstub(int type, int i, u_int addr, signed char regmap[], int target, int adj, u_int reglist)
2933 {
2934   int rs=get_reg(regmap,target);
2935   int rth=get_reg(regmap,target|64);
2936   int rt=get_reg(regmap,target);
2937   if(rs<0) rs=get_reg(regmap,-1);
2938   assert(rs>=0);
2939 #ifdef PCSX
2940   u_int handler,host_addr=0,is_dynamic,far_call=0;
2941   int cc=get_reg(regmap,CCREG);
2942   if(pcsx_direct_read(type,addr,CLOCK_ADJUST(adj+1),cc,target?rs:-1,rt))
2943     return;
2944   handler=get_direct_memhandler(mem_rtab,addr,type,&host_addr);
2945   if (handler==0) {
2946     if(rt<0)
2947       return;
2948     if(addr!=host_addr)
2949       emit_movimm_from(addr,rs,host_addr,rs);
2950     switch(type) {
2951       case LOADB_STUB:  emit_movsbl_indexed(0,rs,rt); break;
2952       case LOADBU_STUB: emit_movzbl_indexed(0,rs,rt); break;
2953       case LOADH_STUB:  emit_movswl_indexed(0,rs,rt); break;
2954       case LOADHU_STUB: emit_movzwl_indexed(0,rs,rt); break;
2955       case LOADW_STUB:  emit_readword_indexed(0,rs,rt); break;
2956       default:          assert(0);
2957     }
2958     return;
2959   }
2960   is_dynamic=pcsxmem_is_handler_dynamic(addr);
2961   if(is_dynamic) {
2962     if(type==LOADB_STUB||type==LOADBU_STUB)
2963       handler=(int)jump_handler_read8;
2964     if(type==LOADH_STUB||type==LOADHU_STUB)
2965       handler=(int)jump_handler_read16;
2966     if(type==LOADW_STUB)
2967       handler=(int)jump_handler_read32;
2968   }
2969
2970   // call a memhandler
2971   if(rt>=0)
2972     reglist&=~(1<<rt);
2973   save_regs(reglist);
2974   if(target==0)
2975     emit_movimm(addr,0);
2976   else if(rs!=0)
2977     emit_mov(rs,0);
2978   int offset=(int)handler-(int)out-8;
2979   if(offset<-33554432||offset>=33554432) {
2980     // unreachable memhandler, a plugin func perhaps
2981     emit_movimm(handler,12);
2982     far_call=1;
2983   }
2984   if(cc<0)
2985     emit_loadreg(CCREG,2);
2986   if(is_dynamic) {
2987     emit_movimm(((u_int *)mem_rtab)[addr>>12]<<1,1);
2988     emit_addimm(cc<0?2:cc,CLOCK_ADJUST(adj+1),2);
2989   }
2990   else {
2991     emit_readword((int)&last_count,3);
2992     emit_addimm(cc<0?2:cc,CLOCK_ADJUST(adj+1),2);
2993     emit_add(2,3,2);
2994     emit_writeword(2,(int)&Count);
2995   }
2996
2997   if(far_call)
2998     emit_callreg(12);
2999   else
3000     emit_call(handler);
3001
3002   if(rt>=0) {
3003     switch(type) {
3004       case LOADB_STUB:  emit_signextend8(0,rt); break;
3005       case LOADBU_STUB: emit_andimm(0,0xff,rt); break;
3006       case LOADH_STUB:  emit_signextend16(0,rt); break;
3007       case LOADHU_STUB: emit_andimm(0,0xffff,rt); break;
3008       case LOADW_STUB:  if(rt!=0) emit_mov(0,rt); break;
3009       default:          assert(0);
3010     }
3011   }
3012   restore_regs(reglist);
3013 #else // if !PCSX
3014   int ftable=0;
3015   if(type==LOADB_STUB||type==LOADBU_STUB)
3016     ftable=(int)readmemb;
3017   if(type==LOADH_STUB||type==LOADHU_STUB)
3018     ftable=(int)readmemh;
3019   if(type==LOADW_STUB)
3020     ftable=(int)readmem;
3021 #ifndef FORCE32
3022   if(type==LOADD_STUB)
3023     ftable=(int)readmemd;
3024 #endif
3025   assert(ftable!=0);
3026   if(target==0)
3027     emit_movimm(addr,rs);
3028   emit_writeword(rs,(int)&address);
3029   //emit_pusha();
3030   save_regs(reglist);
3031 #ifndef PCSX
3032   if((signed int)addr>=(signed int)0xC0000000) {
3033     // Theoretically we can have a pagefault here, if the TLB has never
3034     // been enabled and the address is outside the range 80000000..BFFFFFFF
3035     // Write out the registers so the pagefault can be handled.  This is
3036     // a very rare case and likely represents a bug.
3037     int ds=regmap!=regs[i].regmap;
3038     if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty,i);
3039     if(!ds) wb_dirtys(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty);
3040     else wb_dirtys(branch_regs[i-1].regmap_entry,branch_regs[i-1].was32,branch_regs[i-1].wasdirty);
3041   }
3042 #endif
3043   //emit_shrimm(rs,16,1);
3044   int cc=get_reg(regmap,CCREG);
3045   if(cc<0) {
3046     emit_loadreg(CCREG,2);
3047   }
3048   //emit_movimm(ftable,0);
3049   emit_movimm(((u_int *)ftable)[addr>>16],0);
3050   //emit_readword((int)&last_count,12);
3051   emit_addimm(cc<0?2:cc,CLOCK_ADJUST(adj+1),2);
3052 #ifndef PCSX
3053   if((signed int)addr>=(signed int)0xC0000000) {
3054     // Pagefault address
3055     int ds=regmap!=regs[i].regmap;
3056     emit_movimm(start+i*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,3);
3057   }
3058 #endif
3059   //emit_add(12,2,2);
3060   //emit_writeword(2,(int)&Count);
3061   //emit_call(((u_int *)ftable)[addr>>16]);
3062   emit_call((int)&indirect_jump);
3063 #ifndef PCSX
3064   // We really shouldn't need to update the count here,
3065   // but not doing so causes random crashes...
3066   emit_readword((int)&Count,HOST_TEMPREG);
3067   emit_readword((int)&next_interupt,2);
3068   emit_addimm(HOST_TEMPREG,-CLOCK_ADJUST(adj+1),HOST_TEMPREG);
3069   emit_writeword(2,(int)&last_count);
3070   emit_sub(HOST_TEMPREG,2,cc<0?HOST_TEMPREG:cc);
3071   if(cc<0) {
3072     emit_storereg(CCREG,HOST_TEMPREG);
3073   }
3074 #endif
3075   //emit_popa();
3076   restore_regs(reglist);
3077   if(rt>=0) {
3078     if(type==LOADB_STUB)
3079       emit_movsbl((int)&readmem_dword,rt);
3080     if(type==LOADBU_STUB)
3081       emit_movzbl((int)&readmem_dword,rt);
3082     if(type==LOADH_STUB)
3083       emit_movswl((int)&readmem_dword,rt);
3084     if(type==LOADHU_STUB)
3085       emit_movzwl((int)&readmem_dword,rt);
3086     if(type==LOADW_STUB)
3087       emit_readword((int)&readmem_dword,rt);
3088     if(type==LOADD_STUB) {
3089       emit_readword((int)&readmem_dword,rt);
3090       if(rth>=0) emit_readword(((int)&readmem_dword)+4,rth);
3091     }
3092   }
3093 #endif // !PCSX
3094 }
3095
3096 do_writestub(int n)
3097 {
3098   assem_debug("do_writestub %x\n",start+stubs[n][3]*4);
3099   literal_pool(256);
3100   set_jump_target(stubs[n][1],(int)out);
3101   int type=stubs[n][0];
3102   int i=stubs[n][3];
3103   int rs=stubs[n][4];
3104   struct regstat *i_regs=(struct regstat *)stubs[n][5];
3105   u_int reglist=stubs[n][7];
3106   signed char *i_regmap=i_regs->regmap;
3107   int addr=get_reg(i_regmap,AGEN1+(i&1));
3108   int rth,rt,r;
3109   int ds;
3110   if(itype[i]==C1LS||itype[i]==C2LS) {
3111     rth=get_reg(i_regmap,FTEMP|64);
3112     rt=get_reg(i_regmap,r=FTEMP);
3113   }else{
3114     rth=get_reg(i_regmap,rs2[i]|64);
3115     rt=get_reg(i_regmap,r=rs2[i]);
3116   }
3117   assert(rs>=0);
3118   assert(rt>=0);
3119 #ifdef PCSX
3120   int rtmp,temp=-1,temp2=HOST_TEMPREG,regs_saved=0,restore_jump=0,ra;
3121   int reglist2=reglist|(1<<rs)|(1<<rt);
3122   for(rtmp=0;rtmp<=12;rtmp++) {
3123     if(((1<<rtmp)&0x13ff)&&((1<<rtmp)&reglist2)==0) {
3124       temp=rtmp; break;
3125     }
3126   }
3127   if(temp==-1) {
3128     save_regs(reglist);
3129     regs_saved=1;
3130     for(rtmp=0;rtmp<=3;rtmp++)
3131       if(rtmp!=rs&&rtmp!=rt)
3132         {temp=rtmp;break;}
3133   }
3134   if((regs_saved||(reglist2&8)==0)&&temp!=3&&rs!=3&&rt!=3)
3135     temp2=3;
3136   emit_readword((int)&mem_wtab,temp);
3137   emit_shrimm(rs,12,temp2);
3138   emit_readword_dualindexedx4(temp,temp2,temp2);
3139   emit_lsls_imm(temp2,1,temp2);
3140   switch(type) {
3141     case STOREB_STUB: emit_strccb_dualindexed(temp2,rs,rt); break;
3142     case STOREH_STUB: emit_strcch_dualindexed(temp2,rs,rt); break;
3143     case STOREW_STUB: emit_strcc_dualindexed(temp2,rs,rt); break;
3144     default:          assert(0);
3145   }
3146   if(regs_saved) {
3147     restore_jump=(int)out;
3148     emit_jcc(0); // jump to reg restore
3149   }
3150   else
3151     emit_jcc(stubs[n][2]); // return address (invcode check)
3152
3153   if(!regs_saved)
3154     save_regs(reglist);
3155   int handler=0;
3156   switch(type) {
3157     case STOREB_STUB: handler=(int)jump_handler_write8; break;
3158     case STOREH_STUB: handler=(int)jump_handler_write16; break;
3159     case STOREW_STUB: handler=(int)jump_handler_write32; break;
3160   }
3161   assert(handler!=0);
3162   pass_args(rs,rt);
3163   if(temp2!=3)
3164     emit_mov(temp2,3);
3165   int cc=get_reg(i_regmap,CCREG);
3166   if(cc<0)
3167     emit_loadreg(CCREG,2);
3168   emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n][6]+1),2);
3169   // returns new cycle_count
3170   emit_call(handler);
3171   emit_addimm(0,-CLOCK_ADJUST((int)stubs[n][6]+1),cc<0?2:cc);
3172   if(cc<0)
3173     emit_storereg(CCREG,2);
3174   if(restore_jump)
3175     set_jump_target(restore_jump,(int)out);
3176   restore_regs(reglist);
3177   ra=stubs[n][2];
3178   if(!restore_jump) ra+=4*3; // skip invcode check
3179   emit_jmp(ra);
3180 #else // if !PCSX
3181   if(addr<0) addr=get_reg(i_regmap,-1);
3182   assert(addr>=0);
3183   int ftable=0;
3184   if(type==STOREB_STUB)
3185     ftable=(int)writememb;
3186   if(type==STOREH_STUB)
3187     ftable=(int)writememh;
3188   if(type==STOREW_STUB)
3189     ftable=(int)writemem;
3190 #ifndef FORCE32
3191   if(type==STORED_STUB)
3192     ftable=(int)writememd;
3193 #endif
3194   assert(ftable!=0);
3195   emit_writeword(rs,(int)&address);
3196   //emit_shrimm(rs,16,rs);
3197   //emit_movmem_indexedx4(ftable,rs,rs);
3198   if(type==STOREB_STUB)
3199     emit_writebyte(rt,(int)&byte);
3200   if(type==STOREH_STUB)
3201     emit_writehword(rt,(int)&hword);
3202   if(type==STOREW_STUB)
3203     emit_writeword(rt,(int)&word);
3204   if(type==STORED_STUB) {
3205 #ifndef FORCE32
3206     emit_writeword(rt,(int)&dword);
3207     emit_writeword(r?rth:rt,(int)&dword+4);
3208 #else
3209     printf("STORED_STUB\n");
3210 #endif
3211   }
3212   //emit_pusha();
3213   save_regs(reglist);
3214 #ifndef PCSX
3215   ds=i_regs!=&regs[i];
3216   int real_rs=get_reg(i_regmap,rs1[i]);
3217   u_int cmask=ds?-1:(0x100f|~i_regs->wasconst);
3218   if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs))&0x100f,i);
3219   wb_dirtys(i_regs->regmap_entry,i_regs->was32,i_regs->wasdirty&cmask&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs)));
3220   if(!ds) wb_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs))&~0x100f,i);
3221 #endif
3222   emit_shrimm(rs,16,1);
3223   int cc=get_reg(i_regmap,CCREG);
3224   if(cc<0) {
3225     emit_loadreg(CCREG,2);
3226   }
3227   emit_movimm(ftable,0);
3228   emit_addimm(cc<0?2:cc,2*stubs[n][6]+2,2);
3229 #ifndef PCSX
3230   emit_movimm(start+stubs[n][3]*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,3);
3231 #endif
3232   //emit_readword((int)&last_count,temp);
3233   //emit_addimm(cc,2*stubs[n][5]+2,cc);
3234   //emit_add(cc,temp,cc);
3235   //emit_writeword(cc,(int)&Count);
3236   emit_call((int)&indirect_jump_indexed);
3237   //emit_callreg(rs);
3238   emit_readword((int)&Count,HOST_TEMPREG);
3239   emit_readword((int)&next_interupt,2);
3240   emit_addimm(HOST_TEMPREG,-2*stubs[n][6]-2,HOST_TEMPREG);
3241   emit_writeword(2,(int)&last_count);
3242   emit_sub(HOST_TEMPREG,2,cc<0?HOST_TEMPREG:cc);
3243   if(cc<0) {
3244     emit_storereg(CCREG,HOST_TEMPREG);
3245   }
3246   //emit_popa();
3247   restore_regs(reglist);
3248   //if((cc=get_reg(regmap,CCREG))>=0) {
3249   //  emit_loadreg(CCREG,cc);
3250   //}
3251   emit_jmp(stubs[n][2]); // return address
3252 #endif // !PCSX
3253 }
3254
3255 inline_writestub(int type, int i, u_int addr, signed char regmap[], int target, int adj, u_int reglist)
3256 {
3257   int rs=get_reg(regmap,-1);
3258   int rth=get_reg(regmap,target|64);
3259   int rt=get_reg(regmap,target);
3260   assert(rs>=0);
3261   assert(rt>=0);
3262 #ifdef PCSX
3263   u_int handler,host_addr=0;
3264   handler=get_direct_memhandler(mem_wtab,addr,type,&host_addr);
3265   if (handler==0) {
3266     if(addr!=host_addr)
3267       emit_movimm_from(addr,rs,host_addr,rs);
3268     switch(type) {
3269       case STOREB_STUB: emit_writebyte_indexed(rt,0,rs); break;
3270       case STOREH_STUB: emit_writehword_indexed(rt,0,rs); break;
3271       case STOREW_STUB: emit_writeword_indexed(rt,0,rs); break;
3272       default:          assert(0);
3273     }
3274     return;
3275   }
3276
3277   // call a memhandler
3278   save_regs(reglist);
3279   pass_args(rs,rt);
3280   int cc=get_reg(regmap,CCREG);
3281   if(cc<0)
3282     emit_loadreg(CCREG,2);
3283   emit_addimm(cc<0?2:cc,CLOCK_ADJUST(adj+1),2);
3284   emit_movimm(handler,3);
3285   // returns new cycle_count
3286   emit_call((int)jump_handler_write_h);
3287   emit_addimm(0,-CLOCK_ADJUST(adj+1),cc<0?2:cc);
3288   if(cc<0)
3289     emit_storereg(CCREG,2);
3290   restore_regs(reglist);
3291 #else // if !pcsx
3292   int ftable=0;
3293   if(type==STOREB_STUB)
3294     ftable=(int)writememb;
3295   if(type==STOREH_STUB)
3296     ftable=(int)writememh;
3297   if(type==STOREW_STUB)
3298     ftable=(int)writemem;
3299 #ifndef FORCE32
3300   if(type==STORED_STUB)
3301     ftable=(int)writememd;
3302 #endif
3303   assert(ftable!=0);
3304   emit_writeword(rs,(int)&address);
3305   //emit_shrimm(rs,16,rs);
3306   //emit_movmem_indexedx4(ftable,rs,rs);
3307   if(type==STOREB_STUB)
3308     emit_writebyte(rt,(int)&byte);
3309   if(type==STOREH_STUB)
3310     emit_writehword(rt,(int)&hword);
3311   if(type==STOREW_STUB)
3312     emit_writeword(rt,(int)&word);
3313   if(type==STORED_STUB) {
3314 #ifndef FORCE32
3315     emit_writeword(rt,(int)&dword);
3316     emit_writeword(target?rth:rt,(int)&dword+4);
3317 #else
3318     printf("STORED_STUB\n");
3319 #endif
3320   }
3321   //emit_pusha();
3322   save_regs(reglist);
3323 #ifndef PCSX
3324   // rearmed note: load_all_consts prevents BIOS boot, some bug?
3325   if((signed int)addr>=(signed int)0xC0000000) {
3326     // Theoretically we can have a pagefault here, if the TLB has never
3327     // been enabled and the address is outside the range 80000000..BFFFFFFF
3328     // Write out the registers so the pagefault can be handled.  This is
3329     // a very rare case and likely represents a bug.
3330     int ds=regmap!=regs[i].regmap;
3331     if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty,i);
3332     if(!ds) wb_dirtys(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty);
3333     else wb_dirtys(branch_regs[i-1].regmap_entry,branch_regs[i-1].was32,branch_regs[i-1].wasdirty);
3334   }
3335 #endif
3336   //emit_shrimm(rs,16,1);
3337   int cc=get_reg(regmap,CCREG);
3338   if(cc<0) {
3339     emit_loadreg(CCREG,2);
3340   }
3341   //emit_movimm(ftable,0);
3342   emit_movimm(((u_int *)ftable)[addr>>16],0);
3343   //emit_readword((int)&last_count,12);
3344   emit_addimm(cc<0?2:cc,CLOCK_ADJUST(adj+1),2);
3345 #ifndef PCSX
3346   if((signed int)addr>=(signed int)0xC0000000) {
3347     // Pagefault address
3348     int ds=regmap!=regs[i].regmap;
3349     emit_movimm(start+i*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,3);
3350   }
3351 #endif
3352   //emit_add(12,2,2);
3353   //emit_writeword(2,(int)&Count);
3354   //emit_call(((u_int *)ftable)[addr>>16]);
3355   emit_call((int)&indirect_jump);
3356   emit_readword((int)&Count,HOST_TEMPREG);
3357   emit_readword((int)&next_interupt,2);
3358   emit_addimm(HOST_TEMPREG,-CLOCK_ADJUST(adj+1),HOST_TEMPREG);
3359   emit_writeword(2,(int)&last_count);
3360   emit_sub(HOST_TEMPREG,2,cc<0?HOST_TEMPREG:cc);
3361   if(cc<0) {
3362     emit_storereg(CCREG,HOST_TEMPREG);
3363   }
3364   //emit_popa();
3365   restore_regs(reglist);
3366 #endif
3367 }
3368
3369 do_unalignedwritestub(int n)
3370 {
3371   assem_debug("do_unalignedwritestub %x\n",start+stubs[n][3]*4);
3372   literal_pool(256);
3373   set_jump_target(stubs[n][1],(int)out);
3374
3375   int i=stubs[n][3];
3376   struct regstat *i_regs=(struct regstat *)stubs[n][4];
3377   int addr=stubs[n][5];
3378   u_int reglist=stubs[n][7];
3379   signed char *i_regmap=i_regs->regmap;
3380   int temp2=get_reg(i_regmap,FTEMP);
3381   int rt;
3382   int ds, real_rs;
3383   rt=get_reg(i_regmap,rs2[i]);
3384   assert(rt>=0);
3385   assert(addr>=0);
3386   assert(opcode[i]==0x2a||opcode[i]==0x2e); // SWL/SWR only implemented
3387   reglist|=(1<<addr);
3388   reglist&=~(1<<temp2);
3389
3390 #if 1
3391   // don't bother with it and call write handler
3392   save_regs(reglist);
3393   pass_args(addr,rt);
3394   int cc=get_reg(i_regmap,CCREG);
3395   if(cc<0)
3396     emit_loadreg(CCREG,2);
3397   emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n][6]+1),2);
3398   emit_call((int)(opcode[i]==0x2a?jump_handle_swl:jump_handle_swr));
3399   emit_addimm(0,-CLOCK_ADJUST((int)stubs[n][6]+1),cc<0?2:cc);
3400   if(cc<0)
3401     emit_storereg(CCREG,2);
3402   restore_regs(reglist);
3403   emit_jmp(stubs[n][2]); // return address
3404 #else
3405   emit_andimm(addr,0xfffffffc,temp2);
3406   emit_writeword(temp2,(int)&address);
3407
3408   save_regs(reglist);
3409 #ifndef PCSX
3410   ds=i_regs!=&regs[i];
3411   real_rs=get_reg(i_regmap,rs1[i]);
3412   u_int cmask=ds?-1:(0x100f|~i_regs->wasconst);
3413   if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs))&0x100f,i);
3414   wb_dirtys(i_regs->regmap_entry,i_regs->was32,i_regs->wasdirty&cmask&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs)));
3415   if(!ds) wb_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs))&~0x100f,i);
3416 #endif
3417   emit_shrimm(addr,16,1);
3418   int cc=get_reg(i_regmap,CCREG);
3419   if(cc<0) {
3420     emit_loadreg(CCREG,2);
3421   }
3422   emit_movimm((u_int)readmem,0);
3423   emit_addimm(cc<0?2:cc,2*stubs[n][6]+2,2);
3424 #ifndef PCSX
3425   // pagefault address
3426   emit_movimm(start+stubs[n][3]*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,3);
3427 #endif
3428   emit_call((int)&indirect_jump_indexed);
3429   restore_regs(reglist);
3430
3431   emit_readword((int)&readmem_dword,temp2);
3432   int temp=addr; //hmh
3433   emit_shlimm(addr,3,temp);
3434   emit_andimm(temp,24,temp);
3435 #ifdef BIG_ENDIAN_MIPS
3436   if (opcode[i]==0x2e) // SWR
3437 #else
3438   if (opcode[i]==0x2a) // SWL
3439 #endif
3440     emit_xorimm(temp,24,temp);
3441   emit_movimm(-1,HOST_TEMPREG);
3442   if (opcode[i]==0x2a) { // SWL
3443     emit_bic_lsr(temp2,HOST_TEMPREG,temp,temp2);
3444     emit_orrshr(rt,temp,temp2);
3445   }else{
3446     emit_bic_lsl(temp2,HOST_TEMPREG,temp,temp2);
3447     emit_orrshl(rt,temp,temp2);
3448   }
3449   emit_readword((int)&address,addr);
3450   emit_writeword(temp2,(int)&word);
3451   //save_regs(reglist); // don't need to, no state changes
3452   emit_shrimm(addr,16,1);
3453   emit_movimm((u_int)writemem,0);
3454   //emit_call((int)&indirect_jump_indexed);
3455   emit_mov(15,14);
3456   emit_readword_dualindexedx4(0,1,15);
3457   emit_readword((int)&Count,HOST_TEMPREG);
3458   emit_readword((int)&next_interupt,2);
3459   emit_addimm(HOST_TEMPREG,-2*stubs[n][6]-2,HOST_TEMPREG);
3460   emit_writeword(2,(int)&last_count);
3461   emit_sub(HOST_TEMPREG,2,cc<0?HOST_TEMPREG:cc);
3462   if(cc<0) {
3463     emit_storereg(CCREG,HOST_TEMPREG);
3464   }
3465   restore_regs(reglist);
3466   emit_jmp(stubs[n][2]); // return address
3467 #endif
3468 }
3469
3470 void printregs(int edi,int esi,int ebp,int esp,int b,int d,int c,int a)
3471 {
3472   printf("regs: %x %x %x %x %x %x %x (%x)\n",a,b,c,d,ebp,esi,edi,(&edi)[-1]);
3473 }
3474
3475 do_invstub(int n)
3476 {
3477   literal_pool(20);
3478   u_int reglist=stubs[n][3];
3479   set_jump_target(stubs[n][1],(int)out);
3480   save_regs(reglist);
3481   if(stubs[n][4]!=0) emit_mov(stubs[n][4],0);
3482   emit_call((int)&invalidate_addr);
3483   restore_regs(reglist);
3484   emit_jmp(stubs[n][2]); // return address
3485 }
3486
3487 int do_dirty_stub(int i)
3488 {
3489   assem_debug("do_dirty_stub %x\n",start+i*4);
3490   u_int addr=(int)start<(int)0xC0000000?(u_int)source:(u_int)start;
3491   #ifdef PCSX
3492   addr=(u_int)source;
3493   #endif
3494   // Careful about the code output here, verify_dirty needs to parse it.
3495   #ifdef ARMv5_ONLY
3496   emit_loadlp(addr,1);
3497   emit_loadlp((int)copy,2);
3498   emit_loadlp(slen*4,3);
3499   #else
3500   emit_movw(addr&0x0000FFFF,1);
3501   emit_movw(((u_int)copy)&0x0000FFFF,2);
3502   emit_movt(addr&0xFFFF0000,1);
3503   emit_movt(((u_int)copy)&0xFFFF0000,2);
3504   emit_movw(slen*4,3);
3505   #endif
3506   emit_movimm(start+i*4,0);
3507   emit_call((int)start<(int)0xC0000000?(int)&verify_code:(int)&verify_code_vm);
3508   int entry=(int)out;
3509   load_regs_entry(i);
3510   if(entry==(int)out) entry=instr_addr[i];
3511   emit_jmp(instr_addr[i]);
3512   return entry;
3513 }
3514
3515 void do_dirty_stub_ds()
3516 {
3517   // Careful about the code output here, verify_dirty needs to parse it.
3518   #ifdef ARMv5_ONLY
3519   emit_loadlp((int)start<(int)0xC0000000?(int)source:(int)start,1);
3520   emit_loadlp((int)copy,2);
3521   emit_loadlp(slen*4,3);
3522   #else
3523   emit_movw(((int)start<(int)0xC0000000?(u_int)source:(u_int)start)&0x0000FFFF,1);
3524   emit_movw(((u_int)copy)&0x0000FFFF,2);
3525   emit_movt(((int)start<(int)0xC0000000?(u_int)source:(u_int)start)&0xFFFF0000,1);
3526   emit_movt(((u_int)copy)&0xFFFF0000,2);
3527   emit_movw(slen*4,3);
3528   #endif
3529   emit_movimm(start+1,0);
3530   emit_call((int)&verify_code_ds);
3531 }
3532
3533 do_cop1stub(int n)
3534 {
3535   literal_pool(256);
3536   assem_debug("do_cop1stub %x\n",start+stubs[n][3]*4);
3537   set_jump_target(stubs[n][1],(int)out);
3538   int i=stubs[n][3];
3539 //  int rs=stubs[n][4];
3540   struct regstat *i_regs=(struct regstat *)stubs[n][5];
3541   int ds=stubs[n][6];
3542   if(!ds) {
3543     load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty,i);
3544     //if(i_regs!=&regs[i]) printf("oops: regs[i]=%x i_regs=%x",(int)&regs[i],(int)i_regs);
3545   }
3546   //else {printf("fp exception in delay slot\n");}
3547   wb_dirtys(i_regs->regmap_entry,i_regs->was32,i_regs->wasdirty);
3548   if(regs[i].regmap_entry[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG);
3549   emit_movimm(start+(i-ds)*4,EAX); // Get PC
3550   emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG); // CHECK: is this right?  There should probably be an extra cycle...
3551   emit_jmp(ds?(int)fp_exception_ds:(int)fp_exception);
3552 }
3553
3554 #ifndef DISABLE_TLB
3555
3556 /* TLB */
3557
3558 int do_tlb_r(int s,int ar,int map,int x,int a,int shift,int c,u_int addr)
3559 {
3560   if(c) {
3561     if((signed int)addr>=(signed int)0xC0000000) {
3562       // address_generation already loaded the const
3563       emit_readword_dualindexedx4(FP,map,map);
3564     }
3565     else
3566       return -1; // No mapping