drc: implement memory access speculation
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / pcsxmem_inline.c
CommitLineData
cbbab9cd 1/*
2 * (C) GraÅžvydas "notaz" Ignotas, 2011
3 *
4 * This work is licensed under the terms of GNU GPL version 2 or later.
5 * See the COPYING file in the top-level directory.
6 */
7
8static int emit_ldr_type(int type, int offs, int rs, int rt)
9{
10 switch(type) {
11 case LOADB_STUB:
12 emit_movsbl_indexed(offs,rs,rt);
13 break;
14 case LOADBU_STUB:
15 emit_movzbl_indexed(offs,rs,rt);
16 break;
17 case LOADH_STUB:
18 emit_movswl_indexed(offs,rs,rt);
19 break;
20 case LOADHU_STUB:
21 emit_movzwl_indexed(offs,rs,rt);
22 break;
23 case LOADW_STUB:
24 emit_readword_indexed(offs,rs,rt);
25 break;
26 default:
27 assert(0);
28 }
29}
30
31static int emit_str_type(int type, int offs, int rs, int rt)
32{
33 switch(type) {
34 case STOREB_STUB:
35 emit_writebyte_indexed(rt,offs,rs);
36 break;
37 case STOREH_STUB:
38 emit_writehword_indexed(rt,offs,rs);
39 break;
40 case STOREW_STUB:
41 emit_writeword_indexed(rt,offs,rs);
42 break;
43 default:
44 assert(0);
45 }
46}
47
48static void convert_ram_addr(u_int a_rs, u_int a_rt, int rs, int rt)
49{
50 if(rs<0)
51 emit_movimm(a_rt,rt);
52 else if((a_rs&~0x60000000)==a_rt)
53 emit_andimm(rs,~0x60000000,rt);
54 else if((a_rs&~0x00600000)==a_rt)
55 emit_andimm(rs,~0x00600000,rt);
56 else
57 emit_movimm(a_rt,rt);
58}
59
60static int pcsx_direct_read(int type, u_int addr, int rs, int rt)
61{
62 if((addr & 0x1f800000) == 0) {
63 assem_debug("pcsx_direct_read %08x ram\n",addr);
64 if(rt<0)
65 return 1;
66 u_int a=(addr&~0x60600000)|0x80000000;
67 convert_ram_addr(addr,a,rs,rt);
68 emit_ldr_type(type,0,rt,rt);
69 return 1;
70 }
71 if((addr & 0x1ff80000) == 0x1fc00000) {
72 assem_debug("pcsx_direct_read %08x bios\n",addr);
73 if(rt<0)
74 return 1;
75 emit_movimm((u_int)&psxR[addr&0x7ffff],rt);
76 emit_ldr_type(type,0,rt,rt);
77 return 1;
78 }
79 if((addr & 0xfffff000) == 0x1f800000) {
80 assem_debug("pcsx_direct_read %08x scratchpad\n",addr);
81 if(rt<0)
82 return 1;
83 if(type==LOADW_STUB||type==LOADBU_STUB||(addr&0xf00)==0) {
84 emit_readword((int)&psxH_ptr,rt);
85 emit_ldr_type(type,addr&0xfff,rt,rt);
86 } else {
87 emit_movimm((u_int)&psxH[addr&0xfff],rt);
88 emit_ldr_type(type,0,rt,rt);
89 }
90 return 1;
91 }
92
93 assem_debug("pcsx_direct_read %08x miss\n",addr);
94 return 0;
95}
96
97static int pcsx_direct_write(int type, u_int addr, int rs, int rt, signed char *regmap)
98{
99 if((addr & 0x1f800000) == 0) {
100 assem_debug("pcsx_direct_write %08x ram\n",addr);
101 u_int a=(addr&~0x60600000)|0x80000000;
102 convert_ram_addr(addr,a,rs,HOST_TEMPREG);
103 emit_str_type(type,0,HOST_TEMPREG,rt);
104
105 int ir=get_reg(regmap,INVCP);
106 assert(ir>=0);
274c4243 107 emit_cmpmem_indexedsr12_reg(ir,HOST_TEMPREG,1);
cbbab9cd 108 emit_callne(invalidate_addr_reg[rs]);
109 return 1;
110 }
111 if((addr & 0xfffff000) == 0x1f800000) {
112 assem_debug("pcsx_direct_write %08x scratchpad\n",addr);
113 if(type==STOREW_STUB||type==STOREB_STUB||(addr&0xf00)==0) {
114 emit_readword((int)&psxH_ptr,HOST_TEMPREG);
115 emit_str_type(type,addr&0xfff,HOST_TEMPREG,rt);
116 } else {
117 emit_movimm((u_int)&psxH[addr&0xfff],HOST_TEMPREG);
118 emit_str_type(type,0,HOST_TEMPREG,rt);
119 }
120 return 1;
121 }
122
123 assem_debug("pcsx_direct_write %08x miss\n",addr);
124 return 0;
125}
126
127// vim:shiftwidth=2:expandtab