drc: try to make gte stall handling less bloaty
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / new_dynarec.c
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   Mupen64plus - new_dynarec.c                                           *
3  *   Copyright (C) 2009-2011 Ari64                                         *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
19  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
20
21 #include <stdlib.h>
22 #include <stdint.h> //include for uint64_t
23 #include <assert.h>
24 #include <errno.h>
25 #include <sys/mman.h>
26 #ifdef __MACH__
27 #include <libkern/OSCacheControl.h>
28 #endif
29 #ifdef _3DS
30 #include <3ds_utils.h>
31 #endif
32 #ifdef VITA
33 #include <psp2/kernel/sysmem.h>
34 static int sceBlock;
35 #endif
36
37 #include "new_dynarec_config.h"
38 #include "../psxhle.h"
39 #include "../psxinterpreter.h"
40 #include "../gte.h"
41 #include "emu_if.h" // emulator interface
42
43 #define noinline __attribute__((noinline,noclone))
44 #ifndef ARRAY_SIZE
45 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
46 #endif
47 #ifndef min
48 #define min(a, b) ((b) < (a) ? (b) : (a))
49 #endif
50
51 //#define DISASM
52 //#define assem_debug printf
53 //#define inv_debug printf
54 #define assem_debug(...)
55 #define inv_debug(...)
56
57 #ifdef __i386__
58 #include "assem_x86.h"
59 #endif
60 #ifdef __x86_64__
61 #include "assem_x64.h"
62 #endif
63 #ifdef __arm__
64 #include "assem_arm.h"
65 #endif
66 #ifdef __aarch64__
67 #include "assem_arm64.h"
68 #endif
69
70 #define RAM_SIZE 0x200000
71 #define MAXBLOCK 4096
72 #define MAX_OUTPUT_BLOCK_SIZE 262144
73
74 struct ndrc_mem
75 {
76   u_char translation_cache[1 << TARGET_SIZE_2];
77   struct
78   {
79     struct tramp_insns ops[2048 / sizeof(struct tramp_insns)];
80     const void *f[2048 / sizeof(void *)];
81   } tramp;
82 };
83
84 #ifdef BASE_ADDR_DYNAMIC
85 static struct ndrc_mem *ndrc;
86 #else
87 static struct ndrc_mem ndrc_ __attribute__((aligned(4096)));
88 static struct ndrc_mem *ndrc = &ndrc_;
89 #endif
90
91 // stubs
92 enum stub_type {
93   CC_STUB = 1,
94   FP_STUB = 2,
95   LOADB_STUB = 3,
96   LOADH_STUB = 4,
97   LOADW_STUB = 5,
98   LOADD_STUB = 6,
99   LOADBU_STUB = 7,
100   LOADHU_STUB = 8,
101   STOREB_STUB = 9,
102   STOREH_STUB = 10,
103   STOREW_STUB = 11,
104   STORED_STUB = 12,
105   STORELR_STUB = 13,
106   INVCODE_STUB = 14,
107 };
108
109 struct regstat
110 {
111   signed char regmap_entry[HOST_REGS];
112   signed char regmap[HOST_REGS];
113   uint64_t wasdirty;
114   uint64_t dirty;
115   uint64_t u;
116   u_int wasconst;
117   u_int isconst;
118   u_int loadedconst;             // host regs that have constants loaded
119   u_int waswritten;              // MIPS regs that were used as store base before
120 };
121
122 // note: asm depends on this layout
123 struct ll_entry
124 {
125   u_int vaddr;
126   u_int reg_sv_flags;
127   void *addr;
128   struct ll_entry *next;
129 };
130
131 struct ht_entry
132 {
133   u_int vaddr[2];
134   void *tcaddr[2];
135 };
136
137 struct code_stub
138 {
139   enum stub_type type;
140   void *addr;
141   void *retaddr;
142   u_int a;
143   uintptr_t b;
144   uintptr_t c;
145   u_int d;
146   u_int e;
147 };
148
149 struct link_entry
150 {
151   void *addr;
152   u_int target;
153   u_int ext;
154 };
155
156   // used by asm:
157   u_char *out;
158   struct ht_entry hash_table[65536]  __attribute__((aligned(16)));
159   struct ll_entry *jump_in[4096] __attribute__((aligned(16)));
160   struct ll_entry *jump_dirty[4096];
161
162   static struct ll_entry *jump_out[4096];
163   static u_int start;
164   static u_int *source;
165   static char insn[MAXBLOCK][10];
166   static u_char itype[MAXBLOCK];
167   static u_char opcode[MAXBLOCK];
168   static u_char opcode2[MAXBLOCK];
169   static u_char bt[MAXBLOCK];
170   static u_char rs1[MAXBLOCK];
171   static u_char rs2[MAXBLOCK];
172   static u_char rt1[MAXBLOCK];
173   static u_char rt2[MAXBLOCK];
174   static u_char dep1[MAXBLOCK];
175   static u_char dep2[MAXBLOCK];
176   static u_char lt1[MAXBLOCK];
177   static uint64_t gte_rs[MAXBLOCK]; // gte: 32 data and 32 ctl regs
178   static uint64_t gte_rt[MAXBLOCK];
179   static uint64_t gte_unneeded[MAXBLOCK];
180   static u_int smrv[32]; // speculated MIPS register values
181   static u_int smrv_strong; // mask or regs that are likely to have correct values
182   static u_int smrv_weak; // same, but somewhat less likely
183   static u_int smrv_strong_next; // same, but after current insn executes
184   static u_int smrv_weak_next;
185   static int imm[MAXBLOCK];
186   static u_int ba[MAXBLOCK];
187   static char likely[MAXBLOCK];
188   static char is_ds[MAXBLOCK];
189   static char ooo[MAXBLOCK];
190   static uint64_t unneeded_reg[MAXBLOCK];
191   static uint64_t branch_unneeded_reg[MAXBLOCK];
192   static signed char regmap_pre[MAXBLOCK][HOST_REGS]; // pre-instruction i?
193   // contains 'real' consts at [i] insn, but may differ from what's actually
194   // loaded in host reg as 'final' value is always loaded, see get_final_value()
195   static uint32_t current_constmap[HOST_REGS];
196   static uint32_t constmap[MAXBLOCK][HOST_REGS];
197   static struct regstat regs[MAXBLOCK];
198   static struct regstat branch_regs[MAXBLOCK];
199   static signed char minimum_free_regs[MAXBLOCK];
200   static u_int needed_reg[MAXBLOCK];
201   static u_int wont_dirty[MAXBLOCK];
202   static u_int will_dirty[MAXBLOCK];
203   static int ccadj[MAXBLOCK];
204   static int slen;
205   static void *instr_addr[MAXBLOCK];
206   static struct link_entry link_addr[MAXBLOCK];
207   static int linkcount;
208   static struct code_stub stubs[MAXBLOCK*3];
209   static int stubcount;
210   static u_int literals[1024][2];
211   static int literalcount;
212   static int is_delayslot;
213   static char shadow[1048576]  __attribute__((aligned(16)));
214   static void *copy;
215   static int expirep;
216   static u_int stop_after_jal;
217 #ifndef RAM_FIXED
218   static uintptr_t ram_offset;
219 #else
220   static const uintptr_t ram_offset=0;
221 #endif
222
223   int new_dynarec_hacks;
224   int new_dynarec_hacks_pergame;
225   int new_dynarec_did_compile;
226
227   #define HACK_ENABLED(x) ((new_dynarec_hacks | new_dynarec_hacks_pergame) & (x))
228
229   extern int cycle_count; // ... until end of the timeslice, counts -N -> 0
230   extern int last_count;  // last absolute target, often = next_interupt
231   extern int pcaddr;
232   extern int pending_exception;
233   extern int branch_target;
234   extern uintptr_t mini_ht[32][2];
235   extern u_char restore_candidate[512];
236
237   /* registers that may be allocated */
238   /* 1-31 gpr */
239 #define LOREG 32 // lo
240 #define HIREG 33 // hi
241 //#define FSREG 34 // FPU status (FCSR)
242 #define CSREG 35 // Coprocessor status
243 #define CCREG 36 // Cycle count
244 #define INVCP 37 // Pointer to invalid_code
245 //#define MMREG 38 // Pointer to memory_map
246 //#define ROREG 39 // ram offset (if rdram!=0x80000000)
247 #define TEMPREG 40
248 #define FTEMP 40 // FPU temporary register
249 #define PTEMP 41 // Prefetch temporary register
250 //#define TLREG 42 // TLB mapping offset
251 #define RHASH 43 // Return address hash
252 #define RHTBL 44 // Return address hash table address
253 #define RTEMP 45 // JR/JALR address register
254 #define MAXREG 45
255 #define AGEN1 46 // Address generation temporary register
256 //#define AGEN2 47 // Address generation temporary register
257 //#define MGEN1 48 // Maptable address generation temporary register
258 //#define MGEN2 49 // Maptable address generation temporary register
259 #define BTREG 50 // Branch target temporary register
260
261   /* instruction types */
262 #define NOP 0     // No operation
263 #define LOAD 1    // Load
264 #define STORE 2   // Store
265 #define LOADLR 3  // Unaligned load
266 #define STORELR 4 // Unaligned store
267 #define MOV 5     // Move
268 #define ALU 6     // Arithmetic/logic
269 #define MULTDIV 7 // Multiply/divide
270 #define SHIFT 8   // Shift by register
271 #define SHIFTIMM 9// Shift by immediate
272 #define IMM16 10  // 16-bit immediate
273 #define RJUMP 11  // Unconditional jump to register
274 #define UJUMP 12  // Unconditional jump
275 #define CJUMP 13  // Conditional branch (BEQ/BNE/BGTZ/BLEZ)
276 #define SJUMP 14  // Conditional branch (regimm format)
277 #define COP0 15   // Coprocessor 0
278 #define COP1 16   // Coprocessor 1
279 #define C1LS 17   // Coprocessor 1 load/store
280 //#define FJUMP 18  // Conditional branch (floating point)
281 //#define FLOAT 19  // Floating point unit
282 //#define FCONV 20  // Convert integer to float
283 //#define FCOMP 21  // Floating point compare (sets FSREG)
284 #define SYSCALL 22// SYSCALL
285 #define OTHER 23  // Other
286 #define SPAN 24   // Branch/delay slot spans 2 pages
287 #define NI 25     // Not implemented
288 #define HLECALL 26// PCSX fake opcodes for HLE
289 #define COP2 27   // Coprocessor 2 move
290 #define C2LS 28   // Coprocessor 2 load/store
291 #define C2OP 29   // Coprocessor 2 operation
292 #define INTCALL 30// Call interpreter to handle rare corner cases
293
294   /* branch codes */
295 #define TAKEN 1
296 #define NOTTAKEN 2
297 #define NULLDS 3
298
299 #define DJT_1 (void *)1l // no function, just a label in assem_debug log
300 #define DJT_2 (void *)2l
301
302 // asm linkage
303 int new_recompile_block(u_int addr);
304 void *get_addr_ht(u_int vaddr);
305 void invalidate_block(u_int block);
306 void invalidate_addr(u_int addr);
307 void remove_hash(int vaddr);
308 void dyna_linker();
309 void dyna_linker_ds();
310 void verify_code();
311 void verify_code_ds();
312 void cc_interrupt();
313 void fp_exception();
314 void fp_exception_ds();
315 void jump_to_new_pc();
316 void call_gteStall();
317 void new_dyna_leave();
318
319 // Needed by assembler
320 static void wb_register(signed char r,signed char regmap[],uint64_t dirty);
321 static void wb_dirtys(signed char i_regmap[],uint64_t i_dirty);
322 static void wb_needed_dirtys(signed char i_regmap[],uint64_t i_dirty,int addr);
323 static void load_all_regs(signed char i_regmap[]);
324 static void load_needed_regs(signed char i_regmap[],signed char next_regmap[]);
325 static void load_regs_entry(int t);
326 static void load_all_consts(signed char regmap[],u_int dirty,int i);
327 static u_int get_host_reglist(const signed char *regmap);
328
329 static int verify_dirty(const u_int *ptr);
330 static int get_final_value(int hr, int i, int *value);
331 static void add_stub(enum stub_type type, void *addr, void *retaddr,
332   u_int a, uintptr_t b, uintptr_t c, u_int d, u_int e);
333 static void add_stub_r(enum stub_type type, void *addr, void *retaddr,
334   int i, int addr_reg, const struct regstat *i_regs, int ccadj, u_int reglist);
335 static void add_to_linker(void *addr, u_int target, int ext);
336 static void *emit_fastpath_cmp_jump(int i,int addr,int *addr_reg_override);
337 static void *get_direct_memhandler(void *table, u_int addr,
338   enum stub_type type, uintptr_t *addr_host);
339 static void cop2_call_stall_check(u_int op, int i, const struct regstat *i_regs, u_int reglist);
340 static void pass_args(int a0, int a1);
341 static void emit_far_jump(const void *f);
342 static void emit_far_call(const void *f);
343
344 static void mprotect_w_x(void *start, void *end, int is_x)
345 {
346 #ifdef NO_WRITE_EXEC
347   #if defined(VITA)
348   // *Open* enables write on all memory that was
349   // allocated by sceKernelAllocMemBlockForVM()?
350   if (is_x)
351     sceKernelCloseVMDomain();
352   else
353     sceKernelOpenVMDomain();
354   #else
355   u_long mstart = (u_long)start & ~4095ul;
356   u_long mend = (u_long)end;
357   if (mprotect((void *)mstart, mend - mstart,
358                PROT_READ | (is_x ? PROT_EXEC : PROT_WRITE)) != 0)
359     SysPrintf("mprotect(%c) failed: %s\n", is_x ? 'x' : 'w', strerror(errno));
360   #endif
361 #endif
362 }
363
364 static void start_tcache_write(void *start, void *end)
365 {
366   mprotect_w_x(start, end, 0);
367 }
368
369 static void end_tcache_write(void *start, void *end)
370 {
371 #if defined(__arm__) || defined(__aarch64__)
372   size_t len = (char *)end - (char *)start;
373   #if   defined(__BLACKBERRY_QNX__)
374   msync(start, len, MS_SYNC | MS_CACHE_ONLY | MS_INVALIDATE_ICACHE);
375   #elif defined(__MACH__)
376   sys_cache_control(kCacheFunctionPrepareForExecution, start, len);
377   #elif defined(VITA)
378   sceKernelSyncVMDomain(sceBlock, start, len);
379   #elif defined(_3DS)
380   ctr_flush_invalidate_cache();
381   #elif defined(__aarch64__)
382   // as of 2021, __clear_cache() is still broken on arm64
383   // so here is a custom one :(
384   clear_cache_arm64(start, end);
385   #else
386   __clear_cache(start, end);
387   #endif
388   (void)len;
389 #endif
390
391   mprotect_w_x(start, end, 1);
392 }
393
394 static void *start_block(void)
395 {
396   u_char *end = out + MAX_OUTPUT_BLOCK_SIZE;
397   if (end > ndrc->translation_cache + sizeof(ndrc->translation_cache))
398     end = ndrc->translation_cache + sizeof(ndrc->translation_cache);
399   start_tcache_write(out, end);
400   return out;
401 }
402
403 static void end_block(void *start)
404 {
405   end_tcache_write(start, out);
406 }
407
408 // also takes care of w^x mappings when patching code
409 static u_int needs_clear_cache[1<<(TARGET_SIZE_2-17)];
410
411 static void mark_clear_cache(void *target)
412 {
413   uintptr_t offset = (u_char *)target - ndrc->translation_cache;
414   u_int mask = 1u << ((offset >> 12) & 31);
415   if (!(needs_clear_cache[offset >> 17] & mask)) {
416     char *start = (char *)((uintptr_t)target & ~4095l);
417     start_tcache_write(start, start + 4095);
418     needs_clear_cache[offset >> 17] |= mask;
419   }
420 }
421
422 // Clearing the cache is rather slow on ARM Linux, so mark the areas
423 // that need to be cleared, and then only clear these areas once.
424 static void do_clear_cache(void)
425 {
426   int i, j;
427   for (i = 0; i < (1<<(TARGET_SIZE_2-17)); i++)
428   {
429     u_int bitmap = needs_clear_cache[i];
430     if (!bitmap)
431       continue;
432     for (j = 0; j < 32; j++)
433     {
434       u_char *start, *end;
435       if (!(bitmap & (1<<j)))
436         continue;
437
438       start = ndrc->translation_cache + i*131072 + j*4096;
439       end = start + 4095;
440       for (j++; j < 32; j++) {
441         if (!(bitmap & (1<<j)))
442           break;
443         end += 4096;
444       }
445       end_tcache_write(start, end);
446     }
447     needs_clear_cache[i] = 0;
448   }
449 }
450
451 //#define DEBUG_CYCLE_COUNT 1
452
453 #define NO_CYCLE_PENALTY_THR 12
454
455 int cycle_multiplier; // 100 for 1.0
456 int cycle_multiplier_override;
457
458 static int CLOCK_ADJUST(int x)
459 {
460   int m = cycle_multiplier_override
461         ? cycle_multiplier_override : cycle_multiplier;
462   int s=(x>>31)|1;
463   return (x * m + s * 50) / 100;
464 }
465
466 // is the op an unconditional jump?
467 static int is_ujump(int i)
468 {
469   return itype[i] == UJUMP || itype[i] == RJUMP
470     || (source[i] >> 16) == 0x1000; // beq r0, r0, offset // b offset
471 }
472
473 static int is_jump(int i)
474 {
475   return itype[i] == RJUMP || itype[i] == UJUMP || itype[i] == CJUMP || itype[i] == SJUMP;
476 }
477
478 static u_int get_page(u_int vaddr)
479 {
480   u_int page=vaddr&~0xe0000000;
481   if (page < 0x1000000)
482     page &= ~0x0e00000; // RAM mirrors
483   page>>=12;
484   if(page>2048) page=2048+(page&2047);
485   return page;
486 }
487
488 // no virtual mem in PCSX
489 static u_int get_vpage(u_int vaddr)
490 {
491   return get_page(vaddr);
492 }
493
494 static struct ht_entry *hash_table_get(u_int vaddr)
495 {
496   return &hash_table[((vaddr>>16)^vaddr)&0xFFFF];
497 }
498
499 static void hash_table_add(struct ht_entry *ht_bin, u_int vaddr, void *tcaddr)
500 {
501   ht_bin->vaddr[1] = ht_bin->vaddr[0];
502   ht_bin->tcaddr[1] = ht_bin->tcaddr[0];
503   ht_bin->vaddr[0] = vaddr;
504   ht_bin->tcaddr[0] = tcaddr;
505 }
506
507 // some messy ari64's code, seems to rely on unsigned 32bit overflow
508 static int doesnt_expire_soon(void *tcaddr)
509 {
510   u_int diff = (u_int)((u_char *)tcaddr - out) << (32-TARGET_SIZE_2);
511   return diff > (u_int)(0x60000000 + (MAX_OUTPUT_BLOCK_SIZE << (32-TARGET_SIZE_2)));
512 }
513
514 // Get address from virtual address
515 // This is called from the recompiled JR/JALR instructions
516 void noinline *get_addr(u_int vaddr)
517 {
518   u_int page=get_page(vaddr);
519   u_int vpage=get_vpage(vaddr);
520   struct ll_entry *head;
521   //printf("TRACE: count=%d next=%d (get_addr %x,page %d)\n",Count,next_interupt,vaddr,page);
522   head=jump_in[page];
523   while(head!=NULL) {
524     if(head->vaddr==vaddr) {
525   //printf("TRACE: count=%d next=%d (get_addr match %x: %p)\n",Count,next_interupt,vaddr,head->addr);
526       hash_table_add(hash_table_get(vaddr), vaddr, head->addr);
527       return head->addr;
528     }
529     head=head->next;
530   }
531   head=jump_dirty[vpage];
532   while(head!=NULL) {
533     if(head->vaddr==vaddr) {
534       //printf("TRACE: count=%d next=%d (get_addr match dirty %x: %p)\n",Count,next_interupt,vaddr,head->addr);
535       // Don't restore blocks which are about to expire from the cache
536       if (doesnt_expire_soon(head->addr))
537       if (verify_dirty(head->addr)) {
538         //printf("restore candidate: %x (%d) d=%d\n",vaddr,page,invalid_code[vaddr>>12]);
539         invalid_code[vaddr>>12]=0;
540         inv_code_start=inv_code_end=~0;
541         if(vpage<2048) {
542           restore_candidate[vpage>>3]|=1<<(vpage&7);
543         }
544         else restore_candidate[page>>3]|=1<<(page&7);
545         struct ht_entry *ht_bin = hash_table_get(vaddr);
546         if (ht_bin->vaddr[0] == vaddr)
547           ht_bin->tcaddr[0] = head->addr; // Replace existing entry
548         else
549           hash_table_add(ht_bin, vaddr, head->addr);
550
551         return head->addr;
552       }
553     }
554     head=head->next;
555   }
556   //printf("TRACE: count=%d next=%d (get_addr no-match %x)\n",Count,next_interupt,vaddr);
557   int r=new_recompile_block(vaddr);
558   if(r==0) return get_addr(vaddr);
559   // Execute in unmapped page, generate pagefault execption
560   Status|=2;
561   Cause=(vaddr<<31)|0x8;
562   EPC=(vaddr&1)?vaddr-5:vaddr;
563   BadVAddr=(vaddr&~1);
564   Context=(Context&0xFF80000F)|((BadVAddr>>9)&0x007FFFF0);
565   EntryHi=BadVAddr&0xFFFFE000;
566   return get_addr_ht(0x80000000);
567 }
568 // Look up address in hash table first
569 void *get_addr_ht(u_int vaddr)
570 {
571   //printf("TRACE: count=%d next=%d (get_addr_ht %x)\n",Count,next_interupt,vaddr);
572   const struct ht_entry *ht_bin = hash_table_get(vaddr);
573   if (ht_bin->vaddr[0] == vaddr) return ht_bin->tcaddr[0];
574   if (ht_bin->vaddr[1] == vaddr) return ht_bin->tcaddr[1];
575   return get_addr(vaddr);
576 }
577
578 void clear_all_regs(signed char regmap[])
579 {
580   int hr;
581   for (hr=0;hr<HOST_REGS;hr++) regmap[hr]=-1;
582 }
583
584 static signed char get_reg(const signed char regmap[],int r)
585 {
586   int hr;
587   for (hr=0;hr<HOST_REGS;hr++) if(hr!=EXCLUDE_REG&&regmap[hr]==r) return hr;
588   return -1;
589 }
590
591 // Find a register that is available for two consecutive cycles
592 static signed char get_reg2(signed char regmap1[], const signed char regmap2[], int r)
593 {
594   int hr;
595   for (hr=0;hr<HOST_REGS;hr++) if(hr!=EXCLUDE_REG&&regmap1[hr]==r&&regmap2[hr]==r) return hr;
596   return -1;
597 }
598
599 int count_free_regs(signed char regmap[])
600 {
601   int count=0;
602   int hr;
603   for(hr=0;hr<HOST_REGS;hr++)
604   {
605     if(hr!=EXCLUDE_REG) {
606       if(regmap[hr]<0) count++;
607     }
608   }
609   return count;
610 }
611
612 void dirty_reg(struct regstat *cur,signed char reg)
613 {
614   int hr;
615   if(!reg) return;
616   for (hr=0;hr<HOST_REGS;hr++) {
617     if((cur->regmap[hr]&63)==reg) {
618       cur->dirty|=1<<hr;
619     }
620   }
621 }
622
623 static void set_const(struct regstat *cur, signed char reg, uint32_t value)
624 {
625   int hr;
626   if(!reg) return;
627   for (hr=0;hr<HOST_REGS;hr++) {
628     if(cur->regmap[hr]==reg) {
629       cur->isconst|=1<<hr;
630       current_constmap[hr]=value;
631     }
632   }
633 }
634
635 static void clear_const(struct regstat *cur, signed char reg)
636 {
637   int hr;
638   if(!reg) return;
639   for (hr=0;hr<HOST_REGS;hr++) {
640     if((cur->regmap[hr]&63)==reg) {
641       cur->isconst&=~(1<<hr);
642     }
643   }
644 }
645
646 static int is_const(struct regstat *cur, signed char reg)
647 {
648   int hr;
649   if(reg<0) return 0;
650   if(!reg) return 1;
651   for (hr=0;hr<HOST_REGS;hr++) {
652     if((cur->regmap[hr]&63)==reg) {
653       return (cur->isconst>>hr)&1;
654     }
655   }
656   return 0;
657 }
658
659 static uint32_t get_const(struct regstat *cur, signed char reg)
660 {
661   int hr;
662   if(!reg) return 0;
663   for (hr=0;hr<HOST_REGS;hr++) {
664     if(cur->regmap[hr]==reg) {
665       return current_constmap[hr];
666     }
667   }
668   SysPrintf("Unknown constant in r%d\n",reg);
669   abort();
670 }
671
672 // Least soon needed registers
673 // Look at the next ten instructions and see which registers
674 // will be used.  Try not to reallocate these.
675 void lsn(u_char hsn[], int i, int *preferred_reg)
676 {
677   int j;
678   int b=-1;
679   for(j=0;j<9;j++)
680   {
681     if(i+j>=slen) {
682       j=slen-i-1;
683       break;
684     }
685     if (is_ujump(i+j))
686     {
687       // Don't go past an unconditonal jump
688       j++;
689       break;
690     }
691   }
692   for(;j>=0;j--)
693   {
694     if(rs1[i+j]) hsn[rs1[i+j]]=j;
695     if(rs2[i+j]) hsn[rs2[i+j]]=j;
696     if(rt1[i+j]) hsn[rt1[i+j]]=j;
697     if(rt2[i+j]) hsn[rt2[i+j]]=j;
698     if(itype[i+j]==STORE || itype[i+j]==STORELR) {
699       // Stores can allocate zero
700       hsn[rs1[i+j]]=j;
701       hsn[rs2[i+j]]=j;
702     }
703     // On some architectures stores need invc_ptr
704     #if defined(HOST_IMM8)
705     if(itype[i+j]==STORE || itype[i+j]==STORELR || (opcode[i+j]&0x3b)==0x39 || (opcode[i+j]&0x3b)==0x3a) {
706       hsn[INVCP]=j;
707     }
708     #endif
709     if(i+j>=0&&(itype[i+j]==UJUMP||itype[i+j]==CJUMP||itype[i+j]==SJUMP))
710     {
711       hsn[CCREG]=j;
712       b=j;
713     }
714   }
715   if(b>=0)
716   {
717     if(ba[i+b]>=start && ba[i+b]<(start+slen*4))
718     {
719       // Follow first branch
720       int t=(ba[i+b]-start)>>2;
721       j=7-b;if(t+j>=slen) j=slen-t-1;
722       for(;j>=0;j--)
723       {
724         if(rs1[t+j]) if(hsn[rs1[t+j]]>j+b+2) hsn[rs1[t+j]]=j+b+2;
725         if(rs2[t+j]) if(hsn[rs2[t+j]]>j+b+2) hsn[rs2[t+j]]=j+b+2;
726         //if(rt1[t+j]) if(hsn[rt1[t+j]]>j+b+2) hsn[rt1[t+j]]=j+b+2;
727         //if(rt2[t+j]) if(hsn[rt2[t+j]]>j+b+2) hsn[rt2[t+j]]=j+b+2;
728       }
729     }
730     // TODO: preferred register based on backward branch
731   }
732   // Delay slot should preferably not overwrite branch conditions or cycle count
733   if (i > 0 && is_jump(i-1)) {
734     if(rs1[i-1]) if(hsn[rs1[i-1]]>1) hsn[rs1[i-1]]=1;
735     if(rs2[i-1]) if(hsn[rs2[i-1]]>1) hsn[rs2[i-1]]=1;
736     hsn[CCREG]=1;
737     // ...or hash tables
738     hsn[RHASH]=1;
739     hsn[RHTBL]=1;
740   }
741   // Coprocessor load/store needs FTEMP, even if not declared
742   if(itype[i]==C1LS||itype[i]==C2LS) {
743     hsn[FTEMP]=0;
744   }
745   // Load L/R also uses FTEMP as a temporary register
746   if(itype[i]==LOADLR) {
747     hsn[FTEMP]=0;
748   }
749   // Also SWL/SWR/SDL/SDR
750   if(opcode[i]==0x2a||opcode[i]==0x2e||opcode[i]==0x2c||opcode[i]==0x2d) {
751     hsn[FTEMP]=0;
752   }
753   // Don't remove the miniht registers
754   if(itype[i]==UJUMP||itype[i]==RJUMP)
755   {
756     hsn[RHASH]=0;
757     hsn[RHTBL]=0;
758   }
759 }
760
761 // We only want to allocate registers if we're going to use them again soon
762 int needed_again(int r, int i)
763 {
764   int j;
765   int b=-1;
766   int rn=10;
767
768   if (i > 0 && is_ujump(i-1))
769   {
770     if(ba[i-1]<start || ba[i-1]>start+slen*4-4)
771       return 0; // Don't need any registers if exiting the block
772   }
773   for(j=0;j<9;j++)
774   {
775     if(i+j>=slen) {
776       j=slen-i-1;
777       break;
778     }
779     if (is_ujump(i+j))
780     {
781       // Don't go past an unconditonal jump
782       j++;
783       break;
784     }
785     if(itype[i+j]==SYSCALL||itype[i+j]==HLECALL||itype[i+j]==INTCALL||((source[i+j]&0xfc00003f)==0x0d))
786     {
787       break;
788     }
789   }
790   for(;j>=1;j--)
791   {
792     if(rs1[i+j]==r) rn=j;
793     if(rs2[i+j]==r) rn=j;
794     if((unneeded_reg[i+j]>>r)&1) rn=10;
795     if(i+j>=0&&(itype[i+j]==UJUMP||itype[i+j]==CJUMP||itype[i+j]==SJUMP))
796     {
797       b=j;
798     }
799   }
800   /*
801   if(b>=0)
802   {
803     if(ba[i+b]>=start && ba[i+b]<(start+slen*4))
804     {
805       // Follow first branch
806       int o=rn;
807       int t=(ba[i+b]-start)>>2;
808       j=7-b;if(t+j>=slen) j=slen-t-1;
809       for(;j>=0;j--)
810       {
811         if(!((unneeded_reg[t+j]>>r)&1)) {
812           if(rs1[t+j]==r) if(rn>j+b+2) rn=j+b+2;
813           if(rs2[t+j]==r) if(rn>j+b+2) rn=j+b+2;
814         }
815         else rn=o;
816       }
817     }
818   }*/
819   if(rn<10) return 1;
820   (void)b;
821   return 0;
822 }
823
824 // Try to match register allocations at the end of a loop with those
825 // at the beginning
826 int loop_reg(int i, int r, int hr)
827 {
828   int j,k;
829   for(j=0;j<9;j++)
830   {
831     if(i+j>=slen) {
832       j=slen-i-1;
833       break;
834     }
835     if (is_ujump(i+j))
836     {
837       // Don't go past an unconditonal jump
838       j++;
839       break;
840     }
841   }
842   k=0;
843   if(i>0){
844     if(itype[i-1]==UJUMP||itype[i-1]==CJUMP||itype[i-1]==SJUMP)
845       k--;
846   }
847   for(;k<j;k++)
848   {
849     assert(r < 64);
850     if((unneeded_reg[i+k]>>r)&1) return hr;
851     if(i+k>=0&&(itype[i+k]==UJUMP||itype[i+k]==CJUMP||itype[i+k]==SJUMP))
852     {
853       if(ba[i+k]>=start && ba[i+k]<(start+i*4))
854       {
855         int t=(ba[i+k]-start)>>2;
856         int reg=get_reg(regs[t].regmap_entry,r);
857         if(reg>=0) return reg;
858         //reg=get_reg(regs[t+1].regmap_entry,r);
859         //if(reg>=0) return reg;
860       }
861     }
862   }
863   return hr;
864 }
865
866
867 // Allocate every register, preserving source/target regs
868 void alloc_all(struct regstat *cur,int i)
869 {
870   int hr;
871
872   for(hr=0;hr<HOST_REGS;hr++) {
873     if(hr!=EXCLUDE_REG) {
874       if(((cur->regmap[hr]&63)!=rs1[i])&&((cur->regmap[hr]&63)!=rs2[i])&&
875          ((cur->regmap[hr]&63)!=rt1[i])&&((cur->regmap[hr]&63)!=rt2[i]))
876       {
877         cur->regmap[hr]=-1;
878         cur->dirty&=~(1<<hr);
879       }
880       // Don't need zeros
881       if((cur->regmap[hr]&63)==0)
882       {
883         cur->regmap[hr]=-1;
884         cur->dirty&=~(1<<hr);
885       }
886     }
887   }
888 }
889
890 #ifndef NDEBUG
891 static int host_tempreg_in_use;
892
893 static void host_tempreg_acquire(void)
894 {
895   assert(!host_tempreg_in_use);
896   host_tempreg_in_use = 1;
897 }
898
899 static void host_tempreg_release(void)
900 {
901   host_tempreg_in_use = 0;
902 }
903 #else
904 static void host_tempreg_acquire(void) {}
905 static void host_tempreg_release(void) {}
906 #endif
907
908 #ifdef DRC_DBG
909 extern void gen_interupt();
910 extern void do_insn_cmp();
911 #define FUNCNAME(f) { f, " " #f }
912 static const struct {
913   void *addr;
914   const char *name;
915 } function_names[] = {
916   FUNCNAME(cc_interrupt),
917   FUNCNAME(gen_interupt),
918   FUNCNAME(get_addr_ht),
919   FUNCNAME(get_addr),
920   FUNCNAME(jump_handler_read8),
921   FUNCNAME(jump_handler_read16),
922   FUNCNAME(jump_handler_read32),
923   FUNCNAME(jump_handler_write8),
924   FUNCNAME(jump_handler_write16),
925   FUNCNAME(jump_handler_write32),
926   FUNCNAME(invalidate_addr),
927   FUNCNAME(jump_to_new_pc),
928   FUNCNAME(call_gteStall),
929   FUNCNAME(new_dyna_leave),
930   FUNCNAME(pcsx_mtc0),
931   FUNCNAME(pcsx_mtc0_ds),
932   FUNCNAME(do_insn_cmp),
933 #ifdef __arm__
934   FUNCNAME(verify_code),
935 #endif
936 };
937
938 static const char *func_name(const void *a)
939 {
940   int i;
941   for (i = 0; i < sizeof(function_names)/sizeof(function_names[0]); i++)
942     if (function_names[i].addr == a)
943       return function_names[i].name;
944   return "";
945 }
946 #else
947 #define func_name(x) ""
948 #endif
949
950 #ifdef __i386__
951 #include "assem_x86.c"
952 #endif
953 #ifdef __x86_64__
954 #include "assem_x64.c"
955 #endif
956 #ifdef __arm__
957 #include "assem_arm.c"
958 #endif
959 #ifdef __aarch64__
960 #include "assem_arm64.c"
961 #endif
962
963 static void *get_trampoline(const void *f)
964 {
965   size_t i;
966
967   for (i = 0; i < ARRAY_SIZE(ndrc->tramp.f); i++) {
968     if (ndrc->tramp.f[i] == f || ndrc->tramp.f[i] == NULL)
969       break;
970   }
971   if (i == ARRAY_SIZE(ndrc->tramp.f)) {
972     SysPrintf("trampoline table is full, last func %p\n", f);
973     abort();
974   }
975   if (ndrc->tramp.f[i] == NULL) {
976     start_tcache_write(&ndrc->tramp.f[i], &ndrc->tramp.f[i + 1]);
977     ndrc->tramp.f[i] = f;
978     end_tcache_write(&ndrc->tramp.f[i], &ndrc->tramp.f[i + 1]);
979   }
980   return &ndrc->tramp.ops[i];
981 }
982
983 static void emit_far_jump(const void *f)
984 {
985   if (can_jump_or_call(f)) {
986     emit_jmp(f);
987     return;
988   }
989
990   f = get_trampoline(f);
991   emit_jmp(f);
992 }
993
994 static void emit_far_call(const void *f)
995 {
996   if (can_jump_or_call(f)) {
997     emit_call(f);
998     return;
999   }
1000
1001   f = get_trampoline(f);
1002   emit_call(f);
1003 }
1004
1005 // Add virtual address mapping to linked list
1006 void ll_add(struct ll_entry **head,int vaddr,void *addr)
1007 {
1008   struct ll_entry *new_entry;
1009   new_entry=malloc(sizeof(struct ll_entry));
1010   assert(new_entry!=NULL);
1011   new_entry->vaddr=vaddr;
1012   new_entry->reg_sv_flags=0;
1013   new_entry->addr=addr;
1014   new_entry->next=*head;
1015   *head=new_entry;
1016 }
1017
1018 void ll_add_flags(struct ll_entry **head,int vaddr,u_int reg_sv_flags,void *addr)
1019 {
1020   ll_add(head,vaddr,addr);
1021   (*head)->reg_sv_flags=reg_sv_flags;
1022 }
1023
1024 // Check if an address is already compiled
1025 // but don't return addresses which are about to expire from the cache
1026 void *check_addr(u_int vaddr)
1027 {
1028   struct ht_entry *ht_bin = hash_table_get(vaddr);
1029   size_t i;
1030   for (i = 0; i < ARRAY_SIZE(ht_bin->vaddr); i++) {
1031     if (ht_bin->vaddr[i] == vaddr)
1032       if (doesnt_expire_soon((u_char *)ht_bin->tcaddr[i] - MAX_OUTPUT_BLOCK_SIZE))
1033         if (isclean(ht_bin->tcaddr[i]))
1034           return ht_bin->tcaddr[i];
1035   }
1036   u_int page=get_page(vaddr);
1037   struct ll_entry *head;
1038   head=jump_in[page];
1039   while (head != NULL) {
1040     if (head->vaddr == vaddr) {
1041       if (doesnt_expire_soon(head->addr)) {
1042         // Update existing entry with current address
1043         if (ht_bin->vaddr[0] == vaddr) {
1044           ht_bin->tcaddr[0] = head->addr;
1045           return head->addr;
1046         }
1047         if (ht_bin->vaddr[1] == vaddr) {
1048           ht_bin->tcaddr[1] = head->addr;
1049           return head->addr;
1050         }
1051         // Insert into hash table with low priority.
1052         // Don't evict existing entries, as they are probably
1053         // addresses that are being accessed frequently.
1054         if (ht_bin->vaddr[0] == -1) {
1055           ht_bin->vaddr[0] = vaddr;
1056           ht_bin->tcaddr[0] = head->addr;
1057         }
1058         else if (ht_bin->vaddr[1] == -1) {
1059           ht_bin->vaddr[1] = vaddr;
1060           ht_bin->tcaddr[1] = head->addr;
1061         }
1062         return head->addr;
1063       }
1064     }
1065     head=head->next;
1066   }
1067   return 0;
1068 }
1069
1070 void remove_hash(int vaddr)
1071 {
1072   //printf("remove hash: %x\n",vaddr);
1073   struct ht_entry *ht_bin = hash_table_get(vaddr);
1074   if (ht_bin->vaddr[1] == vaddr) {
1075     ht_bin->vaddr[1] = -1;
1076     ht_bin->tcaddr[1] = NULL;
1077   }
1078   if (ht_bin->vaddr[0] == vaddr) {
1079     ht_bin->vaddr[0] = ht_bin->vaddr[1];
1080     ht_bin->tcaddr[0] = ht_bin->tcaddr[1];
1081     ht_bin->vaddr[1] = -1;
1082     ht_bin->tcaddr[1] = NULL;
1083   }
1084 }
1085
1086 void ll_remove_matching_addrs(struct ll_entry **head,uintptr_t addr,int shift)
1087 {
1088   struct ll_entry *next;
1089   while(*head) {
1090     if(((uintptr_t)((*head)->addr)>>shift)==(addr>>shift) ||
1091        ((uintptr_t)((*head)->addr-MAX_OUTPUT_BLOCK_SIZE)>>shift)==(addr>>shift))
1092     {
1093       inv_debug("EXP: Remove pointer to %p (%x)\n",(*head)->addr,(*head)->vaddr);
1094       remove_hash((*head)->vaddr);
1095       next=(*head)->next;
1096       free(*head);
1097       *head=next;
1098     }
1099     else
1100     {
1101       head=&((*head)->next);
1102     }
1103   }
1104 }
1105
1106 // Remove all entries from linked list
1107 void ll_clear(struct ll_entry **head)
1108 {
1109   struct ll_entry *cur;
1110   struct ll_entry *next;
1111   if((cur=*head)) {
1112     *head=0;
1113     while(cur) {
1114       next=cur->next;
1115       free(cur);
1116       cur=next;
1117     }
1118   }
1119 }
1120
1121 // Dereference the pointers and remove if it matches
1122 static void ll_kill_pointers(struct ll_entry *head,uintptr_t addr,int shift)
1123 {
1124   while(head) {
1125     uintptr_t ptr = (uintptr_t)get_pointer(head->addr);
1126     inv_debug("EXP: Lookup pointer to %lx at %p (%x)\n",(long)ptr,head->addr,head->vaddr);
1127     if(((ptr>>shift)==(addr>>shift)) ||
1128        (((ptr-MAX_OUTPUT_BLOCK_SIZE)>>shift)==(addr>>shift)))
1129     {
1130       inv_debug("EXP: Kill pointer at %p (%x)\n",head->addr,head->vaddr);
1131       void *host_addr=find_extjump_insn(head->addr);
1132       mark_clear_cache(host_addr);
1133       set_jump_target(host_addr, head->addr);
1134     }
1135     head=head->next;
1136   }
1137 }
1138
1139 // This is called when we write to a compiled block (see do_invstub)
1140 static void invalidate_page(u_int page)
1141 {
1142   struct ll_entry *head;
1143   struct ll_entry *next;
1144   head=jump_in[page];
1145   jump_in[page]=0;
1146   while(head!=NULL) {
1147     inv_debug("INVALIDATE: %x\n",head->vaddr);
1148     remove_hash(head->vaddr);
1149     next=head->next;
1150     free(head);
1151     head=next;
1152   }
1153   head=jump_out[page];
1154   jump_out[page]=0;
1155   while(head!=NULL) {
1156     inv_debug("INVALIDATE: kill pointer to %x (%p)\n",head->vaddr,head->addr);
1157     void *host_addr=find_extjump_insn(head->addr);
1158     mark_clear_cache(host_addr);
1159     set_jump_target(host_addr, head->addr);
1160     next=head->next;
1161     free(head);
1162     head=next;
1163   }
1164 }
1165
1166 static void invalidate_block_range(u_int block, u_int first, u_int last)
1167 {
1168   u_int page=get_page(block<<12);
1169   //printf("first=%d last=%d\n",first,last);
1170   invalidate_page(page);
1171   assert(first+5>page); // NB: this assumes MAXBLOCK<=4096 (4 pages)
1172   assert(last<page+5);
1173   // Invalidate the adjacent pages if a block crosses a 4K boundary
1174   while(first<page) {
1175     invalidate_page(first);
1176     first++;
1177   }
1178   for(first=page+1;first<last;first++) {
1179     invalidate_page(first);
1180   }
1181   do_clear_cache();
1182
1183   // Don't trap writes
1184   invalid_code[block]=1;
1185
1186   #ifdef USE_MINI_HT
1187   memset(mini_ht,-1,sizeof(mini_ht));
1188   #endif
1189 }
1190
1191 void invalidate_block(u_int block)
1192 {
1193   u_int page=get_page(block<<12);
1194   u_int vpage=get_vpage(block<<12);
1195   inv_debug("INVALIDATE: %x (%d)\n",block<<12,page);
1196   //inv_debug("invalid_code[block]=%d\n",invalid_code[block]);
1197   u_int first,last;
1198   first=last=page;
1199   struct ll_entry *head;
1200   head=jump_dirty[vpage];
1201   //printf("page=%d vpage=%d\n",page,vpage);
1202   while(head!=NULL) {
1203     if(vpage>2047||(head->vaddr>>12)==block) { // Ignore vaddr hash collision
1204       u_char *start, *end;
1205       get_bounds(head->addr, &start, &end);
1206       //printf("start: %p end: %p\n", start, end);
1207       if (page < 2048 && start >= rdram && end < rdram+RAM_SIZE) {
1208         if (((start-rdram)>>12) <= page && ((end-1-rdram)>>12) >= page) {
1209           if ((((start-rdram)>>12)&2047) < first) first = ((start-rdram)>>12)&2047;
1210           if ((((end-1-rdram)>>12)&2047) > last)  last = ((end-1-rdram)>>12)&2047;
1211         }
1212       }
1213     }
1214     head=head->next;
1215   }
1216   invalidate_block_range(block,first,last);
1217 }
1218
1219 void invalidate_addr(u_int addr)
1220 {
1221   //static int rhits;
1222   // this check is done by the caller
1223   //if (inv_code_start<=addr&&addr<=inv_code_end) { rhits++; return; }
1224   u_int page=get_vpage(addr);
1225   if(page<2048) { // RAM
1226     struct ll_entry *head;
1227     u_int addr_min=~0, addr_max=0;
1228     u_int mask=RAM_SIZE-1;
1229     u_int addr_main=0x80000000|(addr&mask);
1230     int pg1;
1231     inv_code_start=addr_main&~0xfff;
1232     inv_code_end=addr_main|0xfff;
1233     pg1=page;
1234     if (pg1>0) {
1235       // must check previous page too because of spans..
1236       pg1--;
1237       inv_code_start-=0x1000;
1238     }
1239     for(;pg1<=page;pg1++) {
1240       for(head=jump_dirty[pg1];head!=NULL;head=head->next) {
1241         u_char *start_h, *end_h;
1242         u_int start, end;
1243         get_bounds(head->addr, &start_h, &end_h);
1244         start = (uintptr_t)start_h - ram_offset;
1245         end = (uintptr_t)end_h - ram_offset;
1246         if(start<=addr_main&&addr_main<end) {
1247           if(start<addr_min) addr_min=start;
1248           if(end>addr_max) addr_max=end;
1249         }
1250         else if(addr_main<start) {
1251           if(start<inv_code_end)
1252             inv_code_end=start-1;
1253         }
1254         else {
1255           if(end>inv_code_start)
1256             inv_code_start=end;
1257         }
1258       }
1259     }
1260     if (addr_min!=~0) {
1261       inv_debug("INV ADDR: %08x hit %08x-%08x\n", addr, addr_min, addr_max);
1262       inv_code_start=inv_code_end=~0;
1263       invalidate_block_range(addr>>12,(addr_min&mask)>>12,(addr_max&mask)>>12);
1264       return;
1265     }
1266     else {
1267       inv_code_start=(addr&~mask)|(inv_code_start&mask);
1268       inv_code_end=(addr&~mask)|(inv_code_end&mask);
1269       inv_debug("INV ADDR: %08x miss, inv %08x-%08x, sk %d\n", addr, inv_code_start, inv_code_end, 0);
1270       return;
1271     }
1272   }
1273   invalidate_block(addr>>12);
1274 }
1275
1276 // This is called when loading a save state.
1277 // Anything could have changed, so invalidate everything.
1278 void invalidate_all_pages(void)
1279 {
1280   u_int page;
1281   for(page=0;page<4096;page++)
1282     invalidate_page(page);
1283   for(page=0;page<1048576;page++)
1284     if(!invalid_code[page]) {
1285       restore_candidate[(page&2047)>>3]|=1<<(page&7);
1286       restore_candidate[((page&2047)>>3)+256]|=1<<(page&7);
1287     }
1288   #ifdef USE_MINI_HT
1289   memset(mini_ht,-1,sizeof(mini_ht));
1290   #endif
1291   do_clear_cache();
1292 }
1293
1294 static void do_invstub(int n)
1295 {
1296   literal_pool(20);
1297   u_int reglist=stubs[n].a;
1298   set_jump_target(stubs[n].addr, out);
1299   save_regs(reglist);
1300   if(stubs[n].b!=0) emit_mov(stubs[n].b,0);
1301   emit_far_call(invalidate_addr);
1302   restore_regs(reglist);
1303   emit_jmp(stubs[n].retaddr); // return address
1304 }
1305
1306 // Add an entry to jump_out after making a link
1307 // src should point to code by emit_extjump2()
1308 void add_link(u_int vaddr,void *src)
1309 {
1310   u_int page=get_page(vaddr);
1311   inv_debug("add_link: %p -> %x (%d)\n",src,vaddr,page);
1312   check_extjump2(src);
1313   ll_add(jump_out+page,vaddr,src);
1314   //void *ptr=get_pointer(src);
1315   //inv_debug("add_link: Pointer is to %p\n",ptr);
1316 }
1317
1318 // If a code block was found to be unmodified (bit was set in
1319 // restore_candidate) and it remains unmodified (bit is clear
1320 // in invalid_code) then move the entries for that 4K page from
1321 // the dirty list to the clean list.
1322 void clean_blocks(u_int page)
1323 {
1324   struct ll_entry *head;
1325   inv_debug("INV: clean_blocks page=%d\n",page);
1326   head=jump_dirty[page];
1327   while(head!=NULL) {
1328     if(!invalid_code[head->vaddr>>12]) {
1329       // Don't restore blocks which are about to expire from the cache
1330       if (doesnt_expire_soon(head->addr)) {
1331         if(verify_dirty(head->addr)) {
1332           u_char *start, *end;
1333           //printf("Possibly Restore %x (%p)\n",head->vaddr, head->addr);
1334           u_int i;
1335           u_int inv=0;
1336           get_bounds(head->addr, &start, &end);
1337           if (start - rdram < RAM_SIZE) {
1338             for (i = (start-rdram+0x80000000)>>12; i <= (end-1-rdram+0x80000000)>>12; i++) {
1339               inv|=invalid_code[i];
1340             }
1341           }
1342           else if((signed int)head->vaddr>=(signed int)0x80000000+RAM_SIZE) {
1343             inv=1;
1344           }
1345           if(!inv) {
1346             void *clean_addr = get_clean_addr(head->addr);
1347             if (doesnt_expire_soon(clean_addr)) {
1348               u_int ppage=page;
1349               inv_debug("INV: Restored %x (%p/%p)\n",head->vaddr, head->addr, clean_addr);
1350               //printf("page=%x, addr=%x\n",page,head->vaddr);
1351               //assert(head->vaddr>>12==(page|0x80000));
1352               ll_add_flags(jump_in+ppage,head->vaddr,head->reg_sv_flags,clean_addr);
1353               struct ht_entry *ht_bin = hash_table_get(head->vaddr);
1354               if (ht_bin->vaddr[0] == head->vaddr)
1355                 ht_bin->tcaddr[0] = clean_addr; // Replace existing entry
1356               if (ht_bin->vaddr[1] == head->vaddr)
1357                 ht_bin->tcaddr[1] = clean_addr; // Replace existing entry
1358             }
1359           }
1360         }
1361       }
1362     }
1363     head=head->next;
1364   }
1365 }
1366
1367 /* Register allocation */
1368
1369 // Note: registers are allocated clean (unmodified state)
1370 // if you intend to modify the register, you must call dirty_reg().
1371 static void alloc_reg(struct regstat *cur,int i,signed char reg)
1372 {
1373   int r,hr;
1374   int preferred_reg = (reg&7);
1375   if(reg==CCREG) preferred_reg=HOST_CCREG;
1376   if(reg==PTEMP||reg==FTEMP) preferred_reg=12;
1377
1378   // Don't allocate unused registers
1379   if((cur->u>>reg)&1) return;
1380
1381   // see if it's already allocated
1382   for(hr=0;hr<HOST_REGS;hr++)
1383   {
1384     if(cur->regmap[hr]==reg) return;
1385   }
1386
1387   // Keep the same mapping if the register was already allocated in a loop
1388   preferred_reg = loop_reg(i,reg,preferred_reg);
1389
1390   // Try to allocate the preferred register
1391   if(cur->regmap[preferred_reg]==-1) {
1392     cur->regmap[preferred_reg]=reg;
1393     cur->dirty&=~(1<<preferred_reg);
1394     cur->isconst&=~(1<<preferred_reg);
1395     return;
1396   }
1397   r=cur->regmap[preferred_reg];
1398   assert(r < 64);
1399   if((cur->u>>r)&1) {
1400     cur->regmap[preferred_reg]=reg;
1401     cur->dirty&=~(1<<preferred_reg);
1402     cur->isconst&=~(1<<preferred_reg);
1403     return;
1404   }
1405
1406   // Clear any unneeded registers
1407   // We try to keep the mapping consistent, if possible, because it
1408   // makes branches easier (especially loops).  So we try to allocate
1409   // first (see above) before removing old mappings.  If this is not
1410   // possible then go ahead and clear out the registers that are no
1411   // longer needed.
1412   for(hr=0;hr<HOST_REGS;hr++)
1413   {
1414     r=cur->regmap[hr];
1415     if(r>=0) {
1416       assert(r < 64);
1417       if((cur->u>>r)&1) {cur->regmap[hr]=-1;break;}
1418     }
1419   }
1420   // Try to allocate any available register, but prefer
1421   // registers that have not been used recently.
1422   if(i>0) {
1423     for(hr=0;hr<HOST_REGS;hr++) {
1424       if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) {
1425         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]) {
1426           cur->regmap[hr]=reg;
1427           cur->dirty&=~(1<<hr);
1428           cur->isconst&=~(1<<hr);
1429           return;
1430         }
1431       }
1432     }
1433   }
1434   // Try to allocate any available register
1435   for(hr=0;hr<HOST_REGS;hr++) {
1436     if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) {
1437       cur->regmap[hr]=reg;
1438       cur->dirty&=~(1<<hr);
1439       cur->isconst&=~(1<<hr);
1440       return;
1441     }
1442   }
1443
1444   // Ok, now we have to evict someone
1445   // Pick a register we hopefully won't need soon
1446   u_char hsn[MAXREG+1];
1447   memset(hsn,10,sizeof(hsn));
1448   int j;
1449   lsn(hsn,i,&preferred_reg);
1450   //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]);
1451   //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]);
1452   if(i>0) {
1453     // Don't evict the cycle count at entry points, otherwise the entry
1454     // stub will have to write it.
1455     if(bt[i]&&hsn[CCREG]>2) hsn[CCREG]=2;
1456     if(i>1&&hsn[CCREG]>2&&(itype[i-2]==RJUMP||itype[i-2]==UJUMP||itype[i-2]==CJUMP||itype[i-2]==SJUMP)) hsn[CCREG]=2;
1457     for(j=10;j>=3;j--)
1458     {
1459       // Alloc preferred register if available
1460       if(hsn[r=cur->regmap[preferred_reg]&63]==j) {
1461         for(hr=0;hr<HOST_REGS;hr++) {
1462           // Evict both parts of a 64-bit register
1463           if((cur->regmap[hr]&63)==r) {
1464             cur->regmap[hr]=-1;
1465             cur->dirty&=~(1<<hr);
1466             cur->isconst&=~(1<<hr);
1467           }
1468         }
1469         cur->regmap[preferred_reg]=reg;
1470         return;
1471       }
1472       for(r=1;r<=MAXREG;r++)
1473       {
1474         if(hsn[r]==j&&r!=rs1[i-1]&&r!=rs2[i-1]&&r!=rt1[i-1]&&r!=rt2[i-1]) {
1475           for(hr=0;hr<HOST_REGS;hr++) {
1476             if(hr!=HOST_CCREG||j<hsn[CCREG]) {
1477               if(cur->regmap[hr]==r) {
1478                 cur->regmap[hr]=reg;
1479                 cur->dirty&=~(1<<hr);
1480                 cur->isconst&=~(1<<hr);
1481                 return;
1482               }
1483             }
1484           }
1485         }
1486       }
1487     }
1488   }
1489   for(j=10;j>=0;j--)
1490   {
1491     for(r=1;r<=MAXREG;r++)
1492     {
1493       if(hsn[r]==j) {
1494         for(hr=0;hr<HOST_REGS;hr++) {
1495           if(cur->regmap[hr]==r) {
1496             cur->regmap[hr]=reg;
1497             cur->dirty&=~(1<<hr);
1498             cur->isconst&=~(1<<hr);
1499             return;
1500           }
1501         }
1502       }
1503     }
1504   }
1505   SysPrintf("This shouldn't happen (alloc_reg)");abort();
1506 }
1507
1508 // Allocate a temporary register.  This is done without regard to
1509 // dirty status or whether the register we request is on the unneeded list
1510 // Note: This will only allocate one register, even if called multiple times
1511 static void alloc_reg_temp(struct regstat *cur,int i,signed char reg)
1512 {
1513   int r,hr;
1514   int preferred_reg = -1;
1515
1516   // see if it's already allocated
1517   for(hr=0;hr<HOST_REGS;hr++)
1518   {
1519     if(hr!=EXCLUDE_REG&&cur->regmap[hr]==reg) return;
1520   }
1521
1522   // Try to allocate any available register
1523   for(hr=HOST_REGS-1;hr>=0;hr--) {
1524     if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) {
1525       cur->regmap[hr]=reg;
1526       cur->dirty&=~(1<<hr);
1527       cur->isconst&=~(1<<hr);
1528       return;
1529     }
1530   }
1531
1532   // Find an unneeded register
1533   for(hr=HOST_REGS-1;hr>=0;hr--)
1534   {
1535     r=cur->regmap[hr];
1536     if(r>=0) {
1537       assert(r < 64);
1538       if((cur->u>>r)&1) {
1539         if(i==0||((unneeded_reg[i-1]>>r)&1)) {
1540           cur->regmap[hr]=reg;
1541           cur->dirty&=~(1<<hr);
1542           cur->isconst&=~(1<<hr);
1543           return;
1544         }
1545       }
1546     }
1547   }
1548
1549   // Ok, now we have to evict someone
1550   // Pick a register we hopefully won't need soon
1551   // TODO: we might want to follow unconditional jumps here
1552   // TODO: get rid of dupe code and make this into a function
1553   u_char hsn[MAXREG+1];
1554   memset(hsn,10,sizeof(hsn));
1555   int j;
1556   lsn(hsn,i,&preferred_reg);
1557   //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]);
1558   if(i>0) {
1559     // Don't evict the cycle count at entry points, otherwise the entry
1560     // stub will have to write it.
1561     if(bt[i]&&hsn[CCREG]>2) hsn[CCREG]=2;
1562     if(i>1&&hsn[CCREG]>2&&(itype[i-2]==RJUMP||itype[i-2]==UJUMP||itype[i-2]==CJUMP||itype[i-2]==SJUMP)) hsn[CCREG]=2;
1563     for(j=10;j>=3;j--)
1564     {
1565       for(r=1;r<=MAXREG;r++)
1566       {
1567         if(hsn[r]==j&&r!=rs1[i-1]&&r!=rs2[i-1]&&r!=rt1[i-1]&&r!=rt2[i-1]) {
1568           for(hr=0;hr<HOST_REGS;hr++) {
1569             if(hr!=HOST_CCREG||hsn[CCREG]>2) {
1570               if(cur->regmap[hr]==r) {
1571                 cur->regmap[hr]=reg;
1572                 cur->dirty&=~(1<<hr);
1573                 cur->isconst&=~(1<<hr);
1574                 return;
1575               }
1576             }
1577           }
1578         }
1579       }
1580     }
1581   }
1582   for(j=10;j>=0;j--)
1583   {
1584     for(r=1;r<=MAXREG;r++)
1585     {
1586       if(hsn[r]==j) {
1587         for(hr=0;hr<HOST_REGS;hr++) {
1588           if(cur->regmap[hr]==r) {
1589             cur->regmap[hr]=reg;
1590             cur->dirty&=~(1<<hr);
1591             cur->isconst&=~(1<<hr);
1592             return;
1593           }
1594         }
1595       }
1596     }
1597   }
1598   SysPrintf("This shouldn't happen");abort();
1599 }
1600
1601 static void mov_alloc(struct regstat *current,int i)
1602 {
1603   // Note: Don't need to actually alloc the source registers
1604   //alloc_reg(current,i,rs1[i]);
1605   alloc_reg(current,i,rt1[i]);
1606
1607   clear_const(current,rs1[i]);
1608   clear_const(current,rt1[i]);
1609   dirty_reg(current,rt1[i]);
1610 }
1611
1612 static void shiftimm_alloc(struct regstat *current,int i)
1613 {
1614   if(opcode2[i]<=0x3) // SLL/SRL/SRA
1615   {
1616     if(rt1[i]) {
1617       if(rs1[i]&&needed_again(rs1[i],i)) alloc_reg(current,i,rs1[i]);
1618       else lt1[i]=rs1[i];
1619       alloc_reg(current,i,rt1[i]);
1620       dirty_reg(current,rt1[i]);
1621       if(is_const(current,rs1[i])) {
1622         int v=get_const(current,rs1[i]);
1623         if(opcode2[i]==0x00) set_const(current,rt1[i],v<<imm[i]);
1624         if(opcode2[i]==0x02) set_const(current,rt1[i],(u_int)v>>imm[i]);
1625         if(opcode2[i]==0x03) set_const(current,rt1[i],v>>imm[i]);
1626       }
1627       else clear_const(current,rt1[i]);
1628     }
1629   }
1630   else
1631   {
1632     clear_const(current,rs1[i]);
1633     clear_const(current,rt1[i]);
1634   }
1635
1636   if(opcode2[i]>=0x38&&opcode2[i]<=0x3b) // DSLL/DSRL/DSRA
1637   {
1638     assert(0);
1639   }
1640   if(opcode2[i]==0x3c) // DSLL32
1641   {
1642     assert(0);
1643   }
1644   if(opcode2[i]==0x3e) // DSRL32
1645   {
1646     assert(0);
1647   }
1648   if(opcode2[i]==0x3f) // DSRA32
1649   {
1650     assert(0);
1651   }
1652 }
1653
1654 static void shift_alloc(struct regstat *current,int i)
1655 {
1656   if(rt1[i]) {
1657     if(opcode2[i]<=0x07) // SLLV/SRLV/SRAV
1658     {
1659       if(rs1[i]) alloc_reg(current,i,rs1[i]);
1660       if(rs2[i]) alloc_reg(current,i,rs2[i]);
1661       alloc_reg(current,i,rt1[i]);
1662       if(rt1[i]==rs2[i]) {
1663         alloc_reg_temp(current,i,-1);
1664         minimum_free_regs[i]=1;
1665       }
1666     } else { // DSLLV/DSRLV/DSRAV
1667       assert(0);
1668     }
1669     clear_const(current,rs1[i]);
1670     clear_const(current,rs2[i]);
1671     clear_const(current,rt1[i]);
1672     dirty_reg(current,rt1[i]);
1673   }
1674 }
1675
1676 static void alu_alloc(struct regstat *current,int i)
1677 {
1678   if(opcode2[i]>=0x20&&opcode2[i]<=0x23) { // ADD/ADDU/SUB/SUBU
1679     if(rt1[i]) {
1680       if(rs1[i]&&rs2[i]) {
1681         alloc_reg(current,i,rs1[i]);
1682         alloc_reg(current,i,rs2[i]);
1683       }
1684       else {
1685         if(rs1[i]&&needed_again(rs1[i],i)) alloc_reg(current,i,rs1[i]);
1686         if(rs2[i]&&needed_again(rs2[i],i)) alloc_reg(current,i,rs2[i]);
1687       }
1688       alloc_reg(current,i,rt1[i]);
1689     }
1690   }
1691   if(opcode2[i]==0x2a||opcode2[i]==0x2b) { // SLT/SLTU
1692     if(rt1[i]) {
1693       alloc_reg(current,i,rs1[i]);
1694       alloc_reg(current,i,rs2[i]);
1695       alloc_reg(current,i,rt1[i]);
1696     }
1697   }
1698   if(opcode2[i]>=0x24&&opcode2[i]<=0x27) { // AND/OR/XOR/NOR
1699     if(rt1[i]) {
1700       if(rs1[i]&&rs2[i]) {
1701         alloc_reg(current,i,rs1[i]);
1702         alloc_reg(current,i,rs2[i]);
1703       }
1704       else
1705       {
1706         if(rs1[i]&&needed_again(rs1[i],i)) alloc_reg(current,i,rs1[i]);
1707         if(rs2[i]&&needed_again(rs2[i],i)) alloc_reg(current,i,rs2[i]);
1708       }
1709       alloc_reg(current,i,rt1[i]);
1710     }
1711   }
1712   if(opcode2[i]>=0x2c&&opcode2[i]<=0x2f) { // DADD/DADDU/DSUB/DSUBU
1713     assert(0);
1714   }
1715   clear_const(current,rs1[i]);
1716   clear_const(current,rs2[i]);
1717   clear_const(current,rt1[i]);
1718   dirty_reg(current,rt1[i]);
1719 }
1720
1721 static void imm16_alloc(struct regstat *current,int i)
1722 {
1723   if(rs1[i]&&needed_again(rs1[i],i)) alloc_reg(current,i,rs1[i]);
1724   else lt1[i]=rs1[i];
1725   if(rt1[i]) alloc_reg(current,i,rt1[i]);
1726   if(opcode[i]==0x18||opcode[i]==0x19) { // DADDI/DADDIU
1727     assert(0);
1728   }
1729   else if(opcode[i]==0x0a||opcode[i]==0x0b) { // SLTI/SLTIU
1730     clear_const(current,rs1[i]);
1731     clear_const(current,rt1[i]);
1732   }
1733   else if(opcode[i]>=0x0c&&opcode[i]<=0x0e) { // ANDI/ORI/XORI
1734     if(is_const(current,rs1[i])) {
1735       int v=get_const(current,rs1[i]);
1736       if(opcode[i]==0x0c) set_const(current,rt1[i],v&imm[i]);
1737       if(opcode[i]==0x0d) set_const(current,rt1[i],v|imm[i]);
1738       if(opcode[i]==0x0e) set_const(current,rt1[i],v^imm[i]);
1739     }
1740     else clear_const(current,rt1[i]);
1741   }
1742   else if(opcode[i]==0x08||opcode[i]==0x09) { // ADDI/ADDIU
1743     if(is_const(current,rs1[i])) {
1744       int v=get_const(current,rs1[i]);
1745       set_const(current,rt1[i],v+imm[i]);
1746     }
1747     else clear_const(current,rt1[i]);
1748   }
1749   else {
1750     set_const(current,rt1[i],imm[i]<<16); // LUI
1751   }
1752   dirty_reg(current,rt1[i]);
1753 }
1754
1755 static void load_alloc(struct regstat *current,int i)
1756 {
1757   clear_const(current,rt1[i]);
1758   //if(rs1[i]!=rt1[i]&&needed_again(rs1[i],i)) clear_const(current,rs1[i]); // Does this help or hurt?
1759   if(!rs1[i]) current->u&=~1LL; // Allow allocating r0 if it's the source register
1760   if(needed_again(rs1[i],i)) alloc_reg(current,i,rs1[i]);
1761   if(rt1[i]&&!((current->u>>rt1[i])&1)) {
1762     alloc_reg(current,i,rt1[i]);
1763     assert(get_reg(current->regmap,rt1[i])>=0);
1764     if(opcode[i]==0x27||opcode[i]==0x37) // LWU/LD
1765     {
1766       assert(0);
1767     }
1768     else if(opcode[i]==0x1A||opcode[i]==0x1B) // LDL/LDR
1769     {
1770       assert(0);
1771     }
1772     dirty_reg(current,rt1[i]);
1773     // LWL/LWR need a temporary register for the old value
1774     if(opcode[i]==0x22||opcode[i]==0x26)
1775     {
1776       alloc_reg(current,i,FTEMP);
1777       alloc_reg_temp(current,i,-1);
1778       minimum_free_regs[i]=1;
1779     }
1780   }
1781   else
1782   {
1783     // Load to r0 or unneeded register (dummy load)
1784     // but we still need a register to calculate the address
1785     if(opcode[i]==0x22||opcode[i]==0x26)
1786     {
1787       alloc_reg(current,i,FTEMP); // LWL/LWR need another temporary
1788     }
1789     alloc_reg_temp(current,i,-1);
1790     minimum_free_regs[i]=1;
1791     if(opcode[i]==0x1A||opcode[i]==0x1B) // LDL/LDR
1792     {
1793       assert(0);
1794     }
1795   }
1796 }
1797
1798 void store_alloc(struct regstat *current,int i)
1799 {
1800   clear_const(current,rs2[i]);
1801   if(!(rs2[i])) current->u&=~1LL; // Allow allocating r0 if necessary
1802   if(needed_again(rs1[i],i)) alloc_reg(current,i,rs1[i]);
1803   alloc_reg(current,i,rs2[i]);
1804   if(opcode[i]==0x2c||opcode[i]==0x2d||opcode[i]==0x3f) { // 64-bit SDL/SDR/SD
1805     assert(0);
1806   }
1807   #if defined(HOST_IMM8)
1808   // On CPUs without 32-bit immediates we need a pointer to invalid_code
1809   else alloc_reg(current,i,INVCP);
1810   #endif
1811   if(opcode[i]==0x2a||opcode[i]==0x2e||opcode[i]==0x2c||opcode[i]==0x2d) { // SWL/SWL/SDL/SDR
1812     alloc_reg(current,i,FTEMP);
1813   }
1814   // We need a temporary register for address generation
1815   alloc_reg_temp(current,i,-1);
1816   minimum_free_regs[i]=1;
1817 }
1818
1819 void c1ls_alloc(struct regstat *current,int i)
1820 {
1821   //clear_const(current,rs1[i]); // FIXME
1822   clear_const(current,rt1[i]);
1823   if(needed_again(rs1[i],i)) alloc_reg(current,i,rs1[i]);
1824   alloc_reg(current,i,CSREG); // Status
1825   alloc_reg(current,i,FTEMP);
1826   if(opcode[i]==0x35||opcode[i]==0x3d) { // 64-bit LDC1/SDC1
1827     assert(0);
1828   }
1829   #if defined(HOST_IMM8)
1830   // On CPUs without 32-bit immediates we need a pointer to invalid_code
1831   else if((opcode[i]&0x3b)==0x39) // SWC1/SDC1
1832     alloc_reg(current,i,INVCP);
1833   #endif
1834   // We need a temporary register for address generation
1835   alloc_reg_temp(current,i,-1);
1836 }
1837
1838 void c2ls_alloc(struct regstat *current,int i)
1839 {
1840   clear_const(current,rt1[i]);
1841   if(needed_again(rs1[i],i)) alloc_reg(current,i,rs1[i]);
1842   alloc_reg(current,i,FTEMP);
1843   #if defined(HOST_IMM8)
1844   // On CPUs without 32-bit immediates we need a pointer to invalid_code
1845   if((opcode[i]&0x3b)==0x3a) // SWC2/SDC2
1846     alloc_reg(current,i,INVCP);
1847   #endif
1848   // We need a temporary register for address generation
1849   alloc_reg_temp(current,i,-1);
1850   minimum_free_regs[i]=1;
1851 }
1852
1853 #ifndef multdiv_alloc
1854 void multdiv_alloc(struct regstat *current,int i)
1855 {
1856   //  case 0x18: MULT
1857   //  case 0x19: MULTU
1858   //  case 0x1A: DIV
1859   //  case 0x1B: DIVU
1860   //  case 0x1C: DMULT
1861   //  case 0x1D: DMULTU
1862   //  case 0x1E: DDIV
1863   //  case 0x1F: DDIVU
1864   clear_const(current,rs1[i]);
1865   clear_const(current,rs2[i]);
1866   if(rs1[i]&&rs2[i])
1867   {
1868     if((opcode2[i]&4)==0) // 32-bit
1869     {
1870       current->u&=~(1LL<<HIREG);
1871       current->u&=~(1LL<<LOREG);
1872       alloc_reg(current,i,HIREG);
1873       alloc_reg(current,i,LOREG);
1874       alloc_reg(current,i,rs1[i]);
1875       alloc_reg(current,i,rs2[i]);
1876       dirty_reg(current,HIREG);
1877       dirty_reg(current,LOREG);
1878     }
1879     else // 64-bit
1880     {
1881       assert(0);
1882     }
1883   }
1884   else
1885   {
1886     // Multiply by zero is zero.
1887     // MIPS does not have a divide by zero exception.
1888     // The result is undefined, we return zero.
1889     alloc_reg(current,i,HIREG);
1890     alloc_reg(current,i,LOREG);
1891     dirty_reg(current,HIREG);
1892     dirty_reg(current,LOREG);
1893   }
1894 }
1895 #endif
1896
1897 void cop0_alloc(struct regstat *current,int i)
1898 {
1899   if(opcode2[i]==0) // MFC0
1900   {
1901     if(rt1[i]) {
1902       clear_const(current,rt1[i]);
1903       alloc_all(current,i);
1904       alloc_reg(current,i,rt1[i]);
1905       dirty_reg(current,rt1[i]);
1906     }
1907   }
1908   else if(opcode2[i]==4) // MTC0
1909   {
1910     if(rs1[i]){
1911       clear_const(current,rs1[i]);
1912       alloc_reg(current,i,rs1[i]);
1913       alloc_all(current,i);
1914     }
1915     else {
1916       alloc_all(current,i); // FIXME: Keep r0
1917       current->u&=~1LL;
1918       alloc_reg(current,i,0);
1919     }
1920   }
1921   else
1922   {
1923     // TLBR/TLBWI/TLBWR/TLBP/ERET
1924     assert(opcode2[i]==0x10);
1925     alloc_all(current,i);
1926   }
1927   minimum_free_regs[i]=HOST_REGS;
1928 }
1929
1930 static void cop2_alloc(struct regstat *current,int i)
1931 {
1932   if (opcode2[i] < 3) // MFC2/CFC2
1933   {
1934     alloc_cc(current,i); // for stalls
1935     dirty_reg(current,CCREG);
1936     if(rt1[i]){
1937       clear_const(current,rt1[i]);
1938       alloc_reg(current,i,rt1[i]);
1939       dirty_reg(current,rt1[i]);
1940     }
1941   }
1942   else if (opcode2[i] > 3) // MTC2/CTC2
1943   {
1944     if(rs1[i]){
1945       clear_const(current,rs1[i]);
1946       alloc_reg(current,i,rs1[i]);
1947     }
1948     else {
1949       current->u&=~1LL;
1950       alloc_reg(current,i,0);
1951     }
1952   }
1953   alloc_reg_temp(current,i,-1);
1954   minimum_free_regs[i]=1;
1955 }
1956
1957 void c2op_alloc(struct regstat *current,int i)
1958 {
1959   alloc_cc(current,i); // for stalls
1960   dirty_reg(current,CCREG);
1961   alloc_reg_temp(current,i,-1);
1962 }
1963
1964 void syscall_alloc(struct regstat *current,int i)
1965 {
1966   alloc_cc(current,i);
1967   dirty_reg(current,CCREG);
1968   alloc_all(current,i);
1969   minimum_free_regs[i]=HOST_REGS;
1970   current->isconst=0;
1971 }
1972
1973 void delayslot_alloc(struct regstat *current,int i)
1974 {
1975   switch(itype[i]) {
1976     case UJUMP:
1977     case CJUMP:
1978     case SJUMP:
1979     case RJUMP:
1980     case SYSCALL:
1981     case HLECALL:
1982     case SPAN:
1983       assem_debug("jump in the delay slot.  this shouldn't happen.\n");//abort();
1984       SysPrintf("Disabled speculative precompilation\n");
1985       stop_after_jal=1;
1986       break;
1987     case IMM16:
1988       imm16_alloc(current,i);
1989       break;
1990     case LOAD:
1991     case LOADLR:
1992       load_alloc(current,i);
1993       break;
1994     case STORE:
1995     case STORELR:
1996       store_alloc(current,i);
1997       break;
1998     case ALU:
1999       alu_alloc(current,i);
2000       break;
2001     case SHIFT:
2002       shift_alloc(current,i);
2003       break;
2004     case MULTDIV:
2005       multdiv_alloc(current,i);
2006       break;
2007     case SHIFTIMM:
2008       shiftimm_alloc(current,i);
2009       break;
2010     case MOV:
2011       mov_alloc(current,i);
2012       break;
2013     case COP0:
2014       cop0_alloc(current,i);
2015       break;
2016     case COP1:
2017       break;
2018     case COP2:
2019       cop2_alloc(current,i);
2020       break;
2021     case C1LS:
2022       c1ls_alloc(current,i);
2023       break;
2024     case C2LS:
2025       c2ls_alloc(current,i);
2026       break;
2027     case C2OP:
2028       c2op_alloc(current,i);
2029       break;
2030   }
2031 }
2032
2033 // Special case where a branch and delay slot span two pages in virtual memory
2034 static void pagespan_alloc(struct regstat *current,int i)
2035 {
2036   current->isconst=0;
2037   current->wasconst=0;
2038   regs[i].wasconst=0;
2039   minimum_free_regs[i]=HOST_REGS;
2040   alloc_all(current,i);
2041   alloc_cc(current,i);
2042   dirty_reg(current,CCREG);
2043   if(opcode[i]==3) // JAL
2044   {
2045     alloc_reg(current,i,31);
2046     dirty_reg(current,31);
2047   }
2048   if(opcode[i]==0&&(opcode2[i]&0x3E)==8) // JR/JALR
2049   {
2050     alloc_reg(current,i,rs1[i]);
2051     if (rt1[i]!=0) {
2052       alloc_reg(current,i,rt1[i]);
2053       dirty_reg(current,rt1[i]);
2054     }
2055   }
2056   if((opcode[i]&0x2E)==4) // BEQ/BNE/BEQL/BNEL
2057   {
2058     if(rs1[i]) alloc_reg(current,i,rs1[i]);
2059     if(rs2[i]) alloc_reg(current,i,rs2[i]);
2060   }
2061   else
2062   if((opcode[i]&0x2E)==6) // BLEZ/BGTZ/BLEZL/BGTZL
2063   {
2064     if(rs1[i]) alloc_reg(current,i,rs1[i]);
2065   }
2066   //else ...
2067 }
2068
2069 static void add_stub(enum stub_type type, void *addr, void *retaddr,
2070   u_int a, uintptr_t b, uintptr_t c, u_int d, u_int e)
2071 {
2072   assert(stubcount < ARRAY_SIZE(stubs));
2073   stubs[stubcount].type = type;
2074   stubs[stubcount].addr = addr;
2075   stubs[stubcount].retaddr = retaddr;
2076   stubs[stubcount].a = a;
2077   stubs[stubcount].b = b;
2078   stubs[stubcount].c = c;
2079   stubs[stubcount].d = d;
2080   stubs[stubcount].e = e;
2081   stubcount++;
2082 }
2083
2084 static void add_stub_r(enum stub_type type, void *addr, void *retaddr,
2085   int i, int addr_reg, const struct regstat *i_regs, int ccadj, u_int reglist)
2086 {
2087   add_stub(type, addr, retaddr, i, addr_reg, (uintptr_t)i_regs, ccadj, reglist);
2088 }
2089
2090 // Write out a single register
2091 static void wb_register(signed char r,signed char regmap[],uint64_t dirty)
2092 {
2093   int hr;
2094   for(hr=0;hr<HOST_REGS;hr++) {
2095     if(hr!=EXCLUDE_REG) {
2096       if((regmap[hr]&63)==r) {
2097         if((dirty>>hr)&1) {
2098           assert(regmap[hr]<64);
2099           emit_storereg(r,hr);
2100         }
2101       }
2102     }
2103   }
2104 }
2105
2106 static void wb_valid(signed char pre[],signed char entry[],u_int dirty_pre,u_int dirty,uint64_t u)
2107 {
2108   //if(dirty_pre==dirty) return;
2109   int hr,reg;
2110   for(hr=0;hr<HOST_REGS;hr++) {
2111     if(hr!=EXCLUDE_REG) {
2112       reg=pre[hr];
2113       if(((~u)>>(reg&63))&1) {
2114         if(reg>0) {
2115           if(((dirty_pre&~dirty)>>hr)&1) {
2116             if(reg>0&&reg<34) {
2117               emit_storereg(reg,hr);
2118             }
2119             else if(reg>=64) {
2120               assert(0);
2121             }
2122           }
2123         }
2124       }
2125     }
2126   }
2127 }
2128
2129 // trashes r2
2130 static void pass_args(int a0, int a1)
2131 {
2132   if(a0==1&&a1==0) {
2133     // must swap
2134     emit_mov(a0,2); emit_mov(a1,1); emit_mov(2,0);
2135   }
2136   else if(a0!=0&&a1==0) {
2137     emit_mov(a1,1);
2138     if (a0>=0) emit_mov(a0,0);
2139   }
2140   else {
2141     if(a0>=0&&a0!=0) emit_mov(a0,0);
2142     if(a1>=0&&a1!=1) emit_mov(a1,1);
2143   }
2144 }
2145
2146 static void alu_assemble(int i,struct regstat *i_regs)
2147 {
2148   if(opcode2[i]>=0x20&&opcode2[i]<=0x23) { // ADD/ADDU/SUB/SUBU
2149     if(rt1[i]) {
2150       signed char s1,s2,t;
2151       t=get_reg(i_regs->regmap,rt1[i]);
2152       if(t>=0) {
2153         s1=get_reg(i_regs->regmap,rs1[i]);
2154         s2=get_reg(i_regs->regmap,rs2[i]);
2155         if(rs1[i]&&rs2[i]) {
2156           assert(s1>=0);
2157           assert(s2>=0);
2158           if(opcode2[i]&2) emit_sub(s1,s2,t);
2159           else emit_add(s1,s2,t);
2160         }
2161         else if(rs1[i]) {
2162           if(s1>=0) emit_mov(s1,t);
2163           else emit_loadreg(rs1[i],t);
2164         }
2165         else if(rs2[i]) {
2166           if(s2>=0) {
2167             if(opcode2[i]&2) emit_neg(s2,t);
2168             else emit_mov(s2,t);
2169           }
2170           else {
2171             emit_loadreg(rs2[i],t);
2172             if(opcode2[i]&2) emit_neg(t,t);
2173           }
2174         }
2175         else emit_zeroreg(t);
2176       }
2177     }
2178   }
2179   if(opcode2[i]>=0x2c&&opcode2[i]<=0x2f) { // DADD/DADDU/DSUB/DSUBU
2180     assert(0);
2181   }
2182   if(opcode2[i]==0x2a||opcode2[i]==0x2b) { // SLT/SLTU
2183     if(rt1[i]) {
2184       signed char s1l,s2l,t;
2185       {
2186         t=get_reg(i_regs->regmap,rt1[i]);
2187         //assert(t>=0);
2188         if(t>=0) {
2189           s1l=get_reg(i_regs->regmap,rs1[i]);
2190           s2l=get_reg(i_regs->regmap,rs2[i]);
2191           if(rs2[i]==0) // rx<r0
2192           {
2193             if(opcode2[i]==0x2a&&rs1[i]!=0) { // SLT
2194               assert(s1l>=0);
2195               emit_shrimm(s1l,31,t);
2196             }
2197             else // SLTU (unsigned can not be less than zero, 0<0)
2198               emit_zeroreg(t);
2199           }
2200           else if(rs1[i]==0) // r0<rx
2201           {
2202             assert(s2l>=0);
2203             if(opcode2[i]==0x2a) // SLT
2204               emit_set_gz32(s2l,t);
2205             else // SLTU (set if not zero)
2206               emit_set_nz32(s2l,t);
2207           }
2208           else{
2209             assert(s1l>=0);assert(s2l>=0);
2210             if(opcode2[i]==0x2a) // SLT
2211               emit_set_if_less32(s1l,s2l,t);
2212             else // SLTU
2213               emit_set_if_carry32(s1l,s2l,t);
2214           }
2215         }
2216       }
2217     }
2218   }
2219   if(opcode2[i]>=0x24&&opcode2[i]<=0x27) { // AND/OR/XOR/NOR
2220     if(rt1[i]) {
2221       signed char s1l,s2l,tl;
2222       tl=get_reg(i_regs->regmap,rt1[i]);
2223       {
2224         if(tl>=0) {
2225           s1l=get_reg(i_regs->regmap,rs1[i]);
2226           s2l=get_reg(i_regs->regmap,rs2[i]);
2227           if(rs1[i]&&rs2[i]) {
2228             assert(s1l>=0);
2229             assert(s2l>=0);
2230             if(opcode2[i]==0x24) { // AND
2231               emit_and(s1l,s2l,tl);
2232             } else
2233             if(opcode2[i]==0x25) { // OR
2234               emit_or(s1l,s2l,tl);
2235             } else
2236             if(opcode2[i]==0x26) { // XOR
2237               emit_xor(s1l,s2l,tl);
2238             } else
2239             if(opcode2[i]==0x27) { // NOR
2240               emit_or(s1l,s2l,tl);
2241               emit_not(tl,tl);
2242             }
2243           }
2244           else
2245           {
2246             if(opcode2[i]==0x24) { // AND
2247               emit_zeroreg(tl);
2248             } else
2249             if(opcode2[i]==0x25||opcode2[i]==0x26) { // OR/XOR
2250               if(rs1[i]){
2251                 if(s1l>=0) emit_mov(s1l,tl);
2252                 else emit_loadreg(rs1[i],tl); // CHECK: regmap_entry?
2253               }
2254               else
2255               if(rs2[i]){
2256                 if(s2l>=0) emit_mov(s2l,tl);
2257                 else emit_loadreg(rs2[i],tl); // CHECK: regmap_entry?
2258               }
2259               else emit_zeroreg(tl);
2260             } else
2261             if(opcode2[i]==0x27) { // NOR
2262               if(rs1[i]){
2263                 if(s1l>=0) emit_not(s1l,tl);
2264                 else {
2265                   emit_loadreg(rs1[i],tl);
2266                   emit_not(tl,tl);
2267                 }
2268               }
2269               else
2270               if(rs2[i]){
2271                 if(s2l>=0) emit_not(s2l,tl);
2272                 else {
2273                   emit_loadreg(rs2[i],tl);
2274                   emit_not(tl,tl);
2275                 }
2276               }
2277               else emit_movimm(-1,tl);
2278             }
2279           }
2280         }
2281       }
2282     }
2283   }
2284 }
2285
2286 void imm16_assemble(int i,struct regstat *i_regs)
2287 {
2288   if (opcode[i]==0x0f) { // LUI
2289     if(rt1[i]) {
2290       signed char t;
2291       t=get_reg(i_regs->regmap,rt1[i]);
2292       //assert(t>=0);
2293       if(t>=0) {
2294         if(!((i_regs->isconst>>t)&1))
2295           emit_movimm(imm[i]<<16,t);
2296       }
2297     }
2298   }
2299   if(opcode[i]==0x08||opcode[i]==0x09) { // ADDI/ADDIU
2300     if(rt1[i]) {
2301       signed char s,t;
2302       t=get_reg(i_regs->regmap,rt1[i]);
2303       s=get_reg(i_regs->regmap,rs1[i]);
2304       if(rs1[i]) {
2305         //assert(t>=0);
2306         //assert(s>=0);
2307         if(t>=0) {
2308           if(!((i_regs->isconst>>t)&1)) {
2309             if(s<0) {
2310               if(i_regs->regmap_entry[t]!=rs1[i]) emit_loadreg(rs1[i],t);
2311               emit_addimm(t,imm[i],t);
2312             }else{
2313               if(!((i_regs->wasconst>>s)&1))
2314                 emit_addimm(s,imm[i],t);
2315               else
2316                 emit_movimm(constmap[i][s]+imm[i],t);
2317             }
2318           }
2319         }
2320       } else {
2321         if(t>=0) {
2322           if(!((i_regs->isconst>>t)&1))
2323             emit_movimm(imm[i],t);
2324         }
2325       }
2326     }
2327   }
2328   if(opcode[i]==0x18||opcode[i]==0x19) { // DADDI/DADDIU
2329     if(rt1[i]) {
2330       signed char sl,tl;
2331       tl=get_reg(i_regs->regmap,rt1[i]);
2332       sl=get_reg(i_regs->regmap,rs1[i]);
2333       if(tl>=0) {
2334         if(rs1[i]) {
2335           assert(sl>=0);
2336           emit_addimm(sl,imm[i],tl);
2337         } else {
2338           emit_movimm(imm[i],tl);
2339         }
2340       }
2341     }
2342   }
2343   else if(opcode[i]==0x0a||opcode[i]==0x0b) { // SLTI/SLTIU
2344     if(rt1[i]) {
2345       //assert(rs1[i]!=0); // r0 might be valid, but it's probably a bug
2346       signed char sl,t;
2347       t=get_reg(i_regs->regmap,rt1[i]);
2348       sl=get_reg(i_regs->regmap,rs1[i]);
2349       //assert(t>=0);
2350       if(t>=0) {
2351         if(rs1[i]>0) {
2352             if(opcode[i]==0x0a) { // SLTI
2353               if(sl<0) {
2354                 if(i_regs->regmap_entry[t]!=rs1[i]) emit_loadreg(rs1[i],t);
2355                 emit_slti32(t,imm[i],t);
2356               }else{
2357                 emit_slti32(sl,imm[i],t);
2358               }
2359             }
2360             else { // SLTIU
2361               if(sl<0) {
2362                 if(i_regs->regmap_entry[t]!=rs1[i]) emit_loadreg(rs1[i],t);
2363                 emit_sltiu32(t,imm[i],t);
2364               }else{
2365                 emit_sltiu32(sl,imm[i],t);
2366               }
2367             }
2368         }else{
2369           // SLTI(U) with r0 is just stupid,
2370           // nonetheless examples can be found
2371           if(opcode[i]==0x0a) // SLTI
2372             if(0<imm[i]) emit_movimm(1,t);
2373             else emit_zeroreg(t);
2374           else // SLTIU
2375           {
2376             if(imm[i]) emit_movimm(1,t);
2377             else emit_zeroreg(t);
2378           }
2379         }
2380       }
2381     }
2382   }
2383   else if(opcode[i]>=0x0c&&opcode[i]<=0x0e) { // ANDI/ORI/XORI
2384     if(rt1[i]) {
2385       signed char sl,tl;
2386       tl=get_reg(i_regs->regmap,rt1[i]);
2387       sl=get_reg(i_regs->regmap,rs1[i]);
2388       if(tl>=0 && !((i_regs->isconst>>tl)&1)) {
2389         if(opcode[i]==0x0c) //ANDI
2390         {
2391           if(rs1[i]) {
2392             if(sl<0) {
2393               if(i_regs->regmap_entry[tl]!=rs1[i]) emit_loadreg(rs1[i],tl);
2394               emit_andimm(tl,imm[i],tl);
2395             }else{
2396               if(!((i_regs->wasconst>>sl)&1))
2397                 emit_andimm(sl,imm[i],tl);
2398               else
2399                 emit_movimm(constmap[i][sl]&imm[i],tl);
2400             }
2401           }
2402           else
2403             emit_zeroreg(tl);
2404         }
2405         else
2406         {
2407           if(rs1[i]) {
2408             if(sl<0) {
2409               if(i_regs->regmap_entry[tl]!=rs1[i]) emit_loadreg(rs1[i],tl);
2410             }
2411             if(opcode[i]==0x0d) { // ORI
2412               if(sl<0) {
2413                 emit_orimm(tl,imm[i],tl);
2414               }else{
2415                 if(!((i_regs->wasconst>>sl)&1))
2416                   emit_orimm(sl,imm[i],tl);
2417                 else
2418                   emit_movimm(constmap[i][sl]|imm[i],tl);
2419               }
2420             }
2421             if(opcode[i]==0x0e) { // XORI
2422               if(sl<0) {
2423                 emit_xorimm(tl,imm[i],tl);
2424               }else{
2425                 if(!((i_regs->wasconst>>sl)&1))
2426                   emit_xorimm(sl,imm[i],tl);
2427                 else
2428                   emit_movimm(constmap[i][sl]^imm[i],tl);
2429               }
2430             }
2431           }
2432           else {
2433             emit_movimm(imm[i],tl);
2434           }
2435         }
2436       }
2437     }
2438   }
2439 }
2440
2441 void shiftimm_assemble(int i,struct regstat *i_regs)
2442 {
2443   if(opcode2[i]<=0x3) // SLL/SRL/SRA
2444   {
2445     if(rt1[i]) {
2446       signed char s,t;
2447       t=get_reg(i_regs->regmap,rt1[i]);
2448       s=get_reg(i_regs->regmap,rs1[i]);
2449       //assert(t>=0);
2450       if(t>=0&&!((i_regs->isconst>>t)&1)){
2451         if(rs1[i]==0)
2452         {
2453           emit_zeroreg(t);
2454         }
2455         else
2456         {
2457           if(s<0&&i_regs->regmap_entry[t]!=rs1[i]) emit_loadreg(rs1[i],t);
2458           if(imm[i]) {
2459             if(opcode2[i]==0) // SLL
2460             {
2461               emit_shlimm(s<0?t:s,imm[i],t);
2462             }
2463             if(opcode2[i]==2) // SRL
2464             {
2465               emit_shrimm(s<0?t:s,imm[i],t);
2466             }
2467             if(opcode2[i]==3) // SRA
2468             {
2469               emit_sarimm(s<0?t:s,imm[i],t);
2470             }
2471           }else{
2472             // Shift by zero
2473             if(s>=0 && s!=t) emit_mov(s,t);
2474           }
2475         }
2476       }
2477       //emit_storereg(rt1[i],t); //DEBUG
2478     }
2479   }
2480   if(opcode2[i]>=0x38&&opcode2[i]<=0x3b) // DSLL/DSRL/DSRA
2481   {
2482     assert(0);
2483   }
2484   if(opcode2[i]==0x3c) // DSLL32
2485   {
2486     assert(0);
2487   }
2488   if(opcode2[i]==0x3e) // DSRL32
2489   {
2490     assert(0);
2491   }
2492   if(opcode2[i]==0x3f) // DSRA32
2493   {
2494     assert(0);
2495   }
2496 }
2497
2498 #ifndef shift_assemble
2499 static void shift_assemble(int i,struct regstat *i_regs)
2500 {
2501   signed char s,t,shift;
2502   if (rt1[i] == 0)
2503     return;
2504   assert(opcode2[i]<=0x07); // SLLV/SRLV/SRAV
2505   t = get_reg(i_regs->regmap, rt1[i]);
2506   s = get_reg(i_regs->regmap, rs1[i]);
2507   shift = get_reg(i_regs->regmap, rs2[i]);
2508   if (t < 0)
2509     return;
2510
2511   if(rs1[i]==0)
2512     emit_zeroreg(t);
2513   else if(rs2[i]==0) {
2514     assert(s>=0);
2515     if(s!=t) emit_mov(s,t);
2516   }
2517   else {
2518     host_tempreg_acquire();
2519     emit_andimm(shift,31,HOST_TEMPREG);
2520     switch(opcode2[i]) {
2521     case 4: // SLLV
2522       emit_shl(s,HOST_TEMPREG,t);
2523       break;
2524     case 6: // SRLV
2525       emit_shr(s,HOST_TEMPREG,t);
2526       break;
2527     case 7: // SRAV
2528       emit_sar(s,HOST_TEMPREG,t);
2529       break;
2530     default:
2531       assert(0);
2532     }
2533     host_tempreg_release();
2534   }
2535 }
2536
2537 #endif
2538
2539 enum {
2540   MTYPE_8000 = 0,
2541   MTYPE_8020,
2542   MTYPE_0000,
2543   MTYPE_A000,
2544   MTYPE_1F80,
2545 };
2546
2547 static int get_ptr_mem_type(u_int a)
2548 {
2549   if(a < 0x00200000) {
2550     if(a<0x1000&&((start>>20)==0xbfc||(start>>24)==0xa0))
2551       // return wrong, must use memhandler for BIOS self-test to pass
2552       // 007 does similar stuff from a00 mirror, weird stuff
2553       return MTYPE_8000;
2554     return MTYPE_0000;
2555   }
2556   if(0x1f800000 <= a && a < 0x1f801000)
2557     return MTYPE_1F80;
2558   if(0x80200000 <= a && a < 0x80800000)
2559     return MTYPE_8020;
2560   if(0xa0000000 <= a && a < 0xa0200000)
2561     return MTYPE_A000;
2562   return MTYPE_8000;
2563 }
2564
2565 static void *emit_fastpath_cmp_jump(int i,int addr,int *addr_reg_override)
2566 {
2567   void *jaddr = NULL;
2568   int type=0;
2569   int mr=rs1[i];
2570   if(((smrv_strong|smrv_weak)>>mr)&1) {
2571     type=get_ptr_mem_type(smrv[mr]);
2572     //printf("set %08x @%08x r%d %d\n", smrv[mr], start+i*4, mr, type);
2573   }
2574   else {
2575     // use the mirror we are running on
2576     type=get_ptr_mem_type(start);
2577     //printf("set nospec   @%08x r%d %d\n", start+i*4, mr, type);
2578   }
2579
2580   if(type==MTYPE_8020) { // RAM 80200000+ mirror
2581     host_tempreg_acquire();
2582     emit_andimm(addr,~0x00e00000,HOST_TEMPREG);
2583     addr=*addr_reg_override=HOST_TEMPREG;
2584     type=0;
2585   }
2586   else if(type==MTYPE_0000) { // RAM 0 mirror
2587     host_tempreg_acquire();
2588     emit_orimm(addr,0x80000000,HOST_TEMPREG);
2589     addr=*addr_reg_override=HOST_TEMPREG;
2590     type=0;
2591   }
2592   else if(type==MTYPE_A000) { // RAM A mirror
2593     host_tempreg_acquire();
2594     emit_andimm(addr,~0x20000000,HOST_TEMPREG);
2595     addr=*addr_reg_override=HOST_TEMPREG;
2596     type=0;
2597   }
2598   else if(type==MTYPE_1F80) { // scratchpad
2599     if (psxH == (void *)0x1f800000) {
2600       host_tempreg_acquire();
2601       emit_xorimm(addr,0x1f800000,HOST_TEMPREG);
2602       emit_cmpimm(HOST_TEMPREG,0x1000);
2603       host_tempreg_release();
2604       jaddr=out;
2605       emit_jc(0);
2606     }
2607     else {
2608       // do the usual RAM check, jump will go to the right handler
2609       type=0;
2610     }
2611   }
2612
2613   if(type==0)
2614   {
2615     emit_cmpimm(addr,RAM_SIZE);
2616     jaddr=out;
2617     #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
2618     // Hint to branch predictor that the branch is unlikely to be taken
2619     if(rs1[i]>=28)
2620       emit_jno_unlikely(0);
2621     else
2622     #endif
2623       emit_jno(0);
2624     if(ram_offset!=0) {
2625       host_tempreg_acquire();
2626       emit_addimm(addr,ram_offset,HOST_TEMPREG);
2627       addr=*addr_reg_override=HOST_TEMPREG;
2628     }
2629   }
2630
2631   return jaddr;
2632 }
2633
2634 // return memhandler, or get directly accessable address and return 0
2635 static void *get_direct_memhandler(void *table, u_int addr,
2636   enum stub_type type, uintptr_t *addr_host)
2637 {
2638   uintptr_t l1, l2 = 0;
2639   l1 = ((uintptr_t *)table)[addr>>12];
2640   if ((l1 & (1ul << (sizeof(l1)*8-1))) == 0) {
2641     uintptr_t v = l1 << 1;
2642     *addr_host = v + addr;
2643     return NULL;
2644   }
2645   else {
2646     l1 <<= 1;
2647     if (type == LOADB_STUB || type == LOADBU_STUB || type == STOREB_STUB)
2648       l2 = ((uintptr_t *)l1)[0x1000/4 + 0x1000/2 + (addr&0xfff)];
2649     else if (type == LOADH_STUB || type == LOADHU_STUB || type == STOREH_STUB)
2650       l2=((uintptr_t *)l1)[0x1000/4 + (addr&0xfff)/2];
2651     else
2652       l2=((uintptr_t *)l1)[(addr&0xfff)/4];
2653     if ((l2 & (1<<31)) == 0) {
2654       uintptr_t v = l2 << 1;
2655       *addr_host = v + (addr&0xfff);
2656       return NULL;
2657     }
2658     return (void *)(l2 << 1);
2659   }
2660 }
2661
2662 static u_int get_host_reglist(const signed char *regmap)
2663 {
2664   u_int reglist = 0, hr;
2665   for (hr = 0; hr < HOST_REGS; hr++) {
2666     if (hr != EXCLUDE_REG && regmap[hr] >= 0)
2667       reglist |= 1 << hr;
2668   }
2669   return reglist;
2670 }
2671
2672 static u_int reglist_exclude(u_int reglist, int r1, int r2)
2673 {
2674   if (r1 >= 0)
2675     reglist &= ~(1u << r1);
2676   if (r2 >= 0)
2677     reglist &= ~(1u << r2);
2678   return reglist;
2679 }
2680
2681 // find a temp caller-saved register not in reglist (so assumed to be free)
2682 static int reglist_find_free(u_int reglist)
2683 {
2684   u_int free_regs = ~reglist & CALLER_SAVE_REGS;
2685   if (free_regs == 0)
2686     return -1;
2687   return __builtin_ctz(free_regs);
2688 }
2689
2690 static void load_assemble(int i, const struct regstat *i_regs)
2691 {
2692   int s,tl,addr;
2693   int offset;
2694   void *jaddr=0;
2695   int memtarget=0,c=0;
2696   int fastio_reg_override=-1;
2697   u_int reglist=get_host_reglist(i_regs->regmap);
2698   tl=get_reg(i_regs->regmap,rt1[i]);
2699   s=get_reg(i_regs->regmap,rs1[i]);
2700   offset=imm[i];
2701   if(i_regs->regmap[HOST_CCREG]==CCREG) reglist&=~(1<<HOST_CCREG);
2702   if(s>=0) {
2703     c=(i_regs->wasconst>>s)&1;
2704     if (c) {
2705       memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
2706     }
2707   }
2708   //printf("load_assemble: c=%d\n",c);
2709   //if(c) printf("load_assemble: const=%lx\n",(long)constmap[i][s]+offset);
2710   // FIXME: Even if the load is a NOP, we should check for pagefaults...
2711   if((tl<0&&(!c||(((u_int)constmap[i][s]+offset)>>16)==0x1f80))
2712     ||rt1[i]==0) {
2713       // could be FIFO, must perform the read
2714       // ||dummy read
2715       assem_debug("(forced read)\n");
2716       tl=get_reg(i_regs->regmap,-1);
2717       assert(tl>=0);
2718   }
2719   if(offset||s<0||c) addr=tl;
2720   else addr=s;
2721   //if(tl<0) tl=get_reg(i_regs->regmap,-1);
2722  if(tl>=0) {
2723   //printf("load_assemble: c=%d\n",c);
2724   //if(c) printf("load_assemble: const=%lx\n",(long)constmap[i][s]+offset);
2725   assert(tl>=0); // Even if the load is a NOP, we must check for pagefaults and I/O
2726   reglist&=~(1<<tl);
2727   if(!c) {
2728     #ifdef R29_HACK
2729     // Strmnnrmn's speed hack
2730     if(rs1[i]!=29||start<0x80001000||start>=0x80000000+RAM_SIZE)
2731     #endif
2732     {
2733       jaddr=emit_fastpath_cmp_jump(i,addr,&fastio_reg_override);
2734     }
2735   }
2736   else if(ram_offset&&memtarget) {
2737     host_tempreg_acquire();
2738     emit_addimm(addr,ram_offset,HOST_TEMPREG);
2739     fastio_reg_override=HOST_TEMPREG;
2740   }
2741   int dummy=(rt1[i]==0)||(tl!=get_reg(i_regs->regmap,rt1[i])); // ignore loads to r0 and unneeded reg
2742   if (opcode[i]==0x20) { // LB
2743     if(!c||memtarget) {
2744       if(!dummy) {
2745         {
2746           int x=0,a=tl;
2747           if(!c) a=addr;
2748           if(fastio_reg_override>=0) a=fastio_reg_override;
2749
2750           emit_movsbl_indexed(x,a,tl);
2751         }
2752       }
2753       if(jaddr)
2754         add_stub_r(LOADB_STUB,jaddr,out,i,addr,i_regs,ccadj[i],reglist);
2755     }
2756     else
2757       inline_readstub(LOADB_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist);
2758   }
2759   if (opcode[i]==0x21) { // LH
2760     if(!c||memtarget) {
2761       if(!dummy) {
2762         int x=0,a=tl;
2763         if(!c) a=addr;
2764         if(fastio_reg_override>=0) a=fastio_reg_override;
2765         emit_movswl_indexed(x,a,tl);
2766       }
2767       if(jaddr)
2768         add_stub_r(LOADH_STUB,jaddr,out,i,addr,i_regs,ccadj[i],reglist);
2769     }
2770     else
2771       inline_readstub(LOADH_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist);
2772   }
2773   if (opcode[i]==0x23) { // LW
2774     if(!c||memtarget) {
2775       if(!dummy) {
2776         int a=addr;
2777         if(fastio_reg_override>=0) a=fastio_reg_override;
2778         emit_readword_indexed(0,a,tl);
2779       }
2780       if(jaddr)
2781         add_stub_r(LOADW_STUB,jaddr,out,i,addr,i_regs,ccadj[i],reglist);
2782     }
2783     else
2784       inline_readstub(LOADW_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist);
2785   }
2786   if (opcode[i]==0x24) { // LBU
2787     if(!c||memtarget) {
2788       if(!dummy) {
2789         int x=0,a=tl;
2790         if(!c) a=addr;
2791         if(fastio_reg_override>=0) a=fastio_reg_override;
2792
2793         emit_movzbl_indexed(x,a,tl);
2794       }
2795       if(jaddr)
2796         add_stub_r(LOADBU_STUB,jaddr,out,i,addr,i_regs,ccadj[i],reglist);
2797     }
2798     else
2799       inline_readstub(LOADBU_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist);
2800   }
2801   if (opcode[i]==0x25) { // LHU
2802     if(!c||memtarget) {
2803       if(!dummy) {
2804         int x=0,a=tl;
2805         if(!c) a=addr;
2806         if(fastio_reg_override>=0) a=fastio_reg_override;
2807         emit_movzwl_indexed(x,a,tl);
2808       }
2809       if(jaddr)
2810         add_stub_r(LOADHU_STUB,jaddr,out,i,addr,i_regs,ccadj[i],reglist);
2811     }
2812     else
2813       inline_readstub(LOADHU_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist);
2814   }
2815   if (opcode[i]==0x27) { // LWU
2816     assert(0);
2817   }
2818   if (opcode[i]==0x37) { // LD
2819     assert(0);
2820   }
2821  }
2822  if (fastio_reg_override == HOST_TEMPREG)
2823    host_tempreg_release();
2824 }
2825
2826 #ifndef loadlr_assemble
2827 static void loadlr_assemble(int i, const struct regstat *i_regs)
2828 {
2829   int s,tl,temp,temp2,addr;
2830   int offset;
2831   void *jaddr=0;
2832   int memtarget=0,c=0;
2833   int fastio_reg_override=-1;
2834   u_int reglist=get_host_reglist(i_regs->regmap);
2835   tl=get_reg(i_regs->regmap,rt1[i]);
2836   s=get_reg(i_regs->regmap,rs1[i]);
2837   temp=get_reg(i_regs->regmap,-1);
2838   temp2=get_reg(i_regs->regmap,FTEMP);
2839   addr=get_reg(i_regs->regmap,AGEN1+(i&1));
2840   assert(addr<0);
2841   offset=imm[i];
2842   reglist|=1<<temp;
2843   if(offset||s<0||c) addr=temp2;
2844   else addr=s;
2845   if(s>=0) {
2846     c=(i_regs->wasconst>>s)&1;
2847     if(c) {
2848       memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
2849     }
2850   }
2851   if(!c) {
2852     emit_shlimm(addr,3,temp);
2853     if (opcode[i]==0x22||opcode[i]==0x26) {
2854       emit_andimm(addr,0xFFFFFFFC,temp2); // LWL/LWR
2855     }else{
2856       emit_andimm(addr,0xFFFFFFF8,temp2); // LDL/LDR
2857     }
2858     jaddr=emit_fastpath_cmp_jump(i,temp2,&fastio_reg_override);
2859   }
2860   else {
2861     if(ram_offset&&memtarget) {
2862       host_tempreg_acquire();
2863       emit_addimm(temp2,ram_offset,HOST_TEMPREG);
2864       fastio_reg_override=HOST_TEMPREG;
2865     }
2866     if (opcode[i]==0x22||opcode[i]==0x26) {
2867       emit_movimm(((constmap[i][s]+offset)<<3)&24,temp); // LWL/LWR
2868     }else{
2869       emit_movimm(((constmap[i][s]+offset)<<3)&56,temp); // LDL/LDR
2870     }
2871   }
2872   if (opcode[i]==0x22||opcode[i]==0x26) { // LWL/LWR
2873     if(!c||memtarget) {
2874       int a=temp2;
2875       if(fastio_reg_override>=0) a=fastio_reg_override;
2876       emit_readword_indexed(0,a,temp2);
2877       if(fastio_reg_override==HOST_TEMPREG) host_tempreg_release();
2878       if(jaddr) add_stub_r(LOADW_STUB,jaddr,out,i,temp2,i_regs,ccadj[i],reglist);
2879     }
2880     else
2881       inline_readstub(LOADW_STUB,i,(constmap[i][s]+offset)&0xFFFFFFFC,i_regs->regmap,FTEMP,ccadj[i],reglist);
2882     if(rt1[i]) {
2883       assert(tl>=0);
2884       emit_andimm(temp,24,temp);
2885       if (opcode[i]==0x22) // LWL
2886         emit_xorimm(temp,24,temp);
2887       host_tempreg_acquire();
2888       emit_movimm(-1,HOST_TEMPREG);
2889       if (opcode[i]==0x26) {
2890         emit_shr(temp2,temp,temp2);
2891         emit_bic_lsr(tl,HOST_TEMPREG,temp,tl);
2892       }else{
2893         emit_shl(temp2,temp,temp2);
2894         emit_bic_lsl(tl,HOST_TEMPREG,temp,tl);
2895       }
2896       host_tempreg_release();
2897       emit_or(temp2,tl,tl);
2898     }
2899     //emit_storereg(rt1[i],tl); // DEBUG
2900   }
2901   if (opcode[i]==0x1A||opcode[i]==0x1B) { // LDL/LDR
2902     assert(0);
2903   }
2904 }
2905 #endif
2906
2907 void store_assemble(int i, const struct regstat *i_regs)
2908 {
2909   int s,tl;
2910   int addr,temp;
2911   int offset;
2912   void *jaddr=0;
2913   enum stub_type type;
2914   int memtarget=0,c=0;
2915   int agr=AGEN1+(i&1);
2916   int fastio_reg_override=-1;
2917   u_int reglist=get_host_reglist(i_regs->regmap);
2918   tl=get_reg(i_regs->regmap,rs2[i]);
2919   s=get_reg(i_regs->regmap,rs1[i]);
2920   temp=get_reg(i_regs->regmap,agr);
2921   if(temp<0) temp=get_reg(i_regs->regmap,-1);
2922   offset=imm[i];
2923   if(s>=0) {
2924     c=(i_regs->wasconst>>s)&1;
2925     if(c) {
2926       memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
2927     }
2928   }
2929   assert(tl>=0);
2930   assert(temp>=0);
2931   if(i_regs->regmap[HOST_CCREG]==CCREG) reglist&=~(1<<HOST_CCREG);
2932   if(offset||s<0||c) addr=temp;
2933   else addr=s;
2934   if(!c) {
2935     jaddr=emit_fastpath_cmp_jump(i,addr,&fastio_reg_override);
2936   }
2937   else if(ram_offset&&memtarget) {
2938     host_tempreg_acquire();
2939     emit_addimm(addr,ram_offset,HOST_TEMPREG);
2940     fastio_reg_override=HOST_TEMPREG;
2941   }
2942
2943   if (opcode[i]==0x28) { // SB
2944     if(!c||memtarget) {
2945       int x=0,a=temp;
2946       if(!c) a=addr;
2947       if(fastio_reg_override>=0) a=fastio_reg_override;
2948       emit_writebyte_indexed(tl,x,a);
2949     }
2950     type=STOREB_STUB;
2951   }
2952   if (opcode[i]==0x29) { // SH
2953     if(!c||memtarget) {
2954       int x=0,a=temp;
2955       if(!c) a=addr;
2956       if(fastio_reg_override>=0) a=fastio_reg_override;
2957       emit_writehword_indexed(tl,x,a);
2958     }
2959     type=STOREH_STUB;
2960   }
2961   if (opcode[i]==0x2B) { // SW
2962     if(!c||memtarget) {
2963       int a=addr;
2964       if(fastio_reg_override>=0) a=fastio_reg_override;
2965       emit_writeword_indexed(tl,0,a);
2966     }
2967     type=STOREW_STUB;
2968   }
2969   if (opcode[i]==0x3F) { // SD
2970     assert(0);
2971     type=STORED_STUB;
2972   }
2973   if(fastio_reg_override==HOST_TEMPREG)
2974     host_tempreg_release();
2975   if(jaddr) {
2976     // PCSX store handlers don't check invcode again
2977     reglist|=1<<addr;
2978     add_stub_r(type,jaddr,out,i,addr,i_regs,ccadj[i],reglist);
2979     jaddr=0;
2980   }
2981   if(!(i_regs->waswritten&(1<<rs1[i])) && !HACK_ENABLED(NDHACK_NO_SMC_CHECK)) {
2982     if(!c||memtarget) {
2983       #ifdef DESTRUCTIVE_SHIFT
2984       // The x86 shift operation is 'destructive'; it overwrites the
2985       // source register, so we need to make a copy first and use that.
2986       addr=temp;
2987       #endif
2988       #if defined(HOST_IMM8)
2989       int ir=get_reg(i_regs->regmap,INVCP);
2990       assert(ir>=0);
2991       emit_cmpmem_indexedsr12_reg(ir,addr,1);
2992       #else
2993       emit_cmpmem_indexedsr12_imm(invalid_code,addr,1);
2994       #endif
2995       #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT)
2996       emit_callne(invalidate_addr_reg[addr]);
2997       #else
2998       void *jaddr2 = out;
2999       emit_jne(0);
3000       add_stub(INVCODE_STUB,jaddr2,out,reglist|(1<<HOST_CCREG),addr,0,0,0);
3001       #endif
3002     }
3003   }
3004   u_int addr_val=constmap[i][s]+offset;
3005   if(jaddr) {
3006     add_stub_r(type,jaddr,out,i,addr,i_regs,ccadj[i],reglist);
3007   } else if(c&&!memtarget) {
3008     inline_writestub(type,i,addr_val,i_regs->regmap,rs2[i],ccadj[i],reglist);
3009   }
3010   // basic current block modification detection..
3011   // not looking back as that should be in mips cache already
3012   // (see Spyro2 title->attract mode)
3013   if(c&&start+i*4<addr_val&&addr_val<start+slen*4) {
3014     SysPrintf("write to %08x hits block %08x, pc=%08x\n",addr_val,start,start+i*4);
3015     assert(i_regs->regmap==regs[i].regmap); // not delay slot
3016     if(i_regs->regmap==regs[i].regmap) {
3017       load_all_consts(regs[i].regmap_entry,regs[i].wasdirty,i);
3018       wb_dirtys(regs[i].regmap_entry,regs[i].wasdirty);
3019       emit_movimm(start+i*4+4,0);
3020       emit_writeword(0,&pcaddr);
3021       emit_addimm(HOST_CCREG,2,HOST_CCREG);
3022       emit_far_call(get_addr_ht);
3023       emit_jmpreg(0);
3024     }
3025   }
3026 }
3027
3028 static void storelr_assemble(int i, const struct regstat *i_regs)
3029 {
3030   int s,tl;
3031   int temp;
3032   int offset;
3033   void *jaddr=0;
3034   void *case1, *case2, *case3;
3035   void *done0, *done1, *done2;
3036   int memtarget=0,c=0;
3037   int agr=AGEN1+(i&1);
3038   u_int reglist=get_host_reglist(i_regs->regmap);
3039   tl=get_reg(i_regs->regmap,rs2[i]);
3040   s=get_reg(i_regs->regmap,rs1[i]);
3041   temp=get_reg(i_regs->regmap,agr);
3042   if(temp<0) temp=get_reg(i_regs->regmap,-1);
3043   offset=imm[i];
3044   if(s>=0) {
3045     c=(i_regs->isconst>>s)&1;
3046     if(c) {
3047       memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
3048     }
3049   }
3050   assert(tl>=0);
3051   assert(temp>=0);
3052   if(!c) {
3053     emit_cmpimm(s<0||offset?temp:s,RAM_SIZE);
3054     if(!offset&&s!=temp) emit_mov(s,temp);
3055     jaddr=out;
3056     emit_jno(0);
3057   }
3058   else
3059   {
3060     if(!memtarget||!rs1[i]) {
3061       jaddr=out;
3062       emit_jmp(0);
3063     }
3064   }
3065   if(ram_offset)
3066     emit_addimm_no_flags(ram_offset,temp);
3067
3068   if (opcode[i]==0x2C||opcode[i]==0x2D) { // SDL/SDR
3069     assert(0);
3070   }
3071
3072   emit_xorimm(temp,3,temp);
3073   emit_testimm(temp,2);
3074   case2=out;
3075   emit_jne(0);
3076   emit_testimm(temp,1);
3077   case1=out;
3078   emit_jne(0);
3079   // 0
3080   if (opcode[i]==0x2A) { // SWL
3081     emit_writeword_indexed(tl,0,temp);
3082   }
3083   else if (opcode[i]==0x2E) { // SWR
3084     emit_writebyte_indexed(tl,3,temp);
3085   }
3086   else
3087     assert(0);
3088   done0=out;
3089   emit_jmp(0);
3090   // 1
3091   set_jump_target(case1, out);
3092   if (opcode[i]==0x2A) { // SWL
3093     // Write 3 msb into three least significant bytes
3094     if(rs2[i]) emit_rorimm(tl,8,tl);
3095     emit_writehword_indexed(tl,-1,temp);
3096     if(rs2[i]) emit_rorimm(tl,16,tl);
3097     emit_writebyte_indexed(tl,1,temp);
3098     if(rs2[i]) emit_rorimm(tl,8,tl);
3099   }
3100   else if (opcode[i]==0x2E) { // SWR
3101     // Write two lsb into two most significant bytes
3102     emit_writehword_indexed(tl,1,temp);
3103   }
3104   done1=out;
3105   emit_jmp(0);
3106   // 2
3107   set_jump_target(case2, out);
3108   emit_testimm(temp,1);
3109   case3=out;
3110   emit_jne(0);
3111   if (opcode[i]==0x2A) { // SWL
3112     // Write two msb into two least significant bytes
3113     if(rs2[i]) emit_rorimm(tl,16,tl);
3114     emit_writehword_indexed(tl,-2,temp);
3115     if(rs2[i]) emit_rorimm(tl,16,tl);
3116   }
3117   else if (opcode[i]==0x2E) { // SWR
3118     // Write 3 lsb into three most significant bytes
3119     emit_writebyte_indexed(tl,-1,temp);
3120     if(rs2[i]) emit_rorimm(tl,8,tl);
3121     emit_writehword_indexed(tl,0,temp);
3122     if(rs2[i]) emit_rorimm(tl,24,tl);
3123   }
3124   done2=out;
3125   emit_jmp(0);
3126   // 3
3127   set_jump_target(case3, out);
3128   if (opcode[i]==0x2A) { // SWL
3129     // Write msb into least significant byte
3130     if(rs2[i]) emit_rorimm(tl,24,tl);
3131     emit_writebyte_indexed(tl,-3,temp);
3132     if(rs2[i]) emit_rorimm(tl,8,tl);
3133   }
3134   else if (opcode[i]==0x2E) { // SWR
3135     // Write entire word
3136     emit_writeword_indexed(tl,-3,temp);
3137   }
3138   set_jump_target(done0, out);
3139   set_jump_target(done1, out);
3140   set_jump_target(done2, out);
3141   if(!c||!memtarget)
3142     add_stub_r(STORELR_STUB,jaddr,out,i,temp,i_regs,ccadj[i],reglist);
3143   if(!(i_regs->waswritten&(1<<rs1[i])) && !HACK_ENABLED(NDHACK_NO_SMC_CHECK)) {
3144     emit_addimm_no_flags(-ram_offset,temp);
3145     #if defined(HOST_IMM8)
3146     int ir=get_reg(i_regs->regmap,INVCP);
3147     assert(ir>=0);
3148     emit_cmpmem_indexedsr12_reg(ir,temp,1);
3149     #else
3150     emit_cmpmem_indexedsr12_imm(invalid_code,temp,1);
3151     #endif
3152     #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT)
3153     emit_callne(invalidate_addr_reg[temp]);
3154     #else
3155     void *jaddr2 = out;
3156     emit_jne(0);
3157     add_stub(INVCODE_STUB,jaddr2,out,reglist|(1<<HOST_CCREG),temp,0,0,0);
3158     #endif
3159   }
3160 }
3161
3162 static void cop0_assemble(int i,struct regstat *i_regs)
3163 {
3164   if(opcode2[i]==0) // MFC0
3165   {
3166     signed char t=get_reg(i_regs->regmap,rt1[i]);
3167     u_int copr=(source[i]>>11)&0x1f;
3168     //assert(t>=0); // Why does this happen?  OOT is weird
3169     if(t>=0&&rt1[i]!=0) {
3170       emit_readword(&reg_cop0[copr],t);
3171     }
3172   }
3173   else if(opcode2[i]==4) // MTC0
3174   {
3175     signed char s=get_reg(i_regs->regmap,rs1[i]);
3176     char copr=(source[i]>>11)&0x1f;
3177     assert(s>=0);
3178     wb_register(rs1[i],i_regs->regmap,i_regs->dirty);
3179     if(copr==9||copr==11||copr==12||copr==13) {
3180       emit_readword(&last_count,HOST_TEMPREG);
3181       emit_loadreg(CCREG,HOST_CCREG); // TODO: do proper reg alloc
3182       emit_add(HOST_CCREG,HOST_TEMPREG,HOST_CCREG);
3183       emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG);
3184       emit_writeword(HOST_CCREG,&Count);
3185     }
3186     // What a mess.  The status register (12) can enable interrupts,
3187     // so needs a special case to handle a pending interrupt.
3188     // The interrupt must be taken immediately, because a subsequent
3189     // instruction might disable interrupts again.
3190     if(copr==12||copr==13) {
3191       if (is_delayslot) {
3192         // burn cycles to cause cc_interrupt, which will
3193         // reschedule next_interupt. Relies on CCREG from above.
3194         assem_debug("MTC0 DS %d\n", copr);
3195         emit_writeword(HOST_CCREG,&last_count);
3196         emit_movimm(0,HOST_CCREG);
3197         emit_storereg(CCREG,HOST_CCREG);
3198         emit_loadreg(rs1[i],1);
3199         emit_movimm(copr,0);
3200         emit_far_call(pcsx_mtc0_ds);
3201         emit_loadreg(rs1[i],s);
3202         return;
3203       }
3204       emit_movimm(start+i*4+4,HOST_TEMPREG);
3205       emit_writeword(HOST_TEMPREG,&pcaddr);
3206       emit_movimm(0,HOST_TEMPREG);
3207       emit_writeword(HOST_TEMPREG,&pending_exception);
3208     }
3209     if(s==HOST_CCREG)
3210       emit_loadreg(rs1[i],1);
3211     else if(s!=1)
3212       emit_mov(s,1);
3213     emit_movimm(copr,0);
3214     emit_far_call(pcsx_mtc0);
3215     if(copr==9||copr==11||copr==12||copr==13) {
3216       emit_readword(&Count,HOST_CCREG);
3217       emit_readword(&next_interupt,HOST_TEMPREG);
3218       emit_addimm(HOST_CCREG,-CLOCK_ADJUST(ccadj[i]),HOST_CCREG);
3219       emit_sub(HOST_CCREG,HOST_TEMPREG,HOST_CCREG);
3220       emit_writeword(HOST_TEMPREG,&last_count);
3221       emit_storereg(CCREG,HOST_CCREG);
3222     }
3223     if(copr==12||copr==13) {
3224       assert(!is_delayslot);
3225       emit_readword(&pending_exception,14);
3226       emit_test(14,14);
3227       void *jaddr = out;
3228       emit_jeq(0);
3229       emit_readword(&pcaddr, 0);
3230       emit_addimm(HOST_CCREG,2,HOST_CCREG);
3231       emit_far_call(get_addr_ht);
3232       emit_jmpreg(0);
3233       set_jump_target(jaddr, out);
3234     }
3235     emit_loadreg(rs1[i],s);
3236   }
3237   else
3238   {
3239     assert(opcode2[i]==0x10);
3240     //if((source[i]&0x3f)==0x10) // RFE
3241     {
3242       emit_readword(&Status,0);
3243       emit_andimm(0,0x3c,1);
3244       emit_andimm(0,~0xf,0);
3245       emit_orrshr_imm(1,2,0);
3246       emit_writeword(0,&Status);
3247     }
3248   }
3249 }
3250
3251 static void cop1_unusable(int i,struct regstat *i_regs)
3252 {
3253   // XXX: should just just do the exception instead
3254   //if(!cop1_usable)
3255   {
3256     void *jaddr=out;
3257     emit_jmp(0);
3258     add_stub_r(FP_STUB,jaddr,out,i,0,i_regs,is_delayslot,0);
3259   }
3260 }
3261
3262 static void cop1_assemble(int i,struct regstat *i_regs)
3263 {
3264   cop1_unusable(i, i_regs);
3265 }
3266
3267 static void c1ls_assemble(int i,struct regstat *i_regs)
3268 {
3269   cop1_unusable(i, i_regs);
3270 }
3271
3272 // FP_STUB
3273 static void do_cop1stub(int n)
3274 {
3275   literal_pool(256);
3276   assem_debug("do_cop1stub %x\n",start+stubs[n].a*4);
3277   set_jump_target(stubs[n].addr, out);
3278   int i=stubs[n].a;
3279 //  int rs=stubs[n].b;
3280   struct regstat *i_regs=(struct regstat *)stubs[n].c;
3281   int ds=stubs[n].d;
3282   if(!ds) {
3283     load_all_consts(regs[i].regmap_entry,regs[i].wasdirty,i);
3284     //if(i_regs!=&regs[i]) printf("oops: regs[i]=%x i_regs=%x",(int)&regs[i],(int)i_regs);
3285   }
3286   //else {printf("fp exception in delay slot\n");}
3287   wb_dirtys(i_regs->regmap_entry,i_regs->wasdirty);
3288   if(regs[i].regmap_entry[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG);
3289   emit_movimm(start+(i-ds)*4,EAX); // Get PC
3290   emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG); // CHECK: is this right?  There should probably be an extra cycle...
3291   emit_far_jump(ds?fp_exception_ds:fp_exception);
3292 }
3293
3294 static int cop2_is_stalling_op(int i, int *cycles)
3295 {
3296   if (opcode[i] == 0x3a) { // SWC2
3297     *cycles = 0;
3298     return 1;
3299   }
3300   if (itype[i] == COP2 && (opcode2[i] == 0 || opcode2[i] == 2)) { // MFC2/CFC2
3301     *cycles = 0;
3302     return 1;
3303   }
3304   if (itype[i] == C2OP) {
3305     *cycles = gte_cycletab[source[i] & 0x3f];
3306     return 1;
3307   }
3308   // ... what about MTC2/CTC2/LWC2?
3309   return 0;
3310 }
3311
3312 #if 0
3313 static void log_gte_stall(int stall, u_int cycle)
3314 {
3315   if ((u_int)stall <= 44)
3316     printf("x    stall %2d %u\n", stall, cycle + last_count);
3317  if (cycle + last_count > 1215348544) exit(1);
3318 }
3319
3320 static void emit_log_gte_stall(int i, int stall, u_int reglist)
3321 {
3322   save_regs(reglist);
3323   if (stall > 0)
3324     emit_movimm(stall, 0);
3325   else
3326     emit_mov(HOST_TEMPREG, 0);
3327   emit_addimm(HOST_CCREG, CLOCK_ADJUST(ccadj[i]), 1);
3328   emit_far_call(log_gte_stall);
3329   restore_regs(reglist);
3330 }
3331 #endif
3332
3333 static void cop2_call_stall_check(u_int op, int i, const struct regstat *i_regs, u_int reglist)
3334 {
3335   int j = i, other_gte_op_cycles = -1, stall = -MAXBLOCK, cycles_passed;
3336   int rtmp = reglist_find_free(reglist);
3337
3338   if (HACK_ENABLED(NDHACK_GTE_NO_STALL))
3339     return;
3340   //assert(get_reg(i_regs->regmap, CCREG) == HOST_CCREG);
3341   if (get_reg(i_regs->regmap, CCREG) != HOST_CCREG) {
3342     // happens occasionally... cc evicted? Don't bother then
3343     //printf("no cc %08x\n", start + i*4);
3344     return;
3345   }
3346   if (!bt[i]) {
3347     for (j = i - 1; j >= 0; j--) {
3348       //if (is_ds[j]) break;
3349       if (cop2_is_stalling_op(j, &other_gte_op_cycles) || bt[j])
3350         break;
3351     }
3352   }
3353   cycles_passed = CLOCK_ADJUST(ccadj[i] - ccadj[j]);
3354   if (other_gte_op_cycles >= 0)
3355     stall = other_gte_op_cycles - cycles_passed;
3356   else if (cycles_passed >= 44)
3357     stall = 0; // can't stall
3358   if (stall == -MAXBLOCK && rtmp >= 0) {
3359     // unknown stall, do the expensive runtime check
3360     assem_debug("; cop2_call_stall_check\n");
3361 #if 0 // too slow
3362     save_regs(reglist);
3363     emit_movimm(gte_cycletab[op], 0);
3364     emit_addimm(HOST_CCREG, CLOCK_ADJUST(ccadj[i]), 1);
3365     emit_far_call(call_gteStall);
3366     restore_regs(reglist);
3367 #else
3368     host_tempreg_acquire();
3369     emit_readword(&psxRegs.gteBusyCycle, rtmp);
3370     emit_addimm(rtmp, -CLOCK_ADJUST(ccadj[i]), rtmp);
3371     emit_sub(rtmp, HOST_CCREG, HOST_TEMPREG);
3372     emit_cmpimm(HOST_TEMPREG, 44);
3373     emit_cmovb_reg(rtmp, HOST_CCREG);
3374     //emit_log_gte_stall(i, 0, reglist);
3375     host_tempreg_release();
3376 #endif
3377   }
3378   else if (stall > 0) {
3379     //emit_log_gte_stall(i, stall, reglist);
3380     emit_addimm(HOST_CCREG, stall, HOST_CCREG);
3381   }
3382
3383   // save gteBusyCycle, if needed
3384   if (gte_cycletab[op] == 0)
3385     return;
3386   other_gte_op_cycles = -1;
3387   for (j = i + 1; j < slen; j++) {
3388     if (cop2_is_stalling_op(j, &other_gte_op_cycles))
3389       break;
3390     if (is_jump(j)) {
3391       // check ds
3392       if (j + 1 < slen && cop2_is_stalling_op(j + 1, &other_gte_op_cycles))
3393         j++;
3394       break;
3395     }
3396   }
3397   if (other_gte_op_cycles >= 0)
3398     // will handle stall when assembling that op
3399     return;
3400   cycles_passed = CLOCK_ADJUST(ccadj[min(j, slen -1)] - ccadj[i]);
3401   if (cycles_passed >= 44)
3402     return;
3403   assem_debug("; save gteBusyCycle\n");
3404   host_tempreg_acquire();
3405 #if 0
3406   emit_readword(&last_count, HOST_TEMPREG);
3407   emit_add(HOST_TEMPREG, HOST_CCREG, HOST_TEMPREG);
3408   emit_addimm(HOST_TEMPREG, CLOCK_ADJUST(ccadj[i]), HOST_TEMPREG);
3409   emit_addimm(HOST_TEMPREG, gte_cycletab[op]), HOST_TEMPREG);
3410   emit_writeword(HOST_TEMPREG, &psxRegs.gteBusyCycle);
3411 #else
3412   emit_addimm(HOST_CCREG, CLOCK_ADJUST(ccadj[i]) + gte_cycletab[op], HOST_TEMPREG);
3413   emit_writeword(HOST_TEMPREG, &psxRegs.gteBusyCycle);
3414 #endif
3415   host_tempreg_release();
3416 }
3417
3418 static void cop2_get_dreg(u_int copr,signed char tl,signed char temp)
3419 {
3420   switch (copr) {
3421     case 1:
3422     case 3:
3423     case 5:
3424     case 8:
3425     case 9:
3426     case 10:
3427     case 11:
3428       emit_readword(&reg_cop2d[copr],tl);
3429       emit_signextend16(tl,tl);
3430       emit_writeword(tl,&reg_cop2d[copr]); // hmh
3431       break;
3432     case 7:
3433     case 16:
3434     case 17:
3435     case 18:
3436     case 19:
3437       emit_readword(&reg_cop2d[copr],tl);
3438       emit_andimm(tl,0xffff,tl);
3439       emit_writeword(tl,&reg_cop2d[copr]);
3440       break;
3441     case 15:
3442       emit_readword(&reg_cop2d[14],tl); // SXY2
3443       emit_writeword(tl,&reg_cop2d[copr]);
3444       break;
3445     case 28:
3446     case 29:
3447       c2op_mfc2_29_assemble(tl,temp);
3448       break;