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

Annotation of /trunk/pcsx2/R3000AOpcodeTables.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (9 years, 10 months ago) by william
File size: 13338 byte(s)
committing r3113 initial commit again...
1 william 31 /* 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