1 /*
2  * Copyright (c) 2015, Marcos Medeiros
3  * Licensed under BSD 3-clause.
4  */
5 #ifndef MIPS3_RW
6 #define MIPS3_RW
7 
8 #include "mips3.h"
9 #include "mipsdef.h"
10 #include "mips3_memory.h"
11 
12 namespace mips
13 {
14 
15 
LUI(uint32_t opcode)16 void mips3::LUI(uint32_t opcode)
17 {
18     if (RTNUM)
19         RT = (int32_t)(IMM << 16);
20 }
21 
SB(uint32_t opcode)22 void mips3::SB(uint32_t opcode)
23 {
24     addr_t vaddr = ((int32_t)SIMM) + RS;
25     addr_t eaddr;
26     if (translate(vaddr, &eaddr)) {
27     }
28 
29     mem::write_byte(eaddr, RT);
30 }
31 
SH(uint32_t opcode)32 void mips3::SH(uint32_t opcode)
33 {
34     addr_t vaddr = ((int32_t)SIMM) + RS;
35     addr_t eaddr;
36     if (translate(vaddr, &eaddr)) {
37     }
38 
39     mem::write_half(eaddr & ~1, RT);
40 }
41 
SW(uint32_t opcode)42 void mips3::SW(uint32_t opcode)
43 {
44     addr_t vaddr = ((int32_t)SIMM) + RS;
45     addr_t eaddr;
46     if (translate(vaddr & ~3, &eaddr)) {
47     }
48 
49     mem::write_word(eaddr, RT);
50 }
51 
SD(uint32_t opcode)52 void mips3::SD(uint32_t opcode)
53 {
54     addr_t vaddr = ((int32_t)SIMM) + RS;
55     addr_t eaddr;
56     if (translate(vaddr & ~7, &eaddr)) {
57     }
58 
59     mem::write_dword(eaddr, RT);
60 }
61 
SDL(uint32_t opcode)62 void mips3::SDL(uint32_t opcode)
63 {
64     addr_t vaddr = ((int32_t)SIMM) + RS;
65     addr_t eaddr;
66 
67     int shift = 8 * (~vaddr & 7);
68     uint64_t mask = 0xFFFFFFFFFFFFFFFFULL >> shift;
69 
70     if (translate(vaddr & ~7, &eaddr)) {
71     }
72 
73     uint64_t rdata = mem::read_dword(eaddr);
74     mem::write_dword(eaddr, ((RT >> shift) & mask) | (rdata & ~mask));
75 
76 }
77 
SDR(uint32_t opcode)78 void mips3::SDR(uint32_t opcode)
79 {
80     addr_t vaddr = ((int32_t)SIMM) + RS;
81     addr_t eaddr;
82 
83     int shift = 8 * (vaddr & 7);
84     uint64_t mask = 0xFFFFFFFFFFFFFFFFULL << shift;
85 
86     if (translate(vaddr & ~7, &eaddr)) {
87     }
88     uint64_t rdata = mem::read_dword(eaddr);
89     mem::write_dword(eaddr, ((RT << shift) & mask) | (rdata & ~mask));
90 }
91 
92 
LWL(uint32_t opcode)93 void mips3::LWL(uint32_t opcode)
94 {
95     uint32_t vaddr = ((int32_t)SIMM) + RS;
96 
97     int shift = ((~vaddr & 3)) * 8;
98     uint32_t mask = (0xFFFFFFFF << shift);
99 
100     addr_t eaddr;
101     if (translate(vaddr & ~3, &eaddr)) {
102     }
103 
104     uint32_t data = mem::read_word(eaddr) & (mask >> shift);
105 
106     if (RTNUM)
107         RT = (int32_t)((RT_u32 & ~mask) | (data << shift));
108 }
109 
LWR(uint32_t opcode)110 void mips3::LWR(uint32_t opcode)
111 {
112     uint32_t vaddr = ((int32_t)SIMM) + RS;
113 
114     int shift = (vaddr & 3) * 8;
115     uint32_t mask = (0xFFFFFFFF >> shift);
116 
117     addr_t eaddr;
118     if (translate(vaddr & ~3, &eaddr)) {
119     }
120     //d18
121     uint32_t data = mem::read_word(eaddr) & (mask << shift);
122 
123     if (RTNUM)
124         RT = (int32_t)((RT_u32 & ~mask) | (data >> shift));
125 }
126 
127 // Válido apenas para little endian.
LDL(uint32_t opcode)128 void mips3::LDL(uint32_t opcode)
129 {
130     uint32_t vaddr = ((int32_t)SIMM) + RS;
131 
132     int shift = (~vaddr & 7) * 8;
133     uint64_t mask = (0xFFFFFFFFFFFFFFFFULL << shift);
134 
135     addr_t eaddr;
136     if (translate(vaddr & ~7, &eaddr)) {
137     }
138 
139     uint64_t data = mem::read_dword(eaddr) & (mask >> shift);
140 
141     if (RTNUM)
142         RT = (RT & ~mask) | (data << shift);
143 }
144 
145 // Válido apenas para little endian.
LDR(uint32_t opcode)146 void mips3::LDR(uint32_t opcode)
147 {
148     uint32_t vaddr = ((int32_t)SIMM) + RS;
149 
150     int shift = (vaddr & 7) * 8;
151     uint64_t mask = (0xFFFFFFFFFFFFFFFFULL >> shift);
152 
153     addr_t eaddr;
154     if (translate(vaddr & ~7, &eaddr)) {
155     }
156     //d18
157     uint64_t data = mem::read_dword(eaddr) & (mask << shift);
158 
159     if (RTNUM)
160         RT = (RT & ~mask) | (data >> shift);
161 }
162 
LW(uint32_t opcode)163 void mips3::LW(uint32_t opcode)
164 {
165     addr_t vaddr = ((int32_t)SIMM) + RS;
166     addr_t eaddr;
167     if (translate(vaddr, &eaddr)) {
168     }
169 
170     if (RTNUM)
171         RT = (int32_t) mem::read_word(eaddr);
172 }
173 
LWU(uint32_t opcode)174 void mips3::LWU(uint32_t opcode)
175 {
176     addr_t vaddr = ((int32_t)SIMM) + RS;
177     addr_t eaddr;
178     if (translate(vaddr & ~3, &eaddr)) {
179     }
180 
181     if (RTNUM)
182         RT = (uint32_t) mem::read_word(eaddr);
183 }
184 
LD(uint32_t opcode)185 void mips3::LD(uint32_t opcode)
186 {
187     addr_t vaddr = ((int32_t)SIMM) + RS;
188     addr_t eaddr;
189     if (translate(vaddr & ~7, &eaddr)) {
190     }
191 
192     if (RTNUM)
193         RT = mem::read_dword(eaddr);
194 }
195 
LL(uint32_t opcode)196 void mips3::LL(uint32_t opcode)
197 {
198     addr_t vaddr = ((int32_t)SIMM) + RS;
199     addr_t eaddr;
200     if (translate(vaddr & ~3, &eaddr)) {
201     }
202 
203     if (RTNUM)
204         RT = (int32_t) mem::read_word(eaddr);
205 }
206 
207 // TODO: FIX IT
LWC1(uint32_t opcode)208 void mips3::LWC1(uint32_t opcode)
209 {
210     addr_t vaddr = ((int32_t)SIMM) + RS;
211     addr_t eaddr;
212     if (translate(vaddr & ~3, &eaddr)) {
213     }
214     m_state.cpr[1][RTNUM] = (uint32_t) mem::read_word(eaddr);
215 }
216 
217 // TODO: FIX IT
SWC1(uint32_t opcode)218 void mips3::SWC1(uint32_t opcode)
219 {
220     addr_t vaddr = ((int32_t)SIMM) + RS;
221     addr_t eaddr;
222     if (translate(vaddr & ~3, &eaddr)) {
223     }
224     mem::write_word(eaddr, m_state.cpr[1][RTNUM]);
225 }
226 
LB(uint32_t opcode)227 void mips3::LB(uint32_t opcode)
228 {
229     addr_t vaddr = ((int32_t)SIMM) + RS;
230     addr_t eaddr;
231     if (translate(vaddr, &eaddr)) {
232     }
233 
234     if (RTNUM)
235         RT = (int8_t) mem::read_byte(eaddr);
236 }
237 
LBU(uint32_t opcode)238 void mips3::LBU(uint32_t opcode)
239 {
240     addr_t vaddr = ((int32_t)SIMM) + RS;
241     addr_t eaddr;
242     if (translate(vaddr, &eaddr)) {
243     }
244 
245     if (RTNUM)
246         RT = (uint8_t) mem::read_byte(eaddr);
247 }
248 
LH(uint32_t opcode)249 void mips3::LH(uint32_t opcode)
250 {
251     addr_t vaddr = ((int32_t)SIMM) + RS;
252     addr_t eaddr;
253     if (translate(vaddr & ~1, &eaddr)) {
254     }
255 
256     if (RTNUM)
257         RT = (int16_t) mem::read_word(eaddr);
258 }
259 
LHU(uint32_t opcode)260 void mips3::LHU(uint32_t opcode)
261 {
262     addr_t vaddr = ((int32_t)SIMM) + RS;
263     addr_t eaddr;
264     if (translate(vaddr & ~1, &eaddr)) {
265     }
266 
267     if (RTNUM)
268         RT = (uint16_t) mem::read_word(eaddr);
269 }
270 
271 }
272 
273 #endif // MIPS3_RW
274 
275