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 typedef struct Optab Optab;
7*ccaec48aSDavid du Colombier struct Optab {
8*ccaec48aSDavid du Colombier uchar op;
9*ccaec48aSDavid du Colombier uchar a1, a2, a3;
10*ccaec48aSDavid du Colombier };
11*ccaec48aSDavid du Colombier
12*ccaec48aSDavid du Colombier static Optab optab[256] = {
13*ccaec48aSDavid du Colombier //00
14*ccaec48aSDavid du Colombier {OADD, AEb, AGb}, {OADD, AEv, AGv}, {OADD, AGb, AEb}, {OADD, AGv, AEv},
15*ccaec48aSDavid du Colombier {OADD, AAL, AIb}, {OADD, AAX, AIv}, {OPUSH, AES, }, {OPOP, AES },
16*ccaec48aSDavid du Colombier {OOR, AEb, AGb}, {OOR, AEv, AGv}, {OOR, AGb, AEb}, {OOR, AGv, AEv},
17*ccaec48aSDavid du Colombier {OOR, AAL, AIb}, {OOR, AAX, AIv}, {OPUSH, ACS, }, {O0F, },
18*ccaec48aSDavid du Colombier //10
19*ccaec48aSDavid du Colombier {OADC, AEb, AGb}, {OADC, AEv, AGv}, {OADC, AGb, AEb}, {OADC, AGv, AEv},
20*ccaec48aSDavid du Colombier {OADC, AAL, AIb}, {OADC, AAX, AIv}, {OPUSH, ASS, }, {OPOP, ASS, },
21*ccaec48aSDavid du Colombier {OSBB, AEb, AGb}, {OSBB, AEv, AGv}, {OSBB, AGb, AEb}, {OSBB, AGv, AEv},
22*ccaec48aSDavid du Colombier {OSBB, AAL, AIb}, {OSBB, AAX, AIv}, {OPUSH, ADS, }, {OPOP, ADS, },
23*ccaec48aSDavid du Colombier //20
24*ccaec48aSDavid du Colombier {OAND, AEb, AGb}, {OAND, AEv, AGv}, {OAND, AGb, AEb}, {OAND, AGv, AEv},
25*ccaec48aSDavid du Colombier {OAND, AAL, AIb}, {OAND, AAX, AIv}, {OSEG, AES, }, {ODAA, },
26*ccaec48aSDavid du Colombier {OSUB, AEb, AGb}, {OSUB, AEv, AGv}, {OSUB, AGb, AEb}, {OSUB, AGv, AEv},
27*ccaec48aSDavid du Colombier {OSUB, AAL, AIb}, {OSUB, AAX, AIv}, {OSEG, ACS, }, {ODAS, },
28*ccaec48aSDavid du Colombier //30
29*ccaec48aSDavid du Colombier {OXOR, AEb, AGb}, {OXOR, AEv, AGv}, {OXOR, AGb, AEb}, {OXOR, AGv, AEv},
30*ccaec48aSDavid du Colombier {OXOR, AAL, AIb}, {OXOR, AAX, AIv}, {OSEG, ASS, }, {OAAA, },
31*ccaec48aSDavid du Colombier {OCMP, AEb, AGb}, {OCMP, AEv, AGv}, {OCMP, AGb, AEb}, {OCMP, AGv, AEv},
32*ccaec48aSDavid du Colombier {OCMP, AAL, AIb}, {OCMP, AAX, AIv}, {OSEG, ADS, }, {OAAS, },
33*ccaec48aSDavid du Colombier //40
34*ccaec48aSDavid du Colombier {OINC, AAX, }, {OINC, ACX, }, {OINC, ADX, }, {OINC, ABX, },
35*ccaec48aSDavid du Colombier {OINC, ASP, }, {OINC, ABP, }, {OINC, ASI, }, {OINC, ADI, },
36*ccaec48aSDavid du Colombier {ODEC, AAX, }, {ODEC, ACX, }, {ODEC, ADX, }, {ODEC, ABX, },
37*ccaec48aSDavid du Colombier {ODEC, ASP, }, {ODEC, ABP, }, {ODEC, ASI, }, {ODEC, ADI, },
38*ccaec48aSDavid du Colombier //50
39*ccaec48aSDavid du Colombier {OPUSH, AAX, }, {OPUSH, ACX, }, {OPUSH, ADX, }, {OPUSH, ABX, },
40*ccaec48aSDavid du Colombier {OPUSH, ASP, }, {OPUSH, ABP, }, {OPUSH, ASI, }, {OPUSH, ADI, },
41*ccaec48aSDavid du Colombier {OPOP, AAX, }, {OPOP, ACX, }, {OPOP, ADX, }, {OPOP, ABX, },
42*ccaec48aSDavid du Colombier {OPOP, ASP, }, {OPOP, ABP, }, {OPOP, ASI, }, {OPOP, ADI, },
43*ccaec48aSDavid du Colombier //60
44*ccaec48aSDavid du Colombier {OPUSHA, }, {OPOPA, }, {OBOUND,AGv,AMa,AMa2}, {OARPL, AEw, AGw},
45*ccaec48aSDavid du Colombier {OSEG, AFS, }, {OSEG, AGS, }, {OOSIZE, }, {OASIZE, },
46*ccaec48aSDavid du Colombier {OPUSH, AIv, }, {OIMUL,AGv,AEv,AIv},{OPUSH, AIb, }, {OIMUL,AGv,AEv,AIb},
47*ccaec48aSDavid du Colombier {OINS, AYb, ADX}, {OINS, AYv, ADX}, {OOUTS, ADX, AXb}, {OOUTS, ADX, AXv},
48*ccaec48aSDavid du Colombier //70
49*ccaec48aSDavid du Colombier {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, },
50*ccaec48aSDavid du Colombier {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, },
51*ccaec48aSDavid du Colombier {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, },
52*ccaec48aSDavid du Colombier {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, }, {OJUMP, AJb, },
53*ccaec48aSDavid du Colombier //80
54*ccaec48aSDavid du Colombier {OGP1, AEb, AIb}, {OGP1, AEv, AIv}, {OGP1, AEb, AIb}, {OGP1, AEv, AIc},
55*ccaec48aSDavid du Colombier {OTEST, AEb, AGb}, {OTEST, AEv, AGv}, {OXCHG, AEb, AGb}, {OXCHG, AEv, AGv},
56*ccaec48aSDavid du Colombier {OMOV, AEb, AGb}, {OMOV, AEv, AGv}, {OMOV, AGb, AEb}, {OMOV, AGv, AEv},
57*ccaec48aSDavid du Colombier {OMOV, AEw, ASw}, {OLEA, AGv, AM }, {OMOV, ASw, AEw}, {OGP10, },
58*ccaec48aSDavid du Colombier //90
59*ccaec48aSDavid du Colombier {ONOP, }, {OXCHG, ACX, AAX}, {OXCHG, ADX, AAX}, {OXCHG, ABX, AAX},
60*ccaec48aSDavid du Colombier {OXCHG, ASP, AAX}, {OXCHG, ABP, AAX}, {OXCHG, ASI, AAX}, {OXCHG, ADI, AAX},
61*ccaec48aSDavid du Colombier {OCBW, }, {OCWD, }, {OCALL, AAp, }, {OWAIT, },
62*ccaec48aSDavid du Colombier {OPUSHF,AFv, }, {OPOPF, AFv, }, {OSAHF, AAH, }, {OLAHF, AAH, },
63*ccaec48aSDavid du Colombier //A0
64*ccaec48aSDavid du Colombier {OMOV, AAL, AOb}, {OMOV, AAX, AOv}, {OMOV, AOb, AAL}, {OMOV, AOv, AAX},
65*ccaec48aSDavid du Colombier {OMOVS, AYb, AXb}, {OMOVS, AYv, AXv}, {OCMPS, AYb, AXb}, {OCMPS, AYv, AXv},
66*ccaec48aSDavid du Colombier {OTEST, AAL, AIb}, {OTEST, AAX, AIv}, {OSTOS, AYb, AAL}, {OSTOS, AYv, AAX},
67*ccaec48aSDavid du Colombier {OLODS, AAL, AXb}, {OLODS, AAX, AXv}, {OSCAS, AYb, AAL}, {OSCAS, AYv, AAX},
68*ccaec48aSDavid du Colombier //B0
69*ccaec48aSDavid du Colombier {OMOV, AAL, AIb}, {OMOV, ACL, AIb}, {OMOV, ADL, AIb}, {OMOV, ABL, AIb},
70*ccaec48aSDavid du Colombier {OMOV, AAH, AIb}, {OMOV, ACH, AIb}, {OMOV, ADH, AIb}, {OMOV, ABH, AIb},
71*ccaec48aSDavid du Colombier {OMOV, AAX, AIv}, {OMOV, ACX, AIv}, {OMOV, ADX, AIv}, {OMOV, ABX, AIv},
72*ccaec48aSDavid du Colombier {OMOV, ASP, AIv}, {OMOV, ABP, AIv}, {OMOV, ASI, AIv}, {OMOV, ADI, AIv},
73*ccaec48aSDavid du Colombier //C0
74*ccaec48aSDavid du Colombier {OGP2, AEb, AIb}, {OGP2, AEv, AIb}, {ORET, AIw, }, {ORET, A0, },
75*ccaec48aSDavid du Colombier {OLFP,AES,AGv,AMp},{OLFP,ADS,AGv,AMp},{OGP12, AEb, AIb}, {OGP12, AEv, AIv},
76*ccaec48aSDavid du Colombier {OENTER,AIw, AIb}, {OLEAVE, }, {ORETF, AIw, }, {ORETF, A0, },
77*ccaec48aSDavid du Colombier {OINT, A3, }, {OINT, AIb, }, {OINT, A4, }, {OIRET, },
78*ccaec48aSDavid du Colombier //D0
79*ccaec48aSDavid du Colombier {OGP2, AEb, A1 }, {OGP2, AEv, A1 }, {OGP2, AEb, ACL}, {OGP2, AEv, ACL},
80*ccaec48aSDavid du Colombier {OAAM, AIb, }, {OAAD, AIb, }, {OBAD, }, {OXLAT, AAL, ABX},
81*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
82*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
83*ccaec48aSDavid du Colombier //E0
84*ccaec48aSDavid du Colombier {OLOOPNZ,AJb, }, {OLOOPZ,AJb, }, {OLOOP, AJb, }, {OJUMP, AJb, },
85*ccaec48aSDavid du Colombier {OIN, AAL, AIb}, {OIN, AAX, AIb}, {OOUT, AIb, AAL}, {OOUT, AIb, AAX},
86*ccaec48aSDavid du Colombier {OCALL, AJv, }, {OJUMP, AJv, }, {OJUMP, AAp, }, {OJUMP, AJb, },
87*ccaec48aSDavid du Colombier {OIN, AAL, ADX}, {OIN, AAX, ADX}, {OOUT, ADX, AAL}, {OOUT, ADX, AAX},
88*ccaec48aSDavid du Colombier //F0
89*ccaec48aSDavid du Colombier {OLOCK, }, {OBAD, }, {OREPNE, }, {OREPE, },
90*ccaec48aSDavid du Colombier {OHLT, }, {OCMC, }, {OGP3b, }, {OGP3v, },
91*ccaec48aSDavid du Colombier {OCLC, }, {OSTC, }, {OCLI, }, {OSTI, },
92*ccaec48aSDavid du Colombier {OCLD, }, {OSTD, }, {OGP4, }, {OGP5, },
93*ccaec48aSDavid du Colombier };
94*ccaec48aSDavid du Colombier
95*ccaec48aSDavid du Colombier static Optab optab0F[256] = {
96*ccaec48aSDavid du Colombier //00
97*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
98*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
99*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
100*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
101*ccaec48aSDavid du Colombier //10 - mostly floating point and quadword moves
102*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
103*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
104*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
105*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
106*ccaec48aSDavid du Colombier //20 - doubleword <-> control register moves, other arcana
107*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
108*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
109*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
110*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
111*ccaec48aSDavid du Colombier //30 - wrmsr, rdtsc, rdmsr, rdpmc, sysenter, sysexit
112*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
113*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
114*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
115*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
116*ccaec48aSDavid du Colombier //40 - conditional moves
117*ccaec48aSDavid du Colombier {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv},
118*ccaec48aSDavid du Colombier {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv},
119*ccaec48aSDavid du Colombier {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv},
120*ccaec48aSDavid du Colombier {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv}, {OCMOV, AGv, AEv},
121*ccaec48aSDavid du Colombier //50 - floating point, mmx stuff
122*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
123*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
124*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
125*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
126*ccaec48aSDavid du Colombier //60 - floating point, mmx stuff
127*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
128*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
129*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
130*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
131*ccaec48aSDavid du Colombier //70 - floating point, mmx stuff
132*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
133*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
134*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
135*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
136*ccaec48aSDavid du Colombier //80 - long-displacement jumps
137*ccaec48aSDavid du Colombier {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, },
138*ccaec48aSDavid du Colombier {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, },
139*ccaec48aSDavid du Colombier {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, },
140*ccaec48aSDavid du Colombier {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, }, {OJUMP, AJv, },
141*ccaec48aSDavid du Colombier //90 - conditional byte set
142*ccaec48aSDavid du Colombier {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, },
143*ccaec48aSDavid du Colombier {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, },
144*ccaec48aSDavid du Colombier {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, },
145*ccaec48aSDavid du Colombier {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, }, {OSET, AEb, },
146*ccaec48aSDavid du Colombier //A0
147*ccaec48aSDavid du Colombier {OPUSH, AFS, }, {OPOP, AFS, }, {OCPUID, }, {OBT, AEv, AGv},
148*ccaec48aSDavid du Colombier {OSHLD,AEv,AGv,AIb}, {OSHLD,AEv,AGv,ACL}, {OBAD, }, {OBAD, },
149*ccaec48aSDavid du Colombier {OPUSH, AGS, }, {OPOP, AGS, }, {OBAD, }, {OBTS, AEv, AGv},
150*ccaec48aSDavid du Colombier {OSHRD,AEv,AGv,AIb}, {OSHRD,AEv,AGv,ACL}, {OBAD, }, {OIMUL, AGv,AGv,AEv},
151*ccaec48aSDavid du Colombier //B0 - mostly arcana
152*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OLFP,ASS,AGv,AMp},{OBTR,AEv,AGv },
153*ccaec48aSDavid du Colombier {OLFP,AFS,AGv,AMp},{OLFP,AGS,AGv,AMp},{OMOVZX,AGv,AEb }, {OMOVZX,AGv,AEw },
154*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OGP8, }, {OBAD, },
155*ccaec48aSDavid du Colombier {OBSF,AGv,AEv }, {OBSR,AGv,AEv }, {OMOVSX,AGv,AEb }, {OMOVSX,AGv,AEw },
156*ccaec48aSDavid du Colombier //C0 - more arcana
157*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
158*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
159*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
160*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
161*ccaec48aSDavid du Colombier //D0 - mmx
162*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
163*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
164*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
165*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
166*ccaec48aSDavid du Colombier //E0 - mmx
167*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
168*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
169*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
170*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
171*ccaec48aSDavid du Colombier //F0 - mmx
172*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
173*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
174*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
175*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
176*ccaec48aSDavid du Colombier };
177*ccaec48aSDavid du Colombier
178*ccaec48aSDavid du Colombier /* some operands map to whole groups; group numbers from intel opcode map */
179*ccaec48aSDavid du Colombier /* args filled in already (in OGP1 entries) */
180*ccaec48aSDavid du Colombier static Optab optabgp1[8] = {
181*ccaec48aSDavid du Colombier {OADD, }, {OOR, }, {OADC, }, {OSBB, },
182*ccaec48aSDavid du Colombier {OAND, }, {OSUB, }, {OXOR, }, {OCMP, },
183*ccaec48aSDavid du Colombier };
184*ccaec48aSDavid du Colombier
185*ccaec48aSDavid du Colombier /* args filled in already (in OGP2 entries) */
186*ccaec48aSDavid du Colombier static Optab optabgp2[8] = {
187*ccaec48aSDavid du Colombier {OROL, }, {OROR, }, {ORCL, }, {ORCR, },
188*ccaec48aSDavid du Colombier {OSHL, }, {OSHR, }, {OBAD, }, {OSAR, },
189*ccaec48aSDavid du Colombier };
190*ccaec48aSDavid du Colombier
191*ccaec48aSDavid du Colombier static Optab optabgp3b[8] = {
192*ccaec48aSDavid du Colombier {OTEST, AEb, AIb}, {OBAD, }, {ONOT, AEb, }, {ONEG, AEb, },
193*ccaec48aSDavid du Colombier {OMUL,AAX,AAL,AEb},{OIMUL,AAX,AAL,AEb},{ODIV, AEb, }, {OIDIV, AEb, },
194*ccaec48aSDavid du Colombier };
195*ccaec48aSDavid du Colombier
196*ccaec48aSDavid du Colombier static Optab optabgp3v[8] = {
197*ccaec48aSDavid du Colombier {OTEST, AEv, AIv}, {OBAD, }, {ONOT, AEv, }, {ONEG, AEv, },
198*ccaec48aSDavid du Colombier {OMUL,AAX,AAX,AEv},{OIMUL,AAX,AAX,AEv},{ODIV, AEv, }, {OIDIV, AEv, },
199*ccaec48aSDavid du Colombier };
200*ccaec48aSDavid du Colombier
201*ccaec48aSDavid du Colombier static Optab optabgp4[8] = {
202*ccaec48aSDavid du Colombier {OINC, AEb, }, {ODEC, AEb, }, {OBAD, }, {OBAD, },
203*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
204*ccaec48aSDavid du Colombier };
205*ccaec48aSDavid du Colombier
206*ccaec48aSDavid du Colombier static Optab optabgp5[8] = {
207*ccaec48aSDavid du Colombier {OINC, AEv, }, {ODEC, AEv, }, {OCALL, AEv, }, {OCALL, AMp },
208*ccaec48aSDavid du Colombier {OJUMP, AEv, }, {OJUMP, AMp, }, {OPUSH, AEv, }, {OBAD, },
209*ccaec48aSDavid du Colombier };
210*ccaec48aSDavid du Colombier
211*ccaec48aSDavid du Colombier static Optab optabgp8[8] = {
212*ccaec48aSDavid du Colombier {OMOV, }, {OBAD, }, {OBAD, }, {OBAD, },
213*ccaec48aSDavid du Colombier {OBT, AEv, AIb }, {OBTS, AEv, AIb }, {OBTR, AEv, AIb }, {OBTC, AEv, AIb },
214*ccaec48aSDavid du Colombier };
215*ccaec48aSDavid du Colombier
216*ccaec48aSDavid du Colombier static Optab optabgp10[8] = {
217*ccaec48aSDavid du Colombier {OPOP, AEv, }, {OBAD, }, {OBAD, }, {OBAD, },
218*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
219*ccaec48aSDavid du Colombier };
220*ccaec48aSDavid du Colombier
221*ccaec48aSDavid du Colombier static Optab optabgp12[8] = {
222*ccaec48aSDavid du Colombier {OMOV, }, {OBAD, }, {OBAD, }, {OBAD, },
223*ccaec48aSDavid du Colombier {OBAD, }, {OBAD, }, {OBAD, }, {OBAD, },
224*ccaec48aSDavid du Colombier };
225*ccaec48aSDavid du Colombier
226*ccaec48aSDavid du Colombier /* optabg6 unimplemented - mostly segment manipulation */
227*ccaec48aSDavid du Colombier /* optabg7 unimplemented - more segment manipulation */
228*ccaec48aSDavid du Colombier /* optabg8 unimplemented - bit tests */
229*ccaec48aSDavid du Colombier
230*ccaec48aSDavid du Colombier /*
231*ccaec48aSDavid du Colombier * most of optabg9 - optabg16 decode differently depending on the mod value of
232*ccaec48aSDavid du Colombier * the modrm byte. they're mostly arcane instructions so they're not
233*ccaec48aSDavid du Colombier * implemented.
234*ccaec48aSDavid du Colombier */
235*ccaec48aSDavid du Colombier
236*ccaec48aSDavid du Colombier static Optab *optabgp[NUMOP] = {
237*ccaec48aSDavid du Colombier [OGP1] optabgp1,
238*ccaec48aSDavid du Colombier [OGP2] optabgp2,
239*ccaec48aSDavid du Colombier [OGP3b] optabgp3b,
240*ccaec48aSDavid du Colombier [OGP3v] optabgp3v,
241*ccaec48aSDavid du Colombier [OGP4] optabgp4,
242*ccaec48aSDavid du Colombier [OGP5] optabgp5,
243*ccaec48aSDavid du Colombier [OGP8] optabgp8,
244*ccaec48aSDavid du Colombier [OGP10] optabgp10,
245*ccaec48aSDavid du Colombier [OGP12] optabgp12,
246*ccaec48aSDavid du Colombier };
247*ccaec48aSDavid du Colombier
248*ccaec48aSDavid du Colombier static uchar modrmarg[NATYPE] = {
249*ccaec48aSDavid du Colombier [AEb] 1,
250*ccaec48aSDavid du Colombier [AEw] 1,
251*ccaec48aSDavid du Colombier [AEv] 1,
252*ccaec48aSDavid du Colombier [AGb] 1,
253*ccaec48aSDavid du Colombier [AGw] 1,
254*ccaec48aSDavid du Colombier [AGv] 1,
255*ccaec48aSDavid du Colombier [AM] 1,
256*ccaec48aSDavid du Colombier [AMp] 1,
257*ccaec48aSDavid du Colombier [AMa] 1,
258*ccaec48aSDavid du Colombier [AMa2] 1,
259*ccaec48aSDavid du Colombier [ASw] 1,
260*ccaec48aSDavid du Colombier [AJr] 1,
261*ccaec48aSDavid du Colombier };
262*ccaec48aSDavid du Colombier
263*ccaec48aSDavid du Colombier static void
getmodrm16(Iarg * ip,Inst * i)264*ccaec48aSDavid du Colombier getmodrm16(Iarg *ip, Inst *i)
265*ccaec48aSDavid du Colombier {
266*ccaec48aSDavid du Colombier Iarg *p;
267*ccaec48aSDavid du Colombier uchar b;
268*ccaec48aSDavid du Colombier
269*ccaec48aSDavid du Colombier b = ar(ip); ip->off++;
270*ccaec48aSDavid du Colombier
271*ccaec48aSDavid du Colombier i->mod = b>>6;
272*ccaec48aSDavid du Colombier i->reg = (b>>3)&7;
273*ccaec48aSDavid du Colombier i->rm = b&7;
274*ccaec48aSDavid du Colombier
275*ccaec48aSDavid du Colombier if(i->mod == 3)
276*ccaec48aSDavid du Colombier return;
277*ccaec48aSDavid du Colombier
278*ccaec48aSDavid du Colombier switch(i->rm){
279*ccaec48aSDavid du Colombier case 0:
280*ccaec48aSDavid du Colombier i->off = ar(areg(ip->cpu, 2, RBX)) + ar(areg(ip->cpu, 2, RSI));
281*ccaec48aSDavid du Colombier i->off &= 0xFFFF;
282*ccaec48aSDavid du Colombier break;
283*ccaec48aSDavid du Colombier case 1:
284*ccaec48aSDavid du Colombier i->off = ar(areg(ip->cpu, 2, RBX)) + ar(areg(ip->cpu, 2, RDI));
285*ccaec48aSDavid du Colombier i->off &= 0xFFFF;
286*ccaec48aSDavid du Colombier break;
287*ccaec48aSDavid du Colombier case 2:
288*ccaec48aSDavid du Colombier i->dsreg = RSS;
289*ccaec48aSDavid du Colombier i->off = ar(areg(ip->cpu, 2, RBP)) + ar(areg(ip->cpu, 2, RSI));
290*ccaec48aSDavid du Colombier i->off &= 0xFFFF;
291*ccaec48aSDavid du Colombier break;
292*ccaec48aSDavid du Colombier case 3:
293*ccaec48aSDavid du Colombier i->dsreg = RSS;
294*ccaec48aSDavid du Colombier i->off = ar(areg(ip->cpu, 2, RBP)) + ar(areg(ip->cpu, 2, RDI));
295*ccaec48aSDavid du Colombier i->off &= 0xFFFF;
296*ccaec48aSDavid du Colombier break;
297*ccaec48aSDavid du Colombier case 4:
298*ccaec48aSDavid du Colombier i->off = ar(areg(ip->cpu, 2, RSI));
299*ccaec48aSDavid du Colombier break;
300*ccaec48aSDavid du Colombier case 5:
301*ccaec48aSDavid du Colombier i->off = ar(areg(ip->cpu, 2, RDI));
302*ccaec48aSDavid du Colombier break;
303*ccaec48aSDavid du Colombier case 6:
304*ccaec48aSDavid du Colombier if(i->mod == 0){
305*ccaec48aSDavid du Colombier p = adup(ip); ip->off += 2;
306*ccaec48aSDavid du Colombier p->len = 2;
307*ccaec48aSDavid du Colombier i->off = ar(p);
308*ccaec48aSDavid du Colombier return;
309*ccaec48aSDavid du Colombier }
310*ccaec48aSDavid du Colombier i->dsreg = RSS;
311*ccaec48aSDavid du Colombier i->off = ar(areg(ip->cpu, 2, RBP));
312*ccaec48aSDavid du Colombier break;
313*ccaec48aSDavid du Colombier case 7:
314*ccaec48aSDavid du Colombier i->off = ar(areg(ip->cpu, 2, RBX));
315*ccaec48aSDavid du Colombier break;
316*ccaec48aSDavid du Colombier }
317*ccaec48aSDavid du Colombier switch(i->mod){
318*ccaec48aSDavid du Colombier case 1:
319*ccaec48aSDavid du Colombier i->off += (i->disp = ars(ip)); ip->off++;
320*ccaec48aSDavid du Colombier i->off &= 0xFFFF;
321*ccaec48aSDavid du Colombier break;
322*ccaec48aSDavid du Colombier case 2:
323*ccaec48aSDavid du Colombier p = adup(ip); ip->off += 2;
324*ccaec48aSDavid du Colombier p->len = 2;
325*ccaec48aSDavid du Colombier i->off += (i->disp = ars(p));
326*ccaec48aSDavid du Colombier i->off &= 0xFFFF;
327*ccaec48aSDavid du Colombier break;
328*ccaec48aSDavid du Colombier }
329*ccaec48aSDavid du Colombier }
330*ccaec48aSDavid du Colombier
331*ccaec48aSDavid du Colombier static void
getmodrm32(Iarg * ip,Inst * i)332*ccaec48aSDavid du Colombier getmodrm32(Iarg *ip, Inst *i)
333*ccaec48aSDavid du Colombier {
334*ccaec48aSDavid du Colombier static uchar scaler[] = {1, 2, 4, 8};
335*ccaec48aSDavid du Colombier Iarg *p;
336*ccaec48aSDavid du Colombier uchar b;
337*ccaec48aSDavid du Colombier
338*ccaec48aSDavid du Colombier b = ar(ip); ip->off++;
339*ccaec48aSDavid du Colombier
340*ccaec48aSDavid du Colombier i->mod = b>>6;
341*ccaec48aSDavid du Colombier i->reg = (b>>3)&7;
342*ccaec48aSDavid du Colombier i->rm = b&7;
343*ccaec48aSDavid du Colombier
344*ccaec48aSDavid du Colombier if(i->mod == 3)
345*ccaec48aSDavid du Colombier return;
346*ccaec48aSDavid du Colombier
347*ccaec48aSDavid du Colombier switch(i->rm){
348*ccaec48aSDavid du Colombier case 0:
349*ccaec48aSDavid du Colombier case 1:
350*ccaec48aSDavid du Colombier case 2:
351*ccaec48aSDavid du Colombier case 3:
352*ccaec48aSDavid du Colombier case 6:
353*ccaec48aSDavid du Colombier case 7:
354*ccaec48aSDavid du Colombier i->off = ar(areg(ip->cpu, 4, i->rm + RAX));
355*ccaec48aSDavid du Colombier break;
356*ccaec48aSDavid du Colombier case 4:
357*ccaec48aSDavid du Colombier b = ar(ip); ip->off++;
358*ccaec48aSDavid du Colombier i->scale = b>>6;
359*ccaec48aSDavid du Colombier i->index = (b>>3)&7;
360*ccaec48aSDavid du Colombier i->base = b&7;
361*ccaec48aSDavid du Colombier
362*ccaec48aSDavid du Colombier if(i->base != 5){
363*ccaec48aSDavid du Colombier i->off = ar(areg(ip->cpu, 4, i->base + RAX));
364*ccaec48aSDavid du Colombier break;
365*ccaec48aSDavid du Colombier }
366*ccaec48aSDavid du Colombier case 5:
367*ccaec48aSDavid du Colombier if(i->mod == 0){
368*ccaec48aSDavid du Colombier p = adup(ip); ip->off += 4;
369*ccaec48aSDavid du Colombier p->len = 4;
370*ccaec48aSDavid du Colombier i->off = ar(p);
371*ccaec48aSDavid du Colombier } else {
372*ccaec48aSDavid du Colombier i->dsreg = RSS;
373*ccaec48aSDavid du Colombier i->off = ar(areg(ip->cpu, 4, RBP));
374*ccaec48aSDavid du Colombier }
375*ccaec48aSDavid du Colombier break;
376*ccaec48aSDavid du Colombier }
377*ccaec48aSDavid du Colombier
378*ccaec48aSDavid du Colombier if(i->rm == 4 && i->index != 4)
379*ccaec48aSDavid du Colombier i->off += ar(areg(ip->cpu, 4, i->index + RAX)) * scaler[i->scale];
380*ccaec48aSDavid du Colombier
381*ccaec48aSDavid du Colombier switch(i->mod){
382*ccaec48aSDavid du Colombier case 1:
383*ccaec48aSDavid du Colombier i->off += (i->disp = ars(ip)); ip->off++;
384*ccaec48aSDavid du Colombier break;
385*ccaec48aSDavid du Colombier case 2:
386*ccaec48aSDavid du Colombier p = adup(ip); ip->off += 4;
387*ccaec48aSDavid du Colombier p->len = 4;
388*ccaec48aSDavid du Colombier i->off += (i->disp = ars(p));
389*ccaec48aSDavid du Colombier break;
390*ccaec48aSDavid du Colombier }
391*ccaec48aSDavid du Colombier }
392*ccaec48aSDavid du Colombier
393*ccaec48aSDavid du Colombier static Iarg*
getarg(Iarg * ip,Inst * i,uchar atype)394*ccaec48aSDavid du Colombier getarg(Iarg *ip, Inst *i, uchar atype)
395*ccaec48aSDavid du Colombier {
396*ccaec48aSDavid du Colombier Iarg *a;
397*ccaec48aSDavid du Colombier uchar len, reg;
398*ccaec48aSDavid du Colombier
399*ccaec48aSDavid du Colombier len = i->olen;
400*ccaec48aSDavid du Colombier switch(atype){
401*ccaec48aSDavid du Colombier default:
402*ccaec48aSDavid du Colombier abort();
403*ccaec48aSDavid du Colombier
404*ccaec48aSDavid du Colombier case A0:
405*ccaec48aSDavid du Colombier case A1:
406*ccaec48aSDavid du Colombier case A2:
407*ccaec48aSDavid du Colombier case A3:
408*ccaec48aSDavid du Colombier case A4:
409*ccaec48aSDavid du Colombier a = acon(ip->cpu, len, atype - A0);
410*ccaec48aSDavid du Colombier break;
411*ccaec48aSDavid du Colombier
412*ccaec48aSDavid du Colombier case AEb:
413*ccaec48aSDavid du Colombier len = 1;
414*ccaec48aSDavid du Colombier if(0){
415*ccaec48aSDavid du Colombier case AEw:
416*ccaec48aSDavid du Colombier len = 2;
417*ccaec48aSDavid du Colombier }
418*ccaec48aSDavid du Colombier case AEv:
419*ccaec48aSDavid du Colombier if(i->mod == 3){
420*ccaec48aSDavid du Colombier reg = i->rm;
421*ccaec48aSDavid du Colombier goto REG;
422*ccaec48aSDavid du Colombier }
423*ccaec48aSDavid du Colombier goto MEM;
424*ccaec48aSDavid du Colombier
425*ccaec48aSDavid du Colombier case AM:
426*ccaec48aSDavid du Colombier case AMp:
427*ccaec48aSDavid du Colombier case AMa:
428*ccaec48aSDavid du Colombier case AMa2:
429*ccaec48aSDavid du Colombier if(i->mod == 3)
430*ccaec48aSDavid du Colombier trap(ip->cpu, EBADOP);
431*ccaec48aSDavid du Colombier MEM:
432*ccaec48aSDavid du Colombier a = amem(ip->cpu, len, i->sreg, i->off);
433*ccaec48aSDavid du Colombier if(atype == AMa2)
434*ccaec48aSDavid du Colombier a->off += i->olen;
435*ccaec48aSDavid du Colombier break;
436*ccaec48aSDavid du Colombier
437*ccaec48aSDavid du Colombier case AGb:
438*ccaec48aSDavid du Colombier len = 1;
439*ccaec48aSDavid du Colombier if(0){
440*ccaec48aSDavid du Colombier case AGw:
441*ccaec48aSDavid du Colombier len = 2;
442*ccaec48aSDavid du Colombier }
443*ccaec48aSDavid du Colombier case AGv:
444*ccaec48aSDavid du Colombier reg = i->reg;
445*ccaec48aSDavid du Colombier REG:
446*ccaec48aSDavid du Colombier a = areg(ip->cpu, len, reg + RAX);
447*ccaec48aSDavid du Colombier if(len == 1 && reg >= 4){
448*ccaec48aSDavid du Colombier a->reg -= 4;
449*ccaec48aSDavid du Colombier a->tag |= TH;
450*ccaec48aSDavid du Colombier }
451*ccaec48aSDavid du Colombier break;
452*ccaec48aSDavid du Colombier
453*ccaec48aSDavid du Colombier case AIb:
454*ccaec48aSDavid du Colombier case AIc:
455*ccaec48aSDavid du Colombier len = 1;
456*ccaec48aSDavid du Colombier if(0){
457*ccaec48aSDavid du Colombier case AIw:
458*ccaec48aSDavid du Colombier len = 2;
459*ccaec48aSDavid du Colombier }
460*ccaec48aSDavid du Colombier case AIv:
461*ccaec48aSDavid du Colombier a = adup(ip); ip->off += len;
462*ccaec48aSDavid du Colombier a->len = len;
463*ccaec48aSDavid du Colombier break;
464*ccaec48aSDavid du Colombier
465*ccaec48aSDavid du Colombier case AJb:
466*ccaec48aSDavid du Colombier len = 1;
467*ccaec48aSDavid du Colombier case AJv:
468*ccaec48aSDavid du Colombier a = adup(ip); ip->off += len;
469*ccaec48aSDavid du Colombier a->len = len;
470*ccaec48aSDavid du Colombier a->off = ip->off + ars(a);
471*ccaec48aSDavid du Colombier break;
472*ccaec48aSDavid du Colombier
473*ccaec48aSDavid du Colombier case AJr:
474*ccaec48aSDavid du Colombier if(i->mod != 3)
475*ccaec48aSDavid du Colombier trap(ip->cpu, EBADOP);
476*ccaec48aSDavid du Colombier a = adup(ip);
477*ccaec48aSDavid du Colombier a->off = ar(areg(ip->cpu, i->olen, i->rm + RAX));
478*ccaec48aSDavid du Colombier break;
479*ccaec48aSDavid du Colombier
480*ccaec48aSDavid du Colombier case AAp:
481*ccaec48aSDavid du Colombier a = afar(ip, ip->len, len); ip->off += 2+len;
482*ccaec48aSDavid du Colombier break;
483*ccaec48aSDavid du Colombier
484*ccaec48aSDavid du Colombier case AOb:
485*ccaec48aSDavid du Colombier len = 1;
486*ccaec48aSDavid du Colombier case AOv:
487*ccaec48aSDavid du Colombier a = adup(ip); ip->off += i->alen;
488*ccaec48aSDavid du Colombier a->len = i->alen;
489*ccaec48aSDavid du Colombier a = amem(ip->cpu, len, i->sreg, ar(a));
490*ccaec48aSDavid du Colombier break;
491*ccaec48aSDavid du Colombier
492*ccaec48aSDavid du Colombier case ASw:
493*ccaec48aSDavid du Colombier reg = i->reg;
494*ccaec48aSDavid du Colombier SREG:
495*ccaec48aSDavid du Colombier a = areg(ip->cpu, 2, reg + RES);
496*ccaec48aSDavid du Colombier break;
497*ccaec48aSDavid du Colombier
498*ccaec48aSDavid du Colombier case AXb:
499*ccaec48aSDavid du Colombier len = 1;
500*ccaec48aSDavid du Colombier case AXv:
501*ccaec48aSDavid du Colombier a = amem(ip->cpu, len, i->sreg, ar(areg(ip->cpu, i->alen, RSI)));
502*ccaec48aSDavid du Colombier break;
503*ccaec48aSDavid du Colombier
504*ccaec48aSDavid du Colombier case AYb:
505*ccaec48aSDavid du Colombier len = 1;
506*ccaec48aSDavid du Colombier case AYv:
507*ccaec48aSDavid du Colombier a = amem(ip->cpu, len, RES, ar(areg(ip->cpu, i->alen, RDI)));
508*ccaec48aSDavid du Colombier break;
509*ccaec48aSDavid du Colombier
510*ccaec48aSDavid du Colombier case AFv:
511*ccaec48aSDavid du Colombier a = areg(ip->cpu, len, RFL);
512*ccaec48aSDavid du Colombier break;
513*ccaec48aSDavid du Colombier
514*ccaec48aSDavid du Colombier case AAL:
515*ccaec48aSDavid du Colombier case ACL:
516*ccaec48aSDavid du Colombier case ADL:
517*ccaec48aSDavid du Colombier case ABL:
518*ccaec48aSDavid du Colombier case AAH:
519*ccaec48aSDavid du Colombier case ACH:
520*ccaec48aSDavid du Colombier case ADH:
521*ccaec48aSDavid du Colombier case ABH:
522*ccaec48aSDavid du Colombier len = 1;
523*ccaec48aSDavid du Colombier reg = atype - AAL;
524*ccaec48aSDavid du Colombier goto REG;
525*ccaec48aSDavid du Colombier
526*ccaec48aSDavid du Colombier case AAX:
527*ccaec48aSDavid du Colombier case ACX:
528*ccaec48aSDavid du Colombier case ADX:
529*ccaec48aSDavid du Colombier case ABX:
530*ccaec48aSDavid du Colombier case ASP:
531*ccaec48aSDavid du Colombier case ABP:
532*ccaec48aSDavid du Colombier case ASI:
533*ccaec48aSDavid du Colombier case ADI:
534*ccaec48aSDavid du Colombier reg = atype - AAX;
535*ccaec48aSDavid du Colombier goto REG;
536*ccaec48aSDavid du Colombier
537*ccaec48aSDavid du Colombier case AES:
538*ccaec48aSDavid du Colombier case ACS:
539*ccaec48aSDavid du Colombier case ASS:
540*ccaec48aSDavid du Colombier case ADS:
541*ccaec48aSDavid du Colombier case AFS:
542*ccaec48aSDavid du Colombier case AGS:
543*ccaec48aSDavid du Colombier reg = atype - AES;
544*ccaec48aSDavid du Colombier goto SREG;
545*ccaec48aSDavid du Colombier }
546*ccaec48aSDavid du Colombier a->atype = atype;
547*ccaec48aSDavid du Colombier return a;
548*ccaec48aSDavid du Colombier }
549*ccaec48aSDavid du Colombier
550*ccaec48aSDavid du Colombier static int
otherlen(int a)551*ccaec48aSDavid du Colombier otherlen(int a)
552*ccaec48aSDavid du Colombier {
553*ccaec48aSDavid du Colombier if(a == 2)
554*ccaec48aSDavid du Colombier return 4;
555*ccaec48aSDavid du Colombier else if(a == 4)
556*ccaec48aSDavid du Colombier return 2;
557*ccaec48aSDavid du Colombier abort();
558*ccaec48aSDavid du Colombier return 0;
559*ccaec48aSDavid du Colombier }
560*ccaec48aSDavid du Colombier
561*ccaec48aSDavid du Colombier void
decode(Iarg * ip,Inst * i)562*ccaec48aSDavid du Colombier decode(Iarg *ip, Inst *i)
563*ccaec48aSDavid du Colombier {
564*ccaec48aSDavid du Colombier Optab *t, *t2;
565*ccaec48aSDavid du Colombier Cpu *cpu;
566*ccaec48aSDavid du Colombier
567*ccaec48aSDavid du Colombier cpu = ip->cpu;
568*ccaec48aSDavid du Colombier
569*ccaec48aSDavid du Colombier i->op = 0;
570*ccaec48aSDavid du Colombier i->rep = 0;
571*ccaec48aSDavid du Colombier i->sreg = 0;
572*ccaec48aSDavid du Colombier i->dsreg = RDS;
573*ccaec48aSDavid du Colombier i->olen = cpu->olen;
574*ccaec48aSDavid du Colombier i->alen = cpu->alen;
575*ccaec48aSDavid du Colombier i->a1 = i->a2 = i->a3 = nil;
576*ccaec48aSDavid du Colombier
577*ccaec48aSDavid du Colombier for(;;){
578*ccaec48aSDavid du Colombier i->code = ar(ip); ip->off++;
579*ccaec48aSDavid du Colombier t = optab + i->code;
580*ccaec48aSDavid du Colombier switch(t->op){
581*ccaec48aSDavid du Colombier case OOSIZE:
582*ccaec48aSDavid du Colombier i->olen = otherlen(cpu->olen);
583*ccaec48aSDavid du Colombier continue;
584*ccaec48aSDavid du Colombier case OASIZE:
585*ccaec48aSDavid du Colombier i->alen = otherlen(cpu->alen);
586*ccaec48aSDavid du Colombier continue;
587*ccaec48aSDavid du Colombier case OREPE:
588*ccaec48aSDavid du Colombier case OREPNE:
589*ccaec48aSDavid du Colombier i->rep = t->op;
590*ccaec48aSDavid du Colombier continue;
591*ccaec48aSDavid du Colombier case OLOCK:
592*ccaec48aSDavid du Colombier continue;
593*ccaec48aSDavid du Colombier case OSEG:
594*ccaec48aSDavid du Colombier i->sreg = t->a1-AES+RES;
595*ccaec48aSDavid du Colombier continue;
596*ccaec48aSDavid du Colombier case O0F:
597*ccaec48aSDavid du Colombier i->code = ar(ip); ip->off++;
598*ccaec48aSDavid du Colombier t = optab0F + i->code;
599*ccaec48aSDavid du Colombier break;
600*ccaec48aSDavid du Colombier }
601*ccaec48aSDavid du Colombier break;
602*ccaec48aSDavid du Colombier }
603*ccaec48aSDavid du Colombier t2 = optabgp[t->op];
604*ccaec48aSDavid du Colombier if(t2 || modrmarg[t->a1] || modrmarg[t->a2] || modrmarg[t->a3])
605*ccaec48aSDavid du Colombier if(i->alen == 2)
606*ccaec48aSDavid du Colombier getmodrm16(ip, i);
607*ccaec48aSDavid du Colombier else
608*ccaec48aSDavid du Colombier getmodrm32(ip, i);
609*ccaec48aSDavid du Colombier if(i->sreg == 0)
610*ccaec48aSDavid du Colombier i->sreg = i->dsreg;
611*ccaec48aSDavid du Colombier
612*ccaec48aSDavid du Colombier for(;;){
613*ccaec48aSDavid du Colombier if(t->a1)
614*ccaec48aSDavid du Colombier i->a1 = getarg(ip, i, t->a1);
615*ccaec48aSDavid du Colombier if(t->a2)
616*ccaec48aSDavid du Colombier i->a2 = getarg(ip, i, t->a2);
617*ccaec48aSDavid du Colombier if(t->a3)
618*ccaec48aSDavid du Colombier i->a3 = getarg(ip, i, t->a3);
619*ccaec48aSDavid du Colombier if(t2 == nil)
620*ccaec48aSDavid du Colombier break;
621*ccaec48aSDavid du Colombier t = t2 + i->reg;
622*ccaec48aSDavid du Colombier t2 = nil;
623*ccaec48aSDavid du Colombier }
624*ccaec48aSDavid du Colombier i->op = t->op;
625*ccaec48aSDavid du Colombier }
626