1 // Copyright (c) 2012- PPSSPP Project.
2
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0 or later versions.
6
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License 2.0 for more details.
11
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
14
15 // Official git repository and contact information can be found at
16 // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17
18 #include <cstring>
19 #include "Core/HLE/HLE.h"
20
21 #include "Core/MIPS/MIPS.h"
22 #include "Core/MIPS/MIPSDis.h"
23 #include "Core/MIPS/MIPSTables.h"
24 #include "Core/MIPS/MIPSDebugInterface.h"
25
26 #include "Core/MIPS/MIPSVFPUUtils.h"
27
28 #define _RS ((op>>21) & 0x1F)
29 #define _RT ((op>>16) & 0x1F)
30 #define _RD ((op>>11) & 0x1F)
31 #define _FS ((op>>11) & 0x1F)
32 #define _FT ((op>>16) & 0x1F)
33 #define _FD ((op>>6 ) & 0x1F)
34 #define _POS ((op>>6 ) & 0x1F)
35 #define _SIZE ((op>>11) & 0x1F)
36
37
38 #define RN(i) currentDebugMIPS->GetRegName(0,i)
39 #define FN(i) currentDebugMIPS->GetRegName(1,i)
40 //#define VN(i) currentDebugMIPS->GetRegName(2,i)
41
42
43 #define S_not(a,b,c) (a<<2)|(b)|(c<<5)
44 #define SgetA(v) (((v)>>2)&0x7)
45 #define SgetB(v) ((v)&3)
46 #define SgetC(v) (((v)>>5)&0x3)
47
48 #define HorizOff 32
49 #define VertOff 1
50 #define MtxOff 4
51
VN(int v,VectorSize size)52 inline const char *VN(int v, VectorSize size)
53 {
54 static const char *vfpuCtrlNames[VFPU_CTRL_MAX] = {
55 "SPFX",
56 "TPFX",
57 "DPFX",
58 "CC",
59 "INF4",
60 "RSV5",
61 "RSV6",
62 "REV",
63 "RCX0",
64 "RCX1",
65 "RCX2",
66 "RCX3",
67 "RCX4",
68 "RCX5",
69 "RCX6",
70 "RCX7",
71 };
72 if (size == V_Single && v >= 128 && v < 128 + VFPU_CTRL_MAX) {
73 return vfpuCtrlNames[v - 128];
74 } else if (size == V_Single && v == 255) {
75 return "(interlock)";
76 }
77
78 return GetVectorNotation(v, size);
79 }
80
MN(int v,MatrixSize size)81 inline const char *MN(int v, MatrixSize size)
82 {
83 return GetMatrixNotation(v, size);
84 }
85
VSuff(MIPSOpcode op)86 inline const char *VSuff(MIPSOpcode op)
87 {
88 int a = (op>>7)&1;
89 int b = (op>>15)&1;
90 a+=(b<<1);
91 switch (a)
92 {
93 case 0: return ".s";
94 case 1: return ".p";
95 case 2: return ".t";
96 case 3: return ".q";
97 default: return "%";
98 }
99 }
100
101 namespace MIPSDis
102 {
Dis_SV(MIPSOpcode op,char * out)103 void Dis_SV(MIPSOpcode op, char *out)
104 {
105 int offset = (signed short)(op&0xFFFC);
106 int vt = ((op>>16)&0x1f)|((op&3)<<5);
107 int rs = (op>>21) & 0x1f;
108 const char *name = MIPSGetName(op);
109 sprintf(out, "%s\t%s, %d(%s)",name,VN(vt, V_Single),offset,RN(rs));
110 }
111
Dis_SVQ(MIPSOpcode op,char * out)112 void Dis_SVQ(MIPSOpcode op, char *out)
113 {
114 int offset = (signed short)(op&0xFFFC);
115 int vt = (((op>>16)&0x1f))|((op&1)<<5);
116 int rs = (op>>21) & 0x1f;
117 const char *name = MIPSGetName(op);
118 sprintf(out, "%s\t%s, %d(%s)",name,VN(vt,V_Quad),offset,RN(rs));
119 if (op & 2)
120 strcat(out, ", wb");
121 }
122
Dis_SVLRQ(MIPSOpcode op,char * out)123 void Dis_SVLRQ(MIPSOpcode op, char *out)
124 {
125 int offset = (signed short)(op&0xFFFC);
126 int vt = (((op>>16)&0x1f))|((op&1)<<5);
127 int rs = (op>>21) & 0x1f;
128 int lr = (op>>1)&1;
129 const char *name = MIPSGetName(op);
130 sprintf(out, "%s%s.q\t%s, %d(%s)",name,lr?"r":"l",VN(vt,V_Quad),offset,RN(rs));
131 }
132
Dis_Mftv(MIPSOpcode op,char * out)133 void Dis_Mftv(MIPSOpcode op, char *out)
134 {
135 int vr = op & 0xFF;
136 int rt = _RT;
137 const char *name = MIPSGetName(op);
138 sprintf(out, "%s%s\t%s, %s",name,vr>127?"c":"", RN(rt), VN(vr, V_Single));
139 }
140
Dis_Vmfvc(MIPSOpcode op,char * out)141 void Dis_Vmfvc(MIPSOpcode op, char *out)
142 {
143 int vd = _VD;
144 int vr = (op >> 8) & 0x7F;
145 const char* name = MIPSGetName(op);
146 sprintf(out, "%s\t%s, %s", name, VN(vd, V_Single), VN(vr + 128, V_Single));
147 }
148
Dis_Vmtvc(MIPSOpcode op,char * out)149 void Dis_Vmtvc(MIPSOpcode op, char *out)
150 {
151 int vr = op & 0x7F;
152 int vs = _VS;
153 const char *name = MIPSGetName(op);
154 sprintf(out, "%s\t%s, %s", name, VN(vs, V_Single), VN(vr + 128, V_Single));
155 }
156
Dis_VPFXST(MIPSOpcode op,char * out)157 void Dis_VPFXST(MIPSOpcode op, char *out)
158 {
159 int data = op & 0xFFFFF;
160 const char *name = MIPSGetName(op);
161 sprintf(out, "%s\t[",name);
162 static const char *regnam[4] = {"X","Y","Z","W"};
163 static const char *constan[8] = {"0","1","2","1/2","3","1/3","1/4","1/6"};
164 for (int i=0; i<4; i++)
165 {
166 int regnum = (data>>(i*2)) & 3;
167 int abs = (data>>(8+i)) & 1;
168 int negate = (data>>(16+i)) & 1;
169 int constants = (data>>(12+i)) & 1;
170 if (negate)
171 strcat(out, "-");
172 if (abs && !constants)
173 strcat(out, "|");
174 if (!constants)
175 {
176 strcat(out, regnam[regnum]);
177 }
178 else
179 {
180 if (abs)
181 regnum+=4;
182 strcat(out, constan[regnum]);
183 }
184 if (abs && !constants)
185 strcat(out, "|");
186 if (i != 3)
187 strcat(out, ",");
188 }
189
190 strcat(out, "]");
191 }
192
Dis_VPFXD(MIPSOpcode op,char * out)193 void Dis_VPFXD(MIPSOpcode op, char *out)
194 {
195 int data = op & 0xFFFFF;
196 const char *name = MIPSGetName(op);
197 sprintf(out, "%s\t[", name);
198 static const char *satNames[4] = {"", "0:1", "X", "-1:1"};
199 for (int i=0; i<4; i++)
200 {
201 int sat = (data>>i*2)&3;
202 int mask = (data>>(8+i))&1;
203 if (sat)
204 strcat(out, satNames[sat]);
205 if (mask)
206 strcat(out, "M");
207 if (i < 4 - 1)
208 strcat(out, ",");
209 }
210
211 strcat(out, "]");
212 }
213
214
Dis_Viim(MIPSOpcode op,char * out)215 void Dis_Viim(MIPSOpcode op, char *out)
216 {
217 int vt = _VT;
218 int imm = op&0xFFFF;
219 //V(vt) = (float)imm;
220 const char *name = MIPSGetName(op);
221
222 int type = (op >> 23) & 7;
223 if (type == 6)
224 sprintf(out, "%s\t%s, %i", name, VN(vt, V_Single), imm);
225 else if (type == 7)
226 sprintf(out, "%s\t%s, %f", name, VN(vt, V_Single), Float16ToFloat32((u16)imm));
227 else
228 sprintf(out, "%s\tARGH", name);
229 }
230
Dis_Vcst(MIPSOpcode op,char * out)231 void Dis_Vcst(MIPSOpcode op, char *out)
232 {
233 int conNum = (op>>16) & 0x1f;
234 int vd = _VD;
235 VectorSize sz = GetVecSizeSafe(op);
236 static const char *constants[32] =
237 {
238 "(undef)",
239 "MaxFloat",
240 "Sqrt(2)",
241 "Sqrt(1/2)",
242 "2/Sqrt(PI)",
243 "2/PI",
244 "1/PI",
245 "PI/4",
246 "PI/2",
247 "PI",
248 "e",
249 "Log2(e)",
250 "Log10(e)",
251 "ln(2)",
252 "ln(10)",
253 "2*PI",
254 "PI/6",
255 "Log10(2)",
256 "Log2(10)",
257 "Sqrt(3)/2"
258 };
259 const char *name = MIPSGetName(op);
260 const char *c = constants[conNum];
261 if (c==0) c = constants[0];
262 sprintf(out,"%s%s\t%s, %s",name,VSuff(op),VN(vd,sz), c);
263 }
264
265
Dis_MatrixSet1(MIPSOpcode op,char * out)266 void Dis_MatrixSet1(MIPSOpcode op, char *out)
267 {
268 const char *name = MIPSGetName(op);
269 int vd = _VD;
270 MatrixSize sz = GetMtxSizeSafe(op);
271 sprintf(out, "%s%s\t%s",name,VSuff(op),MN(vd, sz));
272 }
Dis_MatrixSet2(MIPSOpcode op,char * out)273 void Dis_MatrixSet2(MIPSOpcode op, char *out)
274 {
275 const char *name = MIPSGetName(op);
276 int vd = _VD;
277 int vs = _VS;
278 MatrixSize sz = GetMtxSizeSafe(op);
279 sprintf(out, "%s%s\t%s, %s",name,VSuff(op),MN(vd, sz),MN(vs,sz));
280 }
Dis_MatrixSet3(MIPSOpcode op,char * out)281 void Dis_MatrixSet3(MIPSOpcode op, char *out)
282 {
283 const char *name = MIPSGetName(op);
284 int vd = _VD;
285 int vs = _VS;
286 int vt = _VT;
287 MatrixSize sz = GetMtxSizeSafe(op);
288 sprintf(out, "%s%s\t%s, %s, %s",name,VSuff(op),MN(vd, sz),MN(vs,sz),MN(vt,sz));
289 }
290
Dis_MatrixMult(MIPSOpcode op,char * out)291 void Dis_MatrixMult(MIPSOpcode op, char *out)
292 {
293 const char *name = MIPSGetName(op);
294 int vd = _VD;
295 int vs = _VS;
296 int vt = _VT;
297 MatrixSize sz = GetMtxSizeSafe(op);
298 // TODO: Xpose?
299 sprintf(out, "%s%s\t%s, %s, %s",name,VSuff(op),MN(vd, sz),MN(Xpose(vs),sz),MN(vt,sz));
300 }
301
Dis_Vmscl(MIPSOpcode op,char * out)302 void Dis_Vmscl(MIPSOpcode op, char *out)
303 {
304 const char *name = MIPSGetName(op);
305 int vd = _VD;
306 int vs = _VS;
307 int vt = _VT;
308 MatrixSize sz = GetMtxSizeSafe(op);
309 sprintf(out, "%s%s\t%s, %s, %s", name, VSuff(op), MN(vd, sz), MN(vs, sz), VN(vt, V_Single));
310 }
311
Dis_VectorDot(MIPSOpcode op,char * out)312 void Dis_VectorDot(MIPSOpcode op, char *out)
313 {
314 const char *name = MIPSGetName(op);
315 int vd = _VD;
316 int vs = _VS;
317 int vt = _VT;
318 VectorSize sz = GetVecSizeSafe(op);
319 sprintf(out, "%s%s\t%s, %s, %s", name, VSuff(op), VN(vd, V_Single), VN(vs,sz), VN(vt, sz));
320 }
321
Dis_Vtfm(MIPSOpcode op,char * out)322 void Dis_Vtfm(MIPSOpcode op, char *out)
323 {
324 int vd = _VD;
325 int vs = _VS;
326 int vt = _VT;
327 int ins = (op>>23) & 7;
328 VectorSize sz = GetVecSizeSafe(op);
329 MatrixSize msz = GetMtxSizeSafe(op);
330 int n = GetNumVectorElements(sz);
331
332 if (n == ins)
333 {
334 //homogenous
335 sprintf(out, "vhtfm%i%s\t%s, %s, %s", n, VSuff(op), VN(vd, sz), MN(vs, msz), VN(vt, sz));
336 }
337 else if (n == ins+1)
338 {
339 sprintf(out, "vtfm%i%s\t%s, %s, %s", n, VSuff(op), VN(vd, sz), MN(vs, msz), VN(vt, sz));
340 }
341 else
342 {
343 sprintf(out,"BADVTFM");
344 }
345 }
346
Dis_Vflush(MIPSOpcode op,char * out)347 void Dis_Vflush(MIPSOpcode op, char *out)
348 {
349 sprintf(out,"vflush");
350 }
351
Dis_Vcrs(MIPSOpcode op,char * out)352 void Dis_Vcrs(MIPSOpcode op, char *out)
353 {
354 const char *name = MIPSGetName(op);
355 int vt = _VT;
356 int vs = _VS;
357 int vd = _VD;
358 VectorSize sz = GetVecSizeSafe(op);
359 if (sz != V_Triple)
360 {
361 sprintf(out, "vcrs\tERROR");
362 }
363 else
364 sprintf(out, "%s%s\t%s, %s, %s", name, VSuff(op), VN(vd, sz), VN(vs, sz), VN(vt,sz));
365 }
366
367
Dis_Vcmp(MIPSOpcode op,char * out)368 void Dis_Vcmp(MIPSOpcode op, char *out)
369 {
370 const char *name = MIPSGetName(op);
371 int vt = _VT;
372 int vs = _VS;
373 int cond = op&15;
374 VectorSize sz = GetVecSizeSafe(op);
375 const char *condNames[16] = {"FL","EQ","LT","LE","TR","NE","GE","GT","EZ","EN","EI","ES","NZ","NN","NI","NS"};
376 sprintf(out, "%s%s\t%s, %s, %s", name, VSuff(op), condNames[cond], VN(vs, sz), VN(vt,sz));
377 }
378
Dis_Vcmov(MIPSOpcode op,char * out)379 void Dis_Vcmov(MIPSOpcode op, char *out)
380 {
381 const char *name = MIPSGetName(op);
382 VectorSize sz = GetVecSizeSafe(op);
383 int vd = _VD;
384 int vs = _VS;
385 int tf = (op >> 19)&3;
386 int imm3 = (op>>16)&7;
387 if (tf > 1)
388 {
389 sprintf(out, "%s\tARGH%i", name, tf);
390 return;
391 }
392 if (imm3<6)
393 sprintf(out, "%s%s%s\t%s, %s, CC[%i]", name, tf==0?"t":"f", VSuff(op), VN(vd, sz), VN(vs,sz), imm3);
394 else if (imm3 == 6)
395 sprintf(out, "%s%s%s\t%s, %s, CC[...]", name, tf==0?"t":"f", VSuff(op), VN(vd, sz), VN(vs,sz));
396 }
397
Dis_Vfad(MIPSOpcode op,char * out)398 void Dis_Vfad(MIPSOpcode op, char *out)
399 {
400 const char *name = MIPSGetName(op);
401 int vd = _VD;
402 int vs = _VS;
403 VectorSize sz = GetVecSizeSafe(op);
404 sprintf(out, "%s%s\t%s, %s", name, VSuff(op), VN(vd, V_Single), VN(vs,sz));
405 }
406
Dis_VScl(MIPSOpcode op,char * out)407 void Dis_VScl(MIPSOpcode op, char *out)
408 {
409 const char *name = MIPSGetName(op);
410 int vd = _VD;
411 int vs = _VS;
412 int vt = _VT;
413 VectorSize sz = GetVecSizeSafe(op);
414 sprintf(out, "%s%s\t%s, %s, %s", name, VSuff(op), VN(vd, sz), VN(vs,sz), VN(vt, V_Single));
415 }
416
Dis_VectorSet1(MIPSOpcode op,char * out)417 void Dis_VectorSet1(MIPSOpcode op, char *out)
418 {
419 const char *name = MIPSGetName(op);
420 int vd = _VD;
421 VectorSize sz = GetVecSizeSafe(op);
422 sprintf(out, "%s%s\t%s",name,VSuff(op),VN(vd, sz));
423 }
Dis_VectorSet2(MIPSOpcode op,char * out)424 void Dis_VectorSet2(MIPSOpcode op, char *out)
425 {
426 const char *name = MIPSGetName(op);
427 int vd = _VD;
428 int vs = _VS;
429 VectorSize sz = GetVecSizeSafe(op);
430 sprintf(out, "%s%s\t%s, %s",name,VSuff(op),VN(vd, sz),VN(vs, sz));
431 }
Dis_VectorSet3(MIPSOpcode op,char * out)432 void Dis_VectorSet3(MIPSOpcode op, char *out)
433 {
434 const char *name = MIPSGetName(op);
435 int vd = _VD;
436 int vs = _VS;
437 int vt = _VT;
438 VectorSize sz = GetVecSizeSafe(op);
439 sprintf(out, "%s%s\t%s, %s, %s", name, VSuff(op), VN(vd, sz), VN(vs,sz), VN(vt, sz));
440 }
441
Dis_VRot(MIPSOpcode op,char * out)442 void Dis_VRot(MIPSOpcode op, char *out)
443 {
444 int vd = _VD;
445 int vs = _VS;
446 int imm = (op>>16) & 0x1f;
447 bool negSin = (imm & 0x10) ? true : false;
448 char c[5] = "0000";
449 char temp[16]={""};
450 if (((imm>>2)&3)==(imm&3))
451 {
452 for (int i=0; i<4; i++)
453 c[i]='S';
454 }
455 c[(imm>>2) & 3] = 'S';
456 c[imm&3] = 'C';
457 VectorSize sz = GetVecSizeSafe(op);
458 int numElems = GetNumVectorElements(sz);
459 int pos = 0;
460 temp[pos++] = '[';
461 for (int i=0; i<numElems; i++)
462 {
463 if (c[i] == 'S' && negSin)
464 temp[pos++] = '-';
465 temp[pos++] = c[i];
466 if (i != numElems-1)
467 temp[pos++] = ',';
468 }
469 temp[pos++] = ']';
470 temp[pos]=0;
471 const char *name = MIPSGetName(op);
472 sprintf(out, "%s%s\t%s, %s, %s",name,VSuff(op),VN(vd, sz),VN(vs, V_Single),temp);
473 }
474
Dis_CrossQuat(MIPSOpcode op,char * out)475 void Dis_CrossQuat(MIPSOpcode op, char *out)
476 {
477 VectorSize sz = GetVecSizeSafe(op);
478 const char *name;
479 switch (sz)
480 {
481 case V_Triple:
482 name = "vcrsp";
483 //Ah, a regular cross product.
484 break;
485 case V_Quad:
486 name = "vqmul";
487 //Ah, a quaternion multiplication.
488 break;
489 default:
490 // invalid
491 name = "???";
492 break;
493 }
494 int vd = _VD;
495 int vs = _VS;
496 int vt = _VT;
497 sprintf(out, "%s%s\t%s, %s, %s", name, VSuff(op), VN(vd, sz), VN(vs,sz), VN(vt, sz));
498 }
499
Dis_Vbfy(MIPSOpcode op,char * out)500 void Dis_Vbfy(MIPSOpcode op, char *out)
501 {
502 VectorSize sz = GetVecSizeSafe(op);
503 int vd = _VD;
504 int vs = _VS;
505 const char *name = MIPSGetName(op);
506 sprintf(out, "%s%s\t%s, %s",name,VSuff(op),VN(vd, sz),VN(vs, sz));
507 }
508
Dis_Vf2i(MIPSOpcode op,char * out)509 void Dis_Vf2i(MIPSOpcode op, char *out)
510 {
511 VectorSize sz = GetVecSizeSafe(op);
512 int vd = _VD;
513 int vs = _VS;
514 int imm = (op>>16)&0x1f;
515 const char *name = MIPSGetName(op);
516 sprintf(out, "%s%s\t%s, %s, %i",name,VSuff(op),VN(vd, sz),VN(vs, sz),imm);
517 }
518
Dis_Vs2i(MIPSOpcode op,char * out)519 void Dis_Vs2i(MIPSOpcode op, char *out)
520 {
521 VectorSize sz = GetVecSizeSafe(op);
522 int vd = _VD;
523 int vs = _VS;
524 const char *name = MIPSGetName(op);
525 sprintf(out, "%s%s\t%s, %s",name,VSuff(op),VN(vd, sz),VN(vs, sz));
526 }
527
Dis_Vi2x(MIPSOpcode op,char * out)528 void Dis_Vi2x(MIPSOpcode op, char *out)
529 {
530 VectorSize sz = GetVecSizeSafe(op);
531 VectorSize dsz = GetHalfVectorSizeSafe(sz);
532 if (((op>>16)&3)==0)
533 dsz = V_Single;
534
535 int vd = _VD;
536 int vs = _VS;
537 const char *name = MIPSGetName(op);
538 sprintf(out, "%s%s\t%s, %s",name,VSuff(op),VN(vd, dsz),VN(vs, sz));
539 }
540
Dis_Vwbn(MIPSOpcode op,char * out)541 void Dis_Vwbn(MIPSOpcode op, char *out)
542 {
543 VectorSize sz = GetVecSizeSafe(op);
544
545 int vd = _VD;
546 int vs = _VS;
547 int imm = (int)((op >> 16) & 0xFF);
548 const char *name = MIPSGetName(op);
549 sprintf(out, "%s%s\t%s, %s, %d", name, VSuff(op), VN(vd, sz), VN(vs, sz), imm);
550 }
551
Dis_Vf2h(MIPSOpcode op,char * out)552 void Dis_Vf2h(MIPSOpcode op, char *out)
553 {
554 VectorSize sz = GetVecSizeSafe(op);
555 VectorSize dsz = GetHalfVectorSizeSafe(sz);
556 if (((op>>16)&3)==0)
557 dsz = V_Single;
558
559 int vd = _VD;
560 int vs = _VS;
561 const char *name = MIPSGetName(op);
562 sprintf(out, "%s%s\t%s, %s", name, VSuff(op), VN(vd, dsz), VN(vs, sz));
563 }
564
Dis_Vh2f(MIPSOpcode op,char * out)565 void Dis_Vh2f(MIPSOpcode op, char *out)
566 {
567 VectorSize sz = GetVecSizeSafe(op);
568 VectorSize dsz = GetDoubleVectorSizeSafe(sz);
569
570 int vd = _VD;
571 int vs = _VS;
572 const char *name = MIPSGetName(op);
573 sprintf(out, "%s%s\t%s, %s", name, VSuff(op), VN(vd, dsz), VN(vs, sz));
574 }
575
Dis_ColorConv(MIPSOpcode op,char * out)576 void Dis_ColorConv(MIPSOpcode op, char *out)
577 {
578 VectorSize sz = GetVecSizeSafe(op);
579 VectorSize dsz = GetHalfVectorSizeSafe(sz);
580
581 int vd = _VD;
582 int vs = _VS;
583 const char *name = MIPSGetName(op);
584 sprintf(out, "%s%s\t%s, %s", name, VSuff(op), VN(vd, dsz), VN(vs, sz));
585 }
586
Dis_Vrnds(MIPSOpcode op,char * out)587 void Dis_Vrnds(MIPSOpcode op, char *out)
588 {
589 int vd = _VD;
590 const char *name = MIPSGetName(op);
591 sprintf(out, "%s%s\t%s", name, VSuff(op), VN(vd, V_Single));
592 }
593
Dis_VrndX(MIPSOpcode op,char * out)594 void Dis_VrndX(MIPSOpcode op, char *out)
595 {
596 VectorSize sz = GetVecSizeSafe(op);
597
598 int vd = _VD;
599 const char *name = MIPSGetName(op);
600 sprintf(out, "%s%s\t%s", name, VSuff(op), VN(vd, sz));
601 }
602
Dis_VBranch(MIPSOpcode op,char * out)603 void Dis_VBranch(MIPSOpcode op, char *out)
604 {
605 u32 off = disPC;
606 int imm = (signed short)(op&0xFFFF)<<2;
607 int imm3 = (op>>18)&7;
608 off += imm + 4;
609 const char *name = MIPSGetName(op);
610 sprintf(out, "%s\t->$%08x (CC[%i])",name,off,imm3);
611 }
612
613 }
614