xref: /plan9-contrib/sys/src/cmd/aux/realemu/fmt.c (revision ccaec48a6a7d481d90233fb80c88e608b0a02604)
1*ccaec48aSDavid du Colombier #include <u.h>
2*ccaec48aSDavid du Colombier #include <libc.h>
3*ccaec48aSDavid du Colombier #include "dat.h"
4*ccaec48aSDavid du Colombier #include "fns.h"
5*ccaec48aSDavid du Colombier 
6*ccaec48aSDavid du Colombier static char *opstr[] = {	/* Edit s/O(.*),/[O\1]=	"\1",/g */
7*ccaec48aSDavid du Colombier 	[OBAD]=	"BAD",
8*ccaec48aSDavid du Colombier 	[O0F]=	"0F",
9*ccaec48aSDavid du Colombier 	[OAAA]=	"AAA",
10*ccaec48aSDavid du Colombier 	[OAAD]=	"AAD",
11*ccaec48aSDavid du Colombier 	[OAAM]=	"AAM",
12*ccaec48aSDavid du Colombier 	[OAAS]=	"AAS",
13*ccaec48aSDavid du Colombier 	[OADC]=	"ADC",
14*ccaec48aSDavid du Colombier 	[OADD]=	"ADD",
15*ccaec48aSDavid du Colombier 	[OAND]=	"AND",
16*ccaec48aSDavid du Colombier 	[OARPL]=	"ARPL",
17*ccaec48aSDavid du Colombier 	[OASIZE]=	"ASIZE",
18*ccaec48aSDavid du Colombier 	[OBOUND]=	"BOUND",
19*ccaec48aSDavid du Colombier 	[OBT]=	"BT",
20*ccaec48aSDavid du Colombier 	[OBTC]= "BTC",
21*ccaec48aSDavid du Colombier 	[OBTR]= "BTR",
22*ccaec48aSDavid du Colombier 	[OBTS]=	"BTS",
23*ccaec48aSDavid du Colombier 	[OBSF]= "BSF",
24*ccaec48aSDavid du Colombier 	[OBSR]= "BSR",
25*ccaec48aSDavid du Colombier 	[OCALL]=	"CALL",
26*ccaec48aSDavid du Colombier 	[OCBW]=	"CBW",
27*ccaec48aSDavid du Colombier 	[OCLC]=	"CLC",
28*ccaec48aSDavid du Colombier 	[OCLD]=	"CLD",
29*ccaec48aSDavid du Colombier 	[OCLI]=	"CLI",
30*ccaec48aSDavid du Colombier 	[OCMC]=	"CMC",
31*ccaec48aSDavid du Colombier 	[OCMOV]=	"CMOV",
32*ccaec48aSDavid du Colombier 	[OCMP]=	"CMP",
33*ccaec48aSDavid du Colombier 	[OCMPS]=	"CMPS",
34*ccaec48aSDavid du Colombier 	[OCWD]=	"CWD",
35*ccaec48aSDavid du Colombier 	[ODAA]=	"DAA",
36*ccaec48aSDavid du Colombier 	[ODAS]=	"DAS",
37*ccaec48aSDavid du Colombier 	[ODEC]=	"DEC",
38*ccaec48aSDavid du Colombier 	[ODIV]=	"DIV",
39*ccaec48aSDavid du Colombier 	[OENTER]=	"ENTER",
40*ccaec48aSDavid du Colombier 	[OGP1]=	"GP1",
41*ccaec48aSDavid du Colombier 	[OGP2]=	"GP2",
42*ccaec48aSDavid du Colombier 	[OGP3b]=	"GP3b",
43*ccaec48aSDavid du Colombier 	[OGP3v]=	"GP3v",
44*ccaec48aSDavid du Colombier 	[OGP4]=	"GP4",
45*ccaec48aSDavid du Colombier 	[OGP5]=	"GP5",
46*ccaec48aSDavid du Colombier 	[OHLT]=	"HLT",
47*ccaec48aSDavid du Colombier 	[OIDIV]=	"IDIV",
48*ccaec48aSDavid du Colombier 	[OIMUL]=	"IMUL",
49*ccaec48aSDavid du Colombier 	[OIN]=	"IN",
50*ccaec48aSDavid du Colombier 	[OINC]=	"INC",
51*ccaec48aSDavid du Colombier 	[OINS]=	"INS",
52*ccaec48aSDavid du Colombier 	[OINT]=	"INT",
53*ccaec48aSDavid du Colombier 	[OIRET]=	"IRET",
54*ccaec48aSDavid du Colombier 	[OJUMP]=	"JUMP",
55*ccaec48aSDavid du Colombier 	[OLAHF]=	"LAHF",
56*ccaec48aSDavid du Colombier 	[OLFP]=	"LFP",
57*ccaec48aSDavid du Colombier 	[OLEA]=	"LEA",
58*ccaec48aSDavid du Colombier 	[OLEAVE]=	"LEAVE",
59*ccaec48aSDavid du Colombier 	[OLOCK]=	"LOCK",
60*ccaec48aSDavid du Colombier 	[OLODS]=	"LODS",
61*ccaec48aSDavid du Colombier 	[OLOOP]=	"LOOP",
62*ccaec48aSDavid du Colombier 	[OLOOPNZ]=	"LOOPNZ",
63*ccaec48aSDavid du Colombier 	[OLOOPZ]=	"LOOPZ",
64*ccaec48aSDavid du Colombier 	[OMOV]=	"MOV",
65*ccaec48aSDavid du Colombier 	[OMOVS]=	"MOVS",
66*ccaec48aSDavid du Colombier 	[OMOVZX]=	"MOVZX",
67*ccaec48aSDavid du Colombier 	[OMOVSX]=	"MOVSX",
68*ccaec48aSDavid du Colombier 	[OMUL]=	"MUL",
69*ccaec48aSDavid du Colombier 	[ONEG]=	"NEG",
70*ccaec48aSDavid du Colombier 	[ONOP]=	"NOP",
71*ccaec48aSDavid du Colombier 	[ONOT]=	"NOT",
72*ccaec48aSDavid du Colombier 	[OOR]=	"OR",
73*ccaec48aSDavid du Colombier 	[OOSIZE]=	"OSIZE",
74*ccaec48aSDavid du Colombier 	[OOUT]=	"OUT",
75*ccaec48aSDavid du Colombier 	[OOUTS]=	"OUTS",
76*ccaec48aSDavid du Colombier 	[OPOP]=	"POP",
77*ccaec48aSDavid du Colombier 	[OPOPA]=	"POPA",
78*ccaec48aSDavid du Colombier 	[OPOPF]=	"POPF",
79*ccaec48aSDavid du Colombier 	[OPUSH]=	"PUSH",
80*ccaec48aSDavid du Colombier 	[OPUSHA]=	"PUSHA",
81*ccaec48aSDavid du Colombier 	[OPUSHF]=	"PUSHF",
82*ccaec48aSDavid du Colombier 	[ORCL]=	"RCL",
83*ccaec48aSDavid du Colombier 	[ORCR]=	"RCR",
84*ccaec48aSDavid du Colombier 	[OREPE]=	"REPE",
85*ccaec48aSDavid du Colombier 	[OREPNE]=	"REPNE",
86*ccaec48aSDavid du Colombier 	[ORET]=	"RET",
87*ccaec48aSDavid du Colombier 	[ORETF]=	"RETF",
88*ccaec48aSDavid du Colombier 	[OROL]=	"ROL",
89*ccaec48aSDavid du Colombier 	[OROR]=	"ROR",
90*ccaec48aSDavid du Colombier 	[OSAHF]=	"SAHF",
91*ccaec48aSDavid du Colombier 	[OSAR]=	"SAR",
92*ccaec48aSDavid du Colombier 	[OSBB]=	"SBB",
93*ccaec48aSDavid du Colombier 	[OSCAS]=	"SCAS",
94*ccaec48aSDavid du Colombier 	[OSEG]=	"SEG",
95*ccaec48aSDavid du Colombier 	[OSET]=	"SET",
96*ccaec48aSDavid du Colombier 	[OSHL]=	"SHL",
97*ccaec48aSDavid du Colombier 	[OSHLD]=	"SHLD",
98*ccaec48aSDavid du Colombier 	[OSHR]=	"SHR",
99*ccaec48aSDavid du Colombier 	[OSHRD]=	"SHRD",
100*ccaec48aSDavid du Colombier 	[OSTC]=	"STC",
101*ccaec48aSDavid du Colombier 	[OSTD]=	"STD",
102*ccaec48aSDavid du Colombier 	[OSTI]=	"STI",
103*ccaec48aSDavid du Colombier 	[OSTOS]=	"STOS",
104*ccaec48aSDavid du Colombier 	[OSUB]=	"SUB",
105*ccaec48aSDavid du Colombier 	[OTEST]=	"TEST",
106*ccaec48aSDavid du Colombier 	[OWAIT]=	"WAIT",
107*ccaec48aSDavid du Colombier 	[OXCHG]=	"XCHG",
108*ccaec48aSDavid du Colombier 	[OXLAT]=	"XLAT",
109*ccaec48aSDavid du Colombier 	[OXOR]=	"XOR",
110*ccaec48aSDavid du Colombier };
111*ccaec48aSDavid du Colombier 
112*ccaec48aSDavid du Colombier static char *memstr16[] = {
113*ccaec48aSDavid du Colombier 	"BX+SI",
114*ccaec48aSDavid du Colombier 	"BX+DI",
115*ccaec48aSDavid du Colombier 	"BP+SI",
116*ccaec48aSDavid du Colombier 	"BP+DI",
117*ccaec48aSDavid du Colombier 	"SI",
118*ccaec48aSDavid du Colombier 	"DI",
119*ccaec48aSDavid du Colombier 	"BP",
120*ccaec48aSDavid du Colombier 	"BX",
121*ccaec48aSDavid du Colombier };
122*ccaec48aSDavid du Colombier 
123*ccaec48aSDavid du Colombier static char *memstr32[] = {
124*ccaec48aSDavid du Colombier 	"EAX",
125*ccaec48aSDavid du Colombier 	"ECX",
126*ccaec48aSDavid du Colombier 	"EDX",
127*ccaec48aSDavid du Colombier 	"EBX",
128*ccaec48aSDavid du Colombier 	"0",
129*ccaec48aSDavid du Colombier 	"EBP",
130*ccaec48aSDavid du Colombier 	"ESI",
131*ccaec48aSDavid du Colombier 	"EDI",
132*ccaec48aSDavid du Colombier };
133*ccaec48aSDavid du Colombier 
134*ccaec48aSDavid du Colombier static int
argconv(char * p,Inst * i,Iarg * a)135*ccaec48aSDavid du Colombier argconv(char *p, Inst *i, Iarg *a)
136*ccaec48aSDavid du Colombier {
137*ccaec48aSDavid du Colombier 	jmp_buf jmp;
138*ccaec48aSDavid du Colombier 	char *s;
139*ccaec48aSDavid du Colombier 
140*ccaec48aSDavid du Colombier 	s = p;
141*ccaec48aSDavid du Colombier 	switch(a->tag){
142*ccaec48aSDavid du Colombier 	default:
143*ccaec48aSDavid du Colombier 		abort();
144*ccaec48aSDavid du Colombier 
145*ccaec48aSDavid du Colombier 	case TCON:
146*ccaec48aSDavid du Colombier 		return sprint(p, "%lud", a->val);
147*ccaec48aSDavid du Colombier 	case TREG:
148*ccaec48aSDavid du Colombier 	case TREG|TH:
149*ccaec48aSDavid du Colombier 		switch(a->len){
150*ccaec48aSDavid du Colombier 		case 1:
151*ccaec48aSDavid du Colombier 			return sprint(p, "%c%c", "ACDB"[a->reg], "LH"[(a->tag & TH) != 0]);
152*ccaec48aSDavid du Colombier 		case 4:
153*ccaec48aSDavid du Colombier 			*p++ = 'E';
154*ccaec48aSDavid du Colombier 		case 2:
155*ccaec48aSDavid du Colombier 			p += sprint(p, "%c%c",
156*ccaec48aSDavid du Colombier 				"ACDBSBSDECSDFGIF"[a->reg],
157*ccaec48aSDavid du Colombier 				"XXXXPPIISSSSSSPL"[a->reg]);
158*ccaec48aSDavid du Colombier 			return p - s;
159*ccaec48aSDavid du Colombier 		}
160*ccaec48aSDavid du Colombier 	case TMEM:
161*ccaec48aSDavid du Colombier 		break;
162*ccaec48aSDavid du Colombier 	}
163*ccaec48aSDavid du Colombier 
164*ccaec48aSDavid du Colombier 	/* setup trap jump in case we dereference bad memory */
165*ccaec48aSDavid du Colombier 	memmove(jmp, a->cpu->jmp, sizeof jmp);
166*ccaec48aSDavid du Colombier 	if(setjmp(a->cpu->jmp)){
167*ccaec48aSDavid du Colombier 		p += sprint(p, "<%.4lux:%.4lux>", a->seg, a->off);
168*ccaec48aSDavid du Colombier 		goto out;
169*ccaec48aSDavid du Colombier 	}
170*ccaec48aSDavid du Colombier 
171*ccaec48aSDavid du Colombier 	switch(a->atype){
172*ccaec48aSDavid du Colombier 	default:
173*ccaec48aSDavid du Colombier 		abort();
174*ccaec48aSDavid du Colombier 
175*ccaec48aSDavid du Colombier 	case AAp:
176*ccaec48aSDavid du Colombier 		p += sprint(p, "[%.4lux:%.4lux]", a->seg, a->off);
177*ccaec48aSDavid du Colombier 		break;
178*ccaec48aSDavid du Colombier 
179*ccaec48aSDavid du Colombier 	case AJb:
180*ccaec48aSDavid du Colombier 	case AJv:
181*ccaec48aSDavid du Colombier 		p += sprint(p, "[%.4lux]", a->off);
182*ccaec48aSDavid du Colombier 		break;
183*ccaec48aSDavid du Colombier 
184*ccaec48aSDavid du Colombier 	case AIc:
185*ccaec48aSDavid du Colombier 		p += sprint(p, "$%.2lx", ars(a));
186*ccaec48aSDavid du Colombier 		break;
187*ccaec48aSDavid du Colombier 	case AIb:
188*ccaec48aSDavid du Colombier 	case AIw:
189*ccaec48aSDavid du Colombier 	case AIv:
190*ccaec48aSDavid du Colombier 		p += sprint(p, "$%.*lux", (int)a->len*2, ar(a));
191*ccaec48aSDavid du Colombier 		break;
192*ccaec48aSDavid du Colombier 
193*ccaec48aSDavid du Colombier 	case AMp:
194*ccaec48aSDavid du Colombier 		*p++ = '*';
195*ccaec48aSDavid du Colombier 	case AEb:
196*ccaec48aSDavid du Colombier 	case AEw:
197*ccaec48aSDavid du Colombier 	case AEv:
198*ccaec48aSDavid du Colombier 	case AM:
199*ccaec48aSDavid du Colombier 	case AMa:
200*ccaec48aSDavid du Colombier 	case AMa2:
201*ccaec48aSDavid du Colombier 	case AOb:
202*ccaec48aSDavid du Colombier 	case AOv:
203*ccaec48aSDavid du Colombier 		if(i->sreg != RDS)
204*ccaec48aSDavid du Colombier 			p += sprint(p, "%cS:", "ECSDFG"[i->sreg - RES]);
205*ccaec48aSDavid du Colombier 		if(a->atype == AOb || a->atype == AOv || (i->mod == 0 &&
206*ccaec48aSDavid du Colombier 			(i->alen == 2 && i->rm == 6) ||
207*ccaec48aSDavid du Colombier 			(i->alen == 4 && ((i->rm == 5) ||
208*ccaec48aSDavid du Colombier 			(i->rm == 4 && i->index == 4 && i->base == 5))))){
209*ccaec48aSDavid du Colombier 			p += sprint(p, "[%.*lux]", (int)i->alen*2, a->off);
210*ccaec48aSDavid du Colombier 			break;
211*ccaec48aSDavid du Colombier 		}
212*ccaec48aSDavid du Colombier 		*p++ = '[';
213*ccaec48aSDavid du Colombier 		if(i->alen == 2)
214*ccaec48aSDavid du Colombier 			p += sprint(p, "%s", memstr16[i->rm]);
215*ccaec48aSDavid du Colombier 		else{
216*ccaec48aSDavid du Colombier 			if(i->rm == 4){
217*ccaec48aSDavid du Colombier 				if(i->index != 4)
218*ccaec48aSDavid du Colombier 					p += sprint(p, "%c*%s+", "1248"[i->scale], memstr32[i->index]);
219*ccaec48aSDavid du Colombier 				if(i->base != 5)
220*ccaec48aSDavid du Colombier 					p += sprint(p, "%s", memstr32[i->base]);
221*ccaec48aSDavid du Colombier 				else{
222*ccaec48aSDavid du Colombier 					if(i->mod == 0)
223*ccaec48aSDavid du Colombier 						p += sprint(p, "%.4lux", i->off);
224*ccaec48aSDavid du Colombier 					else
225*ccaec48aSDavid du Colombier 						p += sprint(p, "EBP");
226*ccaec48aSDavid du Colombier 				}
227*ccaec48aSDavid du Colombier 			} else
228*ccaec48aSDavid du Colombier 				p += sprint(p, "%s", memstr32[i->rm]);
229*ccaec48aSDavid du Colombier 		}
230*ccaec48aSDavid du Colombier 		if(i->mod != 0)
231*ccaec48aSDavid du Colombier 			p += sprint(p, "%+lx", i->disp);
232*ccaec48aSDavid du Colombier 		*p++ = ']';
233*ccaec48aSDavid du Colombier 		break;
234*ccaec48aSDavid du Colombier 
235*ccaec48aSDavid du Colombier 	case AXb:
236*ccaec48aSDavid du Colombier 	case AXv:
237*ccaec48aSDavid du Colombier 		if(a->sreg != RDS)
238*ccaec48aSDavid du Colombier 			p += sprint(p, "%cS:", "ECSDFG"[a->sreg - RES]);
239*ccaec48aSDavid du Colombier 		p += sprint(p, "[SI]");
240*ccaec48aSDavid du Colombier 		break;
241*ccaec48aSDavid du Colombier 	case AYb:
242*ccaec48aSDavid du Colombier 	case AYv:
243*ccaec48aSDavid du Colombier 		if(a->sreg != RDS)
244*ccaec48aSDavid du Colombier 			p += sprint(p, "%cS:", "ECSDFG"[a->sreg - RES]);
245*ccaec48aSDavid du Colombier 		p += sprint(p, "[DI]");
246*ccaec48aSDavid du Colombier 		break;
247*ccaec48aSDavid du Colombier 	}
248*ccaec48aSDavid du Colombier 
249*ccaec48aSDavid du Colombier out:
250*ccaec48aSDavid du Colombier 	memmove(a->cpu->jmp, jmp, sizeof jmp);
251*ccaec48aSDavid du Colombier 	*p = 0;
252*ccaec48aSDavid du Colombier 	return p - s;
253*ccaec48aSDavid du Colombier }
254*ccaec48aSDavid du Colombier 
255*ccaec48aSDavid du Colombier static char *jmpstr[] = {
256*ccaec48aSDavid du Colombier 	"JO", "JNO", "JC", "JNC", "JZ", "JNZ", "JBE", "JA",
257*ccaec48aSDavid du Colombier 	"JS", "JNS", "JP", "JNP", "JL", "JGE", "JLE", "JG",
258*ccaec48aSDavid du Colombier };
259*ccaec48aSDavid du Colombier 
260*ccaec48aSDavid du Colombier int
instfmt(Fmt * fmt)261*ccaec48aSDavid du Colombier instfmt(Fmt *fmt)
262*ccaec48aSDavid du Colombier {
263*ccaec48aSDavid du Colombier 	Inst *i;
264*ccaec48aSDavid du Colombier 	char *p, buf[256];
265*ccaec48aSDavid du Colombier 
266*ccaec48aSDavid du Colombier 	i = va_arg(fmt->args, Inst*);
267*ccaec48aSDavid du Colombier 	p = buf;
268*ccaec48aSDavid du Colombier 
269*ccaec48aSDavid du Colombier 	if(i->olen == 4)
270*ccaec48aSDavid du Colombier 		p += sprint(p, "O32: ");
271*ccaec48aSDavid du Colombier 	if(i->alen == 4)
272*ccaec48aSDavid du Colombier 		p += sprint(p, "A32: ");
273*ccaec48aSDavid du Colombier 	if(i->rep)
274*ccaec48aSDavid du Colombier 		p += sprint(p, "%s: ", opstr[i->rep]);
275*ccaec48aSDavid du Colombier 
276*ccaec48aSDavid du Colombier 	if(i->op == OXLAT && i->sreg != RDS)
277*ccaec48aSDavid du Colombier 		p += sprint(p, "%cS:", "ECSDFG"[i->sreg - RES]);
278*ccaec48aSDavid du Colombier 
279*ccaec48aSDavid du Colombier 	if(i->op == OJUMP){
280*ccaec48aSDavid du Colombier 		switch(i->code){
281*ccaec48aSDavid du Colombier 		case 0xE3:
282*ccaec48aSDavid du Colombier 			p += sprint(p, "%s ", "JCXZ");
283*ccaec48aSDavid du Colombier 			break;
284*ccaec48aSDavid du Colombier 		case 0xEB:
285*ccaec48aSDavid du Colombier 		case 0xE9:
286*ccaec48aSDavid du Colombier 		case 0xEA:
287*ccaec48aSDavid du Colombier 		case 0xFF:
288*ccaec48aSDavid du Colombier 			p += sprint(p, "%s ", "JMP");
289*ccaec48aSDavid du Colombier 			break;
290*ccaec48aSDavid du Colombier 		default:
291*ccaec48aSDavid du Colombier 			p += sprint(p, "%s ", jmpstr[i->code&0xF]);
292*ccaec48aSDavid du Colombier 			break;
293*ccaec48aSDavid du Colombier 		}
294*ccaec48aSDavid du Colombier 	} else
295*ccaec48aSDavid du Colombier 		p += sprint(p, "%s ", opstr[i->op]);
296*ccaec48aSDavid du Colombier 
297*ccaec48aSDavid du Colombier 
298*ccaec48aSDavid du Colombier 	for(;;){
299*ccaec48aSDavid du Colombier 		if(i->a1 == nil)
300*ccaec48aSDavid du Colombier 			break;
301*ccaec48aSDavid du Colombier 		p += argconv(p, i, i->a1);
302*ccaec48aSDavid du Colombier 		if(i->a2 == nil)
303*ccaec48aSDavid du Colombier 			break;
304*ccaec48aSDavid du Colombier 		*p++ = ',';
305*ccaec48aSDavid du Colombier 		*p++ = ' ';
306*ccaec48aSDavid du Colombier 		p += argconv(p, i, i->a2);
307*ccaec48aSDavid du Colombier 		if(i->a3 == nil)
308*ccaec48aSDavid du Colombier 			break;
309*ccaec48aSDavid du Colombier 		*p++ = ',';
310*ccaec48aSDavid du Colombier 		*p++ = ' ';
311*ccaec48aSDavid du Colombier 		p += argconv(p, i, i->a3);
312*ccaec48aSDavid du Colombier 		break;
313*ccaec48aSDavid du Colombier 	}
314*ccaec48aSDavid du Colombier 	*p = 0;
315*ccaec48aSDavid du Colombier 	fmtstrcpy(fmt, buf);
316*ccaec48aSDavid du Colombier 	return 0;
317*ccaec48aSDavid du Colombier }
318*ccaec48aSDavid du Colombier 
319*ccaec48aSDavid du Colombier int
flagfmt(Fmt * fmt)320*ccaec48aSDavid du Colombier flagfmt(Fmt *fmt)
321*ccaec48aSDavid du Colombier {
322*ccaec48aSDavid du Colombier 	char buf[16];
323*ccaec48aSDavid du Colombier 	ulong f;
324*ccaec48aSDavid du Colombier 
325*ccaec48aSDavid du Colombier 	f = va_arg(fmt->args, ulong);
326*ccaec48aSDavid du Colombier 	sprint(buf, "%c%c%c%c%c%c%c",
327*ccaec48aSDavid du Colombier 		(f & CF) ? 'C' : 'c',
328*ccaec48aSDavid du Colombier 		(f & SF) ? 'S' : 's',
329*ccaec48aSDavid du Colombier 		(f & ZF) ? 'Z' : 'z',
330*ccaec48aSDavid du Colombier 		(f & OF) ? 'O' : 'o',
331*ccaec48aSDavid du Colombier 		(f & PF) ? 'P' : 'p',
332*ccaec48aSDavid du Colombier 		(f & DF) ? 'D' : 'd',
333*ccaec48aSDavid du Colombier 		(f & IF) ? 'I' : 'i');
334*ccaec48aSDavid du Colombier 	fmtstrcpy(fmt, buf);
335*ccaec48aSDavid du Colombier 	return 0;
336*ccaec48aSDavid du Colombier }
337*ccaec48aSDavid du Colombier 
338*ccaec48aSDavid du Colombier int
cpufmt(Fmt * fmt)339*ccaec48aSDavid du Colombier cpufmt(Fmt *fmt)
340*ccaec48aSDavid du Colombier {
341*ccaec48aSDavid du Colombier 	char buf[512];
342*ccaec48aSDavid du Colombier 	jmp_buf jmp;
343*ccaec48aSDavid du Colombier 	Cpu *cpu;
344*ccaec48aSDavid du Colombier 	Inst i;
345*ccaec48aSDavid du Colombier 
346*ccaec48aSDavid du Colombier 	cpu = va_arg(fmt->args, Cpu*);
347*ccaec48aSDavid du Colombier 
348*ccaec48aSDavid du Colombier 	memmove(jmp, cpu->jmp, sizeof jmp);
349*ccaec48aSDavid du Colombier 	if(setjmp(cpu->jmp) == 0)
350*ccaec48aSDavid du Colombier 		decode(amem(cpu, 1, RCS, cpu->reg[RIP]), &i);
351*ccaec48aSDavid du Colombier 	memmove(cpu->jmp, jmp, sizeof jmp);
352*ccaec48aSDavid du Colombier 
353*ccaec48aSDavid du Colombier 	snprint(buf, sizeof(buf),
354*ccaec48aSDavid du Colombier 		"%.6lux "
355*ccaec48aSDavid du Colombier 		"%.8lux %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux "
356*ccaec48aSDavid du Colombier 		"%.4lux %.4lux %.4lux %.4lux "
357*ccaec48aSDavid du Colombier 		"%J %.4lux %.2ux %I",
358*ccaec48aSDavid du Colombier 
359*ccaec48aSDavid du Colombier 		cpu->ic,
360*ccaec48aSDavid du Colombier 
361*ccaec48aSDavid du Colombier 		cpu->reg[RAX],
362*ccaec48aSDavid du Colombier 		cpu->reg[RBX],
363*ccaec48aSDavid du Colombier 		cpu->reg[RCX],
364*ccaec48aSDavid du Colombier 		cpu->reg[RDX],
365*ccaec48aSDavid du Colombier 
366*ccaec48aSDavid du Colombier 		cpu->reg[RDI],
367*ccaec48aSDavid du Colombier 		cpu->reg[RSI],
368*ccaec48aSDavid du Colombier 
369*ccaec48aSDavid du Colombier 		cpu->reg[RBP],
370*ccaec48aSDavid du Colombier 		cpu->reg[RSP],
371*ccaec48aSDavid du Colombier 
372*ccaec48aSDavid du Colombier 		cpu->reg[RDS],
373*ccaec48aSDavid du Colombier 		cpu->reg[RES],
374*ccaec48aSDavid du Colombier 		cpu->reg[RSS],
375*ccaec48aSDavid du Colombier 		cpu->reg[RCS],
376*ccaec48aSDavid du Colombier 
377*ccaec48aSDavid du Colombier 		cpu->reg[RFL],
378*ccaec48aSDavid du Colombier 		cpu->reg[RIP],
379*ccaec48aSDavid du Colombier 
380*ccaec48aSDavid du Colombier 		i.code,
381*ccaec48aSDavid du Colombier 		&i);
382*ccaec48aSDavid du Colombier 
383*ccaec48aSDavid du Colombier 	fmtstrcpy(fmt, buf);
384*ccaec48aSDavid du Colombier 	return 0;
385*ccaec48aSDavid du Colombier }
386