4ff20c490318de55e71a79b90aa23a7403ea5f57
[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 #include "arm_features.h"
39
40 #define noinline __attribute__((noinline,noclone))
41 #ifndef ARRAY_SIZE
42 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
43 #endif
44 #ifndef min
45 #define min(a, b) ((b) < (a) ? (b) : (a))
46 #endif
47 #ifndef max
48 #define max(a, b) ((b) > (a) ? (b) : (a))
49 #endif
50
51 //#define DISASM
52 //#define ASSEM_PRINT
53 //#define STAT_PRINT
54
55 #ifdef ASSEM_PRINT
56 #define assem_debug printf
57 #else
58 #define assem_debug(...)
59 #endif
60 //#define inv_debug printf
61 #define inv_debug(...)
62
63 #ifdef __i386__
64 #include "assem_x86.h"
65 #endif
66 #ifdef __x86_64__
67 #include "assem_x64.h"
68 #endif
69 #ifdef __arm__
70 #include "assem_arm.h"
71 #endif
72 #ifdef __aarch64__
73 #include "assem_arm64.h"
74 #endif
75
76 #define RAM_SIZE 0x200000
77 #define MAXBLOCK 4096
78 #define MAX_OUTPUT_BLOCK_SIZE 262144
79
80 #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT)
81 #define INVALIDATE_USE_COND_CALL
82 #endif
83
84 #ifdef VITA
85 // apparently Vita has a 16MB limit, so either we cut tc in half,
86 // or use this hack (it's a hack because tc size was designed to be power-of-2)
87 #define TC_REDUCE_BYTES 4096
88 #else
89 #define TC_REDUCE_BYTES 0
90 #endif
91
92 struct ndrc_mem
93 {
94   u_char translation_cache[(1 << TARGET_SIZE_2) - TC_REDUCE_BYTES];
95   struct
96   {
97     struct tramp_insns ops[2048 / sizeof(struct tramp_insns)];
98     const void *f[2048 / sizeof(void *)];
99   } tramp;
100 };
101
102 #ifdef BASE_ADDR_DYNAMIC
103 static struct ndrc_mem *ndrc;
104 #else
105 static struct ndrc_mem ndrc_ __attribute__((aligned(4096)));
106 static struct ndrc_mem *ndrc = &ndrc_;
107 #endif
108
109 // stubs
110 enum stub_type {
111   CC_STUB = 1,
112   FP_STUB = 2,
113   LOADB_STUB = 3,
114   LOADH_STUB = 4,
115   LOADW_STUB = 5,
116   LOADD_STUB = 6,
117   LOADBU_STUB = 7,
118   LOADHU_STUB = 8,
119   STOREB_STUB = 9,
120   STOREH_STUB = 10,
121   STOREW_STUB = 11,
122   STORED_STUB = 12,
123   STORELR_STUB = 13,
124   INVCODE_STUB = 14,
125 };
126
127 // regmap_pre[i]    - regs before [i] insn starts; dirty things here that
128 //                    don't match .regmap will be written back
129 // [i].regmap_entry - regs that must be set up if someone jumps here
130 // [i].regmap       - regs [i] insn will read/(over)write
131 // branch_regs[i].* - same as above but for branches, takes delay slot into account
132 struct regstat
133 {
134   signed char regmap_entry[HOST_REGS];
135   signed char regmap[HOST_REGS];
136   uint64_t wasdirty;
137   uint64_t dirty;
138   uint64_t u;
139   u_int wasconst;                // before; for example 'lw r2, (r2)' wasconst is true
140   u_int isconst;                 //  ... but isconst is false when r2 is known
141   u_int loadedconst;             // host regs that have constants loaded
142   u_int waswritten;              // MIPS regs that were used as store base before
143 };
144
145 // note: asm depends on this layout
146 struct ll_entry
147 {
148   u_int vaddr;
149   void *addr;
150   struct ll_entry *next;
151 };
152
153 struct ht_entry
154 {
155   u_int vaddr[2];
156   void *tcaddr[2];
157 };
158
159 struct code_stub
160 {
161   enum stub_type type;
162   void *addr;
163   void *retaddr;
164   u_int a;
165   uintptr_t b;
166   uintptr_t c;
167   u_int d;
168   u_int e;
169 };
170
171 struct link_entry
172 {
173   void *addr;
174   u_int target;
175   u_int internal;
176 };
177
178 struct block_info
179 {
180   struct block_info *next;
181   const void *source;
182   const void *copy;
183   u_int start; // vaddr of the block start
184   u_int len;   // of the whole block source
185   u_int tc_offs;
186   //u_int tc_len;
187   u_int reg_sv_flags;
188   u_short is_dirty;
189   u_short jump_in_cnt;
190   struct {
191     u_int vaddr;
192     void *addr;
193   } jump_in[0];
194 };
195
196 static struct decoded_insn
197 {
198   u_char itype;
199   u_char opcode;
200   u_char opcode2;
201   u_char rs1;
202   u_char rs2;
203   u_char rt1;
204   u_char rt2;
205   u_char use_lt1:1;
206   u_char bt:1;
207   u_char ooo:1;
208   u_char is_ds:1;
209   u_char is_jump:1;
210   u_char is_ujump:1;
211   u_char is_load:1;
212   u_char is_store:1;
213 } dops[MAXBLOCK];
214
215   static u_char *out;
216   static struct ht_entry hash_table[65536];
217   static struct block_info *blocks[4096];
218   static struct ll_entry *jump_out[4096];
219   static u_int start;
220   static u_int *source;
221   static uint64_t gte_rs[MAXBLOCK]; // gte: 32 data and 32 ctl regs
222   static uint64_t gte_rt[MAXBLOCK];
223   static uint64_t gte_unneeded[MAXBLOCK];
224   static u_int smrv[32]; // speculated MIPS register values
225   static u_int smrv_strong; // mask or regs that are likely to have correct values
226   static u_int smrv_weak; // same, but somewhat less likely
227   static u_int smrv_strong_next; // same, but after current insn executes
228   static u_int smrv_weak_next;
229   static int imm[MAXBLOCK];
230   static u_int ba[MAXBLOCK];
231   static uint64_t unneeded_reg[MAXBLOCK];
232   static uint64_t branch_unneeded_reg[MAXBLOCK];
233   // see 'struct regstat' for a description
234   static signed char regmap_pre[MAXBLOCK][HOST_REGS];
235   // contains 'real' consts at [i] insn, but may differ from what's actually
236   // loaded in host reg as 'final' value is always loaded, see get_final_value()
237   static uint32_t current_constmap[HOST_REGS];
238   static uint32_t constmap[MAXBLOCK][HOST_REGS];
239   static struct regstat regs[MAXBLOCK];
240   static struct regstat branch_regs[MAXBLOCK];
241   static signed char minimum_free_regs[MAXBLOCK];
242   static int ccadj[MAXBLOCK];
243   static int slen;
244   static void *instr_addr[MAXBLOCK];
245   static struct link_entry link_addr[MAXBLOCK];
246   static int linkcount;
247   static struct code_stub stubs[MAXBLOCK*3];
248   static int stubcount;
249   static u_int literals[1024][2];
250   static int literalcount;
251   static int is_delayslot;
252   static char shadow[1048576]  __attribute__((aligned(16)));
253   static void *copy;
254   static int expirep;
255   static u_int stop_after_jal;
256   static u_int f1_hack;
257 #ifdef STAT_PRINT
258   static int stat_bc_direct;
259   static int stat_bc_pre;
260   static int stat_bc_restore;
261   static int stat_ht_lookups;
262   static int stat_jump_in_lookups;
263   static int stat_restore_tries;
264   static int stat_restore_compares;
265   static int stat_inv_addr_calls;
266   static int stat_inv_hits;
267   static int stat_blocks;
268   static int stat_links;
269   #define stat_inc(s) s++
270   #define stat_dec(s) s--
271   #define stat_clear(s) s = 0
272 #else
273   #define stat_inc(s)
274   #define stat_dec(s)
275   #define stat_clear(s)
276 #endif
277
278   int new_dynarec_hacks;
279   int new_dynarec_hacks_pergame;
280   int new_dynarec_hacks_old;
281   int new_dynarec_did_compile;
282
283   #define HACK_ENABLED(x) ((new_dynarec_hacks | new_dynarec_hacks_pergame) & (x))
284
285   extern int cycle_count; // ... until end of the timeslice, counts -N -> 0
286   extern int last_count;  // last absolute target, often = next_interupt
287   extern int pcaddr;
288   extern int pending_exception;
289   extern int branch_target;
290   extern uintptr_t ram_offset;
291   extern uintptr_t mini_ht[32][2];
292
293   /* registers that may be allocated */
294   /* 1-31 gpr */
295 #define LOREG 32 // lo
296 #define HIREG 33 // hi
297 //#define FSREG 34 // FPU status (FCSR)
298 #define CSREG 35 // Coprocessor status
299 #define CCREG 36 // Cycle count
300 #define INVCP 37 // Pointer to invalid_code
301 //#define MMREG 38 // Pointer to memory_map
302 #define ROREG 39 // ram offset (if rdram!=0x80000000)
303 #define TEMPREG 40
304 #define FTEMP 40 // FPU temporary register
305 #define PTEMP 41 // Prefetch temporary register
306 //#define TLREG 42 // TLB mapping offset
307 #define RHASH 43 // Return address hash
308 #define RHTBL 44 // Return address hash table address
309 #define RTEMP 45 // JR/JALR address register
310 #define MAXREG 45
311 #define AGEN1 46 // Address generation temporary register
312 //#define AGEN2 47 // Address generation temporary register
313 //#define MGEN1 48 // Maptable address generation temporary register
314 //#define MGEN2 49 // Maptable address generation temporary register
315 #define BTREG 50 // Branch target temporary register
316
317   /* instruction types */
318 #define NOP 0     // No operation
319 #define LOAD 1    // Load
320 #define STORE 2   // Store
321 #define LOADLR 3  // Unaligned load
322 #define STORELR 4 // Unaligned store
323 #define MOV 5     // Move
324 #define ALU 6     // Arithmetic/logic
325 #define MULTDIV 7 // Multiply/divide
326 #define SHIFT 8   // Shift by register
327 #define SHIFTIMM 9// Shift by immediate
328 #define IMM16 10  // 16-bit immediate
329 #define RJUMP 11  // Unconditional jump to register
330 #define UJUMP 12  // Unconditional jump
331 #define CJUMP 13  // Conditional branch (BEQ/BNE/BGTZ/BLEZ)
332 #define SJUMP 14  // Conditional branch (regimm format)
333 #define COP0 15   // Coprocessor 0
334 #define COP1 16   // Coprocessor 1
335 #define C1LS 17   // Coprocessor 1 load/store
336 //#define FJUMP 18  // Conditional branch (floating point)
337 //#define FLOAT 19  // Floating point unit
338 //#define FCONV 20  // Convert integer to float
339 //#define FCOMP 21  // Floating point compare (sets FSREG)
340 #define SYSCALL 22// SYSCALL,BREAK
341 #define OTHER 23  // Other
342 //#define SPAN 24   // Branch/delay slot spans 2 pages
343 #define NI 25     // Not implemented
344 #define HLECALL 26// PCSX fake opcodes for HLE
345 #define COP2 27   // Coprocessor 2 move
346 #define C2LS 28   // Coprocessor 2 load/store
347 #define C2OP 29   // Coprocessor 2 operation
348 #define INTCALL 30// Call interpreter to handle rare corner cases
349
350   /* branch codes */
351 #define TAKEN 1
352 #define NOTTAKEN 2
353 #define NULLDS 3
354
355 #define DJT_1 (void *)1l // no function, just a label in assem_debug log
356 #define DJT_2 (void *)2l
357
358 // asm linkage
359 void dyna_linker();
360 void cc_interrupt();
361 void fp_exception();
362 void fp_exception_ds();
363 void jump_syscall   (u_int u0, u_int u1, u_int pc);
364 void jump_syscall_ds(u_int u0, u_int u1, u_int pc);
365 void jump_break   (u_int u0, u_int u1, u_int pc);
366 void jump_break_ds(u_int u0, u_int u1, u_int pc);
367 void jump_to_new_pc();
368 void call_gteStall();
369 void new_dyna_leave();
370
371 void *ndrc_get_addr_ht_param(u_int vaddr, int can_compile);
372 void *ndrc_get_addr_ht(u_int vaddr);
373 void ndrc_invalidate_addr(u_int addr);
374 void ndrc_add_jump_out(u_int vaddr, void *src);
375
376 static int new_recompile_block(u_int addr);
377 static void invalidate_block(struct block_info *block);
378
379 // Needed by assembler
380 static void wb_register(signed char r, const signed char regmap[], uint64_t dirty);
381 static void wb_dirtys(const signed char i_regmap[], uint64_t i_dirty);
382 static void wb_needed_dirtys(const signed char i_regmap[], uint64_t i_dirty, int addr);
383 static void load_all_regs(const signed char i_regmap[]);
384 static void load_needed_regs(const signed char i_regmap[], const signed char next_regmap[]);
385 static void load_regs_entry(int t);
386 static void load_all_consts(const signed char regmap[], u_int dirty, int i);
387 static u_int get_host_reglist(const signed char *regmap);
388
389 static int get_final_value(int hr, int i, int *value);
390 static void add_stub(enum stub_type type, void *addr, void *retaddr,
391   u_int a, uintptr_t b, uintptr_t c, u_int d, u_int e);
392 static void add_stub_r(enum stub_type type, void *addr, void *retaddr,
393   int i, int addr_reg, const struct regstat *i_regs, int ccadj, u_int reglist);
394 static void add_to_linker(void *addr, u_int target, int ext);
395 static void *emit_fastpath_cmp_jump(int i, const struct regstat *i_regs,
396   int addr, int *offset_reg, int *addr_reg_override);
397 static void *get_direct_memhandler(void *table, u_int addr,
398   enum stub_type type, uintptr_t *addr_host);
399 static void cop2_do_stall_check(u_int op, int i, const struct regstat *i_regs, u_int reglist);
400 static void pass_args(int a0, int a1);
401 static void emit_far_jump(const void *f);
402 static void emit_far_call(const void *f);
403
404 #ifdef VITA
405 #include <psp2/kernel/sysmem.h>
406 static int sceBlock;
407 // note: this interacts with RetroArch's Vita bootstrap code: bootstrap/vita/sbrk.c
408 extern int getVMBlock();
409 int _newlib_vm_size_user = sizeof(*ndrc);
410 #endif
411
412 static void mprotect_w_x(void *start, void *end, int is_x)
413 {
414 #ifdef NO_WRITE_EXEC
415   #if defined(VITA)
416   // *Open* enables write on all memory that was
417   // allocated by sceKernelAllocMemBlockForVM()?
418   if (is_x)
419     sceKernelCloseVMDomain();
420   else
421     sceKernelOpenVMDomain();
422   #else
423   u_long mstart = (u_long)start & ~4095ul;
424   u_long mend = (u_long)end;
425   if (mprotect((void *)mstart, mend - mstart,
426                PROT_READ | (is_x ? PROT_EXEC : PROT_WRITE)) != 0)
427     SysPrintf("mprotect(%c) failed: %s\n", is_x ? 'x' : 'w', strerror(errno));
428   #endif
429 #endif
430 }
431
432 static void start_tcache_write(void *start, void *end)
433 {
434   mprotect_w_x(start, end, 0);
435 }
436
437 static void end_tcache_write(void *start, void *end)
438 {
439 #if defined(__arm__) || defined(__aarch64__)
440   size_t len = (char *)end - (char *)start;
441   #if   defined(__BLACKBERRY_QNX__)
442   msync(start, len, MS_SYNC | MS_CACHE_ONLY | MS_INVALIDATE_ICACHE);
443   #elif defined(__MACH__)
444   sys_cache_control(kCacheFunctionPrepareForExecution, start, len);
445   #elif defined(VITA)
446   sceKernelSyncVMDomain(sceBlock, start, len);
447   #elif defined(_3DS)
448   ctr_flush_invalidate_cache();
449   #elif defined(__aarch64__)
450   // as of 2021, __clear_cache() is still broken on arm64
451   // so here is a custom one :(
452   clear_cache_arm64(start, end);
453   #else
454   __clear_cache(start, end);
455   #endif
456   (void)len;
457 #endif
458
459   mprotect_w_x(start, end, 1);
460 }
461
462 static void *start_block(void)
463 {
464   u_char *end = out + MAX_OUTPUT_BLOCK_SIZE;
465   if (end > ndrc->translation_cache + sizeof(ndrc->translation_cache))
466     end = ndrc->translation_cache + sizeof(ndrc->translation_cache);
467   start_tcache_write(out, end);
468   return out;
469 }
470
471 static void end_block(void *start)
472 {
473   end_tcache_write(start, out);
474 }
475
476 // also takes care of w^x mappings when patching code
477 static u_int needs_clear_cache[1<<(TARGET_SIZE_2-17)];
478
479 static void mark_clear_cache(void *target)
480 {
481   uintptr_t offset = (u_char *)target - ndrc->translation_cache;
482   u_int mask = 1u << ((offset >> 12) & 31);
483   if (!(needs_clear_cache[offset >> 17] & mask)) {
484     char *start = (char *)((uintptr_t)target & ~4095l);
485     start_tcache_write(start, start + 4095);
486     needs_clear_cache[offset >> 17] |= mask;
487   }
488 }
489
490 // Clearing the cache is rather slow on ARM Linux, so mark the areas
491 // that need to be cleared, and then only clear these areas once.
492 static void do_clear_cache(void)
493 {
494   int i, j;
495   for (i = 0; i < (1<<(TARGET_SIZE_2-17)); i++)
496   {
497     u_int bitmap = needs_clear_cache[i];
498     if (!bitmap)
499       continue;
500     for (j = 0; j < 32; j++)
501     {
502       u_char *start, *end;
503       if (!(bitmap & (1<<j)))
504         continue;
505
506       start = ndrc->translation_cache + i*131072 + j*4096;
507       end = start + 4095;
508       for (j++; j < 32; j++) {
509         if (!(bitmap & (1<<j)))
510           break;
511         end += 4096;
512       }
513       end_tcache_write(start, end);
514     }
515     needs_clear_cache[i] = 0;
516   }
517 }
518
519 //#define DEBUG_CYCLE_COUNT 1
520
521 #define NO_CYCLE_PENALTY_THR 12
522
523 int cycle_multiplier = CYCLE_MULT_DEFAULT; // 100 for 1.0
524 int cycle_multiplier_override;
525 int cycle_multiplier_old;
526 static int cycle_multiplier_active;
527
528 static int CLOCK_ADJUST(int x)
529 {
530   int m = cycle_multiplier_active;
531   int s = (x >> 31) | 1;
532   return (x * m + s * 50) / 100;
533 }
534
535 static int ds_writes_rjump_rs(int i)
536 {
537   return dops[i].rs1 != 0 && (dops[i].rs1 == dops[i+1].rt1 || dops[i].rs1 == dops[i+1].rt2);
538 }
539
540 // psx addr mirror masking (for invalidation)
541 static u_int pmmask(u_int vaddr)
542 {
543   vaddr &= ~0xe0000000;
544   if (vaddr < 0x01000000)
545     vaddr &= ~0x00e00000; // RAM mirrors
546   return vaddr;
547 }
548
549 static u_int get_page(u_int vaddr)
550 {
551   u_int page = pmmask(vaddr) >> 12;
552   if(page>2048) page=2048+(page&2047);
553   return page;
554 }
555
556 // get a page for looking for a block that has vaddr
557 // (needed because the block may start in previous page)
558 static u_int get_page_prev(u_int vaddr)
559 {
560   assert(MAXBLOCK <= (1 << 12));
561   u_int page = get_page(vaddr);
562   if (page & 511)
563     page--;
564   return page;
565 }
566
567 static struct ht_entry *hash_table_get(u_int vaddr)
568 {
569   return &hash_table[((vaddr>>16)^vaddr)&0xFFFF];
570 }
571
572 static void hash_table_add(u_int vaddr, void *tcaddr)
573 {
574   struct ht_entry *ht_bin = hash_table_get(vaddr);
575   assert(tcaddr);
576   ht_bin->vaddr[1] = ht_bin->vaddr[0];
577   ht_bin->tcaddr[1] = ht_bin->tcaddr[0];
578   ht_bin->vaddr[0] = vaddr;
579   ht_bin->tcaddr[0] = tcaddr;
580 }
581
582 static void hash_table_remove(int vaddr)
583 {
584   //printf("remove hash: %x\n",vaddr);
585   struct ht_entry *ht_bin = hash_table_get(vaddr);
586   if (ht_bin->vaddr[1] == vaddr) {
587     ht_bin->vaddr[1] = -1;
588     ht_bin->tcaddr[1] = NULL;
589   }
590   if (ht_bin->vaddr[0] == vaddr) {
591     ht_bin->vaddr[0] = ht_bin->vaddr[1];
592     ht_bin->tcaddr[0] = ht_bin->tcaddr[1];
593     ht_bin->vaddr[1] = -1;
594     ht_bin->tcaddr[1] = NULL;
595   }
596 }
597
598 static void mark_invalid_code(u_int vaddr, u_int len, char invalid)
599 {
600   u_int i, j;
601   vaddr &= 0x1fffffff;
602   for (i = vaddr & ~0xfff; i < vaddr + len; i += 0x1000) {
603     // ram mirrors, but should not hurt bios
604     for (j = 0; j < 0x800000; j += 0x200000) {
605       invalid_code[(i|j) >> 12] =
606       invalid_code[(i|j|0x80000000u) >> 12] =
607       invalid_code[(i|j|0xa0000000u) >> 12] = invalid;
608     }
609   }
610   if (!invalid && vaddr + len > inv_code_start && vaddr <= inv_code_end)
611     inv_code_start = inv_code_end = ~0;
612 }
613
614 // some messy ari64's code, seems to rely on unsigned 32bit overflow
615 static int doesnt_expire_soon(void *tcaddr)
616 {
617   u_int diff = (u_int)((u_char *)tcaddr - out) << (32-TARGET_SIZE_2);
618   return diff > (u_int)(0x60000000 + (MAX_OUTPUT_BLOCK_SIZE << (32-TARGET_SIZE_2)));
619 }
620
621 static void *try_restore_block(u_int vaddr, u_int start_page, u_int end_page)
622 {
623   void *found_clean = NULL;
624   u_int i, page;
625
626   stat_inc(stat_restore_tries);
627   for (page = start_page; page <= end_page; page++) {
628     struct block_info *block;
629     for (block = blocks[page]; block != NULL; block = block->next) {
630       if (vaddr < block->start)
631         break;
632       if (!block->is_dirty || vaddr >= block->start + block->len)
633         continue;
634       for (i = 0; i < block->jump_in_cnt; i++)
635         if (block->jump_in[i].vaddr == vaddr)
636           break;
637       if (i == block->jump_in_cnt)
638         continue;
639       assert(block->source && block->copy);
640       stat_inc(stat_restore_compares);
641       if (memcmp(block->source, block->copy, block->len))
642         continue;
643
644       block->is_dirty = 0;
645       found_clean = block->jump_in[i].addr;
646       hash_table_add(vaddr, found_clean);
647       mark_invalid_code(block->start, block->len, 0);
648       stat_inc(stat_bc_restore);
649       inv_debug("INV: restored %08x %p (%d)\n", vaddr, found_clean, block->jump_in_cnt);
650       return found_clean;
651     }
652   }
653   return NULL;
654 }
655
656 // Get address from virtual address
657 // This is called from the recompiled JR/JALR instructions
658 static void noinline *get_addr(u_int vaddr, int can_compile)
659 {
660   u_int start_page = get_page_prev(vaddr);
661   u_int i, page, end_page = get_page(vaddr);
662   void *found_clean = NULL;
663
664   stat_inc(stat_jump_in_lookups);
665   for (page = start_page; page <= end_page; page++) {
666     const struct block_info *block;
667     for (block = blocks[page]; block != NULL; block = block->next) {
668       if (vaddr < block->start)
669         break;
670       if (block->is_dirty || vaddr >= block->start + block->len)
671         continue;
672       for (i = 0; i < block->jump_in_cnt; i++)
673         if (block->jump_in[i].vaddr == vaddr)
674           break;
675       if (i == block->jump_in_cnt)
676         continue;
677       found_clean = block->jump_in[i].addr;
678       hash_table_add(vaddr, found_clean);
679       return found_clean;
680     }
681   }
682   found_clean = try_restore_block(vaddr, start_page, end_page);
683   if (found_clean)
684     return found_clean;
685
686   if (!can_compile)
687     return NULL;
688
689   int r = new_recompile_block(vaddr);
690   if (r == 0)
691     return ndrc_get_addr_ht(vaddr);
692
693   // generate an address error
694   Status|=2;
695   Cause=(vaddr<<31)|(4<<2);
696   EPC=(vaddr&1)?vaddr-5:vaddr;
697   BadVAddr=(vaddr&~1);
698   return ndrc_get_addr_ht(0x80000080);
699 }
700
701 // Look up address in hash table first
702 void *ndrc_get_addr_ht_param(u_int vaddr, int can_compile)
703 {
704   const struct ht_entry *ht_bin = hash_table_get(vaddr);
705   stat_inc(stat_ht_lookups);
706   if (ht_bin->vaddr[0] == vaddr) return ht_bin->tcaddr[0];
707   if (ht_bin->vaddr[1] == vaddr) return ht_bin->tcaddr[1];
708   return get_addr(vaddr, can_compile);
709 }
710
711 void *ndrc_get_addr_ht(u_int vaddr)
712 {
713   return ndrc_get_addr_ht_param(vaddr, 1);
714 }
715
716 static void clear_all_regs(signed char regmap[])
717 {
718   memset(regmap, -1, sizeof(regmap[0]) * HOST_REGS);
719 }
720
721 // get_reg: get allocated host reg from mips reg
722 // returns -1 if no such mips reg was allocated
723 #if defined(__arm__) && defined(HAVE_ARMV6) && HOST_REGS == 13 && EXCLUDE_REG == 11
724
725 extern signed char get_reg(const signed char regmap[], signed char r);
726
727 #else
728
729 static signed char get_reg(const signed char regmap[], signed char r)
730 {
731   int hr;
732   for (hr = 0; hr < HOST_REGS; hr++) {
733     if (hr == EXCLUDE_REG)
734       continue;
735     if (regmap[hr] == r)
736       return hr;
737   }
738   return -1;
739 }
740
741 #endif
742
743 // get reg as mask bit (1 << hr)
744 static u_int get_regm(const signed char regmap[], signed char r)
745 {
746   return (1u << (get_reg(regmap, r) & 31)) & ~(1u << 31);
747 }
748
749 static signed char get_reg_temp(const signed char regmap[])
750 {
751   int hr;
752   for (hr = 0; hr < HOST_REGS; hr++) {
753     if (hr == EXCLUDE_REG)
754       continue;
755     if (regmap[hr] == (signed char)-1)
756       return hr;
757   }
758   return -1;
759 }
760
761 // Find a register that is available for two consecutive cycles
762 static signed char get_reg2(signed char regmap1[], const signed char regmap2[], int r)
763 {
764   int hr;
765   for (hr=0;hr<HOST_REGS;hr++) if(hr!=EXCLUDE_REG&&regmap1[hr]==r&&regmap2[hr]==r) return hr;
766   return -1;
767 }
768
769 // reverse reg map: mips -> host
770 #define RRMAP_SIZE 64
771 static void make_rregs(const signed char regmap[], signed char rrmap[RRMAP_SIZE],
772   u_int *regs_can_change)
773 {
774   u_int r, hr, hr_can_change = 0;
775   memset(rrmap, -1, RRMAP_SIZE);
776   for (hr = 0; hr < HOST_REGS; )
777   {
778     r = regmap[hr];
779     rrmap[r & (RRMAP_SIZE - 1)] = hr;
780     // only add mips $1-$31+$lo, others shifted out
781     hr_can_change |= (uint64_t)1 << (hr + ((r - 1) & 32));
782     hr++;
783     if (hr == EXCLUDE_REG)
784       hr++;
785   }
786   hr_can_change |= 1u << (rrmap[33] & 31);
787   hr_can_change |= 1u << (rrmap[CCREG] & 31);
788   hr_can_change &= ~(1u << 31);
789   *regs_can_change = hr_can_change;
790 }
791
792 // same as get_reg, but takes rrmap
793 static signed char get_rreg(signed char rrmap[RRMAP_SIZE], signed char r)
794 {
795   assert(0 <= r && r < RRMAP_SIZE);
796   return rrmap[r];
797 }
798
799 static int count_free_regs(const signed char regmap[])
800 {
801   int count=0;
802   int hr;
803   for(hr=0;hr<HOST_REGS;hr++)
804   {
805     if(hr!=EXCLUDE_REG) {
806       if(regmap[hr]<0) count++;
807     }
808   }
809   return count;
810 }
811
812 static void dirty_reg(struct regstat *cur, signed char reg)
813 {
814   int hr;
815   if (!reg) return;
816   hr = get_reg(cur->regmap, reg);
817   if (hr >= 0)
818     cur->dirty |= 1<<hr;
819 }
820
821 static void set_const(struct regstat *cur, signed char reg, uint32_t value)
822 {
823   int hr;
824   if (!reg) return;
825   hr = get_reg(cur->regmap, reg);
826   if (hr >= 0) {
827     cur->isconst |= 1<<hr;
828     current_constmap[hr] = value;
829   }
830 }
831
832 static void clear_const(struct regstat *cur, signed char reg)
833 {
834   int hr;
835   if (!reg) return;
836   hr = get_reg(cur->regmap, reg);
837   if (hr >= 0)
838     cur->isconst &= ~(1<<hr);
839 }
840
841 static int is_const(const struct regstat *cur, signed char reg)
842 {
843   int hr;
844   if (reg < 0) return 0;
845   if (!reg) return 1;
846   hr = get_reg(cur->regmap, reg);
847   if (hr >= 0)
848     return (cur->isconst>>hr)&1;
849   return 0;
850 }
851
852 static uint32_t get_const(const struct regstat *cur, signed char reg)
853 {
854   int hr;
855   if (!reg) return 0;
856   hr = get_reg(cur->regmap, reg);
857   if (hr >= 0)
858     return current_constmap[hr];
859
860   SysPrintf("Unknown constant in r%d\n", reg);
861   abort();
862 }
863
864 // Least soon needed registers
865 // Look at the next ten instructions and see which registers
866 // will be used.  Try not to reallocate these.
867 static void lsn(u_char hsn[], int i, int *preferred_reg)
868 {
869   int j;
870   int b=-1;
871   for(j=0;j<9;j++)
872   {
873     if(i+j>=slen) {
874       j=slen-i-1;
875       break;
876     }
877     if (dops[i+j].is_ujump)
878     {
879       // Don't go past an unconditonal jump
880       j++;
881       break;
882     }
883   }
884   for(;j>=0;j--)
885   {
886     if(dops[i+j].rs1) hsn[dops[i+j].rs1]=j;
887     if(dops[i+j].rs2) hsn[dops[i+j].rs2]=j;
888     if(dops[i+j].rt1) hsn[dops[i+j].rt1]=j;
889     if(dops[i+j].rt2) hsn[dops[i+j].rt2]=j;
890     if(dops[i+j].itype==STORE || dops[i+j].itype==STORELR) {
891       // Stores can allocate zero
892       hsn[dops[i+j].rs1]=j;
893       hsn[dops[i+j].rs2]=j;
894     }
895     if (ram_offset && (dops[i+j].is_load || dops[i+j].is_store))
896       hsn[ROREG] = j;
897     // On some architectures stores need invc_ptr
898     #if defined(HOST_IMM8)
899     if (dops[i+j].is_store)
900       hsn[INVCP] = j;
901     #endif
902     if(i+j>=0&&(dops[i+j].itype==UJUMP||dops[i+j].itype==CJUMP||dops[i+j].itype==SJUMP))
903     {
904       hsn[CCREG]=j;
905       b=j;
906     }
907   }
908   if(b>=0)
909   {
910     if(ba[i+b]>=start && ba[i+b]<(start+slen*4))
911     {
912       // Follow first branch
913       int t=(ba[i+b]-start)>>2;
914       j=7-b;if(t+j>=slen) j=slen-t-1;
915       for(;j>=0;j--)
916       {
917         if(dops[t+j].rs1) if(hsn[dops[t+j].rs1]>j+b+2) hsn[dops[t+j].rs1]=j+b+2;
918         if(dops[t+j].rs2) if(hsn[dops[t+j].rs2]>j+b+2) hsn[dops[t+j].rs2]=j+b+2;
919         //if(dops[t+j].rt1) if(hsn[dops[t+j].rt1]>j+b+2) hsn[dops[t+j].rt1]=j+b+2;
920         //if(dops[t+j].rt2) if(hsn[dops[t+j].rt2]>j+b+2) hsn[dops[t+j].rt2]=j+b+2;
921       }
922     }
923     // TODO: preferred register based on backward branch
924   }
925   // Delay slot should preferably not overwrite branch conditions or cycle count
926   if (i > 0 && dops[i-1].is_jump) {
927     if(dops[i-1].rs1) if(hsn[dops[i-1].rs1]>1) hsn[dops[i-1].rs1]=1;
928     if(dops[i-1].rs2) if(hsn[dops[i-1].rs2]>1) hsn[dops[i-1].rs2]=1;
929     hsn[CCREG]=1;
930     // ...or hash tables
931     hsn[RHASH]=1;
932     hsn[RHTBL]=1;
933   }
934   // Coprocessor load/store needs FTEMP, even if not declared
935   if(dops[i].itype==C2LS) {
936     hsn[FTEMP]=0;
937   }
938   // Load L/R also uses FTEMP as a temporary register
939   if(dops[i].itype==LOADLR) {
940     hsn[FTEMP]=0;
941   }
942   // Also SWL/SWR/SDL/SDR
943   if(dops[i].opcode==0x2a||dops[i].opcode==0x2e||dops[i].opcode==0x2c||dops[i].opcode==0x2d) {
944     hsn[FTEMP]=0;
945   }
946   // Don't remove the miniht registers
947   if(dops[i].itype==UJUMP||dops[i].itype==RJUMP)
948   {
949     hsn[RHASH]=0;
950     hsn[RHTBL]=0;
951   }
952 }
953
954 // We only want to allocate registers if we're going to use them again soon
955 static int needed_again(int r, int i)
956 {
957   int j;
958   int b=-1;
959   int rn=10;
960
961   if (i > 0 && dops[i-1].is_ujump)
962   {
963     if(ba[i-1]<start || ba[i-1]>start+slen*4-4)
964       return 0; // Don't need any registers if exiting the block
965   }
966   for(j=0;j<9;j++)
967   {
968     if(i+j>=slen) {
969       j=slen-i-1;
970       break;
971     }
972     if (dops[i+j].is_ujump)
973     {
974       // Don't go past an unconditonal jump
975       j++;
976       break;
977     }
978     if(dops[i+j].itype==SYSCALL||dops[i+j].itype==HLECALL||dops[i+j].itype==INTCALL||((source[i+j]&0xfc00003f)==0x0d))
979     {
980       break;
981     }
982   }
983   for(;j>=1;j--)
984   {
985     if(dops[i+j].rs1==r) rn=j;
986     if(dops[i+j].rs2==r) rn=j;
987     if((unneeded_reg[i+j]>>r)&1) rn=10;
988     if(i+j>=0&&(dops[i+j].itype==UJUMP||dops[i+j].itype==CJUMP||dops[i+j].itype==SJUMP))
989     {
990       b=j;
991     }
992   }
993   if(rn<10) return 1;
994   (void)b;
995   return 0;
996 }
997
998 // Try to match register allocations at the end of a loop with those
999 // at the beginning
1000 static int loop_reg(int i, int r, int hr)
1001 {
1002   int j,k;
1003   for(j=0;j<9;j++)
1004   {
1005     if(i+j>=slen) {
1006       j=slen-i-1;
1007       break;
1008     }
1009     if (dops[i+j].is_ujump)
1010     {
1011       // Don't go past an unconditonal jump
1012       j++;
1013       break;
1014     }
1015   }
1016   k=0;
1017   if(i>0){
1018     if(dops[i-1].itype==UJUMP||dops[i-1].itype==CJUMP||dops[i-1].itype==SJUMP)
1019       k--;
1020   }
1021   for(;k<j;k++)
1022   {
1023     assert(r < 64);
1024     if((unneeded_reg[i+k]>>r)&1) return hr;
1025     if(i+k>=0&&(dops[i+k].itype==UJUMP||dops[i+k].itype==CJUMP||dops[i+k].itype==SJUMP))
1026     {
1027       if(ba[i+k]>=start && ba[i+k]<(start+i*4))
1028       {
1029         int t=(ba[i+k]-start)>>2;
1030         int reg=get_reg(regs[t].regmap_entry,r);
1031         if(reg>=0) return reg;
1032         //reg=get_reg(regs[t+1].regmap_entry,r);
1033         //if(reg>=0) return reg;
1034       }
1035     }
1036   }
1037   return hr;
1038 }
1039
1040
1041 // Allocate every register, preserving source/target regs
1042 static void alloc_all(struct regstat *cur,int i)
1043 {
1044   int hr;
1045
1046   for(hr=0;hr<HOST_REGS;hr++) {
1047     if(hr!=EXCLUDE_REG) {
1048       if((cur->regmap[hr]!=dops[i].rs1)&&(cur->regmap[hr]!=dops[i].rs2)&&
1049          (cur->regmap[hr]!=dops[i].rt1)&&(cur->regmap[hr]!=dops[i].rt2))
1050       {
1051         cur->regmap[hr]=-1;
1052         cur->dirty&=~(1<<hr);
1053       }
1054       // Don't need zeros
1055       if(cur->regmap[hr]==0)
1056       {
1057         cur->regmap[hr]=-1;
1058         cur->dirty&=~(1<<hr);
1059       }
1060     }
1061   }
1062 }
1063
1064 #ifndef NDEBUG
1065 static int host_tempreg_in_use;
1066
1067 static void host_tempreg_acquire(void)
1068 {
1069   assert(!host_tempreg_in_use);
1070   host_tempreg_in_use = 1;
1071 }
1072
1073 static void host_tempreg_release(void)
1074 {
1075   host_tempreg_in_use = 0;
1076 }
1077 #else
1078 static void host_tempreg_acquire(void) {}
1079 static void host_tempreg_release(void) {}
1080 #endif
1081
1082 #ifdef ASSEM_PRINT
1083 extern void gen_interupt();
1084 extern void do_insn_cmp();
1085 #define FUNCNAME(f) { f, " " #f }
1086 static const struct {
1087   void *addr;
1088   const char *name;
1089 } function_names[] = {
1090   FUNCNAME(cc_interrupt),
1091   FUNCNAME(gen_interupt),
1092   FUNCNAME(ndrc_get_addr_ht),
1093   FUNCNAME(jump_handler_read8),
1094   FUNCNAME(jump_handler_read16),
1095   FUNCNAME(jump_handler_read32),
1096   FUNCNAME(jump_handler_write8),
1097   FUNCNAME(jump_handler_write16),
1098   FUNCNAME(jump_handler_write32),
1099   FUNCNAME(ndrc_invalidate_addr),
1100   FUNCNAME(jump_to_new_pc),
1101   FUNCNAME(jump_break),
1102   FUNCNAME(jump_break_ds),
1103   FUNCNAME(jump_syscall),
1104   FUNCNAME(jump_syscall_ds),
1105   FUNCNAME(call_gteStall),
1106   FUNCNAME(new_dyna_leave),
1107   FUNCNAME(pcsx_mtc0),
1108   FUNCNAME(pcsx_mtc0_ds),
1109 #ifdef DRC_DBG
1110   FUNCNAME(do_insn_cmp),
1111 #endif
1112 };
1113
1114 static const char *func_name(const void *a)
1115 {
1116   int i;
1117   for (i = 0; i < sizeof(function_names)/sizeof(function_names[0]); i++)
1118     if (function_names[i].addr == a)
1119       return function_names[i].name;
1120   return "";
1121 }
1122 #else
1123 #define func_name(x) ""
1124 #endif
1125
1126 #ifdef __i386__
1127 #include "assem_x86.c"
1128 #endif
1129 #ifdef __x86_64__
1130 #include "assem_x64.c"
1131 #endif
1132 #ifdef __arm__
1133 #include "assem_arm.c"
1134 #endif
1135 #ifdef __aarch64__
1136 #include "assem_arm64.c"
1137 #endif
1138
1139 static void *get_trampoline(const void *f)
1140 {
1141   size_t i;
1142
1143   for (i = 0; i < ARRAY_SIZE(ndrc->tramp.f); i++) {
1144     if (ndrc->tramp.f[i] == f || ndrc->tramp.f[i] == NULL)
1145       break;
1146   }
1147   if (i == ARRAY_SIZE(ndrc->tramp.f)) {
1148     SysPrintf("trampoline table is full, last func %p\n", f);
1149     abort();
1150   }
1151   if (ndrc->tramp.f[i] == NULL) {
1152     start_tcache_write(&ndrc->tramp.f[i], &ndrc->tramp.f[i + 1]);
1153     ndrc->tramp.f[i] = f;
1154     end_tcache_write(&ndrc->tramp.f[i], &ndrc->tramp.f[i + 1]);
1155   }
1156   return &ndrc->tramp.ops[i];
1157 }
1158
1159 static void emit_far_jump(const void *f)
1160 {
1161   if (can_jump_or_call(f)) {
1162     emit_jmp(f);
1163     return;
1164   }
1165
1166   f = get_trampoline(f);
1167   emit_jmp(f);
1168 }
1169
1170 static void emit_far_call(const void *f)
1171 {
1172   if (can_jump_or_call(f)) {
1173     emit_call(f);
1174     return;
1175   }
1176
1177   f = get_trampoline(f);
1178   emit_call(f);
1179 }
1180
1181 // Add virtual address mapping to linked list
1182 static void ll_add(struct ll_entry **head,int vaddr,void *addr)
1183 {
1184   struct ll_entry *new_entry;
1185   new_entry=malloc(sizeof(struct ll_entry));
1186   assert(new_entry!=NULL);
1187   new_entry->vaddr=vaddr;
1188   new_entry->addr=addr;
1189   new_entry->next=*head;
1190   *head=new_entry;
1191 }
1192
1193 // Check if an address is already compiled
1194 // but don't return addresses which are about to expire from the cache
1195 static void *check_addr(u_int vaddr)
1196 {
1197   struct ht_entry *ht_bin = hash_table_get(vaddr);
1198   size_t i;
1199   for (i = 0; i < ARRAY_SIZE(ht_bin->vaddr); i++) {
1200     if (ht_bin->vaddr[i] == vaddr)
1201       if (doesnt_expire_soon((u_char *)ht_bin->tcaddr[i] - MAX_OUTPUT_BLOCK_SIZE))
1202         return ht_bin->tcaddr[i];
1203   }
1204
1205   // refactor to get_addr_nocompile?
1206   u_int start_page = get_page_prev(vaddr);
1207   u_int page, end_page = get_page(vaddr);
1208
1209   stat_inc(stat_jump_in_lookups);
1210   for (page = start_page; page <= end_page; page++) {
1211     const struct block_info *block;
1212     for (block = blocks[page]; block != NULL; block = block->next) {
1213       if (vaddr < block->start)
1214         break;
1215       if (block->is_dirty || vaddr >= block->start + block->len)
1216         continue;
1217       if (!doesnt_expire_soon(ndrc->translation_cache + block->tc_offs))
1218         continue;
1219       for (i = 0; i < block->jump_in_cnt; i++)
1220         if (block->jump_in[i].vaddr == vaddr)
1221           break;
1222       if (i == block->jump_in_cnt)
1223         continue;
1224
1225       // Update existing entry with current address
1226       void *addr = block->jump_in[i].addr;
1227       if (ht_bin->vaddr[0] == vaddr) {
1228         ht_bin->tcaddr[0] = addr;
1229         return addr;
1230       }
1231       if (ht_bin->vaddr[1] == vaddr) {
1232         ht_bin->tcaddr[1] = addr;
1233         return addr;
1234       }
1235       // Insert into hash table with low priority.
1236       // Don't evict existing entries, as they are probably
1237       // addresses that are being accessed frequently.
1238       if (ht_bin->vaddr[0] == -1) {
1239         ht_bin->vaddr[0] = vaddr;
1240         ht_bin->tcaddr[0] = addr;
1241       }
1242       else if (ht_bin->vaddr[1] == -1) {
1243         ht_bin->vaddr[1] = vaddr;
1244         ht_bin->tcaddr[1] = addr;
1245       }
1246       return addr;
1247     }
1248   }
1249   return NULL;
1250 }
1251
1252 static void ll_remove_matching_addrs(struct ll_entry **head,
1253   uintptr_t base_offs_s, int shift)
1254 {
1255   struct ll_entry *next;
1256   while(*head) {
1257     uintptr_t o1 = (u_char *)(*head)->addr - ndrc->translation_cache;
1258     uintptr_t o2 = o1 - MAX_OUTPUT_BLOCK_SIZE;
1259     if ((o1 >> shift) == base_offs_s || (o2 >> shift) == base_offs_s)
1260     {
1261       inv_debug("EXP: rm pointer to %08x (%p)\n", (*head)->vaddr, (*head)->addr);
1262       hash_table_remove((*head)->vaddr);
1263       next=(*head)->next;
1264       free(*head);
1265       *head=next;
1266       stat_dec(stat_links);
1267     }
1268     else
1269     {
1270       head=&((*head)->next);
1271     }
1272   }
1273 }
1274
1275 // Remove all entries from linked list
1276 static void ll_clear(struct ll_entry **head)
1277 {
1278   struct ll_entry *cur;
1279   struct ll_entry *next;
1280   if((cur=*head)) {
1281     *head=0;
1282     while(cur) {
1283       next=cur->next;
1284       free(cur);
1285       cur=next;
1286     }
1287   }
1288 }
1289
1290 #if 0
1291 // Dereference the pointers and remove if it matches
1292 static void ll_kill_pointers(struct ll_entry *head,
1293   uintptr_t base_offs_s, int shift)
1294 {
1295   while(head) {
1296     u_char *ptr = get_pointer(head->addr);
1297     uintptr_t o1 = ptr - ndrc->translation_cache;
1298     uintptr_t o2 = o1 - MAX_OUTPUT_BLOCK_SIZE;
1299     inv_debug("EXP: Lookup pointer to %p at %p (%x)\n",ptr,head->addr,head->vaddr);
1300     if ((o1 >> shift) == base_offs_s || (o2 >> shift) == base_offs_s)
1301     {
1302       inv_debug("EXP: Kill pointer at %p (%x)\n",head->addr,head->vaddr);
1303       void *host_addr=find_extjump_insn(head->addr);
1304       mark_clear_cache(host_addr);
1305       set_jump_target(host_addr, head->addr);
1306     }
1307     head=head->next;
1308   }
1309 }
1310 #endif
1311
1312 static void blocks_clear(struct block_info **head)
1313 {
1314   struct block_info *cur, *next;
1315
1316   if ((cur = *head)) {
1317     *head = NULL;
1318     while (cur) {
1319       next = cur->next;
1320       free(cur);
1321       cur = next;
1322     }
1323   }
1324 }
1325
1326 static void blocks_remove_matching_addrs(struct block_info **head,
1327   uintptr_t base_offs_s, int shift)
1328 {
1329   struct block_info *next;
1330   while (*head) {
1331     u_int o1 = (*head)->tc_offs;
1332     u_int o2 = o1 - MAX_OUTPUT_BLOCK_SIZE;
1333     if ((o1 >> shift) == base_offs_s || (o2 >> shift) == base_offs_s)
1334     {
1335       inv_debug("EXP: rm block %08x (tc_offs %u)\n", (*head)->start, o1);
1336       invalidate_block(*head);
1337       next = (*head)->next;
1338       free(*head);
1339       *head = next;
1340       stat_dec(stat_blocks);
1341     }
1342     else
1343     {
1344       head = &((*head)->next);
1345     }
1346   }
1347 }
1348
1349 // This is called when we write to a compiled block (see do_invstub)
1350 static void unlink_jumps_range(u_int start, u_int end)
1351 {
1352   u_int page, start_page = get_page(start), end_page = get_page(end - 1);
1353   struct ll_entry **head, *next;
1354
1355   for (page = start_page; page <= end_page; page++) {
1356     for (head = &jump_out[page]; *head; ) {
1357       if ((*head)->vaddr < start || (*head)->vaddr >= end) {
1358         head = &((*head)->next);
1359         continue;
1360       }
1361       inv_debug("INV: rm pointer to %08x (%p)\n", (*head)->vaddr, (*head)->addr);
1362       void *host_addr = find_extjump_insn((*head)->addr);
1363       mark_clear_cache(host_addr);
1364       set_jump_target(host_addr, (*head)->addr); // point back to dyna_linker stub
1365
1366       next = (*head)->next;
1367       free(*head);
1368       *head = next;
1369       stat_dec(stat_links);
1370     }
1371   }
1372 }
1373
1374 static void invalidate_block(struct block_info *block)
1375 {
1376   u_int i;
1377
1378   block->is_dirty = 1;
1379   unlink_jumps_range(block->start, block->start + block->len);
1380   for (i = 0; i < block->jump_in_cnt; i++)
1381     hash_table_remove(block->jump_in[i].vaddr);
1382 }
1383
1384 static int invalidate_range(u_int start, u_int end,
1385   u32 *inv_start_ret, u32 *inv_end_ret)
1386 {
1387   u_int start_page = get_page_prev(start);
1388   u_int end_page = get_page(end - 1);
1389   u_int start_m = pmmask(start);
1390   u_int end_m = pmmask(end);
1391   u_int inv_start, inv_end;
1392   u_int blk_start_m, blk_end_m;
1393   u_int page;
1394   int hit = 0;
1395
1396   // additional area without code (to supplement invalid_code[]), [start, end)
1397   // avoids excessive ndrc_invalidate_addr() calls
1398   inv_start = start_m & ~0xfff;
1399   inv_end = end_m | 0xfff;
1400
1401   for (page = start_page; page <= end_page; page++) {
1402     struct block_info *block;
1403     for (block = blocks[page]; block != NULL; block = block->next) {
1404       if (block->is_dirty)
1405         continue;
1406       blk_end_m = pmmask(block->start + block->len);
1407       if (blk_end_m <= start_m) {
1408         inv_start = max(inv_start, blk_end_m);
1409         continue;
1410       }
1411       blk_start_m = pmmask(block->start);
1412       if (end_m <= blk_start_m) {
1413         inv_end = min(inv_end, blk_start_m - 1);
1414         continue;
1415       }
1416       if (!block->source) // "hack" block - leave it alone
1417         continue;
1418
1419       hit++;
1420       invalidate_block(block);
1421       stat_inc(stat_inv_hits);
1422     }
1423   }
1424
1425   if (hit) {
1426     do_clear_cache();
1427 #ifdef USE_MINI_HT
1428     memset(mini_ht, -1, sizeof(mini_ht));
1429 #endif
1430   }
1431   if (inv_start <= (start_m & ~0xfff) && inv_end >= (start_m | 0xfff))
1432     // the whole page is empty now
1433     mark_invalid_code(start, 1, 1);
1434
1435   if (inv_start_ret) *inv_start_ret = inv_start | (start & 0xe0000000);
1436   if (inv_end_ret) *inv_end_ret = inv_end | (end & 0xe0000000);
1437   return hit;
1438 }
1439
1440 void new_dynarec_invalidate_range(unsigned int start, unsigned int end)
1441 {
1442   invalidate_range(start, end, NULL, NULL);
1443 }
1444
1445 void ndrc_invalidate_addr(u_int addr)
1446 {
1447   // this check is done by the caller
1448   //if (inv_code_start<=addr&&addr<=inv_code_end) { rhits++; return; }
1449   int ret = invalidate_range(addr, addr + 4, &inv_code_start, &inv_code_end);
1450   if (ret)
1451     inv_debug("INV ADDR: %08x hit %d blocks\n", addr, ret);
1452   else
1453     inv_debug("INV ADDR: %08x miss, inv %08x-%08x\n", addr, inv_code_start, inv_code_end);
1454   stat_inc(stat_inv_addr_calls);
1455 }
1456
1457 // This is called when loading a save state.
1458 // Anything could have changed, so invalidate everything.
1459 void new_dynarec_invalidate_all_pages(void)
1460 {
1461   struct block_info *block;
1462   u_int page;
1463   for (page = 0; page < ARRAY_SIZE(blocks); page++) {
1464     for (block = blocks[page]; block != NULL; block = block->next) {
1465       if (block->is_dirty)
1466         continue;
1467       if (!block->source) // hack block?
1468         continue;
1469       invalidate_block(block);
1470     }
1471   }
1472
1473   #ifdef USE_MINI_HT
1474   memset(mini_ht,-1,sizeof(mini_ht));
1475   #endif
1476   do_clear_cache();
1477 }
1478
1479 static void do_invstub(int n)
1480 {
1481   literal_pool(20);
1482   u_int reglist = stubs[n].a;
1483   set_jump_target(stubs[n].addr, out);
1484   save_regs(reglist);
1485   if (stubs[n].b != 0)
1486     emit_mov(stubs[n].b, 0);
1487   emit_readword(&inv_code_start, 1);
1488   emit_readword(&inv_code_end, 2);
1489   emit_cmp(0, 1);
1490   emit_cmpcs(2, 0);
1491   void *jaddr = out;
1492   emit_jc(0);
1493   emit_far_call(ndrc_invalidate_addr);
1494   set_jump_target(jaddr, out);
1495   restore_regs(reglist);
1496   emit_jmp(stubs[n].retaddr); // return address
1497 }
1498
1499 // Add an entry to jump_out after making a link
1500 // src should point to code by emit_extjump()
1501 void ndrc_add_jump_out(u_int vaddr,void *src)
1502 {
1503   u_int page=get_page(vaddr);
1504   inv_debug("ndrc_add_jump_out: %p -> %x (%d)\n",src,vaddr,page);
1505   check_extjump2(src);
1506   ll_add(jump_out+page,vaddr,src);
1507   //inv_debug("ndrc_add_jump_out:  to %p\n",get_pointer(src));
1508   stat_inc(stat_links);
1509 }
1510
1511 /* Register allocation */
1512
1513 // Note: registers are allocated clean (unmodified state)
1514 // if you intend to modify the register, you must call dirty_reg().
1515 static void alloc_reg(struct regstat *cur,int i,signed char reg)
1516 {
1517   int r,hr;
1518   int preferred_reg = PREFERRED_REG_FIRST
1519     + reg % (PREFERRED_REG_LAST - PREFERRED_REG_FIRST + 1);
1520   if (reg == CCREG) preferred_reg = HOST_CCREG;
1521   if (reg == PTEMP || reg == FTEMP) preferred_reg = 12;
1522   assert(PREFERRED_REG_FIRST != EXCLUDE_REG && EXCLUDE_REG != HOST_REGS);
1523   assert(reg >= 0);
1524
1525   // Don't allocate unused registers
1526   if((cur->u>>reg)&1) return;
1527
1528   // see if it's already allocated
1529   if (get_reg(cur->regmap, reg) >= 0)
1530     return;
1531
1532   // Keep the same mapping if the register was already allocated in a loop
1533   preferred_reg = loop_reg(i,reg,preferred_reg);
1534
1535   // Try to allocate the preferred register
1536   if(cur->regmap[preferred_reg]==-1) {
1537     cur->regmap[preferred_reg]=reg;
1538     cur->dirty&=~(1<<preferred_reg);
1539     cur->isconst&=~(1<<preferred_reg);
1540     return;
1541   }
1542   r=cur->regmap[preferred_reg];
1543   assert(r < 64);
1544   if((cur->u>>r)&1) {
1545     cur->regmap[preferred_reg]=reg;
1546     cur->dirty&=~(1<<preferred_reg);
1547     cur->isconst&=~(1<<preferred_reg);
1548     return;
1549   }
1550
1551   // Clear any unneeded registers
1552   // We try to keep the mapping consistent, if possible, because it
1553   // makes branches easier (especially loops).  So we try to allocate
1554   // first (see above) before removing old mappings.  If this is not
1555   // possible then go ahead and clear out the registers that are no
1556   // longer needed.
1557   for(hr=0;hr<HOST_REGS;hr++)
1558   {
1559     r=cur->regmap[hr];
1560     if(r>=0) {
1561       assert(r < 64);
1562       if((cur->u>>r)&1) {cur->regmap[hr]=-1;break;}
1563     }
1564   }
1565
1566   // Try to allocate any available register, but prefer
1567   // registers that have not been used recently.
1568   if (i > 0) {
1569     for (hr = PREFERRED_REG_FIRST; ; ) {
1570       if (cur->regmap[hr] < 0) {
1571         int oldreg = regs[i-1].regmap[hr];
1572         if (oldreg < 0 || (oldreg != dops[i-1].rs1 && oldreg != dops[i-1].rs2
1573              && oldreg != dops[i-1].rt1 && oldreg != dops[i-1].rt2))
1574         {
1575           cur->regmap[hr]=reg;
1576           cur->dirty&=~(1<<hr);
1577           cur->isconst&=~(1<<hr);
1578           return;
1579         }
1580       }
1581       hr++;
1582       if (hr == EXCLUDE_REG)
1583         hr++;
1584       if (hr == HOST_REGS)
1585         hr = 0;
1586       if (hr == PREFERRED_REG_FIRST)
1587         break;
1588     }
1589   }
1590
1591   // Try to allocate any available register
1592   for (hr = PREFERRED_REG_FIRST; ; ) {
1593     if (cur->regmap[hr] < 0) {
1594       cur->regmap[hr]=reg;
1595       cur->dirty&=~(1<<hr);
1596       cur->isconst&=~(1<<hr);
1597       return;
1598     }
1599     hr++;
1600     if (hr == EXCLUDE_REG)
1601       hr++;
1602     if (hr == HOST_REGS)
1603       hr = 0;
1604     if (hr == PREFERRED_REG_FIRST)
1605       break;
1606   }
1607
1608   // Ok, now we have to evict someone
1609   // Pick a register we hopefully won't need soon
1610   u_char hsn[MAXREG+1];
1611   memset(hsn,10,sizeof(hsn));
1612   int j;
1613   lsn(hsn,i,&preferred_reg);
1614   //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]);
1615   //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]);
1616   if(i>0) {
1617     // Don't evict the cycle count at entry points, otherwise the entry
1618     // stub will have to write it.
1619     if(dops[i].bt&&hsn[CCREG]>2) hsn[CCREG]=2;
1620     if (i>1 && hsn[CCREG] > 2 && dops[i-2].is_jump) hsn[CCREG]=2;
1621     for(j=10;j>=3;j--)
1622     {
1623       // Alloc preferred register if available
1624       if(hsn[r=cur->regmap[preferred_reg]&63]==j) {
1625         for(hr=0;hr<HOST_REGS;hr++) {
1626           // Evict both parts of a 64-bit register
1627           if(cur->regmap[hr]==r) {
1628             cur->regmap[hr]=-1;
1629             cur->dirty&=~(1<<hr);
1630             cur->isconst&=~(1<<hr);
1631           }
1632         }
1633         cur->regmap[preferred_reg]=reg;
1634         return;
1635       }
1636       for(r=1;r<=MAXREG;r++)
1637       {
1638         if(hsn[r]==j&&r!=dops[i-1].rs1&&r!=dops[i-1].rs2&&r!=dops[i-1].rt1&&r!=dops[i-1].rt2) {
1639           for(hr=0;hr<HOST_REGS;hr++) {
1640             if(hr!=HOST_CCREG||j<hsn[CCREG]) {
1641               if(cur->regmap[hr]==r) {
1642                 cur->regmap[hr]=reg;
1643                 cur->dirty&=~(1<<hr);
1644                 cur->isconst&=~(1<<hr);
1645                 return;
1646               }
1647             }
1648           }
1649         }
1650       }
1651     }
1652   }
1653   for(j=10;j>=0;j--)
1654   {
1655     for(r=1;r<=MAXREG;r++)
1656     {
1657       if(hsn[r]==j) {
1658         for(hr=0;hr<HOST_REGS;hr++) {
1659           if(cur->regmap[hr]==r) {
1660             cur->regmap[hr]=reg;
1661             cur->dirty&=~(1<<hr);
1662             cur->isconst&=~(1<<hr);
1663             return;
1664           }
1665         }
1666       }
1667     }
1668   }
1669   SysPrintf("This shouldn't happen (alloc_reg)");abort();
1670 }
1671
1672 // Allocate a temporary register.  This is done without regard to
1673 // dirty status or whether the register we request is on the unneeded list
1674 // Note: This will only allocate one register, even if called multiple times
1675 static void alloc_reg_temp(struct regstat *cur,int i,signed char reg)
1676 {
1677   int r,hr;
1678   int preferred_reg = -1;
1679
1680   // see if it's already allocated
1681   for(hr=0;hr<HOST_REGS;hr++)
1682   {
1683     if(hr!=EXCLUDE_REG&&cur->regmap[hr]==reg) return;
1684   }
1685
1686   // Try to allocate any available register
1687   for(hr=HOST_REGS-1;hr>=0;hr--) {
1688     if(hr!=EXCLUDE_REG&&cur->regmap[hr]==-1) {
1689       cur->regmap[hr]=reg;
1690       cur->dirty&=~(1<<hr);
1691       cur->isconst&=~(1<<hr);
1692       return;
1693     }
1694   }
1695
1696   // Find an unneeded register
1697   for(hr=HOST_REGS-1;hr>=0;hr--)
1698   {
1699     r=cur->regmap[hr];
1700     if(r>=0) {
1701       assert(r < 64);
1702       if((cur->u>>r)&1) {
1703         if(i==0||((unneeded_reg[i-1]>>r)&1)) {
1704           cur->regmap[hr]=reg;
1705           cur->dirty&=~(1<<hr);
1706           cur->isconst&=~(1<<hr);
1707           return;
1708         }
1709       }
1710     }
1711   }
1712
1713   // Ok, now we have to evict someone
1714   // Pick a register we hopefully won't need soon
1715   // TODO: we might want to follow unconditional jumps here
1716   // TODO: get rid of dupe code and make this into a function
1717   u_char hsn[MAXREG+1];
1718   memset(hsn,10,sizeof(hsn));
1719   int j;
1720   lsn(hsn,i,&preferred_reg);
1721   //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]);
1722   if(i>0) {
1723     // Don't evict the cycle count at entry points, otherwise the entry
1724     // stub will have to write it.
1725     if(dops[i].bt&&hsn[CCREG]>2) hsn[CCREG]=2;
1726     if (i>1 && hsn[CCREG] > 2 && dops[i-2].is_jump) hsn[CCREG]=2;
1727     for(j=10;j>=3;j--)
1728     {
1729       for(r=1;r<=MAXREG;r++)
1730       {
1731         if(hsn[r]==j&&r!=dops[i-1].rs1&&r!=dops[i-1].rs2&&r!=dops[i-1].rt1&&r!=dops[i-1].rt2) {
1732           for(hr=0;hr<HOST_REGS;hr++) {
1733             if(hr!=HOST_CCREG||hsn[CCREG]>2) {
1734               if(cur->regmap[hr]==r) {
1735                 cur->regmap[hr]=reg;
1736                 cur->dirty&=~(1<<hr);
1737                 cur->isconst&=~(1<<hr);
1738                 return;
1739               }
1740             }
1741           }
1742         }
1743       }
1744     }
1745   }
1746   for(j=10;j>=0;j--)
1747   {
1748     for(r=1;r<=MAXREG;r++)
1749     {
1750       if(hsn[r]==j) {
1751         for(hr=0;hr<HOST_REGS;hr++) {
1752           if(cur->regmap[hr]==r) {
1753             cur->regmap[hr]=reg;
1754             cur->dirty&=~(1<<hr);
1755             cur->isconst&=~(1<<hr);
1756             return;
1757           }
1758         }
1759       }
1760     }
1761   }
1762   SysPrintf("This shouldn't happen");abort();
1763 }
1764
1765 static void mov_alloc(struct regstat *current,int i)
1766 {
1767   if (dops[i].rs1 == HIREG || dops[i].rs1 == LOREG) {
1768     alloc_cc(current,i); // for stalls
1769     dirty_reg(current,CCREG);
1770   }
1771
1772   // Note: Don't need to actually alloc the source registers
1773   //alloc_reg(current,i,dops[i].rs1);
1774   alloc_reg(current,i,dops[i].rt1);
1775
1776   clear_const(current,dops[i].rs1);
1777   clear_const(current,dops[i].rt1);
1778   dirty_reg(current,dops[i].rt1);
1779 }
1780
1781 static void shiftimm_alloc(struct regstat *current,int i)
1782 {
1783   if(dops[i].opcode2<=0x3) // SLL/SRL/SRA
1784   {
1785     if(dops[i].rt1) {
1786       if(dops[i].rs1&&needed_again(dops[i].rs1,i)) alloc_reg(current,i,dops[i].rs1);
1787       else dops[i].use_lt1=!!dops[i].rs1;
1788       alloc_reg(current,i,dops[i].rt1);
1789       dirty_reg(current,dops[i].rt1);
1790       if(is_const(current,dops[i].rs1)) {
1791         int v=get_const(current,dops[i].rs1);
1792         if(dops[i].opcode2==0x00) set_const(current,dops[i].rt1,v<<imm[i]);
1793         if(dops[i].opcode2==0x02) set_const(current,dops[i].rt1,(u_int)v>>imm[i]);
1794         if(dops[i].opcode2==0x03) set_const(current,dops[i].rt1,v>>imm[i]);
1795       }
1796       else clear_const(current,dops[i].rt1);
1797     }
1798   }
1799   else
1800   {
1801     clear_const(current,dops[i].rs1);
1802     clear_const(current,dops[i].rt1);
1803   }
1804
1805   if(dops[i].opcode2>=0x38&&dops[i].opcode2<=0x3b) // DSLL/DSRL/DSRA
1806   {
1807     assert(0);
1808   }
1809   if(dops[i].opcode2==0x3c) // DSLL32
1810   {
1811     assert(0);
1812   }
1813   if(dops[i].opcode2==0x3e) // DSRL32
1814   {
1815     assert(0);
1816   }
1817   if(dops[i].opcode2==0x3f) // DSRA32
1818   {
1819     assert(0);
1820   }
1821 }
1822
1823 static void shift_alloc(struct regstat *current,int i)
1824 {
1825   if(dops[i].rt1) {
1826     if(dops[i].opcode2<=0x07) // SLLV/SRLV/SRAV
1827     {
1828       if(dops[i].rs1) alloc_reg(current,i,dops[i].rs1);
1829       if(dops[i].rs2) alloc_reg(current,i,dops[i].rs2);
1830       alloc_reg(current,i,dops[i].rt1);
1831       if(dops[i].rt1==dops[i].rs2) {
1832         alloc_reg_temp(current,i,-1);
1833         minimum_free_regs[i]=1;
1834       }
1835     } else { // DSLLV/DSRLV/DSRAV
1836       assert(0);
1837     }
1838     clear_const(current,dops[i].rs1);
1839     clear_const(current,dops[i].rs2);
1840     clear_const(current,dops[i].rt1);
1841     dirty_reg(current,dops[i].rt1);
1842   }
1843 }
1844
1845 static void alu_alloc(struct regstat *current,int i)
1846 {
1847   if(dops[i].opcode2>=0x20&&dops[i].opcode2<=0x23) { // ADD/ADDU/SUB/SUBU
1848     if(dops[i].rt1) {
1849       if(dops[i].rs1&&dops[i].rs2) {
1850         alloc_reg(current,i,dops[i].rs1);
1851         alloc_reg(current,i,dops[i].rs2);
1852       }
1853       else {
1854         if(dops[i].rs1&&needed_again(dops[i].rs1,i)) alloc_reg(current,i,dops[i].rs1);
1855         if(dops[i].rs2&&needed_again(dops[i].rs2,i)) alloc_reg(current,i,dops[i].rs2);
1856       }
1857       alloc_reg(current,i,dops[i].rt1);
1858     }
1859   }
1860   if(dops[i].opcode2==0x2a||dops[i].opcode2==0x2b) { // SLT/SLTU
1861     if(dops[i].rt1) {
1862       alloc_reg(current,i,dops[i].rs1);
1863       alloc_reg(current,i,dops[i].rs2);
1864       alloc_reg(current,i,dops[i].rt1);
1865     }
1866   }
1867   if(dops[i].opcode2>=0x24&&dops[i].opcode2<=0x27) { // AND/OR/XOR/NOR
1868     if(dops[i].rt1) {
1869       if(dops[i].rs1&&dops[i].rs2) {
1870         alloc_reg(current,i,dops[i].rs1);
1871         alloc_reg(current,i,dops[i].rs2);
1872       }
1873       else
1874       {
1875         if(dops[i].rs1&&needed_again(dops[i].rs1,i)) alloc_reg(current,i,dops[i].rs1);
1876         if(dops[i].rs2&&needed_again(dops[i].rs2,i)) alloc_reg(current,i,dops[i].rs2);
1877       }
1878       alloc_reg(current,i,dops[i].rt1);
1879     }
1880   }
1881   if(dops[i].opcode2>=0x2c&&dops[i].opcode2<=0x2f) { // DADD/DADDU/DSUB/DSUBU
1882     assert(0);
1883   }
1884   clear_const(current,dops[i].rs1);
1885   clear_const(current,dops[i].rs2);
1886   clear_const(current,dops[i].rt1);
1887   dirty_reg(current,dops[i].rt1);
1888 }
1889
1890 static void imm16_alloc(struct regstat *current,int i)
1891 {
1892   if(dops[i].rs1&&needed_again(dops[i].rs1,i)) alloc_reg(current,i,dops[i].rs1);
1893   else dops[i].use_lt1=!!dops[i].rs1;
1894   if(dops[i].rt1) alloc_reg(current,i,dops[i].rt1);
1895   if(dops[i].opcode==0x18||dops[i].opcode==0x19) { // DADDI/DADDIU
1896     assert(0);
1897   }
1898   else if(dops[i].opcode==0x0a||dops[i].opcode==0x0b) { // SLTI/SLTIU
1899     clear_const(current,dops[i].rs1);
1900     clear_const(current,dops[i].rt1);
1901   }
1902   else if(dops[i].opcode>=0x0c&&dops[i].opcode<=0x0e) { // ANDI/ORI/XORI
1903     if(is_const(current,dops[i].rs1)) {
1904       int v=get_const(current,dops[i].rs1);
1905       if(dops[i].opcode==0x0c) set_const(current,dops[i].rt1,v&imm[i]);
1906       if(dops[i].opcode==0x0d) set_const(current,dops[i].rt1,v|imm[i]);
1907       if(dops[i].opcode==0x0e) set_const(current,dops[i].rt1,v^imm[i]);
1908     }
1909     else clear_const(current,dops[i].rt1);
1910   }
1911   else if(dops[i].opcode==0x08||dops[i].opcode==0x09) { // ADDI/ADDIU
1912     if(is_const(current,dops[i].rs1)) {
1913       int v=get_const(current,dops[i].rs1);
1914       set_const(current,dops[i].rt1,v+imm[i]);
1915     }
1916     else clear_const(current,dops[i].rt1);
1917   }
1918   else {
1919     set_const(current,dops[i].rt1,imm[i]<<16); // LUI
1920   }
1921   dirty_reg(current,dops[i].rt1);
1922 }
1923
1924 static void load_alloc(struct regstat *current,int i)
1925 {
1926   clear_const(current,dops[i].rt1);
1927   //if(dops[i].rs1!=dops[i].rt1&&needed_again(dops[i].rs1,i)) clear_const(current,dops[i].rs1); // Does this help or hurt?
1928   if(!dops[i].rs1) current->u&=~1LL; // Allow allocating r0 if it's the source register
1929   if (needed_again(dops[i].rs1, i))
1930     alloc_reg(current, i, dops[i].rs1);
1931   if (ram_offset)
1932     alloc_reg(current, i, ROREG);
1933   if(dops[i].rt1&&!((current->u>>dops[i].rt1)&1)) {
1934     alloc_reg(current,i,dops[i].rt1);
1935     assert(get_reg(current->regmap,dops[i].rt1)>=0);
1936     if(dops[i].opcode==0x27||dops[i].opcode==0x37) // LWU/LD
1937     {
1938       assert(0);
1939     }
1940     else if(dops[i].opcode==0x1A||dops[i].opcode==0x1B) // LDL/LDR
1941     {
1942       assert(0);
1943     }
1944     dirty_reg(current,dops[i].rt1);
1945     // LWL/LWR need a temporary register for the old value
1946     if(dops[i].opcode==0x22||dops[i].opcode==0x26)
1947     {
1948       alloc_reg(current,i,FTEMP);
1949       alloc_reg_temp(current,i,-1);
1950       minimum_free_regs[i]=1;
1951     }
1952   }
1953   else
1954   {
1955     // Load to r0 or unneeded register (dummy load)
1956     // but we still need a register to calculate the address
1957     if(dops[i].opcode==0x22||dops[i].opcode==0x26)
1958     {
1959       alloc_reg(current,i,FTEMP); // LWL/LWR need another temporary
1960     }
1961     alloc_reg_temp(current,i,-1);
1962     minimum_free_regs[i]=1;
1963     if(dops[i].opcode==0x1A||dops[i].opcode==0x1B) // LDL/LDR
1964     {
1965       assert(0);
1966     }
1967   }
1968 }
1969
1970 static void store_alloc(struct regstat *current,int i)
1971 {
1972   clear_const(current,dops[i].rs2);
1973   if(!(dops[i].rs2)) current->u&=~1LL; // Allow allocating r0 if necessary
1974   if(needed_again(dops[i].rs1,i)) alloc_reg(current,i,dops[i].rs1);
1975   alloc_reg(current,i,dops[i].rs2);
1976   if(dops[i].opcode==0x2c||dops[i].opcode==0x2d||dops[i].opcode==0x3f) { // 64-bit SDL/SDR/SD
1977     assert(0);
1978   }
1979   if (ram_offset)
1980     alloc_reg(current, i, ROREG);
1981   #if defined(HOST_IMM8)
1982   // On CPUs without 32-bit immediates we need a pointer to invalid_code
1983   alloc_reg(current, i, INVCP);
1984   #endif
1985   if(dops[i].opcode==0x2a||dops[i].opcode==0x2e||dops[i].opcode==0x2c||dops[i].opcode==0x2d) { // SWL/SWL/SDL/SDR
1986     alloc_reg(current,i,FTEMP);
1987   }
1988   // We need a temporary register for address generation
1989   alloc_reg_temp(current,i,-1);
1990   minimum_free_regs[i]=1;
1991 }
1992
1993 static void c1ls_alloc(struct regstat *current,int i)
1994 {
1995   clear_const(current,dops[i].rt1);
1996   alloc_reg(current,i,CSREG); // Status
1997 }
1998
1999 static void c2ls_alloc(struct regstat *current,int i)
2000 {
2001   clear_const(current,dops[i].rt1);
2002   if(needed_again(dops[i].rs1,i)) alloc_reg(current,i,dops[i].rs1);
2003   alloc_reg(current,i,FTEMP);
2004   if (ram_offset)
2005     alloc_reg(current, i, ROREG);
2006   #if defined(HOST_IMM8)
2007   // On CPUs without 32-bit immediates we need a pointer to invalid_code
2008   if (dops[i].opcode == 0x3a) // SWC2
2009     alloc_reg(current,i,INVCP);
2010   #endif
2011   // We need a temporary register for address generation
2012   alloc_reg_temp(current,i,-1);
2013   minimum_free_regs[i]=1;
2014 }
2015
2016 #ifndef multdiv_alloc
2017 static void multdiv_alloc(struct regstat *current,int i)
2018 {
2019   //  case 0x18: MULT
2020   //  case 0x19: MULTU
2021   //  case 0x1A: DIV
2022   //  case 0x1B: DIVU
2023   //  case 0x1C: DMULT
2024   //  case 0x1D: DMULTU
2025   //  case 0x1E: DDIV
2026   //  case 0x1F: DDIVU
2027   clear_const(current,dops[i].rs1);
2028   clear_const(current,dops[i].rs2);
2029   alloc_cc(current,i); // for stalls
2030   if(dops[i].rs1&&dops[i].rs2)
2031   {
2032     if((dops[i].opcode2&4)==0) // 32-bit
2033     {
2034       current->u&=~(1LL<<HIREG);
2035       current->u&=~(1LL<<LOREG);
2036       alloc_reg(current,i,HIREG);
2037       alloc_reg(current,i,LOREG);
2038       alloc_reg(current,i,dops[i].rs1);
2039       alloc_reg(current,i,dops[i].rs2);
2040       dirty_reg(current,HIREG);
2041       dirty_reg(current,LOREG);
2042     }
2043     else // 64-bit
2044     {
2045       assert(0);
2046     }
2047   }
2048   else
2049   {
2050     // Multiply by zero is zero.
2051     // MIPS does not have a divide by zero exception.
2052     // The result is undefined, we return zero.
2053     alloc_reg(current,i,HIREG);
2054     alloc_reg(current,i,LOREG);
2055     dirty_reg(current,HIREG);
2056     dirty_reg(current,LOREG);
2057   }
2058 }
2059 #endif
2060
2061 static void cop0_alloc(struct regstat *current,int i)
2062 {
2063   if(dops[i].opcode2==0) // MFC0
2064   {
2065     if(dops[i].rt1) {
2066       clear_const(current,dops[i].rt1);
2067       alloc_all(current,i);
2068       alloc_reg(current,i,dops[i].rt1);
2069       dirty_reg(current,dops[i].rt1);
2070     }
2071   }
2072   else if(dops[i].opcode2==4) // MTC0
2073   {
2074     if(dops[i].rs1){
2075       clear_const(current,dops[i].rs1);
2076       alloc_reg(current,i,dops[i].rs1);
2077       alloc_all(current,i);
2078     }
2079     else {
2080       alloc_all(current,i); // FIXME: Keep r0
2081       current->u&=~1LL;
2082       alloc_reg(current,i,0);
2083     }
2084   }
2085   else
2086   {
2087     // TLBR/TLBWI/TLBWR/TLBP/ERET
2088     assert(dops[i].opcode2==0x10);
2089     alloc_all(current,i);
2090   }
2091   minimum_free_regs[i]=HOST_REGS;
2092 }
2093
2094 static void cop2_alloc(struct regstat *current,int i)
2095 {
2096   if (dops[i].opcode2 < 3) // MFC2/CFC2
2097   {
2098     alloc_cc(current,i); // for stalls
2099     dirty_reg(current,CCREG);
2100     if(dops[i].rt1){
2101       clear_const(current,dops[i].rt1);
2102       alloc_reg(current,i,dops[i].rt1);
2103       dirty_reg(current,dops[i].rt1);
2104     }
2105   }
2106   else if (dops[i].opcode2 > 3) // MTC2/CTC2
2107   {
2108     if(dops[i].rs1){
2109       clear_const(current,dops[i].rs1);
2110       alloc_reg(current,i,dops[i].rs1);
2111     }
2112     else {
2113       current->u&=~1LL;
2114       alloc_reg(current,i,0);
2115     }
2116   }
2117   alloc_reg_temp(current,i,-1);
2118   minimum_free_regs[i]=1;
2119 }
2120
2121 static void c2op_alloc(struct regstat *current,int i)
2122 {
2123   alloc_cc(current,i); // for stalls
2124   dirty_reg(current,CCREG);
2125   alloc_reg_temp(current,i,-1);
2126 }
2127
2128 static void syscall_alloc(struct regstat *current,int i)
2129 {
2130   alloc_cc(current,i);
2131   dirty_reg(current,CCREG);
2132   alloc_all(current,i);
2133   minimum_free_regs[i]=HOST_REGS;
2134   current->isconst=0;
2135 }
2136
2137 static void delayslot_alloc(struct regstat *current,int i)
2138 {
2139   switch(dops[i].itype) {
2140     case UJUMP:
2141     case CJUMP:
2142     case SJUMP:
2143     case RJUMP:
2144     case SYSCALL:
2145     case HLECALL:
2146     case IMM16:
2147       imm16_alloc(current,i);
2148       break;
2149     case LOAD:
2150     case LOADLR:
2151       load_alloc(current,i);
2152       break;
2153     case STORE:
2154     case STORELR:
2155       store_alloc(current,i);
2156       break;
2157     case ALU:
2158       alu_alloc(current,i);
2159       break;
2160     case SHIFT:
2161       shift_alloc(current,i);
2162       break;
2163     case MULTDIV:
2164       multdiv_alloc(current,i);
2165       break;
2166     case SHIFTIMM:
2167       shiftimm_alloc(current,i);
2168       break;
2169     case MOV:
2170       mov_alloc(current,i);
2171       break;
2172     case COP0:
2173       cop0_alloc(current,i);
2174       break;
2175     case COP1:
2176       break;
2177     case COP2:
2178       cop2_alloc(current,i);
2179       break;
2180     case C1LS:
2181       c1ls_alloc(current,i);
2182       break;
2183     case C2LS:
2184       c2ls_alloc(current,i);
2185       break;
2186     case C2OP:
2187       c2op_alloc(current,i);
2188       break;
2189   }
2190 }
2191
2192 static void add_stub(enum stub_type type, void *addr, void *retaddr,
2193   u_int a, uintptr_t b, uintptr_t c, u_int d, u_int e)
2194 {
2195   assert(stubcount < ARRAY_SIZE(stubs));
2196   stubs[stubcount].type = type;
2197   stubs[stubcount].addr = addr;
2198   stubs[stubcount].retaddr = retaddr;
2199   stubs[stubcount].a = a;
2200   stubs[stubcount].b = b;
2201   stubs[stubcount].c = c;
2202   stubs[stubcount].d = d;
2203   stubs[stubcount].e = e;
2204   stubcount++;
2205 }
2206
2207 static void add_stub_r(enum stub_type type, void *addr, void *retaddr,
2208   int i, int addr_reg, const struct regstat *i_regs, int ccadj, u_int reglist)
2209 {
2210   add_stub(type, addr, retaddr, i, addr_reg, (uintptr_t)i_regs, ccadj, reglist);
2211 }
2212
2213 // Write out a single register
2214 static void wb_register(signed char r, const signed char regmap[], uint64_t dirty)
2215 {
2216   int hr;
2217   for(hr=0;hr<HOST_REGS;hr++) {
2218     if(hr!=EXCLUDE_REG) {
2219       if(regmap[hr]==r) {
2220         if((dirty>>hr)&1) {
2221           assert(regmap[hr]<64);
2222           emit_storereg(r,hr);
2223         }
2224       }
2225     }
2226   }
2227 }
2228
2229 static void wb_valid(signed char pre[],signed char entry[],u_int dirty_pre,u_int dirty,uint64_t u)
2230 {
2231   //if(dirty_pre==dirty) return;
2232   int hr, r;
2233   for (hr = 0; hr < HOST_REGS; hr++) {
2234     r = pre[hr];
2235     if (r < 1 || r > 33 || ((u >> r) & 1))
2236       continue;
2237     if (((dirty_pre & ~dirty) >> hr) & 1)
2238       emit_storereg(r, hr);
2239   }
2240 }
2241
2242 // trashes r2
2243 static void pass_args(int a0, int a1)
2244 {
2245   if(a0==1&&a1==0) {
2246     // must swap
2247     emit_mov(a0,2); emit_mov(a1,1); emit_mov(2,0);
2248   }
2249   else if(a0!=0&&a1==0) {
2250     emit_mov(a1,1);
2251     if (a0>=0) emit_mov(a0,0);
2252   }
2253   else {
2254     if(a0>=0&&a0!=0) emit_mov(a0,0);
2255     if(a1>=0&&a1!=1) emit_mov(a1,1);
2256   }
2257 }
2258
2259 static void alu_assemble(int i, const struct regstat *i_regs)
2260 {
2261   if(dops[i].opcode2>=0x20&&dops[i].opcode2<=0x23) { // ADD/ADDU/SUB/SUBU
2262     if(dops[i].rt1) {
2263       signed char s1,s2,t;
2264       t=get_reg(i_regs->regmap,dops[i].rt1);
2265       if(t>=0) {
2266         s1=get_reg(i_regs->regmap,dops[i].rs1);
2267         s2=get_reg(i_regs->regmap,dops[i].rs2);
2268         if(dops[i].rs1&&dops[i].rs2) {
2269           assert(s1>=0);
2270           assert(s2>=0);
2271           if(dops[i].opcode2&2) emit_sub(s1,s2,t);
2272           else emit_add(s1,s2,t);
2273         }
2274         else if(dops[i].rs1) {
2275           if(s1>=0) emit_mov(s1,t);
2276           else emit_loadreg(dops[i].rs1,t);
2277         }
2278         else if(dops[i].rs2) {
2279           if(s2>=0) {
2280             if(dops[i].opcode2&2) emit_neg(s2,t);
2281             else emit_mov(s2,t);
2282           }
2283           else {
2284             emit_loadreg(dops[i].rs2,t);
2285             if(dops[i].opcode2&2) emit_neg(t,t);
2286           }
2287         }
2288         else emit_zeroreg(t);
2289       }
2290     }
2291   }
2292   if(dops[i].opcode2>=0x2c&&dops[i].opcode2<=0x2f) { // DADD/DADDU/DSUB/DSUBU
2293     assert(0);
2294   }
2295   if(dops[i].opcode2==0x2a||dops[i].opcode2==0x2b) { // SLT/SLTU
2296     if(dops[i].rt1) {
2297       signed char s1l,s2l,t;
2298       {
2299         t=get_reg(i_regs->regmap,dops[i].rt1);
2300         //assert(t>=0);
2301         if(t>=0) {
2302           s1l=get_reg(i_regs->regmap,dops[i].rs1);
2303           s2l=get_reg(i_regs->regmap,dops[i].rs2);
2304           if(dops[i].rs2==0) // rx<r0
2305           {
2306             if(dops[i].opcode2==0x2a&&dops[i].rs1!=0) { // SLT
2307               assert(s1l>=0);
2308               emit_shrimm(s1l,31,t);
2309             }
2310             else // SLTU (unsigned can not be less than zero, 0<0)
2311               emit_zeroreg(t);
2312           }
2313           else if(dops[i].rs1==0) // r0<rx
2314           {
2315             assert(s2l>=0);
2316             if(dops[i].opcode2==0x2a) // SLT
2317               emit_set_gz32(s2l,t);
2318             else // SLTU (set if not zero)
2319               emit_set_nz32(s2l,t);
2320           }
2321           else{
2322             assert(s1l>=0);assert(s2l>=0);
2323             if(dops[i].opcode2==0x2a) // SLT
2324               emit_set_if_less32(s1l,s2l,t);
2325             else // SLTU
2326               emit_set_if_carry32(s1l,s2l,t);
2327           }
2328         }
2329       }
2330     }
2331   }
2332   if(dops[i].opcode2>=0x24&&dops[i].opcode2<=0x27) { // AND/OR/XOR/NOR
2333     if(dops[i].rt1) {
2334       signed char s1l,s2l,tl;
2335       tl=get_reg(i_regs->regmap,dops[i].rt1);
2336       {
2337         if(tl>=0) {
2338           s1l=get_reg(i_regs->regmap,dops[i].rs1);
2339           s2l=get_reg(i_regs->regmap,dops[i].rs2);
2340           if(dops[i].rs1&&dops[i].rs2) {
2341             assert(s1l>=0);
2342             assert(s2l>=0);
2343             if(dops[i].opcode2==0x24) { // AND
2344               emit_and(s1l,s2l,tl);
2345             } else
2346             if(dops[i].opcode2==0x25) { // OR
2347               emit_or(s1l,s2l,tl);
2348             } else
2349             if(dops[i].opcode2==0x26) { // XOR
2350               emit_xor(s1l,s2l,tl);
2351             } else
2352             if(dops[i].opcode2==0x27) { // NOR
2353               emit_or(s1l,s2l,tl);
2354               emit_not(tl,tl);
2355             }
2356           }
2357           else
2358           {
2359             if(dops[i].opcode2==0x24) { // AND
2360               emit_zeroreg(tl);
2361             } else
2362             if(dops[i].opcode2==0x25||dops[i].opcode2==0x26) { // OR/XOR
2363               if(dops[i].rs1){
2364                 if(s1l>=0) emit_mov(s1l,tl);
2365                 else emit_loadreg(dops[i].rs1,tl); // CHECK: regmap_entry?
2366               }
2367               else
2368               if(dops[i].rs2){
2369                 if(s2l>=0) emit_mov(s2l,tl);
2370                 else emit_loadreg(dops[i].rs2,tl); // CHECK: regmap_entry?
2371               }
2372               else emit_zeroreg(tl);
2373             } else
2374             if(dops[i].opcode2==0x27) { // NOR
2375               if(dops[i].rs1){
2376                 if(s1l>=0) emit_not(s1l,tl);
2377                 else {
2378                   emit_loadreg(dops[i].rs1,tl);
2379                   emit_not(tl,tl);
2380                 }
2381               }
2382               else
2383               if(dops[i].rs2){
2384                 if(s2l>=0) emit_not(s2l,tl);
2385                 else {
2386                   emit_loadreg(dops[i].rs2,tl);
2387                   emit_not(tl,tl);
2388                 }
2389               }
2390               else emit_movimm(-1,tl);
2391             }
2392           }
2393         }
2394       }
2395     }
2396   }
2397 }
2398
2399 static void imm16_assemble(int i, const struct regstat *i_regs)
2400 {
2401   if (dops[i].opcode==0x0f) { // LUI
2402     if(dops[i].rt1) {
2403       signed char t;
2404       t=get_reg(i_regs->regmap,dops[i].rt1);
2405       //assert(t>=0);
2406       if(t>=0) {
2407         if(!((i_regs->isconst>>t)&1))
2408           emit_movimm(imm[i]<<16,t);
2409       }
2410     }
2411   }
2412   if(dops[i].opcode==0x08||dops[i].opcode==0x09) { // ADDI/ADDIU
2413     if(dops[i].rt1) {
2414       signed char s,t;
2415       t=get_reg(i_regs->regmap,dops[i].rt1);
2416       s=get_reg(i_regs->regmap,dops[i].rs1);
2417       if(dops[i].rs1) {
2418         //assert(t>=0);
2419         //assert(s>=0);
2420         if(t>=0) {
2421           if(!((i_regs->isconst>>t)&1)) {
2422             if(s<0) {
2423               if(i_regs->regmap_entry[t]!=dops[i].rs1) emit_loadreg(dops[i].rs1,t);
2424               emit_addimm(t,imm[i],t);
2425             }else{
2426               if(!((i_regs->wasconst>>s)&1))
2427                 emit_addimm(s,imm[i],t);
2428               else
2429                 emit_movimm(constmap[i][s]+imm[i],t);
2430             }
2431           }
2432         }
2433       } else {
2434         if(t>=0) {
2435           if(!((i_regs->isconst>>t)&1))
2436             emit_movimm(imm[i],t);
2437         }
2438       }
2439     }
2440   }
2441   if(dops[i].opcode==0x18||dops[i].opcode==0x19) { // DADDI/DADDIU
2442     if(dops[i].rt1) {
2443       signed char sl,tl;
2444       tl=get_reg(i_regs->regmap,dops[i].rt1);
2445       sl=get_reg(i_regs->regmap,dops[i].rs1);
2446       if(tl>=0) {
2447         if(dops[i].rs1) {
2448           assert(sl>=0);
2449           emit_addimm(sl,imm[i],tl);
2450         } else {
2451           emit_movimm(imm[i],tl);
2452         }
2453       }
2454     }
2455   }
2456   else if(dops[i].opcode==0x0a||dops[i].opcode==0x0b) { // SLTI/SLTIU
2457     if(dops[i].rt1) {
2458       //assert(dops[i].rs1!=0); // r0 might be valid, but it's probably a bug
2459       signed char sl,t;
2460       t=get_reg(i_regs->regmap,dops[i].rt1);
2461       sl=get_reg(i_regs->regmap,dops[i].rs1);
2462       //assert(t>=0);
2463       if(t>=0) {
2464         if(dops[i].rs1>0) {
2465             if(dops[i].opcode==0x0a) { // SLTI
2466               if(sl<0) {
2467                 if(i_regs->regmap_entry[t]!=dops[i].rs1) emit_loadreg(dops[i].rs1,t);
2468                 emit_slti32(t,imm[i],t);
2469               }else{
2470                 emit_slti32(sl,imm[i],t);
2471               }
2472             }
2473             else { // SLTIU
2474               if(sl<0) {
2475                 if(i_regs->regmap_entry[t]!=dops[i].rs1) emit_loadreg(dops[i].rs1,t);
2476                 emit_sltiu32(t,imm[i],t);
2477               }else{
2478                 emit_sltiu32(sl,imm[i],t);
2479               }
2480             }
2481         }else{
2482           // SLTI(U) with r0 is just stupid,
2483           // nonetheless examples can be found
2484           if(dops[i].opcode==0x0a) // SLTI
2485             if(0<imm[i]) emit_movimm(1,t);
2486             else emit_zeroreg(t);
2487           else // SLTIU
2488           {
2489             if(imm[i]) emit_movimm(1,t);
2490             else emit_zeroreg(t);
2491           }
2492         }
2493       }
2494     }
2495   }
2496   else if(dops[i].opcode>=0x0c&&dops[i].opcode<=0x0e) { // ANDI/ORI/XORI
2497     if(dops[i].rt1) {
2498       signed char sl,tl;
2499       tl=get_reg(i_regs->regmap,dops[i].rt1);
2500       sl=get_reg(i_regs->regmap,dops[i].rs1);
2501       if(tl>=0 && !((i_regs->isconst>>tl)&1)) {
2502         if(dops[i].opcode==0x0c) //ANDI
2503         {
2504           if(dops[i].rs1) {
2505             if(sl<0) {
2506               if(i_regs->regmap_entry[tl]!=dops[i].rs1) emit_loadreg(dops[i].rs1,tl);
2507               emit_andimm(tl,imm[i],tl);
2508             }else{
2509               if(!((i_regs->wasconst>>sl)&1))
2510                 emit_andimm(sl,imm[i],tl);
2511               else
2512                 emit_movimm(constmap[i][sl]&imm[i],tl);
2513             }
2514           }
2515           else
2516             emit_zeroreg(tl);
2517         }
2518         else
2519         {
2520           if(dops[i].rs1) {
2521             if(sl<0) {
2522               if(i_regs->regmap_entry[tl]!=dops[i].rs1) emit_loadreg(dops[i].rs1,tl);
2523             }
2524             if(dops[i].opcode==0x0d) { // ORI
2525               if(sl<0) {
2526                 emit_orimm(tl,imm[i],tl);
2527               }else{
2528                 if(!((i_regs->wasconst>>sl)&1))
2529                   emit_orimm(sl,imm[i],tl);
2530                 else
2531                   emit_movimm(constmap[i][sl]|imm[i],tl);
2532               }
2533             }
2534             if(dops[i].opcode==0x0e) { // XORI
2535               if(sl<0) {
2536                 emit_xorimm(tl,imm[i],tl);
2537               }else{
2538                 if(!((i_regs->wasconst>>sl)&1))
2539                   emit_xorimm(sl,imm[i],tl);
2540                 else
2541                   emit_movimm(constmap[i][sl]^imm[i],tl);
2542               }
2543             }
2544           }
2545           else {
2546             emit_movimm(imm[i],tl);
2547           }
2548         }
2549       }
2550     }
2551   }
2552 }
2553
2554 static void shiftimm_assemble(int i, const struct regstat *i_regs)
2555 {
2556   if(dops[i].opcode2<=0x3) // SLL/SRL/SRA
2557   {
2558     if(dops[i].rt1) {
2559       signed char s,t;
2560       t=get_reg(i_regs->regmap,dops[i].rt1);
2561       s=get_reg(i_regs->regmap,dops[i].rs1);
2562       //assert(t>=0);
2563       if(t>=0&&!((i_regs->isconst>>t)&1)){
2564         if(dops[i].rs1==0)
2565         {
2566           emit_zeroreg(t);
2567         }
2568         else
2569         {
2570           if(s<0&&i_regs->regmap_entry[t]!=dops[i].rs1) emit_loadreg(dops[i].rs1,t);
2571           if(imm[i]) {
2572             if(dops[i].opcode2==0) // SLL
2573             {
2574               emit_shlimm(s<0?t:s,imm[i],t);
2575             }
2576             if(dops[i].opcode2==2) // SRL
2577             {
2578               emit_shrimm(s<0?t:s,imm[i],t);
2579             }
2580             if(dops[i].opcode2==3) // SRA
2581             {
2582               emit_sarimm(s<0?t:s,imm[i],t);
2583             }
2584           }else{
2585             // Shift by zero
2586             if(s>=0 && s!=t) emit_mov(s,t);
2587           }
2588         }
2589       }
2590       //emit_storereg(dops[i].rt1,t); //DEBUG
2591     }
2592   }
2593   if(dops[i].opcode2>=0x38&&dops[i].opcode2<=0x3b) // DSLL/DSRL/DSRA
2594   {
2595     assert(0);
2596   }
2597   if(dops[i].opcode2==0x3c) // DSLL32
2598   {
2599     assert(0);
2600   }
2601   if(dops[i].opcode2==0x3e) // DSRL32
2602   {
2603     assert(0);
2604   }
2605   if(dops[i].opcode2==0x3f) // DSRA32
2606   {
2607     assert(0);
2608   }
2609 }
2610
2611 #ifndef shift_assemble
2612 static void shift_assemble(int i, const struct regstat *i_regs)
2613 {
2614   signed char s,t,shift;
2615   if (dops[i].rt1 == 0)
2616     return;
2617   assert(dops[i].opcode2<=0x07); // SLLV/SRLV/SRAV
2618   t = get_reg(i_regs->regmap, dops[i].rt1);
2619   s = get_reg(i_regs->regmap, dops[i].rs1);
2620   shift = get_reg(i_regs->regmap, dops[i].rs2);
2621   if (t < 0)
2622     return;
2623
2624   if(dops[i].rs1==0)
2625     emit_zeroreg(t);
2626   else if(dops[i].rs2==0) {
2627     assert(s>=0);
2628     if(s!=t) emit_mov(s,t);
2629   }
2630   else {
2631     host_tempreg_acquire();
2632     emit_andimm(shift,31,HOST_TEMPREG);
2633     switch(dops[i].opcode2) {
2634     case 4: // SLLV
2635       emit_shl(s,HOST_TEMPREG,t);
2636       break;
2637     case 6: // SRLV
2638       emit_shr(s,HOST_TEMPREG,t);
2639       break;
2640     case 7: // SRAV
2641       emit_sar(s,HOST_TEMPREG,t);
2642       break;
2643     default:
2644       assert(0);
2645     }
2646     host_tempreg_release();
2647   }
2648 }
2649
2650 #endif
2651
2652 enum {
2653   MTYPE_8000 = 0,
2654   MTYPE_8020,
2655   MTYPE_0000,
2656   MTYPE_A000,
2657   MTYPE_1F80,
2658 };
2659
2660 static int get_ptr_mem_type(u_int a)
2661 {
2662   if(a < 0x00200000) {
2663     if(a<0x1000&&((start>>20)==0xbfc||(start>>24)==0xa0))
2664       // return wrong, must use memhandler for BIOS self-test to pass
2665       // 007 does similar stuff from a00 mirror, weird stuff
2666       return MTYPE_8000;
2667     return MTYPE_0000;
2668   }
2669   if(0x1f800000 <= a && a < 0x1f801000)
2670     return MTYPE_1F80;
2671   if(0x80200000 <= a && a < 0x80800000)
2672     return MTYPE_8020;
2673   if(0xa0000000 <= a && a < 0xa0200000)
2674     return MTYPE_A000;
2675   return MTYPE_8000;
2676 }
2677
2678 static int get_ro_reg(const struct regstat *i_regs, int host_tempreg_free)
2679 {
2680   int r = get_reg(i_regs->regmap, ROREG);
2681   if (r < 0 && host_tempreg_free) {
2682     host_tempreg_acquire();
2683     emit_loadreg(ROREG, r = HOST_TEMPREG);
2684   }
2685   if (r < 0)
2686     abort();
2687   return r;
2688 }
2689
2690 static void *emit_fastpath_cmp_jump(int i, const struct regstat *i_regs,
2691   int addr, int *offset_reg, int *addr_reg_override)
2692 {
2693   void *jaddr = NULL;
2694   int type = 0;
2695   int mr = dops[i].rs1;
2696   *offset_reg = -1;
2697   if(((smrv_strong|smrv_weak)>>mr)&1) {
2698     type=get_ptr_mem_type(smrv[mr]);
2699     //printf("set %08x @%08x r%d %d\n", smrv[mr], start+i*4, mr, type);
2700   }
2701   else {
2702     // use the mirror we are running on
2703     type=get_ptr_mem_type(start);
2704     //printf("set nospec   @%08x r%d %d\n", start+i*4, mr, type);
2705   }
2706
2707   if(type==MTYPE_8020) { // RAM 80200000+ mirror
2708     host_tempreg_acquire();
2709     emit_andimm(addr,~0x00e00000,HOST_TEMPREG);
2710     addr=*addr_reg_override=HOST_TEMPREG;
2711     type=0;
2712   }
2713   else if(type==MTYPE_0000) { // RAM 0 mirror
2714     host_tempreg_acquire();
2715     emit_orimm(addr,0x80000000,HOST_TEMPREG);
2716     addr=*addr_reg_override=HOST_TEMPREG;
2717     type=0;
2718   }
2719   else if(type==MTYPE_A000) { // RAM A mirror
2720     host_tempreg_acquire();
2721     emit_andimm(addr,~0x20000000,HOST_TEMPREG);
2722     addr=*addr_reg_override=HOST_TEMPREG;
2723     type=0;
2724   }
2725   else if(type==MTYPE_1F80) { // scratchpad
2726     if (psxH == (void *)0x1f800000) {
2727       host_tempreg_acquire();
2728       emit_xorimm(addr,0x1f800000,HOST_TEMPREG);
2729       emit_cmpimm(HOST_TEMPREG,0x1000);
2730       host_tempreg_release();
2731       jaddr=out;
2732       emit_jc(0);
2733     }
2734     else {
2735       // do the usual RAM check, jump will go to the right handler
2736       type=0;
2737     }
2738   }
2739
2740   if (type == 0) // need ram check
2741   {
2742     emit_cmpimm(addr,RAM_SIZE);
2743     jaddr = out;
2744     #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
2745     // Hint to branch predictor that the branch is unlikely to be taken
2746     if (dops[i].rs1 >= 28)
2747       emit_jno_unlikely(0);
2748     else
2749     #endif
2750       emit_jno(0);
2751     if (ram_offset != 0)
2752       *offset_reg = get_ro_reg(i_regs, 0);
2753   }
2754
2755   return jaddr;
2756 }
2757
2758 // return memhandler, or get directly accessable address and return 0
2759 static void *get_direct_memhandler(void *table, u_int addr,
2760   enum stub_type type, uintptr_t *addr_host)
2761 {
2762   uintptr_t msb = 1ull << (sizeof(uintptr_t)*8 - 1);
2763   uintptr_t l1, l2 = 0;
2764   l1 = ((uintptr_t *)table)[addr>>12];
2765   if (!(l1 & msb)) {
2766     uintptr_t v = l1 << 1;
2767     *addr_host = v + addr;
2768     return NULL;
2769   }
2770   else {
2771     l1 <<= 1;
2772     if (type == LOADB_STUB || type == LOADBU_STUB || type == STOREB_STUB)
2773       l2 = ((uintptr_t *)l1)[0x1000/4 + 0x1000/2 + (addr&0xfff)];
2774     else if (type == LOADH_STUB || type == LOADHU_STUB || type == STOREH_STUB)
2775       l2 = ((uintptr_t *)l1)[0x1000/4 + (addr&0xfff)/2];
2776     else
2777       l2 = ((uintptr_t *)l1)[(addr&0xfff)/4];
2778     if (!(l2 & msb)) {
2779       uintptr_t v = l2 << 1;
2780       *addr_host = v + (addr&0xfff);
2781       return NULL;
2782     }
2783     return (void *)(l2 << 1);
2784   }
2785 }
2786
2787 static u_int get_host_reglist(const signed char *regmap)
2788 {
2789   u_int reglist = 0, hr;
2790   for (hr = 0; hr < HOST_REGS; hr++) {
2791     if (hr != EXCLUDE_REG && regmap[hr] >= 0)
2792       reglist |= 1 << hr;
2793   }
2794   return reglist;
2795 }
2796
2797 static u_int reglist_exclude(u_int reglist, int r1, int r2)
2798 {
2799   if (r1 >= 0)
2800     reglist &= ~(1u << r1);
2801   if (r2 >= 0)
2802     reglist &= ~(1u << r2);
2803   return reglist;
2804 }
2805
2806 // find a temp caller-saved register not in reglist (so assumed to be free)
2807 static int reglist_find_free(u_int reglist)
2808 {
2809   u_int free_regs = ~reglist & CALLER_SAVE_REGS;
2810   if (free_regs == 0)
2811     return -1;
2812   return __builtin_ctz(free_regs);
2813 }
2814
2815 static void do_load_word(int a, int rt, int offset_reg)
2816 {
2817   if (offset_reg >= 0)
2818     emit_ldr_dualindexed(offset_reg, a, rt);
2819   else
2820     emit_readword_indexed(0, a, rt);
2821 }
2822
2823 static void do_store_word(int a, int ofs, int rt, int offset_reg, int preseve_a)
2824 {
2825   if (offset_reg < 0) {
2826     emit_writeword_indexed(rt, ofs, a);
2827     return;
2828   }
2829   if (ofs != 0)
2830     emit_addimm(a, ofs, a);
2831   emit_str_dualindexed(offset_reg, a, rt);
2832   if (ofs != 0 && preseve_a)
2833     emit_addimm(a, -ofs, a);
2834 }
2835
2836 static void do_store_hword(int a, int ofs, int rt, int offset_reg, int preseve_a)
2837 {
2838   if (offset_reg < 0) {
2839     emit_writehword_indexed(rt, ofs, a);
2840     return;
2841   }
2842   if (ofs != 0)
2843     emit_addimm(a, ofs, a);
2844   emit_strh_dualindexed(offset_reg, a, rt);
2845   if (ofs != 0 && preseve_a)
2846     emit_addimm(a, -ofs, a);
2847 }
2848
2849 static void do_store_byte(int a, int rt, int offset_reg)
2850 {
2851   if (offset_reg >= 0)
2852     emit_strb_dualindexed(offset_reg, a, rt);
2853   else
2854     emit_writebyte_indexed(rt, 0, a);
2855 }
2856
2857 static void load_assemble(int i, const struct regstat *i_regs, int ccadj_)
2858 {
2859   int s,tl,addr;
2860   int offset;
2861   void *jaddr=0;
2862   int memtarget=0,c=0;
2863   int offset_reg = -1;
2864   int fastio_reg_override = -1;
2865   u_int reglist=get_host_reglist(i_regs->regmap);
2866   tl=get_reg(i_regs->regmap,dops[i].rt1);
2867   s=get_reg(i_regs->regmap,dops[i].rs1);
2868   offset=imm[i];
2869   if(i_regs->regmap[HOST_CCREG]==CCREG) reglist&=~(1<<HOST_CCREG);
2870   if(s>=0) {
2871     c=(i_regs->wasconst>>s)&1;
2872     if (c) {
2873       memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
2874     }
2875   }
2876   //printf("load_assemble: c=%d\n",c);
2877   //if(c) printf("load_assemble: const=%lx\n",(long)constmap[i][s]+offset);
2878   // FIXME: Even if the load is a NOP, we should check for pagefaults...
2879   if((tl<0&&(!c||(((u_int)constmap[i][s]+offset)>>16)==0x1f80))
2880     ||dops[i].rt1==0) {
2881       // could be FIFO, must perform the read
2882       // ||dummy read
2883       assem_debug("(forced read)\n");
2884       tl=get_reg_temp(i_regs->regmap);
2885       assert(tl>=0);
2886   }
2887   if(offset||s<0||c) addr=tl;
2888   else addr=s;
2889   //if(tl<0) tl=get_reg_temp(i_regs->regmap);
2890  if(tl>=0) {
2891   //printf("load_assemble: c=%d\n",c);
2892   //if(c) printf("load_assemble: const=%lx\n",(long)constmap[i][s]+offset);
2893   assert(tl>=0); // Even if the load is a NOP, we must check for pagefaults and I/O
2894   reglist&=~(1<<tl);
2895   if(!c) {
2896     #ifdef R29_HACK
2897     // Strmnnrmn's speed hack
2898     if(dops[i].rs1!=29||start<0x80001000||start>=0x80000000+RAM_SIZE)
2899     #endif
2900     {
2901       jaddr = emit_fastpath_cmp_jump(i, i_regs, addr,
2902                 &offset_reg, &fastio_reg_override);
2903     }
2904   }
2905   else if (ram_offset && memtarget) {
2906     offset_reg = get_ro_reg(i_regs, 0);
2907   }
2908   int dummy=(dops[i].rt1==0)||(tl!=get_reg(i_regs->regmap,dops[i].rt1)); // ignore loads to r0 and unneeded reg
2909   switch (dops[i].opcode) {
2910   case 0x20: // LB
2911     if(!c||memtarget) {
2912       if(!dummy) {
2913         int a = tl;
2914         if (!c) a = addr;
2915         if (fastio_reg_override >= 0)
2916           a = fastio_reg_override;
2917
2918         if (offset_reg >= 0)
2919           emit_ldrsb_dualindexed(offset_reg, a, tl);
2920         else
2921           emit_movsbl_indexed(0, a, tl);
2922       }
2923       if(jaddr)
2924         add_stub_r(LOADB_STUB,jaddr,out,i,addr,i_regs,ccadj_,reglist);
2925     }
2926     else
2927       inline_readstub(LOADB_STUB,i,constmap[i][s]+offset,i_regs->regmap,dops[i].rt1,ccadj_,reglist);
2928     break;
2929   case 0x21: // LH
2930     if(!c||memtarget) {
2931       if(!dummy) {
2932         int a = tl;
2933         if (!c) a = addr;
2934         if (fastio_reg_override >= 0)
2935           a = fastio_reg_override;
2936         if (offset_reg >= 0)
2937           emit_ldrsh_dualindexed(offset_reg, a, tl);
2938         else
2939           emit_movswl_indexed(0, a, tl);
2940       }
2941       if(jaddr)
2942         add_stub_r(LOADH_STUB,jaddr,out,i,addr,i_regs,ccadj_,reglist);
2943     }
2944     else
2945       inline_readstub(LOADH_STUB,i,constmap[i][s]+offset,i_regs->regmap,dops[i].rt1,ccadj_,reglist);
2946     break;
2947   case 0x23: // LW
2948     if(!c||memtarget) {
2949       if(!dummy) {
2950         int a = addr;
2951         if (fastio_reg_override >= 0)
2952           a = fastio_reg_override;
2953         do_load_word(a, tl, offset_reg);
2954       }
2955       if(jaddr)
2956         add_stub_r(LOADW_STUB,jaddr,out,i,addr,i_regs,ccadj_,reglist);
2957     }
2958     else
2959       inline_readstub(LOADW_STUB,i,constmap[i][s]+offset,i_regs->regmap,dops[i].rt1,ccadj_,reglist);
2960     break;
2961   case 0x24: // LBU
2962     if(!c||memtarget) {
2963       if(!dummy) {
2964         int a = tl;
2965         if (!c) a = addr;
2966         if (fastio_reg_override >= 0)
2967           a = fastio_reg_override;
2968
2969         if (offset_reg >= 0)
2970           emit_ldrb_dualindexed(offset_reg, a, tl);
2971         else
2972           emit_movzbl_indexed(0, a, tl);
2973       }
2974       if(jaddr)
2975         add_stub_r(LOADBU_STUB,jaddr,out,i,addr,i_regs,ccadj_,reglist);
2976     }
2977     else
2978       inline_readstub(LOADBU_STUB,i,constmap[i][s]+offset,i_regs->regmap,dops[i].rt1,ccadj_,reglist);
2979     break;
2980   case 0x25: // LHU
2981     if(!c||memtarget) {
2982       if(!dummy) {
2983         int a = tl;
2984         if(!c) a = addr;
2985         if (fastio_reg_override >= 0)
2986           a = fastio_reg_override;
2987         if (offset_reg >= 0)
2988           emit_ldrh_dualindexed(offset_reg, a, tl);
2989         else
2990           emit_movzwl_indexed(0, a, tl);
2991       }
2992       if(jaddr)
2993         add_stub_r(LOADHU_STUB,jaddr,out,i,addr,i_regs,ccadj_,reglist);
2994     }
2995     else
2996       inline_readstub(LOADHU_STUB,i,constmap[i][s]+offset,i_regs->regmap,dops[i].rt1,ccadj_,reglist);
2997     break;
2998   case 0x27: // LWU
2999   case 0x37: // LD
3000   default:
3001     assert(0);
3002   }
3003  }
3004  if (fastio_reg_override == HOST_TEMPREG || offset_reg == HOST_TEMPREG)
3005    host_tempreg_release();
3006 }
3007
3008 #ifndef loadlr_assemble
3009 static void loadlr_assemble(int i, const struct regstat *i_regs, int ccadj_)
3010 {
3011   int s,tl,temp,temp2,addr;
3012   int offset;
3013   void *jaddr=0;
3014   int memtarget=0,c=0;
3015   int offset_reg = -1;
3016   int fastio_reg_override = -1;
3017   u_int reglist=get_host_reglist(i_regs->regmap);
3018   tl=get_reg(i_regs->regmap,dops[i].rt1);
3019   s=get_reg(i_regs->regmap,dops[i].rs1);
3020   temp=get_reg_temp(i_regs->regmap);
3021   temp2=get_reg(i_regs->regmap,FTEMP);
3022   addr=get_reg(i_regs->regmap,AGEN1+(i&1));
3023   assert(addr<0);
3024   offset=imm[i];
3025   reglist|=1<<temp;
3026   if(offset||s<0||c) addr=temp2;
3027   else addr=s;
3028   if(s>=0) {
3029     c=(i_regs->wasconst>>s)&1;
3030     if(c) {
3031       memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
3032     }
3033   }
3034   if(!c) {
3035     emit_shlimm(addr,3,temp);
3036     if (dops[i].opcode==0x22||dops[i].opcode==0x26) {
3037       emit_andimm(addr,0xFFFFFFFC,temp2); // LWL/LWR
3038     }else{
3039       emit_andimm(addr,0xFFFFFFF8,temp2); // LDL/LDR
3040     }
3041     jaddr = emit_fastpath_cmp_jump(i, i_regs, temp2,
3042               &offset_reg, &fastio_reg_override);
3043   }
3044   else {
3045     if (ram_offset && memtarget) {
3046       offset_reg = get_ro_reg(i_regs, 0);
3047     }
3048     if (dops[i].opcode==0x22||dops[i].opcode==0x26) {
3049       emit_movimm(((constmap[i][s]+offset)<<3)&24,temp); // LWL/LWR
3050     }else{
3051       emit_movimm(((constmap[i][s]+offset)<<3)&56,temp); // LDL/LDR
3052     }
3053   }
3054   if (dops[i].opcode==0x22||dops[i].opcode==0x26) { // LWL/LWR
3055     if(!c||memtarget) {
3056       int a = temp2;
3057       if (fastio_reg_override >= 0)
3058         a = fastio_reg_override;
3059       do_load_word(a, temp2, offset_reg);
3060       if (fastio_reg_override == HOST_TEMPREG || offset_reg == HOST_TEMPREG)
3061         host_tempreg_release();
3062       if(jaddr) add_stub_r(LOADW_STUB,jaddr,out,i,temp2,i_regs,ccadj_,reglist);
3063     }
3064     else
3065       inline_readstub(LOADW_STUB,i,(constmap[i][s]+offset)&0xFFFFFFFC,i_regs->regmap,FTEMP,ccadj_,reglist);
3066     if(dops[i].rt1) {
3067       assert(tl>=0);
3068       emit_andimm(temp,24,temp);
3069       if (dops[i].opcode==0x22) // LWL
3070         emit_xorimm(temp,24,temp);
3071       host_tempreg_acquire();
3072       emit_movimm(-1,HOST_TEMPREG);
3073       if (dops[i].opcode==0x26) {
3074         emit_shr(temp2,temp,temp2);
3075         emit_bic_lsr(tl,HOST_TEMPREG,temp,tl);
3076       }else{
3077         emit_shl(temp2,temp,temp2);
3078         emit_bic_lsl(tl,HOST_TEMPREG,temp,tl);
3079       }
3080       host_tempreg_release();
3081       emit_or(temp2,tl,tl);
3082     }
3083     //emit_storereg(dops[i].rt1,tl); // DEBUG
3084   }
3085   if (dops[i].opcode==0x1A||dops[i].opcode==0x1B) { // LDL/LDR
3086     assert(0);
3087   }
3088 }
3089 #endif
3090
3091 static void store_assemble(int i, const struct regstat *i_regs, int ccadj_)
3092 {
3093   int s,tl;
3094   int addr,temp;
3095   int offset;
3096   void *jaddr=0;
3097   enum stub_type type=0;
3098   int memtarget=0,c=0;
3099   int agr=AGEN1+(i&1);
3100   int offset_reg = -1;
3101   int fastio_reg_override = -1;
3102   u_int reglist=get_host_reglist(i_regs->regmap);
3103   tl=get_reg(i_regs->regmap,dops[i].rs2);
3104   s=get_reg(i_regs->regmap,dops[i].rs1);
3105   temp=get_reg(i_regs->regmap,agr);
3106   if(temp<0) temp=get_reg_temp(i_regs->regmap);
3107   offset=imm[i];
3108   if(s>=0) {
3109     c=(i_regs->wasconst>>s)&1;
3110     if(c) {
3111       memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
3112     }
3113   }
3114   assert(tl>=0);
3115   assert(temp>=0);
3116   if(i_regs->regmap[HOST_CCREG]==CCREG) reglist&=~(1<<HOST_CCREG);
3117   if(offset||s<0||c) addr=temp;
3118   else addr=s;
3119   if (!c) {
3120     jaddr = emit_fastpath_cmp_jump(i, i_regs, addr,
3121               &offset_reg, &fastio_reg_override);
3122   }
3123   else if (ram_offset && memtarget) {
3124     offset_reg = get_ro_reg(i_regs, 0);
3125   }
3126
3127   switch (dops[i].opcode) {
3128   case 0x28: // SB
3129     if(!c||memtarget) {
3130       int a = temp;
3131       if (!c) a = addr;
3132       if (fastio_reg_override >= 0)
3133         a = fastio_reg_override;
3134       do_store_byte(a, tl, offset_reg);
3135     }
3136     type = STOREB_STUB;
3137     break;
3138   case 0x29: // SH
3139     if(!c||memtarget) {
3140       int a = temp;
3141       if (!c) a = addr;
3142       if (fastio_reg_override >= 0)
3143         a = fastio_reg_override;
3144       do_store_hword(a, 0, tl, offset_reg, 1);
3145     }
3146     type = STOREH_STUB;
3147     break;
3148   case 0x2B: // SW
3149     if(!c||memtarget) {
3150       int a = addr;
3151       if (fastio_reg_override >= 0)
3152         a = fastio_reg_override;
3153       do_store_word(a, 0, tl, offset_reg, 1);
3154     }
3155     type = STOREW_STUB;
3156     break;
3157   case 0x3F: // SD
3158   default:
3159     assert(0);
3160   }
3161   if (fastio_reg_override == HOST_TEMPREG || offset_reg == HOST_TEMPREG)
3162     host_tempreg_release();
3163   if(jaddr) {
3164     // PCSX store handlers don't check invcode again
3165     reglist|=1<<addr;
3166     add_stub_r(type,jaddr,out,i,addr,i_regs,ccadj_,reglist);
3167     jaddr=0;
3168   }
3169   if(!(i_regs->waswritten&(1<<dops[i].rs1)) && !HACK_ENABLED(NDHACK_NO_SMC_CHECK)) {
3170     if(!c||memtarget) {
3171       #ifdef DESTRUCTIVE_SHIFT
3172       // The x86 shift operation is 'destructive'; it overwrites the
3173       // source register, so we need to make a copy first and use that.
3174       addr=temp;
3175       #endif
3176       #if defined(HOST_IMM8)
3177       int ir=get_reg(i_regs->regmap,INVCP);
3178       assert(ir>=0);
3179       emit_cmpmem_indexedsr12_reg(ir,addr,1);
3180       #else
3181       emit_cmpmem_indexedsr12_imm(invalid_code,addr,1);
3182       #endif
3183       #ifdef INVALIDATE_USE_COND_CALL
3184       emit_callne(invalidate_addr_reg[addr]);
3185       #else
3186       void *jaddr2 = out;
3187       emit_jne(0);
3188       add_stub(INVCODE_STUB,jaddr2,out,reglist|(1<<HOST_CCREG),addr,0,0,0);
3189       #endif
3190     }
3191   }
3192   u_int addr_val=constmap[i][s]+offset;
3193   if(jaddr) {
3194     add_stub_r(type,jaddr,out,i,addr,i_regs,ccadj_,reglist);
3195   } else if(c&&!memtarget) {
3196     inline_writestub(type,i,addr_val,i_regs->regmap,dops[i].rs2,ccadj_,reglist);
3197   }
3198   // basic current block modification detection..
3199   // not looking back as that should be in mips cache already
3200   // (see Spyro2 title->attract mode)
3201   if(c&&start+i*4<addr_val&&addr_val<start+slen*4) {
3202     SysPrintf("write to %08x hits block %08x, pc=%08x\n",addr_val,start,start+i*4);
3203     assert(i_regs->regmap==regs[i].regmap); // not delay slot
3204     if(i_regs->regmap==regs[i].regmap) {
3205       load_all_consts(regs[i].regmap_entry,regs[i].wasdirty,i);
3206       wb_dirtys(regs[i].regmap_entry,regs[i].wasdirty);
3207       emit_movimm(start+i*4+4,0);
3208       emit_writeword(0,&pcaddr);
3209       emit_addimm(HOST_CCREG,2,HOST_CCREG);
3210       emit_far_call(ndrc_get_addr_ht);
3211       emit_jmpreg(0);
3212     }
3213   }
3214 }
3215
3216 static void storelr_assemble(int i, const struct regstat *i_regs, int ccadj_)
3217 {
3218   int s,tl;
3219   int temp;
3220   int offset;
3221   void *jaddr=0;
3222   void *case1, *case23, *case3;
3223   void *done0, *done1, *done2;
3224   int memtarget=0,c=0;
3225   int agr=AGEN1+(i&1);
3226   int offset_reg = -1;
3227   u_int reglist=get_host_reglist(i_regs->regmap);
3228   tl=get_reg(i_regs->regmap,dops[i].rs2);
3229   s=get_reg(i_regs->regmap,dops[i].rs1);
3230   temp=get_reg(i_regs->regmap,agr);
3231   if(temp<0) temp=get_reg_temp(i_regs->regmap);
3232   offset=imm[i];
3233   if(s>=0) {
3234     c=(i_regs->isconst>>s)&1;
3235     if(c) {
3236       memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
3237     }
3238   }
3239   assert(tl>=0);
3240   assert(temp>=0);
3241   if(!c) {
3242     emit_cmpimm(s<0||offset?temp:s,RAM_SIZE);
3243     if(!offset&&s!=temp) emit_mov(s,temp);
3244     jaddr=out;
3245     emit_jno(0);
3246   }
3247   else
3248   {
3249     if(!memtarget||!dops[i].rs1) {
3250       jaddr=out;
3251       emit_jmp(0);
3252     }
3253   }
3254   if (ram_offset)
3255     offset_reg = get_ro_reg(i_regs, 0);
3256
3257   if (dops[i].opcode==0x2C||dops[i].opcode==0x2D) { // SDL/SDR
3258     assert(0);
3259   }
3260
3261   emit_testimm(temp,2);
3262   case23=out;
3263   emit_jne(0);
3264   emit_testimm(temp,1);
3265   case1=out;
3266   emit_jne(0);
3267   // 0
3268   if (dops[i].opcode == 0x2A) { // SWL
3269     // Write msb into least significant byte
3270     if (dops[i].rs2) emit_rorimm(tl, 24, tl);
3271     do_store_byte(temp, tl, offset_reg);
3272     if (dops[i].rs2) emit_rorimm(tl, 8, tl);
3273   }
3274   else if (dops[i].opcode == 0x2E) { // SWR
3275     // Write entire word
3276     do_store_word(temp, 0, tl, offset_reg, 1);
3277   }
3278   done0 = out;
3279   emit_jmp(0);
3280   // 1
3281   set_jump_target(case1, out);
3282   if (dops[i].opcode == 0x2A) { // SWL
3283     // Write two msb into two least significant bytes
3284     if (dops[i].rs2) emit_rorimm(tl, 16, tl);
3285     do_store_hword(temp, -1, tl, offset_reg, 0);
3286     if (dops[i].rs2) emit_rorimm(tl, 16, tl);
3287   }
3288   else if (dops[i].opcode == 0x2E) { // SWR
3289     // Write 3 lsb into three most significant bytes
3290     do_store_byte(temp, tl, offset_reg);
3291     if (dops[i].rs2) emit_rorimm(tl, 8, tl);
3292     do_store_hword(temp, 1, tl, offset_reg, 0);
3293     if (dops[i].rs2) emit_rorimm(tl, 24, tl);
3294   }
3295   done1=out;
3296   emit_jmp(0);
3297   // 2,3
3298   set_jump_target(case23, out);
3299   emit_testimm(temp,1);
3300   case3 = out;
3301   emit_jne(0);
3302   // 2
3303   if (dops[i].opcode==0x2A) { // SWL
3304     // Write 3 msb into three least significant bytes
3305     if (dops[i].rs2) emit_rorimm(tl, 8, tl);
3306     do_store_hword(temp, -2, tl, offset_reg, 1);
3307     if (dops[i].rs2) emit_rorimm(tl, 16, tl);
3308     do_store_byte(temp, tl, offset_reg);
3309     if (dops[i].rs2) emit_rorimm(tl, 8, tl);
3310   }
3311   else if (dops[i].opcode == 0x2E) { // SWR
3312     // Write two lsb into two most significant bytes
3313     do_store_hword(temp, 0, tl, offset_reg, 1);
3314   }
3315   done2 = out;
3316   emit_jmp(0);
3317   // 3
3318   set_jump_target(case3, out);
3319   if (dops[i].opcode == 0x2A) { // SWL
3320     do_store_word(temp, -3, tl, offset_reg, 0);
3321   }
3322   else if (dops[i].opcode == 0x2E) { // SWR
3323     do_store_byte(temp, tl, offset_reg);
3324   }
3325   set_jump_target(done0, out);
3326   set_jump_target(done1, out);
3327   set_jump_target(done2, out);
3328   if (offset_reg == HOST_TEMPREG)
3329     host_tempreg_release();
3330   if(!c||!memtarget)
3331     add_stub_r(STORELR_STUB,jaddr,out,i,temp,i_regs,ccadj_,reglist);
3332   if(!(i_regs->waswritten&(1<<dops[i].rs1)) && !HACK_ENABLED(NDHACK_NO_SMC_CHECK)) {
3333     #if defined(HOST_IMM8)
3334     int ir=get_reg(i_regs->regmap,INVCP);
3335     assert(ir>=0);
3336     emit_cmpmem_indexedsr12_reg(ir,temp,1);
3337     #else
3338     emit_cmpmem_indexedsr12_imm(invalid_code,temp,1);
3339     #endif
3340     #ifdef INVALIDATE_USE_COND_CALL
3341     emit_callne(invalidate_addr_reg[temp]);
3342     #else
3343     void *jaddr2 = out;
3344     emit_jne(0);
3345     add_stub(INVCODE_STUB,jaddr2,out,reglist|(1<<HOST_CCREG),temp,0,0,0);
3346     #endif
3347   }
3348 }
3349
3350 static void cop0_assemble(int i, const struct regstat *i_regs, int ccadj_)
3351 {
3352   if(dops[i].opcode2==0) // MFC0
3353   {
3354     signed char t=get_reg(i_regs->regmap,dops[i].rt1);
3355     u_int copr=(source[i]>>11)&0x1f;
3356     //assert(t>=0); // Why does this happen?  OOT is weird
3357     if(t>=0&&dops[i].rt1!=0) {
3358       emit_readword(&reg_cop0[copr],t);
3359     }
3360   }
3361   else if(dops[i].opcode2==4) // MTC0
3362   {
3363     signed char s=get_reg(i_regs->regmap,dops[i].rs1);
3364     char copr=(source[i]>>11)&0x1f;
3365     assert(s>=0);
3366     wb_register(dops[i].rs1,i_regs->regmap,i_regs->dirty);
3367     if(copr==9||copr==11||copr==12||copr==13) {
3368       emit_readword(&last_count,HOST_TEMPREG);
3369       emit_loadreg(CCREG,HOST_CCREG); // TODO: do proper reg alloc
3370       emit_add(HOST_CCREG,HOST_TEMPREG,HOST_CCREG);
3371       emit_addimm(HOST_CCREG,ccadj_,HOST_CCREG);
3372       emit_writeword(HOST_CCREG,&Count);
3373     }
3374     // What a mess.  The status register (12) can enable interrupts,
3375     // so needs a special case to handle a pending interrupt.
3376     // The interrupt must be taken immediately, because a subsequent
3377     // instruction might disable interrupts again.
3378     if(copr==12||copr==13) {
3379       if (is_delayslot) {
3380         // burn cycles to cause cc_interrupt, which will
3381         // reschedule next_interupt. Relies on CCREG from above.
3382         assem_debug("MTC0 DS %d\n", copr);
3383         emit_writeword(HOST_CCREG,&last_count);
3384         emit_movimm(0,HOST_CCREG);
3385         emit_storereg(CCREG,HOST_CCREG);
3386         emit_loadreg(dops[i].rs1,1);
3387         emit_movimm(copr,0);
3388         emit_far_call(pcsx_mtc0_ds);
3389         emit_loadreg(dops[i].rs1,s);
3390         return;
3391       }
3392       emit_movimm(start+i*4+4,HOST_TEMPREG);
3393       emit_writeword(HOST_TEMPREG,&pcaddr);
3394       emit_movimm(0,HOST_TEMPREG);
3395       emit_writeword(HOST_TEMPREG,&pending_exception);
3396     }
3397     if(s==HOST_CCREG)
3398       emit_loadreg(dops[i].rs1,1);
3399     else if(s!=1)
3400       emit_mov(s,1);
3401     emit_movimm(copr,0);
3402     emit_far_call(pcsx_mtc0);
3403     if(copr==9||copr==11||copr==12||copr==13) {
3404       emit_readword(&Count,HOST_CCREG);
3405       emit_readword(&next_interupt,HOST_TEMPREG);
3406       emit_addimm(HOST_CCREG,-ccadj_,HOST_CCREG);
3407       emit_sub(HOST_CCREG,HOST_TEMPREG,HOST_CCREG);
3408       emit_writeword(HOST_TEMPREG,&last_count);
3409       emit_storereg(CCREG,HOST_CCREG);
3410     }
3411     if(copr==12||copr==13) {
3412       assert(!is_delayslot);
3413       emit_readword(&pending_exception,14);
3414       emit_test(14,14);
3415       void *jaddr = out;
3416       emit_jeq(0);
3417       emit_readword(&pcaddr, 0);
3418       emit_addimm(HOST_CCREG,2,HOST_CCREG);
3419       emit_far_call(ndrc_get_addr_ht);
3420       emit_jmpreg(0);
3421       set_jump_target(jaddr, out);
3422     }
3423     emit_loadreg(dops[i].rs1,s);
3424   }
3425   else
3426   {
3427     assert(dops[i].opcode2==0x10);
3428     //if((source[i]&0x3f)==0x10) // RFE
3429     {
3430       emit_readword(&Status,0);
3431       emit_andimm(0,0x3c,1);
3432       emit_andimm(0,~0xf,0);
3433       emit_orrshr_imm(1,2,0);
3434       emit_writeword(0,&Status);
3435     }
3436   }
3437 }
3438
3439 static void cop1_unusable(int i, const struct regstat *i_regs)
3440 {
3441   // XXX: should just just do the exception instead
3442   //if(!cop1_usable)
3443   {
3444     void *jaddr=out;
3445     emit_jmp(0);
3446     add_stub_r(FP_STUB,jaddr,out,i,0,i_regs,is_delayslot,0);
3447   }
3448 }
3449
3450 static void cop1_assemble(int i, const struct regstat *i_regs)
3451 {
3452   cop1_unusable(i, i_regs);
3453 }
3454
3455 static void c1ls_assemble(int i, const struct regstat *i_regs)
3456 {
3457   cop1_unusable(i, i_regs);
3458 }
3459
3460 // FP_STUB
3461 static void do_cop1stub(int n)
3462 {
3463   literal_pool(256);
3464   assem_debug("do_cop1stub %x\n",start+stubs[n].a*4);
3465   set_jump_target(stubs[n].addr, out);
3466   int i=stubs[n].a;
3467 //  int rs=stubs[n].b;
3468   struct regstat *i_regs=(struct regstat *)stubs[n].c;
3469   int ds=stubs[n].d;
3470   if(!ds) {
3471     load_all_consts(regs[i].regmap_entry,regs[i].wasdirty,i);
3472     //if(i_regs!=&regs[i]) printf("oops: regs[i]=%x i_regs=%x",(int)&regs[i],(int)i_regs);
3473   }
3474   //else {printf("fp exception in delay slot\n");}
3475   wb_dirtys(i_regs->regmap_entry,i_regs->wasdirty);
3476   if(regs[i].regmap_entry[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG);
3477   emit_movimm(start+(i-ds)*4,EAX); // Get PC
3478   emit_addimm(HOST_CCREG,ccadj[i],HOST_CCREG); // CHECK: is this right?  There should probably be an extra cycle...
3479   emit_far_jump(ds?fp_exception_ds:fp_exception);
3480 }
3481
3482 static int cop2_is_stalling_op(int i, int *cycles)
3483 {
3484   if (dops[i].opcode == 0x3a) { // SWC2
3485     *cycles = 0;
3486     return 1;
3487   }
3488   if (dops[i].itype == COP2 && (dops[i].opcode2 == 0 || dops[i].opcode2 == 2)) { // MFC2/CFC2
3489     *cycles = 0;
3490     return 1;
3491   }
3492   if (dops[i].itype == C2OP) {
3493     *cycles = gte_cycletab[source[i] & 0x3f];
3494     return 1;
3495   }
3496   // ... what about MTC2/CTC2/LWC2?
3497   return 0;
3498 }
3499
3500 #if 0
3501 static void log_gte_stall(int stall, u_int cycle)
3502 {
3503   if ((u_int)stall <= 44)
3504     printf("x    stall %2d %u\n", stall, cycle + last_count);
3505 }
3506
3507 static void emit_log_gte_stall(int i, int stall, u_int reglist)
3508 {
3509   save_regs(reglist);
3510   if (stall > 0)
3511     emit_movimm(stall, 0);
3512   else
3513     emit_mov(HOST_TEMPREG, 0);
3514   emit_addimm(HOST_CCREG, ccadj[i], 1);
3515   emit_far_call(log_gte_stall);
3516   restore_regs(reglist);
3517 }
3518 #endif
3519
3520 static void cop2_do_stall_check(u_int op, int i, const struct regstat *i_regs, u_int reglist)
3521 {
3522   int j = i, other_gte_op_cycles = -1, stall = -MAXBLOCK, cycles_passed;
3523   int rtmp = reglist_find_free(reglist);
3524
3525   if (HACK_ENABLED(NDHACK_NO_STALLS))
3526     return;
3527   if (get_reg(i_regs->regmap, CCREG) != HOST_CCREG) {
3528     // happens occasionally... cc evicted? Don't bother then
3529     //printf("no cc %08x\n", start + i*4);
3530     return;
3531   }
3532   if (!dops[i].bt) {
3533     for (j = i - 1; j >= 0; j--) {
3534       //if (dops[j].is_ds) break;
3535       if (cop2_is_stalling_op(j, &other_gte_op_cycles) || dops[j].bt)
3536         break;
3537       if (j > 0 && ccadj[j - 1] > ccadj[j])
3538         break;
3539     }
3540     j = max(j, 0);
3541   }
3542   cycles_passed = ccadj[i] - ccadj[j];
3543   if (other_gte_op_cycles >= 0)
3544     stall = other_gte_op_cycles - cycles_passed;
3545   else if (cycles_passed >= 44)
3546     stall = 0; // can't stall
3547   if (stall == -MAXBLOCK && rtmp >= 0) {
3548     // unknown stall, do the expensive runtime check
3549     assem_debug("; cop2_do_stall_check\n");
3550 #if 0 // too slow
3551     save_regs(reglist);
3552     emit_movimm(gte_cycletab[op], 0);
3553     emit_addimm(HOST_CCREG, ccadj[i], 1);
3554     emit_far_call(call_gteStall);
3555     restore_regs(reglist);
3556 #else
3557     host_tempreg_acquire();
3558     emit_readword(&psxRegs.gteBusyCycle, rtmp);
3559     emit_addimm(rtmp, -ccadj[i], rtmp);
3560     emit_sub(rtmp, HOST_CCREG, HOST_TEMPREG);
3561     emit_cmpimm(HOST_TEMPREG, 44);
3562     emit_cmovb_reg(rtmp, HOST_CCREG);
3563     //emit_log_gte_stall(i, 0, reglist);
3564     host_tempreg_release();
3565 #endif
3566   }
3567   else if (stall > 0) {
3568     //emit_log_gte_stall(i, stall, reglist);
3569     emit_addimm(HOST_CCREG, stall, HOST_CCREG);
3570   }
3571
3572   // save gteBusyCycle, if needed
3573   if (gte_cycletab[op] == 0)
3574     return;
3575   other_gte_op_cycles = -1;
3576   for (j = i + 1; j < slen; j++) {
3577     if (cop2_is_stalling_op(j, &other_gte_op_cycles))
3578       break;
3579     if (dops[j].is_jump) {
3580       // check ds
3581       if (j + 1 < slen && cop2_is_stalling_op(j + 1, &other_gte_op_cycles))
3582         j++;
3583       break;
3584     }
3585   }
3586   if (other_gte_op_cycles >= 0)
3587     // will handle stall when assembling that op
3588     return;
3589   cycles_passed = ccadj[min(j, slen -1)] - ccadj[i];
3590   if (cycles_passed >= 44)
3591     return;
3592   assem_debug("; save gteBusyCycle\n");
3593   host_tempreg_acquire();
3594 #if 0
3595   emit_readword(&last_count, HOST_TEMPREG);
3596   emit_add(HOST_TEMPREG, HOST_CCREG, HOST_TEMPREG);
3597   emit_addimm(HOST_TEMPREG, ccadj[i], HOST_TEMPREG);
3598   emit_addimm(HOST_TEMPREG, gte_cycletab[op]), HOST_TEMPREG);
3599   emit_writeword(HOST_TEMPREG, &psxRegs.gteBusyCycle);
3600 #else
3601   emit_addimm(HOST_CCREG, ccadj[i] + gte_cycletab[op], HOST_TEMPREG);
3602   emit_writeword(HOST_TEMPREG, &psxRegs.gteBusyCycle);
3603 #endif
3604   host_tempreg_release();
3605 }
3606
3607 static int is_mflohi(int i)
3608 {
3609   return (dops[i].itype == MOV && (dops[i].rs1 == HIREG || dops[i].rs1 == LOREG));
3610 }
3611
3612 static int check_multdiv(int i, int *cycles)
3613 {
3614   if (dops[i].itype != MULTDIV)
3615     return 0;
3616   if (dops[i].opcode2 == 0x18 || dops[i].opcode2 == 0x19) // MULT(U)
3617     *cycles = 11; // approx from 7 11 14
3618   else
3619     *cycles = 37;
3620   return 1;
3621 }
3622
3623 static void multdiv_prepare_stall(int i, const struct regstat *i_regs, int ccadj_)
3624 {
3625   int j, found = 0, c = 0;
3626   if (HACK_ENABLED(NDHACK_NO_STALLS))
3627     return;
3628   if (get_reg(i_regs->regmap, CCREG) != HOST_CCREG) {
3629     // happens occasionally... cc evicted? Don't bother then
3630     return;
3631   }
3632   for (j = i + 1; j < slen; j++) {
3633     if (dops[j].bt)
3634       break;
3635     if ((found = is_mflohi(j)))
3636       break;
3637     if (dops[j].is_jump) {
3638       // check ds
3639       if (j + 1 < slen && (found = is_mflohi(j + 1)))
3640         j++;
3641       break;
3642     }
3643   }
3644   if (found)
3645     // handle all in multdiv_do_stall()
3646     return;
3647   check_multdiv(i, &c);
3648   assert(c > 0);
3649   assem_debug("; muldiv prepare stall %d\n", c);
3650   host_tempreg_acquire();
3651   emit_addimm(HOST_CCREG, ccadj_ + c, HOST_TEMPREG);
3652   emit_writeword(HOST_TEMPREG, &psxRegs.muldivBusyCycle);
3653   host_tempreg_release();
3654 }
3655
3656 static void multdiv_do_stall(int i, const struct regstat *i_regs)
3657 {
3658   int j, known_cycles = 0;
3659   u_int reglist = get_host_reglist(i_regs->regmap);
3660   int rtmp = get_reg_temp(i_regs->regmap);
3661   if (rtmp < 0)
3662     rtmp = reglist_find_free(reglist);
3663   if (HACK_ENABLED(NDHACK_NO_STALLS))
3664     return;
3665   if (get_reg(i_regs->regmap, CCREG) != HOST_CCREG || rtmp < 0) {
3666     // happens occasionally... cc evicted? Don't bother then
3667     //printf("no cc/rtmp %08x\n", start + i*4);
3668     return;
3669   }
3670   if (!dops[i].bt) {
3671     for (j = i - 1; j >= 0; j--) {
3672       if (dops[j].is_ds) break;
3673       if (check_multdiv(j, &known_cycles))
3674         break;
3675       if (is_mflohi(j))
3676         // already handled by this op
3677         return;
3678       if (dops[j].bt || (j > 0 && ccadj[j - 1] > ccadj[j]))
3679         break;
3680     }
3681     j = max(j, 0);
3682   }
3683   if (known_cycles > 0) {
3684     known_cycles -= ccadj[i] - ccadj[j];
3685     assem_debug("; muldiv stall resolved %d\n", known_cycles);
3686     if (known_cycles > 0)
3687       emit_addimm(HOST_CCREG, known_cycles, HOST_CCREG);
3688     return;
3689   }
3690   assem_debug("; muldiv stall unresolved\n");
3691   host_tempreg_acquire();
3692   emit_readword(&psxRegs.muldivBusyCycle, rtmp);
3693   emit_addimm(rtmp, -ccadj[i], rtmp);
3694   emit_sub(rtmp, HOST_CCREG, HOST_TEMPREG);
3695   emit_cmpimm(HOST_TEMPREG, 37);
3696   emit_cmovb_reg(rtmp, HOST_CCREG);
3697   //emit_log_gte_stall(i, 0, reglist);
3698   host_tempreg_release();
3699 }
3700
3701 static void cop2_get_dreg(u_int copr,signed char tl,signed char temp)
3702 {
3703   switch (copr) {
3704     case 1:
3705     case 3:
3706     case 5:
3707     case 8:
3708     case 9:
3709     case 10:
3710     case 11:
3711       emit_readword(&reg_cop2d[copr],tl);
3712       emit_signextend16(tl,tl);
3713       emit_writeword(tl,&reg_cop2d[copr]); // hmh
3714       break;
3715     case 7:
3716     case 16:
3717     case 17:
3718     case 18:
3719     case 19:
3720       emit_readword(&reg_cop2d[copr],tl);
3721       emit_andimm(tl,0xffff,tl);
3722       emit_writeword(tl,&reg_cop2d[copr]);
3723       break;
3724     case 15:
3725       emit_readword(&reg_cop2d[14],tl); // SXY2
3726       emit_writeword(tl,&reg_cop2d[copr]);
3727       break;
3728     case 28:
3729     case 29:
3730       c2op_mfc2_29_assemble(tl,temp);
3731       break;
3732     default:
3733       emit_readword(&reg_cop2d[copr],tl);
3734       break;
3735   }
3736 }
3737
3738 static void cop2_put_dreg(u_int copr,signed char sl,signed char temp)
3739 {
3740   switch (copr) {
3741     case 15:
3742       emit_readword(&reg_cop2d[13],temp);  // SXY1
3743       emit_writeword(sl,&reg_cop2d[copr]);
3744       emit_writeword(temp,&reg_cop2d[12]); // SXY0
3745       emit_readword(&reg_cop2d[14],temp);  // SXY2
3746       emit_writeword(sl,&reg_cop2d[14]);
3747       emit_writeword(temp,&reg_cop2d[13]); // SXY1
3748       break;
3749     case 28:
3750       emit_andimm(sl,0x001f,temp);
3751       emit_shlimm(temp,7,temp);
3752       emit_writeword(temp,&reg_cop2d[9]);
3753       emit_andimm(sl,0x03e0,temp);
3754       emit_shlimm(temp,2,temp);
3755       emit_writeword(temp,&reg_cop2d[10]);
3756       emit_andimm(sl,0x7c00,temp);
3757       emit_shrimm(temp,3,temp);
3758       emit_writeword(temp,&reg_cop2d[11]);
3759       emit_writeword(sl,&reg_cop2d[28]);
3760       break;
3761     case 30:
3762       emit_xorsar_imm(sl,sl,31,temp);
3763 #if defined(HAVE_ARMV5) || defined(__aarch64__)
3764       emit_clz(temp,temp);
3765 #else
3766       emit_movs(temp,HOST_TEMPREG);
3767       emit_movimm(0,temp);
3768       emit_jeq((int)out+4*4);
3769       emit_addpl_imm(temp,1,temp);
3770       emit_lslpls_imm(HOST_TEMPREG,1,HOST_TEMPREG);
3771       emit_jns((int)out-2*4);
3772 #endif
3773       emit_writeword(sl,&reg_cop2d[30]);
3774       emit_writeword(temp,&reg_cop2d[31]);
3775       break;
3776     case 31:
3777       break;
3778     default:
3779       emit_writeword(sl,&reg_cop2d[copr]);
3780       break;
3781   }
3782 }
3783
3784 static void c2ls_assemble(int i, const struct regstat *i_regs, int ccadj_)
3785 {
3786   int s,tl;
3787   int ar;
3788   int offset;
3789   int memtarget=0,c=0;
3790   void *jaddr2=NULL;
3791   enum stub_type type;
3792   int agr=AGEN1+(i&1);
3793   int offset_reg = -1;
3794   int fastio_reg_override = -1;
3795   u_int reglist=get_host_reglist(i_regs->regmap);
3796   u_int copr=(source[i]>>16)&0x1f;
3797   s=get_reg(i_regs->regmap,dops[i].rs1);
3798   tl=get_reg(i_regs->regmap,FTEMP);
3799   offset=imm[i];
3800   assert(dops[i].rs1>0);
3801   assert(tl>=0);
3802
3803   if(i_regs->regmap[HOST_CCREG]==CCREG)
3804     reglist&=~(1<<HOST_CCREG);
3805
3806   // get the address
3807   if (dops[i].opcode==0x3a) { // SWC2
3808     ar=get_reg(i_regs->regmap,agr);
3809     if(ar<0) ar=get_reg_temp(i_regs->regmap);
3810     reglist|=1<<ar;
3811   } else { // LWC2
3812     ar=tl;
3813   }
3814   if(s>=0) c=(i_regs->wasconst>>s)&1;
3815   memtarget=c&&(((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE);
3816   if (!offset&&!c&&s>=0) ar=s;
3817   assert(ar>=0);
3818
3819   cop2_do_stall_check(0, i, i_regs, reglist);
3820
3821   if (dops[i].opcode==0x3a) { // SWC2
3822     cop2_get_dreg(copr,tl,-1);
3823     type=STOREW_STUB;
3824   }
3825   else
3826     type=LOADW_STUB;
3827
3828   if(c&&!memtarget) {
3829     jaddr2=out;
3830     emit_jmp(0); // inline_readstub/inline_writestub?
3831   }
3832   else {
3833     if(!c) {
3834       jaddr2 = emit_fastpath_cmp_jump(i, i_regs, ar,
3835                 &offset_reg, &fastio_reg_override);
3836     }
3837     else if (ram_offset && memtarget) {
3838       offset_reg = get_ro_reg(i_regs, 0);
3839     }
3840     switch (dops[i].opcode) {
3841     case 0x32: { // LWC2
3842       int a = ar;
3843       if (fastio_reg_override >= 0)
3844         a = fastio_reg_override;
3845       do_load_word(a, tl, offset_reg);
3846       break;
3847     }
3848     case 0x3a: { // SWC2
3849       #ifdef DESTRUCTIVE_SHIFT
3850       if(!offset&&!c&&s>=0) emit_mov(s,ar);
3851       #endif
3852       int a = ar;
3853       if (fastio_reg_override >= 0)
3854         a = fastio_reg_override;
3855       do_store_word(a, 0, tl, offset_reg, 1);
3856       break;
3857     }
3858     default:
3859       assert(0);
3860     }
3861   }
3862   if (fastio_reg_override == HOST_TEMPREG || offset_reg == HOST_TEMPREG)
3863     host_tempreg_release();
3864   if(jaddr2)
3865     add_stub_r(type,jaddr2,out,i,ar,i_regs,ccadj_,reglist);
3866   if(dops[i].opcode==0x3a) // SWC2
3867   if(!(i_regs->waswritten&(1<<dops[i].rs1)) && !HACK_ENABLED(NDHACK_NO_SMC_CHECK)) {
3868 #if defined(HOST_IMM8)
3869     int ir=get_reg(i_regs->regmap,INVCP);
3870     assert(ir>=0);
3871     emit_cmpmem_indexedsr12_reg(ir,ar,1);
3872 #else
3873     emit_cmpmem_indexedsr12_imm(invalid_code,ar,1);
3874 #endif
3875     #ifdef INVALIDATE_USE_COND_CALL
3876     emit_callne(invalidate_addr_reg[ar]);
3877     #else
3878     void *jaddr3 = out;
3879     emit_jne(0);
3880     add_stub(INVCODE_STUB,jaddr3,out,reglist|(1<<HOST_CCREG),ar,0,0,0);
3881     #endif
3882   }
3883   if (dops[i].opcode==0x32) { // LWC2
3884     host_tempreg_acquire();
3885     cop2_put_dreg(copr,tl,HOST_TEMPREG);
3886     host_tempreg_release();
3887   }
3888 }
3889
3890 static void cop2_assemble(int i, const struct regstat *i_regs)
3891 {
3892   u_int copr = (source[i]>>11) & 0x1f;
3893   signed char temp = get_reg_temp(i_regs->regmap);
3894
3895   if (!HACK_ENABLED(NDHACK_NO_STALLS)) {
3896     u_int reglist = reglist_exclude(get_host_reglist(i_regs->regmap), temp, -1);
3897     if (dops[i].opcode2 == 0 || dops[i].opcode2 == 2) { // MFC2/CFC2
3898       signed char tl = get_reg(i_regs->regmap, dops[i].rt1);
3899       reglist = reglist_exclude(reglist, tl, -1);
3900     }
3901     cop2_do_stall_check(0, i, i_regs, reglist);
3902   }
3903   if (dops[i].opcode2==0) { // MFC2
3904     signed char tl=get_reg(i_regs->regmap,dops[i].rt1);
3905     if(tl>=0&&dops[i].rt1!=0)
3906       cop2_get_dreg(copr,tl,temp);
3907   }
3908   else if (dops[i].opcode2==4) { // MTC2
3909     signed char sl=get_reg(i_regs->regmap,dops[i].rs1);
3910     cop2_put_dreg(copr,sl,temp);
3911   }
3912   else if (dops[i].opcode2==2) // CFC2
3913   {
3914     signed char tl=get_reg(i_regs->regmap,dops[i].rt1);
3915     if(tl>=0&&dops[i].rt1!=0)
3916       emit_readword(&reg_cop2c[copr],tl);
3917   }
3918   else if (dops[i].opcode2==6) // CTC2
3919   {
3920     signed char sl=get_reg(i_regs->regmap,dops[i].rs1);
3921     switch(copr) {
3922       case 4:
3923       case 12:
3924       case 20:
3925       case 26:
3926       case 27:
3927       case 29:
3928       case 30:
3929         emit_signextend16(sl,temp);
3930         break;
3931       case 31:
3932         c2op_ctc2_31_assemble(sl,temp);
3933         break;
3934       default:
3935         temp=sl;
3936         break;
3937     }
3938     emit_writeword(temp,&reg_cop2c[copr]);
3939     assert(sl>=0);
3940   }
3941 }
3942
3943 static void do_unalignedwritestub(int n)
3944 {
3945   assem_debug("do_unalignedwritestub %x\n",start+stubs[n].a*4);
3946   literal_pool(256);
3947   set_jump_target(stubs[n].addr, out);
3948
3949   int i=stubs[n].a;
3950   struct regstat *i_regs=(struct regstat *)stubs[n].c;
3951   int addr=stubs[n].b;
3952   u_int reglist=stubs[n].e;
3953   signed char *i_regmap=i_regs->regmap;
3954   int temp2=get_reg(i_regmap,FTEMP);
3955   int rt;
3956   rt=get_reg(i_regmap,dops[i].rs2);
3957   assert(rt>=0);
3958   assert(addr>=0);
3959   assert(dops[i].opcode==0x2a||dops[i].opcode==0x2e); // SWL/SWR only implemented
3960   reglist|=(1<<addr);
3961   reglist&=~(1<<temp2);
3962
3963   // don't bother with it and call write handler
3964   save_regs(reglist);
3965   pass_args(addr,rt);
3966   int cc=get_reg(i_regmap,CCREG);
3967   if(cc<0)
3968     emit_loadreg(CCREG,2);
3969   emit_addimm(cc<0?2:cc,(int)stubs[n].d+1,2);
3970   emit_far_call((dops[i].opcode==0x2a?jump_handle_swl:jump_handle_swr));
3971   emit_addimm(0,-((int)stubs[n].d+1),cc<0?2:cc);
3972   if(cc<0)
3973     emit_storereg(CCREG,2);
3974   restore_regs(reglist);
3975   emit_jmp(stubs[n].retaddr); // return address
3976 }
3977
3978 #ifndef multdiv_assemble
3979 void multdiv_assemble(int i,struct regstat *i_regs)
3980 {
3981   printf("Need multdiv_assemble for this architecture.\n");
3982   abort();
3983 }
3984 #endif
3985
3986 static void mov_assemble(int i, const struct regstat *i_regs)
3987 {
3988   //if(dops[i].opcode2==0x10||dops[i].opcode2==0x12) { // MFHI/MFLO
3989   //if(dops[i].opcode2==0x11||dops[i].opcode2==0x13) { // MTHI/MTLO
3990   if(dops[i].rt1) {
3991     signed char sl,tl;
3992     tl=get_reg(i_regs->regmap,dops[i].rt1);
3993     //assert(tl>=0);
3994     if(tl>=0) {
3995       sl=get_reg(i_regs->regmap,dops[i].rs1);
3996       if(sl>=0) emit_mov(sl,tl);
3997       else emit_loadreg(dops[i].rs1,tl);
3998     }
3999   }
4000   if (dops[i].rs1 == HIREG || dops[i].rs1 == LOREG) // MFHI/MFLO
4001     multdiv_do_stall(i, i_regs);
4002 }
4003
4004 // call interpreter, exception handler, things that change pc/regs/cycles ...
4005 static void call_c_cpu_handler(int i, const struct regstat *i_regs, int ccadj_, u_int pc, void *func)
4006 {
4007   signed char ccreg=get_reg(i_regs->regmap,CCREG);
4008   assert(ccreg==HOST_CCREG);
4009   assert(!is_delayslot);
4010   (void)ccreg;
4011
4012   emit_movimm(pc,3); // Get PC
4013   emit_readword(&last_count,2);
4014   emit_writeword(3,&psxRegs.pc);
4015   emit_addimm(HOST_CCREG,ccadj_,HOST_CCREG);
4016   emit_add(2,HOST_CCREG,2);
4017   emit_writeword(2,&psxRegs.cycle);
4018   emit_far_call(func);
4019   emit_far_jump(jump_to_new_pc);
4020 }
4021
4022 static void syscall_assemble(int i, const struct regstat *i_regs, int ccadj_)
4023 {
4024   // 'break' tends to be littered around to catch things like
4025   // division by 0 and is almost never executed, so don't emit much code here
4026   void *func = (dops[i].opcode2 == 0x0C)
4027     ? (is_delayslot ? jump_syscall_ds : jump_syscall)
4028     : (is_delayslot ? jump_break_ds : jump_break);
4029   assert(get_reg(i_regs->regmap, CCREG) == HOST_CCREG);
4030   emit_movimm(start + i*4, 2); // pc
4031   emit_addimm(HOST_CCREG, ccadj_ + CLOCK_ADJUST(1), HOST_CCREG);
4032   emit_far_jump(func);
4033 }
4034
4035 static void hlecall_assemble(int i, const struct regstat *i_regs, int ccadj_)
4036 {
4037   void *hlefunc = psxNULL;
4038   uint32_t hleCode = source[i] & 0x03ffffff;
4039   if (hleCode < ARRAY_SIZE(psxHLEt))
4040     hlefunc = psxHLEt[hleCode];
4041
4042   call_c_cpu_handler(i, i_regs, ccadj_, start + i*4+4, hlefunc);
4043 }
4044
4045 static void intcall_assemble(int i, const struct regstat *i_regs, int ccadj_)
4046 {
4047   call_c_cpu_handler(i, i_regs, ccadj_, start + i*4, execI);
4048 }
4049
4050 static void speculate_mov(int rs,int rt)
4051 {
4052   if(rt!=0) {
4053     smrv_strong_next|=1<<rt;
4054     smrv[rt]=smrv[rs];
4055   }
4056 }
4057
4058 static void speculate_mov_weak(int rs,int rt)
4059 {
4060   if(rt!=0) {
4061     smrv_weak_next|=1<<rt;
4062     smrv[rt]=smrv[rs];
4063   }
4064 }
4065
4066 static void speculate_register_values(int i)
4067 {
4068   if(i==0) {
4069     memcpy(smrv,psxRegs.GPR.r,sizeof(smrv));
4070     // gp,sp are likely to stay the same throughout the block
4071     smrv_strong_next=(1<<28)|(1<<29)|(1<<30);
4072     smrv_weak_next=~smrv_strong_next;
4073     //printf(" llr %08x\n", smrv[4]);
4074   }
4075   smrv_strong=smrv_strong_next;
4076   smrv_weak=smrv_weak_next;
4077   switch(dops[i].itype) {
4078     case ALU:
4079       if     ((smrv_strong>>dops[i].rs1)&1) speculate_mov(dops[i].rs1,dops[i].rt1);
4080       else if((smrv_strong>>dops[i].rs2)&1) speculate_mov(dops[i].rs2,dops[i].rt1);
4081       else if((smrv_weak>>dops[i].rs1)&1) speculate_mov_weak(dops[i].rs1,dops[i].rt1);
4082       else if((smrv_weak>>dops[i].rs2)&1) speculate_mov_weak(dops[i].rs2,dops[i].rt1);
4083       else {
4084         smrv_strong_next&=~(1<<dops[i].rt1);
4085         smrv_weak_next&=~(1<<dops[i].rt1);
4086       }
4087       break;
4088     case SHIFTIMM:
4089       smrv_strong_next&=~(1<<dops[i].rt1);
4090       smrv_weak_next&=~(1<<dops[i].rt1);
4091       // fallthrough
4092     case IMM16:
4093       if(dops[i].rt1&&is_const(&regs[i],dops[i].rt1)) {
4094         int value,hr=get_reg(regs[i].regmap,dops[i].rt1);
4095         if(hr>=0) {
4096           if(get_final_value(hr,i,&value))
4097                smrv[dops[i].rt1]=value;
4098           else smrv[dops[i].rt1]=constmap[i][hr];
4099           smrv_strong_next|=1<<dops[i].rt1;
4100         }
4101       }
4102       else {
4103         if     ((smrv_strong>>dops[i].rs1)&1) speculate_mov(dops[i].rs1,dops[i].rt1);
4104         else if((smrv_weak>>dops[i].rs1)&1) speculate_mov_weak(dops[i].rs1,dops[i].rt1);
4105       }
4106       break;
4107     case LOAD:
4108       if(start<0x2000&&(dops[i].rt1==26||(smrv[dops[i].rt1]>>24)==0xa0)) {
4109         // special case for BIOS
4110         smrv[dops[i].rt1]=0xa0000000;
4111         smrv_strong_next|=1<<dops[i].rt1;
4112         break;
4113       }
4114       // fallthrough
4115     case SHIFT:
4116     case LOADLR:
4117     case MOV:
4118       smrv_strong_next&=~(1<<dops[i].rt1);
4119       smrv_weak_next&=~(1<<dops[i].rt1);
4120       break;
4121     case COP0:
4122     case COP2:
4123       if(dops[i].opcode2==0||dops[i].opcode2==2) { // MFC/CFC
4124         smrv_strong_next&=~(1<<dops[i].rt1);
4125         smrv_weak_next&=~(1<<dops[i].rt1);
4126       }
4127       break;
4128     case C2LS:
4129       if (dops[i].opcode==0x32) { // LWC2
4130         smrv_strong_next&=~(1<<dops[i].rt1);
4131         smrv_weak_next&=~(1<<dops[i].rt1);
4132       }
4133       break;
4134   }
4135 #if 0
4136   int r=4;
4137   printf("x %08x %08x %d %d c %08x %08x\n",smrv[r],start+i*4,
4138     ((smrv_strong>>r)&1),(smrv_weak>>r)&1,regs[i].isconst,regs[i].wasconst);
4139 #endif
4140 }
4141
4142 static void ujump_assemble(int i, const struct regstat *i_regs);
4143 static void rjump_assemble(int i, const struct regstat *i_regs);
4144 static void cjump_assemble(int i, const struct regstat *i_regs);
4145 static void sjump_assemble(int i, const struct regstat *i_regs);
4146
4147 static int assemble(int i, const struct regstat *i_regs, int ccadj_)
4148 {
4149   int ds = 0;
4150   switch (dops[i].itype) {
4151     case ALU:
4152       alu_assemble(i, i_regs);
4153       break;
4154     case IMM16:
4155       imm16_assemble(i, i_regs);
4156       break;
4157     case SHIFT:
4158       shift_assemble(i, i_regs);
4159       break;
4160     case SHIFTIMM:
4161       shiftimm_assemble(i, i_regs);
4162       break;
4163     case LOAD:
4164       load_assemble(i, i_regs, ccadj_);
4165       break;
4166     case LOADLR:
4167       loadlr_assemble(i, i_regs, ccadj_);
4168       break;
4169     case STORE:
4170       store_assemble(i, i_regs, ccadj_);
4171       break;
4172     case STORELR:
4173       storelr_assemble(i, i_regs, ccadj_);
4174       break;
4175     case COP0:
4176       cop0_assemble(i, i_regs, ccadj_);
4177       break;
4178     case COP1:
4179       cop1_assemble(i, i_regs);
4180       break;
4181     case C1LS:
4182       c1ls_assemble(i, i_regs);
4183       break;
4184     case COP2:
4185       cop2_assemble(i, i_regs);
4186       break;
4187     case C2LS:
4188       c2ls_assemble(i, i_regs, ccadj_);
4189       break;
4190     case C2OP:
4191       c2op_assemble(i, i_regs);
4192       break;
4193     case MULTDIV:
4194       multdiv_assemble(i, i_regs);
4195       multdiv_prepare_stall(i, i_regs, ccadj_);
4196       break;
4197     case MOV:
4198       mov_assemble(i, i_regs);
4199       break;
4200     case SYSCALL:
4201       syscall_assemble(i, i_regs, ccadj_);
4202       break;
4203     case HLECALL:
4204       hlecall_assemble(i, i_regs, ccadj_);
4205       break;
4206     case INTCALL:
4207       intcall_assemble(i, i_regs, ccadj_);
4208       break;
4209     case UJUMP:
4210       ujump_assemble(i, i_regs);
4211       ds = 1;
4212       break;
4213     case RJUMP:
4214       rjump_assemble(i, i_regs);
4215       ds = 1;
4216       break;
4217     case CJUMP:
4218       cjump_assemble(i, i_regs);
4219       ds = 1;
4220       break;
4221     case SJUMP:
4222       sjump_assemble(i, i_regs);
4223       ds = 1;
4224       break;
4225     case NOP:
4226     case OTHER:
4227     case NI:
4228       // not handled, just skip
4229       break;
4230     default:
4231       assert(0);
4232   }
4233   return ds;
4234 }
4235
4236 static void ds_assemble(int i, const struct regstat *i_regs)
4237 {
4238   speculate_register_values(i);
4239   is_delayslot = 1;
4240   switch (dops[i].itype) {
4241     case SYSCALL:
4242     case HLECALL:
4243     case INTCALL:
4244     case UJUMP:
4245     case RJUMP:
4246     case CJUMP:
4247     case SJUMP:
4248       SysPrintf("Jump in the delay slot.  This is probably a bug.\n");
4249       break;
4250     default:
4251       assemble(i, i_regs, ccadj[i]);
4252   }
4253   is_delayslot = 0;
4254 }
4255
4256 // Is the branch target a valid internal jump?
4257 static int internal_branch(int addr)
4258 {
4259   if(addr&1) return 0; // Indirect (register) jump
4260   if(addr>=start && addr<start+slen*4-4)
4261   {
4262     return 1;
4263   }
4264   return 0;
4265 }
4266
4267 static void wb_invalidate(signed char pre[],signed char entry[],uint64_t dirty,uint64_t u)
4268 {
4269   int hr;
4270   for(hr=0;hr<HOST_REGS;hr++) {
4271     if(hr!=EXCLUDE_REG) {
4272       if(pre[hr]!=entry[hr]) {
4273         if(pre[hr]>=0) {
4274           if((dirty>>hr)&1) {
4275             if(get_reg(entry,pre[hr])<0) {
4276               assert(pre[hr]<64);
4277               if(!((u>>pre[hr])&1))
4278                 emit_storereg(pre[hr],hr);
4279             }
4280           }
4281         }
4282       }
4283     }
4284   }
4285   // Move from one register to another (no writeback)
4286   for(hr=0;hr<HOST_REGS;hr++) {
4287     if(hr!=EXCLUDE_REG) {
4288       if(pre[hr]!=entry[hr]) {
4289         if(pre[hr]>=0&&pre[hr]<TEMPREG) {
4290           int nr;
4291           if((nr=get_reg(entry,pre[hr]))>=0) {
4292             emit_mov(hr,nr);
4293           }
4294         }
4295       }
4296     }
4297   }
4298 }
4299
4300 // Load the specified registers
4301 // This only loads the registers given as arguments because
4302 // we don't want to load things that will be overwritten
4303 static inline void load_reg(signed char entry[], signed char regmap[], int rs)
4304 {
4305   int hr = get_reg(regmap, rs);
4306   if (hr >= 0 && entry[hr] != regmap[hr])
4307     emit_loadreg(regmap[hr], hr);
4308 }
4309
4310 static void load_regs(signed char entry[], signed char regmap[], int rs1, int rs2)
4311 {
4312   load_reg(entry, regmap, rs1);
4313   if (rs1 != rs2)
4314     load_reg(entry, regmap, rs2);
4315 }
4316
4317 // Load registers prior to the start of a loop
4318 // so that they are not loaded within the loop
4319 static void loop_preload(signed char pre[],signed char entry[])
4320 {
4321   int hr;
4322   for (hr = 0; hr < HOST_REGS; hr++) {
4323     int r = entry[hr];
4324     if (r >= 0 && pre[hr] != r && get_reg(pre, r) < 0) {
4325       assem_debug("loop preload:\n");
4326       if (r < TEMPREG)
4327         emit_loadreg(r, hr);
4328     }
4329   }
4330 }
4331
4332 // Generate address for load/store instruction
4333 // goes to AGEN for writes, FTEMP for LOADLR and cop1/2 loads
4334 static void address_generation(int i, const struct regstat *i_regs, signed char entry[])
4335 {
4336   if (dops[i].is_load || dops[i].is_store) {
4337     int ra=-1;
4338     int agr=AGEN1+(i&1);
4339     if(dops[i].itype==LOAD) {
4340       ra=get_reg(i_regs->regmap,dops[i].rt1);
4341       if(ra<0) ra=get_reg_temp(i_regs->regmap);
4342       assert(ra>=0);
4343     }
4344     if(dops[i].itype==LOADLR) {
4345       ra=get_reg(i_regs->regmap,FTEMP);
4346     }
4347     if(dops[i].itype==STORE||dops[i].itype==STORELR) {
4348       ra=get_reg(i_regs->regmap,agr);
4349       if(ra<0) ra=get_reg_temp(i_regs->regmap);
4350     }
4351     if(dops[i].itype==C2LS) {
4352       if ((dops[i].opcode&0x3b)==0x31||(dops[i].opcode&0x3b)==0x32) // LWC1/LDC1/LWC2/LDC2
4353         ra=get_reg(i_regs->regmap,FTEMP);
4354       else { // SWC1/SDC1/SWC2/SDC2
4355         ra=get_reg(i_regs->regmap,agr);
4356         if(ra<0) ra=get_reg_temp(i_regs->regmap);
4357       }
4358     }
4359     int rs=get_reg(i_regs->regmap,dops[i].rs1);
4360     if(ra>=0) {
4361       int offset=imm[i];
4362       int c=(i_regs->wasconst>>rs)&1;
4363       if(dops[i].rs1==0) {
4364         // Using r0 as a base address
4365         if(!entry||entry[ra]!=agr) {
4366           if (dops[i].opcode==0x22||dops[i].opcode==0x26) {
4367             emit_movimm(offset&0xFFFFFFFC,ra); // LWL/LWR
4368           }else if (dops[i].opcode==0x1a||dops[i].opcode==0x1b) {
4369             emit_movimm(offset&0xFFFFFFF8,ra); // LDL/LDR
4370           }else{
4371             emit_movimm(offset,ra);
4372           }
4373         } // else did it in the previous cycle
4374       }
4375       else if(rs<0) {
4376         if(!entry||entry[ra]!=dops[i].rs1)
4377           emit_loadreg(dops[i].rs1,ra);
4378         //if(!entry||entry[ra]!=dops[i].rs1)
4379         //  printf("poor load scheduling!\n");
4380       }
4381       else if(c) {
4382         if(dops[i].rs1!=dops[i].rt1||dops[i].itype!=LOAD) {
4383           if(!entry||entry[ra]!=agr) {
4384             if (dops[i].opcode==0x22||dops[i].opcode==0x26) {
4385               emit_movimm((constmap[i][rs]+offset)&0xFFFFFFFC,ra); // LWL/LWR
4386             }else if (dops[i].opcode==0x1a||dops[i].opcode==0x1b) {
4387               emit_movimm((constmap[i][rs]+offset)&0xFFFFFFF8,ra); // LDL/LDR
4388             }else{
4389               emit_movimm(constmap[i][rs]+offset,ra);
4390               regs[i].loadedconst|=1<<ra;
4391             }
4392           } // else did it in the previous cycle
4393         } // else load_consts already did it
4394       }
4395       if(offset&&!c&&dops[i].rs1) {
4396         if(rs>=0) {
4397           emit_addimm(rs,offset,ra);
4398         }else{
4399           emit_addimm(ra,offset,ra);
4400         }
4401       }
4402     }
4403   }
4404   // Preload constants for next instruction
4405   if (dops[i+1].is_load || dops[i+1].is_store) {
4406     int agr,ra;
4407     // Actual address
4408     agr=AGEN1+((i+1)&1);
4409     ra=get_reg(i_regs->regmap,agr);
4410     if(ra>=0) {
4411       int rs=get_reg(regs[i+1].regmap,dops[i+1].rs1);
4412       int offset=imm[i+1];
4413       int c=(regs[i+1].wasconst>>rs)&1;
4414       if(c&&(dops[i+1].rs1!=dops[i+1].rt1||dops[i+1].itype!=LOAD)) {
4415         if (dops[i+1].opcode==0x22||dops[i+1].opcode==0x26) {
4416           emit_movimm((constmap[i+1][rs]+offset)&0xFFFFFFFC,ra); // LWL/LWR
4417         }else if (dops[i+1].opcode==0x1a||dops[i+1].opcode==0x1b) {
4418           emit_movimm((constmap[i+1][rs]+offset)&0xFFFFFFF8,ra); // LDL/LDR
4419         }else{
4420           emit_movimm(constmap[i+1][rs]+offset,ra);
4421           regs[i+1].loadedconst|=1<<ra;
4422         }
4423       }
4424       else if(dops[i+1].rs1==0) {
4425         // Using r0 as a base address
4426         if (dops[i+1].opcode==0x22||dops[i+1].opcode==0x26) {
4427           emit_movimm(offset&0xFFFFFFFC,ra); // LWL/LWR
4428         }else if (dops[i+1].opcode==0x1a||dops[i+1].opcode==0x1b) {
4429           emit_movimm(offset&0xFFFFFFF8,ra); // LDL/LDR
4430         }else{
4431           emit_movimm(offset,ra);
4432         }
4433       }
4434     }
4435   }
4436 }
4437
4438 static int get_final_value(int hr, int i, int *value)
4439 {
4440   int reg=regs[i].regmap[hr];
4441   while(i<slen-1) {
4442     if(regs[i+1].regmap[hr]!=reg) break;
4443     if(!((regs[i+1].isconst>>hr)&1)) break;
4444     if(dops[i+1].bt) break;
4445     i++;
4446   }
4447   if(i<slen-1) {
4448     if (dops[i].is_jump) {
4449       *value=constmap[i][hr];
4450       return 1;
4451     }
4452     if(!dops[i+1].bt) {
4453       if (dops[i+1].is_jump) {
4454         // Load in delay slot, out-of-order execution
4455         if(dops[i+2].itype==LOAD&&dops[i+2].rs1==reg&&dops[i+2].rt1==reg&&((regs[i+1].wasconst>>hr)&1))
4456         {
4457           // Precompute load address
4458           *value=constmap[i][hr]+imm[i+2];
4459           return 1;
4460         }
4461       }
4462       if(dops[i+1].itype==LOAD&&dops[i+1].rs1==reg&&dops[i+1].rt1==reg)
4463       {
4464         // Precompute load address
4465         *value=constmap[i][hr]+imm[i+1];
4466         //printf("c=%x imm=%lx\n",(long)constmap[i][hr],imm[i+1]);
4467         return 1;
4468       }
4469     }
4470   }
4471   *value=constmap[i][hr];
4472   //printf("c=%lx\n",(long)constmap[i][hr]);
4473   if(i==slen-1) return 1;
4474   assert(reg < 64);
4475   return !((unneeded_reg[i+1]>>reg)&1);
4476 }
4477
4478 // Load registers with known constants
4479 static void load_consts(signed char pre[],signed char regmap[],int i)
4480 {
4481   int hr,hr2;
4482   // propagate loaded constant flags
4483   if(i==0||dops[i].bt)
4484     regs[i].loadedconst=0;
4485   else {
4486     for(hr=0;hr<HOST_REGS;hr++) {
4487       if(hr!=EXCLUDE_REG&&regmap[hr]>=0&&((regs[i-1].isconst>>hr)&1)&&pre[hr]==regmap[hr]
4488          &&regmap[hr]==regs[i-1].regmap[hr]&&((regs[i-1].loadedconst>>hr)&1))
4489       {
4490         regs[i].loadedconst|=1<<hr;
4491       }
4492     }
4493   }
4494   // Load 32-bit regs
4495   for(hr=0;hr<HOST_REGS;hr++) {
4496     if(hr!=EXCLUDE_REG&&regmap[hr]>=0) {
4497       //if(entry[hr]!=regmap[hr]) {
4498       if(!((regs[i].loadedconst>>hr)&1)) {
4499         assert(regmap[hr]<64);
4500         if(((regs[i].isconst>>hr)&1)&&regmap[hr]>0) {
4501           int value,similar=0;
4502           if(get_final_value(hr,i,&value)) {
4503             // see if some other register has similar value
4504             for(hr2=0;hr2<HOST_REGS;hr2++) {
4505               if(hr2!=EXCLUDE_REG&&((regs[i].loadedconst>>hr2)&1)) {
4506                 if(is_similar_value(value,constmap[i][hr2])) {
4507                   similar=1;
4508                   break;
4509                 }
4510               }
4511             }
4512             if(similar) {
4513               int value2;
4514               if(get_final_value(hr2,i,&value2)) // is this needed?
4515                 emit_movimm_from(value2,hr2,value,hr);
4516               else
4517                 emit_movimm(value,hr);
4518             }
4519             else if(value==0) {
4520               emit_zeroreg(hr);
4521             }
4522             else {
4523               emit_movimm(value,hr);
4524             }
4525           }
4526           regs[i].loadedconst|=1<<hr;
4527         }
4528       }
4529     }
4530   }
4531 }
4532
4533 static void load_all_consts(const signed char regmap[], u_int dirty, int i)
4534 {
4535   int hr;
4536   // Load 32-bit regs
4537   for(hr=0;hr<HOST_REGS;hr++) {
4538     if(hr!=EXCLUDE_REG&&regmap[hr]>=0&&((dirty>>hr)&1)) {
4539       assert(regmap[hr] < 64);
4540       if(((regs[i].isconst>>hr)&1)&&regmap[hr]>0) {
4541         int value=constmap[i][hr];
4542         if(value==0) {
4543           emit_zeroreg(hr);
4544         }
4545         else {
4546           emit_movimm(value,hr);
4547         }
4548       }
4549     }
4550   }
4551 }
4552
4553 // Write out all dirty registers (except cycle count)
4554 static void wb_dirtys(const signed char i_regmap[], uint64_t i_dirty)
4555 {
4556   int hr;
4557   for(hr=0;hr<HOST_REGS;hr++) {
4558     if(hr!=EXCLUDE_REG) {
4559       if(i_regmap[hr]>0) {
4560         if(i_regmap[hr]!=CCREG) {
4561           if((i_dirty>>hr)&1) {
4562             assert(i_regmap[hr]<64);
4563             emit_storereg(i_regmap[hr],hr);
4564           }
4565         }
4566       }
4567     }
4568   }
4569 }
4570
4571 // Write out dirty registers that we need to reload (pair with load_needed_regs)
4572 // This writes the registers not written by store_regs_bt
4573 static void wb_needed_dirtys(const signed char i_regmap[], uint64_t i_dirty, int addr)
4574 {
4575   int hr;
4576   int t=(addr-start)>>2;
4577   for(hr=0;hr<HOST_REGS;hr++) {
4578     if(hr!=EXCLUDE_REG) {
4579       if(i_regmap[hr]>0) {
4580         if(i_regmap[hr]!=CCREG) {
4581           if(i_regmap[hr]==regs[t].regmap_entry[hr] && ((regs[t].dirty>>hr)&1)) {
4582             if((i_dirty>>hr)&1) {
4583               assert(i_regmap[hr]<64);
4584               emit_storereg(i_regmap[hr],hr);
4585             }
4586           }
4587         }
4588       }
4589     }
4590   }
4591 }
4592
4593 // Load all registers (except cycle count)
4594 static void load_all_regs(const signed char i_regmap[])
4595 {
4596   int hr;
4597   for(hr=0;hr<HOST_REGS;hr++) {
4598     if(hr!=EXCLUDE_REG) {
4599       if(i_regmap[hr]==0) {
4600         emit_zeroreg(hr);
4601       }
4602       else
4603       if(i_regmap[hr]>0 && i_regmap[hr]<TEMPREG && i_regmap[hr]!=CCREG)
4604       {
4605         emit_loadreg(i_regmap[hr],hr);
4606       }
4607     }
4608   }
4609 }
4610
4611 // Load all current registers also needed by next instruction
4612 static void load_needed_regs(const signed char i_regmap[], const signed char next_regmap[])
4613 {
4614   int hr;
4615   for(hr=0;hr<HOST_REGS;hr++) {
4616     if(hr!=EXCLUDE_REG) {
4617       if(get_reg(next_regmap,i_regmap[hr])>=0) {
4618         if(i_regmap[hr]==0) {
4619           emit_zeroreg(hr);
4620         }
4621         else
4622         if(i_regmap[hr]>0 && i_regmap[hr]<TEMPREG && i_regmap[hr]!=CCREG)
4623         {
4624           emit_loadreg(i_regmap[hr],hr);
4625         }
4626       }
4627     }
4628   }
4629 }
4630
4631 // Load all regs, storing cycle count if necessary
4632 static void load_regs_entry(int t)
4633 {
4634   int hr;
4635   if(dops[t].is_ds) emit_addimm(HOST_CCREG,CLOCK_ADJUST(1),HOST_CCREG);
4636   else if(ccadj[t]) emit_addimm(HOST_CCREG,-ccadj[t],HOST_CCREG);
4637   if(regs[t].regmap_entry[HOST_CCREG]!=CCREG) {
4638     emit_storereg(CCREG,HOST_CCREG);
4639   }
4640   // Load 32-bit regs
4641   for(hr=0;hr<HOST_REGS;hr++) {
4642     if(regs[t].regmap_entry[hr]>=0&&regs[t].regmap_entry[hr]<TEMPREG) {
4643       if(regs[t].regmap_entry[hr]==0) {
4644         emit_zeroreg(hr);
4645       }
4646       else if(regs[t].regmap_entry[hr]!=CCREG)
4647       {
4648         emit_loadreg(regs[t].regmap_entry[hr],hr);
4649       }
4650     }
4651   }
4652 }
4653
4654 // Store dirty registers prior to branch
4655 static void store_regs_bt(signed char i_regmap[],uint64_t i_dirty,int addr)
4656 {
4657   if(internal_branch(addr))
4658   {
4659     int t=(addr-start)>>2;
4660     int hr;
4661     for(hr=0;hr<HOST_REGS;hr++) {
4662       if(hr!=EXCLUDE_REG) {
4663         if(i_regmap[hr]>0 && i_regmap[hr]!=CCREG) {
4664           if(i_regmap[hr]!=regs[t].regmap_entry[hr] || !((regs[t].dirty>>hr)&1)) {
4665             if((i_dirty>>hr)&1) {
4666               assert(i_regmap[hr]<64);
4667               if(!((unneeded_reg[t]>>i_regmap[hr])&1))
4668                 emit_storereg(i_regmap[hr],hr);
4669             }
4670           }
4671         }
4672       }
4673     }
4674   }
4675   else
4676   {
4677     // Branch out of this block, write out all dirty regs
4678     wb_dirtys(i_regmap,i_dirty);
4679   }
4680 }
4681
4682 // Load all needed registers for branch target
4683 static void load_regs_bt(signed char i_regmap[],uint64_t i_dirty,int addr)
4684 {
4685   //if(addr>=start && addr<(start+slen*4))
4686   if(internal_branch(addr))
4687   {
4688     int t=(addr-start)>>2;
4689     int hr;
4690     // Store the cycle count before loading something else
4691     if(i_regmap[HOST_CCREG]!=CCREG) {
4692       assert(i_regmap[HOST_CCREG]==-1);
4693     }
4694     if(regs[t].regmap_entry[HOST_CCREG]!=CCREG) {
4695       emit_storereg(CCREG,HOST_CCREG);
4696     }
4697     // Load 32-bit regs
4698     for(hr=0;hr<HOST_REGS;hr++) {
4699       if(hr!=EXCLUDE_REG&&regs[t].regmap_entry[hr]>=0&&regs[t].regmap_entry[hr]<TEMPREG) {
4700         if(i_regmap[hr]!=regs[t].regmap_entry[hr]) {
4701           if(regs[t].regmap_entry[hr]==0) {
4702             emit_zeroreg(hr);
4703           }
4704           else if(regs[t].regmap_entry[hr]!=CCREG)
4705           {
4706             emit_loadreg(regs[t].regmap_entry[hr],hr);
4707           }
4708         }
4709       }
4710     }
4711   }
4712 }
4713
4714 static int match_bt(signed char i_regmap[],uint64_t i_dirty,int addr)
4715 {
4716   if(addr>=start && addr<start+slen*4-4)
4717   {
4718     int t=(addr-start)>>2;
4719     int hr;
4720     if(regs[t].regmap_entry[HOST_CCREG]!=CCREG) return 0;
4721     for(hr=0;hr<HOST_REGS;hr++)
4722     {
4723       if(hr!=EXCLUDE_REG)
4724       {
4725         if(i_regmap[hr]!=regs[t].regmap_entry[hr])
4726         {
4727           if(regs[t].regmap_entry[hr]>=0&&(regs[t].regmap_entry[hr]|64)<TEMPREG+64)
4728           {
4729             return 0;
4730           }
4731           else
4732           if((i_dirty>>hr)&1)
4733           {
4734             if(i_regmap[hr]<TEMPREG)
4735             {
4736               if(!((unneeded_reg[t]>>i_regmap[hr])&1))
4737                 return 0;
4738             }
4739             else if(i_regmap[hr]>=64&&i_regmap[hr]<TEMPREG+64)
4740             {
4741               assert(0);
4742             }
4743           }
4744         }
4745         else // Same register but is it 32-bit or dirty?
4746         if(i_regmap[hr]>=0)
4747         {
4748           if(!((regs[t].dirty>>hr)&1))
4749           {
4750             if((i_dirty>>hr)&1)
4751             {
4752               if(!((unneeded_reg[t]>>i_regmap[hr])&1))
4753               {
4754                 //printf("%x: dirty no match\n",addr);
4755                 return 0;
4756               }
4757             }
4758           }
4759         }
4760       }
4761     }
4762     // Delay slots are not valid branch targets
4763     //if(t>0&&(dops[t-1].is_jump) return 0;
4764     // Delay slots require additional processing, so do not match
4765     if(dops[t].is_ds) return 0;
4766   }
4767   else
4768   {
4769     int hr;
4770     for(hr=0;hr<HOST_REGS;hr++)
4771     {
4772       if(hr!=EXCLUDE_REG)
4773       {
4774         if(i_regmap[hr]>=0)
4775         {
4776           if(hr!=HOST_CCREG||i_regmap[hr]!=CCREG)
4777           {
4778             if((i_dirty>>hr)&1)
4779             {
4780               return 0;
4781             }
4782           }
4783         }
4784       }
4785     }
4786   }
4787   return 1;
4788 }
4789
4790 #ifdef DRC_DBG
4791 static void drc_dbg_emit_do_cmp(int i, int ccadj_)
4792 {
4793   extern void do_insn_cmp();
4794   //extern int cycle;
4795   u_int hr, reglist = get_host_reglist(regs[i].regmap);
4796
4797   assem_debug("//do_insn_cmp %08x\n", start+i*4);
4798   save_regs(reglist);
4799   // write out changed consts to match the interpreter
4800   if (i > 0 && !dops[i].bt) {
4801     for (hr = 0; hr < HOST_REGS; hr++) {
4802       int reg = regs[i].regmap_entry[hr]; // regs[i-1].regmap[hr];
4803       if (hr == EXCLUDE_REG || reg < 0)
4804         continue;
4805       if (!((regs[i-1].isconst >> hr) & 1))
4806         continue;
4807       if (i > 1 && reg == regs[i-2].regmap[hr] && constmap[i-1][hr] == constmap[i-2][hr])
4808         continue;
4809       emit_movimm(constmap[i-1][hr],0);
4810       emit_storereg(reg, 0);
4811     }
4812   }
4813   emit_movimm(start+i*4,0);
4814   emit_writeword(0,&pcaddr);
4815   int cc = get_reg(regs[i].regmap_entry, CCREG);
4816   if (cc < 0)
4817     emit_loadreg(CCREG, cc = 0);
4818   emit_addimm(cc, ccadj_, 0);
4819   emit_writeword(0, &psxRegs.cycle);
4820   emit_far_call(do_insn_cmp);
4821   //emit_readword(&cycle,0);
4822   //emit_addimm(0,2,0);
4823   //emit_writeword(0,&cycle);
4824   (void)get_reg2;
4825   restore_regs(reglist);
4826   assem_debug("\\\\do_insn_cmp\n");
4827 }
4828 #else
4829 #define drc_dbg_emit_do_cmp(x,y)
4830 #endif
4831
4832 // Used when a branch jumps into the delay slot of another branch
4833 static void ds_assemble_entry(int i)
4834 {
4835   int t = (ba[i] - start) >> 2;
4836   int ccadj_ = -CLOCK_ADJUST(1);
4837   if (!instr_addr[t])
4838     instr_addr[t] = out;
4839   assem_debug("Assemble delay slot at %x\n",ba[i]);
4840   assem_debug("<->\n");
4841   drc_dbg_emit_do_cmp(t, ccadj_);
4842   if(regs[t].regmap_entry[HOST_CCREG]==CCREG&&regs[t].regmap[HOST_CCREG]!=CCREG)
4843     wb_register(CCREG,regs[t].regmap_entry,regs[t].wasdirty);
4844   load_regs(regs[t].regmap_entry,regs[t].regmap,dops[t].rs1,dops[t].rs2);
4845   address_generation(t,&regs[t],regs[t].regmap_entry);
4846   if (ram_offset && (dops[t].is_load || dops[t].is_store))
4847     load_reg(regs[t].regmap_entry,regs[t].regmap,ROREG);
4848   if (dops[t].is_store)
4849     load_reg(regs[t].regmap_entry,regs[t].regmap,INVCP);
4850   is_delayslot=0;
4851   switch (dops[t].itype) {
4852     case SYSCALL:
4853     case HLECALL:
4854     case INTCALL:
4855     case UJUMP:
4856     case RJUMP:
4857     case CJUMP:
4858     case SJUMP:
4859       SysPrintf("Jump in the delay slot.  This is probably a bug.\n");
4860       break;
4861     default:
4862       assemble(t, &regs[t], ccadj_);
4863   }
4864   store_regs_bt(regs[t].regmap,regs[t].dirty,ba[i]+4);
4865   load_regs_bt(regs[t].regmap,regs[t].dirty,ba[i]+4);
4866   if(internal_branch(ba[i]+4))
4867     assem_debug("branch: internal\n");
4868   else
4869     assem_debug("branch: external\n");
4870   assert(internal_branch(ba[i]+4));
4871   add_to_linker(out,ba[i]+4,internal_branch(ba[i]+4));
4872   emit_jmp(0);
4873 }
4874
4875 // Load 2 immediates optimizing for small code size
4876 static void emit_mov2imm_compact(int imm1,u_int rt1,int imm2,u_int rt2)
4877 {
4878   emit_movimm(imm1,rt1);
4879   emit_movimm_from(imm1,rt1,imm2,rt2);
4880 }
4881
4882 static void do_cc(int i, const signed char i_regmap[], int *adj,
4883   int addr, int taken, int invert)
4884 {
4885   int count, count_plus2;
4886   void *jaddr;
4887   void *idle=NULL;
4888   int t=0;
4889   if(dops[i].itype==RJUMP)
4890   {
4891     *adj=0;
4892   }
4893   //if(ba[i]>=start && ba[i]<(start+slen*4))
4894   if(internal_branch(ba[i]))
4895   {
4896     t=(ba[i]-start)>>2;
4897     if(dops[t].is_ds) *adj=-CLOCK_ADJUST(1); // Branch into delay slot adds an extra cycle
4898     else *adj=ccadj[t];
4899   }
4900   else
4901   {
4902     *adj=0;
4903   }
4904   count = ccadj[i];
4905   count_plus2 = count + CLOCK_ADJUST(2);
4906   if(taken==TAKEN && i==(ba[i]-start)>>2 && source[i+1]==0) {
4907     // Idle loop
4908     if(count&1) emit_addimm_and_set_flags(2*(count+2),HOST_CCREG);
4909     idle=out;
4910     //emit_subfrommem(&idlecount,HOST_CCREG); // Count idle cycles
4911     emit_andimm(HOST_CCREG,3,HOST_CCREG);
4912     jaddr=out;
4913     emit_jmp(0);
4914   }
4915   else if(*adj==0||invert) {
4916     int cycles = count_plus2;
4917     // faster loop HACK
4918 #if 0
4919     if (t&&*adj) {
4920       int rel=t-i;
4921       if(-NO_CYCLE_PENALTY_THR<rel&&rel<0)
4922         cycles=*adj+count+2-*adj;
4923     }
4924 #endif
4925     emit_addimm_and_set_flags(cycles, HOST_CCREG);
4926     jaddr = out;
4927     emit_jns(0);
4928   }
4929   else
4930   {
4931     emit_cmpimm(HOST_CCREG, -count_plus2);
4932     jaddr = out;
4933     emit_jns(0);
4934   }
4935   add_stub(CC_STUB,jaddr,idle?idle:out,(*adj==0||invert||idle)?0:count_plus2,i,addr,taken,0);
4936 }
4937
4938 static void do_ccstub(int n)
4939 {
4940   literal_pool(256);
4941   assem_debug("do_ccstub %x\n",start+(u_int)stubs[n].b*4);
4942   set_jump_target(stubs[n].addr, out);
4943   int i=stubs[n].b;
4944   if(stubs[n].d==NULLDS) {
4945     // Delay slot instruction is nullified ("likely" branch)
4946     wb_dirtys(regs[i].regmap,regs[i].dirty);
4947   }
4948   else if(stubs[n].d!=TAKEN) {
4949     wb_dirtys(branch_regs[i].regmap,branch_regs[i].dirty);
4950   }
4951   else {
4952     if(internal_branch(ba[i]))
4953       wb_needed_dirtys(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
4954   }
4955   if(stubs[n].c!=-1)
4956   {
4957     // Save PC as return address
4958     emit_movimm(stubs[n].c,EAX);
4959     emit_writeword(EAX,&pcaddr);
4960   }
4961   else
4962   {
4963     // Return address depends on which way the branch goes
4964     if(dops[i].itype==CJUMP||dops[i].itype==SJUMP)
4965     {
4966       int s1l=get_reg(branch_regs[i].regmap,dops[i].rs1);
4967       int s2l=get_reg(branch_regs[i].regmap,dops[i].rs2);
4968       if(dops[i].rs1==0)
4969       {
4970         s1l=s2l;
4971         s2l=-1;
4972       }
4973       else if(dops[i].rs2==0)
4974       {
4975         s2l=-1;
4976       }
4977       assert(s1l>=0);
4978       #ifdef DESTRUCTIVE_WRITEBACK
4979       if(dops[i].rs1) {
4980         if((branch_regs[i].dirty>>s1l)&&1)
4981           emit_loadreg(dops[i].rs1,s1l);
4982       }
4983       else {
4984         if((branch_regs[i].dirty>>s1l)&1)
4985           emit_loadreg(dops[i].rs2,s1l);
4986       }
4987       if(s2l>=0)
4988         if((branch_regs[i].dirty>>s2l)&1)
4989           emit_loadreg(dops[i].rs2,s2l);
4990       #endif
4991       int hr=0;
4992       int addr=-1,alt=-1,ntaddr=-1;
4993       while(hr<HOST_REGS)
4994       {
4995         if(hr!=EXCLUDE_REG && hr!=HOST_CCREG &&
4996            branch_regs[i].regmap[hr]!=dops[i].rs1 &&
4997            branch_regs[i].regmap[hr]!=dops[i].rs2 )
4998         {
4999           addr=hr++;break;
5000         }
5001         hr++;
5002       }
5003       while(hr<HOST_REGS)
5004       {
5005         if(hr!=EXCLUDE_REG && hr!=HOST_CCREG &&
5006            branch_regs[i].regmap[hr]!=dops[i].rs1 &&
5007            branch_regs[i].regmap[hr]!=dops[i].rs2 )
5008         {
5009           alt=hr++;break;
5010         }
5011         hr++;
5012       }
5013       if((dops[i].opcode&0x2E)==6) // BLEZ/BGTZ needs another register
5014       {
5015         while(hr<HOST_REGS)
5016         {
5017           if(hr!=EXCLUDE_REG && hr!=HOST_CCREG &&
5018              branch_regs[i].regmap[hr]!=dops[i].rs1 &&
5019              branch_regs[i].regmap[hr]!=dops[i].rs2 )
5020           {
5021             ntaddr=hr;break;
5022           }
5023           hr++;
5024         }
5025         assert(hr<HOST_REGS);
5026       }
5027       if((dops[i].opcode&0x2f)==4) // BEQ
5028       {
5029         #ifdef HAVE_CMOV_IMM
5030         if(s2l>=0) emit_cmp(s1l,s2l);
5031         else emit_test(s1l,s1l);
5032         emit_cmov2imm_e_ne_compact(ba[i],start+i*4+8,addr);
5033         #else
5034         emit_mov2imm_compact(ba[i],addr,start+i*4+8,alt);
5035         if(s2l>=0) emit_cmp(s1l,s2l);
5036         else emit_test(s1l,s1l);
5037         emit_cmovne_reg(alt,addr);
5038         #endif
5039       }
5040       if((dops[i].opcode&0x2f)==5) // BNE
5041       {
5042         #ifdef HAVE_CMOV_IMM
5043         if(s2l>=0) emit_cmp(s1l,s2l);
5044         else emit_test(s1l,s1l);
5045         emit_cmov2imm_e_ne_compact(start+i*4+8,ba[i],addr);
5046         #else
5047         emit_mov2imm_compact(start+i*4+8,addr,ba[i],alt);
5048         if(s2l>=0) emit_cmp(s1l,s2l);
5049         else emit_test(s1l,s1l);
5050         emit_cmovne_reg(alt,addr);
5051         #endif
5052       }
5053       if((dops[i].opcode&0x2f)==6) // BLEZ
5054       {
5055         //emit_movimm(ba[i],alt);
5056         //emit_movimm(start+i*4+8,addr);
5057         emit_mov2imm_compact(ba[i],alt,start+i*4+8,addr);
5058         emit_cmpimm(s1l,1);
5059         emit_cmovl_reg(alt,addr);
5060       }
5061       if((dops[i].opcode&0x2f)==7) // BGTZ
5062       {
5063         //emit_movimm(ba[i],addr);
5064         //emit_movimm(start+i*4+8,ntaddr);
5065         emit_mov2imm_compact(ba[i],addr,start+i*4+8,ntaddr);
5066         emit_cmpimm(s1l,1);
5067         emit_cmovl_reg(ntaddr,addr);
5068       }
5069       if((dops[i].opcode==1)&&(dops[i].opcode2&0x2D)==0) // BLTZ
5070       {
5071         //emit_movimm(ba[i],alt);
5072         //emit_movimm(start+i*4+8,addr);
5073         emit_mov2imm_compact(ba[i],alt,start+i*4+8,addr);
5074         emit_test(s1l,s1l);
5075         emit_cmovs_reg(alt,addr);
5076       }
5077       if((dops[i].opcode==1)&&(dops[i].opcode2&0x2D)==1) // BGEZ
5078       {
5079         //emit_movimm(ba[i],addr);
5080         //emit_movimm(start+i*4+8,alt);
5081         emit_mov2imm_compact(ba[i],addr,start+i*4+8,alt);
5082         emit_test(s1l,s1l);
5083         emit_cmovs_reg(alt,addr);
5084       }
5085       if(dops[i].opcode==0x11 && dops[i].opcode2==0x08 ) {
5086         if(source[i]&0x10000) // BC1T
5087         {
5088           //emit_movimm(ba[i],alt);
5089           //emit_movimm(start+i*4+8,addr);
5090           emit_mov2imm_compact(ba[i],alt,start+i*4+8,addr);
5091           emit_testimm(s1l,0x800000);
5092           emit_cmovne_reg(alt,addr);
5093         }
5094         else // BC1F
5095         {
5096           //emit_movimm(ba[i],addr);
5097           //emit_movimm(start+i*4+8,alt);
5098           emit_mov2imm_compact(ba[i],addr,start+i*4+8,alt);
5099           emit_testimm(s1l,0x800000);
5100           emit_cmovne_reg(alt,addr);
5101         }
5102       }
5103       emit_writeword(addr,&pcaddr);
5104     }
5105     else
5106     if(dops[i].itype==RJUMP)
5107     {
5108       int r=get_reg(branch_regs[i].regmap,dops[i].rs1);
5109       if (ds_writes_rjump_rs(i)) {
5110         r=get_reg(branch_regs[i].regmap,RTEMP);
5111       }
5112       emit_writeword(r,&pcaddr);
5113     }
5114     else {SysPrintf("Unknown branch type in do_ccstub\n");abort();}
5115   }
5116   // Update cycle count
5117   assert(branch_regs[i].regmap[HOST_CCREG]==CCREG||branch_regs[i].regmap[HOST_CCREG]==-1);
5118   if(stubs[n].a) emit_addimm(HOST_CCREG,(int)stubs[n].a,HOST_CCREG);
5119   emit_far_call(cc_interrupt);
5120   if(stubs[n].a) emit_addimm(HOST_CCREG,-(int)stubs[n].a,HOST_CCREG);
5121   if(stubs[n].d==TAKEN) {
5122     if(internal_branch(ba[i]))
5123       load_needed_regs(branch_regs[i].regmap,regs[(ba[i]-start)>>2].regmap_entry);
5124     else if(dops[i].itype==RJUMP) {
5125       if(get_reg(branch_regs[i].regmap,RTEMP)>=0)
5126         emit_readword(&pcaddr,get_reg(branch_regs[i].regmap,RTEMP));
5127       else
5128         emit_loadreg(dops[i].rs1,get_reg(branch_regs[i].regmap,dops[i].rs1));
5129     }
5130   }else if(stubs[n].d==NOTTAKEN) {
5131     if(i<slen-2) load_needed_regs(branch_regs[i].regmap,regmap_pre[i+2]);
5132     else load_all_regs(branch_regs[i].regmap);
5133   }else if(stubs[n].d==NULLDS) {
5134     // Delay slot instruction is nullified ("likely" branch)
5135     if(i<slen-2) load_needed_regs(regs[i].regmap,regmap_pre[i+2]);
5136     else load_all_regs(regs[i].regmap);
5137   }else{
5138     load_all_regs(branch_regs[i].regmap);
5139   }
5140   if (stubs[n].retaddr)
5141     emit_jmp(stubs[n].retaddr);
5142   else
5143     do_jump_vaddr(stubs[n].e);
5144 }
5145
5146 static void add_to_linker(void *addr, u_int target, int is_internal)
5147 {
5148   assert(linkcount < ARRAY_SIZE(link_addr));
5149   link_addr[linkcount].addr = addr;
5150   link_addr[linkcount].target = target;
5151   link_addr[linkcount].internal = is_internal;
5152   linkcount++;
5153 }
5154
5155 static void ujump_assemble_write_ra(int i)
5156 {
5157   int rt;
5158   unsigned int return_address;
5159   rt=get_reg(branch_regs[i].regmap,31);
5160   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]);
5161   //assert(rt>=0);
5162   return_address=start+i*4+8;
5163   if(rt>=0) {
5164     #ifdef USE_MINI_HT
5165     if(internal_branch(return_address)&&dops[i+1].rt1!=31) {
5166       int temp=-1; // note: must be ds-safe
5167       #ifdef HOST_TEMPREG
5168       temp=HOST_TEMPREG;
5169       #endif
5170       if(temp>=0) do_miniht_insert(return_address,rt,temp);
5171       else emit_movimm(return_address,rt);
5172     }
5173     else
5174     #endif
5175     {
5176       #ifdef REG_PREFETCH
5177       if(temp>=0)
5178       {
5179         if(i_regmap[temp]!=PTEMP) emit_movimm((uintptr_t)hash_table_get(return_address),temp);
5180       }
5181       #endif
5182       emit_movimm(return_address,rt); // PC into link register
5183       #ifdef IMM_PREFETCH
5184       emit_prefetch(hash_table_get(return_address));
5185       #endif
5186     }
5187   }
5188 }
5189
5190 static void ujump_assemble(int i, const struct regstat *i_regs)
5191 {
5192   int ra_done=0;
5193   if(i==(ba[i]-start)>>2) assem_debug("idle loop\n");
5194   address_generation(i+1,i_regs,regs[i].regmap_entry);
5195   #ifdef REG_PREFETCH
5196   int temp=get_reg(branch_regs[i].regmap,PTEMP);
5197   if(dops[i].rt1==31&&temp>=0)
5198   {
5199     signed char *i_regmap=i_regs->regmap;
5200     int return_address=start+i*4+8;
5201     if(get_reg(branch_regs[i].regmap,31)>0)
5202     if(i_regmap[temp]==PTEMP) emit_movimm((uintptr_t)hash_table_get(return_address),temp);
5203   }
5204   #endif
5205   if(dops[i].rt1==31&&(dops[i].rt1==dops[i+1].rs1||dops[i].rt1==dops[i+1].rs2)) {
5206     ujump_assemble_write_ra(i); // writeback ra for DS
5207     ra_done=1;
5208   }
5209   ds_assemble(i+1,i_regs);
5210   uint64_t bc_unneeded=branch_regs[i].u;
5211   bc_unneeded|=1|(1LL<<dops[i].rt1);
5212   wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,bc_unneeded);
5213   load_reg(regs[i].regmap,branch_regs[i].regmap,CCREG);
5214   if(!ra_done&&dops[i].rt1==31)
5215     ujump_assemble_write_ra(i);
5216   int cc,adj;
5217   cc=get_reg(branch_regs[i].regmap,CCREG);
5218   assert(cc==HOST_CCREG);
5219   store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5220   #ifdef REG_PREFETCH
5221   if(dops[i].rt1==31&&temp>=0) emit_prefetchreg(temp);
5222   #endif
5223   do_cc(i,branch_regs[i].regmap,&adj,ba[i],TAKEN,0);
5224   if(adj) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5225   load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5226   if(internal_branch(ba[i]))
5227     assem_debug("branch: internal\n");
5228   else
5229     assem_debug("branch: external\n");
5230   if (internal_branch(ba[i]) && dops[(ba[i]-start)>>2].is_ds) {
5231     ds_assemble_entry(i);
5232   }
5233   else {
5234     add_to_linker(out,ba[i],internal_branch(ba[i]));
5235     emit_jmp(0);
5236   }
5237 }
5238
5239 static void rjump_assemble_write_ra(int i)
5240 {
5241   int rt,return_address;
5242   assert(dops[i+1].rt1!=dops[i].rt1);
5243   assert(dops[i+1].rt2!=dops[i].rt1);
5244   rt=get_reg(branch_regs[i].regmap,dops[i].rt1);
5245   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]);
5246   assert(rt>=0);
5247   return_address=start+i*4+8;
5248   #ifdef REG_PREFETCH
5249   if(temp>=0)
5250   {
5251     if(i_regmap[temp]!=PTEMP) emit_movimm((uintptr_t)hash_table_get(return_address),temp);
5252   }
5253   #endif
5254   emit_movimm(return_address,rt); // PC into link register
5255   #ifdef IMM_PREFETCH
5256   emit_prefetch(hash_table_get(return_address));
5257   #endif
5258 }
5259
5260 static void rjump_assemble(int i, const struct regstat *i_regs)
5261 {
5262   int temp;
5263   int rs,cc;
5264   int ra_done=0;
5265   rs=get_reg(branch_regs[i].regmap,dops[i].rs1);
5266   assert(rs>=0);
5267   if (ds_writes_rjump_rs(i)) {
5268     // Delay slot abuse, make a copy of the branch address register
5269     temp=get_reg(branch_regs[i].regmap,RTEMP);
5270     assert(temp>=0);
5271     assert(regs[i].regmap[temp]==RTEMP);
5272     emit_mov(rs,temp);
5273     rs=temp;
5274   }
5275   address_generation(i+1,i_regs,regs[i].regmap_entry);
5276   #ifdef REG_PREFETCH
5277   if(dops[i].rt1==31)
5278   {
5279     if((temp=get_reg(branch_regs[i].regmap,PTEMP))>=0) {
5280       signed char *i_regmap=i_regs->regmap;
5281       int return_address=start+i*4+8;
5282       if(i_regmap[temp]==PTEMP) emit_movimm((uintptr_t)hash_table_get(return_address),temp);
5283     }
5284   }
5285   #endif
5286   #ifdef USE_MINI_HT
5287   if(dops[i].rs1==31) {
5288     int rh=get_reg(regs[i].regmap,RHASH);
5289     if(rh>=0) do_preload_rhash(rh);
5290   }
5291   #endif
5292   if(dops[i].rt1!=0&&(dops[i].rt1==dops[i+1].rs1||dops[i].rt1==dops[i+1].rs2)) {
5293     rjump_assemble_write_ra(i);
5294     ra_done=1;
5295   }
5296   ds_assemble(i+1,i_regs);
5297   uint64_t bc_unneeded=branch_regs[i].u;
5298   bc_unneeded|=1|(1LL<<dops[i].rt1);
5299   bc_unneeded&=~(1LL<<dops[i].rs1);
5300   wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,bc_unneeded);
5301   load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i].rs1,CCREG);
5302   if(!ra_done&&dops[i].rt1!=0)
5303     rjump_assemble_write_ra(i);
5304   cc=get_reg(branch_regs[i].regmap,CCREG);
5305   assert(cc==HOST_CCREG);
5306   (void)cc;
5307   #ifdef USE_MINI_HT
5308   int rh=get_reg(branch_regs[i].regmap,RHASH);
5309   int ht=get_reg(branch_regs[i].regmap,RHTBL);
5310   if(dops[i].rs1==31) {
5311     if(regs[i].regmap[rh]!=RHASH) do_preload_rhash(rh);
5312     do_preload_rhtbl(ht);
5313     do_rhash(rs,rh);
5314   }
5315   #endif
5316   store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,-1);
5317   #ifdef DESTRUCTIVE_WRITEBACK
5318   if((branch_regs[i].dirty>>rs)&1) {
5319     if(dops[i].rs1!=dops[i+1].rt1&&dops[i].rs1!=dops[i+1].rt2) {
5320       emit_loadreg(dops[i].rs1,rs);
5321     }
5322   }
5323   #endif
5324   #ifdef REG_PREFETCH
5325   if(dops[i].rt1==31&&temp>=0) emit_prefetchreg(temp);
5326   #endif
5327   #ifdef USE_MINI_HT
5328   if(dops[i].rs1==31) {
5329     do_miniht_load(ht,rh);
5330   }
5331   #endif
5332   //do_cc(i,branch_regs[i].regmap,&adj,-1,TAKEN);
5333   //if(adj) emit_addimm(cc,2*(ccadj[i]+2-adj),cc); // ??? - Shouldn't happen
5334   //assert(adj==0);
5335   emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), HOST_CCREG);
5336   add_stub(CC_STUB,out,NULL,0,i,-1,TAKEN,rs);
5337   if(dops[i+1].itype==COP0&&(source[i+1]&0x3f)==0x10)
5338     // special case for RFE
5339     emit_jmp(0);
5340   else
5341     emit_jns(0);
5342   //load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,-1);
5343   #ifdef USE_MINI_HT
5344   if(dops[i].rs1==31) {
5345     do_miniht_jump(rs,rh,ht);
5346   }
5347   else
5348   #endif
5349   {
5350     do_jump_vaddr(rs);
5351   }
5352   #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5353   if(dops[i].rt1!=31&&i<slen-2&&(((u_int)out)&7)) emit_mov(13,13);
5354   #endif
5355 }
5356
5357 static void cjump_assemble(int i, const struct regstat *i_regs)
5358 {
5359   const signed char *i_regmap = i_regs->regmap;
5360   int cc;
5361   int match;
5362   match=match_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5363   assem_debug("match=%d\n",match);
5364   int s1l,s2l;
5365   int unconditional=0,nop=0;
5366   int invert=0;
5367   int internal=internal_branch(ba[i]);
5368   if(i==(ba[i]-start)>>2) assem_debug("idle loop\n");
5369   if(!match) invert=1;
5370   #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5371   if(i>(ba[i]-start)>>2) invert=1;
5372   #endif
5373   #ifdef __aarch64__
5374   invert=1; // because of near cond. branches
5375   #endif
5376
5377   if(dops[i].ooo) {
5378     s1l=get_reg(branch_regs[i].regmap,dops[i].rs1);
5379     s2l=get_reg(branch_regs[i].regmap,dops[i].rs2);
5380   }
5381   else {
5382     s1l=get_reg(i_regmap,dops[i].rs1);
5383     s2l=get_reg(i_regmap,dops[i].rs2);
5384   }
5385   if(dops[i].rs1==0&&dops[i].rs2==0)
5386   {
5387     if(dops[i].opcode&1) nop=1;
5388     else unconditional=1;
5389     //assert(dops[i].opcode!=5);
5390     //assert(dops[i].opcode!=7);
5391     //assert(dops[i].opcode!=0x15);
5392     //assert(dops[i].opcode!=0x17);
5393   }
5394   else if(dops[i].rs1==0)
5395   {
5396     s1l=s2l;
5397     s2l=-1;
5398   }
5399   else if(dops[i].rs2==0)
5400   {
5401     s2l=-1;
5402   }
5403
5404   if(dops[i].ooo) {
5405     // Out of order execution (delay slot first)
5406     //printf("OOOE\n");
5407     address_generation(i+1,i_regs,regs[i].regmap_entry);
5408     ds_assemble(i+1,i_regs);
5409     int adj;
5410     uint64_t bc_unneeded=branch_regs[i].u;
5411     bc_unneeded&=~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
5412     bc_unneeded|=1;
5413     wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,bc_unneeded);
5414     load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i].rs1,dops[i].rs2);
5415     load_reg(regs[i].regmap,branch_regs[i].regmap,CCREG);
5416     cc=get_reg(branch_regs[i].regmap,CCREG);
5417     assert(cc==HOST_CCREG);
5418     if(unconditional)
5419       store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5420     //do_cc(i,branch_regs[i].regmap,&adj,unconditional?ba[i]:-1,unconditional);
5421     //assem_debug("cycle count (adj)\n");
5422     if(unconditional) {
5423       do_cc(i,branch_regs[i].regmap,&adj,ba[i],TAKEN,0);
5424       if(i!=(ba[i]-start)>>2 || source[i+1]!=0) {
5425         if(adj) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5426         load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5427         if(internal)
5428           assem_debug("branch: internal\n");
5429         else
5430           assem_debug("branch: external\n");
5431         if (internal && dops[(ba[i]-start)>>2].is_ds) {
5432           ds_assemble_entry(i);
5433         }
5434         else {
5435           add_to_linker(out,ba[i],internal);
5436           emit_jmp(0);
5437         }
5438         #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5439         if(((u_int)out)&7) emit_addnop(0);
5440         #endif
5441       }
5442     }
5443     else if(nop) {
5444       emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), cc);
5445       void *jaddr=out;
5446       emit_jns(0);
5447       add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
5448     }
5449     else {
5450       void *taken = NULL, *nottaken = NULL, *nottaken1 = NULL;
5451       do_cc(i,branch_regs[i].regmap,&adj,-1,0,invert);
5452       if(adj&&!invert) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5453
5454       //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]);
5455       assert(s1l>=0);
5456       if(dops[i].opcode==4) // BEQ
5457       {
5458         if(s2l>=0) emit_cmp(s1l,s2l);
5459         else emit_test(s1l,s1l);
5460         if(invert){
5461           nottaken=out;
5462           emit_jne(DJT_1);
5463         }else{
5464           add_to_linker(out,ba[i],internal);
5465           emit_jeq(0);
5466         }
5467       }
5468       if(dops[i].opcode==5) // BNE
5469       {
5470         if(s2l>=0) emit_cmp(s1l,s2l);
5471         else emit_test(s1l,s1l);
5472         if(invert){
5473           nottaken=out;
5474           emit_jeq(DJT_1);
5475         }else{
5476           add_to_linker(out,ba[i],internal);
5477           emit_jne(0);
5478         }
5479       }
5480       if(dops[i].opcode==6) // BLEZ
5481       {
5482         emit_cmpimm(s1l,1);
5483         if(invert){
5484           nottaken=out;
5485           emit_jge(DJT_1);
5486         }else{
5487           add_to_linker(out,ba[i],internal);
5488           emit_jl(0);
5489         }
5490       }
5491       if(dops[i].opcode==7) // BGTZ
5492       {
5493         emit_cmpimm(s1l,1);
5494         if(invert){
5495           nottaken=out;
5496           emit_jl(DJT_1);
5497         }else{
5498           add_to_linker(out,ba[i],internal);
5499           emit_jge(0);
5500         }
5501       }
5502       if(invert) {
5503         if(taken) set_jump_target(taken, out);
5504         #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5505         if (match && (!internal || !dops[(ba[i]-start)>>2].is_ds)) {
5506           if(adj) {
5507             emit_addimm(cc,-adj,cc);
5508             add_to_linker(out,ba[i],internal);
5509           }else{
5510             emit_addnop(13);
5511             add_to_linker(out,ba[i],internal*2);
5512           }
5513           emit_jmp(0);
5514         }else
5515         #endif
5516         {
5517           if(adj) emit_addimm(cc,-adj,cc);
5518           store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5519           load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5520           if(internal)
5521             assem_debug("branch: internal\n");
5522           else
5523             assem_debug("branch: external\n");
5524           if (internal && dops[(ba[i] - start) >> 2].is_ds) {
5525             ds_assemble_entry(i);
5526           }
5527           else {
5528             add_to_linker(out,ba[i],internal);
5529             emit_jmp(0);
5530           }
5531         }
5532         set_jump_target(nottaken, out);
5533       }
5534
5535       if(nottaken1) set_jump_target(nottaken1, out);
5536       if(adj) {
5537         if(!invert) emit_addimm(cc,adj,cc);
5538       }
5539     } // (!unconditional)
5540   } // if(ooo)
5541   else
5542   {
5543     // In-order execution (branch first)
5544     void *taken = NULL, *nottaken = NULL, *nottaken1 = NULL;
5545     if(!unconditional&&!nop) {
5546       //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]);
5547       assert(s1l>=0);
5548       if((dops[i].opcode&0x2f)==4) // BEQ
5549       {
5550         if(s2l>=0) emit_cmp(s1l,s2l);
5551         else emit_test(s1l,s1l);
5552         nottaken=out;
5553         emit_jne(DJT_2);
5554       }
5555       if((dops[i].opcode&0x2f)==5) // BNE
5556       {
5557         if(s2l>=0) emit_cmp(s1l,s2l);
5558         else emit_test(s1l,s1l);
5559         nottaken=out;
5560         emit_jeq(DJT_2);
5561       }
5562       if((dops[i].opcode&0x2f)==6) // BLEZ
5563       {
5564         emit_cmpimm(s1l,1);
5565         nottaken=out;
5566         emit_jge(DJT_2);
5567       }
5568       if((dops[i].opcode&0x2f)==7) // BGTZ
5569       {
5570         emit_cmpimm(s1l,1);
5571         nottaken=out;
5572         emit_jl(DJT_2);
5573       }
5574     } // if(!unconditional)
5575     int adj;
5576     uint64_t ds_unneeded=branch_regs[i].u;
5577     ds_unneeded&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
5578     ds_unneeded|=1;
5579     // branch taken
5580     if(!nop) {
5581       if(taken) set_jump_target(taken, out);
5582       assem_debug("1:\n");
5583       wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,ds_unneeded);
5584       // load regs
5585       load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i+1].rs1,dops[i+1].rs2);
5586       address_generation(i+1,&branch_regs[i],0);
5587       if (ram_offset)
5588         load_reg(regs[i].regmap,branch_regs[i].regmap,ROREG);
5589       load_regs(regs[i].regmap,branch_regs[i].regmap,CCREG,INVCP);
5590       ds_assemble(i+1,&branch_regs[i]);
5591       cc=get_reg(branch_regs[i].regmap,CCREG);
5592       if(cc==-1) {
5593         emit_loadreg(CCREG,cc=HOST_CCREG);
5594         // CHECK: Is the following instruction (fall thru) allocated ok?
5595       }
5596       assert(cc==HOST_CCREG);
5597       store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5598       do_cc(i,i_regmap,&adj,ba[i],TAKEN,0);
5599       assem_debug("cycle count (adj)\n");
5600       if(adj) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5601       load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5602       if(internal)
5603         assem_debug("branch: internal\n");
5604       else
5605         assem_debug("branch: external\n");
5606       if (internal && dops[(ba[i] - start) >> 2].is_ds) {
5607         ds_assemble_entry(i);
5608       }
5609       else {
5610         add_to_linker(out,ba[i],internal);
5611         emit_jmp(0);
5612       }
5613     }
5614     // branch not taken
5615     if(!unconditional) {
5616       if(nottaken1) set_jump_target(nottaken1, out);
5617       set_jump_target(nottaken, out);
5618       assem_debug("2:\n");
5619       wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,ds_unneeded);
5620       // load regs
5621       load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i+1].rs1,dops[i+1].rs2);
5622       address_generation(i+1,&branch_regs[i],0);
5623       if (ram_offset)
5624         load_reg(regs[i].regmap,branch_regs[i].regmap,ROREG);
5625       load_regs(regs[i].regmap,branch_regs[i].regmap,CCREG,INVCP);
5626       ds_assemble(i+1,&branch_regs[i]);
5627       cc=get_reg(branch_regs[i].regmap,CCREG);
5628       if (cc == -1) {
5629         // Cycle count isn't in a register, temporarily load it then write it out
5630         emit_loadreg(CCREG,HOST_CCREG);
5631         emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), HOST_CCREG);
5632         void *jaddr=out;
5633         emit_jns(0);
5634         add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
5635         emit_storereg(CCREG,HOST_CCREG);
5636       }
5637       else{
5638         cc=get_reg(i_regmap,CCREG);
5639         assert(cc==HOST_CCREG);
5640         emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), cc);
5641         void *jaddr=out;
5642         emit_jns(0);
5643         add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
5644       }
5645     }
5646   }
5647 }
5648
5649 static void sjump_assemble(int i, const struct regstat *i_regs)
5650 {
5651   const signed char *i_regmap = i_regs->regmap;
5652   int cc;
5653   int match;
5654   match=match_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5655   assem_debug("smatch=%d ooo=%d\n", match, dops[i].ooo);
5656   int s1l;
5657   int unconditional=0,nevertaken=0;
5658   int invert=0;
5659   int internal=internal_branch(ba[i]);
5660   if(i==(ba[i]-start)>>2) assem_debug("idle loop\n");
5661   if(!match) invert=1;
5662   #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5663   if(i>(ba[i]-start)>>2) invert=1;
5664   #endif
5665   #ifdef __aarch64__
5666   invert=1; // because of near cond. branches
5667   #endif
5668
5669   //if(dops[i].opcode2>=0x10) return; // FIXME (BxxZAL)
5670   //assert(dops[i].opcode2<0x10||dops[i].rs1==0); // FIXME (BxxZAL)
5671
5672   if(dops[i].ooo) {
5673     s1l=get_reg(branch_regs[i].regmap,dops[i].rs1);
5674   }
5675   else {
5676     s1l=get_reg(i_regmap,dops[i].rs1);
5677   }
5678   if(dops[i].rs1==0)
5679   {
5680     if(dops[i].opcode2&1) unconditional=1;
5681     else nevertaken=1;
5682     // These are never taken (r0 is never less than zero)
5683     //assert(dops[i].opcode2!=0);
5684     //assert(dops[i].opcode2!=2);
5685     //assert(dops[i].opcode2!=0x10);
5686     //assert(dops[i].opcode2!=0x12);
5687   }
5688
5689   if(dops[i].ooo) {
5690     // Out of order execution (delay slot first)
5691     //printf("OOOE\n");
5692     address_generation(i+1,i_regs,regs[i].regmap_entry);
5693     ds_assemble(i+1,i_regs);
5694     int adj;
5695     uint64_t bc_unneeded=branch_regs[i].u;
5696     bc_unneeded&=~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
5697     bc_unneeded|=1;
5698     wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,bc_unneeded);
5699     load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i].rs1,dops[i].rs1);
5700     load_reg(regs[i].regmap,branch_regs[i].regmap,CCREG);
5701     if(dops[i].rt1==31) {
5702       int rt,return_address;
5703       rt=get_reg(branch_regs[i].regmap,31);
5704       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]);
5705       if(rt>=0) {
5706         // Save the PC even if the branch is not taken
5707         return_address=start+i*4+8;
5708         emit_movimm(return_address,rt); // PC into link register
5709         #ifdef IMM_PREFETCH
5710         if(!nevertaken) emit_prefetch(hash_table_get(return_address));
5711         #endif
5712       }
5713     }
5714     cc=get_reg(branch_regs[i].regmap,CCREG);
5715     assert(cc==HOST_CCREG);
5716     if(unconditional)
5717       store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5718     //do_cc(i,branch_regs[i].regmap,&adj,unconditional?ba[i]:-1,unconditional);
5719     assem_debug("cycle count (adj)\n");
5720     if(unconditional) {
5721       do_cc(i,branch_regs[i].regmap,&adj,ba[i],TAKEN,0);
5722       if(i!=(ba[i]-start)>>2 || source[i+1]!=0) {
5723         if(adj) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5724         load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5725         if(internal)
5726           assem_debug("branch: internal\n");
5727         else
5728           assem_debug("branch: external\n");
5729         if (internal && dops[(ba[i] - start) >> 2].is_ds) {
5730           ds_assemble_entry(i);
5731         }
5732         else {
5733           add_to_linker(out,ba[i],internal);
5734           emit_jmp(0);
5735         }
5736         #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5737         if(((u_int)out)&7) emit_addnop(0);
5738         #endif
5739       }
5740     }
5741     else if(nevertaken) {
5742       emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), cc);
5743       void *jaddr=out;
5744       emit_jns(0);
5745       add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
5746     }
5747     else {
5748       void *nottaken = NULL;
5749       do_cc(i,branch_regs[i].regmap,&adj,-1,0,invert);
5750       if(adj&&!invert) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5751       {
5752         assert(s1l>=0);
5753         if((dops[i].opcode2&0xf)==0) // BLTZ/BLTZAL
5754         {
5755           emit_test(s1l,s1l);
5756           if(invert){
5757             nottaken=out;
5758             emit_jns(DJT_1);
5759           }else{
5760             add_to_linker(out,ba[i],internal);
5761             emit_js(0);
5762           }
5763         }
5764         if((dops[i].opcode2&0xf)==1) // BGEZ/BLTZAL
5765         {
5766           emit_test(s1l,s1l);
5767           if(invert){
5768             nottaken=out;
5769             emit_js(DJT_1);
5770           }else{
5771             add_to_linker(out,ba[i],internal);
5772             emit_jns(0);
5773           }
5774         }
5775       }
5776
5777       if(invert) {
5778         #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
5779         if (match && (!internal || !dops[(ba[i] - start) >> 2].is_ds)) {
5780           if(adj) {
5781             emit_addimm(cc,-adj,cc);
5782             add_to_linker(out,ba[i],internal);
5783           }else{
5784             emit_addnop(13);
5785             add_to_linker(out,ba[i],internal*2);
5786           }
5787           emit_jmp(0);
5788         }else
5789         #endif
5790         {
5791           if(adj) emit_addimm(cc,-adj,cc);
5792           store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5793           load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5794           if(internal)
5795             assem_debug("branch: internal\n");
5796           else
5797             assem_debug("branch: external\n");
5798           if (internal && dops[(ba[i] - start) >> 2].is_ds) {
5799             ds_assemble_entry(i);
5800           }
5801           else {
5802             add_to_linker(out,ba[i],internal);
5803             emit_jmp(0);
5804           }
5805         }
5806         set_jump_target(nottaken, out);
5807       }
5808
5809       if(adj) {
5810         if(!invert) emit_addimm(cc,adj,cc);
5811       }
5812     } // (!unconditional)
5813   } // if(ooo)
5814   else
5815   {
5816     // In-order execution (branch first)
5817     //printf("IOE\n");
5818     void *nottaken = NULL;
5819     if(dops[i].rt1==31) {
5820       int rt,return_address;
5821       rt=get_reg(branch_regs[i].regmap,31);
5822       if(rt>=0) {
5823         // Save the PC even if the branch is not taken
5824         return_address=start+i*4+8;
5825         emit_movimm(return_address,rt); // PC into link register
5826         #ifdef IMM_PREFETCH
5827         emit_prefetch(hash_table_get(return_address));
5828         #endif
5829       }
5830     }
5831     if(!unconditional) {
5832       //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]);
5833         assert(s1l>=0);
5834         if((dops[i].opcode2&0x0d)==0) // BLTZ/BLTZL/BLTZAL/BLTZALL
5835         {
5836           emit_test(s1l,s1l);
5837           nottaken=out;
5838           emit_jns(DJT_1);
5839         }
5840         if((dops[i].opcode2&0x0d)==1) // BGEZ/BGEZL/BGEZAL/BGEZALL
5841         {
5842           emit_test(s1l,s1l);
5843           nottaken=out;
5844           emit_js(DJT_1);
5845         }
5846     } // if(!unconditional)
5847     int adj;
5848     uint64_t ds_unneeded=branch_regs[i].u;
5849     ds_unneeded&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
5850     ds_unneeded|=1;
5851     // branch taken
5852     if(!nevertaken) {
5853       //assem_debug("1:\n");
5854       wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,ds_unneeded);
5855       // load regs
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       if (ram_offset)
5859         load_reg(regs[i].regmap,branch_regs[i].regmap,ROREG);
5860       load_regs(regs[i].regmap,branch_regs[i].regmap,CCREG,INVCP);
5861       ds_assemble(i+1,&branch_regs[i]);
5862       cc=get_reg(branch_regs[i].regmap,CCREG);
5863       if(cc==-1) {
5864         emit_loadreg(CCREG,cc=HOST_CCREG);
5865         // CHECK: Is the following instruction (fall thru) allocated ok?
5866       }
5867       assert(cc==HOST_CCREG);
5868       store_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5869       do_cc(i,i_regmap,&adj,ba[i],TAKEN,0);
5870       assem_debug("cycle count (adj)\n");
5871       if(adj) emit_addimm(cc, ccadj[i] + CLOCK_ADJUST(2) - adj, cc);
5872       load_regs_bt(branch_regs[i].regmap,branch_regs[i].dirty,ba[i]);
5873       if(internal)
5874         assem_debug("branch: internal\n");
5875       else
5876         assem_debug("branch: external\n");
5877       if (internal && dops[(ba[i] - start) >> 2].is_ds) {
5878         ds_assemble_entry(i);
5879       }
5880       else {
5881         add_to_linker(out,ba[i],internal);
5882         emit_jmp(0);
5883       }
5884     }
5885     // branch not taken
5886     if(!unconditional) {
5887       set_jump_target(nottaken, out);
5888       assem_debug("1:\n");
5889       wb_invalidate(regs[i].regmap,branch_regs[i].regmap,regs[i].dirty,ds_unneeded);
5890       load_regs(regs[i].regmap,branch_regs[i].regmap,dops[i+1].rs1,dops[i+1].rs2);
5891       address_generation(i+1,&branch_regs[i],0);
5892       if (ram_offset)
5893         load_reg(regs[i].regmap,branch_regs[i].regmap,ROREG);
5894       load_regs(regs[i].regmap,branch_regs[i].regmap,CCREG,INVCP);
5895       ds_assemble(i+1,&branch_regs[i]);
5896       cc=get_reg(branch_regs[i].regmap,CCREG);
5897       if (cc == -1) {
5898         // Cycle count isn't in a register, temporarily load it then write it out
5899         emit_loadreg(CCREG,HOST_CCREG);
5900         emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), HOST_CCREG);
5901         void *jaddr=out;
5902         emit_jns(0);
5903         add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
5904         emit_storereg(CCREG,HOST_CCREG);
5905       }
5906       else{
5907         cc=get_reg(i_regmap,CCREG);
5908         assert(cc==HOST_CCREG);
5909         emit_addimm_and_set_flags(ccadj[i] + CLOCK_ADJUST(2), cc);
5910         void *jaddr=out;
5911         emit_jns(0);
5912         add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
5913       }
5914     }
5915   }
5916 }
5917
5918 static void check_regmap(signed char *regmap)
5919 {
5920 #ifndef NDEBUG
5921   int i,j;
5922   for (i = 0; i < HOST_REGS; i++) {
5923     if (regmap[i] < 0)
5924       continue;
5925     for (j = i + 1; j < HOST_REGS; j++)
5926       assert(regmap[i] != regmap[j]);
5927   }
5928 #endif
5929 }
5930
5931 #ifdef DISASM
5932 #include <inttypes.h>
5933 static char insn[MAXBLOCK][10];
5934
5935 #define set_mnemonic(i_, n_) \
5936   strcpy(insn[i_], n_)
5937
5938 void print_regmap(const char *name, const signed char *regmap)
5939 {
5940   char buf[5];
5941   int i, l;
5942   fputs(name, stdout);
5943   for (i = 0; i < HOST_REGS; i++) {
5944     l = 0;
5945     if (regmap[i] >= 0)
5946       l = snprintf(buf, sizeof(buf), "$%d", regmap[i]);
5947     for (; l < 3; l++)
5948       buf[l] = ' ';
5949     buf[l] = 0;
5950     printf(" r%d=%s", i, buf);
5951   }
5952   fputs("\n", stdout);
5953 }
5954
5955   /* disassembly */
5956 void disassemble_inst(int i)
5957 {
5958     if (dops[i].bt) printf("*"); else printf(" ");
5959     switch(dops[i].itype) {
5960       case UJUMP:
5961         printf (" %x: %s %8x\n",start+i*4,insn[i],ba[i]);break;
5962       case CJUMP:
5963         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;
5964       case SJUMP:
5965         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;
5966       case RJUMP:
5967         if (dops[i].opcode==0x9&&dops[i].rt1!=31)
5968           printf (" %x: %s r%d,r%d\n",start+i*4,insn[i],dops[i].rt1,dops[i].rs1);
5969         else
5970           printf (" %x: %s r%d\n",start+i*4,insn[i],dops[i].rs1);
5971         break;
5972       case IMM16:
5973         if(dops[i].opcode==0xf) //LUI
5974           printf (" %x: %s r%d,%4x0000\n",start+i*4,insn[i],dops[i].rt1,imm[i]&0xffff);
5975         else
5976           printf (" %x: %s r%d,r%d,%d\n",start+i*4,insn[i],dops[i].rt1,dops[i].rs1,imm[i]);
5977         break;
5978       case LOAD:
5979       case LOADLR:
5980         printf (" %x: %s r%d,r%d+%x\n",start+i*4,insn[i],dops[i].rt1,dops[i].rs1,imm[i]);
5981         break;
5982       case STORE:
5983       case STORELR:
5984         printf (" %x: %s r%d,r%d+%x\n",start+i*4,insn[i],dops[i].rs2,dops[i].rs1,imm[i]);
5985         break;
5986       case ALU:
5987       case SHIFT:
5988         printf (" %x: %s r%d,r%d,r%d\n",start+i*4,insn[i],dops[i].rt1,dops[i].rs1,dops[i].rs2);
5989         break;
5990       case MULTDIV:
5991         printf (" %x: %s r%d,r%d\n",start+i*4,insn[i],dops[i].rs1,dops[i].rs2);
5992         break;
5993       case SHIFTIMM:
5994         printf (" %x: %s r%d,r%d,%d\n",start+i*4,insn[i],dops[i].rt1,dops[i].rs1,imm[i]);
5995         break;
5996       case MOV:
5997         if((dops[i].opcode2&0x1d)==0x10)
5998           printf (" %x: %s r%d\n",start+i*4,insn[i],dops[i].rt1);
5999         else if((dops[i].opcode2&0x1d)==0x11)
6000           printf (" %x: %s r%d\n",start+i*4,insn[i],dops[i].rs1);
6001         else
6002           printf (" %x: %s\n",start+i*4,insn[i]);
6003         break;
6004       case COP0:
6005         if(dops[i].opcode2==0)
6006           printf (" %x: %s r%d,cpr0[%d]\n",start+i*4,insn[i],dops[i].rt1,(source[i]>>11)&0x1f); // MFC0
6007         else if(dops[i].opcode2==4)
6008           printf (" %x: %s r%d,cpr0[%d]\n",start+i*4,insn[i],dops[i].rs1,(source[i]>>11)&0x1f); // MTC0
6009         else printf (" %x: %s\n",start+i*4,insn[i]);
6010         break;
6011       case COP1:
6012         if(dops[i].opcode2<3)
6013           printf (" %x: %s r%d,cpr1[%d]\n",start+i*4,insn[i],dops[i].rt1,(source[i]>>11)&0x1f); // MFC1
6014         else if(dops[i].opcode2>3)
6015           printf (" %x: %s r%d,cpr1[%d]\n",start+i*4,insn[i],dops[i].rs1,(source[i]>>11)&0x1f); // MTC1
6016         else printf (" %x: %s\n",start+i*4,insn[i]);
6017         break;
6018       case COP2:
6019         if(dops[i].opcode2<3)
6020           printf (" %x: %s r%d,cpr2[%d]\n",start+i*4,insn[i],dops[i].rt1,(source[i]>>11)&0x1f); // MFC2
6021         else if(dops[i].opcode2>3)
6022           printf (" %x: %s r%d,cpr2[%d]\n",start+i*4,insn[i],dops[i].rs1,(source[i]>>11)&0x1f); // MTC2
6023         else printf (" %x: %s\n",start+i*4,insn[i]);
6024         break;
6025       case C1LS:
6026         printf (" %x: %s cpr1[%d],r%d+%x\n",start+i*4,insn[i],(source[i]>>16)&0x1f,dops[i].rs1,imm[i]);
6027         break;
6028       case C2LS:
6029         printf (" %x: %s cpr2[%d],r%d+%x\n",start+i*4,insn[i],(source[i]>>16)&0x1f,dops[i].rs1,imm[i]);
6030         break;
6031       case INTCALL:
6032         printf (" %x: %s (INTCALL)\n",start+i*4,insn[i]);
6033         break;
6034       default:
6035         //printf (" %s %8x\n",insn[i],source[i]);
6036         printf (" %x: %s\n",start+i*4,insn[i]);
6037     }
6038     return;
6039     printf("D: %"PRIu64"  WD: %"PRIu64"  U: %"PRIu64"\n",
6040       regs[i].dirty, regs[i].wasdirty, unneeded_reg[i]);
6041     print_regmap("pre:   ", regmap_pre[i]);
6042     print_regmap("entry: ", regs[i].regmap_entry);
6043     print_regmap("map:   ", regs[i].regmap);
6044     if (dops[i].is_jump) {
6045       print_regmap("bentry:", branch_regs[i].regmap_entry);
6046       print_regmap("bmap:  ", branch_regs[i].regmap);
6047     }
6048 }
6049 #else
6050 #define set_mnemonic(i_, n_)
6051 static void disassemble_inst(int i) {}
6052 #endif // DISASM
6053
6054 #define DRC_TEST_VAL 0x74657374
6055
6056 static void new_dynarec_test(void)
6057 {
6058   int (*testfunc)(void);
6059   void *beginning;
6060   int ret[2];
6061   size_t i;
6062
6063   // check structure linkage
6064   if ((u_char *)rcnts - (u_char *)&psxRegs != sizeof(psxRegs))
6065   {
6066     SysPrintf("linkage_arm* miscompilation/breakage detected.\n");
6067   }
6068
6069   SysPrintf("testing if we can run recompiled code @%p...\n", out);
6070   ((volatile u_int *)out)[0]++; // make cache dirty
6071
6072   for (i = 0; i < ARRAY_SIZE(ret); i++) {
6073     out = ndrc->translation_cache;
6074     beginning = start_block();
6075     emit_movimm(DRC_TEST_VAL + i, 0); // test
6076     emit_ret();
6077     literal_pool(0);
6078     end_block(beginning);
6079     testfunc = beginning;
6080     ret[i] = testfunc();
6081   }
6082
6083   if (ret[0] == DRC_TEST_VAL && ret[1] == DRC_TEST_VAL + 1)
6084     SysPrintf("test passed.\n");
6085   else
6086     SysPrintf("test failed, will likely crash soon (r=%08x %08x)\n", ret[0], ret[1]);
6087   out = ndrc->translation_cache;
6088 }
6089
6090 // clear the state completely, instead of just marking
6091 // things invalid like invalidate_all_pages() does
6092 void new_dynarec_clear_full(void)
6093 {
6094   int n;
6095   out = ndrc->translation_cache;
6096   memset(invalid_code,1,sizeof(invalid_code));
6097   memset(hash_table,0xff,sizeof(hash_table));
6098   memset(mini_ht,-1,sizeof(mini_ht));
6099   memset(shadow,0,sizeof(shadow));
6100   copy=shadow;
6101   expirep=16384; // Expiry pointer, +2 blocks
6102   pending_exception=0;
6103   literalcount=0;
6104   stop_after_jal=0;
6105   inv_code_start=inv_code_end=~0;
6106   hack_addr=0;
6107   f1_hack=0;
6108   // TLB
6109   for(n=0;n<4096;n++) blocks_clear(&blocks[n]);
6110   for(n=0;n<4096;n++) ll_clear(jump_out+n);
6111   stat_clear(stat_blocks);
6112   stat_clear(stat_links);
6113
6114   cycle_multiplier_old = cycle_multiplier;
6115   new_dynarec_hacks_old = new_dynarec_hacks;
6116 }
6117
6118 void new_dynarec_init(void)
6119 {
6120   SysPrintf("Init new dynarec, ndrc size %x\n", (int)sizeof(*ndrc));
6121
6122 #ifdef _3DS
6123   check_rosalina();
6124 #endif
6125 #ifdef BASE_ADDR_DYNAMIC
6126   #ifdef VITA
6127   sceBlock = getVMBlock(); //sceKernelAllocMemBlockForVM("code", sizeof(*ndrc));
6128   if (sceBlock <= 0)
6129     SysPrintf("sceKernelAllocMemBlockForVM failed: %x\n", sceBlock);
6130   int ret = sceKernelGetMemBlockBase(sceBlock, (void **)&ndrc);
6131   if (ret < 0)
6132     SysPrintf("sceKernelGetMemBlockBase failed: %x\n", ret);
6133   sceKernelOpenVMDomain();
6134   sceClibPrintf("translation_cache = 0x%08lx\n ", (long)ndrc->translation_cache);
6135   #elif defined(_MSC_VER)
6136   ndrc = VirtualAlloc(NULL, sizeof(*ndrc), MEM_COMMIT | MEM_RESERVE,
6137     PAGE_EXECUTE_READWRITE);
6138   #else
6139   uintptr_t desired_addr = 0;
6140   #ifdef __ELF__
6141   extern char _end;
6142   desired_addr = ((uintptr_t)&_end + 0xffffff) & ~0xffffffl;
6143   #endif
6144   ndrc = mmap((void *)desired_addr, sizeof(*ndrc),
6145             PROT_READ | PROT_WRITE | PROT_EXEC,
6146             MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
6147   if (ndrc == MAP_FAILED) {
6148     SysPrintf("mmap() failed: %s\n", strerror(errno));
6149     abort();
6150   }
6151   #endif
6152 #else
6153   #ifndef NO_WRITE_EXEC
6154   // not all systems allow execute in data segment by default
6155   // size must be 4K aligned for 3DS?
6156   if (mprotect(ndrc, sizeof(*ndrc),
6157                PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
6158     SysPrintf("mprotect() failed: %s\n", strerror(errno));
6159   #endif
6160 #endif
6161   out = ndrc->translation_cache;
6162   cycle_multiplier=200;
6163   new_dynarec_clear_full();
6164 #ifdef HOST_IMM8
6165   // Copy this into local area so we don't have to put it in every literal pool
6166   invc_ptr=invalid_code;
6167 #endif
6168   arch_init();
6169   new_dynarec_test();
6170   ram_offset=(uintptr_t)rdram-0x80000000;
6171   if (ram_offset!=0)
6172     SysPrintf("warning: RAM is not directly mapped, performance will suffer\n");
6173   SysPrintf("Mapped (RAM/scrp/ROM/LUTs/TC):\n");
6174   SysPrintf("%p/%p/%p/%p/%p\n", psxM, psxH, psxR, mem_rtab, out);
6175 }
6176
6177 void new_dynarec_cleanup(void)
6178 {
6179   int n;
6180 #ifdef BASE_ADDR_DYNAMIC
6181   #ifdef VITA
6182   // sceBlock is managed by retroarch's bootstrap code
6183   //sceKernelFreeMemBlock(sceBlock);
6184   //sceBlock = -1;
6185   #else
6186   if (munmap(ndrc, sizeof(*ndrc)) < 0)
6187     SysPrintf("munmap() failed\n");
6188   #endif
6189 #endif
6190   for(n=0;n<4096;n++) blocks_clear(&blocks[n]);
6191   for(n=0;n<4096;n++) ll_clear(jump_out+n);
6192   stat_clear(stat_blocks);
6193   stat_clear(stat_links);
6194   #ifdef ROM_COPY
6195   if (munmap (ROM_COPY, 67108864) < 0) {SysPrintf("munmap() failed\n");}
6196   #endif
6197   new_dynarec_print_stats();
6198 }
6199
6200 static u_int *get_source_start(u_int addr, u_int *limit)
6201 {
6202   if (addr < 0x00200000 ||
6203     (0xa0000000 <= addr && addr < 0xa0200000))
6204   {
6205     // used for BIOS calls mostly?
6206     *limit = (addr&0xa0000000)|0x00200000;
6207     return (u_int *)(rdram + (addr&0x1fffff));
6208   }
6209   else if (!Config.HLE && (
6210     /* (0x9fc00000 <= addr && addr < 0x9fc80000) ||*/
6211     (0xbfc00000 <= addr && addr < 0xbfc80000)))
6212   {
6213     // BIOS. The multiplier should be much higher as it's uncached 8bit mem,
6214     // but timings in PCSX are too tied to the interpreter's BIAS
6215     if (!HACK_ENABLED(NDHACK_OVERRIDE_CYCLE_M))
6216       cycle_multiplier_active = 200;
6217
6218     *limit = (addr & 0xfff00000) | 0x80000;
6219     return (u_int *)((u_char *)psxR + (addr&0x7ffff));
6220   }
6221   else if (addr >= 0x80000000 && addr < 0x80000000+RAM_SIZE) {
6222     *limit = (addr & 0x80600000) + 0x00200000;
6223     return (u_int *)(rdram + (addr&0x1fffff));
6224   }
6225   return NULL;
6226 }
6227
6228 static u_int scan_for_ret(u_int addr)
6229 {
6230   u_int limit = 0;
6231   u_int *mem;
6232
6233   mem = get_source_start(addr, &limit);
6234   if (mem == NULL)
6235     return addr;
6236
6237   if (limit > addr + 0x1000)
6238     limit = addr + 0x1000;
6239   for (; addr < limit; addr += 4, mem++) {
6240     if (*mem == 0x03e00008) // jr $ra
6241       return addr + 8;
6242   }
6243   return addr;
6244 }
6245
6246 struct savestate_block {
6247   uint32_t addr;
6248   uint32_t regflags;
6249 };
6250
6251 static int addr_cmp(const void *p1_, const void *p2_)
6252 {
6253   const struct savestate_block *p1 = p1_, *p2 = p2_;
6254   return p1->addr - p2->addr;
6255 }
6256
6257 int new_dynarec_save_blocks(void *save, int size)
6258 {
6259   struct savestate_block *sblocks = save;
6260   int maxcount = size / sizeof(sblocks[0]);
6261   struct savestate_block tmp_blocks[1024];
6262   struct block_info *block;
6263   int p, s, d, o, bcnt;
6264   u_int addr;
6265
6266   o = 0;
6267   for (p = 0; p < ARRAY_SIZE(blocks); p++) {
6268     bcnt = 0;
6269     for (block = blocks[p]; block != NULL; block = block->next) {
6270       if (block->is_dirty)
6271         continue;
6272       tmp_blocks[bcnt].addr = block->start;
6273       tmp_blocks[bcnt].regflags = block->reg_sv_flags;
6274       bcnt++;
6275     }
6276     if (bcnt < 1)
6277       continue;
6278     qsort(tmp_blocks, bcnt, sizeof(tmp_blocks[0]), addr_cmp);
6279
6280     addr = tmp_blocks[0].addr;
6281     for (s = d = 0; s < bcnt; s++) {
6282       if (tmp_blocks[s].addr < addr)
6283         continue;
6284       if (d == 0 || tmp_blocks[d-1].addr != tmp_blocks[s].addr)
6285         tmp_blocks[d++] = tmp_blocks[s];
6286       addr = scan_for_ret(tmp_blocks[s].addr);
6287     }
6288
6289     if (o + d > maxcount)
6290       d = maxcount - o;
6291     memcpy(&sblocks[o], tmp_blocks, d * sizeof(sblocks[0]));
6292     o += d;
6293   }
6294
6295   return o * sizeof(sblocks[0]);
6296 }
6297
6298 void new_dynarec_load_blocks(const void *save, int size)
6299 {
6300   const struct savestate_block *sblocks = save;
6301   int count = size / sizeof(sblocks[0]);
6302   struct block_info *block;
6303   u_int regs_save[32];
6304   u_int page;
6305   uint32_t f;
6306   int i, b;
6307
6308   // restore clean blocks, if any
6309   for (page = 0, b = i = 0; page < ARRAY_SIZE(blocks); page++) {
6310     for (block = blocks[page]; block != NULL; block = block->next, b++) {
6311       if (!block->is_dirty)
6312         continue;
6313       assert(block->source && block->copy);
6314       if (memcmp(block->source, block->copy, block->len))
6315         continue;
6316
6317       // see try_restore_block
6318       block->is_dirty = 0;
6319       mark_invalid_code(block->start, block->len, 0);
6320       i++;
6321     }
6322   }
6323   inv_debug("load_blocks: %d/%d clean blocks\n", i, b);
6324
6325   // change GPRs for speculation to at least partially work..
6326   memcpy(regs_save, &psxRegs.GPR, sizeof(regs_save));
6327   for (i = 1; i < 32; i++)
6328     psxRegs.GPR.r[i] = 0x80000000;
6329
6330   for (b = 0; b < count; b++) {
6331     for (f = sblocks[b].regflags, i = 0; f; f >>= 1, i++) {
6332       if (f & 1)
6333         psxRegs.GPR.r[i] = 0x1f800000;
6334     }
6335
6336     ndrc_get_addr_ht(sblocks[b].addr);
6337
6338     for (f = sblocks[b].regflags, i = 0; f; f >>= 1, i++) {
6339       if (f & 1)
6340         psxRegs.GPR.r[i] = 0x80000000;
6341     }
6342   }
6343
6344   memcpy(&psxRegs.GPR, regs_save, sizeof(regs_save));
6345 }
6346
6347 void new_dynarec_print_stats(void)
6348 {
6349 #ifdef STAT_PRINT
6350   printf("cc %3d,%3d,%3d lu%6d,%3d,%3d c%3d inv%3d,%3d tc_offs %zu b %u,%u\n",
6351     stat_bc_pre, stat_bc_direct, stat_bc_restore,
6352     stat_ht_lookups, stat_jump_in_lookups, stat_restore_tries,
6353     stat_restore_compares, stat_inv_addr_calls, stat_inv_hits,
6354     out - ndrc->translation_cache, stat_blocks, stat_links);
6355   stat_bc_direct = stat_bc_pre = stat_bc_restore =
6356   stat_ht_lookups = stat_jump_in_lookups = stat_restore_tries =
6357   stat_restore_compares = stat_inv_addr_calls = stat_inv_hits = 0;
6358 #endif
6359 }
6360
6361 static int apply_hacks(void)
6362 {
6363   int i;
6364   if (HACK_ENABLED(NDHACK_NO_COMPAT_HACKS))
6365     return 0;
6366   /* special hack(s) */
6367   for (i = 0; i < slen - 4; i++)
6368   {
6369     // lui a4, 0xf200; jal <rcnt_read>; addu a0, 2; slti v0, 28224
6370     if (source[i] == 0x3c04f200 && dops[i+1].itype == UJUMP
6371         && source[i+2] == 0x34840002 && dops[i+3].opcode == 0x0a
6372         && imm[i+3] == 0x6e40 && dops[i+3].rs1 == 2)
6373     {
6374       SysPrintf("PE2 hack @%08x\n", start + (i+3)*4);
6375       dops[i + 3].itype = NOP;
6376     }
6377   }
6378   i = slen;
6379   if (i > 10 && source[i-1] == 0 && source[i-2] == 0x03e00008
6380       && source[i-4] == 0x8fbf0018 && source[i-6] == 0x00c0f809
6381       && dops[i-7].itype == STORE)
6382   {
6383     i = i-8;
6384     if (dops[i].itype == IMM16)
6385       i--;
6386     // swl r2, 15(r6); swr r2, 12(r6); sw r6, *; jalr r6
6387     if (dops[i].itype == STORELR && dops[i].rs1 == 6
6388       && dops[i-1].itype == STORELR && dops[i-1].rs1 == 6)
6389     {
6390       SysPrintf("F1 hack from %08x, old dst %08x\n", start, hack_addr);
6391       f1_hack = 1;
6392       return 1;
6393     }
6394   }
6395   return 0;
6396 }
6397
6398 static noinline void pass1_disassemble(u_int pagelimit)
6399 {
6400   int i, j, done = 0, ni_count = 0;
6401   unsigned int type,op,op2;
6402
6403   for (i = 0; !done; i++)
6404   {
6405     memset(&dops[i], 0, sizeof(dops[i]));
6406     op2=0;
6407     minimum_free_regs[i]=0;
6408     dops[i].opcode=op=source[i]>>26;
6409     switch(op)
6410     {
6411       case 0x00: set_mnemonic(i, "special"); type=NI;
6412         op2=source[i]&0x3f;
6413         switch(op2)
6414         {
6415           case 0x00: set_mnemonic(i, "SLL"); type=SHIFTIMM; break;
6416           case 0x02: set_mnemonic(i, "SRL"); type=SHIFTIMM; break;
6417           case 0x03: set_mnemonic(i, "SRA"); type=SHIFTIMM; break;
6418           case 0x04: set_mnemonic(i, "SLLV"); type=SHIFT; break;
6419           case 0x06: set_mnemonic(i, "SRLV"); type=SHIFT; break;
6420           case 0x07: set_mnemonic(i, "SRAV"); type=SHIFT; break;
6421           case 0x08: set_mnemonic(i, "JR"); type=RJUMP; break;
6422           case 0x09: set_mnemonic(i, "JALR"); type=RJUMP; break;
6423           case 0x0C: set_mnemonic(i, "SYSCALL"); type=SYSCALL; break;
6424           case 0x0D: set_mnemonic(i, "BREAK"); type=SYSCALL; break;
6425           case 0x0F: set_mnemonic(i, "SYNC"); type=OTHER; break;
6426           case 0x10: set_mnemonic(i, "MFHI"); type=MOV; break;
6427           case 0x11: set_mnemonic(i, "MTHI"); type=MOV; break;
6428           case 0x12: set_mnemonic(i, "MFLO"); type=MOV; break;
6429           case 0x13: set_mnemonic(i, "MTLO"); type=MOV; break;
6430           case 0x18: set_mnemonic(i, "MULT"); type=MULTDIV; break;
6431           case 0x19: set_mnemonic(i, "MULTU"); type=MULTDIV; break;
6432           case 0x1A: set_mnemonic(i, "DIV"); type=MULTDIV; break;
6433           case 0x1B: set_mnemonic(i, "DIVU"); type=MULTDIV; break;
6434           case 0x20: set_mnemonic(i, "ADD"); type=ALU; break;
6435           case 0x21: set_mnemonic(i, "ADDU"); type=ALU; break;
6436           case 0x22: set_mnemonic(i, "SUB"); type=ALU; break;
6437           case 0x23: set_mnemonic(i, "SUBU"); type=ALU; break;
6438           case 0x24: set_mnemonic(i, "AND"); type=ALU; break;
6439           case 0x25: set_mnemonic(i, "OR"); type=ALU; break;
6440           case 0x26: set_mnemonic(i, "XOR"); type=ALU; break;
6441           case 0x27: set_mnemonic(i, "NOR"); type=ALU; break;
6442           case 0x2A: set_mnemonic(i, "SLT"); type=ALU; break;
6443           case 0x2B: set_mnemonic(i, "SLTU"); type=ALU; break;
6444           case 0x30: set_mnemonic(i, "TGE"); type=NI; break;
6445           case 0x31: set_mnemonic(i, "TGEU"); type=NI; break;
6446           case 0x32: set_mnemonic(i, "TLT"); type=NI; break;
6447           case 0x33: set_mnemonic(i, "TLTU"); type=NI; break;
6448           case 0x34: set_mnemonic(i, "TEQ"); type=NI; break;
6449           case 0x36: set_mnemonic(i, "TNE"); type=NI; break;
6450 #if 0
6451           case 0x14: set_mnemonic(i, "DSLLV"); type=SHIFT; break;
6452           case 0x16: set_mnemonic(i, "DSRLV"); type=SHIFT; break;
6453           case 0x17: set_mnemonic(i, "DSRAV"); type=SHIFT; break;
6454           case 0x1C: set_mnemonic(i, "DMULT"); type=MULTDIV; break;
6455           case 0x1D: set_mnemonic(i, "DMULTU"); type=MULTDIV; break;
6456           case 0x1E: set_mnemonic(i, "DDIV"); type=MULTDIV; break;
6457           case 0x1F: set_mnemonic(i, "DDIVU"); type=MULTDIV; break;
6458           case 0x2C: set_mnemonic(i, "DADD"); type=ALU; break;
6459           case 0x2D: set_mnemonic(i, "DADDU"); type=ALU; break;
6460           case 0x2E: set_mnemonic(i, "DSUB"); type=ALU; break;
6461           case 0x2F: set_mnemonic(i, "DSUBU"); type=ALU; break;
6462           case 0x38: set_mnemonic(i, "DSLL"); type=SHIFTIMM; break;
6463           case 0x3A: set_mnemonic(i, "DSRL"); type=SHIFTIMM; break;
6464           case 0x3B: set_mnemonic(i, "DSRA"); type=SHIFTIMM; break;
6465           case 0x3C: set_mnemonic(i, "DSLL32"); type=SHIFTIMM; break;
6466           case 0x3E: set_mnemonic(i, "DSRL32"); type=SHIFTIMM; break;
6467           case 0x3F: set_mnemonic(i, "DSRA32"); type=SHIFTIMM; break;
6468 #endif
6469         }
6470         break;
6471       case 0x01: set_mnemonic(i, "regimm"); type=NI;
6472         op2=(source[i]>>16)&0x1f;
6473         switch(op2)
6474         {
6475           case 0x00: set_mnemonic(i, "BLTZ"); type=SJUMP; break;
6476           case 0x01: set_mnemonic(i, "BGEZ"); type=SJUMP; break;
6477           //case 0x02: set_mnemonic(i, "BLTZL"); type=SJUMP; break;
6478           //case 0x03: set_mnemonic(i, "BGEZL"); type=SJUMP; break;
6479           //case 0x08: set_mnemonic(i, "TGEI"); type=NI; break;
6480           //case 0x09: set_mnemonic(i, "TGEIU"); type=NI; break;
6481           //case 0x0A: set_mnemonic(i, "TLTI"); type=NI; break;
6482           //case 0x0B: set_mnemonic(i, "TLTIU"); type=NI; break;
6483           //case 0x0C: set_mnemonic(i, "TEQI"); type=NI; break;
6484           //case 0x0E: set_mnemonic(i, "TNEI"); type=NI; break;
6485           case 0x10: set_mnemonic(i, "BLTZAL"); type=SJUMP; break;
6486           case 0x11: set_mnemonic(i, "BGEZAL"); type=SJUMP; break;
6487           //case 0x12: set_mnemonic(i, "BLTZALL"); type=SJUMP; break;
6488           //case 0x13: set_mnemonic(i, "BGEZALL"); type=SJUMP; break;
6489         }
6490         break;
6491       case 0x02: set_mnemonic(i, "J"); type=UJUMP; break;
6492       case 0x03: set_mnemonic(i, "JAL"); type=UJUMP; break;
6493       case 0x04: set_mnemonic(i, "BEQ"); type=CJUMP; break;
6494       case 0x05: set_mnemonic(i, "BNE"); type=CJUMP; break;
6495       case 0x06: set_mnemonic(i, "BLEZ"); type=CJUMP; break;
6496       case 0x07: set_mnemonic(i, "BGTZ"); type=CJUMP; break;
6497       case 0x08: set_mnemonic(i, "ADDI"); type=IMM16; break;
6498       case 0x09: set_mnemonic(i, "ADDIU"); type=IMM16; break;
6499       case 0x0A: set_mnemonic(i, "SLTI"); type=IMM16; break;
6500       case 0x0B: set_mnemonic(i, "SLTIU"); type=IMM16; break;
6501       case 0x0C: set_mnemonic(i, "ANDI"); type=IMM16; break;
6502       case 0x0D: set_mnemonic(i, "ORI"); type=IMM16; break;
6503       case 0x0E: set_mnemonic(i, "XORI"); type=IMM16; break;
6504       case 0x0F: set_mnemonic(i, "LUI"); type=IMM16; break;
6505       case 0x10: set_mnemonic(i, "cop0"); type=NI;
6506         op2=(source[i]>>21)&0x1f;
6507         switch(op2)
6508         {
6509           case 0x00: set_mnemonic(i, "MFC0"); type=COP0; break;
6510           case 0x02: set_mnemonic(i, "CFC0"); type=COP0; break;
6511           case 0x04: set_mnemonic(i, "MTC0"); type=COP0; break;
6512           case 0x06: set_mnemonic(i, "CTC0"); type=COP0; break;
6513           case 0x10: set_mnemonic(i, "RFE"); type=COP0; break;
6514         }
6515         break;
6516       case 0x11: set_mnemonic(i, "cop1"); type=COP1;
6517         op2=(source[i]>>21)&0x1f;
6518         break;
6519 #if 0
6520       case 0x14: set_mnemonic(i, "BEQL"); type=CJUMP; break;
6521       case 0x15: set_mnemonic(i, "BNEL"); type=CJUMP; break;
6522       case 0x16: set_mnemonic(i, "BLEZL"); type=CJUMP; break;
6523       case 0x17: set_mnemonic(i, "BGTZL"); type=CJUMP; break;
6524       case 0x18: set_mnemonic(i, "DADDI"); type=IMM16; break;
6525       case 0x19: set_mnemonic(i, "DADDIU"); type=IMM16; break;
6526       case 0x1A: set_mnemonic(i, "LDL"); type=LOADLR; break;
6527       case 0x1B: set_mnemonic(i, "LDR"); type=LOADLR; break;
6528 #endif
6529       case 0x20: set_mnemonic(i, "LB"); type=LOAD; break;
6530       case 0x21: set_mnemonic(i, "LH"); type=LOAD; break;
6531       case 0x22: set_mnemonic(i, "LWL"); type=LOADLR; break;
6532       case 0x23: set_mnemonic(i, "LW"); type=LOAD; break;
6533       case 0x24: set_mnemonic(i, "LBU"); type=LOAD; break;
6534       case 0x25: set_mnemonic(i, "LHU"); type=LOAD; break;
6535       case 0x26: set_mnemonic(i, "LWR"); type=LOADLR; break;
6536 #if 0
6537       case 0x27: set_mnemonic(i, "LWU"); type=LOAD; break;
6538 #endif
6539       case 0x28: set_mnemonic(i, "SB"); type=STORE; break;
6540       case 0x29: set_mnemonic(i, "SH"); type=STORE; break;
6541       case 0x2A: set_mnemonic(i, "SWL"); type=STORELR; break;
6542       case 0x2B: set_mnemonic(i, "SW"); type=STORE; break;
6543 #if 0
6544       case 0x2C: set_mnemonic(i, "SDL"); type=STORELR; break;
6545       case 0x2D: set_mnemonic(i, "SDR"); type=STORELR; break;
6546 #endif
6547       case 0x2E: set_mnemonic(i, "SWR"); type=STORELR; break;
6548       case 0x2F: set_mnemonic(i, "CACHE"); type=NOP; break;
6549       case 0x30: set_mnemonic(i, "LL"); type=NI; break;
6550       case 0x31: set_mnemonic(i, "LWC1"); type=C1LS; break;
6551 #if 0
6552       case 0x34: set_mnemonic(i, "LLD"); type=NI; break;
6553       case 0x35: set_mnemonic(i, "LDC1"); type=C1LS; break;
6554       case 0x37: set_mnemonic(i, "LD"); type=LOAD; break;
6555 #endif
6556       case 0x38: set_mnemonic(i, "SC"); type=NI; break;
6557       case 0x39: set_mnemonic(i, "SWC1"); type=C1LS; break;
6558 #if 0
6559       case 0x3C: set_mnemonic(i, "SCD"); type=NI; break;
6560       case 0x3D: set_mnemonic(i, "SDC1"); type=C1LS; break;
6561       case 0x3F: set_mnemonic(i, "SD"); type=STORE; break;
6562 #endif
6563       case 0x12: set_mnemonic(i, "COP2"); type=NI;
6564         op2=(source[i]>>21)&0x1f;
6565         //if (op2 & 0x10)
6566         if (source[i]&0x3f) { // use this hack to support old savestates with patched gte insns
6567           if (gte_handlers[source[i]&0x3f]!=NULL) {
6568 #ifdef DISASM
6569             if (gte_regnames[source[i]&0x3f]!=NULL)
6570               strcpy(insn[i],gte_regnames[source[i]&0x3f]);
6571             else
6572               snprintf(insn[i], sizeof(insn[i]), "COP2 %x", source[i]&0x3f);
6573 #endif
6574             type=C2OP;
6575           }
6576         }
6577         else switch(op2)
6578         {
6579           case 0x00: set_mnemonic(i, "MFC2"); type=COP2; break;
6580           case 0x02: set_mnemonic(i, "CFC2"); type=COP2; break;
6581           case 0x04: set_mnemonic(i, "MTC2"); type=COP2; break;
6582           case 0x06: set_mnemonic(i, "CTC2"); type=COP2; break;
6583         }
6584         break;
6585       case 0x32: set_mnemonic(i, "LWC2"); type=C2LS; break;
6586       case 0x3A: set_mnemonic(i, "SWC2"); type=C2LS; break;
6587       case 0x3B: set_mnemonic(i, "HLECALL"); type=HLECALL; break;
6588       default: set_mnemonic(i, "???"); type=NI;
6589         SysPrintf("NI %08x @%08x (%08x)\n", source[i], start + i*4, start);
6590         break;
6591     }
6592     dops[i].itype=type;
6593     dops[i].opcode2=op2;
6594     /* Get registers/immediates */
6595     dops[i].use_lt1=0;
6596     gte_rs[i]=gte_rt[i]=0;
6597     switch(type) {
6598       case LOAD:
6599         dops[i].rs1=(source[i]>>21)&0x1f;
6600         dops[i].rs2=0;
6601         dops[i].rt1=(source[i]>>16)&0x1f;
6602         dops[i].rt2=0;
6603         imm[i]=(short)source[i];
6604         break;
6605       case STORE:
6606       case STORELR:
6607         dops[i].rs1=(source[i]>>21)&0x1f;
6608         dops[i].rs2=(source[i]>>16)&0x1f;
6609         dops[i].rt1=0;
6610         dops[i].rt2=0;
6611         imm[i]=(short)source[i];
6612         break;
6613       case LOADLR:
6614         // LWL/LWR only load part of the register,
6615         // therefore the target register must be treated as a source too
6616         dops[i].rs1=(source[i]>>21)&0x1f;
6617         dops[i].rs2=(source[i]>>16)&0x1f;
6618         dops[i].rt1=(source[i]>>16)&0x1f;
6619         dops[i].rt2=0;
6620         imm[i]=(short)source[i];
6621         break;
6622       case IMM16:
6623         if (op==0x0f) dops[i].rs1=0; // LUI instruction has no source register
6624         else dops[i].rs1=(source[i]>>21)&0x1f;
6625         dops[i].rs2=0;
6626         dops[i].rt1=(source[i]>>16)&0x1f;
6627         dops[i].rt2=0;
6628         if(op>=0x0c&&op<=0x0e) { // ANDI/ORI/XORI
6629           imm[i]=(unsigned short)source[i];
6630         }else{
6631           imm[i]=(short)source[i];
6632         }
6633         break;
6634       case UJUMP:
6635         dops[i].rs1=0;
6636         dops[i].rs2=0;
6637         dops[i].rt1=0;
6638         dops[i].rt2=0;
6639         // The JAL instruction writes to r31.
6640         if (op&1) {
6641           dops[i].rt1=31;
6642         }
6643         dops[i].rs2=CCREG;
6644         break;
6645       case RJUMP:
6646         dops[i].rs1=(source[i]>>21)&0x1f;
6647         dops[i].rs2=0;
6648         dops[i].rt1=0;
6649         dops[i].rt2=0;
6650         // The JALR instruction writes to rd.
6651         if (op2&1) {
6652           dops[i].rt1=(source[i]>>11)&0x1f;
6653         }
6654         dops[i].rs2=CCREG;
6655         break;
6656       case CJUMP:
6657         dops[i].rs1=(source[i]>>21)&0x1f;
6658         dops[i].rs2=(source[i]>>16)&0x1f;
6659         dops[i].rt1=0;
6660         dops[i].rt2=0;
6661         if(op&2) { // BGTZ/BLEZ
6662           dops[i].rs2=0;
6663         }
6664         break;
6665       case SJUMP:
6666         dops[i].rs1=(source[i]>>21)&0x1f;
6667         dops[i].rs2=CCREG;
6668         dops[i].rt1=0;
6669         dops[i].rt2=0;
6670         if(op2&0x10) { // BxxAL
6671           dops[i].rt1=31;
6672           // NOTE: If the branch is not taken, r31 is still overwritten
6673         }
6674         break;
6675       case ALU:
6676         dops[i].rs1=(source[i]>>21)&0x1f; // source
6677         dops[i].rs2=(source[i]>>16)&0x1f; // subtract amount
6678         dops[i].rt1=(source[i]>>11)&0x1f; // destination
6679         dops[i].rt2=0;
6680         break;
6681       case MULTDIV:
6682         dops[i].rs1=(source[i]>>21)&0x1f; // source
6683         dops[i].rs2=(source[i]>>16)&0x1f; // divisor
6684         dops[i].rt1=HIREG;
6685         dops[i].rt2=LOREG;
6686         break;
6687       case MOV:
6688         dops[i].rs1=0;
6689         dops[i].rs2=0;
6690         dops[i].rt1=0;
6691         dops[i].rt2=0;
6692         if(op2==0x10) dops[i].rs1=HIREG; // MFHI
6693         if(op2==0x11) dops[i].rt1=HIREG; // MTHI
6694         if(op2==0x12) dops[i].rs1=LOREG; // MFLO
6695         if(op2==0x13) dops[i].rt1=LOREG; // MTLO
6696         if((op2&0x1d)==0x10) dops[i].rt1=(source[i]>>11)&0x1f; // MFxx
6697         if((op2&0x1d)==0x11) dops[i].rs1=(source[i]>>21)&0x1f; // MTxx
6698         break;
6699       case SHIFT:
6700         dops[i].rs1=(source[i]>>16)&0x1f; // target of shift
6701         dops[i].rs2=(source[i]>>21)&0x1f; // shift amount
6702         dops[i].rt1=(source[i]>>11)&0x1f; // destination
6703         dops[i].rt2=0;
6704         break;
6705       case SHIFTIMM:
6706         dops[i].rs1=(source[i]>>16)&0x1f;
6707         dops[i].rs2=0;
6708         dops[i].rt1=(source[i]>>11)&0x1f;
6709         dops[i].rt2=0;
6710         imm[i]=(source[i]>>6)&0x1f;
6711         // DSxx32 instructions
6712         if(op2>=0x3c) imm[i]|=0x20;
6713         break;
6714       case COP0:
6715         dops[i].rs1=0;
6716         dops[i].rs2=0;
6717         dops[i].rt1=0;
6718         dops[i].rt2=0;
6719         if(op2==0||op2==2) dops[i].rt1=(source[i]>>16)&0x1F; // MFC0/CFC0
6720         if(op2==4||op2==6) dops[i].rs1=(source[i]>>16)&0x1F; // MTC0/CTC0
6721         if(op2==4&&((source[i]>>11)&0x1f)==12) dops[i].rt2=CSREG; // Status
6722         if(op2==16) if((source[i]&0x3f)==0x18) dops[i].rs2=CCREG; // ERET
6723         break;
6724       case COP1:
6725         dops[i].rs1=0;
6726         dops[i].rs2=0;
6727         dops[i].rt1=0;
6728         dops[i].rt2=0;
6729         if(op2<3) dops[i].rt1=(source[i]>>16)&0x1F; // MFC1/DMFC1/CFC1
6730         if(op2>3) dops[i].rs1=(source[i]>>16)&0x1F; // MTC1/DMTC1/CTC1
6731         dops[i].rs2=CSREG;
6732         break;
6733       case COP2:
6734         dops[i].rs1=0;
6735         dops[i].rs2=0;
6736         dops[i].rt1=0;
6737         dops[i].rt2=0;
6738         if(op2<3) dops[i].rt1=(source[i]>>16)&0x1F; // MFC2/CFC2
6739         if(op2>3) dops[i].rs1=(source[i]>>16)&0x1F; // MTC2/CTC2
6740         dops[i].rs2=CSREG;
6741         int gr=(source[i]>>11)&0x1F;
6742         switch(op2)
6743         {
6744           case 0x00: gte_rs[i]=1ll<<gr; break; // MFC2
6745           case 0x04: gte_rt[i]=1ll<<gr; break; // MTC2
6746           case 0x02: gte_rs[i]=1ll<<(gr+32); break; // CFC2
6747           case 0x06: gte_rt[i]=1ll<<(gr+32); break; // CTC2
6748         }
6749         break;
6750       case C1LS:
6751         dops[i].rs1=(source[i]>>21)&0x1F;
6752         dops[i].rs2=CSREG;
6753         dops[i].rt1=0;
6754         dops[i].rt2=0;
6755         imm[i]=(short)source[i];
6756         break;
6757       case C2LS:
6758         dops[i].rs1=(source[i]>>21)&0x1F;
6759         dops[i].rs2=0;
6760         dops[i].rt1=0;
6761         dops[i].rt2=0;
6762         imm[i]=(short)source[i];
6763         if(op==0x32) gte_rt[i]=1ll<<((source[i]>>16)&0x1F); // LWC2
6764         else gte_rs[i]=1ll<<((source[i]>>16)&0x1F); // SWC2
6765         break;
6766       case C2OP:
6767         dops[i].rs1=0;
6768         dops[i].rs2=0;
6769         dops[i].rt1=0;
6770         dops[i].rt2=0;
6771         gte_rs[i]=gte_reg_reads[source[i]&0x3f];
6772         gte_rt[i]=gte_reg_writes[source[i]&0x3f];
6773         gte_rt[i]|=1ll<<63; // every op changes flags
6774         if((source[i]&0x3f)==GTE_MVMVA) {
6775           int v = (source[i] >> 15) & 3;
6776           gte_rs[i]&=~0xe3fll;
6777           if(v==3) gte_rs[i]|=0xe00ll;
6778           else gte_rs[i]|=3ll<<(v*2);
6779         }
6780         break;
6781       case SYSCALL:
6782       case HLECALL:
6783       case INTCALL:
6784         dops[i].rs1=CCREG;
6785         dops[i].rs2=0;
6786         dops[i].rt1=0;
6787         dops[i].rt2=0;
6788         break;
6789       default:
6790         dops[i].rs1=0;
6791         dops[i].rs2=0;
6792         dops[i].rt1=0;
6793         dops[i].rt2=0;
6794     }
6795     /* Calculate branch target addresses */
6796     if(type==UJUMP)
6797       ba[i]=((start+i*4+4)&0xF0000000)|(((unsigned int)source[i]<<6)>>4);
6798     else if(type==CJUMP&&dops[i].rs1==dops[i].rs2&&(op&1))
6799       ba[i]=start+i*4+8; // Ignore never taken branch
6800     else if(type==SJUMP&&dops[i].rs1==0&&!(op2&1))
6801       ba[i]=start+i*4+8; // Ignore never taken branch
6802     else if(type==CJUMP||type==SJUMP)
6803       ba[i]=start+i*4+4+((signed int)((unsigned int)source[i]<<16)>>14);
6804     else ba[i]=-1;
6805
6806     /* simplify always (not)taken branches */
6807     if (type == CJUMP && dops[i].rs1 == dops[i].rs2) {
6808       dops[i].rs1 = dops[i].rs2 = 0;
6809       if (!(op & 1)) {
6810         dops[i].itype = type = UJUMP;
6811         dops[i].rs2 = CCREG;
6812       }
6813     }
6814     else if (type == SJUMP && dops[i].rs1 == 0 && (op2 & 1))
6815       dops[i].itype = type = UJUMP;
6816
6817     dops[i].is_jump = (dops[i].itype == RJUMP || dops[i].itype == UJUMP || dops[i].itype == CJUMP || dops[i].itype == SJUMP);
6818     dops[i].is_ujump = (dops[i].itype == RJUMP || dops[i].itype == UJUMP); // || (source[i] >> 16) == 0x1000 // beq r0,r0
6819     dops[i].is_load = (dops[i].itype == LOAD || dops[i].itype == LOADLR || op == 0x32); // LWC2
6820     dops[i].is_store = (dops[i].itype == STORE || dops[i].itype == STORELR || op == 0x3a); // SWC2
6821
6822     /* messy cases to just pass over to the interpreter */
6823     if (i > 0 && dops[i-1].is_jump) {
6824       int do_in_intrp=0;
6825       // branch in delay slot?
6826       if (dops[i].is_jump) {
6827         // don't handle first branch and call interpreter if it's hit
6828         SysPrintf("branch in delay slot @%08x (%08x)\n", start + i*4, start);
6829         do_in_intrp=1;
6830       }
6831       // basic load delay detection
6832       else if((type==LOAD||type==LOADLR||type==COP0||type==COP2||type==C2LS)&&dops[i].rt1!=0) {
6833         int t=(ba[i-1]-start)/4;
6834         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) {
6835           // jump target wants DS result - potential load delay effect
6836           SysPrintf("load delay @%08x (%08x)\n", start + i*4, start);
6837           do_in_intrp=1;
6838           dops[t+1].bt=1; // expected return from interpreter
6839         }
6840         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&&
6841               !(i>=3&&dops[i-3].is_jump)) {
6842           // v0 overwrite like this is a sign of trouble, bail out
6843           SysPrintf("v0 overwrite @%08x (%08x)\n", start + i*4, start);
6844           do_in_intrp=1;
6845         }
6846       }
6847       if (do_in_intrp) {
6848         memset(&dops[i-1], 0, sizeof(dops[i-1]));
6849         dops[i-1].itype = INTCALL;
6850         dops[i-1].rs1 = CCREG;
6851         ba[i-1] = -1;
6852         done = 2;
6853         i--; // don't compile the DS
6854       }
6855     }
6856
6857     /* Is this the end of the block? */
6858     if (i > 0 && dops[i-1].is_ujump) {
6859       if (dops[i-1].rt1 == 0) { // not jal
6860         int found_bbranch = 0, t = (ba[i-1] - start) / 4;
6861         if ((u_int)(t - i) < 64 && start + (t+64)*4 < pagelimit) {
6862           // scan for a branch back to i+1
6863           for (j = t; j < t + 64; j++) {
6864             int tmpop = source[j] >> 26;
6865             if (tmpop == 1 || ((tmpop & ~3) == 4)) {
6866               int t2 = j + 1 + (int)(signed short)source[j];
6867               if (t2 == i + 1) {
6868                 //printf("blk expand %08x<-%08x\n", start + (i+1)*4, start + j*4);
6869                 found_bbranch = 1;
6870                 break;
6871               }
6872             }
6873           }
6874         }
6875         if (!found_bbranch)
6876           done = 2;
6877       }
6878       else {
6879         if(stop_after_jal) done=1;
6880         // Stop on BREAK
6881         if((source[i+1]&0xfc00003f)==0x0d) done=1;
6882       }
6883       // Don't recompile stuff that's already compiled
6884       if(check_addr(start+i*4+4)) done=1;
6885       // Don't get too close to the limit
6886       if(i>MAXBLOCK/2) done=1;
6887     }
6888     if (dops[i].itype == SYSCALL || dops[i].itype == HLECALL || dops[i].itype == INTCALL)
6889       done = stop_after_jal ? 1 : 2;
6890     if (done == 2) {
6891       // Does the block continue due to a branch?
6892       for(j=i-1;j>=0;j--)
6893       {
6894         if(ba[j]==start+i*4) done=j=0; // Branch into delay slot
6895         if(ba[j]==start+i*4+4) done=j=0;
6896         if(ba[j]==start+i*4+8) done=j=0;
6897       }
6898     }
6899     //assert(i<MAXBLOCK-1);
6900     if(start+i*4==pagelimit-4) done=1;
6901     assert(start+i*4<pagelimit);
6902     if (i==MAXBLOCK-1) done=1;
6903     // Stop if we're compiling junk
6904     if(dops[i].itype == NI && (++ni_count > 8 || dops[i].opcode == 0x11)) {
6905       done=stop_after_jal=1;
6906       SysPrintf("Disabled speculative precompilation\n");
6907     }
6908   }
6909   while (i > 0 && dops[i-1].is_jump)
6910     i--;
6911   assert(i > 0);
6912   assert(!dops[i-1].is_jump);
6913   slen = i;
6914 }
6915
6916 // Basic liveness analysis for MIPS registers
6917 static noinline void pass2_unneeded_regs(int istart,int iend,int r)
6918 {
6919   int i;
6920   uint64_t u,gte_u,b,gte_b;
6921   uint64_t temp_u,temp_gte_u=0;
6922   uint64_t gte_u_unknown=0;
6923   if (HACK_ENABLED(NDHACK_GTE_UNNEEDED))
6924     gte_u_unknown=~0ll;
6925   if(iend==slen-1) {
6926     u=1;
6927     gte_u=gte_u_unknown;
6928   }else{
6929     //u=unneeded_reg[iend+1];
6930     u=1;
6931     gte_u=gte_unneeded[iend+1];
6932   }
6933
6934   for (i=iend;i>=istart;i--)
6935   {
6936     //printf("unneeded registers i=%d (%d,%d) r=%d\n",i,istart,iend,r);
6937     if(dops[i].is_jump)
6938     {
6939       // If subroutine call, flag return address as a possible branch target
6940       if(dops[i].rt1==31 && i<slen-2) dops[i+2].bt=1;
6941
6942       if(ba[i]<start || ba[i]>=(start+slen*4))
6943       {
6944         // Branch out of this block, flush all regs
6945         u=1;
6946         gte_u=gte_u_unknown;
6947         branch_unneeded_reg[i]=u;
6948         // Merge in delay slot
6949         u|=(1LL<<dops[i+1].rt1)|(1LL<<dops[i+1].rt2);
6950         u&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
6951         u|=1;
6952         gte_u|=gte_rt[i+1];
6953         gte_u&=~gte_rs[i+1];
6954       }
6955       else
6956       {
6957         // Internal branch, flag target
6958         dops[(ba[i]-start)>>2].bt=1;
6959         if(ba[i]<=start+i*4) {
6960           // Backward branch
6961           if(dops[i].is_ujump)
6962           {
6963             // Unconditional branch
6964             temp_u=1;
6965             temp_gte_u=0;
6966           } else {
6967             // Conditional branch (not taken case)
6968             temp_u=unneeded_reg[i+2];
6969             temp_gte_u&=gte_unneeded[i+2];
6970           }
6971           // Merge in delay slot
6972           temp_u|=(1LL<<dops[i+1].rt1)|(1LL<<dops[i+1].rt2);
6973           temp_u&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
6974           temp_u|=1;
6975           temp_gte_u|=gte_rt[i+1];
6976           temp_gte_u&=~gte_rs[i+1];
6977           temp_u|=(1LL<<dops[i].rt1)|(1LL<<dops[i].rt2);
6978           temp_u&=~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
6979           temp_u|=1;
6980           temp_gte_u|=gte_rt[i];
6981           temp_gte_u&=~gte_rs[i];
6982           unneeded_reg[i]=temp_u;
6983           gte_unneeded[i]=temp_gte_u;
6984           // Only go three levels deep.  This recursion can take an
6985           // excessive amount of time if there are a lot of nested loops.
6986           if(r<2) {
6987             pass2_unneeded_regs((ba[i]-start)>>2,i-1,r+1);
6988           }else{
6989             unneeded_reg[(ba[i]-start)>>2]=1;
6990             gte_unneeded[(ba[i]-start)>>2]=gte_u_unknown;
6991           }
6992         } /*else*/ if(1) {
6993           if (dops[i].is_ujump)
6994           {
6995             // Unconditional branch
6996             u=unneeded_reg[(ba[i]-start)>>2];
6997             gte_u=gte_unneeded[(ba[i]-start)>>2];
6998             branch_unneeded_reg[i]=u;
6999             // Merge in delay slot
7000             u|=(1LL<<dops[i+1].rt1)|(1LL<<dops[i+1].rt2);
7001             u&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
7002             u|=1;
7003             gte_u|=gte_rt[i+1];
7004             gte_u&=~gte_rs[i+1];
7005           } else {
7006             // Conditional branch
7007             b=unneeded_reg[(ba[i]-start)>>2];
7008             gte_b=gte_unneeded[(ba[i]-start)>>2];
7009             branch_unneeded_reg[i]=b;
7010             // Branch delay slot
7011             b|=(1LL<<dops[i+1].rt1)|(1LL<<dops[i+1].rt2);
7012             b&=~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
7013             b|=1;
7014             gte_b|=gte_rt[i+1];
7015             gte_b&=~gte_rs[i+1];
7016             u&=b;
7017             gte_u&=gte_b;
7018             if(i<slen-1) {
7019               branch_unneeded_reg[i]&=unneeded_reg[i+2];
7020             } else {
7021               branch_unneeded_reg[i]=1;
7022             }
7023           }
7024         }
7025       }
7026     }
7027     else if(dops[i].itype==SYSCALL||dops[i].itype==HLECALL||dops[i].itype==INTCALL)
7028     {
7029       // SYSCALL instruction (software interrupt)
7030       u=1;
7031     }
7032     else if(dops[i].itype==COP0 && (source[i]&0x3f)==0x18)
7033     {
7034       // ERET instruction (return from interrupt)
7035       u=1;
7036     }
7037     //u=1; // DEBUG
7038     // Written registers are unneeded
7039     u|=1LL<<dops[i].rt1;
7040     u|=1LL<<dops[i].rt2;
7041     gte_u|=gte_rt[i];
7042     // Accessed registers are needed
7043     u&=~(1LL<<dops[i].rs1);
7044     u&=~(1LL<<dops[i].rs2);
7045     gte_u&=~gte_rs[i];
7046     if(gte_rs[i]&&dops[i].rt1&&(unneeded_reg[i+1]&(1ll<<dops[i].rt1)))
7047       gte_u|=gte_rs[i]&gte_unneeded[i+1]; // MFC2/CFC2 to dead register, unneeded
7048     // Source-target dependencies
7049     // R0 is always unneeded
7050     u|=1;
7051     // Save it
7052     unneeded_reg[i]=u;
7053     gte_unneeded[i]=gte_u;
7054     /*
7055     printf("ur (%d,%d) %x: ",istart,iend,start+i*4);
7056     printf("U:");
7057     int r;
7058     for(r=1;r<=CCREG;r++) {
7059       if((unneeded_reg[i]>>r)&1) {
7060         if(r==HIREG) printf(" HI");
7061         else if(r==LOREG) printf(" LO");
7062         else printf(" r%d",r);
7063       }
7064     }
7065     printf("\n");
7066     */
7067   }
7068 }
7069
7070 static noinline void pass3_register_alloc(u_int addr)
7071 {
7072   struct regstat current; // Current register allocations/status
7073   clear_all_regs(current.regmap_entry);
7074   clear_all_regs(current.regmap);
7075   current.wasdirty = current.dirty = 0;
7076   current.u = unneeded_reg[0];
7077   alloc_reg(&current, 0, CCREG);
7078   dirty_reg(&current, CCREG);
7079   current.wasconst = 0;
7080   current.isconst = 0;
7081   current.loadedconst = 0;
7082   current.waswritten = 0;
7083   int ds=0;
7084   int cc=0;
7085   int hr;
7086   int i, j;
7087
7088   if (addr & 1) {
7089     // First instruction is delay slot
7090     cc=-1;
7091     dops[1].bt=1;
7092     ds=1;
7093     unneeded_reg[0]=1;
7094     current.regmap[HOST_BTREG]=BTREG;
7095   }
7096
7097   for(i=0;i<slen;i++)
7098   {
7099     if(dops[i].bt)
7100     {
7101       for(hr=0;hr<HOST_REGS;hr++)
7102       {
7103         // Is this really necessary?
7104         if(current.regmap[hr]==0) current.regmap[hr]=-1;
7105       }
7106       current.isconst=0;
7107       current.waswritten=0;
7108     }
7109
7110     memcpy(regmap_pre[i],current.regmap,sizeof(current.regmap));
7111     regs[i].wasconst=current.isconst;
7112     regs[i].wasdirty=current.dirty;
7113     regs[i].dirty=0;
7114     regs[i].u=0;
7115     regs[i].isconst=0;
7116     regs[i].loadedconst=0;
7117     if (!dops[i].is_jump) {
7118       if(i+1<slen) {
7119         current.u=unneeded_reg[i+1]&~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
7120         current.u|=1;
7121       } else {
7122         current.u=1;
7123       }
7124     } else {
7125       if(i+1<slen) {
7126         current.u=branch_unneeded_reg[i]&~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
7127         current.u&=~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
7128         current.u|=1;
7129       } else {
7130         SysPrintf("oops, branch at end of block with no delay slot @%08x\n", start + i*4);
7131         abort();
7132       }
7133     }
7134     dops[i].is_ds=ds;
7135     if(ds) {
7136       ds=0; // Skip delay slot, already allocated as part of branch
7137       // ...but we need to alloc it in case something jumps here
7138       if(i+1<slen) {
7139         current.u=branch_unneeded_reg[i-1]&unneeded_reg[i+1];
7140       }else{
7141         current.u=branch_unneeded_reg[i-1];
7142       }
7143       current.u&=~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
7144       current.u|=1;
7145       struct regstat temp;
7146       memcpy(&temp,&current,sizeof(current));
7147       temp.wasdirty=temp.dirty;
7148       // TODO: Take into account unconditional branches, as below
7149       delayslot_alloc(&temp,i);
7150       memcpy(regs[i].regmap,temp.regmap,sizeof(temp.regmap));
7151       regs[i].wasdirty=temp.wasdirty;
7152       regs[i].dirty=temp.dirty;
7153       regs[i].isconst=0;
7154       regs[i].wasconst=0;
7155       current.isconst=0;
7156       // Create entry (branch target) regmap
7157       for(hr=0;hr<HOST_REGS;hr++)
7158       {
7159         int r=temp.regmap[hr];
7160         if(r>=0) {
7161           if(r!=regmap_pre[i][hr]) {
7162             regs[i].regmap_entry[hr]=-1;
7163           }
7164           else
7165           {
7166               assert(r < 64);
7167               if((current.u>>r)&1) {
7168                 regs[i].regmap_entry[hr]=-1;
7169                 regs[i].regmap[hr]=-1;
7170                 //Don't clear regs in the delay slot as the branch might need them
7171                 //current.regmap[hr]=-1;
7172               }else
7173                 regs[i].regmap_entry[hr]=r;
7174           }
7175         } else {
7176           // First instruction expects CCREG to be allocated
7177           if(i==0&&hr==HOST_CCREG)
7178             regs[i].regmap_entry[hr]=CCREG;
7179           else
7180             regs[i].regmap_entry[hr]=-1;
7181         }
7182       }
7183     }
7184     else { // Not delay slot
7185       switch(dops[i].itype) {
7186         case UJUMP:
7187           //current.isconst=0; // DEBUG
7188           //current.wasconst=0; // DEBUG
7189           //regs[i].wasconst=0; // DEBUG
7190           clear_const(&current,dops[i].rt1);
7191           alloc_cc(&current,i);
7192           dirty_reg(&current,CCREG);
7193           if (dops[i].rt1==31) {
7194             alloc_reg(&current,i,31);
7195             dirty_reg(&current,31);
7196             //assert(dops[i+1].rs1!=31&&dops[i+1].rs2!=31);
7197             //assert(dops[i+1].rt1!=dops[i].rt1);
7198             #ifdef REG_PREFETCH
7199             alloc_reg(&current,i,PTEMP);
7200             #endif
7201           }
7202           dops[i].ooo=1;
7203           delayslot_alloc(&current,i+1);
7204           //current.isconst=0; // DEBUG
7205           ds=1;
7206           //printf("i=%d, isconst=%x\n",i,current.isconst);
7207           break;
7208         case RJUMP:
7209           //current.isconst=0;
7210           //current.wasconst=0;
7211           //regs[i].wasconst=0;
7212           clear_const(&current,dops[i].rs1);
7213           clear_const(&current,dops[i].rt1);
7214           alloc_cc(&current,i);
7215           dirty_reg(&current,CCREG);
7216           if (!ds_writes_rjump_rs(i)) {
7217             alloc_reg(&current,i,dops[i].rs1);
7218             if (dops[i].rt1!=0) {
7219               alloc_reg(&current,i,dops[i].rt1);
7220               dirty_reg(&current,dops[i].rt1);
7221               assert(dops[i+1].rs1!=dops[i].rt1&&dops[i+1].rs2!=dops[i].rt1);
7222               assert(dops[i+1].rt1!=dops[i].rt1);
7223               #ifdef REG_PREFETCH
7224               alloc_reg(&current,i,PTEMP);
7225               #endif
7226             }
7227             #ifdef USE_MINI_HT
7228             if(dops[i].rs1==31) { // JALR
7229               alloc_reg(&current,i,RHASH);
7230               alloc_reg(&current,i,RHTBL);
7231             }
7232             #endif
7233             delayslot_alloc(&current,i+1);
7234           } else {
7235             // The delay slot overwrites our source register,
7236             // allocate a temporary register to hold the old value.
7237             current.isconst=0;
7238             current.wasconst=0;
7239             regs[i].wasconst=0;
7240             delayslot_alloc(&current,i+1);
7241             current.isconst=0;
7242             alloc_reg(&current,i,RTEMP);
7243           }
7244           //current.isconst=0; // DEBUG
7245           dops[i].ooo=1;
7246           ds=1;
7247           break;
7248         case CJUMP:
7249           //current.isconst=0;
7250           //current.wasconst=0;
7251           //regs[i].wasconst=0;
7252           clear_const(&current,dops[i].rs1);
7253           clear_const(&current,dops[i].rs2);
7254           if((dops[i].opcode&0x3E)==4) // BEQ/BNE
7255           {
7256             alloc_cc(&current,i);
7257             dirty_reg(&current,CCREG);
7258             if(dops[i].rs1) alloc_reg(&current,i,dops[i].rs1);
7259             if(dops[i].rs2) alloc_reg(&current,i,dops[i].rs2);
7260             if((dops[i].rs1&&(dops[i].rs1==dops[i+1].rt1||dops[i].rs1==dops[i+1].rt2))||
7261                (dops[i].rs2&&(dops[i].rs2==dops[i+1].rt1||dops[i].rs2==dops[i+1].rt2))) {
7262               // The delay slot overwrites one of our conditions.
7263               // Allocate the branch condition registers instead.
7264               current.isconst=0;
7265               current.wasconst=0;
7266               regs[i].wasconst=0;
7267               if(dops[i].rs1) alloc_reg(&current,i,dops[i].rs1);
7268               if(dops[i].rs2) alloc_reg(&current,i,dops[i].rs2);
7269             }
7270             else
7271             {
7272               dops[i].ooo=1;
7273               delayslot_alloc(&current,i+1);
7274             }
7275           }
7276           else
7277           if((dops[i].opcode&0x3E)==6) // BLEZ/BGTZ
7278           {
7279             alloc_cc(&current,i);
7280             dirty_reg(&current,CCREG);
7281             alloc_reg(&current,i,dops[i].rs1);
7282             if(dops[i].rs1&&(dops[i].rs1==dops[i+1].rt1||dops[i].rs1==dops[i+1].rt2)) {
7283               // The delay slot overwrites one of our conditions.
7284               // Allocate the branch condition registers instead.
7285               current.isconst=0;
7286               current.wasconst=0;
7287               regs[i].wasconst=0;
7288               if(dops[i].rs1) alloc_reg(&current,i,dops[i].rs1);
7289             }
7290             else
7291             {
7292               dops[i].ooo=1;
7293               delayslot_alloc(&current,i+1);
7294             }
7295           }
7296           else
7297           // Don't alloc the delay slot yet because we might not execute it
7298           if((dops[i].opcode&0x3E)==0x14) // BEQL/BNEL
7299           {
7300             current.isconst=0;
7301             current.wasconst=0;
7302             regs[i].wasconst=0;
7303             alloc_cc(&current,i);
7304             dirty_reg(&current,CCREG);
7305             alloc_reg(&current,i,dops[i].rs1);
7306             alloc_reg(&current,i,dops[i].rs2);
7307           }
7308           else
7309           if((dops[i].opcode&0x3E)==0x16) // BLEZL/BGTZL
7310           {
7311             current.isconst=0;
7312             current.wasconst=0;
7313             regs[i].wasconst=0;
7314             alloc_cc(&current,i);
7315             dirty_reg(&current,CCREG);
7316             alloc_reg(&current,i,dops[i].rs1);
7317           }
7318           ds=1;
7319           //current.isconst=0;
7320           break;
7321         case SJUMP:
7322           //current.isconst=0;
7323           //current.wasconst=0;
7324           //regs[i].wasconst=0;
7325           clear_const(&current,dops[i].rs1);
7326           clear_const(&current,dops[i].rt1);
7327           //if((dops[i].opcode2&0x1E)==0x0) // BLTZ/BGEZ
7328           if((dops[i].opcode2&0x0E)==0x0) // BLTZ/BGEZ
7329           {
7330             alloc_cc(&current,i);
7331             dirty_reg(&current,CCREG);
7332             alloc_reg(&current,i,dops[i].rs1);
7333             if (dops[i].rt1==31) { // BLTZAL/BGEZAL
7334               alloc_reg(&current,i,31);
7335               dirty_reg(&current,31);
7336               //#ifdef REG_PREFETCH
7337               //alloc_reg(&current,i,PTEMP);
7338               //#endif
7339             }
7340             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.
7341                ||(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
7342               // Allocate the branch condition registers instead.
7343               current.isconst=0;
7344               current.wasconst=0;
7345               regs[i].wasconst=0;
7346               if(dops[i].rs1) alloc_reg(&current,i,dops[i].rs1);
7347             }
7348             else
7349             {
7350               dops[i].ooo=1;
7351               delayslot_alloc(&current,i+1);
7352             }
7353           }
7354           else
7355           // Don't alloc the delay slot yet because we might not execute it
7356           if((dops[i].opcode2&0x1E)==0x2) // BLTZL/BGEZL
7357           {
7358             current.isconst=0;
7359             current.wasconst=0;
7360             regs[i].wasconst=0;
7361             alloc_cc(&current,i);
7362             dirty_reg(&current,CCREG);
7363             alloc_reg(&current,i,dops[i].rs1);
7364           }
7365           ds=1;
7366           //current.isconst=0;
7367           break;
7368         case IMM16:
7369           imm16_alloc(&current,i);
7370           break;
7371         case LOAD:
7372         case LOADLR:
7373           load_alloc(&current,i);
7374           break;
7375         case STORE:
7376         case STORELR:
7377           store_alloc(&current,i);
7378           break;
7379         case ALU:
7380           alu_alloc(&current,i);
7381           break;
7382         case SHIFT:
7383           shift_alloc(&current,i);
7384           break;
7385         case MULTDIV:
7386           multdiv_alloc(&current,i);
7387           break;
7388         case SHIFTIMM:
7389           shiftimm_alloc(&current,i);
7390           break;
7391         case MOV:
7392           mov_alloc(&current,i);
7393           break;
7394         case COP0:
7395           cop0_alloc(&current,i);
7396           break;
7397         case COP1:
7398           break;
7399         case COP2:
7400           cop2_alloc(&current,i);
7401           break;
7402         case C1LS:
7403           c1ls_alloc(&current,i);
7404           break;
7405         case C2LS:
7406           c2ls_alloc(&current,i);
7407           break;
7408         case C2OP:
7409           c2op_alloc(&current,i);
7410           break;
7411         case SYSCALL:
7412         case HLECALL:
7413         case INTCALL:
7414           syscall_alloc(&current,i);
7415           break;
7416       }
7417
7418       // Create entry (branch target) regmap
7419       for(hr=0;hr<HOST_REGS;hr++)
7420       {
7421         int r,or;
7422         r=current.regmap[hr];
7423         if(r>=0) {
7424           if(r!=regmap_pre[i][hr]) {
7425             // TODO: delay slot (?)
7426             or=get_reg(regmap_pre[i],r); // Get old mapping for this register
7427             if(or<0||r>=TEMPREG){
7428               regs[i].regmap_entry[hr]=-1;
7429             }
7430             else
7431             {
7432               // Just move it to a different register
7433               regs[i].regmap_entry[hr]=r;
7434               // If it was dirty before, it's still dirty
7435               if((regs[i].wasdirty>>or)&1) dirty_reg(&current,r);
7436             }
7437           }
7438           else
7439           {
7440             // Unneeded
7441             if(r==0){
7442               regs[i].regmap_entry[hr]=0;
7443             }
7444             else
7445             {
7446               assert(r<64);
7447               if((current.u>>r)&1) {
7448                 regs[i].regmap_entry[hr]=-1;
7449                 //regs[i].regmap[hr]=-1;
7450                 current.regmap[hr]=-1;
7451               }else
7452                 regs[i].regmap_entry[hr]=r;
7453             }
7454           }
7455         } else {
7456           // Branches expect CCREG to be allocated at the target
7457           if(regmap_pre[i][hr]==CCREG)
7458             regs[i].regmap_entry[hr]=CCREG;
7459           else
7460             regs[i].regmap_entry[hr]=-1;
7461         }
7462       }
7463       memcpy(regs[i].regmap,current.regmap,sizeof(current.regmap));
7464     }
7465
7466     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)
7467       current.waswritten|=1<<dops[i-1].rs1;
7468     current.waswritten&=~(1<<dops[i].rt1);
7469     current.waswritten&=~(1<<dops[i].rt2);
7470     if((dops[i].itype==STORE||dops[i].itype==STORELR||(dops[i].itype==C2LS&&dops[i].opcode==0x3a))&&(u_int)imm[i]>=0x800)
7471       current.waswritten&=~(1<<dops[i].rs1);
7472
7473     /* Branch post-alloc */
7474     if(i>0)
7475     {
7476       current.wasdirty=current.dirty;
7477       switch(dops[i-1].itype) {
7478         case UJUMP:
7479           memcpy(&branch_regs[i-1],&current,sizeof(current));
7480           branch_regs[i-1].isconst=0;
7481           branch_regs[i-1].wasconst=0;
7482           branch_regs[i-1].u=branch_unneeded_reg[i-1]&~((1LL<<dops[i-1].rs1)|(1LL<<dops[i-1].rs2));
7483           alloc_cc(&branch_regs[i-1],i-1);
7484           dirty_reg(&branch_regs[i-1],CCREG);
7485           if(dops[i-1].rt1==31) { // JAL
7486             alloc_reg(&branch_regs[i-1],i-1,31);
7487             dirty_reg(&branch_regs[i-1],31);
7488           }
7489           memcpy(&branch_regs[i-1].regmap_entry,&branch_regs[i-1].regmap,sizeof(current.regmap));
7490           memcpy(constmap[i],constmap[i-1],sizeof(constmap[i]));
7491           break;
7492         case RJUMP:
7493           memcpy(&branch_regs[i-1],&current,sizeof(current));
7494           branch_regs[i-1].isconst=0;
7495           branch_regs[i-1].wasconst=0;
7496           branch_regs[i-1].u=branch_unneeded_reg[i-1]&~((1LL<<dops[i-1].rs1)|(1LL<<dops[i-1].rs2));
7497           alloc_cc(&branch_regs[i-1],i-1);
7498           dirty_reg(&branch_regs[i-1],CCREG);
7499           alloc_reg(&branch_regs[i-1],i-1,dops[i-1].rs1);
7500           if(dops[i-1].rt1!=0) { // JALR
7501             alloc_reg(&branch_regs[i-1],i-1,dops[i-1].rt1);
7502             dirty_reg(&branch_regs[i-1],dops[i-1].rt1);
7503           }
7504           #ifdef USE_MINI_HT
7505           if(dops[i-1].rs1==31) { // JALR
7506             alloc_reg(&branch_regs[i-1],i-1,RHASH);
7507             alloc_reg(&branch_regs[i-1],i-1,RHTBL);
7508           }
7509           #endif
7510           memcpy(&branch_regs[i-1].regmap_entry,&branch_regs[i-1].regmap,sizeof(current.regmap));
7511           memcpy(constmap[i],constmap[i-1],sizeof(constmap[i]));
7512           break;
7513         case CJUMP:
7514           if((dops[i-1].opcode&0x3E)==4) // BEQ/BNE
7515           {
7516             alloc_cc(&current,i-1);
7517             dirty_reg(&current,CCREG);
7518             if((dops[i-1].rs1&&(dops[i-1].rs1==dops[i].rt1||dops[i-1].rs1==dops[i].rt2))||
7519                (dops[i-1].rs2&&(dops[i-1].rs2==dops[i].rt1||dops[i-1].rs2==dops[i].rt2))) {
7520               // The delay slot overwrote one of our conditions
7521               // Delay slot goes after the test (in order)
7522               current.u=branch_unneeded_reg[i-1]&~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
7523               current.u|=1;
7524               delayslot_alloc(&current,i);
7525               current.isconst=0;
7526             }
7527             else
7528             {
7529               current.u=branch_unneeded_reg[i-1]&~((1LL<<dops[i-1].rs1)|(1LL<<dops[i-1].rs2));
7530               // Alloc the branch condition registers
7531               if(dops[i-1].rs1) alloc_reg(&current,i-1,dops[i-1].rs1);
7532               if(dops[i-1].rs2) alloc_reg(&current,i-1,dops[i-1].rs2);
7533             }
7534             memcpy(&branch_regs[i-1],&current,sizeof(current));
7535             branch_regs[i-1].isconst=0;
7536             branch_regs[i-1].wasconst=0;
7537             memcpy(&branch_regs[i-1].regmap_entry,&current.regmap,sizeof(current.regmap));
7538             memcpy(constmap[i],constmap[i-1],sizeof(constmap[i]));
7539           }
7540           else
7541           if((dops[i-1].opcode&0x3E)==6) // BLEZ/BGTZ
7542           {
7543             alloc_cc(&current,i-1);
7544             dirty_reg(&current,CCREG);
7545             if(dops[i-1].rs1==dops[i].rt1||dops[i-1].rs1==dops[i].rt2) {
7546               // The delay slot overwrote the branch condition
7547               // Delay slot goes after the test (in order)
7548               current.u=branch_unneeded_reg[i-1]&~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
7549               current.u|=1;
7550               delayslot_alloc(&current,i);
7551               current.isconst=0;
7552             }
7553             else
7554             {
7555               current.u=branch_unneeded_reg[i-1]&~(1LL<<dops[i-1].rs1);
7556               // Alloc the branch condition register
7557               alloc_reg(&current,i-1,dops[i-1].rs1);
7558             }
7559             memcpy(&branch_regs[i-1],&current,sizeof(current));
7560             branch_regs[i-1].isconst=0;
7561             branch_regs[i-1].wasconst=0;
7562             memcpy(&branch_regs[i-1].regmap_entry,&current.regmap,sizeof(current.regmap));
7563             memcpy(constmap[i],constmap[i-1],sizeof(constmap[i]));
7564           }
7565           else
7566           // Alloc the delay slot in case the branch is taken
7567           if((dops[i-1].opcode&0x3E)==0x14) // BEQL/BNEL
7568           {
7569             memcpy(&branch_regs[i-1],&current,sizeof(current));
7570             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;
7571             alloc_cc(&branch_regs[i-1],i);
7572             dirty_reg(&branch_regs[i-1],CCREG);
7573             delayslot_alloc(&branch_regs[i-1],i);
7574             branch_regs[i-1].isconst=0;
7575             alloc_reg(&current,i,CCREG); // Not taken path
7576             dirty_reg(&current,CCREG);
7577             memcpy(&branch_regs[i-1].regmap_entry,&branch_regs[i-1].regmap,sizeof(current.regmap));
7578           }
7579           else
7580           if((dops[i-1].opcode&0x3E)==0x16) // BLEZL/BGTZL
7581           {
7582             memcpy(&branch_regs[i-1],&current,sizeof(current));
7583             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;
7584             alloc_cc(&branch_regs[i-1],i);
7585             dirty_reg(&branch_regs[i-1],CCREG);
7586             delayslot_alloc(&branch_regs[i-1],i);
7587             branch_regs[i-1].isconst=0;
7588             alloc_reg(&current,i,CCREG); // Not taken path
7589             dirty_reg(&current,CCREG);
7590             memcpy(&branch_regs[i-1].regmap_entry,&branch_regs[i-1].regmap,sizeof(current.regmap));
7591           }
7592           break;
7593         case SJUMP:
7594           //if((dops[i-1].opcode2&0x1E)==0) // BLTZ/BGEZ
7595           if((dops[i-1].opcode2&0x0E)==0) // BLTZ/BGEZ
7596           {
7597             alloc_cc(&current,i-1);
7598             dirty_reg(&current,CCREG);
7599             if(dops[i-1].rs1==dops[i].rt1||dops[i-1].rs1==dops[i].rt2) {
7600               // The delay slot overwrote the branch condition
7601               // Delay slot goes after the test (in order)
7602               current.u=branch_unneeded_reg[i-1]&~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
7603               current.u|=1;
7604               delayslot_alloc(&current,i);
7605               current.isconst=0;
7606             }
7607             else
7608             {
7609               current.u=branch_unneeded_reg[i-1]&~(1LL<<dops[i-1].rs1);
7610               // Alloc the branch condition register
7611               alloc_reg(&current,i-1,dops[i-1].rs1);
7612             }
7613             memcpy(&branch_regs[i-1],&current,sizeof(current));
7614             branch_regs[i-1].isconst=0;
7615             branch_regs[i-1].wasconst=0;
7616             memcpy(&branch_regs[i-1].regmap_entry,&current.regmap,sizeof(current.regmap));
7617             memcpy(constmap[i],constmap[i-1],sizeof(constmap[i]));
7618           }
7619           else
7620           // Alloc the delay slot in case the branch is taken
7621           if((dops[i-1].opcode2&0x1E)==2) // BLTZL/BGEZL
7622           {
7623             memcpy(&branch_regs[i-1],&current,sizeof(current));
7624             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;
7625             alloc_cc(&branch_regs[i-1],i);
7626             dirty_reg(&branch_regs[i-1],CCREG);
7627             delayslot_alloc(&branch_regs[i-1],i);
7628             branch_regs[i-1].isconst=0;
7629             alloc_reg(&current,i,CCREG); // Not taken path
7630             dirty_reg(&current,CCREG);
7631             memcpy(&branch_regs[i-1].regmap_entry,&branch_regs[i-1].regmap,sizeof(current.regmap));
7632           }
7633           // FIXME: BLTZAL/BGEZAL
7634           if(dops[i-1].opcode2&0x10) { // BxxZAL
7635             alloc_reg(&branch_regs[i-1],i-1,31);
7636             dirty_reg(&branch_regs[i-1],31);
7637           }
7638           break;
7639       }
7640
7641       if (dops[i-1].is_ujump)
7642       {
7643         if(dops[i-1].rt1==31) // JAL/JALR
7644         {
7645           // Subroutine call will return here, don't alloc any registers
7646           current.dirty=0;
7647           clear_all_regs(current.regmap);
7648           alloc_reg(&current,i,CCREG);
7649           dirty_reg(&current,CCREG);
7650         }
7651         else if(i+1<slen)
7652         {
7653           // Internal branch will jump here, match registers to caller
7654           current.dirty=0;
7655           clear_all_regs(current.regmap);
7656           alloc_reg(&current,i,CCREG);
7657           dirty_reg(&current,CCREG);
7658           for(j=i-1;j>=0;j--)
7659           {
7660             if(ba[j]==start+i*4+4) {
7661               memcpy(current.regmap,branch_regs[j].regmap,sizeof(current.regmap));
7662               current.dirty=branch_regs[j].dirty;
7663               break;
7664             }
7665           }
7666           while(j>=0) {
7667             if(ba[j]==start+i*4+4) {
7668               for(hr=0;hr<HOST_REGS;hr++) {
7669                 if(current.regmap[hr]!=branch_regs[j].regmap[hr]) {
7670                   current.regmap[hr]=-1;
7671                 }
7672                 current.dirty&=branch_regs[j].dirty;
7673               }
7674             }
7675             j--;
7676           }
7677         }
7678       }
7679     }
7680
7681     // Count cycles in between branches
7682     ccadj[i] = CLOCK_ADJUST(cc);
7683     if (i > 0 && (dops[i-1].is_jump || dops[i].itype == SYSCALL || dops[i].itype == HLECALL))
7684     {
7685       cc=0;
7686     }
7687 #if !defined(DRC_DBG)
7688     else if(dops[i].itype==C2OP&&gte_cycletab[source[i]&0x3f]>2)
7689     {
7690       // this should really be removed since the real stalls have been implemented,
7691       // but doing so causes sizeable perf regression against the older version
7692       u_int gtec = gte_cycletab[source[i] & 0x3f];
7693       cc += HACK_ENABLED(NDHACK_NO_STALLS) ? gtec/2 : 2;
7694     }
7695     else if(i>1&&dops[i].itype==STORE&&dops[i-1].itype==STORE&&dops[i-2].itype==STORE&&!dops[i].bt)
7696     {
7697       cc+=4;
7698     }
7699     else if(dops[i].itype==C2LS)
7700     {
7701       // same as with C2OP
7702       cc += HACK_ENABLED(NDHACK_NO_STALLS) ? 4 : 2;
7703     }
7704 #endif
7705     else
7706     {
7707       cc++;
7708     }
7709
7710     if(!dops[i].is_ds) {
7711       regs[i].dirty=current.dirty;
7712       regs[i].isconst=current.isconst;
7713       memcpy(constmap[i],current_constmap,sizeof(constmap[i]));
7714     }
7715     for(hr=0;hr<HOST_REGS;hr++) {
7716       if(hr!=EXCLUDE_REG&&regs[i].regmap[hr]>=0) {
7717         if(regmap_pre[i][hr]!=regs[i].regmap[hr]) {
7718           regs[i].wasconst&=~(1<<hr);
7719         }
7720       }
7721     }
7722     if(current.regmap[HOST_BTREG]==BTREG) current.regmap[HOST_BTREG]=-1;
7723     regs[i].waswritten=current.waswritten;
7724   }
7725 }
7726
7727 static noinline void pass4_cull_unused_regs(void)
7728 {
7729   u_int last_needed_regs[4] = {0,0,0,0};
7730   u_int nr=0;
7731   int i;
7732
7733   for (i=slen-1;i>=0;i--)
7734   {
7735     int hr;
7736     __builtin_prefetch(regs[i-2].regmap);
7737     if(dops[i].is_jump)
7738     {
7739       if(ba[i]<start || ba[i]>=(start+slen*4))
7740       {
7741         // Branch out of this block, don't need anything
7742         nr=0;
7743       }
7744       else
7745       {
7746         // Internal branch
7747         // Need whatever matches the target
7748         nr=0;
7749         int t=(ba[i]-start)>>2;
7750         for(hr=0;hr<HOST_REGS;hr++)
7751         {
7752           if(regs[i].regmap_entry[hr]>=0) {
7753             if(regs[i].regmap_entry[hr]==regs[t].regmap_entry[hr]) nr|=1<<hr;
7754           }
7755         }
7756       }
7757       // Conditional branch may need registers for following instructions
7758       if (!dops[i].is_ujump)
7759       {
7760         if(i<slen-2) {
7761           nr |= last_needed_regs[(i+2) & 3];
7762           for(hr=0;hr<HOST_REGS;hr++)
7763           {
7764             if(regmap_pre[i+2][hr]>=0&&get_reg(regs[i+2].regmap_entry,regmap_pre[i+2][hr])<0) nr&=~(1<<hr);
7765             //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]);
7766           }
7767         }
7768       }
7769       // Don't need stuff which is overwritten
7770       //if(regs[i].regmap[hr]!=regmap_pre[i][hr]) nr&=~(1<<hr);
7771       //if(regs[i].regmap[hr]<0) nr&=~(1<<hr);
7772       // Merge in delay slot
7773       if (dops[i+1].rt1) nr &= ~get_regm(regs[i].regmap, dops[i+1].rt1);
7774       if (dops[i+1].rt2) nr &= ~get_regm(regs[i].regmap, dops[i+1].rt2);
7775       nr |= get_regm(regmap_pre[i], dops[i+1].rs1);
7776       nr |= get_regm(regmap_pre[i], dops[i+1].rs2);
7777       nr |= get_regm(regs[i].regmap_entry, dops[i+1].rs1);
7778       nr |= get_regm(regs[i].regmap_entry, dops[i+1].rs2);
7779       if (ram_offset && (dops[i+1].is_load || dops[i+1].is_store)) {
7780         nr |= get_regm(regmap_pre[i], ROREG);
7781         nr |= get_regm(regs[i].regmap_entry, ROREG);
7782       }
7783       if (dops[i+1].is_store) {
7784         nr |= get_regm(regmap_pre[i], INVCP);
7785         nr |= get_regm(regs[i].regmap_entry, INVCP);
7786       }
7787     }
7788     else if(dops[i].itype==SYSCALL||dops[i].itype==HLECALL||dops[i].itype==INTCALL)
7789     {
7790       // SYSCALL instruction (software interrupt)
7791       nr=0;
7792     }
7793     else if(dops[i].itype==COP0 && (source[i]&0x3f)==0x18)
7794     {
7795       // ERET instruction (return from interrupt)
7796       nr=0;
7797     }
7798     else // Non-branch
7799     {
7800       if(i<slen-1) {
7801         for(hr=0;hr<HOST_REGS;hr++) {
7802           if(regmap_pre[i+1][hr]>=0&&get_reg(regs[i+1].regmap_entry,regmap_pre[i+1][hr])<0) nr&=~(1<<hr);
7803           if(regs[i].regmap[hr]!=regmap_pre[i+1][hr]) nr&=~(1<<hr);
7804           if(regs[i].regmap[hr]!=regmap_pre[i][hr]) nr&=~(1<<hr);
7805           if(regs[i].regmap[hr]<0) nr&=~(1<<hr);
7806         }
7807       }
7808     }
7809     // Overwritten registers are not needed
7810     if (dops[i].rt1) nr &= ~get_regm(regs[i].regmap, dops[i].rt1);
7811     if (dops[i].rt2) nr &= ~get_regm(regs[i].regmap, dops[i].rt2);
7812     nr &= ~get_regm(regs[i].regmap, FTEMP);
7813     // Source registers are needed
7814     nr |= get_regm(regmap_pre[i], dops[i].rs1);
7815     nr |= get_regm(regmap_pre[i], dops[i].rs2);
7816     nr |= get_regm(regs[i].regmap_entry, dops[i].rs1);
7817     nr |= get_regm(regs[i].regmap_entry, dops[i].rs2);
7818     if (ram_offset && (dops[i].is_load || dops[i].is_store)) {
7819       nr |= get_regm(regmap_pre[i], ROREG);
7820       nr |= get_regm(regs[i].regmap_entry, ROREG);
7821     }
7822     if (dops[i].is_store) {
7823       nr |= get_regm(regmap_pre[i], INVCP);
7824       nr |= get_regm(regs[i].regmap_entry, INVCP);
7825     }
7826
7827     if (i > 0 && !dops[i].bt && regs[i].wasdirty)
7828     for(hr=0;hr<HOST_REGS;hr++)
7829     {
7830       // Don't store a register immediately after writing it,
7831       // may prevent dual-issue.
7832       // But do so if this is a branch target, otherwise we
7833       // might have to load the register before the branch.
7834       if((regs[i].wasdirty>>hr)&1) {
7835         if((regmap_pre[i][hr]>0&&!((unneeded_reg[i]>>regmap_pre[i][hr])&1))) {
7836           if(dops[i-1].rt1==regmap_pre[i][hr]) nr|=1<<hr;
7837           if(dops[i-1].rt2==regmap_pre[i][hr]) nr|=1<<hr;
7838         }
7839         if((regs[i].regmap_entry[hr]>0&&!((unneeded_reg[i]>>regs[i].regmap_entry[hr])&1))) {
7840           if(dops[i-1].rt1==regs[i].regmap_entry[hr]) nr|=1<<hr;
7841           if(dops[i-1].rt2==regs[i].regmap_entry[hr]) nr|=1<<hr;
7842         }
7843       }
7844     }
7845     // Cycle count is needed at branches.  Assume it is needed at the target too.
7846     if(i==0||dops[i].bt||dops[i].itype==CJUMP) {
7847       if(regmap_pre[i][HOST_CCREG]==CCREG) nr|=1<<HOST_CCREG;
7848       if(regs[i].regmap_entry[HOST_CCREG]==CCREG) nr|=1<<HOST_CCREG;
7849     }
7850     // Save it
7851     last_needed_regs[i & 3] = nr;
7852
7853     // Deallocate unneeded registers
7854     for(hr=0;hr<HOST_REGS;hr++)
7855     {
7856       if(!((nr>>hr)&1)) {
7857         if(regs[i].regmap_entry[hr]!=CCREG) regs[i].regmap_entry[hr]=-1;
7858         if(dops[i].is_jump)
7859         {
7860           int map1 = 0, map2 = 0, temp = 0; // or -1 ??
7861           if (dops[i+1].is_load || dops[i+1].is_store)
7862             map1 = ROREG;
7863           if (dops[i+1].is_store)
7864             map2 = INVCP;
7865           if(dops[i+1].itype==LOADLR || dops[i+1].itype==STORELR || dops[i+1].itype==C2LS)
7866             temp = FTEMP;
7867           if(regs[i].regmap[hr]!=dops[i].rs1 && regs[i].regmap[hr]!=dops[i].rs2 &&
7868              regs[i].regmap[hr]!=dops[i].rt1 && regs[i].regmap[hr]!=dops[i].rt2 &&
7869              regs[i].regmap[hr]!=dops[i+1].rt1 && regs[i].regmap[hr]!=dops[i+1].rt2 &&
7870              regs[i].regmap[hr]!=dops[i+1].rs1 && regs[i].regmap[hr]!=dops[i+1].rs2 &&
7871              regs[i].regmap[hr]!=temp && regs[i].regmap[hr]!=PTEMP &&
7872              regs[i].regmap[hr]!=RHASH && regs[i].regmap[hr]!=RHTBL &&
7873              regs[i].regmap[hr]!=RTEMP && regs[i].regmap[hr]!=CCREG &&
7874              regs[i].regmap[hr]!=map1 && regs[i].regmap[hr]!=map2)
7875           {
7876             regs[i].regmap[hr]=-1;
7877             regs[i].isconst&=~(1<<hr);
7878             regs[i].dirty&=~(1<<hr);
7879             regs[i+1].wasdirty&=~(1<<hr);
7880             if(branch_regs[i].regmap[hr]!=dops[i].rs1 && branch_regs[i].regmap[hr]!=dops[i].rs2 &&
7881                branch_regs[i].regmap[hr]!=dops[i].rt1 && branch_regs[i].regmap[hr]!=dops[i].rt2 &&
7882                branch_regs[i].regmap[hr]!=dops[i+1].rt1 && branch_regs[i].regmap[hr]!=dops[i+1].rt2 &&
7883                branch_regs[i].regmap[hr]!=dops[i+1].rs1 && branch_regs[i].regmap[hr]!=dops[i+1].rs2 &&
7884                branch_regs[i].regmap[hr]!=temp && branch_regs[i].regmap[hr]!=PTEMP &&
7885                branch_regs[i].regmap[hr]!=RHASH && branch_regs[i].regmap[hr]!=RHTBL &&
7886                branch_regs[i].regmap[hr]!=RTEMP && branch_regs[i].regmap[hr]!=CCREG &&
7887                branch_regs[i].regmap[hr]!=map1 && branch_regs[i].regmap[hr]!=map2)
7888             {
7889               branch_regs[i].regmap[hr]=-1;
7890               branch_regs[i].regmap_entry[hr]=-1;
7891               if (!dops[i].is_ujump)
7892               {
7893                 if (i < slen-2) {
7894                   regmap_pre[i+2][hr]=-1;
7895                   regs[i+2].wasconst&=~(1<<hr);
7896                 }
7897               }
7898             }
7899           }
7900         }
7901         else
7902         {
7903           // Non-branch
7904           if(i>0)
7905           {
7906             int map1 = -1, map2 = -1, temp=-1;
7907             if (dops[i].is_load || dops[i].is_store)
7908               map1 = ROREG;
7909             if (dops[i].is_store)
7910               map2 = INVCP;
7911             if (dops[i].itype==LOADLR || dops[i].itype==STORELR || dops[i].itype==C2LS)
7912               temp = FTEMP;
7913             if(regs[i].regmap[hr]!=dops[i].rt1 && regs[i].regmap[hr]!=dops[i].rt2 &&
7914                regs[i].regmap[hr]!=dops[i].rs1 && regs[i].regmap[hr]!=dops[i].rs2 &&
7915                regs[i].regmap[hr]!=temp && regs[i].regmap[hr]!=map1 && regs[i].regmap[hr]!=map2 &&
7916                //(dops[i].itype!=SPAN||regs[i].regmap[hr]!=CCREG)
7917                regs[i].regmap[hr] != CCREG)
7918             {
7919               if(i<slen-1&&!dops[i].is_ds) {
7920                 assert(regs[i].regmap[hr]<64);
7921                 if(regmap_pre[i+1][hr]!=-1 || regs[i].regmap[hr]>0)
7922                 if(regmap_pre[i+1][hr]!=regs[i].regmap[hr])
7923                 {
7924                   SysPrintf("fail: %x (%d %d!=%d)\n",start+i*4,hr,regmap_pre[i+1][hr],regs[i].regmap[hr]);
7925                   assert(regmap_pre[i+1][hr]==regs[i].regmap[hr]);
7926                 }
7927                 regmap_pre[i+1][hr]=-1;
7928                 if(regs[i+1].regmap_entry[hr]==CCREG) regs[i+1].regmap_entry[hr]=-1;
7929                 regs[i+1].wasconst&=~(1<<hr);
7930               }
7931               regs[i].regmap[hr]=-1;
7932               regs[i].isconst&=~(1<<hr);
7933               regs[i].dirty&=~(1<<hr);
7934               regs[i+1].wasdirty&=~(1<<hr);
7935             }
7936           }
7937         }
7938       } // if needed
7939     } // for hr
7940   }
7941 }
7942
7943 // If a register is allocated during a loop, try to allocate it for the
7944 // entire loop, if possible.  This avoids loading/storing registers
7945 // inside of the loop.
7946 static noinline void pass5a_preallocate1(void)
7947 {
7948   int i, j, hr;
7949   signed char f_regmap[HOST_REGS];
7950   clear_all_regs(f_regmap);
7951   for(i=0;i<slen-1;i++)
7952   {
7953     if(dops[i].itype==UJUMP||dops[i].itype==CJUMP||dops[i].itype==SJUMP)
7954     {
7955       if(ba[i]>=start && ba[i]<(start+i*4))
7956       if(dops[i+1].itype==NOP||dops[i+1].itype==MOV||dops[i+1].itype==ALU
7957       ||dops[i+1].itype==SHIFTIMM||dops[i+1].itype==IMM16||dops[i+1].itype==LOAD
7958       ||dops[i+1].itype==STORE||dops[i+1].itype==STORELR||dops[i+1].itype==C1LS
7959       ||dops[i+1].itype==SHIFT||dops[i+1].itype==COP1
7960       ||dops[i+1].itype==COP2||dops[i+1].itype==C2LS||dops[i+1].itype==C2OP)
7961       {
7962         int t=(ba[i]-start)>>2;
7963         if(t > 0 && !dops[t-1].is_jump) // loop_preload can't handle jumps into delay slots
7964         if(t<2||(dops[t-2].itype!=UJUMP&&dops[t-2].itype!=RJUMP)||dops[t-2].rt1!=31) // call/ret assumes no registers allocated
7965         for(hr=0;hr<HOST_REGS;hr++)
7966         {
7967           if(regs[i].regmap[hr]>=0) {
7968             if(f_regmap[hr]!=regs[i].regmap[hr]) {
7969               // dealloc old register
7970               int n;
7971               for(n=0;n<HOST_REGS;n++)
7972               {
7973                 if(f_regmap[n]==regs[i].regmap[hr]) {f_regmap[n]=-1;}
7974               }
7975               // and alloc new one
7976               f_regmap[hr]=regs[i].regmap[hr];
7977             }
7978           }
7979           if(branch_regs[i].regmap[hr]>=0) {
7980             if(f_regmap[hr]!=branch_regs[i].regmap[hr]) {
7981               // dealloc old register
7982               int n;
7983               for(n=0;n<HOST_REGS;n++)
7984               {
7985                 if(f_regmap[n]==branch_regs[i].regmap[hr]) {f_regmap[n]=-1;}
7986               }
7987               // and alloc new one
7988               f_regmap[hr]=branch_regs[i].regmap[hr];
7989             }
7990           }
7991           if(dops[i].ooo) {
7992             if(count_free_regs(regs[i].regmap)<=minimum_free_regs[i+1])
7993               f_regmap[hr]=branch_regs[i].regmap[hr];
7994           }else{
7995             if(count_free_regs(branch_regs[i].regmap)<=minimum_free_regs[i+1])
7996               f_regmap[hr]=branch_regs[i].regmap[hr];
7997           }
7998           // Avoid dirty->clean transition
7999           #ifdef DESTRUCTIVE_WRITEBACK
8000           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;
8001           #endif
8002           // This check is only strictly required in the DESTRUCTIVE_WRITEBACK
8003           // case above, however it's always a good idea.  We can't hoist the
8004           // load if the register was already allocated, so there's no point
8005           // wasting time analyzing most of these cases.  It only "succeeds"
8006           // when the mapping was different and the load can be replaced with
8007           // a mov, which is of negligible benefit.  So such cases are
8008           // skipped below.
8009           if(f_regmap[hr]>0) {
8010             if(regs[t].regmap[hr]==f_regmap[hr]||(regs[t].regmap_entry[hr]<0&&get_reg(regmap_pre[t],f_regmap[hr])<0)) {
8011               int r=f_regmap[hr];
8012               for(j=t;j<=i;j++)
8013               {
8014                 //printf("Test %x -> %x, %x %d/%d\n",start+i*4,ba[i],start+j*4,hr,r);
8015                 if(r<34&&((unneeded_reg[j]>>r)&1)) break;
8016                 assert(r < 64);
8017                 if(regs[j].regmap[hr]==f_regmap[hr]&&f_regmap[hr]<TEMPREG) {
8018                   //printf("Hit %x -> %x, %x %d/%d\n",start+i*4,ba[i],start+j*4,hr,r);
8019                   int k;
8020                   if(regs[i].regmap[hr]==-1&&branch_regs[i].regmap[hr]==-1) {
8021                     if(get_reg(regs[i].regmap,f_regmap[hr])>=0) break;
8022                     if(get_reg(regs[i+2].regmap,f_regmap[hr])>=0) break;
8023                     k=i;
8024                     while(k>1&&regs[k-1].regmap[hr]==-1) {
8025                       if(count_free_regs(regs[k-1].regmap)<=minimum_free_regs[k-1]) {
8026                         //printf("no free regs for store %x\n",start+(k-1)*4);
8027                         break;
8028                       }
8029                       if(get_reg(regs[k-1].regmap,f_regmap[hr])>=0) {
8030                         //printf("no-match due to different register\n");
8031                         break;
8032                       }
8033                       if (dops[k-2].is_jump) {
8034                         //printf("no-match due to branch\n");
8035                         break;
8036                       }
8037                       // call/ret fast path assumes no registers allocated
8038                       if(k>2&&(dops[k-3].itype==UJUMP||dops[k-3].itype==RJUMP)&&dops[k-3].rt1==31) {
8039                         break;
8040                       }
8041                       k--;
8042                     }
8043                     if(regs[k-1].regmap[hr]==f_regmap[hr]&&regmap_pre[k][hr]==f_regmap[hr]) {
8044                       //printf("Extend r%d, %x ->\n",hr,start+k*4);
8045                       while(k<i) {
8046                         regs[k].regmap_entry[hr]=f_regmap[hr];
8047                         regs[k].regmap[hr]=f_regmap[hr];
8048                         regmap_pre[k+1][hr]=f_regmap[hr];
8049                         regs[k].wasdirty&=~(1<<hr);
8050                         regs[k].dirty&=~(1<<hr);
8051                         regs[k].wasdirty|=(1<<hr)&regs[k-1].dirty;
8052                         regs[k].dirty|=(1<<hr)&regs[k].wasdirty;
8053                         regs[k].wasconst&=~(1<<hr);
8054                         regs[k].isconst&=~(1<<hr);
8055                         k++;
8056                       }
8057                     }
8058                     else {
8059                       //printf("Fail Extend r%d, %x ->\n",hr,start+k*4);
8060                       break;
8061                     }
8062                     assert(regs[i-1].regmap[hr]==f_regmap[hr]);
8063                     if(regs[i-1].regmap[hr]==f_regmap[hr]&&regmap_pre[i][hr]==f_regmap[hr]) {
8064                       //printf("OK fill %x (r%d)\n",start+i*4,hr);
8065                       regs[i].regmap_entry[hr]=f_regmap[hr];
8066                       regs[i].regmap[hr]=f_regmap[hr];
8067                       regs[i].wasdirty&=~(1<<hr);
8068                       regs[i].dirty&=~(1<<hr);
8069                       regs[i].wasdirty|=(1<<hr)&regs[i-1].dirty;
8070                       regs[i].dirty|=(1<<hr)&regs[i-1].dirty;
8071                       regs[i].wasconst&=~(1<<hr);
8072                       regs[i].isconst&=~(1<<hr);
8073                       branch_regs[i].regmap_entry[hr]=f_regmap[hr];
8074                       branch_regs[i].wasdirty&=~(1<<hr);
8075                       branch_regs[i].wasdirty|=(1<<hr)&regs[i].dirty;
8076                       branch_regs[i].regmap[hr]=f_regmap[hr];
8077                       branch_regs[i].dirty&=~(1<<hr);
8078                       branch_regs[i].dirty|=(1<<hr)&regs[i].dirty;
8079                       branch_regs[i].wasconst&=~(1<<hr);
8080                       branch_regs[i].isconst&=~(1<<hr);
8081                       if (!dops[i].is_ujump) {
8082                         regmap_pre[i+2][hr]=f_regmap[hr];
8083                         regs[i+2].wasdirty&=~(1<<hr);
8084                         regs[i+2].wasdirty|=(1<<hr)&regs[i].dirty;
8085                       }
8086                     }
8087                   }
8088                   for(k=t;k<j;k++) {
8089                     // Alloc register clean at beginning of loop,
8090                     // but may dirty it in pass 6
8091                     regs[k].regmap_entry[hr]=f_regmap[hr];
8092                     regs[k].regmap[hr]=f_regmap[hr];
8093                     regs[k].dirty&=~(1<<hr);
8094                     regs[k].wasconst&=~(1<<hr);
8095                     regs[k].isconst&=~(1<<hr);
8096                     if (dops[k].is_jump) {
8097                       branch_regs[k].regmap_entry[hr]=f_regmap[hr];
8098                       branch_regs[k].regmap[hr]=f_regmap[hr];
8099                       branch_regs[k].dirty&=~(1<<hr);
8100                       branch_regs[k].wasconst&=~(1<<hr);
8101                       branch_regs[k].isconst&=~(1<<hr);
8102                       if (!dops[k].is_ujump) {
8103                         regmap_pre[k+2][hr]=f_regmap[hr];
8104                         regs[k+2].wasdirty&=~(1<<hr);
8105                       }
8106                     }
8107                     else
8108                     {
8109                       regmap_pre[k+1][hr]=f_regmap[hr];
8110                       regs[k+1].wasdirty&=~(1<<hr);
8111                     }
8112                   }
8113                   if(regs[j].regmap[hr]==f_regmap[hr])
8114                     regs[j].regmap_entry[hr]=f_regmap[hr];
8115                   break;
8116                 }
8117                 if(j==i) break;
8118                 if(regs[j].regmap[hr]>=0)
8119                   break;
8120                 if(get_reg(regs[j].regmap,f_regmap[hr])>=0) {
8121                   //printf("no-match due to different register\n");
8122                   break;
8123                 }
8124                 if (dops[j].is_ujump)
8125                 {
8126                   // Stop on unconditional branch
8127                   break;
8128                 }
8129                 if(dops[j].itype==CJUMP||dops[j].itype==SJUMP)
8130                 {
8131                   if(dops[j].ooo) {
8132                     if(count_free_regs(regs[j].regmap)<=minimum_free_regs[j+1])
8133                       break;
8134                   }else{
8135                     if(count_free_regs(branch_regs[j].regmap)<=minimum_free_regs[j+1])
8136                       break;
8137                   }
8138                   if(get_reg(branch_regs[j].regmap,f_regmap[hr])>=0) {
8139                     //printf("no-match due to different register (branch)\n");
8140                     break;
8141                   }
8142                 }
8143                 if(count_free_regs(regs[j].regmap)<=minimum_free_regs[j]) {
8144                   //printf("No free regs for store %x\n",start+j*4);
8145                   break;
8146                 }
8147                 assert(f_regmap[hr]<64);
8148               }
8149             }
8150           }
8151         }
8152       }
8153     }else{
8154       // Non branch or undetermined branch target
8155       for(hr=0;hr<HOST_REGS;hr++)
8156       {
8157         if(hr!=EXCLUDE_REG) {
8158           if(regs[i].regmap[hr]>=0) {
8159             if(f_regmap[hr]!=regs[i].regmap[hr]) {
8160               // dealloc old register
8161               int n;
8162               for(n=0;n<HOST_REGS;n++)
8163               {
8164                 if(f_regmap[n]==regs[i].regmap[hr]) {f_regmap[n]=-1;}
8165               }
8166               // and alloc new one
8167               f_regmap[hr]=regs[i].regmap[hr];
8168             }
8169           }
8170         }
8171       }
8172       // Try to restore cycle count at branch targets
8173       if(dops[i].bt) {
8174         for(j=i;j<slen-1;j++) {
8175           if(regs[j].regmap[HOST_CCREG]!=-1) break;
8176           if(count_free_regs(regs[j].regmap)<=minimum_free_regs[j]) {
8177             //printf("no free regs for store %x\n",start+j*4);
8178             break;
8179           }
8180         }
8181         if(regs[j].regmap[HOST_CCREG]==CCREG) {
8182           int k=i;
8183           //printf("Extend CC, %x -> %x\n",start+k*4,start+j*4);
8184           while(k<j) {
8185             regs[k].regmap_entry[HOST_CCREG]=CCREG;
8186             regs[k].regmap[HOST_CCREG]=CCREG;
8187             regmap_pre[k+1][HOST_CCREG]=CCREG;
8188             regs[k+1].wasdirty|=1<<HOST_CCREG;
8189             regs[k].dirty|=1<<HOST_CCREG;
8190             regs[k].wasconst&=~(1<<HOST_CCREG);
8191             regs[k].isconst&=~(1<<HOST_CCREG);
8192             k++;
8193           }
8194           regs[j].regmap_entry[HOST_CCREG]=CCREG;
8195         }
8196         // Work backwards from the branch target
8197         if(j>i&&f_regmap[HOST_CCREG]==CCREG)
8198         {
8199           //printf("Extend backwards\n");
8200           int k;
8201           k=i;
8202           while(regs[k-1].regmap[HOST_CCREG]==-1) {
8203             if(count_free_regs(regs[k-1].regmap)<=minimum_free_regs[k-1]) {
8204               //printf("no free regs for store %x\n",start+(k-1)*4);
8205               break;
8206             }
8207             k--;
8208           }
8209           if(regs[k-1].regmap[HOST_CCREG]==CCREG) {
8210             //printf("Extend CC, %x ->\n",start+k*4);
8211             while(k<=i) {
8212               regs[k].regmap_entry[HOST_CCREG]=CCREG;
8213               regs[k].regmap[HOST_CCREG]=CCREG;
8214               regmap_pre[k+1][HOST_CCREG]=CCREG;
8215               regs[k+1].wasdirty|=1<<HOST_CCREG;
8216               regs[k].dirty|=1<<HOST_CCREG;
8217               regs[k].wasconst&=~(1<<HOST_CCREG);
8218               regs[k].isconst&=~(1<<HOST_CCREG);
8219               k++;
8220             }
8221           }
8222           else {
8223             //printf("Fail Extend CC, %x ->\n",start+k*4);
8224           }
8225         }
8226       }
8227       if(dops[i].itype!=STORE&&dops[i].itype!=STORELR&&dops[i].itype!=C1LS&&dops[i].itype!=SHIFT&&
8228          dops[i].itype!=NOP&&dops[i].itype!=MOV&&dops[i].itype!=ALU&&dops[i].itype!=SHIFTIMM&&
8229          dops[i].itype!=IMM16&&dops[i].itype!=LOAD&&dops[i].itype!=COP1)
8230       {
8231         memcpy(f_regmap,regs[i].regmap,sizeof(f_regmap));
8232       }
8233     }
8234   }
8235 }
8236
8237 // This allocates registers (if possible) one instruction prior
8238 // to use, which can avoid a load-use penalty on certain CPUs.
8239 static noinline void pass5b_preallocate2(void)
8240 {
8241   int i, hr;
8242   for(i=0;i<slen-1;i++)
8243   {
8244     if (!i || !dops[i-1].is_jump)
8245     {
8246       if(!dops[i+1].bt)
8247       {
8248         if(dops[i].itype==ALU||dops[i].itype==MOV||dops[i].itype==LOAD||dops[i].itype==SHIFTIMM||dops[i].itype==IMM16
8249            ||((dops[i].itype==COP1||dops[i].itype==COP2)&&dops[i].opcode2<3))
8250         {
8251           if(dops[i+1].rs1) {
8252             if((hr=get_reg(regs[i+1].regmap,dops[i+1].rs1))>=0)
8253             {
8254               if(regs[i].regmap[hr]<0&&regs[i+1].regmap_entry[hr]<0)
8255               {
8256                 regs[i].regmap[hr]=regs[i+1].regmap[hr];
8257                 regmap_pre[i+1][hr]=regs[i+1].regmap[hr];
8258                 regs[i+1].regmap_entry[hr]=regs[i+1].regmap[hr];
8259                 regs[i].isconst&=~(1<<hr);
8260                 regs[i].isconst|=regs[i+1].isconst&(1<<hr);
8261                 constmap[i][hr]=constmap[i+1][hr];
8262                 regs[i+1].wasdirty&=~(1<<hr);
8263                 regs[i].dirty&=~(1<<hr);
8264               }
8265             }
8266           }
8267           if(dops[i+1].rs2) {
8268             if((hr=get_reg(regs[i+1].regmap,dops[i+1].rs2))>=0)
8269             {
8270               if(regs[i].regmap[hr]<0&&regs[i+1].regmap_entry[hr]<0)
8271               {
8272                 regs[i].regmap[hr]=regs[i+1].regmap[hr];
8273                 regmap_pre[i+1][hr]=regs[i+1].regmap[hr];
8274                 regs[i+1].regmap_entry[hr]=regs[i+1].regmap[hr];
8275                 regs[i].isconst&=~(1<<hr);
8276                 regs[i].isconst|=regs[i+1].isconst&(1<<hr);
8277                 constmap[i][hr]=constmap[i+1][hr];
8278                 regs[i+1].wasdirty&=~(1<<hr);
8279                 regs[i].dirty&=~(1<<hr);
8280               }
8281             }
8282           }
8283           // Preload target address for load instruction (non-constant)
8284           if(dops[i+1].itype==LOAD&&dops[i+1].rs1&&get_reg(regs[i+1].regmap,dops[i+1].rs1)<0) {
8285             if((hr=get_reg(regs[i+1].regmap,dops[i+1].rt1))>=0)
8286             {
8287               if(regs[i].regmap[hr]<0&&regs[i+1].regmap_entry[hr]<0)
8288               {
8289                 regs[i].regmap[hr]=dops[i+1].rs1;
8290                 regmap_pre[i+1][hr]=dops[i+1].rs1;
8291                 regs[i+1].regmap_entry[hr]=dops[i+1].rs1;
8292                 regs[i].isconst&=~(1<<hr);
8293                 regs[i].isconst|=regs[i+1].isconst&(1<<hr);
8294                 constmap[i][hr]=constmap[i+1][hr];
8295                 regs[i+1].wasdirty&=~(1<<hr);
8296                 regs[i].dirty&=~(1<<hr);
8297               }
8298             }
8299           }
8300           // Load source into target register
8301           if(dops[i+1].use_lt1&&get_reg(regs[i+1].regmap,dops[i+1].rs1)<0) {
8302             if((hr=get_reg(regs[i+1].regmap,dops[i+1].rt1))>=0)
8303             {
8304               if(regs[i].regmap[hr]<0&&regs[i+1].regmap_entry[hr]<0)
8305               {
8306                 regs[i].regmap[hr]=dops[i+1].rs1;
8307                 regmap_pre[i+1][hr]=dops[i+1].rs1;
8308                 regs[i+1].regmap_entry[hr]=dops[i+1].rs1;
8309                 regs[i].isconst&=~(1<<hr);
8310                 regs[i].isconst|=regs[i+1].isconst&(1<<hr);
8311                 constmap[i][hr]=constmap[i+1][hr];
8312                 regs[i+1].wasdirty&=~(1<<hr);
8313                 regs[i].dirty&=~(1<<hr);
8314               }
8315             }
8316           }
8317           // Address for store instruction (non-constant)
8318           if(dops[i+1].itype==STORE||dops[i+1].itype==STORELR
8319              ||(dops[i+1].opcode&0x3b)==0x39||(dops[i+1].opcode&0x3b)==0x3a) { // SB/SH/SW/SD/SWC1/SDC1/SWC2/SDC2
8320             if(get_reg(regs[i+1].regmap,dops[i+1].rs1)<0) {
8321               hr=get_reg2(regs[i].regmap,regs[i+1].regmap,-1);
8322               if(hr<0) hr=get_reg_temp(regs[i+1].regmap);
8323               else {
8324                 regs[i+1].regmap[hr]=AGEN1+((i+1)&1);
8325                 regs[i+1].isconst&=~(1<<hr);
8326               }
8327               assert(hr>=0);
8328               if(regs[i].regmap[hr]<0&&regs[i+1].regmap_entry[hr]<0)
8329               {
8330                 regs[i].regmap[hr]=dops[i+1].rs1;
8331                 regmap_pre[i+1][hr]=dops[i+1].rs1;
8332                 regs[i+1].regmap_entry[hr]=dops[i+1].rs1;
8333                 regs[i].isconst&=~(1<<hr);
8334                 regs[i].isconst|=regs[i+1].isconst&(1<<hr);
8335                 constmap[i][hr]=constmap[i+1][hr];
8336                 regs[i+1].wasdirty&=~(1<<hr);
8337                 regs[i].dirty&=~(1<<hr);
8338               }
8339             }
8340           }
8341           if(dops[i+1].itype==LOADLR||(dops[i+1].opcode&0x3b)==0x31||(dops[i+1].opcode&0x3b)==0x32) { // LWC1/LDC1, LWC2/LDC2
8342             if(get_reg(regs[i+1].regmap,dops[i+1].rs1)<0) {
8343               int nr;
8344               hr=get_reg(regs[i+1].regmap,FTEMP);
8345               assert(hr>=0);
8346               if(regs[i].regmap[hr]<0&&regs[i+1].regmap_entry[hr]<0)
8347               {
8348                 regs[i].regmap[hr]=dops[i+1].rs1;
8349                 regmap_pre[i+1][hr]=dops[i+1].rs1;
8350                 regs[i+1].regmap_entry[hr]=dops[i+1].rs1;
8351                 regs[i].isconst&=~(1<<hr);
8352                 regs[i].isconst|=regs[i+1].isconst&(1<<hr);
8353                 constmap[i][hr]=constmap[i+1][hr];
8354                 regs[i+1].wasdirty&=~(1<<hr);
8355                 regs[i].dirty&=~(1<<hr);
8356               }
8357               else if((nr=get_reg2(regs[i].regmap,regs[i+1].regmap,-1))>=0)
8358               {
8359                 // move it to another register
8360                 regs[i+1].regmap[hr]=-1;
8361                 regmap_pre[i+2][hr]=-1;
8362                 regs[i+1].regmap[nr]=FTEMP;
8363                 regmap_pre[i+2][nr]=FTEMP;
8364                 regs[i].regmap[nr]=dops[i+1].rs1;
8365                 regmap_pre[i+1][nr]=dops[i+1].rs1;
8366                 regs[i+1].regmap_entry[nr]=dops[i+1].rs1;
8367                 regs[i].isconst&=~(1<<nr);
8368                 regs[i+1].isconst&=~(1<<nr);
8369                 regs[i].dirty&=~(1<<nr);
8370                 regs[i+1].wasdirty&=~(1<<nr);
8371                 regs[i+1].dirty&=~(1<<nr);
8372                 regs[i+2].wasdirty&=~(1<<nr);
8373               }
8374             }
8375           }
8376           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*/) {
8377             hr = -1;
8378             if(dops[i+1].itype==LOAD)
8379               hr=get_reg(regs[i+1].regmap,dops[i+1].rt1);
8380             if(dops[i+1].itype==LOADLR||(dops[i+1].opcode&0x3b)==0x31||(dops[i+1].opcode&0x3b)==0x32) // LWC1/LDC1, LWC2/LDC2
8381               hr=get_reg(regs[i+1].regmap,FTEMP);
8382             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
8383               hr=get_reg(regs[i+1].regmap,AGEN1+((i+1)&1));
8384               if(hr<0) hr=get_reg_temp(regs[i+1].regmap);
8385             }
8386             if(hr>=0&&regs[i].regmap[hr]<0) {
8387               int rs=get_reg(regs[i+1].regmap,dops[i+1].rs1);
8388               if(rs>=0&&((regs[i+1].wasconst>>rs)&1)) {
8389                 regs[i].regmap[hr]=AGEN1+((i+1)&1);
8390                 regmap_pre[i+1][hr]=AGEN1+((i+1)&1);
8391                 regs[i+1].regmap_entry[hr]=AGEN1+((i+1)&1);
8392                 regs[i].isconst&=~(1<<hr);
8393                 regs[i+1].wasdirty&=~(1<<hr);
8394                 regs[i].dirty&=~(1<<hr);
8395               }
8396             }
8397           }
8398         }
8399       }
8400     }
8401   }
8402 }
8403
8404 // Write back dirty registers as soon as we will no longer modify them,
8405 // so that we don't end up with lots of writes at the branches.
8406 static noinline void pass6_clean_registers(int istart, int iend, int wr)
8407 {
8408   static u_int wont_dirty[MAXBLOCK];
8409   static u_int will_dirty[MAXBLOCK];
8410   int i;
8411   int r;
8412   u_int will_dirty_i,will_dirty_next,temp_will_dirty;
8413   u_int wont_dirty_i,wont_dirty_next,temp_wont_dirty;
8414   if(iend==slen-1) {
8415     will_dirty_i=will_dirty_next=0;
8416     wont_dirty_i=wont_dirty_next=0;
8417   }else{
8418     will_dirty_i=will_dirty_next=will_dirty[iend+1];
8419     wont_dirty_i=wont_dirty_next=wont_dirty[iend+1];
8420   }
8421   for (i=iend;i>=istart;i--)
8422   {
8423     signed char rregmap_i[RRMAP_SIZE];
8424     u_int hr_candirty = 0;
8425     assert(HOST_REGS < 32);
8426     make_rregs(regs[i].regmap, rregmap_i, &hr_candirty);
8427     __builtin_prefetch(regs[i-1].regmap);
8428     if(dops[i].is_jump)
8429     {
8430       signed char branch_rregmap_i[RRMAP_SIZE];
8431       u_int branch_hr_candirty = 0;
8432       make_rregs(branch_regs[i].regmap, branch_rregmap_i, &branch_hr_candirty);
8433       if(ba[i]<start || ba[i]>=(start+slen*4))
8434       {
8435         // Branch out of this block, flush all regs
8436         will_dirty_i = 0;
8437         will_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i].rt1) & 31);
8438         will_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i].rt2) & 31);
8439         will_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i+1].rt1) & 31);
8440         will_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i+1].rt2) & 31);
8441         will_dirty_i |= 1u << (get_rreg(branch_rregmap_i, CCREG) & 31);
8442         will_dirty_i &= branch_hr_candirty;
8443         if (dops[i].is_ujump)
8444         {
8445           // Unconditional branch
8446           wont_dirty_i = 0;
8447           // Merge in delay slot (will dirty)
8448           will_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i].rt1) & 31);
8449           will_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i].rt2) & 31);
8450           will_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i+1].rt1) & 31);
8451           will_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i+1].rt2) & 31);
8452           will_dirty_i |= 1u << (get_rreg(rregmap_i, CCREG) & 31);
8453           will_dirty_i &= hr_candirty;
8454         }
8455         else
8456         {
8457           // Conditional branch
8458           wont_dirty_i = wont_dirty_next;
8459           // Merge in delay slot (will dirty)
8460           // (the original code had no explanation why these 2 are commented out)
8461           //will_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i].rt1) & 31);
8462           //will_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i].rt2) & 31);
8463           will_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i+1].rt1) & 31);
8464           will_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i+1].rt2) & 31);
8465           will_dirty_i |= 1u << (get_rreg(rregmap_i, CCREG) & 31);
8466           will_dirty_i &= hr_candirty;
8467         }
8468         // Merge in delay slot (wont dirty)
8469         wont_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i].rt1) & 31);
8470         wont_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i].rt2) & 31);
8471         wont_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i+1].rt1) & 31);
8472         wont_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i+1].rt2) & 31);
8473         wont_dirty_i |= 1u << (get_rreg(rregmap_i, CCREG) & 31);
8474         wont_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i].rt1) & 31);
8475         wont_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i].rt2) & 31);
8476         wont_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i+1].rt1) & 31);
8477         wont_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i+1].rt2) & 31);
8478         wont_dirty_i |= 1u << (get_rreg(branch_rregmap_i, CCREG) & 31);
8479         wont_dirty_i &= ~(1u << 31);
8480         if(wr) {
8481           #ifndef DESTRUCTIVE_WRITEBACK
8482           branch_regs[i].dirty&=wont_dirty_i;
8483           #endif
8484           branch_regs[i].dirty|=will_dirty_i;
8485         }
8486       }
8487       else
8488       {
8489         // Internal branch
8490         if(ba[i]<=start+i*4) {
8491           // Backward branch
8492           if (dops[i].is_ujump)
8493           {
8494             // Unconditional branch
8495             temp_will_dirty=0;
8496             temp_wont_dirty=0;
8497             // Merge in delay slot (will dirty)
8498             temp_will_dirty |= 1u << (get_rreg(branch_rregmap_i, dops[i].rt1) & 31);
8499             temp_will_dirty |= 1u << (get_rreg(branch_rregmap_i, dops[i].rt2) & 31);
8500             temp_will_dirty |= 1u << (get_rreg(branch_rregmap_i, dops[i+1].rt1) & 31);
8501             temp_will_dirty |= 1u << (get_rreg(branch_rregmap_i, dops[i+1].rt2) & 31);
8502             temp_will_dirty |= 1u << (get_rreg(branch_rregmap_i, CCREG) & 31);
8503             temp_will_dirty &= branch_hr_candirty;
8504             temp_will_dirty |= 1u << (get_rreg(rregmap_i, dops[i].rt1) & 31);
8505             temp_will_dirty |= 1u << (get_rreg(rregmap_i, dops[i].rt2) & 31);
8506             temp_will_dirty |= 1u << (get_rreg(rregmap_i, dops[i+1].rt1) & 31);
8507             temp_will_dirty |= 1u << (get_rreg(rregmap_i, dops[i+1].rt2) & 31);
8508             temp_will_dirty |= 1u << (get_rreg(rregmap_i, CCREG) & 31);
8509             temp_will_dirty &= hr_candirty;
8510           } else {
8511             // Conditional branch (not taken case)
8512             temp_will_dirty=will_dirty_next;
8513             temp_wont_dirty=wont_dirty_next;
8514             // Merge in delay slot (will dirty)
8515             temp_will_dirty |= 1u << (get_rreg(branch_rregmap_i, dops[i].rt1) & 31);
8516             temp_will_dirty |= 1u << (get_rreg(branch_rregmap_i, dops[i].rt2) & 31);
8517             temp_will_dirty |= 1u << (get_rreg(branch_rregmap_i, dops[i+1].rt1) & 31);
8518             temp_will_dirty |= 1u << (get_rreg(branch_rregmap_i, dops[i+1].rt2) & 31);
8519             temp_will_dirty |= 1u << (get_rreg(branch_rregmap_i, CCREG) & 31);
8520             temp_will_dirty &= branch_hr_candirty;
8521             //temp_will_dirty |= 1u << (get_rreg(rregmap_i, dops[i].rt1) & 31);
8522             //temp_will_dirty |= 1u << (get_rreg(rregmap_i, dops[i].rt2) & 31);
8523             temp_will_dirty |= 1u << (get_rreg(rregmap_i, dops[i+1].rt1) & 31);
8524             temp_will_dirty |= 1u << (get_rreg(rregmap_i, dops[i+1].rt2) & 31);
8525             temp_will_dirty |= 1u << (get_rreg(rregmap_i, CCREG) & 31);
8526             temp_will_dirty &= hr_candirty;
8527           }
8528           // Merge in delay slot (wont dirty)
8529           temp_wont_dirty |= 1u << (get_rreg(rregmap_i, dops[i].rt1) & 31);
8530           temp_wont_dirty |= 1u << (get_rreg(rregmap_i, dops[i].rt2) & 31);
8531           temp_wont_dirty |= 1u << (get_rreg(rregmap_i, dops[i+1].rt1) & 31);
8532           temp_wont_dirty |= 1u << (get_rreg(rregmap_i, dops[i+1].rt2) & 31);
8533           temp_wont_dirty |= 1u << (get_rreg(rregmap_i, CCREG) & 31);
8534           temp_wont_dirty |= 1u << (get_rreg(branch_rregmap_i, dops[i].rt1) & 31);
8535           temp_wont_dirty |= 1u << (get_rreg(branch_rregmap_i, dops[i].rt2) & 31);
8536           temp_wont_dirty |= 1u << (get_rreg(branch_rregmap_i, dops[i+1].rt1) & 31);
8537           temp_wont_dirty |= 1u << (get_rreg(branch_rregmap_i, dops[i+1].rt2) & 31);
8538           temp_wont_dirty |= 1u << (get_rreg(branch_rregmap_i, CCREG) & 31);
8539           temp_wont_dirty &= ~(1u << 31);
8540           // Deal with changed mappings
8541           if(i<iend) {
8542             for(r=0;r<HOST_REGS;r++) {
8543               if(r!=EXCLUDE_REG) {
8544                 if(regs[i].regmap[r]!=regmap_pre[i][r]) {
8545                   temp_will_dirty&=~(1<<r);
8546                   temp_wont_dirty&=~(1<<r);
8547                   if(regmap_pre[i][r]>0 && regmap_pre[i][r]<34) {
8548                     temp_will_dirty|=((unneeded_reg[i]>>regmap_pre[i][r])&1)<<r;
8549                     temp_wont_dirty|=((unneeded_reg[i]>>regmap_pre[i][r])&1)<<r;
8550                   } else {
8551                     temp_will_dirty|=1<<r;
8552                     temp_wont_dirty|=1<<r;
8553                   }
8554                 }
8555               }
8556             }
8557           }
8558           if(wr) {
8559             will_dirty[i]=temp_will_dirty;
8560             wont_dirty[i]=temp_wont_dirty;
8561             pass6_clean_registers((ba[i]-start)>>2,i-1,0);
8562           }else{
8563             // Limit recursion.  It can take an excessive amount
8564             // of time if there are a lot of nested loops.
8565             will_dirty[(ba[i]-start)>>2]=0;
8566             wont_dirty[(ba[i]-start)>>2]=-1;
8567           }
8568         }
8569         /*else*/ if(1)
8570         {
8571           if (dops[i].is_ujump)
8572           {
8573             // Unconditional branch
8574             will_dirty_i=0;
8575             wont_dirty_i=0;
8576           //if(ba[i]>start+i*4) { // Disable recursion (for debugging)
8577             for(r=0;r<HOST_REGS;r++) {
8578               if(r!=EXCLUDE_REG) {
8579                 if(branch_regs[i].regmap[r]==regs[(ba[i]-start)>>2].regmap_entry[r]) {
8580                   will_dirty_i|=will_dirty[(ba[i]-start)>>2]&(1<<r);
8581                   wont_dirty_i|=wont_dirty[(ba[i]-start)>>2]&(1<<r);
8582                 }
8583                 if(branch_regs[i].regmap[r]>=0) {
8584                   will_dirty_i|=((unneeded_reg[(ba[i]-start)>>2]>>branch_regs[i].regmap[r])&1)<<r;
8585                   wont_dirty_i|=((unneeded_reg[(ba[i]-start)>>2]>>branch_regs[i].regmap[r])&1)<<r;
8586                 }
8587               }
8588             }
8589           //}
8590             // Merge in delay slot
8591             will_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i].rt1) & 31);
8592             will_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i].rt2) & 31);
8593             will_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i+1].rt1) & 31);
8594             will_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i+1].rt2) & 31);
8595             will_dirty_i |= 1u << (get_rreg(branch_rregmap_i, CCREG) & 31);
8596             will_dirty_i &= branch_hr_candirty;
8597             will_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i].rt1) & 31);
8598             will_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i].rt2) & 31);
8599             will_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i+1].rt1) & 31);
8600             will_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i+1].rt2) & 31);
8601             will_dirty_i |= 1u << (get_rreg(rregmap_i, CCREG) & 31);
8602             will_dirty_i &= hr_candirty;
8603           } else {
8604             // Conditional branch
8605             will_dirty_i=will_dirty_next;
8606             wont_dirty_i=wont_dirty_next;
8607           //if(ba[i]>start+i*4) // Disable recursion (for debugging)
8608             for(r=0;r<HOST_REGS;r++) {
8609               if(r!=EXCLUDE_REG) {
8610                 signed char target_reg=branch_regs[i].regmap[r];
8611                 if(target_reg==regs[(ba[i]-start)>>2].regmap_entry[r]) {
8612                   will_dirty_i&=will_dirty[(ba[i]-start)>>2]&(1<<r);
8613                   wont_dirty_i|=wont_dirty[(ba[i]-start)>>2]&(1<<r);
8614                 }
8615                 else if(target_reg>=0) {
8616                   will_dirty_i&=((unneeded_reg[(ba[i]-start)>>2]>>target_reg)&1)<<r;
8617                   wont_dirty_i|=((unneeded_reg[(ba[i]-start)>>2]>>target_reg)&1)<<r;
8618                 }
8619               }
8620             }
8621             // Merge in delay slot
8622             will_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i].rt1) & 31);
8623             will_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i].rt2) & 31);
8624             will_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i+1].rt1) & 31);
8625             will_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i+1].rt2) & 31);
8626             will_dirty_i |= 1u << (get_rreg(branch_rregmap_i, CCREG) & 31);
8627             will_dirty_i &= branch_hr_candirty;
8628             //will_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i].rt1) & 31);
8629             //will_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i].rt2) & 31);
8630             will_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i+1].rt1) & 31);
8631             will_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i+1].rt2) & 31);
8632             will_dirty_i |= 1u << (get_rreg(rregmap_i, CCREG) & 31);
8633             will_dirty_i &= hr_candirty;
8634           }
8635           // Merge in delay slot (won't dirty)
8636           wont_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i].rt1) & 31);
8637           wont_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i].rt2) & 31);
8638           wont_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i+1].rt1) & 31);
8639           wont_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i+1].rt2) & 31);
8640           wont_dirty_i |= 1u << (get_rreg(rregmap_i, CCREG) & 31);
8641           wont_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i].rt1) & 31);
8642           wont_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i].rt2) & 31);
8643           wont_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i+1].rt1) & 31);
8644           wont_dirty_i |= 1u << (get_rreg(branch_rregmap_i, dops[i+1].rt2) & 31);
8645           wont_dirty_i |= 1u << (get_rreg(branch_rregmap_i, CCREG) & 31);
8646           wont_dirty_i &= ~(1u << 31);
8647           if(wr) {
8648             #ifndef DESTRUCTIVE_WRITEBACK
8649             branch_regs[i].dirty&=wont_dirty_i;
8650             #endif
8651             branch_regs[i].dirty|=will_dirty_i;
8652           }
8653         }
8654       }
8655     }
8656     else if(dops[i].itype==SYSCALL||dops[i].itype==HLECALL||dops[i].itype==INTCALL)
8657     {
8658       // SYSCALL instruction (software interrupt)
8659       will_dirty_i=0;
8660       wont_dirty_i=0;
8661     }
8662     else if(dops[i].itype==COP0 && (source[i]&0x3f)==0x18)
8663     {
8664       // ERET instruction (return from interrupt)
8665       will_dirty_i=0;
8666       wont_dirty_i=0;
8667     }
8668     will_dirty_next=will_dirty_i;
8669     wont_dirty_next=wont_dirty_i;
8670     will_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i].rt1) & 31);
8671     will_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i].rt2) & 31);
8672     will_dirty_i |= 1u << (get_rreg(rregmap_i, CCREG) & 31);
8673     will_dirty_i &= hr_candirty;
8674     wont_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i].rt1) & 31);
8675     wont_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i].rt2) & 31);
8676     wont_dirty_i |= 1u << (get_rreg(rregmap_i, CCREG) & 31);
8677     wont_dirty_i &= ~(1u << 31);
8678     if (i > istart && !dops[i].is_jump) {
8679       // Don't store a register immediately after writing it,
8680       // may prevent dual-issue.
8681       wont_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i-1].rt1) & 31);
8682       wont_dirty_i |= 1u << (get_rreg(rregmap_i, dops[i-1].rt2) & 31);
8683     }
8684     // Save it
8685     will_dirty[i]=will_dirty_i;
8686     wont_dirty[i]=wont_dirty_i;
8687     // Mark registers that won't be dirtied as not dirty
8688     if(wr) {
8689         regs[i].dirty|=will_dirty_i;
8690         #ifndef DESTRUCTIVE_WRITEBACK
8691         regs[i].dirty&=wont_dirty_i;
8692         if(dops[i].is_jump)
8693         {
8694           if (i < iend-1 && !dops[i].is_ujump) {
8695             for(r=0;r<HOST_REGS;r++) {
8696               if(r!=EXCLUDE_REG) {
8697                 if(regs[i].regmap[r]==regmap_pre[i+2][r]) {
8698                   regs[i+2].wasdirty&=wont_dirty_i|~(1<<r);
8699                 }else {/*printf("i: %x (%d) mismatch(+2): %d\n",start+i*4,i,r);assert(!((wont_dirty_i>>r)&1));*/}
8700               }
8701             }
8702           }
8703         }
8704         else
8705         {
8706           if(i<iend) {
8707             for(r=0;r<HOST_REGS;r++) {
8708               if(r!=EXCLUDE_REG) {
8709                 if(regs[i].regmap[r]==regmap_pre[i+1][r]) {
8710                   regs[i+1].wasdirty&=wont_dirty_i|~(1<<r);
8711                 }else {/*printf("i: %x (%d) mismatch(+1): %d\n",start+i*4,i,r);assert(!((wont_dirty_i>>r)&1));*/}
8712               }
8713             }
8714           }
8715         }
8716         #endif
8717     }
8718     // Deal with changed mappings
8719     temp_will_dirty=will_dirty_i;
8720     temp_wont_dirty=wont_dirty_i;
8721     for(r=0;r<HOST_REGS;r++) {
8722       if(r!=EXCLUDE_REG) {
8723         int nr;
8724         if(regs[i].regmap[r]==regmap_pre[i][r]) {
8725           if(wr) {
8726             #ifndef DESTRUCTIVE_WRITEBACK
8727             regs[i].wasdirty&=wont_dirty_i|~(1<<r);
8728             #endif
8729             regs[i].wasdirty|=will_dirty_i&(1<<r);
8730           }
8731         }
8732         else if(regmap_pre[i][r]>=0&&(nr=get_rreg(rregmap_i,regmap_pre[i][r]))>=0) {
8733           // Register moved to a different register
8734           will_dirty_i&=~(1<<r);
8735           wont_dirty_i&=~(1<<r);
8736           will_dirty_i|=((temp_will_dirty>>nr)&1)<<r;
8737           wont_dirty_i|=((temp_wont_dirty>>nr)&1)<<r;
8738           if(wr) {
8739             #ifndef DESTRUCTIVE_WRITEBACK
8740             regs[i].wasdirty&=wont_dirty_i|~(1<<r);
8741             #endif
8742             regs[i].wasdirty|=will_dirty_i&(1<<r);
8743           }
8744         }
8745         else {
8746           will_dirty_i&=~(1<<r);
8747           wont_dirty_i&=~(1<<r);
8748           if(regmap_pre[i][r]>0 && regmap_pre[i][r]<34) {
8749             will_dirty_i|=((unneeded_reg[i]>>regmap_pre[i][r])&1)<<r;
8750             wont_dirty_i|=((unneeded_reg[i]>>regmap_pre[i][r])&1)<<r;
8751           } else {
8752             wont_dirty_i|=1<<r;
8753             /*printf("i: %x (%d) mismatch: %d\n",start+i*4,i,r);assert(!((will_dirty>>r)&1));*/
8754           }
8755         }
8756       }
8757     }
8758   }
8759 }
8760
8761 static noinline void pass10_expire_blocks(void)
8762 {
8763   int i, end;
8764   end = (((out-ndrc->translation_cache)>>(TARGET_SIZE_2-16)) + 16384) & 65535;
8765   while (expirep != end)
8766   {
8767     int shift=TARGET_SIZE_2-3; // Divide into 8 blocks
8768     uintptr_t base_offs = ((uintptr_t)(expirep >> 13) << shift); // Base offset of this block
8769     uintptr_t base_offs_s = base_offs >> shift;
8770     if (!(expirep & ((1 << 13) - 1)))
8771       inv_debug("EXP: base_offs %x\n", base_offs);
8772     switch((expirep>>11)&3)
8773     {
8774       case 0:
8775         // Clear blocks
8776         blocks_remove_matching_addrs(&blocks[expirep & 2047], base_offs_s, shift);
8777         blocks_remove_matching_addrs(&blocks[2048 + (expirep & 2047)], base_offs_s, shift);
8778         break;
8779       case 1:
8780         // Clear pointers
8781         //ll_kill_pointers(jump_out[expirep&2047],base_offs_s,shift);
8782         //ll_kill_pointers(jump_out[(expirep&2047)+2048],base_offs_s,shift);
8783         break;
8784       case 2:
8785         // Clear hash table
8786         for(i=0;i<32;i++) {
8787           struct ht_entry *ht_bin = &hash_table[((expirep&2047)<<5)+i];
8788           uintptr_t o1 = (u_char *)ht_bin->tcaddr[1] - ndrc->translation_cache;
8789           uintptr_t o2 = o1 - MAX_OUTPUT_BLOCK_SIZE;
8790           if ((o1 >> shift) == base_offs_s || (o2 >> shift) == base_offs_s) {
8791             inv_debug("EXP: Remove hash %x -> %p\n",ht_bin->vaddr[1],ht_bin->tcaddr[1]);
8792             ht_bin->vaddr[1] = -1;
8793             ht_bin->tcaddr[1] = NULL;
8794           }
8795           o1 = (u_char *)ht_bin->tcaddr[0] - ndrc->translation_cache;
8796           o2 = o1 - MAX_OUTPUT_BLOCK_SIZE;
8797           if ((o1 >> shift) == base_offs_s || (o2 >> shift) == base_offs_s) {
8798             inv_debug("EXP: Remove hash %x -> %p\n",ht_bin->vaddr[0],ht_bin->tcaddr[0]);
8799             ht_bin->vaddr[0] = ht_bin->vaddr[1];
8800             ht_bin->tcaddr[0] = ht_bin->tcaddr[1];
8801             ht_bin->vaddr[1] = -1;
8802             ht_bin->tcaddr[1] = NULL;
8803           }
8804         }
8805         break;
8806       case 3:
8807         // Clear jump_out
8808         if((expirep&2047)==0)
8809           do_clear_cache();
8810         ll_remove_matching_addrs(jump_out+(expirep&2047),base_offs_s,shift);
8811         ll_remove_matching_addrs(jump_out+2048+(expirep&2047),base_offs_s,shift);
8812         break;
8813     }
8814     expirep=(expirep+1)&65535;
8815   }
8816 }
8817
8818 static struct block_info *new_block_info(u_int start, u_int len,
8819   const void *source, const void *copy, u_char *beginning, u_short jump_in_count)
8820 {
8821   struct block_info **b_pptr;
8822   struct block_info *block;
8823   u_int page = get_page(start);
8824
8825   block = malloc(sizeof(*block) + jump_in_count * sizeof(block->jump_in[0]));
8826   assert(block);
8827   assert(jump_in_count > 0);
8828   block->source = source;
8829   block->copy = copy;
8830   block->start = start;
8831   block->len = len;
8832   block->reg_sv_flags = 0;
8833   block->tc_offs = beginning - ndrc->translation_cache;
8834   //block->tc_len = out - beginning;
8835   block->is_dirty = 0;
8836   block->jump_in_cnt = jump_in_count;
8837
8838   // insert sorted by start vaddr
8839   for (b_pptr = &blocks[page]; ; b_pptr = &((*b_pptr)->next)) {
8840     if (*b_pptr == NULL || (*b_pptr)->start >= start) {
8841       block->next = *b_pptr;
8842       *b_pptr = block;
8843       break;
8844     }
8845   }
8846   stat_inc(stat_blocks);
8847   return block;
8848 }
8849
8850 static int new_recompile_block(u_int addr)
8851 {
8852   u_int pagelimit = 0;
8853   u_int state_rflags = 0;
8854   int i;
8855
8856   assem_debug("NOTCOMPILED: addr = %x -> %p\n", addr, out);
8857
8858   // this is just for speculation
8859   for (i = 1; i < 32; i++) {
8860     if ((psxRegs.GPR.r[i] & 0xffff0000) == 0x1f800000)
8861       state_rflags |= 1 << i;
8862   }
8863
8864   assert(!(addr & 3));
8865   start = addr & ~3;
8866   new_dynarec_did_compile=1;
8867   if (Config.HLE && start == 0x80001000) // hlecall
8868   {
8869     // XXX: is this enough? Maybe check hleSoftCall?
8870     void *beginning = start_block();
8871
8872     emit_movimm(start,0);
8873     emit_writeword(0,&pcaddr);
8874     emit_far_jump(new_dyna_leave);
8875     literal_pool(0);
8876     end_block(beginning);
8877     struct block_info *block = new_block_info(start, 4, NULL, NULL, beginning, 1);
8878     block->jump_in[0].vaddr = start;
8879     block->jump_in[0].addr = beginning;
8880     return 0;
8881   }
8882   else if (f1_hack && hack_addr == 0) {
8883     void *beginning = start_block();
8884     emit_movimm(start, 0);
8885     emit_writeword(0, &hack_addr);
8886     emit_readword(&psxRegs.GPR.n.sp, 0);
8887     emit_readptr(&mem_rtab, 1);
8888     emit_shrimm(0, 12, 2);
8889     emit_readptr_dualindexedx_ptrlen(1, 2, 1);
8890     emit_addimm(0, 0x18, 0);
8891     emit_adds_ptr(1, 1, 1);
8892     emit_ldr_dualindexed(1, 0, 0);
8893     emit_writeword(0, &psxRegs.GPR.r[26]); // lw k0, 0x18(sp)
8894     emit_far_call(ndrc_get_addr_ht);
8895     emit_jmpreg(0); // jr k0
8896     literal_pool(0);
8897     end_block(beginning);
8898
8899     struct block_info *block = new_block_info(start, 4, NULL, NULL, beginning, 1);
8900     block->jump_in[0].vaddr = start;
8901     block->jump_in[0].addr = beginning;
8902     SysPrintf("F1 hack to   %08x\n", start);
8903     return 0;
8904   }
8905
8906   cycle_multiplier_active = cycle_multiplier_override && cycle_multiplier == CYCLE_MULT_DEFAULT
8907     ? cycle_multiplier_override : cycle_multiplier;
8908
8909   source = get_source_start(start, &pagelimit);
8910   if (source == NULL) {
8911     if (addr != hack_addr) {
8912       SysPrintf("Compile at bogus memory address: %08x\n", addr);
8913       hack_addr = addr;
8914     }
8915     //abort();
8916     return -1;
8917   }
8918
8919   /* Pass 1: disassemble */
8920   /* Pass 2: register dependencies, branch targets */
8921   /* Pass 3: register allocation */
8922   /* Pass 4: branch dependencies */
8923   /* Pass 5: pre-alloc */
8924   /* Pass 6: optimize clean/dirty state */
8925   /* Pass 7: flag 32-bit registers */
8926   /* Pass 8: assembly */
8927   /* Pass 9: linker */
8928   /* Pass 10: garbage collection / free memory */
8929
8930   /* Pass 1 disassembly */
8931
8932   pass1_disassemble(pagelimit);
8933
8934   int clear_hack_addr = apply_hacks();
8935
8936   /* Pass 2 - Register dependencies and branch targets */
8937
8938   pass2_unneeded_regs(0,slen-1,0);
8939
8940   /* Pass 3 - Register allocation */
8941
8942   pass3_register_alloc(addr);
8943
8944   /* Pass 4 - Cull unused host registers */
8945
8946   pass4_cull_unused_regs();
8947
8948   /* Pass 5 - Pre-allocate registers */
8949
8950   pass5a_preallocate1();
8951   pass5b_preallocate2();
8952
8953   /* Pass 6 - Optimize clean/dirty state */
8954   pass6_clean_registers(0, slen-1, 1);
8955
8956   /* Pass 7 - Identify 32-bit registers */
8957   for (i=slen-1;i>=0;i--)
8958   {
8959     if(dops[i].itype==CJUMP||dops[i].itype==SJUMP)
8960     {
8961       // Conditional branch
8962       if((source[i]>>16)!=0x1000&&i<slen-2) {
8963         // Mark this address as a branch target since it may be called
8964         // upon return from interrupt
8965         dops[i+2].bt=1;
8966       }
8967     }
8968   }
8969
8970   /* Pass 8 - Assembly */
8971   linkcount=0;stubcount=0;
8972   is_delayslot=0;
8973   u_int dirty_pre=0;
8974   void *beginning=start_block();
8975   void *instr_addr0_override = NULL;
8976   int ds = 0;
8977
8978   if (start == 0x80030000) {
8979     // nasty hack for the fastbios thing
8980     // override block entry to this code
8981     instr_addr0_override = out;
8982     emit_movimm(start,0);
8983     // abuse io address var as a flag that we
8984     // have already returned here once
8985     emit_readword(&address,1);
8986     emit_writeword(0,&pcaddr);
8987     emit_writeword(0,&address);
8988     emit_cmp(0,1);
8989     #ifdef __aarch64__
8990     emit_jeq(out + 4*2);
8991     emit_far_jump(new_dyna_leave);
8992     #else
8993     emit_jne(new_dyna_leave);
8994     #endif
8995   }
8996   for(i=0;i<slen;i++)
8997   {
8998     __builtin_prefetch(regs[i+1].regmap);
8999     check_regmap(regmap_pre[i]);
9000     check_regmap(regs[i].regmap_entry);
9001     check_regmap(regs[i].regmap);
9002     //if(ds) printf("ds: ");
9003     disassemble_inst(i);
9004     if(ds) {
9005       ds=0; // Skip delay slot
9006       if(dops[i].bt) assem_debug("OOPS - branch into delay slot\n");
9007       instr_addr[i] = NULL;
9008     } else {
9009       speculate_register_values(i);
9010       #ifndef DESTRUCTIVE_WRITEBACK
9011       if (i < 2 || !dops[i-2].is_ujump)
9012       {
9013         wb_valid(regmap_pre[i],regs[i].regmap_entry,dirty_pre,regs[i].wasdirty,unneeded_reg[i]);
9014       }
9015       if((dops[i].itype==CJUMP||dops[i].itype==SJUMP)) {
9016         dirty_pre=branch_regs[i].dirty;
9017       }else{
9018         dirty_pre=regs[i].dirty;
9019       }
9020       #endif
9021       // write back
9022       if (i < 2 || !dops[i-2].is_ujump)
9023       {
9024         wb_invalidate(regmap_pre[i],regs[i].regmap_entry,regs[i].wasdirty,unneeded_reg[i]);
9025         loop_preload(regmap_pre[i],regs[i].regmap_entry);
9026       }
9027       // branch target entry point
9028       instr_addr[i] = out;
9029       assem_debug("<->\n");
9030       drc_dbg_emit_do_cmp(i, ccadj[i]);
9031       if (clear_hack_addr) {
9032         emit_movimm(0, 0);
9033         emit_writeword(0, &hack_addr);
9034         clear_hack_addr = 0;
9035       }
9036
9037       // load regs
9038       if(regs[i].regmap_entry[HOST_CCREG]==CCREG&&regs[i].regmap[HOST_CCREG]!=CCREG)
9039         wb_register(CCREG,regs[i].regmap_entry,regs[i].wasdirty);
9040       load_regs(regs[i].regmap_entry,regs[i].regmap,dops[i].rs1,dops[i].rs2);
9041       address_generation(i,&regs[i],regs[i].regmap_entry);
9042       load_consts(regmap_pre[i],regs[i].regmap,i);
9043       if(dops[i].is_jump)
9044       {
9045         // Load the delay slot registers if necessary
9046         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))
9047           load_regs(regs[i].regmap_entry,regs[i].regmap,dops[i+1].rs1,dops[i+1].rs1);
9048         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))
9049           load_regs(regs[i].regmap_entry,regs[i].regmap,dops[i+1].rs2,dops[i+1].rs2);
9050         if (ram_offset && (dops[i+1].is_load || dops[i+1].is_store))
9051           load_reg(regs[i].regmap_entry,regs[i].regmap,ROREG);
9052         if (dops[i+1].is_store)
9053           load_reg(regs[i].regmap_entry,regs[i].regmap,INVCP);
9054       }
9055       else if(i+1<slen)
9056       {
9057         // Preload registers for following instruction
9058         if(dops[i+1].rs1!=dops[i].rs1&&dops[i+1].rs1!=dops[i].rs2)
9059           if(dops[i+1].rs1!=dops[i].rt1&&dops[i+1].rs1!=dops[i].rt2)
9060             load_regs(regs[i].regmap_entry,regs[i].regmap,dops[i+1].rs1,dops[i+1].rs1);
9061         if(dops[i+1].rs2!=dops[i+1].rs1&&dops[i+1].rs2!=dops[i].rs1&&dops[i+1].rs2!=dops[i].rs2)
9062           if(dops[i+1].rs2!=dops[i].rt1&&dops[i+1].rs2!=dops[i].rt2)
9063             load_regs(regs[i].regmap_entry,regs[i].regmap,dops[i+1].rs2,dops[i+1].rs2);
9064       }
9065       // TODO: if(is_ooo(i)) address_generation(i+1);
9066       if (!dops[i].is_jump || dops[i].itype == CJUMP)
9067         load_reg(regs[i].regmap_entry,regs[i].regmap,CCREG);
9068       if (ram_offset && (dops[i].is_load || dops[i].is_store))
9069         load_reg(regs[i].regmap_entry,regs[i].regmap,ROREG);
9070       if (dops[i].is_store)
9071         load_reg(regs[i].regmap_entry,regs[i].regmap,INVCP);
9072
9073       ds = assemble(i, &regs[i], ccadj[i]);
9074
9075       if (dops[i].is_ujump)
9076         literal_pool(1024);
9077       else
9078         literal_pool_jumpover(256);
9079     }
9080   }
9081
9082   assert(slen > 0);
9083   if (slen > 0 && dops[slen-1].itype == INTCALL) {
9084     // no ending needed for this block since INTCALL never returns
9085   }
9086   // If the block did not end with an unconditional branch,
9087   // add a jump to the next instruction.
9088   else if (i > 1) {
9089     if (!dops[i-2].is_ujump) {
9090       assert(!dops[i-1].is_jump);
9091       assert(i==slen);
9092       if(dops[i-2].itype!=CJUMP&&dops[i-2].itype!=SJUMP) {
9093         store_regs_bt(regs[i-1].regmap,regs[i-1].dirty,start+i*4);
9094         if(regs[i-1].regmap[HOST_CCREG]!=CCREG)
9095           emit_loadreg(CCREG,HOST_CCREG);
9096         emit_addimm(HOST_CCREG, ccadj[i-1] + CLOCK_ADJUST(1), HOST_CCREG);
9097       }
9098       else
9099       {
9100         store_regs_bt(branch_regs[i-2].regmap,branch_regs[i-2].dirty,start+i*4);
9101         assert(branch_regs[i-2].regmap[HOST_CCREG]==CCREG);
9102       }
9103       add_to_linker(out,start+i*4,0);
9104       emit_jmp(0);
9105     }
9106   }
9107   else
9108   {
9109     assert(i>0);
9110     assert(!dops[i-1].is_jump);
9111     store_regs_bt(regs[i-1].regmap,regs[i-1].dirty,start+i*4);
9112     if(regs[i-1].regmap[HOST_CCREG]!=CCREG)
9113       emit_loadreg(CCREG,HOST_CCREG);
9114     emit_addimm(HOST_CCREG, ccadj[i-1] + CLOCK_ADJUST(1), HOST_CCREG);
9115     add_to_linker(out,start+i*4,0);
9116     emit_jmp(0);
9117   }
9118
9119   // TODO: delay slot stubs?
9120   // Stubs
9121   for(i=0;i<stubcount;i++)
9122   {
9123     switch(stubs[i].type)
9124     {
9125       case LOADB_STUB:
9126       case LOADH_STUB:
9127       case LOADW_STUB:
9128       case LOADD_STUB:
9129       case LOADBU_STUB:
9130       case LOADHU_STUB:
9131         do_readstub(i);break;
9132       case STOREB_STUB:
9133       case STOREH_STUB:
9134       case STOREW_STUB:
9135       case STORED_STUB:
9136         do_writestub(i);break;
9137       case CC_STUB:
9138         do_ccstub(i);break;
9139       case INVCODE_STUB:
9140         do_invstub(i);break;
9141       case FP_STUB:
9142         do_cop1stub(i);break;
9143       case STORELR_STUB:
9144         do_unalignedwritestub(i);break;
9145     }
9146   }
9147
9148   if (instr_addr0_override)
9149     instr_addr[0] = instr_addr0_override;
9150
9151   /* Pass 9 - Linker */
9152   for(i=0;i<linkcount;i++)
9153   {
9154     assem_debug("%p -> %8x\n",link_addr[i].addr,link_addr[i].target);
9155     literal_pool(64);
9156     if (!link_addr[i].internal)
9157     {
9158       void *stub = out;
9159       void *addr = check_addr(link_addr[i].target);
9160       emit_extjump(link_addr[i].addr, link_addr[i].target);
9161       if (addr) {
9162         set_jump_target(link_addr[i].addr, addr);
9163         ndrc_add_jump_out(link_addr[i].target,stub);
9164       }
9165       else
9166         set_jump_target(link_addr[i].addr, stub);
9167     }
9168     else
9169     {
9170       // Internal branch
9171       int target=(link_addr[i].target-start)>>2;
9172       assert(target>=0&&target<slen);
9173       assert(instr_addr[target]);
9174       //#ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
9175       //set_jump_target_fillslot(link_addr[i].addr,instr_addr[target],link_addr[i].ext>>1);
9176       //#else
9177       set_jump_target(link_addr[i].addr, instr_addr[target]);
9178       //#endif
9179     }
9180   }
9181
9182   u_int source_len = slen*4;
9183   if (dops[slen-1].itype == INTCALL && source_len > 4)
9184     // no need to treat the last instruction as compiled
9185     // as interpreter fully handles it
9186     source_len -= 4;
9187
9188   if ((u_char *)copy + source_len > (u_char *)shadow + sizeof(shadow))
9189     copy = shadow;
9190
9191   // External Branch Targets (jump_in)
9192   int jump_in_count = 1;
9193   assert(instr_addr[0]);
9194   for (i = 1; i < slen; i++)
9195   {
9196     if (dops[i].bt && instr_addr[i])
9197       jump_in_count++;
9198   }
9199
9200   struct block_info *block =
9201     new_block_info(start, slen * 4, source, copy, beginning, jump_in_count);
9202   block->reg_sv_flags = state_rflags;
9203
9204   int jump_in_i = 0;
9205   for (i = 0; i < slen; i++)
9206   {
9207     if ((i == 0 || dops[i].bt) && instr_addr[i])
9208     {
9209       assem_debug("%p (%d) <- %8x\n", instr_addr[i], i, start + i*4);
9210       u_int vaddr = start + i*4;
9211
9212       literal_pool(256);
9213       void *entry = out;
9214       load_regs_entry(i);
9215       if (entry == out)
9216         entry = instr_addr[i];
9217       else
9218         emit_jmp(instr_addr[i]);
9219
9220       block->jump_in[jump_in_i].vaddr = vaddr;
9221       block->jump_in[jump_in_i].addr = entry;
9222       jump_in_i++;
9223     }
9224   }
9225   assert(jump_in_i == jump_in_count);
9226   hash_table_add(block->jump_in[0].vaddr, block->jump_in[0].addr);
9227   // Write out the literal pool if necessary
9228   literal_pool(0);
9229   #ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
9230   // Align code
9231   if(((u_int)out)&7) emit_addnop(13);
9232   #endif
9233   assert(out - (u_char *)beginning < MAX_OUTPUT_BLOCK_SIZE);
9234   //printf("shadow buffer: %p-%p\n",copy,(u_char *)copy+slen*4);
9235   memcpy(copy, source, source_len);
9236   copy += source_len;
9237
9238   end_block(beginning);
9239
9240   // If we're within 256K of the end of the buffer,
9241   // start over from the beginning. (Is 256K enough?)
9242   if (out > ndrc->translation_cache + sizeof(ndrc->translation_cache) - MAX_OUTPUT_BLOCK_SIZE)
9243     out = ndrc->translation_cache;
9244
9245   // Trap writes to any of the pages we compiled
9246   mark_invalid_code(start, slen*4, 0);
9247
9248   /* Pass 10 - Free memory by expiring oldest blocks */
9249
9250   pass10_expire_blocks();
9251
9252 #ifdef ASSEM_PRINT
9253   fflush(stdout);
9254 #endif
9255   stat_inc(stat_bc_direct);
9256   return 0;
9257 }
9258
9259 // vim:shiftwidth=2:expandtab