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