Mercurial > repos > blastem
comparison 68kinst.c @ 15:c0f339564819
Make x86 generator generic with respect to operand size for immediate parameters.
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 27 Nov 2012 22:43:32 -0800 |
parents | 168b1a873895 |
children | 3e7bfde7606e |
comparison
equal
deleted
inserted
replaced
14:2bdad0f52f42 | 15:c0f339564819 |
---|---|
37 switch(reg) | 37 switch(reg) |
38 { | 38 { |
39 case 0: | 39 case 0: |
40 dst->addr_mode = MODE_ABSOLUTE_SHORT; | 40 dst->addr_mode = MODE_ABSOLUTE_SHORT; |
41 ext = *(++cur); | 41 ext = *(++cur); |
42 dst->params.u32 = sign_extend16(ext); | 42 dst->params.immed = sign_extend16(ext); |
43 break; | 43 break; |
44 case 1: | 44 case 1: |
45 dst->addr_mode = MODE_ABSOLUTE; | 45 dst->addr_mode = MODE_ABSOLUTE; |
46 ext = *(++cur); | 46 ext = *(++cur); |
47 dst->params.u32 = ext << 16 | *(++cur); | 47 dst->params.immed = ext << 16 | *(++cur); |
48 break; | 48 break; |
49 case 2: | 49 case 2: |
50 dst->addr_mode = MODE_PC_DISPLACE; | 50 dst->addr_mode = MODE_PC_DISPLACE; |
51 ext = *(++cur); | 51 ext = *(++cur); |
52 dst->params.regs.displacement = sign_extend16(ext); | 52 dst->params.regs.displacement = sign_extend16(ext); |
55 dst->addr_mode = MODE_IMMEDIATE; | 55 dst->addr_mode = MODE_IMMEDIATE; |
56 ext = *(++cur); | 56 ext = *(++cur); |
57 switch (size) | 57 switch (size) |
58 { | 58 { |
59 case OPSIZE_BYTE: | 59 case OPSIZE_BYTE: |
60 dst->params.u8 = ext; | 60 dst->params.immed = ext & 0xFF; |
61 break; | 61 break; |
62 case OPSIZE_WORD: | 62 case OPSIZE_WORD: |
63 dst->params.u16 = ext; | 63 dst->params.immed = ext; |
64 break; | 64 break; |
65 case OPSIZE_LONG: | 65 case OPSIZE_LONG: |
66 dst->params.u32 = ext << 16 | *(++cur); | 66 dst->params.immed = ext << 16 | *(++cur); |
67 break; | 67 break; |
68 } | 68 } |
69 break; | 69 break; |
70 //TODO: implement the rest of these | 70 //TODO: implement the rest of these |
71 } | 71 } |
143 break; | 143 break; |
144 } | 144 } |
145 opmode = (*istream >> 3) & 0x7; | 145 opmode = (*istream >> 3) & 0x7; |
146 reg = *istream & 0x7; | 146 reg = *istream & 0x7; |
147 decoded->src.addr_mode = MODE_IMMEDIATE; | 147 decoded->src.addr_mode = MODE_IMMEDIATE; |
148 decoded->src.params.u8 = *(++istream); | 148 decoded->src.params.immed = *(++istream) & 0xFF; |
149 decoded->extra.size = OPSIZE_BYTE; | 149 decoded->extra.size = OPSIZE_BYTE; |
150 istream = m68k_decode_op_ex(istream, opmode, reg, OPSIZE_BYTE, &(decoded->dst)); | 150 istream = m68k_decode_op_ex(istream, opmode, reg, OPSIZE_BYTE, &(decoded->dst)); |
151 } else if ((*istream & 0xC0) == 0xC0) { | 151 } else if ((*istream & 0xC0) == 0xC0) { |
152 #ifdef M68020 | 152 #ifdef M68020 |
153 //CMP2, CHK2, CAS, CAS2, RTM, CALLM | 153 //CMP2, CHK2, CAS, CAS2, RTM, CALLM |
158 case 0: | 158 case 0: |
159 if ((*istream & 0xFF) == 0x3C) { | 159 if ((*istream & 0xFF) == 0x3C) { |
160 decoded->op = M68K_ORI_CCR; | 160 decoded->op = M68K_ORI_CCR; |
161 decoded->extra.size = OPSIZE_BYTE; | 161 decoded->extra.size = OPSIZE_BYTE; |
162 decoded->src.addr_mode = MODE_IMMEDIATE; | 162 decoded->src.addr_mode = MODE_IMMEDIATE; |
163 decoded->src.params.u8 = *(++istream); | 163 decoded->src.params.immed = *(++istream) & 0xFF; |
164 } else if((*istream & 0xFF) == 0x7C) { | 164 } else if((*istream & 0xFF) == 0x7C) { |
165 decoded->op = M68K_ORI_SR; | 165 decoded->op = M68K_ORI_SR; |
166 decoded->extra.size = OPSIZE_WORD; | 166 decoded->extra.size = OPSIZE_WORD; |
167 decoded->src.addr_mode = MODE_IMMEDIATE; | 167 decoded->src.addr_mode = MODE_IMMEDIATE; |
168 decoded->src.params.u16 = *(++istream); | 168 decoded->src.params.immed = *(++istream); |
169 } else { | 169 } else { |
170 decoded->op = M68K_OR; | 170 decoded->op = M68K_OR; |
171 decoded->variant = VAR_IMMEDIATE; | 171 decoded->variant = VAR_IMMEDIATE; |
172 decoded->src.addr_mode = MODE_IMMEDIATE; | 172 decoded->src.addr_mode = MODE_IMMEDIATE; |
173 decoded->extra.size = size = (*istream >> 6) & 3; | 173 decoded->extra.size = size = (*istream >> 6) & 3; |
174 reg = *istream & 0x7; | 174 reg = *istream & 0x7; |
175 opmode = (*istream >> 3) & 0x7; | 175 opmode = (*istream >> 3) & 0x7; |
176 switch (size) | 176 switch (size) |
177 { | 177 { |
178 case OPSIZE_BYTE: | 178 case OPSIZE_BYTE: |
179 decoded->src.params.u8 = *(++istream); | 179 decoded->src.params.immed = *(++istream) & 0xFF; |
180 break; | 180 break; |
181 case OPSIZE_WORD: | 181 case OPSIZE_WORD: |
182 decoded->src.params.u16 = *(++istream); | 182 decoded->src.params.immed = *(++istream); |
183 break; | 183 break; |
184 case OPSIZE_LONG: | 184 case OPSIZE_LONG: |
185 immed = *(++istream); | 185 immed = *(++istream); |
186 decoded->src.params.u32 = immed << 16 | *(++istream); | 186 decoded->src.params.immed = immed << 16 | *(++istream); |
187 break; | 187 break; |
188 } | 188 } |
189 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 189 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
190 } | 190 } |
191 break; | 191 break; |
193 //ANDI, ANDI to CCR, ANDI to SR | 193 //ANDI, ANDI to CCR, ANDI to SR |
194 if ((*istream & 0xFF) == 0x3C) { | 194 if ((*istream & 0xFF) == 0x3C) { |
195 decoded->op = M68K_ANDI_CCR; | 195 decoded->op = M68K_ANDI_CCR; |
196 decoded->extra.size = OPSIZE_BYTE; | 196 decoded->extra.size = OPSIZE_BYTE; |
197 decoded->src.addr_mode = MODE_IMMEDIATE; | 197 decoded->src.addr_mode = MODE_IMMEDIATE; |
198 decoded->src.params.u8 = *(++istream); | 198 decoded->src.params.immed = *(++istream) & 0xFF; |
199 } else if((*istream & 0xFF) == 0x7C) { | 199 } else if((*istream & 0xFF) == 0x7C) { |
200 decoded->op = M68K_ANDI_SR; | 200 decoded->op = M68K_ANDI_SR; |
201 decoded->extra.size = OPSIZE_WORD; | 201 decoded->extra.size = OPSIZE_WORD; |
202 decoded->src.addr_mode = MODE_IMMEDIATE; | 202 decoded->src.addr_mode = MODE_IMMEDIATE; |
203 decoded->src.params.u16 = *(++istream); | 203 decoded->src.params.immed = *(++istream); |
204 } else { | 204 } else { |
205 decoded->op = M68K_AND; | 205 decoded->op = M68K_AND; |
206 decoded->variant = VAR_IMMEDIATE; | 206 decoded->variant = VAR_IMMEDIATE; |
207 decoded->src.addr_mode = MODE_IMMEDIATE; | 207 decoded->src.addr_mode = MODE_IMMEDIATE; |
208 decoded->extra.size = size = (*istream >> 6) & 3; | 208 decoded->extra.size = size = (*istream >> 6) & 3; |
209 reg = *istream & 0x7; | 209 reg = *istream & 0x7; |
210 opmode = (*istream >> 3) & 0x7; | 210 opmode = (*istream >> 3) & 0x7; |
211 switch (size) | 211 switch (size) |
212 { | 212 { |
213 case OPSIZE_BYTE: | 213 case OPSIZE_BYTE: |
214 decoded->src.params.u8 = *(++istream); | 214 decoded->src.params.immed = *(++istream) & 0xFF; |
215 break; | 215 break; |
216 case OPSIZE_WORD: | 216 case OPSIZE_WORD: |
217 decoded->src.params.u16 = *(++istream); | 217 decoded->src.params.immed = *(++istream); |
218 break; | 218 break; |
219 case OPSIZE_LONG: | 219 case OPSIZE_LONG: |
220 immed = *(++istream); | 220 immed = *(++istream); |
221 decoded->src.params.u32 = immed << 16 | *(++istream); | 221 decoded->src.params.immed = immed << 16 | *(++istream); |
222 break; | 222 break; |
223 } | 223 } |
224 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 224 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
225 } | 225 } |
226 break; | 226 break; |
232 reg = *istream & 0x7; | 232 reg = *istream & 0x7; |
233 opmode = (*istream >> 3) & 0x7; | 233 opmode = (*istream >> 3) & 0x7; |
234 switch (size) | 234 switch (size) |
235 { | 235 { |
236 case OPSIZE_BYTE: | 236 case OPSIZE_BYTE: |
237 decoded->src.params.u8 = *(++istream); | 237 decoded->src.params.immed = *(++istream) & 0xFF; |
238 break; | 238 break; |
239 case OPSIZE_WORD: | 239 case OPSIZE_WORD: |
240 decoded->src.params.u16 = *(++istream); | 240 decoded->src.params.immed = *(++istream); |
241 break; | 241 break; |
242 case OPSIZE_LONG: | 242 case OPSIZE_LONG: |
243 immed = *(++istream); | 243 immed = *(++istream); |
244 decoded->src.params.u32 = immed << 16 | *(++istream); | 244 decoded->src.params.immed = immed << 16 | *(++istream); |
245 break; | 245 break; |
246 } | 246 } |
247 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 247 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
248 break; | 248 break; |
249 case 3: | 249 case 3: |
254 reg = *istream & 0x7; | 254 reg = *istream & 0x7; |
255 opmode = (*istream >> 3) & 0x7; | 255 opmode = (*istream >> 3) & 0x7; |
256 switch (size) | 256 switch (size) |
257 { | 257 { |
258 case OPSIZE_BYTE: | 258 case OPSIZE_BYTE: |
259 decoded->src.params.u8 = *(++istream); | 259 decoded->src.params.immed = *(++istream) & 0xFF; |
260 break; | 260 break; |
261 case OPSIZE_WORD: | 261 case OPSIZE_WORD: |
262 decoded->src.params.u16 = *(++istream); | 262 decoded->src.params.immed = *(++istream); |
263 break; | 263 break; |
264 case OPSIZE_LONG: | 264 case OPSIZE_LONG: |
265 immed = *(++istream); | 265 immed = *(++istream); |
266 decoded->src.params.u32 = immed << 16 | *(++istream); | 266 decoded->src.params.immed = immed << 16 | *(++istream); |
267 break; | 267 break; |
268 } | 268 } |
269 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 269 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
270 break; | 270 break; |
271 case 4: | 271 case 4: |
284 case 3: | 284 case 3: |
285 decoded->op = M68K_BSET; | 285 decoded->op = M68K_BSET; |
286 break; | 286 break; |
287 } | 287 } |
288 decoded->src.addr_mode = MODE_IMMEDIATE; | 288 decoded->src.addr_mode = MODE_IMMEDIATE; |
289 decoded->src.params.u8 = *(++istream); | 289 decoded->src.params.immed = *(++istream) & 0xFF; |
290 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); | 290 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); |
291 break; | 291 break; |
292 case 5: | 292 case 5: |
293 //EORI, EORI to CCR, EORI to SR | 293 //EORI, EORI to CCR, EORI to SR |
294 if ((*istream & 0xFF) == 0x3C) { | 294 if ((*istream & 0xFF) == 0x3C) { |
295 decoded->op = M68K_EORI_CCR; | 295 decoded->op = M68K_EORI_CCR; |
296 decoded->extra.size = OPSIZE_BYTE; | 296 decoded->extra.size = OPSIZE_BYTE; |
297 decoded->src.addr_mode = MODE_IMMEDIATE; | 297 decoded->src.addr_mode = MODE_IMMEDIATE; |
298 decoded->src.params.u8 = *(++istream); | 298 decoded->src.params.immed = *(++istream) & 0xFF; |
299 } else if((*istream & 0xFF) == 0x7C) { | 299 } else if((*istream & 0xFF) == 0x7C) { |
300 decoded->op = M68K_EORI_SR; | 300 decoded->op = M68K_EORI_SR; |
301 decoded->extra.size = OPSIZE_WORD; | 301 decoded->extra.size = OPSIZE_WORD; |
302 decoded->src.addr_mode = MODE_IMMEDIATE; | 302 decoded->src.addr_mode = MODE_IMMEDIATE; |
303 decoded->src.params.u16 = *(++istream); | 303 decoded->src.params.immed = *(++istream); |
304 } else { | 304 } else { |
305 decoded->op = M68K_EOR; | 305 decoded->op = M68K_EOR; |
306 decoded->variant = VAR_IMMEDIATE; | 306 decoded->variant = VAR_IMMEDIATE; |
307 decoded->src.addr_mode = MODE_IMMEDIATE; | 307 decoded->src.addr_mode = MODE_IMMEDIATE; |
308 decoded->extra.size = size = (*istream >> 6) & 3; | 308 decoded->extra.size = size = (*istream >> 6) & 3; |
309 reg = *istream & 0x7; | 309 reg = *istream & 0x7; |
310 opmode = (*istream >> 3) & 0x7; | 310 opmode = (*istream >> 3) & 0x7; |
311 switch (size) | 311 switch (size) |
312 { | 312 { |
313 case OPSIZE_BYTE: | 313 case OPSIZE_BYTE: |
314 decoded->src.params.u8 = *(++istream); | 314 decoded->src.params.immed = *(++istream) & 0xFF; |
315 break; | 315 break; |
316 case OPSIZE_WORD: | 316 case OPSIZE_WORD: |
317 decoded->src.params.u16 = *(++istream); | 317 decoded->src.params.immed = *(++istream); |
318 break; | 318 break; |
319 case OPSIZE_LONG: | 319 case OPSIZE_LONG: |
320 immed = *(++istream); | 320 immed = *(++istream); |
321 decoded->src.params.u32 = immed << 16 | *(++istream); | 321 decoded->src.params.immed = immed << 16 | *(++istream); |
322 break; | 322 break; |
323 } | 323 } |
324 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 324 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
325 } | 325 } |
326 break; | 326 break; |
332 reg = *istream & 0x7; | 332 reg = *istream & 0x7; |
333 opmode = (*istream >> 3) & 0x7; | 333 opmode = (*istream >> 3) & 0x7; |
334 switch (decoded->extra.size) | 334 switch (decoded->extra.size) |
335 { | 335 { |
336 case OPSIZE_BYTE: | 336 case OPSIZE_BYTE: |
337 decoded->src.params.u8 = *(++istream); | 337 decoded->src.params.immed = *(++istream) & 0xFF; |
338 break; | 338 break; |
339 case OPSIZE_WORD: | 339 case OPSIZE_WORD: |
340 decoded->src.params.u16 = *(++istream); | 340 decoded->src.params.immed = *(++istream); |
341 break; | 341 break; |
342 case OPSIZE_LONG: | 342 case OPSIZE_LONG: |
343 immed = *(++istream); | 343 immed = *(++istream); |
344 decoded->src.params.u32 = (immed << 16) | *(++istream); | 344 decoded->src.params.immed = (immed << 16) | *(++istream); |
345 break; | 345 break; |
346 } | 346 } |
347 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); | 347 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); |
348 break; | 348 break; |
349 case 7: | 349 case 7: |
409 decoded->extra.size = *istream & 0x40 ? OPSIZE_LONG : OPSIZE_WORD; | 409 decoded->extra.size = *istream & 0x40 ? OPSIZE_LONG : OPSIZE_WORD; |
410 reg = *istream & 0x7; | 410 reg = *istream & 0x7; |
411 immed = *(++istream); | 411 immed = *(++istream); |
412 if(*istream & 0x400) { | 412 if(*istream & 0x400) { |
413 decoded->dst.addr_mode = MODE_REG; | 413 decoded->dst.addr_mode = MODE_REG; |
414 decoded->dst.params.u16 = immed; | 414 decoded->dst.params.immed = immed; |
415 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->src)); | 415 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->src)); |
416 } else { | 416 } else { |
417 decoded->src.addr_mode = MODE_REG; | 417 decoded->src.addr_mode = MODE_REG; |
418 decoded->src.params.u16 = immed; | 418 decoded->src.params.immed = immed; |
419 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); | 419 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); |
420 } | 420 } |
421 } else { | 421 } else { |
422 optype = (*istream >> 9) & 0x7; | 422 optype = (*istream >> 9) & 0x7; |
423 size = (*istream >> 6) & 0x3; | 423 size = (*istream >> 6) & 0x3; |
495 case 9: | 495 case 9: |
496 #ifdef M68010 | 496 #ifdef M68010 |
497 decoded->op = M68K_BKPT; | 497 decoded->op = M68K_BKPT; |
498 decoded->src.addr_mode = MODE_IMMEDIATE; | 498 decoded->src.addr_mode = MODE_IMMEDIATE; |
499 decoded->extra.size = OPSIZE_UNSIZED; | 499 decoded->extra.size = OPSIZE_UNSIZED; |
500 decoded->src.params.u32 = *istream & 0x7; | 500 decoded->src.params.immed = *istream & 0x7; |
501 #endif | 501 #endif |
502 break; | 502 break; |
503 case 0x10: | 503 case 0x10: |
504 decoded->op = M68K_EXT; | 504 decoded->op = M68K_EXT; |
505 decoded->src.addr_mode = MODE_REG; | 505 decoded->src.addr_mode = MODE_REG; |
571 case 1: | 571 case 1: |
572 //TRAP | 572 //TRAP |
573 decoded->op = M68K_TRAP; | 573 decoded->op = M68K_TRAP; |
574 decoded->extra.size = OPSIZE_UNSIZED; | 574 decoded->extra.size = OPSIZE_UNSIZED; |
575 decoded->src.addr_mode = MODE_IMMEDIATE; | 575 decoded->src.addr_mode = MODE_IMMEDIATE; |
576 decoded->src.params.u32 = *istream & 0xF; | 576 decoded->src.params.immed = *istream & 0xF; |
577 break; | 577 break; |
578 case 2: | 578 case 2: |
579 //LINK.w | 579 //LINK.w |
580 decoded->op = M68K_LINK; | 580 decoded->op = M68K_LINK; |
581 decoded->extra.size = OPSIZE_WORD; | 581 decoded->extra.size = OPSIZE_WORD; |
582 decoded->src.addr_mode = MODE_AREG; | 582 decoded->src.addr_mode = MODE_AREG; |
583 decoded->src.params.regs.pri = *istream & 0x7; | 583 decoded->src.params.regs.pri = *istream & 0x7; |
584 decoded->dst.addr_mode = MODE_IMMEDIATE; | 584 decoded->dst.addr_mode = MODE_IMMEDIATE; |
585 decoded->dst.params.u16 = *(++istream); | 585 decoded->dst.params.immed = *(++istream); |
586 break; | 586 break; |
587 case 3: | 587 case 3: |
588 //UNLK | 588 //UNLK |
589 decoded->op = M68K_UNLK; | 589 decoded->op = M68K_UNLK; |
590 decoded->extra.size = OPSIZE_UNSIZED; | 590 decoded->extra.size = OPSIZE_UNSIZED; |
614 decoded->op = M68K_NOP; | 614 decoded->op = M68K_NOP; |
615 break; | 615 break; |
616 case 2: | 616 case 2: |
617 decoded->op = M68K_STOP; | 617 decoded->op = M68K_STOP; |
618 decoded->src.addr_mode = MODE_IMMEDIATE; | 618 decoded->src.addr_mode = MODE_IMMEDIATE; |
619 decoded->src.params.u32 =*(++istream); | 619 decoded->src.params.immed =*(++istream); |
620 break; | 620 break; |
621 case 3: | 621 case 3: |
622 decoded->op = M68K_RTE; | 622 decoded->op = M68K_RTE; |
623 break; | 623 break; |
624 case 4: | 624 case 4: |
625 #ifdef M68010 | 625 #ifdef M68010 |
626 decoded->op = M68K_RTD; | 626 decoded->op = M68K_RTD; |
627 decoded->src.addr_mode = MODE_IMMEDIATE; | 627 decoded->src.addr_mode = MODE_IMMEDIATE; |
628 decoded->src.params.u32 =*(++istream); | 628 decoded->src.params.immed =*(++istream); |
629 #endif | 629 #endif |
630 break; | 630 break; |
631 case 5: | 631 case 5: |
632 decoded->op = M68K_RTS; | 632 decoded->op = M68K_RTS; |
633 break; | 633 break; |
660 switch ((*istream >> 3) & 0x7) | 660 switch ((*istream >> 3) & 0x7) |
661 { | 661 { |
662 case 1: //DBcc | 662 case 1: //DBcc |
663 decoded->op = M68K_DBCC; | 663 decoded->op = M68K_DBCC; |
664 decoded->src.addr_mode = MODE_IMMEDIATE; | 664 decoded->src.addr_mode = MODE_IMMEDIATE; |
665 decoded->src.params.u16 = *(++istream); | 665 decoded->src.params.immed = *(++istream); |
666 decoded->dst.addr_mode = MODE_REG; | 666 decoded->dst.addr_mode = MODE_REG; |
667 decoded->dst.params.regs.pri = *istream & 0x7; | 667 decoded->dst.params.regs.pri = *istream & 0x7; |
668 break; | 668 break; |
669 case 7: //TRAPcc | 669 case 7: //TRAPcc |
670 #ifdef M68020 | 670 #ifdef M68020 |
686 istream = m68k_decode_op(istream, size, &(decoded->dst)); | 686 istream = m68k_decode_op(istream, size, &(decoded->dst)); |
687 immed = m68K_reg_quick_field(*istream); | 687 immed = m68K_reg_quick_field(*istream); |
688 if (!immed) { | 688 if (!immed) { |
689 immed = 8; | 689 immed = 8; |
690 } | 690 } |
691 switch (size) | 691 decoded->src.params.immed = immed; |
692 { | |
693 case OPSIZE_BYTE: | |
694 decoded->src.params.u8 = immed; | |
695 break; | |
696 case OPSIZE_WORD: | |
697 decoded->src.params.u16 = immed; | |
698 break; | |
699 case OPSIZE_LONG: | |
700 decoded->src.params.u32 = immed; | |
701 break; | |
702 } | |
703 if (*istream & 0x100) { | 692 if (*istream & 0x100) { |
704 decoded->op = M68K_SUB; | 693 decoded->op = M68K_SUB; |
705 } else { | 694 } else { |
706 decoded->op = M68K_ADD; | 695 decoded->op = M68K_ADD; |
707 } | 696 } |
722 immed |= *(++istream); | 711 immed |= *(++istream); |
723 } else { | 712 } else { |
724 decoded->variant = VAR_BYTE; | 713 decoded->variant = VAR_BYTE; |
725 immed = sign_extend8(immed); | 714 immed = sign_extend8(immed); |
726 } | 715 } |
727 decoded->src.params.u32 = immed; | 716 decoded->src.params.immed = immed; |
728 break; | 717 break; |
729 case MOVEQ: | 718 case MOVEQ: |
730 decoded->op = M68K_MOVE; | 719 decoded->op = M68K_MOVE; |
731 decoded->variant = VAR_QUICK; | 720 decoded->variant = VAR_QUICK; |
721 decoded->extra.size = OPSIZE_LONG; | |
732 decoded->src.addr_mode = MODE_IMMEDIATE; | 722 decoded->src.addr_mode = MODE_IMMEDIATE; |
733 decoded->src.params.u32 = sign_extend8(*istream & 0xFF); | 723 decoded->src.params.immed = sign_extend8(*istream & 0xFF); |
734 decoded->dst.addr_mode = MODE_REG; | 724 decoded->dst.addr_mode = MODE_REG; |
735 decoded->dst.params.regs.pri = m68K_reg_quick_field(*istream); | 725 decoded->dst.params.regs.pri = m68K_reg_quick_field(*istream); |
736 immed = *istream & 0xFF; | 726 immed = *istream & 0xFF; |
737 break; | 727 break; |
738 case OR_DIV_SBCD: | 728 case OR_DIV_SBCD: |
1010 } | 1000 } |
1011 decoded->extra.size = (*istream >> 6) & 0x3; | 1001 decoded->extra.size = (*istream >> 6) & 0x3; |
1012 immed = (*istream >> 9) & 0x7; | 1002 immed = (*istream >> 9) & 0x7; |
1013 if (*istream & 0x100) { | 1003 if (*istream & 0x100) { |
1014 decoded->src.addr_mode = MODE_IMMEDIATE; | 1004 decoded->src.addr_mode = MODE_IMMEDIATE; |
1015 switch(decoded->extra.size) | 1005 decoded->src.params.immed = immed; |
1016 { | |
1017 case OPSIZE_BYTE: | |
1018 decoded->src.params.u8 = immed; | |
1019 break; | |
1020 case OPSIZE_WORD: | |
1021 decoded->src.params.u16 = immed; | |
1022 break; | |
1023 case OPSIZE_LONG: | |
1024 decoded->src.params.u32 = immed; | |
1025 break; | |
1026 } | |
1027 } else { | 1006 } else { |
1028 decoded->src.addr_mode = MODE_REG; | 1007 decoded->src.addr_mode = MODE_REG; |
1029 decoded->src.params.regs.pri = immed; | 1008 decoded->src.params.regs.pri = immed; |
1030 } | 1009 } |
1031 decoded->dst.addr_mode = MODE_REG; | 1010 decoded->dst.addr_mode = MODE_REG; |
1134 "lt", | 1113 "lt", |
1135 "gt", | 1114 "gt", |
1136 "le" | 1115 "le" |
1137 }; | 1116 }; |
1138 | 1117 |
1139 int m68k_disasm_op(m68k_op_info *decoded, uint8_t size, char *dst, int need_comma) | 1118 int m68k_disasm_op(m68k_op_info *decoded, char *dst, int need_comma) |
1140 { | 1119 { |
1141 char * c = need_comma ? "," : ""; | 1120 char * c = need_comma ? "," : ""; |
1142 switch(decoded->addr_mode) | 1121 switch(decoded->addr_mode) |
1143 { | 1122 { |
1144 case MODE_REG: | 1123 case MODE_REG: |
1152 case MODE_AREG_PREDEC: | 1131 case MODE_AREG_PREDEC: |
1153 return sprintf(dst, "%s -(a%d)", c, decoded->params.regs.pri); | 1132 return sprintf(dst, "%s -(a%d)", c, decoded->params.regs.pri); |
1154 case MODE_AREG_DISPLACE: | 1133 case MODE_AREG_DISPLACE: |
1155 return sprintf(dst, "%s (a%d, %d)", c, decoded->params.regs.pri, decoded->params.regs.displacement); | 1134 return sprintf(dst, "%s (a%d, %d)", c, decoded->params.regs.pri, decoded->params.regs.displacement); |
1156 case MODE_IMMEDIATE: | 1135 case MODE_IMMEDIATE: |
1157 return sprintf(dst, "%s #%d", c, (size == OPSIZE_LONG || size == OPSIZE_UNSIZED) ? decoded->params.u32 : (size == OPSIZE_WORD ? decoded->params.u16 : decoded->params.u8)); | 1136 return sprintf(dst, "%s #%d", c, decoded->params.immed); |
1158 case MODE_ABSOLUTE_SHORT: | 1137 case MODE_ABSOLUTE_SHORT: |
1159 return sprintf(dst, "%s $%X.w", c, decoded->params.u32); | 1138 return sprintf(dst, "%s $%X.w", c, decoded->params.immed); |
1160 case MODE_ABSOLUTE: | 1139 case MODE_ABSOLUTE: |
1161 return sprintf(dst, "%s $%X", c, decoded->params.u32); | 1140 return sprintf(dst, "%s $%X", c, decoded->params.immed); |
1162 case MODE_PC_DISPLACE: | 1141 case MODE_PC_DISPLACE: |
1163 return sprintf(dst, "%s (pc, %d)", c, decoded->params.regs.displacement); | 1142 return sprintf(dst, "%s (pc, %d)", c, decoded->params.regs.displacement); |
1164 default: | 1143 default: |
1165 return 0; | 1144 return 0; |
1166 } | 1145 } |
1167 } | 1146 } |
1168 | 1147 |
1169 int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, uint8_t size, char *dst, int need_comma) | 1148 int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, char *dst, int need_comma) |
1170 { | 1149 { |
1171 int8_t dir, reg, bit, regnum, last=-1, lastreg, first=-1; | 1150 int8_t dir, reg, bit, regnum, last=-1, lastreg, first=-1; |
1172 char *rtype, *last_rtype; | 1151 char *rtype, *last_rtype; |
1173 int oplen; | 1152 int oplen; |
1174 if (decoded->addr_mode == MODE_REG) { | 1153 if (decoded->addr_mode == MODE_REG) { |
1179 reg = 0; | 1158 reg = 0; |
1180 bit = 1; | 1159 bit = 1; |
1181 } | 1160 } |
1182 strcat(dst, " "); | 1161 strcat(dst, " "); |
1183 for (oplen = 1, reg=0; bit < 16 && bit > -1; bit += dir, reg++) { | 1162 for (oplen = 1, reg=0; bit < 16 && bit > -1; bit += dir, reg++) { |
1184 if (decoded->params.u16 & (1 << bit)) { | 1163 if (decoded->params.immed & (1 << bit)) { |
1185 if (reg > 7) { | 1164 if (reg > 7) { |
1186 rtype = "a"; | 1165 rtype = "a"; |
1187 regnum = reg - 8; | 1166 regnum = reg - 8; |
1188 } else { | 1167 } else { |
1189 rtype = "d"; | 1168 rtype = "d"; |
1212 if (last >= 0 && last != first) { | 1191 if (last >= 0 && last != first) { |
1213 oplen += sprintf(dst + oplen, "-%s%d", last_rtype, last); | 1192 oplen += sprintf(dst + oplen, "-%s%d", last_rtype, last); |
1214 } | 1193 } |
1215 return oplen; | 1194 return oplen; |
1216 } else { | 1195 } else { |
1217 return m68k_disasm_op(decoded, size, dst, need_comma); | 1196 return m68k_disasm_op(decoded, dst, need_comma); |
1218 } | 1197 } |
1219 } | 1198 } |
1220 | 1199 |
1221 int m68k_disasm(m68kinst * decoded, char * dst) | 1200 int m68k_disasm(m68kinst * decoded, char * dst) |
1222 { | 1201 { |
1231 ret = strlen(mnemonics[decoded->op]) - 2; | 1210 ret = strlen(mnemonics[decoded->op]) - 2; |
1232 memcpy(dst, mnemonics[decoded->op], ret); | 1211 memcpy(dst, mnemonics[decoded->op], ret); |
1233 dst[ret] = 0; | 1212 dst[ret] = 0; |
1234 strcat(dst, cond_mnem[decoded->extra.cond]); | 1213 strcat(dst, cond_mnem[decoded->extra.cond]); |
1235 ret = strlen(dst); | 1214 ret = strlen(dst); |
1236 size = decoded->op = M68K_BCC ? OPSIZE_LONG : OPSIZE_WORD; | |
1237 break; | 1215 break; |
1238 case M68K_BSR: | 1216 case M68K_BSR: |
1239 size = OPSIZE_LONG; | |
1240 ret = sprintf(dst, "bsr%s", decoded->variant == VAR_BYTE ? ".s" : ""); | 1217 ret = sprintf(dst, "bsr%s", decoded->variant == VAR_BYTE ? ".s" : ""); |
1241 break; | 1218 break; |
1242 case M68K_MOVE_FROM_SR: | 1219 case M68K_MOVE_FROM_SR: |
1243 ret = sprintf(dst, "%s", mnemonics[decoded->op]); | 1220 ret = sprintf(dst, "%s", mnemonics[decoded->op]); |
1244 ret += sprintf(dst + ret, " SR"); | 1221 ret += sprintf(dst + ret, " SR"); |
1245 ret += m68k_disasm_op(&(decoded->dst), decoded->extra.size, dst + ret, 1); | 1222 ret += m68k_disasm_op(&(decoded->dst), dst + ret, 1); |
1246 return ret; | 1223 return ret; |
1247 case M68K_ANDI_SR: | 1224 case M68K_ANDI_SR: |
1248 case M68K_EORI_SR: | 1225 case M68K_EORI_SR: |
1249 case M68K_MOVE_SR: | 1226 case M68K_MOVE_SR: |
1250 case M68K_ORI_SR: | 1227 case M68K_ORI_SR: |
1252 case M68K_ANDI_CCR: | 1229 case M68K_ANDI_CCR: |
1253 case M68K_EORI_CCR: | 1230 case M68K_EORI_CCR: |
1254 case M68K_MOVE_CCR: | 1231 case M68K_MOVE_CCR: |
1255 case M68K_ORI_CCR: | 1232 case M68K_ORI_CCR: |
1256 ret = sprintf(dst, "%s", mnemonics[decoded->op]); | 1233 ret = sprintf(dst, "%s", mnemonics[decoded->op]); |
1257 ret += m68k_disasm_op(&(decoded->src), decoded->extra.size, dst + ret, 0); | 1234 ret += m68k_disasm_op(&(decoded->src), dst + ret, 0); |
1258 ret += sprintf(dst + ret, ", %s", special_op); | 1235 ret += sprintf(dst + ret, ", %s", special_op); |
1259 return ret; | 1236 return ret; |
1260 default: | 1237 default: |
1261 size = decoded->extra.size; | 1238 size = decoded->extra.size; |
1262 ret = sprintf(dst, "%s%s%s", | 1239 ret = sprintf(dst, "%s%s%s", |
1263 mnemonics[decoded->op], | 1240 mnemonics[decoded->op], |
1264 decoded->variant == VAR_QUICK ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""), | 1241 decoded->variant == VAR_QUICK ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""), |
1265 size == OPSIZE_BYTE ? ".b" : (size == OPSIZE_WORD ? ".w" : (size == OPSIZE_LONG ? ".l" : ""))); | 1242 size == OPSIZE_BYTE ? ".b" : (size == OPSIZE_WORD ? ".w" : (size == OPSIZE_LONG ? ".l" : ""))); |
1266 } | 1243 } |
1267 if (decoded->op == M68K_MOVEM) { | 1244 if (decoded->op == M68K_MOVEM) { |
1268 op1len = m68k_disasm_movem_op(&(decoded->src), &(decoded->dst), size, dst + ret, 0); | 1245 op1len = m68k_disasm_movem_op(&(decoded->src), &(decoded->dst), dst + ret, 0); |
1269 ret += op1len; | 1246 ret += op1len; |
1270 ret += m68k_disasm_movem_op(&(decoded->dst), &(decoded->src), size, dst + ret, op1len); | 1247 ret += m68k_disasm_movem_op(&(decoded->dst), &(decoded->src), dst + ret, op1len); |
1271 } else { | 1248 } else { |
1272 op1len = m68k_disasm_op(&(decoded->src), size, dst + ret, 0); | 1249 op1len = m68k_disasm_op(&(decoded->src), dst + ret, 0); |
1273 ret += op1len; | 1250 ret += op1len; |
1274 ret += m68k_disasm_op(&(decoded->dst), size, dst + ret, op1len); | 1251 ret += m68k_disasm_op(&(decoded->dst), dst + ret, op1len); |
1275 } | 1252 } |
1276 return ret; | 1253 return ret; |
1277 } | 1254 } |
1278 | 1255 |