drc: clear dirty flag when deallocating a reg
[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 // regmap_pre[i]    - regs before [i] insn starts; dirty things here that
123 //                    don't match .regmap will be written back
124 // [i].regmap_entry - regs that must be set up if someone jumps here
125 // [i].regmap       - regs [i] insn will read/(over)write
126 struct regstat
127 {
128   signed char regmap_entry[HOST_REGS];
129   signed char regmap[HOST_REGS];
130   uint64_t wasdirty;
131   uint64_t dirty;
132   uint64_t u;
133   u_int wasconst;                // before; for example 'lw r2, (r2)' wasconst is true
134   u_int isconst;                 //  ... but isconst is false when r2 is known
135   u_int loadedconst;             // host regs that have constants loaded
136   u_int waswritten;              // MIPS regs that were used as store base before
137 };
138
139 // note: asm depends on this layout
140 struct ll_entry
141 {
142   u_int vaddr;
143   u_int reg_sv_flags;
144   void *addr;
145   struct ll_entry *next;
146 };
147
148 struct ht_entry
149 {
150   u_int vaddr[2];
151   void *tcaddr[2];
152 };
153
154 struct code_stub
155 {
156   enum stub_type type;
157   void *addr;
158   void *retaddr;
159   u_int a;
160   uintptr_t b;
161   uintptr_t c;
162   u_int d;
163   u_int e;
164 };
165
166 struct link_entry
167 {
168   void *addr;
169   u_int target;
170   u_int ext;
171 };
172
173 static struct decoded_insn
174 {
175   u_char itype;
176   u_char opcode;
177   u_char opcode2;
178   u_char rs1;
179   u_char rs2;
180   u_char rt1;
181   u_char rt2;
182   u_char lt1;
183   u_char bt:1;
184   u_char ooo:1;
185   u_char is_ds:1;
186   u_char is_jump:1;
187   u_char is_ujump:1;
188   u_char is_load:1;
189   u_char is_store:1;
190 } dops[MAXBLOCK];
191
192   // used by asm:
193   u_char *out;
194   struct ht_entry hash_table[65536]  __attribute__((aligned(16)));
195   struct ll_entry *jump_in[4096] __attribute__((aligned(16)));
196   struct ll_entry *jump_dirty[4096];
197
198   static struct ll_entry *jump_out[4096];
199   static u_int start;
200   static u_int *source;
201   static char insn[MAXBLOCK][10];
202   static uint64_t gte_rs[MAXBLOCK]; // gte: 32 data and 32 ctl regs
203   static uint64_t gte_rt[MAXBLOCK];
204   static uint64_t gte_unneeded[MAXBLOCK];
205   static u_int smrv[32]; // speculated MIPS register values
206   static u_int smrv_strong; // mask or regs that are likely to have correct values
207   static u_int smrv_weak; // same, but somewhat less likely
208   static u_int smrv_strong_next; // same, but after current insn executes
209   static u_int smrv_weak_next;
210   static int imm[MAXBLOCK];
211   static u_int ba[MAXBLOCK];
212   static uint64_t unneeded_reg[MAXBLOCK];
213   static uint64_t branch_unneeded_reg[MAXBLOCK];
214   // see 'struct regstat' for a description
215   static signed char regmap_pre[MAXBLOCK][HOST_REGS];
216   // contains 'real' consts at [i] insn, but may differ from what's actually
217   // loaded in host reg as 'final' value is always loaded, see get_final_value()
218   static uint32_t current_constmap[HOST_REGS];
219   static uint32_t constmap[MAXBLOCK][HOST_REGS];
220   static struct regstat regs[MAXBLOCK];
221   static struct regstat branch_regs[MAXBLOCK];
222   static signed char minimum_free_regs[MAXBLOCK];
223   static u_int needed_reg[MAXBLOCK];
224   static u_int wont_dirty[MAXBLOCK];
225   static u_int will_dirty[MAXBLOCK];
226   static int ccadj[MAXBLOCK];
227   static int slen;
228   static void *instr_addr[MAXBLOCK];
229   static struct link_entry link_addr[MAXBLOCK];
230   static int linkcount;
231   static struct code_stub stubs[MAXBLOCK*3];
232   static int stubcount;
233   static u_int literals[1024][2];
234   static int literalcount;
235   static int is_delayslot;
236   static char shadow[1048576]  __attribute__((aligned(16)));
237   static void *copy;
238   static int expirep;
239   static u_int stop_after_jal;
240   static u_int f1_hack;
241
242   int new_dynarec_hacks;
243   int new_dynarec_hacks_pergame;
244   int new_dynarec_hacks_old;
245   int new_dynarec_did_compile;
246
247   #define HACK_ENABLED(x) ((new_dynarec_hacks | new_dynarec_hacks_pergame) & (x))
248
249   extern int cycle_count; // ... until end of the timeslice, counts -N -> 0
250   extern int last_count;  // last absolute target, often = next_interupt
251   extern int pcaddr;
252   extern int pending_exception;
253   extern int branch_target;
254   extern uintptr_t ram_offset;
255   extern uintptr_t mini_ht[32][2];
256   extern u_char restore_candidate[512];
257
258   /* registers that may be allocated */
259   /* 1-31 gpr */
260 #define LOREG 32 // lo
261 #define HIREG 33 // hi
262 //#define FSREG 34 // FPU status (FCSR)
263 #define CSREG 35 // Coprocessor status
264 #define CCREG 36 // Cycle count
265 #define INVCP 37 // Pointer to invalid_code
266 //#define MMREG 38 // Pointer to memory_map
267 #define ROREG 39 // ram offset (if rdram!=0x80000000)
268 #define TEMPREG 40
269 #define FTEMP 40 // FPU temporary register
270 #define PTEMP 41 // Prefetch temporary register
271 //#define TLREG 42 // TLB mapping offset
272 #define RHASH 43 // Return address hash
273 #define RHTBL 44 // Return address hash table address
274 #define RTEMP 45 // JR/JALR address register
275 #define MAXREG 45
276 #define AGEN1 46 // Address generation temporary register
277 //#define AGEN2 47 // Address generation temporary register
278 //#define MGEN1 48 // Maptable address generation temporary register
279 //#define MGEN2 49 // Maptable address generation temporary register
280 #define BTREG 50 // Branch target temporary register
281
282   /* instruction types */
283 #define NOP 0     // No operation
284 #define LOAD 1    // Load
285 #define STORE 2   // Store
286 #define LOADLR 3  // Unaligned load
287 #define STORELR 4 // Unaligned store
288 #define MOV 5     // Move
289 #define ALU 6     // Arithmetic/logic
290 #define MULTDIV 7 // Multiply/divide
291 #define SHIFT 8   // Shift by register
292 #define SHIFTIMM 9// Shift by immediate
293 #define IMM16 10  // 16-bit immediate
294 #define RJUMP 11  // Unconditional jump to register
295 #define UJUMP 12  // Unconditional jump
296 #define CJUMP 13  // Conditional branch (BEQ/BNE/BGTZ/BLEZ)
297 #define SJUMP 14  // Conditional branch (regimm format)
298 #define COP0 15   // Coprocessor 0
299 #define COP1 16   // Coprocessor 1
300 #define C1LS 17   // Coprocessor 1 load/store
301 //#define FJUMP 18  // Conditional branch (floating point)
302 //#define FLOAT 19  // Floating point unit
303 //#define FCONV 20  // Convert integer to float
304 //#define FCOMP 21  // Floating point compare (sets FSREG)
305 #define SYSCALL 22// SYSCALL,BREAK
306 #define OTHER 23  // Other
307 #define SPAN 24   // Branch/delay slot spans 2 pages
308 #define NI 25     // Not implemented
309 #define HLECALL 26// PCSX fake opcodes for HLE
310 #define COP2 27   // Coprocessor 2 move
311 #define C2LS 28   // Coprocessor 2 load/store
312 #define C2OP 29   // Coprocessor 2 operation
313 #define INTCALL 30// Call interpreter to handle rare corner cases
314
315   /* branch codes */
316 #define TAKEN 1
317 #define NOTTAKEN 2
318 #define NULLDS 3
319
320 #define DJT_1 (void *)1l // no function, just a label in assem_debug log
321 #define DJT_2 (void *)2l
322
323 // asm linkage
324 int new_recompile_block(u_int addr);
325 void *get_addr_ht(u_int vaddr);
326 void invalidate_block(u_int block);
327 void invalidate_addr(u_int addr);
328 void remove_hash(int vaddr);
329 void dyna_linker();
330 void dyna_linker_ds();
331 void verify_code();
332 void verify_code_ds();
333 void cc_interrupt();
334 void fp_exception();
335 void fp_exception_ds();
336 void jump_syscall   (u_int u0, u_int u1, u_int pc);
337 void jump_syscall_ds(u_int u0, u_int u1, u_int pc);
338 void jump_break   (u_int u0, u_int u1, u_int pc);
339 void jump_break_ds(u_int u0, u_int u1, u_int pc);
340 void jump_to_new_pc();
341 void call_gteStall();
342 void new_dyna_leave();
343
344 // Needed by assembler
345 static void wb_register(signed char r, const signed char regmap[], uint64_t dirty);
346 static void wb_dirtys(const signed char i_regmap[], uint64_t i_dirty);
347 static void wb_needed_dirtys(const signed char i_regmap[], uint64_t i_dirty, int addr);
348 static void load_all_regs(const signed char i_regmap[]);
349 static void load_needed_regs(const signed char i_regmap[], const signed char next_regmap[]);
350 static void load_regs_entry(int t);
351 static void load_all_consts(const signed char regmap[], u_int dirty, int i);
352 static u_int get_host_reglist(const signed char *regmap);
353
354 static int verify_dirty(const u_int *ptr);
355 static int get_final_value(int hr, int i, int *value);
356 static void add_stub(enum stub_type type, void *addr, void *retaddr,
357   u_int a, uintptr_t b, uintptr_t c, u_int d, u_int e);
358 static void add_stub_r(enum stub_type type, void *addr, void *retaddr,
359   int i, int addr_reg, const struct regstat *i_regs, int ccadj, u_int reglist);
360 static void add_to_linker(void *addr, u_int target, int ext);
361 static void *emit_fastpath_cmp_jump(int i, const struct regstat *i_regs,
362   int addr, int *offset_reg, int *addr_reg_override);
363 static void *get_direct_memhandler(void *table, u_int addr,
364   enum stub_type type, uintptr_t *addr_host);
365 static void cop2_do_stall_check(u_int op, int i, const struct regstat *i_regs, u_int reglist);
366 static void pass_args(int a0, int a1);
367 static void emit_far_jump(const void *f);
368 static void emit_far_call(const void *f);
369
370 #ifdef VITA
371 #include <psp2/kernel/sysmem.h>
372 static int sceBlock;
373 // note: this interacts with RetroArch's Vita bootstrap code: bootstrap/vita/sbrk.c
374 extern int getVMBlock();
375 int _newlib_vm_size_user = sizeof(*ndrc);
376 #endif
377
378 static void mprotect_w_x(void *start, void *end, int is_x)
379 {
380 #ifdef NO_WRITE_EXEC
381   #if defined(VITA)
382   // *Open* enables write on all memory that was
383   // allocated by sceKernelAllocMemBlockForVM()?
384   if (is_x)
385     sceKernelCloseVMDomain();
386   else
387     sceKernelOpenVMDomain();
388   #else
389   u_long mstart = (u_long)start & ~4095ul;
390   u_long mend = (u_long)end;
391   if (mprotect((void *)mstart, mend - mstart,
392                PROT_READ | (is_x ? PROT_EXEC : PROT_WRITE)) != 0)
393     SysPrintf("mprotect(%c) failed: %s\n", is_x ? 'x' : 'w', strerror(errno));
394   #endif
395 #endif
396 }
397
398 static void start_tcache_write(void *start, void *end)
399 {
400   mprotect_w_x(start, end, 0);
401 }
402
403 static void end_tcache_write(void *start, void *end)
404 {
405 #if defined(__arm__) || defined(__aarch64__)
406   size_t len = (char *)end - (char *)start;
407   #if   defined(__BLACKBERRY_QNX__)
408   msync(start, len, MS_SYNC | MS_CACHE_ONLY | MS_INVALIDATE_ICACHE);
409   #elif defined(__MACH__)
410   sys_cache_control(kCacheFunctionPrepareForExecution, start, len);
411   #elif defined(VITA)
412   sceKernelSyncVMDomain(sceBlock, start, len);
413   #elif defined(_3DS)
414   ctr_flush_invalidate_cache();
415   #elif defined(__aarch64__)
416   // as of 2021, __clear_cache() is still broken on arm64
417   // so here is a custom one :(
418   clear_cache_arm64(start, end);
419   #else
420   __clear_cache(start, end);
421   #endif
422   (void)len;
423 #endif
424
425   mprotect_w_x(start, end, 1);
426 }
427
428 static void *start_block(void)
429 {
430   u_char *end = out + MAX_OUTPUT_BLOCK_SIZE;
431   if (end > ndrc->translation_cache + sizeof(ndrc->translation_cache))
432     end = ndrc->translation_cache + sizeof(ndrc->translation_cache);
433   start_tcache_write(out, end);
434   return out;
435 }
436
437 static void end_block(void *start)
438 {
439   end_tcache_write(start, out);
440 }
441
442 // also takes care of w^x mappings when patching code
443 static u_int needs_clear_cache[1<<(TARGET_SIZE_2-17)];
444
445 static void mark_clear_cache(void *target)
446 {
447   uintptr_t offset = (u_char *)target - ndrc->translation_cache;
448   u_int mask = 1u << ((offset >> 12) & 31);
449   if (!(needs_clear_cache[offset >> 17] & mask)) {
450     char *start = (char *)((uintptr_t)target & ~4095l);
451     start_tcache_write(start, start + 4095);
452     needs_clear_cache[offset >> 17] |= mask;
453   }
454 }
455
456 // Clearing the cache is rather slow on ARM Linux, so mark the areas
457 // that need to be cleared, and then only clear these areas once.
458 static void do_clear_cache(void)
459 {
460   int i, j;
461   for (i = 0; i < (1<<(TARGET_SIZE_2-17)); i++)
462   {
463     u_int bitmap = needs_clear_cache[i];
464     if (!bitmap)
465       continue;
466     for (j = 0; j < 32; j++)
467     {
468       u_char *start, *end;
469       if (!(bitmap & (1<<j)))
470         continue;
471
472       start = ndrc->translation_cache + i*131072 + j*4096;
473       end = start + 4095;
474       for (j++; j < 32; j++) {
475         if (!(bitmap & (1<<j)))
476           break;
477         end += 4096;
478       }
479       end_tcache_write(start, end);
480     }
481     needs_clear_cache[i] = 0;
482   }
483 }
484
485 //#define DEBUG_CYCLE_COUNT 1
486
487 #define NO_CYCLE_PENALTY_THR 12
488
489 int cycle_multiplier = CYCLE_MULT_DEFAULT; // 100 for 1.0
490 int cycle_multiplier_override;
491 int cycle_multiplier_old;
492 static int cycle_multiplier_active;
493
494 static int CLOCK_ADJUST(int x)
495 {
496   int m = cycle_multiplier_active;
497   int s = (x >> 31) | 1;
498   return (x * m + s * 50) / 100;
499 }
500
501 static int ds_writes_rjump_rs(int i)
502 {
503   return dops[i].rs1 != 0 && (dops[i].rs1 == dops[i+1].rt1 || dops[i].rs1 == dops[i+1].rt2);
504 }
505
506 static u_int get_page(u_int vaddr)
507 {
508   u_int page=vaddr&~0xe0000000;
509   if (page < 0x1000000)
510     page &= ~0x0e00000; // RAM mirrors
511   page>>=12;
512   if(page>2048) page=2048+(page&2047);
513   return page;
514 }
515
516 // no virtual mem in PCSX
517 static u_int get_vpage(u_int vaddr)
518 {
519   return get_page(vaddr);
520 }
521
522 static struct ht_entry *hash_table_get(u_int vaddr)
523 {
524   return &hash_table[((vaddr>>16)^vaddr)&0xFFFF];
525 }
526
527 static void hash_table_add(struct ht_entry *ht_bin, u_int vaddr, void *tcaddr)
528 {
529   ht_bin->vaddr[1] = ht_bin->vaddr[0];
530   ht_bin->tcaddr[1] = ht_bin->tcaddr[0];
531   ht_bin->vaddr[0] = vaddr;
532   ht_bin->tcaddr[0] = tcaddr;
533 }
534
535 // some messy ari64's code, seems to rely on unsigned 32bit overflow
536 static int doesnt_expire_soon(void *tcaddr)
537 {
538   u_int diff = (u_int)((u_char *)tcaddr - out) << (32-TARGET_SIZE_2);
539   return diff > (u_int)(0x60000000 + (MAX_OUTPUT_BLOCK_SIZE << (32-TARGET_SIZE_2)));
540 }
541
542 // Get address from virtual address
543 // This is called from the recompiled JR/JALR instructions
544 void noinline *get_addr(u_int vaddr)
545 {
546   u_int page=get_page(vaddr);
547   u_int vpage=get_vpage(vaddr);
548   struct ll_entry *head;
549   //printf("TRACE: count=%d next=%d (get_addr %x,page %d)\n",Count,next_interupt,vaddr,page);
550   head=jump_in[page];
551   while(head!=NULL) {
552     if(head->vaddr==vaddr) {
553   //printf("TRACE: count=%d next=%d (get_addr match %x: %p)\n",Count,next_interupt,vaddr,head->addr);
554       hash_table_add(hash_table_get(vaddr), vaddr, head->addr);
555       return head->addr;
556     }
557     head=head->next;
558   }
559   head=jump_dirty[vpage];
560   while(head!=NULL) {
561     if(head->vaddr==vaddr) {
562       //printf("TRACE: count=%d next=%d (get_addr match dirty %x: %p)\n",Count,next_interupt,vaddr,head->addr);
563       // Don't restore blocks which are about to expire from the cache
564       if (doesnt_expire_soon(head->addr))
565       if (verify_dirty(head->addr)) {
566         //printf("restore candidate: %x (%d) d=%d\n",vaddr,page,invalid_code[vaddr>>12]);
567         invalid_code[vaddr>>12]=0;
568         inv_code_start=inv_code_end=~0;
569         if(vpage<2048) {
570           restore_candidate[vpage>>3]|=1<<(vpage&7);
571         }
572         else restore_candidate[page>>3]|=1<<(page&7);
573         struct ht_entry *ht_bin = hash_table_get(vaddr);
574         if (ht_bin->vaddr[0] == vaddr)
575           ht_bin->tcaddr[0] = head->addr; // Replace existing entry
576         else
577           hash_table_add(ht_bin, vaddr, head->addr);
578
579         return head->addr;
580       }
581     }
582     head=head->next;
583   }
584   //printf("TRACE: count=%d next=%d (get_addr no-match %x)\n",Count,next_interupt,vaddr);
585   int r=new_recompile_block(vaddr);
586   if(r==0) return get_addr(vaddr);
587   // Execute in unmapped page, generate pagefault execption
588   Status|=2;
589   Cause=(vaddr<<31)|0x8;
590   EPC=(vaddr&1)?vaddr-5:vaddr;
591   BadVAddr=(vaddr&~1);
592   Context=(Context&0xFF80000F)|((BadVAddr>>9)&0x007FFFF0);
593   EntryHi=BadVAddr&0xFFFFE000;
594   return get_addr_ht(0x80000000);
595 }
596 // Look up address in hash table first
597 void *get_addr_ht(u_int vaddr)
598 {
599   //printf("TRACE: count=%d next=%d (get_addr_ht %x)\n",Count,next_interupt,vaddr);
600   const struct ht_entry *ht_bin = hash_table_get(vaddr);
601   if (ht_bin->vaddr[0] == vaddr) return ht_bin->tcaddr[0];
602   if (ht_bin->vaddr[1] == vaddr) return ht_bin->tcaddr[1];
603   return get_addr(vaddr);
604 }
605
606 static void clear_all_regs(signed char regmap[])
607 {
608   memset(regmap, -1, sizeof(regmap[0]) * HOST_REGS);
609 }
610
611 static signed char get_reg(const signed char regmap[],int r)
612 {
613   int hr;
614   for (hr=0;hr<HOST_REGS;hr++) if(hr!=EXCLUDE_REG&&regmap[hr]==r) return hr;
615   return -1;
616 }
617
618 // Find a register that is available for two consecutive cycles
619 static signed char get_reg2(signed char regmap1[], const signed char regmap2[], int r)
620 {
621   int hr;
622   for (hr=0;hr<HOST_REGS;hr++) if(hr!=EXCLUDE_REG&&regmap1[hr]==r&&regmap2[hr]==r) return hr;
623   return -1;
624 }
625
626 int count_free_regs(signed char regmap[])
627 {
628   int count=0;
629   int hr;
630   for(hr=0;hr<HOST_REGS;hr++)
631   {
632     if(hr!=EXCLUDE_REG) {
633       if(regmap[hr]<0) count++;
634     }
635   }
636   return count;
637 }
638
639 void dirty_reg(struct regstat *cur,signed char reg)
640 {
641   int hr;
642   if(!reg) return;
643   for (hr=0;hr<HOST_REGS;hr++) {
644     if((cur->regmap[hr]&63)==reg) {
645       cur->dirty|=1<<hr;
646     }
647   }
648 }
649
650 static void set_const(struct regstat *cur, signed char reg, uint32_t value)
651 {
652   int hr;
653   if(!reg) return;
654   for (hr=0;hr<HOST_REGS;hr++) {
655     if(cur->regmap[hr]==reg) {
656       cur->isconst|=1<<hr;
657       current_constmap[hr]=value;
658     }
659   }
660 }
661
662 static void clear_const(struct regstat *cur, signed char reg)
663 {
664   int hr;
665   if(!reg) return;
666   for (hr=0;hr<HOST_REGS;hr++) {
667     if((cur->regmap[hr]&63)==reg) {
668       cur->isconst&=~(1<<hr);
669     }
670   }
671 }
672
673 static int is_const(struct regstat *cur, signed char reg)
674 {
675   int hr;
676   if(reg<0) return 0;
677   if(!reg) return 1;
678   for (hr=0;hr<HOST_REGS;hr++) {
679     if((cur->regmap[hr]&63)==reg) {
680       return (cur->isconst>>hr)&1;
681     }
682   }
683   return 0;
684 }
685
686 static uint32_t get_const(struct regstat *cur, signed char reg)
687 {
688   int hr;
689   if(!reg) return 0;
690   for (hr=0;hr<HOST_REGS;hr++) {
691     if(cur->regmap[hr]==reg) {
692       return current_constmap[hr];
693     }
694   }
695   SysPrintf("Unknown constant in r%d\n",reg);
696   abort();
697 }
698
699 // Least soon needed registers
700 // Look at the next ten instructions and see which registers
701 // will be used.  Try not to reallocate these.
702 void lsn(u_char hsn[], int i, int *preferred_reg)
703 {
704   int j;
705   int b=-1;
706   for(j=0;j<9;j++)
707   {
708     if(i+j>=slen) {
709       j=slen-i-1;
710       break;
711     }
712     if (dops[i+j].is_ujump)
713     {
714       // Don't go past an unconditonal jump
715       j++;
716       break;
717     }
718   }
719   for(;j>=0;j--)
720   {
721     if(dops[i+j].rs1) hsn[dops[i+j].rs1]=j;
722     if(dops[i+j].rs2) hsn[dops[i+j].rs2]=j;
723     if(dops[i+j].rt1) hsn[dops[i+j].rt1]=j;
724     if(dops[i+j].rt2) hsn[dops[i+j].rt2]=j;
725     if(dops[i+j].itype==STORE || dops[i+j].itype==STORELR) {
726       // Stores can allocate zero
727       hsn[dops[i+j].rs1]=j;
728       hsn[dops[i+j].rs2]=j;
729     }
730     if (ram_offset && (dops[i+j].is_load || dops[i+j].is_store))
731       hsn[ROREG] = j;
732     // On some architectures stores need invc_ptr
733     #if defined(HOST_IMM8)
734     if (dops[i+j].is_store)
735       hsn[INVCP] = j;
736     #endif
737     if(i+j>=0&&(dops[i+j].itype==UJUMP||dops[i+j].itype==CJUMP||dops[i+j].itype==SJUMP))
738     {
739       hsn[CCREG]=j;
740       b=j;
741     }
742   }
743   if(b>=0)
744   {
745     if(ba[i+b]>=start && ba[i+b]<(start+slen*4))
746     {
747       // Follow first branch
748       int t=(ba[i+b]-start)>>2;
749       j=7-b;if(t+j>=slen) j=slen-t-1;
750       for(;j>=0;j--)
751       {
752         if(dops[t+j].rs1) if(hsn[dops[t+j].rs1]>j+b+2) hsn[dops[t+j].rs1]=j+b+2;
753         if(dops[t+j].rs2) if(hsn[dops[t+j].rs2]>j+b+2) hsn[dops[t+j].rs2]=j+b+2;
754         //if(dops[t+j].rt1) if(hsn[dops[t+j].rt1]>j+b+2) hsn[dops[t+j].rt1]=j+b+2;
755         //if(dops[t+j].rt2) if(hsn[dops[t+j].rt2]>j+b+2) hsn[dops[t+j].rt2]=j+b+2;
756       }
757     }
758     // TODO: preferred register based on backward branch
759   }
760   // Delay slot should preferably not overwrite branch conditions or cycle count
761   if (i > 0 && dops[i-1].is_jump) {
762     if(dops[i-1].rs1) if(hsn[dops[i-1].rs1]>1) hsn[dops[i-1].rs1]=1;
763     if(dops[i-1].rs2) if(hsn[dops[i-1].rs2]>1) hsn[dops[i-1].rs2]=1;
764     hsn[CCREG]=1;
765     // ...or hash tables
766     hsn[RHASH]=1;
767     hsn[RHTBL]=1;
768   }
769   // Coprocessor load/store needs FTEMP, even if not declared
770   if(dops[i].itype==C2LS) {
771     hsn[FTEMP]=0;
772   }
773   // Load L/R also uses FTEMP as a temporary register
774   if(dops[i].itype==LOADLR) {
775     hsn[FTEMP]=0;
776   }
777   // Also SWL/SWR/SDL/SDR
778   if(dops[i].opcode==0x2a||dops[i].opcode==0x2e||dops[i].opcode==0x2c||dops[i].opcode==0x2d) {
779     hsn[FTEMP]=0;
780   }
781   // Don't remove the miniht registers
782   if(dops[i].itype==UJUMP||dops[i].itype==RJUMP)
783   {
784     hsn[RHASH]=0;
785     hsn[RHTBL]=0;
786   }
787 }
788
789 // We only want to allocate registers if we're going to use them again soon
790 int needed_again(int r, int i)
791 {
792   int j;
793   int b=-1;
794   int rn=10;
795
796   if (i > 0 && dops[i-1].is_ujump)
797   {
798     if(ba[i-1]<start || ba[i-1]>start+slen*4-4)
799       return 0; // Don't need any registers if exiting the block
800   }
801   for(j=0;j<9;j++)
802   {
803     if(i+j>=slen) {
804       j=slen-i-1;
805       break;
806     }
807     if (dops[i+j].is_ujump)
808     {
809       // Don't go past an unconditonal jump
810       j++;
811       break;
812     }
813     if(dops[i+j].itype==SYSCALL||dops[i+j].itype==HLECALL||dops[i+j].itype==INTCALL||((source[i+j]&0xfc00003f)==0x0d))
814     {
815       break;
816     }
817   }
818   for(;j>=1;j--)
819   {
820     if(dops[i+j].rs1==r) rn=j;
821     if(dops[i+j].rs2==r) rn=j;
822     if((unneeded_reg[i+j]>>r)&1) rn=10;
823     if(i+j>=0&&(dops[i+j].itype==UJUMP||dops[i+j].itype==CJUMP||dops[i+j].itype==SJUMP))
824     {
825       b=j;
826     }
827   }
828   if(rn<10) return 1;
829   (void)b;
830   return 0;
831 }
832
833 // Try to match register allocations at the end of a loop with those
834 // at the beginning
835 int loop_reg(int i, int r, int hr)
836 {
837   int j,k;
838   for(j=0;j<9;j++)
839   {
840     if(i+j>=slen) {
841       j=slen-i-1;
842       break;
843     }
844     if (dops[i+j].is_ujump)
845     {
846       // Don't go past an unconditonal jump
847       j++;
848       break;
849     }
850   }
851   k=0;
852   if(i>0){
853     if(dops[i-1].itype==UJUMP||dops[i-1].itype==CJUMP||dops[i-1].itype==SJUMP)
854       k--;
855   }
856   for(;k<j;k++)
857   {
858     assert(r < 64);
859     if((unneeded_reg[i+k]>>r)&1) return hr;
860     if(i+k>=0&&(dops[i+k].itype==UJUMP||dops[i+k].itype==CJUMP||dops[i+k].itype==SJUMP))
861     {
862       if(ba[i+k]>=start && ba[i+k]<(start+i*4))
863       {
864         int t=(ba[i+k]-start)>>2;
865         int reg=get_reg(regs[t].regmap_entry,r);
866         if(reg>=0) return reg;
867         //reg=get_reg(regs[t+1].regmap_entry,r);
868         //if(reg>=0) return reg;
869       }
870     }
871   }
872   return hr;
873 }
874
875
876 // Allocate every register, preserving source/target regs
877 void alloc_all(struct regstat *cur,int i)
878 {
879   int hr;
880
881   for(hr=0;hr<HOST_REGS;hr++) {
882     if(hr!=EXCLUDE_REG) {
883       if(((cur->regmap[hr]&63)!=dops[i].rs1)&&((cur->regmap[hr]&63)!=dops[i].rs2)&&
884          ((cur->regmap[hr]&63)!=dops[i].rt1)&&((cur->regmap[hr]&63)!=dops[i].rt2))
885       {
886         cur->regmap[hr]=-1;
887         cur->dirty&=~(1<<hr);
888       }
889       // Don't need zeros
890       if((cur->regmap[hr]&63)==0)
891       {
892         cur->regmap[hr]=-1;
893         cur->dirty&=~(1<<hr);
894       }
895     }
896   }
897 }
898
899 #ifndef NDEBUG
900 static int host_tempreg_in_use;
901
902 static void host_tempreg_acquire(void)
903 {
904   assert(!host_tempreg_in_use);
905   host_tempreg_in_use = 1;
906 }
907
908 static void host_tempreg_release(void)
909 {
910   host_tempreg_in_use = 0;
911 }
912 #else
913 static void host_tempreg_acquire(void) {}
914 static void host_tempreg_release(void) {}
915 #endif
916
917 #ifdef ASSEM_PRINT
918 extern void gen_interupt();
919 extern void do_insn_cmp();
920 #define FUNCNAME(f) { f, " " #f }
921 static const struct {
922   void *addr;
923   const char *name;
924 } function_names[] = {
925   FUNCNAME(cc_interrupt),
926   FUNCNAME(gen_interupt),
927   FUNCNAME(get_addr_ht),
928   FUNCNAME(get_addr),
929   FUNCNAME(jump_handler_read8),
930   FUNCNAME(jump_handler_read16),
931   FUNCNAME(jump_handler_read32),
932   FUNCNAME(jump_handler_write8),
933   FUNCNAME(jump_handler_write16),
934   FUNCNAME(jump_handler_write32),
935   FUNCNAME(invalidate_addr),
936   FUNCNAME(jump_to_new_pc),
937   FUNCNAME(jump_break),
938   FUNCNAME(jump_break_ds),
939   FUNCNAME(jump_syscall),
940   FUNCNAME(jump_syscall_ds),
941   FUNCNAME(call_gteStall),
942   FUNCNAME(new_dyna_leave),
943   FUNCNAME(pcsx_mtc0),
944   FUNCNAME(pcsx_mtc0_ds),
945 #ifdef DRC_DBG
946   FUNCNAME(do_insn_cmp),
947 #endif
948 #ifdef __arm__
949   FUNCNAME(verify_code),
950 #endif
951 };
952
953 static const char *func_name(const void *a)
954 {
955   int i;
956   for (i = 0; i < sizeof(function_names)/sizeof(function_names[0]); i++)
957     if (function_names[i].addr == a)
958       return function_names[i].name;
959   return "";
960 }
961 #else
962 #define func_name(x) ""
963 #endif
964
965 #ifdef __i386__
966 #include "assem_x86.c"
967 #endif
968 #ifdef __x86_64__
969 #include "assem_x64.c"
970 #endif
971 #ifdef __arm__
972 #include "assem_arm.c"
973 #endif
974 #ifdef __aarch64__
975 #include "assem_arm64.c"
976 #endif
977
978 static void *get_trampoline(const void *f)
979 {
980   size_t i;
981
982   for (i = 0; i < ARRAY_SIZE(ndrc->tramp.f); i++) {
983     if (ndrc->tramp.f[i] == f || ndrc->tramp.f[i] == NULL)
984       break;
985   }
986   if (i == ARRAY_SIZE(ndrc->tramp.f)) {
987     SysPrintf("trampoline table is full, last func %p\n", f);
988     abort();
989   }
990   if (ndrc->tramp.f[i] == NULL) {
991     start_tcache_write(&ndrc->tramp.f[i], &ndrc->tramp.f[i + 1]);
992     ndrc->tramp.f[i] = f;
993     end_tcache_write(&ndrc->tramp.f[i], &ndrc->tramp.f[i + 1]);
994   }
995   return &ndrc->tramp.ops[i];
996 }
997
998 static void emit_far_jump(const void *f)
999 {
1000   if (can_jump_or_call(f)) {
1001     emit_jmp(f);
1002     return;
1003   }
1004
1005   f = get_trampoline(f);
1006   emit_jmp(f);
1007 }
1008
1009 static void emit_far_call(const void *f)
1010 {
1011   if (can_jump_or_call(f)) {
1012     emit_call(f);
1013     return;
1014   }
1015
1016   f = get_trampoline(f);
1017   emit_call(f);
1018 }
1019
1020 // Add virtual address mapping to linked list
1021 void ll_add(struct ll_entry **head,int vaddr,void *addr)
1022 {
1023   struct ll_entry *new_entry;
1024   new_entry=malloc(sizeof(struct ll_entry));
1025   assert(new_entry!=NULL);
1026   new_entry->vaddr=vaddr;
1027   new_entry->reg_sv_flags=0;
1028   new_entry->addr=addr;
1029   new_entry->next=*head;
1030   *head=new_entry;
1031 }
1032
1033 void ll_add_flags(struct ll_entry **head,int vaddr,u_int reg_sv_flags,void *addr)
1034 {
1035   ll_add(head,vaddr,addr);
1036   (*head)->reg_sv_flags=reg_sv_flags;
1037 }
1038
1039 // Check if an address is already compiled
1040 // but don't return addresses which are about to expire from the cache
1041 void *check_addr(u_int vaddr)
1042 {
1043   struct ht_entry *ht_bin = hash_table_get(vaddr);
1044   size_t i;
1045   for (i = 0; i < ARRAY_SIZE(ht_bin->vaddr); i++) {
1046     if (ht_bin->vaddr[i] == vaddr)
1047       if (doesnt_expire_soon((u_char *)ht_bin->tcaddr[i] - MAX_OUTPUT_BLOCK_SIZE))
1048         if (isclean(ht_bin->tcaddr[i]))
1049           return ht_bin->tcaddr[i];
1050   }
1051   u_int page=get_page(vaddr);
1052   struct ll_entry *head;
1053   head=jump_in[page];
1054   while (head != NULL) {
1055     if (head->vaddr == vaddr) {
1056       if (doesnt_expire_soon(head->addr)) {
1057         // Update existing entry with current address
1058         if (ht_bin->vaddr[0] == vaddr) {
1059           ht_bin->tcaddr[0] = head->addr;
1060           return head->addr;
1061         }
1062         if (ht_bin->vaddr[1] == vaddr) {
1063           ht_bin->tcaddr[1] = head->addr;
1064           return head->addr;
1065         }
1066         // Insert into hash table with low priority.
1067         // Don't evict existing entries, as they are probably
1068         // addresses that are being accessed frequently.
1069         if (ht_bin->vaddr[0] == -1) {
1070           ht_bin->vaddr[0] = vaddr;
1071           ht_bin->tcaddr[0] = head->addr;
1072         }
1073         else if (ht_bin->vaddr[1] == -1) {
1074           ht_bin->vaddr[1] = vaddr;
1075           ht_bin->tcaddr[1] = head->addr;
1076         }
1077         return head->addr;
1078       }
1079     }
1080     head=head->next;
1081   }
1082   return 0;
1083 }
1084
1085 void remove_hash(int vaddr)
1086 {
1087   //printf("remove hash: %x\n",vaddr);
1088   struct ht_entry *ht_bin = hash_table_get(vaddr);
1089   if (ht_bin->vaddr[1] == vaddr) {
1090     ht_bin->vaddr[1] = -1;
1091     ht_bin->tcaddr[1] = NULL;
1092   }
1093   if (ht_bin->vaddr[0] == vaddr) {
1094     ht_bin->vaddr[0] = ht_bin->vaddr[1];
1095     ht_bin->tcaddr[0] = ht_bin->tcaddr[1];
1096     ht_bin->vaddr[1] = -1;
1097     ht_bin->tcaddr[1] = NULL;
1098   }
1099 }
1100
1101 static void ll_remove_matching_addrs(struct ll_entry **head,
1102   uintptr_t base_offs_s, int shift)
1103 {
1104   struct ll_entry *next;
1105   while(*head) {
1106     uintptr_t o1 = (u_char *)(*head)->addr - ndrc->translation_cache;
1107     uintptr_t o2 = o1 - MAX_OUTPUT_BLOCK_SIZE;
1108     if ((o1 >> shift) == base_offs_s || (o2 >> shift) == base_offs_s)
1109     {
1110       inv_debug("EXP: Remove pointer to %p (%x)\n",(*head)->addr,(*head)->vaddr);
1111       remove_hash((*head)->vaddr);
1112       next=(*head)->next;
1113       free(*head);
1114       *head=next;
1115     }
1116     else
1117     {
1118       head=&((*head)->next);
1119     }
1120   }
1121 }
1122
1123 // Remove all entries from linked list
1124 void ll_clear(struct ll_entry **head)
1125 {
1126   struct ll_entry *cur;
1127   struct ll_entry *next;
1128   if((cur=*head)) {
1129     *head=0;
1130     while(cur) {
1131       next=cur->next;
1132       free(cur);
1133       cur=next;
1134     }
1135   }
1136 }
1137
1138 // Dereference the pointers and remove if it matches
1139 static void ll_kill_pointers(struct ll_entry *head,
1140   uintptr_t base_offs_s, int shift)
1141 {
1142   while(head) {
1143     u_char *ptr = get_pointer(head->addr);
1144     uintptr_t o1 = ptr - ndrc->translation_cache;
1145     uintptr_t o2 = o1 - MAX_OUTPUT_BLOCK_SIZE;
1146     inv_debug("EXP: Lookup pointer to %p at %p (%x)\n",ptr,head->addr,head->vaddr);
1147     if ((o1 >> shift) == base_offs_s || (o2 >> shift) == base_offs_s)
1148     {
1149       inv_debug("EXP: Kill pointer at %p (%x)\n",head->addr,head->vaddr);
1150       void *host_addr=find_extjump_insn(head->addr);
1151       mark_clear_cache(host_addr);
1152       set_jump_target(host_addr, head->addr);
1153     }
1154     head=head->next;
1155   }
1156 }
1157
1158 // This is called when we write to a compiled block (see do_invstub)
1159 static void invalidate_page(u_int page)
1160 {
1161   struct ll_entry *head;
1162   struct ll_entry *next;
1163   head=jump_in[page];
1164   jump_in[page]=0;
1165   while(head!=NULL) {
1166     inv_debug("INVALIDATE: %x\n",head->vaddr);
1167     remove_hash(head->vaddr);
1168     next=head->next;
1169     free(head);
1170     head=next;
1171   }
1172   head=jump_out[page];
1173   jump_out[page]=0;
1174   while(head!=NULL) {
1175     inv_debug("INVALIDATE: kill pointer to %x (%p)\n",head->vaddr,head->addr);
1176     void *host_addr=find_extjump_insn(head->addr);
1177     mark_clear_cache(host_addr);
1178     set_jump_target(host_addr, head->addr); // point back to dyna_linker
1179     next=head->next;
1180     free(head);
1181     head=next;
1182   }
1183 }
1184
1185 static void invalidate_block_range(u_int block, u_int first, u_int last)
1186 {
1187   u_int page=get_page(block<<12);
1188   //printf("first=%d last=%d\n",first,last);
1189   invalidate_page(page);
1190   assert(first+5>page); // NB: this assumes MAXBLOCK<=4096 (4 pages)
1191   assert(last<page+5);
1192   // Invalidate the adjacent pages if a block crosses a 4K boundary
1193   while(first<page) {
1194     invalidate_page(first);
1195     first++;
1196   }
1197   for(first=page+1;first<last;first++) {
1198     invalidate_page(first);
1199   }
1200   do_clear_cache();
1201
1202   // Don't trap writes
1203   invalid_code[block]=1;
1204
1205   #ifdef USE_MINI_HT
1206   memset(mini_ht,-1,sizeof(mini_ht));
1207   #endif
1208 }
1209
1210 void invalidate_block(u_int block)
1211 {
1212   u_int page=get_page(block<<12);
1213   u_int vpage=get_vpage(block<<12);
1214   inv_debug("INVALIDATE: %x (%d)\n",block<<12,page);
1215   //inv_debug("invalid_code[block]=%d\n",invalid_code[block]);
1216   u_int first,last;
1217   first=last=page;
1218   struct ll_entry *head;
1219   head=jump_dirty[vpage];
1220   //printf("page=%d vpage=%d\n",page,vpage);
1221   while(head!=NULL) {
1222     if(vpage>2047||(head->vaddr>>12)==block) { // Ignore vaddr hash collision
1223       u_char *start, *end;
1224       get_bounds(head->addr, &start, &end);
1225       //printf("start: %p end: %p\n", start, end);
1226       if (page < 2048 && start >= rdram && end < rdram+RAM_SIZE) {
1227         if (((start-rdram)>>12) <= page && ((end-1-rdram)>>12) >= page) {
1228           if ((((start-rdram)>>12)&2047) < first) first = ((start-rdram)>>12)&2047;
1229           if ((((end-1-rdram)>>12)&2047) > last)  last = ((end-1-rdram)>>12)&2047;
1230         }
1231       }
1232     }
1233     head=head->next;
1234   }
1235   invalidate_block_range(block,first,last);
1236 }
1237
1238 void invalidate_addr(u_int addr)
1239 {
1240   //static int rhits;
1241   // this check is done by the caller
1242   //if (inv_code_start<=addr&&addr<=inv_code_end) { rhits++; return; }
1243   u_int page=get_vpage(addr);
1244   if(page<2048) { // RAM
1245     struct ll_entry *head;
1246     u_int addr_min=~0, addr_max=0;
1247     u_int mask=RAM_SIZE-1;
1248     u_int addr_main=0x80000000|(addr&mask);
1249     int pg1;
1250     inv_code_start=addr_main&~0xfff;
1251     inv_code_end=addr_main|0xfff;
1252     pg1=page;
1253     if (pg1>0) {
1254       // must check previous page too because of spans..
1255       pg1--;
1256       inv_code_start-=0x1000;
1257     }
1258     for(;pg1<=page;pg1++) {
1259       for(head=jump_dirty[pg1];head!=NULL;head=head->next) {
1260         u_char *start_h, *end_h;
1261         u_int start, end;
1262         get_bounds(head->addr, &start_h, &end_h);
1263         start = (uintptr_t)start_h - ram_offset;
1264         end = (uintptr_t)end_h - ram_offset;
1265         if(start<=addr_main&&addr_main<end) {
1266           if(start<addr_min) addr_min=start;
1267           if(end>addr_max) addr_max=end;
1268         }
1269         else if(addr_main<start) {
1270           if(start<inv_code_end)
1271             inv_code_end=start-1;
1272         }
1273         else {
1274           if(end>inv_code_start)
1275             inv_code_start=end;
1276         }
1277       }
1278     }
1279     if (addr_min!=~0) {
1280       inv_debug("INV ADDR: %08x hit %08x-%08x\n", addr, addr_min, addr_max);
1281       inv_code_start=inv_code_end=~0;
1282       invalidate_block_range(addr>>12,(addr_min&mask)>>12,(addr_max&mask)>>12);
1283       return;
1284     }
1285     else {
1286       inv_code_start=(addr&~mask)|(inv_code_start&mask);
1287       inv_code_end=(addr&~mask)|(inv_code_end&mask);
1288       inv_debug("INV ADDR: %08x miss, inv %08x-%08x, sk %d\n", addr, inv_code_start, inv_code_end, 0);
1289       return;
1290     }
1291   }
1292   invalidate_block(addr>>12);
1293 }
1294
1295 // This is called when loading a save state.
1296 // Anything could have changed, so invalidate everything.
1297 void invalidate_all_pages(void)
1298 {
1299   u_int page;
1300   for(page=0;page<4096;page++)
1301     invalidate_page(page);
1302   for(page=0;page<1048576;page++)
1303     if(!invalid_code[page]) {
1304       restore_candidate[(page&2047)>>3]|=1<<(page&7);
1305       restore_candidate[((page&2047)>>3)+256]|=1<<(page&7);
1306     }
1307   #ifdef USE_MINI_HT
1308   memset(mini_ht,-1,sizeof(mini_ht));
1309   #endif
1310   do_clear_cache();
1311 }
1312
1313 static void do_invstub(int n)
1314 {
1315   literal_pool(20);
1316   u_int reglist=stubs[n].a;
1317   set_jump_target(stubs[n].addr, out);
1318   save_regs(reglist);
1319   if(stubs[n].b!=0) emit_mov(stubs[n].b,0);
1320   emit_far_call(invalidate_addr);
1321   restore_regs(reglist);
1322   emit_jmp(stubs[n].retaddr); // return address
1323 }
1324
1325 // Add an entry to jump_out after making a link
1326 // src should point to code by emit_extjump2()
1327 void add_jump_out(u_int vaddr,void *src)
1328 {
1329   u_int page=get_page(vaddr);
1330   inv_debug("add_jump_out: %p -> %x (%d)\n",src,vaddr,page);
1331   check_extjump2(src);
1332   ll_add(jump_out+page,vaddr,src);
1333   //inv_debug("add_jump_out:  to %p\n",get_pointer(src));
1334 }
1335
1336 // If a code block was found to be unmodified (bit was set in
1337 // restore_candidate) and it remains unmodified (bit is clear
1338 // in invalid_code) then move the entries for that 4K page from
1339 // the dirty list to the clean list.
1340 void clean_blocks(u_int page)
1341 {
1342   struct ll_entry *head;
1343   inv_debug("INV: clean_blocks page=%d\n",page);
1344   head=jump_dirty[page];
1345   while(head!=NULL) {
1346     if(!invalid_code[head->vaddr>>12]) {
1347       // Don't restore blocks which are about to expire from the cache
1348       if (doesnt_expire_soon(head->addr)) {
1349         if(verify_dirty(head->addr)) {
1350           u_char *start, *end;
1351           //printf("Possibly Restore %x (%p)\n",head->vaddr, head->addr);
1352           u_int i;
1353           u_int inv=0;
1354           get_bounds(head->addr, &start, &end);
1355           if (start - rdram < RAM_SIZE) {
1356             for (i = (start-rdram+0x80000000)>>12; i <= (end-1-rdram+0x80000000)>>12; i++) {
1357               inv|=invalid_code[i];
1358             }
1359           }
1360           else if((signed int)head->vaddr>=(signed int)0x80000000+RAM_SIZE) {
1361             inv=1;
1362           }
1363           if(!inv) {
1364             void *clean_addr = get_clean_addr(head->addr);
1365             if (doesnt_expire_soon(clean_addr)) {
1366               u_int ppage=page;
1367               inv_debug("INV: Restored %x (%p/%p)\n",head->vaddr, head->addr, clean_addr);
1368               //printf("page=%x, addr=%x\n",page,head->vaddr);
1369               //assert(head->vaddr>>12==(page|0x80000));
1370               ll_add_flags(jump_in+ppage,head->vaddr,head->reg_sv_flags,clean_addr);
1371               struct ht_entry *ht_bin = hash_table_get(head->vaddr);
1372               if (ht_bin->vaddr[0] == head->vaddr)
1373                 ht_bin->tcaddr[0] = clean_addr; // Replace existing entry
1374               if (ht_bin->vaddr[1] == head->vaddr)
1375                 ht_bin->tcaddr[1] = clean_addr; // Replace existing entry
1376             }
1377           }
1378         }
1379       }
1380     }
1381     head=head->next;
1382   }
1383 }
1384
1385 /* Register allocation */
1386
1387 // Note: registers are allocated clean (unmodified state)
1388 // if you intend to modify the register, you must call dirty_reg().
1389 static void alloc_reg(struct regstat *cur,int i,signed char reg)
1390 {
1391   int r,hr;
1392   int preferred_reg = PREFERRED_REG_FIRST
1393     + reg % (PREFERRED_REG_LAST - PREFERRED_REG_FIRST + 1);
1394   if (reg == CCREG) preferred_reg = HOST_CCREG;
1395   if (reg == PTEMP || reg == FTEMP) preferred_reg = 12;
1396   assert(PREFERRED_REG_FIRST != EXCLUDE_REG && EXCLUDE_REG != HOST_REGS);
1397
1398   // Don't allocate unused registers
1399   if((cur->u>>reg)&1) return;
1400
1401   // see if it's already allocated
1402   for(hr=0;hr<HOST_REGS;hr++)
1403   {
1404     if(cur->regmap[hr]==reg) return;
1405   }
1406
1407   // Keep the same mapping if the register was already allocated in a loop
1408   preferred_reg = loop_reg(i,reg,preferred_reg);
1409
1410   // Try to allocate the preferred register
1411   if(cur->regmap[preferred_reg]==-1) {
1412     cur->regmap[preferred_reg]=reg;
1413     cur->dirty&=~(1<<preferred_reg);
1414     cur->isconst&=~(1<<preferred_reg);
1415     return;
1416   }
1417   r=cur->regmap[preferred_reg];
1418   assert(r < 64);
1419   if((cur->u>>r)&1) {
1420     cur->regmap[preferred_reg]=reg;
1421     cur->dirty&=~(1<<preferred_reg);
1422     cur->isconst&=~(1<<preferred_reg);
1423     return;
1424   }
1425
1426   // Clear any unneeded registers
1427   // We try to keep the mapping consistent, if possible, because it
1428   // makes branches easier (especially loops).  So we try to allocate
1429   // first (see above) before removing old mappings.  If this is not
1430   // possible then go ahead and clear out the registers that are no
1431   // longer needed.
1432   for(hr=0;hr<HOST_REGS;hr++)
1433   {
1434     r=cur->regmap[hr];
1435     if(r>=0) {
1436       assert(r < 64);
1437       if((cur->u>>r)&1) {cur->regmap[hr]=-1;break;}
1438     }
1439   }
1440
1441   // Try to allocate any available register, but prefer
1442   // registers that have not been used recently.
1443   if (i > 0) {
1444     for (hr = PREFERRED_REG_FIRST; ; ) {
1445       if (cur->regmap[hr] < 0) {
1446         int oldreg = regs[i-1].regmap[hr];
1447         if (oldreg < 0 || (oldreg != dops[i-1].rs1 && oldreg != dops[i-1].rs2
1448              && oldreg != dops[i-1].rt1 && oldreg != dops[i-1].rt2))
1449         {
1450           cur->regmap[hr]=reg;
1451           cur->dirty&=~(1<<hr);
1452           cur->isconst&=~(1<<hr);
1453           return;
1454         }
1455       }
1456       hr++;
1457       if (hr == EXCLUDE_REG)
1458         hr++;
1459       if (hr == HOST_REGS)
1460         hr = 0;
1461       if (hr == PREFERRED_REG_FIRST)
1462         break;
1463     }
1464   }
1465
1466   // Try to allocate any available register
1467   for (hr = PREFERRED_REG_FIRST; ; ) {
1468     if (cur->regmap[hr] < 0) {
1469       cur->regmap[hr]=reg;
1470       cur->dirty&=~(1<<hr);
1471       cur->isconst&=~(1<<hr);
1472       return;
1473     }
1474     hr++;
1475     if (hr == EXCLUDE_REG)
1476       hr++;
1477     if (hr == HOST_REGS)
1478       hr = 0;
1479     if (hr == PREFERRED_REG_FIRST)
1480       break;
1481   }
1482
1483   // Ok, now we have to evict someone
1484   // Pick a register we hopefully won't need soon
1485   u_char hsn[MAXREG+1];
1486   memset(hsn,10,sizeof(hsn));
1487   int j;
1488   lsn(hsn,i,&preferred_reg);
1489   //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]);
1490   //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]);
1491   if(i>0) {
1492     // Don't evict the cycle count at entry points, otherwise the entry
1493     // stub will have to write it.
1494     if(dops[i].bt&&hsn[CCREG]>2) hsn[CCREG]=2;
1495     if (i>1 && hsn[CCREG] > 2 && dops[i-2].is_jump) hsn[CCREG]=2;
1496     for(j=10;j>=3;j--)
1497     {
1498       // Alloc preferred register if available
1499       if(hsn[r=cur->regmap[preferred_reg]&63]==j) {
1500         for(hr=0;hr<HOST_REGS;hr++) {
1501           // Evict both parts of a 64-bit register
1502           if((cur->regmap[hr]&63)==r) {
1503             cur->regmap[hr]=-1;
1504             cur->dirty&=~(1<<hr);
1505             cur->isconst&=~(1<<hr);
1506           }
1507         }
1508         cur->regmap[preferred_reg]=reg;
1509         return;
1510       }
1511       for(r=1;r<=MAXREG;r++)
1512       {
1513         if(hsn[r]==j&&r!=dops[i-1].rs1&&r!=dops[i-1].rs2&&r!=dops[i-1].rt1&&r!=dops[i-1].rt2) {
1514           for(hr=0;hr<HOST_REGS;hr++) {
1515             if(hr!=HOST_CCREG||j<hsn[CCREG]) {
1516               if(cur->regmap[hr]==r) {
1517                 cur->regmap[hr]=reg;
1518                 cur->dirty&=~(1<<hr);
1519                 cur->isconst&=~(1<<hr);
1520                 return;
1521               }
1522             }
1523           }
1524         }
1525       }
1526     }
1527   }
1528   for(j=10;j>=0;j--)
1529   {
1530     for(r=1;r<=MAXREG;r++)
1531     {
1532       if(hsn[r]==j) {
1533         for(hr=0;hr<HOST_REGS;hr++) {
1534           if(cur->regmap[hr]==r) {
1535             cur->regmap[hr]=reg;
1536             cur->dirty&=~(1<<hr);
1537             cur->isconst&=~(1<<hr);
1538             return;
1539           }
1540         }
1541       }
1542     }
1543   }
1544   SysPrintf("This shouldn't happen (alloc_reg)");abort();
1545 }
1546
1547 // Allocate a temporary register.  This is done without regard to
1548 // dirty status or whether the register we request is on the unneeded list
1549 // Note: This will only allocate one register, even if called multiple times
1550 static void alloc_reg_temp(struct regstat *cur,int i,signed char reg)
1551 {
1552   int r,hr;
1553   int preferred_reg = -1;
1554
1555   // see if it's already allocated
1556   for(hr=0;hr<HOST_REGS;hr++)
1557   {
1558     if(hr!=EXCLUDE_REG&&cur->regmap[hr]==reg) return;
1559   }
1560
1561   // Try to allocate any available register
1562   for(hr=HOST_REGS-1;hr>=0;hr--) {
1563     if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) {
1564       cur->regmap[hr]=reg;
1565       cur->dirty&=~(1<<hr);
1566       cur->isconst&=~(1<<hr);
1567       return;
1568     }
1569   }
1570
1571   // Find an unneeded register
1572   for(hr=HOST_REGS-1;hr>=0;hr--)
1573   {
1574     r=cur->regmap[hr];
1575     if(r>=0) {
1576       assert(r < 64);
1577       if((cur->u>>r)&1) {
1578         if(i==0||((unneeded_reg[i-1]>>r)&1)) {
1579           cur->regmap[hr]=reg;
1580           cur->dirty&=~(1<<hr);
1581           cur->isconst&=~(1<<hr);
1582           return;
1583         }
1584       }
1585     }
1586   }
1587
1588   // Ok, now we have to evict someone
1589   // Pick a register we hopefully won't need soon
1590   // TODO: we might want to follow unconditional jumps here
1591   // TODO: get rid of dupe code and make this into a function
1592   u_char hsn[MAXREG+1];
1593   memset(hsn,10,sizeof(hsn));
1594   int j;
1595   lsn(hsn,i,&preferred_reg);
1596   //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]);
1597   if(i>0) {
1598     // Don't evict the cycle count at entry points, otherwise the entry
1599     // stub will have to write it.
1600     if(dops[i].bt&&hsn[CCREG]>2) hsn[CCREG]=2;
1601     if (i>1 && hsn[CCREG] > 2 && dops[i-2].is_jump) hsn[CCREG]=2;
1602     for(j=10;j>=3;j--)
1603     {
1604       for(r=1;r<=MAXREG;r++)
1605       {
1606         if(hsn[r]==j&&r!=dops[i-1].rs1&&r!=dops[i-1].rs2&&r!=dops[i-1].rt1&&r!=dops[i-1].rt2) {
1607           for(hr=0;hr<HOST_REGS;hr++) {
1608             if(hr!=HOST_CCREG||hsn[CCREG]>2) {
1609               if(cur->regmap[hr]==r) {
1610                 cur->regmap[hr]=reg;
1611                 cur->dirty&=~(1<<hr);
1612                 cur->isconst&=~(1<<hr);
1613                 return;
1614               }
1615             }
1616           }
1617         }
1618       }
1619     }
1620   }
1621   for(j=10;j>=0;j--)
1622   {
1623     for(r=1;r<=MAXREG;r++)
1624     {
1625       if(hsn[r]==j) {
1626         for(hr=0;hr<HOST_REGS;hr++) {
1627           if(cur->regmap[hr]==r) {
1628             cur->regmap[hr]=reg;
1629             cur->dirty&=~(1<<hr);
1630             cur->isconst&=~(1<<hr);
1631             return;
1632           }
1633         }
1634       }
1635     }
1636   }
1637   SysPrintf("This shouldn't happen");abort();
1638 }
1639
1640 static void mov_alloc(struct regstat *current,int i)
1641 {
1642   if (dops[i].rs1 == HIREG || dops[i].rs1 == LOREG) {
1643     alloc_cc(current,i); // for stalls
1644     dirty_reg(current,CCREG);
1645   }
1646
1647   // Note: Don't need to actually alloc the source registers
1648   //alloc_reg(current,i,dops[i].rs1);
1649   alloc_reg(current,i,dops[i].rt1);
1650
1651   clear_const(current,dops[i].rs1);
1652   clear_const(current,dops[i].rt1);
1653   dirty_reg(current,dops[i].rt1);
1654 }
1655
1656 static void shiftimm_alloc(struct regstat *current,int i)
1657 {
1658   if(dops[i].opcode2<=0x3) // SLL/SRL/SRA
1659   {
1660     if(dops[i].rt1) {
1661       if(dops[i].rs1&&needed_again(dops[i].rs1,i)) alloc_reg(current,i,dops[i].rs1);
1662       else dops[i].lt1=dops[i].rs1;
1663       alloc_reg(current,i,dops[i].rt1);
1664       dirty_reg(current,dops[i].rt1);
1665       if(is_const(current,dops[i].rs1)) {
1666         int v=get_const(current,dops[i].rs1);
1667         if(dops[i].opcode2==0x00) set_const(current,dops[i].rt1,v<<imm[i]);
1668         if(dops[i].opcode2==0x02) set_const(current,dops[i].rt1,(u_int)v>>imm[i]);
1669         if(dops[i].opcode2==0x03) set_const(current,dops[i].rt1,v>>imm[i]);
1670       }
1671       else clear_const(current,dops[i].rt1);
1672     }
1673   }
1674   else
1675   {
1676     clear_const(current,dops[i].rs1);
1677     clear_const(current,dops[i].rt1);
1678   }
1679
1680   if(dops[i].opcode2>=0x38&&dops[i].opcode2<=0x3b) // DSLL/DSRL/DSRA
1681   {
1682     assert(0);
1683   }
1684   if(dops[i].opcode2==0x3c) // DSLL32
1685   {
1686     assert(0);
1687   }
1688   if(dops[i].opcode2==0x3e) // DSRL32
1689   {
1690     assert(0);
1691   }
1692   if(dops[i].opcode2==0x3f) // DSRA32
1693   {
1694     assert(0);
1695   }
1696 }
1697
1698 static void shift_alloc(struct regstat *current,int i)
1699 {
1700   if(dops[i].rt1) {
1701     if(dops[i].opcode2<=0x07) // SLLV/SRLV/SRAV
1702     {
1703       if(dops[i].rs1) alloc_reg(current,i,dops[i].rs1);
1704       if(dops[i].rs2) alloc_reg(current,i,dops[i].rs2);
1705       alloc_reg(current,i,dops[i].rt1);
1706       if(dops[i].rt1==dops[i].rs2) {
1707         alloc_reg_temp(current,i,-1);
1708         minimum_free_regs[i]=1;
1709       }
1710     } else { // DSLLV/DSRLV/DSRAV
1711       assert(0);
1712     }
1713     clear_const(current,dops[i].rs1);
1714     clear_const(current,dops[i].rs2);
1715     clear_const(current,dops[i].rt1);
1716     dirty_reg(current,dops[i].rt1);
1717   }
1718 }
1719
1720 static void alu_alloc(struct regstat *current,int i)
1721 {
1722   if(dops[i].opcode2>=0x20&&dops[i].opcode2<=0x23) { // ADD/ADDU/SUB/SUBU
1723     if(dops[i].rt1) {
1724       if(dops[i].rs1&&dops[i].rs2) {
1725         alloc_reg(current,i,dops[i].rs1);
1726         alloc_reg(current,i,dops[i].rs2);
1727       }
1728       else {
1729         if(dops[i].rs1&&needed_again(dops[i].rs1,i)) alloc_reg(current,i,dops[i].rs1);
1730         if(dops[i].rs2&&needed_again(dops[i].rs2,i)) alloc_reg(current,i,dops[i].rs2);
1731       }
1732       alloc_reg(current,i,dops[i].rt1);
1733     }
1734   }
1735   if(dops[i].opcode2==0x2a||dops[i].opcode2==0x2b) { // SLT/SLTU
1736     if(dops[i].rt1) {
1737       alloc_reg(current,i,dops[i].rs1);
1738       alloc_reg(current,i,dops[i].rs2);
1739       alloc_reg(current,i,dops[i].rt1);
1740     }
1741   }
1742   if(dops[i].opcode2>=0x24&&dops[i].opcode2<=0x27) { // AND/OR/XOR/NOR
1743     if(dops[i].rt1) {
1744       if(dops[i].rs1&&dops[i].rs2) {
1745         alloc_reg(current,i,dops[i].rs1);
1746         alloc_reg(current,i,dops[i].rs2);
1747       }
1748       else
1749       {
1750         if(dops[i].rs1&&needed_again(dops[i].rs1,i)) alloc_reg(current,i,dops[i].rs1);
1751         if(dops[i].rs2&&needed_again(dops[i].rs2,i)) alloc_reg(current,i,dops[i].rs2);
1752       }
1753       alloc_reg(current,i,dops[i].rt1);
1754     }
1755   }
1756   if(dops[i].opcode2>=0x2c&&dops[i].opcode2<=0x2f) { // DADD/DADDU/DSUB/DSUBU
1757     assert(0);
1758   }
1759   clear_const(current,dops[i].rs1);
1760   clear_const(current,dops[i].rs2);
1761   clear_const(current,dops[i].rt1);
1762   dirty_reg(current,dops[i].rt1);
1763 }
1764
1765 static void imm16_alloc(struct regstat *current,int i)
1766 {
1767   if(dops[i].rs1&&needed_again(dops[i].rs1,i)) alloc_reg(current,i,dops[i].rs1);
1768   else dops[i].lt1=dops[i].rs1;
1769   if(dops[i].rt1) alloc_reg(current,i,dops[i].rt1);
1770   if(dops[i].opcode==0x18||dops[i].opcode==0x19) { // DADDI/DADDIU
1771     assert(0);
1772   }
1773   else if(dops[i].opcode==0x0a||dops[i].opcode==0x0b) { // SLTI/SLTIU
1774     clear_const(current,dops[i].rs1);
1775     clear_const(current,dops[i].rt1);
1776   }
1777   else if(dops[i].opcode>=0x0c&&dops[i].opcode<=0x0e) { // ANDI/ORI/XORI
1778     if(is_const(current,dops[i].rs1)) {
1779       int v=get_const(current,dops[i].rs1);
1780       if(dops[i].opcode==0x0c) set_const(current,dops[i].rt1,v&imm[i]);
1781       if(dops[i].opcode==0x0d) set_const(current,dops[i].rt1,v|imm[i]);
1782       if(dops[i].opcode==0x0e) set_const(current,dops[i].rt1,v^imm[i]);
1783     }
1784     else clear_const(current,dops[i].rt1);
1785   }
1786   else if(dops[i].opcode==0x08||dops[i].opcode==0x09) { // ADDI/ADDIU
1787     if(is_const(current,dops[i].rs1)) {
1788       int v=get_const(current,dops[i].rs1);
1789       set_const(current,dops[i].rt1,v+imm[i]);
1790     }
1791     else clear_const(current,dops[i].rt1);
1792   }
1793   else {
1794     set_const(current,dops[i].rt1,imm[i]<<16); // LUI
1795   }
1796   dirty_reg(current,dops[i].rt1);
1797 }
1798
1799 static void load_alloc(struct regstat *current,int i)
1800 {
1801   clear_const(current,dops[i].rt1);
1802   //if(dops[i].rs1!=dops[i].rt1&&needed_again(dops[i].rs1,i)) clear_const(current,dops[i].rs1); // Does this help or hurt?
1803   if(!dops[i].rs1) current->u&=~1LL; // Allow allocating r0 if it's the source register
1804   if (needed_again(dops[i].rs1, i))
1805     alloc_reg(current, i, dops[i].rs1);
1806   if (ram_offset)
1807     alloc_reg(current, i, ROREG);
1808   if(dops[i].rt1&&!((current->u>>dops[i].rt1)&1)) {
1809     alloc_reg(current,i,dops[i].rt1);
1810     assert(get_reg(current->regmap,dops[i].rt1)>=0);
1811     if(dops[i].opcode==0x27||dops[i].opcode==0x37) // LWU/LD
1812     {
1813       assert(0);
1814     }
1815     else if(dops[i].opcode==0x1A||dops[i].opcode==0x1B) // LDL/LDR
1816     {
1817       assert(0);
1818     }
1819     dirty_reg(current,dops[i].rt1);
1820     // LWL/LWR need a temporary register for the old value
1821     if(dops[i].opcode==0x22||dops[i].opcode==0x26)
1822     {
1823       alloc_reg(current,i,FTEMP);
1824       alloc_reg_temp(current,i,-1);
1825       minimum_free_regs[i]=1;
1826     }
1827   }
1828   else
1829   {
1830     // Load to r0 or unneeded register (dummy load)
1831     // but we still need a register to calculate the address
1832     if(dops[i].opcode==0x22||dops[i].opcode==0x26)
1833     {
1834       alloc_reg(current,i,FTEMP); // LWL/LWR need another temporary
1835     }
1836     alloc_reg_temp(current,i,-1);
1837     minimum_free_regs[i]=1;
1838     if(dops[i].opcode==0x1A||dops[i].opcode==0x1B) // LDL/LDR
1839     {
1840       assert(0);
1841     }
1842   }
1843 }
1844
1845 void store_alloc(struct regstat *current,int i)
1846 {
1847   clear_const(current,dops[i].rs2);
1848   if(!(dops[i].rs2)) current->u&=~1LL; // Allow allocating r0 if necessary
1849   if(needed_again(dops[i].rs1,i)) alloc_reg(current,i,dops[i].rs1);
1850   alloc_reg(current,i,dops[i].rs2);
1851   if(dops[i].opcode==0x2c||dops[i].opcode==0x2d||dops[i].opcode==0x3f) { // 64-bit SDL/SDR/SD
1852     assert(0);
1853   }
1854   if (ram_offset)
1855     alloc_reg(current, i, ROREG);
1856   #if defined(HOST_IMM8)
1857   // On CPUs without 32-bit immediates we need a pointer to invalid_code
1858   alloc_reg(current, i, INVCP);
1859   #endif
1860   if(dops[i].opcode==0x2a||dops[i].opcode==0x2e||dops[i].opcode==0x2c||dops[i].opcode==0x2d) { // SWL/SWL/SDL/SDR
1861     alloc_reg(current,i,FTEMP);
1862   }
1863   // We need a temporary register for address generation
1864   alloc_reg_temp(current,i,-1);
1865   minimum_free_regs[i]=1;
1866 }
1867
1868 void c1ls_alloc(struct regstat *current,int i)
1869 {
1870   clear_const(current,dops[i].rt1);
1871   alloc_reg(current,i,CSREG); // Status
1872 }
1873
1874 void c2ls_alloc(struct regstat *current,int i)
1875 {
1876   clear_const(current,dops[i].rt1);
1877   if(needed_again(dops[i].rs1,i)) alloc_reg(current,i,dops[i].rs1);
1878   alloc_reg(current,i,FTEMP);
1879   if (ram_offset)
1880     alloc_reg(current, i, ROREG);
1881   #if defined(HOST_IMM8)
1882   // On CPUs without 32-bit immediates we need a pointer to invalid_code
1883   if (dops[i].opcode == 0x3a) // SWC2
1884     alloc_reg(current,i,INVCP);
1885   #endif
1886   // We need a temporary register for address generation
1887   alloc_reg_temp(current,i,-1);
1888   minimum_free_regs[i]=1;
1889 }
1890
1891 #ifndef multdiv_alloc
1892 void multdiv_alloc(struct regstat *current,int i)
1893 {
1894   //  case 0x18: MULT
1895   //  case 0x19: MULTU
1896   //  case 0x1A: DIV
1897   //  case 0x1B: DIVU
1898   //  case 0x1C: DMULT
1899   //  case 0x1D: DMULTU
1900   //  case 0x1E: DDIV
1901   //  case 0x1F: DDIVU
1902   clear_const(current,dops[i].rs1);
1903   clear_const(current,dops[i].rs2);
1904   alloc_cc(current,i); // for stalls
1905   if(dops[i].rs1&&dops[i].rs2)
1906   {
1907     if((dops[i].opcode2&4)==0) // 32-bit
1908     {
1909       current->u&=~(1LL<<HIREG);
1910       current->u&=~(1LL<<LOREG);
1911       alloc_reg(current,i,HIREG);
1912       alloc_reg(current,i,LOREG);
1913       alloc_reg(current,i,dops[i].rs1);
1914       alloc_reg(current,i,dops[i].rs2);
1915       dirty_reg(current,HIREG);
1916       dirty_reg(current,LOREG);
1917     }
1918     else // 64-bit
1919     {
1920       assert(0);
1921     }
1922   }
1923   else
1924   {
1925     // Multiply by zero is zero.
1926     // MIPS does not have a divide by zero exception.
1927     // The result is undefined, we return zero.
1928     alloc_reg(current,i,HIREG);
1929     alloc_reg(current,i,LOREG);
1930     dirty_reg(current,HIREG);
1931     dirty_reg(current,LOREG);
1932   }
1933 }
1934 #endif
1935
1936 void cop0_alloc(struct regstat *current,int i)
1937 {
1938   if(dops[i].opcode2==0) // MFC0
1939   {
1940     if(dops[i].rt1) {
1941       clear_const(current,dops[i].rt1);
1942       alloc_all(current,i);
1943       alloc_reg(current,i,dops[i].rt1);
1944       dirty_reg(current,dops[i].rt1);
1945     }
1946   }
1947   else if(dops[i].opcode2==4) // MTC0
1948   {
1949     if(dops[i].rs1){
1950       clear_const(current,dops[i].rs1);
1951       alloc_reg(current,i,dops[i].rs1);
1952       alloc_all(current,i);
1953     }
1954     else {
1955       alloc_all(current,i); // FIXME: Keep r0
1956       current->u&=~1LL;
1957       alloc_reg(current,i,0);
1958     }
1959   }
1960   else
1961   {
1962     // TLBR/TLBWI/TLBWR/TLBP/ERET
1963     assert(dops[i].opcode2==0x10);
1964     alloc_all(current,i);
1965   }
1966   minimum_free_regs[i]=HOST_REGS;
1967 }
1968
1969 static void cop2_alloc(struct regstat *current,int i)
1970 {
1971   if (dops[i].opcode2 < 3) // MFC2/CFC2
1972   {
1973     alloc_cc(current,i); // for stalls
1974     dirty_reg(current,CCREG);
1975     if(dops[i].rt1){
1976       clear_const(current,dops[i].rt1);
1977       alloc_reg(current,i,dops[i].rt1);
1978       dirty_reg(current,dops[i].rt1);
1979     }
1980   }
1981   else if (dops[i].opcode2 > 3) // MTC2/CTC2
1982   {
1983     if(dops[i].rs1){
1984       clear_const(current,dops[i].rs1);
1985       alloc_reg(current,i,dops[i].rs1);
1986     }
1987     else {
1988       current->u&=~1LL;
1989       alloc_reg(current,i,0);
1990     }
1991   }
1992   alloc_reg_temp(current,i,-1);
1993   minimum_free_regs[i]=1;
1994 }
1995
1996 void c2op_alloc(struct regstat *current,int i)
1997 {
1998   alloc_cc(current,i); // for stalls
1999   dirty_reg(current,CCREG);
2000   alloc_reg_temp(current,i,-1);
2001 }
2002
2003 void syscall_alloc(struct regstat *current,int i)
2004 {
2005   alloc_cc(current,i);
2006   dirty_reg(current,CCREG);
2007   alloc_all(current,i);
2008   minimum_free_regs[i]=HOST_REGS;
2009   current->isconst=0;
2010 }
2011
2012 void delayslot_alloc(struct regstat *current,int i)
2013 {
2014   switch(dops[i].itype) {
2015     case UJUMP:
2016     case CJUMP:
2017     case SJUMP:
2018     case RJUMP:
2019     case SYSCALL:
2020     case HLECALL:
2021     case SPAN:
2022       assem_debug("jump in the delay slot.  this shouldn't happen.\n");//abort();
2023       SysPrintf("Disabled speculative precompilation\n");
2024       stop_after_jal=1;
2025       break;
2026     case IMM16:
2027       imm16_alloc(current,i);
2028       break;
2029     case LOAD:
2030     case LOADLR:
2031       load_alloc(current,i);
2032       break;
2033     case STORE:
2034     case STORELR:
2035       store_alloc(current,i);
2036       break;
2037     case ALU:
2038       alu_alloc(current,i);
2039       break;
2040     case SHIFT:
2041       shift_alloc(current,i);
2042       break;
2043     case MULTDIV:
2044       multdiv_alloc(current,i);
2045       break;
2046     case SHIFTIMM:
2047       shiftimm_alloc(current,i);
2048       break;
2049     case MOV:
2050       mov_alloc(current,i);
2051       break;
2052     case COP0:
2053       cop0_alloc(current,i);
2054       break;
2055     case COP1:
2056       break;
2057     case COP2:
2058       cop2_alloc(current,i);
2059       break;
2060     case C1LS:
2061       c1ls_alloc(current,i);
2062       break;
2063     case C2LS:
2064       c2ls_alloc(current,i);
2065       break;
2066     case C2OP:
2067       c2op_alloc(current,i);
2068       break;
2069   }
2070 }
2071
2072 // Special case where a branch and delay slot span two pages in virtual memory
2073 static void pagespan_alloc(struct regstat *current,int i)
2074 {
2075   current->isconst=0;
2076   current->wasconst=0;
2077   regs[i].wasconst=0;
2078   minimum_free_regs[i]=HOST_REGS;
2079   alloc_all(current,i);
2080   alloc_cc(current,i);
2081   dirty_reg(current,CCREG);
2082   if(dops[i].opcode==3) // JAL
2083   {
2084     alloc_reg(current,i,31);
2085     dirty_reg(current,31);
2086   }
2087   if(dops[i].opcode==0&&(dops[i].opcode2&0x3E)==8) // JR/JALR
2088   {
2089     alloc_reg(current,i,dops[i].rs1);
2090     if (dops[i].rt1!=0) {
2091       alloc_reg(current,i,dops[i].rt1);
2092       dirty_reg(current,dops[i].rt1);
2093     }
2094   }
2095   if((dops[i].opcode&0x2E)==4) // BEQ/BNE/BEQL/BNEL
2096   {
2097     if(dops[i].rs1) alloc_reg(current,i,dops[i].rs1);
2098     if(dops[i].rs2) alloc_reg(current,i,dops[i].rs2);
2099   }
2100   else
2101   if((dops[i].opcode&0x2E)==6) // BLEZ/BGTZ/BLEZL/BGTZL
2102   {
2103     if(dops[i].rs1) alloc_reg(current,i,dops[i].rs1);
2104   }
2105   //else ...
2106 }
2107
2108 static void add_stub(enum stub_type type, void *addr, void *retaddr,
2109   u_int a, uintptr_t b, uintptr_t c, u_int d, u_int e)
2110 {
2111   assert(stubcount < ARRAY_SIZE(stubs));
2112   stubs[stubcount].type = type;
2113   stubs[stubcount].addr = addr;
2114   stubs[stubcount].retaddr = retaddr;
2115   stubs[stubcount].a = a;
2116   stubs[stubcount].b = b;
2117   stubs[stubcount].c = c;
2118   stubs[stubcount].d = d;
2119   stubs[stubcount].e = e;
2120   stubcount++;
2121 }
2122
2123 static void add_stub_r(enum stub_type type, void *addr, void *retaddr,
2124   int i, int addr_reg, const struct regstat *i_regs, int ccadj, u_int reglist)
2125 {
2126   add_stub(type, addr, retaddr, i, addr_reg, (uintptr_t)i_regs, ccadj, reglist);
2127 }
2128
2129 // Write out a single register
2130 static void wb_register(signed char r, const signed char regmap[], uint64_t dirty)
2131 {
2132   int hr;
2133   for(hr=0;hr<HOST_REGS;hr++) {
2134     if(hr!=EXCLUDE_REG) {
2135       if((regmap[hr]&63)==r) {
2136         if((dirty>>hr)&1) {
2137           assert(regmap[hr]<64);
2138           emit_storereg(r,hr);
2139         }
2140       }
2141     }
2142   }
2143 }
2144
2145 static void wb_valid(signed char pre[],signed char entry[],u_int dirty_pre,u_int dirty,uint64_t u)
2146 {
2147   //if(dirty_pre==dirty) return;
2148   int hr,reg;
2149   for(hr=0;hr<HOST_REGS;hr++) {
2150     if(hr!=EXCLUDE_REG) {
2151       reg=pre[hr];
2152       if(((~u)>>(reg&63))&1) {
2153         if(reg>0) {
2154           if(((dirty_pre&~dirty)>>hr)&1) {
2155             if(reg>0&&reg<34) {
2156               emit_storereg(reg,hr);
2157             }
2158             else if(reg>=64) {
2159               assert(0);
2160             }
2161           }
2162         }
2163       }
2164     }
2165   }
2166 }
2167
2168 // trashes r2
2169 static void pass_args(int a0, int a1)
2170 {
2171   if(a0==1&&a1==0) {
2172     // must swap
2173     emit_mov(a0,2); emit_mov(a1,1); emit_mov(2,0);
2174   }
2175   else if(a0!=0&&a1==0) {
2176     emit_mov(a1,1);
2177     if (a0>=0) emit_mov(a0,0);
2178   }
2179   else {
2180     if(a0>=0&&a0!=0) emit_mov(a0,0);
2181     if(a1>=0&&a1!=1) emit_mov(a1,1);
2182   }
2183 }
2184
2185 static void alu_assemble(int i, const struct regstat *i_regs)
2186 {
2187   if(dops[i].opcode2>=0x20&&dops[i].opcode2<=0x23) { // ADD/ADDU/SUB/SUBU
2188     if(dops[i].rt1) {
2189       signed char s1,s2,t;
2190       t=get_reg(i_regs->regmap,dops[i].rt1);
2191       if(t>=0) {
2192         s1=get_reg(i_regs->regmap,dops[i].rs1);
2193         s2=get_reg(i_regs->regmap,dops[i].rs2);
2194         if(dops[i].rs1&&dops[i].rs2) {
2195           assert(s1>=0);
2196           assert(s2>=0);
2197           if(dops[i].opcode2&2) emit_sub(s1,s2,t);
2198           else emit_add(s1,s2,t);
2199         }
2200         else if(dops[i].rs1) {
2201           if(s1>=0) emit_mov(s1,t);
2202           else emit_loadreg(dops[i].rs1,t);
2203         }
2204         else if(dops[i].rs2) {
2205           if(s2>=0) {
2206             if(dops[i].opcode2&2) emit_neg(s2,t);
2207             else emit_mov(s2,t);
2208           }
2209           else {
2210             emit_loadreg(dops[i].rs2,t);
2211             if(dops[i].opcode2&2) emit_neg(t,t);
2212           }
2213         }
2214         else emit_zeroreg(t);
2215       }
2216     }
2217   }
2218   if(dops[i].opcode2>=0x2c&&dops[i].opcode2<=0x2f) { // DADD/DADDU/DSUB/DSUBU
2219     assert(0);
2220   }
2221   if(dops[i].opcode2==0x2a||dops[i].opcode2==0x2b) { // SLT/SLTU
2222     if(dops[i].rt1) {
2223       signed char s1l,s2l,t;
2224       {
2225         t=get_reg(i_regs->regmap,dops[i].rt1);
2226         //assert(t>=0);
2227         if(t>=0) {
2228           s1l=get_reg(i_regs->regmap,dops[i].rs1);
2229           s2l=get_reg(i_regs->regmap,dops[i].rs2);
2230           if(dops[i].rs2==0) // rx<r0
2231           {
2232             if(dops[i].opcode2==0x2a&&dops[i].rs1!=0) { // SLT
2233               assert(s1l>=0);
2234               emit_shrimm(s1l,31,t);
2235             }
2236             else // SLTU (unsigned can not be less than zero, 0<0)
2237               emit_zeroreg(t);
2238           }
2239           else if(dops[i].rs1==0) // r0<rx
2240           {
2241             assert(s2l>=0);
2242             if(dops[i].opcode2==0x2a) // SLT
2243               emit_set_gz32(s2l,t);
2244             else // SLTU (set if not zero)
2245               emit_set_nz32(s2l,t);
2246           }
2247           else{
2248             assert(s1l>=0);assert(s2l>=0);
2249             if(dops[i].opcode2==0x2a) // SLT
2250               emit_set_if_less32(s1l,s2l,t);
2251             else // SLTU
2252               emit_set_if_carry32(s1l,s2l,t);
2253           }
2254         }
2255       }
2256     }
2257   }
2258   if(dops[i].opcode2>=0x24&&dops[i].opcode2<=0x27) { // AND/OR/XOR/NOR
2259     if(dops[i].rt1) {
2260       signed char s1l,s2l,tl;
2261       tl=get_reg(i_regs->regmap,dops[i].rt1);
2262       {
2263         if(tl>=0) {
2264           s1l=get_reg(i_regs->regmap,dops[i].rs1);
2265           s2l=get_reg(i_regs->regmap,dops[i].rs2);
2266           if(dops[i].rs1&&dops[i].rs2) {
2267             assert(s1l>=0);
2268             assert(s2l>=0);
2269             if(dops[i].opcode2==0x24) { // AND
2270               emit_and(s1l,s2l,tl);
2271             } else
2272             if(dops[i].opcode2==0x25) { // OR
2273               emit_or(s1l,s2l,tl);
2274             } else
2275             if(dops[i].opcode2==0x26) { // XOR
2276               emit_xor(s1l,s2l,tl);
2277             } else
2278             if(dops[i].opcode2==0x27) { // NOR
2279               emit_or(s1l,s2l,tl);
2280               emit_not(tl,tl);
2281             }
2282           }
2283           else
2284           {
2285             if(dops[i].opcode2==0x24) { // AND
2286               emit_zeroreg(tl);
2287             } else
2288             if(dops[i].opcode2==0x25||dops[i].opcode2==0x26) { // OR/XOR
2289               if(dops[i].rs1){
2290                 if(s1l>=0) emit_mov(s1l,tl);
2291                 else emit_loadreg(dops[i].rs1,tl); // CHECK: regmap_entry?
2292               }
2293               else
2294               if(dops[i].rs2){
2295                 if(s2l>=0) emit_mov(s2l,tl);
2296                 else emit_loadreg(dops[i].rs2,tl); // CHECK: regmap_entry?
2297               }
2298               else emit_zeroreg(tl);
2299             } else
2300             if(dops[i].opcode2==0x27) { // NOR
2301               if(dops[i].rs1){
2302                 if(s1l>=0) emit_not(s1l,tl);
2303                 else {
2304                   emit_loadreg(dops[i].rs1,tl);
2305                   emit_not(tl,tl);
2306                 }
2307               }
2308               else
2309               if(dops[i].rs2){
2310                 if(s2l>=0) emit_not(s2l,tl);
2311                 else {
2312                   emit_loadreg(dops[i].rs2,tl);
2313                   emit_not(tl,tl);
2314                 }
2315               }
2316               else emit_movimm(-1,tl);
2317             }
2318           }
2319         }
2320       }
2321     }
2322   }
2323 }
2324
2325 static void imm16_assemble(int i, const struct regstat *i_regs)
2326 {
2327   if (dops[i].opcode==0x0f) { // LUI
2328     if(dops[i].rt1) {
2329       signed char t;
2330       t=get_reg(i_regs->regmap,dops[i].rt1);
2331       //assert(t>=0);
2332       if(t>=0) {
2333         if(!((i_regs->isconst>>t)&1))
2334           emit_movimm(imm[i]<<16,t);
2335       }
2336     }
2337   }
2338   if(dops[i].opcode==0x08||dops[i].opcode==0x09) { // ADDI/ADDIU
2339     if(dops[i].rt1) {
2340       signed char s,t;
2341       t=get_reg(i_regs->regmap,dops[i].rt1);
2342       s=get_reg(i_regs->regmap,dops[i].rs1);
2343       if(dops[i].rs1) {
2344         //assert(t>=0);
2345         //assert(s>=0);
2346         if(t>=0) {
2347           if(!((i_regs->isconst>>t)&1)) {
2348             if(s<0) {
2349               if(i_regs->regmap_entry[t]!=dops[i].rs1) emit_loadreg(dops[i].rs1,t);
2350               emit_addimm(t,imm[i],t);
2351             }else{
2352               if(!((i_regs->wasconst>>s)&1))
2353                 emit_addimm(s,imm[i],t);
2354               else
2355                 emit_movimm(constmap[i][s]+imm[i],t);
2356             }
2357           }
2358         }
2359       } else {
2360         if(t>=0) {
2361           if(!((i_regs->isconst>>t)&1))
2362             emit_movimm(imm[i],t);
2363         }
2364       }
2365     }
2366   }
2367   if(dops[i].opcode==0x18||dops[i].opcode==0x19) { // DADDI/DADDIU
2368     if(dops[i].rt1) {
2369       signed char sl,tl;
2370       tl=get_reg(i_regs->regmap,dops[i].rt1);
2371       sl=get_reg(i_regs->regmap,dops[i].rs1);
2372       if(tl>=0) {
2373         if(dops[i].rs1) {
2374           assert(sl>=0);
2375           emit_addimm(sl,imm[i],tl);
2376         } else {
2377           emit_movimm(imm[i],tl);
2378         }
2379       }
2380     }
2381   }
2382   else if(dops[i].opcode==0x0a||dops[i].opcode==0x0b) { // SLTI/SLTIU
2383     if(dops[i].rt1) {
2384       //assert(dops[i].rs1!=0); // r0 might be valid, but it's probably a bug
2385       signed char sl,t;
2386       t=get_reg(i_regs->regmap,dops[i].rt1);
2387       sl=get_reg(i_regs->regmap,dops[i].rs1);
2388       //assert(t>=0);
2389       if(t>=0) {
2390         if(dops[i].rs1>0) {
2391             if(dops[i].opcode==0x0a) { // SLTI
2392               if(sl<0) {
2393                 if(i_regs->regmap_entry[t]!=dops[i].rs1) emit_loadreg(dops[i].rs1,t);
2394                 emit_slti32(t,imm[i],t);
2395               }else{
2396                 emit_slti32(sl,imm[i],t);
2397               }
2398             }
2399             else { // SLTIU
2400               if(sl<0) {
2401                 if(i_regs->regmap_entry[t]!=dops[i].rs1) emit_loadreg(dops[i].rs1,t);
2402                 emit_sltiu32(t,imm[i],t);
2403               }else{
2404                 emit_sltiu32(sl,imm[i],t);
2405               }
2406             }
2407         }else{
2408           // SLTI(U) with r0 is just stupid,
2409           // nonetheless examples can be found
2410           if(dops[i].opcode==0x0a) // SLTI
2411             if(0<imm[i]) emit_movimm(1,t);
2412             else emit_zeroreg(t);
2413           else // SLTIU
2414           {
2415             if(imm[i]) emit_movimm(1,t);
2416             else emit_zeroreg(t);
2417           }
2418         }
2419       }
2420     }
2421   }
2422   else if(dops[i].opcode>=0x0c&&dops[i].opcode<=0x0e) { // ANDI/ORI/XORI
2423     if(dops[i].rt1) {
2424       signed char sl,tl;
2425       tl=get_reg(i_regs->regmap,dops[i].rt1);
2426       sl=get_reg(i_regs->regmap,dops[i].rs1);
2427       if(tl>=0 && !((i_regs->isconst>>tl)&1)) {
2428         if(dops[i].opcode==0x0c) //ANDI
2429         {
2430           if(dops[i].rs1) {
2431             if(sl<0) {
2432               if(i_regs->regmap_entry[tl]!=dops[i].rs1) emit_loadreg(dops[i].rs1,tl);
2433               emit_andimm(tl,imm[i],tl);
2434             }else{
2435               if(!((i_regs->wasconst>>sl)&1))
2436                 emit_andimm(sl,imm[i],tl);
2437               else
2438                 emit_movimm(constmap[i][sl]&imm[i],tl);
2439             }
2440           }
2441           else
2442             emit_zeroreg(tl);
2443         }
2444         else
2445         {
2446           if(dops[i].rs1) {
2447             if(sl<0) {
2448               if(i_regs->regmap_entry[tl]!=dops[i].rs1) emit_loadreg(dops[i].rs1,tl);
2449             }
2450             if(dops[i].opcode==0x0d) { // ORI
2451               if(sl<0) {
2452                 emit_orimm(tl,imm[i],tl);
2453               }else{
2454                 if(!((i_regs->wasconst>>sl)&1))
2455                   emit_orimm(sl,imm[i],tl);
2456                 else
2457                   emit_movimm(constmap[i][sl]|imm[i],tl);
2458               }
2459             }
2460             if(dops[i].opcode==0x0e) { // XORI
2461               if(sl<0) {
2462                 emit_xorimm(tl,imm[i],tl);
2463               }else{
2464                 if(!((i_regs->wasconst>>sl)&1))
2465                   emit_xorimm(sl,imm[i],tl);
2466                 else
2467                   emit_movimm(constmap[i][sl]^imm[i],tl);
2468               }
2469             }
2470           }
2471           else {
2472             emit_movimm(imm[i],tl);
2473           }
2474         }
2475       }
2476     }
2477   }
2478 }
2479
2480 static void shiftimm_assemble(int i, const struct regstat *i_regs)
2481 {
2482   if(dops[i].opcode2<=0x3) // SLL/SRL/SRA
2483   {
2484     if(dops[i].rt1) {
2485       signed char s,t;
2486       t=get_reg(i_regs->regmap,dops[i].rt1);
2487       s=get_reg(i_regs->regmap,dops[i].rs1);
2488       //assert(t>=0);
2489       if(t>=0&&!((i_regs->isconst>>t)&1)){
2490         if(dops[i].rs1==0)
2491         {
2492           emit_zeroreg(t);
2493         }
2494         else
2495         {
2496           if(s<0&&i_regs->regmap_entry[t]!=dops[i].rs1) emit_loadreg(dops[i].rs1,t);
2497           if(imm[i]) {
2498             if(dops[i].opcode2==0) // SLL
2499             {
2500               emit_shlimm(s<0?t:s,imm[i],t);
2501             }
2502             if(dops[i].opcode2==2) // SRL
2503             {
2504               emit_shrimm(s<0?t:s,imm[i],t);
2505             }
2506             if(dops[i].opcode2==3) // SRA
2507             {
2508               emit_sarimm(s<0?t:s,imm[i],t);
2509             }
2510           }else{
2511             // Shift by zero
2512             if(s>=0 && s!=t) emit_mov(s,t);
2513           }
2514         }
2515       }
2516       //emit_storereg(dops[i].rt1,t); //DEBUG
2517     }
2518   }
2519   if(dops[i].opcode2>=0x38&&dops[i].opcode2<=0x3b) // DSLL/DSRL/DSRA
2520   {
2521     assert(0);
2522   }
2523   if(dops[i].opcode2==0x3c) // DSLL32
2524   {
2525     assert(0);
2526   }
2527   if(dops[i].opcode2==0x3e) // DSRL32
2528   {
2529     assert(0);
2530   }
2531   if(dops[i].opcode2==0x3f) // DSRA32
2532   {
2533     assert(0);
2534   }
2535 }
2536
2537 #ifndef shift_assemble
2538 static void shift_assemble(int i, const struct regstat *i_regs)
2539 {
2540   signed char s,t,shift;
2541   if (dops[i].rt1 == 0)
2542     return;
2543   assert(dops[i].opcode2<=0x07); // SLLV/SRLV/SRAV
2544   t = get_reg(i_regs->regmap, dops[i].rt1);
2545   s = get_reg(i_regs->regmap, dops[i].rs1);
2546   shift = get_reg(i_regs->regmap, dops[i].rs2);
2547   if (t < 0)
2548     return;
2549
2550   if(dops[i].rs1==0)
2551     emit_zeroreg(t);
2552   else if(dops[i].rs2==0) {
2553     assert(s>=0);
2554     if(s!=t) emit_mov(s,t);
2555   }
2556   else {
2557     host_tempreg_acquire();
2558     emit_andimm(shift,31,HOST_TEMPREG);
2559     switch(dops[i].opcode2) {
2560     case 4: // SLLV
2561       emit_shl(s,HOST_TEMPREG,t);
2562       break;
2563     case 6: // SRLV
2564       emit_shr(s,HOST_TEMPREG,t);
2565       break;
2566     case 7: // SRAV
2567       emit_sar(s,HOST_TEMPREG,t);
2568       break;
2569     default:
2570       assert(0);
2571     }
2572     host_tempreg_release();
2573   }
2574 }
2575
2576 #endif
2577
2578 enum {
2579   MTYPE_8000 = 0,
2580   MTYPE_8020,
2581   MTYPE_0000,
2582   MTYPE_A000,
2583   MTYPE_1F80,
2584 };
2585
2586 static int get_ptr_mem_type(u_int a)
2587 {
2588   if(a < 0x00200000) {
2589     if(a<0x1000&&((start>>20)==0xbfc||(start>>24)==0xa0))
2590       // return wrong, must use memhandler for BIOS self-test to pass
2591       // 007 does similar stuff from a00 mirror, weird stuff
2592       return MTYPE_8000;
2593     return MTYPE_0000;
2594   }
2595   if(0x1f800000 <= a && a < 0x1f801000)
2596     return MTYPE_1F80;
2597   if(0x80200000 <= a && a < 0x80800000)
2598     return MTYPE_8020;
2599   if(0xa0000000 <= a && a < 0xa0200000)
2600     return MTYPE_A000;
2601   return MTYPE_8000;
2602 }
2603
2604 static int get_ro_reg(const struct regstat *i_regs, int host_tempreg_free)
2605 {
2606   int r = get_reg(i_regs->regmap, ROREG);
2607   if (r < 0 && host_tempreg_free) {
2608     host_tempreg_acquire();
2609     emit_loadreg(ROREG, r = HOST_TEMPREG);
2610   }
2611   if (r < 0)
2612     abort();
2613   return r;
2614 }
2615
2616 static void *emit_fastpath_cmp_jump(int i, const struct regstat *i_regs,
2617   int addr, int *offset_reg, int *addr_reg_override)
2618 {
2619   void *jaddr = NULL;
2620   int type = 0;
2621   int mr = dops[i].rs1;
2622   *offset_reg = -1;
2623   if(((smrv_strong|smrv_weak)>>mr)&1) {
2624     type=get_ptr_mem_type(smrv[mr]);
2625     //printf("set %08x @%08x r%d %d\n", smrv[mr], start+i*4, mr, type);
2626   }
2627   else {
2628     // use the mirror we are running on
2629     type=get_ptr_mem_type(start);
2630     //printf("set nospec   @%08x r%d %d\n", start+i*4, mr, type);
2631   }
2632
2633   if(type==MTYPE_8020) { // RAM 80200000+ mirror
2634     host_tempreg_acquire();
2635     emit_andimm(addr,~0x00e00000,HOST_TEMPREG);
2636     addr=*addr_reg_override=HOST_TEMPREG;
2637     type=0;
2638   }
2639   else if(type==MTYPE_0000) { // RAM 0 mirror
2640     host_tempreg_acquire();
2641     emit_orimm(addr,0x80000000,HOST_TEMPREG);
2642     addr=*addr_reg_override=HOST_TEMPREG;
2643     type=0;
2644   }
2645   else if(type==MTYPE_A000) { // RAM A mirror
2646     host_tempreg_acquire();
2647     emit_andimm(addr,~0x20000000,HOST_TEMPREG);
2648     addr=*addr_reg_override=HOST_TEMPREG;
2649     type=0;
2650   }
2651   else if(type==MTYPE_1F80) { // scratchpad
2652     if (psxH == (void *)0x1f800000) {
2653       host_tempreg_acquire();
2654       emit_xorimm(addr,0x1f800000,HOST_TEMPREG);
2655       emit_cmpimm(HOST_TEMPREG,0x1000);
2656       host_tempreg_release();
2657       jaddr=out;
2658       emit_jc(0);
2659     }
2660     else {
2661       // do the usual RAM check, jump will go to the right handler
2662       type=0;
2663     }
2664   }
2665
2666   if (type == 0) // need ram check
2667   {
2668     emit_cmpimm(addr,RAM_SIZE);
2669     jaddr = out;
2670     #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
2671     // Hint to branch predictor that the branch is unlikely to be taken
2672     if (dops[i].rs1 >= 28)
2673       emit_jno_unlikely(0);
2674     else
2675     #endif
2676       emit_jno(0);
2677     if (ram_offset != 0)
2678       *offset_reg = get_ro_reg(i_regs, 0);
2679   }
2680
2681   return jaddr;
2682 }
2683
2684 // return memhandler, or get directly accessable address and return 0
2685 static void *get_direct_memhandler(void *table, u_int addr,
2686   enum stub_type type, uintptr_t *addr_host)
2687 {
2688   uintptr_t msb = 1ull << (sizeof(uintptr_t)*8 - 1);
2689   uintptr_t l1, l2 = 0;
2690   l1 = ((uintptr_t *)table)[addr>>12];
2691   if (!(l1 & msb)) {
2692     uintptr_t v = l1 << 1;
2693     *addr_host = v + addr;
2694     return NULL;
2695   }
2696   else {
2697     l1 <<= 1;
2698     if (type == LOADB_STUB || type == LOADBU_STUB || type == STOREB_STUB)
2699       l2 = ((uintptr_t *)l1)[0x1000/4 + 0x1000/2 + (addr&0xfff)];
2700     else if (type == LOADH_STUB || type == LOADHU_STUB || type == STOREH_STUB)
2701       l2 = ((uintptr_t *)l1)[0x1000/4 + (addr&0xfff)/2];
2702     else
2703       l2 = ((uintptr_t *)l1)[(addr&0xfff)/4];
2704     if (!(l2 & msb)) {
2705       uintptr_t v = l2 << 1;
2706       *addr_host = v + (addr&0xfff);
2707       return NULL;
2708     }
2709     return (void *)(l2 << 1);
2710   }
2711 }
2712
2713 static u_int get_host_reglist(const signed char *regmap)
2714 {
2715   u_int reglist = 0, hr;
2716   for (hr = 0; hr < HOST_REGS; hr++) {
2717     if (hr != EXCLUDE_REG && regmap[hr] >= 0)
2718       reglist |= 1 << hr;
2719   }
2720   return reglist;
2721 }
2722
2723 static u_int reglist_exclude(u_int reglist, int r1, int r2)
2724 {
2725   if (r1 >= 0)
2726     reglist &= ~(1u << r1);
2727   if (r2 >= 0)
2728     reglist &= ~(1u << r2);
2729   return reglist;
2730 }
2731
2732 // find a temp caller-saved register not in reglist (so assumed to be free)
2733 static int reglist_find_free(u_int reglist)
2734 {
2735   u_int free_regs = ~reglist & CALLER_SAVE_REGS;
2736   if (free_regs == 0)
2737     return -1;
2738   return __builtin_ctz(free_regs);
2739 }
2740
2741 static void do_load_word(int a, int rt, int offset_reg)
2742 {
2743   if (offset_reg >= 0)
2744     emit_ldr_dualindexed(offset_reg, a, rt);
2745   else
2746     emit_readword_indexed(0, a, rt);
2747 }
2748
2749 static void do_store_word(int a, int ofs, int rt, int offset_reg, int preseve_a)
2750 {
2751   if (offset_reg < 0) {
2752     emit_writeword_indexed(rt, ofs, a);
2753     return;
2754   }
2755   if (ofs != 0)
2756     emit_addimm(a, ofs, a);
2757   emit_str_dualindexed(offset_reg, a, rt);
2758   if (ofs != 0 && preseve_a)
2759     emit_addimm(a, -ofs, a);
2760 }
2761
2762 static void do_store_hword(int a, int ofs, int rt, int offset_reg, int preseve_a)
2763 {
2764   if (offset_reg < 0) {
2765     emit_writehword_indexed(rt, ofs, a);
2766     return;
2767   }
2768   if (ofs != 0)
2769     emit_addimm(a, ofs, a);
2770   emit_strh_dualindexed(offset_reg, a, rt);
2771   if (ofs != 0 && preseve_a)
2772     emit_addimm(a, -ofs, a);
2773 }
2774
2775 static void do_store_byte(int a, int rt, int offset_reg)
2776 {
2777   if (offset_reg >= 0)
2778     emit_strb_dualindexed(offset_reg, a, rt);
2779   else
2780     emit_writebyte_indexed(rt, 0, a);
2781 }
2782
2783 static void load_assemble(int i, const struct regstat *i_regs, int ccadj_)
2784 {
2785   int s,tl,addr;
2786   int offset;
2787   void *jaddr=0;
2788   int memtarget=0,c=0;
2789   int offset_reg = -1;
2790   int fastio_reg_override = -1;
2791   u_int reglist=get_host_reglist(i_regs->regmap);
2792   tl=get_reg(i_regs->regmap,dops[i].rt1);
2793   s=get_reg(i_regs->regmap,dops[i].rs1);
2794   offset=imm[i];
2795   if(i_regs->regmap[HOST_CCREG]==CCREG) reglist&=~(1<<HOST_CCREG);
2796   if(s>=0) {
2797     c=(i_regs->wasconst>>s)&1;
2798     if (c) {
2799       memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
2800     }
2801   }
2802   //printf("load_assemble: c=%d\n",c);
2803   //if(c) printf("load_assemble: const=%lx\n",(long)constmap[i][s]+offset);
2804   // FIXME: Even if the load is a NOP, we should check for pagefaults...
2805   if((tl<0&&(!c||(((u_int)constmap[i][s]+offset)>>16)==0x1f80))
2806     ||dops[i].rt1==0) {
2807       // could be FIFO, must perform the read
2808       // ||dummy read
2809       assem_debug("(forced read)\n");
2810       tl=get_reg(i_regs->regmap,-1);
2811       assert(tl>=0);
2812   }
2813   if(offset||s<0||c) addr=tl;
2814   else addr=s;
2815   //if(tl<0) tl=get_reg(i_regs->regmap,-1);
2816  if(tl>=0) {
2817   //printf("load_assemble: c=%d\n",c);
2818   //if(c) printf("load_assemble: const=%lx\n",(long)constmap[i][s]+offset);
2819   assert(tl>=0); // Even if the load is a NOP, we must check for pagefaults and I/O
2820   reglist&=~(1<<tl);
2821   if(!c) {
2822     #ifdef R29_HACK
2823     // Strmnnrmn's speed hack
2824     if(dops[i].rs1!=29||start<0x80001000||start>=0x80000000+RAM_SIZE)
2825     #endif
2826     {
2827       jaddr = emit_fastpath_cmp_jump(i, i_regs, addr,
2828                 &offset_reg, &fastio_reg_override);
2829     }
2830   }
2831   else if (ram_offset && memtarget) {
2832     offset_reg = get_ro_reg(i_regs, 0);
2833   }
2834   int dummy=(dops[i].rt1==0)||(tl!=get_reg(i_regs->regmap,dops[i].rt1)); // ignore loads to r0 and unneeded reg
2835   switch (dops[i].opcode) {
2836   case 0x20: // LB
2837     if(!c||memtarget) {
2838       if(!dummy) {
2839         int a = tl;
2840         if (!c) a = addr;
2841         if (fastio_reg_override >= 0)
2842           a = fastio_reg_override;
2843
2844         if (offset_reg >= 0)
2845           emit_ldrsb_dualindexed(offset_reg, a, tl);
2846         else
2847           emit_movsbl_indexed(0, a, tl);
2848       }
2849       if(jaddr)
2850         add_stub_r(LOADB_STUB,jaddr,out,i,addr,i_regs,ccadj_,reglist);
2851     }
2852     else
2853       inline_readstub(LOADB_STUB,i,constmap[i][s]+offset,i_regs->regmap,dops[i].rt1,ccadj_,reglist);
2854     break;
2855   case 0x21: // LH
2856     if(!c||memtarget) {
2857       if(!dummy) {
2858         int a = tl;
2859         if (!c) a = addr;
2860         if (fastio_reg_override >= 0)
2861           a = fastio_reg_override;
2862         if (offset_reg >= 0)
2863           emit_ldrsh_dualindexed(offset_reg, a, tl);
2864         else
2865           emit_movswl_indexed(0, a, tl);
2866       }
2867       if(jaddr)
2868         add_stub_r(LOADH_STUB,jaddr,out,i,addr,i_regs,ccadj_,reglist);
2869     }
2870     else
2871       inline_readstub(LOADH_STUB,i,constmap[i][s]+offset,i_regs->regmap,dops[i].rt1,ccadj_,reglist);
2872     break;
2873   case 0x23: // LW
2874     if(!c||memtarget) {
2875       if(!dummy) {
2876         int a = addr;
2877         if (fastio_reg_override >= 0)
2878           a = fastio_reg_override;
2879         do_load_word(a, tl, offset_reg);
2880       }
2881       if(jaddr)
2882         add_stub_r(LOADW_STUB,jaddr,out,i,addr,i_regs,ccadj_,reglist);
2883     }
2884     else
2885       inline_readstub(LOADW_STUB,i,constmap[i][s]+offset,i_regs->regmap,dops[i].rt1,ccadj_,reglist);
2886     break;
2887   case 0x24: // LBU
2888     if(!c||memtarget) {
2889       if(!dummy) {
2890         int a = tl;
2891         if (!c) a = addr;
2892         if (fastio_reg_override >= 0)
2893           a = fastio_reg_override;
2894
2895         if (offset_reg >= 0)
2896           emit_ldrb_dualindexed(offset_reg, a, tl);
2897         else
2898           emit_movzbl_indexed(0, a, tl);
2899       }
2900       if(jaddr)
2901         add_stub_r(LOADBU_STUB,jaddr,out,i,addr,i_regs,ccadj_,reglist);
2902     }
2903     else
2904       inline_readstub(LOADBU_STUB,i,constmap[i][s]+offset,i_regs->regmap,dops[i].rt1,ccadj_,reglist);
2905     break;
2906   case 0x25: // LHU
2907     if(!c||memtarget) {
2908       if(!dummy) {
2909         int a = tl;
2910         if(!c) a = addr;
2911         if (fastio_reg_override >= 0)
2912           a = fastio_reg_override;
2913         if (offset_reg >= 0)
2914           emit_ldrh_dualindexed(offset_reg, a, tl);
2915         else
2916           emit_movzwl_indexed(0, a, tl);
2917       }
2918       if(jaddr)
2919         add_stub_r(LOADHU_STUB,jaddr,out,i,addr,i_regs,ccadj_,reglist);
2920     }
2921     else
2922       inline_readstub(LOADHU_STUB,i,constmap[i][s]+offset,i_regs->regmap,dops[i].rt1,ccadj_,reglist);
2923     break;
2924   case 0x27: // LWU
2925   case 0x37: // LD
2926   default:
2927     assert(0);
2928   }
2929  }
2930  if (fastio_reg_override == HOST_TEMPREG || offset_reg == HOST_TEMPREG)
2931    host_tempreg_release();
2932 }
2933
2934 #ifndef loadlr_assemble
2935 static void loadlr_assemble(int i, const struct regstat *i_regs, int ccadj_)
2936 {
2937   int s,tl,temp,temp2,addr;
2938   int offset;
2939   void *jaddr=0;
2940   int memtarget=0,c=0;
2941   int offset_reg = -1;
2942   int fastio_reg_override = -1;
2943   u_int reglist=get_host_reglist(i_regs->regmap);
2944   tl=get_reg(i_regs->regmap,dops[i].rt1);
2945   s=get_reg(i_regs->regmap,dops[i].rs1);
2946   temp=get_reg(i_regs->regmap,-1);
2947   temp2=get_reg(i_regs->regmap,FTEMP);
2948   addr=get_reg(i_regs->regmap,AGEN1+(i&1));
2949   assert(addr<0);
2950   offset=imm[i];
2951   reglist|=1<<temp;
2952   if(offset||s<0||c) addr=temp2;
2953   else addr=s;
2954   if(s>=0) {
2955     c=(i_regs->wasconst>>s)&1;
2956     if(c) {
2957       memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
2958     }
2959   }
2960   if(!c) {
2961     emit_shlimm(addr,3,temp);
2962     if (dops[i].opcode==0x22||dops[i].opcode==0x26) {
2963       emit_andimm(addr,0xFFFFFFFC,temp2); // LWL/LWR
2964     }else{
2965       emit_andimm(addr,0xFFFFFFF8,temp2); // LDL/LDR
2966     }
2967     jaddr = emit_fastpath_cmp_jump(i, i_regs, temp2,
2968               &offset_reg, &fastio_reg_override);
2969   }
2970   else {
2971     if (ram_offset && memtarget) {
2972       offset_reg = get_ro_reg(i_regs, 0);
2973     }
2974     if (dops[i].opcode==0x22||dops[i].opcode==0x26) {
2975       emit_movimm(((constmap[i][s]+offset)<<3)&24,temp); // LWL/LWR
2976     }else{
2977       emit_movimm(((constmap[i][s]+offset)<<3)&56,temp); // LDL/LDR
2978     }
2979   }
2980   if (dops[i].opcode==0x22||dops[i].opcode==0x26) { // LWL/LWR
2981     if(!c||memtarget) {
2982       int a = temp2;
2983       if (fastio_reg_override >= 0)
2984         a = fastio_reg_override;
2985       do_load_word(a, temp2, offset_reg);
2986       if (fastio_reg_override == HOST_TEMPREG || offset_reg == HOST_TEMPREG)
2987         host_tempreg_release();
2988       if(jaddr) add_stub_r(LOADW_STUB,jaddr,out,i,temp2,i_regs,ccadj_,reglist);
2989     }
2990     else
2991       inline_readstub(LOADW_STUB,i,(constmap[i][s]+offset)&0xFFFFFFFC,i_regs->regmap,FTEMP,ccadj_,reglist);
2992     if(dops[i].rt1) {
2993       assert(tl>=0);
2994       emit_andimm(temp,24,temp);
2995       if (dops[i].opcode==0x22) // LWL
2996         emit_xorimm(temp,24,temp);
2997       host_tempreg_acquire();
2998       emit_movimm(-1,HOST_TEMPREG);
2999       if (dops[i].opcode==0x26) {
3000         emit_shr(temp2,temp,temp2);
3001         emit_bic_lsr(tl,HOST_TEMPREG,temp,tl);
3002       }else{
3003         emit_shl(temp2,temp,temp2);
3004         emit_bic_lsl(tl,HOST_TEMPREG,temp,tl);
3005       }
3006       host_tempreg_release();
3007       emit_or(temp2,tl,tl);
3008     }
3009     //emit_storereg(dops[i].rt1,tl); // DEBUG
3010   }
3011   if (dops[i].opcode==0x1A||dops[i].opcode==0x1B) { // LDL/LDR
3012     assert(0);
3013   }
3014 }
3015 #endif
3016
3017 static void store_assemble(int i, const struct regstat *i_regs, int ccadj_)
3018 {
3019   int s,tl;
3020   int addr,temp;
3021   int offset;
3022   void *jaddr=0;
3023   enum stub_type type=0;
3024   int memtarget=0,c=0;
3025   int agr=AGEN1+(i&1);
3026   int offset_reg = -1;
3027   int fastio_reg_override = -1;
3028   u_int reglist=get_host_reglist(i_regs->regmap);
3029   tl=get_reg(i_regs->regmap,dops[i].rs2);
3030   s=get_reg(i_regs->regmap,dops[i].rs1);
3031   temp=get_reg(i_regs->regmap,agr);
3032   if(temp<0) temp=get_reg(i_regs->regmap,-1);
3033   offset=imm[i];
3034   if(s>=0) {
3035     c=(i_regs->wasconst>>s)&1;
3036     if(c) {
3037       memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
3038     }
3039   }
3040   assert(tl>=0);
3041   assert(temp>=0);
3042   if(i_regs->regmap[HOST_CCREG]==CCREG) reglist&=~(1<<HOST_CCREG);
3043   if(offset||s<0||c) addr=temp;
3044   else addr=s;
3045   if (!c) {
3046     jaddr = emit_fastpath_cmp_jump(i, i_regs, addr,
3047               &offset_reg, &fastio_reg_override);
3048   }
3049   else if (ram_offset && memtarget) {
3050     offset_reg = get_ro_reg(i_regs, 0);
3051   }
3052
3053   switch (dops[i].opcode) {
3054   case 0x28: // SB
3055     if(!c||memtarget) {
3056       int a = temp;
3057       if (!c) a = addr;
3058       if (fastio_reg_override >= 0)
3059         a = fastio_reg_override;
3060       do_store_byte(a, tl, offset_reg);
3061     }
3062     type = STOREB_STUB;
3063     break;
3064   case 0x29: // SH
3065     if(!c||memtarget) {
3066       int a = temp;
3067       if (!c) a = addr;
3068       if (fastio_reg_override >= 0)
3069         a = fastio_reg_override;
3070       do_store_hword(a, 0, tl, offset_reg, 1);
3071     }
3072     type = STOREH_STUB;
3073     break;
3074   case 0x2B: // SW
3075     if(!c||memtarget) {
3076       int a = addr;
3077       if (fastio_reg_override >= 0)
3078         a = fastio_reg_override;
3079       do_store_word(a, 0, tl, offset_reg, 1);
3080     }
3081     type = STOREW_STUB;
3082     break;
3083   case 0x3F: // SD
3084   default:
3085     assert(0);
3086   }
3087   if (fastio_reg_override == HOST_TEMPREG || offset_reg == HOST_TEMPREG)
3088     host_tempreg_release();
3089   if(jaddr) {
3090     // PCSX store handlers don't check invcode again
3091     reglist|=1<<addr;
3092     add_stub_r(type,jaddr,out,i,addr,i_regs,ccadj_,reglist);
3093     jaddr=0;
3094   }
3095   if(!(i_regs->waswritten&(1<<dops[i].rs1)) && !HACK_ENABLED(NDHACK_NO_SMC_CHECK)) {
3096     if(!c||memtarget) {
3097       #ifdef DESTRUCTIVE_SHIFT
3098       // The x86 shift operation is 'destructive'; it overwrites the
3099       // source register, so we need to make a copy first and use that.
3100       addr=temp;
3101       #endif
3102       #if defined(HOST_IMM8)
3103       int ir=get_reg(i_regs->regmap,INVCP);
3104       assert(ir>=0);
3105       emit_cmpmem_indexedsr12_reg(ir,addr,1);
3106       #else
3107       emit_cmpmem_indexedsr12_imm(invalid_code,addr,1);
3108       #endif
3109       #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT)
3110       emit_callne(invalidate_addr_reg[addr]);
3111       #else
3112       void *jaddr2 = out;
3113       emit_jne(0);
3114       add_stub(INVCODE_STUB,jaddr2,out,reglist|(1<<HOST_CCREG),addr,0,0,0);
3115       #endif
3116     }
3117   }
3118   u_int addr_val=constmap[i][s]+offset;
3119   if(jaddr) {
3120     add_stub_r(type,jaddr,out,i,addr,i_regs,ccadj_,reglist);
3121   } else if(c&&!memtarget) {
3122     inline_writestub(type,i,addr_val,i_regs->regmap,dops[i].rs2,ccadj_,reglist);
3123   }
3124   // basic current block modification detection..
3125   // not looking back as that should be in mips cache already
3126   // (see Spyro2 title->attract mode)
3127   if(c&&start+i*4<addr_val&&addr_val<start+slen*4) {
3128     SysPrintf("write to %08x hits block %08x, pc=%08x\n",addr_val,start,start+i*4);
3129     assert(i_regs->regmap==regs[i].regmap); // not delay slot
3130     if(i_regs->regmap==regs[i].regmap) {
3131       load_all_consts(regs[i].regmap_entry,regs[i].wasdirty,i);
3132       wb_dirtys(regs[i].regmap_entry,regs[i].wasdirty);
3133       emit_movimm(start+i*4+4,0);
3134       emit_writeword(0,&pcaddr);
3135       emit_addimm(HOST_CCREG,2,HOST_CCREG);
3136       emit_far_call(get_addr_ht);
3137       emit_jmpreg(0);
3138     }
3139   }
3140 }
3141
3142 static void storelr_assemble(int i, const struct regstat *i_regs, int ccadj_)
3143 {
3144   int s,tl;
3145   int temp;
3146   int offset;
3147   void *jaddr=0;
3148   void *case1, *case23, *case3;
3149   void *done0, *done1, *done2;
3150   int memtarget=0,c=0;
3151   int agr=AGEN1+(i&1);
3152   int offset_reg = -1;
3153   u_int reglist=get_host_reglist(i_regs->regmap);
3154   tl=get_reg(i_regs->regmap,dops[i].rs2);
3155   s=get_reg(i_regs->regmap,dops[i].rs1);
3156   temp=get_reg(i_regs->regmap,agr);
3157   if(temp<0) temp=get_reg(i_regs->regmap,-1);
3158   offset=imm[i];
3159   if(s>=0) {
3160     c=(i_regs->isconst>>s)&1;
3161     if(c) {
3162       memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
3163     }
3164   }
3165   assert(tl>=0);
3166   assert(temp>=0);
3167   if(!c) {
3168     emit_cmpimm(s<0||offset?temp:s,RAM_SIZE);
3169     if(!offset&&s!=temp) emit_mov(s,temp);
3170     jaddr=out;
3171     emit_jno(0);
3172   }
3173   else
3174   {
3175     if(!memtarget||!dops[i].rs1) {
3176       jaddr=out;
3177       emit_jmp(0);
3178     }
3179   }
3180   if (ram_offset)
3181     offset_reg = get_ro_reg(i_regs, 0);
3182
3183   if (dops[i].opcode==0x2C||dops[i].opcode==0x2D) { // SDL/SDR
3184     assert(0);
3185   }
3186
3187   emit_testimm(temp,2);
3188   case23=out;
3189   emit_jne(0);
3190   emit_testimm(temp,1);
3191   case1=out;
3192   emit_jne(0);
3193   // 0
3194   if (dops[i].opcode == 0x2A) { // SWL
3195     // Write msb into least significant byte
3196     if (dops[i].rs2) emit_rorimm(tl, 24, tl);
3197     do_store_byte(temp, tl, offset_reg);
3198     if (dops[i].rs2) emit_rorimm(tl, 8, tl);
3199   }
3200   else if (dops[i].opcode == 0x2E) { // SWR
3201     // Write entire word
3202     do_store_word(temp, 0, tl, offset_reg, 1);
3203   }
3204   done0 = out;
3205   emit_jmp(0);
3206   // 1
3207   set_jump_target(case1, out);
3208   if (dops[i].opcode == 0x2A) { // SWL
3209     // Write two msb into two least significant bytes
3210     if (dops[i].rs2) emit_rorimm(tl, 16, tl);
3211     do_store_hword(temp, -1, tl, offset_reg, 0);
3212     if (dops[i].rs2) emit_rorimm(tl, 16, tl);
3213   }
3214   else if (dops[i].opcode == 0x2E) { // SWR
3215     // Write 3 lsb into three most significant bytes
3216     do_store_byte(temp, tl, offset_reg);
3217     if (dops[i].rs2) emit_rorimm(tl, 8, tl);
3218     do_store_hword(temp, 1, tl, offset_reg, 0);
3219     if (dops[i].rs2) emit_rorimm(tl, 24, tl);
3220   }
3221   done1=out;
3222   emit_jmp(0);
3223   // 2,3
3224   set_jump_target(case23, out);
3225   emit_testimm(temp,1);
3226   case3 = out;
3227   emit_jne(0);
3228   // 2
3229   if (dops[i].opcode==0x2A) { // SWL
3230     // Write 3 msb into three least significant bytes
3231     if (dops[i].rs2) emit_rorimm(tl, 8, tl);
3232     do_store_hword(temp, -2, tl, offset_reg, 1);
3233     if (dops[i].rs2) emit_rorimm(tl, 16, tl);
3234     do_store_byte(temp, tl, offset_reg);
3235     if (dops[i].rs2) emit_rorimm(tl, 8, tl);
3236   }
3237   else if (dops[i].opcode == 0x2E) { // SWR
3238     // Write two lsb into two most significant bytes
3239     do_store_hword(temp, 0, tl, offset_reg, 1);
3240   }
3241   done2 = out;
3242   emit_jmp(0);
3243   // 3
3244   set_jump_target(case3, out);
3245   if (dops[i].opcode == 0x2A) { // SWL
3246     do_store_word(temp, -3, tl, offset_reg, 0);
3247   }
3248   else if (dops[i].opcode == 0x2E) { // SWR
3249     do_store_byte(temp, tl, offset_reg);
3250   }
3251   set_jump_target(done0, out);
3252   set_jump_target(done1, out);
3253   set_jump_target(done2, out);
3254   if (offset_reg == HOST_TEMPREG)
3255     host_tempreg_release();
3256   if(!c||!memtarget)
3257     add_stub_r(STORELR_STUB,jaddr,out,i,temp,i_regs,ccadj_,reglist);
3258   if(!(i_regs->waswritten&(1<<dops[i].rs1)) && !HACK_ENABLED(NDHACK_NO_SMC_CHECK)) {
3259     #if defined(HOST_IMM8)
3260     int ir=get_reg(i_regs->regmap,INVCP);
3261     assert(ir>=0);
3262     emit_cmpmem_indexedsr12_reg(ir,temp,1);
3263     #else
3264     emit_cmpmem_indexedsr12_imm(invalid_code,temp,1);
3265     #endif
3266     #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT)
3267     emit_callne(invalidate_addr_reg[temp]);
3268     #else
3269     void *jaddr2 = out;
3270     emit_jne(0);
3271     add_stub(INVCODE_STUB,jaddr2,out,reglist|(1<<HOST_CCREG),temp,0,0,0);
3272     #endif
3273   }
3274 }
3275
3276 static void cop0_assemble(int i, const struct regstat *i_regs, int ccadj_)
3277 {
3278   if(dops[i].opcode2==0) // MFC0
3279   {
3280     signed char t=get_reg(i_regs->regmap,dops[i].rt1);
3281     u_int copr=(source[i]>>11)&0x1f;
3282     //assert(t>=0); // Why does this happen?  OOT is weird
3283     if(t>=0&&dops[i].rt1!=0) {
3284       emit_readword(&reg_cop0[copr],t);
3285     }
3286   }
3287   else if(dops[i].opcode2==4) // MTC0
3288   {
3289     signed char s=get_reg(i_regs->regmap,dops[i].rs1);
3290     char copr=(source[i]>>11)&0x1f;
3291     assert(s>=0);
3292     wb_register(dops[i].rs1,i_regs->regmap,i_regs->dirty);
3293     if(copr==9||copr==11||copr==12||copr==13) {
3294       emit_readword(&last_count,HOST_TEMPREG);
3295       emit_loadreg(CCREG,HOST_CCREG); // TODO: do proper reg alloc
3296       emit_add(HOST_CCREG,HOST_TEMPREG,HOST_CCREG);
3297       emit_addimm(HOST_CCREG,ccadj_,HOST_CCREG);
3298       emit_writeword(HOST_CCREG,&Count);
3299     }
3300     // What a mess.  The status register (12) can enable interrupts,
3301     // so needs a special case to handle a pending interrupt.
3302     // The interrupt must be taken immediately, because a subsequent
3303     // instruction might disable interrupts again.
3304     if(copr==12||copr==13) {
3305       if (is_delayslot) {
3306         // burn cycles to cause cc_interrupt, which will
3307         // reschedule next_interupt. Relies on CCREG from above.
3308         assem_debug("MTC0 DS %d\n", copr);
3309         emit_writeword(HOST_CCREG,&last_count);
3310         emit_movimm(0,HOST_CCREG);
3311         emit_storereg(CCREG,HOST_CCREG);
3312         emit_loadreg(dops[i].rs1,1);
3313         emit_movimm(copr,0);
3314         emit_far_call(pcsx_mtc0_ds);
3315         emit_loadreg(dops[i].rs1,s);
3316         return;
3317       }
3318       emit_movimm(start+i*4+4,HOST_TEMPREG);
3319       emit_writeword(HOST_TEMPREG,&pcaddr);
3320       emit_movimm(0,HOST_TEMPREG);
3321       emit_writeword(HOST_TEMPREG,&pending_exception);
3322     }
3323     if(s==HOST_CCREG)
3324       emit_loadreg(dops[i].rs1,1);
3325     else if(s!=1)
3326       emit_mov(s,1);
3327     emit_movimm(copr,0);
3328     emit_far_call(pcsx_mtc0);
3329     if(copr==9||copr==11||copr==12||copr==13) {
3330       emit_readword(&Count,HOST_CCREG);
3331       emit_readword(&next_interupt,HOST_TEMPREG);
3332       emit_addimm(HOST_CCREG,-ccadj_,HOST_CCREG);
3333       emit_sub(HOST_CCREG,HOST_TEMPREG,HOST_CCREG);
3334       emit_writeword(HOST_TEMPREG,&last_count);
3335       emit_storereg(CCREG,HOST_CCREG);
3336     }
3337     if(copr==12||copr==13) {
3338       assert(!is_delayslot);
3339       emit_readword(&pending_exception,14);
3340       emit_test(14,14);
3341       void *jaddr = out;
3342       emit_jeq(0);
3343       emit_readword(&pcaddr, 0);
3344       emit_addimm(HOST_CCREG,2,HOST_CCREG);
3345       emit_far_call(get_addr_ht);
3346       emit_jmpreg(0);
3347       set_jump_target(jaddr, out);
3348     }
3349     emit_loadreg(dops[i].rs1,s);
3350   }
3351   else
3352   {
3353     assert(dops[i].opcode2==0x10);
3354     //if((source[i]&0x3f)==0x10) // RFE
3355     {
3356       emit_readword(&Status,0);
3357       emit_andimm(0,0x3c,1);
3358       emit_andimm(0,~0xf,0);
3359       emit_orrshr_imm(1,2,0);
3360       emit_writeword(0,&Status);
3361     }
3362   }
3363 }
3364
3365 static void cop1_unusable(int i, const struct regstat *i_regs)
3366 {
3367   // XXX: should just just do the exception instead
3368   //if(!cop1_usable)
3369   {
3370     void *jaddr=out;
3371     emit_jmp(0);
3372     add_stub_r(FP_STUB,jaddr,out,i,0,i_regs,is_delayslot,0);
3373   }
3374 }
3375
3376 static void cop1_assemble(int i, const struct regstat *i_regs)
3377 {
3378   cop1_unusable(i, i_regs);
3379 }
3380
3381 static void c1ls_assemble(int i, const struct regstat *i_regs)
3382 {
3383   cop1_unusable(i, i_regs);
3384 }
3385
3386 // FP_STUB
3387 static void do_cop1stub(int n)
3388 {
3389   literal_pool(256);
3390   assem_debug("do_cop1stub %x\n",start+stubs[n].a*4);
3391   set_jump_target(stubs[n].addr, out);
3392   int i=stubs[n].a;
3393 //  int rs=stubs[n].b;
3394   struct regstat *i_regs=(struct regstat *)stubs[n].c;
3395   int ds=stubs[n].d;
3396   if(!ds) {
3397     load_all_consts(regs[i].regmap_entry,regs[i].wasdirty,i);
3398     //if(i_regs!=&regs[i]) printf("oops: regs[i]=%x i_regs=%x",(int)&regs[i],(int)i_regs);
3399   }
3400   //else {printf("fp exception in delay slot\n");}
3401   wb_dirtys(i_regs->regmap_entry,i_regs->wasdirty);
3402   if(regs[i].regmap_entry[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG);
3403   emit_movimm(start+(i-ds)*4,EAX); // Get PC
3404   emit_addimm(HOST_CCREG,ccadj[i],HOST_CCREG); // CHECK: is this right?  There should probably be an extra cycle...
3405   emit_far_jump(ds?fp_exception_ds:fp_exception);
3406 }
3407
3408 static int cop2_is_stalling_op(int i, int *cycles)
3409 {
3410   if (dops[i].opcode == 0x3a) { // SWC2
3411     *cycles = 0;
3412     return 1;
3413   }
3414   if (dops[i].itype == COP2 && (dops[i].opcode2 == 0 || dops[i].opcode2 == 2)) { // MFC2/CFC2
3415     *cycles = 0;
3416     return 1;
3417   }
3418   if (dops[i].itype == C2OP) {
3419     *cycles = gte_cycletab[source[i] & 0x3f];
3420     return 1;
3421   }
3422   // ... what about MTC2/CTC2/LWC2?
3423   return 0;
3424 }
3425
3426 #if 0
3427 static void log_gte_stall(int stall, u_int cycle)
3428 {
3429   if ((u_int)stall <= 44)
3430     printf("x    stall %2d %u\n", stall, cycle + last_count);
3431 }
3432
3433 static void emit_log_gte_stall(int i, int stall, u_int reglist)
3434 {
3435   save_regs(reglist);
3436   if (stall > 0)
3437     emit_movimm(stall, 0);
3438   else
3439     emit_mov(HOST_TEMPREG, 0);
3440   emit_addimm(HOST_CCREG, ccadj[i], 1);
3441   emit_far_call(log_gte_stall);
3442   restore_regs(reglist);
3443 }
3444 #endif
3445
3446 static void cop2_do_stall_check(u_int op, int i, const struct regstat *i_regs, u_int reglist)
3447 {
3448   int j = i, other_gte_op_cycles = -1, stall = -MAXBLOCK, cycles_passed;
3449   int rtmp = reglist_find_free(reglist);
3450
3451   if (HACK_ENABLED(NDHACK_NO_STALLS))
3452     return;
3453   if (get_reg(i_regs->regmap, CCREG) != HOST_CCREG) {
3454     // happens occasionally... cc evicted? Don't bother then
3455     //printf("no cc %08x\n", start + i*4);
3456     return;
3457   }
3458   if (!dops[i].bt) {
3459     for (j = i - 1; j >= 0; j--) {
3460       //if (dops[j].is_ds) break;
3461       if (cop2_is_stalling_op(j, &other_gte_op_cycles) || dops[j].bt)
3462         break;
3463       if (j > 0 && ccadj[j - 1] > ccadj[j])
3464         break;
3465     }
3466     j = max(j, 0);
3467   }
3468   cycles_passed = ccadj[i] - ccadj[j];
3469   if (other_gte_op_cycles >= 0)
3470     stall = other_gte_op_cycles - cycles_passed;
3471   else if (cycles_passed >= 44)
3472     stall = 0; // can't stall
3473   if (stall == -MAXBLOCK && rtmp >= 0) {
3474     // unknown stall, do the expensive runtime check
3475     assem_debug("; cop2_do_stall_check\n");
3476 #if 0 // too slow
3477     save_regs(reglist);
3478     emit_movimm(gte_cycletab[op], 0);
3479     emit_addimm(HOST_CCREG, ccadj[i], 1);
3480     emit_far_call(call_gteStall);
3481     restore_regs(reglist);
3482 #else
3483     host_tempreg_acquire();
3484     emit_readword(&psxRegs.gteBusyCycle, rtmp);
3485     emit_addimm(rtmp, -ccadj[i], rtmp);
3486     emit_sub(rtmp, HOST_CCREG, HOST_TEMPREG);
3487     emit_cmpimm(HOST_TEMPREG, 44);
3488     emit_cmovb_reg(rtmp, HOST_CCREG);
3489     //emit_log_gte_stall(i, 0, reglist);
3490     host_tempreg_release();
3491 #endif
3492   }
3493   else if (stall > 0) {
3494     //emit_log_gte_stall(i, stall, reglist);
3495     emit_addimm(HOST_CCREG, stall, HOST_CCREG);
3496   }
3497
3498   // save gteBusyCycle, if needed
3499   if (gte_cycletab[op] == 0)
3500     return;
3501   other_gte_op_cycles = -1;
3502   for (j = i + 1; j < slen; j++) {
3503     if (cop2_is_stalling_op(j, &other_gte_op_cycles))
3504       break;
3505     if (dops[j].is_jump) {
3506       // check ds
3507       if (j + 1 < slen && cop2_is_stalling_op(j + 1, &other_gte_op_cycles))
3508         j++;
3509       break;
3510     }
3511   }
3512   if (other_gte_op_cycles >= 0)
3513     // will handle stall when assembling that op
3514     return;
3515   cycles_passed = ccadj[min(j, slen -1)] - ccadj[i];
3516   if (cycles_passed >= 44)
3517     return;
3518   assem_debug("; save gteBusyCycle\n");
3519   host_tempreg_acquire();
3520 #if 0
3521   emit_readword(&last_count, HOST_TEMPREG);
3522   emit_add(HOST_TEMPREG, HOST_CCREG, HOST_TEMPREG);
3523   emit_addimm(HOST_TEMPREG, ccadj[i], HOST_TEMPREG);
3524   emit_addimm(HOST_TEMPREG, gte_cycletab[op]), HOST_TEMPREG);
3525   emit_writeword(HOST_TEMPREG, &psxRegs.gteBusyCycle);
3526 #else
3527   emit_addimm(HOST_CCREG, ccadj[i] + gte_cycletab[op], HOST_TEMPREG);
3528   emit_writeword(HOST_TEMPREG, &psxRegs.gteBusyCycle);
3529 #endif
3530   host_tempreg_release();
3531 }
3532
3533 static int is_mflohi(int i)
3534 {
3535   return (dops[i].itype == MOV && (dops[i].rs1 == HIREG || dops[i].rs1 == LOREG));
3536 }
3537
3538 static int check_multdiv(int i, int *cycles)
3539 {
3540   if (dops[i].itype != MULTDIV)
3541     return 0;
3542   if (dops[i].opcode2 == 0x18 || dops[i].opcode2 == 0x19) // MULT(U)
3543     *cycles = 11; // approx from 7 11 14
3544   else
3545     *cycles = 37;
3546   return 1;
3547 }
3548
3549 static void multdiv_prepare_stall(int i, const struct regstat *i_regs, int ccadj_)
3550 {
3551   int j, found = 0, c = 0;
3552   if (HACK_ENABLED(NDHACK_NO_STALLS))
3553     return;
3554   if (get_reg(i_regs->regmap, CCREG) != HOST_CCREG) {
3555     // happens occasionally... cc evicted? Don't bother then
3556     return;
3557   }
3558   for (j = i + 1; j < slen; j++) {
3559     if (dops[j].bt)
3560       break;
3561     if ((found = is_mflohi(j)))
3562       break;
3563     if (dops[j].is_jump) {
3564       // check ds
3565       if (j + 1 < slen && (found = is_mflohi(j + 1)))
3566         j++;
3567       break;
3568     }
3569   }
3570   if (found)
3571     // handle all in multdiv_do_stall()
3572     return;
3573   check_multdiv(i, &c);
3574   assert(c > 0);
3575   assem_debug("; muldiv prepare stall %d\n", c);
3576   host_tempreg_acquire();
3577   emit_addimm(HOST_CCREG, ccadj_ + c, HOST_TEMPREG);
3578   emit_writeword(HOST_TEMPREG, &psxRegs.muldivBusyCycle);
3579   host_tempreg_release();
3580 }
3581
3582 static void multdiv_do_stall(int i, const struct regstat *i_regs)
3583 {
3584   int j, known_cycles = 0;
3585   u_int reglist = get_host_reglist(i_regs->regmap);
3586   int rtmp = get_reg(i_regs->regmap, -1);
3587   if (rtmp < 0)
3588     rtmp = reglist_find_free(reglist);
3589   if (HACK_ENABLED(NDHACK_NO_STALLS))
3590     return;
3591   if (get_reg(i_regs->regmap, CCREG) != HOST_CCREG || rtmp < 0) {
3592     // happens occasionally... cc evicted? Don't bother then
3593     //printf("no cc/rtmp %08x\n", start + i*4);
3594     return;
3595   }
3596   if (!dops[i].bt) {
3597     for (j = i - 1; j >= 0; j--) {
3598       if (dops[j].is_ds) break;
3599       if (check_multdiv(j, &known_cycles))
3600         break;
3601       if (is_mflohi(j))
3602         // already handled by this op
3603         return;
3604       if (dops[j].bt || (j > 0 && ccadj[j - 1] > ccadj[j]))
3605         break;
3606     }
3607     j = max(j, 0);
3608   }
3609   if (known_cycles > 0) {
3610     known_cycles -= ccadj[i] - ccadj[j];
3611     assem_debug("; muldiv stall resolved %d\n", known_cycles);
3612     if (known_cycles > 0)
3613       emit_addimm(HOST_CCREG, known_cycles, HOST_CCREG);
3614     return;
3615   }
3616   assem_debug("; muldiv stall unresolved\n");
3617   host_tempreg_acquire();
3618   emit_readword(&psxRegs.muldivBusyCycle, rtmp);
3619   emit_addimm(rtmp, -ccadj[i], rtmp);
3620   emit_sub(rtmp, HOST_CCREG, HOST_TEMPREG);
3621   emit_cmpimm(HOST_TEMPREG, 37);
3622   emit_cmovb_reg(rtmp, HOST_CCREG);
3623   //emit_log_gte_stall(i, 0, reglist);
3624   host_tempreg_release();
3625 }
3626
3627 static void cop2_get_dreg(u_int copr,signed char tl,signed char temp)
3628 {
3629   switch (copr) {
3630     case 1:
3631     case 3:
3632     case 5:
3633     case 8:
3634     case 9:
3635     case 10:
3636     case 11:
3637       emit_readword(&reg_cop2d[copr],tl);
3638       emit_signextend16(tl,tl);
3639       emit_writeword(tl,&reg_cop2d[copr]); // hmh
3640       break;
3641     case 7:
3642     case 16:
3643     case 17:
3644     case 18:
3645     case 19:
3646       emit_readword(&reg_cop2d[copr],tl);
3647       emit_andimm(tl,0xffff,tl);
3648       emit_writeword(tl,&reg_cop2d[copr]);
3649       break;
3650     case 15:
3651       emit_readword(&reg_cop2d[14],tl); // SXY2
3652       emit_writeword(tl,&reg_cop2d[copr]);
3653       break;
3654     case 28:
3655     case 29:
3656       c2op_mfc2_29_assemble(tl,temp);
3657       break;
3658     default:
3659       emit_readword(&reg_cop2d[copr],tl);
3660       break;
3661   }
3662 }
3663
3664 static void cop2_put_dreg(u_int copr,signed char sl,signed char temp)
3665 {
3666   switch (copr) {
3667     case 15:
3668       emit_readword(&reg_cop2d[13],temp);  // SXY1
3669       emit_writeword(sl,&reg_cop2d[copr]);
3670       emit_writeword(temp,&reg_cop2d[12]); // SXY0
3671       emit_readword(&reg_cop2d[14],temp);  // SXY2
3672       emit_writeword(sl,&reg_cop2d[14]);
3673       emit_writeword(temp,&reg_cop2d[13]); // SXY1
3674       break;
3675     case 28:
3676       emit_andimm(sl,0x001f,temp);
3677       emit_shlimm(temp,7,temp);
3678       emit_writeword(temp,&reg_cop2d[9]);
3679       emit_andimm(sl,0x03e0,temp);
3680       emit_shlimm(temp,2,temp);
3681       emit_writeword(temp,&reg_cop2d[10]);
3682       emit_andimm(sl,0x7c00,temp);
3683       emit_shrimm(temp,3,temp);
3684       emit_writeword(temp,&reg_cop2d[11]);
3685       emit_writeword(sl,&reg_cop2d[28]);
3686       break;
3687     case 30:
3688       emit_xorsar_imm(sl,sl,31,temp);
3689 #if defined(HAVE_ARMV5) || defined(__aarch64__)
3690       emit_clz(temp,temp);
3691 #else
3692       emit_movs(temp,HOST_TEMPREG);
3693       emit_movimm(0,temp);
3694       emit_jeq((int)out+4*4);
3695       emit_addpl_imm(temp,1,temp);
3696       emit_lslpls_imm(HOST_TEMPREG,1,HOST_TEMPREG);
3697       emit_jns((int)out-2*4);
3698 #endif
3699       emit_writeword(sl,&reg_cop2d[30]);
3700       emit_writeword(temp,&reg_cop2d[31]);
3701       break;
3702     case 31:
3703       break;
3704     default:
3705       emit_writeword(sl,&reg_cop2d[copr]);
3706       break;
3707   }
3708 }
3709
3710 static void c2ls_assemble(int i, const struct regstat *i_regs, int ccadj_)
3711 {
3712   int s,tl;
3713   int ar;
3714   int offset;
3715   int memtarget=0,c=0;
3716   void *jaddr2=NULL;
3717   enum stub_type type;
3718   int agr=AGEN1+(i&1);
3719   int offset_reg = -1;
3720   int fastio_reg_override = -1;
3721   u_int reglist=get_host_reglist(i_regs->regmap);
3722   u_int copr=(source[i]>>16)&0x1f;
3723   s=get_reg(i_regs->regmap,dops[i].rs1);
3724   tl=get_reg(i_regs->regmap,FTEMP);
3725   offset=imm[i];
3726   assert(dops[i].rs1>0);
3727   assert(tl>=0);
3728
3729   if(i_regs->regmap[HOST_CCREG]==CCREG)
3730     reglist&=~(1<<HOST_CCREG);
3731
3732   // get the address
3733   if (dops[i].opcode==0x3a) { // SWC2
3734     ar=get_reg(i_regs->regmap,agr);
3735     if(ar<0) ar=get_reg(i_regs->regmap,-1);
3736     reglist|=1<<ar;
3737   } else { // LWC2
3738     ar=tl;
3739   }
3740   if(s>=0) c=(i_regs->wasconst>>s)&1;
3741   memtarget=c&&(((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE);
3742   if (!offset&&!c&&s>=0) ar=s;
3743   assert(ar>=0);
3744
3745   cop2_do_stall_check(0, i, i_regs, reglist);
3746
3747   if (dops[i].opcode==0x3a) { // SWC2
3748     cop2_get_dreg(copr,tl,-1);
3749     type=STOREW_STUB;
3750   }
3751   else
3752     type=LOADW_STUB;
3753
3754   if(c&&!memtarget) {
3755     jaddr2=out;
3756     emit_jmp(0); // inline_readstub/inline_writestub?
3757   }
3758   else {
3759     if(!c) {
3760       jaddr2 = emit_fastpath_cmp_jump(i, i_regs, ar,
3761                 &offset_reg, &fastio_reg_override);
3762     }
3763     else if (ram_offset && memtarget) {
3764       offset_reg = get_ro_reg(i_regs, 0);
3765     }
3766     switch (dops[i].opcode) {
3767     case 0x32: { // LWC2
3768       int a = ar;
3769       if (fastio_reg_override >= 0)
3770         a = fastio_reg_override;
3771       do_load_word(a, tl, offset_reg);
3772       break;
3773     }
3774     case 0x3a: { // SWC2
3775       #ifdef DESTRUCTIVE_SHIFT
3776       if(!offset&&!c&&s>=0) emit_mov(s,ar);
3777       #endif
3778       int a = ar;
3779       if (fastio_reg_override >= 0)
3780         a = fastio_reg_override;
3781       do_store_word(a, 0, tl, offset_reg, 1);
3782       break;
3783     }
3784     default:
3785       assert(0);
3786     }
3787   }
3788   if (fastio_reg_override == HOST_TEMPREG || offset_reg == HOST_TEMPREG)
3789     host_tempreg_release();
3790   if(jaddr2)
3791     add_stub_r(type,jaddr2,out,i,ar,i_regs,ccadj_,reglist);
3792   if(dops[i].opcode==0x3a) // SWC2
3793   if(!(i_regs->waswritten&(1<<dops[i].rs1)) && !HACK_ENABLED(NDHACK_NO_SMC_CHECK)) {
3794 #if defined(HOST_IMM8)
3795     int ir=get_reg(i_regs->regmap,INVCP);
3796     assert(ir>=0);
3797     emit_cmpmem_indexedsr12_reg(ir,ar,1);
3798 #else
3799     emit_cmpmem_indexedsr12_imm(invalid_code,ar,1);
3800 #endif
3801     #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT)
3802     emit_callne(invalidate_addr_reg[ar]);
3803     #else
3804     void *jaddr3 = out;
3805     emit_jne(0);
3806     add_stub(INVCODE_STUB,jaddr3,out,reglist|(1<<HOST_CCREG),ar,0,0,0);
3807     #endif
3808   }
3809   if (dops[i].opcode==0x32) { // LWC2
3810     host_tempreg_acquire();
3811     cop2_put_dreg(copr,tl,HOST_TEMPREG);
3812     host_tempreg_release();
3813   }
3814 }
3815
3816 static void cop2_assemble(int i, const struct regstat *i_regs)
3817 {
3818   u_int copr = (source[i]>>11) & 0x1f;
3819   signed char temp = get_reg(i_regs->regmap, -1);
3820
3821   if (!HACK_ENABLED(NDHACK_NO_STALLS)) {
3822     u_int reglist = reglist_exclude(get_host_reglist(i_regs->regmap), temp, -1);
3823     if (dops[i].opcode2 == 0 || dops[i].opcode2 == 2) { // MFC2/CFC2
3824       signed char tl = get_reg(i_regs->regmap, dops[i].rt1);
3825       reglist = reglist_exclude(reglist, tl, -1);
3826     }
3827     cop2_do_stall_check(0, i, i_regs, reglist);
3828   }
3829   if (dops[i].opcode2==0) { // MFC2
3830     signed char tl=get_reg(i_regs->regmap,dops[i].rt1);
3831     if(tl>=0&&dops[i].rt1!=0)
3832       cop2_get_dreg(copr,tl,temp);
3833   }
3834   else if (dops[i].opcode2==4) { // MTC2
3835     signed char sl=get_reg(i_regs->regmap,dops[i].rs1);
3836     cop2_put_dreg(copr,sl,temp);
3837   }
3838   else if (dops[i].opcode2==2) // CFC2
3839   {
3840     signed char tl=get_reg(i_regs->regmap,dops[i].rt1);
3841     if(tl>=0&&dops[i].rt1!=0)
3842       emit_readword(&reg_cop2c[copr],tl);
3843   }
3844   else if (dops[i].opcode2==6) // CTC2
3845   {
3846     signed char sl=get_reg(i_regs->regmap,dops[i].rs1);
3847     switch(copr) {
3848       case 4:
3849       case 12:
3850       case 20:
3851       case 26:
3852       case 27:
3853       case 29:
3854       case 30:
3855         emit_signextend16(sl,temp);
3856         break;
3857       case 31:
3858         c2op_ctc2_31_assemble(sl,temp);
3859         break;
3860       default:
3861         temp=sl;
3862         break;
3863     }
3864     emit_writeword(temp,&reg_cop2c[copr]);
3865     assert(sl>=0);
3866   }
3867 }
3868
3869 static void do_unalignedwritestub(int n)
3870 {
3871   assem_debug("do_unalignedwritestub %x\n",start+stubs[n].a*4);
3872   literal_pool(256);
3873   set_jump_target(stubs[n].addr, out);
3874
3875   int i=stubs[n].a;
3876   struct regstat *i_regs=(struct regstat *)stubs[n].c;
3877   int addr=stubs[n].b;
3878   u_int reglist=stubs[n].e;
3879   signed char *i_regmap=i_regs->regmap;
3880   int temp2=get_reg(i_regmap,FTEMP);
3881   int rt;
3882   rt=get_reg(i_regmap,dops[i].rs2);
3883   assert(rt>=0);
3884   assert(addr>=0);
3885   assert(dops[i].opcode==0x2a||dops[i].opcode==0x2e); // SWL/SWR only implemented
3886   reglist|=(1<<addr);
3887   reglist&=~(1<<temp2);
3888
3889   // don't bother with it and call write handler
3890   save_regs(reglist);
3891   pass_args(addr,rt);
3892   int cc=get_reg(i_regmap,CCREG);
3893   if(cc<0)
3894     emit_loadreg(CCREG,2);
3895   emit_addimm(cc<0?2:cc,(int)stubs[n].d+1,2);
3896   emit_far_call((dops[i].opcode==0x2a?jump_handle_swl:jump_handle_swr));
3897   emit_addimm(0,-((int)stubs[n].d+1),cc<0?2:cc);
3898   if(cc<0)
3899     emit_storereg(CCREG,2);
3900   restore_regs(reglist);
3901   emit_jmp(stubs[n].retaddr); // return address
3902 }
3903
3904 #ifndef multdiv_assemble
3905 void multdiv_assemble(int i,struct regstat *i_regs)
3906 {
3907   printf("Need multdiv_assemble for this architecture.\n");
3908   abort();
3909 }
3910 #endif
3911
3912 static void mov_assemble(int i, const struct regstat *i_regs)
3913 {
3914   //if(dops[i].opcode2==0x10||dops[i].opcode2==0x12) { // MFHI/MFLO
3915   //if(dops[i].opcode2==0x11||dops[i].opcode2==0x13) { // MTHI/MTLO
3916   if(dops[i].rt1) {
3917     signed char sl,tl;
3918     tl=get_reg(i_regs->regmap,dops[i].rt1);
3919     //assert(tl>=0);
3920     if(tl>=0) {
3921       sl=get_reg(i_regs->regmap,dops[i].rs1);
3922       if(sl>=0) emit_mov(sl,tl);
3923       else emit_loadreg(dops[i].rs1,tl);
3924     }
3925   }
3926   if (dops[i].rs1 == HIREG || dops[i].rs1 == LOREG) // MFHI/MFLO
3927     multdiv_do_stall(i, i_regs);
3928 }
3929
3930 // call interpreter, exception handler, things that change pc/regs/cycles ...
3931 static void call_c_cpu_handler(int i, const struct regstat *i_regs, int ccadj_, u_int pc, void *func)
3932 {
3933   signed char ccreg=get_reg(i_regs->regmap,CCREG);
3934   assert(ccreg==HOST_CCREG);
3935   assert(!is_delayslot);
3936   (void)ccreg;
3937
3938   emit_movimm(pc,3); // Get PC
3939   emit_readword(&last_count,2);
3940   emit_writeword(3,&psxRegs.pc);
3941   emit_addimm(HOST_CCREG,ccadj_,HOST_CCREG);
3942   emit_add(2,HOST_CCREG,2);
3943   emit_writeword(2,&psxRegs.cycle);
3944   emit_far_call(func);
3945   emit_far_jump(jump_to_new_pc);
3946 }
3947
3948 static void syscall_assemble(int i, const struct regstat *i_regs, int ccadj_)
3949 {
3950   // 'break' tends to be littered around to catch things like
3951   // division by 0 and is almost never executed, so don't emit much code here
3952   void *func = (dops[i].opcode2 == 0x0C)
3953     ? (is_delayslot ? jump_syscall_ds : jump_syscall)
3954     : (is_delayslot ? jump_break_ds : jump_break);
3955   signed char ccreg = get_reg(i_regs->regmap, CCREG);
3956   assert(ccreg == HOST_CCREG);
3957   emit_movimm(start + i*4, 2); // pc
3958   emit_addimm(HOST_CCREG, ccadj_ + CLOCK_ADJUST(1), HOST_CCREG);
3959   emit_far_jump(func);
3960 }
3961
3962 static void hlecall_assemble(int i, const struct regstat *i_regs, int ccadj_)
3963 {
3964   void *hlefunc = psxNULL;
3965   uint32_t hleCode = source[i] & 0x03ffffff;
3966   if (hleCode < ARRAY_SIZE(psxHLEt))
3967     hlefunc = psxHLEt[hleCode];
3968
3969   call_c_cpu_handler(i, i_regs, ccadj_, start + i*4+4, hlefunc);
3970 }
3971
3972 static void intcall_assemble(int i, const struct regstat *i_regs, int ccadj_)
3973 {
3974   call_c_cpu_handler(i, i_regs, ccadj_, start + i*4, execI);
3975 }
3976
3977 static void speculate_mov(int rs,int rt)
3978 {
3979   if(rt!=0) {
3980     smrv_strong_next|=1<<rt;
3981     smrv[rt]=smrv[rs];
3982   }
3983 }
3984
3985 static void speculate_mov_weak(int rs,int rt)
3986 {
3987   if(rt!=0) {
3988     smrv_weak_next|=1<<rt;
3989     smrv[rt]=smrv[rs];
3990   }
3991 }
3992
3993 static void speculate_register_values(int i)
3994 {
3995   if(i==0) {
3996     memcpy(smrv,psxRegs.GPR.r,sizeof(smrv));
3997     // gp,sp are likely to stay the same throughout the block
3998     smrv_strong_next=(1<<28)|(1<<29)|(1<<30);
3999     smrv_weak_next=~smrv_strong_next;
4000     //printf(" llr %08x\n", smrv[4]);
4001   }
4002   smrv_strong=smrv_strong_next;
4003   smrv_weak=smrv_weak_next;
4004   switch(dops[i].itype) {
4005     case ALU:
4006       if     ((smrv_strong>>dops[i].rs1)&1) speculate_mov(dops[i].rs1,dops[i].rt1);
4007       else if((smrv_strong>>dops[i].rs2)&1) speculate_mov(dops[i].rs2,dops[i].rt1);
4008       else if((smrv_weak>>dops[i].rs1)&1) speculate_mov_weak(dops[i].rs1,dops[i].rt1);
4009       else if((smrv_weak>>dops[i].rs2)&1) speculate_mov_weak(dops[i].rs2,dops[i].rt1);
4010       else {
4011         smrv_strong_next&=~(1<<dops[i].rt1);
4012         smrv_weak_next&=~(1<<dops[i].rt1);
4013       }
4014       break;
4015     case SHIFTIMM:
4016       smrv_strong_next&=~(1<<dops[i].rt1);
4017       smrv_weak_next&=~(1<<dops[i].rt1);
4018       // fallthrough
4019     case IMM16:
4020       if(dops[i].rt1&&is_const(&regs[i],dops[i].rt1)) {
4021         int value,hr=get_reg(regs[i].regmap,dops[i].rt1);
4022         if(hr>=0) {
4023           if(get_final_value(hr,i,&value))
4024                smrv[dops[i].rt1]=value;
4025           else smrv[dops[i].rt1]=constmap[i][hr];
4026           smrv_strong_next|=1<<dops[i].rt1;
4027         }
4028       }
4029       else {
4030         if     ((smrv_strong>>dops[i].rs1)&1) speculate_mov(dops[i].rs1,dops[i].rt1);
4031         else if((smrv_weak>>dops[i].rs1)&1) speculate_mov_weak(dops[i].rs1,dops[i].rt1);
4032       }
4033       break;
4034     case LOAD:
4035       if(start<0x2000&&(dops[i].rt1==26||(smrv[dops[i].rt1]>>24)==0xa0)) {
4036         // special case for BIOS
4037         smrv[dops[i].rt1]=0xa0000000;
4038         smrv_strong_next|=1<<dops[i].rt1;
4039         break;
4040       }
4041       // fallthrough
4042     case SHIFT:
4043     case LOADLR:
4044     case MOV:
4045       smrv_strong_next&=~(1<<dops[i].rt1);
4046       smrv_weak_next&=~(1<<dops[i].rt1);
4047       break;
4048     case COP0:
4049     case COP2:
4050       if(dops[i].opcode2==0||dops[i].opcode2==2) { // MFC/CFC
4051         smrv_strong_next&=~(1<<dops[i].rt1);
4052         smrv_weak_next&=~(1<<dops[i].rt1);
4053       }
4054       break;
4055     case C2LS:
4056       if (dops[i].opcode==0x32) { // LWC2
4057         smrv_strong_next&=~(1<<dops[i].rt1);
4058         smrv_weak_next&=~(1<<dops[i].rt1);
4059       }
4060       break;
4061   }
4062 #if 0
4063   int r=4;
4064   printf("x %08x %08x %d %d c %08x %08x\n",smrv[r],start+i*4,
4065     ((smrv_strong>>r)&1),(smrv_weak>>r)&1,regs[i].isconst,regs[i].wasconst);
4066 #endif
4067 }
4068
4069 static void ujump_assemble(int i, const struct regstat *i_regs);
4070 static void rjump_assemble(int i, const struct regstat *i_regs);
4071 static void cjump_assemble(int i, const struct regstat *i_regs);
4072 static void sjump_assemble(int i, const struct regstat *i_regs);
4073 static void pagespan_assemble(int i, const struct regstat *i_regs);
4074
4075 static int assemble(int i, const struct regstat *i_regs, int ccadj_)
4076 {
4077   int ds = 0;
4078   switch (dops[i].itype) {
4079     case ALU:
4080       alu_assemble(i, i_regs);
4081       break;
4082     case IMM16:
4083       imm16_assemble(i, i_regs);
4084       break;
4085     case SHIFT:
4086       shift_assemble(i, i_regs);
4087       break;
4088     case SHIFTIMM:
4089       shiftimm_assemble(i, i_regs);
4090       break;
4091     case LOAD:
4092       load_assemble(i, i_regs, ccadj_);
4093       break;
4094     case LOADLR:
4095       loadlr_assemble(i, i_regs, ccadj_);
4096       break;
4097     case STORE:
4098       store_assemble(i, i_regs, ccadj_);
4099       break;
4100     case STORELR:
4101       storelr_assemble(i, i_regs, ccadj_);
4102       break;
4103     case COP0:
4104       cop0_assemble(i, i_regs, ccadj_);
4105       break;
4106     case COP1:
4107       cop1_assemble(i, i_regs);
4108       break;
4109     case C1LS:
4110       c1ls_assemble(i, i_regs);
4111       break;
4112     case COP2:
4113       cop2_assemble(i, i_regs);
4114       break;
4115     case C2LS:
4116       c2ls_assemble(i, i_regs, ccadj_);
4117       break;
4118     case C2OP:
4119       c2op_assemble(i, i_regs);
4120       break;
4121     case MULTDIV:
4122       multdiv_assemble(i, i_regs);
4123       multdiv_prepare_stall(i, i_regs, ccadj_);
4124       break;
4125     case MOV:
4126       mov_assemble(i, i_regs);
4127       break;
4128     case SYSCALL:
4129       syscall_assemble(i, i_regs, ccadj_);
4130       break;
4131     case HLECALL:
4132       hlecall_assemble(i, i_regs, ccadj_);
4133       break;
4134     case INTCALL:
4135       intcall_assemble(i, i_regs, ccadj_);
4136       break;
4137     case UJUMP:
4138       ujump_assemble(i, i_regs);
4139       ds = 1;
4140       break;
4141     case RJUMP:
4142       rjump_assemble(i, i_regs);
4143       ds = 1;
4144       break;
4145     case CJUMP:
4146       cjump_assemble(i, i_regs);
4147       ds = 1;
4148       break;
4149     case SJUMP:
4150       sjump_assemble(i, i_regs);
4151       ds = 1;
4152       break;
4153     case SPAN:
4154       pagespan_assemble(i, i_regs);
4155       break;
4156     case NOP:
4157     case OTHER:
4158     case NI:
4159       // not handled, just skip
4160       break;
4161     default:
4162       assert(0);
4163   }
4164   return ds;
4165 }
4166
4167 static void ds_assemble(int i, const struct regstat *i_regs)
4168 {
4169   speculate_register_values(i);
4170   is_delayslot = 1;
4171   switch (dops[i].itype) {
4172     case SYSCALL:
4173     case HLECALL:
4174     case INTCALL:
4175     case SPAN:
4176     case UJUMP:
4177     case RJUMP:
4178     case CJUMP:
4179     case SJUMP:
4180       SysPrintf("Jump in the delay slot.  This is probably a bug.\n");
4181       break;
4182     default:
4183       assemble(i, i_regs, ccadj[i]);
4184   }
4185   is_delayslot = 0;
4186 }
4187
4188 // Is the branch target a valid internal jump?
4189 static int internal_branch(int addr)
4190 {
4191   if(addr&1) return 0; // Indirect (register) jump
4192   if(addr>=start && addr<start+slen*4-4)
4193   {
4194     return 1;
4195   }
4196   return 0;
4197 }
4198
4199 static void wb_invalidate(signed char pre[],signed char entry[],uint64_t dirty,uint64_t u)
4200 {
4201   int hr;
4202   for(hr=0;hr<HOST_REGS;hr++) {
4203     if(hr!=EXCLUDE_REG) {
4204       if(pre[hr]!=entry[hr]) {
4205         if(pre[hr]>=0) {
4206           if((dirty>>hr)&1) {
4207             if(get_reg(entry,pre[hr])<0) {
4208               assert(pre[hr]<64);
4209               if(!((u>>pre[hr])&1))
4210                 emit_storereg(pre[hr],hr);
4211             }
4212           }
4213         }
4214       }
4215     }
4216   }
4217   // Move from one register to another (no writeback)
4218   for(hr=0;hr<HOST_REGS;hr++) {
4219     if(hr!=EXCLUDE_REG) {
4220       if(pre[hr]!=entry[hr]) {
4221         if(pre[hr]>=0&&(pre[hr]&63)<TEMPREG) {
4222           int nr;
4223           if((nr=get_reg(entry,pre[hr]))>=0) {
4224             emit_mov(hr,nr);
4225           }
4226         }
4227       }
4228     }
4229   }
4230 }
4231
4232 // Load the specified registers
4233 // This only loads the registers given as arguments because
4234 // we don't want to load things that will be overwritten
4235 static void load_regs(signed char entry[],signed char regmap[],int rs1,int rs2)
4236 {
4237   int hr;
4238   // Load 32-bit regs
4239   for(hr=0;hr<HOST_REGS;hr++) {
4240     if(hr!=EXCLUDE_REG&&regmap[hr]>=0) {
4241       if(entry[hr]!=regmap[hr]) {
4242         if(regmap[hr]==rs1||regmap[hr]==rs2)
4243         {
4244           if(regmap[hr]==0) {
4245             emit_zeroreg(hr);
4246           }
4247           else
4248           {
4249             emit_loadreg(regmap[hr],hr);
4250           }
4251         }
4252       }
4253     }
4254   }
4255 }
4256
4257 // Load registers prior to the start of a loop
4258 // so that they are not loaded within the loop
4259 static void loop_preload(signed char pre[],signed char entry[])
4260 {
4261   int hr;
4262   for(hr=0;hr<HOST_REGS;hr++) {
4263     if(hr!=EXCLUDE_REG) {
4264       if(pre[hr]!=entry[hr]) {
4265         if(entry[hr]>=0) {
4266           if(get_reg(pre,entry[hr])<0) {
4267             assem_debug("loop preload:\n");
4268             //printf("loop preload: %d\n",hr);
4269             if(entry[hr]==0) {
4270               emit_zeroreg(hr);
4271             }
4272             else if(entry[hr]<TEMPREG)
4273             {
4274               emit_loadreg(entry[hr],hr);
4275             }
4276             else if(entry[hr]-64<TEMPREG)
4277             {
4278               emit_loadreg(entry[hr],hr);
4279             }
4280           }
4281         }
4282       }
4283     }
4284   }
4285 }
4286
4287 // Generate address for load/store instruction
4288 // goes to AGEN for writes, FTEMP for LOADLR and cop1/2 loads
4289 void address_generation(int i, const struct regstat *i_regs, signed char entry[])
4290 {
4291   if (dops[i].is_load || dops[i].is_store) {
4292     int ra=-1;
4293     int agr=AGEN1+(i&1);
4294     if(dops[i].itype==LOAD) {
4295       ra=get_reg(i_regs->regmap,dops[i].rt1);
4296       if(ra<0) ra=get_reg(i_regs->regmap,-1);
4297       assert(ra>=0);
4298     }
4299     if(dops[i].itype==LOADLR) {
4300       ra=get_reg(i_regs->regmap,FTEMP);
4301     }
4302     if(dops[i].itype==STORE||dops[i].itype==STORELR) {
4303       ra=get_reg(i_regs->regmap,agr);
4304       if(ra<0) ra=get_reg(i_regs->regmap,-1);
4305     }
4306     if(dops[i].itype==C2LS) {
4307       if ((dops[i].opcode&0x3b)==0x31||(dops[i].opcode&0x3b)==0x32) // LWC1/LDC1/LWC2/LDC2
4308         ra=get_reg(i_regs->regmap,FTEMP);
4309       else { // SWC1/SDC1/SWC2/SDC2
4310         ra=get_reg(i_regs->regmap,agr);
4311         if(ra<0) ra=get_reg(i_regs->regmap,-1);
4312       }
4313     }
4314     int rs=get_reg(i_regs->regmap,dops[i].rs1);
4315     if(ra>=0) {
4316       int offset=imm[i];
4317       int c=(i_regs->wasconst>>rs)&1;
4318       if(dops[i].rs1==0) {
4319         // Using r0 as a base address
4320         if(!entry||entry[ra]!=agr) {
4321           if (dops[i].opcode==0x22||dops[i].opcode==0x26) {
4322             emit_movimm(offset&0xFFFFFFFC,ra); // LWL/LWR
4323           }else if (dops[i].opcode==0x1a||dops[i].opcode==0x1b) {
4324             emit_movimm(offset&0xFFFFFFF8,ra); // LDL/LDR
4325           }else{
4326             emit_movimm(offset,ra);
4327           }
4328         } // else did it in the previous cycle
4329       }
4330       else if(rs<0) {
4331         if(!entry||entry[ra]!=dops[i].rs1)
4332           emit_loadreg(dops[i].rs1,ra);
4333         //if(!entry||entry[ra]!=dops[i].rs1)
4334         //  printf("poor load scheduling!\n");
4335       }
4336       else if(c) {
4337         if(dops[i].rs1!=dops[i].rt1||dops[i].itype!=LOAD) {
4338           if(!entry||entry[ra]!=agr) {
4339             if (dops[i].opcode==0x22||dops[i].opcode==0x26) {
4340               emit_movimm((constmap[i][rs]+offset)&0xFFFFFFFC,ra); // LWL/LWR
4341             }else if (dops[i].opcode==0x1a||dops[i].opcode==0x1b) {
4342               emit_movimm((constmap[i][rs]+offset)&0xFFFFFFF8,ra); // LDL/LDR
4343             }else{
4344               emit_movimm(constmap[i][rs]+offset,ra);
4345               regs[i].loadedconst|=1<<ra;
4346             }
4347           } // else did it in the previous cycle
4348         } // else load_consts already did it
4349       }
4350       if(offset&&!c&&dops[i].rs1) {
4351         if(rs>=0) {
4352           emit_addimm(rs,offset,ra);
4353         }else{
4354           emit_addimm(ra,offset,ra);
4355         }
4356       }
4357     }
4358   }
4359   // Preload constants for next instruction
4360   if (dops[i+1].is_load || dops[i+1].is_store) {
4361     int agr,ra;
4362     // Actual address
4363     agr=AGEN1+((i+1)&1);
4364     ra=get_reg(i_regs->regmap,agr);
4365     if(ra>=0) {
4366       int rs=get_reg(regs[i+1].regmap,dops[i+1].rs1);
4367       int offset=imm[i+1];
4368       int c=(regs[i+1].wasconst>>rs)&1;
4369       if(c&&(dops[i+1].rs1!=dops[i+1].rt1||dops[i+1].itype!=LOAD)) {
4370         if (dops[i+1].opcode==0x22||dops[i+1].opcode==0x26) {
4371           emit_movimm((constmap[i+1][rs]+offset)&0xFFFFFFFC,ra); // LWL/LWR
4372         }else if (dops[i+1].opcode==0x1a||dops[i+1].opcode==0x1b) {
4373           emit_movimm((constmap[i+1][rs]+offset)&0xFFFFFFF8,ra); // LDL/LDR
4374         }else{
4375           emit_movimm(constmap[i+1][rs]+offset,ra);
4376           regs[i+1].loadedconst|=1<<ra;
4377         }
4378       }
4379       else if(dops[i+1].rs1==0) {
4380         // Using r0 as a base address
4381         if (dops[i+1].opcode==0x22||dops[i+1].opcode==0x26) {
4382           emit_movimm(offset&0xFFFFFFFC,ra); // LWL/LWR
4383         }else if (dops[i+1].opcode==0x1a||dops[i+1].opcode==0x1b) {
4384           emit_movimm(offset&0xFFFFFFF8,ra); // LDL/LDR
4385         }else{
4386           emit_movimm(offset,ra);
4387         }
4388       }
4389     }
4390   }
4391 }
4392
4393 static int get_final_value(int hr, int i, int *value)
4394 {
4395   int reg=regs[i].regmap[hr];
4396   while(i<slen-1) {
4397     if(regs[i+1].regmap[hr]!=reg) break;
4398     if(!((regs[i+1].isconst>>hr)&1)) break;
4399     if(dops[i+1].bt) break;
4400     i++;
4401   }
4402   if(i<slen-1) {
4403     if (dops[i].is_jump) {
4404       *value=constmap[i][hr];
4405       return 1;
4406     }
4407     if(!dops[i+1].bt) {
4408       if (dops[i+1].is_jump) {
4409         // Load in delay slot, out-of-order execution
4410         if(dops[i+2].itype==LOAD&&dops[i+2].rs1==reg&&dops[i+2].rt1==reg&&((regs[i+1].wasconst>>hr)&1))
4411         {
4412           // Precompute load address
4413           *value=constmap[i][hr]+imm[i+2];
4414           return 1;
4415         }
4416       }
4417       if(dops[i+1].itype==LOAD&&dops[i+1].rs1==reg&&dops[i+1].rt1==reg)
4418       {
4419         // Precompute load address
4420         *value=constmap[i][hr]+imm[i+1];
4421         //printf("c=%x imm=%lx\n",(long)constmap[i][hr],imm[i+1]);
4422         return 1;
4423       }
4424     }
4425   }
4426   *value=constmap[i][hr];
4427   //printf("c=%lx\n",(long)constmap[i][hr]);
4428   if(i==slen-1) return 1;
4429   assert(reg < 64);
4430   return !((unneeded_reg[i+1]>>reg)&1);
4431 }
4432
4433 // Load registers with known constants
4434 static void load_consts(signed char pre[],signed char regmap[],int i)
4435 {
4436   int hr,hr2;
4437   // propagate loaded constant flags
4438   if(i==0||dops[i].bt)
4439     regs[i].loadedconst=0;
4440   else {
4441     for(hr=0;hr<HOST_REGS;hr++) {
4442       if(hr!=EXCLUDE_REG&&regmap[hr]>=0&&((regs[i-1].isconst>>hr)&1)&&pre[hr]==regmap[hr]
4443          &&regmap[hr]==regs[i-1].regmap[hr]&&((regs[i-1].loadedconst>>hr)&1))
4444       {
4445         regs[i].loadedconst|=1<<hr;
4446       }
4447     }
4448   }
4449   // Load 32-bit regs
4450   for(hr=0;hr<HOST_REGS;hr++) {
4451     if(hr!=EXCLUDE_REG&&regmap[hr]>=0) {
4452       //if(entry[hr]!=regmap[hr]) {
4453       if(!((regs[i].loadedconst>>hr)&1)) {
4454         assert(regmap[hr]<64);
4455         if(((regs[i].isconst>>hr)&1)&&regmap[hr]>0) {
4456           int value,similar=0;
4457           if(get_final_value(hr,i,&value)) {
4458             // see if some other register has similar value
4459             for(hr2=0;hr2<HOST_REGS;hr2++) {
4460               if(hr2!=EXCLUDE_REG&&((regs[i].loadedconst>>hr2)&1)) {
4461                 if(is_similar_value(value,constmap[i][hr2])) {
4462                   similar=1;
4463                   break;
4464                 }
4465               }
4466             }
4467             if(similar) {
4468               int value2;
4469               if(get_final_value(hr2,i,&value2)) // is this needed?
4470                 emit_movimm_from(value2,hr2,value,hr);
4471               else
4472                 emit_movimm(value,hr);
4473             }
4474             else if(value==0) {
4475               emit_zeroreg(hr);
4476             }
4477             else {
4478               emit_movimm(value,hr);
4479             }
4480           }
4481           regs[i].loadedconst|=1<<hr;
4482         }
4483       }
4484     }
4485   }
4486 }
4487
4488 static void load_all_consts(const signed char regmap[], u_int dirty, int i)
4489 {
4490   int hr;
4491   // Load 32-bit regs
4492   for(hr=0;hr<HOST_REGS;hr++) {
4493     if(hr!=EXCLUDE_REG&&regmap[hr]>=0&&((dirty>>hr)&1)) {
4494       assert(regmap[hr] < 64);
4495       if(((regs[i].isconst>>hr)&1)&&regmap[hr]>0) {
4496         int value=constmap[i][hr];
4497         if(value==0) {
4498           emit_zeroreg(hr);
4499         }
4500         else {
4501           emit_movimm(value,hr);
4502         }
4503       }
4504     }
4505   }
4506 }
4507
4508 // Write out all dirty registers (except cycle count)
4509 static void wb_dirtys(const signed char i_regmap[], uint64_t i_dirty)
4510 {
4511   int hr;
4512   for(hr=0;hr<HOST_REGS;hr++) {
4513     if(hr!=EXCLUDE_REG) {
4514       if(i_regmap[hr]>0) {
4515         if(i_regmap[hr]!=CCREG) {
4516           if((i_dirty>>hr)&1) {
4517             assert(i_regmap[hr]<64);
4518             emit_storereg(i_regmap[hr],hr);
4519           }
4520         }
4521       }
4522     }
4523   }
4524 }
4525
4526 // Write out dirty registers that we need to reload (pair with load_needed_regs)
4527 // This writes the registers not written by store_regs_bt
4528 static void wb_needed_dirtys(const signed char i_regmap[], uint64_t i_dirty, int addr)
4529 {
4530   int hr;
4531   int t=(addr-start)>>2;
4532   for(hr=0;hr<HOST_REGS;hr++) {
4533     if(hr!=EXCLUDE_REG) {
4534       if(i_regmap[hr]>0) {
4535         if(i_regmap[hr]!=CCREG) {
4536           if(i_regmap[hr]==regs[t].regmap_entry[hr] && ((regs[t].dirty>>hr)&1)) {
4537             if((i_dirty>>hr)&1) {
4538               assert(i_regmap[hr]<64);
4539               emit_storereg(i_regmap[hr],hr);
4540             }
4541           }
4542         }
4543       }
4544     }
4545   }
4546 }
4547
4548 // Load all registers (except cycle count)
4549 static void load_all_regs(const signed char i_regmap[])
4550 {
4551   int hr;
4552   for(hr=0;hr<HOST_REGS;hr++) {
4553     if(hr!=EXCLUDE_REG) {
4554       if(i_regmap[hr]==0) {
4555         emit_zeroreg(hr);
4556       }
4557       else
4558       if(i_regmap[hr]>0 && (i_regmap[hr]&63)<TEMPREG && i_regmap[hr]!=CCREG)
4559       {
4560         emit_loadreg(i_regmap[hr],hr);
4561       }
4562     }
4563   }
4564 }
4565
4566 // Load all current registers also needed by next instruction
4567 static void load_needed_regs(const signed char i_regmap[], const signed char next_regmap[])
4568 {
4569   int hr;
4570   for(hr=0;hr<HOST_REGS;hr++) {
4571     if(hr!=EXCLUDE_REG) {
4572       if(get_reg(next_regmap,i_regmap[hr])>=0) {
4573         if(i_regmap[hr]==0) {
4574           emit_zeroreg(hr);
4575         }
4576         else
4577         if(i_regmap[hr]>0 && (i_regmap[hr]&63)<TEMPREG && i_regmap[hr]!=CCREG)
4578         {
4579           emit_loadreg(i_regmap[hr],hr);
4580         }
4581       }
4582     }
4583   }
4584 }
4585
4586 // Load all regs, storing cycle count if necessary
4587 static void load_regs_entry(int t)
4588 {
4589   int hr;
4590   if(dops[t].is_ds) emit_addimm(HOST_CCREG,CLOCK_ADJUST(1),HOST_CCREG);
4591   else if(ccadj[t]) emit_addimm(HOST_CCREG,-ccadj[t],HOST_CCREG);
4592   if(regs[t].regmap_entry[HOST_CCREG]!=CCREG) {
4593     emit_storereg(CCREG,HOST_CCREG);
4594   }
4595   // Load 32-bit regs
4596   for(hr=0;hr<HOST_REGS;hr++) {
4597     if(regs[t].regmap_entry[hr]>=0&&regs[t].regmap_entry[hr]<TEMPREG) {
4598       if(regs[t].regmap_entry[hr]==0) {
4599         emit_zeroreg(hr);
4600       }
4601       else if(regs[t].regmap_entry[hr]!=CCREG)
4602       {
4603         emit_loadreg(regs[t].regmap_entry[hr],hr);
4604       }
4605     }
4606   }
4607 }
4608
4609 // Store dirty registers prior to branch
4610 void store_regs_bt(signed char i_regmap[],uint64_t i_dirty,int addr)
4611 {
4612   if(internal_branch(addr))
4613   {
4614     int t=(addr-start)>>2;
4615     int hr;
4616     for(hr=0;hr<HOST_REGS;hr++) {
4617       if(hr!=EXCLUDE_REG) {
4618         if(i_regmap[hr]>0 && i_regmap[hr]!=CCREG) {
4619           if(i_regmap[hr]!=regs[t].regmap_entry[hr] || !((regs[t].dirty>>hr)&1)) {
4620             if((i_dirty>>hr)&1) {
4621               assert(i_regmap[hr]<64);
4622               if(!((unneeded_reg[t]>>i_regmap[hr])&1))
4623                 emit_storereg(i_regmap[hr],hr);
4624             }
4625           }
4626         }
4627       }
4628     }
4629   }
4630   else
4631   {
4632     // Branch out of this block, write out all dirty regs
4633     wb_dirtys(i_regmap,i_dirty);
4634   }
4635 }
4636
4637 // Load all needed registers for branch target
4638 static void load_regs_bt(signed char i_regmap[],uint64_t i_dirty,int addr)
4639 {
4640   //if(addr>=start && addr<(start+slen*4))
4641   if(internal_branch(addr))
4642   {
4643     int t=(addr-start)>>2;
4644     int hr;
4645     // Store the cycle count before loading something else
4646     if(i_regmap[HOST_CCREG]!=CCREG) {
4647       assert(i_regmap[HOST_CCREG]==-1);
4648     }
4649     if(regs[t].regmap_entry[HOST_CCREG]!=CCREG) {
4650       emit_storereg(CCREG,HOST_CCREG);
4651     }
4652     // Load 32-bit regs
4653     for(hr=0;hr<HOST_REGS;hr++) {
4654       if(hr!=EXCLUDE_REG&&regs[t].regmap_entry[hr]>=0&&regs[t].regmap_entry[hr]<TEMPREG) {
4655         if(i_regmap[hr]!=regs[t].regmap_entry[hr]) {
4656           if(regs[t].regmap_entry[hr]==0) {
4657             emit_zeroreg(hr);
4658           }
4659           else if(regs[t].regmap_entry[hr]!=CCREG)
4660           {
4661             emit_loadreg(regs[t].regmap_entry[hr],hr);
4662           }
4663         }
4664       }
4665     }
4666   }
4667 }
4668
4669 static int match_bt(signed char i_regmap[],uint64_t i_dirty,int addr)
4670 {
4671   if(addr>=start && addr<start+slen*4-4)
4672   {
4673     int t=(addr-start)>>2;
4674     int hr;
4675     if(regs[t].regmap_entry[HOST_CCREG]!=CCREG) return 0;
4676     for(hr=0;hr<HOST_REGS;hr++)
4677     {
4678       if(hr!=EXCLUDE_REG)
4679       {
4680         if(i_regmap[hr]!=regs[t].regmap_entry[hr])
4681         {
4682           if(regs[t].regmap_entry[hr]>=0&&(regs[t].regmap_entry[hr]|64)<TEMPREG+64)
4683           {
4684             return 0;
4685           }
4686           else
4687           if((i_dirty>>hr)&1)
4688           {
4689             if(i_regmap[hr]<TEMPREG)
4690             {
4691               if(!((unneeded_reg[t]>>i_regmap[hr])&1))
4692                 return 0;
4693             }
4694             else if(i_regmap[hr]>=64&&i_regmap[hr]<TEMPREG+64)
4695             {
4696               assert(0);
4697             }
4698           }
4699         }
4700         else // Same register but is it 32-bit or dirty?
4701         if(i_regmap[hr]>=0)
4702         {
4703           if(!((regs[t].dirty>>hr)&1))
4704           {
4705             if((i_dirty>>hr)&1)
4706             {
4707               if(!((unneeded_reg[t]>>i_regmap[hr])&1))
4708               {
4709                 //printf("%x: dirty no match\n",addr);
4710                 return 0;
4711               }
4712             }
4713           }
4714         }
4715       }
4716     }
4717     // Delay slots are not valid branch targets
4718     //if(t>0&&(dops[t-1].is_jump) return 0;
4719     // Delay slots require additional processing, so do not match
4720     if(dops[t].is_ds) return 0;
4721   }
4722   else
4723   {
4724     int hr;
4725     for(hr=0;hr<HOST_REGS;hr++)
4726     {
4727       if(hr!=EXCLUDE_REG)
4728       {
4729         if(i_regmap[hr]>=0)
4730         {
4731           if(hr!=HOST_CCREG||i_regmap[hr]!=CCREG)
4732           {
4733             if((i_dirty>>hr)&1)
4734             {
4735               return 0;
4736             }
4737           }
4738         }
4739       }
4740     }
4741   }
4742   return 1;
4743 }
4744
4745 #ifdef DRC_DBG
4746 static void drc_dbg_emit_do_cmp(int i, int ccadj_)
4747 {
4748   extern void do_insn_cmp();
4749   //extern int cycle;
4750   u_int hr, reglist = get_host_reglist(regs[i].regmap);
4751
4752   assem_debug("//do_insn_cmp %08x\n", start+i*4);
4753   save_regs(reglist);
4754   // write out changed consts to match the interpreter
4755   if (i > 0 && !dops[i].bt) {
4756     for (hr = 0; hr < HOST_REGS; hr++) {
4757       int reg = regs[i].regmap_entry[hr]; // regs[i-1].regmap[hr];
4758       if (hr == EXCLUDE_REG || reg < 0)
4759         continue;
4760       if (!((regs[i-1].isconst >> hr) & 1))
4761         continue;
4762       if (i > 1 && reg == regs[i-2].regmap[hr] && constmap[i-1][hr] == constmap[i-2][hr])
4763         continue;
4764       emit_movimm(constmap[i-1][hr],0);
4765       emit_storereg(reg, 0);
4766     }
4767   }
4768   emit_movimm(start+i*4,0);
4769   emit_writeword(0,&pcaddr);
4770   int cc = get_reg(regs[i].regmap_entry, CCREG);
4771   if (cc < 0)
4772     emit_loadreg(CCREG, cc = 0);
4773   emit_addimm(cc, ccadj_, 0);
4774   emit_writeword(0, &psxRegs.cycle);
4775   emit_far_call(do_insn_cmp);
4776   //emit_readword(&cycle,0);
4777   //emit_addimm(0,2,0);
4778   //emit_writeword(0,&cycle);
4779   (void)get_reg2;
4780   restore_regs(reglist);
4781   assem_debug("\\\\do_insn_cmp\n");
4782 }
4783 #else
4784 #define drc_dbg_emit_do_cmp(x,y)
4785 #endif
4786
4787 // Used when a branch jumps into the delay slot of another branch
4788 static void ds_assemble_entry(int i)
4789 {
4790   int t = (ba[i] - start) >> 2;
4791   int ccadj_ = -CLOCK_ADJUST(1);
4792   if (!instr_addr[t])
4793     instr_addr[t] = out;
4794   assem_debug("Assemble delay slot at %x\n",ba[i]);
4795   assem_debug("<->\n");
4796   drc_dbg_emit_do_cmp(t, ccadj_);
4797   if(regs[t].regmap_entry[HOST_CCREG]==CCREG&&regs[t].regmap[HOST_CCREG]!=CCREG)
4798     wb_register(CCREG,regs[t].regmap_entry,regs[t].wasdirty);
4799   load_regs(regs[t].regmap_entry,regs[t].regmap,dops[t].rs1,dops[t].rs2);
4800   address_generation(t,&regs[t],regs[t].regmap_entry);
4801   if (ram_offset && (dops[t].is_load || dops[t].is_store))
4802     load_regs(regs[t].regmap_entry,regs[t].regmap,ROREG,ROREG);
4803   if (dops[t].is_store)
4804     load_regs(regs[t].regmap_entry,regs[t].regmap,INVCP,INVCP);
4805   is_delayslot=0;
4806   switch (dops[t].itype) {
4807     case SYSCALL:
4808     case HLECALL:
4809     case INTCALL:
4810     case SPAN:
4811     case UJUMP:
4812     case RJUMP:
4813     case CJUMP:
4814     case SJUMP:
4815       SysPrintf("Jump in the delay slot.  This is probably a bug.\n");
4816       break;
4817     default:
4818       assemble(t, &regs[t], ccadj_);
4819   }
4820   store_regs_bt(regs[t].regmap,regs[t].dirty,ba[i]+4);
4821   load_regs_bt(regs[t].regmap,regs[t].dirty,ba[i]+4);
4822   if(internal_branch(ba[i]+4))
4823     assem_debug("branch: internal\n");
4824   else
4825     assem_debug("branch: external\n");
4826   assert(internal_branch(ba[i]+4));
4827   add_to_linker(out,ba[i]+4,internal_branch(ba[i]+4));
4828   emit_jmp(0);
4829 }
4830
4831 static void emit_extjump(void *addr, u_int target)
4832 {
4833   emit_extjump2(addr, target, dyna_linker);
4834 }
4835
4836 static void emit_extjump_ds(void *addr, u_int target)
4837 {
4838   emit_extjump2(addr, target, dyna_linker_ds);
4839 }
4840
4841 // Load 2 immediates optimizing for small code size
4842 static void emit_mov2imm_compact(int imm1,u_int rt1,int imm2,u_int rt2)
4843 {
4844   emit_movimm(imm1,rt1);
4845   emit_movimm_from(imm1,rt1,imm2,rt2);
4846 }
4847
4848 static void do_cc(int i, const signed char i_regmap[], int *adj,
4849   int addr, int taken, int invert)
4850 {
4851   int count, count_plus2;
4852   void *jaddr;
4853   void *idle=NULL;
4854   int t=0;
4855   if(dops[i].itype==RJUMP)
4856   {
4857     *adj=0;
4858   }
4859   //if(ba[i]>=start && ba[i]<(start+slen*4))
4860   if(internal_branch(ba[i]))
4861   {
4862     t=(ba[i]-start)>>2;
4863     if(dops[t].is_ds) *adj=-CLOCK_ADJUST(1); // Branch into delay slot adds an extra cycle
4864     else *adj=ccadj[t];
4865   }
4866   else
4867   {
4868     *adj=0;
4869   }
4870   count = ccadj[i];
4871   count_plus2 = count + CLOCK_ADJUST(2);
4872   if(taken==TAKEN && i==(ba[i]-start)>>2 && source[i+1]==0) {
4873     // Idle loop
4874     if(count&1) emit_addimm_and_set_flags(2*(count+2),HOST_CCREG);
4875     idle=out;
4876     //emit_subfrommem(&idlecount,HOST_CCREG); // Count idle cycles
4877     emit_andimm(HOST_CCREG,3,HOST_CCREG);
4878     jaddr=out;
4879     emit_jmp(0);
4880   }
4881   else if(*adj==0||invert) {
4882     int cycles = count_plus2;
4883     // faster loop HACK
4884 #if 0
4885     if (t&&*adj) {
4886       int rel=t-i;
4887       if(-NO_CYCLE_PENALTY_THR<rel&&rel<0)
4888         cycles=*adj+count+2-*adj;
4889     }
4890 #endif
4891     emit_addimm_and_set_flags(cycles, HOST_CCREG);
4892     jaddr = out;
4893     emit_jns(0);
4894   }
4895   else
4896   {
4897     emit_cmpimm(HOST_CCREG, -count_plus2);
4898     jaddr = out;
4899     emit_jns(0);
4900   }
4901   add_stub(CC_STUB,jaddr,idle?idle:out,(*adj==0||invert||idle)?0:count_plus2,i,addr,taken,0);
4902 }
4903
4904 static void do_ccstub(int n)
4905 {
4906   literal_pool(256);
4907   assem_debug("do_ccstub %x\n",start+(u_int)stubs[n].b*4);
4908   set_jump_target(stubs[n].addr, out);
4909   int i=stubs[n].b;
4910   if(stubs[n].d==NULLDS) {
4911     // Delay slot instruction is nullified ("likely" branch)
4912     wb_dirtys(regs[i].regmap,regs[i].dirty);
4913   }
4914   else if(stubs[n].d!=TAKEN) {
4915     wb_dirtys(branch_regs[i].regmap,branch_regs[i].dirty);
4916   }
4917   else {
4918     if(internal_branch(ba[i]))
4919       wb_needed_dirtys(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
4920   }
4921   if(stubs[n].c!=-1)
4922   {
4923     // Save PC as return address
4924     emit_movimm(stubs[n].c,EAX);
4925     emit_writeword(EAX,&pcaddr);
4926   }
4927   else
4928   {
4929     // Return address depends on which way the branch goes
4930     if(dops[i].itype==CJUMP||dops[i].itype==SJUMP)
4931     {
4932       int s1l=get_reg(branch_regs[i].regmap,dops[i].rs1);
4933       int s2l=get_reg(branch_regs[i].regmap,dops[i].rs2);
4934       if(dops[i].rs1==0)
4935       {
4936         s1l=s2l;
4937         s2l=-1;
4938       }
4939       else if(dops[i].rs2==0)
4940       {
4941         s2l=-1;
4942       }
4943       assert(s1l>=0);
4944       #ifdef DESTRUCTIVE_WRITEBACK
4945       if(dops[i].rs1) {
4946         if((branch_regs[i].dirty>>s1l)&&1)
4947           emit_loadreg(dops[i].rs1,s1l);
4948       }
4949       else {
4950         if((branch_regs[i].dirty>>s1l)&1)
4951           emit_loadreg(dops[i].rs2,s1l);
4952       }
4953       if(s2l>=0)
4954         if((branch_regs[i].dirty>>s2l)&1)
4955           emit_loadreg(dops[i].rs2,s2l);
4956       #endif
4957       int hr=0;
4958       int addr=-1,alt=-1,ntaddr=-1;
4959       while(hr<HOST_REGS)
4960       {
4961         if(hr!=EXCLUDE_REG && hr!=HOST_CCREG &&
4962            (branch_regs[i].regmap[hr]&63)!=dops[i].rs1 &&
4963            (branch_regs[i].regmap[hr]&63)!=dops[i].rs2 )
4964         {
4965           addr=hr++;break;
4966         }
4967         hr++;
4968       }
4969       while(hr<HOST_REGS)
4970       {
4971         if(hr!=EXCLUDE_REG && hr!=HOST_CCREG &&
4972            (branch_regs[i].regmap[hr]&63)!=dops[i].rs1 &&
4973            (branch_regs[i].regmap[hr]&63)!=dops[i].rs2 )
4974         {
4975           alt=hr++;break;
4976         }
4977         hr++;
4978       }
4979       if((dops[i].opcode&0x2E)==6) // BLEZ/BGTZ needs another register
4980       {
4981         while(hr<HOST_REGS)
4982         {
4983           if(hr!=EXCLUDE_REG && hr!=HOST_CCREG &&
4984              (branch_regs[i].regmap[hr]&63)!=dops[i].rs1 &&
4985              (branch_regs[i].regmap[hr]&63)!=dops[i].rs2 )
4986           {
4987             ntaddr=hr;break;
4988           }
4989           hr++;
4990         }
4991         assert(hr<HOST_REGS);
4992       }
4993       if((dops[i].opcode&0x2f)==4) // BEQ
4994       {
4995         #ifdef HAVE_CMOV_IMM
4996         if(s2l>=0) emit_cmp(s1l,s2l);
4997         else emit_test(s1l,s1l);
4998         emit_cmov2imm_e_ne_compact(ba[i],start+i*4+8,addr);
4999         #else
5000         emit_mov2imm_compact(ba[i],addr,start+i*4+8,alt);
5001         if(s2l>=0) emit_cmp(s1l,s2l);
5002         else emit_test(s1l,s1l);
5003         emit_cmovne_reg(alt,addr);
5004         #endif
5005       }
5006       if((dops[i].opcode&0x2f)==5) // BNE
5007       {
5008         #ifdef HAVE_CMOV_IMM
5009         if(s2l>=0) emit_cmp(s1l,s2l);
5010         else emit_test(s1l,s1l);
5011         emit_cmov2imm_e_ne_compact(start+i*4+8,ba[i],addr);
5012         #else
5013         emit_mov2imm_compact(start+i*4+8,addr,ba[i],alt);
5014         if(s2l>=0) emit_cmp(s1l,s2l);
5015         else emit_test(s1l,s1l);
5016         emit_cmovne_reg(alt,addr);
5017         #endif
5018       }
5019       if((dops[i].opcode&0x2f)==6) // BLEZ
5020       {
5021         //emit_movimm(ba[i],alt);
5022         //emit_movimm(start+i*4+8,addr);
5023         emit_mov2imm_compact(ba[i],alt,start+i*4+8,addr);
5024         emit_cmpimm(s1l,1);
5025         emit_cmovl_reg(alt,addr);
5026       }
5027       if((dops[i].opcode&0x2f)==7) // BGTZ
5028       {
5029         //emit_movimm(ba[i],addr);
5030         //emit_movimm(start+i*4+8,ntaddr);
5031         emit_mov2imm_compact(ba[i],addr,start+i*4+8,ntaddr);
5032         emit_cmpimm(s1l,1);
5033         emit_cmovl_reg(ntaddr,addr);
5034       }
5035       if((dops[i].opcode==1)&&(dops[i].opcode2&0x2D)==0) // BLTZ
5036       {
5037         //emit_movimm(ba[i],alt);
5038         //emit_movimm(start+i*4+8,addr);
5039         emit_mov2imm_compact(ba[i],alt,start+i*4+8,addr);
5040         emit_test(s1l,s1l);
5041         emit_cmovs_reg(alt,addr);
5042       }
5043       if((dops[i].opcode==1)&&(dops[i].opcode2&0x2D)==1) // BGEZ
5044       {
5045         //emit_movimm(ba[i],addr);
5046         //emit_movimm(start+i*4+8,alt);
5047         emit_mov2imm_compact(ba[i],addr,start+i*4+8,alt);
5048         emit_test(s1l,s1l);
5049         emit_cmovs_reg(alt,addr);
5050       }
5051       if(dops[i].opcode==0x11 && dops[i].opcode2==0x08 ) {
5052         if(source[i]&0x10000) // BC1T
5053         {
5054           //emit_movimm(ba[i],alt);
5055           //emit_movimm(start+i*4+8,addr);
5056           emit_mov2imm_compact(ba[i],alt,start+i*4+8,addr);
5057           emit_testimm(s1l,0x800000);
5058           emit_cmovne_reg(alt,addr);
5059         }
5060         else // BC1F
5061         {
5062           //emit_movimm(ba[i],addr);
5063           //emit_movimm(start+i*4+8,alt);
5064           emit_mov2imm_compact(ba[i],addr,start+i*4+8,alt);
5065           emit_testimm(s1l,0x800000);
5066           emit_cmovne_reg(alt,addr);
5067         }
5068       }
5069       emit_writeword(addr,&pcaddr);
5070     }
5071     else
5072     if(dops[i].itype==RJUMP)
5073     {
5074       int r=get_reg(branch_regs[i].regmap,dops[i].rs1);
5075       if (ds_writes_rjump_rs(i)) {
5076         r=get_reg(branch_regs[i].regmap,RTEMP);
5077       }
5078       emit_writeword(r,&pcaddr);
5079     }
5080     else {SysPrintf("Unknown branch type in do_ccstub\n");abort();}
5081   }
5082   // Update cycle count
5083   assert(branch_regs[i].regmap[HOST_CCREG]==CCREG||branch_regs[i].regmap[HOST_CCREG]==-1);
5084   if(stubs[n].a) emit_addimm(HOST_CCREG,(int)stubs[n].a,HOST_CCREG);
5085   emit_far_call(cc_interrupt);
5086   if(stubs[n].a) emit_addimm(HOST_CCREG,-(int)stubs[n].a,HOST_CCREG);
5087   if(stubs[n].d==TAKEN) {
5088     if(internal_branch(ba[i]))
5089       load_needed_regs(branch_regs[i].regmap,regs[(ba[i]-start)>>2].regmap_entry);
5090     else if(dops[i].itype==RJUMP) {
5091       if(get_reg(branch_regs[i].regmap,RTEMP)>=0)
5092         emit_readword(&pcaddr,get_reg(branch_regs[i].regmap,RTEMP));
5093       else
5094         emit_loadreg(dops[i].rs1,get_reg(branch_regs[i].regmap,dops[i].rs1));
5095     }
5096   }else if(stubs[n].d==NOTTAKEN) {
5097     if(i<slen-2) load_needed_regs(branch_regs[i].regmap,regmap_pre[i+2]);
5098     else load_all_regs(branch_regs[i].regmap);
5099   }else if(stubs[n].d==NULLDS) {
5100     // Delay slot instruction is nullified ("likely" branch)
5101     if(i<slen-2) load_needed_regs(regs[i].regmap,regmap_pre[i+2]);
5102     else load_all_regs(regs[i].regmap);
5103   }else{
5104     load_all_regs(branch_regs[i].regmap);
5105   }
5106   if (stubs[n].retaddr)
5107     emit_jmp(stubs[n].retaddr);
5108   else
5109     do_jump_vaddr(stubs[n].e);
5110 }
5111
5112 static void add_to_linker(void *addr, u_int target, int ext)
5113 {
5114   assert(linkcount < ARRAY_SIZE(link_addr));
5115   link_addr[linkcount].addr = addr;
5116   link_addr[linkcount].target = target;
5117   link_addr[linkcount].ext = ext;
5118   linkcount++;
5119 }
5120
5121 static void ujump_assemble_write_ra(int i)
5122 {
5123   int rt;
5124   unsigned int return_address;
5125   rt=get_reg(branch_regs[i].regmap,31);
5126   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]);
5127   //assert(rt>=0);
5128   return_address=start+i*4+8;
5129   if(rt>=0) {
5130     #ifdef USE_MINI_HT
5131     if(internal_branch(return_address)&&dops[i+1].rt1!=31) {
5132       int temp=-1; // note: must be ds-safe
5133       #ifdef HOST_TEMPREG
5134       temp=HOST_TEMPREG;
5135       #endif
5136       if(temp>=0) do_miniht_insert(return_address,rt,temp);
5137       else emit_movimm(return_address,rt);
5138     }
5139     else
5140     #endif
5141     {
5142       #ifdef REG_PREFETCH
5143       if(temp>=0)
5144       {
5145         if(i_regmap[temp]!=PTEMP) emit_movimm((uintptr_t)hash_table_get(return_address),temp);
5146       }
5147       #endif
5148       emit_movimm(return_address,rt); // PC into link register
5149       #ifdef IMM_PREFETCH
5150       emit_prefetch(hash_table_get(return_address));
5151       #endif
5152     }
5153   }
5154 }
5155
5156 static void ujump_assemble(int i, const struct regstat *i_regs)
5157 {
5158   int ra_done=0;
5159   if(i==(ba[i]-start)>>2) assem_debug("idle loop\n");
5160   address_generation(i+1,i_regs,regs[i].regmap_entry);
5161   #ifdef REG_PREFETCH
5162   int temp=get_reg(branch_regs[i].regmap,PTEMP);
5163   if(dops[i].rt1==31&&temp>=0)
5164   {
5165     signed char *i_regmap=i_regs->regmap;
5166     int return_address=start+i*4+8;
5167     if(get_reg(branch_regs[i].regmap,31)>0)
5168     if(i_regmap[temp]==PTEMP) emit_movimm((uintptr_t)hash_table_get(return_address),temp);
5169   }
5170   #endif
5171   if(dops[i].rt1==31&&(dops[i].rt1==dops[i+1].rs1||dops[i].rt1==dops[i+1].rs2)) {
5172     ujump_assemble_write_ra(i); // writeback ra for DS
5173     ra_done=1;
5174   }
5175   ds_assemble(i+1,i_regs);
5176   uint64_t bc_unneeded=branch_regs[i].u;
5177   bc_unneeded|=1|(1LL<<dops[i].rt1);
5178   wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,bc_unneeded);
5179   load_regs(regs[i].regmap,branch_regs[i].regmap,CCREG,CCREG);
5180   if(!ra_done&&dops[i].rt1==31)
5181     ujump_assemble_write_ra(i);
5182   int cc,adj;
5183   cc=get_reg(branch_regs[i].regmap,CCREG);
5184   assert(cc==HOST_CCREG);
5185   store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5186   #ifdef REG_PREFETCH
5187   if(dops[i].rt1==31&&temp>=0) emit_prefetchreg(temp);
5188   #endif
5189   do_cc(i,branch_regs[i].regmap,&adj,ba[i],TAKEN,0);
5190   if(adj) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5191   load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5192   if(internal_branch(ba[i]))
5193     assem_debug("branch: internal\n");
5194   else
5195     assem_debug("branch: external\n");
5196   if (internal_branch(ba[i]) && dops[(ba[i]-start)>>2].is_ds) {
5197     ds_assemble_entry(i);
5198   }
5199   else {
5200     add_to_linker(out,ba[i],internal_branch(ba[i]));
5201     emit_jmp(0);
5202   }
5203 }
5204
5205 static void rjump_assemble_write_ra(int i)
5206 {
5207   int rt,return_address;
5208   assert(dops[i+1].rt1!=dops[i].rt1);
5209   assert(dops[i+1].rt2!=dops[i].rt1);
5210   rt=get_reg(branch_regs[i].regmap,dops[i].rt1);
5211   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]);
5212   assert(rt>=0);
5213   return_address=start+i*4+8;
5214   #ifdef REG_PREFETCH
5215   if(temp>=0)
5216   {
5217     if(i_regmap[temp]!=PTEMP) emit_movimm((uintptr_t)hash_table_get(return_address),temp);
5218   }
5219   #endif
5220   emit_movimm(return_address,rt); // PC into link register
5221   #ifdef IMM_PREFETCH
5222   emit_prefetch(hash_table_get(return_address));
5223   #endif
5224 }
5225
5226 static void rjump_assemble(int i, const struct regstat *i_regs)
5227 {
5228   int temp;
5229   int rs,cc;
5230   int ra_done=0;
5231   rs=get_reg(branch_regs[i].regmap,dops[i].rs1);
5232   assert(rs>=0);
5233   if (ds_writes_rjump_rs(i)) {
5234     // Delay slot abuse, make a copy of the branch address register
5235     temp=get_reg(branch_regs[i].regmap,RTEMP);
5236     assert(temp>=0);
5237     assert(regs[i].regmap[temp]==RTEMP);
5238     emit_mov(rs,temp);
5239     rs=temp;
5240   }
5241   address_generation(i+1,i_regs,regs[i].regmap_entry);
5242   #ifdef REG_PREFETCH
5243   if(dops[i].rt1==31)
5244   {
5245     if((temp=get_reg(branch_regs[i].regmap,PTEMP))>=0) {
5246       signed char *i_regmap=i_regs->regmap;
5247       int return_address=start+i*4+8;
5248       if(i_regmap[temp]==PTEMP) emit_movimm((uintptr_t)hash_table_get(return_address),temp);
5249     }
5250   }
5251   #endif
5252   #ifdef USE_MINI_HT
5253   if(dops[i].rs1==31) {
5254     int rh=get_reg(regs[i].regmap,RHASH);
5255     if(rh>=0) do_preload_rhash(rh);
5256   }
5257   #endif
5258   if(dops[i].rt1!=0&&(dops[i].rt1==dops[i+1].rs1||dops[i].rt1==dops[i+1].rs2)) {
5259     rjump_assemble_write_ra(i);
5260     ra_done=1;
5261   }
5262   ds_assemble(i+1,i_regs);
5263   uint64_t bc_unneeded=branch_regs[i].u;
5264   bc_unneeded|=1|(1LL<<dops[i].rt1);
5265   bc_unneeded&=~(1LL<<dops[i].rs1);
5266   wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,bc_unneeded);
5267   load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i].rs1,CCREG);
5268   if(!ra_done&&dops[i].rt1!=0)
5269     rjump_assemble_write_ra(i);
5270   cc=get_reg(branch_regs[i].regmap,CCREG);
5271   assert(cc==HOST_CCREG);
5272   (void)cc;
5273   #ifdef USE_MINI_HT
5274   int rh=get_reg(branch_regs[i].regmap,RHASH);
5275   int ht=get_reg(branch_regs[i].regmap,RHTBL);
5276   if(dops[i].rs1==31) {
5277     if(regs[i].regmap[rh]!=RHASH) do_preload_rhash(rh);
5278     do_preload_rhtbl(ht);
5279     do_rhash(rs,rh);
5280   }
5281   #endif
5282   store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,-1);
5283   #ifdef DESTRUCTIVE_WRITEBACK
5284   if((branch_regs[i].dirty>>rs)&1) {
5285     if(dops[i].rs1!=dops[i+1].rt1&&dops[i].rs1!=dops[i+1].rt2) {
5286       emit_loadreg(dops[i].rs1,rs);
5287     }
5288   }
5289   #endif
5290   #ifdef REG_PREFETCH
5291   if(dops[i].rt1==31&&temp>=0) emit_prefetchreg(temp);
5292   #endif
5293   #ifdef USE_MINI_HT
5294   if(dops[i].rs1==31) {
5295     do_miniht_load(ht,rh);
5296   }
5297   #endif
5298   //do_cc(i,branch_regs[i].regmap,&adj,-1,TAKEN);
5299   //if(adj) emit_addimm(cc,2*(ccadj[i]+2-adj),cc); // ??? - Shouldn't happen
5300   //assert(adj==0);
5301   emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), HOST_CCREG);
5302   add_stub(CC_STUB,out,NULL,0,i,-1,TAKEN,rs);
5303   if(dops[i+1].itype==COP0&&(source[i+1]&0x3f)==0x10)
5304     // special case for RFE
5305     emit_jmp(0);
5306   else
5307     emit_jns(0);
5308   //load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,-1);
5309   #ifdef USE_MINI_HT
5310   if(dops[i].rs1==31) {
5311     do_miniht_jump(rs,rh,ht);
5312   }
5313   else
5314   #endif
5315   {
5316     do_jump_vaddr(rs);
5317   }
5318   #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5319   if(dops[i].rt1!=31&&i<slen-2&&(((u_int)out)&7)) emit_mov(13,13);
5320   #endif
5321 }
5322
5323 static void cjump_assemble(int i, const struct regstat *i_regs)
5324 {
5325   const signed char *i_regmap = i_regs->regmap;
5326   int cc;
5327   int match;
5328   match=match_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5329   assem_debug("match=%d\n",match);
5330   int s1l,s2l;
5331   int unconditional=0,nop=0;
5332   int invert=0;
5333   int internal=internal_branch(ba[i]);
5334   if(i==(ba[i]-start)>>2) assem_debug("idle loop\n");
5335   if(!match) invert=1;
5336   #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5337   if(i>(ba[i]-start)>>2) invert=1;
5338   #endif
5339   #ifdef __aarch64__
5340   invert=1; // because of near cond. branches
5341   #endif
5342
5343   if(dops[i].ooo) {
5344     s1l=get_reg(branch_regs[i].regmap,dops[i].rs1);
5345     s2l=get_reg(branch_regs[i].regmap,dops[i].rs2);
5346   }
5347   else {
5348     s1l=get_reg(i_regmap,dops[i].rs1);
5349     s2l=get_reg(i_regmap,dops[i].rs2);
5350   }
5351   if(dops[i].rs1==0&&dops[i].rs2==0)
5352   {
5353     if(dops[i].opcode&1) nop=1;
5354     else unconditional=1;
5355     //assert(dops[i].opcode!=5);
5356     //assert(dops[i].opcode!=7);
5357     //assert(dops[i].opcode!=0x15);
5358     //assert(dops[i].opcode!=0x17);
5359   }
5360   else if(dops[i].rs1==0)
5361   {
5362     s1l=s2l;
5363     s2l=-1;
5364   }
5365   else if(dops[i].rs2==0)
5366   {
5367     s2l=-1;
5368   }
5369
5370   if(dops[i].ooo) {
5371     // Out of order execution (delay slot first)
5372     //printf("OOOE\n");
5373     address_generation(i+1,i_regs,regs[i].regmap_entry);
5374     ds_assemble(i+1,i_regs);
5375     int adj;
5376     uint64_t bc_unneeded=branch_regs[i].u;
5377     bc_unneeded&=~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
5378     bc_unneeded|=1;
5379     wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,bc_unneeded);
5380     load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i].rs1,dops[i].rs2);
5381     load_regs(regs[i].regmap,branch_regs[i].regmap,CCREG,CCREG);
5382     cc=get_reg(branch_regs[i].regmap,CCREG);
5383     assert(cc==HOST_CCREG);
5384     if(unconditional)
5385       store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5386     //do_cc(i,branch_regs[i].regmap,&adj,unconditional?ba[i]:-1,unconditional);
5387     //assem_debug("cycle count (adj)\n");
5388     if(unconditional) {
5389       do_cc(i,branch_regs[i].regmap,&adj,ba[i],TAKEN,0);
5390       if(i!=(ba[i]-start)>>2 || source[i+1]!=0) {
5391         if(adj) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5392         load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5393         if(internal)
5394           assem_debug("branch: internal\n");
5395         else
5396           assem_debug("branch: external\n");
5397         if (internal && dops[(ba[i]-start)>>2].is_ds) {
5398           ds_assemble_entry(i);
5399         }
5400         else {
5401           add_to_linker(out,ba[i],internal);
5402           emit_jmp(0);
5403         }
5404         #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5405         if(((u_int)out)&7) emit_addnop(0);
5406         #endif
5407       }
5408     }
5409     else if(nop) {
5410       emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), cc);
5411       void *jaddr=out;
5412       emit_jns(0);
5413       add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
5414     }
5415     else {
5416       void *taken = NULL, *nottaken = NULL, *nottaken1 = NULL;
5417       do_cc(i,branch_regs[i].regmap,&adj,-1,0,invert);
5418       if(adj&&!invert) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5419
5420       //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]);
5421       assert(s1l>=0);
5422       if(dops[i].opcode==4) // BEQ
5423       {
5424         if(s2l>=0) emit_cmp(s1l,s2l);
5425         else emit_test(s1l,s1l);
5426         if(invert){
5427           nottaken=out;
5428           emit_jne(DJT_1);
5429         }else{
5430           add_to_linker(out,ba[i],internal);
5431           emit_jeq(0);
5432         }
5433       }
5434       if(dops[i].opcode==5) // BNE
5435       {
5436         if(s2l>=0) emit_cmp(s1l,s2l);
5437         else emit_test(s1l,s1l);
5438         if(invert){
5439           nottaken=out;
5440           emit_jeq(DJT_1);
5441         }else{
5442           add_to_linker(out,ba[i],internal);
5443           emit_jne(0);
5444         }
5445       }
5446       if(dops[i].opcode==6) // BLEZ
5447       {
5448         emit_cmpimm(s1l,1);
5449         if(invert){
5450           nottaken=out;
5451           emit_jge(DJT_1);
5452         }else{
5453           add_to_linker(out,ba[i],internal);
5454           emit_jl(0);
5455         }
5456       }
5457       if(dops[i].opcode==7) // BGTZ
5458       {
5459         emit_cmpimm(s1l,1);
5460         if(invert){
5461           nottaken=out;
5462           emit_jl(DJT_1);
5463         }else{
5464           add_to_linker(out,ba[i],internal);
5465           emit_jge(0);
5466         }
5467       }
5468       if(invert) {
5469         if(taken) set_jump_target(taken, out);
5470         #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5471         if (match && (!internal || !dops[(ba[i]-start)>>2].is_ds)) {
5472           if(adj) {
5473             emit_addimm(cc,-adj,cc);
5474             add_to_linker(out,ba[i],internal);
5475           }else{
5476             emit_addnop(13);
5477             add_to_linker(out,ba[i],internal*2);
5478           }
5479           emit_jmp(0);
5480         }else
5481         #endif
5482         {
5483           if(adj) emit_addimm(cc,-adj,cc);
5484           store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5485           load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5486           if(internal)
5487             assem_debug("branch: internal\n");
5488           else
5489             assem_debug("branch: external\n");
5490           if (internal && dops[(ba[i] - start) >> 2].is_ds) {
5491             ds_assemble_entry(i);
5492           }
5493           else {
5494             add_to_linker(out,ba[i],internal);
5495             emit_jmp(0);
5496           }
5497         }
5498         set_jump_target(nottaken, out);
5499       }
5500
5501       if(nottaken1) set_jump_target(nottaken1, out);
5502       if(adj) {
5503         if(!invert) emit_addimm(cc,adj,cc);
5504       }
5505     } // (!unconditional)
5506   } // if(ooo)
5507   else
5508   {
5509     // In-order execution (branch first)
5510     void *taken = NULL, *nottaken = NULL, *nottaken1 = NULL;
5511     if(!unconditional&&!nop) {
5512       //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]);
5513       assert(s1l>=0);
5514       if((dops[i].opcode&0x2f)==4) // BEQ
5515       {
5516         if(s2l>=0) emit_cmp(s1l,s2l);
5517         else emit_test(s1l,s1l);
5518         nottaken=out;
5519         emit_jne(DJT_2);
5520       }
5521       if((dops[i].opcode&0x2f)==5) // BNE
5522       {
5523         if(s2l>=0) emit_cmp(s1l,s2l);
5524         else emit_test(s1l,s1l);
5525         nottaken=out;
5526         emit_jeq(DJT_2);
5527       }
5528       if((dops[i].opcode&0x2f)==6) // BLEZ
5529       {
5530         emit_cmpimm(s1l,1);
5531         nottaken=out;
5532         emit_jge(DJT_2);
5533       }
5534       if((dops[i].opcode&0x2f)==7) // BGTZ
5535       {
5536         emit_cmpimm(s1l,1);
5537         nottaken=out;
5538         emit_jl(DJT_2);
5539       }
5540     } // if(!unconditional)
5541     int adj;
5542     uint64_t ds_unneeded=branch_regs[i].u;
5543     ds_unneeded&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
5544     ds_unneeded|=1;
5545     // branch taken
5546     if(!nop) {
5547       if(taken) set_jump_target(taken, out);
5548       assem_debug("1:\n");
5549       wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,ds_unneeded);
5550       // load regs
5551       load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i+1].rs1,dops[i+1].rs2);
5552       address_generation(i+1,&branch_regs[i],0);
5553       if (ram_offset)
5554         load_regs(regs[i].regmap,branch_regs[i].regmap,ROREG,ROREG);
5555       load_regs(regs[i].regmap,branch_regs[i].regmap,CCREG,INVCP);
5556       ds_assemble(i+1,&branch_regs[i]);
5557       cc=get_reg(branch_regs[i].regmap,CCREG);
5558       if(cc==-1) {
5559         emit_loadreg(CCREG,cc=HOST_CCREG);
5560         // CHECK: Is the following instruction (fall thru) allocated ok?
5561       }
5562       assert(cc==HOST_CCREG);
5563       store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5564       do_cc(i,i_regmap,&adj,ba[i],TAKEN,0);
5565       assem_debug("cycle count (adj)\n");
5566       if(adj) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5567       load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5568       if(internal)
5569         assem_debug("branch: internal\n");
5570       else
5571         assem_debug("branch: external\n");
5572       if (internal && dops[(ba[i] - start) >> 2].is_ds) {
5573         ds_assemble_entry(i);
5574       }
5575       else {
5576         add_to_linker(out,ba[i],internal);
5577         emit_jmp(0);
5578       }
5579     }
5580     // branch not taken
5581     if(!unconditional) {
5582       if(nottaken1) set_jump_target(nottaken1, out);
5583       set_jump_target(nottaken, out);
5584       assem_debug("2:\n");
5585       wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,ds_unneeded);
5586       // load regs
5587       load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i+1].rs1,dops[i+1].rs2);
5588       address_generation(i+1,&branch_regs[i],0);
5589       if (ram_offset)
5590         load_regs(regs[i].regmap,branch_regs[i].regmap,ROREG,ROREG);
5591       load_regs(regs[i].regmap,branch_regs[i].regmap,CCREG,INVCP);
5592       ds_assemble(i+1,&branch_regs[i]);
5593       cc=get_reg(branch_regs[i].regmap,CCREG);
5594       if (cc == -1) {
5595         // Cycle count isn't in a register, temporarily load it then write it out
5596         emit_loadreg(CCREG,HOST_CCREG);
5597         emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), HOST_CCREG);
5598         void *jaddr=out;
5599         emit_jns(0);
5600         add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
5601         emit_storereg(CCREG,HOST_CCREG);
5602       }
5603       else{
5604         cc=get_reg(i_regmap,CCREG);
5605         assert(cc==HOST_CCREG);
5606         emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), cc);
5607         void *jaddr=out;
5608         emit_jns(0);
5609         add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
5610       }
5611     }
5612   }
5613 }
5614
5615 static void sjump_assemble(int i, const struct regstat *i_regs)
5616 {
5617   const signed char *i_regmap = i_regs->regmap;
5618   int cc;
5619   int match;
5620   match=match_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5621   assem_debug("smatch=%d\n",match);
5622   int s1l;
5623   int unconditional=0,nevertaken=0;
5624   int invert=0;
5625   int internal=internal_branch(ba[i]);
5626   if(i==(ba[i]-start)>>2) assem_debug("idle loop\n");
5627   if(!match) invert=1;
5628   #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5629   if(i>(ba[i]-start)>>2) invert=1;
5630   #endif
5631   #ifdef __aarch64__
5632   invert=1; // because of near cond. branches
5633   #endif
5634
5635   //if(dops[i].opcode2>=0x10) return; // FIXME (BxxZAL)
5636   //assert(dops[i].opcode2<0x10||dops[i].rs1==0); // FIXME (BxxZAL)
5637
5638   if(dops[i].ooo) {
5639     s1l=get_reg(branch_regs[i].regmap,dops[i].rs1);
5640   }
5641   else {
5642     s1l=get_reg(i_regmap,dops[i].rs1);
5643   }
5644   if(dops[i].rs1==0)
5645   {
5646     if(dops[i].opcode2&1) unconditional=1;
5647     else nevertaken=1;
5648     // These are never taken (r0 is never less than zero)
5649     //assert(dops[i].opcode2!=0);
5650     //assert(dops[i].opcode2!=2);
5651     //assert(dops[i].opcode2!=0x10);
5652     //assert(dops[i].opcode2!=0x12);
5653   }
5654
5655   if(dops[i].ooo) {
5656     // Out of order execution (delay slot first)
5657     //printf("OOOE\n");
5658     address_generation(i+1,i_regs,regs[i].regmap_entry);
5659     ds_assemble(i+1,i_regs);
5660     int adj;
5661     uint64_t bc_unneeded=branch_regs[i].u;
5662     bc_unneeded&=~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
5663     bc_unneeded|=1;
5664     wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,bc_unneeded);
5665     load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i].rs1,dops[i].rs1);
5666     load_regs(regs[i].regmap,branch_regs[i].regmap,CCREG,CCREG);
5667     if(dops[i].rt1==31) {
5668       int rt,return_address;
5669       rt=get_reg(branch_regs[i].regmap,31);
5670       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]);
5671       if(rt>=0) {
5672         // Save the PC even if the branch is not taken
5673         return_address=start+i*4+8;
5674         emit_movimm(return_address,rt); // PC into link register
5675         #ifdef IMM_PREFETCH
5676         if(!nevertaken) emit_prefetch(hash_table_get(return_address));
5677         #endif
5678       }
5679     }
5680     cc=get_reg(branch_regs[i].regmap,CCREG);
5681     assert(cc==HOST_CCREG);
5682     if(unconditional)
5683       store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5684     //do_cc(i,branch_regs[i].regmap,&adj,unconditional?ba[i]:-1,unconditional);
5685     assem_debug("cycle count (adj)\n");
5686     if(unconditional) {
5687       do_cc(i,branch_regs[i].regmap,&adj,ba[i],TAKEN,0);
5688       if(i!=(ba[i]-start)>>2 || source[i+1]!=0) {
5689         if(adj) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5690         load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5691         if(internal)
5692           assem_debug("branch: internal\n");
5693         else
5694           assem_debug("branch: external\n");
5695         if (internal && dops[(ba[i] - start) >> 2].is_ds) {
5696           ds_assemble_entry(i);
5697         }
5698         else {
5699           add_to_linker(out,ba[i],internal);
5700           emit_jmp(0);
5701         }
5702         #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5703         if(((u_int)out)&7) emit_addnop(0);
5704         #endif
5705       }
5706     }
5707     else if(nevertaken) {
5708       emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), cc);
5709       void *jaddr=out;
5710       emit_jns(0);
5711       add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
5712     }
5713     else {
5714       void *nottaken = NULL;
5715       do_cc(i,branch_regs[i].regmap,&adj,-1,0,invert);
5716       if(adj&&!invert) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5717       {
5718         assert(s1l>=0);
5719         if((dops[i].opcode2&0xf)==0) // BLTZ/BLTZAL
5720         {
5721           emit_test(s1l,s1l);
5722           if(invert){
5723             nottaken=out;
5724             emit_jns(DJT_1);
5725           }else{
5726             add_to_linker(out,ba[i],internal);
5727             emit_js(0);
5728           }
5729         }
5730         if((dops[i].opcode2&0xf)==1) // BGEZ/BLTZAL
5731         {
5732           emit_test(s1l,s1l);
5733           if(invert){
5734             nottaken=out;
5735             emit_js(DJT_1);
5736           }else{
5737             add_to_linker(out,ba[i],internal);
5738             emit_jns(0);
5739           }
5740         }
5741       }
5742
5743       if(invert) {
5744         #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5745         if (match && (!internal || !dops[(ba[i] - start) >> 2].is_ds)) {
5746           if(adj) {
5747             emit_addimm(cc,-adj,cc);
5748             add_to_linker(out,ba[i],internal);
5749           }else{
5750             emit_addnop(13);
5751             add_to_linker(out,ba[i],internal*2);
5752           }
5753           emit_jmp(0);
5754         }else
5755         #endif
5756         {
5757           if(adj) emit_addimm(cc,-adj,cc);
5758           store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5759           load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5760           if(internal)
5761             assem_debug("branch: internal\n");
5762           else
5763             assem_debug("branch: external\n");
5764           if (internal && dops[(ba[i] - start) >> 2].is_ds) {
5765             ds_assemble_entry(i);
5766           }
5767           else {
5768             add_to_linker(out,ba[i],internal);
5769             emit_jmp(0);
5770           }
5771         }
5772         set_jump_target(nottaken, out);
5773       }
5774
5775       if(adj) {
5776         if(!invert) emit_addimm(cc,adj,cc);
5777       }
5778     } // (!unconditional)
5779   } // if(ooo)
5780   else
5781   {
5782     // In-order execution (branch first)
5783     //printf("IOE\n");
5784     void *nottaken = NULL;
5785     if(dops[i].rt1==31) {
5786       int rt,return_address;
5787       rt=get_reg(branch_regs[i].regmap,31);
5788       if(rt>=0) {
5789         // Save the PC even if the branch is not taken
5790         return_address=start+i*4+8;
5791         emit_movimm(return_address,rt); // PC into link register
5792         #ifdef IMM_PREFETCH
5793         emit_prefetch(hash_table_get(return_address));
5794         #endif
5795       }
5796     }
5797     if(!unconditional) {
5798       //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]);
5799         assert(s1l>=0);
5800         if((dops[i].opcode2&0x0d)==0) // BLTZ/BLTZL/BLTZAL/BLTZALL
5801         {
5802           emit_test(s1l,s1l);
5803           nottaken=out;
5804           emit_jns(DJT_1);
5805         }
5806         if((dops[i].opcode2&0x0d)==1) // BGEZ/BGEZL/BGEZAL/BGEZALL
5807         {
5808           emit_test(s1l,s1l);
5809           nottaken=out;
5810           emit_js(DJT_1);
5811         }
5812     } // if(!unconditional)
5813     int adj;
5814     uint64_t ds_unneeded=branch_regs[i].u;
5815     ds_unneeded&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
5816     ds_unneeded|=1;
5817     // branch taken
5818     if(!nevertaken) {
5819       //assem_debug("1:\n");
5820       wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,ds_unneeded);
5821       // load regs
5822       load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i+1].rs1,dops[i+1].rs2);
5823       address_generation(i+1,&branch_regs[i],0);
5824       if (ram_offset)
5825         load_regs(regs[i].regmap,branch_regs[i].regmap,ROREG,ROREG);
5826       load_regs(regs[i].regmap,branch_regs[i].regmap,CCREG,INVCP);
5827       ds_assemble(i+1,&branch_regs[i]);
5828       cc=get_reg(branch_regs[i].regmap,CCREG);
5829       if(cc==-1) {
5830         emit_loadreg(CCREG,cc=HOST_CCREG);
5831         // CHECK: Is the following instruction (fall thru) allocated ok?
5832       }
5833       assert(cc==HOST_CCREG);
5834       store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5835       do_cc(i,i_regmap,&adj,ba[i],TAKEN,0);
5836       assem_debug("cycle count (adj)\n");
5837       if(adj) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5838       load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5839       if(internal)
5840         assem_debug("branch: internal\n");
5841       else
5842         assem_debug("branch: external\n");
5843       if (internal && dops[(ba[i] - start) >> 2].is_ds) {
5844         ds_assemble_entry(i);
5845       }
5846       else {
5847         add_to_linker(out,ba[i],internal);
5848         emit_jmp(0);
5849       }
5850     }
5851     // branch not taken
5852     if(!unconditional) {
5853       set_jump_target(nottaken, out);
5854       assem_debug("1:\n");
5855       wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,ds_unneeded);
5856       load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i+1].rs1,dops[i+1].rs2);
5857       address_generation(i+1,&branch_regs[i],0);
5858       load_regs(regs[i].regmap,branch_regs[i].regmap,CCREG,CCREG);
5859       ds_assemble(i+1,&branch_regs[i]);
5860       cc=get_reg(branch_regs[i].regmap,CCREG);
5861       if (cc == -1) {
5862         // Cycle count isn't in a register, temporarily load it then write it out
5863         emit_loadreg(CCREG,HOST_CCREG);
5864         emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), HOST_CCREG);
5865         void *jaddr=out;
5866         emit_jns(0);
5867         add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
5868         emit_storereg(CCREG,HOST_CCREG);
5869       }
5870       else{
5871         cc=get_reg(i_regmap,CCREG);
5872         assert(cc==HOST_CCREG);
5873         emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), cc);
5874         void *jaddr=out;
5875         emit_jns(0);
5876         add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
5877       }
5878     }
5879   }
5880 }
5881
5882 static void pagespan_assemble(int i, const struct regstat *i_regs)
5883 {
5884   int s1l=get_reg(i_regs->regmap,dops[i].rs1);
5885   int s2l=get_reg(i_regs->regmap,dops[i].rs2);
5886   void *taken = NULL;
5887   void *nottaken = NULL;
5888   int unconditional=0;
5889   if(dops[i].rs1==0)
5890   {
5891     s1l=s2l;
5892     s2l=-1;
5893   }
5894   else if(dops[i].rs2==0)
5895   {
5896     s2l=-1;
5897   }
5898   int hr=0;
5899   int addr=-1,alt=-1,ntaddr=-1;
5900   if(i_regs->regmap[HOST_BTREG]<0) {addr=HOST_BTREG;}
5901   else {
5902     while(hr<HOST_REGS)
5903     {
5904       if(hr!=EXCLUDE_REG && hr!=HOST_CCREG &&
5905          (i_regs->regmap[hr]&63)!=dops[i].rs1 &&
5906          (i_regs->regmap[hr]&63)!=dops[i].rs2 )
5907       {
5908         addr=hr++;break;
5909       }
5910       hr++;
5911     }
5912   }
5913   while(hr<HOST_REGS)
5914   {
5915     if(hr!=EXCLUDE_REG && hr!=HOST_CCREG && hr!=HOST_BTREG &&
5916        (i_regs->regmap[hr]&63)!=dops[i].rs1 &&
5917        (i_regs->regmap[hr]&63)!=dops[i].rs2 )
5918     {
5919       alt=hr++;break;
5920     }
5921     hr++;
5922   }
5923   if((dops[i].opcode&0x2E)==6) // BLEZ/BGTZ needs another register
5924   {
5925     while(hr<HOST_REGS)
5926     {
5927       if(hr!=EXCLUDE_REG && hr!=HOST_CCREG && hr!=HOST_BTREG &&
5928          (i_regs->regmap[hr]&63)!=dops[i].rs1 &&
5929          (i_regs->regmap[hr]&63)!=dops[i].rs2 )
5930       {
5931         ntaddr=hr;break;
5932       }
5933       hr++;
5934     }
5935   }
5936   assert(hr<HOST_REGS);
5937   if((dops[i].opcode&0x2e)==4||dops[i].opcode==0x11) { // BEQ/BNE/BEQL/BNEL/BC1
5938     load_regs(regs[i].regmap_entry,regs[i].regmap,CCREG,CCREG);
5939   }
5940   emit_addimm(HOST_CCREG, ccadj[i] + CLOCK_ADJUST(2), HOST_CCREG);
5941   if(dops[i].opcode==2) // J
5942   {
5943     unconditional=1;
5944   }
5945   if(dops[i].opcode==3) // JAL
5946   {
5947     // TODO: mini_ht
5948     int rt=get_reg(i_regs->regmap,31);
5949     emit_movimm(start+i*4+8,rt);
5950     unconditional=1;
5951   }
5952   if(dops[i].opcode==0&&(dops[i].opcode2&0x3E)==8) // JR/JALR
5953   {
5954     emit_mov(s1l,addr);
5955     if(dops[i].opcode2==9) // JALR
5956     {
5957       int rt=get_reg(i_regs->regmap,dops[i].rt1);
5958       emit_movimm(start+i*4+8,rt);
5959     }
5960   }
5961   if((dops[i].opcode&0x3f)==4) // BEQ
5962   {
5963     if(dops[i].rs1==dops[i].rs2)
5964     {
5965       unconditional=1;
5966     }
5967     else
5968     #ifdef HAVE_CMOV_IMM
5969     if(1) {
5970       if(s2l>=0) emit_cmp(s1l,s2l);
5971       else emit_test(s1l,s1l);
5972       emit_cmov2imm_e_ne_compact(ba[i],start+i*4+8,addr);
5973     }
5974     else
5975     #endif
5976     {
5977       assert(s1l>=0);
5978       emit_mov2imm_compact(ba[i],addr,start+i*4+8,alt);
5979       if(s2l>=0) emit_cmp(s1l,s2l);
5980       else emit_test(s1l,s1l);
5981       emit_cmovne_reg(alt,addr);
5982     }
5983   }
5984   if((dops[i].opcode&0x3f)==5) // BNE
5985   {
5986     #ifdef HAVE_CMOV_IMM
5987     if(s2l>=0) emit_cmp(s1l,s2l);
5988     else emit_test(s1l,s1l);
5989     emit_cmov2imm_e_ne_compact(start+i*4+8,ba[i],addr);
5990     #else
5991     assert(s1l>=0);
5992     emit_mov2imm_compact(start+i*4+8,addr,ba[i],alt);
5993     if(s2l>=0) emit_cmp(s1l,s2l);
5994     else emit_test(s1l,s1l);
5995     emit_cmovne_reg(alt,addr);
5996     #endif
5997   }
5998   if((dops[i].opcode&0x3f)==0x14) // BEQL
5999   {
6000     if(s2l>=0) emit_cmp(s1l,s2l);
6001     else emit_test(s1l,s1l);
6002     if(nottaken) set_jump_target(nottaken, out);
6003     nottaken=out;
6004     emit_jne(0);
6005   }
6006   if((dops[i].opcode&0x3f)==0x15) // BNEL
6007   {
6008     if(s2l>=0) emit_cmp(s1l,s2l);
6009     else emit_test(s1l,s1l);
6010     nottaken=out;
6011     emit_jeq(0);
6012     if(taken) set_jump_target(taken, out);
6013   }
6014   if((dops[i].opcode&0x3f)==6) // BLEZ
6015   {
6016     emit_mov2imm_compact(ba[i],alt,start+i*4+8,addr);
6017     emit_cmpimm(s1l,1);
6018     emit_cmovl_reg(alt,addr);
6019   }
6020   if((dops[i].opcode&0x3f)==7) // BGTZ
6021   {
6022     emit_mov2imm_compact(ba[i],addr,start+i*4+8,ntaddr);
6023     emit_cmpimm(s1l,1);
6024     emit_cmovl_reg(ntaddr,addr);
6025   }
6026   if((dops[i].opcode&0x3f)==0x16) // BLEZL
6027   {
6028     assert((dops[i].opcode&0x3f)!=0x16);
6029   }
6030   if((dops[i].opcode&0x3f)==0x17) // BGTZL
6031   {
6032     assert((dops[i].opcode&0x3f)!=0x17);
6033   }
6034   assert(dops[i].opcode!=1); // BLTZ/BGEZ
6035
6036   //FIXME: Check CSREG
6037   if(dops[i].opcode==0x11 && dops[i].opcode2==0x08 ) {
6038     if((source[i]&0x30000)==0) // BC1F
6039     {
6040       emit_mov2imm_compact(ba[i],addr,start+i*4+8,alt);
6041       emit_testimm(s1l,0x800000);
6042       emit_cmovne_reg(alt,addr);
6043     }
6044     if((source[i]&0x30000)==0x10000) // BC1T
6045     {
6046       emit_mov2imm_compact(ba[i],alt,start+i*4+8,addr);
6047       emit_testimm(s1l,0x800000);
6048       emit_cmovne_reg(alt,addr);
6049     }
6050     if((source[i]&0x30000)==0x20000) // BC1FL
6051     {
6052       emit_testimm(s1l,0x800000);
6053       nottaken=out;
6054       emit_jne(0);
6055     }
6056     if((source[i]&0x30000)==0x30000) // BC1TL
6057     {
6058       emit_testimm(s1l,0x800000);
6059       nottaken=out;
6060       emit_jeq(0);
6061     }
6062   }
6063
6064   assert(i_regs->regmap[HOST_CCREG]==CCREG);
6065   wb_dirtys(regs[i].regmap,regs[i].dirty);
6066   if(unconditional)
6067   {
6068     emit_movimm(ba[i],HOST_BTREG);
6069   }
6070   else if(addr!=HOST_BTREG)
6071   {
6072     emit_mov(addr,HOST_BTREG);
6073   }
6074   void *branch_addr=out;
6075   emit_jmp(0);
6076   int target_addr=start+i*4+5;
6077   void *stub=out;
6078   void *compiled_target_addr=check_addr(target_addr);
6079   emit_extjump_ds(branch_addr, target_addr);
6080   if(compiled_target_addr) {
6081     set_jump_target(branch_addr, compiled_target_addr);
6082     add_jump_out(target_addr,stub);
6083   }
6084   else set_jump_target(branch_addr, stub);
6085 }
6086
6087 // Assemble the delay slot for the above
6088 static void pagespan_ds()
6089 {
6090   assem_debug("initial delay slot:\n");
6091   u_int vaddr=start+1;
6092   u_int page=get_page(vaddr);
6093   u_int vpage=get_vpage(vaddr);
6094   ll_add(jump_dirty+vpage,vaddr,(void *)out);
6095   do_dirty_stub_ds(slen*4);
6096   ll_add(jump_in+page,vaddr,(void *)out);
6097   assert(regs[0].regmap_entry[HOST_CCREG]==CCREG);
6098   if(regs[0].regmap[HOST_CCREG]!=CCREG)
6099     wb_register(CCREG,regs[0].regmap_entry,regs[0].wasdirty);
6100   if(regs[0].regmap[HOST_BTREG]!=BTREG)
6101     emit_writeword(HOST_BTREG,&branch_target);
6102   load_regs(regs[0].regmap_entry,regs[0].regmap,dops[0].rs1,dops[0].rs2);
6103   address_generation(0,&regs[0],regs[0].regmap_entry);
6104   if (ram_offset && (dops[0].is_load || dops[0].is_store))
6105     load_regs(regs[0].regmap_entry,regs[0].regmap,ROREG,ROREG);
6106   if (dops[0].is_store)
6107     load_regs(regs[0].regmap_entry,regs[0].regmap,INVCP,INVCP);
6108   is_delayslot=0;
6109   switch (dops[0].itype) {
6110     case SYSCALL:
6111     case HLECALL:
6112     case INTCALL:
6113     case SPAN:
6114     case UJUMP:
6115     case RJUMP:
6116     case CJUMP:
6117     case SJUMP:
6118       SysPrintf("Jump in the delay slot.  This is probably a bug.\n");
6119       break;
6120     default:
6121       assemble(0, &regs[0], 0);
6122   }
6123   int btaddr=get_reg(regs[0].regmap,BTREG);
6124   if(btaddr<0) {
6125     btaddr=get_reg(regs[0].regmap,-1);
6126     emit_readword(&branch_target,btaddr);
6127   }
6128   assert(btaddr!=HOST_CCREG);
6129   if(regs[0].regmap[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG);
6130 #ifdef HOST_IMM8
6131   host_tempreg_acquire();
6132   emit_movimm(start+4,HOST_TEMPREG);
6133   emit_cmp(btaddr,HOST_TEMPREG);
6134   host_tempreg_release();
6135 #else
6136   emit_cmpimm(btaddr,start+4);
6137 #endif
6138   void *branch = out;
6139   emit_jeq(0);
6140   store_regs_bt(regs[0].regmap,regs[0].dirty,-1);
6141   do_jump_vaddr(btaddr);
6142   set_jump_target(branch, out);
6143   store_regs_bt(regs[0].regmap,regs[0].dirty,start+4);
6144   load_regs_bt(regs[0].regmap,regs[0].dirty,start+4);
6145 }
6146
6147 // Basic liveness analysis for MIPS registers
6148 void unneeded_registers(int istart,int iend,int r)
6149 {
6150   int i;
6151   uint64_t u,gte_u,b,gte_b;
6152   uint64_t temp_u,temp_gte_u=0;
6153   uint64_t gte_u_unknown=0;
6154   if (HACK_ENABLED(NDHACK_GTE_UNNEEDED))
6155     gte_u_unknown=~0ll;
6156   if(iend==slen-1) {
6157     u=1;
6158     gte_u=gte_u_unknown;
6159   }else{
6160     //u=unneeded_reg[iend+1];
6161     u=1;
6162     gte_u=gte_unneeded[iend+1];
6163   }
6164
6165   for (i=iend;i>=istart;i--)
6166   {
6167     //printf("unneeded registers i=%d (%d,%d) r=%d\n",i,istart,iend,r);
6168     if(dops[i].is_jump)
6169     {
6170       // If subroutine call, flag return address as a possible branch target
6171       if(dops[i].rt1==31 && i<slen-2) dops[i+2].bt=1;
6172
6173       if(ba[i]<start || ba[i]>=(start+slen*4))
6174       {
6175         // Branch out of this block, flush all regs
6176         u=1;
6177         gte_u=gte_u_unknown;
6178         branch_unneeded_reg[i]=u;
6179         // Merge in delay slot
6180         u|=(1LL<<dops[i+1].rt1)|(1LL<<dops[i+1].rt2);
6181         u&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
6182         u|=1;
6183         gte_u|=gte_rt[i+1];
6184         gte_u&=~gte_rs[i+1];
6185       }
6186       else
6187       {
6188         // Internal branch, flag target
6189         dops[(ba[i]-start)>>2].bt=1;
6190         if(ba[i]<=start+i*4) {
6191           // Backward branch
6192           if(dops[i].is_ujump)
6193           {
6194             // Unconditional branch
6195             temp_u=1;
6196             temp_gte_u=0;
6197           } else {
6198             // Conditional branch (not taken case)
6199             temp_u=unneeded_reg[i+2];
6200             temp_gte_u&=gte_unneeded[i+2];
6201           }
6202           // Merge in delay slot
6203           temp_u|=(1LL<<dops[i+1].rt1)|(1LL<<dops[i+1].rt2);
6204           temp_u&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
6205           temp_u|=1;
6206           temp_gte_u|=gte_rt[i+1];
6207           temp_gte_u&=~gte_rs[i+1];
6208           temp_u|=(1LL<<dops[i].rt1)|(1LL<<dops[i].rt2);
6209           temp_u&=~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
6210           temp_u|=1;
6211           temp_gte_u|=gte_rt[i];
6212           temp_gte_u&=~gte_rs[i];
6213           unneeded_reg[i]=temp_u;
6214           gte_unneeded[i]=temp_gte_u;
6215           // Only go three levels deep.  This recursion can take an
6216           // excessive amount of time if there are a lot of nested loops.
6217           if(r<2) {
6218             unneeded_registers((ba[i]-start)>>2,i-1,r+1);
6219           }else{
6220             unneeded_reg[(ba[i]-start)>>2]=1;
6221             gte_unneeded[(ba[i]-start)>>2]=gte_u_unknown;
6222           }
6223         } /*else*/ if(1) {
6224           if (dops[i].is_ujump)
6225           {
6226             // Unconditional branch
6227             u=unneeded_reg[(ba[i]-start)>>2];
6228             gte_u=gte_unneeded[(ba[i]-start)>>2];
6229             branch_unneeded_reg[i]=u;
6230             // Merge in delay slot
6231             u|=(1LL<<dops[i+1].rt1)|(1LL<<dops[i+1].rt2);
6232             u&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
6233             u|=1;
6234             gte_u|=gte_rt[i+1];
6235             gte_u&=~gte_rs[i+1];
6236           } else {
6237             // Conditional branch
6238             b=unneeded_reg[(ba[i]-start)>>2];
6239             gte_b=gte_unneeded[(ba[i]-start)>>2];
6240             branch_unneeded_reg[i]=b;
6241             // Branch delay slot
6242             b|=(1LL<<dops[i+1].rt1)|(1LL<<dops[i+1].rt2);
6243             b&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
6244             b|=1;
6245             gte_b|=gte_rt[i+1];
6246             gte_b&=~gte_rs[i+1];
6247             u&=b;
6248             gte_u&=gte_b;
6249             if(i<slen-1) {
6250               branch_unneeded_reg[i]&=unneeded_reg[i+2];
6251             } else {
6252               branch_unneeded_reg[i]=1;
6253             }
6254           }
6255         }
6256       }
6257     }
6258     else if(dops[i].itype==SYSCALL||dops[i].itype==HLECALL||dops[i].itype==INTCALL)
6259     {
6260       // SYSCALL instruction (software interrupt)
6261       u=1;
6262     }
6263     else if(dops[i].itype==COP0 && (source[i]&0x3f)==0x18)
6264     {
6265       // ERET instruction (return from interrupt)
6266       u=1;
6267     }
6268     //u=1; // DEBUG
6269     // Written registers are unneeded
6270     u|=1LL<<dops[i].rt1;
6271     u|=1LL<<dops[i].rt2;
6272     gte_u|=gte_rt[i];
6273     // Accessed registers are needed
6274     u&=~(1LL<<dops[i].rs1);
6275     u&=~(1LL<<dops[i].rs2);
6276     gte_u&=~gte_rs[i];
6277     if(gte_rs[i]&&dops[i].rt1&&(unneeded_reg[i+1]&(1ll<<dops[i].rt1)))
6278       gte_u|=gte_rs[i]&gte_unneeded[i+1]; // MFC2/CFC2 to dead register, unneeded
6279     // Source-target dependencies
6280     // R0 is always unneeded
6281     u|=1;
6282     // Save it
6283     unneeded_reg[i]=u;
6284     gte_unneeded[i]=gte_u;
6285     /*
6286     printf("ur (%d,%d) %x: ",istart,iend,start+i*4);
6287     printf("U:");
6288     int r;
6289     for(r=1;r<=CCREG;r++) {
6290       if((unneeded_reg[i]>>r)&1) {
6291         if(r==HIREG) printf(" HI");
6292         else if(r==LOREG) printf(" LO");
6293         else printf(" r%d",r);
6294       }
6295     }
6296     printf("\n");
6297     */
6298   }
6299 }
6300
6301 // Write back dirty registers as soon as we will no longer modify them,
6302 // so that we don't end up with lots of writes at the branches.
6303 void clean_registers(int istart,int iend,int wr)
6304 {
6305   int i;
6306   int r;
6307   u_int will_dirty_i,will_dirty_next,temp_will_dirty;
6308   u_int wont_dirty_i,wont_dirty_next,temp_wont_dirty;
6309   if(iend==slen-1) {
6310     will_dirty_i=will_dirty_next=0;
6311     wont_dirty_i=wont_dirty_next=0;
6312   }else{
6313     will_dirty_i=will_dirty_next=will_dirty[iend+1];
6314     wont_dirty_i=wont_dirty_next=wont_dirty[iend+1];
6315   }
6316   for (i=iend;i>=istart;i--)
6317   {
6318     if(dops[i].is_jump)
6319     {
6320       if(ba[i]<start || ba[i]>=(start+slen*4))
6321       {
6322         // Branch out of this block, flush all regs
6323         if (dops[i].is_ujump)
6324         {
6325           // Unconditional branch
6326           will_dirty_i=0;
6327           wont_dirty_i=0;
6328           // Merge in delay slot (will dirty)
6329           for(r=0;r<HOST_REGS;r++) {
6330             if(r!=EXCLUDE_REG) {
6331               if((branch_regs[i].regmap[r]&63)==dops[i].rt1) will_dirty_i|=1<<r;
6332               if((branch_regs[i].regmap[r]&63)==dops[i].rt2) will_dirty_i|=1<<r;
6333               if((branch_regs[i].regmap[r]&63)==dops[i+1].rt1) will_dirty_i|=1<<r;
6334               if((branch_regs[i].regmap[r]&63)==dops[i+1].rt2) will_dirty_i|=1<<r;
6335               if((branch_regs[i].regmap[r]&63)>33) will_dirty_i&=~(1<<r);
6336               if(branch_regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
6337               if(branch_regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
6338               if((regs[i].regmap[r]&63)==dops[i].rt1) will_dirty_i|=1<<r;
6339               if((regs[i].regmap[r]&63)==dops[i].rt2) will_dirty_i|=1<<r;
6340               if((regs[i].regmap[r]&63)==dops[i+1].rt1) will_dirty_i|=1<<r;
6341               if((regs[i].regmap[r]&63)==dops[i+1].rt2) will_dirty_i|=1<<r;
6342               if((regs[i].regmap[r]&63)>33) will_dirty_i&=~(1<<r);
6343               if(regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
6344               if(regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
6345             }
6346           }
6347         }
6348         else
6349         {
6350           // Conditional branch
6351           will_dirty_i=0;
6352           wont_dirty_i=wont_dirty_next;
6353           // Merge in delay slot (will dirty)
6354           for(r=0;r<HOST_REGS;r++) {
6355             if(r!=EXCLUDE_REG) {
6356               if (1) { // !dops[i].likely) {
6357                 // Might not dirty if likely branch is not taken
6358                 if((branch_regs[i].regmap[r]&63)==dops[i].rt1) will_dirty_i|=1<<r;
6359                 if((branch_regs[i].regmap[r]&63)==dops[i].rt2) will_dirty_i|=1<<r;
6360                 if((branch_regs[i].regmap[r]&63)==dops[i+1].rt1) will_dirty_i|=1<<r;
6361                 if((branch_regs[i].regmap[r]&63)==dops[i+1].rt2) will_dirty_i|=1<<r;
6362                 if((branch_regs[i].regmap[r]&63)>33) will_dirty_i&=~(1<<r);
6363                 if(branch_regs[i].regmap[r]==0) will_dirty_i&=~(1<<r);
6364                 if(branch_regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
6365                 //if((regs[i].regmap[r]&63)==dops[i].rt1) will_dirty_i|=1<<r;
6366                 //if((regs[i].regmap[r]&63)==dops[i].rt2) will_dirty_i|=1<<r;
6367                 if((regs[i].regmap[r]&63)==dops[i+1].rt1) will_dirty_i|=1<<r;
6368                 if((regs[i].regmap[r]&63)==dops[i+1].rt2) will_dirty_i|=1<<r;
6369                 if((regs[i].regmap[r]&63)>33) will_dirty_i&=~(1<<r);
6370                 if(regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
6371                 if(regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
6372               }
6373             }
6374           }
6375         }
6376         // Merge in delay slot (wont dirty)
6377         for(r=0;r<HOST_REGS;r++) {
6378           if(r!=EXCLUDE_REG) {
6379             if((regs[i].regmap[r]&63)==dops[i].rt1) wont_dirty_i|=1<<r;
6380             if((regs[i].regmap[r]&63)==dops[i].rt2) wont_dirty_i|=1<<r;
6381             if((regs[i].regmap[r]&63)==dops[i+1].rt1) wont_dirty_i|=1<<r;
6382             if((regs[i].regmap[r]&63)==dops[i+1].rt2) wont_dirty_i|=1<<r;
6383             if(regs[i].regmap[r]==CCREG) wont_dirty_i|=1<<r;
6384             if((branch_regs[i].regmap[r]&63)==dops[i].rt1) wont_dirty_i|=1<<r;
6385             if((branch_regs[i].regmap[r]&63)==dops[i].rt2) wont_dirty_i|=1<<r;
6386             if((branch_regs[i].regmap[r]&63)==dops[i+1].rt1) wont_dirty_i|=1<<r;
6387             if((branch_regs[i].regmap[r]&63)==dops[i+1].rt2) wont_dirty_i|=1<<r;
6388             if(branch_regs[i].regmap[r]==CCREG) wont_dirty_i|=1<<r;
6389           }
6390         }
6391         if(wr) {
6392           #ifndef DESTRUCTIVE_WRITEBACK
6393           branch_regs[i].dirty&=wont_dirty_i;
6394           #endif
6395           branch_regs[i].dirty|=will_dirty_i;
6396         }
6397       }
6398       else
6399       {
6400         // Internal branch
6401         if(ba[i]<=start+i*4) {
6402           // Backward branch
6403           if (dops[i].is_ujump)
6404           {
6405             // Unconditional branch
6406             temp_will_dirty=0;
6407             temp_wont_dirty=0;
6408             // Merge in delay slot (will dirty)
6409             for(r=0;r<HOST_REGS;r++) {
6410               if(r!=EXCLUDE_REG) {
6411                 if((branch_regs[i].regmap[r]&63)==dops[i].rt1) temp_will_dirty|=1<<r;
6412                 if((branch_regs[i].regmap[r]&63)==dops[i].rt2) temp_will_dirty|=1<<r;
6413                 if((branch_regs[i].regmap[r]&63)==dops[i+1].rt1) temp_will_dirty|=1<<r;
6414                 if((branch_regs[i].regmap[r]&63)==dops[i+1].rt2) temp_will_dirty|=1<<r;
6415                 if((branch_regs[i].regmap[r]&63)>33) temp_will_dirty&=~(1<<r);
6416                 if(branch_regs[i].regmap[r]<=0) temp_will_dirty&=~(1<<r);
6417                 if(branch_regs[i].regmap[r]==CCREG) temp_will_dirty|=1<<r;
6418                 if((regs[i].regmap[r]&63)==dops[i].rt1) temp_will_dirty|=1<<r;
6419                 if((regs[i].regmap[r]&63)==dops[i].rt2) temp_will_dirty|=1<<r;
6420                 if((regs[i].regmap[r]&63)==dops[i+1].rt1) temp_will_dirty|=1<<r;
6421                 if((regs[i].regmap[r]&63)==dops[i+1].rt2) temp_will_dirty|=1<<r;
6422                 if((regs[i].regmap[r]&63)>33) temp_will_dirty&=~(1<<r);
6423                 if(regs[i].regmap[r]<=0) temp_will_dirty&=~(1<<r);
6424                 if(regs[i].regmap[r]==CCREG) temp_will_dirty|=1<<r;
6425               }
6426             }
6427           } else {
6428             // Conditional branch (not taken case)
6429             temp_will_dirty=will_dirty_next;
6430             temp_wont_dirty=wont_dirty_next;
6431             // Merge in delay slot (will dirty)
6432             for(r=0;r<HOST_REGS;r++) {
6433               if(r!=EXCLUDE_REG) {
6434                 if (1) { // !dops[i].likely) {
6435                   // Will not dirty if likely branch is not taken
6436                   if((branch_regs[i].regmap[r]&63)==dops[i].rt1) temp_will_dirty|=1<<r;
6437                   if((branch_regs[i].regmap[r]&63)==dops[i].rt2) temp_will_dirty|=1<<r;
6438                   if((branch_regs[i].regmap[r]&63)==dops[i+1].rt1) temp_will_dirty|=1<<r;
6439                   if((branch_regs[i].regmap[r]&63)==dops[i+1].rt2) temp_will_dirty|=1<<r;
6440                   if((branch_regs[i].regmap[r]&63)>33) temp_will_dirty&=~(1<<r);
6441                   if(branch_regs[i].regmap[r]==0) temp_will_dirty&=~(1<<r);
6442                   if(branch_regs[i].regmap[r]==CCREG) temp_will_dirty|=1<<r;
6443                   //if((regs[i].regmap[r]&63)==dops[i].rt1) temp_will_dirty|=1<<r;
6444                   //if((regs[i].regmap[r]&63)==dops[i].rt2) temp_will_dirty|=1<<r;
6445                   if((regs[i].regmap[r]&63)==dops[i+1].rt1) temp_will_dirty|=1<<r;
6446                   if((regs[i].regmap[r]&63)==dops[i+1].rt2) temp_will_dirty|=1<<r;
6447                   if((regs[i].regmap[r]&63)>33) temp_will_dirty&=~(1<<r);
6448                   if(regs[i].regmap[r]<=0) temp_will_dirty&=~(1<<r);
6449                   if(regs[i].regmap[r]==CCREG) temp_will_dirty|=1<<r;
6450                 }
6451               }
6452             }
6453           }
6454           // Merge in delay slot (wont dirty)
6455           for(r=0;r<HOST_REGS;r++) {
6456             if(r!=EXCLUDE_REG) {
6457               if((regs[i].regmap[r]&63)==dops[i].rt1) temp_wont_dirty|=1<<r;
6458               if((regs[i].regmap[r]&63)==dops[i].rt2) temp_wont_dirty|=1<<r;
6459               if((regs[i].regmap[r]&63)==dops[i+1].rt1) temp_wont_dirty|=1<<r;
6460               if((regs[i].regmap[r]&63)==dops[i+1].rt2) temp_wont_dirty|=1<<r;
6461               if(regs[i].regmap[r]==CCREG) temp_wont_dirty|=1<<r;
6462               if((branch_regs[i].regmap[r]&63)==dops[i].rt1) temp_wont_dirty|=1<<r;
6463               if((branch_regs[i].regmap[r]&63)==dops[i].rt2) temp_wont_dirty|=1<<r;
6464               if((branch_regs[i].regmap[r]&63)==dops[i+1].rt1) temp_wont_dirty|=1<<r;
6465               if((branch_regs[i].regmap[r]&63)==dops[i+1].rt2) temp_wont_dirty|=1<<r;
6466               if(branch_regs[i].regmap[r]==CCREG) temp_wont_dirty|=1<<r;
6467             }
6468           }
6469           // Deal with changed mappings
6470           if(i<iend) {
6471             for(r=0;r<HOST_REGS;r++) {
6472               if(r!=EXCLUDE_REG) {
6473                 if(regs[i].regmap[r]!=regmap_pre[i][r]) {
6474                   temp_will_dirty&=~(1<<r);
6475                   temp_wont_dirty&=~(1<<r);
6476                   if((regmap_pre[i][r]&63)>0 && (regmap_pre[i][r]&63)<34) {
6477                     temp_will_dirty|=((unneeded_reg[i]>>(regmap_pre[i][r]&63))&1)<<r;
6478                     temp_wont_dirty|=((unneeded_reg[i]>>(regmap_pre[i][r]&63))&1)<<r;
6479                   } else {
6480                     temp_will_dirty|=1<<r;
6481                     temp_wont_dirty|=1<<r;
6482                   }
6483                 }
6484               }
6485             }
6486           }
6487           if(wr) {
6488             will_dirty[i]=temp_will_dirty;
6489             wont_dirty[i]=temp_wont_dirty;
6490             clean_registers((ba[i]-start)>>2,i-1,0);
6491           }else{
6492             // Limit recursion.  It can take an excessive amount
6493             // of time if there are a lot of nested loops.
6494             will_dirty[(ba[i]-start)>>2]=0;
6495             wont_dirty[(ba[i]-start)>>2]=-1;
6496           }
6497         }
6498         /*else*/ if(1)
6499         {
6500           if (dops[i].is_ujump)
6501           {
6502             // Unconditional branch
6503             will_dirty_i=0;
6504             wont_dirty_i=0;
6505           //if(ba[i]>start+i*4) { // Disable recursion (for debugging)
6506             for(r=0;r<HOST_REGS;r++) {
6507               if(r!=EXCLUDE_REG) {
6508                 if(branch_regs[i].regmap[r]==regs[(ba[i]-start)>>2].regmap_entry[r]) {
6509                   will_dirty_i|=will_dirty[(ba[i]-start)>>2]&(1<<r);
6510                   wont_dirty_i|=wont_dirty[(ba[i]-start)>>2]&(1<<r);
6511                 }
6512                 if(branch_regs[i].regmap[r]>=0) {
6513                   will_dirty_i|=((unneeded_reg[(ba[i]-start)>>2]>>(branch_regs[i].regmap[r]&63))&1)<<r;
6514                   wont_dirty_i|=((unneeded_reg[(ba[i]-start)>>2]>>(branch_regs[i].regmap[r]&63))&1)<<r;
6515                 }
6516               }
6517             }
6518           //}
6519             // Merge in delay slot
6520             for(r=0;r<HOST_REGS;r++) {
6521               if(r!=EXCLUDE_REG) {
6522                 if((branch_regs[i].regmap[r]&63)==dops[i].rt1) will_dirty_i|=1<<r;
6523                 if((branch_regs[i].regmap[r]&63)==dops[i].rt2) will_dirty_i|=1<<r;
6524                 if((branch_regs[i].regmap[r]&63)==dops[i+1].rt1) will_dirty_i|=1<<r;
6525                 if((branch_regs[i].regmap[r]&63)==dops[i+1].rt2) will_dirty_i|=1<<r;
6526                 if((branch_regs[i].regmap[r]&63)>33) will_dirty_i&=~(1<<r);
6527                 if(branch_regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
6528                 if(branch_regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
6529                 if((regs[i].regmap[r]&63)==dops[i].rt1) will_dirty_i|=1<<r;
6530                 if((regs[i].regmap[r]&63)==dops[i].rt2) will_dirty_i|=1<<r;
6531                 if((regs[i].regmap[r]&63)==dops[i+1].rt1) will_dirty_i|=1<<r;
6532                 if((regs[i].regmap[r]&63)==dops[i+1].rt2) will_dirty_i|=1<<r;
6533                 if((regs[i].regmap[r]&63)>33) will_dirty_i&=~(1<<r);
6534                 if(regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
6535                 if(regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
6536               }
6537             }
6538           } else {
6539             // Conditional branch
6540             will_dirty_i=will_dirty_next;
6541             wont_dirty_i=wont_dirty_next;
6542           //if(ba[i]>start+i*4) { // Disable recursion (for debugging)
6543             for(r=0;r<HOST_REGS;r++) {
6544               if(r!=EXCLUDE_REG) {
6545                 signed char target_reg=branch_regs[i].regmap[r];
6546                 if(target_reg==regs[(ba[i]-start)>>2].regmap_entry[r]) {
6547                   will_dirty_i&=will_dirty[(ba[i]-start)>>2]&(1<<r);
6548                   wont_dirty_i|=wont_dirty[(ba[i]-start)>>2]&(1<<r);
6549                 }
6550                 else if(target_reg>=0) {
6551                   will_dirty_i&=((unneeded_reg[(ba[i]-start)>>2]>>(target_reg&63))&1)<<r;
6552                   wont_dirty_i|=((unneeded_reg[(ba[i]-start)>>2]>>(target_reg&63))&1)<<r;
6553                 }
6554               }
6555             }
6556           //}
6557             // Merge in delay slot
6558             for(r=0;r<HOST_REGS;r++) {
6559               if(r!=EXCLUDE_REG) {
6560                 if (1) { // !dops[i].likely) {
6561                   // Might not dirty if likely branch is not taken
6562                   if((branch_regs[i].regmap[r]&63)==dops[i].rt1) will_dirty_i|=1<<r;
6563                   if((branch_regs[i].regmap[r]&63)==dops[i].rt2) will_dirty_i|=1<<r;
6564                   if((branch_regs[i].regmap[r]&63)==dops[i+1].rt1) will_dirty_i|=1<<r;
6565                   if((branch_regs[i].regmap[r]&63)==dops[i+1].rt2) will_dirty_i|=1<<r;
6566                   if((branch_regs[i].regmap[r]&63)>33) will_dirty_i&=~(1<<r);
6567                   if(branch_regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
6568                   if(branch_regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
6569                   //if((regs[i].regmap[r]&63)==dops[i].rt1) will_dirty_i|=1<<r;
6570                   //if((regs[i].regmap[r]&63)==dops[i].rt2) will_dirty_i|=1<<r;
6571                   if((regs[i].regmap[r]&63)==dops[i+1].rt1) will_dirty_i|=1<<r;
6572                   if((regs[i].regmap[r]&63)==dops[i+1].rt2) will_dirty_i|=1<<r;
6573                   if((regs[i].regmap[r]&63)>33) will_dirty_i&=~(1<<r);
6574                   if(regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
6575                   if(regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
6576                 }
6577               }
6578             }
6579           }
6580           // Merge in delay slot (won't dirty)
6581           for(r=0;r<HOST_REGS;r++) {
6582             if(r!=EXCLUDE_REG) {
6583               if((regs[i].regmap[r]&63)==dops[i].rt1) wont_dirty_i|=1<<r;
6584               if((regs[i].regmap[r]&63)==dops[i].rt2) wont_dirty_i|=1<<r;
6585               if((regs[i].regmap[r]&63)==dops[i+1].rt1) wont_dirty_i|=1<<r;
6586               if((regs[i].regmap[r]&63)==dops[i+1].rt2) wont_dirty_i|=1<<r;
6587               if(regs[i].regmap[r]==CCREG) wont_dirty_i|=1<<r;
6588               if((branch_regs[i].regmap[r]&63)==dops[i].rt1) wont_dirty_i|=1<<r;
6589               if((branch_regs[i].regmap[r]&63)==dops[i].rt2) wont_dirty_i|=1<<r;
6590               if((branch_regs[i].regmap[r]&63)==dops[i+1].rt1) wont_dirty_i|=1<<r;
6591               if((branch_regs[i].regmap[r]&63)==dops[i+1].rt2) wont_dirty_i|=1<<r;
6592               if(branch_regs[i].regmap[r]==CCREG) wont_dirty_i|=1<<r;
6593             }
6594           }
6595           if(wr) {
6596             #ifndef DESTRUCTIVE_WRITEBACK
6597             branch_regs[i].dirty&=wont_dirty_i;
6598             #endif
6599             branch_regs[i].dirty|=will_dirty_i;
6600           }
6601         }
6602       }
6603     }
6604     else if(dops[i].itype==SYSCALL||dops[i].itype==HLECALL||dops[i].itype==INTCALL)
6605     {
6606       // SYSCALL instruction (software interrupt)
6607       will_dirty_i=0;
6608       wont_dirty_i=0;
6609     }
6610     else if(dops[i].itype==COP0 && (source[i]&0x3f)==0x18)
6611     {
6612       // ERET instruction (return from interrupt)
6613       will_dirty_i=0;
6614       wont_dirty_i=0;
6615     }
6616     will_dirty_next=will_dirty_i;
6617     wont_dirty_next=wont_dirty_i;
6618     for(r=0;r<HOST_REGS;r++) {
6619       if(r!=EXCLUDE_REG) {
6620         if((regs[i].regmap[r]&63)==dops[i].rt1) will_dirty_i|=1<<r;
6621         if((regs[i].regmap[r]&63)==dops[i].rt2) will_dirty_i|=1<<r;
6622         if((regs[i].regmap[r]&63)>33) will_dirty_i&=~(1<<r);
6623         if(regs[i].regmap[r]<=0) will_dirty_i&=~(1<<r);
6624         if(regs[i].regmap[r]==CCREG) will_dirty_i|=1<<r;
6625         if((regs[i].regmap[r]&63)==dops[i].rt1) wont_dirty_i|=1<<r;
6626         if((regs[i].regmap[r]&63)==dops[i].rt2) wont_dirty_i|=1<<r;
6627         if(regs[i].regmap[r]==CCREG) wont_dirty_i|=1<<r;
6628         if(i>istart) {
6629           if (!dops[i].is_jump)
6630           {
6631             // Don't store a register immediately after writing it,
6632             // may prevent dual-issue.
6633             if((regs[i].regmap[r]&63)==dops[i-1].rt1) wont_dirty_i|=1<<r;
6634             if((regs[i].regmap[r]&63)==dops[i-1].rt2) wont_dirty_i|=1<<r;
6635           }
6636         }
6637       }
6638     }
6639     // Save it
6640     will_dirty[i]=will_dirty_i;
6641     wont_dirty[i]=wont_dirty_i;
6642     // Mark registers that won't be dirtied as not dirty
6643     if(wr) {
6644         regs[i].dirty|=will_dirty_i;
6645         #ifndef DESTRUCTIVE_WRITEBACK
6646         regs[i].dirty&=wont_dirty_i;
6647         if(dops[i].is_jump)
6648         {
6649           if (i < iend-1 && !dops[i].is_ujump) {
6650             for(r=0;r<HOST_REGS;r++) {
6651               if(r!=EXCLUDE_REG) {
6652                 if(regs[i].regmap[r]==regmap_pre[i+2][r]) {
6653                   regs[i+2].wasdirty&=wont_dirty_i|~(1<<r);
6654                 }else {/*printf("i: %x (%d) mismatch(+2): %d\n",start+i*4,i,r);assert(!((wont_dirty_i>>r)&1));*/}
6655               }
6656             }
6657           }
6658         }
6659         else
6660         {
6661           if(i<iend) {
6662             for(r=0;r<HOST_REGS;r++) {
6663               if(r!=EXCLUDE_REG) {
6664                 if(regs[i].regmap[r]==regmap_pre[i+1][r]) {
6665                   regs[i+1].wasdirty&=wont_dirty_i|~(1<<r);
6666                 }else {/*printf("i: %x (%d) mismatch(+1): %d\n",start+i*4,i,r);assert(!((wont_dirty_i>>r)&1));*/}
6667               }
6668             }
6669           }
6670         }
6671         #endif
6672       //}
6673     }
6674     // Deal with changed mappings
6675     temp_will_dirty=will_dirty_i;
6676     temp_wont_dirty=wont_dirty_i;
6677     for(r=0;r<HOST_REGS;r++) {
6678       if(r!=EXCLUDE_REG) {
6679         int nr;
6680         if(regs[i].regmap[r]==regmap_pre[i][r]) {
6681           if(wr) {
6682             #ifndef DESTRUCTIVE_WRITEBACK
6683             regs[i].wasdirty&=wont_dirty_i|~(1<<r);
6684             #endif
6685             regs[i].wasdirty|=will_dirty_i&(1<<r);
6686           }
6687         }
6688         else if(regmap_pre[i][r]>=0&&(nr=get_reg(regs[i].regmap,regmap_pre[i][r]))>=0) {
6689           // Register moved to a different register
6690           will_dirty_i&=~(1<<r);
6691           wont_dirty_i&=~(1<<r);
6692           will_dirty_i|=((temp_will_dirty>>nr)&1)<<r;
6693           wont_dirty_i|=((temp_wont_dirty>>nr)&1)<<r;
6694           if(wr) {
6695             #ifndef DESTRUCTIVE_WRITEBACK
6696             regs[i].wasdirty&=wont_dirty_i|~(1<<r);
6697             #endif
6698             regs[i].wasdirty|=will_dirty_i&(1<<r);
6699           }
6700         }
6701         else {
6702           will_dirty_i&=~(1<<r);
6703           wont_dirty_i&=~(1<<r);
6704           if((regmap_pre[i][r]&63)>0 && (regmap_pre[i][r]&63)<34) {
6705             will_dirty_i|=((unneeded_reg[i]>>(regmap_pre[i][r]&63))&1)<<r;
6706             wont_dirty_i|=((unneeded_reg[i]>>(regmap_pre[i][r]&63))&1)<<r;
6707           } else {
6708             wont_dirty_i|=1<<r;
6709             /*printf("i: %x (%d) mismatch: %d\n",start+i*4,i,r);assert(!((will_dirty>>r)&1));*/
6710           }
6711         }
6712       }
6713     }
6714   }
6715 }
6716
6717 #ifdef DISASM
6718   /* disassembly */
6719 void disassemble_inst(int i)
6720 {
6721     if (dops[i].bt) printf("*"); else printf(" ");
6722     switch(dops[i].itype) {
6723       case UJUMP:
6724         printf (" %x: %s %8x\n",start+i*4,insn[i],ba[i]);break;
6725       case CJUMP:
6726         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;
6727       case SJUMP:
6728         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;
6729       case RJUMP:
6730         if (dops[i].opcode==0x9&&dops[i].rt1!=31)
6731           printf (" %x: %s r%d,r%d\n",start+i*4,insn[i],dops[i].rt1,dops[i].rs1);
6732         else
6733           printf (" %x: %s r%d\n",start+i*4,insn[i],dops[i].rs1);
6734         break;
6735       case SPAN:
6736         printf (" %x: %s (pagespan) r%d,r%d,%8x\n",start+i*4,insn[i],dops[i].rs1,dops[i].rs2,ba[i]);break;
6737       case IMM16:
6738         if(dops[i].opcode==0xf) //LUI
6739           printf (" %x: %s r%d,%4x0000\n",start+i*4,insn[i],dops[i].rt1,imm[i]&0xffff);
6740         else
6741           printf (" %x: %s r%d,r%d,%d\n",start+i*4,insn[i],dops[i].rt1,dops[i].rs1,imm[i]);
6742         break;
6743       case LOAD:
6744       case LOADLR:
6745         printf (" %x: %s r%d,r%d+%x\n",start+i*4,insn[i],dops[i].rt1,dops[i].rs1,imm[i]);
6746         break;
6747       case STORE:
6748       case STORELR:
6749         printf (" %x: %s r%d,r%d+%x\n",start+i*4,insn[i],dops[i].rs2,dops[i].rs1,imm[i]);
6750         break;
6751       case ALU:
6752       case SHIFT:
6753         printf (" %x: %s r%d,r%d,r%d\n",start+i*4,insn[i],dops[i].rt1,dops[i].rs1,dops[i].rs2);
6754         break;
6755       case MULTDIV:
6756         printf (" %x: %s r%d,r%d\n",start+i*4,insn[i],dops[i].rs1,dops[i].rs2);
6757         break;
6758       case SHIFTIMM:
6759         printf (" %x: %s r%d,r%d,%d\n",start+i*4,insn[i],dops[i].rt1,dops[i].rs1,imm[i]);
6760         break;
6761       case MOV:
6762         if((dops[i].opcode2&0x1d)==0x10)
6763           printf (" %x: %s r%d\n",start+i*4,insn[i],dops[i].rt1);
6764         else if((dops[i].opcode2&0x1d)==0x11)
6765           printf (" %x: %s r%d\n",start+i*4,insn[i],dops[i].rs1);
6766         else
6767           printf (" %x: %s\n",start+i*4,insn[i]);
6768         break;
6769       case COP0:
6770         if(dops[i].opcode2==0)
6771           printf (" %x: %s r%d,cpr0[%d]\n",start+i*4,insn[i],dops[i].rt1,(source[i]>>11)&0x1f); // MFC0
6772         else if(dops[i].opcode2==4)
6773           printf (" %x: %s r%d,cpr0[%d]\n",start+i*4,insn[i],dops[i].rs1,(source[i]>>11)&0x1f); // MTC0
6774         else printf (" %x: %s\n",start+i*4,insn[i]);
6775         break;
6776       case COP1:
6777         if(dops[i].opcode2<3)
6778           printf (" %x: %s r%d,cpr1[%d]\n",start+i*4,insn[i],dops[i].rt1,(source[i]>>11)&0x1f); // MFC1
6779         else if(dops[i].opcode2>3)
6780           printf (" %x: %s r%d,cpr1[%d]\n",start+i*4,insn[i],dops[i].rs1,(source[i]>>11)&0x1f); // MTC1
6781         else printf (" %x: %s\n",start+i*4,insn[i]);
6782         break;
6783       case COP2:
6784         if(dops[i].opcode2<3)
6785           printf (" %x: %s r%d,cpr2[%d]\n",start+i*4,insn[i],dops[i].rt1,(source[i]>>11)&0x1f); // MFC2
6786         else if(dops[i].opcode2>3)
6787           printf (" %x: %s r%d,cpr2[%d]\n",start+i*4,insn[i],dops[i].rs1,(source[i]>>11)&0x1f); // MTC2
6788         else printf (" %x: %s\n",start+i*4,insn[i]);
6789         break;
6790       case C1LS:
6791         printf (" %x: %s cpr1[%d],r%d+%x\n",start+i*4,insn[i],(source[i]>>16)&0x1f,dops[i].rs1,imm[i]);
6792         break;
6793       case C2LS:
6794         printf (" %x: %s cpr2[%d],r%d+%x\n",start+i*4,insn[i],(source[i]>>16)&0x1f,dops[i].rs1,imm[i]);
6795         break;
6796       case INTCALL:
6797         printf (" %x: %s (INTCALL)\n",start+i*4,insn[i]);
6798         break;
6799       default:
6800         //printf (" %s %8x\n",insn[i],source[i]);
6801         printf (" %x: %s\n",start+i*4,insn[i]);
6802     }
6803 }
6804 #else
6805 static void disassemble_inst(int i) {}
6806 #endif // DISASM
6807
6808 #define DRC_TEST_VAL 0x74657374
6809
6810 static void new_dynarec_test(void)
6811 {
6812   int (*testfunc)(void);
6813   void *beginning;
6814   int ret[2];
6815   size_t i;
6816
6817   // check structure linkage
6818   if ((u_char *)rcnts - (u_char *)&psxRegs != sizeof(psxRegs))
6819   {
6820     SysPrintf("linkage_arm* miscompilation/breakage detected.\n");
6821   }
6822
6823   SysPrintf("testing if we can run recompiled code @%p...\n", out);
6824   ((volatile u_int *)out)[0]++; // make cache dirty
6825
6826   for (i = 0; i < ARRAY_SIZE(ret); i++) {
6827     out = ndrc->translation_cache;
6828     beginning = start_block();
6829     emit_movimm(DRC_TEST_VAL + i, 0); // test
6830     emit_ret();
6831     literal_pool(0);
6832     end_block(beginning);
6833     testfunc = beginning;
6834     ret[i] = testfunc();
6835   }
6836
6837   if (ret[0] == DRC_TEST_VAL && ret[1] == DRC_TEST_VAL + 1)
6838     SysPrintf("test passed.\n");
6839   else
6840     SysPrintf("test failed, will likely crash soon (r=%08x %08x)\n", ret[0], ret[1]);
6841   out = ndrc->translation_cache;
6842 }
6843
6844 // clear the state completely, instead of just marking
6845 // things invalid like invalidate_all_pages() does
6846 void new_dynarec_clear_full(void)
6847 {
6848   int n;
6849   out = ndrc->translation_cache;
6850   memset(invalid_code,1,sizeof(invalid_code));
6851   memset(hash_table,0xff,sizeof(hash_table));
6852   memset(mini_ht,-1,sizeof(mini_ht));
6853   memset(restore_candidate,0,sizeof(restore_candidate));
6854   memset(shadow,0,sizeof(shadow));
6855   copy=shadow;
6856   expirep=16384; // Expiry pointer, +2 blocks
6857   pending_exception=0;
6858   literalcount=0;
6859   stop_after_jal=0;
6860   inv_code_start=inv_code_end=~0;
6861   hack_addr=0;
6862   f1_hack=0;
6863   // TLB
6864   for(n=0;n<4096;n++) ll_clear(jump_in+n);
6865   for(n=0;n<4096;n++) ll_clear(jump_out+n);
6866   for(n=0;n<4096;n++) ll_clear(jump_dirty+n);
6867
6868   cycle_multiplier_old = cycle_multiplier;
6869   new_dynarec_hacks_old = new_dynarec_hacks;
6870 }
6871
6872 void new_dynarec_init(void)
6873 {
6874   SysPrintf("Init new dynarec, ndrc size %x\n", (int)sizeof(*ndrc));
6875
6876 #ifdef _3DS
6877   check_rosalina();
6878 #endif
6879 #ifdef BASE_ADDR_DYNAMIC
6880   #ifdef VITA
6881   sceBlock = getVMBlock(); //sceKernelAllocMemBlockForVM("code", sizeof(*ndrc));
6882   if (sceBlock <= 0)
6883     SysPrintf("sceKernelAllocMemBlockForVM failed: %x\n", sceBlock);
6884   int ret = sceKernelGetMemBlockBase(sceBlock, (void **)&ndrc);
6885   if (ret < 0)
6886     SysPrintf("sceKernelGetMemBlockBase failed: %x\n", ret);
6887   sceKernelOpenVMDomain();
6888   sceClibPrintf("translation_cache = 0x%08lx\n ", (long)ndrc->translation_cache);
6889   #elif defined(_MSC_VER)
6890   ndrc = VirtualAlloc(NULL, sizeof(*ndrc), MEM_COMMIT | MEM_RESERVE,
6891     PAGE_EXECUTE_READWRITE);
6892   #else
6893   uintptr_t desired_addr = 0;
6894   #ifdef __ELF__
6895   extern char _end;
6896   desired_addr = ((uintptr_t)&_end + 0xffffff) & ~0xffffffl;
6897   #endif
6898   ndrc = mmap((void *)desired_addr, sizeof(*ndrc),
6899             PROT_READ | PROT_WRITE | PROT_EXEC,
6900             MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
6901   if (ndrc == MAP_FAILED) {
6902     SysPrintf("mmap() failed: %s\n", strerror(errno));
6903     abort();
6904   }
6905   #endif
6906 #else
6907   #ifndef NO_WRITE_EXEC
6908   // not all systems allow execute in data segment by default
6909   // size must be 4K aligned for 3DS?
6910   if (mprotect(ndrc, sizeof(*ndrc),
6911                PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
6912     SysPrintf("mprotect() failed: %s\n", strerror(errno));
6913   #endif
6914 #endif
6915   out = ndrc->translation_cache;
6916   cycle_multiplier=200;
6917   new_dynarec_clear_full();
6918 #ifdef HOST_IMM8
6919   // Copy this into local area so we don't have to put it in every literal pool
6920   invc_ptr=invalid_code;
6921 #endif
6922   arch_init();
6923   new_dynarec_test();
6924   ram_offset=(uintptr_t)rdram-0x80000000;
6925   if (ram_offset!=0)
6926     SysPrintf("warning: RAM is not directly mapped, performance will suffer\n");
6927 }
6928
6929 void new_dynarec_cleanup(void)
6930 {
6931   int n;
6932 #ifdef BASE_ADDR_DYNAMIC
6933   #ifdef VITA
6934   // sceBlock is managed by retroarch's bootstrap code
6935   //sceKernelFreeMemBlock(sceBlock);
6936   //sceBlock = -1;
6937   #else
6938   if (munmap(ndrc, sizeof(*ndrc)) < 0)
6939     SysPrintf("munmap() failed\n");
6940   #endif
6941 #endif
6942   for(n=0;n<4096;n++) ll_clear(jump_in+n);
6943   for(n=0;n<4096;n++) ll_clear(jump_out+n);
6944   for(n=0;n<4096;n++) ll_clear(jump_dirty+n);
6945   #ifdef ROM_COPY
6946   if (munmap (ROM_COPY, 67108864) < 0) {SysPrintf("munmap() failed\n");}
6947   #endif
6948 }
6949
6950 static u_int *get_source_start(u_int addr, u_int *limit)
6951 {
6952   if (addr < 0x00200000 ||
6953     (0xa0000000 <= addr && addr < 0xa0200000))
6954   {
6955     // used for BIOS calls mostly?
6956     *limit = (addr&0xa0000000)|0x00200000;
6957     return (u_int *)(rdram + (addr&0x1fffff));
6958   }
6959   else if (!Config.HLE && (
6960     /* (0x9fc00000 <= addr && addr < 0x9fc80000) ||*/
6961     (0xbfc00000 <= addr && addr < 0xbfc80000)))
6962   {
6963     // BIOS. The multiplier should be much higher as it's uncached 8bit mem,
6964     // but timings in PCSX are too tied to the interpreter's BIAS
6965     if (!HACK_ENABLED(NDHACK_OVERRIDE_CYCLE_M))
6966       cycle_multiplier_active = 200;
6967
6968     *limit = (addr & 0xfff00000) | 0x80000;
6969     return (u_int *)((u_char *)psxR + (addr&0x7ffff));
6970   }
6971   else if (addr >= 0x80000000 && addr < 0x80000000+RAM_SIZE) {
6972     *limit = (addr & 0x80600000) + 0x00200000;
6973     return (u_int *)(rdram + (addr&0x1fffff));
6974   }
6975   return NULL;
6976 }
6977
6978 static u_int scan_for_ret(u_int addr)
6979 {
6980   u_int limit = 0;
6981   u_int *mem;
6982
6983   mem = get_source_start(addr, &limit);
6984   if (mem == NULL)
6985     return addr;
6986
6987   if (limit > addr + 0x1000)
6988     limit = addr + 0x1000;
6989   for (; addr < limit; addr += 4, mem++) {
6990     if (*mem == 0x03e00008) // jr $ra
6991       return addr + 8;
6992   }
6993   return addr;
6994 }
6995
6996 struct savestate_block {
6997   uint32_t addr;
6998   uint32_t regflags;
6999 };
7000
7001 static int addr_cmp(const void *p1_, const void *p2_)
7002 {
7003   const struct savestate_block *p1 = p1_, *p2 = p2_;
7004   return p1->addr - p2->addr;
7005 }
7006
7007 int new_dynarec_save_blocks(void *save, int size)
7008 {
7009   struct savestate_block *blocks = save;
7010   int maxcount = size / sizeof(blocks[0]);
7011   struct savestate_block tmp_blocks[1024];
7012   struct ll_entry *head;
7013   int p, s, d, o, bcnt;
7014   u_int addr;
7015
7016   o = 0;
7017   for (p = 0; p < ARRAY_SIZE(jump_in); p++) {
7018     bcnt = 0;
7019     for (head = jump_in[p]; head != NULL; head = head->next) {
7020       tmp_blocks[bcnt].addr = head->vaddr;
7021       tmp_blocks[bcnt].regflags = head->reg_sv_flags;
7022       bcnt++;
7023     }
7024     if (bcnt < 1)
7025       continue;
7026     qsort(tmp_blocks, bcnt, sizeof(tmp_blocks[0]), addr_cmp);
7027
7028     addr = tmp_blocks[0].addr;
7029     for (s = d = 0; s < bcnt; s++) {
7030       if (tmp_blocks[s].addr < addr)
7031         continue;
7032       if (d == 0 || tmp_blocks[d-1].addr != tmp_blocks[s].addr)
7033         tmp_blocks[d++] = tmp_blocks[s];
7034       addr = scan_for_ret(tmp_blocks[s].addr);
7035     }
7036
7037     if (o + d > maxcount)
7038       d = maxcount - o;
7039     memcpy(&blocks[o], tmp_blocks, d * sizeof(blocks[0]));
7040     o += d;
7041   }
7042
7043   return o * sizeof(blocks[0]);
7044 }
7045
7046 void new_dynarec_load_blocks(const void *save, int size)
7047 {
7048   const struct savestate_block *blocks = save;
7049   int count = size / sizeof(blocks[0]);
7050   u_int regs_save[32];
7051   uint32_t f;
7052   int i, b;
7053
7054   get_addr(psxRegs.pc);
7055
7056   // change GPRs for speculation to at least partially work..
7057   memcpy(regs_save, &psxRegs.GPR, sizeof(regs_save));
7058   for (i = 1; i < 32; i++)
7059     psxRegs.GPR.r[i] = 0x80000000;
7060
7061   for (b = 0; b < count; b++) {
7062     for (f = blocks[b].regflags, i = 0; f; f >>= 1, i++) {
7063       if (f & 1)
7064         psxRegs.GPR.r[i] = 0x1f800000;
7065     }
7066
7067     get_addr(blocks[b].addr);
7068
7069     for (f = blocks[b].regflags, i = 0; f; f >>= 1, i++) {
7070       if (f & 1)
7071         psxRegs.GPR.r[i] = 0x80000000;
7072     }
7073   }
7074
7075   memcpy(&psxRegs.GPR, regs_save, sizeof(regs_save));
7076 }
7077
7078 static int apply_hacks(void)
7079 {
7080   int i;
7081   if (HACK_ENABLED(NDHACK_NO_COMPAT_HACKS))
7082     return 0;
7083   /* special hack(s) */
7084   for (i = 0; i < slen - 4; i++)
7085   {
7086     // lui a4, 0xf200; jal <rcnt_read>; addu a0, 2; slti v0, 28224
7087     if (source[i] == 0x3c04f200 && dops[i+1].itype == UJUMP
7088         && source[i+2] == 0x34840002 && dops[i+3].opcode == 0x0a
7089         && imm[i+3] == 0x6e40 && dops[i+3].rs1 == 2)
7090     {
7091       SysPrintf("PE2 hack @%08x\n", start + (i+3)*4);
7092       dops[i + 3].itype = NOP;
7093     }
7094   }
7095   i = slen;
7096   if (i > 10 && source[i-1] == 0 && source[i-2] == 0x03e00008
7097       && source[i-4] == 0x8fbf0018 && source[i-6] == 0x00c0f809
7098       && dops[i-7].itype == STORE)
7099   {
7100     i = i-8;
7101     if (dops[i].itype == IMM16)
7102       i--;
7103     // swl r2, 15(r6); swr r2, 12(r6); sw r6, *; jalr r6
7104     if (dops[i].itype == STORELR && dops[i].rs1 == 6
7105       && dops[i-1].itype == STORELR && dops[i-1].rs1 == 6)
7106     {
7107       SysPrintf("F1 hack from %08x, old dst %08x\n", start, hack_addr);
7108       f1_hack = 1;
7109       return 1;
7110     }
7111   }
7112   return 0;
7113 }
7114
7115 int new_recompile_block(u_int addr)
7116 {
7117   u_int pagelimit = 0;
7118   u_int state_rflags = 0;
7119   int i;
7120
7121   assem_debug("NOTCOMPILED: addr = %x -> %p\n", addr, out);
7122   //printf("TRACE: count=%d next=%d (compile %x)\n",Count,next_interupt,addr);
7123   //if(debug)
7124   //printf("fpu mapping=%x enabled=%x\n",(Status & 0x04000000)>>26,(Status & 0x20000000)>>29);
7125
7126   // this is just for speculation
7127   for (i = 1; i < 32; i++) {
7128     if ((psxRegs.GPR.r[i] & 0xffff0000) == 0x1f800000)
7129       state_rflags |= 1 << i;
7130   }
7131
7132   start = (u_int)addr&~3;
7133   //assert(((u_int)addr&1)==0); // start-in-delay-slot flag
7134   new_dynarec_did_compile=1;
7135   if (Config.HLE && start == 0x80001000) // hlecall
7136   {
7137     // XXX: is this enough? Maybe check hleSoftCall?
7138     void *beginning=start_block();
7139     u_int page=get_page(start);
7140
7141     invalid_code[start>>12]=0;
7142     emit_movimm(start,0);
7143     emit_writeword(0,&pcaddr);
7144     emit_far_jump(new_dyna_leave);
7145     literal_pool(0);
7146     end_block(beginning);
7147     ll_add_flags(jump_in+page,start,state_rflags,(void *)beginning);
7148     return 0;
7149   }
7150   else if (f1_hack && hack_addr == 0) {
7151     void *beginning = start_block();
7152     u_int page = get_page(start);
7153     emit_movimm(start, 0);
7154     emit_writeword(0, &hack_addr);
7155     emit_readword(&psxRegs.GPR.n.sp, 0);
7156     emit_readptr(&mem_rtab, 1);
7157     emit_shrimm(0, 12, 2);
7158     emit_readptr_dualindexedx_ptrlen(1, 2, 1);
7159     emit_addimm(0, 0x18, 0);
7160     emit_adds_ptr(1, 1, 1);
7161     emit_ldr_dualindexed(1, 0, 0);
7162     emit_writeword(0, &psxRegs.GPR.r[26]); // lw k0, 0x18(sp)
7163     emit_far_call(get_addr_ht);
7164     emit_jmpreg(0); // jr k0
7165     literal_pool(0);
7166     end_block(beginning);
7167
7168     ll_add_flags(jump_in + page, start, state_rflags, beginning);
7169     SysPrintf("F1 hack to   %08x\n", start);
7170     return 0;
7171   }
7172
7173   cycle_multiplier_active = cycle_multiplier_override && cycle_multiplier == CYCLE_MULT_DEFAULT
7174     ? cycle_multiplier_override : cycle_multiplier;
7175
7176   source = get_source_start(start, &pagelimit);
7177   if (source == NULL) {
7178     SysPrintf("Compile at bogus memory address: %08x\n", addr);
7179     abort();
7180   }
7181
7182   /* Pass 1: disassemble */
7183   /* Pass 2: register dependencies, branch targets */
7184   /* Pass 3: register allocation */
7185   /* Pass 4: branch dependencies */
7186   /* Pass 5: pre-alloc */
7187   /* Pass 6: optimize clean/dirty state */
7188   /* Pass 7: flag 32-bit registers */
7189   /* Pass 8: assembly */
7190   /* Pass 9: linker */
7191   /* Pass 10: garbage collection / free memory */
7192
7193   int j;
7194   int done=0;
7195   unsigned int type,op,op2;
7196
7197   //printf("addr = %x source = %x %x\n", addr,source,source[0]);
7198
7199   /* Pass 1 disassembly */
7200
7201   for (i = 0; !done; i++)
7202   {
7203     memset(&dops[i], 0, sizeof(dops[i]));
7204     op2=0;
7205     minimum_free_regs[i]=0;
7206     dops[i].opcode=op=source[i]>>26;
7207     switch(op)
7208     {
7209       case 0x00: strcpy(insn[i],"special"); type=NI;
7210         op2=source[i]&0x3f;
7211         switch(op2)
7212         {
7213           case 0x00: strcpy(insn[i],"SLL"); type=SHIFTIMM; break;
7214           case 0x02: strcpy(insn[i],"SRL"); type=SHIFTIMM; break;
7215           case 0x03: strcpy(insn[i],"SRA"); type=SHIFTIMM; break;
7216           case 0x04: strcpy(insn[i],"SLLV"); type=SHIFT; break;
7217           case 0x06: strcpy(insn[i],"SRLV"); type=SHIFT; break;
7218           case 0x07: strcpy(insn[i],"SRAV"); type=SHIFT; break;
7219           case 0x08: strcpy(insn[i],"JR"); type=RJUMP; break;
7220           case 0x09: strcpy(insn[i],"JALR"); type=RJUMP; break;
7221           case 0x0C: strcpy(insn[i],"SYSCALL"); type=SYSCALL; break;
7222           case 0x0D: strcpy(insn[i],"BREAK"); type=SYSCALL; break;
7223           case 0x0F: strcpy(insn[i],"SYNC"); type=OTHER; break;
7224           case 0x10: strcpy(insn[i],"MFHI"); type=MOV; break;
7225           case 0x11: strcpy(insn[i],"MTHI"); type=MOV; break;
7226           case 0x12: strcpy(insn[i],"MFLO"); type=MOV; break;
7227           case 0x13: strcpy(insn[i],"MTLO"); type=MOV; break;
7228           case 0x18: strcpy(insn[i],"MULT"); type=MULTDIV; break;
7229           case 0x19: strcpy(insn[i],"MULTU"); type=MULTDIV; break;
7230           case 0x1A: strcpy(insn[i],"DIV"); type=MULTDIV; break;
7231           case 0x1B: strcpy(insn[i],"DIVU"); type=MULTDIV; break;
7232           case 0x20: strcpy(insn[i],"ADD"); type=ALU; break;
7233           case 0x21: strcpy(insn[i],"ADDU"); type=ALU; break;
7234           case 0x22: strcpy(insn[i],"SUB"); type=ALU; break;
7235           case 0x23: strcpy(insn[i],"SUBU"); type=ALU; break;
7236           case 0x24: strcpy(insn[i],"AND"); type=ALU; break;
7237           case 0x25: strcpy(insn[i],"OR"); type=ALU; break;
7238           case 0x26: strcpy(insn[i],"XOR"); type=ALU; break;
7239           case 0x27: strcpy(insn[i],"NOR"); type=ALU; break;
7240           case 0x2A: strcpy(insn[i],"SLT"); type=ALU; break;
7241           case 0x2B: strcpy(insn[i],"SLTU"); type=ALU; break;
7242           case 0x30: strcpy(insn[i],"TGE"); type=NI; break;
7243           case 0x31: strcpy(insn[i],"TGEU"); type=NI; break;
7244           case 0x32: strcpy(insn[i],"TLT"); type=NI; break;
7245           case 0x33: strcpy(insn[i],"TLTU"); type=NI; break;
7246           case 0x34: strcpy(insn[i],"TEQ"); type=NI; break;
7247           case 0x36: strcpy(insn[i],"TNE"); type=NI; break;
7248 #if 0
7249           case 0x14: strcpy(insn[i],"DSLLV"); type=SHIFT; break;
7250           case 0x16: strcpy(insn[i],"DSRLV"); type=SHIFT; break;
7251           case 0x17: strcpy(insn[i],"DSRAV"); type=SHIFT; break;
7252           case 0x1C: strcpy(insn[i],"DMULT"); type=MULTDIV; break;
7253           case 0x1D: strcpy(insn[i],"DMULTU"); type=MULTDIV; break;
7254           case 0x1E: strcpy(insn[i],"DDIV"); type=MULTDIV; break;
7255           case 0x1F: strcpy(insn[i],"DDIVU"); type=MULTDIV; break;
7256           case 0x2C: strcpy(insn[i],"DADD"); type=ALU; break;
7257           case 0x2D: strcpy(insn[i],"DADDU"); type=ALU; break;
7258           case 0x2E: strcpy(insn[i],"DSUB"); type=ALU; break;
7259           case 0x2F: strcpy(insn[i],"DSUBU"); type=ALU; break;
7260           case 0x38: strcpy(insn[i],"DSLL"); type=SHIFTIMM; break;
7261           case 0x3A: strcpy(insn[i],"DSRL"); type=SHIFTIMM; break;
7262           case 0x3B: strcpy(insn[i],"DSRA"); type=SHIFTIMM; break;
7263           case 0x3C: strcpy(insn[i],"DSLL32"); type=SHIFTIMM; break;
7264           case 0x3E: strcpy(insn[i],"DSRL32"); type=SHIFTIMM; break;
7265           case 0x3F: strcpy(insn[i],"DSRA32"); type=SHIFTIMM; break;
7266 #endif
7267         }
7268         break;
7269       case 0x01: strcpy(insn[i],"regimm"); type=NI;
7270         op2=(source[i]>>16)&0x1f;
7271         switch(op2)
7272         {
7273           case 0x00: strcpy(insn[i],"BLTZ"); type=SJUMP; break;
7274           case 0x01: strcpy(insn[i],"BGEZ"); type=SJUMP; break;
7275           //case 0x02: strcpy(insn[i],"BLTZL"); type=SJUMP; break;
7276           //case 0x03: strcpy(insn[i],"BGEZL"); type=SJUMP; break;
7277           //case 0x08: strcpy(insn[i],"TGEI"); type=NI; break;
7278           //case 0x09: strcpy(insn[i],"TGEIU"); type=NI; break;
7279           //case 0x0A: strcpy(insn[i],"TLTI"); type=NI; break;
7280           //case 0x0B: strcpy(insn[i],"TLTIU"); type=NI; break;
7281           //case 0x0C: strcpy(insn[i],"TEQI"); type=NI; break;
7282           //case 0x0E: strcpy(insn[i],"TNEI"); type=NI; break;
7283           case 0x10: strcpy(insn[i],"BLTZAL"); type=SJUMP; break;
7284           case 0x11: strcpy(insn[i],"BGEZAL"); type=SJUMP; break;
7285           //case 0x12: strcpy(insn[i],"BLTZALL"); type=SJUMP; break;
7286           //case 0x13: strcpy(insn[i],"BGEZALL"); type=SJUMP; break;
7287         }
7288         break;
7289       case 0x02: strcpy(insn[i],"J"); type=UJUMP; break;
7290       case 0x03: strcpy(insn[i],"JAL"); type=UJUMP; break;
7291       case 0x04: strcpy(insn[i],"BEQ"); type=CJUMP; break;
7292       case 0x05: strcpy(insn[i],"BNE"); type=CJUMP; break;
7293       case 0x06: strcpy(insn[i],"BLEZ"); type=CJUMP; break;
7294       case 0x07: strcpy(insn[i],"BGTZ"); type=CJUMP; break;
7295       case 0x08: strcpy(insn[i],"ADDI"); type=IMM16; break;
7296       case 0x09: strcpy(insn[i],"ADDIU"); type=IMM16; break;
7297       case 0x0A: strcpy(insn[i],"SLTI"); type=IMM16; break;
7298       case 0x0B: strcpy(insn[i],"SLTIU"); type=IMM16; break;
7299       case 0x0C: strcpy(insn[i],"ANDI"); type=IMM16; break;
7300       case 0x0D: strcpy(insn[i],"ORI"); type=IMM16; break;
7301       case 0x0E: strcpy(insn[i],"XORI"); type=IMM16; break;
7302       case 0x0F: strcpy(insn[i],"LUI"); type=IMM16; break;
7303       case 0x10: strcpy(insn[i],"cop0"); type=NI;
7304         op2=(source[i]>>21)&0x1f;
7305         switch(op2)
7306         {
7307           case 0x00: strcpy(insn[i],"MFC0"); type=COP0; break;
7308           case 0x02: strcpy(insn[i],"CFC0"); type=COP0; break;
7309           case 0x04: strcpy(insn[i],"MTC0"); type=COP0; break;
7310           case 0x06: strcpy(insn[i],"CTC0"); type=COP0; break;
7311           case 0x10: strcpy(insn[i],"RFE"); type=COP0; break;
7312         }
7313         break;
7314       case 0x11: strcpy(insn[i],"cop1"); type=COP1;
7315         op2=(source[i]>>21)&0x1f;
7316         break;
7317 #if 0
7318       case 0x14: strcpy(insn[i],"BEQL"); type=CJUMP; break;
7319       case 0x15: strcpy(insn[i],"BNEL"); type=CJUMP; break;
7320       case 0x16: strcpy(insn[i],"BLEZL"); type=CJUMP; break;
7321       case 0x17: strcpy(insn[i],"BGTZL"); type=CJUMP; break;
7322       case 0x18: strcpy(insn[i],"DADDI"); type=IMM16; break;
7323       case 0x19: strcpy(insn[i],"DADDIU"); type=IMM16; break;
7324       case 0x1A: strcpy(insn[i],"LDL"); type=LOADLR; break;
7325       case 0x1B: strcpy(insn[i],"LDR"); type=LOADLR; break;
7326 #endif
7327       case 0x20: strcpy(insn[i],"LB"); type=LOAD; break;
7328       case 0x21: strcpy(insn[i],"LH"); type=LOAD; break;
7329       case 0x22: strcpy(insn[i],"LWL"); type=LOADLR; break;
7330       case 0x23: strcpy(insn[i],"LW"); type=LOAD; break;
7331       case 0x24: strcpy(insn[i],"LBU"); type=LOAD; break;
7332       case 0x25: strcpy(insn[i],"LHU"); type=LOAD; break;
7333       case 0x26: strcpy(insn[i],"LWR"); type=LOADLR; break;
7334 #if 0
7335       case 0x27: strcpy(insn[i],"LWU"); type=LOAD; break;
7336 #endif
7337       case 0x28: strcpy(insn[i],"SB"); type=STORE; break;
7338       case 0x29: strcpy(insn[i],"SH"); type=STORE; break;
7339       case 0x2A: strcpy(insn[i],"SWL"); type=STORELR; break;
7340       case 0x2B: strcpy(insn[i],"SW"); type=STORE; break;
7341 #if 0
7342       case 0x2C: strcpy(insn[i],"SDL"); type=STORELR; break;
7343       case 0x2D: strcpy(insn[i],"SDR"); type=STORELR; break;
7344 #endif
7345       case 0x2E: strcpy(insn[i],"SWR"); type=STORELR; break;
7346       case 0x2F: strcpy(insn[i],"CACHE"); type=NOP; break;
7347       case 0x30: strcpy(insn[i],"LL"); type=NI; break;
7348       case 0x31: strcpy(insn[i],"LWC1"); type=C1LS; break;
7349 #if 0
7350       case 0x34: strcpy(insn[i],"LLD"); type=NI; break;
7351       case 0x35: strcpy(insn[i],"LDC1"); type=C1LS; break;
7352       case 0x37: strcpy(insn[i],"LD"); type=LOAD; break;
7353 #endif
7354       case 0x38: strcpy(insn[i],"SC"); type=NI; break;
7355       case 0x39: strcpy(insn[i],"SWC1"); type=C1LS; break;
7356 #if 0
7357       case 0x3C: strcpy(insn[i],"SCD"); type=NI; break;
7358       case 0x3D: strcpy(insn[i],"SDC1"); type=C1LS; break;
7359       case 0x3F: strcpy(insn[i],"SD"); type=STORE; break;
7360 #endif
7361       case 0x12: strcpy(insn[i],"COP2"); type=NI;
7362         op2=(source[i]>>21)&0x1f;
7363         //if (op2 & 0x10)
7364         if (source[i]&0x3f) { // use this hack to support old savestates with patched gte insns
7365           if (gte_handlers[source[i]&0x3f]!=NULL) {
7366             if (gte_regnames[source[i]&0x3f]!=NULL)
7367               strcpy(insn[i],gte_regnames[source[i]&0x3f]);
7368             else
7369               snprintf(insn[i], sizeof(insn[i]), "COP2 %x", source[i]&0x3f);
7370             type=C2OP;
7371           }
7372         }
7373         else switch(op2)
7374         {
7375           case 0x00: strcpy(insn[i],"MFC2"); type=COP2; break;
7376           case 0x02: strcpy(insn[i],"CFC2"); type=COP2; break;
7377           case 0x04: strcpy(insn[i],"MTC2"); type=COP2; break;
7378           case 0x06: strcpy(insn[i],"CTC2"); type=COP2; break;
7379         }
7380         break;
7381       case 0x32: strcpy(insn[i],"LWC2"); type=C2LS; break;
7382       case 0x3A: strcpy(insn[i],"SWC2"); type=C2LS; break;
7383       case 0x3B: strcpy(insn[i],"HLECALL"); type=HLECALL; break;
7384       default: strcpy(insn[i],"???"); type=NI;
7385         SysPrintf("NI %08x @%08x (%08x)\n", source[i], addr + i*4, addr);
7386         break;
7387     }
7388     dops[i].itype=type;
7389     dops[i].opcode2=op2;
7390     /* Get registers/immediates */
7391     dops[i].lt1=0;
7392     gte_rs[i]=gte_rt[i]=0;
7393     switch(type) {
7394       case LOAD:
7395         dops[i].rs1=(source[i]>>21)&0x1f;
7396         dops[i].rs2=0;
7397         dops[i].rt1=(source[i]>>16)&0x1f;
7398         dops[i].rt2=0;
7399         imm[i]=(short)source[i];
7400         break;
7401       case STORE:
7402       case STORELR:
7403         dops[i].rs1=(source[i]>>21)&0x1f;
7404         dops[i].rs2=(source[i]>>16)&0x1f;
7405         dops[i].rt1=0;
7406         dops[i].rt2=0;
7407         imm[i]=(short)source[i];
7408         break;
7409       case LOADLR:
7410         // LWL/LWR only load part of the register,
7411         // therefore the target register must be treated as a source too
7412         dops[i].rs1=(source[i]>>21)&0x1f;
7413         dops[i].rs2=(source[i]>>16)&0x1f;
7414         dops[i].rt1=(source[i]>>16)&0x1f;
7415         dops[i].rt2=0;
7416         imm[i]=(short)source[i];
7417         break;
7418       case IMM16:
7419         if (op==0x0f) dops[i].rs1=0; // LUI instruction has no source register
7420         else dops[i].rs1=(source[i]>>21)&0x1f;
7421         dops[i].rs2=0;
7422         dops[i].rt1=(source[i]>>16)&0x1f;
7423         dops[i].rt2=0;
7424         if(op>=0x0c&&op<=0x0e) { // ANDI/ORI/XORI
7425           imm[i]=(unsigned short)source[i];
7426         }else{
7427           imm[i]=(short)source[i];
7428         }
7429         break;
7430       case UJUMP:
7431         dops[i].rs1=0;
7432         dops[i].rs2=0;
7433         dops[i].rt1=0;
7434         dops[i].rt2=0;
7435         // The JAL instruction writes to r31.
7436         if (op&1) {
7437           dops[i].rt1=31;
7438         }
7439         dops[i].rs2=CCREG;
7440         break;
7441       case RJUMP:
7442         dops[i].rs1=(source[i]>>21)&0x1f;
7443         dops[i].rs2=0;
7444         dops[i].rt1=0;
7445         dops[i].rt2=0;
7446         // The JALR instruction writes to rd.
7447         if (op2&1) {
7448           dops[i].rt1=(source[i]>>11)&0x1f;
7449         }
7450         dops[i].rs2=CCREG;
7451         break;
7452       case CJUMP:
7453         dops[i].rs1=(source[i]>>21)&0x1f;
7454         dops[i].rs2=(source[i]>>16)&0x1f;
7455         dops[i].rt1=0;
7456         dops[i].rt2=0;
7457         if(op&2) { // BGTZ/BLEZ
7458           dops[i].rs2=0;
7459         }
7460         break;
7461       case SJUMP:
7462         dops[i].rs1=(source[i]>>21)&0x1f;
7463         dops[i].rs2=CCREG;
7464         dops[i].rt1=0;
7465         dops[i].rt2=0;
7466         if(op2&0x10) { // BxxAL
7467           dops[i].rt1=31;
7468           // NOTE: If the branch is not taken, r31 is still overwritten
7469         }
7470         break;
7471       case ALU:
7472         dops[i].rs1=(source[i]>>21)&0x1f; // source
7473         dops[i].rs2=(source[i]>>16)&0x1f; // subtract amount
7474         dops[i].rt1=(source[i]>>11)&0x1f; // destination
7475         dops[i].rt2=0;
7476         break;
7477       case MULTDIV:
7478         dops[i].rs1=(source[i]>>21)&0x1f; // source
7479         dops[i].rs2=(source[i]>>16)&0x1f; // divisor
7480         dops[i].rt1=HIREG;
7481         dops[i].rt2=LOREG;
7482         break;
7483       case MOV:
7484         dops[i].rs1=0;
7485         dops[i].rs2=0;
7486         dops[i].rt1=0;
7487         dops[i].rt2=0;
7488         if(op2==0x10) dops[i].rs1=HIREG; // MFHI
7489         if(op2==0x11) dops[i].rt1=HIREG; // MTHI
7490         if(op2==0x12) dops[i].rs1=LOREG; // MFLO
7491         if(op2==0x13) dops[i].rt1=LOREG; // MTLO
7492         if((op2&0x1d)==0x10) dops[i].rt1=(source[i]>>11)&0x1f; // MFxx
7493         if((op2&0x1d)==0x11) dops[i].rs1=(source[i]>>21)&0x1f; // MTxx
7494         break;
7495       case SHIFT:
7496         dops[i].rs1=(source[i]>>16)&0x1f; // target of shift
7497         dops[i].rs2=(source[i]>>21)&0x1f; // shift amount
7498         dops[i].rt1=(source[i]>>11)&0x1f; // destination
7499         dops[i].rt2=0;
7500         break;
7501       case SHIFTIMM:
7502         dops[i].rs1=(source[i]>>16)&0x1f;
7503         dops[i].rs2=0;
7504         dops[i].rt1=(source[i]>>11)&0x1f;
7505         dops[i].rt2=0;
7506         imm[i]=(source[i]>>6)&0x1f;
7507         // DSxx32 instructions
7508         if(op2>=0x3c) imm[i]|=0x20;
7509         break;
7510       case COP0:
7511         dops[i].rs1=0;
7512         dops[i].rs2=0;
7513         dops[i].rt1=0;
7514         dops[i].rt2=0;
7515         if(op2==0||op2==2) dops[i].rt1=(source[i]>>16)&0x1F; // MFC0/CFC0
7516         if(op2==4||op2==6) dops[i].rs1=(source[i]>>16)&0x1F; // MTC0/CTC0
7517         if(op2==4&&((source[i]>>11)&0x1f)==12) dops[i].rt2=CSREG; // Status
7518         if(op2==16) if((source[i]&0x3f)==0x18) dops[i].rs2=CCREG; // ERET
7519         break;
7520       case COP1:
7521         dops[i].rs1=0;
7522         dops[i].rs2=0;
7523         dops[i].rt1=0;
7524         dops[i].rt2=0;
7525         if(op2<3) dops[i].rt1=(source[i]>>16)&0x1F; // MFC1/DMFC1/CFC1
7526         if(op2>3) dops[i].rs1=(source[i]>>16)&0x1F; // MTC1/DMTC1/CTC1
7527         dops[i].rs2=CSREG;
7528         break;
7529       case COP2:
7530         dops[i].rs1=0;
7531         dops[i].rs2=0;
7532         dops[i].rt1=0;
7533         dops[i].rt2=0;
7534         if(op2<3) dops[i].rt1=(source[i]>>16)&0x1F; // MFC2/CFC2
7535         if(op2>3) dops[i].rs1=(source[i]>>16)&0x1F; // MTC2/CTC2
7536         dops[i].rs2=CSREG;
7537         int gr=(source[i]>>11)&0x1F;
7538         switch(op2)
7539         {
7540           case 0x00: gte_rs[i]=1ll<<gr; break; // MFC2
7541           case 0x04: gte_rt[i]=1ll<<gr; break; // MTC2
7542           case 0x02: gte_rs[i]=1ll<<(gr+32); break; // CFC2
7543           case 0x06: gte_rt[i]=1ll<<(gr+32); break; // CTC2
7544         }
7545         break;
7546       case C1LS:
7547         dops[i].rs1=(source[i]>>21)&0x1F;
7548         dops[i].rs2=CSREG;
7549         dops[i].rt1=0;
7550         dops[i].rt2=0;
7551         imm[i]=(short)source[i];
7552         break;
7553       case C2LS:
7554         dops[i].rs1=(source[i]>>21)&0x1F;
7555         dops[i].rs2=0;
7556         dops[i].rt1=0;
7557         dops[i].rt2=0;
7558         imm[i]=(short)source[i];
7559         if(op==0x32) gte_rt[i]=1ll<<((source[i]>>16)&0x1F); // LWC2
7560         else gte_rs[i]=1ll<<((source[i]>>16)&0x1F); // SWC2
7561         break;
7562       case C2OP:
7563         dops[i].rs1=0;
7564         dops[i].rs2=0;
7565         dops[i].rt1=0;
7566         dops[i].rt2=0;
7567         gte_rs[i]=gte_reg_reads[source[i]&0x3f];
7568         gte_rt[i]=gte_reg_writes[source[i]&0x3f];
7569         gte_rt[i]|=1ll<<63; // every op changes flags
7570         if((source[i]&0x3f)==GTE_MVMVA) {
7571           int v = (source[i] >> 15) & 3;
7572           gte_rs[i]&=~0xe3fll;
7573           if(v==3) gte_rs[i]|=0xe00ll;
7574           else gte_rs[i]|=3ll<<(v*2);
7575         }
7576         break;
7577       case SYSCALL:
7578       case HLECALL:
7579       case INTCALL:
7580         dops[i].rs1=CCREG;
7581         dops[i].rs2=0;
7582         dops[i].rt1=0;
7583         dops[i].rt2=0;
7584         break;
7585       default:
7586         dops[i].rs1=0;
7587         dops[i].rs2=0;
7588         dops[i].rt1=0;
7589         dops[i].rt2=0;
7590     }
7591     /* Calculate branch target addresses */
7592     if(type==UJUMP)
7593       ba[i]=((start+i*4+4)&0xF0000000)|(((unsigned int)source[i]<<6)>>4);
7594     else if(type==CJUMP&&dops[i].rs1==dops[i].rs2&&(op&1))
7595       ba[i]=start+i*4+8; // Ignore never taken branch
7596     else if(type==SJUMP&&dops[i].rs1==0&&!(op2&1))
7597       ba[i]=start+i*4+8; // Ignore never taken branch
7598     else if(type==CJUMP||type==SJUMP)
7599       ba[i]=start+i*4+4+((signed int)((unsigned int)source[i]<<16)>>14);
7600     else ba[i]=-1;
7601
7602     /* simplify always (not)taken branches */
7603     if (type == CJUMP && dops[i].rs1 == dops[i].rs2) {
7604       dops[i].rs1 = dops[i].rs2 = 0;
7605       if (!(op & 1)) {
7606         dops[i].itype = type = UJUMP;
7607         dops[i].rs2 = CCREG;
7608       }
7609     }
7610     else if (type == SJUMP && dops[i].rs1 == 0 && (op2 & 1))
7611       dops[i].itype = type = UJUMP;
7612
7613     dops[i].is_jump = (dops[i].itype == RJUMP || dops[i].itype == UJUMP || dops[i].itype == CJUMP || dops[i].itype == SJUMP);
7614     dops[i].is_ujump = (dops[i].itype == RJUMP || dops[i].itype == UJUMP); // || (source[i] >> 16) == 0x1000 // beq r0,r0
7615     dops[i].is_load = (dops[i].itype == LOAD || dops[i].itype == LOADLR || op == 0x32); // LWC2
7616     dops[i].is_store = (dops[i].itype == STORE || dops[i].itype == STORELR || op == 0x3a); // SWC2
7617
7618     /* messy cases to just pass over to the interpreter */
7619     if (i > 0 && dops[i-1].is_jump) {
7620       int do_in_intrp=0;
7621       // branch in delay slot?
7622       if (dops[i].is_jump) {
7623         // don't handle first branch and call interpreter if it's hit
7624         SysPrintf("branch in delay slot @%08x (%08x)\n", addr + i*4, addr);
7625         do_in_intrp=1;
7626       }
7627       // basic load delay detection
7628       else if((type==LOAD||type==LOADLR||type==COP0||type==COP2||type==C2LS)&&dops[i].rt1!=0) {
7629         int t=(ba[i-1]-start)/4;
7630         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) {
7631           // jump target wants DS result - potential load delay effect
7632           SysPrintf("load delay @%08x (%08x)\n", addr + i*4, addr);
7633           do_in_intrp=1;
7634           dops[t+1].bt=1; // expected return from interpreter
7635         }
7636         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&&
7637               !(i>=3&&dops[i-3].is_jump)) {
7638           // v0 overwrite like this is a sign of trouble, bail out
7639           SysPrintf("v0 overwrite @%08x (%08x)\n", addr + i*4, addr);
7640           do_in_intrp=1;
7641         }
7642       }
7643       if (do_in_intrp) {
7644         memset(&dops[i-1], 0, sizeof(dops[i-1]));
7645         dops[i-1].itype = INTCALL;
7646         dops[i-1].rs1 = CCREG;
7647         ba[i-1] = -1;
7648         done = 2;
7649         i--; // don't compile the DS
7650       }
7651     }
7652
7653     /* Is this the end of the block? */
7654     if (i > 0 && dops[i-1].is_ujump) {
7655       if(dops[i-1].rt1==0) { // Continue past subroutine call (JAL)
7656         done=2;
7657       }
7658       else {
7659         if(stop_after_jal) done=1;
7660         // Stop on BREAK
7661         if((source[i+1]&0xfc00003f)==0x0d) done=1;
7662       }
7663       // Don't recompile stuff that's already compiled
7664       if(check_addr(start+i*4+4)) done=1;
7665       // Don't get too close to the limit
7666       if(i>MAXBLOCK/2) done=1;
7667     }
7668     if (dops[i].itype == SYSCALL || dops[i].itype == HLECALL || dops[i].itype == INTCALL)
7669       done = stop_after_jal ? 1 : 2;
7670     if (done == 2) {
7671       // Does the block continue due to a branch?
7672       for(j=i-1;j>=0;j--)
7673       {
7674         if(ba[j]==start+i*4) done=j=0; // Branch into delay slot
7675         if(ba[j]==start+i*4+4) done=j=0;
7676         if(ba[j]==start+i*4+8) done=j=0;
7677       }
7678     }
7679     //assert(i<MAXBLOCK-1);
7680     if(start+i*4==pagelimit-4) done=1;
7681     assert(start+i*4<pagelimit);
7682     if (i==MAXBLOCK-1) done=1;
7683     // Stop if we're compiling junk
7684     if(dops[i].itype==NI&&dops[i].opcode==0x11) {
7685       done=stop_after_jal=1;
7686       SysPrintf("Disabled speculative precompilation\n");
7687     }
7688   }
7689   slen=i;
7690   if (dops[i-1].is_jump) {
7691     if(start+i*4==pagelimit) {
7692       dops[i-1].itype=SPAN;
7693     }
7694   }
7695   assert(slen>0);
7696
7697   int clear_hack_addr = apply_hacks();
7698
7699   /* Pass 2 - Register dependencies and branch targets */
7700
7701   unneeded_registers(0,slen-1,0);
7702
7703   /* Pass 3 - Register allocation */
7704
7705   struct regstat current; // Current register allocations/status
7706   clear_all_regs(current.regmap_entry);
7707   clear_all_regs(current.regmap);
7708   current.wasdirty = current.dirty = 0;
7709   current.u = unneeded_reg[0];
7710   alloc_reg(&current, 0, CCREG);
7711   dirty_reg(&current, CCREG);
7712   current.wasconst = 0;
7713   current.isconst = 0;
7714   current.loadedconst = 0;
7715   current.waswritten = 0;
7716   int ds=0;
7717   int cc=0;
7718   int hr=-1;
7719
7720   if((u_int)addr&1) {
7721     // First instruction is delay slot
7722     cc=-1;
7723     dops[1].bt=1;
7724     ds=1;
7725     unneeded_reg[0]=1;
7726     current.regmap[HOST_BTREG]=BTREG;
7727   }
7728
7729   for(i=0;i<slen;i++)
7730   {
7731     if(dops[i].bt)
7732     {
7733       int hr;
7734       for(hr=0;hr<HOST_REGS;hr++)
7735       {
7736         // Is this really necessary?
7737         if(current.regmap[hr]==0) current.regmap[hr]=-1;
7738       }
7739       current.isconst=0;
7740       current.waswritten=0;
7741     }
7742
7743     memcpy(regmap_pre[i],current.regmap,sizeof(current.regmap));
7744     regs[i].wasconst=current.isconst;
7745     regs[i].wasdirty=current.dirty;
7746     regs[i].dirty=0;
7747     regs[i].u=0;
7748     regs[i].isconst=0;
7749     regs[i].loadedconst=0;
7750     if (!dops[i].is_jump) {
7751       if(i+1<slen) {
7752         current.u=unneeded_reg[i+1]&~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
7753         current.u|=1;
7754       } else {
7755         current.u=1;
7756       }
7757     } else {
7758       if(i+1<slen) {
7759         current.u=branch_unneeded_reg[i]&~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
7760         current.u&=~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
7761         current.u|=1;
7762       } else {
7763         SysPrintf("oops, branch at end of block with no delay slot @%08x\n", start + i*4);
7764         abort();
7765       }
7766     }
7767     dops[i].is_ds=ds;
7768     if(ds) {
7769       ds=0; // Skip delay slot, already allocated as part of branch
7770       // ...but we need to alloc it in case something jumps here
7771       if(i+1<slen) {
7772         current.u=branch_unneeded_reg[i-1]&unneeded_reg[i+1];
7773       }else{
7774         current.u=branch_unneeded_reg[i-1];
7775       }
7776       current.u&=~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
7777       current.u|=1;
7778       struct regstat temp;
7779       memcpy(&temp,&current,sizeof(current));
7780       temp.wasdirty=temp.dirty;
7781       // TODO: Take into account unconditional branches, as below
7782       delayslot_alloc(&temp,i);
7783       memcpy(regs[i].regmap,temp.regmap,sizeof(temp.regmap));
7784       regs[i].wasdirty=temp.wasdirty;
7785       regs[i].dirty=temp.dirty;
7786       regs[i].isconst=0;
7787       regs[i].wasconst=0;
7788       current.isconst=0;
7789       // Create entry (branch target) regmap
7790       for(hr=0;hr<HOST_REGS;hr++)
7791       {
7792         int r=temp.regmap[hr];
7793         if(r>=0) {
7794           if(r!=regmap_pre[i][hr]) {
7795             regs[i].regmap_entry[hr]=-1;
7796           }
7797           else
7798           {
7799               assert(r < 64);
7800               if((current.u>>r)&1) {
7801                 regs[i].regmap_entry[hr]=-1;
7802                 regs[i].regmap[hr]=-1;
7803                 //Don't clear regs in the delay slot as the branch might need them
7804                 //current.regmap[hr]=-1;
7805               }else
7806                 regs[i].regmap_entry[hr]=r;
7807           }
7808         } else {
7809           // First instruction expects CCREG to be allocated
7810           if(i==0&&hr==HOST_CCREG)
7811             regs[i].regmap_entry[hr]=CCREG;
7812           else
7813             regs[i].regmap_entry[hr]=-1;
7814         }
7815       }
7816     }
7817     else { // Not delay slot
7818       switch(dops[i].itype) {
7819         case UJUMP:
7820           //current.isconst=0; // DEBUG
7821           //current.wasconst=0; // DEBUG
7822           //regs[i].wasconst=0; // DEBUG
7823           clear_const(&current,dops[i].rt1);
7824           alloc_cc(&current,i);
7825           dirty_reg(&current,CCREG);
7826           if (dops[i].rt1==31) {
7827             alloc_reg(&current,i,31);
7828             dirty_reg(&current,31);
7829             //assert(dops[i+1].rs1!=31&&dops[i+1].rs2!=31);
7830             //assert(dops[i+1].rt1!=dops[i].rt1);
7831             #ifdef REG_PREFETCH
7832             alloc_reg(&current,i,PTEMP);
7833             #endif
7834           }
7835           dops[i].ooo=1;
7836           delayslot_alloc(&current,i+1);
7837           //current.isconst=0; // DEBUG
7838           ds=1;
7839           //printf("i=%d, isconst=%x\n",i,current.isconst);
7840           break;
7841         case RJUMP:
7842           //current.isconst=0;
7843           //current.wasconst=0;
7844           //regs[i].wasconst=0;
7845           clear_const(&current,dops[i].rs1);
7846           clear_const(&current,dops[i].rt1);
7847           alloc_cc(&current,i);
7848           dirty_reg(&current,CCREG);
7849           if (!ds_writes_rjump_rs(i)) {
7850             alloc_reg(&current,i,dops[i].rs1);
7851             if (dops[i].rt1!=0) {
7852               alloc_reg(&current,i,dops[i].rt1);
7853               dirty_reg(&current,dops[i].rt1);
7854               assert(dops[i+1].rs1!=dops[i].rt1&&dops[i+1].rs2!=dops[i].rt1);
7855               assert(dops[i+1].rt1!=dops[i].rt1);
7856               #ifdef REG_PREFETCH
7857               alloc_reg(&current,i,PTEMP);
7858               #endif
7859             }
7860             #ifdef USE_MINI_HT
7861             if(dops[i].rs1==31) { // JALR
7862               alloc_reg(&current,i,RHASH);
7863               alloc_reg(&current,i,RHTBL);
7864             }
7865             #endif
7866             delayslot_alloc(&current,i+1);
7867           } else {
7868             // The delay slot overwrites our source register,
7869             // allocate a temporary register to hold the old value.
7870             current.isconst=0;
7871             current.wasconst=0;
7872             regs[i].wasconst=0;
7873             delayslot_alloc(&current,i+1);
7874             current.isconst=0;
7875             alloc_reg(&current,i,RTEMP);
7876           }
7877           //current.isconst=0; // DEBUG
7878           dops[i].ooo=1;
7879           ds=1;
7880           break;
7881         case CJUMP:
7882           //current.isconst=0;
7883           //current.wasconst=0;
7884           //regs[i].wasconst=0;
7885           clear_const(&current,dops[i].rs1);
7886           clear_const(&current,dops[i].rs2);
7887           if((dops[i].opcode&0x3E)==4) // BEQ/BNE
7888           {
7889             alloc_cc(&current,i);
7890             dirty_reg(&current,CCREG);
7891             if(dops[i].rs1) alloc_reg(&current,i,dops[i].rs1);
7892             if(dops[i].rs2) alloc_reg(&current,i,dops[i].rs2);
7893             if((dops[i].rs1&&(dops[i].rs1==dops[i+1].rt1||dops[i].rs1==dops[i+1].rt2))||
7894                (dops[i].rs2&&(dops[i].rs2==dops[i+1].rt1||dops[i].rs2==dops[i+1].rt2))) {
7895               // The delay slot overwrites one of our conditions.
7896               // Allocate the branch condition registers instead.
7897               current.isconst=0;
7898               current.wasconst=0;
7899               regs[i].wasconst=0;
7900               if(dops[i].rs1) alloc_reg(&current,i,dops[i].rs1);
7901               if(dops[i].rs2) alloc_reg(&current,i,dops[i].rs2);
7902             }
7903             else
7904             {
7905               dops[i].ooo=1;
7906               delayslot_alloc(&current,i+1);
7907             }
7908           }
7909           else
7910           if((dops[i].opcode&0x3E)==6) // BLEZ/BGTZ
7911           {
7912             alloc_cc(&current,i);
7913             dirty_reg(&current,CCREG);
7914             alloc_reg(&current,i,dops[i].rs1);
7915             if(dops[i].rs1&&(dops[i].rs1==dops[i+1].rt1||dops[i].rs1==dops[i+1].rt2)) {
7916               // The delay slot overwrites one of our conditions.
7917               // Allocate the branch condition registers instead.
7918               current.isconst=0;
7919               current.wasconst=0;
7920               regs[i].wasconst=0;
7921               if(dops[i].rs1) alloc_reg(&current,i,dops[i].rs1);
7922             }
7923             else
7924             {
7925               dops[i].ooo=1;
7926               delayslot_alloc(&current,i+1);
7927             }
7928           }
7929           else
7930           // Don't alloc the delay slot yet because we might not execute it
7931           if((dops[i].opcode&0x3E)==0x14) // BEQL/BNEL
7932           {
7933             current.isconst=0;
7934             current.wasconst=0;
7935             regs[i].wasconst=0;
7936             alloc_cc(&current,i);
7937             dirty_reg(&current,CCREG);
7938             alloc_reg(&current,i,dops[i].rs1);
7939             alloc_reg(&current,i,dops[i].rs2);
7940           }
7941           else
7942           if((dops[i].opcode&0x3E)==0x16) // BLEZL/BGTZL
7943           {
7944             current.isconst=0;
7945             current.wasconst=0;
7946             regs[i].wasconst=0;
7947             alloc_cc(&current,i);
7948             dirty_reg(&current,CCREG);
7949             alloc_reg(&current,i,dops[i].rs1);
7950           }
7951           ds=1;
7952           //current.isconst=0;
7953           break;
7954         case SJUMP:
7955           //current.isconst=0;
7956           //current.wasconst=0;
7957           //regs[i].wasconst=0;
7958           clear_const(&current,dops[i].rs1);
7959           clear_const(&current,dops[i].rt1);
7960           //if((dops[i].opcode2&0x1E)==0x0) // BLTZ/BGEZ
7961           if((dops[i].opcode2&0x0E)==0x0) // BLTZ/BGEZ
7962           {
7963             alloc_cc(&current,i);
7964             dirty_reg(&current,CCREG);
7965             alloc_reg(&current,i,dops[i].rs1);
7966             if (dops[i].rt1==31) { // BLTZAL/BGEZAL
7967               alloc_reg(&current,i,31);
7968               dirty_reg(&current,31);
7969               //#ifdef REG_PREFETCH
7970               //alloc_reg(&current,i,PTEMP);
7971               //#endif
7972             }
7973             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.
7974                ||(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
7975               // Allocate the branch condition registers instead.
7976               current.isconst=0;
7977               current.wasconst=0;
7978               regs[i].wasconst=0;
7979               if(dops[i].rs1) alloc_reg(&current,i,dops[i].rs1);
7980             }
7981             else
7982             {
7983               dops[i].ooo=1;
7984               delayslot_alloc(&current,i+1);
7985             }
7986           }
7987           else
7988           // Don't alloc the delay slot yet because we might not execute it
7989           if((dops[i].opcode2&0x1E)==0x2) // BLTZL/BGEZL
7990           {
7991             current.isconst=0;
7992             current.wasconst=0;
7993             regs[i].wasconst=0;
7994             alloc_cc(&current,i);
7995             dirty_reg(&current,CCREG);
7996             alloc_reg(&current,i,dops[i].rs1);
7997           }
7998           ds=1;
7999           //current.isconst=0;
8000           break;
8001         case IMM16:
8002           imm16_alloc(&current,i);
8003           break;
8004         case LOAD:
8005         case LOADLR:
8006           load_alloc(&current,i);
8007           break;
8008         case STORE:
8009         case STORELR:
8010           store_alloc(&current,i);
8011           break;
8012         case ALU:
8013           alu_alloc(&current,i);
8014           break;
8015         case SHIFT:
8016           shift_alloc(&current,i);
8017           break;
8018         case MULTDIV:
8019           multdiv_alloc(&current,i);
8020           break;
8021         case SHIFTIMM:
8022           shiftimm_alloc(&current,i);
8023           break;
8024         case MOV:
8025           mov_alloc(&current,i);
8026           break;
8027         case COP0:
8028           cop0_alloc(&current,i);
8029           break;
8030         case COP1:
8031           break;
8032         case COP2:
8033           cop2_alloc(&current,i);
8034           break;
8035         case C1LS:
8036           c1ls_alloc(&current,i);
8037           break;
8038         case C2LS:
8039           c2ls_alloc(&current,i);
8040           break;
8041         case C2OP:
8042           c2op_alloc(&current,i);
8043           break;
8044         case SYSCALL:
8045         case HLECALL:
8046         case INTCALL:
8047           syscall_alloc(&current,i);
8048           break;
8049         case SPAN:
8050           pagespan_alloc(&current,i);
8051           break;
8052       }
8053
8054       // Create entry (branch target) regmap
8055       for(hr=0;hr<HOST_REGS;hr++)
8056       {
8057         int r,or;
8058         r=current.regmap[hr];
8059         if(r>=0) {
8060           if(r!=regmap_pre[i][hr]) {
8061             // TODO: delay slot (?)
8062             or=get_reg(regmap_pre[i],r); // Get old mapping for this register
8063             if(or<0||(r&63)>=TEMPREG){
8064               regs[i].regmap_entry[hr]=-1;
8065             }
8066             else
8067             {
8068               // Just move it to a different register
8069               regs[i].regmap_entry[hr]=r;
8070               // If it was dirty before, it's still dirty
8071               if((regs[i].wasdirty>>or)&1) dirty_reg(&current,r&63);
8072             }
8073           }
8074           else
8075           {
8076             // Unneeded
8077             if(r==0){
8078               regs[i].regmap_entry[hr]=0;
8079             }
8080             else
8081             {
8082               assert(r<64);
8083               if((current.u>>r)&1) {
8084                 regs[i].regmap_entry[hr]=-1;
8085                 //regs[i].regmap[hr]=-1;
8086                 current.regmap[hr]=-1;
8087               }else
8088                 regs[i].regmap_entry[hr]=r;
8089             }
8090           }
8091         } else {
8092           // Branches expect CCREG to be allocated at the target
8093           if(regmap_pre[i][hr]==CCREG)
8094             regs[i].regmap_entry[hr]=CCREG;
8095           else
8096             regs[i].regmap_entry[hr]=-1;
8097         }
8098       }
8099       memcpy(regs[i].regmap,current.regmap,sizeof(current.regmap));
8100     }
8101
8102     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)
8103       current.waswritten|=1<<dops[i-1].rs1;
8104     current.waswritten&=~(1<<dops[i].rt1);
8105     current.waswritten&=~(1<<dops[i].rt2);
8106     if((dops[i].itype==STORE||dops[i].itype==STORELR||(dops[i].itype==C2LS&&dops[i].opcode==0x3a))&&(u_int)imm[i]>=0x800)
8107       current.waswritten&=~(1<<dops[i].rs1);
8108
8109     /* Branch post-alloc */
8110     if(i>0)
8111     {
8112       current.wasdirty=current.dirty;
8113       switch(dops[i-1].itype) {
8114         case UJUMP:
8115           memcpy(&branch_regs[i-1],&current,sizeof(current));
8116           branch_regs[i-1].isconst=0;
8117           branch_regs[i-1].wasconst=0;
8118           branch_regs[i-1].u=branch_unneeded_reg[i-1]&~((1LL<<dops[i-1].rs1)|(1LL<<dops[i-1].rs2));
8119           alloc_cc(&branch_regs[i-1],i-1);
8120           dirty_reg(&branch_regs[i-1],CCREG);
8121           if(dops[i-1].rt1==31) { // JAL
8122             alloc_reg(&branch_regs[i-1],i-1,31);
8123             dirty_reg(&branch_regs[i-1],31);
8124           }
8125           memcpy(&branch_regs[i-1].regmap_entry,&branch_regs[i-1].regmap,sizeof(current.regmap));
8126           memcpy(constmap[i],constmap[i-1],sizeof(constmap[i]));
8127           break;
8128         case RJUMP:
8129           memcpy(&branch_regs[i-1],&current,sizeof(current));
8130           branch_regs[i-1].isconst=0;
8131           branch_regs[i-1].wasconst=0;
8132           branch_regs[i-1].u=branch_unneeded_reg[i-1]&~((1LL<<dops[i-1].rs1)|(1LL<<dops[i-1].rs2));
8133           alloc_cc(&branch_regs[i-1],i-1);
8134           dirty_reg(&branch_regs[i-1],CCREG);
8135           alloc_reg(&branch_regs[i-1],i-1,dops[i-1].rs1);
8136           if(dops[i-1].rt1!=0) { // JALR
8137             alloc_reg(&branch_regs[i-1],i-1,dops[i-1].rt1);
8138             dirty_reg(&branch_regs[i-1],dops[i-1].rt1);
8139           }
8140           #ifdef USE_MINI_HT
8141           if(dops[i-1].rs1==31) { // JALR
8142             alloc_reg(&branch_regs[i-1],i-1,RHASH);
8143             alloc_reg(&branch_regs[i-1],i-1,RHTBL);
8144           }
8145           #endif
8146           memcpy(&branch_regs[i-1].regmap_entry,&branch_regs[i-1].regmap,sizeof(current.regmap));
8147           memcpy(constmap[i],constmap[i-1],sizeof(constmap[i]));
8148           break;
8149         case CJUMP:
8150           if((dops[i-1].opcode&0x3E)==4) // BEQ/BNE
8151           {
8152             alloc_cc(&current,i-1);
8153             dirty_reg(&current,CCREG);
8154             if((dops[i-1].rs1&&(dops[i-1].rs1==dops[i].rt1||dops[i-1].rs1==dops[i].rt2))||
8155                (dops[i-1].rs2&&(dops[i-1].rs2==dops[i].rt1||dops[i-1].rs2==dops[i].rt2))) {
8156               // The delay slot overwrote one of our conditions
8157               // Delay slot goes after the test (in order)
8158               current.u=branch_unneeded_reg[i-1]&~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
8159               current.u|=1;
8160               delayslot_alloc(&current,i);
8161               current.isconst=0;
8162             }
8163             else
8164             {
8165               current.u=branch_unneeded_reg[i-1]&~((1LL<<dops[i-1].rs1)|(1LL<<dops[i-1].rs2));
8166               // Alloc the branch condition registers
8167               if(dops[i-1].rs1) alloc_reg(&current,i-1,dops[i-1].rs1);
8168               if(dops[i-1].rs2) alloc_reg(&current,i-1,dops[i-1].rs2);
8169             }
8170             memcpy(&branch_regs[i-1],&current,sizeof(current));
8171             branch_regs[i-1].isconst=0;
8172             branch_regs[i-1].wasconst=0;
8173             memcpy(&branch_regs[i-1].regmap_entry,&current.regmap,sizeof(current.regmap));
8174             memcpy(constmap[i],constmap[i-1],sizeof(constmap[i]));
8175           }
8176           else
8177           if((dops[i-1].opcode&0x3E)==6) // BLEZ/BGTZ
8178           {
8179             alloc_cc(&current,i-1);
8180             dirty_reg(&current,CCREG);
8181             if(dops[i-1].rs1==dops[i].rt1||dops[i-1].rs1==dops[i].rt2) {
8182               // The delay slot overwrote the branch condition
8183               // Delay slot goes after the test (in order)
8184               current.u=branch_unneeded_reg[i-1]&~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
8185               current.u|=1;
8186               delayslot_alloc(&current,i);
8187               current.isconst=0;
8188             }
8189             else
8190             {
8191               current.u=branch_unneeded_reg[i-1]&~(1LL<<dops[i-1].rs1);
8192               // Alloc the branch condition register
8193               alloc_reg(&current,i-1,dops[i-1].rs1);
8194             }
8195             memcpy(&branch_regs[i-1],&current,sizeof(current));
8196             branch_regs[i-1].isconst=0;
8197             branch_regs[i-1].wasconst=0;
8198             memcpy(&branch_regs[i-1].regmap_entry,&current.regmap,sizeof(current.regmap));
8199             memcpy(constmap[i],constmap[i-1],sizeof(constmap[i]));
8200           }
8201           else
8202           // Alloc the delay slot in case the branch is taken
8203           if((dops[i-1].opcode&0x3E)==0x14) // BEQL/BNEL
8204           {
8205             memcpy(&branch_regs[i-1],&current,sizeof(current));
8206             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;
8207             alloc_cc(&branch_regs[i-1],i);
8208             dirty_reg(&branch_regs[i-1],CCREG);
8209             delayslot_alloc(&branch_regs[i-1],i);
8210             branch_regs[i-1].isconst=0;
8211             alloc_reg(&current,i,CCREG); // Not taken path
8212             dirty_reg(&current,CCREG);
8213             memcpy(&branch_regs[i-1].regmap_entry,&branch_regs[i-1].regmap,sizeof(current.regmap));
8214           }
8215           else
8216           if((dops[i-1].opcode&0x3E)==0x16) // BLEZL/BGTZL
8217           {
8218             memcpy(&branch_regs[i-1],&current,sizeof(current));
8219             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;
8220             alloc_cc(&branch_regs[i-1],i);
8221             dirty_reg(&branch_regs[i-1],CCREG);
8222             delayslot_alloc(&branch_regs[i-1],i);
8223             branch_regs[i-1].isconst=0;
8224             alloc_reg(&current,i,CCREG); // Not taken path
8225             dirty_reg(&current,CCREG);
8226             memcpy(&branch_regs[i-1].regmap_entry,&branch_regs[i-1].regmap,sizeof(current.regmap));
8227           }
8228           break;
8229         case SJUMP:
8230           //if((dops[i-1].opcode2&0x1E)==0) // BLTZ/BGEZ
8231           if((dops[i-1].opcode2&0x0E)==0) // BLTZ/BGEZ
8232           {
8233             alloc_cc(&current,i-1);
8234             dirty_reg(&current,CCREG);
8235             if(dops[i-1].rs1==dops[i].rt1||dops[i-1].rs1==dops[i].rt2) {
8236               // The delay slot overwrote the branch condition
8237               // Delay slot goes after the test (in order)
8238               current.u=branch_unneeded_reg[i-1]&~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
8239               current.u|=1;
8240               delayslot_alloc(&current,i);
8241               current.isconst=0;
8242             }
8243             else
8244             {
8245               current.u=branch_unneeded_reg[i-1]&~(1LL<<dops[i-1].rs1);
8246               // Alloc the branch condition register
8247               alloc_reg(&current,i-1,dops[i-1].rs1);
8248             }
8249             memcpy(&branch_regs[i-1],&current,sizeof(current));
8250             branch_regs[i-1].isconst=0;
8251             branch_regs[i-1].wasconst=0;
8252             memcpy(&branch_regs[i-1].regmap_entry,&current.regmap,sizeof(current.regmap));
8253             memcpy(constmap[i],constmap[i-1],sizeof(constmap[i]));
8254           }
8255           else
8256           // Alloc the delay slot in case the branch is taken
8257           if((dops[i-1].opcode2&0x1E)==2) // BLTZL/BGEZL
8258           {
8259             memcpy(&branch_regs[i-1],&current,sizeof(current));
8260             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;
8261             alloc_cc(&branch_regs[i-1],i);
8262             dirty_reg(&branch_regs[i-1],CCREG);
8263             delayslot_alloc(&branch_regs[i-1],i);
8264             branch_regs[i-1].isconst=0;
8265             alloc_reg(&current,i,CCREG); // Not taken path
8266             dirty_reg(&current,CCREG);
8267             memcpy(&branch_regs[i-1].regmap_entry,&branch_regs[i-1].regmap,sizeof(current.regmap));
8268           }
8269           // FIXME: BLTZAL/BGEZAL
8270           if(dops[i-1].opcode2&0x10) { // BxxZAL
8271             alloc_reg(&branch_regs[i-1],i-1,31);
8272             dirty_reg(&branch_regs[i-1],31);
8273           }
8274           break;
8275       }
8276
8277       if (dops[i-1].is_ujump)
8278       {
8279         if(dops[i-1].rt1==31) // JAL/JALR
8280         {
8281           // Subroutine call will return here, don't alloc any registers
8282           current.dirty=0;
8283           clear_all_regs(current.regmap);
8284           alloc_reg(&current,i,CCREG);
8285           dirty_reg(&current,CCREG);
8286         }
8287         else if(i+1<slen)
8288         {
8289           // Internal branch will jump here, match registers to caller
8290           current.dirty=0;
8291           clear_all_regs(current.regmap);
8292           alloc_reg(&current,i,CCREG);
8293           dirty_reg(&current,CCREG);
8294           for(j=i-1;j>=0;j--)
8295           {
8296             if(ba[j]==start+i*4+4) {
8297               memcpy(current.regmap,branch_regs[j].regmap,sizeof(current.regmap));
8298               current.dirty=branch_regs[j].dirty;
8299               break;
8300             }
8301           }
8302           while(j>=0) {
8303             if(ba[j]==start+i*4+4) {
8304               for(hr=0;hr<HOST_REGS;hr++) {
8305                 if(current.regmap[hr]!=branch_regs[j].regmap[hr]) {
8306                   current.regmap[hr]=-1;
8307                 }
8308                 current.dirty&=branch_regs[j].dirty;
8309               }
8310             }
8311             j--;
8312           }
8313         }
8314       }
8315     }
8316
8317     // Count cycles in between branches
8318     ccadj[i] = CLOCK_ADJUST(cc);
8319     if (i > 0 && (dops[i-1].is_jump || dops[i].itype == SYSCALL || dops[i].itype == HLECALL))
8320     {
8321       cc=0;
8322     }
8323 #if !defined(DRC_DBG)
8324     else if(dops[i].itype==C2OP&&gte_cycletab[source[i]&0x3f]>2)
8325     {
8326       // this should really be removed since the real stalls have been implemented,
8327       // but doing so causes sizeable perf regression against the older version
8328       u_int gtec = gte_cycletab[source[i] & 0x3f];
8329       cc += HACK_ENABLED(NDHACK_NO_STALLS) ? gtec/2 : 2;
8330     }
8331     else if(i>1&&dops[i].itype==STORE&&dops[i-1].itype==STORE&&dops[i-2].itype==STORE&&!dops[i].bt)
8332     {
8333       cc+=4;
8334     }
8335     else if(dops[i].itype==C2LS)
8336     {
8337       // same as with C2OP
8338       cc += HACK_ENABLED(NDHACK_NO_STALLS) ? 4 : 2;
8339     }
8340 #endif
8341     else
8342     {
8343       cc++;
8344     }
8345
8346     if(!dops[i].is_ds) {
8347       regs[i].dirty=current.dirty;
8348       regs[i].isconst=current.isconst;
8349       memcpy(constmap[i],current_constmap,sizeof(constmap[i]));
8350     }
8351     for(hr=0;hr<HOST_REGS;hr++) {
8352       if(hr!=EXCLUDE_REG&&regs[i].regmap[hr]>=0) {
8353         if(regmap_pre[i][hr]!=regs[i].regmap[hr]) {
8354           regs[i].wasconst&=~(1<<hr);
8355         }
8356       }
8357     }
8358     if(current.regmap[HOST_BTREG]==BTREG) current.regmap[HOST_BTREG]=-1;
8359     regs[i].waswritten=current.waswritten;
8360   }
8361
8362   /* Pass 4 - Cull unused host registers */
8363
8364   uint64_t nr=0;
8365
8366   for (i=slen-1;i>=0;i--)
8367   {
8368     int hr;
8369     if(dops[i].is_jump)
8370     {
8371       if(ba[i]<start || ba[i]>=(start+slen*4))
8372       {
8373         // Branch out of this block, don't need anything
8374         nr=0;
8375       }
8376       else
8377       {
8378         // Internal branch
8379         // Need whatever matches the target
8380         nr=0;
8381         int t=(ba[i]-start)>>2;
8382         for(hr=0;hr<HOST_REGS;hr++)
8383         {
8384           if(regs[i].regmap_entry[hr]>=0) {
8385             if(regs[i].regmap_entry[hr]==regs[t].regmap_entry[hr]) nr|=1<<hr;
8386           }
8387         }
8388       }
8389       // Conditional branch may need registers for following instructions
8390       if (!dops[i].is_ujump)
8391       {
8392         if(i<slen-2) {
8393           nr|=needed_reg[i+2];
8394           for(hr=0;hr<HOST_REGS;hr++)
8395           {
8396             if(regmap_pre[i+2][hr]>=0&&get_reg(regs[i+2].regmap_entry,regmap_pre[i+2][hr])<0) nr&=~(1<<hr);
8397             //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]);
8398           }
8399         }
8400       }
8401       // Don't need stuff which is overwritten
8402       //if(regs[i].regmap[hr]!=regmap_pre[i][hr]) nr&=~(1<<hr);
8403       //if(regs[i].regmap[hr]<0) nr&=~(1<<hr);
8404       // Merge in delay slot
8405       for(hr=0;hr<HOST_REGS;hr++)
8406       {
8407         if(dops[i+1].rt1&&dops[i+1].rt1==(regs[i].regmap[hr]&63)) nr&=~(1<<hr);
8408         if(dops[i+1].rt2&&dops[i+1].rt2==(regs[i].regmap[hr]&63)) nr&=~(1<<hr);
8409         if(dops[i+1].rs1==regmap_pre[i][hr]) nr|=1<<hr;
8410         if(dops[i+1].rs2==regmap_pre[i][hr]) nr|=1<<hr;
8411         if(dops[i+1].rs1==regs[i].regmap_entry[hr]) nr|=1<<hr;
8412         if(dops[i+1].rs2==regs[i].regmap_entry[hr]) nr|=1<<hr;
8413         if(ram_offset && (dops[i+1].is_load || dops[i+1].is_store)) {
8414           if(regmap_pre[i][hr]==ROREG) nr|=1<<hr;
8415           if(regs[i].regmap_entry[hr]==ROREG) nr|=1<<hr;
8416         }
8417         if(dops[i+1].is_store) {
8418           if(regmap_pre[i][hr]==INVCP) nr|=1<<hr;
8419           if(regs[i].regmap_entry[hr]==INVCP) nr|=1<<hr;
8420         }
8421       }
8422     }
8423     else if(dops[i].itype==SYSCALL||dops[i].itype==HLECALL||dops[i].itype==INTCALL)
8424     {
8425       // SYSCALL instruction (software interrupt)
8426       nr=0;
8427     }
8428     else if(dops[i].itype==COP0 && (source[i]&0x3f)==0x18)
8429     {
8430       // ERET instruction (return from interrupt)
8431       nr=0;
8432     }
8433     else // Non-branch
8434     {
8435       if(i<slen-1) {
8436         for(hr=0;hr<HOST_REGS;hr++) {
8437           if(regmap_pre[i+1][hr]>=0&&get_reg(regs[i+1].regmap_entry,regmap_pre[i+1][hr])<0) nr&=~(1<<hr);
8438           if(regs[i].regmap[hr]!=regmap_pre[i+1][hr]) nr&=~(1<<hr);
8439           if(regs[i].regmap[hr]!=regmap_pre[i][hr]) nr&=~(1<<hr);
8440           if(regs[i].regmap[hr]<0) nr&=~(1<<hr);
8441         }
8442       }
8443     }
8444     for(hr=0;hr<HOST_REGS;hr++)
8445     {
8446       // Overwritten registers are not needed
8447       if(dops[i].rt1&&dops[i].rt1==(regs[i].regmap[hr]&63)) nr&=~(1<<hr);
8448       if(dops[i].rt2&&dops[i].rt2==(regs[i].regmap[hr]&63)) nr&=~(1<<hr);
8449       if(FTEMP==(regs[i].regmap[hr]&63)) nr&=~(1<<hr);
8450       // Source registers are needed
8451       if(dops[i].rs1==regmap_pre[i][hr]) nr|=1<<hr;
8452       if(dops[i].rs2==regmap_pre[i][hr]) nr|=1<<hr;
8453       if(dops[i].rs1==regs[i].regmap_entry[hr]) nr|=1<<hr;
8454       if(dops[i].rs2==regs[i].regmap_entry[hr]) nr|=1<<hr;
8455       if(ram_offset && (dops[i].is_load || dops[i].is_store)) {
8456         if(regmap_pre[i][hr]==ROREG) nr|=1<<hr;
8457         if(regs[i].regmap_entry[hr]==ROREG) nr|=1<<hr;
8458       }
8459       if(dops[i].is_store) {
8460         if(regmap_pre[i][hr]==INVCP) nr|=1<<hr;
8461         if(regs[i].regmap_entry[hr]==INVCP) nr|=1<<hr;
8462       }
8463       // Don't store a register immediately after writing it,
8464       // may prevent dual-issue.
8465       // But do so if this is a branch target, otherwise we
8466       // might have to load the register before the branch.
8467       if(i>0&&!dops[i].bt&&((regs[i].wasdirty>>hr)&1)) {
8468         if((regmap_pre[i][hr]>0&&!((unneeded_reg[i]>>regmap_pre[i][hr])&1))) {
8469           if(dops[i-1].rt1==(regmap_pre[i][hr]&63)) nr|=1<<hr;
8470           if(dops[i-1].rt2==(regmap_pre[i][hr]&63)) nr|=1<<hr;
8471         }
8472         if((regs[i].regmap_entry[hr]>0&&!((unneeded_reg[i]>>regs[i].regmap_entry[hr])&1))) {
8473           if(dops[i-1].rt1==(regs[i].regmap_entry[hr]&63)) nr|=1<<hr;
8474           if(dops[i-1].rt2==(regs[i].regmap_entry[hr]&63)) nr|=1<<hr;
8475         }
8476       }
8477     }
8478     // Cycle count is needed at branches.  Assume it is needed at the target too.
8479     if(i==0||dops[i].bt||dops[i].itype==CJUMP||dops[i].itype==SPAN) {
8480       if(regmap_pre[i][HOST_CCREG]==CCREG) nr|=1<<HOST_CCREG;
8481       if(regs[i].regmap_entry[HOST_CCREG]==CCREG) nr|=1<<HOST_CCREG;
8482     }
8483     // Save it
8484     needed_reg[i]=nr;
8485
8486     // Deallocate unneeded registers
8487     for(hr=0;hr<HOST_REGS;hr++)
8488     {
8489       if(!((nr>>hr)&1)) {
8490         if(regs[i].regmap_entry[hr]!=CCREG) regs[i].regmap_entry[hr]=-1;
8491         if(dops[i].is_jump)
8492         {
8493           int map1 = 0, map2 = 0, temp = 0; // or -1 ??
8494           if (dops[i+1].is_load || dops[i+1].is_store)
8495             map1 = ROREG;
8496           if (dops[i+1].is_store)
8497             map2 = INVCP;
8498           if(dops[i+1].itype==LOADLR || dops[i+1].itype==STORELR || dops[i+1].itype==C2LS)
8499             temp = FTEMP;
8500           if((regs[i].regmap[hr]&63)!=dops[i].rs1 && (regs[i].regmap[hr]&63)!=dops[i].rs2 &&
8501              (regs[i].regmap[hr]&63)!=dops[i].rt1 && (regs[i].regmap[hr]&63)!=dops[i].rt2 &&
8502              (regs[i].regmap[hr]&63)!=dops[i+1].rt1 && (regs[i].regmap[hr]&63)!=dops[i+1].rt2 &&
8503              regs[i].regmap[hr]!=dops[i+1].rs1 && regs[i].regmap[hr]!=dops[i+1].rs2 &&
8504              (regs[i].regmap[hr]&63)!=temp && regs[i].regmap[hr]!=PTEMP &&
8505              regs[i].regmap[hr]!=RHASH && regs[i].regmap[hr]!=RHTBL &&
8506              regs[i].regmap[hr]!=RTEMP && regs[i].regmap[hr]!=CCREG &&
8507              regs[i].regmap[hr]!=map1 && regs[i].regmap[hr]!=map2)
8508           {
8509             regs[i].regmap[hr]=-1;
8510             regs[i].isconst&=~(1<<hr);
8511             regs[i].dirty&=~(1<<hr);
8512             regs[i+1].wasdirty&=~(1<<hr);
8513             if((branch_regs[i].regmap[hr]&63)!=dops[i].rs1 && (branch_regs[i].regmap[hr]&63)!=dops[i].rs2 &&
8514                (branch_regs[i].regmap[hr]&63)!=dops[i].rt1 && (branch_regs[i].regmap[hr]&63)!=dops[i].rt2 &&
8515                (branch_regs[i].regmap[hr]&63)!=dops[i+1].rt1 && (branch_regs[i].regmap[hr]&63)!=dops[i+1].rt2 &&
8516                branch_regs[i].regmap[hr]!=dops[i+1].rs1 && branch_regs[i].regmap[hr]!=dops[i+1].rs2 &&
8517                (branch_regs[i].regmap[hr]&63)!=temp && branch_regs[i].regmap[hr]!=PTEMP &&
8518                branch_regs[i].regmap[hr]!=RHASH && branch_regs[i].regmap[hr]!=RHTBL &&
8519                branch_regs[i].regmap[hr]!=RTEMP && branch_regs[i].regmap[hr]!=CCREG &&
8520                branch_regs[i].regmap[hr]!=map1 && branch_regs[i].regmap[hr]!=map2)
8521             {
8522               branch_regs[i].regmap[hr]=-1;
8523               branch_regs[i].regmap_entry[hr]=-1;
8524               if (!dops[i].is_ujump)
8525               {
8526                 if (i < slen-2) {
8527                   regmap_pre[i+2][hr]=-1;
8528                   regs[i+2].wasconst&=~(1<<hr);
8529                 }
8530               }
8531             }
8532           }
8533         }
8534         else
8535         {
8536           // Non-branch
8537           if(i>0)
8538           {
8539             int map1 = -1, map2 = -1, temp=-1;
8540             if (dops[i].is_load || dops[i].is_store)
8541               map1 = ROREG;
8542             if (dops[i].is_store)
8543               map2 = INVCP;
8544             if (dops[i].itype==LOADLR || dops[i].itype==STORELR || dops[i].itype==C2LS)
8545               temp = FTEMP;
8546             if((regs[i].regmap[hr]&63)!=dops[i].rt1 && (regs[i].regmap[hr]&63)!=dops[i].rt2 &&
8547                regs[i].regmap[hr]!=dops[i].rs1 && regs[i].regmap[hr]!=dops[i].rs2 &&
8548                (regs[i].regmap[hr]&63)!=temp && regs[i].regmap[hr]!=map1 && regs[i].regmap[hr]!=map2 &&
8549                //(dops[i].itype!=SPAN||regs[i].regmap[hr]!=CCREG)
8550                regs[i].regmap[hr] != CCREG)
8551             {
8552               if(i<slen-1&&!dops[i].is_ds) {
8553                 assert(regs[i].regmap[hr]<64);
8554                 if(regmap_pre[i+1][hr]!=-1 || regs[i].regmap[hr]>0)
8555                 if(regmap_pre[i+1][hr]!=regs[i].regmap[hr])
8556                 {
8557                   SysPrintf("fail: %x (%d %d!=%d)\n",start+i*4,hr,regmap_pre[i+1][hr],regs[i].regmap[hr]);
8558                   assert(regmap_pre[i+1][hr]==regs[i].regmap[hr]);
8559                 }
8560                 regmap_pre[i+1][hr]=-1;
8561                 if(regs[i+1].regmap_entry[hr]==CCREG) regs[i+1].regmap_entry[hr]=-1;
8562                 regs[i+1].wasconst&=~(1<<hr);
8563               }
8564               regs[i].regmap[hr]=-1;
8565               regs[i].isconst&=~(1<<hr);
8566               regs[i].dirty&=~(1<<hr);
8567               regs[i+1].wasdirty&=~(1<<hr);
8568             }
8569           }
8570         }
8571       } // if needed
8572     } // for hr
8573   }
8574
8575   /* Pass 5 - Pre-allocate registers */
8576
8577   // If a register is allocated during a loop, try to allocate it for the
8578   // entire loop, if possible.  This avoids loading/storing registers
8579   // inside of the loop.
8580
8581   signed char f_regmap[HOST_REGS];
8582   clear_all_regs(f_regmap);
8583   for(i=0;i<slen-1;i++)
8584   {
8585     if(dops[i].itype==UJUMP||dops[i].itype==CJUMP||dops[i].itype==SJUMP)
8586     {
8587       if(ba[i]>=start && ba[i]<(start+i*4))
8588       if(dops[i+1].itype==NOP||dops[i+1].itype==MOV||dops[i+1].itype==ALU
8589       ||dops[i+1].itype==SHIFTIMM||dops[i+1].itype==IMM16||dops[i+1].itype==LOAD
8590       ||dops[i+1].itype==STORE||dops[i+1].itype==STORELR||dops[i+1].itype==C1LS
8591       ||dops[i+1].itype==SHIFT||dops[i+1].itype==COP1
8592       ||dops[i+1].itype==COP2||dops[i+1].itype==C2LS||dops[i+1].itype==C2OP)
8593       {
8594         int t=(ba[i]-start)>>2;
8595         if(t > 0 && !dops[t-1].is_jump) // loop_preload can't handle jumps into delay slots
8596         if(t<2||(dops[t-2].itype!=UJUMP&&dops[t-2].itype!=RJUMP)||dops[t-2].rt1!=31) // call/ret assumes no registers allocated
8597         for(hr=0;hr<HOST_REGS;hr++)
8598         {
8599           if(regs[i].regmap[hr]>=0) {
8600             if(f_regmap[hr]!=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]==regs[i].regmap[hr]) {f_regmap[n]=-1;}
8606               }
8607               // and alloc new one
8608               f_regmap[hr]=regs[i].regmap[hr];
8609             }
8610           }
8611           if(branch_regs[i].regmap[hr]>=0) {
8612             if(f_regmap[hr]!=branch_regs[i].regmap[hr]) {
8613               // dealloc old register
8614               int n;
8615               for(n=0;n<HOST_REGS;n++)
8616               {
8617                 if(f_regmap[n]==branch_regs[i].regmap[hr]) {f_regmap[n]=-1;}
8618               }
8619               // and alloc new one
8620               f_regmap[hr]=branch_regs[i].regmap[hr];
8621             }
8622           }
8623           if(dops[i].ooo) {
8624             if(count_free_regs(regs[i].regmap)<=minimum_free_regs[i+1])
8625               f_regmap[hr]=branch_regs[i].regmap[hr];
8626           }else{
8627             if(count_free_regs(branch_regs[i].regmap)<=minimum_free_regs[i+1])
8628               f_regmap[hr]=branch_regs[i].regmap[hr];
8629           }
8630           // Avoid dirty->clean transition
8631           #ifdef DESTRUCTIVE_WRITEBACK
8632           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;
8633           #endif
8634           // This check is only strictly required in the DESTRUCTIVE_WRITEBACK
8635           // case above, however it's always a good idea.  We can't hoist the
8636           // load if the register was already allocated, so there's no point
8637           // wasting time analyzing most of these cases.  It only "succeeds"
8638           // when the mapping was different and the load can be replaced with
8639           // a mov, which is of negligible benefit.  So such cases are
8640           // skipped below.
8641           if(f_regmap[hr]>0) {
8642             if(regs[t].regmap[hr]==f_regmap[hr]||(regs[t].regmap_entry[hr]<0&&get_reg(regmap_pre[t],f_regmap[hr])<0)) {
8643               int r=f_regmap[hr];
8644               for(j=t;j<=i;j++)
8645               {
8646                 //printf("Test %x -> %x, %x %d/%d\n",start+i*4,ba[i],start+j*4,hr,r);
8647                 if(r<34&&((unneeded_reg[j]>>r)&1)) break;
8648                 assert(r < 64);
8649                 if(regs[j].regmap[hr]==f_regmap[hr]&&(f_regmap[hr]&63)<TEMPREG) {
8650                   //printf("Hit %x -> %x, %x %d/%d\n",start+i*4,ba[i],start+j*4,hr,r);
8651                   int k;
8652                   if(regs[i].regmap[hr]==-1&&branch_regs[i].regmap[hr]==-1) {
8653                     if(get_reg(regs[i+2].regmap,f_regmap[hr])>=0) break;
8654                     if(r>63) {
8655                       if(get_reg(regs[i].regmap,r&63)<0) break;
8656                       if(get_reg(branch_regs[i].regmap,r&63)<0) break;
8657                     }
8658                     k=i;
8659                     while(k>1&&regs[k-1].regmap[hr]==-1) {
8660                       if(count_free_regs(regs[k-1].regmap)<=minimum_free_regs[k-1]) {
8661                         //printf("no free regs for store %x\n",start+(k-1)*4);
8662                         break;
8663                       }
8664                       if(get_reg(regs[k-1].regmap,f_regmap[hr])>=0) {
8665                         //printf("no-match due to different register\n");
8666                         break;
8667                       }
8668                       if (dops[k-2].is_jump) {
8669                         //printf("no-match due to branch\n");
8670                         break;
8671                       }
8672                       // call/ret fast path assumes no registers allocated
8673                       if(k>2&&(dops[k-3].itype==UJUMP||dops[k-3].itype==RJUMP)&&dops[k-3].rt1==31) {
8674                         break;
8675                       }
8676                       assert(r < 64);
8677                       k--;
8678                     }
8679                     if(regs[k-1].regmap[hr]==f_regmap[hr]&&regmap_pre[k][hr]==f_regmap[hr]) {
8680                       //printf("Extend r%d, %x ->\n",hr,start+k*4);
8681                       while(k<i) {
8682                         regs[k].regmap_entry[hr]=f_regmap[hr];
8683                         regs[k].regmap[hr]=f_regmap[hr];
8684                         regmap_pre[k+1][hr]=f_regmap[hr];
8685                         regs[k].wasdirty&=~(1<<hr);
8686                         regs[k].dirty&=~(1<<hr);
8687                         regs[k].wasdirty|=(1<<hr)&regs[k-1].dirty;
8688                         regs[k].dirty|=(1<<hr)&regs[k].wasdirty;
8689                         regs[k].wasconst&=~(1<<hr);
8690                         regs[k].isconst&=~(1<<hr);
8691                         k++;
8692                       }
8693                     }
8694                     else {
8695                       //printf("Fail Extend r%d, %x ->\n",hr,start+k*4);
8696                       break;
8697                     }
8698                     assert(regs[i-1].regmap[hr]==f_regmap[hr]);
8699                     if(regs[i-1].regmap[hr]==f_regmap[hr]&&regmap_pre[i][hr]==f_regmap[hr]) {
8700                       //printf("OK fill %x (r%d)\n",start+i*4,hr);
8701                       regs[i].regmap_entry[hr]=f_regmap[hr];
8702                       regs[i].regmap[hr]=f_regmap[hr];
8703                       regs[i].wasdirty&=~(1<<hr);
8704                       regs[i].dirty&=~(1<<hr);
8705                       regs[i].wasdirty|=(1<<hr)&regs[i-1].dirty;
8706                       regs[i].dirty|=(1<<hr)&regs[i-1].dirty;
8707                       regs[i].wasconst&=~(1<<hr);
8708                       regs[i].isconst&=~(1<<hr);
8709                       branch_regs[i].regmap_entry[hr]=f_regmap[hr];
8710                       branch_regs[i].wasdirty&=~(1<<hr);
8711                       branch_regs[i].wasdirty|=(1<<hr)&regs[i].dirty;
8712                       branch_regs[i].regmap[hr]=f_regmap[hr];
8713                       branch_regs[i].dirty&=~(1<<hr);
8714                       branch_regs[i].dirty|=(1<<hr)&regs[i].dirty;
8715                       branch_regs[i].wasconst&=~(1<<hr);
8716                       branch_regs[i].isconst&=~(1<<hr);
8717                       if (!dops[i].is_ujump) {
8718                         regmap_pre[i+2][hr]=f_regmap[hr];
8719                         regs[i+2].wasdirty&=~(1<<hr);
8720                         regs[i+2].wasdirty|=(1<<hr)&regs[i].dirty;
8721                       }
8722                     }
8723                   }
8724                   for(k=t;k<j;k++) {
8725                     // Alloc register clean at beginning of loop,
8726                     // but may dirty it in pass 6
8727                     regs[k].regmap_entry[hr]=f_regmap[hr];
8728                     regs[k].regmap[hr]=f_regmap[hr];
8729                     regs[k].dirty&=~(1<<hr);
8730                     regs[k].wasconst&=~(1<<hr);
8731                     regs[k].isconst&=~(1<<hr);
8732                     if (dops[k].is_jump) {
8733                       branch_regs[k].regmap_entry[hr]=f_regmap[hr];
8734                       branch_regs[k].regmap[hr]=f_regmap[hr];
8735                       branch_regs[k].dirty&=~(1<<hr);
8736                       branch_regs[k].wasconst&=~(1<<hr);
8737                       branch_regs[k].isconst&=~(1<<hr);
8738                       if (!dops[k].is_ujump) {
8739                         regmap_pre[k+2][hr]=f_regmap[hr];
8740                         regs[k+2].wasdirty&=~(1<<hr);
8741                       }
8742                     }
8743                     else
8744                     {
8745                       regmap_pre[k+1][hr]=f_regmap[hr];
8746                       regs[k+1].wasdirty&=~(1<<hr);
8747                     }
8748                   }
8749                   if(regs[j].regmap[hr]==f_regmap[hr])
8750                     regs[j].regmap_entry[hr]=f_regmap[hr];
8751                   break;
8752                 }
8753                 if(j==i) break;
8754                 if(regs[j].regmap[hr]>=0)
8755                   break;
8756                 if(get_reg(regs[j].regmap,f_regmap[hr])>=0) {
8757                   //printf("no-match due to different register\n");
8758                   break;
8759                 }
8760                 if (dops[j].is_ujump)
8761                 {
8762                   // Stop on unconditional branch
8763                   break;
8764                 }
8765                 if(dops[j].itype==CJUMP||dops[j].itype==SJUMP)
8766                 {
8767                   if(dops[j].ooo) {
8768                     if(count_free_regs(regs[j].regmap)<=minimum_free_regs[j+1])
8769                       break;
8770                   }else{
8771                     if(count_free_regs(branch_regs[j].regmap)<=minimum_free_regs[j+1])
8772                       break;
8773                   }
8774                   if(get_reg(branch_regs[j].regmap,f_regmap[hr])>=0) {
8775                     //printf("no-match due to different register (branch)\n");
8776                     break;
8777                   }
8778                 }
8779                 if(count_free_regs(regs[j].regmap)<=minimum_free_regs[j]) {
8780                   //printf("No free regs for store %x\n",start+j*4);
8781                   break;
8782                 }
8783                 assert(f_regmap[hr]<64);
8784               }
8785             }
8786           }
8787         }
8788       }
8789     }else{
8790       // Non branch or undetermined branch target
8791       for(hr=0;hr<HOST_REGS;hr++)
8792       {
8793         if(hr!=EXCLUDE_REG) {
8794           if(regs[i].regmap[hr]>=0) {
8795             if(f_regmap[hr]!=regs[i].regmap[hr]) {
8796               // dealloc old register
8797               int n;
8798               for(n=0;n<HOST_REGS;n++)
8799               {
8800                 if(f_regmap[n]==regs[i].regmap[hr]) {f_regmap[n]=-1;}
8801               }
8802               // and alloc new one
8803               f_regmap[hr]=regs[i].regmap[hr];
8804             }
8805           }
8806         }
8807       }
8808       // Try to restore cycle count at branch targets
8809       if(dops[i].bt) {
8810         for(j=i;j<slen-1;j++) {
8811           if(regs[j].regmap[HOST_CCREG]!=-1) break;
8812           if(count_free_regs(regs[j].regmap)<=minimum_free_regs[j]) {
8813             //printf("no free regs for store %x\n",start+j*4);
8814             break;
8815           }
8816         }
8817         if(regs[j].regmap[HOST_CCREG]==CCREG) {
8818           int k=i;
8819           //printf("Extend CC, %x -> %x\n",start+k*4,start+j*4);
8820           while(k<j) {
8821             regs[k].regmap_entry[HOST_CCREG]=CCREG;
8822             regs[k].regmap[HOST_CCREG]=CCREG;
8823             regmap_pre[k+1][HOST_CCREG]=CCREG;
8824             regs[k+1].wasdirty|=1<<HOST_CCREG;
8825             regs[k].dirty|=1<<HOST_CCREG;
8826             regs[k].wasconst&=~(1<<HOST_CCREG);
8827             regs[k].isconst&=~(1<<HOST_CCREG);
8828             k++;
8829           }
8830           regs[j].regmap_entry[HOST_CCREG]=CCREG;
8831         }
8832         // Work backwards from the branch target
8833         if(j>i&&f_regmap[HOST_CCREG]==CCREG)
8834         {
8835           //printf("Extend backwards\n");
8836           int k;
8837           k=i;
8838           while(regs[k-1].regmap[HOST_CCREG]==-1) {
8839             if(count_free_regs(regs[k-1].regmap)<=minimum_free_regs[k-1]) {
8840               //printf("no free regs for store %x\n",start+(k-1)*4);
8841               break;
8842             }
8843             k--;
8844           }
8845           if(regs[k-1].regmap[HOST_CCREG]==CCREG) {
8846             //printf("Extend CC, %x ->\n",start+k*4);
8847             while(k<=i) {
8848               regs[k].regmap_entry[HOST_CCREG]=CCREG;
8849               regs[k].regmap[HOST_CCREG]=CCREG;
8850               regmap_pre[k+1][HOST_CCREG]=CCREG;
8851               regs[k+1].wasdirty|=1<<HOST_CCREG;
8852               regs[k].dirty|=1<<HOST_CCREG;
8853               regs[k].wasconst&=~(1<<HOST_CCREG);
8854               regs[k].isconst&=~(1<<HOST_CCREG);
8855               k++;
8856             }
8857           }
8858           else {
8859             //printf("Fail Extend CC, %x ->\n",start+k*4);
8860           }
8861         }
8862       }
8863       if(dops[i].itype!=STORE&&dops[i].itype!=STORELR&&dops[i].itype!=C1LS&&dops[i].itype!=SHIFT&&
8864          dops[i].itype!=NOP&&dops[i].itype!=MOV&&dops[i].itype!=ALU&&dops[i].itype!=SHIFTIMM&&
8865          dops[i].itype!=IMM16&&dops[i].itype!=LOAD&&dops[i].itype!=COP1)
8866       {
8867         memcpy(f_regmap,regs[i].regmap,sizeof(f_regmap));
8868       }
8869     }
8870   }
8871
8872   // This allocates registers (if possible) one instruction prior
8873   // to use, which can avoid a load-use penalty on certain CPUs.
8874   for(i=0;i<slen-1;i++)
8875   {
8876     if (!i || !dops[i-1].is_jump)
8877     {
8878       if(!dops[i+1].bt)
8879       {
8880         if(dops[i].itype==ALU||dops[i].itype==MOV||dops[i].itype==LOAD||dops[i].itype==SHIFTIMM||dops[i].itype==IMM16
8881            ||((dops[i].itype==COP1||dops[i].itype==COP2)&&dops[i].opcode2<3))
8882         {
8883           if(dops[i+1].rs1) {
8884             if((hr=get_reg(regs[i+1].regmap,dops[i+1].rs1))>=0)
8885             {
8886               if(regs[i].regmap[hr]<0&&regs[i+1].regmap_entry[hr]<0)
8887               {
8888                 regs[i].regmap[hr]=regs[i+1].regmap[hr];
8889                 regmap_pre[i+1][hr]=regs[i+1].regmap[hr];
8890                 regs[i+1].regmap_entry[hr]=regs[i+1].regmap[hr];
8891                 regs[i].isconst&=~(1<<hr);
8892                 regs[i].isconst|=regs[i+1].isconst&(1<<hr);
8893                 constmap[i][hr]=constmap[i+1][hr];
8894                 regs[i+1].wasdirty&=~(1<<hr);
8895                 regs[i].dirty&=~(1<<hr);
8896               }
8897             }
8898           }
8899           if(dops[i+1].rs2) {
8900             if((hr=get_reg(regs[i+1].regmap,dops[i+1].rs2))>=0)
8901             {
8902               if(regs[i].regmap[hr]<0&&regs[i+1].regmap_entry[hr]<0)
8903               {
8904                 regs[i].regmap[hr]=regs[i+1].regmap[hr];
8905                 regmap_pre[i+1][hr]=regs[i+1].regmap[hr];
8906                 regs[i+1].regmap_entry[hr]=regs[i+1].regmap[hr];
8907                 regs[i].isconst&=~(1<<hr);
8908                 regs[i].isconst|=regs[i+1].isconst&(1<<hr);
8909                 constmap[i][hr]=constmap[i+1][hr];
8910                 regs[i+1].wasdirty&=~(1<<hr);
8911                 regs[i].dirty&=~(1<<hr);
8912               }
8913             }
8914           }
8915           // Preload target address for load instruction (non-constant)
8916           if(dops[i+1].itype==LOAD&&dops[i+1].rs1&&get_reg(regs[i+1].regmap,dops[i+1].rs1)<0) {
8917             if((hr=get_reg(regs[i+1].regmap,dops[i+1].rt1))>=0)
8918             {
8919               if(regs[i].regmap[hr]<0&&regs[i+1].regmap_entry[hr]<0)
8920               {
8921                 regs[i].regmap[hr]=dops[i+1].rs1;
8922                 regmap_pre[i+1][hr]=dops[i+1].rs1;
8923                 regs[i+1].regmap_entry[hr]=dops[i+1].rs1;
8924                 regs[i].isconst&=~(1<<hr);
8925                 regs[i].isconst|=regs[i+1].isconst&(1<<hr);
8926                 constmap[i][hr]=constmap[i+1][hr];
8927                 regs[i+1].wasdirty&=~(1<<hr);
8928                 regs[i].dirty&=~(1<<hr);
8929               }
8930             }
8931           }
8932           // Load source into target register
8933           if(dops[i+1].lt1&&get_reg(regs[i+1].regmap,dops[i+1].rs1)<0) {
8934             if((hr=get_reg(regs[i+1].regmap,dops[i+1].rt1))>=0)
8935             {
8936               if(regs[i].regmap[hr]<0&&regs[i+1].regmap_entry[hr]<0)
8937               {
8938                 regs[i].regmap[hr]=dops[i+1].rs1;
8939                 regmap_pre[i+1][hr]=dops[i+1].rs1;
8940                 regs[i+1].regmap_entry[hr]=dops[i+1].rs1;
8941                 regs[i].isconst&=~(1<<hr);
8942                 regs[i].isconst|=regs[i+1].isconst&(1<<hr);
8943                 constmap[i][hr]=constmap[i+1][hr];
8944                 regs[i+1].wasdirty&=~(1<<hr);
8945                 regs[i].dirty&=~(1<<hr);
8946               }
8947             }
8948           }
8949           // Address for store instruction (non-constant)
8950           if(dops[i+1].itype==STORE||dops[i+1].itype==STORELR
8951              ||(dops[i+1].opcode&0x3b)==0x39||(dops[i+1].opcode&0x3b)==0x3a) { // SB/SH/SW/SD/SWC1/SDC1/SWC2/SDC2
8952             if(get_reg(regs[i+1].regmap,dops[i+1].rs1)<0) {
8953               hr=get_reg2(regs[i].regmap,regs[i+1].regmap,-1);
8954               if(hr<0) hr=get_reg(regs[i+1].regmap,-1);
8955               else {
8956                 regs[i+1].regmap[hr]=AGEN1+((i+1)&1);
8957                 regs[i+1].isconst&=~(1<<hr);
8958               }
8959               assert(hr>=0);
8960               if(regs[i].regmap[hr]<0&&regs[i+1].regmap_entry[hr]<0)
8961               {
8962                 regs[i].regmap[hr]=dops[i+1].rs1;
8963                 regmap_pre[i+1][hr]=dops[i+1].rs1;
8964                 regs[i+1].regmap_entry[hr]=dops[i+1].rs1;
8965                 regs[i].isconst&=~(1<<hr);
8966                 regs[i].isconst|=regs[i+1].isconst&(1<<hr);
8967                 constmap[i][hr]=constmap[i+1][hr];
8968                 regs[i+1].wasdirty&=~(1<<hr);
8969                 regs[i].dirty&=~(1<<hr);
8970               }
8971             }
8972           }
8973           if(dops[i+1].itype==LOADLR||(dops[i+1].opcode&0x3b)==0x31||(dops[i+1].opcode&0x3b)==0x32) { // LWC1/LDC1, LWC2/LDC2
8974             if(get_reg(regs[i+1].regmap,dops[i+1].rs1)<0) {
8975               int nr;
8976               hr=get_reg(regs[i+1].regmap,FTEMP);
8977               assert(hr>=0);
8978               if(regs[i].regmap[hr]<0&&regs[i+1].regmap_entry[hr]<0)
8979               {
8980                 regs[i].regmap[hr]=dops[i+1].rs1;
8981                 regmap_pre[i+1][hr]=dops[i+1].rs1;
8982                 regs[i+1].regmap_entry[hr]=dops[i+1].rs1;
8983                 regs[i].isconst&=~(1<<hr);
8984                 regs[i].isconst|=regs[i+1].isconst&(1<<hr);
8985                 constmap[i][hr]=constmap[i+1][hr];
8986                 regs[i+1].wasdirty&=~(1<<hr);
8987                 regs[i].dirty&=~(1<<hr);
8988               }
8989               else if((nr=get_reg2(regs[i].regmap,regs[i+1].regmap,-1))>=0)
8990               {
8991                 // move it to another register
8992                 regs[i+1].regmap[hr]=-1;
8993                 regmap_pre[i+2][hr]=-1;
8994                 regs[i+1].regmap[nr]=FTEMP;
8995                 regmap_pre[i+2][nr]=FTEMP;
8996                 regs[i].regmap[nr]=dops[i+1].rs1;
8997                 regmap_pre[i+1][nr]=dops[i+1].rs1;
8998                 regs[i+1].regmap_entry[nr]=dops[i+1].rs1;
8999                 regs[i].isconst&=~(1<<nr);
9000                 regs[i+1].isconst&=~(1<<nr);
9001                 regs[i].dirty&=~(1<<nr);
9002                 regs[i+1].wasdirty&=~(1<<nr);
9003                 regs[i+1].dirty&=~(1<<nr);
9004                 regs[i+2].wasdirty&=~(1<<nr);
9005               }
9006             }
9007           }
9008           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*/) {
9009             if(dops[i+1].itype==LOAD)
9010               hr=get_reg(regs[i+1].regmap,dops[i+1].rt1);
9011             if(dops[i+1].itype==LOADLR||(dops[i+1].opcode&0x3b)==0x31||(dops[i+1].opcode&0x3b)==0x32) // LWC1/LDC1, LWC2/LDC2
9012               hr=get_reg(regs[i+1].regmap,FTEMP);
9013             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
9014               hr=get_reg(regs[i+1].regmap,AGEN1+((i+1)&1));
9015               if(hr<0) hr=get_reg(regs[i+1].regmap,-1);
9016             }
9017             if(hr>=0&&regs[i].regmap[hr]<0) {
9018               int rs=get_reg(regs[i+1].regmap,dops[i+1].rs1);
9019               if(rs>=0&&((regs[i+1].wasconst>>rs)&1)) {
9020                 regs[i].regmap[hr]=AGEN1+((i+1)&1);
9021                 regmap_pre[i+1][hr]=AGEN1+((i+1)&1);
9022                 regs[i+1].regmap_entry[hr]=AGEN1+((i+1)&1);
9023                 regs[i].isconst&=~(1<<hr);
9024                 regs[i+1].wasdirty&=~(1<<hr);
9025                 regs[i].dirty&=~(1<<hr);
9026               }
9027             }
9028           }
9029         }
9030       }
9031     }
9032   }
9033
9034   /* Pass 6 - Optimize clean/dirty state */
9035   clean_registers(0,slen-1,1);
9036
9037   /* Pass 7 - Identify 32-bit registers */
9038   for (i=slen-1;i>=0;i--)
9039   {
9040     if(dops[i].itype==CJUMP||dops[i].itype==SJUMP)
9041     {
9042       // Conditional branch
9043       if((source[i]>>16)!=0x1000&&i<slen-2) {
9044         // Mark this address as a branch target since it may be called
9045         // upon return from interrupt
9046         dops[i+2].bt=1;
9047       }
9048     }
9049   }
9050
9051   if(dops[slen-1].itype==SPAN) {
9052     dops[slen-1].bt=1; // Mark as a branch target so instruction can restart after exception
9053   }
9054
9055 #ifdef REG_ALLOC_PRINT
9056   /* Debug/disassembly */
9057   for(i=0;i<slen;i++)
9058   {
9059     printf("U:");
9060     int r;
9061     for(r=1;r<=CCREG;r++) {
9062       if((unneeded_reg[i]>>r)&1) {
9063         if(r==HIREG) printf(" HI");
9064         else if(r==LOREG) printf(" LO");
9065         else printf(" r%d",r);
9066       }
9067     }
9068     printf("\n");
9069     #if defined(__i386__) || defined(__x86_64__)
9070     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]);
9071     #endif
9072     #ifdef __arm__
9073     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]);
9074     #endif
9075     #if defined(__i386__) || defined(__x86_64__)
9076     printf("needs: ");
9077     if(needed_reg[i]&1) printf("eax ");
9078     if((needed_reg[i]>>1)&1) printf("ecx ");
9079     if((needed_reg[i]>>2)&1) printf("edx ");
9080     if((needed_reg[i]>>3)&1) printf("ebx ");
9081     if((needed_reg[i]>>5)&1) printf("ebp ");
9082     if((needed_reg[i]>>6)&1) printf("esi ");
9083     if((needed_reg[i]>>7)&1) printf("edi ");
9084     printf("\n");
9085     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]);
9086     printf("dirty: ");
9087     if(regs[i].wasdirty&1) printf("eax ");
9088     if((regs[i].wasdirty>>1)&1) printf("ecx ");
9089     if((regs[i].wasdirty>>2)&1) printf("edx ");
9090     if((regs[i].wasdirty>>3)&1) printf("ebx ");
9091     if((regs[i].wasdirty>>5)&1) printf("ebp ");
9092     if((regs[i].wasdirty>>6)&1) printf("esi ");
9093     if((regs[i].wasdirty>>7)&1) printf("edi ");
9094     #endif
9095     #ifdef __arm__
9096     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]);
9097     printf("dirty: ");
9098     if(regs[i].wasdirty&1) printf("r0 ");
9099     if((regs[i].wasdirty>>1)&1) printf("r1 ");
9100     if((regs[i].wasdirty>>2)&1) printf("r2 ");
9101     if((regs[i].wasdirty>>3)&1) printf("r3 ");
9102     if((regs[i].wasdirty>>4)&1) printf("r4 ");
9103     if((regs[i].wasdirty>>5)&1) printf("r5 ");
9104     if((regs[i].wasdirty>>6)&1) printf("r6 ");
9105     if((regs[i].wasdirty>>7)&1) printf("r7 ");
9106     if((regs[i].wasdirty>>8)&1) printf("r8 ");
9107     if((regs[i].wasdirty>>9)&1) printf("r9 ");
9108     if((regs[i].wasdirty>>10)&1) printf("r10 ");
9109     if((regs[i].wasdirty>>12)&1) printf("r12 ");
9110     #endif
9111     printf("\n");
9112     disassemble_inst(i);
9113     //printf ("ccadj[%d] = %d\n",i,ccadj[i]);
9114     #if defined(__i386__) || defined(__x86_64__)
9115     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]);
9116     if(regs[i].dirty&1) printf("eax ");
9117     if((regs[i].dirty>>1)&1) printf("ecx ");
9118     if((regs[i].dirty>>2)&1) printf("edx ");
9119     if((regs[i].dirty>>3)&1) printf("ebx ");
9120     if((regs[i].dirty>>5)&1) printf("ebp ");
9121     if((regs[i].dirty>>6)&1) printf("esi ");
9122     if((regs[i].dirty>>7)&1) printf("edi ");
9123     #endif
9124     #ifdef __arm__
9125     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]);
9126     if(regs[i].dirty&1) printf("r0 ");
9127     if((regs[i].dirty>>1)&1) printf("r1 ");
9128     if((regs[i].dirty>>2)&1) printf("r2 ");
9129     if((regs[i].dirty>>3)&1) printf("r3 ");
9130     if((regs[i].dirty>>4)&1) printf("r4 ");
9131     if((regs[i].dirty>>5)&1) printf("r5 ");
9132     if((regs[i].dirty>>6)&1) printf("r6 ");
9133     if((regs[i].dirty>>7)&1) printf("r7 ");
9134     if((regs[i].dirty>>8)&1) printf("r8 ");
9135     if((regs[i].dirty>>9)&1) printf("r9 ");
9136     if((regs[i].dirty>>10)&1) printf("r10 ");
9137     if((regs[i].dirty>>12)&1) printf("r12 ");
9138     #endif
9139     printf("\n");
9140     if(regs[i].isconst) {
9141       printf("constants: ");
9142       #if defined(__i386__) || defined(__x86_64__)
9143       if(regs[i].isconst&1) printf("eax=%x ",(u_int)constmap[i][0]);
9144       if((regs[i].isconst>>1)&1) printf("ecx=%x ",(u_int)constmap[i][1]);
9145       if((regs[i].isconst>>2)&1) printf("edx=%x ",(u_int)constmap[i][2]);
9146       if((regs[i].isconst>>3)&1) printf("ebx=%x ",(u_int)constmap[i][3]);
9147       if((regs[i].isconst>>5)&1) printf("ebp=%x ",(u_int)constmap[i][5]);
9148       if((regs[i].isconst>>6)&1) printf("esi=%x ",(u_int)constmap[i][6]);
9149       if((regs[i].isconst>>7)&1) printf("edi=%x ",(u_int)constmap[i][7]);
9150       #endif
9151       #if defined(__arm__) || defined(__aarch64__)
9152       int r;
9153       for (r = 0; r < ARRAY_SIZE(constmap[i]); r++)
9154         if ((regs[i].isconst >> r) & 1)
9155           printf(" r%d=%x", r, (u_int)constmap[i][r]);
9156       #endif
9157       printf("\n");
9158     }
9159     if(dops[i].is_jump) {
9160       #if defined(__i386__) || defined(__x86_64__)
9161       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]);
9162       if(branch_regs[i].dirty&1) printf("eax ");
9163       if((branch_regs[i].dirty>>1)&1) printf("ecx ");
9164       if((branch_regs[i].dirty>>2)&1) printf("edx ");
9165       if((branch_regs[i].dirty>>3)&1) printf("ebx ");
9166       if((branch_regs[i].dirty>>5)&1) printf("ebp ");
9167       if((branch_regs[i].dirty>>6)&1) printf("esi ");
9168       if((branch_regs[i].dirty>>7)&1) printf("edi ");
9169       #endif
9170       #ifdef __arm__
9171       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]);
9172       if(branch_regs[i].dirty&1) printf("r0 ");
9173       if((branch_regs[i].dirty>>1)&1) printf("r1 ");
9174       if((branch_regs[i].dirty>>2)&1) printf("r2 ");
9175       if((branch_regs[i].dirty>>3)&1) printf("r3 ");
9176       if((branch_regs[i].dirty>>4)&1) printf("r4 ");
9177       if((branch_regs[i].dirty>>5)&1) printf("r5 ");
9178       if((branch_regs[i].dirty>>6)&1) printf("r6 ");
9179       if((branch_regs[i].dirty>>7)&1) printf("r7 ");
9180       if((branch_regs[i].dirty>>8)&1) printf("r8 ");
9181       if((branch_regs[i].dirty>>9)&1) printf("r9 ");
9182       if((branch_regs[i].dirty>>10)&1) printf("r10 ");
9183       if((branch_regs[i].dirty>>12)&1) printf("r12 ");
9184       #endif
9185     }
9186   }
9187 #endif // REG_ALLOC_PRINT
9188
9189   /* Pass 8 - Assembly */
9190   linkcount=0;stubcount=0;
9191   ds=0;is_delayslot=0;
9192   u_int dirty_pre=0;
9193   void *beginning=start_block();
9194   if((u_int)addr&1) {
9195     ds=1;
9196     pagespan_ds();
9197   }
9198   void *instr_addr0_override = NULL;
9199
9200   if (start == 0x80030000) {
9201     // nasty hack for the fastbios thing
9202     // override block entry to this code
9203     instr_addr0_override = out;
9204     emit_movimm(start,0);
9205     // abuse io address var as a flag that we
9206     // have already returned here once
9207     emit_readword(&address,1);
9208     emit_writeword(0,&pcaddr);
9209     emit_writeword(0,&address);
9210     emit_cmp(0,1);
9211     #ifdef __aarch64__
9212     emit_jeq(out + 4*2);
9213     emit_far_jump(new_dyna_leave);
9214     #else
9215     emit_jne(new_dyna_leave);
9216     #endif
9217   }
9218   for(i=0;i<slen;i++)
9219   {
9220     //if(ds) printf("ds: ");
9221     disassemble_inst(i);
9222     if(ds) {
9223       ds=0; // Skip delay slot
9224       if(dops[i].bt) assem_debug("OOPS - branch into delay slot\n");
9225       instr_addr[i] = NULL;
9226     } else {
9227       speculate_register_values(i);
9228       #ifndef DESTRUCTIVE_WRITEBACK
9229       if (i < 2 || !dops[i-2].is_ujump)
9230       {
9231         wb_valid(regmap_pre[i],regs[i].regmap_entry,dirty_pre,regs[i].wasdirty,unneeded_reg[i]);
9232       }
9233       if((dops[i].itype==CJUMP||dops[i].itype==SJUMP)) {
9234         dirty_pre=branch_regs[i].dirty;
9235       }else{
9236         dirty_pre=regs[i].dirty;
9237       }
9238       #endif
9239       // write back
9240       if (i < 2 || !dops[i-2].is_ujump)
9241       {
9242         wb_invalidate(regmap_pre[i],regs[i].regmap_entry,regs[i].wasdirty,unneeded_reg[i]);
9243         loop_preload(regmap_pre[i],regs[i].regmap_entry);
9244       }
9245       // branch target entry point
9246       instr_addr[i] = out;
9247       assem_debug("<->\n");
9248       drc_dbg_emit_do_cmp(i, ccadj[i]);
9249       if (clear_hack_addr) {
9250         emit_movimm(0, 0);
9251         emit_writeword(0, &hack_addr);
9252         clear_hack_addr = 0;
9253       }
9254
9255       // load regs
9256       if(regs[i].regmap_entry[HOST_CCREG]==CCREG&&regs[i].regmap[HOST_CCREG]!=CCREG)
9257         wb_register(CCREG,regs[i].regmap_entry,regs[i].wasdirty);
9258       load_regs(regs[i].regmap_entry,regs[i].regmap,dops[i].rs1,dops[i].rs2);
9259       address_generation(i,&regs[i],regs[i].regmap_entry);
9260       load_consts(regmap_pre[i],regs[i].regmap,i);
9261       if(dops[i].is_jump)
9262       {
9263         // Load the delay slot registers if necessary
9264         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))
9265           load_regs(regs[i].regmap_entry,regs[i].regmap,dops[i+1].rs1,dops[i+1].rs1);
9266         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))
9267           load_regs(regs[i].regmap_entry,regs[i].regmap,dops[i+1].rs2,dops[i+1].rs2);
9268         if (ram_offset && (dops[i+1].is_load || dops[i+1].is_store))
9269           load_regs(regs[i].regmap_entry,regs[i].regmap,ROREG,ROREG);
9270         if (dops[i+1].is_store)
9271           load_regs(regs[i].regmap_entry,regs[i].regmap,INVCP,INVCP);
9272       }
9273       else if(i+1<slen)
9274       {
9275         // Preload registers for following instruction
9276         if(dops[i+1].rs1!=dops[i].rs1&&dops[i+1].rs1!=dops[i].rs2)
9277           if(dops[i+1].rs1!=dops[i].rt1&&dops[i+1].rs1!=dops[i].rt2)
9278             load_regs(regs[i].regmap_entry,regs[i].regmap,dops[i+1].rs1,dops[i+1].rs1);
9279         if(dops[i+1].rs2!=dops[i+1].rs1&&dops[i+1].rs2!=dops[i].rs1&&dops[i+1].rs2!=dops[i].rs2)
9280           if(dops[i+1].rs2!=dops[i].rt1&&dops[i+1].rs2!=dops[i].rt2)
9281             load_regs(regs[i].regmap_entry,regs[i].regmap,dops[i+1].rs2,dops[i+1].rs2);
9282       }
9283       // TODO: if(is_ooo(i)) address_generation(i+1);
9284       if (!dops[i].is_jump || dops[i].itype == CJUMP)
9285         load_regs(regs[i].regmap_entry,regs[i].regmap,CCREG,CCREG);
9286       if (ram_offset && (dops[i].is_load || dops[i].is_store))
9287         load_regs(regs[i].regmap_entry,regs[i].regmap,ROREG,ROREG);
9288       if (dops[i].is_store)
9289         load_regs(regs[i].regmap_entry,regs[i].regmap,INVCP,INVCP);
9290
9291       ds = assemble(i, &regs[i], ccadj[i]);
9292
9293       if (dops[i].is_ujump)
9294         literal_pool(1024);
9295       else
9296         literal_pool_jumpover(256);
9297     }
9298   }
9299
9300   assert(slen > 0);
9301   if (slen > 0 && dops[slen-1].itype == INTCALL) {
9302     // no ending needed for this block since INTCALL never returns
9303   }
9304   // If the block did not end with an unconditional branch,
9305   // add a jump to the next instruction.
9306   else if (i > 1) {
9307     if (!dops[i-2].is_ujump && dops[i-1].itype != SPAN) {
9308       assert(!dops[i-1].is_jump);
9309       assert(i==slen);
9310       if(dops[i-2].itype!=CJUMP&&dops[i-2].itype!=SJUMP) {
9311         store_regs_bt(regs[i-1].regmap,regs[i-1].dirty,start+i*4);
9312         if(regs[i-1].regmap[HOST_CCREG]!=CCREG)
9313           emit_loadreg(CCREG,HOST_CCREG);
9314         emit_addimm(HOST_CCREG, ccadj[i-1] + CLOCK_ADJUST(1), HOST_CCREG);
9315       }
9316       else
9317       {
9318         store_regs_bt(branch_regs[i-2].regmap,branch_regs[i-2].dirty,start+i*4);
9319         assert(branch_regs[i-2].regmap[HOST_CCREG]==CCREG);
9320       }
9321       add_to_linker(out,start+i*4,0);
9322       emit_jmp(0);
9323     }
9324   }
9325   else
9326   {
9327     assert(i>0);
9328     assert(!dops[i-1].is_jump);
9329     store_regs_bt(regs[i-1].regmap,regs[i-1].dirty,start+i*4);
9330     if(regs[i-1].regmap[HOST_CCREG]!=CCREG)
9331       emit_loadreg(CCREG,HOST_CCREG);
9332     emit_addimm(HOST_CCREG, ccadj[i-1] + CLOCK_ADJUST(1), HOST_CCREG);
9333     add_to_linker(out,start+i*4,0);
9334     emit_jmp(0);
9335   }
9336
9337   // TODO: delay slot stubs?
9338   // Stubs
9339   for(i=0;i<stubcount;i++)
9340   {
9341     switch(stubs[i].type)
9342     {
9343       case LOADB_STUB:
9344       case LOADH_STUB:
9345       case LOADW_STUB:
9346       case LOADD_STUB:
9347       case LOADBU_STUB:
9348       case LOADHU_STUB:
9349         do_readstub(i);break;
9350       case STOREB_STUB:
9351       case STOREH_STUB:
9352       case STOREW_STUB:
9353       case STORED_STUB:
9354         do_writestub(i);break;
9355       case CC_STUB:
9356         do_ccstub(i);break;
9357       case INVCODE_STUB:
9358         do_invstub(i);break;
9359       case FP_STUB:
9360         do_cop1stub(i);break;
9361       case STORELR_STUB:
9362         do_unalignedwritestub(i);break;
9363     }
9364   }
9365
9366   if (instr_addr0_override)
9367     instr_addr[0] = instr_addr0_override;
9368
9369   /* Pass 9 - Linker */
9370   for(i=0;i<linkcount;i++)
9371   {
9372     assem_debug("%p -> %8x\n",link_addr[i].addr,link_addr[i].target);
9373     literal_pool(64);
9374     if (!link_addr[i].ext)
9375     {
9376       void *stub = out;
9377       void *addr = check_addr(link_addr[i].target);
9378       emit_extjump(link_addr[i].addr, link_addr[i].target);
9379       if (addr) {
9380         set_jump_target(link_addr[i].addr, addr);
9381         add_jump_out(link_addr[i].target,stub);
9382       }
9383       else
9384         set_jump_target(link_addr[i].addr, stub);
9385     }
9386     else
9387     {
9388       // Internal branch
9389       int target=(link_addr[i].target-start)>>2;
9390       assert(target>=0&&target<slen);
9391       assert(instr_addr[target]);
9392       //#ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
9393       //set_jump_target_fillslot(link_addr[i].addr,instr_addr[target],link_addr[i].ext>>1);
9394       //#else
9395       set_jump_target(link_addr[i].addr, instr_addr[target]);
9396       //#endif
9397     }
9398   }
9399
9400   u_int source_len = slen*4;
9401   if (dops[slen-1].itype == INTCALL && source_len > 4)
9402     // no need to treat the last instruction as compiled
9403     // as interpreter fully handles it
9404     source_len -= 4;
9405
9406   if ((u_char *)copy + source_len > (u_char *)shadow + sizeof(shadow))
9407     copy = shadow;
9408
9409   // External Branch Targets (jump_in)
9410   for(i=0;i<slen;i++)
9411   {
9412     if(dops[i].bt||i==0)
9413     {
9414       if(instr_addr[i]) // TODO - delay slots (=null)
9415       {
9416         u_int vaddr=start+i*4;
9417         u_int page=get_page(vaddr);
9418         u_int vpage=get_vpage(vaddr);
9419         literal_pool(256);
9420         {
9421           assem_debug("%p (%d) <- %8x\n",instr_addr[i],i,start+i*4);
9422           assem_debug("jump_in: %x\n",start+i*4);
9423           ll_add(jump_dirty+vpage,vaddr,out);
9424           void *entry_point = do_dirty_stub(i, source_len);
9425           ll_add_flags(jump_in+page,vaddr,state_rflags,entry_point);
9426           // If there was an existing entry in the hash table,
9427           // replace it with the new address.
9428           // Don't add new entries.  We'll insert the
9429           // ones that actually get used in check_addr().
9430           struct ht_entry *ht_bin = hash_table_get(vaddr);
9431           if (ht_bin->vaddr[0] == vaddr)
9432             ht_bin->tcaddr[0] = entry_point;
9433           if (ht_bin->vaddr[1] == vaddr)
9434             ht_bin->tcaddr[1] = entry_point;
9435         }
9436       }
9437     }
9438   }
9439   // Write out the literal pool if necessary
9440   literal_pool(0);
9441   #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
9442   // Align code
9443   if(((u_int)out)&7) emit_addnop(13);
9444   #endif
9445   assert(out - (u_char *)beginning < MAX_OUTPUT_BLOCK_SIZE);
9446   //printf("shadow buffer: %p-%p\n",copy,(u_char *)copy+slen*4);
9447   memcpy(copy, source, source_len);
9448   copy += source_len;
9449
9450   end_block(beginning);
9451
9452   // If we're within 256K of the end of the buffer,
9453   // start over from the beginning. (Is 256K enough?)
9454   if (out > ndrc->translation_cache + sizeof(ndrc->translation_cache) - MAX_OUTPUT_BLOCK_SIZE)
9455     out = ndrc->translation_cache;
9456
9457   // Trap writes to any of the pages we compiled
9458   for(i=start>>12;i<=(start+slen*4)>>12;i++) {
9459     invalid_code[i]=0;
9460   }
9461   inv_code_start=inv_code_end=~0;
9462
9463   // for PCSX we need to mark all mirrors too
9464   if(get_page(start)<(RAM_SIZE>>12))
9465     for(i=start>>12;i<=(start+slen*4)>>12;i++)
9466       invalid_code[((u_int)0x00000000>>12)|(i&0x1ff)]=
9467       invalid_code[((u_int)0x80000000>>12)|(i&0x1ff)]=
9468       invalid_code[((u_int)0xa0000000>>12)|(i&0x1ff)]=0;
9469
9470   /* Pass 10 - Free memory by expiring oldest blocks */
9471
9472   int end=(((out-ndrc->translation_cache)>>(TARGET_SIZE_2-16))+16384)&65535;
9473   while(expirep!=end)
9474   {
9475     int shift=TARGET_SIZE_2-3; // Divide into 8 blocks
9476     uintptr_t base_offs = ((uintptr_t)(expirep >> 13) << shift); // Base offset of this block
9477     uintptr_t base_offs_s = base_offs >> shift;
9478     inv_debug("EXP: Phase %d\n",expirep);
9479     switch((expirep>>11)&3)
9480     {
9481       case 0:
9482         // Clear jump_in and jump_dirty
9483         ll_remove_matching_addrs(jump_in+(expirep&2047),base_offs_s,shift);
9484         ll_remove_matching_addrs(jump_dirty+(expirep&2047),base_offs_s,shift);
9485         ll_remove_matching_addrs(jump_in+2048+(expirep&2047),base_offs_s,shift);
9486         ll_remove_matching_addrs(jump_dirty+2048+(expirep&2047),base_offs_s,shift);
9487         break;
9488       case 1:
9489         // Clear pointers
9490         ll_kill_pointers(jump_out[expirep&2047],base_offs_s,shift);
9491         ll_kill_pointers(jump_out[(expirep&2047)+2048],base_offs_s,shift);
9492         break;
9493       case 2:
9494         // Clear hash table
9495         for(i=0;i<32;i++) {
9496           struct ht_entry *ht_bin = &hash_table[((expirep&2047)<<5)+i];
9497           uintptr_t o1 = (u_char *)ht_bin->tcaddr[1] - ndrc->translation_cache;
9498           uintptr_t o2 = o1 - MAX_OUTPUT_BLOCK_SIZE;
9499           if ((o1 >> shift) == base_offs_s || (o2 >> shift) == base_offs_s) {
9500             inv_debug("EXP: Remove hash %x -> %p\n",ht_bin->vaddr[1],ht_bin->tcaddr[1]);
9501             ht_bin->vaddr[1] = -1;
9502             ht_bin->tcaddr[1] = NULL;
9503           }
9504           o1 = (u_char *)ht_bin->tcaddr[0] - ndrc->translation_cache;
9505           o2 = o1 - MAX_OUTPUT_BLOCK_SIZE;
9506           if ((o1 >> shift) == base_offs_s || (o2 >> shift) == base_offs_s) {
9507             inv_debug("EXP: Remove hash %x -> %p\n",ht_bin->vaddr[0],ht_bin->tcaddr[0]);
9508             ht_bin->vaddr[0] = ht_bin->vaddr[1];
9509             ht_bin->tcaddr[0] = ht_bin->tcaddr[1];
9510             ht_bin->vaddr[1] = -1;
9511             ht_bin->tcaddr[1] = NULL;
9512           }
9513         }
9514         break;
9515       case 3:
9516         // Clear jump_out
9517         if((expirep&2047)==0)
9518           do_clear_cache();
9519         ll_remove_matching_addrs(jump_out+(expirep&2047),base_offs_s,shift);
9520         ll_remove_matching_addrs(jump_out+2048+(expirep&2047),base_offs_s,shift);
9521         break;
9522     }
9523     expirep=(expirep+1)&65535;
9524   }
9525 #ifdef ASSEM_PRINT
9526   fflush(stdout);
9527 #endif
9528   return 0;
9529 }
9530
9531 // vim:shiftwidth=2:expandtab