/[pcsx2_0.9.7]/trunk/pcsx2/R3000AOpcodeTables.cpp
ViewVC logotype

Contents of /trunk/pcsx2/R3000AOpcodeTables.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (9 years, 5 months ago) by william
File size: 13338 byte(s)
committing r3113 initial commit again...
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16
17 #include "PrecompiledHeader.h"
18 #include "IopCommon.h"
19
20 // Note: Branch instructions of the Interpreter are defined externally because
21 // the recompiler shouldn't be using them (it isn't entirely safe, due to the
22 // delay slot and event handling differences between recs and ints)
23 void psxBGEZ();
24 void psxBGEZAL();
25 void psxBGTZ();
26 void psxBLEZ();
27 void psxBLTZ();
28 void psxBLTZAL();
29
30 void psxBEQ();
31 void psxBNE();
32 void psxJ();
33 void psxJAL();
34
35 void psxJR();
36 void psxJALR();
37
38 /*********************************************************
39 * Arithmetic with immediate operand *
40 * Format: OP rt, rs, immediate *
41 *********************************************************/
42 void psxADDI() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) + _Imm_ ; } // Rt = Rs + Im (Exception on Integer Overflow)
43 void psxADDIU() { // Rt = Rs + Im
44 if (!_Rt_)
45 return;
46 _rRt_ = _u32(_rRs_) + _Imm_ ;
47 }
48 void psxANDI() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) & _ImmU_; } // Rt = Rs And Im
49 void psxORI() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) | _ImmU_; } // Rt = Rs Or Im
50 void psxXORI() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) ^ _ImmU_; } // Rt = Rs Xor Im
51 void psxSLTI() { if (!_Rt_) return; _rRt_ = _i32(_rRs_) < _Imm_ ; } // Rt = Rs < Im (Signed)
52 void psxSLTIU() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) < (u32)_Imm_; } // Rt = Rs < Im (Unsigned)
53
54 /*********************************************************
55 * Register arithmetic *
56 * Format: OP rd, rs, rt *
57 *********************************************************/
58 void psxADD() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) + _u32(_rRt_); } // Rd = Rs + Rt (Exception on Integer Overflow)
59 void psxADDU() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) + _u32(_rRt_); } // Rd = Rs + Rt
60 void psxSUB() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) - _u32(_rRt_); } // Rd = Rs - Rt (Exception on Integer Overflow)
61 void psxSUBU() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) - _u32(_rRt_); } // Rd = Rs - Rt
62 void psxAND() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) & _u32(_rRt_); } // Rd = Rs And Rt
63 void psxOR() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) | _u32(_rRt_); } // Rd = Rs Or Rt
64 void psxXOR() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) ^ _u32(_rRt_); } // Rd = Rs Xor Rt
65 void psxNOR() { if (!_Rd_) return; _rRd_ =~(_u32(_rRs_) | _u32(_rRt_)); }// Rd = Rs Nor Rt
66 void psxSLT() { if (!_Rd_) return; _rRd_ = _i32(_rRs_) < _i32(_rRt_); } // Rd = Rs < Rt (Signed)
67 void psxSLTU() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) < _u32(_rRt_); } // Rd = Rs < Rt (Unsigned)
68
69 /*********************************************************
70 * Register mult/div & Register trap logic *
71 * Format: OP rs, rt *
72 *********************************************************/
73 void psxDIV() {
74 if (_rRt_ != 0) {
75 _rLo_ = _i32(_rRs_) / _i32(_rRt_);
76 _rHi_ = _i32(_rRs_) % _i32(_rRt_);
77 }
78 }
79
80 void psxDIVU() {
81 if (_rRt_ != 0) {
82 _rLo_ = _rRs_ / _rRt_;
83 _rHi_ = _rRs_ % _rRt_;
84 }
85 }
86
87 void psxMULT() {
88 u64 res = (s64)((s64)_i32(_rRs_) * (s64)_i32(_rRt_));
89
90 psxRegs.GPR.n.lo = (u32)(res & 0xffffffff);
91 psxRegs.GPR.n.hi = (u32)((res >> 32) & 0xffffffff);
92 }
93
94 void psxMULTU() {
95 u64 res = (u64)((u64)_u32(_rRs_) * (u64)_u32(_rRt_));
96
97 psxRegs.GPR.n.lo = (u32)(res & 0xffffffff);
98 psxRegs.GPR.n.hi = (u32)((res >> 32) & 0xffffffff);
99 }
100
101 /*********************************************************
102 * Shift arithmetic with constant shift *
103 * Format: OP rd, rt, sa *
104 *********************************************************/
105 void psxSLL() { if (!_Rd_) return; _rRd_ = _u32(_rRt_) << _Sa_; } // Rd = Rt << sa
106 void psxSRA() { if (!_Rd_) return; _rRd_ = _i32(_rRt_) >> _Sa_; } // Rd = Rt >> sa (arithmetic)
107 void psxSRL() { if (!_Rd_) return; _rRd_ = _u32(_rRt_) >> _Sa_; } // Rd = Rt >> sa (logical)
108
109 /*********************************************************
110 * Shift arithmetic with variant register shift *
111 * Format: OP rd, rt, rs *
112 *********************************************************/
113 void psxSLLV() { if (!_Rd_) return; _rRd_ = _u32(_rRt_) << _u32(_rRs_); } // Rd = Rt << rs
114 void psxSRAV() { if (!_Rd_) return; _rRd_ = _i32(_rRt_) >> _u32(_rRs_); } // Rd = Rt >> rs (arithmetic)
115 void psxSRLV() { if (!_Rd_) return; _rRd_ = _u32(_rRt_) >> _u32(_rRs_); } // Rd = Rt >> rs (logical)
116
117 /*********************************************************
118 * Load higher 16 bits of the first word in GPR with imm *
119 * Format: OP rt, immediate *
120 *********************************************************/
121 void psxLUI() { if (!_Rt_) return; _rRt_ = psxRegs.code << 16; } // Upper halfword of Rt = Im
122
123 /*********************************************************
124 * Move from HI/LO to GPR *
125 * Format: OP rd *
126 *********************************************************/
127 void psxMFHI() { if (!_Rd_) return; _rRd_ = _rHi_; } // Rd = Hi
128 void psxMFLO() { if (!_Rd_) return; _rRd_ = _rLo_; } // Rd = Lo
129
130 /*********************************************************
131 * Move to GPR to HI/LO & Register jump *
132 * Format: OP rs *
133 *********************************************************/
134 void psxMTHI() { _rHi_ = _rRs_; } // Hi = Rs
135 void psxMTLO() { _rLo_ = _rRs_; } // Lo = Rs
136
137 /*********************************************************
138 * Special purpose instructions *
139 * Format: OP *
140 *********************************************************/
141 void psxBREAK() {
142 // Break exception - psx rom doens't handles this
143 psxRegs.pc -= 4;
144 psxException(0x24, iopIsDelaySlot);
145 }
146
147 void psxSYSCALL() {
148 psxRegs.pc -= 4;
149 psxException(0x20, iopIsDelaySlot);
150
151 }
152
153 void psxRFE() {
154 // Console.WriteLn("RFE\n");
155 psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) |
156 ((psxRegs.CP0.n.Status & 0x3c) >> 2);
157 // Log=0;
158 }
159
160 /*********************************************************
161 * Load and store for GPR *
162 * Format: OP rt, offset(base) *
163 *********************************************************/
164
165 #define _oB_ (_u32(_rRs_) + _Imm_)
166
167 void psxLB() {
168 if (_Rt_) {
169 _rRt_ = (s8 )iopMemRead8(_oB_);
170 } else {
171 iopMemRead8(_oB_);
172 }
173 }
174
175 void psxLBU() {
176 if (_Rt_) {
177 _rRt_ = iopMemRead8(_oB_);
178 } else {
179 iopMemRead8(_oB_);
180 }
181 }
182
183 void psxLH() {
184 if (_Rt_) {
185 _rRt_ = (s16)iopMemRead16(_oB_);
186 } else {
187 iopMemRead16(_oB_);
188 }
189 }
190
191 void psxLHU() {
192 if (_Rt_) {
193 _rRt_ = iopMemRead16(_oB_);
194 } else {
195 iopMemRead16(_oB_);
196 }
197 }
198
199 void psxLW() {
200 if (_Rt_) {
201 _rRt_ = iopMemRead32(_oB_);
202 } else {
203 iopMemRead32(_oB_);
204 }
205 }
206
207 void psxLWL() {
208 u32 shift = (_oB_ & 3) << 3;
209 u32 mem = iopMemRead32(_oB_ & 0xfffffffc);
210
211 if (!_Rt_) return;
212 _rRt_ = ( _u32(_rRt_) & (0x00ffffff >> shift) ) |
213 ( mem << (24 - shift) );
214
215 /*
216 Mem = 1234. Reg = abcd
217
218 0 4bcd (mem << 24) | (reg & 0x00ffffff)
219 1 34cd (mem << 16) | (reg & 0x0000ffff)
220 2 234d (mem << 8) | (reg & 0x000000ff)
221 3 1234 (mem ) | (reg & 0x00000000)
222
223 */
224 }
225
226 void psxLWR() {
227 u32 shift = (_oB_ & 3) << 3;
228 u32 mem = iopMemRead32(_oB_ & 0xfffffffc);
229
230 if (!_Rt_) return;
231 _rRt_ = ( _u32(_rRt_) & (0xffffff00 << (24 - shift)) ) |
232 ( mem >> shift );
233
234 /*
235 Mem = 1234. Reg = abcd
236
237 0 1234 (mem ) | (reg & 0x00000000)
238 1 a123 (mem >> 8) | (reg & 0xff000000)
239 2 ab12 (mem >> 16) | (reg & 0xffff0000)
240 3 abc1 (mem >> 24) | (reg & 0xffffff00)
241
242 */
243 }
244
245 void psxSB() { iopMemWrite8 (_oB_, _u8 (_rRt_)); }
246 void psxSH() { iopMemWrite16(_oB_, _u16(_rRt_)); }
247 void psxSW() { iopMemWrite32(_oB_, _u32(_rRt_)); }
248
249 void psxSWL() {
250 u32 shift = (_oB_ & 3) << 3;
251 u32 mem = iopMemRead32(_oB_ & 0xfffffffc);
252
253 iopMemWrite32((_oB_ & 0xfffffffc), ( ( _u32(_rRt_) >> (24 - shift) ) ) |
254 ( mem & (0xffffff00 << shift) ));
255 /*
256 Mem = 1234. Reg = abcd
257
258 0 123a (reg >> 24) | (mem & 0xffffff00)
259 1 12ab (reg >> 16) | (mem & 0xffff0000)
260 2 1abc (reg >> 8) | (mem & 0xff000000)
261 3 abcd (reg ) | (mem & 0x00000000)
262
263 */
264 }
265
266 void psxSWR() {
267 u32 shift = (_oB_ & 3) << 3;
268 u32 mem = iopMemRead32(_oB_ & 0xfffffffc);
269
270 iopMemWrite32((_oB_ & 0xfffffffc), ( ( _u32(_rRt_) << shift ) |
271 (mem & (0x00ffffff >> (24 - shift)) ) ) );
272 /*
273 Mem = 1234. Reg = abcd
274
275 0 abcd (reg ) | (mem & 0x00000000)
276 1 bcd4 (reg << 8) | (mem & 0x000000ff)
277 2 cd34 (reg << 16) | (mem & 0x0000ffff)
278 3 d234 (reg << 24) | (mem & 0x00ffffff)
279
280 */
281 }
282
283 /*********************************************************
284 * Moves between GPR and COPx *
285 * Format: OP rt, fs *
286 *********************************************************/
287 void psxMFC0() { if (!_Rt_) return; _rRt_ = (int)_rFs_; }
288 void psxCFC0() { if (!_Rt_) return; _rRt_ = (int)_rFs_; }
289
290 void psxMTC0() { _rFs_ = _u32(_rRt_); }
291 void psxCTC0() { _rFs_ = _u32(_rRt_); }
292
293 /*********************************************************
294 * Unknown instruction (would generate an exception) *
295 * Format: ? *
296 *********************************************************/
297 void psxNULL() {
298 Console.Warning("psx: Unimplemented op %x", psxRegs.code);
299 }
300
301 void psxSPECIAL() {
302 psxSPC[_Funct_]();
303 }
304
305 void psxREGIMM() {
306 psxREG[_Rt_]();
307 }
308
309 void psxCOP0() {
310 psxCP0[_Rs_]();
311 }
312
313 void psxCOP2() {
314 psxCP2[_Funct_]();
315 }
316
317 void psxBASIC() {
318 psxCP2BSC[_Rs_]();
319 }
320
321 void (*psxBSC[64])() = {
322 psxSPECIAL, psxREGIMM, psxJ , psxJAL , psxBEQ , psxBNE , psxBLEZ, psxBGTZ,
323 psxADDI , psxADDIU , psxSLTI, psxSLTIU, psxANDI, psxORI , psxXORI, psxLUI ,
324 psxCOP0 , psxNULL , psxCOP2, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL,
325 psxNULL , psxNULL , psxNULL, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL,
326 psxLB , psxLH , psxLWL , psxLW , psxLBU , psxLHU , psxLWR , psxNULL,
327 psxSB , psxSH , psxSWL , psxSW , psxNULL, psxNULL, psxSWR , psxNULL,
328 psxNULL , psxNULL , psxNULL, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL,
329 psxNULL , psxNULL , psxNULL, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL
330 };
331
332
333 void (*psxSPC[64])() = {
334 psxSLL , psxNULL , psxSRL , psxSRA , psxSLLV , psxNULL , psxSRLV, psxSRAV,
335 psxJR , psxJALR , psxNULL, psxNULL, psxSYSCALL, psxBREAK, psxNULL, psxNULL,
336 psxMFHI, psxMTHI , psxMFLO, psxMTLO, psxNULL , psxNULL , psxNULL, psxNULL,
337 psxMULT, psxMULTU, psxDIV , psxDIVU, psxNULL , psxNULL , psxNULL, psxNULL,
338 psxADD , psxADDU , psxSUB , psxSUBU, psxAND , psxOR , psxXOR , psxNOR ,
339 psxNULL, psxNULL , psxSLT , psxSLTU, psxNULL , psxNULL , psxNULL, psxNULL,
340 psxNULL, psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL, psxNULL,
341 psxNULL, psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL, psxNULL
342 };
343
344 void (*psxREG[32])() = {
345 psxBLTZ , psxBGEZ , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
346 psxNULL , psxNULL , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
347 psxBLTZAL, psxBGEZAL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
348 psxNULL , psxNULL , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL
349 };
350
351 void (*psxCP0[32])() = {
352 psxMFC0, psxNULL, psxCFC0, psxNULL, psxMTC0, psxNULL, psxCTC0, psxNULL,
353 psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
354 psxRFE , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
355 psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL
356 };
357
358 void (*psxCP2[64])() = {
359 psxBASIC, psxNULL , psxNULL , psxNULL, psxNULL, psxNULL , psxNULL, psxNULL, // 00
360 psxNULL , psxNULL , psxNULL , psxNULL, psxNULL , psxNULL , psxNULL , psxNULL, // 08
361 psxNULL , psxNULL, psxNULL, psxNULL, psxNULL , psxNULL , psxNULL , psxNULL, // 10
362 psxNULL , psxNULL , psxNULL , psxNULL, psxNULL , psxNULL , psxNULL , psxNULL, // 18
363 psxNULL , psxNULL , psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL, // 20
364 psxNULL , psxNULL , psxNULL , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, // 28
365 psxNULL , psxNULL , psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL, // 30
366 psxNULL , psxNULL , psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL // 38
367 };
368
369 void (*psxCP2BSC[32])() = {
370 psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
371 psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
372 psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL,
373 psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL
374 };

  ViewVC Help
Powered by ViewVC 1.1.22