drc: emulate break opcode
[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
33 #include "new_dynarec_config.h"
34 #include "../psxhle.h"
35 #include "../psxinterpreter.h"
36 #include "../gte.h"
37 #include "emu_if.h" // emulator interface
38
39 #define noinline __attribute__((noinline,noclone))
40 #ifndef ARRAY_SIZE
41 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
42 #endif
43 #ifndef min
44 #define min(a, b) ((b) < (a) ? (b) : (a))
45 #endif
46 #ifndef max
47 #define max(a, b) ((b) > (a) ? (b) : (a))
48 #endif
49
50 //#define DISASM
51 //#define ASSEM_PRINT
52 //#define REG_ALLOC_PRINT
53
54 #ifdef ASSEM_PRINT
55 #define assem_debug printf
56 #else
57 #define assem_debug(...)
58 #endif
59 //#define inv_debug printf
60 #define inv_debug(...)
61
62 #ifdef __i386__
63 #include "assem_x86.h"
64 #endif
65 #ifdef __x86_64__
66 #include "assem_x64.h"
67 #endif
68 #ifdef __arm__
69 #include "assem_arm.h"
70 #endif
71 #ifdef __aarch64__
72 #include "assem_arm64.h"
73 #endif
74
75 #define RAM_SIZE 0x200000
76 #define MAXBLOCK 4096
77 #define MAX_OUTPUT_BLOCK_SIZE 262144
78
79 #ifdef VITA
80 // apparently Vita has a 16MB limit, so either we cut tc in half,
81 // or use this hack (it's a hack because tc size was designed to be power-of-2)
82 #define TC_REDUCE_BYTES 4096
83 #else
84 #define TC_REDUCE_BYTES 0
85 #endif
86
87 struct ndrc_mem
88 {
89   u_char translation_cache[(1 << TARGET_SIZE_2) - TC_REDUCE_BYTES];
90   struct
91   {
92     struct tramp_insns ops[2048 / sizeof(struct tramp_insns)];
93     const void *f[2048 / sizeof(void *)];
94   } tramp;
95 };
96
97 #ifdef BASE_ADDR_DYNAMIC
98 static struct ndrc_mem *ndrc;
99 #else
100 static struct ndrc_mem ndrc_ __attribute__((aligned(4096)));
101 static struct ndrc_mem *ndrc = &ndrc_;
102 #endif
103
104 // stubs
105 enum stub_type {
106   CC_STUB = 1,
107   FP_STUB = 2,
108   LOADB_STUB = 3,
109   LOADH_STUB = 4,
110   LOADW_STUB = 5,
111   LOADD_STUB = 6,
112   LOADBU_STUB = 7,
113   LOADHU_STUB = 8,
114   STOREB_STUB = 9,
115   STOREH_STUB = 10,
116   STOREW_STUB = 11,
117   STORED_STUB = 12,
118   STORELR_STUB = 13,
119   INVCODE_STUB = 14,
120 };
121
122 struct regstat
123 {
124   signed char regmap_entry[HOST_REGS]; // pre-insn + loop preloaded regs?
125   signed char regmap[HOST_REGS];
126   uint64_t wasdirty;
127   uint64_t dirty;
128   uint64_t u;
129   u_int wasconst;                // before; for example 'lw r2, (r2)' wasconst is true
130   u_int isconst;                 //  ... but isconst is false when r2 is known
131   u_int loadedconst;             // host regs that have constants loaded
132   u_int waswritten;              // MIPS regs that were used as store base before
133 };
134
135 // note: asm depends on this layout
136 struct ll_entry
137 {
138   u_int vaddr;
139   u_int reg_sv_flags;
140   void *addr;
141   struct ll_entry *next;
142 };
143
144 struct ht_entry
145 {
146   u_int vaddr[2];
147   void *tcaddr[2];
148 };
149
150 struct code_stub
151 {
152   enum stub_type type;
153   void *addr;
154   void *retaddr;
155   u_int a;
156   uintptr_t b;
157   uintptr_t c;
158   u_int d;
159   u_int e;
160 };
161
162 struct link_entry
163 {
164   void *addr;
165   u_int target;
166   u_int ext;
167 };
168
169 static struct decoded_insn
170 {
171   u_char itype;
172   u_char opcode;
173   u_char opcode2;
174   u_char rs1;
175   u_char rs2;
176   u_char rt1;
177   u_char rt2;
178   u_char lt1;
179   u_char bt:1;
180   u_char ooo:1;
181   u_char is_ds:1;
182   u_char is_jump:1;
183   u_char is_ujump:1;
184   u_char is_load:1;
185   u_char is_store:1;
186 } dops[MAXBLOCK];
187
188   // used by asm:
189   u_char *out;
190   struct ht_entry hash_table[65536]  __attribute__((aligned(16)));
191   struct ll_entry *jump_in[4096] __attribute__((aligned(16)));
192   struct ll_entry *jump_dirty[4096];
193
194   static struct ll_entry *jump_out[4096];
195   static u_int start;
196   static u_int *source;
197   static char insn[MAXBLOCK][10];
198   static uint64_t gte_rs[MAXBLOCK]; // gte: 32 data and 32 ctl regs
199   static uint64_t gte_rt[MAXBLOCK];
200   static uint64_t gte_unneeded[MAXBLOCK];
201   static u_int smrv[32]; // speculated MIPS register values
202   static u_int smrv_strong; // mask or regs that are likely to have correct values
203   static u_int smrv_weak; // same, but somewhat less likely
204   static u_int smrv_strong_next; // same, but after current insn executes
205   static u_int smrv_weak_next;
206   static int imm[MAXBLOCK];
207   static u_int ba[MAXBLOCK];
208   static uint64_t unneeded_reg[MAXBLOCK];
209   static uint64_t branch_unneeded_reg[MAXBLOCK];
210   // pre-instruction [i], excluding loop-preload regs?
211   static signed char regmap_pre[MAXBLOCK][HOST_REGS];
212   // contains 'real' consts at [i] insn, but may differ from what's actually
213   // loaded in host reg as 'final' value is always loaded, see get_final_value()
214   static uint32_t current_constmap[HOST_REGS];
215   static uint32_t constmap[MAXBLOCK][HOST_REGS];
216   static struct regstat regs[MAXBLOCK];
217   static struct regstat branch_regs[MAXBLOCK];
218   static signed char minimum_free_regs[MAXBLOCK];
219   static u_int needed_reg[MAXBLOCK];
220   static u_int wont_dirty[MAXBLOCK];
221   static u_int will_dirty[MAXBLOCK];
222   static int ccadj[MAXBLOCK];
223   static int slen;
224   static void *instr_addr[MAXBLOCK];
225   static struct link_entry link_addr[MAXBLOCK];
226   static int linkcount;
227   static struct code_stub stubs[MAXBLOCK*3];
228   static int stubcount;
229   static u_int literals[1024][2];
230   static int literalcount;
231   static int is_delayslot;
232   static char shadow[1048576]  __attribute__((aligned(16)));
233   static void *copy;
234   static int expirep;
235   static u_int stop_after_jal;
236   static u_int f1_hack;
237
238   int new_dynarec_hacks;
239   int new_dynarec_hacks_pergame;
240   int new_dynarec_hacks_old;
241   int new_dynarec_did_compile;
242
243   #define HACK_ENABLED(x) ((new_dynarec_hacks | new_dynarec_hacks_pergame) & (x))
244
245   extern int cycle_count; // ... until end of the timeslice, counts -N -> 0
246   extern int last_count;  // last absolute target, often = next_interupt
247   extern int pcaddr;
248   extern int pending_exception;
249   extern int branch_target;
250   extern uintptr_t ram_offset;
251   extern uintptr_t mini_ht[32][2];
252   extern u_char restore_candidate[512];
253
254   /* registers that may be allocated */
255   /* 1-31 gpr */
256 #define LOREG 32 // lo
257 #define HIREG 33 // hi
258 //#define FSREG 34 // FPU status (FCSR)
259 #define CSREG 35 // Coprocessor status
260 #define CCREG 36 // Cycle count
261 #define INVCP 37 // Pointer to invalid_code
262 //#define MMREG 38 // Pointer to memory_map
263 #define ROREG 39 // ram offset (if rdram!=0x80000000)
264 #define TEMPREG 40
265 #define FTEMP 40 // FPU temporary register
266 #define PTEMP 41 // Prefetch temporary register
267 //#define TLREG 42 // TLB mapping offset
268 #define RHASH 43 // Return address hash
269 #define RHTBL 44 // Return address hash table address
270 #define RTEMP 45 // JR/JALR address register
271 #define MAXREG 45
272 #define AGEN1 46 // Address generation temporary register
273 //#define AGEN2 47 // Address generation temporary register
274 //#define MGEN1 48 // Maptable address generation temporary register
275 //#define MGEN2 49 // Maptable address generation temporary register
276 #define BTREG 50 // Branch target temporary register
277
278   /* instruction types */
279 #define NOP 0     // No operation
280 #define LOAD 1    // Load
281 #define STORE 2   // Store
282 #define LOADLR 3  // Unaligned load
283 #define STORELR 4 // Unaligned store
284 #define MOV 5     // Move
285 #define ALU 6     // Arithmetic/logic
286 #define MULTDIV 7 // Multiply/divide
287 #define SHIFT 8   // Shift by register
288 #define SHIFTIMM 9// Shift by immediate
289 #define IMM16 10  // 16-bit immediate
290 #define RJUMP 11  // Unconditional jump to register
291 #define UJUMP 12  // Unconditional jump
292 #define CJUMP 13  // Conditional branch (BEQ/BNE/BGTZ/BLEZ)
293 #define SJUMP 14  // Conditional branch (regimm format)
294 #define COP0 15   // Coprocessor 0
295 #define COP1 16   // Coprocessor 1
296 #define C1LS 17   // Coprocessor 1 load/store
297 //#define FJUMP 18  // Conditional branch (floating point)
298 //#define FLOAT 19  // Floating point unit
299 //#define FCONV 20  // Convert integer to float
300 //#define FCOMP 21  // Floating point compare (sets FSREG)
301 #define SYSCALL 22// SYSCALL,BREAK
302 #define OTHER 23  // Other
303 #define SPAN 24   // Branch/delay slot spans 2 pages
304 #define NI 25     // Not implemented
305 #define HLECALL 26// PCSX fake opcodes for HLE
306 #define COP2 27   // Coprocessor 2 move
307 #define C2LS 28   // Coprocessor 2 load/store
308 #define C2OP 29   // Coprocessor 2 operation
309 #define INTCALL 30// Call interpreter to handle rare corner cases
310
311   /* branch codes */
312 #define TAKEN 1
313 #define NOTTAKEN 2
314 #define NULLDS 3
315
316 #define DJT_1 (void *)1l // no function, just a label in assem_debug log
317 #define DJT_2 (void *)2l
318
319 // asm linkage
320 int new_recompile_block(u_int addr);
321 void *get_addr_ht(u_int vaddr);
322 void invalidate_block(u_int block);
323 void invalidate_addr(u_int addr);
324 void remove_hash(int vaddr);
325 void dyna_linker();
326 void dyna_linker_ds();
327 void verify_code();
328 void verify_code_ds();
329 void cc_interrupt();
330 void fp_exception();
331 void fp_exception_ds();
332 void jump_syscall   (u_int u0, u_int u1, u_int pc);
333 void jump_syscall_ds(u_int u0, u_int u1, u_int pc);
334 void jump_break   (u_int u0, u_int u1, u_int pc);
335 void jump_break_ds(u_int u0, u_int u1, u_int pc);
336 void jump_to_new_pc();
337 void call_gteStall();
338 void new_dyna_leave();
339
340 // Needed by assembler
341 static void wb_register(signed char r, const signed char regmap[], uint64_t dirty);
342 static void wb_dirtys(const signed char i_regmap[], uint64_t i_dirty);
343 static void wb_needed_dirtys(const signed char i_regmap[], uint64_t i_dirty, int addr);
344 static void load_all_regs(const signed char i_regmap[]);
345 static void load_needed_regs(const signed char i_regmap[], const signed char next_regmap[]);
346 static void load_regs_entry(int t);
347 static void load_all_consts(const signed char regmap[], u_int dirty, int i);
348 static u_int get_host_reglist(const signed char *regmap);
349
350 static int verify_dirty(const u_int *ptr);
351 static int get_final_value(int hr, int i, int *value);
352 static void add_stub(enum stub_type type, void *addr, void *retaddr,
353   u_int a, uintptr_t b, uintptr_t c, u_int d, u_int e);
354 static void add_stub_r(enum stub_type type, void *addr, void *retaddr,
355   int i, int addr_reg, const struct regstat *i_regs, int ccadj, u_int reglist);
356 static void add_to_linker(void *addr, u_int target, int ext);
357 static void *emit_fastpath_cmp_jump(int i, const struct regstat *i_regs,
358   int addr, int *offset_reg, int *addr_reg_override);
359 static void *get_direct_memhandler(void *table, u_int addr,
360   enum stub_type type, uintptr_t *addr_host);
361 static void cop2_do_stall_check(u_int op, int i, const struct regstat *i_regs, u_int reglist);
362 static void pass_args(int a0, int a1);
363 static void emit_far_jump(const void *f);
364 static void emit_far_call(const void *f);
365
366 #ifdef VITA
367 #include <psp2/kernel/sysmem.h>
368 static int sceBlock;
369 // note: this interacts with RetroArch's Vita bootstrap code: bootstrap/vita/sbrk.c
370 extern int getVMBlock();
371 int _newlib_vm_size_user = sizeof(*ndrc);
372 #endif
373
374 static void mprotect_w_x(void *start, void *end, int is_x)
375 {
376 #ifdef NO_WRITE_EXEC
377   #if defined(VITA)
378   // *Open* enables write on all memory that was
379   // allocated by sceKernelAllocMemBlockForVM()?
380   if (is_x)
381     sceKernelCloseVMDomain();
382   else
383     sceKernelOpenVMDomain();
384   #else
385   u_long mstart = (u_long)start & ~4095ul;
386   u_long mend = (u_long)end;
387   if (mprotect((void *)mstart, mend - mstart,
388                PROT_READ | (is_x ? PROT_EXEC : PROT_WRITE)) != 0)
389     SysPrintf("mprotect(%c) failed: %s\n", is_x ? 'x' : 'w', strerror(errno));
390   #endif
391 #endif
392 }
393
394 static void start_tcache_write(void *start, void *end)
395 {
396   mprotect_w_x(start, end, 0);
397 }
398
399 static void end_tcache_write(void *start, void *end)
400 {
401 #if defined(__arm__) || defined(__aarch64__)
402   size_t len = (char *)end - (char *)start;
403   #if   defined(__BLACKBERRY_QNX__)
404   msync(start, len, MS_SYNC | MS_CACHE_ONLY | MS_INVALIDATE_ICACHE);
405   #elif defined(__MACH__)
406   sys_cache_control(kCacheFunctionPrepareForExecution, start, len);
407   #elif defined(VITA)
408   sceKernelSyncVMDomain(sceBlock, start, len);
409   #elif defined(_3DS)
410   ctr_flush_invalidate_cache();
411   #elif defined(__aarch64__)
412   // as of 2021, __clear_cache() is still broken on arm64
413   // so here is a custom one :(
414   clear_cache_arm64(start, end);
415   #else
416   __clear_cache(start, end);
417   #endif
418   (void)len;
419 #endif
420
421   mprotect_w_x(start, end, 1);
422 }
423
424 static void *start_block(void)
425 {
426   u_char *end = out + MAX_OUTPUT_BLOCK_SIZE;
427   if (end > ndrc->translation_cache + sizeof(ndrc->translation_cache))
428     end = ndrc->translation_cache + sizeof(ndrc->translation_cache);
429   start_tcache_write(out, end);
430   return out;
431 }
432
433 static void end_block(void *start)
434 {
435   end_tcache_write(start, out);
436 }
437
438 // also takes care of w^x mappings when patching code
439 static u_int needs_clear_cache[1<<(TARGET_SIZE_2-17)];
440
441 static void mark_clear_cache(void *target)
442 {
443   uintptr_t offset = (u_char *)target - ndrc->translation_cache;
444   u_int mask = 1u << ((offset >> 12) & 31);
445   if (!(needs_clear_cache[offset >> 17] & mask)) {
446     char *start = (char *)((uintptr_t)target & ~4095l);
447     start_tcache_write(start, start + 4095);
448     needs_clear_cache[offset >> 17] |= mask;
449   }
450 }
451
452 // Clearing the cache is rather slow on ARM Linux, so mark the areas
453 // that need to be cleared, and then only clear these areas once.
454 static void do_clear_cache(void)
455 {
456   int i, j;
457   for (i = 0; i < (1<<(TARGET_SIZE_2-17)); i++)
458   {
459     u_int bitmap = needs_clear_cache[i];
460     if (!bitmap)
461       continue;
462     for (j = 0; j < 32; j++)
463     {
464       u_char *start, *end;
465       if (!(bitmap & (1<<j)))
466         continue;
467
468       start = ndrc->translation_cache + i*131072 + j*4096;
469       end = start + 4095;
470       for (j++; j < 32; j++) {
471         if (!(bitmap & (1<<j)))
472           break;
473         end += 4096;
474       }
475       end_tcache_write(start, end);
476     }
477     needs_clear_cache[i] = 0;
478   }
479 }
480
481 //#define DEBUG_CYCLE_COUNT 1
482
483 #define NO_CYCLE_PENALTY_THR 12
484
485 int cycle_multiplier = CYCLE_MULT_DEFAULT; // 100 for 1.0
486 int cycle_multiplier_override;
487 int cycle_multiplier_old;
488 static int cycle_multiplier_active;
489
490 static int CLOCK_ADJUST(int x)
491 {
492   int m = cycle_multiplier_active;
493   int s = (x >> 31) | 1;
494   return (x * m + s * 50) / 100;
495 }
496
497 static int ds_writes_rjump_rs(int i)
498 {
499   return dops[i].rs1 != 0 && (dops[i].rs1 == dops[i+1].rt1 || dops[i].rs1 == dops[i+1].rt2);
500 }
501
502 static u_int get_page(u_int vaddr)
503 {
504   u_int page=vaddr&~0xe0000000;
505   if (page < 0x1000000)
506     page &= ~0x0e00000; // RAM mirrors
507   page>>=12;
508   if(page>2048) page=2048+(page&2047);
509   return page;
510 }
511
512 // no virtual mem in PCSX
513 static u_int get_vpage(u_int vaddr)
514 {
515   return get_page(vaddr);
516 }
517
518 static struct ht_entry *hash_table_get(u_int vaddr)
519 {
520   return &hash_table[((vaddr>>16)^vaddr)&0xFFFF];
521 }
522
523 static void hash_table_add(struct ht_entry *ht_bin, u_int vaddr, void *tcaddr)
524 {
525   ht_bin->vaddr[1] = ht_bin->vaddr[0];
526   ht_bin->tcaddr[1] = ht_bin->tcaddr[0];
527   ht_bin->vaddr[0] = vaddr;
528   ht_bin->tcaddr[0] = tcaddr;
529 }
530
531 // some messy ari64's code, seems to rely on unsigned 32bit overflow
532 static int doesnt_expire_soon(void *tcaddr)
533 {
534   u_int diff = (u_int)((u_char *)tcaddr - out) << (32-TARGET_SIZE_2);
535   return diff > (u_int)(0x60000000 + (MAX_OUTPUT_BLOCK_SIZE << (32-TARGET_SIZE_2)));
536 }
537
538 // Get address from virtual address
539 // This is called from the recompiled JR/JALR instructions
540 void noinline *get_addr(u_int vaddr)
541 {
542   u_int page=get_page(vaddr);
543   u_int vpage=get_vpage(vaddr);
544   struct ll_entry *head;
545   //printf("TRACE: count=%d next=%d (get_addr %x,page %d)\n",Count,next_interupt,vaddr,page);
546   head=jump_in[page];
547   while(head!=NULL) {
548     if(head->vaddr==vaddr) {
549   //printf("TRACE: count=%d next=%d (get_addr match %x: %p)\n",Count,next_interupt,vaddr,head->addr);
550       hash_table_add(hash_table_get(vaddr), vaddr, head->addr);
551       return head->addr;
552     }
553     head=head->next;
554   }
555   head=jump_dirty[vpage];
556   while(head!=NULL) {
557     if(head->vaddr==vaddr) {
558       //printf("TRACE: count=%d next=%d (get_addr match dirty %x: %p)\n",Count,next_interupt,vaddr,head->addr);
559       // Don't restore blocks which are about to expire from the cache
560       if (doesnt_expire_soon(head->addr))
561       if (verify_dirty(head->addr)) {
562         //printf("restore candidate: %x (%d) d=%d\n",vaddr,page,invalid_code[vaddr>>12]);
563         invalid_code[vaddr>>12]=0;
564         inv_code_start=inv_code_end=~0;
565         if(vpage<2048) {
566           restore_candidate[vpage>>3]|=1<<(vpage&7);
567         }
568         else restore_candidate[page>>3]|=1<<(page&7);
569         struct ht_entry *ht_bin = hash_table_get(vaddr);
570         if (ht_bin->vaddr[0] == vaddr)
571           ht_bin->tcaddr[0] = head->addr; // Replace existing entry
572         else
573           hash_table_add(ht_bin, vaddr, head->addr);
574
575         return head->addr;
576       }
577     }
578     head=head->next;
579   }
580   //printf("TRACE: count=%d next=%d (get_addr no-match %x)\n",Count,next_interupt,vaddr);
581   int r=new_recompile_block(vaddr);
582   if(r==0) return get_addr(vaddr);
583   // Execute in unmapped page, generate pagefault execption
584   Status|=2;
585   Cause=(vaddr<<31)|0x8;
586   EPC=(vaddr&1)?vaddr-5:vaddr;
587   BadVAddr=(vaddr&~1);
588   Context=(Context&0xFF80000F)|((BadVAddr>>9)&0x007FFFF0);
589   EntryHi=BadVAddr&0xFFFFE000;
590   return get_addr_ht(0x80000000);
591 }
592 // Look up address in hash table first
593 void *get_addr_ht(u_int vaddr)
594 {
595   //printf("TRACE: count=%d next=%d (get_addr_ht %x)\n",Count,next_interupt,vaddr);
596   const struct ht_entry *ht_bin = hash_table_get(vaddr);
597   if (ht_bin->vaddr[0] == vaddr) return ht_bin->tcaddr[0];
598   if (ht_bin->vaddr[1] == vaddr) return ht_bin->tcaddr[1];
599   return get_addr(vaddr);
600 }
601
602 void clear_all_regs(signed char regmap[])
603 {
604   int hr;
605   for (hr=0;hr<HOST_REGS;hr++) regmap[hr]=-1;
606 }
607
608 static signed char get_reg(const signed char regmap[],int r)
609 {
610   int hr;
611   for (hr=0;hr<HOST_REGS;hr++) if(hr!=EXCLUDE_REG&&regmap[hr]==r) return hr;
612   return -1;
613 }
614
615 // Find a register that is available for two consecutive cycles
616 static signed char get_reg2(signed char regmap1[], const signed char regmap2[], int r)
617 {
618   int hr;
619   for (hr=0;hr<HOST_REGS;hr++) if(hr!=EXCLUDE_REG&&regmap1[hr]==r&&regmap2[hr]==r) return hr;
620   return -1;
621 }
622
623 int count_free_regs(signed char regmap[])
624 {
625   int count=0;
626   int hr;
627   for(hr=0;hr<HOST_REGS;hr++)
628   {
629     if(hr!=EXCLUDE_REG) {
630       if(regmap[hr]<0) count++;
631     }
632   }
633   return count;
634 }
635
636 void dirty_reg(struct regstat *cur,signed char reg)
637 {
638   int hr;
639   if(!reg) return;
640   for (hr=0;hr<HOST_REGS;hr++) {
641     if((cur->regmap[hr]&63)==reg) {
642       cur->dirty|=1<<hr;
643     }
644   }
645 }
646
647 static void set_const(struct regstat *cur, signed char reg, uint32_t value)
648 {
649   int hr;
650   if(!reg) return;
651   for (hr=0;hr<HOST_REGS;hr++) {
652     if(cur->regmap[hr]==reg) {
653       cur->isconst|=1<<hr;
654       current_constmap[hr]=value;
655     }
656   }
657 }
658
659 static void clear_const(struct regstat *cur, signed char reg)
660 {
661   int hr;
662   if(!reg) return;
663   for (hr=0;hr<HOST_REGS;hr++) {
664     if((cur->regmap[hr]&63)==reg) {
665       cur->isconst&=~(1<<hr);
666     }
667   }
668 }
669
670 static int is_const(struct regstat *cur, signed char reg)
671 {
672   int hr;
673   if(reg<0) return 0;
674   if(!reg) return 1;
675   for (hr=0;hr<HOST_REGS;hr++) {
676     if((cur->regmap[hr]&63)==reg) {
677       return (cur->isconst>>hr)&1;
678     }
679   }
680   return 0;
681 }
682
683 static uint32_t get_const(struct regstat *cur, signed char reg)
684 {
685   int hr;
686   if(!reg) return 0;
687   for (hr=0;hr<HOST_REGS;hr++) {
688     if(cur->regmap[hr]==reg) {
689       return current_constmap[hr];
690     }
691   }
692   SysPrintf("Unknown constant in r%d\n",reg);
693   abort();
694 }
695
696 // Least soon needed registers
697 // Look at the next ten instructions and see which registers
698 // will be used.  Try not to reallocate these.
699 void lsn(u_char hsn[], int i, int *preferred_reg)
700 {
701   int j;
702   int b=-1;
703   for(j=0;j<9;j++)
704   {
705     if(i+j>=slen) {
706       j=slen-i-1;
707       break;
708     }
709     if (dops[i+j].is_ujump)
710     {
711       // Don't go past an unconditonal jump
712       j++;
713       break;
714     }
715   }
716   for(;j>=0;j--)
717   {
718     if(dops[i+j].rs1) hsn[dops[i+j].rs1]=j;
719     if(dops[i+j].rs2) hsn[dops[i+j].rs2]=j;
720     if(dops[i+j].rt1) hsn[dops[i+j].rt1]=j;
721     if(dops[i+j].rt2) hsn[dops[i+j].rt2]=j;
722     if(dops[i+j].itype==STORE || dops[i+j].itype==STORELR) {
723       // Stores can allocate zero
724       hsn[dops[i+j].rs1]=j;
725       hsn[dops[i+j].rs2]=j;
726     }
727     if (ram_offset && (dops[i+j].is_load || dops[i+j].is_store))
728       hsn[ROREG] = j;
729     // On some architectures stores need invc_ptr
730     #if defined(HOST_IMM8)
731     if (dops[i+j].is_store)
732       hsn[INVCP] = j;
733     #endif
734     if(i+j>=0&&(dops[i+j].itype==UJUMP||dops[i+j].itype==CJUMP||dops[i+j].itype==SJUMP))
735     {
736       hsn[CCREG]=j;
737       b=j;
738     }
739   }
740   if(b>=0)
741   {
742     if(ba[i+b]>=start && ba[i+b]<(start+slen*4))
743     {
744       // Follow first branch
745       int t=(ba[i+b]-start)>>2;
746       j=7-b;if(t+j>=slen) j=slen-t-1;
747       for(;j>=0;j--)
748       {
749         if(dops[t+j].rs1) if(hsn[dops[t+j].rs1]>j+b+2) hsn[dops[t+j].rs1]=j+b+2;
750         if(dops[t+j].rs2) if(hsn[dops[t+j].rs2]>j+b+2) hsn[dops[t+j].rs2]=j+b+2;
751         //if(dops[t+j].rt1) if(hsn[dops[t+j].rt1]>j+b+2) hsn[dops[t+j].rt1]=j+b+2;
752         //if(dops[t+j].rt2) if(hsn[dops[t+j].rt2]>j+b+2) hsn[dops[t+j].rt2]=j+b+2;
753       }
754     }
755     // TODO: preferred register based on backward branch
756   }
757   // Delay slot should preferably not overwrite branch conditions or cycle count
758   if (i > 0 && dops[i-1].is_jump) {
759     if(dops[i-1].rs1) if(hsn[dops[i-1].rs1]>1) hsn[dops[i-1].rs1]=1;
760     if(dops[i-1].rs2) if(hsn[dops[i-1].rs2]>1) hsn[dops[i-1].rs2]=1;
761     hsn[CCREG]=1;
762     // ...or hash tables
763     hsn[RHASH]=1;
764     hsn[RHTBL]=1;
765   }
766   // Coprocessor load/store needs FTEMP, even if not declared
767   if(dops[i].itype==C2LS) {
768     hsn[FTEMP]=0;
769   }
770   // Load L/R also uses FTEMP as a temporary register
771   if(dops[i].itype==LOADLR) {
772     hsn[FTEMP]=0;
773   }
774   // Also SWL/SWR/SDL/SDR
775   if(dops[i].opcode==0x2a||dops[i].opcode==0x2e||dops[i].opcode==0x2c||dops[i].opcode==0x2d) {
776     hsn[FTEMP]=0;
777   }
778   // Don't remove the miniht registers
779   if(dops[i].itype==UJUMP||dops[i].itype==RJUMP)
780   {
781     hsn[RHASH]=0;
782     hsn[RHTBL]=0;
783   }
784 }
785
786 // We only want to allocate registers if we're going to use them again soon
787 int needed_again(int r, int i)
788 {
789   int j;
790   int b=-1;
791   int rn=10;
792
793   if (i > 0 && dops[i-1].is_ujump)
794   {
795     if(ba[i-1]<start || ba[i-1]>start+slen*4-4)
796       return 0; // Don't need any registers if exiting the block
797   }
798   for(j=0;j<9;j++)
799   {
800     if(i+j>=slen) {
801       j=slen-i-1;
802       break;
803     }
804     if (dops[i+j].is_ujump)
805     {
806       // Don't go past an unconditonal jump
807       j++;
808       break;
809     }
810     if(dops[i+j].itype==SYSCALL||dops[i+j].itype==HLECALL||dops[i+j].itype==INTCALL||((source[i+j]&0xfc00003f)==0x0d))
811     {
812       break;
813     }
814   }
815   for(;j>=1;j--)
816   {
817     if(dops[i+j].rs1==r) rn=j;
818     if(dops[i+j].rs2==r) rn=j;
819     if((unneeded_reg[i+j]>>r)&1) rn=10;
820     if(i+j>=0&&(dops[i+j].itype==UJUMP||dops[i+j].itype==CJUMP||dops[i+j].itype==SJUMP))
821     {
822       b=j;
823     }
824   }
825   if(rn<10) return 1;
826   (void)b;
827   return 0;
828 }
829
830 // Try to match register allocations at the end of a loop with those
831 // at the beginning
832 int loop_reg(int i, int r, int hr)
833 {
834   int j,k;
835   for(j=0;j<9;j++)
836   {
837     if(i+j>=slen) {
838       j=slen-i-1;
839       break;
840     }
841     if (dops[i+j].is_ujump)
842     {
843       // Don't go past an unconditonal jump
844       j++;
845       break;
846     }
847   }
848   k=0;
849   if(i>0){
850     if(dops[i-1].itype==UJUMP||dops[i-1].itype==CJUMP||dops[i-1].itype==SJUMP)
851       k--;
852   }
853   for(;k<j;k++)
854   {
855     assert(r < 64);
856     if((unneeded_reg[i+k]>>r)&1) return hr;
857     if(i+k>=0&&(dops[i+k].itype==UJUMP||dops[i+k].itype==CJUMP||dops[i+k].itype==SJUMP))
858     {
859       if(ba[i+k]>=start && ba[i+k]<(start+i*4))
860       {
861         int t=(ba[i+k]-start)>>2;
862         int reg=get_reg(regs[t].regmap_entry,r);
863         if(reg>=0) return reg;
864         //reg=get_reg(regs[t+1].regmap_entry,r);
865         //if(reg>=0) return reg;
866       }
867     }
868   }
869   return hr;
870 }
871
872
873 // Allocate every register, preserving source/target regs
874 void alloc_all(struct regstat *cur,int i)
875 {
876   int hr;
877
878   for(hr=0;hr<HOST_REGS;hr++) {
879     if(hr!=EXCLUDE_REG) {
880       if(((cur->regmap[hr]&63)!=dops[i].rs1)&&((cur->regmap[hr]&63)!=dops[i].rs2)&&
881          ((cur->regmap[hr]&63)!=dops[i].rt1)&&((cur->regmap[hr]&63)!=dops[i].rt2))
882       {
883         cur->regmap[hr]=-1;
884         cur->dirty&=~(1<<hr);
885       }
886       // Don't need zeros
887       if((cur->regmap[hr]&63)==0)
888       {
889         cur->regmap[hr]=-1;
890         cur->dirty&=~(1<<hr);
891       }
892     }
893   }
894 }
895
896 #ifndef NDEBUG
897 static int host_tempreg_in_use;
898
899 static void host_tempreg_acquire(void)
900 {
901   assert(!host_tempreg_in_use);
902   host_tempreg_in_use = 1;
903 }
904
905 static void host_tempreg_release(void)
906 {
907   host_tempreg_in_use = 0;
908 }
909 #else
910 static void host_tempreg_acquire(void) {}
911 static void host_tempreg_release(void) {}
912 #endif
913
914 #ifdef ASSEM_PRINT
915 extern void gen_interupt();
916 extern void do_insn_cmp();
917 #define FUNCNAME(f) { f, " " #f }
918 static const struct {
919   void *addr;
920   const char *name;
921 } function_names[] = {
922   FUNCNAME(cc_interrupt),
923   FUNCNAME(gen_interupt),
924   FUNCNAME(get_addr_ht),
925   FUNCNAME(get_addr),
926   FUNCNAME(jump_handler_read8),
927   FUNCNAME(jump_handler_read16),
928   FUNCNAME(jump_handler_read32),
929   FUNCNAME(jump_handler_write8),
930   FUNCNAME(jump_handler_write16),
931   FUNCNAME(jump_handler_write32),
932   FUNCNAME(invalidate_addr),
933   FUNCNAME(jump_to_new_pc),
934   FUNCNAME(jump_break),
935   FUNCNAME(jump_break_ds),
936   FUNCNAME(jump_syscall),
937   FUNCNAME(jump_syscall_ds),
938   FUNCNAME(call_gteStall),
939   FUNCNAME(new_dyna_leave),
940   FUNCNAME(pcsx_mtc0),
941   FUNCNAME(pcsx_mtc0_ds),
942 #ifdef DRC_DBG
943   FUNCNAME(do_insn_cmp),
944 #endif
945 #ifdef __arm__
946   FUNCNAME(verify_code),
947 #endif
948 };
949
950 static const char *func_name(const void *a)
951 {
952   int i;
953   for (i = 0; i < sizeof(function_names)/sizeof(function_names[0]); i++)
954     if (function_names[i].addr == a)
955       return function_names[i].name;
956   return "";
957 }
958 #else
959 #define func_name(x) ""
960 #endif
961
962 #ifdef __i386__
963 #include "assem_x86.c"
964 #endif
965 #ifdef __x86_64__
966 #include "assem_x64.c"
967 #endif
968 #ifdef __arm__
969 #include "assem_arm.c"
970 #endif
971 #ifdef __aarch64__
972 #include "assem_arm64.c"
973 #endif
974
975 static void *get_trampoline(const void *f)
976 {
977   size_t i;
978
979   for (i = 0; i < ARRAY_SIZE(ndrc->tramp.f); i++) {
980     if (ndrc->tramp.f[i] == f || ndrc->tramp.f[i] == NULL)
981       break;
982   }
983   if (i == ARRAY_SIZE(ndrc->tramp.f)) {
984     SysPrintf("trampoline table is full, last func %p\n", f);
985     abort();
986   }
987   if (ndrc->tramp.f[i] == NULL) {
988     start_tcache_write(&ndrc->tramp.f[i], &ndrc->tramp.f[i + 1]);
989     ndrc->tramp.f[i] = f;
990     end_tcache_write(&ndrc->tramp.f[i], &ndrc->tramp.f[i + 1]);
991   }
992   return &ndrc->tramp.ops[i];
993 }
994
995 static void emit_far_jump(const void *f)
996 {
997   if (can_jump_or_call(f)) {
998     emit_jmp(f);
999     return;
1000   }
1001
1002   f = get_trampoline(f);
1003   emit_jmp(f);
1004 }
1005
1006 static void emit_far_call(const void *f)
1007 {
1008   if (can_jump_or_call(f)) {
1009     emit_call(f);
1010     return;
1011   }
1012
1013   f = get_trampoline(f);
1014   emit_call(f);
1015 }
1016
1017 // Add virtual address mapping to linked list
1018 void ll_add(struct ll_entry **head,int vaddr,void *addr)
1019 {
1020   struct ll_entry *new_entry;
1021   new_entry=malloc(sizeof(struct ll_entry));
1022   assert(new_entry!=NULL);
1023   new_entry->vaddr=vaddr;
1024   new_entry->reg_sv_flags=0;
1025   new_entry->addr=addr;
1026   new_entry->next=*head;
1027   *head=new_entry;
1028 }
1029
1030 void ll_add_flags(struct ll_entry **head,int vaddr,u_int reg_sv_flags,void *addr)
1031 {
1032   ll_add(head,vaddr,addr);
1033   (*head)->reg_sv_flags=reg_sv_flags;
1034 }
1035
1036 // Check if an address is already compiled
1037 // but don't return addresses which are about to expire from the cache
1038 void *check_addr(u_int vaddr)
1039 {
1040   struct ht_entry *ht_bin = hash_table_get(vaddr);
1041   size_t i;
1042   for (i = 0; i < ARRAY_SIZE(ht_bin->vaddr); i++) {
1043     if (ht_bin->vaddr[i] == vaddr)
1044       if (doesnt_expire_soon((u_char *)ht_bin->tcaddr[i] - MAX_OUTPUT_BLOCK_SIZE))
1045         if (isclean(ht_bin->tcaddr[i]))
1046           return ht_bin->tcaddr[i];
1047   }
1048   u_int page=get_page(vaddr);
1049   struct ll_entry *head;
1050   head=jump_in[page];
1051   while (head != NULL) {
1052     if (head->vaddr == vaddr) {
1053       if (doesnt_expire_soon(head->addr)) {
1054         // Update existing entry with current address
1055         if (ht_bin->vaddr[0] == vaddr) {
1056           ht_bin->tcaddr[0] = head->addr;
1057           return head->addr;
1058         }
1059         if (ht_bin->vaddr[1] == vaddr) {
1060           ht_bin->tcaddr[1] = head->addr;
1061           return head->addr;
1062         }
1063         // Insert into hash table with low priority.
1064         // Don't evict existing entries, as they are probably
1065         // addresses that are being accessed frequently.
1066         if (ht_bin->vaddr[0] == -1) {
1067           ht_bin->vaddr[0] = vaddr;
1068           ht_bin->tcaddr[0] = head->addr;
1069         }
1070         else if (ht_bin->vaddr[1] == -1) {
1071           ht_bin->vaddr[1] = vaddr;
1072           ht_bin->tcaddr[1] = head->addr;
1073         }
1074         return head->addr;
1075       }
1076     }
1077     head=head->next;
1078   }
1079   return 0;
1080 }
1081
1082 void remove_hash(int vaddr)
1083 {
1084   //printf("remove hash: %x\n",vaddr);
1085   struct ht_entry *ht_bin = hash_table_get(vaddr);
1086   if (ht_bin->vaddr[1] == vaddr) {
1087     ht_bin->vaddr[1] = -1;
1088     ht_bin->tcaddr[1] = NULL;
1089   }
1090   if (ht_bin->vaddr[0] == vaddr) {
1091     ht_bin->vaddr[0] = ht_bin->vaddr[1];
1092     ht_bin->tcaddr[0] = ht_bin->tcaddr[1];
1093     ht_bin->vaddr[1] = -1;
1094     ht_bin->tcaddr[1] = NULL;
1095   }
1096 }
1097
1098 static void ll_remove_matching_addrs(struct ll_entry **head,
1099   uintptr_t base_offs_s, int shift)
1100 {
1101   struct ll_entry *next;
1102   while(*head) {
1103     uintptr_t o1 = (u_char *)(*head)->addr - ndrc->translation_cache;
1104     uintptr_t o2 = o1 - MAX_OUTPUT_BLOCK_SIZE;
1105     if ((o1 >> shift) == base_offs_s || (o2 >> shift) == base_offs_s)
1106     {
1107       inv_debug("EXP: Remove pointer to %p (%x)\n",(*head)->addr,(*head)->vaddr);
1108       remove_hash((*head)->vaddr);
1109       next=(*head)->next;
1110       free(*head);
1111       *head=next;
1112     }
1113     else
1114     {
1115       head=&((*head)->next);
1116     }
1117   }
1118 }
1119
1120 // Remove all entries from linked list
1121 void ll_clear(struct ll_entry **head)
1122 {
1123   struct ll_entry *cur;
1124   struct ll_entry *next;
1125   if((cur=*head)) {
1126     *head=0;
1127     while(cur) {
1128       next=cur->next;
1129       free(cur);
1130       cur=next;
1131     }
1132   }
1133 }
1134
1135 // Dereference the pointers and remove if it matches
1136 static void ll_kill_pointers(struct ll_entry *head,
1137   uintptr_t base_offs_s, int shift)
1138 {
1139   while(head) {
1140     u_char *ptr = get_pointer(head->addr);
1141     uintptr_t o1 = ptr - ndrc->translation_cache;
1142     uintptr_t o2 = o1 - MAX_OUTPUT_BLOCK_SIZE;
1143     inv_debug("EXP: Lookup pointer to %p at %p (%x)\n",ptr,head->addr,head->vaddr);
1144     if ((o1 >> shift) == base_offs_s || (o2 >> shift) == base_offs_s)
1145     {
1146       inv_debug("EXP: Kill pointer at %p (%x)\n",head->addr,head->vaddr);
1147       void *host_addr=find_extjump_insn(head->addr);
1148       mark_clear_cache(host_addr);
1149       set_jump_target(host_addr, head->addr);
1150     }
1151     head=head->next;
1152   }
1153 }
1154
1155 // This is called when we write to a compiled block (see do_invstub)
1156 static void invalidate_page(u_int page)
1157 {
1158   struct ll_entry *head;
1159   struct ll_entry *next;
1160   head=jump_in[page];
1161   jump_in[page]=0;
1162   while(head!=NULL) {
1163     inv_debug("INVALIDATE: %x\n",head->vaddr);
1164     remove_hash(head->vaddr);
1165     next=head->next;
1166     free(head);
1167     head=next;
1168   }
1169   head=jump_out[page];
1170   jump_out[page]=0;
1171   while(head!=NULL) {
1172     inv_debug("INVALIDATE: kill pointer to %x (%p)\n",head->vaddr,head->addr);
1173     void *host_addr=find_extjump_insn(head->addr);
1174     mark_clear_cache(host_addr);
1175     set_jump_target(host_addr, head->addr); // point back to dyna_linker
1176     next=head->next;
1177     free(head);
1178     head=next;
1179   }
1180 }
1181
1182 static void invalidate_block_range(u_int block, u_int first, u_int last)
1183 {
1184   u_int page=get_page(block<<12);
1185   //printf("first=%d last=%d\n",first,last);
1186   invalidate_page(page);
1187   assert(first+5>page); // NB: this assumes MAXBLOCK<=4096 (4 pages)
1188   assert(last<page+5);
1189   // Invalidate the adjacent pages if a block crosses a 4K boundary
1190   while(first<page) {
1191     invalidate_page(first);
1192     first++;
1193   }
1194   for(first=page+1;first<last;first++) {
1195     invalidate_page(first);
1196   }
1197   do_clear_cache();
1198
1199   // Don't trap writes
1200   invalid_code[block]=1;
1201
1202   #ifdef USE_MINI_HT
1203   memset(mini_ht,-1,sizeof(mini_ht));
1204   #endif
1205 }
1206
1207 void invalidate_block(u_int block)
1208 {
1209   u_int page=get_page(block<<12);
1210   u_int vpage=get_vpage(block<<12);
1211   inv_debug("INVALIDATE: %x (%d)\n",block<<12,page);
1212   //inv_debug("invalid_code[block]=%d\n",invalid_code[block]);
1213   u_int first,last;
1214   first=last=page;
1215   struct ll_entry *head;
1216   head=jump_dirty[vpage];
1217   //printf("page=%d vpage=%d\n",page,vpage);
1218   while(head!=NULL) {
1219     if(vpage>2047||(head->vaddr>>12)==block) { // Ignore vaddr hash collision
1220       u_char *start, *end;
1221       get_bounds(head->addr, &start, &end);
1222       //printf("start: %p end: %p\n", start, end);
1223       if (page < 2048 && start >= rdram && end < rdram+RAM_SIZE) {
1224         if (((start-rdram)>>12) <= page && ((end-1-rdram)>>12) >= page) {
1225           if ((((start-rdram)>>12)&2047) < first) first = ((start-rdram)>>12)&2047;
1226           if ((((end-1-rdram)>>12)&2047) > last)  last = ((end-1-rdram)>>12)&2047;
1227         }
1228       }
1229     }
1230     head=head->next;
1231   }
1232   invalidate_block_range(block,first,last);
1233 }
1234
1235 void invalidate_addr(u_int addr)
1236 {
1237   //static int rhits;
1238   // this check is done by the caller
1239   //if (inv_code_start<=addr&&addr<=inv_code_end) { rhits++; return; }
1240   u_int page=get_vpage(addr);
1241   if(page<2048) { // RAM
1242     struct ll_entry *head;
1243     u_int addr_min=~0, addr_max=0;
1244     u_int mask=RAM_SIZE-1;
1245     u_int addr_main=0x80000000|(addr&mask);
1246     int pg1;
1247     inv_code_start=addr_main&~0xfff;
1248     inv_code_end=addr_main|0xfff;
1249     pg1=page;
1250     if (pg1>0) {
1251       // must check previous page too because of spans..
1252       pg1--;
1253       inv_code_start-=0x1000;
1254     }
1255     for(;pg1<=page;pg1++) {
1256       for(head=jump_dirty[pg1];head!=NULL;head=head->next) {
1257         u_char *start_h, *end_h;
1258         u_int start, end;
1259         get_bounds(head->addr, &start_h, &end_h);
1260         start = (uintptr_t)start_h - ram_offset;
1261         end = (uintptr_t)end_h - ram_offset;
1262         if(start<=addr_main&&addr_main<end) {
1263           if(start<addr_min) addr_min=start;
1264           if(end>addr_max) addr_max=end;
1265         }
1266         else if(addr_main<start) {
1267           if(start<inv_code_end)
1268             inv_code_end=start-1;
1269         }
1270         else {
1271           if(end>inv_code_start)
1272             inv_code_start=end;
1273         }
1274       }
1275     }
1276     if (addr_min!=~0) {
1277       inv_debug("INV ADDR: %08x hit %08x-%08x\n", addr, addr_min, addr_max);
1278       inv_code_start=inv_code_end=~0;
1279       invalidate_block_range(addr>>12,(addr_min&mask)>>12,(addr_max&mask)>>12);
1280       return;
1281     }
1282     else {
1283       inv_code_start=(addr&~mask)|(inv_code_start&mask);
1284       inv_code_end=(addr&~mask)|(inv_code_end&mask);
1285       inv_debug("INV ADDR: %08x miss, inv %08x-%08x, sk %d\n", addr, inv_code_start, inv_code_end, 0);
1286       return;
1287     }
1288   }
1289   invalidate_block(addr>>12);
1290 }
1291
1292 // This is called when loading a save state.
1293 // Anything could have changed, so invalidate everything.
1294 void invalidate_all_pages(void)
1295 {
1296   u_int page;
1297   for(page=0;page<4096;page++)
1298     invalidate_page(page);
1299   for(page=0;page<1048576;page++)
1300     if(!invalid_code[page]) {
1301       restore_candidate[(page&2047)>>3]|=1<<(page&7);
1302       restore_candidate[((page&2047)>>3)+256]|=1<<(page&7);
1303     }
1304   #ifdef USE_MINI_HT
1305   memset(mini_ht,-1,sizeof(mini_ht));
1306   #endif
1307   do_clear_cache();
1308 }
1309
1310 static void do_invstub(int n)
1311 {
1312   literal_pool(20);
1313   u_int reglist=stubs[n].a;
1314   set_jump_target(stubs[n].addr, out);
1315   save_regs(reglist);
1316   if(stubs[n].b!=0) emit_mov(stubs[n].b,0);
1317   emit_far_call(invalidate_addr);
1318   restore_regs(reglist);
1319   emit_jmp(stubs[n].retaddr); // return address
1320 }
1321
1322 // Add an entry to jump_out after making a link
1323 // src should point to code by emit_extjump2()
1324 void add_jump_out(u_int vaddr,void *src)
1325 {
1326   u_int page=get_page(vaddr);
1327   inv_debug("add_jump_out: %p -> %x (%d)\n",src,vaddr,page);
1328   check_extjump2(src);
1329   ll_add(jump_out+page,vaddr,src);
1330   //inv_debug("add_jump_out:  to %p\n",get_pointer(src));
1331 }
1332
1333 // If a code block was found to be unmodified (bit was set in
1334 // restore_candidate) and it remains unmodified (bit is clear
1335 // in invalid_code) then move the entries for that 4K page from
1336 // the dirty list to the clean list.
1337 void clean_blocks(u_int page)
1338 {
1339   struct ll_entry *head;
1340   inv_debug("INV: clean_blocks page=%d\n",page);
1341   head=jump_dirty[page];
1342   while(head!=NULL) {
1343     if(!invalid_code[head->vaddr>>12]) {
1344       // Don't restore blocks which are about to expire from the cache
1345       if (doesnt_expire_soon(head->addr)) {
1346         if(verify_dirty(head->addr)) {
1347           u_char *start, *end;
1348           //printf("Possibly Restore %x (%p)\n",head->vaddr, head->addr);
1349           u_int i;
1350           u_int inv=0;
1351           get_bounds(head->addr, &start, &end);
1352           if (start - rdram < RAM_SIZE) {
1353             for (i = (start-rdram+0x80000000)>>12; i <= (end-1-rdram+0x80000000)>>12; i++) {
1354               inv|=invalid_code[i];
1355             }
1356           }
1357           else if((signed int)head->vaddr>=(signed int)0x80000000+RAM_SIZE) {
1358             inv=1;
1359           }
1360           if(!inv) {
1361             void *clean_addr = get_clean_addr(head->addr);
1362             if (doesnt_expire_soon(clean_addr)) {
1363               u_int ppage=page;
1364               inv_debug("INV: Restored %x (%p/%p)\n",head->vaddr, head->addr, clean_addr);
1365               //printf("page=%x, addr=%x\n",page,head->vaddr);
1366               //assert(head->vaddr>>12==(page|0x80000));
1367               ll_add_flags(jump_in+ppage,head->vaddr,head->reg_sv_flags,clean_addr);
1368               struct ht_entry *ht_bin = hash_table_get(head->vaddr);
1369               if (ht_bin->vaddr[0] == head->vaddr)
1370                 ht_bin->tcaddr[0] = clean_addr; // Replace existing entry
1371               if (ht_bin->vaddr[1] == head->vaddr)
1372                 ht_bin->tcaddr[1] = clean_addr; // Replace existing entry
1373             }
1374           }
1375         }
1376       }
1377     }
1378     head=head->next;
1379   }
1380 }
1381
1382 /* Register allocation */
1383
1384 // Note: registers are allocated clean (unmodified state)
1385 // if you intend to modify the register, you must call dirty_reg().
1386 static void alloc_reg(struct regstat *cur,int i,signed char reg)
1387 {
1388   int r,hr;
1389   int preferred_reg = PREFERRED_REG_FIRST
1390     + reg % (PREFERRED_REG_LAST - PREFERRED_REG_FIRST + 1);
1391   if (reg == CCREG) preferred_reg = HOST_CCREG;
1392   if (reg == PTEMP || reg == FTEMP) preferred_reg = 12;
1393   assert(PREFERRED_REG_FIRST != EXCLUDE_REG && EXCLUDE_REG != HOST_REGS);
1394
1395   // Don't allocate unused registers
1396   if((cur->u>>reg)&1) return;
1397
1398   // see if it's already allocated
1399   for(hr=0;hr<HOST_REGS;hr++)
1400   {
1401     if(cur->regmap[hr]==reg) return;
1402   }
1403
1404   // Keep the same mapping if the register was already allocated in a loop
1405   preferred_reg = loop_reg(i,reg,preferred_reg);
1406
1407   // Try to allocate the preferred register
1408   if(cur->regmap[preferred_reg]==-1) {
1409     cur->regmap[preferred_reg]=reg;
1410     cur->dirty&=~(1<<preferred_reg);
1411     cur->isconst&=~(1<<preferred_reg);
1412     return;
1413   }
1414   r=cur->regmap[preferred_reg];
1415   assert(r < 64);
1416   if((cur->u>>r)&1) {
1417     cur->regmap[preferred_reg]=reg;
1418     cur->dirty&=~(1<<preferred_reg);
1419     cur->isconst&=~(1<<preferred_reg);
1420     return;
1421   }
1422
1423   // Clear any unneeded registers
1424   // We try to keep the mapping consistent, if possible, because it
1425   // makes branches easier (especially loops).  So we try to allocate
1426   // first (see above) before removing old mappings.  If this is not
1427   // possible then go ahead and clear out the registers that are no
1428   // longer needed.
1429   for(hr=0;hr<HOST_REGS;hr++)
1430   {
1431     r=cur->regmap[hr];
1432     if(r>=0) {
1433       assert(r < 64);
1434       if((cur->u>>r)&1) {cur->regmap[hr]=-1;break;}
1435     }
1436   }
1437
1438   // Try to allocate any available register, but prefer
1439   // registers that have not been used recently.
1440   if (i > 0) {
1441     for (hr = PREFERRED_REG_FIRST; ; ) {
1442       if (cur->regmap[hr] < 0) {
1443         int oldreg = regs[i-1].regmap[hr];
1444         if (oldreg < 0 || (oldreg != dops[i-1].rs1 && oldreg != dops[i-1].rs2
1445              && oldreg != dops[i-1].rt1 && oldreg != dops[i-1].rt2))
1446         {
1447           cur->regmap[hr]=reg;
1448           cur->dirty&=~(1<<hr);
1449           cur->isconst&=~(1<<hr);
1450           return;
1451         }
1452       }
1453       hr++;
1454       if (hr == EXCLUDE_REG)
1455         hr++;
1456       if (hr == HOST_REGS)
1457         hr = 0;
1458       if (hr == PREFERRED_REG_FIRST)
1459         break;
1460     }
1461   }
1462
1463   // Try to allocate any available register
1464   for (hr = PREFERRED_REG_FIRST; ; ) {
1465     if (cur->regmap[hr] < 0) {
1466       cur->regmap[hr]=reg;
1467       cur->dirty&=~(1<<hr);
1468       cur->isconst&=~(1<<hr);
1469       return;
1470     }
1471     hr++;
1472     if (hr == EXCLUDE_REG)
1473       hr++;
1474     if (hr == HOST_REGS)
1475       hr = 0;
1476     if (hr == PREFERRED_REG_FIRST)
1477       break;
1478   }
1479
1480   // Ok, now we have to evict someone
1481   // Pick a register we hopefully won't need soon
1482   u_char hsn[MAXREG+1];
1483   memset(hsn,10,sizeof(hsn));
1484   int j;
1485   lsn(hsn,i,&preferred_reg);
1486   //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]);
1487   //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]);
1488   if(i>0) {
1489     // Don't evict the cycle count at entry points, otherwise the entry
1490     // stub will have to write it.
1491     if(dops[i].bt&&hsn[CCREG]>2) hsn[CCREG]=2;
1492     if (i>1 && hsn[CCREG] > 2 && dops[i-2].is_jump) hsn[CCREG]=2;
1493     for(j=10;j>=3;j--)
1494     {
1495       // Alloc preferred register if available
1496       if(hsn[r=cur->regmap[preferred_reg]&63]==j) {
1497         for(hr=0;hr<HOST_REGS;hr++) {
1498           // Evict both parts of a 64-bit register
1499           if((cur->regmap[hr]&63)==r) {
1500             cur->regmap[hr]=-1;
1501             cur->dirty&=~(1<<hr);
1502             cur->isconst&=~(1<<hr);
1503           }
1504         }
1505         cur->regmap[preferred_reg]=reg;
1506         return;
1507       }
1508       for(r=1;r<=MAXREG;r++)
1509       {
1510         if(hsn[r]==j&&r!=dops[i-1].rs1&&r!=dops[i-1].rs2&&r!=dops[i-1].rt1&&r!=dops[i-1].rt2) {
1511           for(hr=0;hr<HOST_REGS;hr++) {
1512             if(hr!=HOST_CCREG||j<hsn[CCREG]) {
1513               if(cur->regmap[hr]==r) {
1514                 cur->regmap[hr]=reg;
1515                 cur->dirty&=~(1<<hr);
1516                 cur->isconst&=~(1<<hr);
1517                 return;
1518               }
1519             }
1520           }
1521         }
1522       }
1523     }
1524   }
1525   for(j=10;j>=0;j--)
1526   {
1527     for(r=1;r<=MAXREG;r++)
1528     {
1529       if(hsn[r]==j) {
1530         for(hr=0;hr<HOST_REGS;hr++) {
1531           if(cur->regmap[hr]==r) {
1532             cur->regmap[hr]=reg;
1533             cur->dirty&=~(1<<hr);
1534             cur->isconst&=~(1<<hr);
1535             return;
1536           }
1537         }
1538       }
1539     }
1540   }
1541   SysPrintf("This shouldn't happen (alloc_reg)");abort();
1542 }
1543
1544 // Allocate a temporary register.  This is done without regard to
1545 // dirty status or whether the register we request is on the unneeded list
1546 // Note: This will only allocate one register, even if called multiple times
1547 static void alloc_reg_temp(struct regstat *cur,int i,signed char reg)
1548 {
1549   int r,hr;
1550   int preferred_reg = -1;
1551
1552   // see if it's already allocated
1553   for(hr=0;hr<HOST_REGS;hr++)
1554   {
1555     if(hr!=EXCLUDE_REG&&cur->regmap[hr]==reg) return;
1556   }
1557
1558   // Try to allocate any available register
1559   for(hr=HOST_REGS-1;hr>=0;hr--) {
1560     if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) {
1561       cur->regmap[hr]=reg;
1562       cur->dirty&=~(1<<hr);
1563       cur->isconst&=~(1<<hr);
1564       return;
1565     }
1566   }
1567
1568   // Find an unneeded register
1569   for(hr=HOST_REGS-1;hr>=0;hr--)
1570   {
1571     r=cur->regmap[hr];
1572     if(r>=0) {
1573       assert(r < 64);
1574       if((cur->u>>r)&1) {
1575         if(i==0||((unneeded_reg[i-1]>>r)&1)) {
1576           cur->regmap[hr]=reg;
1577           cur->dirty&=~(1<<hr);
1578           cur->isconst&=~(1<<hr);
1579           return;
1580         }
1581       }
1582     }
1583   }
1584
1585   // Ok, now we have to evict someone
1586   // Pick a register we hopefully won't need soon
1587   // TODO: we might want to follow unconditional jumps here
1588   // TODO: get rid of dupe code and make this into a function
1589   u_char hsn[MAXREG+1];
1590   memset(hsn,10,sizeof(hsn));
1591   int j;
1592   lsn(hsn,i,&preferred_reg);
1593   //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]);
1594   if(i>0) {
1595     // Don't evict the cycle count at entry points, otherwise the entry
1596     // stub will have to write it.
1597     if(dops[i].bt&&hsn[CCREG]>2) hsn[CCREG]=2;
1598     if (i>1 && hsn[CCREG] > 2 && dops[i-2].is_jump) hsn[CCREG]=2;
1599     for(j=10;j>=3;j--)
1600     {
1601       for(r=1;r<=MAXREG;r++)
1602       {
1603         if(hsn[r]==j&&r!=dops[i-1].rs1&&r!=dops[i-1].rs2&&r!=dops[i-1].rt1&&r!=dops[i-1].rt2) {
1604           for(hr=0;hr<HOST_REGS;hr++) {
1605             if(hr!=HOST_CCREG||hsn[CCREG]>2) {
1606               if(cur->regmap[hr]==r) {
1607                 cur->regmap[hr]=reg;
1608                 cur->dirty&=~(1<<hr);
1609                 cur->isconst&=~(1<<hr);
1610                 return;
1611               }
1612             }
1613           }
1614         }
1615       }
1616     }
1617   }
1618   for(j=10;j>=0;j--)
1619   {
1620     for(r=1;r<=MAXREG;r++)
1621     {
1622       if(hsn[r]==j) {
1623         for(hr=0;hr<HOST_REGS;hr++) {
1624           if(cur->regmap[hr]==r) {
1625             cur->regmap[hr]=reg;
1626             cur->dirty&=~(1<<hr);
1627             cur->isconst&=~(1<<hr);
1628             return;
1629           }
1630         }
1631       }
1632     }
1633   }
1634   SysPrintf("This shouldn't happen");abort();
1635 }
1636
1637 static void mov_alloc(struct regstat *current,int i)
1638 {
1639   if (dops[i].rs1 == HIREG || dops[i].rs1 == LOREG) {
1640     alloc_cc(current,i); // for stalls
1641     dirty_reg(current,CCREG);
1642   }
1643
1644   // Note: Don't need to actually alloc the source registers
1645   //alloc_reg(current,i,dops[i].rs1);
1646   alloc_reg(current,i,dops[i].rt1);
1647
1648   clear_const(current,dops[i].rs1);
1649   clear_const(current,dops[i].rt1);
1650   dirty_reg(current,dops[i].rt1);
1651 }
1652
1653 static void shiftimm_alloc(struct regstat *current,int i)
1654 {
1655   if(dops[i].opcode2<=0x3) // SLL/SRL/SRA
1656   {
1657     if(dops[i].rt1) {
1658       if(dops[i].rs1&&needed_again(dops[i].rs1,i)) alloc_reg(current,i,dops[i].rs1);
1659       else dops[i].lt1=dops[i].rs1;
1660       alloc_reg(current,i,dops[i].rt1);
1661       dirty_reg(current,dops[i].rt1);
1662       if(is_const(current,dops[i].rs1)) {
1663         int v=get_const(current,dops[i].rs1);
1664         if(dops[i].opcode2==0x00) set_const(current,dops[i].rt1,v<<imm[i]);
1665         if(dops[i].opcode2==0x02) set_const(current,dops[i].rt1,(u_int)v>>imm[i]);
1666         if(dops[i].opcode2==0x03) set_const(current,dops[i].rt1,v>>imm[i]);
1667       }
1668       else clear_const(current,dops[i].rt1);
1669     }
1670   }
1671   else
1672   {
1673     clear_const(current,dops[i].rs1);
1674     clear_const(current,dops[i].rt1);
1675   }
1676
1677   if(dops[i].opcode2>=0x38&&dops[i].opcode2<=0x3b) // DSLL/DSRL/DSRA
1678   {
1679     assert(0);
1680   }
1681   if(dops[i].opcode2==0x3c) // DSLL32
1682   {
1683     assert(0);
1684   }
1685   if(dops[i].opcode2==0x3e) // DSRL32
1686   {
1687     assert(0);
1688   }
1689   if(dops[i].opcode2==0x3f) // DSRA32
1690   {
1691     assert(0);
1692   }
1693 }
1694
1695 static void shift_alloc(struct regstat *current,int i)
1696 {
1697   if(dops[i].rt1) {
1698     if(dops[i].opcode2<=0x07) // SLLV/SRLV/SRAV
1699     {
1700       if(dops[i].rs1) alloc_reg(current,i,dops[i].rs1);
1701       if(dops[i].rs2) alloc_reg(current,i,dops[i].rs2);
1702       alloc_reg(current,i,dops[i].rt1);
1703       if(dops[i].rt1==dops[i].rs2) {
1704         alloc_reg_temp(current,i,-1);
1705         minimum_free_regs[i]=1;
1706       }
1707     } else { // DSLLV/DSRLV/DSRAV
1708       assert(0);
1709     }
1710     clear_const(current,dops[i].rs1);
1711     clear_const(current,dops[i].rs2);
1712     clear_const(current,dops[i].rt1);
1713     dirty_reg(current,dops[i].rt1);
1714   }
1715 }
1716
1717 static void alu_alloc(struct regstat *current,int i)
1718 {
1719   if(dops[i].opcode2>=0x20&&dops[i].opcode2<=0x23) { // ADD/ADDU/SUB/SUBU
1720     if(dops[i].rt1) {
1721       if(dops[i].rs1&&dops[i].rs2) {
1722         alloc_reg(current,i,dops[i].rs1);
1723         alloc_reg(current,i,dops[i].rs2);
1724       }
1725       else {
1726         if(dops[i].rs1&&needed_again(dops[i].rs1,i)) alloc_reg(current,i,dops[i].rs1);
1727         if(dops[i].rs2&&needed_again(dops[i].rs2,i)) alloc_reg(current,i,dops[i].rs2);
1728       }
1729       alloc_reg(current,i,dops[i].rt1);
1730     }
1731   }
1732   if(dops[i].opcode2==0x2a||dops[i].opcode2==0x2b) { // SLT/SLTU
1733     if(dops[i].rt1) {
1734       alloc_reg(current,i,dops[i].rs1);
1735       alloc_reg(current,i,dops[i].rs2);
1736       alloc_reg(current,i,dops[i].rt1);
1737     }
1738   }
1739   if(dops[i].opcode2>=0x24&&dops[i].opcode2<=0x27) { // AND/OR/XOR/NOR
1740     if(dops[i].rt1) {
1741       if(dops[i].rs1&&dops[i].rs2) {
1742         alloc_reg(current,i,dops[i].rs1);
1743         alloc_reg(current,i,dops[i].rs2);
1744       }
1745       else
1746       {
1747         if(dops[i].rs1&&needed_again(dops[i].rs1,i)) alloc_reg(current,i,dops[i].rs1);
1748         if(dops[i].rs2&&needed_again(dops[i].rs2,i)) alloc_reg(current,i,dops[i].rs2);
1749       }
1750       alloc_reg(current,i,dops[i].rt1);
1751     }
1752   }
1753   if(dops[i].opcode2>=0x2c&&dops[i].opcode2<=0x2f) { // DADD/DADDU/DSUB/DSUBU
1754     assert(0);
1755   }
1756   clear_const(current,dops[i].rs1);
1757   clear_const(current,dops[i].rs2);
1758   clear_const(current,dops[i].rt1);
1759   dirty_reg(current,dops[i].rt1);
1760 }
1761
1762 static void imm16_alloc(struct regstat *current,int i)
1763 {
1764   if(dops[i].rs1&&needed_again(dops[i].rs1,i)) alloc_reg(current,i,dops[i].rs1);
1765   else dops[i].lt1=dops[i].rs1;
1766   if(dops[i].rt1) alloc_reg(current,i,dops[i].rt1);
1767   if(dops[i].opcode==0x18||dops[i].opcode==0x19) { // DADDI/DADDIU
1768     assert(0);
1769   }
1770   else if(dops[i].opcode==0x0a||dops[i].opcode==0x0b) { // SLTI/SLTIU
1771     clear_const(current,dops[i].rs1);
1772     clear_const(current,dops[i].rt1);
1773   }
1774   else if(dops[i].opcode>=0x0c&&dops[i].opcode<=0x0e) { // ANDI/ORI/XORI
1775     if(is_const(current,dops[i].rs1)) {
1776       int v=get_const(current,dops[i].rs1);
1777       if(dops[i].opcode==0x0c) set_const(current,dops[i].rt1,v&imm[i]);
1778       if(dops[i].opcode==0x0d) set_const(current,dops[i].rt1,v|imm[i]);
1779       if(dops[i].opcode==0x0e) set_const(current,dops[i].rt1,v^imm[i]);
1780     }
1781     else clear_const(current,dops[i].rt1);
1782   }
1783   else if(dops[i].opcode==0x08||dops[i].opcode==0x09) { // ADDI/ADDIU
1784     if(is_const(current,dops[i].rs1)) {
1785       int v=get_const(current,dops[i].rs1);
1786       set_const(current,dops[i].rt1,v+imm[i]);
1787     }
1788     else clear_const(current,dops[i].rt1);
1789   }
1790   else {
1791     set_const(current,dops[i].rt1,imm[i]<<16); // LUI
1792   }
1793   dirty_reg(current,dops[i].rt1);
1794 }
1795
1796 static void load_alloc(struct regstat *current,int i)
1797 {
1798   clear_const(current,dops[i].rt1);
1799   //if(dops[i].rs1!=dops[i].rt1&&needed_again(dops[i].rs1,i)) clear_const(current,dops[i].rs1); // Does this help or hurt?
1800   if(!dops[i].rs1) current->u&=~1LL; // Allow allocating r0 if it's the source register
1801   if (needed_again(dops[i].rs1, i))
1802     alloc_reg(current, i, dops[i].rs1);
1803   if (ram_offset)
1804     alloc_reg(current, i, ROREG);
1805   if(dops[i].rt1&&!((current->u>>dops[i].rt1)&1)) {
1806     alloc_reg(current,i,dops[i].rt1);
1807     assert(get_reg(current->regmap,dops[i].rt1)>=0);
1808     if(dops[i].opcode==0x27||dops[i].opcode==0x37) // LWU/LD
1809     {
1810       assert(0);
1811     }
1812     else if(dops[i].opcode==0x1A||dops[i].opcode==0x1B) // LDL/LDR
1813     {
1814       assert(0);
1815     }
1816     dirty_reg(current,dops[i].rt1);
1817     // LWL/LWR need a temporary register for the old value
1818     if(dops[i].opcode==0x22||dops[i].opcode==0x26)
1819     {
1820       alloc_reg(current,i,FTEMP);
1821       alloc_reg_temp(current,i,-1);
1822       minimum_free_regs[i]=1;
1823     }
1824   }
1825   else
1826   {
1827     // Load to r0 or unneeded register (dummy load)
1828     // but we still need a register to calculate the address
1829     if(dops[i].opcode==0x22||dops[i].opcode==0x26)
1830     {
1831       alloc_reg(current,i,FTEMP); // LWL/LWR need another temporary
1832     }
1833     alloc_reg_temp(current,i,-1);
1834     minimum_free_regs[i]=1;
1835     if(dops[i].opcode==0x1A||dops[i].opcode==0x1B) // LDL/LDR
1836     {
1837       assert(0);
1838     }
1839   }
1840 }
1841
1842 void store_alloc(struct regstat *current,int i)
1843 {
1844   clear_const(current,dops[i].rs2);
1845   if(!(dops[i].rs2)) current->u&=~1LL; // Allow allocating r0 if necessary
1846   if(needed_again(dops[i].rs1,i)) alloc_reg(current,i,dops[i].rs1);
1847   alloc_reg(current,i,dops[i].rs2);
1848   if(dops[i].opcode==0x2c||dops[i].opcode==0x2d||dops[i].opcode==0x3f) { // 64-bit SDL/SDR/SD
1849     assert(0);
1850   }
1851   if (ram_offset)
1852     alloc_reg(current, i, ROREG);
1853   #if defined(HOST_IMM8)
1854   // On CPUs without 32-bit immediates we need a pointer to invalid_code
1855   alloc_reg(current, i, INVCP);
1856   #endif
1857   if(dops[i].opcode==0x2a||dops[i].opcode==0x2e||dops[i].opcode==0x2c||dops[i].opcode==0x2d) { // SWL/SWL/SDL/SDR
1858     alloc_reg(current,i,FTEMP);
1859   }
1860   // We need a temporary register for address generation
1861   alloc_reg_temp(current,i,-1);
1862   minimum_free_regs[i]=1;
1863 }
1864
1865 void c1ls_alloc(struct regstat *current,int i)
1866 {
1867   clear_const(current,dops[i].rt1);
1868   alloc_reg(current,i,CSREG); // Status
1869 }
1870
1871 void c2ls_alloc(struct regstat *current,int i)
1872 {
1873   clear_const(current,dops[i].rt1);
1874   if(needed_again(dops[i].rs1,i)) alloc_reg(current,i,dops[i].rs1);
1875   alloc_reg(current,i,FTEMP);
1876   if (ram_offset)
1877     alloc_reg(current, i, ROREG);
1878   #if defined(HOST_IMM8)
1879   // On CPUs without 32-bit immediates we need a pointer to invalid_code
1880   if (dops[i].opcode == 0x3a) // SWC2
1881     alloc_reg(current,i,INVCP);
1882   #endif
1883   // We need a temporary register for address generation
1884   alloc_reg_temp(current,i,-1);
1885   minimum_free_regs[i]=1;
1886 }
1887
1888 #ifndef multdiv_alloc
1889 void multdiv_alloc(struct regstat *current,int i)
1890 {
1891   //  case 0x18: MULT
1892   //  case 0x19: MULTU
1893   //  case 0x1A: DIV
1894   //  case 0x1B: DIVU
1895   //  case 0x1C: DMULT
1896   //  case 0x1D: DMULTU
1897   //  case 0x1E: DDIV
1898   //  case 0x1F: DDIVU
1899   clear_const(current,dops[i].rs1);
1900   clear_const(current,dops[i].rs2);
1901   alloc_cc(current,i); // for stalls
1902   if(dops[i].rs1&&dops[i].rs2)
1903   {
1904     if((dops[i].opcode2&4)==0) // 32-bit
1905     {
1906       current->u&=~(1LL<<HIREG);
1907       current->u&=~(1LL<<LOREG);
1908       alloc_reg(current,i,HIREG);
1909       alloc_reg(current,i,LOREG);
1910       alloc_reg(current,i,dops[i].rs1);
1911       alloc_reg(current,i,dops[i].rs2);
1912       dirty_reg(current,HIREG);
1913       dirty_reg(current,LOREG);
1914     }
1915     else // 64-bit
1916     {
1917       assert(0);
1918     }
1919   }
1920   else
1921   {
1922     // Multiply by zero is zero.
1923     // MIPS does not have a divide by zero exception.
1924     // The result is undefined, we return zero.
1925     alloc_reg(current,i,HIREG);
1926     alloc_reg(current,i,LOREG);
1927     dirty_reg(current,HIREG);
1928     dirty_reg(current,LOREG);
1929   }
1930 }
1931 #endif
1932
1933 void cop0_alloc(struct regstat *current,int i)
1934 {
1935   if(dops[i].opcode2==0) // MFC0
1936   {
1937     if(dops[i].rt1) {
1938       clear_const(current,dops[i].rt1);
1939       alloc_all(current,i);
1940       alloc_reg(current,i,dops[i].rt1);
1941       dirty_reg(current,dops[i].rt1);
1942     }
1943   }
1944   else if(dops[i].opcode2==4) // MTC0
1945   {
1946     if(dops[i].rs1){
1947       clear_const(current,dops[i].rs1);
1948       alloc_reg(current,i,dops[i].rs1);
1949       alloc_all(current,i);
1950     }
1951     else {
1952       alloc_all(current,i); // FIXME: Keep r0
1953       current->u&=~1LL;
1954       alloc_reg(current,i,0);
1955     }
1956   }
1957   else
1958   {
1959     // TLBR/TLBWI/TLBWR/TLBP/ERET
1960     assert(dops[i].opcode2==0x10);
1961     alloc_all(current,i);
1962   }
1963   minimum_free_regs[i]=HOST_REGS;
1964 }
1965
1966 static void cop2_alloc(struct regstat *current,int i)
1967 {
1968   if (dops[i].opcode2 < 3) // MFC2/CFC2
1969   {
1970     alloc_cc(current,i); // for stalls
1971     dirty_reg(current,CCREG);
1972     if(dops[i].rt1){
1973       clear_const(current,dops[i].rt1);
1974       alloc_reg(current,i,dops[i].rt1);
1975       dirty_reg(current,dops[i].rt1);
1976     }
1977   }
1978   else if (dops[i].opcode2 > 3) // MTC2/CTC2
1979   {
1980     if(dops[i].rs1){
1981       clear_const(current,dops[i].rs1);
1982       alloc_reg(current,i,dops[i].rs1);
1983     }
1984     else {
1985       current->u&=~1LL;
1986       alloc_reg(current,i,0);
1987     }
1988   }
1989   alloc_reg_temp(current,i,-1);
1990   minimum_free_regs[i]=1;
1991 }
1992
1993 void c2op_alloc(struct regstat *current,int i)
1994 {
1995   alloc_cc(current,i); // for stalls
1996   dirty_reg(current,CCREG);
1997   alloc_reg_temp(current,i,-1);
1998 }
1999
2000 void syscall_alloc(struct regstat *current,int i)
2001 {
2002   alloc_cc(current,i);
2003   dirty_reg(current,CCREG);
2004   alloc_all(current,i);
2005   minimum_free_regs[i]=HOST_REGS;
2006   current->isconst=0;
2007 }
2008
2009 void delayslot_alloc(struct regstat *current,int i)
2010 {
2011   switch(dops[i].itype) {
2012     case UJUMP:
2013     case CJUMP:
2014     case SJUMP:
2015     case RJUMP:
2016     case SYSCALL:
2017     case HLECALL:
2018     case SPAN:
2019       assem_debug("jump in the delay slot.  this shouldn't happen.\n");//abort();
2020       SysPrintf("Disabled speculative precompilation\n");
2021       stop_after_jal=1;
2022       break;
2023     case IMM16:
2024       imm16_alloc(current,i);
2025       break;
2026     case LOAD:
2027     case LOADLR:
2028       load_alloc(current,i);
2029       break;
2030     case STORE:
2031     case STORELR:
2032       store_alloc(current,i);
2033       break;
2034     case ALU:
2035       alu_alloc(current,i);
2036       break;
2037     case SHIFT:
2038       shift_alloc(current,i);
2039       break;
2040     case MULTDIV:
2041       multdiv_alloc(current,i);
2042       break;
2043     case SHIFTIMM:
2044       shiftimm_alloc(current,i);
2045       break;
2046     case MOV:
2047       mov_alloc(current,i);
2048       break;
2049     case COP0:
2050       cop0_alloc(current,i);
2051       break;
2052     case COP1:
2053       break;
2054     case COP2:
2055       cop2_alloc(current,i);
2056       break;
2057     case C1LS:
2058       c1ls_alloc(current,i);
2059       break;
2060     case C2LS:
2061       c2ls_alloc(current,i);
2062       break;
2063     case C2OP:
2064       c2op_alloc(current,i);
2065       break;
2066   }
2067 }
2068
2069 // Special case where a branch and delay slot span two pages in virtual memory
2070 static void pagespan_alloc(struct regstat *current,int i)
2071 {
2072   current->isconst=0;
2073   current->wasconst=0;
2074   regs[i].wasconst=0;
2075   minimum_free_regs[i]=HOST_REGS;
2076   alloc_all(current,i);
2077   alloc_cc(current,i);
2078   dirty_reg(current,CCREG);
2079   if(dops[i].opcode==3) // JAL
2080   {
2081     alloc_reg(current,i,31);
2082     dirty_reg(current,31);
2083   }
2084   if(dops[i].opcode==0&&(dops[i].opcode2&0x3E)==8) // JR/JALR
2085   {
2086     alloc_reg(current,i,dops[i].rs1);
2087     if (dops[i].rt1!=0) {
2088       alloc_reg(current,i,dops[i].rt1);
2089       dirty_reg(current,dops[i].rt1);
2090     }
2091   }
2092   if((dops[i].opcode&0x2E)==4) // BEQ/BNE/BEQL/BNEL
2093   {
2094     if(dops[i].rs1) alloc_reg(current,i,dops[i].rs1);
2095     if(dops[i].rs2) alloc_reg(current,i,dops[i].rs2);
2096   }
2097   else
2098   if((dops[i].opcode&0x2E)==6) // BLEZ/BGTZ/BLEZL/BGTZL
2099   {
2100     if(dops[i].rs1) alloc_reg(current,i,dops[i].rs1);
2101   }
2102   //else ...
2103 }
2104
2105 static void add_stub(enum stub_type type, void *addr, void *retaddr,
2106   u_int a, uintptr_t b, uintptr_t c, u_int d, u_int e)
2107 {
2108   assert(stubcount < ARRAY_SIZE(stubs));
2109   stubs[stubcount].type = type;
2110   stubs[stubcount].addr = addr;
2111   stubs[stubcount].retaddr = retaddr;
2112   stubs[stubcount].a = a;
2113   stubs[stubcount].b = b;
2114   stubs[stubcount].c = c;
2115   stubs[stubcount].d = d;
2116   stubs[stubcount].e = e;
2117   stubcount++;
2118 }
2119
2120 static void add_stub_r(enum stub_type type, void *addr, void *retaddr,
2121   int i, int addr_reg, const struct regstat *i_regs, int ccadj, u_int reglist)
2122 {
2123   add_stub(type, addr, retaddr, i, addr_reg, (uintptr_t)i_regs, ccadj, reglist);
2124 }
2125
2126 // Write out a single register
2127 static void wb_register(signed char r, const signed char regmap[], uint64_t dirty)
2128 {
2129   int hr;
2130   for(hr=0;hr<HOST_REGS;hr++) {
2131     if(hr!=EXCLUDE_REG) {
2132       if((regmap[hr]&63)==r) {
2133         if((dirty>>hr)&1) {
2134           assert(regmap[hr]<64);
2135           emit_storereg(r,hr);
2136         }
2137       }
2138     }
2139   }
2140 }
2141
2142 static void wb_valid(signed char pre[],signed char entry[],u_int dirty_pre,u_int dirty,uint64_t u)
2143 {
2144   //if(dirty_pre==dirty) return;
2145   int hr,reg;
2146   for(hr=0;hr<HOST_REGS;hr++) {
2147     if(hr!=EXCLUDE_REG) {
2148       reg=pre[hr];
2149       if(((~u)>>(reg&63))&1) {
2150         if(reg>0) {
2151           if(((dirty_pre&~dirty)>>hr)&1) {
2152             if(reg>0&&reg<34) {
2153               emit_storereg(reg,hr);
2154             }
2155             else if(reg>=64) {
2156               assert(0);
2157             }
2158           }
2159         }
2160       }
2161     }
2162   }
2163 }
2164
2165 // trashes r2
2166 static void pass_args(int a0, int a1)
2167 {
2168   if(a0==1&&a1==0) {
2169     // must swap
2170     emit_mov(a0,2); emit_mov(a1,1); emit_mov(2,0);
2171   }
2172   else if(a0!=0&&a1==0) {
2173     emit_mov(a1,1);
2174     if (a0>=0) emit_mov(a0,0);
2175   }
2176   else {
2177     if(a0>=0&&a0!=0) emit_mov(a0,0);
2178     if(a1>=0&&a1!=1) emit_mov(a1,1);
2179   }
2180 }
2181
2182 static void alu_assemble(int i, const struct regstat *i_regs)
2183 {
2184   if(dops[i].opcode2>=0x20&&dops[i].opcode2<=0x23) { // ADD/ADDU/SUB/SUBU
2185     if(dops[i].rt1) {
2186       signed char s1,s2,t;
2187       t=get_reg(i_regs->regmap,dops[i].rt1);
2188       if(t>=0) {
2189         s1=get_reg(i_regs->regmap,dops[i].rs1);
2190         s2=get_reg(i_regs->regmap,dops[i].rs2);
2191         if(dops[i].rs1&&dops[i].rs2) {
2192           assert(s1>=0);
2193           assert(s2>=0);
2194           if(dops[i].opcode2&2) emit_sub(s1,s2,t);
2195           else emit_add(s1,s2,t);
2196         }
2197         else if(dops[i].rs1) {
2198           if(s1>=0) emit_mov(s1,t);
2199           else emit_loadreg(dops[i].rs1,t);
2200         }
2201         else if(dops[i].rs2) {
2202           if(s2>=0) {
2203             if(dops[i].opcode2&2) emit_neg(s2,t);
2204             else emit_mov(s2,t);
2205           }
2206           else {
2207             emit_loadreg(dops[i].rs2,t);
2208             if(dops[i].opcode2&2) emit_neg(t,t);
2209           }
2210         }
2211         else emit_zeroreg(t);
2212       }
2213     }
2214   }
2215   if(dops[i].opcode2>=0x2c&&dops[i].opcode2<=0x2f) { // DADD/DADDU/DSUB/DSUBU
2216     assert(0);
2217   }
2218   if(dops[i].opcode2==0x2a||dops[i].opcode2==0x2b) { // SLT/SLTU
2219     if(dops[i].rt1) {
2220       signed char s1l,s2l,t;
2221       {
2222         t=get_reg(i_regs->regmap,dops[i].rt1);
2223         //assert(t>=0);
2224         if(t>=0) {
2225           s1l=get_reg(i_regs->regmap,dops[i].rs1);
2226           s2l=get_reg(i_regs->regmap,dops[i].rs2);
2227           if(dops[i].rs2==0) // rx<r0
2228           {
2229             if(dops[i].opcode2==0x2a&&dops[i].rs1!=0) { // SLT
2230               assert(s1l>=0);
2231               emit_shrimm(s1l,31,t);
2232             }
2233             else // SLTU (unsigned can not be less than zero, 0<0)
2234               emit_zeroreg(t);
2235           }
2236           else if(dops[i].rs1==0) // r0<rx
2237           {
2238             assert(s2l>=0);
2239             if(dops[i].opcode2==0x2a) // SLT
2240               emit_set_gz32(s2l,t);
2241             else // SLTU (set if not zero)
2242               emit_set_nz32(s2l,t);
2243           }
2244           else{
2245             assert(s1l>=0);assert(s2l>=0);
2246             if(dops[i].opcode2==0x2a) // SLT
2247               emit_set_if_less32(s1l,s2l,t);
2248             else // SLTU
2249               emit_set_if_carry32(s1l,s2l,t);
2250           }
2251         }
2252       }
2253     }
2254   }
2255   if(dops[i].opcode2>=0x24&&dops[i].opcode2<=0x27) { // AND/OR/XOR/NOR
2256     if(dops[i].rt1) {
2257       signed char s1l,s2l,tl;
2258       tl=get_reg(i_regs->regmap,dops[i].rt1);
2259       {
2260         if(tl>=0) {
2261           s1l=get_reg(i_regs->regmap,dops[i].rs1);
2262           s2l=get_reg(i_regs->regmap,dops[i].rs2);
2263           if(dops[i].rs1&&dops[i].rs2) {
2264             assert(s1l>=0);
2265             assert(s2l>=0);
2266             if(dops[i].opcode2==0x24) { // AND
2267               emit_and(s1l,s2l,tl);
2268             } else
2269             if(dops[i].opcode2==0x25) { // OR
2270               emit_or(s1l,s2l,tl);
2271             } else
2272             if(dops[i].opcode2==0x26) { // XOR
2273               emit_xor(s1l,s2l,tl);
2274             } else
2275             if(dops[i].opcode2==0x27) { // NOR
2276               emit_or(s1l,s2l,tl);
2277               emit_not(tl,tl);
2278             }
2279           }
2280           else
2281           {
2282             if(dops[i].opcode2==0x24) { // AND
2283               emit_zeroreg(tl);
2284             } else
2285             if(dops[i].opcode2==0x25||dops[i].opcode2==0x26) { // OR/XOR
2286               if(dops[i].rs1){
2287                 if(s1l>=0) emit_mov(s1l,tl);
2288                 else emit_loadreg(dops[i].rs1,tl); // CHECK: regmap_entry?
2289               }
2290               else
2291               if(dops[i].rs2){
2292                 if(s2l>=0) emit_mov(s2l,tl);
2293                 else emit_loadreg(dops[i].rs2,tl); // CHECK: regmap_entry?
2294               }
2295               else emit_zeroreg(tl);
2296             } else
2297             if(dops[i].opcode2==0x27) { // NOR
2298               if(dops[i].rs1){
2299                 if(s1l>=0) emit_not(s1l,tl);
2300                 else {
2301                   emit_loadreg(dops[i].rs1,tl);
2302                   emit_not(tl,tl);
2303                 }
2304               }
2305               else
2306               if(dops[i].rs2){
2307                 if(s2l>=0) emit_not(s2l,tl);
2308                 else {
2309                   emit_loadreg(dops[i].rs2,tl);
2310                   emit_not(tl,tl);
2311                 }
2312               }
2313               else emit_movimm(-1,tl);
2314             }
2315           }
2316         }
2317       }
2318     }
2319   }
2320 }
2321
2322 static void imm16_assemble(int i, const struct regstat *i_regs)
2323 {
2324   if (dops[i].opcode==0x0f) { // LUI
2325     if(dops[i].rt1) {
2326       signed char t;
2327       t=get_reg(i_regs->regmap,dops[i].rt1);
2328       //assert(t>=0);
2329       if(t>=0) {
2330         if(!((i_regs->isconst>>t)&1))
2331           emit_movimm(imm[i]<<16,t);
2332       }
2333     }
2334   }
2335   if(dops[i].opcode==0x08||dops[i].opcode==0x09) { // ADDI/ADDIU
2336     if(dops[i].rt1) {
2337       signed char s,t;
2338       t=get_reg(i_regs->regmap,dops[i].rt1);
2339       s=get_reg(i_regs->regmap,dops[i].rs1);
2340       if(dops[i].rs1) {
2341         //assert(t>=0);
2342         //assert(s>=0);
2343         if(t>=0) {
2344           if(!((i_regs->isconst>>t)&1)) {
2345             if(s<0) {
2346               if(i_regs->regmap_entry[t]!=dops[i].rs1) emit_loadreg(dops[i].rs1,t);
2347               emit_addimm(t,imm[i],t);
2348             }else{
2349               if(!((i_regs->wasconst>>s)&1))
2350                 emit_addimm(s,imm[i],t);
2351               else
2352                 emit_movimm(constmap[i][s]+imm[i],t);
2353             }
2354           }
2355         }
2356       } else {
2357         if(t>=0) {
2358           if(!((i_regs->isconst>>t)&1))
2359             emit_movimm(imm[i],t);
2360         }
2361       }
2362     }
2363   }
2364   if(dops[i].opcode==0x18||dops[i].opcode==0x19) { // DADDI/DADDIU
2365     if(dops[i].rt1) {
2366       signed char sl,tl;
2367       tl=get_reg(i_regs->regmap,dops[i].rt1);
2368       sl=get_reg(i_regs->regmap,dops[i].rs1);
2369       if(tl>=0) {
2370         if(dops[i].rs1) {
2371           assert(sl>=0);
2372           emit_addimm(sl,imm[i],tl);
2373         } else {
2374           emit_movimm(imm[i],tl);
2375         }
2376       }
2377     }
2378   }
2379   else if(dops[i].opcode==0x0a||dops[i].opcode==0x0b) { // SLTI/SLTIU
2380     if(dops[i].rt1) {
2381       //assert(dops[i].rs1!=0); // r0 might be valid, but it's probably a bug
2382       signed char sl,t;
2383       t=get_reg(i_regs->regmap,dops[i].rt1);
2384       sl=get_reg(i_regs->regmap,dops[i].rs1);
2385       //assert(t>=0);
2386       if(t>=0) {
2387         if(dops[i].rs1>0) {
2388             if(dops[i].opcode==0x0a) { // SLTI
2389               if(sl<0) {
2390                 if(i_regs->regmap_entry[t]!=dops[i].rs1) emit_loadreg(dops[i].rs1,t);
2391                 emit_slti32(t,imm[i],t);
2392               }else{
2393                 emit_slti32(sl,imm[i],t);
2394               }
2395             }
2396             else { // SLTIU
2397               if(sl<0) {
2398                 if(i_regs->regmap_entry[t]!=dops[i].rs1) emit_loadreg(dops[i].rs1,t);
2399                 emit_sltiu32(t,imm[i],t);
2400               }else{
2401                 emit_sltiu32(sl,imm[i],t);
2402               }
2403             }
2404         }else{
2405           // SLTI(U) with r0 is just stupid,
2406           // nonetheless examples can be found
2407           if(dops[i].opcode==0x0a) // SLTI
2408             if(0<imm[i]) emit_movimm(1,t);
2409             else emit_zeroreg(t);
2410           else // SLTIU
2411           {
2412             if(imm[i]) emit_movimm(1,t);
2413             else emit_zeroreg(t);
2414           }
2415         }
2416       }
2417     }
2418   }
2419   else if(dops[i].opcode>=0x0c&&dops[i].opcode<=0x0e) { // ANDI/ORI/XORI
2420     if(dops[i].rt1) {
2421       signed char sl,tl;
2422       tl=get_reg(i_regs->regmap,dops[i].rt1);
2423       sl=get_reg(i_regs->regmap,dops[i].rs1);
2424       if(tl>=0 && !((i_regs->isconst>>tl)&1)) {
2425         if(dops[i].opcode==0x0c) //ANDI
2426         {
2427           if(dops[i].rs1) {
2428             if(sl<0) {
2429               if(i_regs->regmap_entry[tl]!=dops[i].rs1) emit_loadreg(dops[i].rs1,tl);
2430               emit_andimm(tl,imm[i],tl);
2431             }else{
2432               if(!((i_regs->wasconst>>sl)&1))
2433                 emit_andimm(sl,imm[i],tl);
2434               else
2435                 emit_movimm(constmap[i][sl]&imm[i],tl);
2436             }
2437           }
2438           else
2439             emit_zeroreg(tl);
2440         }
2441         else
2442         {
2443           if(dops[i].rs1) {
2444             if(sl<0) {
2445               if(i_regs->regmap_entry[tl]!=dops[i].rs1) emit_loadreg(dops[i].rs1,tl);
2446             }
2447             if(dops[i].opcode==0x0d) { // ORI
2448               if(sl<0) {
2449                 emit_orimm(tl,imm[i],tl);
2450               }else{
2451                 if(!((i_regs->wasconst>>sl)&1))
2452                   emit_orimm(sl,imm[i],tl);
2453                 else
2454                   emit_movimm(constmap[i][sl]|imm[i],tl);
2455               }
2456             }
2457             if(dops[i].opcode==0x0e) { // XORI
2458               if(sl<0) {
2459                 emit_xorimm(tl,imm[i],tl);
2460               }else{
2461                 if(!((i_regs->wasconst>>sl)&1))
2462                   emit_xorimm(sl,imm[i],tl);
2463                 else
2464                   emit_movimm(constmap[i][sl]^imm[i],tl);
2465               }
2466             }
2467           }
2468           else {
2469             emit_movimm(imm[i],tl);
2470           }
2471         }
2472       }
2473     }
2474   }
2475 }
2476
2477 static void shiftimm_assemble(int i, const struct regstat *i_regs)
2478 {
2479   if(dops[i].opcode2<=0x3) // SLL/SRL/SRA
2480   {
2481     if(dops[i].rt1) {
2482       signed char s,t;
2483       t=get_reg(i_regs->regmap,dops[i].rt1);
2484       s=get_reg(i_regs->regmap,dops[i].rs1);
2485       //assert(t>=0);
2486       if(t>=0&&!((i_regs->isconst>>t)&1)){
2487         if(dops[i].rs1==0)
2488         {
2489           emit_zeroreg(t);
2490         }
2491         else
2492         {
2493           if(s<0&&i_regs->regmap_entry[t]!=dops[i].rs1) emit_loadreg(dops[i].rs1,t);
2494           if(imm[i]) {
2495             if(dops[i].opcode2==0) // SLL
2496             {
2497               emit_shlimm(s<0?t:s,imm[i],t);
2498             }
2499             if(dops[i].opcode2==2) // SRL
2500             {
2501               emit_shrimm(s<0?t:s,imm[i],t);
2502             }
2503             if(dops[i].opcode2==3) // SRA
2504             {
2505               emit_sarimm(s<0?t:s,imm[i],t);
2506             }
2507           }else{
2508             // Shift by zero
2509             if(s>=0 && s!=t) emit_mov(s,t);
2510           }
2511         }
2512       }
2513       //emit_storereg(dops[i].rt1,t); //DEBUG
2514     }
2515   }
2516   if(dops[i].opcode2>=0x38&&dops[i].opcode2<=0x3b) // DSLL/DSRL/DSRA
2517   {
2518     assert(0);
2519   }
2520   if(dops[i].opcode2==0x3c) // DSLL32
2521   {
2522     assert(0);
2523   }
2524   if(dops[i].opcode2==0x3e) // DSRL32
2525   {
2526     assert(0);
2527   }
2528   if(dops[i].opcode2==0x3f) // DSRA32
2529   {
2530     assert(0);
2531   }
2532 }
2533
2534 #ifndef shift_assemble
2535 static void shift_assemble(int i, const struct regstat *i_regs)
2536 {
2537   signed char s,t,shift;
2538   if (dops[i].rt1 == 0)
2539     return;
2540   assert(dops[i].opcode2<=0x07); // SLLV/SRLV/SRAV
2541   t = get_reg(i_regs->regmap, dops[i].rt1);
2542   s = get_reg(i_regs->regmap, dops[i].rs1);
2543   shift = get_reg(i_regs->regmap, dops[i].rs2);
2544   if (t < 0)
2545     return;
2546
2547   if(dops[i].rs1==0)
2548     emit_zeroreg(t);
2549   else if(dops[i].rs2==0) {
2550     assert(s>=0);
2551     if(s!=t) emit_mov(s,t);
2552   }
2553   else {
2554     host_tempreg_acquire();
2555     emit_andimm(shift,31,HOST_TEMPREG);
2556     switch(dops[i].opcode2) {
2557     case 4: // SLLV
2558       emit_shl(s,HOST_TEMPREG,t);
2559       break;
2560     case 6: // SRLV
2561       emit_shr(s,HOST_TEMPREG,t);
2562       break;
2563     case 7: // SRAV
2564       emit_sar(s,HOST_TEMPREG,t);
2565       break;
2566     default:
2567       assert(0);
2568     }
2569     host_tempreg_release();
2570   }
2571 }
2572
2573 #endif
2574
2575 enum {
2576   MTYPE_8000 = 0,
2577   MTYPE_8020,
2578   MTYPE_0000,
2579   MTYPE_A000,
2580   MTYPE_1F80,
2581 };
2582
2583 static int get_ptr_mem_type(u_int a)
2584 {
2585   if(a < 0x00200000) {
2586     if(a<0x1000&&((start>>20)==0xbfc||(start>>24)==0xa0))
2587       // return wrong, must use memhandler for BIOS self-test to pass
2588       // 007 does similar stuff from a00 mirror, weird stuff
2589       return MTYPE_8000;
2590     return MTYPE_0000;
2591   }
2592   if(0x1f800000 <= a && a < 0x1f801000)
2593     return MTYPE_1F80;
2594   if(0x80200000 <= a && a < 0x80800000)
2595     return MTYPE_8020;
2596   if(0xa0000000 <= a && a < 0xa0200000)
2597     return MTYPE_A000;
2598   return MTYPE_8000;
2599 }
2600
2601 static int get_ro_reg(const struct regstat *i_regs, int host_tempreg_free)
2602 {
2603   int r = get_reg(i_regs->regmap, ROREG);
2604   if (r < 0 && host_tempreg_free) {
2605     host_tempreg_acquire();
2606     emit_loadreg(ROREG, r = HOST_TEMPREG);
2607   }
2608   if (r < 0)
2609     abort();
2610   return r;
2611 }
2612
2613 static void *emit_fastpath_cmp_jump(int i, const struct regstat *i_regs,
2614   int addr, int *offset_reg, int *addr_reg_override)
2615 {
2616   void *jaddr = NULL;
2617   int type = 0;
2618   int mr = dops[i].rs1;
2619   *offset_reg = -1;
2620   if(((smrv_strong|smrv_weak)>>mr)&1) {
2621     type=get_ptr_mem_type(smrv[mr]);
2622     //printf("set %08x @%08x r%d %d\n", smrv[mr], start+i*4, mr, type);
2623   }
2624   else {
2625     // use the mirror we are running on
2626     type=get_ptr_mem_type(start);
2627     //printf("set nospec   @%08x r%d %d\n", start+i*4, mr, type);
2628   }
2629
2630   if(type==MTYPE_8020) { // RAM 80200000+ mirror
2631     host_tempreg_acquire();
2632     emit_andimm(addr,~0x00e00000,HOST_TEMPREG);
2633     addr=*addr_reg_override=HOST_TEMPREG;
2634     type=0;
2635   }
2636   else if(type==MTYPE_0000) { // RAM 0 mirror
2637     host_tempreg_acquire();
2638     emit_orimm(addr,0x80000000,HOST_TEMPREG);
2639     addr=*addr_reg_override=HOST_TEMPREG;
2640     type=0;
2641   }
2642   else if(type==MTYPE_A000) { // RAM A mirror
2643     host_tempreg_acquire();
2644     emit_andimm(addr,~0x20000000,HOST_TEMPREG);
2645     addr=*addr_reg_override=HOST_TEMPREG;
2646     type=0;
2647   }
2648   else if(type==MTYPE_1F80) { // scratchpad
2649     if (psxH == (void *)0x1f800000) {
2650       host_tempreg_acquire();
2651       emit_xorimm(addr,0x1f800000,HOST_TEMPREG);
2652       emit_cmpimm(HOST_TEMPREG,0x1000);
2653       host_tempreg_release();
2654       jaddr=out;
2655       emit_jc(0);
2656     }
2657     else {
2658       // do the usual RAM check, jump will go to the right handler
2659       type=0;
2660     }
2661   }
2662
2663   if (type == 0) // need ram check
2664   {
2665     emit_cmpimm(addr,RAM_SIZE);
2666     jaddr = out;
2667     #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
2668     // Hint to branch predictor that the branch is unlikely to be taken
2669     if (dops[i].rs1 >= 28)
2670       emit_jno_unlikely(0);
2671     else
2672     #endif
2673       emit_jno(0);
2674     if (ram_offset != 0)
2675       *offset_reg = get_ro_reg(i_regs, 0);
2676   }
2677
2678   return jaddr;
2679 }
2680
2681 // return memhandler, or get directly accessable address and return 0
2682 static void *get_direct_memhandler(void *table, u_int addr,
2683   enum stub_type type, uintptr_t *addr_host)
2684 {
2685   uintptr_t msb = 1ull << (sizeof(uintptr_t)*8 - 1);
2686   uintptr_t l1, l2 = 0;
2687   l1 = ((uintptr_t *)table)[addr>>12];
2688   if (!(l1 & msb)) {
2689     uintptr_t v = l1 << 1;
2690     *addr_host = v + addr;
2691     return NULL;
2692   }
2693   else {
2694     l1 <<= 1;
2695     if (type == LOADB_STUB || type == LOADBU_STUB || type == STOREB_STUB)
2696       l2 = ((uintptr_t *)l1)[0x1000/4 + 0x1000/2 + (addr&0xfff)];
2697     else if (type == LOADH_STUB || type == LOADHU_STUB || type == STOREH_STUB)
2698       l2 = ((uintptr_t *)l1)[0x1000/4 + (addr&0xfff)/2];
2699     else
2700       l2 = ((uintptr_t *)l1)[(addr&0xfff)/4];
2701     if (!(l2 & msb)) {
2702       uintptr_t v = l2 << 1;
2703       *addr_host = v + (addr&0xfff);
2704       return NULL;
2705     }
2706     return (void *)(l2 << 1);
2707   }
2708 }
2709
2710 static u_int get_host_reglist(const signed char *regmap)
2711 {
2712   u_int reglist = 0, hr;
2713   for (hr = 0; hr < HOST_REGS; hr++) {
2714     if (hr != EXCLUDE_REG && regmap[hr] >= 0)
2715       reglist |= 1 << hr;
2716   }
2717   return reglist;
2718 }
2719
2720 static u_int reglist_exclude(u_int reglist, int r1, int r2)
2721 {
2722   if (r1 >= 0)
2723     reglist &= ~(1u << r1);
2724   if (r2 >= 0)
2725     reglist &= ~(1u << r2);
2726   return reglist;
2727 }
2728
2729 // find a temp caller-saved register not in reglist (so assumed to be free)
2730 static int reglist_find_free(u_int reglist)
2731 {
2732   u_int free_regs = ~reglist & CALLER_SAVE_REGS;
2733   if (free_regs == 0)
2734     return -1;
2735   return __builtin_ctz(free_regs);
2736 }
2737
2738 static void do_load_word(int a, int rt, int offset_reg)
2739 {
2740   if (offset_reg >= 0)
2741     emit_ldr_dualindexed(offset_reg, a, rt);
2742   else
2743     emit_readword_indexed(0, a, rt);
2744 }
2745
2746 static void do_store_word(int a, int ofs, int rt, int offset_reg, int preseve_a)
2747 {
2748   if (offset_reg < 0) {
2749     emit_writeword_indexed(rt, ofs, a);
2750     return;
2751   }
2752   if (ofs != 0)
2753     emit_addimm(a, ofs, a);
2754   emit_str_dualindexed(offset_reg, a, rt);
2755   if (ofs != 0 && preseve_a)
2756     emit_addimm(a, -ofs, a);
2757 }
2758
2759 static void do_store_hword(int a, int ofs, int rt, int offset_reg, int preseve_a)
2760 {
2761   if (offset_reg < 0) {
2762     emit_writehword_indexed(rt, ofs, a);
2763     return;
2764   }
2765   if (ofs != 0)
2766     emit_addimm(a, ofs, a);
2767   emit_strh_dualindexed(offset_reg, a, rt);
2768   if (ofs != 0 && preseve_a)
2769     emit_addimm(a, -ofs, a);
2770 }
2771
2772 static void do_store_byte(int a, int rt, int offset_reg)
2773 {
2774   if (offset_reg >= 0)
2775     emit_strb_dualindexed(offset_reg, a, rt);
2776   else
2777     emit_writebyte_indexed(rt, 0, a);
2778 }
2779
2780 static void load_assemble(int i, const struct regstat *i_regs, int ccadj_)
2781 {
2782   int s,tl,addr;
2783   int offset;
2784   void *jaddr=0;
2785   int memtarget=0,c=0;
2786   int offset_reg = -1;
2787   int fastio_reg_override = -1;
2788   u_int reglist=get_host_reglist(i_regs->regmap);
2789   tl=get_reg(i_regs->regmap,dops[i].rt1);
2790   s=get_reg(i_regs->regmap,dops[i].rs1);
2791   offset=imm[i];
2792   if(i_regs->regmap[HOST_CCREG]==CCREG) reglist&=~(1<<HOST_CCREG);
2793   if(s>=0) {
2794     c=(i_regs->wasconst>>s)&1;
2795     if (c) {
2796       memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
2797     }
2798   }
2799   //printf("load_assemble: c=%d\n",c);
2800   //if(c) printf("load_assemble: const=%lx\n",(long)constmap[i][s]+offset);
2801   // FIXME: Even if the load is a NOP, we should check for pagefaults...
2802   if((tl<0&&(!c||(((u_int)constmap[i][s]+offset)>>16)==0x1f80))
2803     ||dops[i].rt1==0) {
2804       // could be FIFO, must perform the read
2805       // ||dummy read
2806       assem_debug("(forced read)\n");
2807       tl=get_reg(i_regs->regmap,-1);
2808       assert(tl>=0);
2809   }
2810   if(offset||s<0||c) addr=tl;
2811   else addr=s;
2812   //if(tl<0) tl=get_reg(i_regs->regmap,-1);
2813  if(tl>=0) {
2814   //printf("load_assemble: c=%d\n",c);
2815   //if(c) printf("load_assemble: const=%lx\n",(long)constmap[i][s]+offset);
2816   assert(tl>=0); // Even if the load is a NOP, we must check for pagefaults and I/O
2817   reglist&=~(1<<tl);
2818   if(!c) {
2819     #ifdef R29_HACK
2820     // Strmnnrmn's speed hack
2821     if(dops[i].rs1!=29||start<0x80001000||start>=0x80000000+RAM_SIZE)
2822     #endif
2823     {
2824       jaddr = emit_fastpath_cmp_jump(i, i_regs, addr,
2825                 &offset_reg, &fastio_reg_override);
2826     }
2827   }
2828   else if (ram_offset && memtarget) {
2829     offset_reg = get_ro_reg(i_regs, 0);
2830   }
2831   int dummy=(dops[i].rt1==0)||(tl!=get_reg(i_regs->regmap,dops[i].rt1)); // ignore loads to r0 and unneeded reg
2832   switch (dops[i].opcode) {
2833   case 0x20: // LB
2834     if(!c||memtarget) {
2835       if(!dummy) {
2836         int a = tl;
2837         if (!c) a = addr;
2838         if (fastio_reg_override >= 0)
2839           a = fastio_reg_override;
2840
2841         if (offset_reg >= 0)
2842           emit_ldrsb_dualindexed(offset_reg, a, tl);
2843         else
2844           emit_movsbl_indexed(0, a, tl);
2845       }
2846       if(jaddr)
2847         add_stub_r(LOADB_STUB,jaddr,out,i,addr,i_regs,ccadj_,reglist);
2848     }
2849     else
2850       inline_readstub(LOADB_STUB,i,constmap[i][s]+offset,i_regs->regmap,dops[i].rt1,ccadj_,reglist);
2851     break;
2852   case 0x21: // LH
2853     if(!c||memtarget) {
2854       if(!dummy) {
2855         int a = tl;
2856         if (!c) a = addr;
2857         if (fastio_reg_override >= 0)
2858           a = fastio_reg_override;
2859         if (offset_reg >= 0)
2860           emit_ldrsh_dualindexed(offset_reg, a, tl);
2861         else
2862           emit_movswl_indexed(0, a, tl);
2863       }
2864       if(jaddr)
2865         add_stub_r(LOADH_STUB,jaddr,out,i,addr,i_regs,ccadj_,reglist);
2866     }
2867     else
2868       inline_readstub(LOADH_STUB,i,constmap[i][s]+offset,i_regs->regmap,dops[i].rt1,ccadj_,reglist);
2869     break;
2870   case 0x23: // LW
2871     if(!c||memtarget) {
2872       if(!dummy) {
2873         int a = addr;
2874         if (fastio_reg_override >= 0)
2875           a = fastio_reg_override;
2876         do_load_word(a, tl, offset_reg);
2877       }
2878       if(jaddr)
2879         add_stub_r(LOADW_STUB,jaddr,out,i,addr,i_regs,ccadj_,reglist);
2880     }
2881     else
2882       inline_readstub(LOADW_STUB,i,constmap[i][s]+offset,i_regs->regmap,dops[i].rt1,ccadj_,reglist);
2883     break;
2884   case 0x24: // LBU
2885     if(!c||memtarget) {
2886       if(!dummy) {
2887         int a = tl;
2888         if (!c) a = addr;
2889         if (fastio_reg_override >= 0)
2890           a = fastio_reg_override;
2891
2892         if (offset_reg >= 0)
2893           emit_ldrb_dualindexed(offset_reg, a, tl);
2894         else
2895           emit_movzbl_indexed(0, a, tl);
2896       }
2897       if(jaddr)
2898         add_stub_r(LOADBU_STUB,jaddr,out,i,addr,i_regs,ccadj_,reglist);
2899     }
2900     else
2901       inline_readstub(LOADBU_STUB,i,constmap[i][s]+offset,i_regs->regmap,dops[i].rt1,ccadj_,reglist);
2902     break;
2903   case 0x25: // LHU
2904     if(!c||memtarget) {
2905       if(!dummy) {
2906         int a = tl;
2907         if(!c) a = addr;
2908         if (fastio_reg_override >= 0)
2909           a = fastio_reg_override;
2910         if (offset_reg >= 0)
2911           emit_ldrh_dualindexed(offset_reg, a, tl);
2912         else
2913           emit_movzwl_indexed(0, a, tl);
2914       }
2915       if(jaddr)
2916         add_stub_r(LOADHU_STUB,jaddr,out,i,addr,i_regs,ccadj_,reglist);
2917     }
2918     else
2919       inline_readstub(LOADHU_STUB,i,constmap[i][s]+offset,i_regs->regmap,dops[i].rt1,ccadj_,reglist);
2920     break;
2921   case 0x27: // LWU
2922   case 0x37: // LD
2923   default:
2924     assert(0);
2925   }
2926  }
2927  if (fastio_reg_override == HOST_TEMPREG || offset_reg == HOST_TEMPREG)
2928    host_tempreg_release();
2929 }
2930
2931 #ifndef loadlr_assemble
2932 static void loadlr_assemble(int i, const struct regstat *i_regs, int ccadj_)
2933 {
2934   int s,tl,temp,temp2,addr;
2935   int offset;
2936   void *jaddr=0;
2937   int memtarget=0,c=0;
2938   int offset_reg = -1;
2939   int fastio_reg_override = -1;
2940   u_int reglist=get_host_reglist(i_regs->regmap);
2941   tl=get_reg(i_regs->regmap,dops[i].rt1);
2942   s=get_reg(i_regs->regmap,dops[i].rs1);
2943   temp=get_reg(i_regs->regmap,-1);
2944   temp2=get_reg(i_regs->regmap,FTEMP);
2945   addr=get_reg(i_regs->regmap,AGEN1+(i&1));
2946   assert(addr<0);
2947   offset=imm[i];
2948   reglist|=1<<temp;
2949   if(offset||s<0||c) addr=temp2;
2950   else addr=s;
2951   if(s>=0) {
2952     c=(i_regs->wasconst>>s)&1;
2953     if(c) {
2954       memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
2955     }
2956   }
2957   if(!c) {
2958     emit_shlimm(addr,3,temp);
2959     if (dops[i].opcode==0x22||dops[i].opcode==0x26) {
2960       emit_andimm(addr,0xFFFFFFFC,temp2); // LWL/LWR
2961     }else{
2962       emit_andimm(addr,0xFFFFFFF8,temp2); // LDL/LDR
2963     }
2964     jaddr = emit_fastpath_cmp_jump(i, i_regs, temp2,
2965               &offset_reg, &fastio_reg_override);
2966   }
2967   else {
2968     if (ram_offset && memtarget) {
2969       offset_reg = get_ro_reg(i_regs, 0);
2970     }
2971     if (dops[i].opcode==0x22||dops[i].opcode==0x26) {
2972       emit_movimm(((constmap[i][s]+offset)<<3)&24,temp); // LWL/LWR
2973     }else{
2974       emit_movimm(((constmap[i][s]+offset)<<3)&56,temp); // LDL/LDR
2975     }
2976   }
2977   if (dops[i].opcode==0x22||dops[i].opcode==0x26) { // LWL/LWR
2978     if(!c||memtarget) {
2979       int a = temp2;
2980       if (fastio_reg_override >= 0)
2981         a = fastio_reg_override;
2982       do_load_word(a, temp2, offset_reg);
2983       if (fastio_reg_override == HOST_TEMPREG || offset_reg == HOST_TEMPREG)
2984         host_tempreg_release();
2985       if(jaddr) add_stub_r(LOADW_STUB,jaddr,out,i,temp2,i_regs,ccadj_,reglist);
2986     }
2987     else
2988       inline_readstub(LOADW_STUB,i,(constmap[i][s]+offset)&0xFFFFFFFC,i_regs->regmap,FTEMP,ccadj_,reglist);
2989     if(dops[i].rt1) {
2990       assert(tl>=0);
2991       emit_andimm(temp,24,temp);
2992       if (dops[i].opcode==0x22) // LWL
2993         emit_xorimm(temp,24,temp);
2994       host_tempreg_acquire();
2995       emit_movimm(-1,HOST_TEMPREG);
2996       if (dops[i].opcode==0x26) {
2997         emit_shr(temp2,temp,temp2);
2998         emit_bic_lsr(tl,HOST_TEMPREG,temp,tl);
2999       }else{
3000         emit_shl(temp2,temp,temp2);
3001         emit_bic_lsl(tl,HOST_TEMPREG,temp,tl);
3002       }
3003       host_tempreg_release();
3004       emit_or(temp2,tl,tl);
3005     }
3006     //emit_storereg(dops[i].rt1,tl); // DEBUG
3007   }
3008   if (dops[i].opcode==0x1A||dops[i].opcode==0x1B) { // LDL/LDR
3009     assert(0);
3010   }
3011 }
3012 #endif
3013
3014 static void store_assemble(int i, const struct regstat *i_regs, int ccadj_)
3015 {
3016   int s,tl;
3017   int addr,temp;
3018   int offset;
3019   void *jaddr=0;
3020   enum stub_type type=0;
3021   int memtarget=0,c=0;
3022   int agr=AGEN1+(i&1);
3023   int offset_reg = -1;
3024   int fastio_reg_override = -1;
3025   u_int reglist=get_host_reglist(i_regs->regmap);
3026   tl=get_reg(i_regs->regmap,dops[i].rs2);
3027   s=get_reg(i_regs->regmap,dops[i].rs1);
3028   temp=get_reg(i_regs->regmap,agr);
3029   if(temp<0) temp=get_reg(i_regs->regmap,-1);
3030   offset=imm[i];
3031   if(s>=0) {
3032     c=(i_regs->wasconst>>s)&1;
3033     if(c) {
3034       memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
3035     }
3036   }
3037   assert(tl>=0);
3038   assert(temp>=0);
3039   if(i_regs->regmap[HOST_CCREG]==CCREG) reglist&=~(1<<HOST_CCREG);
3040   if(offset||s<0||c) addr=temp;
3041   else addr=s;
3042   if (!c) {
3043     jaddr = emit_fastpath_cmp_jump(i, i_regs, addr,
3044               &offset_reg, &fastio_reg_override);
3045   }
3046   else if (ram_offset && memtarget) {
3047     offset_reg = get_ro_reg(i_regs, 0);
3048   }
3049
3050   switch (dops[i].opcode) {
3051   case 0x28: // SB
3052     if(!c||memtarget) {
3053       int a = temp;
3054       if (!c) a = addr;
3055       if (fastio_reg_override >= 0)
3056         a = fastio_reg_override;
3057       do_store_byte(a, tl, offset_reg);
3058     }
3059     type = STOREB_STUB;
3060     break;
3061   case 0x29: // SH
3062     if(!c||memtarget) {
3063       int a = temp;
3064       if (!c) a = addr;
3065       if (fastio_reg_override >= 0)
3066         a = fastio_reg_override;
3067       do_store_hword(a, 0, tl, offset_reg, 1);
3068     }
3069     type = STOREH_STUB;
3070     break;
3071   case 0x2B: // SW
3072     if(!c||memtarget) {
3073       int a = addr;
3074       if (fastio_reg_override >= 0)
3075         a = fastio_reg_override;
3076       do_store_word(a, 0, tl, offset_reg, 1);
3077     }
3078     type = STOREW_STUB;
3079     break;
3080   case 0x3F: // SD
3081   default:
3082     assert(0);
3083   }
3084   if (fastio_reg_override == HOST_TEMPREG || offset_reg == HOST_TEMPREG)
3085     host_tempreg_release();
3086   if(jaddr) {
3087     // PCSX store handlers don't check invcode again
3088     reglist|=1<<addr;
3089     add_stub_r(type,jaddr,out,i,addr,i_regs,ccadj_,reglist);
3090     jaddr=0;
3091   }
3092   if(!(i_regs->waswritten&(1<<dops[i].rs1)) && !HACK_ENABLED(NDHACK_NO_SMC_CHECK)) {
3093     if(!c||memtarget) {
3094       #ifdef DESTRUCTIVE_SHIFT
3095       // The x86 shift operation is 'destructive'; it overwrites the
3096       // source register, so we need to make a copy first and use that.
3097       addr=temp;
3098       #endif
3099       #if defined(HOST_IMM8)
3100       int ir=get_reg(i_regs->regmap,INVCP);
3101       assert(ir>=0);
3102       emit_cmpmem_indexedsr12_reg(ir,addr,1);
3103       #else
3104       emit_cmpmem_indexedsr12_imm(invalid_code,addr,1);
3105       #endif
3106       #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT)
3107       emit_callne(invalidate_addr_reg[addr]);
3108       #else
3109       void *jaddr2 = out;
3110       emit_jne(0);
3111       add_stub(INVCODE_STUB,jaddr2,out,reglist|(1<<HOST_CCREG),addr,0,0,0);
3112       #endif
3113     }
3114   }
3115   u_int addr_val=constmap[i][s]+offset;
3116   if(jaddr) {
3117     add_stub_r(type,jaddr,out,i,addr,i_regs,ccadj_,reglist);
3118   } else if(c&&!memtarget) {
3119     inline_writestub(type,i,addr_val,i_regs->regmap,dops[i].rs2,ccadj_,reglist);
3120   }
3121   // basic current block modification detection..
3122   // not looking back as that should be in mips cache already
3123   // (see Spyro2 title->attract mode)
3124   if(c&&start+i*4<addr_val&&addr_val<start+slen*4) {
3125     SysPrintf("write to %08x hits block %08x, pc=%08x\n",addr_val,start,start+i*4);
3126     assert(i_regs->regmap==regs[i].regmap); // not delay slot
3127     if(i_regs->regmap==regs[i].regmap) {
3128       load_all_consts(regs[i].regmap_entry,regs[i].wasdirty,i);
3129       wb_dirtys(regs[i].regmap_entry,regs[i].wasdirty);
3130       emit_movimm(start+i*4+4,0);
3131       emit_writeword(0,&pcaddr);
3132       emit_addimm(HOST_CCREG,2,HOST_CCREG);
3133       emit_far_call(get_addr_ht);
3134       emit_jmpreg(0);
3135     }
3136   }
3137 }
3138
3139 static void storelr_assemble(int i, const struct regstat *i_regs, int ccadj_)
3140 {
3141   int s,tl;
3142   int temp;
3143   int offset;
3144   void *jaddr=0;
3145   void *case1, *case23, *case3;
3146   void *done0, *done1, *done2;
3147   int memtarget=0,c=0;
3148   int agr=AGEN1+(i&1);
3149   int offset_reg = -1;
3150   u_int reglist=get_host_reglist(i_regs->regmap);
3151   tl=get_reg(i_regs->regmap,dops[i].rs2);
3152   s=get_reg(i_regs->regmap,dops[i].rs1);
3153   temp=get_reg(i_regs->regmap,agr);
3154   if(temp<0) temp=get_reg(i_regs->regmap,-1);
3155   offset=imm[i];
3156   if(s>=0) {
3157     c=(i_regs->isconst>>s)&1;
3158     if(c) {
3159       memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
3160     }
3161   }
3162   assert(tl>=0);
3163   assert(temp>=0);
3164   if(!c) {
3165     emit_cmpimm(s<0||offset?temp:s,RAM_SIZE);
3166     if(!offset&&s!=temp) emit_mov(s,temp);
3167     jaddr=out;
3168     emit_jno(0);
3169   }
3170   else
3171   {
3172     if(!memtarget||!dops[i].rs1) {
3173       jaddr=out;
3174       emit_jmp(0);
3175     }
3176   }
3177   if (ram_offset)
3178     offset_reg = get_ro_reg(i_regs, 0);
3179
3180   if (dops[i].opcode==0x2C||dops[i].opcode==0x2D) { // SDL/SDR
3181     assert(0);
3182   }
3183
3184   emit_testimm(temp,2);
3185   case23=out;
3186   emit_jne(0);
3187   emit_testimm(temp,1);
3188   case1=out;
3189   emit_jne(0);
3190   // 0
3191   if (dops[i].opcode == 0x2A) { // SWL
3192     // Write msb into least significant byte
3193     if (dops[i].rs2) emit_rorimm(tl, 24, tl);
3194     do_store_byte(temp, tl, offset_reg);
3195     if (dops[i].rs2) emit_rorimm(tl, 8, tl);
3196   }
3197   else if (dops[i].opcode == 0x2E) { // SWR
3198     // Write entire word
3199     do_store_word(temp, 0, tl, offset_reg, 1);
3200   }
3201   done0 = out;
3202   emit_jmp(0);
3203   // 1
3204   set_jump_target(case1, out);
3205   if (dops[i].opcode == 0x2A) { // SWL
3206     // Write two msb into two least significant bytes
3207     if (dops[i].rs2) emit_rorimm(tl, 16, tl);
3208     do_store_hword(temp, -1, tl, offset_reg, 0);
3209     if (dops[i].rs2) emit_rorimm(tl, 16, tl);
3210   }
3211   else if (dops[i].opcode == 0x2E) { // SWR
3212     // Write 3 lsb into three most significant bytes
3213     do_store_byte(temp, tl, offset_reg);
3214     if (dops[i].rs2) emit_rorimm(tl, 8, tl);
3215     do_store_hword(temp, 1, tl, offset_reg, 0);
3216     if (dops[i].rs2) emit_rorimm(tl, 24, tl);
3217   }
3218   done1=out;
3219   emit_jmp(0);
3220   // 2,3
3221   set_jump_target(case23, out);
3222   emit_testimm(temp,1);
3223   case3 = out;
3224   emit_jne(0);
3225   // 2
3226   if (dops[i].opcode==0x2A) { // SWL
3227     // Write 3 msb into three least significant bytes
3228     if (dops[i].rs2) emit_rorimm(tl, 8, tl);
3229     do_store_hword(temp, -2, tl, offset_reg, 1);
3230     if (dops[i].rs2) emit_rorimm(tl, 16, tl);
3231     do_store_byte(temp, tl, offset_reg);
3232     if (dops[i].rs2) emit_rorimm(tl, 8, tl);
3233   }
3234   else if (dops[i].opcode == 0x2E) { // SWR
3235     // Write two lsb into two most significant bytes
3236     do_store_hword(temp, 0, tl, offset_reg, 1);
3237   }
3238   done2 = out;
3239   emit_jmp(0);
3240   // 3
3241   set_jump_target(case3, out);
3242   if (dops[i].opcode == 0x2A) { // SWL
3243     do_store_word(temp, -3, tl, offset_reg, 0);
3244   }
3245   else if (dops[i].opcode == 0x2E) { // SWR
3246     do_store_byte(temp, tl, offset_reg);
3247   }
3248   set_jump_target(done0, out);
3249   set_jump_target(done1, out);
3250   set_jump_target(done2, out);
3251   if (offset_reg == HOST_TEMPREG)
3252     host_tempreg_release();
3253   if(!c||!memtarget)
3254     add_stub_r(STORELR_STUB,jaddr,out,i,temp,i_regs,ccadj_,reglist);
3255   if(!(i_regs->waswritten&(1<<dops[i].rs1)) && !HACK_ENABLED(NDHACK_NO_SMC_CHECK)) {
3256     #if defined(HOST_IMM8)
3257     int ir=get_reg(i_regs->regmap,INVCP);
3258     assert(ir>=0);
3259     emit_cmpmem_indexedsr12_reg(ir,temp,1);
3260     #else
3261     emit_cmpmem_indexedsr12_imm(invalid_code,temp,1);
3262     #endif
3263     #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT)
3264     emit_callne(invalidate_addr_reg[temp]);
3265     #else
3266     void *jaddr2 = out;
3267     emit_jne(0);
3268     add_stub(INVCODE_STUB,jaddr2,out,reglist|(1<<HOST_CCREG),temp,0,0,0);
3269     #endif
3270   }
3271 }
3272
3273 static void cop0_assemble(int i, const struct regstat *i_regs, int ccadj_)
3274 {
3275   if(dops[i].opcode2==0) // MFC0
3276   {
3277     signed char t=get_reg(i_regs->regmap,dops[i].rt1);
3278     u_int copr=(source[i]>>11)&0x1f;
3279     //assert(t>=0); // Why does this happen?  OOT is weird
3280     if(t>=0&&dops[i].rt1!=0) {
3281       emit_readword(&reg_cop0[copr],t);
3282     }
3283   }
3284   else if(dops[i].opcode2==4) // MTC0
3285   {
3286     signed char s=get_reg(i_regs->regmap,dops[i].rs1);
3287     char copr=(source[i]>>11)&0x1f;
3288     assert(s>=0);
3289     wb_register(dops[i].rs1,i_regs->regmap,i_regs->dirty);
3290     if(copr==9||copr==11||copr==12||copr==13) {
3291       emit_readword(&last_count,HOST_TEMPREG);
3292       emit_loadreg(CCREG,HOST_CCREG); // TODO: do proper reg alloc
3293       emit_add(HOST_CCREG,HOST_TEMPREG,HOST_CCREG);
3294       emit_addimm(HOST_CCREG,ccadj_,HOST_CCREG);
3295       emit_writeword(HOST_CCREG,&Count);
3296     }
3297     // What a mess.  The status register (12) can enable interrupts,
3298     // so needs a special case to handle a pending interrupt.
3299     // The interrupt must be taken immediately, because a subsequent
3300     // instruction might disable interrupts again.
3301     if(copr==12||copr==13) {
3302       if (is_delayslot) {
3303         // burn cycles to cause cc_interrupt, which will
3304         // reschedule next_interupt. Relies on CCREG from above.
3305         assem_debug("MTC0 DS %d\n", copr);
3306         emit_writeword(HOST_CCREG,&last_count);
3307         emit_movimm(0,HOST_CCREG);
3308         emit_storereg(CCREG,HOST_CCREG);
3309         emit_loadreg(dops[i].rs1,1);
3310         emit_movimm(copr,0);
3311         emit_far_call(pcsx_mtc0_ds);
3312         emit_loadreg(dops[i].rs1,s);
3313         return;
3314       }
3315       emit_movimm(start+i*4+4,HOST_TEMPREG);
3316       emit_writeword(HOST_TEMPREG,&pcaddr);
3317       emit_movimm(0,HOST_TEMPREG);
3318       emit_writeword(HOST_TEMPREG,&pending_exception);
3319     }
3320     if(s==HOST_CCREG)
3321       emit_loadreg(dops[i].rs1,1);
3322     else if(s!=1)
3323       emit_mov(s,1);
3324     emit_movimm(copr,0);
3325     emit_far_call(pcsx_mtc0);
3326     if(copr==9||copr==11||copr==12||copr==13) {
3327       emit_readword(&Count,HOST_CCREG);
3328       emit_readword(&next_interupt,HOST_TEMPREG);
3329       emit_addimm(HOST_CCREG,-ccadj_,HOST_CCREG);
3330       emit_sub(HOST_CCREG,HOST_TEMPREG,HOST_CCREG);
3331       emit_writeword(HOST_TEMPREG,&last_count);
3332       emit_storereg(CCREG,HOST_CCREG);
3333     }
3334     if(copr==12||copr==13) {
3335       assert(!is_delayslot);
3336       emit_readword(&pending_exception,14);
3337       emit_test(14,14);
3338       void *jaddr = out;
3339       emit_jeq(0);
3340       emit_readword(&pcaddr, 0);
3341       emit_addimm(HOST_CCREG,2,HOST_CCREG);
3342       emit_far_call(get_addr_ht);
3343       emit_jmpreg(0);
3344       set_jump_target(jaddr, out);
3345     }
3346     emit_loadreg(dops[i].rs1,s);
3347   }
3348   else
3349   {
3350     assert(dops[i].opcode2==0x10);
3351     //if((source[i]&0x3f)==0x10) // RFE
3352     {
3353       emit_readword(&Status,0);
3354       emit_andimm(0,0x3c,1);
3355       emit_andimm(0,~0xf,0);
3356       emit_orrshr_imm(1,2,0);
3357       emit_writeword(0,&Status);
3358     }
3359   }
3360 }
3361
3362 static void cop1_unusable(int i, const struct regstat *i_regs)
3363 {
3364   // XXX: should just just do the exception instead
3365   //if(!cop1_usable)
3366   {
3367     void *jaddr=out;
3368     emit_jmp(0);
3369     add_stub_r(FP_STUB,jaddr,out,i,0,i_regs,is_delayslot,0);
3370   }
3371 }
3372
3373 static void cop1_assemble(int i, const struct regstat *i_regs)
3374 {
3375   cop1_unusable(i, i_regs);
3376 }
3377
3378 static void c1ls_assemble(int i, const struct regstat *i_regs)
3379 {
3380   cop1_unusable(i, i_regs);
3381 }
3382
3383 // FP_STUB
3384 static void do_cop1stub(int n)
3385 {
3386   literal_pool(256);
3387   assem_debug("do_cop1stub %x\n",start+stubs[n].a*4);
3388   set_jump_target(stubs[n].addr, out);
3389   int i=stubs[n].a;
3390 //  int rs=stubs[n].b;
3391   struct regstat *i_regs=(struct regstat *)stubs[n].c;
3392   int ds=stubs[n].d;
3393   if(!ds) {
3394     load_all_consts(regs[i].regmap_entry,regs[i].wasdirty,i);
3395     //if(i_regs!=&regs[i]) printf("oops: regs[i]=%x i_regs=%x",(int)&regs[i],(int)i_regs);
3396   }
3397   //else {printf("fp exception in delay slot\n");}
3398   wb_dirtys(i_regs->regmap_entry,i_regs->wasdirty);
3399   if(regs[i].regmap_entry[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG);
3400   emit_movimm(start+(i-ds)*4,EAX); // Get PC
3401   emit_addimm(HOST_CCREG,ccadj[i],HOST_CCREG); // CHECK: is this right?  There should probably be an extra cycle...
3402   emit_far_jump(ds?fp_exception_ds:fp_exception);
3403 }
3404
3405 static int cop2_is_stalling_op(int i, int *cycles)
3406 {
3407   if (dops[i].opcode == 0x3a) { // SWC2
3408     *cycles = 0;
3409     return 1;
3410   }
3411   if (dops[i].itype == COP2 && (dops[i].opcode2 == 0 || dops[i].opcode2 == 2)) { // MFC2/CFC2
3412     *cycles = 0;
3413     return 1;
3414   }
3415   if (dops[i].itype == C2OP) {
3416     *cycles = gte_cycletab[source[i] & 0x3f];
3417     return 1;
3418   }
3419   // ... what about MTC2/CTC2/LWC2?
3420   return 0;
3421 }
3422
3423 #if 0
3424 static void log_gte_stall(int stall, u_int cycle)
3425 {
3426   if ((u_int)stall <= 44)
3427     printf("x    stall %2d %u\n", stall, cycle + last_count);
3428 }
3429
3430 static void emit_log_gte_stall(int i, int stall, u_int reglist)
3431 {
3432   save_regs(reglist);
3433   if (stall > 0)
3434     emit_movimm(stall, 0);
3435   else
3436     emit_mov(HOST_TEMPREG, 0);
3437   emit_addimm(HOST_CCREG, ccadj[i], 1);
3438   emit_far_call(log_gte_stall);
3439   restore_regs(reglist);
3440 }
3441 #endif
3442
3443 static void cop2_do_stall_check(u_int op, int i, const struct regstat *i_regs, u_int reglist)
3444 {
3445   int j = i, other_gte_op_cycles = -1, stall = -MAXBLOCK, cycles_passed;
3446   int rtmp = reglist_find_free(reglist);
3447
3448   if (HACK_ENABLED(NDHACK_NO_STALLS))
3449     return;
3450   if (get_reg(i_regs->regmap, CCREG) != HOST_CCREG) {
3451     // happens occasionally... cc evicted? Don't bother then
3452     //printf("no cc %08x\n", start + i*4);
3453     return;
3454   }
3455   if (!dops[i].bt) {
3456     for (j = i - 1; j >= 0; j--) {
3457       //if (dops[j].is_ds) break;
3458       if (cop2_is_stalling_op(j, &other_gte_op_cycles) || dops[j].bt)
3459         break;
3460       if (j > 0 && ccadj[j - 1] > ccadj[j])
3461         break;
3462     }
3463     j = max(j, 0);
3464   }
3465   cycles_passed = ccadj[i] - ccadj[j];
3466   if (other_gte_op_cycles >= 0)
3467     stall = other_gte_op_cycles - cycles_passed;
3468   else if (cycles_passed >= 44)
3469     stall = 0; // can't stall
3470   if (stall == -MAXBLOCK && rtmp >= 0) {
3471     // unknown stall, do the expensive runtime check
3472     assem_debug("; cop2_do_stall_check\n");
3473 #if 0 // too slow
3474     save_regs(reglist);
3475     emit_movimm(gte_cycletab[op], 0);
3476     emit_addimm(HOST_CCREG, ccadj[i], 1);
3477     emit_far_call(call_gteStall);
3478     restore_regs(reglist);
3479 #else
3480     host_tempreg_acquire();
3481     emit_readword(&psxRegs.gteBusyCycle, rtmp);
3482     emit_addimm(rtmp, -ccadj[i], rtmp);
3483     emit_sub(rtmp, HOST_CCREG, HOST_TEMPREG);
3484     emit_cmpimm(HOST_TEMPREG, 44);
3485     emit_cmovb_reg(rtmp, HOST_CCREG);
3486     //emit_log_gte_stall(i, 0, reglist);
3487     host_tempreg_release();
3488 #endif
3489   }
3490   else if (stall > 0) {
3491     //emit_log_gte_stall(i, stall, reglist);
3492     emit_addimm(HOST_CCREG, stall, HOST_CCREG);
3493   }
3494
3495   // save gteBusyCycle, if needed
3496   if (gte_cycletab[op] == 0)
3497     return;
3498   other_gte_op_cycles = -1;
3499   for (j = i + 1; j < slen; j++) {
3500     if (cop2_is_stalling_op(j, &other_gte_op_cycles))
3501       break;
3502     if (dops[j].is_jump) {
3503       // check ds
3504       if (j + 1 < slen && cop2_is_stalling_op(j + 1, &other_gte_op_cycles))
3505         j++;
3506       break;
3507     }
3508   }
3509   if (other_gte_op_cycles >= 0)
3510     // will handle stall when assembling that op
3511     return;
3512   cycles_passed = ccadj[min(j, slen -1)] - ccadj[i];
3513   if (cycles_passed >= 44)
3514     return;
3515   assem_debug("; save gteBusyCycle\n");
3516   host_tempreg_acquire();
3517 #if 0
3518   emit_readword(&last_count, HOST_TEMPREG);
3519   emit_add(HOST_TEMPREG, HOST_CCREG, HOST_TEMPREG);
3520   emit_addimm(HOST_TEMPREG, ccadj[i], HOST_TEMPREG);
3521   emit_addimm(HOST_TEMPREG, gte_cycletab[op]), HOST_TEMPREG);
3522   emit_writeword(HOST_TEMPREG, &psxRegs.gteBusyCycle);
3523 #else
3524   emit_addimm(HOST_CCREG, ccadj[i] + gte_cycletab[op], HOST_TEMPREG);
3525   emit_writeword(HOST_TEMPREG, &psxRegs.gteBusyCycle);
3526 #endif
3527   host_tempreg_release();
3528 }
3529
3530 static int is_mflohi(int i)
3531 {
3532   return (dops[i].itype == MOV && (dops[i].rs1 == HIREG || dops[i].rs1 == LOREG));
3533 }
3534
3535 static int check_multdiv(int i, int *cycles)
3536 {
3537   if (dops[i].itype != MULTDIV)
3538     return 0;
3539   if (dops[i].opcode2 == 0x18 || dops[i].opcode2 == 0x19) // MULT(U)
3540     *cycles = 11; // approx from 7 11 14
3541   else
3542     *cycles = 37;
3543   return 1;
3544 }
3545
3546 static void multdiv_prepare_stall(int i, const struct regstat *i_regs, int ccadj_)
3547 {
3548   int j, found = 0, c = 0;
3549   if (HACK_ENABLED(NDHACK_NO_STALLS))
3550     return;
3551   if (get_reg(i_regs->regmap, CCREG) != HOST_CCREG) {
3552     // happens occasionally... cc evicted? Don't bother then
3553     return;
3554   }
3555   for (j = i + 1; j < slen; j++) {
3556     if (dops[j].bt)
3557       break;
3558     if ((found = is_mflohi(j)))
3559       break;
3560     if (dops[j].is_jump) {
3561       // check ds
3562       if (j + 1 < slen && (found = is_mflohi(j + 1)))
3563         j++;
3564       break;
3565     }
3566   }
3567   if (found)
3568     // handle all in multdiv_do_stall()
3569     return;
3570   check_multdiv(i, &c);
3571   assert(c > 0);
3572   assem_debug("; muldiv prepare stall %d\n", c);
3573   host_tempreg_acquire();
3574   emit_addimm(HOST_CCREG, ccadj_ + c, HOST_TEMPREG);
3575   emit_writeword(HOST_TEMPREG, &psxRegs.muldivBusyCycle);
3576   host_tempreg_release();
3577 }
3578
3579 static void multdiv_do_stall(int i, const struct regstat *i_regs)
3580 {
3581   int j, known_cycles = 0;
3582   u_int reglist = get_host_reglist(i_regs->regmap);
3583   int rtmp = get_reg(i_regs->regmap, -1);
3584   if (rtmp < 0)
3585     rtmp = reglist_find_free(reglist);
3586   if (HACK_ENABLED(NDHACK_NO_STALLS))
3587     return;
3588   if (get_reg(i_regs->regmap, CCREG) != HOST_CCREG || rtmp < 0) {
3589     // happens occasionally... cc evicted? Don't bother then
3590     //printf("no cc/rtmp %08x\n", start + i*4);
3591     return;
3592   }
3593   if (!dops[i].bt) {
3594     for (j = i - 1; j >= 0; j--) {
3595       if (dops[j].is_ds) break;
3596       if (check_multdiv(j, &known_cycles))
3597         break;
3598       if (is_mflohi(j))
3599         // already handled by this op
3600         return;
3601       if (dops[j].bt || (j > 0 && ccadj[j - 1] > ccadj[j]))
3602         break;
3603     }
3604     j = max(j, 0);
3605   }
3606   if (known_cycles > 0) {
3607     known_cycles -= ccadj[i] - ccadj[j];
3608     assem_debug("; muldiv stall resolved %d\n", known_cycles);
3609     if (known_cycles > 0)
3610       emit_addimm(HOST_CCREG, known_cycles, HOST_CCREG);
3611     return;
3612   }
3613   assem_debug("; muldiv stall unresolved\n");
3614   host_tempreg_acquire();
3615   emit_readword(&psxRegs.muldivBusyCycle, rtmp);
3616   emit_addimm(rtmp, -ccadj[i], rtmp);
3617   emit_sub(rtmp, HOST_CCREG, HOST_TEMPREG);
3618   emit_cmpimm(HOST_TEMPREG, 37);
3619   emit_cmovb_reg(rtmp, HOST_CCREG);
3620   //emit_log_gte_stall(i, 0, reglist);
3621   host_tempreg_release();
3622 }
3623
3624 static void cop2_get_dreg(u_int copr,signed char tl,signed char temp)
3625 {
3626   switch (copr) {
3627     case 1:
3628     case 3:
3629     case 5:
3630     case 8:
3631     case 9:
3632     case 10:
3633     case 11:
3634       emit_readword(&reg_cop2d[copr],tl);
3635       emit_signextend16(tl,tl);
3636       emit_writeword(tl,&reg_cop2d[copr]); // hmh
3637       break;
3638     case 7:
3639     case 16:
3640     case 17:
3641     case 18:
3642     case 19:
3643       emit_readword(&reg_cop2d[copr],tl);
3644       emit_andimm(tl,0xffff,tl);
3645       emit_writeword(tl,&reg_cop2d[copr]);
3646       break;
3647     case 15:
3648       emit_readword(&reg_cop2d[14],tl); // SXY2
3649       emit_writeword(tl,&reg_cop2d[copr]);
3650       break;
3651     case 28:
3652     case 29:
3653       c2op_mfc2_29_assemble(tl,temp);
3654       break;
3655     default:
3656       emit_readword(&reg_cop2d[copr],tl);
3657       break;
3658   }
3659 }
3660
3661 static void cop2_put_dreg(u_int copr,signed char sl,signed char temp)
3662 {
3663   switch (copr) {
3664     case 15:
3665       emit_readword(&reg_cop2d[13],temp);  // SXY1
3666       emit_writeword(sl,&reg_cop2d[copr]);
3667       emit_writeword(temp,&reg_cop2d[12]); // SXY0
3668       emit_readword(&reg_cop2d[14],temp);  // SXY2
3669       emit_writeword(sl,&reg_cop2d[14]);
3670       emit_writeword(temp,&reg_cop2d[13]); // SXY1
3671       break;
3672     case 28:
3673       emit_andimm(sl,0x001f,temp);
3674       emit_shlimm(temp,7,temp);
3675       emit_writeword(temp,&reg_cop2d[9]);
3676       emit_andimm(sl,0x03e0,temp);
3677       emit_shlimm(temp,2,temp);
3678       emit_writeword(temp,&reg_cop2d[10]);
3679       emit_andimm(sl,0x7c00,temp);
3680       emit_shrimm(temp,3,temp);
3681       emit_writeword(temp,&reg_cop2d[11]);
3682       emit_writeword(sl,&reg_cop2d[28]);
3683       break;
3684     case 30:
3685       emit_xorsar_imm(sl,sl,31,temp);
3686 #if defined(HAVE_ARMV5) || defined(__aarch64__)
3687       emit_clz(temp,temp);
3688 #else
3689       emit_movs(temp,HOST_TEMPREG);
3690       emit_movimm(0,temp);
3691       emit_jeq((int)out+4*4);
3692       emit_addpl_imm(temp,1,temp);
3693       emit_lslpls_imm(HOST_TEMPREG,1,HOST_TEMPREG);
3694       emit_jns((int)out-2*4);
3695 #endif
3696       emit_writeword(sl,&reg_cop2d[30]);
3697       emit_writeword(temp,&reg_cop2d[31]);
3698       break;
3699     case 31:
3700       break;
3701     default:
3702       emit_writeword(sl,&reg_cop2d[copr]);
3703       break;
3704   }
3705 }
3706
3707 static void c2ls_assemble(int i, const struct regstat *i_regs, int ccadj_)
3708 {
3709   int s,tl;
3710   int ar;
3711   int offset;
3712   int memtarget=0,c=0;
3713   void *jaddr2=NULL;
3714   enum stub_type type;
3715   int agr=AGEN1+(i&1);
3716   int offset_reg = -1;
3717   int fastio_reg_override = -1;
3718   u_int reglist=get_host_reglist(i_regs->regmap);
3719   u_int copr=(source[i]>>16)&0x1f;
3720   s=get_reg(i_regs->regmap,dops[i].rs1);
3721   tl=get_reg(i_regs->regmap,FTEMP);
3722   offset=imm[i];
3723   assert(dops[i].rs1>0);
3724   assert(tl>=0);
3725
3726   if(i_regs->regmap[HOST_CCREG]==CCREG)
3727     reglist&=~(1<<HOST_CCREG);
3728
3729   // get the address
3730   if (dops[i].opcode==0x3a) { // SWC2
3731     ar=get_reg(i_regs->regmap,agr);
3732     if(ar<0) ar=get_reg(i_regs->regmap,-1);
3733     reglist|=1<<ar;
3734   } else { // LWC2
3735     ar=tl;
3736   }
3737   if(s>=0) c=(i_regs->wasconst>>s)&1;
3738   memtarget=c&&(((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE);
3739   if (!offset&&!c&&s>=0) ar=s;
3740   assert(ar>=0);
3741
3742   cop2_do_stall_check(0, i, i_regs, reglist);
3743
3744   if (dops[i].opcode==0x3a) { // SWC2
3745     cop2_get_dreg(copr,tl,-1);
3746     type=STOREW_STUB;
3747   }
3748   else
3749     type=LOADW_STUB;
3750
3751   if(c&&!memtarget) {
3752     jaddr2=out;
3753     emit_jmp(0); // inline_readstub/inline_writestub?
3754   }
3755   else {
3756     if(!c) {
3757       jaddr2 = emit_fastpath_cmp_jump(i, i_regs, ar,
3758                 &offset_reg, &fastio_reg_override);
3759     }
3760     else if (ram_offset && memtarget) {
3761       offset_reg = get_ro_reg(i_regs, 0);
3762     }
3763     switch (dops[i].opcode) {
3764     case 0x32: { // LWC2
3765       int a = ar;
3766       if (fastio_reg_override >= 0)
3767         a = fastio_reg_override;
3768       do_load_word(a, tl, offset_reg);
3769       break;
3770     }
3771     case 0x3a: { // SWC2
3772       #ifdef DESTRUCTIVE_SHIFT
3773       if(!offset&&!c&&s>=0) emit_mov(s,ar);
3774       #endif
3775       int a = ar;
3776       if (fastio_reg_override >= 0)
3777         a = fastio_reg_override;
3778       do_store_word(a, 0, tl, offset_reg, 1);
3779       break;
3780     }
3781     default:
3782       assert(0);
3783     }
3784   }
3785   if (fastio_reg_override == HOST_TEMPREG || offset_reg == HOST_TEMPREG)
3786     host_tempreg_release();
3787   if(jaddr2)
3788     add_stub_r(type,jaddr2,out,i,ar,i_regs,ccadj_,reglist);
3789   if(dops[i].opcode==0x3a) // SWC2
3790   if(!(i_regs->waswritten&(1<<dops[i].rs1)) && !HACK_ENABLED(NDHACK_NO_SMC_CHECK)) {
3791 #if defined(HOST_IMM8)
3792     int ir=get_reg(i_regs->regmap,INVCP);
3793     assert(ir>=0);
3794     emit_cmpmem_indexedsr12_reg(ir,ar,1);
3795 #else
3796     emit_cmpmem_indexedsr12_imm(invalid_code,ar,1);
3797 #endif
3798     #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT)
3799     emit_callne(invalidate_addr_reg[ar]);
3800     #else
3801     void *jaddr3 = out;
3802     emit_jne(0);
3803     add_stub(INVCODE_STUB,jaddr3,out,reglist|(1<<HOST_CCREG),ar,0,0,0);
3804     #endif
3805   }
3806   if (dops[i].opcode==0x32) { // LWC2
3807     host_tempreg_acquire();
3808     cop2_put_dreg(copr,tl,HOST_TEMPREG);
3809     host_tempreg_release();
3810   }
3811 }
3812
3813 static void cop2_assemble(int i, const struct regstat *i_regs)
3814 {
3815   u_int copr = (source[i]>>11) & 0x1f;
3816   signed char temp = get_reg(i_regs->regmap, -1);
3817
3818   if (!HACK_ENABLED(NDHACK_NO_STALLS)) {
3819     u_int reglist = reglist_exclude(get_host_reglist(i_regs->regmap), temp, -1);
3820     if (dops[i].opcode2 == 0 || dops[i].opcode2 == 2) { // MFC2/CFC2
3821       signed char tl = get_reg(i_regs->regmap, dops[i].rt1);
3822       reglist = reglist_exclude(reglist, tl, -1);
3823     }
3824     cop2_do_stall_check(0, i, i_regs, reglist);
3825   }
3826   if (dops[i].opcode2==0) { // MFC2
3827     signed char tl=get_reg(i_regs->regmap,dops[i].rt1);
3828     if(tl>=0&&dops[i].rt1!=0)
3829       cop2_get_dreg(copr,tl,temp);
3830   }
3831   else if (dops[i].opcode2==4) { // MTC2
3832     signed char sl=get_reg(i_regs->regmap,dops[i].rs1);
3833     cop2_put_dreg(copr,sl,temp);
3834   }
3835   else if (dops[i].opcode2==2) // CFC2
3836   {
3837     signed char tl=get_reg(i_regs->regmap,dops[i].rt1);
3838     if(tl>=0&&dops[i].rt1!=0)
3839       emit_readword(&reg_cop2c[copr],tl);
3840   }
3841   else if (dops[i].opcode2==6) // CTC2
3842   {
3843     signed char sl=get_reg(i_regs->regmap,dops[i].rs1);
3844     switch(copr) {
3845       case 4:
3846       case 12:
3847       case 20:
3848       case 26:
3849       case 27:
3850       case 29:
3851       case 30:
3852         emit_signextend16(sl,temp);
3853         break;
3854       case 31:
3855         c2op_ctc2_31_assemble(sl,temp);
3856         break;
3857       default:
3858         temp=sl;
3859         break;
3860     }
3861     emit_writeword(temp,&reg_cop2c[copr]);
3862     assert(sl>=0);
3863   }
3864 }
3865
3866 static void do_unalignedwritestub(int n)
3867 {
3868   assem_debug("do_unalignedwritestub %x\n",start+stubs[n].a*4);
3869   literal_pool(256);
3870   set_jump_target(stubs[n].addr, out);
3871
3872   int i=stubs[n].a;
3873   struct regstat *i_regs=(struct regstat *)stubs[n].c;
3874   int addr=stubs[n].b;
3875   u_int reglist=stubs[n].e;
3876   signed char *i_regmap=i_regs->regmap;
3877   int temp2=get_reg(i_regmap,FTEMP);
3878   int rt;
3879   rt=get_reg(i_regmap,dops[i].rs2);
3880   assert(rt>=0);
3881   assert(addr>=0);
3882   assert(dops[i].opcode==0x2a||dops[i].opcode==0x2e); // SWL/SWR only implemented
3883   reglist|=(1<<addr);
3884   reglist&=~(1<<temp2);
3885
3886   // don't bother with it and call write handler
3887   save_regs(reglist);
3888   pass_args(addr,rt);
3889   int cc=get_reg(i_regmap,CCREG);
3890   if(cc<0)
3891     emit_loadreg(CCREG,2);
3892   emit_addimm(cc<0?2:cc,(int)stubs[n].d+1,2);
3893   emit_far_call((dops[i].opcode==0x2a?jump_handle_swl:jump_handle_swr));
3894   emit_addimm(0,-((int)stubs[n].d+1),cc<0?2:cc);
3895   if(cc<0)
3896     emit_storereg(CCREG,2);
3897   restore_regs(reglist);
3898   emit_jmp(stubs[n].retaddr); // return address
3899 }
3900
3901 #ifndef multdiv_assemble
3902 void multdiv_assemble(int i,struct regstat *i_regs)
3903 {
3904   printf("Need multdiv_assemble for this architecture.\n");
3905   abort();
3906 }
3907 #endif
3908
3909 static void mov_assemble(int i, const struct regstat *i_regs)
3910 {
3911   //if(dops[i].opcode2==0x10||dops[i].opcode2==0x12) { // MFHI/MFLO
3912   //if(dops[i].opcode2==0x11||dops[i].opcode2==0x13) { // MTHI/MTLO
3913   if(dops[i].rt1) {
3914     signed char sl,tl;
3915     tl=get_reg(i_regs->regmap,dops[i].rt1);
3916     //assert(tl>=0);
3917     if(tl>=0) {
3918       sl=get_reg(i_regs->regmap,dops[i].rs1);
3919       if(sl>=0) emit_mov(sl,tl);
3920       else emit_loadreg(dops[i].rs1,tl);
3921     }
3922   }
3923   if (dops[i].rs1 == HIREG || dops[i].rs1 == LOREG) // MFHI/MFLO
3924     multdiv_do_stall(i, i_regs);
3925 }
3926
3927 // call interpreter, exception handler, things that change pc/regs/cycles ...
3928 static void call_c_cpu_handler(int i, const struct regstat *i_regs, int ccadj_, u_int pc, void *func)
3929 {
3930   signed char ccreg=get_reg(i_regs->regmap,CCREG);
3931   assert(ccreg==HOST_CCREG);
3932   assert(!is_delayslot);
3933   (void)ccreg;
3934
3935   emit_movimm(pc,3); // Get PC
3936   emit_readword(&last_count,2);
3937   emit_writeword(3,&psxRegs.pc);
3938   emit_addimm(HOST_CCREG,ccadj_,HOST_CCREG);
3939   emit_add(2,HOST_CCREG,2);
3940   emit_writeword(2,&psxRegs.cycle);
3941   emit_far_call(func);
3942   emit_far_jump(jump_to_new_pc);
3943 }
3944
3945 static void syscall_assemble(int i, const struct regstat *i_regs, int ccadj_)
3946 {
3947   // 'break' tends to be littered around to catch things like
3948   // division by 0 and is almost never executed, so don't emit much code here
3949   void *func = (dops[i].opcode2 == 0x0C)
3950     ? (is_delayslot ? jump_syscall_ds : jump_syscall)
3951     : (is_delayslot ? jump_break_ds : jump_break);
3952   signed char ccreg = get_reg(i_regs->regmap, CCREG);
3953   assert(ccreg == HOST_CCREG);
3954   emit_movimm(start + i*4, 2); // pc
3955   emit_addimm(HOST_CCREG, ccadj_ + CLOCK_ADJUST(1), HOST_CCREG);
3956   emit_far_jump(func);
3957 }
3958
3959 static void hlecall_assemble(int i, const struct regstat *i_regs, int ccadj_)
3960 {
3961   void *hlefunc = psxNULL;
3962   uint32_t hleCode = source[i] & 0x03ffffff;
3963   if (hleCode < ARRAY_SIZE(psxHLEt))
3964     hlefunc = psxHLEt[hleCode];
3965
3966   call_c_cpu_handler(i, i_regs, ccadj_, start + i*4+4, hlefunc);
3967 }
3968
3969 static void intcall_assemble(int i, const struct regstat *i_regs, int ccadj_)
3970 {
3971   call_c_cpu_handler(i, i_regs, ccadj_, start + i*4, execI);
3972 }
3973
3974 static void speculate_mov(int rs,int rt)
3975 {
3976   if(rt!=0) {
3977     smrv_strong_next|=1<<rt;
3978     smrv[rt]=smrv[rs];
3979   }
3980 }
3981
3982 static void speculate_mov_weak(int rs,int rt)
3983 {
3984   if(rt!=0) {
3985     smrv_weak_next|=1<<rt;
3986     smrv[rt]=smrv[rs];
3987   }
3988 }
3989
3990 static void speculate_register_values(int i)
3991 {
3992   if(i==0) {
3993     memcpy(smrv,psxRegs.GPR.r,sizeof(smrv));
3994     // gp,sp are likely to stay the same throughout the block
3995     smrv_strong_next=(1<<28)|(1<<29)|(1<<30);
3996     smrv_weak_next=~smrv_strong_next;
3997     //printf(" llr %08x\n", smrv[4]);
3998   }
3999   smrv_strong=smrv_strong_next;
4000   smrv_weak=smrv_weak_next;
4001   switch(dops[i].itype) {
4002     case ALU:
4003       if     ((smrv_strong>>dops[i].rs1)&1) speculate_mov(dops[i].rs1,dops[i].rt1);
4004       else if((smrv_strong>>dops[i].rs2)&1) speculate_mov(dops[i].rs2,dops[i].rt1);
4005       else if((smrv_weak>>dops[i].rs1)&1) speculate_mov_weak(dops[i].rs1,dops[i].rt1);
4006       else if((smrv_weak>>dops[i].rs2)&1) speculate_mov_weak(dops[i].rs2,dops[i].rt1);
4007       else {
4008         smrv_strong_next&=~(1<<dops[i].rt1);
4009         smrv_weak_next&=~(1<<dops[i].rt1);
4010       }
4011       break;
4012     case SHIFTIMM:
4013       smrv_strong_next&=~(1<<dops[i].rt1);
4014       smrv_weak_next&=~(1<<dops[i].rt1);
4015       // fallthrough
4016     case IMM16:
4017       if(dops[i].rt1&&is_const(&regs[i],dops[i].rt1)) {
4018         int value,hr=get_reg(regs[i].regmap,dops[i].rt1);
4019         if(hr>=0) {
4020           if(get_final_value(hr,i,&value))
4021                smrv[dops[i].rt1]=value;
4022           else smrv[dops[i].rt1]=constmap[i][hr];
4023           smrv_strong_next|=1<<dops[i].rt1;
4024         }
4025       }
4026       else {
4027         if     ((smrv_strong>>dops[i].rs1)&1) speculate_mov(dops[i].rs1,dops[i].rt1);
4028         else if((smrv_weak>>dops[i].rs1)&1) speculate_mov_weak(dops[i].rs1,dops[i].rt1);
4029       }
4030       break;
4031     case LOAD:
4032       if(start<0x2000&&(dops[i].rt1==26||(smrv[dops[i].rt1]>>24)==0xa0)) {
4033         // special case for BIOS
4034         smrv[dops[i].rt1]=0xa0000000;
4035         smrv_strong_next|=1<<dops[i].rt1;
4036         break;
4037       }
4038       // fallthrough
4039     case SHIFT:
4040     case LOADLR:
4041     case MOV:
4042       smrv_strong_next&=~(1<<dops[i].rt1);
4043       smrv_weak_next&=~(1<<dops[i].rt1);
4044       break;
4045     case COP0:
4046     case COP2:
4047       if(dops[i].opcode2==0||dops[i].opcode2==2) { // MFC/CFC
4048         smrv_strong_next&=~(1<<dops[i].rt1);
4049         smrv_weak_next&=~(1<<dops[i].rt1);
4050       }
4051       break;
4052     case C2LS:
4053       if (dops[i].opcode==0x32) { // LWC2
4054         smrv_strong_next&=~(1<<dops[i].rt1);
4055         smrv_weak_next&=~(1<<dops[i].rt1);
4056       }
4057       break;
4058   }
4059 #if 0
4060   int r=4;
4061   printf("x %08x %08x %d %d c %08x %08x\n",smrv[r],start+i*4,
4062     ((smrv_strong>>r)&1),(smrv_weak>>r)&1,regs[i].isconst,regs[i].wasconst);
4063 #endif
4064 }
4065
4066 static void ujump_assemble(int i, const struct regstat *i_regs);
4067 static void rjump_assemble(int i, const struct regstat *i_regs);
4068 static void cjump_assemble(int i, const struct regstat *i_regs);
4069 static void sjump_assemble(int i, const struct regstat *i_regs);
4070 static void pagespan_assemble(int i, const struct regstat *i_regs);
4071
4072 static int assemble(int i, const struct regstat *i_regs, int ccadj_)
4073 {
4074   int ds = 0;
4075   switch (dops[i].itype) {
4076     case ALU:
4077       alu_assemble(i, i_regs);
4078       break;
4079     case IMM16:
4080       imm16_assemble(i, i_regs);
4081       break;
4082     case SHIFT:
4083       shift_assemble(i, i_regs);
4084       break;
4085     case SHIFTIMM:
4086       shiftimm_assemble(i, i_regs);
4087       break;
4088     case LOAD:
4089       load_assemble(i, i_regs, ccadj_);
4090       break;
4091     case LOADLR:
4092       loadlr_assemble(i, i_regs, ccadj_);
4093       break;
4094     case STORE:
4095       store_assemble(i, i_regs, ccadj_);
4096       break;
4097     case STORELR:
4098       storelr_assemble(i, i_regs, ccadj_);
4099       break;
4100     case COP0:
4101       cop0_assemble(i, i_regs, ccadj_);
4102       break;
4103     case COP1:
4104       cop1_assemble(i, i_regs);
4105       break;
4106     case C1LS:
4107       c1ls_assemble(i, i_regs);
4108       break;
4109     case COP2:
4110       cop2_assemble(i, i_regs);
4111       break;
4112     case C2LS:
4113       c2ls_assemble(i, i_regs, ccadj_);
4114       break;
4115     case C2OP:
4116       c2op_assemble(i, i_regs);
4117       break;
4118     case MULTDIV:
4119       multdiv_assemble(i, i_regs);
4120       multdiv_prepare_stall(i, i_regs, ccadj_);
4121       break;
4122     case MOV:
4123       mov_assemble(i, i_regs);
4124       break;
4125     case SYSCALL:
4126       syscall_assemble(i, i_regs, ccadj_);
4127       break;
4128     case HLECALL:
4129       hlecall_assemble(i, i_regs, ccadj_);
4130       break;
4131     case INTCALL:
4132       intcall_assemble(i, i_regs, ccadj_);
4133       break;
4134     case UJUMP:
4135       ujump_assemble(i, i_regs);
4136       ds = 1;
4137       break;
4138     case RJUMP:
4139       rjump_assemble(i, i_regs);
4140       ds = 1;
4141       break;
4142     case CJUMP:
4143       cjump_assemble(i, i_regs);
4144       ds = 1;
4145       break;
4146     case SJUMP:
4147       sjump_assemble(i, i_regs);
4148       ds = 1;
4149       break;
4150     case SPAN:
4151       pagespan_assemble(i, i_regs);
4152       break;
4153     case NOP:
4154     case OTHER:
4155     case NI:
4156       // not handled, just skip
4157       break;
4158     default:
4159       assert(0);
4160   }
4161   return ds;
4162 }
4163
4164 static void ds_assemble(int i, const struct regstat *i_regs)
4165 {
4166   speculate_register_values(i);
4167   is_delayslot = 1;
4168   switch (dops[i].itype) {
4169     case SYSCALL:
4170     case HLECALL:
4171     case INTCALL:
4172     case SPAN:
4173     case UJUMP:
4174     case RJUMP:
4175     case CJUMP:
4176     case SJUMP:
4177       SysPrintf("Jump in the delay slot.  This is probably a bug.\n");
4178       break;
4179     default:
4180       assemble(i, i_regs, ccadj[i]);
4181   }
4182   is_delayslot = 0;
4183 }
4184
4185 // Is the branch target a valid internal jump?
4186 static int internal_branch(int addr)
4187 {
4188   if(addr&1) return 0; // Indirect (register) jump
4189   if(addr>=start && addr<start+slen*4-4)
4190   {
4191     return 1;
4192   }
4193   return 0;
4194 }
4195
4196 static void wb_invalidate(signed char pre[],signed char entry[],uint64_t dirty,uint64_t u)
4197 {
4198   int hr;
4199   for(hr=0;hr<HOST_REGS;hr++) {
4200     if(hr!=EXCLUDE_REG) {
4201       if(pre[hr]!=entry[hr]) {
4202         if(pre[hr]>=0) {
4203           if((dirty>>hr)&1) {
4204             if(get_reg(entry,pre[hr])<0) {
4205               assert(pre[hr]<64);
4206               if(!((u>>pre[hr])&1))
4207                 emit_storereg(pre[hr],hr);
4208             }
4209           }
4210         }
4211       }
4212     }
4213   }
4214   // Move from one register to another (no writeback)
4215   for(hr=0;hr<HOST_REGS;hr++) {
4216     if(hr!=EXCLUDE_REG) {
4217       if(pre[hr]!=entry[hr]) {
4218         if(pre[hr]>=0&&(pre[hr]&63)<TEMPREG) {
4219           int nr;
4220           if((nr=get_reg(entry,pre[hr]))>=0) {
4221             emit_mov(hr,nr);
4222           }
4223         }
4224       }
4225     }
4226   }
4227 }
4228
4229 // Load the specified registers
4230 // This only loads the registers given as arguments because
4231 // we don't want to load things that will be overwritten
4232 static void load_regs(signed char entry[],signed char regmap[],int rs1,int rs2)
4233 {
4234   int hr;
4235   // Load 32-bit regs
4236   for(hr=0;hr<HOST_REGS;hr++) {
4237     if(hr!=EXCLUDE_REG&&regmap[hr]>=0) {
4238       if(entry[hr]!=regmap[hr]) {
4239         if(regmap[hr]==rs1||regmap[hr]==rs2)
4240         {
4241           if(regmap[hr]==0) {
4242             emit_zeroreg(hr);
4243           }
4244           else
4245           {
4246             emit_loadreg(regmap[hr],hr);
4247           }
4248         }
4249       }
4250     }
4251   }
4252 }
4253
4254 // Load registers prior to the start of a loop
4255 // so that they are not loaded within the loop
4256 static void loop_preload(signed char pre[],signed char entry[])
4257 {
4258   int hr;
4259   for(hr=0;hr<HOST_REGS;hr++) {
4260     if(hr!=EXCLUDE_REG) {
4261       if(pre[hr]!=entry[hr]) {
4262         if(entry[hr]>=0) {
4263           if(get_reg(pre,entry[hr])<0) {
4264             assem_debug("loop preload:\n");
4265             //printf("loop preload: %d\n",hr);
4266             if(entry[hr]==0) {
4267               emit_zeroreg(hr);
4268             }
4269             else if(entry[hr]<TEMPREG)
4270             {
4271               emit_loadreg(entry[hr],hr);
4272             }
4273             else if(entry[hr]-64<TEMPREG)
4274             {
4275               emit_loadreg(entry[hr],hr);
4276             }
4277           }
4278         }
4279       }
4280     }
4281   }
4282 }
4283
4284 // Generate address for load/store instruction
4285 // goes to AGEN for writes, FTEMP for LOADLR and cop1/2 loads
4286 void address_generation(int i, const struct regstat *i_regs, signed char entry[])
4287 {
4288   if (dops[i].is_load || dops[i].is_store) {
4289     int ra=-1;
4290     int agr=AGEN1+(i&1);
4291     if(dops[i].itype==LOAD) {
4292       ra=get_reg(i_regs->regmap,dops[i].rt1);
4293       if(ra<0) ra=get_reg(i_regs->regmap,-1);
4294       assert(ra>=0);
4295     }
4296     if(dops[i].itype==LOADLR) {
4297       ra=get_reg(i_regs->regmap,FTEMP);
4298     }
4299     if(dops[i].itype==STORE||dops[i].itype==STORELR) {
4300       ra=get_reg(i_regs->regmap,agr);
4301       if(ra<0) ra=get_reg(i_regs->regmap,-1);
4302     }
4303     if(dops[i].itype==C2LS) {
4304       if ((dops[i].opcode&0x3b)==0x31||(dops[i].opcode&0x3b)==0x32) // LWC1/LDC1/LWC2/LDC2
4305         ra=get_reg(i_regs->regmap,FTEMP);
4306       else { // SWC1/SDC1/SWC2/SDC2
4307         ra=get_reg(i_regs->regmap,agr);
4308         if(ra<0) ra=get_reg(i_regs->regmap,-1);
4309       }
4310     }
4311     int rs=get_reg(i_regs->regmap,dops[i].rs1);
4312     if(ra>=0) {
4313       int offset=imm[i];
4314       int c=(i_regs->wasconst>>rs)&1;
4315       if(dops[i].rs1==0) {
4316         // Using r0 as a base address
4317         if(!entry||entry[ra]!=agr) {
4318           if (dops[i].opcode==0x22||dops[i].opcode==0x26) {
4319             emit_movimm(offset&0xFFFFFFFC,ra); // LWL/LWR
4320           }else if (dops[i].opcode==0x1a||dops[i].opcode==0x1b) {
4321             emit_movimm(offset&0xFFFFFFF8,ra); // LDL/LDR
4322           }else{
4323             emit_movimm(offset,ra);
4324           }
4325         } // else did it in the previous cycle
4326       }
4327       else if(rs<0) {
4328         if(!entry||entry[ra]!=dops[i].rs1)
4329           emit_loadreg(dops[i].rs1,ra);
4330         //if(!entry||entry[ra]!=dops[i].rs1)
4331         //  printf("poor load scheduling!\n");
4332       }
4333       else if(c) {
4334         if(dops[i].rs1!=dops[i].rt1||dops[i].itype!=LOAD) {
4335           if(!entry||entry[ra]!=agr) {
4336             if (dops[i].opcode==0x22||dops[i].opcode==0x26) {
4337               emit_movimm((constmap[i][rs]+offset)&0xFFFFFFFC,ra); // LWL/LWR
4338             }else if (dops[i].opcode==0x1a||dops[i].opcode==0x1b) {
4339               emit_movimm((constmap[i][rs]+offset)&0xFFFFFFF8,ra); // LDL/LDR
4340             }else{
4341               emit_movimm(constmap[i][rs]+offset,ra);
4342               regs[i].loadedconst|=1<<ra;
4343             }
4344           } // else did it in the previous cycle
4345         } // else load_consts already did it
4346       }
4347       if(offset&&!c&&dops[i].rs1) {
4348         if(rs>=0) {
4349           emit_addimm(rs,offset,ra);
4350         }else{
4351           emit_addimm(ra,offset,ra);
4352         }
4353       }
4354     }
4355   }
4356   // Preload constants for next instruction
4357   if (dops[i+1].is_load || dops[i+1].is_store) {
4358     int agr,ra;
4359     // Actual address
4360     agr=AGEN1+((i+1)&1);
4361     ra=get_reg(i_regs->regmap,agr);
4362     if(ra>=0) {
4363       int rs=get_reg(regs[i+1].regmap,dops[i+1].rs1);
4364       int offset=imm[i+1];
4365       int c=(regs[i+1].wasconst>>rs)&1;
4366       if(c&&(dops[i+1].rs1!=dops[i+1].rt1||dops[i+1].itype!=LOAD)) {
4367         if (dops[i+1].opcode==0x22||dops[i+1].opcode==0x26) {
4368           emit_movimm((constmap[i+1][rs]+offset)&0xFFFFFFFC,ra); // LWL/LWR
4369         }else if (dops[i+1].opcode==0x1a||dops[i+1].opcode==0x1b) {
4370           emit_movimm((constmap[i+1][rs]+offset)&0xFFFFFFF8,ra); // LDL/LDR
4371         }else{
4372           emit_movimm(constmap[i+1][rs]+offset,ra);
4373           regs[i+1].loadedconst|=1<<ra;
4374         }
4375       }
4376       else if(dops[i+1].rs1==0) {
4377         // Using r0 as a base address
4378         if (dops[i+1].opcode==0x22||dops[i+1].opcode==0x26) {
4379           emit_movimm(offset&0xFFFFFFFC,ra); // LWL/LWR
4380         }else if (dops[i+1].opcode==0x1a||dops[i+1].opcode==0x1b) {
4381           emit_movimm(offset&0xFFFFFFF8,ra); // LDL/LDR
4382         }else{
4383           emit_movimm(offset,ra);
4384         }
4385       }
4386     }
4387   }
4388 }
4389
4390 static int get_final_value(int hr, int i, int *value)
4391 {
4392   int reg=regs[i].regmap[hr];
4393   while(i<slen-1) {
4394     if(regs[i+1].regmap[hr]!=reg) break;
4395     if(!((regs[i+1].isconst>>hr)&1)) break;
4396     if(dops[i+1].bt) break;
4397     i++;
4398   }
4399   if(i<slen-1) {
4400     if (dops[i].is_jump) {
4401       *value=constmap[i][hr];
4402       return 1;
4403     }
4404     if(!dops[i+1].bt) {
4405       if (dops[i+1].is_jump) {
4406         // Load in delay slot, out-of-order execution
4407         if(dops[i+2].itype==LOAD&&dops[i+2].rs1==reg&&dops[i+2].rt1==reg&&((regs[i+1].wasconst>>hr)&1))
4408         {
4409           // Precompute load address
4410           *value=constmap[i][hr]+imm[i+2];
4411           return 1;
4412         }
4413       }
4414       if(dops[i+1].itype==LOAD&&dops[i+1].rs1==reg&&dops[i+1].rt1==reg)
4415       {
4416         // Precompute load address
4417         *value=constmap[i][hr]+imm[i+1];
4418         //printf("c=%x imm=%lx\n",(long)constmap[i][hr],imm[i+1]);
4419         return 1;
4420       }
4421     }
4422   }
4423   *value=constmap[i][hr];
4424   //printf("c=%lx\n",(long)constmap[i][hr]);
4425   if(i==slen-1) return 1;
4426   assert(reg < 64);
4427   return !((unneeded_reg[i+1]>>reg)&1);
4428 }
4429
4430 // Load registers with known constants
4431 static void load_consts(signed char pre[],signed char regmap[],int i)
4432 {
4433   int hr,hr2;
4434   // propagate loaded constant flags
4435   if(i==0||dops[i].bt)
4436     regs[i].loadedconst=0;
4437   else {
4438     for(hr=0;hr<HOST_REGS;hr++) {
4439       if(hr!=EXCLUDE_REG&&regmap[hr]>=0&&((regs[i-1].isconst>>hr)&1)&&pre[hr]==regmap[hr]
4440          &&regmap[hr]==regs[i-1].regmap[hr]&&((regs[i-1].loadedconst>>hr)&1))
4441       {
4442         regs[i].loadedconst|=1<<hr;
4443       }
4444     }
4445   }
4446   // Load 32-bit regs
4447   for(hr=0;hr<HOST_REGS;hr++) {
4448     if(hr!=EXCLUDE_REG&&regmap[hr]>=0) {
4449       //if(entry[hr]!=regmap[hr]) {
4450       if(!((regs[i].loadedconst>>hr)&1)) {
4451         assert(regmap[hr]<64);
4452         if(((regs[i].isconst>>hr)&1)&&regmap[hr]>0) {
4453           int value,similar=0;
4454           if(get_final_value(hr,i,&value)) {
4455             // see if some other register has similar value
4456             for(hr2=0;hr2<HOST_REGS;hr2++) {
4457               if(hr2!=EXCLUDE_REG&&((regs[i].loadedconst>>hr2)&1)) {
4458                 if(is_similar_value(value,constmap[i][hr2])) {
4459                   similar=1;
4460                   break;
4461                 }
4462               }
4463             }
4464             if(similar) {
4465               int value2;
4466               if(get_final_value(hr2,i,&value2)) // is this needed?
4467                 emit_movimm_from(value2,hr2,value,hr);
4468               else
4469                 emit_movimm(value,hr);
4470             }
4471             else if(value==0) {
4472               emit_zeroreg(hr);
4473             }
4474             else {
4475               emit_movimm(value,hr);
4476             }
4477           }
4478           regs[i].loadedconst|=1<<hr;
4479         }
4480       }
4481     }
4482   }
4483 }
4484
4485 static void load_all_consts(const signed char regmap[], u_int dirty, int i)
4486 {
4487   int hr;
4488   // Load 32-bit regs
4489   for(hr=0;hr<HOST_REGS;hr++) {
4490     if(hr!=EXCLUDE_REG&&regmap[hr]>=0&&((dirty>>hr)&1)) {
4491       assert(regmap[hr] < 64);
4492       if(((regs[i].isconst>>hr)&1)&&regmap[hr]>0) {
4493         int value=constmap[i][hr];
4494         if(value==0) {
4495           emit_zeroreg(hr);
4496         }
4497         else {
4498           emit_movimm(value,hr);
4499         }
4500       }
4501     }
4502   }
4503 }
4504
4505 // Write out all dirty registers (except cycle count)
4506 static void wb_dirtys(const signed char i_regmap[], uint64_t i_dirty)
4507 {
4508   int hr;
4509   for(hr=0;hr<HOST_REGS;hr++) {
4510     if(hr!=EXCLUDE_REG) {
4511       if(i_regmap[hr]>0) {
4512         if(i_regmap[hr]!=CCREG) {
4513           if((i_dirty>>hr)&1) {
4514             assert(i_regmap[hr]<64);
4515             emit_storereg(i_regmap[hr],hr);
4516           }
4517         }
4518       }
4519     }
4520   }
4521 }
4522
4523 // Write out dirty registers that we need to reload (pair with load_needed_regs)
4524 // This writes the registers not written by store_regs_bt
4525 static void wb_needed_dirtys(const signed char i_regmap[], uint64_t i_dirty, int addr)
4526 {
4527   int hr;
4528   int t=(addr-start)>>2;
4529   for(hr=0;hr<HOST_REGS;hr++) {
4530     if(hr!=EXCLUDE_REG) {
4531       if(i_regmap[hr]>0) {
4532         if(i_regmap[hr]!=CCREG) {
4533           if(i_regmap[hr]==regs[t].regmap_entry[hr] && ((regs[t].dirty>>hr)&1)) {
4534             if((i_dirty>>hr)&1) {
4535               assert(i_regmap[hr]<64);
4536               emit_storereg(i_regmap[hr],hr);
4537             }
4538           }
4539         }
4540       }
4541     }
4542   }
4543 }
4544
4545 // Load all registers (except cycle count)
4546 static void load_all_regs(const signed char i_regmap[])
4547 {
4548   int hr;
4549   for(hr=0;hr<HOST_REGS;hr++) {
4550     if(hr!=EXCLUDE_REG) {
4551       if(i_regmap[hr]==0) {
4552         emit_zeroreg(hr);
4553       }
4554       else
4555       if(i_regmap[hr]>0 && (i_regmap[hr]&63)<TEMPREG && i_regmap[hr]!=CCREG)
4556       {
4557         emit_loadreg(i_regmap[hr],hr);
4558       }
4559     }
4560   }
4561 }
4562
4563 // Load all current registers also needed by next instruction
4564 static void load_needed_regs(const signed char i_regmap[], const signed char next_regmap[])
4565 {
4566   int hr;
4567   for(hr=0;hr<HOST_REGS;hr++) {
4568     if(hr!=EXCLUDE_REG) {
4569       if(get_reg(next_regmap,i_regmap[hr])>=0) {
4570         if(i_regmap[hr]==0) {
4571           emit_zeroreg(hr);
4572         }
4573         else
4574         if(i_regmap[hr]>0 && (i_regmap[hr]&63)<TEMPREG && i_regmap[hr]!=CCREG)
4575         {
4576           emit_loadreg(i_regmap[hr],hr);
4577         }
4578       }
4579     }
4580   }
4581 }
4582
4583 // Load all regs, storing cycle count if necessary
4584 static void load_regs_entry(int t)
4585 {
4586   int hr;
4587   if(dops[t].is_ds) emit_addimm(HOST_CCREG,CLOCK_ADJUST(1),HOST_CCREG);
4588   else if(ccadj[t]) emit_addimm(HOST_CCREG,-ccadj[t],HOST_CCREG);
4589   if(regs[t].regmap_entry[HOST_CCREG]!=CCREG) {
4590     emit_storereg(CCREG,HOST_CCREG);
4591   }
4592   // Load 32-bit regs
4593   for(hr=0;hr<HOST_REGS;hr++) {
4594     if(regs[t].regmap_entry[hr]>=0&&regs[t].regmap_entry[hr]<TEMPREG) {
4595       if(regs[t].regmap_entry[hr]==0) {
4596         emit_zeroreg(hr);
4597       }
4598       else if(regs[t].regmap_entry[hr]!=CCREG)
4599       {
4600         emit_loadreg(regs[t].regmap_entry[hr],hr);
4601       }
4602     }
4603   }
4604 }
4605
4606 // Store dirty registers prior to branch
4607 void store_regs_bt(signed char i_regmap[],uint64_t i_dirty,int addr)
4608 {
4609   if(internal_branch(addr))
4610   {
4611     int t=(addr-start)>>2;
4612     int hr;
4613     for(hr=0;hr<HOST_REGS;hr++) {
4614       if(hr!=EXCLUDE_REG) {
4615         if(i_regmap[hr]>0 && i_regmap[hr]!=CCREG) {
4616           if(i_regmap[hr]!=regs[t].regmap_entry[hr] || !((regs[t].dirty>>hr)&1)) {
4617             if((i_dirty>>hr)&1) {
4618               assert(i_regmap[hr]<64);
4619               if(!((unneeded_reg[t]>>i_regmap[hr])&1))
4620                 emit_storereg(i_regmap[hr],hr);
4621             }
4622           }
4623         }
4624       }
4625     }
4626   }
4627   else
4628   {
4629     // Branch out of this block, write out all dirty regs
4630     wb_dirtys(i_regmap,i_dirty);
4631   }
4632 }
4633
4634 // Load all needed registers for branch target
4635 static void load_regs_bt(signed char i_regmap[],uint64_t i_dirty,int addr)
4636 {
4637   //if(addr>=start && addr<(start+slen*4))
4638   if(internal_branch(addr))
4639   {
4640     int t=(addr-start)>>2;
4641     int hr;
4642     // Store the cycle count before loading something else
4643     if(i_regmap[HOST_CCREG]!=CCREG) {
4644       assert(i_regmap[HOST_CCREG]==-1);
4645     }
4646     if(regs[t].regmap_entry[HOST_CCREG]!=CCREG) {
4647       emit_storereg(CCREG,HOST_CCREG);
4648     }
4649     // Load 32-bit regs
4650     for(hr=0;hr<HOST_REGS;hr++) {
4651       if(hr!=EXCLUDE_REG&&regs[t].regmap_entry[hr]>=0&&regs[t].regmap_entry[hr]<TEMPREG) {
4652         if(i_regmap[hr]!=regs[t].regmap_entry[hr]) {
4653           if(regs[t].regmap_entry[hr]==0) {
4654             emit_zeroreg(hr);
4655           }
4656           else if(regs[t].regmap_entry[hr]!=CCREG)
4657           {
4658             emit_loadreg(regs[t].regmap_entry[hr],hr);
4659           }
4660         }
4661       }
4662     }
4663   }
4664 }
4665
4666 static int match_bt(signed char i_regmap[],uint64_t i_dirty,int addr)
4667 {
4668   if(addr>=start && addr<start+slen*4-4)
4669   {
4670     int t=(addr-start)>>2;
4671     int hr;
4672     if(regs[t].regmap_entry[HOST_CCREG]!=CCREG) return 0;
4673     for(hr=0;hr<HOST_REGS;hr++)
4674     {
4675       if(hr!=EXCLUDE_REG)
4676       {
4677         if(i_regmap[hr]!=regs[t].regmap_entry[hr])
4678         {
4679           if(regs[t].regmap_entry[hr]>=0&&(regs[t].regmap_entry[hr]|64)<TEMPREG+64)
4680           {
4681             return 0;
4682           }
4683           else
4684           if((i_dirty>>hr)&1)
4685           {
4686             if(i_regmap[hr]<TEMPREG)
4687             {
4688               if(!((unneeded_reg[t]>>i_regmap[hr])&1))
4689                 return 0;
4690             }
4691             else if(i_regmap[hr]>=64&&i_regmap[hr]<TEMPREG+64)
4692             {
4693               assert(0);
4694             }
4695           }
4696         }
4697         else // Same register but is it 32-bit or dirty?
4698         if(i_regmap[hr]>=0)
4699         {
4700           if(!((regs[t].dirty>>hr)&1))
4701           {
4702             if((i_dirty>>hr)&1)
4703             {
4704               if(!((unneeded_reg[t]>>i_regmap[hr])&1))
4705               {
4706                 //printf("%x: dirty no match\n",addr);
4707                 return 0;
4708               }
4709             }
4710           }
4711         }
4712       }
4713     }
4714     // Delay slots are not valid branch targets
4715     //if(t>0&&(dops[t-1].is_jump) return 0;
4716     // Delay slots require additional processing, so do not match
4717     if(dops[t].is_ds) return 0;
4718   }
4719   else
4720   {
4721     int hr;
4722     for(hr=0;hr<HOST_REGS;hr++)
4723     {
4724       if(hr!=EXCLUDE_REG)
4725       {
4726         if(i_regmap[hr]>=0)
4727         {
4728           if(hr!=HOST_CCREG||i_regmap[hr]!=CCREG)
4729           {
4730             if((i_dirty>>hr)&1)
4731             {
4732               return 0;
4733             }
4734           }
4735         }
4736       }
4737     }
4738   }
4739   return 1;
4740 }
4741
4742 #ifdef DRC_DBG
4743 static void drc_dbg_emit_do_cmp(int i, int ccadj_)
4744 {
4745   extern void do_insn_cmp();
4746   //extern int cycle;
4747   u_int hr, reglist = get_host_reglist(regs[i].regmap);
4748
4749   assem_debug("//do_insn_cmp %08x\n", start+i*4);
4750   save_regs(reglist);
4751   // write out changed consts to match the interpreter
4752   if (i > 0 && !dops[i].bt) {
4753     for (hr = 0; hr < HOST_REGS; hr++) {
4754       int reg = regs[i].regmap_entry[hr]; // regs[i-1].regmap[hr];
4755       if (hr == EXCLUDE_REG || reg < 0)
4756         continue;
4757       if (!((regs[i-1].isconst >> hr) & 1))
4758         continue;
4759       if (i > 1 && reg == regs[i-2].regmap[hr] && constmap[i-1][hr] == constmap[i-2][hr])
4760         continue;
4761       emit_movimm(constmap[i-1][hr],0);
4762       emit_storereg(reg, 0);
4763     }
4764   }
4765   emit_movimm(start+i*4,0);
4766   emit_writeword(0,&pcaddr);
4767   int cc = get_reg(regs[i].regmap_entry, CCREG);
4768   if (cc < 0)
4769     emit_loadreg(CCREG, cc = 0);
4770   emit_addimm(cc, ccadj_, 0);
4771   emit_writeword(0, &psxRegs.cycle);
4772   emit_far_call(do_insn_cmp);
4773   //emit_readword(&cycle,0);
4774   //emit_addimm(0,2,0);
4775   //emit_writeword(0,&cycle);
4776   (void)get_reg2;
4777   restore_regs(reglist);
4778   assem_debug("\\\\do_insn_cmp\n");
4779 }
4780 #else
4781 #define drc_dbg_emit_do_cmp(x,y)
4782 #endif
4783
4784 // Used when a branch jumps into the delay slot of another branch
4785 static void ds_assemble_entry(int i)
4786 {
4787   int t = (ba[i] - start) >> 2;
4788   int ccadj_ = -CLOCK_ADJUST(1);
4789   if (!instr_addr[t])
4790     instr_addr[t] = out;
4791   assem_debug("Assemble delay slot at %x\n",ba[i]);
4792   assem_debug("<->\n");
4793   drc_dbg_emit_do_cmp(t, ccadj_);
4794   if(regs[t].regmap_entry[HOST_CCREG]==CCREG&&regs[t].regmap[HOST_CCREG]!=CCREG)
4795     wb_register(CCREG,regs[t].regmap_entry,regs[t].wasdirty);
4796   load_regs(regs[t].regmap_entry,regs[t].regmap,dops[t].rs1,dops[t].rs2);
4797   address_generation(t,&regs[t],regs[t].regmap_entry);
4798   if (ram_offset && (dops[t].is_load || dops[t].is_store))
4799     load_regs(regs[t].regmap_entry,regs[t].regmap,ROREG,ROREG);
4800   if (dops[t].is_store)
4801     load_regs(regs[t].regmap_entry,regs[t].regmap,INVCP,INVCP);
4802   is_delayslot=0;
4803   switch (dops[t].itype) {
4804     case SYSCALL:
4805     case HLECALL:
4806     case INTCALL:
4807     case SPAN:
4808     case UJUMP:
4809     case RJUMP:
4810     case CJUMP:
4811     case SJUMP:
4812       SysPrintf("Jump in the delay slot.  This is probably a bug.\n");
4813       break;
4814     default:
4815       assemble(t, &regs[t], ccadj_);
4816   }
4817   store_regs_bt(regs[t].regmap,regs[t].dirty,ba[i]+4);
4818   load_regs_bt(regs[t].regmap,regs[t].dirty,ba[i]+4);
4819   if(internal_branch(ba[i]+4))
4820     assem_debug("branch: internal\n");
4821   else
4822     assem_debug("branch: external\n");
4823   assert(internal_branch(ba[i]+4));
4824   add_to_linker(out,ba[i]+4,internal_branch(ba[i]+4));
4825   emit_jmp(0);
4826 }
4827
4828 static void emit_extjump(void *addr, u_int target)
4829 {
4830   emit_extjump2(addr, target, dyna_linker);
4831 }
4832
4833 static void emit_extjump_ds(void *addr, u_int target)
4834 {
4835   emit_extjump2(addr, target, dyna_linker_ds);
4836 }
4837
4838 // Load 2 immediates optimizing for small code size
4839 static void emit_mov2imm_compact(int imm1,u_int rt1,int imm2,u_int rt2)
4840 {
4841   emit_movimm(imm1,rt1);
4842   emit_movimm_from(imm1,rt1,imm2,rt2);
4843 }
4844
4845 static void do_cc(int i, const signed char i_regmap[], int *adj,
4846   int addr, int taken, int invert)
4847 {
4848   int count, count_plus2;
4849   void *jaddr;
4850   void *idle=NULL;
4851   int t=0;
4852   if(dops[i].itype==RJUMP)
4853   {
4854     *adj=0;
4855   }
4856   //if(ba[i]>=start && ba[i]<(start+slen*4))
4857   if(internal_branch(ba[i]))
4858   {
4859     t=(ba[i]-start)>>2;
4860     if(dops[t].is_ds) *adj=-CLOCK_ADJUST(1); // Branch into delay slot adds an extra cycle
4861     else *adj=ccadj[t];
4862   }
4863   else
4864   {
4865     *adj=0;
4866   }
4867   count = ccadj[i];
4868   count_plus2 = count + CLOCK_ADJUST(2);
4869   if(taken==TAKEN && i==(ba[i]-start)>>2 && source[i+1]==0) {
4870     // Idle loop
4871     if(count&1) emit_addimm_and_set_flags(2*(count+2),HOST_CCREG);
4872     idle=out;
4873     //emit_subfrommem(&idlecount,HOST_CCREG); // Count idle cycles
4874     emit_andimm(HOST_CCREG,3,HOST_CCREG);
4875     jaddr=out;
4876     emit_jmp(0);
4877   }
4878   else if(*adj==0||invert) {
4879     int cycles = count_plus2;
4880     // faster loop HACK
4881 #if 0
4882     if (t&&*adj) {
4883       int rel=t-i;
4884       if(-NO_CYCLE_PENALTY_THR<rel&&rel<0)
4885         cycles=*adj+count+2-*adj;
4886     }
4887 #endif
4888     emit_addimm_and_set_flags(cycles, HOST_CCREG);
4889     jaddr = out;
4890     emit_jns(0);
4891   }
4892   else
4893   {
4894     emit_cmpimm(HOST_CCREG, -count_plus2);
4895     jaddr = out;
4896     emit_jns(0);
4897   }
4898   add_stub(CC_STUB,jaddr,idle?idle:out,(*adj==0||invert||idle)?0:count_plus2,i,addr,taken,0);
4899 }
4900
4901 static void do_ccstub(int n)
4902 {
4903   literal_pool(256);
4904   assem_debug("do_ccstub %x\n",start+(u_int)stubs[n].b*4);
4905   set_jump_target(stubs[n].addr, out);
4906   int i=stubs[n].b;
4907   if(stubs[n].d==NULLDS) {
4908     // Delay slot instruction is nullified ("likely" branch)
4909     wb_dirtys(regs[i].regmap,regs[i].dirty);
4910   }
4911   else if(stubs[n].d!=TAKEN) {
4912     wb_dirtys(branch_regs[i].regmap,branch_regs[i].dirty);
4913   }
4914   else {
4915     if(internal_branch(ba[i]))
4916       wb_needed_dirtys(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
4917   }
4918   if(stubs[n].c!=-1)
4919   {
4920     // Save PC as return address
4921     emit_movimm(stubs[n].c,EAX);
4922     emit_writeword(EAX,&pcaddr);
4923   }
4924   else
4925   {
4926     // Return address depends on which way the branch goes
4927     if(dops[i].itype==CJUMP||dops[i].itype==SJUMP)
4928     {
4929       int s1l=get_reg(branch_regs[i].regmap,dops[i].rs1);
4930       int s2l=get_reg(branch_regs[i].regmap,dops[i].rs2);
4931       if(dops[i].rs1==0)
4932       {
4933         s1l=s2l;
4934         s2l=-1;
4935       }
4936       else if(dops[i].rs2==0)
4937       {
4938         s2l=-1;
4939       }
4940       assert(s1l>=0);
4941       #ifdef DESTRUCTIVE_WRITEBACK
4942       if(dops[i].rs1) {
4943         if((branch_regs[i].dirty>>s1l)&&1)
4944           emit_loadreg(dops[i].rs1,s1l);
4945       }
4946       else {
4947         if((branch_regs[i].dirty>>s1l)&1)
4948           emit_loadreg(dops[i].rs2,s1l);
4949       }
4950       if(s2l>=0)
4951         if((branch_regs[i].dirty>>s2l)&1)
4952           emit_loadreg(dops[i].rs2,s2l);
4953       #endif
4954       int hr=0;
4955       int addr=-1,alt=-1,ntaddr=-1;
4956       while(hr<HOST_REGS)
4957       {
4958         if(hr!=EXCLUDE_REG && hr!=HOST_CCREG &&
4959            (branch_regs[i].regmap[hr]&63)!=dops[i].rs1 &&
4960            (branch_regs[i].regmap[hr]&63)!=dops[i].rs2 )
4961         {
4962           addr=hr++;break;
4963         }
4964         hr++;
4965       }
4966       while(hr<HOST_REGS)
4967       {
4968         if(hr!=EXCLUDE_REG && hr!=HOST_CCREG &&
4969            (branch_regs[i].regmap[hr]&63)!=dops[i].rs1 &&
4970            (branch_regs[i].regmap[hr]&63)!=dops[i].rs2 )
4971         {
4972           alt=hr++;break;
4973         }
4974         hr++;
4975       }
4976       if((dops[i].opcode&0x2E)==6) // BLEZ/BGTZ needs another register
4977       {
4978         while(hr<HOST_REGS)
4979         {
4980           if(hr!=EXCLUDE_REG && hr!=HOST_CCREG &&
4981              (branch_regs[i].regmap[hr]&63)!=dops[i].rs1 &&
4982              (branch_regs[i].regmap[hr]&63)!=dops[i].rs2 )
4983           {
4984             ntaddr=hr;break;
4985           }
4986           hr++;
4987         }
4988         assert(hr<HOST_REGS);
4989       }
4990       if((dops[i].opcode&0x2f)==4) // BEQ
4991       {
4992         #ifdef HAVE_CMOV_IMM
4993         if(s2l>=0) emit_cmp(s1l,s2l);
4994         else emit_test(s1l,s1l);
4995         emit_cmov2imm_e_ne_compact(ba[i],start+i*4+8,addr);
4996         #else
4997         emit_mov2imm_compact(ba[i],addr,start+i*4+8,alt);
4998         if(s2l>=0) emit_cmp(s1l,s2l);
4999         else emit_test(s1l,s1l);
5000         emit_cmovne_reg(alt,addr);
5001         #endif
5002       }
5003       if((dops[i].opcode&0x2f)==5) // BNE
5004       {
5005         #ifdef HAVE_CMOV_IMM
5006         if(s2l>=0) emit_cmp(s1l,s2l);
5007         else emit_test(s1l,s1l);
5008         emit_cmov2imm_e_ne_compact(start+i*4+8,ba[i],addr);
5009         #else
5010         emit_mov2imm_compact(start+i*4+8,addr,ba[i],alt);
5011         if(s2l>=0) emit_cmp(s1l,s2l);
5012         else emit_test(s1l,s1l);
5013         emit_cmovne_reg(alt,addr);
5014         #endif
5015       }
5016       if((dops[i].opcode&0x2f)==6) // BLEZ
5017       {
5018         //emit_movimm(ba[i],alt);
5019         //emit_movimm(start+i*4+8,addr);
5020         emit_mov2imm_compact(ba[i],alt,start+i*4+8,addr);
5021         emit_cmpimm(s1l,1);
5022         emit_cmovl_reg(alt,addr);
5023       }
5024       if((dops[i].opcode&0x2f)==7) // BGTZ
5025       {
5026         //emit_movimm(ba[i],addr);
5027         //emit_movimm(start+i*4+8,ntaddr);
5028         emit_mov2imm_compact(ba[i],addr,start+i*4+8,ntaddr);
5029         emit_cmpimm(s1l,1);
5030         emit_cmovl_reg(ntaddr,addr);
5031       }
5032       if((dops[i].opcode==1)&&(dops[i].opcode2&0x2D)==0) // BLTZ
5033       {
5034         //emit_movimm(ba[i],alt);
5035         //emit_movimm(start+i*4+8,addr);
5036         emit_mov2imm_compact(ba[i],alt,start+i*4+8,addr);
5037         emit_test(s1l,s1l);
5038         emit_cmovs_reg(alt,addr);
5039       }
5040       if((dops[i].opcode==1)&&(dops[i].opcode2&0x2D)==1) // BGEZ
5041       {
5042         //emit_movimm(ba[i],addr);
5043         //emit_movimm(start+i*4+8,alt);
5044         emit_mov2imm_compact(ba[i],addr,start+i*4+8,alt);
5045         emit_test(s1l,s1l);
5046         emit_cmovs_reg(alt,addr);
5047       }
5048       if(dops[i].opcode==0x11 && dops[i].opcode2==0x08 ) {
5049         if(source[i]&0x10000) // BC1T
5050         {
5051           //emit_movimm(ba[i],alt);
5052           //emit_movimm(start+i*4+8,addr);
5053           emit_mov2imm_compact(ba[i],alt,start+i*4+8,addr);
5054           emit_testimm(s1l,0x800000);
5055           emit_cmovne_reg(alt,addr);
5056         }
5057         else // BC1F
5058         {
5059           //emit_movimm(ba[i],addr);
5060           //emit_movimm(start+i*4+8,alt);
5061           emit_mov2imm_compact(ba[i],addr,start+i*4+8,alt);
5062           emit_testimm(s1l,0x800000);
5063           emit_cmovne_reg(alt,addr);
5064         }
5065       }
5066       emit_writeword(addr,&pcaddr);
5067     }
5068     else
5069     if(dops[i].itype==RJUMP)
5070     {
5071       int r=get_reg(branch_regs[i].regmap,dops[i].rs1);
5072       if (ds_writes_rjump_rs(i)) {
5073         r=get_reg(branch_regs[i].regmap,RTEMP);
5074       }
5075       emit_writeword(r,&pcaddr);
5076     }
5077     else {SysPrintf("Unknown branch type in do_ccstub\n");abort();}
5078   }
5079   // Update cycle count
5080   assert(branch_regs[i].regmap[HOST_CCREG]==CCREG||branch_regs[i].regmap[HOST_CCREG]==-1);
5081   if(stubs[n].a) emit_addimm(HOST_CCREG,(int)stubs[n].a,HOST_CCREG);
5082   emit_far_call(cc_interrupt);
5083   if(stubs[n].a) emit_addimm(HOST_CCREG,-(int)stubs[n].a,HOST_CCREG);
5084   if(stubs[n].d==TAKEN) {
5085     if(internal_branch(ba[i]))
5086       load_needed_regs(branch_regs[i].regmap,regs[(ba[i]-start)>>2].regmap_entry);
5087     else if(dops[i].itype==RJUMP) {
5088       if(get_reg(branch_regs[i].regmap,RTEMP)>=0)
5089         emit_readword(&pcaddr,get_reg(branch_regs[i].regmap,RTEMP));
5090       else
5091         emit_loadreg(dops[i].rs1,get_reg(branch_regs[i].regmap,dops[i].rs1));
5092     }
5093   }else if(stubs[n].d==NOTTAKEN) {
5094     if(i<slen-2) load_needed_regs(branch_regs[i].regmap,regmap_pre[i+2]);
5095     else load_all_regs(branch_regs[i].regmap);
5096   }else if(stubs[n].d==NULLDS) {
5097     // Delay slot instruction is nullified ("likely" branch)
5098     if(i<slen-2) load_needed_regs(regs[i].regmap,regmap_pre[i+2]);
5099     else load_all_regs(regs[i].regmap);
5100   }else{
5101     load_all_regs(branch_regs[i].regmap);
5102   }
5103   if (stubs[n].retaddr)
5104     emit_jmp(stubs[n].retaddr);
5105   else
5106     do_jump_vaddr(stubs[n].e);
5107 }
5108
5109 static void add_to_linker(void *addr, u_int target, int ext)
5110 {
5111   assert(linkcount < ARRAY_SIZE(link_addr));
5112   link_addr[linkcount].addr = addr;
5113   link_addr[linkcount].target = target;
5114   link_addr[linkcount].ext = ext;
5115   linkcount++;
5116 }
5117
5118 static void ujump_assemble_write_ra(int i)
5119 {
5120   int rt;
5121   unsigned int return_address;
5122   rt=get_reg(branch_regs[i].regmap,31);
5123   assem_debug("branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d\n",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]);
5124   //assert(rt>=0);
5125   return_address=start+i*4+8;
5126   if(rt>=0) {
5127     #ifdef USE_MINI_HT
5128     if(internal_branch(return_address)&&dops[i+1].rt1!=31) {
5129       int temp=-1; // note: must be ds-safe
5130       #ifdef HOST_TEMPREG
5131       temp=HOST_TEMPREG;
5132       #endif
5133       if(temp>=0) do_miniht_insert(return_address,rt,temp);
5134       else emit_movimm(return_address,rt);
5135     }
5136     else
5137     #endif
5138     {
5139       #ifdef REG_PREFETCH
5140       if(temp>=0)
5141       {
5142         if(i_regmap[temp]!=PTEMP) emit_movimm((uintptr_t)hash_table_get(return_address),temp);
5143       }
5144       #endif
5145       emit_movimm(return_address,rt); // PC into link register
5146       #ifdef IMM_PREFETCH
5147       emit_prefetch(hash_table_get(return_address));
5148       #endif
5149     }
5150   }
5151 }
5152
5153 static void ujump_assemble(int i, const struct regstat *i_regs)
5154 {
5155   int ra_done=0;
5156   if(i==(ba[i]-start)>>2) assem_debug("idle loop\n");
5157   address_generation(i+1,i_regs,regs[i].regmap_entry);
5158   #ifdef REG_PREFETCH
5159   int temp=get_reg(branch_regs[i].regmap,PTEMP);
5160   if(dops[i].rt1==31&&temp>=0)
5161   {
5162     signed char *i_regmap=i_regs->regmap;
5163     int return_address=start+i*4+8;
5164     if(get_reg(branch_regs[i].regmap,31)>0)
5165     if(i_regmap[temp]==PTEMP) emit_movimm((uintptr_t)hash_table_get(return_address),temp);
5166   }
5167   #endif
5168   if(dops[i].rt1==31&&(dops[i].rt1==dops[i+1].rs1||dops[i].rt1==dops[i+1].rs2)) {
5169     ujump_assemble_write_ra(i); // writeback ra for DS
5170     ra_done=1;
5171   }
5172   ds_assemble(i+1,i_regs);
5173   uint64_t bc_unneeded=branch_regs[i].u;
5174   bc_unneeded|=1|(1LL<<dops[i].rt1);
5175   wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,bc_unneeded);
5176   load_regs(regs[i].regmap,branch_regs[i].regmap,CCREG,CCREG);
5177   if(!ra_done&&dops[i].rt1==31)
5178     ujump_assemble_write_ra(i);
5179   int cc,adj;
5180   cc=get_reg(branch_regs[i].regmap,CCREG);
5181   assert(cc==HOST_CCREG);
5182   store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5183   #ifdef REG_PREFETCH
5184   if(dops[i].rt1==31&&temp>=0) emit_prefetchreg(temp);
5185   #endif
5186   do_cc(i,branch_regs[i].regmap,&adj,ba[i],TAKEN,0);
5187   if(adj) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5188   load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5189   if(internal_branch(ba[i]))
5190     assem_debug("branch: internal\n");
5191   else
5192     assem_debug("branch: external\n");
5193   if (internal_branch(ba[i]) && dops[(ba[i]-start)>>2].is_ds) {
5194     ds_assemble_entry(i);
5195   }
5196   else {
5197     add_to_linker(out,ba[i],internal_branch(ba[i]));
5198     emit_jmp(0);
5199   }
5200 }
5201
5202 static void rjump_assemble_write_ra(int i)
5203 {
5204   int rt,return_address;
5205   assert(dops[i+1].rt1!=dops[i].rt1);
5206   assert(dops[i+1].rt2!=dops[i].rt1);
5207   rt=get_reg(branch_regs[i].regmap,dops[i].rt1);
5208   assem_debug("branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d\n",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]);
5209   assert(rt>=0);
5210   return_address=start+i*4+8;
5211   #ifdef REG_PREFETCH
5212   if(temp>=0)
5213   {
5214     if(i_regmap[temp]!=PTEMP) emit_movimm((uintptr_t)hash_table_get(return_address),temp);
5215   }
5216   #endif
5217   emit_movimm(return_address,rt); // PC into link register
5218   #ifdef IMM_PREFETCH
5219   emit_prefetch(hash_table_get(return_address));
5220   #endif
5221 }
5222
5223 static void rjump_assemble(int i, const struct regstat *i_regs)
5224 {
5225   int temp;
5226   int rs,cc;
5227   int ra_done=0;
5228   rs=get_reg(branch_regs[i].regmap,dops[i].rs1);
5229   assert(rs>=0);
5230   if (ds_writes_rjump_rs(i)) {
5231     // Delay slot abuse, make a copy of the branch address register
5232     temp=get_reg(branch_regs[i].regmap,RTEMP);
5233     assert(temp>=0);
5234     assert(regs[i].regmap[temp]==RTEMP);
5235     emit_mov(rs,temp);
5236     rs=temp;
5237   }
5238   address_generation(i+1,i_regs,regs[i].regmap_entry);
5239   #ifdef REG_PREFETCH
5240   if(dops[i].rt1==31)
5241   {
5242     if((temp=get_reg(branch_regs[i].regmap,PTEMP))>=0) {
5243       signed char *i_regmap=i_regs->regmap;
5244       int return_address=start+i*4+8;
5245       if(i_regmap[temp]==PTEMP) emit_movimm((uintptr_t)hash_table_get(return_address),temp);
5246     }
5247   }
5248   #endif
5249   #ifdef USE_MINI_HT
5250   if(dops[i].rs1==31) {
5251     int rh=get_reg(regs[i].regmap,RHASH);
5252     if(rh>=0) do_preload_rhash(rh);
5253   }
5254   #endif
5255   if(dops[i].rt1!=0&&(dops[i].rt1==dops[i+1].rs1||dops[i].rt1==dops[i+1].rs2)) {
5256     rjump_assemble_write_ra(i);
5257     ra_done=1;
5258   }
5259   ds_assemble(i+1,i_regs);
5260   uint64_t bc_unneeded=branch_regs[i].u;
5261   bc_unneeded|=1|(1LL<<dops[i].rt1);
5262   bc_unneeded&=~(1LL<<dops[i].rs1);
5263   wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,bc_unneeded);
5264   load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i].rs1,CCREG);
5265   if(!ra_done&&dops[i].rt1!=0)
5266     rjump_assemble_write_ra(i);
5267   cc=get_reg(branch_regs[i].regmap,CCREG);
5268   assert(cc==HOST_CCREG);
5269   (void)cc;
5270   #ifdef USE_MINI_HT
5271   int rh=get_reg(branch_regs[i].regmap,RHASH);
5272   int ht=get_reg(branch_regs[i].regmap,RHTBL);
5273   if(dops[i].rs1==31) {
5274     if(regs[i].regmap[rh]!=RHASH) do_preload_rhash(rh);
5275     do_preload_rhtbl(ht);
5276     do_rhash(rs,rh);
5277   }
5278   #endif
5279   store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,-1);
5280   #ifdef DESTRUCTIVE_WRITEBACK
5281   if((branch_regs[i].dirty>>rs)&1) {
5282     if(dops[i].rs1!=dops[i+1].rt1&&dops[i].rs1!=dops[i+1].rt2) {
5283       emit_loadreg(dops[i].rs1,rs);
5284     }
5285   }
5286   #endif
5287   #ifdef REG_PREFETCH
5288   if(dops[i].rt1==31&&temp>=0) emit_prefetchreg(temp);
5289   #endif
5290   #ifdef USE_MINI_HT
5291   if(dops[i].rs1==31) {
5292     do_miniht_load(ht,rh);
5293   }
5294   #endif
5295   //do_cc(i,branch_regs[i].regmap,&adj,-1,TAKEN);
5296   //if(adj) emit_addimm(cc,2*(ccadj[i]+2-adj),cc); // ??? - Shouldn't happen
5297   //assert(adj==0);
5298   emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), HOST_CCREG);
5299   add_stub(CC_STUB,out,NULL,0,i,-1,TAKEN,rs);
5300   if(dops[i+1].itype==COP0&&(source[i+1]&0x3f)==0x10)
5301     // special case for RFE
5302     emit_jmp(0);
5303   else
5304     emit_jns(0);
5305   //load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,-1);
5306   #ifdef USE_MINI_HT
5307   if(dops[i].rs1==31) {
5308     do_miniht_jump(rs,rh,ht);
5309   }
5310   else
5311   #endif
5312   {
5313     do_jump_vaddr(rs);
5314   }
5315   #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5316   if(dops[i].rt1!=31&&i<slen-2&&(((u_int)out)&7)) emit_mov(13,13);
5317   #endif
5318 }
5319
5320 static void cjump_assemble(int i, const struct regstat *i_regs)
5321 {
5322   const signed char *i_regmap = i_regs->regmap;
5323   int cc;
5324   int match;
5325   match=match_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5326   assem_debug("match=%d\n",match);
5327   int s1l,s2l;
5328   int unconditional=0,nop=0;
5329   int invert=0;
5330   int internal=internal_branch(ba[i]);
5331   if(i==(ba[i]-start)>>2) assem_debug("idle loop\n");
5332   if(!match) invert=1;
5333   #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5334   if(i>(ba[i]-start)>>2) invert=1;
5335   #endif
5336   #ifdef __aarch64__
5337   invert=1; // because of near cond. branches
5338   #endif
5339
5340   if(dops[i].ooo) {
5341     s1l=get_reg(branch_regs[i].regmap,dops[i].rs1);
5342     s2l=get_reg(branch_regs[i].regmap,dops[i].rs2);
5343   }
5344   else {
5345     s1l=get_reg(i_regmap,dops[i].rs1);
5346     s2l=get_reg(i_regmap,dops[i].rs2);
5347   }
5348   if(dops[i].rs1==0&&dops[i].rs2==0)
5349   {
5350     if(dops[i].opcode&1) nop=1;
5351     else unconditional=1;
5352     //assert(dops[i].opcode!=5);
5353     //assert(dops[i].opcode!=7);
5354     //assert(dops[i].opcode!=0x15);
5355     //assert(dops[i].opcode!=0x17);
5356   }
5357   else if(dops[i].rs1==0)
5358   {
5359     s1l=s2l;
5360     s2l=-1;
5361   }
5362   else if(dops[i].rs2==0)
5363   {
5364     s2l=-1;
5365   }
5366
5367   if(dops[i].ooo) {
5368     // Out of order execution (delay slot first)
5369     //printf("OOOE\n");
5370     address_generation(i+1,i_regs,regs[i].regmap_entry);
5371     ds_assemble(i+1,i_regs);
5372     int adj;
5373     uint64_t bc_unneeded=branch_regs[i].u;
5374     bc_unneeded&=~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
5375     bc_unneeded|=1;
5376     wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,bc_unneeded);
5377     load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i].rs1,dops[i].rs2);
5378     load_regs(regs[i].regmap,branch_regs[i].regmap,CCREG,CCREG);
5379     cc=get_reg(branch_regs[i].regmap,CCREG);
5380     assert(cc==HOST_CCREG);
5381     if(unconditional)
5382       store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5383     //do_cc(i,branch_regs[i].regmap,&adj,unconditional?ba[i]:-1,unconditional);
5384     //assem_debug("cycle count (adj)\n");
5385     if(unconditional) {
5386       do_cc(i,branch_regs[i].regmap,&adj,ba[i],TAKEN,0);
5387       if(i!=(ba[i]-start)>>2 || source[i+1]!=0) {
5388         if(adj) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5389         load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5390         if(internal)
5391           assem_debug("branch: internal\n");
5392         else
5393           assem_debug("branch: external\n");
5394         if (internal && dops[(ba[i]-start)>>2].is_ds) {
5395           ds_assemble_entry(i);
5396         }
5397         else {
5398           add_to_linker(out,ba[i],internal);
5399           emit_jmp(0);
5400         }
5401         #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5402         if(((u_int)out)&7) emit_addnop(0);
5403         #endif
5404       }
5405     }
5406     else if(nop) {
5407       emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), cc);
5408       void *jaddr=out;
5409       emit_jns(0);
5410       add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
5411     }
5412     else {
5413       void *taken = NULL, *nottaken = NULL, *nottaken1 = NULL;
5414       do_cc(i,branch_regs[i].regmap,&adj,-1,0,invert);
5415       if(adj&&!invert) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5416
5417       //printf("branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d\n",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]);
5418       assert(s1l>=0);
5419       if(dops[i].opcode==4) // BEQ
5420       {
5421         if(s2l>=0) emit_cmp(s1l,s2l);
5422         else emit_test(s1l,s1l);
5423         if(invert){
5424           nottaken=out;
5425           emit_jne(DJT_1);
5426         }else{
5427           add_to_linker(out,ba[i],internal);
5428           emit_jeq(0);
5429         }
5430       }
5431       if(dops[i].opcode==5) // BNE
5432       {
5433         if(s2l>=0) emit_cmp(s1l,s2l);
5434         else emit_test(s1l,s1l);
5435         if(invert){
5436           nottaken=out;
5437           emit_jeq(DJT_1);
5438         }else{
5439           add_to_linker(out,ba[i],internal);
5440           emit_jne(0);
5441         }
5442       }
5443       if(dops[i].opcode==6) // BLEZ
5444       {
5445         emit_cmpimm(s1l,1);
5446         if(invert){
5447           nottaken=out;
5448           emit_jge(DJT_1);
5449         }else{
5450           add_to_linker(out,ba[i],internal);
5451           emit_jl(0);
5452         }
5453       }
5454       if(dops[i].opcode==7) // BGTZ
5455       {
5456         emit_cmpimm(s1l,1);
5457         if(invert){
5458           nottaken=out;
5459           emit_jl(DJT_1);
5460         }else{
5461           add_to_linker(out,ba[i],internal);
5462           emit_jge(0);
5463         }
5464       }
5465       if(invert) {
5466         if(taken) set_jump_target(taken, out);
5467         #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5468         if (match && (!internal || !dops[(ba[i]-start)>>2].is_ds)) {
5469           if(adj) {
5470             emit_addimm(cc,-adj,cc);
5471             add_to_linker(out,ba[i],internal);
5472           }else{
5473             emit_addnop(13);
5474             add_to_linker(out,ba[i],internal*2);
5475           }
5476           emit_jmp(0);
5477         }else
5478         #endif
5479         {
5480           if(adj) emit_addimm(cc,-adj,cc);
5481           store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5482           load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5483           if(internal)
5484             assem_debug("branch: internal\n");
5485           else
5486             assem_debug("branch: external\n");
5487           if (internal && dops[(ba[i] - start) >> 2].is_ds) {
5488             ds_assemble_entry(i);
5489           }
5490           else {
5491             add_to_linker(out,ba[i],internal);
5492             emit_jmp(0);
5493           }
5494         }
5495         set_jump_target(nottaken, out);
5496       }
5497
5498       if(nottaken1) set_jump_target(nottaken1, out);
5499       if(adj) {
5500         if(!invert) emit_addimm(cc,adj,cc);
5501       }
5502     } // (!unconditional)
5503   } // if(ooo)
5504   else
5505   {
5506     // In-order execution (branch first)
5507     void *taken = NULL, *nottaken = NULL, *nottaken1 = NULL;
5508     if(!unconditional&&!nop) {
5509       //printf("branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d\n",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]);
5510       assert(s1l>=0);
5511       if((dops[i].opcode&0x2f)==4) // BEQ
5512       {
5513         if(s2l>=0) emit_cmp(s1l,s2l);
5514         else emit_test(s1l,s1l);
5515         nottaken=out;
5516         emit_jne(DJT_2);
5517       }
5518       if((dops[i].opcode&0x2f)==5) // BNE
5519       {
5520         if(s2l>=0) emit_cmp(s1l,s2l);
5521         else emit_test(s1l,s1l);
5522         nottaken=out;
5523         emit_jeq(DJT_2);
5524       }
5525       if((dops[i].opcode&0x2f)==6) // BLEZ
5526       {
5527         emit_cmpimm(s1l,1);
5528         nottaken=out;
5529         emit_jge(DJT_2);
5530       }
5531       if((dops[i].opcode&0x2f)==7) // BGTZ
5532       {
5533         emit_cmpimm(s1l,1);
5534         nottaken=out;
5535         emit_jl(DJT_2);
5536       }
5537     } // if(!unconditional)
5538     int adj;
5539     uint64_t ds_unneeded=branch_regs[i].u;
5540     ds_unneeded&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
5541     ds_unneeded|=1;
5542     // branch taken
5543     if(!nop) {
5544       if(taken) set_jump_target(taken, out);
5545       assem_debug("1:\n");
5546       wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,ds_unneeded);
5547       // load regs
5548       load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i+1].rs1,dops[i+1].rs2);
5549       address_generation(i+1,&branch_regs[i],0);
5550       if (ram_offset)
5551         load_regs(regs[i].regmap,branch_regs[i].regmap,ROREG,ROREG);
5552       load_regs(regs[i].regmap,branch_regs[i].regmap,CCREG,INVCP);
5553       ds_assemble(i+1,&branch_regs[i]);
5554       cc=get_reg(branch_regs[i].regmap,CCREG);
5555       if(cc==-1) {
5556         emit_loadreg(CCREG,cc=HOST_CCREG);
5557         // CHECK: Is the following instruction (fall thru) allocated ok?
5558       }
5559       assert(cc==HOST_CCREG);
5560       store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5561       do_cc(i,i_regmap,&adj,ba[i],TAKEN,0);
5562       assem_debug("cycle count (adj)\n");
5563       if(adj) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5564       load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5565       if(internal)
5566         assem_debug("branch: internal\n");
5567       else
5568         assem_debug("branch: external\n");
5569       if (internal && dops[(ba[i] - start) >> 2].is_ds) {
5570         ds_assemble_entry(i);
5571       }
5572       else {
5573         add_to_linker(out,ba[i],internal);
5574         emit_jmp(0);
5575       }
5576     }
5577     // branch not taken
5578     if(!unconditional) {
5579       if(nottaken1) set_jump_target(nottaken1, out);
5580       set_jump_target(nottaken, out);
5581       assem_debug("2:\n");
5582       wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,ds_unneeded);
5583       // load regs
5584       load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i+1].rs1,dops[i+1].rs2);
5585       address_generation(i+1,&branch_regs[i],0);
5586       if (ram_offset)
5587         load_regs(regs[i].regmap,branch_regs[i].regmap,ROREG,ROREG);
5588       load_regs(regs[i].regmap,branch_regs[i].regmap,CCREG,INVCP);
5589       ds_assemble(i+1,&branch_regs[i]);
5590       cc=get_reg(branch_regs[i].regmap,CCREG);
5591       if (cc == -1) {
5592         // Cycle count isn't in a register, temporarily load it then write it out
5593         emit_loadreg(CCREG,HOST_CCREG);
5594         emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), HOST_CCREG);
5595         void *jaddr=out;
5596         emit_jns(0);
5597         add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
5598         emit_storereg(CCREG,HOST_CCREG);
5599       }
5600       else{
5601         cc=get_reg(i_regmap,CCREG);
5602         assert(cc==HOST_CCREG);
5603         emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), cc);
5604         void *jaddr=out;
5605         emit_jns(0);
5606         add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
5607       }
5608     }
5609   }
5610 }
5611
5612 static void sjump_assemble(int i, const struct regstat *i_regs)
5613 {
5614   const signed char *i_regmap = i_regs->regmap;
5615   int cc;
5616   int match;
5617   match=match_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5618   assem_debug("smatch=%d\n",match);
5619   int s1l;
5620   int unconditional=0,nevertaken=0;
5621   int invert=0;
5622   int internal=internal_branch(ba[i]);
5623   if(i==(ba[i]-start)>>2) assem_debug("idle loop\n");
5624   if(!match) invert=1;
5625   #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5626   if(i>(ba[i]-start)>>2) invert=1;
5627   #endif
5628   #ifdef __aarch64__
5629   invert=1; // because of near cond. branches
5630   #endif
5631
5632   //if(dops[i].opcode2>=0x10) return; // FIXME (BxxZAL)
5633   //assert(dops[i].opcode2<0x10||dops[i].rs1==0); // FIXME (BxxZAL)
5634
5635   if(dops[i].ooo) {
5636     s1l=get_reg(branch_regs[i].regmap,dops[i].rs1);
5637   }
5638   else {
5639     s1l=get_reg(i_regmap,dops[i].rs1);
5640   }
5641   if(dops[i].rs1==0)
5642   {
5643     if(dops[i].opcode2&1) unconditional=1;
5644     else nevertaken=1;
5645     // These are never taken (r0 is never less than zero)
5646     //assert(dops[i].opcode2!=0);
5647     //assert(dops[i].opcode2!=2);
5648     //assert(dops[i].opcode2!=0x10);
5649     //assert(dops[i].opcode2!=0x12);
5650   }
5651
5652   if(dops[i].ooo) {
5653     // Out of order execution (delay slot first)
5654     //printf("OOOE\n");
5655     address_generation(i+1,i_regs,regs[i].regmap_entry);
5656     ds_assemble(i+1,i_regs);
5657     int adj;
5658     uint64_t bc_unneeded=branch_regs[i].u;
5659     bc_unneeded&=~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
5660     bc_unneeded|=1;
5661     wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,bc_unneeded);
5662     load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i].rs1,dops[i].rs1);
5663     load_regs(regs[i].regmap,branch_regs[i].regmap,CCREG,CCREG);
5664     if(dops[i].rt1==31) {
5665       int rt,return_address;
5666       rt=get_reg(branch_regs[i].regmap,31);
5667       assem_debug("branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d\n",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]);
5668       if(rt>=0) {
5669         // Save the PC even if the branch is not taken
5670         return_address=start+i*4+8;
5671         emit_movimm(return_address,rt); // PC into link register
5672         #ifdef IMM_PREFETCH
5673         if(!nevertaken) emit_prefetch(hash_table_get(return_address));
5674         #endif
5675       }
5676     }
5677     cc=get_reg(branch_regs[i].regmap,CCREG);
5678     assert(cc==HOST_CCREG);
5679     if(unconditional)
5680       store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5681     //do_cc(i,branch_regs[i].regmap,&adj,unconditional?ba[i]:-1,unconditional);
5682     assem_debug("cycle count (adj)\n");
5683     if(unconditional) {
5684       do_cc(i,branch_regs[i].regmap,&adj,ba[i],TAKEN,0);
5685       if(i!=(ba[i]-start)>>2 || source[i+1]!=0) {
5686         if(adj) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5687         load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5688         if(internal)
5689           assem_debug("branch: internal\n");
5690         else
5691           assem_debug("branch: external\n");
5692         if (internal && dops[(ba[i] - start) >> 2].is_ds) {
5693           ds_assemble_entry(i);
5694         }
5695         else {
5696           add_to_linker(out,ba[i],internal);
5697           emit_jmp(0);
5698         }
5699         #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5700         if(((u_int)out)&7) emit_addnop(0);
5701         #endif
5702       }
5703     }
5704     else if(nevertaken) {
5705       emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), cc);
5706       void *jaddr=out;
5707       emit_jns(0);
5708       add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
5709     }
5710     else {
5711       void *nottaken = NULL;
5712       do_cc(i,branch_regs[i].regmap,&adj,-1,0,invert);
5713       if(adj&&!invert) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5714       {
5715         assert(s1l>=0);
5716         if((dops[i].opcode2&0xf)==0) // BLTZ/BLTZAL
5717         {
5718           emit_test(s1l,s1l);
5719           if(invert){
5720             nottaken=out;
5721             emit_jns(DJT_1);
5722           }else{
5723             add_to_linker(out,ba[i],internal);
5724             emit_js(0);
5725           }
5726         }
5727         if((dops[i].opcode2&0xf)==1) // BGEZ/BLTZAL
5728         {
5729           emit_test(s1l,s1l);
5730           if(invert){
5731             nottaken=out;
5732             emit_js(DJT_1);
5733           }else{
5734             add_to_linker(out,ba[i],internal);
5735             emit_jns(0);
5736           }
5737         }
5738       }
5739
5740       if(invert) {
5741         #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5742         if (match && (!internal || !dops[(ba[i] - start) >> 2].is_ds)) {
5743           if(adj) {
5744             emit_addimm(cc,-adj,cc);
5745             add_to_linker(out,ba[i],internal);
5746           }else{
5747             emit_addnop(13);
5748             add_to_linker(out,ba[i],internal*2);
5749           }
5750           emit_jmp(0);
5751         }else
5752         #endif
5753         {
5754           if(adj) emit_addimm(cc,-adj,cc);
5755           store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5756           load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5757           if(internal)
5758             assem_debug("branch: internal\n");
5759           else
5760             assem_debug("branch: external\n");
5761           if (internal && dops[(ba[i] - start) >> 2].is_ds) {
5762             ds_assemble_entry(i);
5763           }
5764           else {
5765             add_to_linker(out,ba[i],internal);
5766             emit_jmp(0);
5767           }
5768         }
5769         set_jump_target(nottaken, out);
5770       }
5771
5772       if(adj) {
5773         if(!invert) emit_addimm(cc,adj,cc);
5774       }
5775     } // (!unconditional)
5776   } // if(ooo)
5777   else
5778   {
5779     // In-order execution (branch first)
5780     //printf("IOE\n");
5781     void *nottaken = NULL;
5782     if(dops[i].rt1==31) {
5783       int rt,return_address;
5784       rt=get_reg(branch_regs[i].regmap,31);
5785       if(rt>=0) {
5786         // Save the PC even if the branch is not taken
5787         return_address=start+i*4+8;
5788         emit_movimm(return_address,rt); // PC into link register
5789         #ifdef IMM_PREFETCH
5790         emit_prefetch(hash_table_get(return_address));
5791         #endif
5792       }
5793     }
5794     if(!unconditional) {
5795       //printf("branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d\n",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]);
5796         assert(s1l>=0);
5797         if((dops[i].opcode2&0x0d)==0) // BLTZ/BLTZL/BLTZAL/BLTZALL
5798         {
5799           emit_test(s1l,s1l);
5800           nottaken=out;
5801           emit_jns(DJT_1);
5802         }
5803         if((dops[i].opcode2&0x0d)==1) // BGEZ/BGEZL/BGEZAL/BGEZALL
5804         {
5805           emit_test(s1l,s1l);
5806           nottaken=out;
5807           emit_js(DJT_1);
5808         }
5809     } // if(!unconditional)
5810     int adj;
5811     uint64_t ds_unneeded=branch_regs[i].u;
5812     ds_unneeded&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
5813     ds_unneeded|=1;
5814     // branch taken
5815     if(!nevertaken) {
5816       //assem_debug("1:\n");
5817       wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,ds_unneeded);
5818       // load regs
5819       load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i+1].rs1,dops[i+1].rs2);
5820       address_generation(i+1,&branch_regs[i],0);
5821       if (ram_offset)
5822         load_regs(regs[i].regmap,branch_regs[i].regmap,ROREG,ROREG);
5823       load_regs(regs[i].regmap,branch_regs[i].regmap,CCREG,INVCP);
5824       ds_assemble(i+1,&branch_regs[i]);
5825       cc=get_reg(branch_regs[i].regmap,CCREG);
5826       if(cc==-1) {
5827         emit_loadreg(CCREG,cc=HOST_CCREG);
5828         // CHECK: Is the following instruction (fall thru) allocated ok?
5829       }
5830       assert(cc==HOST_CCREG);
5831       store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5832       do_cc(i,i_regmap,&adj,ba[i],TAKEN,0);
5833       assem_debug("cycle count (adj)\n");
5834       if(adj) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5835       load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5836       if(internal)
5837         assem_debug("branch: internal\n");
5838       else
5839         assem_debug("branch: external\n");
5840       if (internal && dops[(ba[i] - start) >> 2].is_ds) {
5841         ds_assemble_entry(i);
5842       }
5843       else {
5844         add_to_linker(out,ba[i],internal);
5845         emit_jmp(0);
5846       }
5847     }
5848     // branch not taken
5849     if(!unconditional) {
5850       set_jump_target(nottaken, out);
5851       assem_debug("1:\n");
5852       wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,ds_unneeded);
5853       load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i+1].rs1,dops[i+1].rs2);
5854       address_generation(i+1,&branch_regs[i],0);
5855       load_regs(regs[i].regmap,branch_regs[i].regmap,CCREG,CCREG);
5856       ds_assemble(i+1,&branch_regs[i]);
5857       cc=get_reg(branch_regs[i].regmap,CCREG);
5858       if (cc == -1) {
5859         // Cycle count isn't in a register, temporarily load it then write it out
5860         emit_loadreg(CCREG,HOST_CCREG);
5861         emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), HOST_CCREG);
5862         void *jaddr=out;
5863         emit_jns(0);
5864         add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
5865         emit_storereg(CCREG,HOST_CCREG);
5866       }
5867       else{
5868         cc=get_reg(i_regmap,CCREG);
5869         assert(cc==HOST_CCREG);
5870         emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), cc);
5871         void *jaddr=out;
5872         emit_jns(0);
5873         add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
5874       }
5875     }
5876   }
5877 }
5878
5879 static void pagespan_assemble(int i, const struct regstat *i_regs)
5880 {
5881   int s1l=get_reg(i_regs->regmap,dops[i].rs1);
5882   int s2l=get_reg(i_regs->regmap,dops[i].rs2);
5883   void *taken = NULL;
5884   void *nottaken = NULL;
5885   int unconditional=0;
5886   if(dops[i].rs1==0)
5887   {
5888     s1l=s2l;
5889     s2l=-1;
5890   }
5891   else if(dops[i].rs2==0)
5892   {
5893     s2l=-1;
5894   }
5895   int hr=0;
5896   int addr=-1,alt=-1,ntaddr=-1;
5897   if(i_regs->regmap[HOST_BTREG]<0) {addr=HOST_BTREG;}
5898   else {
5899     while(hr<HOST_REGS)
5900     {
5901       if(hr!=EXCLUDE_REG && hr!=HOST_CCREG &&
5902          (i_regs->regmap[hr]&63)!=dops[i].rs1 &&
5903          (i_regs->regmap[hr]&63)!=dops[i].rs2 )
5904       {
5905         addr=hr++;break;
5906       }
5907       hr++;
5908     }
5909   }
5910   while(hr<HOST_REGS)
5911   {
5912     if(hr!=EXCLUDE_REG && hr!=HOST_CCREG && hr!=HOST_BTREG &&
5913        (i_regs->regmap[hr]&63)!=dops[i].rs1 &&
5914        (i_regs->regmap[hr]&63)!=dops[i].rs2 )
5915     {
5916       alt=hr++;break;
5917     }
5918     hr++;
5919   }
5920   if((dops[i].opcode&0x2E)==6) // BLEZ/BGTZ needs another register
5921   {
5922     while(hr<HOST_REGS)
5923     {
5924       if(hr!=EXCLUDE_REG && hr!=HOST_CCREG && hr!=HOST_BTREG &&
5925          (i_regs->regmap[hr]&63)!=dops[i].rs1 &&
5926          (i_regs->regmap[hr]&63)!=dops[i].rs2 )
5927       {
5928         ntaddr=hr;break;
5929       }
5930       hr++;
5931     }
5932   }
5933   assert(hr<HOST_REGS);
5934   if((dops[i].opcode&0x2e)==4||dops[i].opcode==0x11) { // BEQ/BNE/BEQL/BNEL/BC1
5935     load_regs(regs[i].regmap_entry,regs[i].regmap,CCREG,CCREG);
5936   }
5937   emit_addimm(HOST_CCREG, ccadj[i] + CLOCK_ADJUST(2), HOST_CCREG);
5938   if(dops[i].opcode==2) // J
5939   {
5940     unconditional=1;
5941   }
5942   if(dops[i].opcode==3) // JAL
5943   {
5944     // TODO: mini_ht
5945     int rt=get_reg(i_regs->regmap,31);
5946     emit_movimm(start+i*4+8,rt);
5947     unconditional=1;
5948   }
5949   if(dops[i].opcode==0&&(dops[i].opcode2&0x3E)==8) // JR/JALR
5950   {
5951     emit_mov(s1l,addr);
5952     if(dops[i].opcode2==9) // JALR
5953     {
5954       int rt=get_reg(i_regs->regmap,dops[i].rt1);
5955       emit_movimm(start+i*4+8,rt);
5956     }
5957   }
5958   if((dops[i].opcode&0x3f)==4) // BEQ
5959   {
5960     if(dops[i].rs1==dops[i].rs2)
5961     {
5962       unconditional=1;
5963     }
5964     else
5965     #ifdef HAVE_CMOV_IMM
5966     if(1) {
5967       if(s2l>=0) emit_cmp(s1l,s2l);
5968       else emit_test(s1l,s1l);
5969       emit_cmov2imm_e_ne_compact(ba[i],start+i*4+8,addr);
5970     }
5971     else
5972     #endif
5973     {
5974       assert(s1l>=0);
5975       emit_mov2imm_compact(ba[i],addr,start+i*4+8,alt);
5976       if(s2l>=0) emit_cmp(s1l,s2l);
5977       else emit_test(s1l,s1l);
5978       emit_cmovne_reg(alt,addr);
5979     }
5980   }
5981   if((dops[i].opcode&0x3f)==5) // BNE
5982   {
5983     #ifdef HAVE_CMOV_IMM
5984     if(s2l>=0) emit_cmp(s1l,s2l);
5985     else emit_test(s1l,s1l);
5986     emit_cmov2imm_e_ne_compact(start+i*4+8,ba[i],addr);
5987     #else
5988     assert(s1l>=0);
5989     emit_mov2imm_compact(start+i*4+8,addr,ba[i],alt);
5990     if(s2l>=0) emit_cmp(s1l,s2l);
5991     else emit_test(s1l,s1l);
5992     emit_cmovne_reg(alt,addr);
5993     #endif
5994   }
5995   if((dops[i].opcode&0x3f)==0x14) // BEQL
5996   {
5997     if(s2l>=0) emit_cmp(s1l,s2l);
5998     else emit_test(s1l,s1l);
5999     if(nottaken) set_jump_target(nottaken, out);
6000     nottaken=out;
6001     emit_jne(0);
6002   }
6003   if((dops[i].opcode&0x3f)==0x15) // BNEL
6004   {
6005     if(s2l>=0) emit_cmp(s1l,s2l);
6006     else emit_test(s1l,s1l);
6007     nottaken=out;
6008     emit_jeq(0);
6009     if(taken) set_jump_target(taken, out);
6010   }
6011   if((dops[i].opcode&0x3f)==6) // BLEZ
6012   {
6013     emit_mov2imm_compact(ba[i],alt,start+i*4+8,addr);
6014     emit_cmpimm(s1l,1);
6015     emit_cmovl_reg(alt,addr);
6016   }
6017   if((dops[i].opcode&0x3f)==7) // BGTZ
6018   {
6019     emit_mov2imm_compact(ba[i],addr,start+i*4+8,ntaddr);
6020     emit_cmpimm(s1l,1);
6021     emit_cmovl_reg(ntaddr,addr);
6022   }
6023   if((dops[i].opcode&0x3f)==0x16) // BLEZL
6024   {
6025     assert((dops[i].opcode&0x3f)!=0x16);
6026   }
6027   if((dops[i].opcode&0x3f)==0x17) // BGTZL
6028   {
6029     assert((dops[i].opcode&0x3f)!=0x17);
6030   }
6031   assert(dops[i].opcode!=1); // BLTZ/BGEZ
6032
6033   //FIXME: Check CSREG
6034   if(dops[i].opcode==0x11 && dops[i].opcode2==0x08 ) {
6035     if((source[i]&0x30000)==0) // BC1F
6036     {
6037       emit_mov2imm_compact(ba[i],addr,start+i*4+8,alt);
6038       emit_testimm(s1l,0x800000);
6039       emit_cmovne_reg(alt,addr);
6040     }
6041     if((source[i]&0x30000)==0x10000) // BC1T
6042     {
6043       emit_mov2imm_compact(ba[i],alt,start+i*4+8,addr);
6044       emit_testimm(s1l,0x800000);
6045       emit_cmovne_reg(alt,addr);
6046     }
6047     if((source[i]&0x30000)==0x20000) // BC1FL
6048     {
6049       emit_testimm(s1l,0x800000);
6050       nottaken=out;
6051       emit_jne(0);
6052     }
6053     if((source[i]&0x30000)==0x30000) // BC1TL
6054     {
6055       emit_testimm(s1l,0x800000);
6056       nottaken=out;
6057       emit_jeq(0);
6058     }
6059   }
6060
6061   assert(i_regs->regmap[HOST_CCREG]==CCREG);
6062   wb_dirtys(regs[i].regmap,regs[i].dirty);
6063   if(unconditional)
6064   {
6065     emit_movimm(ba[i],HOST_BTREG);
6066   }
6067   else if(addr!=HOST_BTREG)
6068   {
6069     emit_mov(addr,HOST_BTREG);
6070   }
6071   void *branch_addr=out;
6072   emit_jmp(0);
6073   int target_addr=start+i*4+5;
6074   void *stub=out;
6075   void *compiled_target_addr=check_addr(target_addr);
6076   emit_extjump_ds(branch_addr, target_addr);
6077   if(compiled_target_addr) {
6078     set_jump_target(branch_addr, compiled_target_addr);
6079     add_jump_out(target_addr,stub);
6080   }
6081   else set_jump_target(branch_addr, stub);
6082 }
6083
6084 // Assemble the delay slot for the above
6085 static void pagespan_ds()
6086 {
6087   assem_debug("initial delay slot:\n");
6088   u_int vaddr=start+1;
6089   u_int page=get_page(vaddr);
6090   u_int vpage=get_vpage(vaddr);
6091   ll_add(jump_dirty+vpage,vaddr,(void *)out);
6092   do_dirty_stub_ds(slen*4);
6093   ll_add(jump_in+page,vaddr,(void *)out);
6094   assert(regs[0].regmap_entry[HOST_CCREG]==CCREG);
6095   if(regs[0].regmap[HOST_CCREG]!=CCREG)
6096     wb_register(CCREG,regs[0].regmap_entry,regs[0].wasdirty);
6097   if(regs[0].regmap[HOST_BTREG]!=BTREG)
6098     emit_writeword(HOST_BTREG,&branch_target);
6099   load_regs(regs[0].regmap_entry,regs[0].regmap,dops[0].rs1,dops[0].rs2);
6100   address_generation(0,&regs[0],regs[0].regmap_entry);
6101   if (ram_offset && (dops[0].is_load || dops[0].is_store))
6102     load_regs(regs[0].regmap_entry,regs[0].regmap,ROREG,ROREG);
6103   if (dops[0].is_store)
6104     load_regs(regs[0].regmap_entry,regs[0].regmap,INVCP,INVCP);
6105   is_delayslot=0;
6106   switch (dops[0].itype) {
6107     case SYSCALL:
6108     case HLECALL:
6109     case INTCALL:
6110     case SPAN:
6111     case UJUMP:
6112     case RJUMP:
6113     case CJUMP:
6114     case SJUMP:
6115       SysPrintf("Jump in the delay slot.  This is probably a bug.\n");
6116       break;
6117     default:
6118       assemble(0, &regs[0], 0);
6119   }
6120   int btaddr=get_reg(regs[0].regmap,BTREG);
6121   if(btaddr<0) {
6122     btaddr=get_reg(regs[0].regmap,-1);
6123     emit_readword(&branch_target,btaddr);
6124   }
6125   assert(btaddr!=HOST_CCREG);
6126   if(regs[0].regmap[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG);
6127 #ifdef HOST_IMM8
6128   host_tempreg_acquire();
6129   emit_movimm(start+4,HOST_TEMPREG);
6130   emit_cmp(btaddr,HOST_TEMPREG);
6131   host_tempreg_release();
6132 #else
6133   emit_cmpimm(btaddr,start+4);
6134 #endif
6135   void *branch = out;
6136   emit_jeq(0);
6137   store_regs_bt(regs[0].regmap,regs[0].dirty,-1);
6138   do_jump_vaddr(btaddr);
6139   set_jump_target(branch, out);
6140   store_regs_bt(regs[0].regmap,regs[0].dirty,start+4);
6141   load_regs_bt(regs[0].regmap,regs[0].dirty,start+4);
6142 }
6143
6144 // Basic liveness analysis for MIPS registers
6145 void unneeded_registers(int istart,int iend,int r)
6146 {
6147   int i;
6148   uint64_t u,gte_u,b,gte_b;
6149   uint64_t temp_u,temp_gte_u=0;
6150   uint64_t gte_u_unknown=0;
6151   if (HACK_ENABLED(NDHACK_GTE_UNNEEDED))
6152     gte_u_unknown=~0ll;
6153   if(iend==slen-1) {
6154     u=1;
6155     gte_u=gte_u_unknown;
6156   }else{
6157     //u=unneeded_reg[iend+1];
6158     u=1;
6159     gte_u=gte_unneeded[iend+1];
6160   }
6161
6162   for (i=iend;i>=istart;i--)
6163   {
6164     //printf("unneeded registers i=%d (%d,%d) r=%d\n",i,istart,iend,r);
6165     if(dops[i].is_jump)
6166     {
6167       // If subroutine call, flag return address as a possible branch target
6168       if(dops[i].rt1==31 && i<slen-2) dops[i+2].bt=1;
6169
6170       if(ba[i]<start || ba[i]>=(start+slen*4))
6171       {
6172         // Branch out of this block, flush all regs
6173         u=1;
6174         gte_u=gte_u_unknown;
6175         branch_unneeded_reg[i]=u;
6176         // Merge in delay slot
6177         u|=(1LL<<dops[i+1].rt1)|(1LL<<dops[i+1].rt2);
6178         u&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
6179         u|=1;
6180         gte_u|=gte_rt[i+1];
6181         gte_u&=~gte_rs[i+1];
6182       }
6183       else
6184       {
6185         // Internal branch, flag target
6186         dops[(ba[i]-start)>>2].bt=1;
6187         if(ba[i]<=start+i*4) {
6188           // Backward branch
6189           if(dops[i].is_ujump)
6190           {
6191             // Unconditional branch
6192             temp_u=1;
6193             temp_gte_u=0;
6194           } else {
6195             // Conditional branch (not taken case)
6196             temp_u=unneeded_reg[i+2];
6197             temp_gte_u&=gte_unneeded[i+2];
6198           }
6199           // Merge in delay slot
6200           temp_u|=(1LL<<dops[i+1].rt1)|(1LL<<dops[i+1].rt2);
6201           temp_u&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
6202           temp_u|=1;
6203           temp_gte_u|=gte_rt[i+1];
6204           temp_gte_u&=~gte_rs[i+1];
6205           temp_u|=(1LL<<dops[i].rt1)|(1LL<<dops[i].rt2);
6206           temp_u&=~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
6207           temp_u|=1;
6208           temp_gte_u|=gte_rt[i];
6209           temp_gte_u&=~gte_rs[i];
6210           unneeded_reg[i]=temp_u;
6211           gte_unneeded[i]=temp_gte_u;
6212           // Only go three levels deep.  This recursion can take an
6213           // excessive amount of time if there are a lot of nested loops.
6214           if(r<2) {
6215             unneeded_registers((ba[i]-start)>>2,i-1,r+1);
6216           }else{
6217             unneeded_reg[(ba[i]-start)>>2]=1;
6218             gte_unneeded[(ba[i]-start)>>2]=gte_u_unknown;
6219           }
6220         } /*else*/ if(1) {
6221           if (dops[i].is_ujump)
6222           {
6223             // Unconditional branch
6224             u=unneeded_reg[(ba[i]-start)>>2];
6225             gte_u=gte_unneeded[(ba[i]-start)>>2];
6226             branch_unneeded_reg[i]=u;
6227             // Merge in delay slot
6228             u|=(1LL<<dops[i+1].rt1)|(1LL<<dops[i+1].rt2);
6229             u&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
6230             u|=1;
6231             gte_u|=gte_rt[i+1];
6232             gte_u&=~gte_rs[i+1];
6233           } else {
6234             // Conditional branch
6235             b=unneeded_reg[(ba[i]-start)>>2];
6236             gte_b=gte_unneeded[(ba[i]-start)>>2];
6237             branch_unneeded_reg[i]=b;
6238             // Branch delay slot
6239             b|=(1LL<<dops[i+1].rt1)|(1LL<<dops[i+1].rt2);
6240             b&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
6241             b|=1;
6242             gte_b|=gte_rt[i+1];
6243             gte_b&=~gte_rs[i+1];
6244             u&=b;
6245             gte_u&=gte_b;
6246             if(i<slen-1) {
6247               branch_unneeded_reg[i]&=unneeded_reg[i+2];
6248             } else {
6249               branch_unneeded_reg[i]=1;
6250             }
6251           }
6252         }
6253       }
6254     }
6255     else if(dops[i].itype==SYSCALL||dops[i].itype==HLECALL||dops[i].itype==INTCALL)
6256     {
6257       // SYSCALL instruction (software interrupt)
6258       u=1;
6259     }
6260     else if(dops[i].itype==COP0 && (source[i]&0x3f)==0x18)
6261     {
6262       // ERET instruction (return from interrupt)
6263       u=1;
6264     }
6265     //u=1; // DEBUG
6266     // Written registers are unneeded
6267     u|=1LL<<dops[i].rt1;
6268     u|=1LL<<dops[i].rt2;
6269     gte_u|=gte_rt[i];
6270     // Accessed registers are needed
6271     u&=~(1LL<<dops[i].rs1);
6272     u&=~(1LL<<dops[i].rs2);
6273     gte_u&=~gte_rs[i];
6274     if(gte_rs[i]&&dops[i].rt1&&(unneeded_reg[i+1]&(1ll<<dops[i].rt1)))
6275       gte_u|=gte_rs[i]&gte_unneeded[i+1]; // MFC2/CFC2 to dead register, unneeded
6276     // Source-target dependencies
6277     // R0 is always unneeded
6278     u|=1;
6279     // Save it
6280     unneeded_reg[i]=u;
6281     gte_unneeded[i]=gte_u;
6282     /*
6283     printf("ur (%d,%d) %x: ",istart,iend,start+i*4);
6284     printf("U:");
6285     int r;
6286     for(r=1;r<=CCREG;r++) {
6287       if((unneeded_reg[i]>>r)&1) {
6288         if(r==HIREG) printf(" HI");
6289         else if(r==LOREG) printf(" LO");
6290         else printf(" r%d",r);
6291       }
6292     }
6293     printf("\n");
6294     */
6295   }
6296 }
6297
6298 // Write back dirty registers as soon as we will no longer modify them,
6299 // so that we don't end up with lots of writes at the branches.
6300 void clean_registers(int istart,int iend,int wr)
6301 {
6302   int i;
6303   int r;
6304   u_int will_dirty_i,will_dirty_next,temp_will_dirty;
6305   u_int wont_dirty_i,wont_dirty_next,temp_wont_dirty;
6306   if(iend==slen-1) {
6307     will_dirty_i=will_dirty_next=0;
6308     wont_dirty_i=wont_dirty_next=0;
6309   }else{
6310     will_dirty_i=will_dirty_next=will_dirty[iend+1];
6311     wont_dirty_i=wont_dirty_next=wont_dirty[iend+1];
6312   }
6313   for (i=iend;i>=istart;i--)
6314   {
6315     if(dops[i].is_jump)
6316     {
6317       if(ba[i]<start || ba[i]>=(start+slen*4))
6318       {
6319         // Branch out of this block, flush all regs
6320         if (dops[i].is_ujump)
6321         {
6322           // Unconditional branch
6323           will_dirty_i=0;
6324           wont_dirty_i=0;
6325           // Merge in delay slot (will dirty)
6326           for(r=0;r<HOST_REGS;r++) {
6327             if(r!=EXCLUDE_REG) {
6328               if((branch_regs[i].regmap[r]&63)==dops[i].rt1) will_dirty_i|=1<<r;
6329               if((branch_regs[i].regmap[r]&63)==dops[i].rt2) will_dirty_i|=1<<r;
6330               if((branch_regs[i].regmap[r]&63)==dops[i+1].rt1) will_dirty_i|=1<<r;
6331               if((branch_regs[i].regmap[r]&63)==dops[i+1].rt2) will_dirty_i|=1<<r;
6332               if((branch_regs[i].regmap[r]&63)>33) will_dirty_i&=~(1<<r);
6333               if(branch_regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
6334               if(branch_regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
6335               if((regs[i].regmap[r]&63)==dops[i].rt1) will_dirty_i|=1<<r;
6336               if((regs[i].regmap[r]&63)==dops[i].rt2) will_dirty_i|=1<<r;
6337               if((regs[i].regmap[r]&63)==dops[i+1].rt1) will_dirty_i|=1<<r;
6338               if((regs[i].regmap[r]&63)==dops[i+1].rt2) will_dirty_i|=1<<r;
6339               if((regs[i].regmap[r]&63)>33) will_dirty_i&=~(1<<r);
6340               if(regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
6341               if(regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
6342             }
6343           }
6344         }
6345         else
6346         {
6347           // Conditional branch
6348           will_dirty_i=0;
6349           wont_dirty_i=wont_dirty_next;
6350           // Merge in delay slot (will dirty)
6351           for(r=0;r<HOST_REGS;r++) {
6352             if(r!=EXCLUDE_REG) {
6353               if (1) { // !dops[i].likely) {
6354                 // Might not dirty if likely branch is not taken
6355                 if((branch_regs[i].regmap[r]&63)==dops[i].rt1) will_dirty_i|=1<<r;
6356                 if((branch_regs[i].regmap[r]&63)==dops[i].rt2) will_dirty_i|=1<<r;
6357                 if((branch_regs[i].regmap[r]&63)==dops[i+1].rt1) will_dirty_i|=1<<r;
6358                 if((branch_regs[i].regmap[r]&63)==dops[i+1].rt2) will_dirty_i|=1<<r;
6359                 if((branch_regs[i].regmap[r]&63)>33) will_dirty_i&=~(1<<r);
6360                 if(branch_regs[i].regmap[r]==0) will_dirty_i&=~(1<<r);
6361                 if(branch_regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
6362                 //if((regs[i].regmap[r]&63)==dops[i].rt1) will_dirty_i|=1<<r;
6363                 //if((regs[i].regmap[r]&63)==dops[i].rt2) will_dirty_i|=1<<r;
6364                 if((regs[i].regmap[r]&63)==dops[i+1].rt1) will_dirty_i|=1<<r;
6365                 if((regs[i].regmap[r]&63)==dops[i+1].rt2) will_dirty_i|=1<<r;
6366                 if((regs[i].regmap[r]&63)>33) will_dirty_i&=~(1<<r);
6367                 if(regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
6368                 if(regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
6369               }
6370             }
6371           }
6372         }
6373         // Merge in delay slot (wont dirty)
6374         for(r=0;r<HOST_REGS;r++) {
6375           if(r!=EXCLUDE_REG) {
6376             if((regs[i].regmap[r]&63)==dops[i].rt1) wont_dirty_i|=1<<r;
6377             if((regs[i].regmap[r]&63)==dops[i].rt2) wont_dirty_i|=1<<r;
6378             if((regs[i].regmap[r]&63)==dops[i+1].rt1) wont_dirty_i|=1<<r;
6379             if((regs[i].regmap[r]&63)==dops[i+1].rt2) wont_dirty_i|=1<<r;
6380             if(regs[i].regmap[r]==CCREG) wont_dirty_i|=1<<r;
6381             if((branch_regs[i].regmap[r]&63)==dops[i].rt1) wont_dirty_i|=1<<r;
6382             if((branch_regs[i].regmap[r]&63)==dops[i].rt2) wont_dirty_i|=1<<r;
6383             if((branch_regs[i].regmap[r]&63)==dops[i+1].rt1) wont_dirty_i|=1<<r;
6384             if((branch_regs[i].regmap[r]&63)==dops[i+1].rt2) wont_dirty_i|=1<<r;
6385             if(branch_regs[i].regmap[r]==CCREG) wont_dirty_i|=1<<r;
6386           }
6387         }
6388         if(wr) {
6389           #ifndef DESTRUCTIVE_WRITEBACK
6390           branch_regs[i].dirty&=wont_dirty_i;
6391           #endif
6392           branch_regs[i].dirty|=will_dirty_i;
6393         }
6394       }
6395       else
6396       {
6397         // Internal branch
6398         if(ba[i]<=start+i*4) {
6399           // Backward branch
6400           if (dops[i].is_ujump)
6401           {
6402             // Unconditional branch
6403             temp_will_dirty=0;
6404             temp_wont_dirty=0;
6405             // Merge in delay slot (will dirty)
6406             for(r=0;r<HOST_REGS;r++) {
6407               if(r!=EXCLUDE_REG) {
6408                 if((branch_regs[i].regmap[r]&63)==dops[i].rt1) temp_will_dirty|=1<<r;
6409                 if((branch_regs[i].regmap[r]&63)==dops[i].rt2) temp_will_dirty|=1<<r;
6410                 if((branch_regs[i].regmap[r]&63)==dops[i+1].rt1) temp_will_dirty|=1<<r;
6411                 if((branch_regs[i].regmap[r]&63)==dops[i+1].rt2) temp_will_dirty|=1<<r;
6412                 if((branch_regs[i].regmap[r]&63)>33) temp_will_dirty&=~(1<<r);
6413                 if(branch_regs[i].regmap[r]<=0) temp_will_dirty&=~(1<<r);
6414                 if(branch_regs[i].regmap[r]==CCREG) temp_will_dirty|=1<<r;
6415                 if((regs[i].regmap[r]&63)==dops[i].rt1) temp_will_dirty|=1<<r;
6416                 if((regs[i].regmap[r]&63)==dops[i].rt2) temp_will_dirty|=1<<r;
6417                 if((regs[i].regmap[r]&63)==dops[i+1].rt1) temp_will_dirty|=1<<r;
6418                 if((regs[i].regmap[r]&63)==dops[i+1].rt2) temp_will_dirty|=1<<r;
6419                 if((regs[i].regmap[r]&63)>33) temp_will_dirty&=~(1<<r);
6420                 if(regs[i].regmap[r]<=0) temp_will_dirty&=~(1<<r);
6421                 if(regs[i].regmap[r]==CCREG) temp_will_dirty|=1<<r;
6422               }
6423             }
6424           } else {
6425             // Conditional branch (not taken case)
6426             temp_will_dirty=will_dirty_next;
6427             temp_wont_dirty=wont_dirty_next;
6428             // Merge in delay slot (will dirty)
6429             for(r=0;r<HOST_REGS;r++) {
6430               if(r!=EXCLUDE_REG) {
6431                 if (1) { // !dops[i].likely) {
6432                   // Will not dirty if likely branch is not taken
6433                   if((branch_regs[i].regmap[r]&63)==dops[i].rt1) temp_will_dirty|=1<<r;
6434                   if((branch_regs[i].regmap[r]&63)==dops[i].rt2) temp_will_dirty|=1<<r;
6435                   if((branch_regs[i].regmap[r]&63)==dops[i+1].rt1) temp_will_dirty|=1<<r;
6436                   if((branch_regs[i].regmap[r]&63)==dops[i+1].rt2) temp_will_dirty|=1<<r;
6437                   if((branch_regs[i].regmap[r]&63)>33) temp_will_dirty&=~(1<<r);
6438                   if(branch_regs[i].regmap[r]==0) temp_will_dirty&=~(1<<r);
6439                   if(branch_regs[i].regmap[r]==CCREG) temp_will_dirty|=1<<r;
6440                   //if((regs[i].regmap[r]&63)==dops[i].rt1) temp_will_dirty|=1<<r;
6441                   //if((regs[i].regmap[r]&63)==dops[i].rt2) temp_will_dirty|=1<<r;
6442                   if((regs[i].regmap[r]&63)==dops[i+1].rt1) temp_will_dirty|=1<<r;
6443                   if((regs[i].regmap[r]&63)==dops[i+1].rt2) temp_will_dirty|=1<<r;
6444                   if((regs[i].regmap[r]&63)>33) temp_will_dirty&=~(1<<r);
6445                   if(regs[i].regmap[r]<=0) temp_will_dirty&=~(1<<r);
6446                   if(regs[i].regmap[r]==CCREG) temp_will_dirty|=1<<r;
6447                 }
6448               }
6449             }
6450           }
6451           // Merge in delay slot (wont dirty)
6452           for(r=0;r<HOST_REGS;r++) {
6453             if(r!=EXCLUDE_REG) {
6454               if((regs[i].regmap[r]&63)==dops[i].rt1) temp_wont_dirty|=1<<r;
6455               if((regs[i].regmap[r]&63)==dops[i].rt2) temp_wont_dirty|=1<<r;
6456               if((regs[i].regmap[r]&63)==dops[i+1].rt1) temp_wont_dirty|=1<<r;
6457               if((regs[i].regmap[r]&63)==dops[i+1].rt2) temp_wont_dirty|=1<<r;
6458               if(regs[i].regmap[r]==CCREG) temp_wont_dirty|=1<<r;
6459               if((branch_regs[i].regmap[r]&63)==dops[i].rt1) temp_wont_dirty|=1<<r;
6460               if((branch_regs[i].regmap[r]&63)==dops[i].rt2) temp_wont_dirty|=1<<r;
6461               if((branch_regs[i].regmap[r]&63)==dops[i+1].rt1) temp_wont_dirty|=1<<r;
6462               if((branch_regs[i].regmap[r]&63)==dops[i+1].rt2) temp_wont_dirty|=1<<r;
6463               if(branch_regs[i].regmap[r]==CCREG) temp_wont_dirty|=1<<r;
6464             }
6465           }
6466           // Deal with changed mappings
6467           if(i<iend) {
6468             for(r=0;r<HOST_REGS;r++) {
6469               if(r!=EXCLUDE_REG) {
6470                 if(regs[i].regmap[r]!=regmap_pre[i][r]) {
6471                   temp_will_dirty&=~(1<<r);
6472                   temp_wont_dirty&=~(1<<r);
6473                   if((regmap_pre[i][r]&63)>0 && (regmap_pre[i][r]&63)<34) {
6474                     temp_will_dirty|=((unneeded_reg[i]>>(regmap_pre[i][r]&63))&1)<<r;
6475                     temp_wont_dirty|=((unneeded_reg[i]>>(regmap_pre[i][r]&63))&1)<<r;
6476                   } else {
6477                     temp_will_dirty|=1<<r;
6478                     temp_wont_dirty|=1<<r;
6479                   }
6480                 }
6481               }
6482             }
6483           }
6484           if(wr) {
6485             will_dirty[i]=temp_will_dirty;
6486             wont_dirty[i]=temp_wont_dirty;
6487             clean_registers((ba[i]-start)>>2,i-1,0);
6488           }else{
6489             // Limit recursion.  It can take an excessive amount
6490             // of time if there are a lot of nested loops.
6491             will_dirty[(ba[i]-start)>>2]=0;
6492             wont_dirty[(ba[i]-start)>>2]=-1;
6493           }
6494         }
6495         /*else*/ if(1)
6496         {
6497           if (dops[i].is_ujump)
6498           {
6499             // Unconditional branch
6500             will_dirty_i=0;
6501             wont_dirty_i=0;
6502           //if(ba[i]>start+i*4) { // Disable recursion (for debugging)
6503             for(r=0;r<HOST_REGS;r++) {
6504               if(r!=EXCLUDE_REG) {
6505                 if(branch_regs[i].regmap[r]==regs[(ba[i]-start)>>2].regmap_entry[r]) {
6506                   will_dirty_i|=will_dirty[(ba[i]-start)>>2]&(1<<r);
6507                   wont_dirty_i|=wont_dirty[(ba[i]-start)>>2]&(1<<r);
6508                 }
6509                 if(branch_regs[i].regmap[r]>=0) {
6510                   will_dirty_i|=((unneeded_reg[(ba[i]-start)>>2]>>(branch_regs[i].regmap[r]&63))&1)<<r;
6511                   wont_dirty_i|=((unneeded_reg[(ba[i]-start)>>2]>>(branch_regs[i].regmap[r]&63))&1)<<r;
6512                 }
6513               }
6514             }
6515           //}
6516             // Merge in delay slot
6517             for(r=0;r<HOST_REGS;r++) {
6518               if(r!=EXCLUDE_REG) {
6519                 if((branch_regs[i].regmap[r]&63)==dops[i].rt1) will_dirty_i|=1<<r;
6520                 if((branch_regs[i].regmap[r]&63)==dops[i].rt2) will_dirty_i|=1<<r;
6521                 if((branch_regs[i].regmap[r]&63)==dops[i+1].rt1) will_dirty_i|=1<<r;
6522                 if((branch_regs[i].regmap[r]&63)==dops[i+1].rt2) will_dirty_i|=1<<r;
6523                 if((branch_regs[i].regmap[r]&63)>33) will_dirty_i&=~(1<<r);
6524                 if(branch_regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
6525                 if(branch_regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
6526                 if((regs[i].regmap[r]&63)==dops[i].rt1) will_dirty_i|=1<<r;
6527                 if((regs[i].regmap[r]&63)==dops[i].rt2) will_dirty_i|=1<<r;
6528                 if((regs[i].regmap[r]&63)==dops[i+1].rt1) will_dirty_i|=1<<r;
6529                 if((regs[i].regmap[r]&63)==dops[i+1].rt2) will_dirty_i|=1<<r;
6530                 if((regs[i].regmap[r]&63)>33) will_dirty_i&=~(1<<r);
6531                 if(regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
6532                 if(regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
6533               }
6534             }
6535           } else {
6536             // Conditional branch
6537             will_dirty_i=will_dirty_next;
6538             wont_dirty_i=wont_dirty_next;
6539           //if(ba[i]>start+i*4) { // Disable recursion (for debugging)
6540             for(r=0;r<HOST_REGS;r++) {
6541               if(r!=EXCLUDE_REG) {
6542                 signed char target_reg=branch_regs[i].regmap[r];
6543                 if(target_reg==regs[(ba[i]-start)>>2].regmap_entry[r]) {
6544                   will_dirty_i&=will_dirty[(ba[i]-start)>>2]&(1<<r);
6545                   wont_dirty_i|=wont_dirty[(ba[i]-start)>>2]&(1<<r);
6546                 }
6547                 else if(target_reg>=0) {
6548                   will_dirty_i&=((unneeded_reg[(ba[i]-start)>>2]>>(target_reg&63))&1)<<r;
6549                   wont_dirty_i|=((unneeded_reg[(ba[i]-start)>>2]>>(target_reg&63))&1)<<r;
6550                 }
6551               }
6552             }
6553           //}
6554             // Merge in delay slot
6555             for(r=0;r<HOST_REGS;r++) {
6556               if(r!=EXCLUDE_REG) {
6557                 if (1) { // !dops[i].likely) {
6558                   // Might not dirty if likely branch is not taken
6559                   if((branch_regs[i].regmap[r]&63)==dops[i].rt1) will_dirty_i|=1<<r;
6560                   if((branch_regs[i].regmap[r]&63)==dops[i].rt2) will_dirty_i|=1<<r;
6561                   if((branch_regs[i].regmap[r]&63)==dops[i+1].rt1) will_dirty_i|=1<<r;
6562                   if((branch_regs[i].regmap[r]&63)==dops[i+1].rt2) will_dirty_i|=1<<r;
6563                   if((branch_regs[i].regmap[r]&63)>33) will_dirty_i&=~(1<<r);
6564                   if(branch_regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
6565                   if(branch_regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
6566                   //if((regs[i].regmap[r]&63)==dops[i].rt1) will_dirty_i|=1<<r;
6567                   //if((regs[i].regmap[r]&63)==dops[i].rt2) will_dirty_i|=1<<r;
6568                   if((regs[i].regmap[r]&63)==dops[i+1].rt1) will_dirty_i|=1<<r;
6569                   if((regs[i].regmap[r]&63)==dops[i+1].rt2) will_dirty_i|=1<<r;
6570                   if((regs[i].regmap[r]&63)>33) will_dirty_i&=~(1<<r);
6571                   if(regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
6572                   if(regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
6573                 }
6574               }
6575             }
6576           }
6577           // Merge in delay slot (won't dirty)
6578           for(r=0;r<HOST_REGS;r++) {
6579             if(r!=EXCLUDE_REG) {
6580               if((regs[i].regmap[r]&63)==dops[i].rt1) wont_dirty_i|=1<<r;
6581               if((regs[i].regmap[r]&63)==dops[i].rt2) wont_dirty_i|=1<<r;
6582               if((regs[i].regmap[r]&63)==dops[i+1].rt1) wont_dirty_i|=1<<r;
6583               if((regs[i].regmap[r]&63)==dops[i+1].rt2) wont_dirty_i|=1<<r;
6584               if(regs[i].regmap[r]==CCREG) wont_dirty_i|=1<<r;
6585               if((branch_regs[i].regmap[r]&63)==dops[i].rt1) wont_dirty_i|=1<<r;
6586               if((branch_regs[i].regmap[r]&63)==dops[i].rt2) wont_dirty_i|=1<<r;
6587               if((branch_regs[i].regmap[r]&63)==dops[i+1].rt1) wont_dirty_i|=1<<r;
6588               if((branch_regs[i].regmap[r]&63)==dops[i+1].rt2) wont_dirty_i|=1<<r;
6589               if(branch_regs[i].regmap[r]==CCREG) wont_dirty_i|=1<<r;
6590             }
6591           }
6592           if(wr) {
6593             #ifndef DESTRUCTIVE_WRITEBACK
6594             branch_regs[i].dirty&=wont_dirty_i;
6595             #endif
6596             branch_regs[i].dirty|=will_dirty_i;
6597           }
6598         }
6599       }
6600     }
6601     else if(dops[i].itype==SYSCALL||dops[i].itype==HLECALL||dops[i].itype==INTCALL)
6602     {
6603       // SYSCALL instruction (software interrupt)
6604       will_dirty_i=0;
6605       wont_dirty_i=0;
6606     }
6607     else if(dops[i].itype==COP0 && (source[i]&0x3f)==0x18)
6608     {
6609       // ERET instruction (return from interrupt)
6610       will_dirty_i=0;
6611       wont_dirty_i=0;
6612     }
6613     will_dirty_next=will_dirty_i;
6614     wont_dirty_next=wont_dirty_i;
6615     for(r=0;r<HOST_REGS;r++) {
6616       if(r!=EXCLUDE_REG) {
6617         if((regs[i].regmap[r]&63)==dops[i].rt1) will_dirty_i|=1<<r;
6618         if((regs[i].regmap[r]&63)==dops[i].rt2) will_dirty_i|=1<<r;
6619         if((regs[i].regmap[r]&63)>33) will_dirty_i&=~(1<<r);
6620         if(regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
6621         if(regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
6622         if((regs[i].regmap[r]&63)==dops[i].rt1) wont_dirty_i|=1<<r;
6623         if((regs[i].regmap[r]&63)==dops[i].rt2) wont_dirty_i|=1<<r;
6624         if(regs[i].regmap[r]==CCREG) wont_dirty_i|=1<<r;
6625         if(i>istart) {
6626           if (!dops[i].is_jump)
6627           {
6628             // Don't store a register immediately after writing it,
6629             // may prevent dual-issue.
6630             if((regs[i].regmap[r]&63)==dops[i-1].rt1) wont_dirty_i|=1<<r;
6631             if((regs[i].regmap[r]&63)==dops[i-1].rt2) wont_dirty_i|=1<<r;
6632           }
6633         }
6634       }
6635     }
6636     // Save it
6637     will_dirty[i]=will_dirty_i;
6638     wont_dirty[i]=wont_dirty_i;
6639     // Mark registers that won't be dirtied as not dirty
6640     if(wr) {
6641         regs[i].dirty|=will_dirty_i;
6642         #ifndef DESTRUCTIVE_WRITEBACK
6643         regs[i].dirty&=wont_dirty_i;
6644         if(dops[i].is_jump)
6645         {
6646           if (i < iend-1 && !dops[i].is_ujump) {
6647             for(r=0;r<HOST_REGS;r++) {
6648               if(r!=EXCLUDE_REG) {
6649                 if(regs[i].regmap[r]==regmap_pre[i+2][r]) {
6650                   regs[i+2].wasdirty&=wont_dirty_i|~(1<<r);
6651                 }else {/*printf("i: %x (%d) mismatch(+2): %d\n",start+i*4,i,r);assert(!((wont_dirty_i>>r)&1));*/}
6652               }
6653             }
6654           }
6655         }
6656         else
6657         {
6658           if(i<iend) {
6659             for(r=0;r<HOST_REGS;r++) {
6660               if(r!=EXCLUDE_REG) {
6661                 if(regs[i].regmap[r]==regmap_pre[i+1][r]) {
6662                   regs[i+1].wasdirty&=wont_dirty_i|~(1<<r);
6663                 }else {/*printf("i: %x (%d) mismatch(+1): %d\n",start+i*4,i,r);assert(!((wont_dirty_i>>r)&1));*/}
6664               }
6665             }
6666           }
6667         }
6668         #endif
6669       //}
6670     }
6671     // Deal with changed mappings
6672     temp_will_dirty=will_dirty_i;
6673     temp_wont_dirty=wont_dirty_i;
6674     for(r=0;r<HOST_REGS;r++) {
6675       if(r!=EXCLUDE_REG) {
6676         int nr;
6677         if(regs[i].regmap[r]==regmap_pre[i][r]) {
6678           if(wr) {
6679             #ifndef DESTRUCTIVE_WRITEBACK
6680             regs[i].wasdirty&=wont_dirty_i|~(1<<r);
6681             #endif
6682             regs[i].wasdirty|=will_dirty_i&(1<<r);
6683           }
6684         }
6685         else if(regmap_pre[i][r]>=0&&(nr=get_reg(regs[i].regmap,regmap_pre[i][r]))>=0) {
6686           // Register moved to a different register
6687           will_dirty_i&=~(1<<r);
6688           wont_dirty_i&=~(1<<r);
6689           will_dirty_i|=((temp_will_dirty>>nr)&1)<<r;
6690           wont_dirty_i|=((temp_wont_dirty>>nr)&1)<<r;
6691           if(wr) {
6692             #ifndef DESTRUCTIVE_WRITEBACK
6693             regs[i].wasdirty&=wont_dirty_i|~(1<<r);
6694             #endif
6695             regs[i].wasdirty|=will_dirty_i&(1<<r);
6696           }
6697         }
6698         else {
6699           will_dirty_i&=~(1<<r);
6700           wont_dirty_i&=~(1<<r);
6701           if((regmap_pre[i][r]&63)>0 && (regmap_pre[i][r]&63)<34) {
6702             will_dirty_i|=((unneeded_reg[i]>>(regmap_pre[i][r]&63))&1)<<r;
6703             wont_dirty_i|=((unneeded_reg[i]>>(regmap_pre[i][r]&63))&1)<<r;
6704           } else {
6705             wont_dirty_i|=1<<r;
6706             /*printf("i: %x (%d) mismatch: %d\n",start+i*4,i,r);assert(!((will_dirty>>r)&1));*/
6707           }
6708         }
6709       }
6710     }
6711   }
6712 }
6713
6714 #ifdef DISASM
6715   /* disassembly */
6716 void disassemble_inst(int i)
6717 {
6718     if (dops[i].bt) printf("*"); else printf(" ");
6719     switch(dops[i].itype) {
6720       case UJUMP:
6721         printf (" %x: %s %8x\n",start+i*4,insn[i],ba[i]);break;
6722       case CJUMP:
6723         printf (" %x: %s r%d,r%d,%8x\n",start+i*4,insn[i],dops[i].rs1,dops[i].rs2,i?start+i*4+4+((signed int)((unsigned int)source[i]<<16)>>14):*ba);break;
6724       case SJUMP:
6725         printf (" %x: %s r%d,%8x\n",start+i*4,insn[i],dops[i].rs1,start+i*4+4+((signed int)((unsigned int)source[i]<<16)>>14));break;
6726       case RJUMP:
6727         if (dops[i].opcode==0x9&&dops[i].rt1!=31)
6728           printf (" %x: %s r%d,r%d\n",start+i*4,insn[i],dops[i].rt1,dops[i].rs1);
6729         else
6730           printf (" %x: %s r%d\n",start+i*4,insn[i],dops[i].rs1);
6731         break;
6732       case SPAN:
6733         printf (" %x: %s (pagespan) r%d,r%d,%8x\n",start+i*4,insn[i],dops[i].rs1,dops[i].rs2,ba[i]);break;
6734       case IMM16:
6735         if(dops[i].opcode==0xf) //LUI
6736           printf (" %x: %s r%d,%4x0000\n",start+i*4,insn[i],dops[i].rt1,imm[i]&0xffff);
6737         else
6738           printf (" %x: %s r%d,r%d,%d\n",start+i*4,insn[i],dops[i].rt1,dops[i].rs1,imm[i]);
6739         break;
6740       case LOAD:
6741       case LOADLR:
6742         printf (" %x: %s r%d,r%d+%x\n",start+i*4,insn[i],dops[i].rt1,dops[i].rs1,imm[i]);
6743         break;
6744       case STORE:
6745       case STORELR:
6746         printf (" %x: %s r%d,r%d+%x\n",start+i*4,insn[i],dops[i].rs2,dops[i].rs1,imm[i]);
6747         break;
6748       case ALU:
6749       case SHIFT:
6750         printf (" %x: %s r%d,r%d,r%d\n",start+i*4,insn[i],dops[i].rt1,dops[i].rs1,dops[i].rs2);
6751         break;
6752       case MULTDIV:
6753         printf (" %x: %s r%d,r%d\n",start+i*4,insn[i],dops[i].rs1,dops[i].rs2);
6754         break;
6755       case SHIFTIMM:
6756         printf (" %x: %s r%d,r%d,%d\n",start+i*4,insn[i],dops[i].rt1,dops[i].rs1,imm[i]);
6757         break;
6758       case MOV:
6759         if((dops[i].opcode2&0x1d)==0x10)
6760           printf (" %x: %s r%d\n",start+i*4,insn[i],dops[i].rt1);
6761         else if((dops[i].opcode2&0x1d)==0x11)
6762           printf (" %x: %s r%d\n",start+i*4,insn[i],dops[i].rs1);
6763         else
6764           printf (" %x: %s\n",start+i*4,insn[i]);
6765         break;
6766       case COP0:
6767         if(dops[i].opcode2==0)
6768           printf (" %x: %s r%d,cpr0[%d]\n",start+i*4,insn[i],dops[i].rt1,(source[i]>>11)&0x1f); // MFC0
6769         else if(dops[i].opcode2==4)
6770           printf (" %x: %s r%d,cpr0[%d]\n",start+i*4,insn[i],dops[i].rs1,(source[i]>>11)&0x1f); // MTC0
6771         else printf (" %x: %s\n",start+i*4,insn[i]);
6772         break;
6773       case COP1:
6774         if(dops[i].opcode2<3)
6775           printf (" %x: %s r%d,cpr1[%d]\n",start+i*4,insn[i],dops[i].rt1,(source[i]>>11)&0x1f); // MFC1
6776         else if(dops[i].opcode2>3)
6777           printf (" %x: %s r%d,cpr1[%d]\n",start+i*4,insn[i],dops[i].rs1,(source[i]>>11)&0x1f); // MTC1
6778         else printf (" %x: %s\n",start+i*4,insn[i]);
6779         break;
6780       case COP2:
6781         if(dops[i].opcode2<3)
6782           printf (" %x: %s r%d,cpr2[%d]\n",start+i*4,insn[i],dops[i].rt1,(source[i]>>11)&0x1f); // MFC2
6783         else if(dops[i].opcode2>3)
6784           printf (" %x: %s r%d,cpr2[%d]\n",start+i*4,insn[i],dops[i].rs1,(source[i]>>11)&0x1f); // MTC2
6785         else printf (" %x: %s\n",start+i*4,insn[i]);
6786         break;
6787       case C1LS:
6788         printf (" %x: %s cpr1[%d],r%d+%x\n",start+i*4,insn[i],(source[i]>>16)&0x1f,dops[i].rs1,imm[i]);
6789         break;
6790       case C2LS:
6791         printf (" %x: %s cpr2[%d],r%d+%x\n",start+i*4,insn[i],(source[i]>>16)&0x1f,dops[i].rs1,imm[i]);
6792         break;
6793       case INTCALL:
6794         printf (" %x: %s (INTCALL)\n",start+i*4,insn[i]);
6795         break;
6796       default:
6797         //printf (" %s %8x\n",insn[i],source[i]);
6798         printf (" %x: %s\n",start+i*4,insn[i]);
6799     }
6800 }
6801 #else
6802 static void disassemble_inst(int i) {}
6803 #endif // DISASM
6804
6805 #define DRC_TEST_VAL 0x74657374
6806
6807 static void new_dynarec_test(void)
6808 {
6809   int (*testfunc)(void);
6810   void *beginning;
6811   int ret[2];
6812   size_t i;
6813
6814   // check structure linkage
6815   if ((u_char *)rcnts - (u_char *)&psxRegs != sizeof(psxRegs))
6816   {
6817     SysPrintf("linkage_arm* miscompilation/breakage detected.\n");
6818   }
6819
6820   SysPrintf("testing if we can run recompiled code @%p...\n", out);
6821   ((volatile u_int *)out)[0]++; // make cache dirty
6822
6823   for (i = 0; i < ARRAY_SIZE(ret); i++) {
6824     out = ndrc->translation_cache;
6825     beginning = start_block();
6826     emit_movimm(DRC_TEST_VAL + i, 0); // test
6827     emit_ret();
6828     literal_pool(0);
6829     end_block(beginning);
6830     testfunc = beginning;
6831     ret[i] = testfunc();
6832   }
6833
6834   if (ret[0] == DRC_TEST_VAL && ret[1] == DRC_TEST_VAL + 1)
6835     SysPrintf("test passed.\n");
6836   else
6837     SysPrintf("test failed, will likely crash soon (r=%08x %08x)\n", ret[0], ret[1]);
6838   out = ndrc->translation_cache;
6839 }
6840
6841 // clear the state completely, instead of just marking
6842 // things invalid like invalidate_all_pages() does
6843 void new_dynarec_clear_full(void)
6844 {
6845   int n;
6846   out = ndrc->translation_cache;
6847   memset(invalid_code,1,sizeof(invalid_code));
6848   memset(hash_table,0xff,sizeof(hash_table));
6849   memset(mini_ht,-1,sizeof(mini_ht));
6850   memset(restore_candidate,0,sizeof(restore_candidate));
6851   memset(shadow,0,sizeof(shadow));
6852   copy=shadow;
6853   expirep=16384; // Expiry pointer, +2 blocks
6854   pending_exception=0;
6855   literalcount=0;
6856   stop_after_jal=0;
6857   inv_code_start=inv_code_end=~0;
6858   hack_addr=0;
6859   f1_hack=0;
6860   // TLB
6861   for(n=0;n<4096;n++) ll_clear(jump_in+n);
6862   for(n=0;n<4096;n++) ll_clear(jump_out+n);
6863   for(n=0;n<4096;n++) ll_clear(jump_dirty+n);
6864
6865   cycle_multiplier_old = cycle_multiplier;
6866   new_dynarec_hacks_old = new_dynarec_hacks;
6867 }
6868
6869 void new_dynarec_init(void)
6870 {
6871   SysPrintf("Init new dynarec, ndrc size %x\n", (int)sizeof(*ndrc));
6872
6873 #ifdef _3DS
6874   check_rosalina();
6875 #endif
6876 #ifdef BASE_ADDR_DYNAMIC
6877   #ifdef VITA
6878   sceBlock = getVMBlock(); //sceKernelAllocMemBlockForVM("code", sizeof(*ndrc));
6879   if (sceBlock <= 0)
6880     SysPrintf("sceKernelAllocMemBlockForVM failed: %x\n", sceBlock);
6881   int ret = sceKernelGetMemBlockBase(sceBlock, (void **)&ndrc);
6882   if (ret < 0)
6883     SysPrintf("sceKernelGetMemBlockBase failed: %x\n", ret);
6884   sceKernelOpenVMDomain();
6885   sceClibPrintf("translation_cache = 0x%08lx\n ", (long)ndrc->translation_cache);
6886   #elif defined(_MSC_VER)
6887   ndrc = VirtualAlloc(NULL, sizeof(*ndrc), MEM_COMMIT | MEM_RESERVE,
6888     PAGE_EXECUTE_READWRITE);
6889   #else
6890   uintptr_t desired_addr = 0;
6891   #ifdef __ELF__
6892   extern char _end;
6893   desired_addr = ((uintptr_t)&_end + 0xffffff) & ~0xffffffl;
6894   #endif
6895   ndrc = mmap((void *)desired_addr, sizeof(*ndrc),
6896             PROT_READ | PROT_WRITE | PROT_EXEC,
6897             MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
6898   if (ndrc == MAP_FAILED) {
6899     SysPrintf("mmap() failed: %s\n", strerror(errno));
6900     abort();
6901   }
6902   #endif
6903 #else
6904   #ifndef NO_WRITE_EXEC
6905   // not all systems allow execute in data segment by default
6906   // size must be 4K aligned for 3DS?
6907   if (mprotect(ndrc, sizeof(*ndrc),
6908                PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
6909     SysPrintf("mprotect() failed: %s\n", strerror(errno));
6910   #endif
6911 #endif
6912   out = ndrc->translation_cache;
6913   cycle_multiplier=200;
6914   new_dynarec_clear_full();
6915 #ifdef HOST_IMM8
6916   // Copy this into local area so we don't have to put it in every literal pool
6917   invc_ptr=invalid_code;
6918 #endif
6919   arch_init();
6920   new_dynarec_test();
6921   ram_offset=(uintptr_t)rdram-0x80000000;
6922   if (ram_offset!=0)
6923     SysPrintf("warning: RAM is not directly mapped, performance will suffer\n");
6924 }
6925
6926 void new_dynarec_cleanup(void)
6927 {
6928   int n;
6929 #ifdef BASE_ADDR_DYNAMIC
6930   #ifdef VITA
6931   // sceBlock is managed by retroarch's bootstrap code
6932   //sceKernelFreeMemBlock(sceBlock);
6933   //sceBlock = -1;
6934   #else
6935   if (munmap(ndrc, sizeof(*ndrc)) < 0)
6936     SysPrintf("munmap() failed\n");
6937   #endif
6938 #endif
6939   for(n=0;n<4096;n++) ll_clear(jump_in+n);
6940   for(n=0;n<4096;n++) ll_clear(jump_out+n);
6941   for(n=0;n<4096;n++) ll_clear(jump_dirty+n);
6942   #ifdef ROM_COPY
6943   if (munmap (ROM_COPY, 67108864) < 0) {SysPrintf("munmap() failed\n");}
6944   #endif
6945 }
6946
6947 static u_int *get_source_start(u_int addr, u_int *limit)
6948 {
6949   if (addr < 0x00200000 ||
6950     (0xa0000000 <= addr && addr < 0xa0200000))
6951   {
6952     // used for BIOS calls mostly?
6953     *limit = (addr&0xa0000000)|0x00200000;
6954     return (u_int *)(rdram + (addr&0x1fffff));
6955   }
6956   else if (!Config.HLE && (
6957     /* (0x9fc00000 <= addr && addr < 0x9fc80000) ||*/
6958     (0xbfc00000 <= addr && addr < 0xbfc80000)))
6959   {
6960     // BIOS. The multiplier should be much higher as it's uncached 8bit mem,
6961     // but timings in PCSX are too tied to the interpreter's BIAS
6962     if (!HACK_ENABLED(NDHACK_OVERRIDE_CYCLE_M))
6963       cycle_multiplier_active = 200;
6964
6965     *limit = (addr & 0xfff00000) | 0x80000;
6966     return (u_int *)((u_char *)psxR + (addr&0x7ffff));
6967   }
6968   else if (addr >= 0x80000000 && addr < 0x80000000+RAM_SIZE) {
6969     *limit = (addr & 0x80600000) + 0x00200000;
6970     return (u_int *)(rdram + (addr&0x1fffff));
6971   }
6972   return NULL;
6973 }
6974
6975 static u_int scan_for_ret(u_int addr)
6976 {
6977   u_int limit = 0;
6978   u_int *mem;
6979
6980   mem = get_source_start(addr, &limit);
6981   if (mem == NULL)
6982     return addr;
6983
6984   if (limit > addr + 0x1000)
6985     limit = addr + 0x1000;
6986   for (; addr < limit; addr += 4, mem++) {
6987     if (*mem == 0x03e00008) // jr $ra
6988       return addr + 8;
6989   }
6990   return addr;
6991 }
6992
6993 struct savestate_block {
6994   uint32_t addr;
6995   uint32_t regflags;
6996 };
6997
6998 static int addr_cmp(const void *p1_, const void *p2_)
6999 {
7000   const struct savestate_block *p1 = p1_, *p2 = p2_;
7001   return p1->addr - p2->addr;
7002 }
7003
7004 int new_dynarec_save_blocks(void *save, int size)
7005 {
7006   struct savestate_block *blocks = save;
7007   int maxcount = size / sizeof(blocks[0]);
7008   struct savestate_block tmp_blocks[1024];
7009   struct ll_entry *head;
7010   int p, s, d, o, bcnt;
7011   u_int addr;
7012
7013   o = 0;
7014   for (p = 0; p < ARRAY_SIZE(jump_in); p++) {
7015     bcnt = 0;
7016     for (head = jump_in[p]; head != NULL; head = head->next) {
7017       tmp_blocks[bcnt].addr = head->vaddr;
7018       tmp_blocks[bcnt].regflags = head->reg_sv_flags;
7019       bcnt++;
7020     }
7021     if (bcnt < 1)
7022       continue;
7023     qsort(tmp_blocks, bcnt, sizeof(tmp_blocks[0]), addr_cmp);
7024
7025     addr = tmp_blocks[0].addr;
7026     for (s = d = 0; s < bcnt; s++) {
7027       if (tmp_blocks[s].addr < addr)
7028         continue;
7029       if (d == 0 || tmp_blocks[d-1].addr != tmp_blocks[s].addr)
7030         tmp_blocks[d++] = tmp_blocks[s];
7031       addr = scan_for_ret(tmp_blocks[s].addr);
7032     }
7033
7034     if (o + d > maxcount)
7035       d = maxcount - o;
7036     memcpy(&blocks[o], tmp_blocks, d * sizeof(blocks[0]));
7037     o += d;
7038   }
7039
7040   return o * sizeof(blocks[0]);
7041 }
7042
7043 void new_dynarec_load_blocks(const void *save, int size)
7044 {
7045   const struct savestate_block *blocks = save;
7046   int count = size / sizeof(blocks[0]);
7047   u_int regs_save[32];
7048   uint32_t f;
7049   int i, b;
7050
7051   get_addr(psxRegs.pc);
7052
7053   // change GPRs for speculation to at least partially work..
7054   memcpy(regs_save, &psxRegs.GPR, sizeof(regs_save));
7055   for (i = 1; i < 32; i++)
7056     psxRegs.GPR.r[i] = 0x80000000;
7057
7058   for (b = 0; b < count; b++) {
7059     for (f = blocks[b].regflags, i = 0; f; f >>= 1, i++) {
7060       if (f & 1)
7061         psxRegs.GPR.r[i] = 0x1f800000;
7062     }
7063
7064     get_addr(blocks[b].addr);
7065
7066     for (f = blocks[b].regflags, i = 0; f; f >>= 1, i++) {
7067       if (f & 1)
7068         psxRegs.GPR.r[i] = 0x80000000;
7069     }
7070   }
7071
7072   memcpy(&psxRegs.GPR, regs_save, sizeof(regs_save));
7073 }
7074
7075 static int apply_hacks(void)
7076 {
7077   int i;
7078   if (HACK_ENABLED(NDHACK_NO_COMPAT_HACKS))
7079     return 0;
7080   /* special hack(s) */
7081   for (i = 0; i < slen - 4; i++)
7082   {
7083     // lui a4, 0xf200; jal <rcnt_read>; addu a0, 2; slti v0, 28224
7084     if (source[i] == 0x3c04f200 && dops[i+1].itype == UJUMP
7085         && source[i+2] == 0x34840002 && dops[i+3].opcode == 0x0a
7086         && imm[i+3] == 0x6e40 && dops[i+3].rs1 == 2)
7087     {
7088       SysPrintf("PE2 hack @%08x\n", start + (i+3)*4);
7089       dops[i + 3].itype = NOP;
7090     }
7091   }
7092   i = slen;
7093   if (i > 10 && source[i-1] == 0 && source[i-2] == 0x03e00008
7094       && source[i-4] == 0x8fbf0018 && source[i-6] == 0x00c0f809
7095       && dops[i-7].itype == STORE)
7096   {
7097     i = i-8;
7098     if (dops[i].itype == IMM16)
7099       i--;
7100     // swl r2, 15(r6); swr r2, 12(r6); sw r6, *; jalr r6
7101     if (dops[i].itype == STORELR && dops[i].rs1 == 6
7102       && dops[i-1].itype == STORELR && dops[i-1].rs1 == 6)
7103     {
7104       SysPrintf("F1 hack from %08x, old dst %08x\n", start, hack_addr);
7105       f1_hack = 1;
7106       return 1;
7107     }
7108   }
7109   return 0;
7110 }
7111
7112 int new_recompile_block(u_int addr)
7113 {
7114   u_int pagelimit = 0;
7115   u_int state_rflags = 0;
7116   int i;
7117
7118   assem_debug("NOTCOMPILED: addr = %x -> %p\n", addr, out);
7119   //printf("TRACE: count=%d next=%d (compile %x)\n",Count,next_interupt,addr);
7120   //if(debug)
7121   //printf("fpu mapping=%x enabled=%x\n",(Status & 0x04000000)>>26,(Status & 0x20000000)>>29);
7122
7123   // this is just for speculation
7124   for (i = 1; i < 32; i++) {
7125     if ((psxRegs.GPR.r[i] & 0xffff0000) == 0x1f800000)
7126       state_rflags |= 1 << i;
7127   }
7128
7129   start = (u_int)addr&~3;
7130   //assert(((u_int)addr&1)==0); // start-in-delay-slot flag
7131   new_dynarec_did_compile=1;
7132   if (Config.HLE && start == 0x80001000) // hlecall
7133   {
7134     // XXX: is this enough? Maybe check hleSoftCall?
7135     void *beginning=start_block();
7136     u_int page=get_page(start);
7137
7138     invalid_code[start>>12]=0;
7139     emit_movimm(start,0);
7140     emit_writeword(0,&pcaddr);
7141     emit_far_jump(new_dyna_leave);
7142     literal_pool(0);
7143     end_block(beginning);
7144     ll_add_flags(jump_in+page,start,state_rflags,(void *)beginning);
7145     return 0;
7146   }
7147   else if (f1_hack && hack_addr == 0) {
7148     void *beginning = start_block();
7149     u_int page = get_page(start);
7150     emit_movimm(start, 0);
7151     emit_writeword(0, &hack_addr);
7152     emit_readword(&psxRegs.GPR.n.sp, 0);
7153     emit_readptr(&mem_rtab, 1);
7154     emit_shrimm(0, 12, 2);
7155     emit_readptr_dualindexedx_ptrlen(1, 2, 1);
7156     emit_addimm(0, 0x18, 0);
7157     emit_adds_ptr(1, 1, 1);
7158     emit_ldr_dualindexed(1, 0, 0);
7159     emit_writeword(0, &psxRegs.GPR.r[26]); // lw k0, 0x18(sp)
7160     emit_far_call(get_addr_ht);
7161     emit_jmpreg(0); // jr k0
7162     literal_pool(0);
7163     end_block(beginning);
7164
7165     ll_add_flags(jump_in + page, start, state_rflags, beginning);
7166     SysPrintf("F1 hack to   %08x\n", start);
7167     return 0;
7168   }
7169
7170   cycle_multiplier_active = cycle_multiplier_override && cycle_multiplier == CYCLE_MULT_DEFAULT
7171     ? cycle_multiplier_override : cycle_multiplier;
7172
7173   source = get_source_start(start, &pagelimit);
7174   if (source == NULL) {
7175     SysPrintf("Compile at bogus memory address: %08x\n", addr);
7176     abort();
7177   }
7178
7179   /* Pass 1: disassemble */
7180   /* Pass 2: register dependencies, branch targets */
7181   /* Pass 3: register allocation */
7182   /* Pass 4: branch dependencies */
7183   /* Pass 5: pre-alloc */
7184   /* Pass 6: optimize clean/dirty state */
7185   /* Pass 7: flag 32-bit registers */
7186   /* Pass 8: assembly */
7187   /* Pass 9: linker */
7188   /* Pass 10: garbage collection / free memory */
7189
7190   int j;
7191   int done=0;
7192   unsigned int type,op,op2;
7193
7194   //printf("addr = %x source = %x %x\n", addr,source,source[0]);
7195
7196   /* Pass 1 disassembly */
7197
7198   for (i = 0; !done; i++)
7199   {
7200     memset(&dops[i], 0, sizeof(dops[i]));
7201     op2=0;
7202     minimum_free_regs[i]=0;
7203     dops[i].opcode=op=source[i]>>26;
7204     switch(op)
7205     {
7206       case 0x00: strcpy(insn[i],"special"); type=NI;
7207         op2=source[i]&0x3f;
7208         switch(op2)
7209         {
7210           case 0x00: strcpy(insn[i],"SLL"); type=SHIFTIMM; break;
7211           case 0x02: strcpy(insn[i],"SRL"); type=SHIFTIMM; break;
7212           case 0x03: strcpy(insn[i],"SRA"); type=SHIFTIMM; break;
7213           case 0x04: strcpy(insn[i],"SLLV"); type=SHIFT; break;
7214           case 0x06: strcpy(insn[i],"SRLV"); type=SHIFT; break;
7215           case 0x07: strcpy(insn[i],"SRAV"); type=SHIFT; break;
7216           case 0x08: strcpy(insn[i],"JR"); type=RJUMP; break;
7217           case 0x09: strcpy(insn[i],"JALR"); type=RJUMP; break;
7218           case 0x0C: strcpy(insn[i],"SYSCALL"); type=SYSCALL; break;
7219           case 0x0D: strcpy(insn[i],"BREAK"); type=SYSCALL; break;
7220           case 0x0F: strcpy(insn[i],"SYNC"); type=OTHER; break;
7221           case 0x10: strcpy(insn[i],"MFHI"); type=MOV; break;
7222           case 0x11: strcpy(insn[i],"MTHI"); type=MOV; break;
7223           case 0x12: strcpy(insn[i],"MFLO"); type=MOV; break;
7224           case 0x13: strcpy(insn[i],"MTLO"); type=MOV; break;
7225           case 0x18: strcpy(insn[i],"MULT"); type=MULTDIV; break;
7226           case 0x19: strcpy(insn[i],"MULTU"); type=MULTDIV; break;
7227           case 0x1A: strcpy(insn[i],"DIV"); type=MULTDIV; break;
7228           case 0x1B: strcpy(insn[i],"DIVU"); type=MULTDIV; break;
7229           case 0x20: strcpy(insn[i],"ADD"); type=ALU; break;
7230           case 0x21: strcpy(insn[i],"ADDU"); type=ALU; break;
7231           case 0x22: strcpy(insn[i],"SUB"); type=ALU; break;
7232           case 0x23: strcpy(insn[i],"SUBU"); type=ALU; break;
7233           case 0x24: strcpy(insn[i],"AND"); type=ALU; break;
7234           case 0x25: strcpy(insn[i],"OR"); type=ALU; break;
7235           case 0x26: strcpy(insn[i],"XOR"); type=ALU; break;
7236           case 0x27: strcpy(insn[i],"NOR"); type=ALU; break;
7237           case 0x2A: strcpy(insn[i],"SLT"); type=ALU; break;
7238           case 0x2B: strcpy(insn[i],"SLTU"); type=ALU; break;
7239           case 0x30: strcpy(insn[i],"TGE"); type=NI; break;
7240           case 0x31: strcpy(insn[i],"TGEU"); type=NI; break;
7241           case 0x32: strcpy(insn[i],"TLT"); type=NI; break;
7242           case 0x33: strcpy(insn[i],"TLTU"); type=NI; break;
7243           case 0x34: strcpy(insn[i],"TEQ"); type=NI; break;
7244           case 0x36: strcpy(insn[i],"TNE"); type=NI; break;
7245 #if 0
7246           case 0x14: strcpy(insn[i],"DSLLV"); type=SHIFT; break;
7247           case 0x16: strcpy(insn[i],"DSRLV"); type=SHIFT; break;
7248           case 0x17: strcpy(insn[i],"DSRAV"); type=SHIFT; break;
7249           case 0x1C: strcpy(insn[i],"DMULT"); type=MULTDIV; break;
7250           case 0x1D: strcpy(insn[i],"DMULTU"); type=MULTDIV; break;
7251           case 0x1E: strcpy(insn[i],"DDIV"); type=MULTDIV; break;
7252           case 0x1F: strcpy(insn[i],"DDIVU"); type=MULTDIV; break;
7253           case 0x2C: strcpy(insn[i],"DADD"); type=ALU; break;
7254           case 0x2D: strcpy(insn[i],"DADDU"); type=ALU; break;
7255           case 0x2E: strcpy(insn[i],"DSUB"); type=ALU; break;
7256           case 0x2F: strcpy(insn[i],"DSUBU"); type=ALU; break;
7257           case 0x38: strcpy(insn[i],"DSLL"); type=SHIFTIMM; break;
7258           case 0x3A: strcpy(insn[i],"DSRL"); type=SHIFTIMM; break;
7259           case 0x3B: strcpy(insn[i],"DSRA"); type=SHIFTIMM; break;
7260           case 0x3C: strcpy(insn[i],"DSLL32"); type=SHIFTIMM; break;
7261           case 0x3E: strcpy(insn[i],"DSRL32"); type=SHIFTIMM; break;
7262           case 0x3F: strcpy(insn[i],"DSRA32"); type=SHIFTIMM; break;
7263 #endif
7264         }
7265         break;
7266       case 0x01: strcpy(insn[i],"regimm"); type=NI;
7267         op2=(source[i]>>16)&0x1f;
7268         switch(op2)
7269         {
7270           case 0x00: strcpy(insn[i],"BLTZ"); type=SJUMP; break;
7271           case 0x01: strcpy(insn[i],"BGEZ"); type=SJUMP; break;
7272           //case 0x02: strcpy(insn[i],"BLTZL"); type=SJUMP; break;
7273           //case 0x03: strcpy(insn[i],"BGEZL"); type=SJUMP; break;
7274           //case 0x08: strcpy(insn[i],"TGEI"); type=NI; break;
7275           //case 0x09: strcpy(insn[i],"TGEIU"); type=NI; break;
7276           //case 0x0A: strcpy(insn[i],"TLTI"); type=NI; break;
7277           //case 0x0B: strcpy(insn[i],"TLTIU"); type=NI; break;
7278           //case 0x0C: strcpy(insn[i],"TEQI"); type=NI; break;
7279           //case 0x0E: strcpy(insn[i],"TNEI"); type=NI; break;
7280           case 0x10: strcpy(insn[i],"BLTZAL"); type=SJUMP; break;
7281           case 0x11: strcpy(insn[i],"BGEZAL"); type=SJUMP; break;
7282           //case 0x12: strcpy(insn[i],"BLTZALL"); type=SJUMP; break;
7283           //case 0x13: strcpy(insn[i],"BGEZALL"); type=SJUMP; break;
7284         }
7285         break;
7286       case 0x02: strcpy(insn[i],"J"); type=UJUMP; break;
7287       case 0x03: strcpy(insn[i],"JAL"); type=UJUMP; break;
7288       case 0x04: strcpy(insn[i],"BEQ"); type=CJUMP; break;
7289       case 0x05: strcpy(insn[i],"BNE"); type=CJUMP; break;
7290       case 0x06: strcpy(insn[i],"BLEZ"); type=CJUMP; break;
7291       case 0x07: strcpy(insn[i],"BGTZ"); type=CJUMP; break;
7292       case 0x08: strcpy(insn[i],"ADDI"); type=IMM16; break;
7293       case 0x09: strcpy(insn[i],"ADDIU"); type=IMM16; break;
7294       case 0x0A: strcpy(insn[i],"SLTI"); type=IMM16; break;
7295       case 0x0B: strcpy(insn[i],"SLTIU"); type=IMM16; break;
7296       case 0x0C: strcpy(insn[i],"ANDI"); type=IMM16; break;
7297       case 0x0D: strcpy(insn[i],"ORI"); type=IMM16; break;
7298       case 0x0E: strcpy(insn[i],"XORI"); type=IMM16; break;
7299       case 0x0F: strcpy(insn[i],"LUI"); type=IMM16; break;
7300       case 0x10: strcpy(insn[i],"cop0"); type=NI;
7301         op2=(source[i]>>21)&0x1f;
7302         switch(op2)
7303         {
7304           case 0x00: strcpy(insn[i],"MFC0"); type=COP0; break;
7305           case 0x02: strcpy(insn[i],"CFC0"); type=COP0; break;
7306           case 0x04: strcpy(insn[i],"MTC0"); type=COP0; break;
7307           case 0x06: strcpy(insn[i],"CTC0"); type=COP0; break;
7308           case 0x10: strcpy(insn[i],"RFE"); type=COP0; break;
7309         }
7310         break;
7311       case 0x11: strcpy(insn[i],"cop1"); type=COP1;
7312         op2=(source[i]>>21)&0x1f;
7313         break;
7314 #if 0
7315       case 0x14: strcpy(insn[i],"BEQL"); type=CJUMP; break;
7316       case 0x15: strcpy(insn[i],"BNEL"); type=CJUMP; break;
7317       case 0x16: strcpy(insn[i],"BLEZL"); type=CJUMP; break;
7318       case 0x17: strcpy(insn[i],"BGTZL"); type=CJUMP; break;
7319       case 0x18: strcpy(insn[i],"DADDI"); type=IMM16; break;
7320       case 0x19: strcpy(insn[i],"DADDIU"); type=IMM16; break;
7321       case 0x1A: strcpy(insn[i],"LDL"); type=LOADLR; break;
7322       case 0x1B: strcpy(insn[i],"LDR"); type=LOADLR; break;
7323 #endif
7324       case 0x20: strcpy(insn[i],"LB"); type=LOAD; break;
7325       case 0x21: strcpy(insn[i],"LH"); type=LOAD; break;
7326       case 0x22: strcpy(insn[i],"LWL"); type=LOADLR; break;
7327       case 0x23: strcpy(insn[i],"LW"); type=LOAD; break;
7328       case 0x24: strcpy(insn[i],"LBU"); type=LOAD; break;
7329       case 0x25: strcpy(insn[i],"LHU"); type=LOAD; break;
7330       case 0x26: strcpy(insn[i],"LWR"); type=LOADLR; break;
7331 #if 0
7332       case 0x27: strcpy(insn[i],"LWU"); type=LOAD; break;
7333 #endif
7334       case 0x28: strcpy(insn[i],"SB"); type=STORE; break;
7335       case 0x29: strcpy(insn[i],"SH"); type=STORE; break;
7336       case 0x2A: strcpy(insn[i],"SWL"); type=STORELR; break;
7337       case 0x2B: strcpy(insn[i],"SW"); type=STORE; break;
7338 #if 0
7339       case 0x2C: strcpy(insn[i],"SDL"); type=STORELR; break;
7340       case 0x2D: strcpy(insn[i],"SDR"); type=STORELR; break;
7341 #endif
7342       case 0x2E: strcpy(insn[i],"SWR"); type=STORELR; break;
7343       case 0x2F: strcpy(insn[i],"CACHE"); type=NOP; break;
7344       case 0x30: strcpy(insn[i],"LL"); type=NI; break;
7345       case 0x31: strcpy(insn[i],"LWC1"); type=C1LS; break;
7346 #if 0
7347       case 0x34: strcpy(insn[i],"LLD"); type=NI; break;
7348       case 0x35: strcpy(insn[i],"LDC1"); type=C1LS; break;
7349       case 0x37: strcpy(insn[i],"LD"); type=LOAD; break;
7350 #endif
7351       case 0x38: strcpy(insn[i],"SC"); type=NI; break;
7352       case 0x39: strcpy(insn[i],"SWC1"); type=C1LS; break;
7353 #if 0
7354       case 0x3C: strcpy(insn[i],"SCD"); type=NI; break;
7355       case 0x3D: strcpy(insn[i],"SDC1"); type=C1LS; break;
7356       case 0x3F: strcpy(insn[i],"SD"); type=STORE; break;
7357 #endif
7358       case 0x12: strcpy(insn[i],"COP2"); type=NI;
7359         op2=(source[i]>>21)&0x1f;
7360         //if (op2 & 0x10)
7361         if (source[i]&0x3f) { // use this hack to support old savestates with patched gte insns
7362           if (gte_handlers[source[i]&0x3f]!=NULL) {
7363             if (gte_regnames[source[i]&0x3f]!=NULL)
7364               strcpy(insn[i],gte_regnames[source[i]&0x3f]);
7365             else
7366               snprintf(insn[i], sizeof(insn[i]), "COP2 %x", source[i]&0x3f);
7367             type=C2OP;
7368           }
7369         }
7370         else switch(op2)
7371         {
7372           case 0x00: strcpy(insn[i],"MFC2"); type=COP2; break;
7373           case 0x02: strcpy(insn[i],"CFC2"); type=COP2; break;
7374           case 0x04: strcpy(insn[i],"MTC2"); type=COP2; break;
7375           case 0x06: strcpy(insn[i],"CTC2"); type=COP2; break;
7376         }
7377         break;
7378       case 0x32: strcpy(insn[i],"LWC2"); type=C2LS; break;
7379       case 0x3A: strcpy(insn[i],"SWC2"); type=C2LS; break;
7380       case 0x3B: strcpy(insn[i],"HLECALL"); type=HLECALL; break;
7381       default: strcpy(insn[i],"???"); type=NI;
7382         SysPrintf("NI %08x @%08x (%08x)\n", source[i], addr + i*4, addr);
7383         break;
7384     }
7385     dops[i].itype=type;
7386     dops[i].opcode2=op2;
7387     /* Get registers/immediates */
7388     dops[i].lt1=0;
7389     gte_rs[i]=gte_rt[i]=0;
7390     switch(type) {
7391       case LOAD:
7392         dops[i].rs1=(source[i]>>21)&0x1f;
7393         dops[i].rs2=0;
7394         dops[i].rt1=(source[i]>>16)&0x1f;
7395         dops[i].rt2=0;
7396         imm[i]=(short)source[i];
7397         break;
7398       case STORE:
7399       case STORELR:
7400         dops[i].rs1=(source[i]>>21)&0x1f;
7401         dops[i].rs2=(source[i]>>16)&0x1f;
7402         dops[i].rt1=0;
7403         dops[i].rt2=0;
7404         imm[i]=(short)source[i];
7405         break;
7406       case LOADLR:
7407         // LWL/LWR only load part of the register,
7408         // therefore the target register must be treated as a source too
7409         dops[i].rs1=(source[i]>>21)&0x1f;
7410         dops[i].rs2=(source[i]>>16)&0x1f;
7411         dops[i].rt1=(source[i]>>16)&0x1f;
7412         dops[i].rt2=0;
7413         imm[i]=(short)source[i];
7414         break;
7415       case IMM16:
7416         if (op==0x0f) dops[i].rs1=0; // LUI instruction has no source register
7417         else dops[i].rs1=(source[i]>>21)&0x1f;
7418         dops[i].rs2=0;
7419         dops[i].rt1=(source[i]>>16)&0x1f;
7420         dops[i].rt2=0;
7421         if(op>=0x0c&&op<=0x0e) { // ANDI/ORI/XORI
7422           imm[i]=(unsigned short)source[i];
7423         }else{
7424           imm[i]=(short)source[i];
7425         }
7426         break;
7427       case UJUMP:
7428         dops[i].rs1=0;
7429         dops[i].rs2=0;
7430         dops[i].rt1=0;
7431         dops[i].rt2=0;
7432         // The JAL instruction writes to r31.
7433         if (op&1) {
7434           dops[i].rt1=31;
7435         }
7436         dops[i].rs2=CCREG;
7437         break;
7438       case RJUMP:
7439         dops[i].rs1=(source[i]>>21)&0x1f;
7440         dops[i].rs2=0;
7441         dops[i].rt1=0;
7442         dops[i].rt2=0;
7443         // The JALR instruction writes to rd.
7444         if (op2&1) {
7445           dops[i].rt1=(source[i]>>11)&0x1f;
7446         }
7447         dops[i].rs2=CCREG;
7448         break;
7449       case CJUMP:
7450         dops[i].rs1=(source[i]>>21)&0x1f;
7451         dops[i].rs2=(source[i]>>16)&0x1f;
7452         dops[i].rt1=0;
7453         dops[i].rt2=0;
7454         if(op&2) { // BGTZ/BLEZ
7455           dops[i].rs2=0;
7456         }
7457         break;
7458       case SJUMP:
7459         dops[i].rs1=(source[i]>>21)&0x1f;
7460         dops[i].rs2=CCREG;
7461         dops[i].rt1=0;
7462         dops[i].rt2=0;
7463         if(op2&0x10) { // BxxAL
7464           dops[i].rt1=31;
7465           // NOTE: If the branch is not taken, r31 is still overwritten
7466         }
7467         break;
7468       case ALU:
7469         dops[i].rs1=(source[i]>>21)&0x1f; // source
7470         dops[i].rs2=(source[i]>>16)&0x1f; // subtract amount
7471         dops[i].rt1=(source[i]>>11)&0x1f; // destination
7472         dops[i].rt2=0;
7473         break;
7474       case MULTDIV:
7475         dops[i].rs1=(source[i]>>21)&0x1f; // source
7476         dops[i].rs2=(source[i]>>16)&0x1f; // divisor
7477         dops[i].rt1=HIREG;
7478         dops[i].rt2=LOREG;
7479         break;
7480       case MOV:
7481         dops[i].rs1=0;
7482         dops[i].rs2=0;
7483         dops[i].rt1=0;
7484         dops[i].rt2=0;
7485         if(op2==0x10) dops[i].rs1=HIREG; // MFHI
7486         if(op2==0x11) dops[i].rt1=HIREG; // MTHI
7487         if(op2==0x12) dops[i].rs1=LOREG; // MFLO
7488         if(op2==0x13) dops[i].rt1=LOREG; // MTLO
7489         if((op2&0x1d)==0x10) dops[i].rt1=(source[i]>>11)&0x1f; // MFxx
7490         if((op2&0x1d)==0x11) dops[i].rs1=(source[i]>>21)&0x1f; // MTxx
7491         break;
7492       case SHIFT:
7493         dops[i].rs1=(source[i]>>16)&0x1f; // target of shift
7494         dops[i].rs2=(source[i]>>21)&0x1f; // shift amount
7495         dops[i].rt1=(source[i]>>11)&0x1f; // destination
7496         dops[i].rt2=0;
7497         break;
7498       case SHIFTIMM:
7499         dops[i].rs1=(source[i]>>16)&0x1f;
7500         dops[i].rs2=0;
7501         dops[i].rt1=(source[i]>>11)&0x1f;
7502         dops[i].rt2=0;
7503         imm[i]=(source[i]>>6)&0x1f;
7504         // DSxx32 instructions
7505         if(op2>=0x3c) imm[i]|=0x20;
7506         break;
7507       case COP0:
7508         dops[i].rs1=0;
7509         dops[i].rs2=0;
7510         dops[i].rt1=0;
7511         dops[i].rt2=0;
7512         if(op2==0||op2==2) dops[i].rt1=(source[i]>>16)&0x1F; // MFC0/CFC0
7513         if(op2==4||op2==6) dops[i].rs1=(source[i]>>16)&0x1F; // MTC0/CTC0
7514         if(op2==4&&((source[i]>>11)&0x1f)==12) dops[i].rt2=CSREG; // Status
7515         if(op2==16) if((source[i]&0x3f)==0x18) dops[i].rs2=CCREG; // ERET
7516         break;
7517       case COP1:
7518         dops[i].rs1=0;
7519         dops[i].rs2=0;
7520         dops[i].rt1=0;
7521         dops[i].rt2=0;
7522         if(op2<3) dops[i].rt1=(source[i]>>16)&0x1F; // MFC1/DMFC1/CFC1
7523         if(op2>3) dops[i].rs1=(source[i]>>16)&0x1F; // MTC1/DMTC1/CTC1
7524         dops[i].rs2=CSREG;
7525         break;
7526       case COP2:
7527         dops[i].rs1=0;
7528         dops[i].rs2=0;
7529         dops[i].rt1=0;
7530         dops[i].rt2=0;
7531         if(op2<3) dops[i].rt1=(source[i]>>16)&0x1F; // MFC2/CFC2
7532         if(op2>3) dops[i].rs1=(source[i]>>16)&0x1F; // MTC2/CTC2
7533         dops[i].rs2=CSREG;
7534         int gr=(source[i]>>11)&0x1F;
7535         switch(op2)
7536         {
7537           case 0x00: gte_rs[i]=1ll<<gr; break; // MFC2
7538           case 0x04: gte_rt[i]=1ll<<gr; break; // MTC2
7539           case 0x02: gte_rs[i]=1ll<<(gr+32); break; // CFC2
7540           case 0x06: gte_rt[i]=1ll<<(gr+32); break; // CTC2
7541         }
7542         break;
7543       case C1LS:
7544         dops[i].rs1=(source[i]>>21)&0x1F;
7545         dops[i].rs2=CSREG;
7546         dops[i].rt1=0;
7547         dops[i].rt2=0;
7548         imm[i]=(short)source[i];
7549         break;
7550       case C2LS:
7551         dops[i].rs1=(source[i]>>21)&0x1F;
7552         dops[i].rs2=0;
7553         dops[i].rt1=0;
7554         dops[i].rt2=0;
7555         imm[i]=(short)source[i];
7556         if(op==0x32) gte_rt[i]=1ll<<((source[i]>>16)&0x1F); // LWC2
7557         else gte_rs[i]=1ll<<((source[i]>>16)&0x1F); // SWC2
7558         break;
7559       case C2OP:
7560         dops[i].rs1=0;
7561         dops[i].rs2=0;
7562         dops[i].rt1=0;
7563         dops[i].rt2=0;
7564         gte_rs[i]=gte_reg_reads[source[i]&0x3f];
7565         gte_rt[i]=gte_reg_writes[source[i]&0x3f];
7566         gte_rt[i]|=1ll<<63; // every op changes flags
7567         if((source[i]&0x3f)==GTE_MVMVA) {
7568           int v = (source[i] >> 15) & 3;
7569           gte_rs[i]&=~0xe3fll;
7570           if(v==3) gte_rs[i]|=0xe00ll;
7571           else gte_rs[i]|=3ll<<(v*2);
7572         }
7573         break;
7574       case SYSCALL:
7575       case HLECALL:
7576       case INTCALL:
7577         dops[i].rs1=CCREG;
7578         dops[i].rs2=0;
7579         dops[i].rt1=0;
7580         dops[i].rt2=0;
7581         break;
7582       default:
7583         dops[i].rs1=0;
7584         dops[i].rs2=0;
7585         dops[i].rt1=0;
7586         dops[i].rt2=0;
7587     }
7588     /* Calculate branch target addresses */
7589     if(type==UJUMP)
7590       ba[i]=((start+i*4+4)&0xF0000000)|(((unsigned int)source[i]<<6)>>4);
7591     else if(type==CJUMP&&dops[i].rs1==dops[i].rs2&&(op&1))
7592       ba[i]=start+i*4+8; // Ignore never taken branch
7593     else if(type==SJUMP&&dops[i].rs1==0&&!(op2&1))
7594       ba[i]=start+i*4+8; // Ignore never taken branch
7595     else if(type==CJUMP||type==SJUMP)
7596       ba[i]=start+i*4+4+((signed int)((unsigned int)source[i]<<16)>>14);
7597     else ba[i]=-1;
7598
7599     /* simplify always (not)taken branches */
7600     if (type == CJUMP && dops[i].rs1 == dops[i].rs2) {
7601       dops[i].rs1 = dops[i].rs2 = 0;
7602       if (!(op & 1)) {
7603         dops[i].itype = type = UJUMP;
7604         dops[i].rs2 = CCREG;
7605       }
7606     }
7607     else if (type == SJUMP && dops[i].rs1 == 0 && (op2 & 1))
7608       dops[i].itype = type = UJUMP;
7609
7610     dops[i].is_jump = (dops[i].itype == RJUMP || dops[i].itype == UJUMP || dops[i].itype == CJUMP || dops[i].itype == SJUMP);
7611     dops[i].is_ujump = (dops[i].itype == RJUMP || dops[i].itype == UJUMP); // || (source[i] >> 16) == 0x1000 // beq r0,r0
7612     dops[i].is_load = (dops[i].itype == LOAD || dops[i].itype == LOADLR || op == 0x32); // LWC2
7613     dops[i].is_store = (dops[i].itype == STORE || dops[i].itype == STORELR || op == 0x3a); // SWC2
7614
7615     /* messy cases to just pass over to the interpreter */
7616     if (i > 0 && dops[i-1].is_jump) {
7617       int do_in_intrp=0;
7618       // branch in delay slot?
7619       if (dops[i].is_jump) {
7620         // don't handle first branch and call interpreter if it's hit
7621         SysPrintf("branch in delay slot @%08x (%08x)\n", addr + i*4, addr);
7622         do_in_intrp=1;
7623       }
7624       // basic load delay detection
7625       else if((type==LOAD||type==LOADLR||type==COP0||type==COP2||type==C2LS)&&dops[i].rt1!=0) {
7626         int t=(ba[i-1]-start)/4;
7627         if(0 <= t && t < i &&(dops[i].rt1==dops[t].rs1||dops[i].rt1==dops[t].rs2)&&dops[t].itype!=CJUMP&&dops[t].itype!=SJUMP) {
7628           // jump target wants DS result - potential load delay effect
7629           SysPrintf("load delay @%08x (%08x)\n", addr + i*4, addr);
7630           do_in_intrp=1;
7631           dops[t+1].bt=1; // expected return from interpreter
7632         }
7633         else if(i>=2&&dops[i-2].rt1==2&&dops[i].rt1==2&&dops[i].rs1!=2&&dops[i].rs2!=2&&dops[i-1].rs1!=2&&dops[i-1].rs2!=2&&
7634               !(i>=3&&dops[i-3].is_jump)) {
7635           // v0 overwrite like this is a sign of trouble, bail out
7636           SysPrintf("v0 overwrite @%08x (%08x)\n", addr + i*4, addr);
7637           do_in_intrp=1;
7638         }
7639       }
7640       if (do_in_intrp) {
7641         memset(&dops[i-1], 0, sizeof(dops[i-1]));
7642         dops[i-1].itype = INTCALL;
7643         dops[i-1].rs1 = CCREG;
7644         ba[i-1] = -1;
7645         done = 2;
7646         i--; // don't compile the DS
7647       }
7648     }
7649
7650     /* Is this the end of the block? */
7651     if (i > 0 && dops[i-1].is_ujump) {
7652       if(dops[i-1].rt1==0) { // Continue past subroutine call (JAL)
7653         done=2;
7654       }
7655       else {
7656         if(stop_after_jal) done=1;
7657         // Stop on BREAK
7658         if((source[i+1]&0xfc00003f)==0x0d) done=1;
7659       }
7660       // Don't recompile stuff that's already compiled
7661       if(check_addr(start+i*4+4)) done=1;
7662       // Don't get too close to the limit
7663       if(i>MAXBLOCK/2) done=1;
7664     }
7665     if (dops[i].itype == SYSCALL || dops[i].itype == HLECALL || dops[i].itype == INTCALL)
7666       done = stop_after_jal ? 1 : 2;
7667     if (done == 2) {
7668       // Does the block continue due to a branch?
7669       for(j=i-1;j>=0;j--)
7670       {
7671         if(ba[j]==start+i*4) done=j=0; // Branch into delay slot
7672         if(ba[j]==start+i*4+4) done=j=0;
7673         if(ba[j]==start+i*4+8) done=j=0;
7674       }
7675     }
7676     //assert(i<MAXBLOCK-1);
7677     if(start+i*4==pagelimit-4) done=1;
7678     assert(start+i*4<pagelimit);
7679     if (i==MAXBLOCK-1) done=1;
7680     // Stop if we're compiling junk
7681     if(dops[i].itype==NI&&dops[i].opcode==0x11) {
7682       done=stop_after_jal=1;
7683       SysPrintf("Disabled speculative precompilation\n");
7684     }
7685   }
7686   slen=i;
7687   if (dops[i-1].is_jump) {
7688     if(start+i*4==pagelimit) {
7689       dops[i-1].itype=SPAN;
7690     }
7691   }
7692   assert(slen>0);
7693
7694   int clear_hack_addr = apply_hacks();
7695
7696   /* Pass 2 - Register dependencies and branch targets */
7697
7698   unneeded_registers(0,slen-1,0);
7699
7700   /* Pass 3 - Register allocation */
7701
7702   struct regstat current; // Current register allocations/status
7703   current.dirty=0;
7704   current.u=unneeded_reg[0];
7705   clear_all_regs(current.regmap);
7706   alloc_reg(&current,0,CCREG);
7707   dirty_reg(&current,CCREG);
7708   current.isconst=0;
7709   current.wasconst=0;
7710   current.waswritten=0;
7711   int ds=0;
7712   int cc=0;
7713   int hr=-1;
7714
7715   if((u_int)addr&1) {
7716     // First instruction is delay slot
7717     cc=-1;
7718     dops[1].bt=1;
7719     ds=1;
7720     unneeded_reg[0]=1;
7721     current.regmap[HOST_BTREG]=BTREG;
7722   }
7723
7724   for(i=0;i<slen;i++)
7725   {
7726     if(dops[i].bt)
7727     {
7728       int hr;
7729       for(hr=0;hr<HOST_REGS;hr++)
7730       {
7731         // Is this really necessary?
7732         if(current.regmap[hr]==0) current.regmap[hr]=-1;
7733       }
7734       current.isconst=0;
7735       current.waswritten=0;
7736     }
7737
7738     memcpy(regmap_pre[i],current.regmap,sizeof(current.regmap));
7739     regs[i].wasconst=current.isconst;
7740     regs[i].wasdirty=current.dirty;
7741     regs[i].loadedconst=0;
7742     if (!dops[i].is_jump) {
7743       if(i+1<slen) {
7744         current.u=unneeded_reg[i+1]&~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
7745         current.u|=1;
7746       } else {
7747         current.u=1;
7748       }
7749     } else {
7750       if(i+1<slen) {
7751         current.u=branch_unneeded_reg[i]&~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
7752         current.u&=~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
7753         current.u|=1;
7754       } else {
7755         SysPrintf("oops, branch at end of block with no delay slot @%08x\n", start + i*4);
7756         abort();
7757       }
7758     }
7759     dops[i].is_ds=ds;
7760     if(ds) {
7761       ds=0; // Skip delay slot, already allocated as part of branch
7762       // ...but we need to alloc it in case something jumps here
7763       if(i+1<slen) {
7764         current.u=branch_unneeded_reg[i-1]&unneeded_reg[i+1];
7765       }else{
7766         current.u=branch_unneeded_reg[i-1];
7767       }
7768       current.u&=~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
7769       current.u|=1;
7770       struct regstat temp;
7771       memcpy(&temp,&current,sizeof(current));
7772       temp.wasdirty=temp.dirty;
7773       // TODO: Take into account unconditional branches, as below
7774       delayslot_alloc(&temp,i);
7775       memcpy(regs[i].regmap,temp.regmap,sizeof(temp.regmap));
7776       regs[i].wasdirty=temp.wasdirty;
7777       regs[i].dirty=temp.dirty;
7778       regs[i].isconst=0;
7779       regs[i].wasconst=0;
7780       current.isconst=0;
7781       // Create entry (branch target) regmap
7782       for(hr=0;hr<HOST_REGS;hr++)
7783       {
7784         int r=temp.regmap[hr];
7785         if(r>=0) {
7786           if(r!=regmap_pre[i][hr]) {
7787             regs[i].regmap_entry[hr]=-1;
7788           }
7789           else
7790           {
7791               assert(r < 64);
7792               if((current.u>>r)&1) {
7793                 regs[i].regmap_entry[hr]=-1;
7794                 regs[i].regmap[hr]=-1;
7795                 //Don't clear regs in the delay slot as the branch might need them
7796                 //current.regmap[hr]=-1;
7797               }else
7798                 regs[i].regmap_entry[hr]=r;
7799           }
7800         } else {
7801           // First instruction expects CCREG to be allocated
7802           if(i==0&&hr==HOST_CCREG)
7803             regs[i].regmap_entry[hr]=CCREG;
7804           else
7805             regs[i].regmap_entry[hr]=-1;
7806         }
7807       }
7808     }
7809     else { // Not delay slot
7810       switch(dops[i].itype) {
7811         case UJUMP:
7812           //current.isconst=0; // DEBUG
7813           //current.wasconst=0; // DEBUG
7814           //regs[i].wasconst=0; // DEBUG
7815           clear_const(&current,dops[i].rt1);
7816           alloc_cc(&current,i);
7817           dirty_reg(&current,CCREG);
7818           if (dops[i].rt1==31) {
7819             alloc_reg(&current,i,31);
7820             dirty_reg(&current,31);
7821             //assert(dops[i+1].rs1!=31&&dops[i+1].rs2!=31);
7822             //assert(dops[i+1].rt1!=dops[i].rt1);
7823             #ifdef REG_PREFETCH
7824             alloc_reg(&current,i,PTEMP);
7825             #endif
7826           }
7827           dops[i].ooo=1;
7828           delayslot_alloc(&current,i+1);
7829           //current.isconst=0; // DEBUG
7830           ds=1;
7831           //printf("i=%d, isconst=%x\n",i,current.isconst);
7832           break;
7833         case RJUMP:
7834           //current.isconst=0;
7835           //current.wasconst=0;
7836           //regs[i].wasconst=0;
7837           clear_const(&current,dops[i].rs1);
7838           clear_const(&current,dops[i].rt1);
7839           alloc_cc(&current,i);
7840           dirty_reg(&current,CCREG);
7841           if (!ds_writes_rjump_rs(i)) {
7842             alloc_reg(&current,i,dops[i].rs1);
7843             if (dops[i].rt1!=0) {
7844               alloc_reg(&current,i,dops[i].rt1);
7845               dirty_reg(&current,dops[i].rt1);
7846               assert(dops[i+1].rs1!=dops[i].rt1&&dops[i+1].rs2!=dops[i].rt1);
7847               assert(dops[i+1].rt1!=dops[i].rt1);
7848               #ifdef REG_PREFETCH
7849               alloc_reg(&current,i,PTEMP);
7850               #endif
7851             }
7852             #ifdef USE_MINI_HT
7853             if(dops[i].rs1==31) { // JALR
7854               alloc_reg(&current,i,RHASH);
7855               alloc_reg(&current,i,RHTBL);
7856             }
7857             #endif
7858             delayslot_alloc(&current,i+1);
7859           } else {
7860             // The delay slot overwrites our source register,
7861             // allocate a temporary register to hold the old value.
7862             current.isconst=0;
7863             current.wasconst=0;
7864             regs[i].wasconst=0;
7865             delayslot_alloc(&current,i+1);
7866             current.isconst=0;
7867             alloc_reg(&current,i,RTEMP);
7868           }
7869           //current.isconst=0; // DEBUG
7870           dops[i].ooo=1;
7871           ds=1;
7872           break;
7873         case CJUMP:
7874           //current.isconst=0;
7875           //current.wasconst=0;
7876           //regs[i].wasconst=0;
7877           clear_const(&current,dops[i].rs1);
7878           clear_const(&current,dops[i].rs2);
7879           if((dops[i].opcode&0x3E)==4) // BEQ/BNE
7880           {
7881             alloc_cc(&current,i);
7882             dirty_reg(&current,CCREG);
7883             if(dops[i].rs1) alloc_reg(&current,i,dops[i].rs1);
7884             if(dops[i].rs2) alloc_reg(&current,i,dops[i].rs2);
7885             if((dops[i].rs1&&(dops[i].rs1==dops[i+1].rt1||dops[i].rs1==dops[i+1].rt2))||
7886                (dops[i].rs2&&(dops[i].rs2==dops[i+1].rt1||dops[i].rs2==dops[i+1].rt2))) {
7887               // The delay slot overwrites one of our conditions.
7888               // Allocate the branch condition registers instead.
7889               current.isconst=0;
7890               current.wasconst=0;
7891               regs[i].wasconst=0;
7892               if(dops[i].rs1) alloc_reg(&current,i,dops[i].rs1);
7893               if(dops[i].rs2) alloc_reg(&current,i,dops[i].rs2);
7894             }
7895             else
7896             {
7897               dops[i].ooo=1;
7898               delayslot_alloc(&current,i+1);
7899             }
7900           }
7901           else
7902           if((dops[i].opcode&0x3E)==6) // BLEZ/BGTZ
7903           {
7904             alloc_cc(&current,i);
7905             dirty_reg(&current,CCREG);
7906             alloc_reg(&current,i,dops[i].rs1);
7907             if(dops[i].rs1&&(dops[i].rs1==dops[i+1].rt1||dops[i].rs1==dops[i+1].rt2)) {
7908               // The delay slot overwrites one of our conditions.
7909               // Allocate the branch condition registers instead.
7910               current.isconst=0;
7911               current.wasconst=0;
7912               regs[i].wasconst=0;
7913               if(dops[i].rs1) alloc_reg(&current,i,dops[i].rs1);
7914             }
7915             else
7916             {
7917               dops[i].ooo=1;
7918               delayslot_alloc(&current,i+1);
7919             }
7920           }
7921           else
7922           // Don't alloc the delay slot yet because we might not execute it
7923           if((dops[i].opcode&0x3E)==0x14) // BEQL/BNEL
7924           {
7925             current.isconst=0;
7926             current.wasconst=0;
7927             regs[i].wasconst=0;
7928             alloc_cc(&current,i);
7929             dirty_reg(&current,CCREG);
7930             alloc_reg(&current,i,dops[i].rs1);
7931             alloc_reg(&current,i,dops[i].rs2);
7932           }
7933           else
7934           if((dops[i].opcode&0x3E)==0x16) // BLEZL/BGTZL
7935           {
7936             current.isconst=0;
7937             current.wasconst=0;
7938             regs[i].wasconst=0;
7939             alloc_cc(&current,i);
7940             dirty_reg(&current,CCREG);
7941             alloc_reg(&current,i,dops[i].rs1);
7942           }
7943           ds=1;
7944           //current.isconst=0;
7945           break;
7946         case SJUMP:
7947           //current.isconst=0;
7948           //current.wasconst=0;
7949           //regs[i].wasconst=0;
7950           clear_const(&current,dops[i].rs1);
7951           clear_const(&current,dops[i].rt1);
7952           //if((dops[i].opcode2&0x1E)==0x0) // BLTZ/BGEZ
7953           if((dops[i].opcode2&0x0E)==0x0) // BLTZ/BGEZ
7954           {
7955             alloc_cc(&current,i);
7956             dirty_reg(&current,CCREG);
7957             alloc_reg(&current,i,dops[i].rs1);
7958             if (dops[i].rt1==31) { // BLTZAL/BGEZAL
7959               alloc_reg(&current,i,31);
7960               dirty_reg(&current,31);
7961               //#ifdef REG_PREFETCH
7962               //alloc_reg(&current,i,PTEMP);
7963               //#endif
7964             }
7965             if((dops[i].rs1&&(dops[i].rs1==dops[i+1].rt1||dops[i].rs1==dops[i+1].rt2)) // The delay slot overwrites the branch condition.
7966                ||(dops[i].rt1==31&&(dops[i+1].rs1==31||dops[i+1].rs2==31||dops[i+1].rt1==31||dops[i+1].rt2==31))) { // DS touches $ra
7967               // Allocate the branch condition registers instead.
7968               current.isconst=0;
7969               current.wasconst=0;
7970               regs[i].wasconst=0;
7971               if(dops[i].rs1) alloc_reg(&current,i,dops[i].rs1);
7972             }
7973             else
7974             {
7975               dops[i].ooo=1;
7976               delayslot_alloc(&current,i+1);
7977             }
7978           }
7979           else
7980           // Don't alloc the delay slot yet because we might not execute it
7981           if((dops[i].opcode2&0x1E)==0x2) // BLTZL/BGEZL
7982           {
7983             current.isconst=0;
7984             current.wasconst=0;
7985             regs[i].wasconst=0;
7986             alloc_cc(&current,i);
7987             dirty_reg(&current,CCREG);
7988             alloc_reg(&current,i,dops[i].rs1);
7989           }
7990           ds=1;
7991           //current.isconst=0;
7992           break;
7993         case IMM16:
7994           imm16_alloc(&current,i);
7995           break;
7996         case LOAD:
7997         case LOADLR:
7998           load_alloc(&current,i);
7999           break;
8000         case STORE:
8001         case STORELR:
8002           store_alloc(&current,i);
8003           break;
8004         case ALU:
8005           alu_alloc(&current,i);
8006           break;
8007         case SHIFT:
8008           shift_alloc(&current,i);
8009           break;
8010         case MULTDIV:
8011           multdiv_alloc(&current,i);
8012           break;
8013         case SHIFTIMM:
8014           shiftimm_alloc(&current,i);
8015           break;
8016         case MOV:
8017           mov_alloc(&current,i);
8018           break;
8019         case COP0:
8020           cop0_alloc(&current,i);
8021           break;
8022         case COP1:
8023           break;
8024         case COP2:
8025           cop2_alloc(&current,i);
8026           break;
8027         case C1LS:
8028           c1ls_alloc(&current,i);
8029           break;
8030         case C2LS:
8031           c2ls_alloc(&current,i);
8032           break;
8033         case C2OP:
8034           c2op_alloc(&current,i);
8035           break;
8036         case SYSCALL:
8037         case HLECALL:
8038         case INTCALL:
8039           syscall_alloc(&current,i);
8040           break;
8041         case SPAN:
8042           pagespan_alloc(&current,i);
8043           break;
8044       }
8045
8046       // Create entry (branch target) regmap
8047       for(hr=0;hr<HOST_REGS;hr++)
8048       {
8049         int r,or;
8050         r=current.regmap[hr];
8051         if(r>=0) {
8052           if(r!=regmap_pre[i][hr]) {
8053             // TODO: delay slot (?)
8054             or=get_reg(regmap_pre[i],r); // Get old mapping for this register
8055             if(or<0||(r&63)>=TEMPREG){
8056               regs[i].regmap_entry[hr]=-1;
8057             }
8058             else
8059             {
8060               // Just move it to a different register
8061               regs[i].regmap_entry[hr]=r;
8062               // If it was dirty before, it's still dirty
8063               if((regs[i].wasdirty>>or)&1) dirty_reg(&current,r&63);
8064             }
8065           }
8066           else
8067           {
8068             // Unneeded
8069             if(r==0){
8070               regs[i].regmap_entry[hr]=0;
8071             }
8072             else
8073             {
8074               assert(r<64);
8075               if((current.u>>r)&1) {
8076                 regs[i].regmap_entry[hr]=-1;
8077                 //regs[i].regmap[hr]=-1;
8078                 current.regmap[hr]=-1;
8079               }else
8080                 regs[i].regmap_entry[hr]=r;
8081             }
8082           }
8083         } else {
8084           // Branches expect CCREG to be allocated at the target
8085           if(regmap_pre[i][hr]==CCREG)
8086             regs[i].regmap_entry[hr]=CCREG;
8087           else
8088             regs[i].regmap_entry[hr]=-1;
8089         }
8090       }
8091       memcpy(regs[i].regmap,current.regmap,sizeof(current.regmap));
8092     }
8093
8094     if(i>0&&(dops[i-1].itype==STORE||dops[i-1].itype==STORELR||(dops[i-1].itype==C2LS&&dops[i-1].opcode==0x3a))&&(u_int)imm[i-1]<0x800)
8095       current.waswritten|=1<<dops[i-1].rs1;
8096     current.waswritten&=~(1<<dops[i].rt1);
8097     current.waswritten&=~(1<<dops[i].rt2);
8098     if((dops[i].itype==STORE||dops[i].itype==STORELR||(dops[i].itype==C2LS&&dops[i].opcode==0x3a))&&(u_int)imm[i]>=0x800)
8099       current.waswritten&=~(1<<dops[i].rs1);
8100
8101     /* Branch post-alloc */
8102     if(i>0)
8103     {
8104       current.wasdirty=current.dirty;
8105       switch(dops[i-1].itype) {
8106         case UJUMP:
8107           memcpy(&branch_regs[i-1],&current,sizeof(current));
8108           branch_regs[i-1].isconst=0;
8109           branch_regs[i-1].wasconst=0;
8110           branch_regs[i-1].u=branch_unneeded_reg[i-1]&~((1LL<<dops[i-1].rs1)|(1LL<<dops[i-1].rs2));
8111           alloc_cc(&branch_regs[i-1],i-1);
8112           dirty_reg(&branch_regs[i-1],CCREG);
8113           if(dops[i-1].rt1==31) { // JAL
8114             alloc_reg(&branch_regs[i-1],i-1,31);
8115             dirty_reg(&branch_regs[i-1],31);
8116           }
8117           memcpy(&branch_regs[i-1].regmap_entry,&branch_regs[i-1].regmap,sizeof(current.regmap));
8118           memcpy(constmap[i],constmap[i-1],sizeof(constmap[i]));
8119           break;
8120         case RJUMP:
8121           memcpy(&branch_regs[i-1],&current,sizeof(current));
8122           branch_regs[i-1].isconst=0;
8123           branch_regs[i-1].wasconst=0;
8124           branch_regs[i-1].u=branch_unneeded_reg[i-1]&~((1LL<<dops[i-1].rs1)|(1LL<<dops[i-1].rs2));
8125           alloc_cc(&branch_regs[i-1],i-1);
8126           dirty_reg(&branch_regs[i-1],CCREG);
8127           alloc_reg(&branch_regs[i-1],i-1,dops[i-1].rs1);
8128           if(dops[i-1].rt1!=0) { // JALR
8129             alloc_reg(&branch_regs[i-1],i-1,dops[i-1].rt1);
8130             dirty_reg(&branch_regs[i-1],dops[i-1].rt1);
8131           }
8132           #ifdef USE_MINI_HT
8133           if(dops[i-1].rs1==31) { // JALR
8134             alloc_reg(&branch_regs[i-1],i-1,RHASH);
8135             alloc_reg(&branch_regs[i-1],i-1,RHTBL);
8136           }
8137           #endif
8138           memcpy(&branch_regs[i-1].regmap_entry,&branch_regs[i-1].regmap,sizeof(current.regmap));
8139           memcpy(constmap[i],constmap[i-1],sizeof(constmap[i]));
8140           break;
8141         case CJUMP:
8142           if((dops[i-1].opcode&0x3E)==4) // BEQ/BNE
8143           {
8144             alloc_cc(&current,i-1);
8145             dirty_reg(&current,CCREG);
8146             if((dops[i-1].rs1&&(dops[i-1].rs1==dops[i].rt1||dops[i-1].rs1==dops[i].rt2))||
8147                (dops[i-1].rs2&&(dops[i-1].rs2==dops[i].rt1||dops[i-1].rs2==dops[i].rt2))) {
8148               // The delay slot overwrote one of our conditions
8149               // Delay slot goes after the test (in order)
8150               current.u=branch_unneeded_reg[i-1]&~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
8151               current.u|=1;
8152               delayslot_alloc(&current,i);
8153               current.isconst=0;
8154             }
8155             else
8156             {
8157               current.u=branch_unneeded_reg[i-1]&~((1LL<<dops[i-1].rs1)|(1LL<<dops[i-1].rs2));
8158               // Alloc the branch condition registers
8159               if(dops[i-1].rs1) alloc_reg(&current,i-1,dops[i-1].rs1);
8160               if(dops[i-1].rs2) alloc_reg(&current,i-1,dops[i-1].rs2);
8161             }
8162             memcpy(&branch_regs[i-1],&current,sizeof(current));
8163             branch_regs[i-1].isconst=0;
8164             branch_regs[i-1].wasconst=0;
8165             memcpy(&branch_regs[i-1].regmap_entry,&current.regmap,sizeof(current.regmap));
8166             memcpy(constmap[i],constmap[i-1],sizeof(constmap[i]));
8167           }
8168           else
8169           if((dops[i-1].opcode&0x3E)==6) // BLEZ/BGTZ
8170           {
8171             alloc_cc(&current,i-1);
8172             dirty_reg(&current,CCREG);
8173             if(dops[i-1].rs1==dops[i].rt1||dops[i-1].rs1==dops[i].rt2) {
8174               // The delay slot overwrote the branch condition
8175               // Delay slot goes after the test (in order)
8176               current.u=branch_unneeded_reg[i-1]&~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
8177               current.u|=1;
8178               delayslot_alloc(&current,i);
8179               current.isconst=0;
8180             }
8181             else
8182             {
8183               current.u=branch_unneeded_reg[i-1]&~(1LL<<dops[i-1].rs1);
8184               // Alloc the branch condition register
8185               alloc_reg(&current,i-1,dops[i-1].rs1);
8186             }
8187             memcpy(&branch_regs[i-1],&current,sizeof(current));
8188             branch_regs[i-1].isconst=0;
8189             branch_regs[i-1].wasconst=0;
8190             memcpy(&branch_regs[i-1].regmap_entry,&current.regmap,sizeof(current.regmap));
8191             memcpy(constmap[i],constmap[i-1],sizeof(constmap[i]));
8192           }
8193           else
8194           // Alloc the delay slot in case the branch is taken
8195           if((dops[i-1].opcode&0x3E)==0x14) // BEQL/BNEL
8196           {
8197             memcpy(&branch_regs[i-1],&current,sizeof(current));
8198             branch_regs[i-1].u=(branch_unneeded_reg[i-1]&~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2)|(1LL<<dops[i].rt1)|(1LL<<dops[i].rt2)))|1;
8199             alloc_cc(&branch_regs[i-1],i);
8200             dirty_reg(&branch_regs[i-1],CCREG);
8201             delayslot_alloc(&branch_regs[i-1],i);
8202             branch_regs[i-1].isconst=0;
8203             alloc_reg(&current,i,CCREG); // Not taken path
8204             dirty_reg(&current,CCREG);
8205             memcpy(&branch_regs[i-1].regmap_entry,&branch_regs[i-1].regmap,sizeof(current.regmap));
8206           }
8207           else
8208           if((dops[i-1].opcode&0x3E)==0x16) // BLEZL/BGTZL
8209           {
8210             memcpy(&branch_regs[i-1],&current,sizeof(current));
8211             branch_regs[i-1].u=(branch_unneeded_reg[i-1]&~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2)|(1LL<<dops[i].rt1)|(1LL<<dops[i].rt2)))|1;
8212             alloc_cc(&branch_regs[i-1],i);
8213             dirty_reg(&branch_regs[i-1],CCREG);
8214             delayslot_alloc(&branch_regs[i-1],i);
8215             branch_regs[i-1].isconst=0;
8216             alloc_reg(&current,i,CCREG); // Not taken path
8217             dirty_reg(&current,CCREG);
8218             memcpy(&branch_regs[i-1].regmap_entry,&branch_regs[i-1].regmap,sizeof(current.regmap));
8219           }
8220           break;
8221         case SJUMP:
8222           //if((dops[i-1].opcode2&0x1E)==0) // BLTZ/BGEZ
8223           if((dops[i-1].opcode2&0x0E)==0) // BLTZ/BGEZ
8224           {
8225             alloc_cc(&current,i-1);
8226             dirty_reg(&current,CCREG);
8227             if(dops[i-1].rs1==dops[i].rt1||dops[i-1].rs1==dops[i].rt2) {
8228               // The delay slot overwrote the branch condition
8229               // Delay slot goes after the test (in order)
8230               current.u=branch_unneeded_reg[i-1]&~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
8231               current.u|=1;
8232               delayslot_alloc(&current,i);
8233               current.isconst=0;
8234             }
8235             else
8236             {
8237               current.u=branch_unneeded_reg[i-1]&~(1LL<<dops[i-1].rs1);
8238               // Alloc the branch condition register
8239               alloc_reg(&current,i-1,dops[i-1].rs1);
8240             }
8241             memcpy(&branch_regs[i-1],&current,sizeof(current));
8242             branch_regs[i-1].isconst=0;
8243             branch_regs[i-1].wasconst=0;
8244             memcpy(&branch_regs[i-1].regmap_entry,&current.regmap,sizeof(current.regmap));
8245             memcpy(constmap[i],constmap[i-1],sizeof(constmap[i]));
8246           }
8247           else
8248           // Alloc the delay slot in case the branch is taken
8249           if((dops[i-1].opcode2&0x1E)==2) // BLTZL/BGEZL
8250           {
8251             memcpy(&branch_regs[i-1],&current,sizeof(current));
8252             branch_regs[i-1].u=(branch_unneeded_reg[i-1]&~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2)|(1LL<<dops[i].rt1)|(1LL<<dops[i].rt2)))|1;
8253             alloc_cc(&branch_regs[i-1],i);
8254             dirty_reg(&branch_regs[i-1],CCREG);
8255             delayslot_alloc(&branch_regs[i-1],i);
8256             branch_regs[i-1].isconst=0;
8257             alloc_reg(&current,i,CCREG); // Not taken path
8258             dirty_reg(&current,CCREG);
8259             memcpy(&branch_regs[i-1].regmap_entry,&branch_regs[i-1].regmap,sizeof(current.regmap));
8260           }
8261           // FIXME: BLTZAL/BGEZAL
8262           if(dops[i-1].opcode2&0x10) { // BxxZAL
8263             alloc_reg(&branch_regs[i-1],i-1,31);
8264             dirty_reg(&branch_regs[i-1],31);
8265           }
8266           break;
8267       }
8268
8269       if (dops[i-1].is_ujump)
8270       {
8271         if(dops[i-1].rt1==31) // JAL/JALR
8272         {
8273           // Subroutine call will return here, don't alloc any registers
8274           current.dirty=0;
8275           clear_all_regs(current.regmap);
8276           alloc_reg(&current,i,CCREG);
8277           dirty_reg(&current,CCREG);
8278         }
8279         else if(i+1<slen)
8280         {
8281           // Internal branch will jump here, match registers to caller
8282           current.dirty=0;
8283           clear_all_regs(current.regmap);
8284           alloc_reg(&current,i,CCREG);
8285           dirty_reg(&current,CCREG);
8286           for(j=i-1;j>=0;j--)
8287           {
8288             if(ba[j]==start+i*4+4) {
8289               memcpy(current.regmap,branch_regs[j].regmap,sizeof(current.regmap));
8290               current.dirty=branch_regs[j].dirty;
8291               break;
8292             }
8293           }
8294           while(j>=0) {
8295             if(ba[j]==start+i*4+4) {
8296               for(hr=0;hr<HOST_REGS;hr++) {
8297                 if(current.regmap[hr]!=branch_regs[j].regmap[hr]) {
8298                   current.regmap[hr]=-1;
8299                 }
8300                 current.dirty&=branch_regs[j].dirty;
8301               }
8302             }
8303             j--;
8304           }
8305         }
8306       }
8307     }
8308
8309     // Count cycles in between branches
8310     ccadj[i] = CLOCK_ADJUST(cc);
8311     if (i > 0 && (dops[i-1].is_jump || dops[i].itype == SYSCALL || dops[i].itype == HLECALL))
8312     {
8313       cc=0;
8314     }
8315 #if !defined(DRC_DBG)
8316     else if(dops[i].itype==C2OP&&gte_cycletab[source[i]&0x3f]>2)
8317     {
8318       // this should really be removed since the real stalls have been implemented,
8319       // but doing so causes sizeable perf regression against the older version
8320       u_int gtec = gte_cycletab[source[i] & 0x3f];
8321       cc += HACK_ENABLED(NDHACK_NO_STALLS) ? gtec/2 : 2;
8322     }
8323     else if(i>1&&dops[i].itype==STORE&&dops[i-1].itype==STORE&&dops[i-2].itype==STORE&&!dops[i].bt)
8324     {
8325       cc+=4;
8326     }
8327     else if(dops[i].itype==C2LS)
8328     {
8329       // same as with C2OP
8330       cc += HACK_ENABLED(NDHACK_NO_STALLS) ? 4 : 2;
8331     }
8332 #endif
8333     else
8334     {
8335       cc++;
8336     }
8337
8338     if(!dops[i].is_ds) {
8339       regs[i].dirty=current.dirty;
8340       regs[i].isconst=current.isconst;
8341       memcpy(constmap[i],current_constmap,sizeof(constmap[i]));
8342     }
8343     for(hr=0;hr<HOST_REGS;hr++) {
8344       if(hr!=EXCLUDE_REG&&regs[i].regmap[hr]>=0) {
8345         if(regmap_pre[i][hr]!=regs[i].regmap[hr]) {
8346           regs[i].wasconst&=~(1<<hr);
8347         }
8348       }
8349     }
8350     if(current.regmap[HOST_BTREG]==BTREG) current.regmap[HOST_BTREG]=-1;
8351     regs[i].waswritten=current.waswritten;
8352   }
8353
8354   /* Pass 4 - Cull unused host registers */
8355
8356   uint64_t nr=0;
8357
8358   for (i=slen-1;i>=0;i--)
8359   {
8360     int hr;
8361     if(dops[i].is_jump)
8362     {
8363       if(ba[i]<start || ba[i]>=(start+slen*4))
8364       {
8365         // Branch out of this block, don't need anything
8366         nr=0;
8367       }
8368       else
8369       {
8370         // Internal branch
8371         // Need whatever matches the target
8372         nr=0;
8373         int t=(ba[i]-start)>>2;
8374         for(hr=0;hr<HOST_REGS;hr++)
8375         {
8376           if(regs[i].regmap_entry[hr]>=0) {
8377             if(regs[i].regmap_entry[hr]==regs[t].regmap_entry[hr]) nr|=1<<hr;
8378           }
8379         }
8380       }
8381       // Conditional branch may need registers for following instructions
8382       if (!dops[i].is_ujump)
8383       {
8384         if(i<slen-2) {
8385           nr|=needed_reg[i+2];
8386           for(hr=0;hr<HOST_REGS;hr++)
8387           {
8388             if(regmap_pre[i+2][hr]>=0&&get_reg(regs[i+2].regmap_entry,regmap_pre[i+2][hr])<0) nr&=~(1<<hr);
8389             //if((regmap_entry[i+2][hr])>=0) if(!((nr>>hr)&1)) printf("%x-bogus(%d=%d)\n",start+i*4,hr,regmap_entry[i+2][hr]);
8390           }
8391         }
8392       }
8393       // Don't need stuff which is overwritten
8394       //if(regs[i].regmap[hr]!=regmap_pre[i][hr]) nr&=~(1<<hr);
8395       //if(regs[i].regmap[hr]<0) nr&=~(1<<hr);
8396       // Merge in delay slot
8397       for(hr=0;hr<HOST_REGS;hr++)
8398       {
8399         if(dops[i+1].rt1&&dops[i+1].rt1==(regs[i].regmap[hr]&63)) nr&=~(1<<hr);
8400         if(dops[i+1].rt2&&dops[i+1].rt2==(regs[i].regmap[hr]&63)) nr&=~(1<<hr);
8401         if(dops[i+1].rs1==regmap_pre[i][hr]) nr|=1<<hr;
8402         if(dops[i+1].rs2==regmap_pre[i][hr]) nr|=1<<hr;
8403         if(dops[i+1].rs1==regs[i].regmap_entry[hr]) nr|=1<<hr;
8404         if(dops[i+1].rs2==regs[i].regmap_entry[hr]) nr|=1<<hr;
8405         if(ram_offset && (dops[i+1].is_load || dops[i+1].is_store)) {
8406           if(regmap_pre[i][hr]==ROREG) nr|=1<<hr;
8407           if(regs[i].regmap_entry[hr]==ROREG) nr|=1<<hr;
8408         }
8409         if(dops[i+1].is_store) {
8410           if(regmap_pre[i][hr]==INVCP) nr|=1<<hr;
8411           if(regs[i].regmap_entry[hr]==INVCP) nr|=1<<hr;
8412         }
8413       }
8414     }
8415     else if(dops[i].itype==SYSCALL||dops[i].itype==HLECALL||dops[i].itype==INTCALL)
8416     {
8417       // SYSCALL instruction (software interrupt)
8418       nr=0;
8419     }
8420     else if(dops[i].itype==COP0 && (source[i]&0x3f)==0x18)
8421     {
8422       // ERET instruction (return from interrupt)
8423       nr=0;
8424     }
8425     else // Non-branch
8426     {
8427       if(i<slen-1) {
8428         for(hr=0;hr<HOST_REGS;hr++) {
8429           if(regmap_pre[i+1][hr]>=0&&get_reg(regs[i+1].regmap_entry,regmap_pre[i+1][hr])<0) nr&=~(1<<hr);
8430           if(regs[i].regmap[hr]!=regmap_pre[i+1][hr]) nr&=~(1<<hr);
8431           if(regs[i].regmap[hr]!=regmap_pre[i][hr]) nr&=~(1<<hr);
8432           if(regs[i].regmap[hr]<0) nr&=~(1<<hr);
8433         }
8434       }
8435     }
8436     for(hr=0;hr<HOST_REGS;hr++)
8437     {
8438       // Overwritten registers are not needed
8439       if(dops[i].rt1&&dops[i].rt1==(regs[i].regmap[hr]&63)) nr&=~(1<<hr);
8440       if(dops[i].rt2&&dops[i].rt2==(regs[i].regmap[hr]&63)) nr&=~(1<<hr);
8441       if(FTEMP==(regs[i].regmap[hr]&63)) nr&=~(1<<hr);
8442       // Source registers are needed
8443       if(dops[i].rs1==regmap_pre[i][hr]) nr|=1<<hr;
8444       if(dops[i].rs2==regmap_pre[i][hr]) nr|=1<<hr;
8445       if(dops[i].rs1==regs[i].regmap_entry[hr]) nr|=1<<hr;
8446       if(dops[i].rs2==regs[i].regmap_entry[hr]) nr|=1<<hr;
8447       if(ram_offset && (dops[i].is_load || dops[i].is_store)) {
8448         if(regmap_pre[i][hr]==ROREG) nr|=1<<hr;
8449         if(regs[i].regmap_entry[hr]==ROREG) nr|=1<<hr;
8450       }
8451       if(dops[i].is_store) {
8452         if(regmap_pre[i][hr]==INVCP) nr|=1<<hr;
8453         if(regs[i].regmap_entry[hr]==INVCP) nr|=1<<hr;
8454       }
8455       // Don't store a register immediately after writing it,
8456       // may prevent dual-issue.
8457       // But do so if this is a branch target, otherwise we
8458       // might have to load the register before the branch.
8459       if(i>0&&!dops[i].bt&&((regs[i].wasdirty>>hr)&1)) {
8460         if((regmap_pre[i][hr]>0&&!((unneeded_reg[i]>>regmap_pre[i][hr])&1))) {
8461           if(dops[i-1].rt1==(regmap_pre[i][hr]&63)) nr|=1<<hr;
8462           if(dops[i-1].rt2==(regmap_pre[i][hr]&63)) nr|=1<<hr;
8463         }
8464         if((regs[i].regmap_entry[hr]>0&&!((unneeded_reg[i]>>regs[i].regmap_entry[hr])&1))) {
8465           if(dops[i-1].rt1==(regs[i].regmap_entry[hr]&63)) nr|=1<<hr;
8466           if(dops[i-1].rt2==(regs[i].regmap_entry[hr]&63)) nr|=1<<hr;
8467         }
8468       }
8469     }
8470     // Cycle count is needed at branches.  Assume it is needed at the target too.
8471     if(i==0||dops[i].bt||dops[i].itype==CJUMP||dops[i].itype==SPAN) {
8472       if(regmap_pre[i][HOST_CCREG]==CCREG) nr|=1<<HOST_CCREG;
8473       if(regs[i].regmap_entry[HOST_CCREG]==CCREG) nr|=1<<HOST_CCREG;
8474     }
8475     // Save it
8476     needed_reg[i]=nr;
8477
8478     // Deallocate unneeded registers
8479     for(hr=0;hr<HOST_REGS;hr++)
8480     {
8481       if(!((nr>>hr)&1)) {
8482         if(regs[i].regmap_entry[hr]!=CCREG) regs[i].regmap_entry[hr]=-1;
8483         if(dops[i].is_jump)
8484         {
8485           int map1 = 0, map2 = 0, temp = 0; // or -1 ??
8486           if (dops[i+1].is_load || dops[i+1].is_store)
8487             map1 = ROREG;
8488           if (dops[i+1].is_store)
8489             map2 = INVCP;
8490           if(dops[i+1].itype==LOADLR || dops[i+1].itype==STORELR || dops[i+1].itype==C2LS)
8491             temp = FTEMP;
8492           if((regs[i].regmap[hr]&63)!=dops[i].rs1 && (regs[i].regmap[hr]&63)!=dops[i].rs2 &&
8493              (regs[i].regmap[hr]&63)!=dops[i].rt1 && (regs[i].regmap[hr]&63)!=dops[i].rt2 &&
8494              (regs[i].regmap[hr]&63)!=dops[i+1].rt1 && (regs[i].regmap[hr]&63)!=dops[i+1].rt2 &&
8495              regs[i].regmap[hr]!=dops[i+1].rs1 && regs[i].regmap[hr]!=dops[i+1].rs2 &&
8496              (regs[i].regmap[hr]&63)!=temp && regs[i].regmap[hr]!=PTEMP &&
8497              regs[i].regmap[hr]!=RHASH && regs[i].regmap[hr]!=RHTBL &&
8498              regs[i].regmap[hr]!=RTEMP && regs[i].regmap[hr]!=CCREG &&
8499              regs[i].regmap[hr]!=map1 && regs[i].regmap[hr]!=map2)
8500           {
8501             regs[i].regmap[hr]=-1;
8502             regs[i].isconst&=~(1<<hr);
8503             if((branch_regs[i].regmap[hr]&63)!=dops[i].rs1 && (branch_regs[i].regmap[hr]&63)!=dops[i].rs2 &&
8504                (branch_regs[i].regmap[hr]&63)!=dops[i].rt1 && (branch_regs[i].regmap[hr]&63)!=dops[i].rt2 &&
8505                (branch_regs[i].regmap[hr]&63)!=dops[i+1].rt1 && (branch_regs[i].regmap[hr]&63)!=dops[i+1].rt2 &&
8506                branch_regs[i].regmap[hr]!=dops[i+1].rs1 && branch_regs[i].regmap[hr]!=dops[i+1].rs2 &&
8507                (branch_regs[i].regmap[hr]&63)!=temp && branch_regs[i].regmap[hr]!=PTEMP &&
8508                branch_regs[i].regmap[hr]!=RHASH && branch_regs[i].regmap[hr]!=RHTBL &&
8509                branch_regs[i].regmap[hr]!=RTEMP && branch_regs[i].regmap[hr]!=CCREG &&
8510                branch_regs[i].regmap[hr]!=map1 && branch_regs[i].regmap[hr]!=map2)
8511             {
8512               branch_regs[i].regmap[hr]=-1;
8513               branch_regs[i].regmap_entry[hr]=-1;
8514               if (!dops[i].is_ujump)
8515               {
8516                 if (i < slen-2) {
8517                   regmap_pre[i+2][hr]=-1;
8518                   regs[i+2].wasconst&=~(1<<hr);
8519                 }
8520               }
8521             }
8522           }
8523         }
8524         else
8525         {
8526           // Non-branch
8527           if(i>0)
8528           {
8529             int map1 = -1, map2 = -1, temp=-1;
8530             if (dops[i].is_load || dops[i].is_store)
8531               map1 = ROREG;
8532             if (dops[i].is_store)
8533               map2 = INVCP;
8534             if (dops[i].itype==LOADLR || dops[i].itype==STORELR || dops[i].itype==C2LS)
8535               temp = FTEMP;
8536             if((regs[i].regmap[hr]&63)!=dops[i].rt1 && (regs[i].regmap[hr]&63)!=dops[i].rt2 &&
8537                regs[i].regmap[hr]!=dops[i].rs1 && regs[i].regmap[hr]!=dops[i].rs2 &&
8538                (regs[i].regmap[hr]&63)!=temp && regs[i].regmap[hr]!=map1 && regs[i].regmap[hr]!=map2 &&
8539                //(dops[i].itype!=SPAN||regs[i].regmap[hr]!=CCREG)
8540                regs[i].regmap[hr] != CCREG)
8541             {
8542               if(i<slen-1&&!dops[i].is_ds) {
8543                 assert(regs[i].regmap[hr]<64);
8544                 if(regmap_pre[i+1][hr]!=-1 || regs[i].regmap[hr]>0)
8545                 if(regmap_pre[i+1][hr]!=regs[i].regmap[hr])
8546                 {
8547                   SysPrintf("fail: %x (%d %d!=%d)\n",start+i*4,hr,regmap_pre[i+1][hr],regs[i].regmap[hr]);
8548                   assert(regmap_pre[i+1][hr]==regs[i].regmap[hr]);
8549                 }
8550                 regmap_pre[i+1][hr]=-1;
8551                 if(regs[i+1].regmap_entry[hr]==CCREG) regs[i+1].regmap_entry[hr]=-1;
8552                 regs[i+1].wasconst&=~(1<<hr);
8553               }
8554               regs[i].regmap[hr]=-1;
8555               regs[i].isconst&=~(1<<hr);
8556             }
8557           }
8558         }
8559       } // if needed
8560     } // for hr
8561   }
8562
8563   /* Pass 5 - Pre-allocate registers */
8564
8565   // If a register is allocated during a loop, try to allocate it for the
8566   // entire loop, if possible.  This avoids loading/storing registers
8567   // inside of the loop.
8568
8569   signed char f_regmap[HOST_REGS];
8570   clear_all_regs(f_regmap);
8571   for(i=0;i<slen-1;i++)
8572   {
8573     if(dops[i].itype==UJUMP||dops[i].itype==CJUMP||dops[i].itype==SJUMP)
8574     {
8575       if(ba[i]>=start && ba[i]<(start+i*4))
8576       if(dops[i+1].itype==NOP||dops[i+1].itype==MOV||dops[i+1].itype==ALU
8577       ||dops[i+1].itype==SHIFTIMM||dops[i+1].itype==IMM16||dops[i+1].itype==LOAD
8578       ||dops[i+1].itype==STORE||dops[i+1].itype==STORELR||dops[i+1].itype==C1LS
8579       ||dops[i+1].itype==SHIFT||dops[i+1].itype==COP1
8580       ||dops[i+1].itype==COP2||dops[i+1].itype==C2LS||dops[i+1].itype==C2OP)
8581       {
8582         int t=(ba[i]-start)>>2;
8583         if(t > 0 && !dops[t-1].is_jump) // loop_preload can't handle jumps into delay slots
8584         if(t<2||(dops[t-2].itype!=UJUMP&&dops[t-2].itype!=RJUMP)||dops[t-2].rt1!=31) // call/ret assumes no registers allocated
8585         for(hr=0;hr<HOST_REGS;hr++)
8586         {
8587           if(regs[i].regmap[hr]>=0) {
8588             if(f_regmap[hr]!=regs[i].regmap[hr]) {
8589               // dealloc old register
8590               int n;
8591               for(n=0;n<HOST_REGS;n++)
8592               {
8593                 if(f_regmap[n]==regs[i].regmap[hr]) {f_regmap[n]=-1;}
8594               }
8595               // and alloc new one
8596               f_regmap[hr]=regs[i].regmap[hr];
8597             }
8598           }
8599           if(branch_regs[i].regmap[hr]>=0) {
8600             if(f_regmap[hr]!=branch_regs[i].regmap[hr]) {
8601               // dealloc old register
8602               int n;
8603               for(n=0;n<HOST_REGS;n++)
8604               {
8605                 if(f_regmap[n]==branch_regs[i].regmap[hr]) {f_regmap[n]=-1;}
8606               }
8607               // and alloc new one
8608               f_regmap[hr]=branch_regs[i].regmap[hr];
8609             }
8610           }
8611           if(dops[i].ooo) {
8612             if(count_free_regs(regs[i].regmap)<=minimum_free_regs[i+1])
8613               f_regmap[hr]=branch_regs[i].regmap[hr];
8614           }else{
8615             if(count_free_regs(branch_regs[i].regmap)<=minimum_free_regs[i+1])
8616               f_regmap[hr]=branch_regs[i].regmap[hr];
8617           }
8618           // Avoid dirty->clean transition
8619           #ifdef DESTRUCTIVE_WRITEBACK
8620           if(t>0) if(get_reg(regmap_pre[t],f_regmap[hr])>=0) if((regs[t].wasdirty>>get_reg(regmap_pre[t],f_regmap[hr]))&1) f_regmap[hr]=-1;
8621           #endif
8622           // This check is only strictly required in the DESTRUCTIVE_WRITEBACK
8623           // case above, however it's always a good idea.  We can't hoist the
8624           // load if the register was already allocated, so there's no point
8625           // wasting time analyzing most of these cases.  It only "succeeds"
8626           // when the mapping was different and the load can be replaced with
8627           // a mov, which is of negligible benefit.  So such cases are
8628           // skipped below.
8629           if(f_regmap[hr]>0) {
8630             if(regs[t].regmap[hr]==f_regmap[hr]||(regs[t].regmap_entry[hr]<0&&get_reg(regmap_pre[t],f_regmap[hr])<0)) {
8631               int r=f_regmap[hr];
8632               for(j=t;j<=i;j++)
8633               {
8634                 //printf("Test %x -> %x, %x %d/%d\n",start+i*4,ba[i],start+j*4,hr,r);
8635                 if(r<34&&((unneeded_reg[j]>>r)&1)) break;
8636                 assert(r < 64);
8637                 if(regs[j].regmap[hr]==f_regmap[hr]&&(f_regmap[hr]&63)<TEMPREG) {
8638                   //printf("Hit %x -> %x, %x %d/%d\n",start+i*4,ba[i],start+j*4,hr,r);
8639                   int k;
8640                   if(regs[i].regmap[hr]==-1&&branch_regs[i].regmap[hr]==-1) {
8641                     if(get_reg(regs[i+2].regmap,f_regmap[hr])>=0) break;
8642                     if(r>63) {
8643                       if(get_reg(regs[i].regmap,r&63)<0) break;
8644                       if(get_reg(branch_regs[i].regmap,r&63)<0) break;
8645                     }
8646                     k=i;
8647                     while(k>1&&regs[k-1].regmap[hr]==-1) {
8648                       if(count_free_regs(regs[k-1].regmap)<=minimum_free_regs[k-1]) {
8649                         //printf("no free regs for store %x\n",start+(k-1)*4);
8650                         break;
8651                       }
8652                       if(get_reg(regs[k-1].regmap,f_regmap[hr])>=0) {
8653                         //printf("no-match due to different register\n");
8654                         break;
8655                       }
8656                       if (dops[k-2].is_jump) {
8657                         //printf("no-match due to branch\n");
8658                         break;
8659                       }
8660                       // call/ret fast path assumes no registers allocated
8661                       if(k>2&&(dops[k-3].itype==UJUMP||dops[k-3].itype==RJUMP)&&dops[k-3].rt1==31) {
8662                         break;
8663                       }
8664                       assert(r < 64);
8665                       k--;
8666                     }
8667                     if(regs[k-1].regmap[hr]==f_regmap[hr]&&regmap_pre[k][hr]==f_regmap[hr]) {
8668                       //printf("Extend r%d, %x ->\n",hr,start+k*4);
8669                       while(k<i) {
8670                         regs[k].regmap_entry[hr]=f_regmap[hr];
8671                         regs[k].regmap[hr]=f_regmap[hr];
8672                         regmap_pre[k+1][hr]=f_regmap[hr];
8673                         regs[k].wasdirty&=~(1<<hr);
8674                         regs[k].dirty&=~(1<<hr);
8675                         regs[k].wasdirty|=(1<<hr)&regs[k-1].dirty;
8676                         regs[k].dirty|=(1<<hr)&regs[k].wasdirty;
8677                         regs[k].wasconst&=~(1<<hr);
8678                         regs[k].isconst&=~(1<<hr);
8679                         k++;
8680                       }
8681                     }
8682                     else {
8683                       //printf("Fail Extend r%d, %x ->\n",hr,start+k*4);
8684                       break;
8685                     }
8686                     assert(regs[i-1].regmap[hr]==f_regmap[hr]);
8687                     if(regs[i-1].regmap[hr]==f_regmap[hr]&&regmap_pre[i][hr]==f_regmap[hr]) {
8688                       //printf("OK fill %x (r%d)\n",start+i*4,hr);
8689                       regs[i].regmap_entry[hr]=f_regmap[hr];
8690                       regs[i].regmap[hr]=f_regmap[hr];
8691                       regs[i].wasdirty&=~(1<<hr);
8692                       regs[i].dirty&=~(1<<hr);
8693                       regs[i].wasdirty|=(1<<hr)&regs[i-1].dirty;
8694                       regs[i].dirty|=(1<<hr)&regs[i-1].dirty;
8695                       regs[i].wasconst&=~(1<<hr);
8696                       regs[i].isconst&=~(1<<hr);
8697                       branch_regs[i].regmap_entry[hr]=f_regmap[hr];
8698                       branch_regs[i].wasdirty&=~(1<<hr);
8699                       branch_regs[i].wasdirty|=(1<<hr)&regs[i].dirty;
8700                       branch_regs[i].regmap[hr]=f_regmap[hr];
8701                       branch_regs[i].dirty&=~(1<<hr);
8702                       branch_regs[i].dirty|=(1<<hr)&regs[i].dirty;
8703                       branch_regs[i].wasconst&=~(1<<hr);
8704                       branch_regs[i].isconst&=~(1<<hr);
8705                       if (!dops[i].is_ujump) {
8706                         regmap_pre[i+2][hr]=f_regmap[hr];
8707                         regs[i+2].wasdirty&=~(1<<hr);
8708                         regs[i+2].wasdirty|=(1<<hr)&regs[i].dirty;
8709                       }
8710                     }
8711                   }
8712                   for(k=t;k<j;k++) {
8713                     // Alloc register clean at beginning of loop,
8714                     // but may dirty it in pass 6
8715                     regs[k].regmap_entry[hr]=f_regmap[hr];
8716                     regs[k].regmap[hr]=f_regmap[hr];
8717                     regs[k].dirty&=~(1<<hr);
8718                     regs[k].wasconst&=~(1<<hr);
8719                     regs[k].isconst&=~(1<<hr);
8720                     if (dops[k].is_jump) {
8721                       branch_regs[k].regmap_entry[hr]=f_regmap[hr];
8722                       branch_regs[k].regmap[hr]=f_regmap[hr];
8723                       branch_regs[k].dirty&=~(1<<hr);
8724                       branch_regs[k].wasconst&=~(1<<hr);
8725                       branch_regs[k].isconst&=~(1<<hr);
8726                       if (!dops[k].is_ujump) {
8727                         regmap_pre[k+2][hr]=f_regmap[hr];
8728                         regs[k+2].wasdirty&=~(1<<hr);
8729                       }
8730                     }
8731                     else
8732                     {
8733                       regmap_pre[k+1][hr]=f_regmap[hr];
8734                       regs[k+1].wasdirty&=~(1<<hr);
8735                     }
8736                   }
8737                   if(regs[j].regmap[hr]==f_regmap[hr])
8738                     regs[j].regmap_entry[hr]=f_regmap[hr];
8739                   break;
8740                 }
8741                 if(j==i) break;
8742                 if(regs[j].regmap[hr]>=0)
8743                   break;
8744                 if(get_reg(regs[j].regmap,f_regmap[hr])>=0) {
8745                   //printf("no-match due to different register\n");
8746                   break;
8747                 }
8748                 if (dops[j].is_ujump)
8749                 {
8750                   // Stop on unconditional branch
8751                   break;
8752                 }
8753                 if(dops[j].itype==CJUMP||dops[j].itype==SJUMP)
8754                 {
8755                   if(dops[j].ooo) {
8756                     if(count_free_regs(regs[j].regmap)<=minimum_free_regs[j+1])
8757                       break;
8758                   }else{
8759                     if(count_free_regs(branch_regs[j].regmap)<=minimum_free_regs[j+1])
8760                       break;
8761                   }
8762                   if(get_reg(branch_regs[j].regmap,f_regmap[hr])>=0) {
8763                     //printf("no-match due to different register (branch)\n");
8764                     break;
8765                   }
8766                 }
8767                 if(count_free_regs(regs[j].regmap)<=minimum_free_regs[j]) {
8768                   //printf("No free regs for store %x\n",start+j*4);
8769                   break;
8770                 }
8771                 assert(f_regmap[hr]<64);
8772               }
8773             }
8774           }
8775         }
8776       }
8777     }else{
8778       // Non branch or undetermined branch target
8779       for(hr=0;hr<HOST_REGS;hr++)
8780       {
8781         if(hr!=EXCLUDE_REG) {
8782           if(regs[i].regmap[hr]>=0) {
8783             if(f_regmap[hr]!=regs[i].regmap[hr]) {
8784               // dealloc old register
8785               int n;
8786               for(n=0;n<HOST_REGS;n++)
8787               {
8788                 if(f_regmap[n]==regs[i].regmap[hr]) {f_regmap[n]=-1;}
8789               }
8790               // and alloc new one
8791               f_regmap[hr]=regs[i].regmap[hr];
8792             }
8793           }
8794         }
8795       }
8796       // Try to restore cycle count at branch targets
8797       if(dops[i].bt) {
8798         for(j=i;j<slen-1;j++) {
8799           if(regs[j].regmap[HOST_CCREG]!=-1) break;
8800           if(count_free_regs(regs[j].regmap)<=minimum_free_regs[j]) {
8801             //printf("no free regs for store %x\n",start+j*4);
8802             break;
8803           }
8804         }
8805         if(regs[j].regmap[HOST_CCREG]==CCREG) {
8806           int k=i;
8807           //printf("Extend CC, %x -> %x\n",start+k*4,start+j*4);
8808           while(k<j) {
8809             regs[k].regmap_entry[HOST_CCREG]=CCREG;
8810             regs[k].regmap[HOST_CCREG]=CCREG;
8811             regmap_pre[k+1][HOST_CCREG]=CCREG;
8812             regs[k+1].wasdirty|=1<<HOST_CCREG;
8813             regs[k].dirty|=1<<HOST_CCREG;
8814             regs[k].wasconst&=~(1<<HOST_CCREG);
8815             regs[k].isconst&=~(1<<HOST_CCREG);
8816             k++;
8817           }
8818           regs[j].regmap_entry[HOST_CCREG]=CCREG;
8819         }
8820         // Work backwards from the branch target
8821         if(j>i&&f_regmap[HOST_CCREG]==CCREG)
8822         {
8823           //printf("Extend backwards\n");
8824           int k;
8825           k=i;
8826           while(regs[k-1].regmap[HOST_CCREG]==-1) {
8827             if(count_free_regs(regs[k-1].regmap)<=minimum_free_regs[k-1]) {
8828               //printf("no free regs for store %x\n",start+(k-1)*4);
8829               break;
8830             }
8831             k--;
8832           }
8833           if(regs[k-1].regmap[HOST_CCREG]==CCREG) {
8834             //printf("Extend CC, %x ->\n",start+k*4);
8835             while(k<=i) {
8836               regs[k].regmap_entry[HOST_CCREG]=CCREG;
8837               regs[k].regmap[HOST_CCREG]=CCREG;
8838               regmap_pre[k+1][HOST_CCREG]=CCREG;
8839               regs[k+1].wasdirty|=1<<HOST_CCREG;
8840               regs[k].dirty|=1<<HOST_CCREG;
8841               regs[k].wasconst&=~(1<<HOST_CCREG);
8842               regs[k].isconst&=~(1<<HOST_CCREG);
8843               k++;
8844             }
8845           }
8846           else {
8847             //printf("Fail Extend CC, %x ->\n",start+k*4);
8848           }
8849         }
8850       }
8851       if(dops[i].itype!=STORE&&dops[i].itype!=STORELR&&dops[i].itype!=C1LS&&dops[i].itype!=SHIFT&&
8852          dops[i].itype!=NOP&&dops[i].itype!=MOV&&dops[i].itype!=ALU&&dops[i].itype!=SHIFTIMM&&
8853          dops[i].itype!=IMM16&&dops[i].itype!=LOAD&&dops[i].itype!=COP1)
8854       {
8855         memcpy(f_regmap,regs[i].regmap,sizeof(f_regmap));
8856       }
8857     }
8858   }
8859
8860   // This allocates registers (if possible) one instruction prior
8861   // to use, which can avoid a load-use penalty on certain CPUs.
8862   for(i=0;i<slen-1;i++)
8863   {
8864     if (!i || !dops[i-1].is_jump)
8865     {
8866       if(!dops[i+1].bt)
8867       {
8868         if(dops[i].itype==ALU||dops[i].itype==MOV||dops[i].itype==LOAD||dops[i].itype==SHIFTIMM||dops[i].itype==IMM16
8869            ||((dops[i].itype==COP1||dops[i].itype==COP2)&&dops[i].opcode2<3))
8870         {
8871           if(dops[i+1].rs1) {
8872             if((hr=get_reg(regs[i+1].regmap,dops[i+1].rs1))>=0)
8873             {
8874               if(regs[i].regmap[hr]<0&&regs[i+1].regmap_entry[hr]<0)
8875               {
8876                 regs[i].regmap[hr]=regs[i+1].regmap[hr];
8877                 regmap_pre[i+1][hr]=regs[i+1].regmap[hr];
8878                 regs[i+1].regmap_entry[hr]=regs[i+1].regmap[hr];
8879                 regs[i].isconst&=~(1<<hr);
8880                 regs[i].isconst|=regs[i+1].isconst&(1<<hr);
8881                 constmap[i][hr]=constmap[i+1][hr];
8882                 regs[i+1].wasdirty&=~(1<<hr);
8883                 regs[i].dirty&=~(1<<hr);
8884               }
8885             }
8886           }
8887           if(dops[i+1].rs2) {
8888             if((hr=get_reg(regs[i+1].regmap,dops[i+1].rs2))>=0)
8889             {
8890               if(regs[i].regmap[hr]<0&&regs[i+1].regmap_entry[hr]<0)
8891               {
8892                 regs[i].regmap[hr]=regs[i+1].regmap[hr];
8893                 regmap_pre[i+1][hr]=regs[i+1].regmap[hr];
8894                 regs[i+1].regmap_entry[hr]=regs[i+1].regmap[hr];
8895                 regs[i].isconst&=~(1<<hr);
8896                 regs[i].isconst|=regs[i+1].isconst&(1<<hr);
8897                 constmap[i][hr]=constmap[i+1][hr];
8898                 regs[i+1].wasdirty&=~(1<<hr);
8899                 regs[i].dirty&=~(1<<hr);
8900               }
8901             }
8902           }
8903           // Preload target address for load instruction (non-constant)
8904           if(dops[i+1].itype==LOAD&&dops[i+1].rs1&&get_reg(regs[i+1].regmap,dops[i+1].rs1)<0) {
8905             if((hr=get_reg(regs[i+1].regmap,dops[i+1].rt1))>=0)
8906             {
8907               if(regs[i].regmap[hr]<0&&regs[i+1].regmap_entry[hr]<0)
8908               {
8909                 regs[i].regmap[hr]=dops[i+1].rs1;
8910                 regmap_pre[i+1][hr]=dops[i+1].rs1;
8911                 regs[i+1].regmap_entry[hr]=dops[i+1].rs1;
8912                 regs[i].isconst&=~(1<<hr);
8913                 regs[i].isconst|=regs[i+1].isconst&(1<<hr);
8914                 constmap[i][hr]=constmap[i+1][hr];
8915                 regs[i+1].wasdirty&=~(1<<hr);
8916                 regs[i].dirty&=~(1<<hr);
8917               }
8918             }
8919           }
8920           // Load source into target register
8921           if(dops[i+1].lt1&&get_reg(regs[i+1].regmap,dops[i+1].rs1)<0) {
8922             if((hr=get_reg(regs[i+1].regmap,dops[i+1].rt1))>=0)
8923             {
8924               if(regs[i].regmap[hr]<0&&regs[i+1].regmap_entry[hr]<0)
8925               {
8926                 regs[i].regmap[hr]=dops[i+1].rs1;
8927                 regmap_pre[i+1][hr]=dops[i+1].rs1;
8928                 regs[i+1].regmap_entry[hr]=dops[i+1].rs1;
8929                 regs[i].isconst&=~(1<<hr);
8930                 regs[i].isconst|=regs[i+1].isconst&(1<<hr);
8931                 constmap[i][hr]=constmap[i+1][hr];
8932                 regs[i+1].wasdirty&=~(1<<hr);
8933                 regs[i].dirty&=~(1<<hr);
8934               }
8935             }
8936           }
8937           // Address for store instruction (non-constant)
8938           if(dops[i+1].itype==STORE||dops[i+1].itype==STORELR
8939              ||(dops[i+1].opcode&0x3b)==0x39||(dops[i+1].opcode&0x3b)==0x3a) { // SB/SH/SW/SD/SWC1/SDC1/SWC2/SDC2
8940             if(get_reg(regs[i+1].regmap,dops[i+1].rs1)<0) {
8941               hr=get_reg2(regs[i].regmap,regs[i+1].regmap,-1);
8942               if(hr<0) hr=get_reg(regs[i+1].regmap,-1);
8943               else {regs[i+1].regmap[hr]=AGEN1+((i+1)&1);regs[i+1].isconst&=~(1<<hr);}
8944               assert(hr>=0);
8945               if(regs[i].regmap[hr]<0&&regs[i+1].regmap_entry[hr]<0)
8946               {
8947                 regs[i].regmap[hr]=dops[i+1].rs1;
8948                 regmap_pre[i+1][hr]=dops[i+1].rs1;
8949                 regs[i+1].regmap_entry[hr]=dops[i+1].rs1;
8950                 regs[i].isconst&=~(1<<hr);
8951                 regs[i].isconst|=regs[i+1].isconst&(1<<hr);
8952                 constmap[i][hr]=constmap[i+1][hr];
8953                 regs[i+1].wasdirty&=~(1<<hr);
8954                 regs[i].dirty&=~(1<<hr);
8955               }
8956             }
8957           }
8958           if(dops[i+1].itype==LOADLR||(dops[i+1].opcode&0x3b)==0x31||(dops[i+1].opcode&0x3b)==0x32) { // LWC1/LDC1, LWC2/LDC2
8959             if(get_reg(regs[i+1].regmap,dops[i+1].rs1)<0) {
8960               int nr;
8961               hr=get_reg(regs[i+1].regmap,FTEMP);
8962               assert(hr>=0);
8963               if(regs[i].regmap[hr]<0&&regs[i+1].regmap_entry[hr]<0)
8964               {
8965                 regs[i].regmap[hr]=dops[i+1].rs1;
8966                 regmap_pre[i+1][hr]=dops[i+1].rs1;
8967                 regs[i+1].regmap_entry[hr]=dops[i+1].rs1;
8968                 regs[i].isconst&=~(1<<hr);
8969                 regs[i].isconst|=regs[i+1].isconst&(1<<hr);
8970                 constmap[i][hr]=constmap[i+1][hr];
8971                 regs[i+1].wasdirty&=~(1<<hr);
8972                 regs[i].dirty&=~(1<<hr);
8973               }
8974               else if((nr=get_reg2(regs[i].regmap,regs[i+1].regmap,-1))>=0)
8975               {
8976                 // move it to another register
8977                 regs[i+1].regmap[hr]=-1;
8978                 regmap_pre[i+2][hr]=-1;
8979                 regs[i+1].regmap[nr]=FTEMP;
8980                 regmap_pre[i+2][nr]=FTEMP;
8981                 regs[i].regmap[nr]=dops[i+1].rs1;
8982                 regmap_pre[i+1][nr]=dops[i+1].rs1;
8983                 regs[i+1].regmap_entry[nr]=dops[i+1].rs1;
8984                 regs[i].isconst&=~(1<<nr);
8985                 regs[i+1].isconst&=~(1<<nr);
8986                 regs[i].dirty&=~(1<<nr);
8987                 regs[i+1].wasdirty&=~(1<<nr);
8988                 regs[i+1].dirty&=~(1<<nr);
8989                 regs[i+2].wasdirty&=~(1<<nr);
8990               }
8991             }
8992           }
8993           if(dops[i+1].itype==LOAD||dops[i+1].itype==LOADLR||dops[i+1].itype==STORE||dops[i+1].itype==STORELR/*||dops[i+1].itype==C1LS||||dops[i+1].itype==C2LS*/) {
8994             if(dops[i+1].itype==LOAD)
8995               hr=get_reg(regs[i+1].regmap,dops[i+1].rt1);
8996             if(dops[i+1].itype==LOADLR||(dops[i+1].opcode&0x3b)==0x31||(dops[i+1].opcode&0x3b)==0x32) // LWC1/LDC1, LWC2/LDC2
8997               hr=get_reg(regs[i+1].regmap,FTEMP);
8998             if(dops[i+1].itype==STORE||dops[i+1].itype==STORELR||(dops[i+1].opcode&0x3b)==0x39||(dops[i+1].opcode&0x3b)==0x3a) { // SWC1/SDC1/SWC2/SDC2
8999               hr=get_reg(regs[i+1].regmap,AGEN1+((i+1)&1));
9000               if(hr<0) hr=get_reg(regs[i+1].regmap,-1);
9001             }
9002             if(hr>=0&&regs[i].regmap[hr]<0) {
9003               int rs=get_reg(regs[i+1].regmap,dops[i+1].rs1);
9004               if(rs>=0&&((regs[i+1].wasconst>>rs)&1)) {
9005                 regs[i].regmap[hr]=AGEN1+((i+1)&1);
9006                 regmap_pre[i+1][hr]=AGEN1+((i+1)&1);
9007                 regs[i+1].regmap_entry[hr]=AGEN1+((i+1)&1);
9008                 regs[i].isconst&=~(1<<hr);
9009                 regs[i+1].wasdirty&=~(1<<hr);
9010                 regs[i].dirty&=~(1<<hr);
9011               }
9012             }
9013           }
9014         }
9015       }
9016     }
9017   }
9018
9019   /* Pass 6 - Optimize clean/dirty state */
9020   clean_registers(0,slen-1,1);
9021
9022   /* Pass 7 - Identify 32-bit registers */
9023   for (i=slen-1;i>=0;i--)
9024   {
9025     if(dops[i].itype==CJUMP||dops[i].itype==SJUMP)
9026     {
9027       // Conditional branch
9028       if((source[i]>>16)!=0x1000&&i<slen-2) {
9029         // Mark this address as a branch target since it may be called
9030         // upon return from interrupt
9031         dops[i+2].bt=1;
9032       }
9033     }
9034   }
9035
9036   if(dops[slen-1].itype==SPAN) {
9037     dops[slen-1].bt=1; // Mark as a branch target so instruction can restart after exception
9038   }
9039
9040 #ifdef REG_ALLOC_PRINT
9041   /* Debug/disassembly */
9042   for(i=0;i<slen;i++)
9043   {
9044     printf("U:");
9045     int r;
9046     for(r=1;r<=CCREG;r++) {
9047       if((unneeded_reg[i]>>r)&1) {
9048         if(r==HIREG) printf(" HI");
9049         else if(r==LOREG) printf(" LO");
9050         else printf(" r%d",r);
9051       }
9052     }
9053     printf("\n");
9054     #if defined(__i386__) || defined(__x86_64__)
9055     printf("pre: eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d\n",regmap_pre[i][0],regmap_pre[i][1],regmap_pre[i][2],regmap_pre[i][3],regmap_pre[i][5],regmap_pre[i][6],regmap_pre[i][7]);
9056     #endif
9057     #ifdef __arm__
9058     printf("pre: r0=%d r1=%d r2=%d r3=%d r4=%d r5=%d r6=%d r7=%d r8=%d r9=%d r10=%d r12=%d\n",regmap_pre[i][0],regmap_pre[i][1],regmap_pre[i][2],regmap_pre[i][3],regmap_pre[i][4],regmap_pre[i][5],regmap_pre[i][6],regmap_pre[i][7],regmap_pre[i][8],regmap_pre[i][9],regmap_pre[i][10],regmap_pre[i][12]);
9059     #endif
9060     #if defined(__i386__) || defined(__x86_64__)
9061     printf("needs: ");
9062     if(needed_reg[i]&1) printf("eax ");
9063     if((needed_reg[i]>>1)&1) printf("ecx ");
9064     if((needed_reg[i]>>2)&1) printf("edx ");
9065     if((needed_reg[i]>>3)&1) printf("ebx ");
9066     if((needed_reg[i]>>5)&1) printf("ebp ");
9067     if((needed_reg[i]>>6)&1) printf("esi ");
9068     if((needed_reg[i]>>7)&1) printf("edi ");
9069     printf("\n");
9070     printf("entry: eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d\n",regs[i].regmap_entry[0],regs[i].regmap_entry[1],regs[i].regmap_entry[2],regs[i].regmap_entry[3],regs[i].regmap_entry[5],regs[i].regmap_entry[6],regs[i].regmap_entry[7]);
9071     printf("dirty: ");
9072     if(regs[i].wasdirty&1) printf("eax ");
9073     if((regs[i].wasdirty>>1)&1) printf("ecx ");
9074     if((regs[i].wasdirty>>2)&1) printf("edx ");
9075     if((regs[i].wasdirty>>3)&1) printf("ebx ");
9076     if((regs[i].wasdirty>>5)&1) printf("ebp ");
9077     if((regs[i].wasdirty>>6)&1) printf("esi ");
9078     if((regs[i].wasdirty>>7)&1) printf("edi ");
9079     #endif
9080     #ifdef __arm__
9081     printf("entry: r0=%d r1=%d r2=%d r3=%d r4=%d r5=%d r6=%d r7=%d r8=%d r9=%d r10=%d r12=%d\n",regs[i].regmap_entry[0],regs[i].regmap_entry[1],regs[i].regmap_entry[2],regs[i].regmap_entry[3],regs[i].regmap_entry[4],regs[i].regmap_entry[5],regs[i].regmap_entry[6],regs[i].regmap_entry[7],regs[i].regmap_entry[8],regs[i].regmap_entry[9],regs[i].regmap_entry[10],regs[i].regmap_entry[12]);
9082     printf("dirty: ");
9083     if(regs[i].wasdirty&1) printf("r0 ");
9084     if((regs[i].wasdirty>>1)&1) printf("r1 ");
9085     if((regs[i].wasdirty>>2)&1) printf("r2 ");
9086     if((regs[i].wasdirty>>3)&1) printf("r3 ");
9087     if((regs[i].wasdirty>>4)&1) printf("r4 ");
9088     if((regs[i].wasdirty>>5)&1) printf("r5 ");
9089     if((regs[i].wasdirty>>6)&1) printf("r6 ");
9090     if((regs[i].wasdirty>>7)&1) printf("r7 ");
9091     if((regs[i].wasdirty>>8)&1) printf("r8 ");
9092     if((regs[i].wasdirty>>9)&1) printf("r9 ");
9093     if((regs[i].wasdirty>>10)&1) printf("r10 ");
9094     if((regs[i].wasdirty>>12)&1) printf("r12 ");
9095     #endif
9096     printf("\n");
9097     disassemble_inst(i);
9098     //printf ("ccadj[%d] = %d\n",i,ccadj[i]);
9099     #if defined(__i386__) || defined(__x86_64__)
9100     printf("eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d dirty: ",regs[i].regmap[0],regs[i].regmap[1],regs[i].regmap[2],regs[i].regmap[3],regs[i].regmap[5],regs[i].regmap[6],regs[i].regmap[7]);
9101     if(regs[i].dirty&1) printf("eax ");
9102     if((regs[i].dirty>>1)&1) printf("ecx ");
9103     if((regs[i].dirty>>2)&1) printf("edx ");
9104     if((regs[i].dirty>>3)&1) printf("ebx ");
9105     if((regs[i].dirty>>5)&1) printf("ebp ");
9106     if((regs[i].dirty>>6)&1) printf("esi ");
9107     if((regs[i].dirty>>7)&1) printf("edi ");
9108     #endif
9109     #ifdef __arm__
9110     printf("r0=%d r1=%d r2=%d r3=%d r4=%d r5=%d r6=%d r7=%d r8=%d r9=%d r10=%d r12=%d dirty: ",regs[i].regmap[0],regs[i].regmap[1],regs[i].regmap[2],regs[i].regmap[3],regs[i].regmap[4],regs[i].regmap[5],regs[i].regmap[6],regs[i].regmap[7],regs[i].regmap[8],regs[i].regmap[9],regs[i].regmap[10],regs[i].regmap[12]);
9111     if(regs[i].dirty&1) printf("r0 ");
9112     if((regs[i].dirty>>1)&1) printf("r1 ");
9113     if((regs[i].dirty>>2)&1) printf("r2 ");
9114     if((regs[i].dirty>>3)&1) printf("r3 ");
9115     if((regs[i].dirty>>4)&1) printf("r4 ");
9116     if((regs[i].dirty>>5)&1) printf("r5 ");
9117     if((regs[i].dirty>>6)&1) printf("r6 ");
9118     if((regs[i].dirty>>7)&1) printf("r7 ");
9119     if((regs[i].dirty>>8)&1) printf("r8 ");
9120     if((regs[i].dirty>>9)&1) printf("r9 ");
9121     if((regs[i].dirty>>10)&1) printf("r10 ");
9122     if((regs[i].dirty>>12)&1) printf("r12 ");
9123     #endif
9124     printf("\n");
9125     if(regs[i].isconst) {
9126       printf("constants: ");
9127       #if defined(__i386__) || defined(__x86_64__)
9128       if(regs[i].isconst&1) printf("eax=%x ",(u_int)constmap[i][0]);
9129       if((regs[i].isconst>>1)&1) printf("ecx=%x ",(u_int)constmap[i][1]);
9130       if((regs[i].isconst>>2)&1) printf("edx=%x ",(u_int)constmap[i][2]);
9131       if((regs[i].isconst>>3)&1) printf("ebx=%x ",(u_int)constmap[i][3]);
9132       if((regs[i].isconst>>5)&1) printf("ebp=%x ",(u_int)constmap[i][5]);
9133       if((regs[i].isconst>>6)&1) printf("esi=%x ",(u_int)constmap[i][6]);
9134       if((regs[i].isconst>>7)&1) printf("edi=%x ",(u_int)constmap[i][7]);
9135       #endif
9136       #if defined(__arm__) || defined(__aarch64__)
9137       int r;
9138       for (r = 0; r < ARRAY_SIZE(constmap[i]); r++)
9139         if ((regs[i].isconst >> r) & 1)
9140           printf(" r%d=%x", r, (u_int)constmap[i][r]);
9141       #endif
9142       printf("\n");
9143     }
9144     if(dops[i].is_jump) {
9145       #if defined(__i386__) || defined(__x86_64__)
9146       printf("branch(%d): eax=%d ecx=%d edx=%d ebx=%d ebp=%d esi=%d edi=%d dirty: ",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7]);
9147       if(branch_regs[i].dirty&1) printf("eax ");
9148       if((branch_regs[i].dirty>>1)&1) printf("ecx ");
9149       if((branch_regs[i].dirty>>2)&1) printf("edx ");
9150       if((branch_regs[i].dirty>>3)&1) printf("ebx ");
9151       if((branch_regs[i].dirty>>5)&1) printf("ebp ");
9152       if((branch_regs[i].dirty>>6)&1) printf("esi ");
9153       if((branch_regs[i].dirty>>7)&1) printf("edi ");
9154       #endif
9155       #ifdef __arm__
9156       printf("branch(%d): r0=%d r1=%d r2=%d r3=%d r4=%d r5=%d r6=%d r7=%d r8=%d r9=%d r10=%d r12=%d dirty: ",i,branch_regs[i].regmap[0],branch_regs[i].regmap[1],branch_regs[i].regmap[2],branch_regs[i].regmap[3],branch_regs[i].regmap[4],branch_regs[i].regmap[5],branch_regs[i].regmap[6],branch_regs[i].regmap[7],branch_regs[i].regmap[8],branch_regs[i].regmap[9],branch_regs[i].regmap[10],branch_regs[i].regmap[12]);
9157       if(branch_regs[i].dirty&1) printf("r0 ");
9158       if((branch_regs[i].dirty>>1)&1) printf("r1 ");
9159       if((branch_regs[i].dirty>>2)&1) printf("r2 ");
9160       if((branch_regs[i].dirty>>3)&1) printf("r3 ");
9161       if((branch_regs[i].dirty>>4)&1) printf("r4 ");
9162       if((branch_regs[i].dirty>>5)&1) printf("r5 ");
9163       if((branch_regs[i].dirty>>6)&1) printf("r6 ");
9164       if((branch_regs[i].dirty>>7)&1) printf("r7 ");
9165       if((branch_regs[i].dirty>>8)&1) printf("r8 ");
9166       if((branch_regs[i].dirty>>9)&1) printf("r9 ");
9167       if((branch_regs[i].dirty>>10)&1) printf("r10 ");
9168       if((branch_regs[i].dirty>>12)&1) printf("r12 ");
9169       #endif
9170     }
9171   }
9172 #endif // REG_ALLOC_PRINT
9173
9174   /* Pass 8 - Assembly */
9175   linkcount=0;stubcount=0;
9176   ds=0;is_delayslot=0;
9177   u_int dirty_pre=0;
9178   void *beginning=start_block();
9179   if((u_int)addr&1) {
9180     ds=1;
9181     pagespan_ds();
9182   }
9183   void *instr_addr0_override = NULL;
9184
9185   if (start == 0x80030000) {
9186     // nasty hack for the fastbios thing
9187     // override block entry to this code
9188     instr_addr0_override = out;
9189     emit_movimm(start,0);
9190     // abuse io address var as a flag that we
9191     // have already returned here once
9192     emit_readword(&address,1);
9193     emit_writeword(0,&pcaddr);
9194     emit_writeword(0,&address);
9195     emit_cmp(0,1);
9196     #ifdef __aarch64__
9197     emit_jeq(out + 4*2);
9198     emit_far_jump(new_dyna_leave);
9199     #else
9200     emit_jne(new_dyna_leave);
9201     #endif
9202   }
9203   for(i=0;i<slen;i++)
9204   {
9205     //if(ds) printf("ds: ");
9206     disassemble_inst(i);
9207     if(ds) {
9208       ds=0; // Skip delay slot
9209       if(dops[i].bt) assem_debug("OOPS - branch into delay slot\n");
9210       instr_addr[i] = NULL;
9211     } else {
9212       speculate_register_values(i);
9213       #ifndef DESTRUCTIVE_WRITEBACK
9214       if (i < 2 || !dops[i-2].is_ujump)
9215       {
9216         wb_valid(regmap_pre[i],regs[i].regmap_entry,dirty_pre,regs[i].wasdirty,unneeded_reg[i]);
9217       }
9218       if((dops[i].itype==CJUMP||dops[i].itype==SJUMP)) {
9219         dirty_pre=branch_regs[i].dirty;
9220       }else{
9221         dirty_pre=regs[i].dirty;
9222       }
9223       #endif
9224       // write back
9225       if (i < 2 || !dops[i-2].is_ujump)
9226       {
9227         wb_invalidate(regmap_pre[i],regs[i].regmap_entry,regs[i].wasdirty,unneeded_reg[i]);
9228         loop_preload(regmap_pre[i],regs[i].regmap_entry);
9229       }
9230       // branch target entry point
9231       instr_addr[i] = out;
9232       assem_debug("<->\n");
9233       drc_dbg_emit_do_cmp(i, ccadj[i]);
9234       if (clear_hack_addr) {
9235         emit_movimm(0, 0);
9236         emit_writeword(0, &hack_addr);
9237         clear_hack_addr = 0;
9238       }
9239
9240       // load regs
9241       if(regs[i].regmap_entry[HOST_CCREG]==CCREG&&regs[i].regmap[HOST_CCREG]!=CCREG)
9242         wb_register(CCREG,regs[i].regmap_entry,regs[i].wasdirty);
9243       load_regs(regs[i].regmap_entry,regs[i].regmap,dops[i].rs1,dops[i].rs2);
9244       address_generation(i,&regs[i],regs[i].regmap_entry);
9245       load_consts(regmap_pre[i],regs[i].regmap,i);
9246       if(dops[i].is_jump)
9247       {
9248         // Load the delay slot registers if necessary
9249         if(dops[i+1].rs1!=dops[i].rs1&&dops[i+1].rs1!=dops[i].rs2&&(dops[i+1].rs1!=dops[i].rt1||dops[i].rt1==0))
9250           load_regs(regs[i].regmap_entry,regs[i].regmap,dops[i+1].rs1,dops[i+1].rs1);
9251         if(dops[i+1].rs2!=dops[i+1].rs1&&dops[i+1].rs2!=dops[i].rs1&&dops[i+1].rs2!=dops[i].rs2&&(dops[i+1].rs2!=dops[i].rt1||dops[i].rt1==0))
9252           load_regs(regs[i].regmap_entry,regs[i].regmap,dops[i+1].rs2,dops[i+1].rs2);
9253         if (ram_offset && (dops[i+1].is_load || dops[i+1].is_store))
9254           load_regs(regs[i].regmap_entry,regs[i].regmap,ROREG,ROREG);
9255         if (dops[i+1].is_store)
9256           load_regs(regs[i].regmap_entry,regs[i].regmap,INVCP,INVCP);
9257       }
9258       else if(i+1<slen)
9259       {
9260         // Preload registers for following instruction
9261         if(dops[i+1].rs1!=dops[i].rs1&&dops[i+1].rs1!=dops[i].rs2)
9262           if(dops[i+1].rs1!=dops[i].rt1&&dops[i+1].rs1!=dops[i].rt2)
9263             load_regs(regs[i].regmap_entry,regs[i].regmap,dops[i+1].rs1,dops[i+1].rs1);
9264         if(dops[i+1].rs2!=dops[i+1].rs1&&dops[i+1].rs2!=dops[i].rs1&&dops[i+1].rs2!=dops[i].rs2)
9265           if(dops[i+1].rs2!=dops[i].rt1&&dops[i+1].rs2!=dops[i].rt2)
9266             load_regs(regs[i].regmap_entry,regs[i].regmap,dops[i+1].rs2,dops[i+1].rs2);
9267       }
9268       // TODO: if(is_ooo(i)) address_generation(i+1);
9269       if (!dops[i].is_jump || dops[i].itype == CJUMP)
9270         load_regs(regs[i].regmap_entry,regs[i].regmap,CCREG,CCREG);
9271       if (ram_offset && (dops[i].is_load || dops[i].is_store))
9272         load_regs(regs[i].regmap_entry,regs[i].regmap,ROREG,ROREG);
9273       if (dops[i].is_store)
9274         load_regs(regs[i].regmap_entry,regs[i].regmap,INVCP,INVCP);
9275
9276       ds = assemble(i, &regs[i], ccadj[i]);
9277
9278       if (dops[i].is_ujump)
9279         literal_pool(1024);
9280       else
9281         literal_pool_jumpover(256);
9282     }
9283   }
9284
9285   assert(slen > 0);
9286   if (slen > 0 && dops[slen-1].itype == INTCALL) {
9287     // no ending needed for this block since INTCALL never returns
9288   }
9289   // If the block did not end with an unconditional branch,
9290   // add a jump to the next instruction.
9291   else if (i > 1) {
9292     if (!dops[i-2].is_ujump && dops[i-1].itype != SPAN) {
9293       assert(!dops[i-1].is_jump);
9294       assert(i==slen);
9295       if(dops[i-2].itype!=CJUMP&&dops[i-2].itype!=SJUMP) {
9296         store_regs_bt(regs[i-1].regmap,regs[i-1].dirty,start+i*4);
9297         if(regs[i-1].regmap[HOST_CCREG]!=CCREG)
9298           emit_loadreg(CCREG,HOST_CCREG);
9299         emit_addimm(HOST_CCREG, ccadj[i-1] + CLOCK_ADJUST(1), HOST_CCREG);
9300       }
9301       else
9302       {
9303         store_regs_bt(branch_regs[i-2].regmap,branch_regs[i-2].dirty,start+i*4);
9304         assert(branch_regs[i-2].regmap[HOST_CCREG]==CCREG);
9305       }
9306       add_to_linker(out,start+i*4,0);
9307       emit_jmp(0);
9308     }
9309   }
9310   else
9311   {
9312     assert(i>0);
9313     assert(!dops[i-1].is_jump);
9314     store_regs_bt(regs[i-1].regmap,regs[i-1].dirty,start+i*4);
9315     if(regs[i-1].regmap[HOST_CCREG]!=CCREG)
9316       emit_loadreg(CCREG,HOST_CCREG);
9317     emit_addimm(HOST_CCREG, ccadj[i-1] + CLOCK_ADJUST(1), HOST_CCREG);
9318     add_to_linker(out,start+i*4,0);
9319     emit_jmp(0);
9320   }
9321
9322   // TODO: delay slot stubs?
9323   // Stubs
9324   for(i=0;i<stubcount;i++)
9325   {
9326     switch(stubs[i].type)
9327     {
9328       case LOADB_STUB:
9329       case LOADH_STUB:
9330       case LOADW_STUB:
9331       case LOADD_STUB:
9332       case LOADBU_STUB:
9333       case LOADHU_STUB:
9334         do_readstub(i);break;
9335       case STOREB_STUB:
9336       case STOREH_STUB:
9337       case STOREW_STUB:
9338       case STORED_STUB:
9339         do_writestub(i);break;
9340       case CC_STUB:
9341         do_ccstub(i);break;
9342       case INVCODE_STUB:
9343         do_invstub(i);break;
9344       case FP_STUB:
9345         do_cop1stub(i);break;
9346       case STORELR_STUB:
9347         do_unalignedwritestub(i);break;
9348     }
9349   }
9350
9351   if (instr_addr0_override)
9352     instr_addr[0] = instr_addr0_override;
9353
9354   /* Pass 9 - Linker */
9355   for(i=0;i<linkcount;i++)
9356   {
9357     assem_debug("%p -> %8x\n",link_addr[i].addr,link_addr[i].target);
9358     literal_pool(64);
9359     if (!link_addr[i].ext)
9360     {
9361       void *stub = out;
9362       void *addr = check_addr(link_addr[i].target);
9363       emit_extjump(link_addr[i].addr, link_addr[i].target);
9364       if (addr) {
9365         set_jump_target(link_addr[i].addr, addr);
9366         add_jump_out(link_addr[i].target,stub);
9367       }
9368       else
9369         set_jump_target(link_addr[i].addr, stub);
9370     }
9371     else
9372     {
9373       // Internal branch
9374       int target=(link_addr[i].target-start)>>2;
9375       assert(target>=0&&target<slen);
9376       assert(instr_addr[target]);
9377       //#ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
9378       //set_jump_target_fillslot(link_addr[i].addr,instr_addr[target],link_addr[i].ext>>1);
9379       //#else
9380       set_jump_target(link_addr[i].addr, instr_addr[target]);
9381       //#endif
9382     }
9383   }
9384
9385   u_int source_len = slen*4;
9386   if (dops[slen-1].itype == INTCALL && source_len > 4)
9387     // no need to treat the last instruction as compiled
9388     // as interpreter fully handles it
9389     source_len -= 4;
9390
9391   if ((u_char *)copy + source_len > (u_char *)shadow + sizeof(shadow))
9392     copy = shadow;
9393
9394   // External Branch Targets (jump_in)
9395   for(i=0;i<slen;i++)
9396   {
9397     if(dops[i].bt||i==0)
9398     {
9399       if(instr_addr[i]) // TODO - delay slots (=null)
9400       {
9401         u_int vaddr=start+i*4;
9402         u_int page=get_page(vaddr);
9403         u_int vpage=get_vpage(vaddr);
9404         literal_pool(256);
9405         {
9406           assem_debug("%p (%d) <- %8x\n",instr_addr[i],i,start+i*4);
9407           assem_debug("jump_in: %x\n",start+i*4);
9408           ll_add(jump_dirty+vpage,vaddr,out);
9409           void *entry_point = do_dirty_stub(i, source_len);
9410           ll_add_flags(jump_in+page,vaddr,state_rflags,entry_point);
9411           // If there was an existing entry in the hash table,
9412           // replace it with the new address.
9413           // Don't add new entries.  We'll insert the
9414           // ones that actually get used in check_addr().
9415           struct ht_entry *ht_bin = hash_table_get(vaddr);
9416           if (ht_bin->vaddr[0] == vaddr)
9417             ht_bin->tcaddr[0] = entry_point;
9418           if (ht_bin->vaddr[1] == vaddr)
9419             ht_bin->tcaddr[1] = entry_point;
9420         }
9421       }
9422     }
9423   }
9424   // Write out the literal pool if necessary
9425   literal_pool(0);
9426   #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
9427   // Align code
9428   if(((u_int)out)&7) emit_addnop(13);
9429   #endif
9430   assert(out - (u_char *)beginning < MAX_OUTPUT_BLOCK_SIZE);
9431   //printf("shadow buffer: %p-%p\n",copy,(u_char *)copy+slen*4);
9432   memcpy(copy, source, source_len);
9433   copy += source_len;
9434
9435   end_block(beginning);
9436
9437   // If we're within 256K of the end of the buffer,
9438   // start over from the beginning. (Is 256K enough?)
9439   if (out > ndrc->translation_cache + sizeof(ndrc->translation_cache) - MAX_OUTPUT_BLOCK_SIZE)
9440     out = ndrc->translation_cache;
9441
9442   // Trap writes to any of the pages we compiled
9443   for(i=start>>12;i<=(start+slen*4)>>12;i++) {
9444     invalid_code[i]=0;
9445   }
9446   inv_code_start=inv_code_end=~0;
9447
9448   // for PCSX we need to mark all mirrors too
9449   if(get_page(start)<(RAM_SIZE>>12))
9450     for(i=start>>12;i<=(start+slen*4)>>12;i++)
9451       invalid_code[((u_int)0x00000000>>12)|(i&0x1ff)]=
9452       invalid_code[((u_int)0x80000000>>12)|(i&0x1ff)]=
9453       invalid_code[((u_int)0xa0000000>>12)|(i&0x1ff)]=0;
9454
9455   /* Pass 10 - Free memory by expiring oldest blocks */
9456
9457   int end=(((out-ndrc->translation_cache)>>(TARGET_SIZE_2-16))+16384)&65535;
9458   while(expirep!=end)
9459   {
9460     int shift=TARGET_SIZE_2-3; // Divide into 8 blocks
9461     uintptr_t base_offs = ((uintptr_t)(expirep >> 13) << shift); // Base offset of this block
9462     uintptr_t base_offs_s = base_offs >> shift;
9463     inv_debug("EXP: Phase %d\n",expirep);
9464     switch((expirep>>11)&3)
9465     {
9466       case 0:
9467         // Clear jump_in and jump_dirty
9468         ll_remove_matching_addrs(jump_in+(expirep&2047),base_offs_s,shift);
9469         ll_remove_matching_addrs(jump_dirty+(expirep&2047),base_offs_s,shift);
9470         ll_remove_matching_addrs(jump_in+2048+(expirep&2047),base_offs_s,shift);
9471         ll_remove_matching_addrs(jump_dirty+2048+(expirep&2047),base_offs_s,shift);
9472         break;
9473       case 1:
9474         // Clear pointers
9475         ll_kill_pointers(jump_out[expirep&2047],base_offs_s,shift);
9476         ll_kill_pointers(jump_out[(expirep&2047)+2048],base_offs_s,shift);
9477         break;
9478       case 2:
9479         // Clear hash table
9480         for(i=0;i<32;i++) {
9481           struct ht_entry *ht_bin = &hash_table[((expirep&2047)<<5)+i];
9482           uintptr_t o1 = (u_char *)ht_bin->tcaddr[1] - ndrc->translation_cache;
9483           uintptr_t o2 = o1 - MAX_OUTPUT_BLOCK_SIZE;
9484           if ((o1 >> shift) == base_offs_s || (o2 >> shift) == base_offs_s) {
9485             inv_debug("EXP: Remove hash %x -> %p\n",ht_bin->vaddr[1],ht_bin->tcaddr[1]);
9486             ht_bin->vaddr[1] = -1;
9487             ht_bin->tcaddr[1] = NULL;
9488           }
9489           o1 = (u_char *)ht_bin->tcaddr[0] - ndrc->translation_cache;
9490           o2 = o1 - MAX_OUTPUT_BLOCK_SIZE;
9491           if ((o1 >> shift) == base_offs_s || (o2 >> shift) == base_offs_s) {
9492             inv_debug("EXP: Remove hash %x -> %p\n",ht_bin->vaddr[0],ht_bin->tcaddr[0]);
9493             ht_bin->vaddr[0] = ht_bin->vaddr[1];
9494             ht_bin->tcaddr[0] = ht_bin->tcaddr[1];
9495             ht_bin->vaddr[1] = -1;
9496             ht_bin->tcaddr[1] = NULL;
9497           }
9498         }
9499         break;
9500       case 3:
9501         // Clear jump_out
9502         if((expirep&2047)==0)
9503           do_clear_cache();
9504         ll_remove_matching_addrs(jump_out+(expirep&2047),base_offs_s,shift);
9505         ll_remove_matching_addrs(jump_out+2048+(expirep&2047),base_offs_s,shift);
9506         break;
9507     }
9508     expirep=(expirep+1)&65535;
9509   }
9510 #ifdef ASSEM_PRINT
9511   fflush(stdout);
9512 #endif
9513   return 0;
9514 }
9515
9516 // vim:shiftwidth=2:expandtab